From 530ff2129a9395c6d9739394dd7bb5a7ebdd2695 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eloy=20Dur=C3=A1n?= Date: Wed, 30 Sep 2020 20:21:14 +0200 Subject: [PATCH] Revert "v0.63 sync from upstream (#613)" This reverts commit efc221bd10cd8bf8fcf675eaec6a47f9bf5d385c. --- .ado/templates/apple-job-javascript.yml | 6 +- .ado/templates/apple-job-react-native.yml | 6 +- .appveyor/config.yml | 47 + .buckconfig | 2 +- .circleci/Dockerfiles/Dockerfile.android | 2 +- .circleci/config.yml | 514 +- .eslintignore | 8 +- .eslintrc | 1 - .flowconfig | 4 +- .flowconfig.android | 4 +- .flowconfig.macos | 3 +- .github/CODEOWNERS | 1 - .github/ISSUE_TEMPLATE.md | 2 + .github/ISSUE_TEMPLATE/config.yml | 14 - .github/ISSUE_TEMPLATE/question.md | 9 + .github/PULL_REQUEST_TEMPLATE.md | 4 +- .github/SUPPORT.md | 2 +- .github/label-actions.yml | 52 - .github/workflows/needs-attention.yml | 21 - .github/workflows/process-label-actions.yml | 16 - .gitignore | 6 +- IntegrationTests/IntegrationTestsApp.js | 3 - Libraries/ART/ARTSurfaceView.m | 2 + Libraries/ART/React-ART.podspec | 4 +- Libraries/ActionSheetIOS/ActionSheetIOS.js | 19 +- .../NativeActionSheetManager.js | 8 +- .../React-RCTActionSheet.podspec | 6 +- Libraries/Alert/Alert.js | 24 +- Libraries/Animated/src/Animated.js | 3 +- Libraries/Animated/src/AnimatedEvent.js | 127 +- .../Animated/src/AnimatedImplementation.js | 62 +- .../Animated/src/NativeAnimatedHelper.js | 7 +- .../src/__tests__/AnimatedNative-test.js | 4 +- .../Animated/src/animations/Animation.js | 1 + .../Animated/src/animations/DecayAnimation.js | 8 +- .../src/animations/SpringAnimation.js | 14 +- .../src/animations/TimingAnimation.js | 14 +- .../src/components/AnimatedFlatList.js | 8 +- .../Animated/src/components/AnimatedImage.js | 12 +- .../src/components/AnimatedScrollView.js | 8 +- .../src/components/AnimatedSectionList.js | 8 +- .../Animated/src/components/AnimatedText.js | 12 +- .../Animated/src/components/AnimatedView.js | 5 +- .../Animated/src/createAnimatedComponent.js | 23 +- .../src/nodes/AnimatedInterpolation.js | 41 +- Libraries/Animated/src/nodes/AnimatedNode.js | 6 +- Libraries/Animated/src/nodes/AnimatedValue.js | 23 +- .../Animated/src/nodes/AnimatedValueXY.js | 24 +- Libraries/AppState/AppState.js | 6 +- Libraries/BatchedBridge/MessageQueue.js | 20 +- Libraries/Blob/FileReader.js | 16 +- Libraries/Blob/NativeBlobModule.js | 2 +- Libraries/Blob/RCTBlobManager.mm | 22 +- Libraries/Blob/RCTFileReaderModule.mm | 8 +- Libraries/Blob/React-RCTBlob.podspec | 7 +- Libraries/CameraRoll/RCTCameraRollManager.mm | 8 +- Libraries/CameraRoll/RCTImagePickerManager.mm | 10 +- .../AccessibilityInfo.android.js | 8 +- .../AccessibilityInfo.ios.js | 24 +- .../ActivityIndicator/ActivityIndicator.js | 14 +- .../ActivityIndicatorViewNativeComponent.js | 8 +- Libraries/Components/Button.js | 3 +- .../AndroidCheckBoxNativeComponent.js | 6 +- .../Components/CheckBox/CheckBox.android.js | 33 +- .../RCTDatePickerNativeComponent.js | 1 + .../RCTDatePickerNativeComponentMacOS.js | 4 +- .../DrawerLayoutAndroid.android.js | 2 +- .../AndroidDialogPickerNativeComponent.js | 5 +- .../AndroidDropdownPickerNativeComponent.js | 5 +- Libraries/Components/Picker/Picker.js | 10 - .../Picker/PickerAndroid.android.js | 34 +- Libraries/Components/Picker/PickerIOS.ios.js | 15 +- .../Picker/RCTPickerNativeComponent.js | 5 +- Libraries/Components/Pressable/Pressable.js | 240 - .../Pressable/__tests__/Pressable-test.js | 34 - .../__snapshots__/Pressable-test.js.snap | 49 - .../Pressable/useAndroidRippleForView.js | 105 - .../ProgressBarAndroid.android.js | 3 +- .../PullToRefreshViewNativeComponent.js | 1 - .../RefreshControl/RefreshControl.js | 46 +- Libraries/Components/ScrollResponder.js | 42 +- Libraries/Components/ScrollView/ScrollView.js | 178 +- .../ScrollView/__mocks__/ScrollViewMock.js | 39 + .../ScrollView/__tests__/ScrollView-test.js | 51 - .../__snapshots__/ScrollView-test.js.snap | 93 - .../RCTSegmentedControlNativeComponent.js | 2 - Libraries/Components/StaticContainer.react.js | 9 +- .../NativeStatusBarManagerAndroid.js | 7 +- Libraries/Components/StatusBar/StatusBar.js | 51 +- .../Switch/AndroidSwitchNativeComponent.js | 13 +- Libraries/Components/Switch/Switch.js | 54 +- .../Switch/SwitchNativeComponent.js | 14 +- .../AndroidTextInputNativeComponent.js | 43 +- .../TextInput/AndroidTextInputViewConfig.js | 84 - .../TextInput/InputAccessoryView.js | 4 +- .../RCTMultilineTextInputNativeComponent.js | 32 - .../RCTSingelineTextInputNativeComponent.js | 43 - .../RCTSinglelineTextInputViewConfig.js | 134 - Libraries/Components/TextInput/TextInput.js | 210 +- .../TextInput/TextInputNativeCommands.js | 31 - .../Components/TextInput/TextInputState.js | 151 +- .../TextInput/__tests__/TextInput-test.js | 26 +- .../__snapshots__/TextInput-test.js.snap | 2 - Libraries/Components/Touchable/TVTouchable.js | 2 +- .../Components/Touchable/TouchableBounce.js | 53 +- .../Touchable/TouchableHighlight.js | 57 +- .../Touchable/TouchableNativeFeedback.js | 105 +- .../Components/Touchable/TouchableOpacity.js | 56 +- .../Touchable/TouchableWithoutFeedback.js | 81 +- .../View/ReactNativeViewViewConfig.js | 9 +- Libraries/Components/View/View.js | 23 +- .../Components/View/ViewNativeComponent.js | 3 +- Libraries/Components/View/ViewPropTypes.js | 61 +- Libraries/Core/ExceptionsManager.js | 87 +- Libraries/Core/InitializeCore.js | 1 - Libraries/Core/ReactFiberErrorDialog.js | 4 + Libraries/Core/ReactNativeVersion.js | 2 +- Libraries/Core/Timers/JSTimers.js | 44 +- .../Core/Timers/__tests__/JSTimers-test.js | 413 - .../Core/__tests__/ExceptionsManager-test.js | 101 +- Libraries/Core/setUpBatchedBridge.js | 77 +- Libraries/Core/setUpDeveloperTools.js | 1 - Libraries/Core/setUpPerformance.js | 26 - Libraries/Core/setUpReactDevTools.js | 2 +- .../DeprecatedTextPropTypes.js | 36 +- .../DeprecatedViewPropTypes.js | 60 +- Libraries/Experimental/Incremental.js | 198 + Libraries/FBLazyVector/BUCK | 4 +- Libraries/FBLazyVector/FBLazyVector.podspec | 4 +- Libraries/FBReactNativeSpec/BUCK | 7 +- .../FBReactNativeSpec.podspec | 6 +- .../FBReactNativeSpec-generated.mm | 297 +- .../FBReactNativeSpec/FBReactNativeSpec.h | 210 +- Libraries/HeapCapture/HeapCapture.js | 6 +- ...JSCHeapCapture.js => NativeHeapCapture.js} | 6 +- Libraries/Image/AssetSourceResolver.js | 7 +- Libraries/Image/Image.android.js | 74 +- Libraries/Image/Image.ios.js | 25 +- Libraries/Image/ImageBackground.js | 2 +- Libraries/Image/ImageProps.js | 44 +- Libraries/Image/ImageViewNativeComponent.js | 16 +- Libraries/Image/ImageViewViewConfig.js | 68 - Libraries/Image/RCTAnimatedImage.m | 2 +- Libraries/Image/RCTDisplayWeakRefreshable.h | 24 - Libraries/Image/RCTDisplayWeakRefreshable.m | 29 - Libraries/Image/RCTImageEditingManager.mm | 8 +- Libraries/Image/RCTImageLoader.h | 5 + Libraries/Image/RCTImageLoader.mm | 221 +- .../RCTImageLoaderWithAttributionProtocol.h | 38 +- Libraries/Image/RCTImageStoreManager.mm | 8 +- .../Image/RCTImageURLLoaderWithAttribution.h | 46 +- .../Image/RCTImageURLLoaderWithAttribution.mm | 30 - Libraries/Image/RCTImageView.mm | 43 +- Libraries/Image/RCTLocalAssetImageLoader.mm | 33 +- Libraries/Image/RCTUIImageViewAnimated.m | 10 +- Libraries/Image/React-RCTImage.podspec | 9 +- .../__tests__/resolveAssetSource-test.js | 46 - Libraries/Image/nativeImageSource.js | 4 +- Libraries/Inspector/Inspector.js | 142 +- Libraries/Inspector/InspectorOverlay.js | 17 +- Libraries/LayoutAnimation/LayoutAnimation.js | 2 +- Libraries/Linking/Linking.js | 16 +- Libraries/LinkingIOS/RCTLinkingManager.mm | 63 +- Libraries/LinkingIOS/React-RCTLinking.podspec | 9 +- Libraries/Lists/FlatList.js | 19 +- Libraries/Lists/SectionList.js | 4 +- Libraries/Lists/ViewabilityHelper.js | 12 +- Libraries/Lists/VirtualizedList.js | 133 +- .../Lists/__flowtests__/FlatList-flowtest.js | 3 +- .../__flowtests__/SectionList-flowtest.js | 8 +- .../Lists/__tests__/VirtualizedList-test.js | 126 +- Libraries/LogBox/Data/LogBoxData.js | 1 - Libraries/LogBox/Data/LogBoxLog.js | 3 - .../Data/__tests__/parseLogBoxLog-test.js | 149 +- Libraries/LogBox/Data/parseLogBoxLog.js | 98 +- Libraries/LogBox/LogBox.js | 91 +- Libraries/LogBox/UI/AnsiHighlight.js | 2 +- Libraries/LogBox/UI/LogBoxInspector.js | 1 - .../LogBox/UI/LogBoxInspectorCodeFrame.js | 22 +- .../UI/LogBoxInspectorSourceMapStatus.js | 3 - Libraries/LogBox/UI/LogBoxNotification.js | 2 - .../LogBoxInspector-test.js.snap | 2 - .../LogBoxInspectorCodeFrame-test.js.snap | 8 +- Libraries/LogBox/__tests__/LogBox-test.js | 43 +- .../LogBoxInspectorContainer-test.js.snap | 4 - .../LogBoxNotificationContainer-test.js.snap | 2 - Libraries/Modal/Modal.js | 40 +- .../Modal/RCTModalHostViewNativeComponent.js | 18 +- .../RCTNativeAnimatedModule.mm | 11 - .../React-RCTAnimation.podspec | 7 +- .../NativeModules/specs/NativeDevSettings.js | 4 - Libraries/Network/RCTNetworking.mm | 8 +- Libraries/Network/React-RCTNetwork.podspec | 7 +- Libraries/Network/XMLHttpRequest.js | 59 +- .../NewAppScreen/components/LearnMoreLinks.js | 14 +- .../Performance/QuickPerformanceLogger.js | 9 - Libraries/Performance/Systrace.js | 20 +- .../PermissionsAndroid/PermissionsAndroid.js | 8 +- Libraries/Pressability/Pressability.js | 247 +- Libraries/Pressability/PressabilityDebug.js | 16 +- .../__tests__/Pressability-test.js | 211 +- Libraries/Pressability/usePressability.js | 43 - .../PushNotificationIOS.js | 50 +- .../RCTPushNotificationManager.mm | 136 +- .../React-RCTPushNotification.podspec | 9 +- Libraries/RCTRequired/BUCK | 4 +- Libraries/RCTRequired/RCTRequired.podspec | 4 +- Libraries/ReactNative/AppContainer.js | 23 +- Libraries/ReactNative/AppRegistry.js | 16 +- Libraries/ReactNative/DummyUIManager.js | 5 +- Libraries/ReactNative/FabricUIManager.js | 1 + Libraries/ReactNative/ReactFabricInternals.js | 8 + .../ReactNativePrivateInterface.js | 4 +- Libraries/Renderer/REVISION | 2 +- .../implementations/ReactFabric-dev.fb.js | 19341 +++++++++------- .../implementations/ReactFabric-dev.js | 19187 +++++++++------ .../implementations/ReactFabric-prod.fb.js | 4835 ++-- .../implementations/ReactFabric-prod.js | 4821 ++-- .../ReactFabric-profiling.fb.js | 4488 ++-- .../implementations/ReactFabric-profiling.js | 4474 ++-- .../ReactNativeRenderer-dev.fb.js | 13527 +++++++---- .../ReactNativeRenderer-dev.js | 13415 +++++++---- .../ReactNativeRenderer-prod.fb.js | 5015 ++-- .../ReactNativeRenderer-prod.js | 5002 ++-- .../ReactNativeRenderer-profiling.fb.js | 4695 ++-- .../ReactNativeRenderer-profiling.js | 4680 ++-- .../Renderer/shims/NativeMethodsMixin.js | 21 + Libraries/Renderer/shims/ReactFabric.js | 6 +- Libraries/Renderer/shims/ReactFeatureFlags.js | 1 + Libraries/Renderer/shims/ReactNativeTypes.js | 127 +- .../shims/ReactNativeViewConfigRegistry.js | 2 +- Libraries/Renderer/shims/ReactTypes.js | 190 + Libraries/Settings/RCTSettingsManager.mm | 9 +- Libraries/Settings/React-RCTSettings.podspec | 9 +- Libraries/Share/Share.js | 7 +- Libraries/Storage/AsyncStorage.js | 24 +- Libraries/StyleSheet/EdgeInsetsPropType.js | 9 +- .../NativeOrDynamicColorType.js} | 18 +- .../PlatformColorValueTypes.android.js | 41 - .../StyleSheet/PlatformColorValueTypes.ios.js | 77 - .../PlatformColorValueTypes.macos.js | 78 - .../PlatformColorValueTypesAndroid.android.js | 18 - .../PlatformColorValueTypesAndroid.js | 17 - .../PlatformColorValueTypesIOS.ios.js | 23 - .../StyleSheet/PlatformColorValueTypesIOS.js | 22 - .../PlatformColorValueTypesIOS.macos.js | 24 - Libraries/StyleSheet/Rect.js | 28 - Libraries/StyleSheet/StyleSheet.js | 2 +- Libraries/StyleSheet/StyleSheetTypes.js | 7 +- Libraries/StyleSheet/StyleSheetValidation.js | 6 +- .../__flowtests__/StyleSheet-flowtest.js | 1 - .../__tests__/normalizeColor-test.js | 53 - .../StyleSheet/__tests__/processColor-test.js | 36 - .../__tests__/processColorArray-test.js | 51 - Libraries/StyleSheet/normalizeColor.js | 21 +- .../normalizeColorObject.android.js | 22 + .../StyleSheet/normalizeColorObject.ios.js | 39 + .../StyleSheet/normalizeColorObject.macos.js | 39 + Libraries/StyleSheet/processColor.js | 33 +- Libraries/StyleSheet/processColorArray.js | 8 +- .../StyleSheet/processColorObject.android.js | 22 + .../StyleSheet/processColorObject.ios.js | 33 + .../StyleSheet/processColorObject.macos.js | 33 + Libraries/StyleSheet/processTransform.js | 8 +- Libraries/Text/React-RCTText.podspec | 6 +- Libraries/Text/Text.js | 16 +- Libraries/Text/Text/RCTTextShadowView.m | 1 - Libraries/Text/Text/RCTTextView.m | 1 - .../RCTMultilineTextInputViewManager.m | 1 + .../Text/TextInput/Multiline/RCTUITextView.h | 5 +- .../Text/TextInput/Multiline/RCTUITextView.m | 17 - .../RCTBackedTextInputViewProtocol.h | 11 +- .../Text/TextInput/RCTBaseTextInputView.h | 7 - .../Text/TextInput/RCTBaseTextInputView.m | 147 +- .../TextInput/RCTBaseTextInputViewManager.m | 47 +- .../TextInput/Singleline/RCTUITextField.h | 9 +- .../TextInput/Singleline/RCTUITextField.m | 16 +- Libraries/Text/TextProps.js | 36 +- Libraries/TurboModule/RCTExport.js | 3 +- Libraries/TypeSafety/RCTConvertHelpers.mm | 2 +- Libraries/TypeSafety/RCTTypeSafety.podspec | 6 +- Libraries/Utilities/Dimensions.js | 2 + Libraries/Utilities/HMRClient.js | 40 +- Libraries/Utilities/LoadingView.ios.js | 14 +- Libraries/Utilities/MatrixMath.js | 2 + Libraries/Utilities/NativeDevLoadingView.js | 4 +- Libraries/Utilities/NativeJSDevSupport.js | 2 +- .../NativePlatformConstantsAndroid.js | 2 +- Libraries/Utilities/PixelRatio.js | 6 +- Libraries/Utilities/Platform.android.js | 2 +- Libraries/Utilities/RCTLog.js | 2 +- Libraries/Utilities/ReactNativeTestTools.js | 54 +- Libraries/Utilities/SceneTracker.js | 2 +- .../Utilities/__tests__/stringifySafe-test.js | 44 +- .../Utilities/createPerformanceLogger.js | 12 +- Libraries/Utilities/deprecatedPropType.js | 1 - .../differ/__tests__/matricesDiffer-test.js | 45 - Libraries/Utilities/differ/matricesDiffer.js | 1 - Libraries/Utilities/dismissKeyboard.js | 2 +- Libraries/Utilities/infoLog.js | 3 +- .../Utilities/registerGeneratedViewConfig.js | 18 +- Libraries/Utilities/stringifySafe.js | 129 +- Libraries/Utilities/useWindowDimensions.js | 17 +- Libraries/Vibration/RCTVibration.mm | 8 +- .../Vibration/React-RCTVibration.podspec | 9 +- Libraries/Vibration/Vibration.js | 6 +- .../WebSocket/RCTReconnectingWebSocket.m | 13 +- Libraries/WebSocket/WebSocket.js | 1 + Libraries/YellowBox/Data/YellowBoxCategory.js | 155 + Libraries/YellowBox/Data/YellowBoxRegistry.js | 154 + .../YellowBox/Data/YellowBoxSymbolication.js | 89 + Libraries/YellowBox/Data/YellowBoxWarning.js | 126 + .../Data/__tests__/YellowBoxCategory-test.js | 185 + .../Data/__tests__/YellowBoxRegistry-test.js | 281 + .../__tests__/YellowBoxSymbolication-test.js | 52 + .../Data/__tests__/YellowBoxWarning-test.js | 126 + .../YellowBoxCategory-test.js.snap | 95 + Libraries/YellowBox/UI/YellowBoxButton.js | 53 + Libraries/YellowBox/UI/YellowBoxInspector.js | 213 + .../YellowBox/UI/YellowBoxInspectorFooter.js | 76 + .../YellowBox/UI/YellowBoxInspectorHeader.js | 116 + .../UI/YellowBoxInspectorSourceMapStatus.js | 155 + .../UI/YellowBoxInspectorStackFrame.js | 93 + Libraries/YellowBox/UI/YellowBoxList.js | 142 + Libraries/YellowBox/UI/YellowBoxListRow.js | 100 + Libraries/YellowBox/UI/YellowBoxPressable.js | 88 + Libraries/YellowBox/UI/YellowBoxStyle.js | 31 + Libraries/YellowBox/YellowBox.js | 234 + Libraries/YellowBox/YellowBoxContainer.js | 65 + Libraries/YellowBox/YellowBoxDeprecated.js | 75 - .../YellowBox/__tests__/YellowBox-test.js | 270 + .../__tests__/YellowBoxDeprecated-test.js | 53 - .../__snapshots__/YellowBox-test.js.snap | 5 + .../ReactNativeTypes-flowtest.js | 24 +- Libraries/vendor/core/ErrorUtils.js | 2 +- RNTester/Podfile | 39 +- RNTester/Podfile.lock | 175 +- RNTester/RCTTest/RCTTestModule.m | 89 + RNTester/RCTTest/RCTTestModule.mm | 161 - RNTester/RCTTest/RCTTestPlugins.h | 40 - RNTester/RCTTest/RCTTestPlugins.mm | 32 - RNTester/RCTTest/React-RCTTest.podspec | 18 +- RNTester/README.md | 4 +- RNTester/RNTester-macOS/AppDelegate.mm | 5 +- RNTester/RNTester/AppDelegate.mm | 29 +- RNTester/RNTester/Base.lproj/LaunchScreen.xib | 46 + RNTester/RNTester/LaunchScreen.storyboard | 58 - .../RNTester/RNTesterTurboModuleProvider.h | 4 +- .../RNTester/RNTesterTurboModuleProvider.mm | 6 +- .../testLayoutExample_1-iOS13@2x.png | Bin 169616 -> 170852 bytes .../RNTesterPods.xcodeproj/project.pbxproj | 327 +- .../xcshareddata/xcschemes/RNTester.xcscheme | 38 +- .../RNTesterIntegrationTests.xcscheme | 40 +- .../xcschemes/RNTesterUnitTests.xcscheme | 31 +- .../RNTesterUnitTests/RCTAllocationTests.m | 1 + .../RCTConvert_UIColorTests.m | 52 +- .../RNTesterUnitTests/RCTImageLoaderTests.m | 4 +- RNTester/android/app/build.gradle | 33 +- RNTester/android/app/gradle.properties | 2 +- .../com/facebook/react/uiapp/DetoxTest.java | 33 - RNTester/e2e/__tests__/DatePickerIOS-test.js | 2 +- RNTester/e2e/__tests__/TextInput-test.js | 62 - RNTester/e2e/test-init.js | 23 +- RNTester/js/RNTesterApp.android.js | 2 - RNTester/js/RNTesterApp.ios.js | 16 +- RNTester/js/components/RNTesterBlock.js | 26 +- RNTester/js/components/RNTesterExampleList.js | 25 +- RNTester/js/components/RNTesterTheme.js | 41 +- .../js/examples/Alert/AlertMacOSExample.js | 8 +- .../examples/Appearance/AppearanceExample.js | 4 +- .../DarkModeExample/DarkModeExample.js | 10 +- .../DatePicker/DatePickerMacOSExample.js | 6 +- .../FocusEventsExample/FocusEventsExample.js | 18 +- RNTester/js/examples/Image/ImageExample.js | 12 - .../js/examples/Layout/LayoutEventsExample.js | 3 +- .../examples/MaskedView/MaskedViewExample.js | 9 +- .../NativeAnimationsExample.js | 6 - RNTester/js/examples/Picker/PickerExample.js | 31 - .../PlatformColor/PlatformColorExample.js | 358 - .../js/examples/Pressable/PressableExample.js | 469 - .../PushNotificationIOSExample.js | 67 +- .../RefreshControl/RefreshControlExample.js | 1 - .../ScrollView/ScrollViewAnimatedExample.js | 4 - .../ScrollView/ScrollViewSimpleExample.js | 2 +- RNTester/js/examples/Share/ShareExample.js | 2 +- RNTester/js/examples/Text/TextExample.ios.js | 17 - .../TextInput/TextInputExample.android.js | 3 - .../TextInput/TextInputSharedExamples.js | 13 +- .../js/examples/Touchable/TouchableExample.js | 104 +- .../js/examples/Transform/TransformExample.js | 57 - .../TurboModule/SampleTurboModuleExample.js | 6 +- RNTester/js/examples/View/ViewExample.js | 49 +- .../examples/XHR/XHRExampleAbortController.js | 2 +- RNTester/js/utils/RNTesterActions.js | 2 + RNTester/js/utils/RNTesterList.android.js | 8 - RNTester/js/utils/RNTesterList.ios.js | 10 - RNTester/js/utils/RNTesterStatePersister.js | 8 +- React-Core.podspec | 9 +- React.podspec | 4 +- .../en.lproj/Localizable.strings | 26 - React/Base/RCTAssert.h | 73 +- React/Base/RCTAssert.m | 65 +- React/Base/RCTBridge+Private.h | 12 +- React/Base/RCTBridge.h | 11 +- React/Base/RCTBridge.m | 98 +- React/Base/RCTBridgeDelegate.h | 15 +- React/Base/RCTBridgeMethod.h | 7 +- React/Base/RCTBridgeModule.h | 107 +- React/Base/RCTBundleURLProvider.h | 19 +- React/Base/RCTBundleURLProvider.m | 63 +- React/Base/RCTComponentEvent.h | 2 +- React/Base/RCTComponentEvent.m | 7 +- React/Base/RCTConvert.h | 83 +- React/Base/RCTConvert.m | 963 +- React/Base/RCTDefines.h | 28 +- React/Base/RCTDisplayLink.h | 3 +- React/Base/RCTDisplayLink.m | 23 +- React/Base/RCTErrorInfo.h | 4 +- React/Base/RCTErrorInfo.m | 4 +- React/Base/RCTEventDispatcher.h | 10 +- React/Base/RCTEventDispatcher.m | 50 +- React/Base/RCTFrameUpdate.m | 2 +- React/Base/RCTImageSource.h | 4 +- React/Base/RCTImageSource.m | 15 +- React/Base/RCTJSInvokerModule.h | 16 - React/Base/RCTJSStackFrame.h | 6 +- React/Base/RCTJSStackFrame.m | 85 +- React/Base/RCTJavaScriptExecutor.h | 8 +- React/Base/RCTJavaScriptLoader.h | 26 +- React/Base/RCTJavaScriptLoader.mm | 308 +- React/Base/RCTKeyCommands.h | 16 +- React/Base/RCTKeyCommands.m | 80 +- React/Base/RCTLog.h | 31 +- React/Base/RCTLog.mm | 138 +- React/Base/RCTManagedPointer.h | 5 +- React/Base/RCTManagedPointer.mm | 6 +- React/Base/RCTModuleData.h | 5 +- React/Base/RCTModuleData.mm | 156 +- React/Base/RCTModuleMethod.mm | 307 +- React/Base/RCTMultipartDataTask.h | 7 +- React/Base/RCTMultipartDataTask.m | 51 +- React/Base/RCTMultipartStreamReader.h | 1 + React/Base/RCTMultipartStreamReader.m | 9 +- React/Base/RCTParserUtils.m | 16 +- React/Base/RCTPerformanceLogger.m | 10 +- React/Base/RCTRedBoxSetEnabled.h | 5 +- React/Base/RCTRedBoxSetEnabled.m | 6 +- React/Base/RCTReloadCommand.m | 12 +- React/Base/RCTRootContentView.m | 12 +- React/Base/RCTRootView.h | 19 +- React/Base/RCTRootView.m | 92 +- React/Base/RCTTVRemoteHandler.h | 1 + React/Base/RCTTVRemoteHandler.m | 17 +- React/Base/RCTTouchEvent.m | 38 +- React/Base/RCTTouchHandler.m | 33 +- React/Base/RCTURLRequestHandler.h | 3 +- React/Base/RCTUtils.h | 29 +- React/Base/RCTUtils.m | 230 +- React/Base/RCTVersion.h | 11 +- React/Base/RCTVersion.m | 2 +- React/Base/Surface/RCTSurface.h | 10 +- React/Base/Surface/RCTSurface.mm | 74 +- React/Base/Surface/RCTSurfaceRootShadowView.m | 3 +- React/Base/Surface/RCTSurfaceRootView.mm | 2 +- React/Base/Surface/RCTSurfaceStage.h | 19 +- React/Base/Surface/RCTSurfaceStage.m | 14 +- React/Base/Surface/RCTSurfaceView.mm | 9 +- .../RCTSurfaceHostingProxyRootView.h | 4 +- .../RCTSurfaceHostingProxyRootView.mm | 27 +- .../RCTSurfaceHostingView.h | 2 +- .../RCTSurfaceHostingView.mm | 49 +- .../RCTSurfaceSizeMeasureMode.h | 21 +- .../RCTSurfaceSizeMeasureMode.mm | 16 +- React/CoreModules/BUCK | 18 +- React/CoreModules/CoreModulesPlugins.h | 1 - React/CoreModules/CoreModulesPlugins.mm | 1 - React/CoreModules/RCTAccessibilityManager.mm | 140 +- React/CoreModules/RCTActionSheetManager.mm | 121 +- React/CoreModules/RCTAlertManager.h | 1 + React/CoreModules/RCTAlertManager.mm | 117 +- React/CoreModules/RCTAppState.h | 2 +- React/CoreModules/RCTAppState.mm | 56 +- React/CoreModules/RCTAppearance.h | 1 - React/CoreModules/RCTAppearance.mm | 38 +- React/CoreModules/RCTAsyncLocalStorage.h | 6 +- React/CoreModules/RCTAsyncLocalStorage.mm | 87 +- React/CoreModules/RCTClipboard.mm | 17 +- React/CoreModules/RCTDevLoadingView.h | 14 - React/CoreModules/RCTDevMenu.h | 12 +- React/CoreModules/RCTDevMenu.mm | 49 +- React/CoreModules/RCTDevSettings.h | 15 +- React/CoreModules/RCTDevSettings.mm | 93 +- React/CoreModules/RCTDeviceInfo.mm | 68 +- React/CoreModules/RCTExceptionsManager.h | 20 +- React/CoreModules/RCTExceptionsManager.mm | 110 +- React/CoreModules/RCTFPSGraph.h | 3 +- React/CoreModules/RCTFPSGraph.m | 9 +- React/CoreModules/RCTI18nManager.mm | 19 +- React/CoreModules/RCTKeyboardObserver.mm | 68 +- React/CoreModules/RCTLogBox.mm | 56 +- React/CoreModules/RCTPerfMonitor.mm | 198 +- React/CoreModules/RCTPlatform.mm | 35 +- React/CoreModules/RCTRedBox.h | 8 +- React/CoreModules/RCTRedBox.mm | 804 +- React/CoreModules/RCTSourceCode.mm | 9 +- React/CoreModules/RCTStatusBarManager.mm | 20 +- .../RCTTVNavigationEventEmitter.mm | 16 +- React/CoreModules/RCTTiming.h | 3 +- React/CoreModules/RCTWebSocketExecutor.mm | 112 +- React/CoreModules/RCTWebSocketModule.mm | 72 +- React/CoreModules/React-CoreModules.podspec | 7 +- React/CxxBridge/JSCExecutorFactory.h | 7 +- React/CxxBridge/JSCExecutorFactory.mm | 10 +- React/CxxBridge/NSDataBigString.h | 16 +- React/CxxBridge/NSDataBigString.mm | 3 +- React/CxxBridge/RCTCxxBridge.mm | 437 +- .../RCTJSIExecutorRuntimeInstaller.h | 22 - .../RCTJSIExecutorRuntimeInstaller.mm | 36 - React/CxxBridge/RCTMessageThread.h | 10 +- React/CxxBridge/RCTMessageThread.mm | 42 +- React/CxxBridge/RCTObjcExecutor.h | 16 +- React/CxxBridge/RCTObjcExecutor.mm | 117 +- React/CxxModule/DispatchMessageQueueThread.h | 21 +- React/CxxModule/RCTCxxMethod.mm | 42 +- React/CxxModule/RCTCxxModule.mm | 11 +- React/CxxModule/RCTCxxUtils.h | 8 +- React/CxxModule/RCTCxxUtils.mm | 32 +- React/CxxModule/RCTNativeModule.h | 11 +- React/CxxModule/RCTNativeModule.mm | 69 +- React/CxxUtils/RCTFollyConvert.h | 3 +- React/CxxUtils/RCTFollyConvert.mm | 25 +- ...dingViewProtocol.h => RCTDevLoadingView.h} | 6 +- .../RCTDevLoadingView.m} | 117 +- .../DevSupport/RCTDevLoadingViewSetEnabled.h | 11 - .../DevSupport/RCTDevLoadingViewSetEnabled.m | 24 - .../DevSupport/RCTInspectorDevServerHelper.h | 5 +- .../DevSupport/RCTInspectorDevServerHelper.mm | 69 +- React/DevSupport/RCTPackagerClient.m | 16 +- React/DevSupport/RCTPackagerConnection.h | 5 +- React/DevSupport/RCTPackagerConnection.mm | 97 +- .../ART/RCTARTSurfaceViewComponentView.mm | 7 - .../RCTActivityIndicatorViewComponentView.mm | 7 - .../Image/RCTImageComponentView.mm | 57 +- .../Modal/RCTModalHostViewComponentView.mm | 36 +- .../RCTFabricComponentsPlugins.h | 8 - .../RCTFabricComponentsPlugins.mm | 8 - .../RCTSafeAreaViewComponentView.mm | 35 +- .../ScrollView/RCTEnhancedScrollView.mm | 6 + .../RCTPullToRefreshViewComponentView.mm | 11 +- .../ScrollView/RCTScrollViewComponentView.mm | 39 +- .../Slider/RCTSliderComponentView.mm | 57 +- .../Switch/RCTSwitchComponentView.mm | 9 +- .../Text/RCTParagraphComponentView.h | 8 +- .../Text/RCTParagraphComponentView.mm | 55 +- .../TextInput/RCTTextInputComponentView.h | 21 - .../TextInput/RCTTextInputComponentView.mm | 439 - .../TextInput/RCTTextInputNativeCommands.h | 104 - .../TextInput/RCTTextInputUtils.h | 43 - .../TextInput/RCTTextInputUtils.mm | 198 - .../RCTUnimplementedViewComponentView.mm | 7 - .../View/RCTViewComponentView.mm | 42 +- .../Fabric/Mounting/RCTComponentViewFactory.h | 12 + .../Mounting/RCTComponentViewFactory.mm | 104 +- .../Mounting/RCTComponentViewProtocol.h | 11 +- React/Fabric/Mounting/RCTMountingManager.mm | 19 +- ...CTMountingTransactionObserverCoordinator.h | 5 +- .../Mounting/UIView+ComponentViewProtocol.h | 3 + .../Mounting/UIView+ComponentViewProtocol.mm | 13 +- React/Fabric/RCTConversions.h | 162 +- React/Fabric/RCTImageResponseObserverProxy.mm | 7 +- React/Fabric/RCTScheduler.h | 2 - React/Fabric/RCTScheduler.mm | 5 - React/Fabric/RCTSurfacePresenter.h | 7 +- React/Fabric/RCTSurfacePresenter.mm | 207 +- React/Fabric/RCTSurfaceRegistry.mm | 2 +- React/Fabric/RCTSurfaceTouchHandler.mm | 99 +- React/Fabric/Surface/RCTFabricSurface.h | 6 +- React/Fabric/Surface/RCTFabricSurface.mm | 7 +- React/Fabric/Utils/MainRunLoopEventBeat.mm | 25 +- .../Fabric/Utils/RCTGenericDelegateSplitter.h | 1 - .../Utils/RCTGenericDelegateSplitter.mm | 14 +- React/Inspector/RCTInspector.mm | 33 +- .../RCTInspectorPackagerConnection.h | 4 +- .../RCTInspectorPackagerConnection.m | 88 +- React/Modules/RCTEventEmitter.h | 4 +- React/Modules/RCTEventEmitter.m | 51 +- React/Modules/RCTI18nUtil.m | 10 +- React/Modules/RCTLayoutAnimation.h | 8 +- React/Modules/RCTLayoutAnimation.m | 33 +- React/Modules/RCTLayoutAnimationGroup.h | 3 +- React/Modules/RCTLayoutAnimationGroup.m | 25 +- .../RCTRedBoxExtraDataViewController.m | 361 +- React/Modules/RCTSurfacePresenterStub.h | 1 + React/Modules/RCTSurfacePresenterStub.m | 2 +- React/Modules/RCTUIManager.m | 512 +- .../RCTUIManagerObserverCoordinator.mm | 1 + React/Modules/RCTUIManagerUtils.h | 5 +- React/Modules/RCTUIManagerUtils.m | 3 +- React/Profiler/RCTProfile.h | 95 +- React/Profiler/RCTProfile.m | 337 +- React/React-RCTFabric.podspec | 8 +- React/UIUtils/RCTUIUtils.h | 4 +- React/UIUtils/RCTUIUtils.m | 40 +- React/Views/RCTActivityIndicatorView.m | 4 +- React/Views/RCTActivityIndicatorViewManager.m | 15 +- React/Views/RCTBorderDrawing.h | 25 +- React/Views/RCTBorderDrawing.m | 340 +- React/Views/RCTComponentData.h | 6 +- React/Views/RCTComponentData.m | 78 +- React/Views/RCTConvert+CoreLocation.m | 8 +- React/Views/RCTConvert+Transform.m | 3 +- React/Views/RCTDatePicker.m | 5 +- React/Views/RCTDatePickerManager.h | 4 +- React/Views/RCTDatePickerManager.m | 25 +- React/Views/RCTFont.h | 2 +- React/Views/RCTFont.mm | 111 +- React/Views/RCTLayout.h | 9 +- React/Views/RCTLayout.m | 53 +- React/Views/RCTModalHostView.h | 8 +- React/Views/RCTModalHostView.m | 36 +- React/Views/RCTModalHostViewController.m | 25 +- React/Views/RCTModalHostViewManager.h | 8 +- React/Views/RCTModalHostViewManager.m | 32 +- React/Views/RCTPicker.m | 44 +- React/Views/RCTPickerManager.m | 10 +- React/Views/RCTProgressViewManager.m | 12 +- React/Views/RCTRootShadowView.h | 6 - React/Views/RCTRootShadowView.m | 3 +- React/Views/RCTSegmentedControl.m | 34 +- React/Views/RCTSegmentedControlManager.m | 2 - React/Views/RCTShadowView+Internal.m | 3 +- React/Views/RCTShadowView+Layout.m | 30 +- React/Views/RCTShadowView.h | 6 +- React/Views/RCTShadowView.m | 274 +- React/Views/RCTSlider.m | 29 +- React/Views/RCTSliderManager.m | 26 +- React/Views/RCTSwitch.m | 3 +- React/Views/RCTSwitchManager.m | 14 +- React/Views/RCTTVView.m | 196 +- React/Views/RCTView.m | 370 +- React/Views/RCTViewManager.h | 36 +- React/Views/RCTViewManager.m | 161 +- React/Views/RCTWrapperViewController.m | 11 +- .../Views/RefreshControl/RCTRefreshControl.m | 48 +- .../RefreshControl/RCTRefreshControlManager.m | 4 +- .../RefreshControl/RCTRefreshableProtocol.h | 2 +- .../SafeAreaView/RCTSafeAreaShadowView.m | 27 +- React/Views/SafeAreaView/RCTSafeAreaView.m | 33 +- .../ScrollView/RCTScrollContentShadowView.m | 3 +- React/Views/ScrollView/RCTScrollContentView.m | 3 +- React/Views/ScrollView/RCTScrollEvent.m | 49 +- React/Views/ScrollView/RCTScrollView.m | 309 +- React/Views/ScrollView/RCTScrollViewManager.m | 222 +- .../Views/ScrollView/RCTScrollableProtocol.h | 2 +- React/Views/UIView+React.h | 2 +- React/Views/UIView+React.m | 67 +- React/third-party.xcconfig | 2 +- ReactAndroid/DevExperience.md | 2 +- ReactAndroid/README.md | 4 +- ReactAndroid/build.gradle | 3 +- ReactAndroid/gradle.properties | 6 +- ReactAndroid/proguard-rules.pro | 3 - .../facebook/react/bridge/ArgumentsTest.java | 17 +- .../java/com/facebook/react/testing/BUCK | 2 +- .../react/testing/ReactAppTestActivity.java | 7 - .../react/testing/ReactTestHelper.java | 7 +- .../java/com/facebook/react/testing/rule/BUCK | 2 +- .../react/tests/TextInputTestCase.java | 92 - .../java/com/facebook/react/tests/core/BUCK | 2 +- ReactAndroid/src/androidTest/js/TestBundle.js | 4 +- .../src/androidTest/js/TextInputTestModule.js | 2 +- .../main/java/com/facebook/fbreact/specs/BUCK | 43 +- .../fbreact/specs/NativeBlobModuleSpec.java | 7 +- .../specs/NativeDevLoadingViewSpec.java | 3 +- .../fbreact/specs/NativeDevSettingsSpec.java | 6 - .../specs/NativeJSCHeapCaptureSpec.java | 29 - .../fbreact/specs/NativeJSDevSupportSpec.java | 3 +- .../NativePlatformConstantsAndroidSpec.java | 5 +- .../specs/jni/FBReactNativeSpec-generated.cpp | 2492 -- .../fbreact/specs/jni/FBReactNativeSpec.h | 833 - .../main/java/com/facebook/hermes/.clang-tidy | 5 - .../hermes/instrumentation/OnLoad.cpp | 2 +- .../hermes/reactexecutor/HermesExecutor.java | 5 +- .../facebook/hermes/reactexecutor/OnLoad.cpp | 26 +- .../hermes/reactexecutor/RuntimeConfig.java | 4 +- .../src/main/java/com/facebook/react/BUCK | 5 +- .../facebook/react/CoreModulesPackage.java | 7 +- .../com/facebook/react/DebugCorePackage.java | 74 +- .../facebook/react/ReactInstanceManager.java | 93 +- .../react/ReactInstanceManagerBuilder.java | 4 +- .../com/facebook/react/ReactRootView.java | 108 +- .../react/animated/NativeAnimatedModule.java | 148 +- .../com/facebook/react/bridge/Arguments.java | 1 + .../main/java/com/facebook/react/bridge/BUCK | 6 +- .../react/bridge/CatalystInstanceImpl.java | 41 +- .../react/bridge/ColorPropConverter.java | 124 - .../facebook/react/bridge/JavaJSExecutor.java | 2 +- .../bridge/JavaScriptModuleRegistry.java | 25 +- .../facebook/react/bridge/ReactContext.java | 57 +- .../bridge/ReactContextBaseJavaModule.java | 6 +- .../bridge/ReactNoCrashSoftException.java | 12 +- .../RetryableMountingLayerException.java | 26 - .../com/facebook/react/bridge/UIManager.java | 15 +- .../react/config/ReactFeatureFlags.java | 35 +- .../java/com/facebook/react/devsupport/BUCK | 5 +- .../react/devsupport/BundleDownloader.java | 5 +- .../react/devsupport/DevServerHelper.java | 43 + .../devsupport/DevSupportManagerBase.java | 1234 - .../devsupport/DevSupportManagerImpl.java | 1183 +- .../devsupport/DisabledDevSupportManager.java | 10 +- .../react/devsupport/JSCHeapCapture.java | 11 +- .../devsupport/JSDebuggerWebSocketClient.java | 4 +- .../react/devsupport/JSDevSupport.java | 15 +- .../react/devsupport/LogBoxModule.java | 55 +- .../WebsocketJavaScriptExecutor.java | 7 +- .../interfaces/DevSupportManager.java | 11 - .../com/facebook/react/fabric/.clang-tidy | 5 - .../com/facebook/react/fabric/Binding.java | 12 +- .../react/fabric/FabricComponents.java | 1 - .../react/fabric/FabricJSIModuleProvider.java | 4 +- .../react/fabric/FabricUIManager.java | 353 +- .../java/com/facebook/react/fabric/jni/BUCK | 10 +- .../com/facebook/react/fabric/jni/Binding.cpp | 82 +- .../com/facebook/react/fabric/jni/Binding.h | 10 +- .../fabric/mounting/MountingManager.java | 66 +- .../mountitems/DispatchCommandMountItem.java | 36 +- .../DispatchIntCommandMountItem.java | 37 - .../DispatchStringCommandMountItem.java | 2 +- .../java/com/facebook/react/jscexecutor/BUCK | 2 +- .../com/facebook/react/jscexecutor/OnLoad.cpp | 5 - .../processing/ReactModuleSpecProcessor.java | 38 +- .../com/facebook/react/modules/.clang-tidy | 5 - .../AccessibilityInfoModule.java | 16 +- .../modules/appearance/AppearanceModule.java | 35 +- .../modules/appstate/AppStateModule.java | 32 +- .../react/modules/blob/BlobModule.java | 33 +- .../react/modules/blob/FileReaderModule.java | 9 +- .../modules/camera/CameraRollManager.java | 14 +- .../modules/camera/ImageEditingManager.java | 76 +- .../modules/camera/ImageStoreManager.java | 23 +- .../core/DeviceEventManagerModule.java | 7 +- .../modules/core/ExceptionsManagerModule.java | 29 +- .../core/HeadlessJsTaskSupportModule.java | 17 +- .../react/modules/core/JavaTimerManager.java | 37 - .../react/modules/core/TimingModule.java | 28 +- .../datepicker/DatePickerDialogModule.java | 6 +- .../modules/debug/AnimationsDebugModule.java | 9 +- .../modules/debug/DevSettingsModule.java | 36 +- .../react/modules/debug/SourceCodeModule.java | 2 +- .../modules/deviceinfo/DeviceInfoModule.java | 25 +- .../react/modules/dialog/DialogModule.java | 9 +- .../com/facebook/react/modules/fresco/BUCK | 6 +- .../react/modules/fresco/FrescoModule.java | 3 +- .../react/modules/intent/IntentModule.java | 25 +- .../permissions/PermissionsModule.java | 13 +- .../react/modules/share/ShareModule.java | 7 +- .../modules/sound/SoundManagerModule.java | 7 +- .../modules/statusbar/StatusBarModule.java | 19 +- .../modules/storage/AsyncStorageModule.java | 17 +- .../modules/systeminfo/AndroidInfoModule.java | 9 +- .../systeminfo/ReactNativeVersion.java | 2 +- .../timepicker/TimePickerDialogModule.java | 11 +- .../react/modules/toast/ToastModule.java | 36 +- .../modules/vibration/VibrationModule.java | 15 +- .../modules/websocket/WebSocketModule.java | 13 +- .../packagerconnection/JSPackagerClient.java | 2 + .../processing/ReactPropertyProcessor.java | 19 +- .../main/java/com/facebook/react/shell/BUCK | 1 - .../react/shell/MainReactPackage.java | 5 +- .../facebook/react/turbomodule/.clang-tidy | 5 - .../core/CallInvokerHolderImpl.java | 13 +- .../turbomodule/core/TurboModuleManager.java | 302 +- .../core/TurboModuleManagerDelegate.java | 18 +- .../facebook/react/turbomodule/core/jni/BUCK | 2 +- .../jni/ReactCommon/CallInvokerHolder.cpp | 3 +- .../jni/ReactCommon/TurboModuleManager.cpp | 125 +- .../react/uimanager/BaseViewManager.java | 4 +- .../uimanager/BaseViewManagerDelegate.java | 4 +- .../uimanager/NativeViewHierarchyManager.java | 122 +- .../NativeViewHierarchyOptimizer.java | 35 +- .../uimanager/ReactAccessibilityDelegate.java | 1 + .../react/uimanager/ThemedReactContext.java | 15 - .../react/uimanager/UIImplementation.java | 13 +- .../react/uimanager/UIManagerHelper.java | 83 +- .../react/uimanager/UIManagerModule.java | 37 +- .../UIManagerModuleConstantsHelper.java | 5 +- .../react/uimanager/UIViewOperationQueue.java | 153 +- .../facebook/react/uimanager/ViewManager.java | 27 +- .../uimanager/ViewManagersPropertyCache.java | 61 +- .../facebook/react/uimanager/ViewProps.java | 2 - .../uimanager/events/ReactEventEmitter.java | 28 +- .../LayoutAnimationController.java | 3 - .../main/java/com/facebook/react/util/BUCK | 2 - .../java/com/facebook/react/util/RCTLog.java | 26 - .../java/com/facebook/react/util/RNLog.java | 125 - .../ActivityIndicatorViewManagerDelegate.java | 3 +- .../AndroidDialogPickerManagerDelegate.java | 3 - .../AndroidDialogPickerManagerInterface.java | 1 - .../AndroidDrawerLayoutManagerDelegate.java | 5 +- .../AndroidProgressBarManagerDelegate.java | 3 +- ...roidSwipeRefreshLayoutManagerDelegate.java | 3 +- .../AndroidSwitchManagerDelegate.java | 11 +- .../InputAccessoryViewManagerDelegate.java | 3 +- .../ProgressViewManagerDelegate.java | 5 +- .../PullToRefreshViewManagerDelegate.java | 50 + .../PullToRefreshViewManagerInterface.java | 21 + .../SegmentedControlManagerDelegate.java | 9 +- .../SegmentedControlManagerInterface.java | 2 - .../viewmanagers/SliderManagerDelegate.java | 7 +- .../react/views/drawer/ReactDrawerLayout.java | 4 +- .../react/views/image/ImageResizeMode.java | 26 +- .../image/ReactCallerContextFactory.java | 3 +- .../react/views/image/ReactImageManager.java | 11 +- .../react/views/image/ReactImageView.java | 11 +- .../picker/ReactDialogPickerManager.java | 7 - .../react/views/picker/ReactPicker.java | 12 - .../views/picker/ReactPickerAdapter.java | 14 - .../java/com/facebook/react/views/scroll/BUCK | 1 - .../scroll/ReactHorizontalScrollView.java | 68 +- .../ReactHorizontalScrollViewManager.java | 19 +- .../react/views/scroll/ReactScrollView.java | 77 +- .../views/scroll/ReactScrollViewHelper.java | 6 +- .../views/scroll/ReactScrollViewManager.java | 31 +- .../views/slider/ReactSliderManager.java | 3 +- .../SwipeRefreshLayoutManager.java | 19 +- .../views/switchview/ReactSwitchManager.java | 3 +- .../react/views/text/CustomStyleSpan.java | 4 +- .../views/text/ReactBaseTextShadowNode.java | 36 +- .../react/views/text/ReactTextShadowNode.java | 5 - .../react/views/text/ReactTextView.java | 14 +- .../views/text/ReactTextViewManager.java | 53 +- .../text/ReactTextViewManagerCallback.java | 25 - .../react/views/text/TextAttributeProps.java | 130 +- .../react/views/text/TextLayoutManager.java | 137 +- .../react/views/text/frescosupport/BUCK | 1 - ...coBasedReactTextInlineImageShadowNode.java | 10 +- .../FrescoBasedReactTextInlineImageSpan.java | 13 +- .../com/facebook/react/views/textinput/BUCK | 10 +- .../react/views/textinput/ReactEditText.java | 95 +- .../textinput/ReactTextInputManager.java | 215 +- .../textinput/ReactTextInputShadowNode.java | 9 +- .../react/views/view/ReactDrawableHelper.java | 101 +- .../view/ReactViewBackgroundDrawable.java | 37 +- .../react/views/view/ReactViewGroup.java | 2 +- .../java/com/facebook/yoga/YogaNative.java | 1 - .../main/java/com/facebook/yoga/YogaNode.java | 2 - .../com/facebook/yoga/YogaNodeJNIBase.java | 87 +- .../src/main/jni/first-party/.clang-tidy | 5 - .../src/main/jni/first-party/fb/assert.cpp | 30 +- .../main/jni/first-party/fb/include/fb/ALog.h | 61 +- .../jni/first-party/fb/include/fb/Build.h | 12 +- .../jni/first-party/fb/include/fb/Countable.h | 16 +- .../first-party/fb/include/fb/Environment.h | 71 +- .../fb/include/fb/ProgramLocation.h | 50 +- .../jni/first-party/fb/include/fb/RefPtr.h | 116 +- .../fb/include/fb/StaticInitialized.h | 19 +- .../first-party/fb/include/fb/ThreadLocal.h | 46 +- .../jni/first-party/fb/include/fb/assert.h | 21 +- .../main/jni/first-party/fb/include/fb/log.h | 12 +- .../first-party/fb/include/fb/noncopyable.h | 9 +- .../first-party/fb/include/fb/nonmovable.h | 9 +- .../src/main/jni/first-party/fb/log.cpp | 46 +- .../jni/first-party/fbgloginit/fb/glog_init.h | 8 +- .../jni/first-party/fbgloginit/glog_init.cpp | 66 +- .../main/jni/first-party/jni-hack/real/jni.h | 2194 +- .../main/jni/first-party/yogajni/.clang-tidy | 5 - .../first-party/yogajni/jni/ScopedGlobalRef.h | 8 +- .../first-party/yogajni/jni/ScopedLocalRef.h | 8 +- .../first-party/yogajni/jni/YGJNIVanilla.cpp | 11 - .../jni/first-party/yogajni/jni/common.cpp | 7 +- .../main/jni/first-party/yogajni/jni/common.h | 7 +- .../src/main/jni/react/jni/.clang-tidy | 5 - ReactAndroid/src/main/jni/react/jni/BUCK | 9 +- .../jni/react/jni/CatalystInstanceImpl.cpp | 33 +- .../main/jni/react/jni/CatalystInstanceImpl.h | 1 + .../main/jni/react/jni/CxxModuleWrapper.cpp | 39 +- .../src/main/jni/react/jni/CxxModuleWrapper.h | 24 +- .../jni/react/jni/CxxSharedModuleWrapper.h | 13 +- .../src/main/jni/react/jni/JInspector.cpp | 45 +- .../src/main/jni/react/jni/JNativeRunnable.h | 13 +- .../src/main/jni/react/jni/JReactMarker.cpp | 5 - .../src/main/jni/react/jni/JSLogging.cpp | 4 +- .../src/main/jni/react/jni/JSLogging.h | 6 +- .../jni/react/jni/JniJSModulesUnbundle.cpp | 44 +- .../main/jni/react/jni/JniJSModulesUnbundle.h | 25 +- .../jni/react/jni/ModuleRegistryBuilder.cpp | 34 +- .../src/main/jni/react/jni/NativeCommon.cpp | 7 +- .../src/main/jni/react/jni/NativeMap.cpp | 6 +- .../src/main/jni/react/jni/NativeTime.cpp | 26 - .../src/main/jni/react/jni/NativeTime.h | 16 - .../src/main/jni/react/jni/ProxyExecutor.cpp | 15 +- .../src/main/jni/react/jni/ProxyExecutor.h | 3 +- .../main/jni/react/jni/ReadableNativeArray.h | 14 +- .../jni/react/jni/WritableNativeArray.cpp | 7 +- .../main/jni/react/jni/WritableNativeMap.cpp | 20 +- .../src/main/jni/react/perftests/BUCK | 2 +- .../src/main/jni/third-party/folly/Android.mk | 21 +- .../soloader/java/com/facebook/soloader/BUCK | 10 +- .../src/main/res/devsupport/values/styles.xml | 1 - .../test/java/com/facebook/react/bridge/BUCK | 3 +- .../bridge/JavaScriptModuleRegistryTest.java | 35 - .../JSDebuggerWebSocketClientTest.java | 4 +- .../test/java/com/facebook/react/modules/BUCK | 1 - .../modules/timing/TimingModuleTest.java | 14 - .../ReactPropForShadowNodeSetterTest.java | 1 - .../react/views/text/ReactTextTest.java | 2 - ReactCommon/React-Fabric.podspec | 7 +- ReactCommon/ReactCommon.podspec | 17 +- ReactCommon/better/.clang-tidy | 5 - ReactCommon/better/BUCK | 16 +- ReactCommon/better/mutex.h | 2 +- ReactCommon/callinvoker/.clang-tidy | 5 - ReactCommon/callinvoker/Android.mk | 2 + ReactCommon/callinvoker/BUCK | 7 +- .../callinvoker/React-callinvoker.podspec | 34 - .../ReactCommon/BridgeJSCallInvoker.cpp | 26 + .../ReactCommon/BridgeJSCallInvoker.h | 42 + .../callinvoker/ReactCommon/CallInvoker.h | 2 +- .../MessageQueueThreadCallInvoker.cpp | 22 + .../MessageQueueThreadCallInvoker.h | 35 + ReactCommon/config/.clang-tidy | 5 - ReactCommon/config/BUCK | 16 +- ReactCommon/config/ReactNativeConfig.h | 4 +- ReactCommon/cxxreact/.clang-tidy | 5 - ReactCommon/cxxreact/Android.mk | 3 +- ReactCommon/cxxreact/BUCK | 37 +- ReactCommon/cxxreact/CxxModule.h | 204 +- ReactCommon/cxxreact/CxxNativeModule.cpp | 125 +- ReactCommon/cxxreact/CxxNativeModule.h | 35 +- ReactCommon/cxxreact/Instance.cpp | 100 +- ReactCommon/cxxreact/Instance.h | 133 +- ReactCommon/cxxreact/JSBundleType.cpp | 22 +- ReactCommon/cxxreact/JSBundleType.h | 10 +- ReactCommon/cxxreact/JSDeltaBundleClient.h | 14 +- ReactCommon/cxxreact/JSExecutor.cpp | 6 +- ReactCommon/cxxreact/JSExecutor.h | 68 +- ReactCommon/cxxreact/JSIndexedRAMBundle.h | 29 +- ReactCommon/cxxreact/JSModulesUnbundle.h | 19 +- ReactCommon/cxxreact/JsArgumentHelpers-inl.h | 82 +- ReactCommon/cxxreact/JsArgumentHelpers.h | 44 +- ReactCommon/cxxreact/MessageQueueThread.h | 7 +- ReactCommon/cxxreact/MethodCall.cpp | 52 +- ReactCommon/cxxreact/MethodCall.h | 15 +- ReactCommon/cxxreact/ModuleRegistry.cpp | 56 +- ReactCommon/cxxreact/ModuleRegistry.h | 47 +- ReactCommon/cxxreact/NativeModule.h | 16 +- ReactCommon/cxxreact/NativeToJsBridge.cpp | 58 +- ReactCommon/cxxreact/NativeToJsBridge.h | 63 +- ReactCommon/cxxreact/RAMBundleRegistry.h | 21 +- ReactCommon/cxxreact/React-cxxreact.podspec | 7 +- ReactCommon/cxxreact/ReactMarker.cpp | 6 +- ReactCommon/cxxreact/ReactMarker.h | 11 +- ReactCommon/cxxreact/ReactNativeVersion.h | 24 - ReactCommon/cxxreact/RecoverableError.h | 12 +- ReactCommon/cxxreact/SampleCxxModule.h | 20 +- ReactCommon/cxxreact/SharedProxyCxxModule.h | 20 +- ReactCommon/cxxreact/tests/BUCK | 16 +- .../cxxreact/tests/RecoverableErrorTest.cpp | 10 +- ReactCommon/cxxreact/tests/jsarg_helpers.cpp | 57 +- ReactCommon/cxxreact/tests/jsbigstring.cpp | 50 +- ReactCommon/cxxreact/tests/methodcall.cpp | 97 +- ReactCommon/fabric/.clang-tidy | 5 - .../attributedstring/AttributedString.cpp | 34 +- .../attributedstring/AttributedString.h | 19 +- .../attributedstring/AttributedStringBox.cpp | 21 - .../attributedstring/AttributedStringBox.h | 18 - ReactCommon/fabric/attributedstring/BUCK | 20 +- .../fabric/attributedstring/TextAttributes.h | 5 - .../fabric/attributedstring/conversions.h | 49 +- .../fabric/components/activityindicator/BUCK | 20 +- ReactCommon/fabric/components/image/BUCK | 20 +- .../image/ImageComponentDescriptor.h | 9 +- .../components/image/ImageLocalData.cpp | 37 + .../fabric/components/image/ImageLocalData.h | 54 + .../fabric/components/image/ImageProps.cpp | 13 +- .../components/image/ImageShadowNode.cpp | 36 +- .../fabric/components/image/ImageShadowNode.h | 19 +- .../fabric/components/image/ImageState.cpp | 22 - .../fabric/components/image/ImageState.h | 55 - .../fabric/components/image/conversions.h | 20 +- .../components/legacyviewmanagerinterop/BUCK | 12 +- ...acyViewManagerInteropComponentDescriptor.h | 4 +- ...cyViewManagerInteropComponentDescriptor.mm | 27 +- .../LegacyViewManagerInteropState.mm | 3 +- .../RCTLegacyViewManagerInteropCoordinator.mm | 2 +- ReactCommon/fabric/components/modal/BUCK | 22 +- .../modal/ModalHostViewComponentDescriptor.h | 9 + .../modal/ModalHostViewShadowNode.h | 6 - ReactCommon/fabric/components/picker/BUCK | 20 +- ReactCommon/fabric/components/root/BUCK | 23 +- .../fabric/components/root/RootProps.cpp | 21 +- .../fabric/components/root/RootShadowNode.cpp | 61 +- .../fabric/components/root/RootShadowNode.h | 22 +- .../fabric/components/safeareaview/BUCK | 8 +- .../SafeAreaViewComponentDescriptor.h | 5 +- .../safeareaview/SafeAreaViewShadowNode.h | 3 - .../safeareaview/SafeAreaViewState.h | 9 +- ReactCommon/fabric/components/scrollview/BUCK | 20 +- .../components/scrollview/ScrollViewProps.cpp | 54 +- .../components/scrollview/ScrollViewProps.h | 2 +- .../components/scrollview/ScrollViewState.h | 9 +- ReactCommon/fabric/components/slider/BUCK | 22 +- .../slider/SliderComponentDescriptor.h | 11 +- .../components/slider/SliderLocalData.cpp | 68 + .../components/slider/SliderLocalData.h | 108 + .../components/slider/SliderShadowNode.cpp | 54 +- .../components/slider/SliderShadowNode.h | 22 +- .../fabric/components/slider/SliderState.cpp | 46 - .../fabric/components/slider/SliderState.h | 81 - ReactCommon/fabric/components/switch/BUCK | 22 +- .../AndroidSwitchComponentDescriptor.h | 8 +- ReactCommon/fabric/components/text/BUCK | 22 +- .../text/basetext/BaseTextProps.cpp | 112 +- .../text/basetext/BaseTextShadowNode.cpp | 55 +- .../text/basetext/BaseTextShadowNode.h | 34 +- .../paragraph/ParagraphComponentDescriptor.h | 12 +- .../text/paragraph/ParagraphProps.cpp | 13 +- .../text/paragraph/ParagraphShadowNode.cpp | 186 +- .../text/paragraph/ParagraphShadowNode.h | 43 +- .../components/text/rawtext/RawTextProps.cpp | 2 +- .../text/rawtext/RawTextShadowNode.h | 2 +- .../components/text/text/TextShadowNode.h | 37 +- ReactCommon/fabric/components/textinput/BUCK | 26 +- .../AndroidTextInputComponentDescriptor.h | 142 +- .../AndroidTextInputProps.cpp | 82 +- .../androidtextinput/AndroidTextInputProps.h | 19 - .../AndroidTextInputShadowNode.cpp | 88 +- .../AndroidTextInputShadowNode.h | 5 - .../AndroidTextInputState.cpp | 1 - .../androidtextinput/AndroidTextInputState.h | 45 +- .../components/textinput/iostextinput/BUCK | 99 - .../TextInputComponentDescriptor.h | 46 - .../iostextinput/TextInputEventEmitter.cpp | 126 - .../iostextinput/TextInputEventEmitter.h | 56 - .../textinput/iostextinput/TextInputProps.cpp | 92 - .../textinput/iostextinput/TextInputProps.h | 68 - .../iostextinput/TextInputShadowNode.cpp | 111 - .../iostextinput/TextInputShadowNode.h | 76 - .../textinput/iostextinput/TextInputState.cpp | 12 - .../textinput/iostextinput/TextInputState.h | 57 - .../textinput/iostextinput/conversions.h | 210 - .../textinput/iostextinput/primitives.h | 209 - .../textinput/iostextinput/propsConversions.h | 116 - .../fabric/components/unimplementedview/BUCK | 23 +- ReactCommon/fabric/components/view/BUCK | 26 +- .../components/view/ConcreteViewShadowNode.h | 75 +- ReactCommon/fabric/components/view/Touch.h | 2 +- .../fabric/components/view/TouchEvent.cpp | 4 +- .../components/view/TouchEventEmitter.cpp | 8 +- .../components/view/TouchEventEmitter.h | 2 +- .../components/view/ViewEventEmitter.cpp | 11 - .../fabric/components/view/ViewEventEmitter.h | 5 - .../fabric/components/view/ViewProps.cpp | 65 +- .../fabric/components/view/ViewProps.h | 39 +- .../fabric/components/view/ViewShadowNode.cpp | 78 +- .../fabric/components/view/ViewShadowNode.h | 12 +- .../view/accessibility/AccessibilityProps.cpp | 42 +- .../view/accessibility/AccessibilityProps.h | 27 +- .../fabric/components/view/conversions.h | 6 +- .../fabric/components/view/primitives.h | 4 +- .../fabric/components/view/propsConversions.h | 111 +- .../fabric/components/view/tests/ViewTest.cpp | 210 +- .../view/yoga/YogaLayoutableShadowNode.cpp | 323 +- .../view/yoga/YogaLayoutableShadowNode.h | 121 +- .../view/yoga/YogaStylableProps.cpp | 6 +- .../components/view/yoga/YogaStylableProps.h | 8 +- ReactCommon/fabric/core/BUCK | 33 +- .../ComponentDescriptor.cpp | 10 +- .../componentdescriptor/ComponentDescriptor.h | 46 +- .../ConcreteComponentDescriptor.h | 64 +- .../fabric/core/events/EventDispatcher.cpp | 6 + .../fabric/core/events/EventDispatcher.h | 2 +- ReactCommon/fabric/core/events/EventEmitter.h | 3 - ReactCommon/fabric/core/events/EventQueue.cpp | 3 +- .../fabric/core/layout/LayoutContext.h | 14 - .../fabric/core/layout/LayoutMetrics.h | 24 +- .../core/layout/LayoutableShadowNode.cpp | 177 +- .../fabric/core/layout/LayoutableShadowNode.h | 112 +- ReactCommon/fabric/core/propsConversions.h | 4 +- .../core/shadownode/ConcreteShadowNode.h | 68 +- .../fabric/core/shadownode/LocalData.h | 41 + ReactCommon/fabric/core/shadownode/Props.cpp | 2 +- ReactCommon/fabric/core/shadownode/Props.h | 2 +- .../fabric/core/shadownode/ShadowNode.cpp | 144 +- .../fabric/core/shadownode/ShadowNode.h | 80 +- .../core/shadownode/ShadowNodeFamily.cpp | 100 +- .../fabric/core/shadownode/ShadowNodeFamily.h | 50 +- .../shadownode/ShadowNodeFamilyFragment.h | 29 - .../core/shadownode/ShadowNodeFragment.cpp | 27 +- .../core/shadownode/ShadowNodeFragment.h | 13 + .../fabric/core/shadownode/ShadowNodeTraits.h | 17 - ReactCommon/fabric/core/state/ConcreteState.h | 65 +- ReactCommon/fabric/core/state/State.cpp | 32 +- ReactCommon/fabric/core/state/State.h | 64 +- .../fabric/core/state/StateCoordinator.cpp | 62 + .../fabric/core/state/StateCoordinator.h | 48 + ReactCommon/fabric/core/state/StateData.h | 2 +- ReactCommon/fabric/core/state/StatePipe.h | 6 +- ReactCommon/fabric/core/state/StateTarget.cpp | 29 + ReactCommon/fabric/core/state/StateTarget.h | 57 + ReactCommon/fabric/core/state/StateUpdate.cpp | 10 + ReactCommon/fabric/core/state/StateUpdate.h | 20 +- .../core/tests/ComponentDescriptorTest.cpp | 135 +- .../fabric/core/tests/FindNodeAtPointTest.cpp | 119 - .../core/tests/LayoutableShadowNodeTest.cpp | 206 - .../fabric/core/tests/PrimitivesTest.cpp | 6 +- .../fabric/core/tests/RawPropsTest.cpp | 116 +- .../core/tests/ShadowNodeFamilyTest.cpp | 79 - .../fabric/core/tests/ShadowNodeTest.cpp | 525 +- ReactCommon/fabric/core/tests/TestComponent.h | 42 +- .../tests/benchmarks/RawPropsBenchmark.cpp | 4 +- .../fabric/core/tests/traitCastTest.cpp | 105 - ReactCommon/fabric/debug/BUCK | 18 +- .../fabric/debug/DebugStringConvertible.h | 2 +- .../debug/DebugStringConvertibleItem.cpp | 4 +- .../fabric/debug/DebugStringConvertibleItem.h | 2 +- ReactCommon/fabric/element/BUCK | 85 - .../fabric/element/ComponentBuilder.cpp | 59 - ReactCommon/fabric/element/ComponentBuilder.h | 59 - ReactCommon/fabric/element/Element.cpp | 10 - ReactCommon/fabric/element/Element.h | 160 - .../fabric/element/ElementFragment.cpp | 10 - ReactCommon/fabric/element/ElementFragment.h | 61 - ReactCommon/fabric/element/testUtils.h | 46 - .../fabric/element/tests/ElementTest.cpp | 102 - ReactCommon/fabric/graphics/BUCK | 24 +- ReactCommon/fabric/graphics/Geometry.h | 58 - .../fabric/graphics/React-graphics.podspec | 6 +- ReactCommon/fabric/graphics/Transform.cpp | 55 +- ReactCommon/fabric/graphics/Transform.h | 13 - .../fabric/graphics/platform/cxx/Color.h | 8 - .../fabric/graphics/platform/ios/Color.cpp | 1 - ReactCommon/fabric/graphics/rounding.h | 82 - .../fabric/graphics/tests/TransformTest.cpp | 68 - ReactCommon/fabric/imagemanager/BUCK | 25 +- .../imagemanager/ImageInstrumentation.h | 40 - .../fabric/imagemanager/ImageRequest.h | 25 +- .../platform/cxx/ImageManager.cpp | 2 +- .../platform/cxx/ImageRequest.cpp | 18 +- .../imagemanager/platform/ios/ImageManager.mm | 8 +- .../platform/ios/ImageRequest.cpp | 19 +- .../ios/RCTImageInstrumentationProxy.h | 40 - .../ios/RCTImageInstrumentationProxy.mm | 81 - .../platform/ios/RCTImageManager.h | 6 +- .../platform/ios/RCTImageManager.mm | 13 +- .../platform/ios/RCTImageManagerProtocol.h | 16 - .../ios/RCTImagePrimitivesConversions.h | 29 +- .../platform/ios/RCTSyncImageManager.h | 28 - .../platform/ios/RCTSyncImageManager.mm | 97 - ReactCommon/fabric/mapbuffer/BUCK | 14 +- ReactCommon/fabric/mounting/BUCK | 23 +- .../fabric/mounting/Differentiator.cpp | 501 +- ReactCommon/fabric/mounting/Differentiator.h | 3 - .../fabric/mounting/MountingCoordinator.cpp | 44 +- .../fabric/mounting/MountingCoordinator.h | 4 +- .../fabric/mounting/MountingTelemetry.cpp | 106 +- .../fabric/mounting/MountingTelemetry.h | 44 +- ReactCommon/fabric/mounting/ShadowTree.cpp | 57 +- ReactCommon/fabric/mounting/ShadowTree.h | 11 +- .../fabric/mounting/ShadowTreeDelegate.h | 2 +- .../fabric/mounting/ShadowTreeRegistry.cpp | 4 +- ReactCommon/fabric/mounting/ShadowView.cpp | 14 +- ReactCommon/fabric/mounting/ShadowView.h | 3 + .../mounting/TreeStateReconciliation.cpp | 94 - .../fabric/mounting/TreeStateReconciliation.h | 33 - .../fabric/mounting/stubs/StubView.cpp | 24 +- ReactCommon/fabric/mounting/stubs/StubView.h | 2 - ReactCommon/fabric/mounting/stubs/stubs.cpp | 5 +- ReactCommon/fabric/mounting/tests/Entropy.h | 131 - .../mounting/tests/MountingTelemetryTest.cpp | 103 - .../fabric/mounting/tests/MountingTest.cpp | 315 +- .../tests/ShadowTreeLifeCycleTest.cpp | 181 - .../mounting/tests/shadowTreeGeneration.h | 259 - ReactCommon/fabric/textlayoutmanager/BUCK | 21 +- .../textlayoutmanager/TextMeasureCache.h | 19 +- .../platform/android/TextLayoutManager.cpp | 51 +- .../platform/android/TextLayoutManager.h | 4 +- .../platform/cxx/TextLayoutManager.cpp | 2 +- .../platform/cxx/TextLayoutManager.h | 5 +- .../platform/ios/NSTextStorage+FontScaling.m | 76 +- .../platform/ios/RCTAttributedTextUtils.h | 24 +- .../platform/ios/RCTAttributedTextUtils.mm | 45 +- .../platform/ios/RCTTextLayoutManager.h | 22 +- .../platform/ios/RCTTextLayoutManager.mm | 95 +- .../ios/RCTTextPrimitivesConversions.h | 21 +- .../platform/ios/TextLayoutManager.h | 9 +- .../platform/ios/TextLayoutManager.mm | 28 +- ReactCommon/fabric/uimanager/BUCK | 29 +- .../uimanager/ComponentDescriptorProvider.h | 16 +- .../uimanager/ComponentDescriptorRegistry.cpp | 45 +- .../uimanager/ComponentDescriptorRegistry.h | 2 +- ReactCommon/fabric/uimanager/Scheduler.cpp | 55 +- ReactCommon/fabric/uimanager/Scheduler.h | 9 +- ReactCommon/fabric/uimanager/UIManager.cpp | 231 +- ReactCommon/fabric/uimanager/UIManager.h | 38 +- .../fabric/uimanager/UIManagerBinding.cpp | 71 +- .../fabric/uimanager/UIManagerDelegate.h | 6 +- .../fabric/uimanager/UITemplateProcessor.cpp | 10 +- .../fabric/uimanager/UITemplateProcessor.h | 4 +- ReactCommon/fabric/uimanager/primitives.h | 6 +- .../tests/UITemplateProcessorTest.cpp | 6 +- ReactCommon/hermes/.clang-tidy | 5 - ReactCommon/hermes/executor/Android.mk | 1 + .../hermes/executor/HermesExecutorFactory.cpp | 38 +- .../hermes/executor/HermesExecutorFactory.h | 4 +- ReactCommon/hermes/executor/JSITracing.cpp | 2 +- ReactCommon/hermes/inspector/BUCK | 33 +- ReactCommon/hermes/inspector/DEFS.bzl | 4 +- ReactCommon/hermes/inspector/Inspector.cpp | 9 +- ReactCommon/hermes/inspector/README.md | 6 +- .../hermes/inspector/RuntimeAdapter.cpp | 11 +- ReactCommon/hermes/inspector/RuntimeAdapter.h | 15 +- .../inspector/chrome/AutoAttachUtils.cpp | 19 - .../hermes/inspector/chrome/Connection.cpp | 114 +- .../hermes/inspector/chrome/Connection.h | 2 +- .../inspector/chrome/MessageConverters.cpp | 16 +- .../inspector/chrome/MessageConverters.h | 8 +- .../hermes/inspector/chrome/MessageTypes.cpp | 126 +- .../hermes/inspector/chrome/MessageTypes.h | 64 +- .../hermes/inspector/chrome/cli/main.cpp | 4 +- .../chrome/tests/ConnectionDemuxTests.cpp | 6 +- .../chrome/tests/ConnectionTests.cpp | 83 +- .../inspector/chrome/tests/SyncConnection.cpp | 4 +- .../inspector/detail/SerialExecutor.cpp | 2 + ReactCommon/hermes/inspector/detail/Thread.h | 4 +- .../hermes/inspector/tests/InspectorTests.cpp | 4 +- .../hermes/inspector/tools/message_types.txt | 3 +- .../hermes/inspector/tools/msggen/.babelrc | 2 +- .../hermes/inspector/tools/msggen/.flowconfig | 16 + .../inspector/tools/msggen/package.json | 25 +- .../inspector/tools/msggen/src/Converters.js | 18 +- .../inspector/tools/msggen/src/Property.js | 21 +- .../inspector/tools/msggen/src/index.js | 16 +- .../hermes/inspector/tools/msggen/yarn.lock | 6239 ++--- ReactCommon/hermes/inspector/tools/run_msggen | 3 +- .../tools/sandcastle/build_and_test.sh | 8 +- ReactCommon/jscallinvoker/.clang-tidy | 5 - ReactCommon/jsengineinstance/.clang-tidy | 5 - ReactCommon/jsi/.clang-tidy | 5 - ReactCommon/jsi/BUCK | 34 +- ReactCommon/jsi/JSCRuntime.cpp | 581 +- ReactCommon/jsi/React-jsi.podspec | 6 +- ReactCommon/jsi/jsi/decorator.h | 24 +- ReactCommon/jsi/jsi/instrumentation.h | 23 +- ReactCommon/jsi/jsi/jsi-inl.h | 2 +- ReactCommon/jsi/jsi/jsi.cpp | 64 +- ReactCommon/jsi/jsi/jsi.h | 49 +- ReactCommon/jsi/jsi/test/testlib.cpp | 176 +- ReactCommon/jsiexecutor/.clang-tidy | 5 - ReactCommon/jsiexecutor/BUCK | 10 +- .../jsiexecutor/React-jsiexecutor.podspec | 6 +- .../jsiexecutor/jsireact/JSIExecutor.cpp | 126 +- .../jsiexecutor/jsireact/JSIExecutor.h | 12 +- .../jsiexecutor/jsireact/JSINativeModules.cpp | 6 +- .../jsiexecutor/jsireact/JSINativeModules.h | 6 +- ReactCommon/jsinspector/.clang-tidy | 5 - ReactCommon/jsinspector/BUCK | 2 +- .../jsinspector/InspectorInterfaces.cpp | 19 +- ReactCommon/jsinspector/InspectorInterfaces.h | 7 +- .../jsinspector/React-jsinspector.podspec | 4 +- ReactCommon/microprofiler/.clang-tidy | 5 - ReactCommon/microprofiler/BUCK | 2 +- ReactCommon/microprofiler/MicroProfiler.cpp | 90 +- ReactCommon/microprofiler/MicroProfiler.h | 45 +- ReactCommon/turbomodule/.clang-tidy | 5 - ReactCommon/turbomodule/core/BUCK | 26 +- .../turbomodule/core/TurboCxxModule.cpp | 45 +- .../turbomodule/core/TurboModuleBinding.cpp | 12 +- .../turbomodule/core/TurboModuleBinding.h | 11 +- .../turbomodule/core/TurboModuleUtils.h | 57 +- .../core/platform/android/JavaTurboModule.cpp | 112 +- .../core/platform/android/JavaTurboModule.h | 16 + .../core/platform/ios/RCTTurboModule.h | 154 +- .../core/platform/ios/RCTTurboModule.mm | 212 +- .../core/platform/ios/RCTTurboModuleManager.h | 17 +- .../platform/ios/RCTTurboModuleManager.mm | 308 +- ReactCommon/turbomodule/samples/BUCK | 18 +- .../ios/RCTNativeSampleTurboModuleSpec.h | 6 +- .../ios/RCTNativeSampleTurboModuleSpec.mm | 6 +- .../platform/ios/RCTSampleTurboModule.mm | 8 +- ReactCommon/utils/.clang-tidy | 5 - ReactCommon/utils/BUCK | 16 +- ReactCommon/utils/ManagedObjectWrapper.h | 6 +- ReactCommon/utils/RuntimeExecutor.h | 82 - ReactCommon/utils/SimpleThreadSafeCache.h | 9 +- ReactCommon/utils/Telemetry.h | 65 - ReactCommon/utils/TimeUtils.h | 74 + ReactCommon/yoga/.clang-tidy | 5 - ReactCommon/yoga/Yoga.podspec | 2 +- ReactCommon/yoga/yoga/YGNode.h | 2 +- ReactCommon/yoga/yoga/YGValue.h | 11 - ReactCommon/yoga/yoga/Yoga.cpp | 11 +- ReactCommon/yoga/yoga/Yoga.h | 5 - bots/code-analysis-bot.js | 28 +- bots/dangerfile.js | 10 +- bots/datastore.js | 150 - bots/make-comment.js | 112 - bots/package.json | 3 +- bots/report-bundle-size.js | 190 - bots/yarn.lock | 1071 +- build.gradle.kts | 7 +- flow-typed/npm/create-react-class_v15.x.x.js | 17 + flow-typed/npm/react-dom_v16.x.x.js | 115 - gradle/wrapper/gradle-wrapper.jar | Bin 58695 -> 55616 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 29 +- gradlew.bat | 203 +- index.js | 46 +- jest/mockScrollView.js | 35 - jest/preprocessor.js | 2 + jest/renderer.js | 3 - jest/setup.js | 46 +- .../generator-macos/templates/macos/Podfile | 4 +- metro.config.js | 62 +- package.json | 75 +- .../__test_fixtures__/failures.js | 12 +- .../__test_fixtures__/fixtures.js | 8 +- .../__snapshots__/index-test.js.snap | 41 +- .../__tests__/index-test.js | 18 +- .../babel-plugin-inline-view-configs/index.js | 37 +- .../README.md | 6 - .../index.js | 3 - .../package.json | 24 +- .../yarn.lock | 969 +- .../__tests__/platform-colors-test.js | 62 - .../index.js | 1 - .../platform-colors.js | 119 - packages/react-native-codegen/BUCK | 8 +- packages/react-native-codegen/DEFS.bzl | 54 +- packages/react-native-codegen/README.md | 14 - packages/react-native-codegen/package.json | 12 +- .../src/cli/combine/combine-js-to-schema.js | 3 + .../src/generators/components/CppHelpers.js | 6 - .../components/GenerateEventEmitterCpp.js | 7 +- .../components/GenerateEventEmitterH.js | 57 +- .../generators/components/GeneratePropsH.js | 2 +- .../components/GeneratePropsJavaDelegate.js | 4 +- .../components/GeneratePropsJavaInterface.js | 2 +- .../src/generators/components/JavaHelpers.js | 8 +- .../GenerateEventEmitterCpp-test.js.snap | 14 +- .../GenerateEventEmitterH-test.js.snap | 120 +- .../__snapshots__/GeneratePropsH-test.js.snap | 98 +- .../GeneratePropsJavaDelegate-test.js.snap | 8 +- .../modules/GenerateModuleHObjCpp.js | 2 +- .../generators/modules/GenerateModuleMm.js | 4 +- .../GenerateModuleHObjCpp-test.js.snap | 14 +- .../GenerateModuleMm-test.js.snap | 28 +- .../components/__test_fixtures__/fixtures.js | 14 +- .../component-parser-test.js.snap | 100 - .../src/parsers/flow/components/props.js | 2 - react.gradle | 40 +- scripts/.tests.env | 9 +- .../{react_native_pods.rb => autolink-ios.rb} | 22 +- scripts/circleci/report-bundle-size.sh | 19 - scripts/ios-install-third-party.sh | 89 + scripts/objc-test.sh | 13 +- scripts/publish-npm.js | 52 +- scripts/react-native-xcode.sh | 21 +- .../run-android-local-integration-tests.sh | 2 +- scripts/run-android-local-unit-tests.sh | 2 +- scripts/run-ci-e2e-tests.js | 23 +- scripts/test-manual-e2e.sh | 10 +- scripts/validate-android-sdk.sh | 9 +- scripts/validate-android-test-env.sh | 6 +- scripts/validate-ios-test-env.sh | 8 +- .../ReactNativeVersion.h.template | 24 - template/_flowconfig | 6 +- template/android/app/build.gradle | 12 +- template/android/build.gradle | 9 +- template/android/gradle.properties | 2 +- .../android/gradle/wrapper/gradle-wrapper.jar | Bin 58695 -> 55616 bytes .../gradle/wrapper/gradle-wrapper.properties | 2 +- template/android/gradlew | 29 +- template/android/gradlew.bat | 203 +- template/ios/HelloWorld-tvOSTests/Info.plist | 2 +- .../ios/HelloWorld.xcodeproj/project.pbxproj | 36 +- template/ios/HelloWorld/AppDelegate.m | 4 +- .../HelloWorld/Base.lproj/LaunchScreen.xib | 42 + .../ios/HelloWorld/LaunchScreen.storyboard | 58 - template/ios/Podfile | 81 +- template/package.json | 18 +- third-party-podspecs/DoubleConversion.podspec | 2 +- third-party-podspecs/RCT-Folly.podspec | 35 +- third-party-podspecs/glog.podspec | 2 +- tools/build_defs/oss/rn_defs.bzl | 21 +- yarn.lock | 1298 +- 1386 files changed, 87093 insertions(+), 89842 deletions(-) create mode 100644 .appveyor/config.yml delete mode 100644 .github/ISSUE_TEMPLATE/config.yml create mode 100644 .github/ISSUE_TEMPLATE/question.md delete mode 100644 .github/label-actions.yml delete mode 100644 .github/workflows/needs-attention.yml delete mode 100644 .github/workflows/process-label-actions.yml delete mode 100644 Libraries/Components/Pressable/Pressable.js delete mode 100644 Libraries/Components/Pressable/__tests__/Pressable-test.js delete mode 100644 Libraries/Components/Pressable/__tests__/__snapshots__/Pressable-test.js.snap delete mode 100644 Libraries/Components/Pressable/useAndroidRippleForView.js create mode 100644 Libraries/Components/ScrollView/__mocks__/ScrollViewMock.js delete mode 100644 Libraries/Components/ScrollView/__tests__/ScrollView-test.js delete mode 100644 Libraries/Components/ScrollView/__tests__/__snapshots__/ScrollView-test.js.snap delete mode 100644 Libraries/Components/TextInput/AndroidTextInputViewConfig.js delete mode 100644 Libraries/Components/TextInput/RCTMultilineTextInputNativeComponent.js delete mode 100644 Libraries/Components/TextInput/RCTSingelineTextInputNativeComponent.js delete mode 100644 Libraries/Components/TextInput/RCTSinglelineTextInputViewConfig.js delete mode 100644 Libraries/Components/TextInput/TextInputNativeCommands.js delete mode 100644 Libraries/Core/Timers/__tests__/JSTimers-test.js delete mode 100644 Libraries/Core/setUpPerformance.js create mode 100644 Libraries/Experimental/Incremental.js rename Libraries/HeapCapture/{NativeJSCHeapCapture.js => NativeHeapCapture.js} (76%) delete mode 100644 Libraries/Image/ImageViewViewConfig.js delete mode 100644 Libraries/Image/RCTDisplayWeakRefreshable.h delete mode 100644 Libraries/Image/RCTDisplayWeakRefreshable.m delete mode 100644 Libraries/Image/RCTImageURLLoaderWithAttribution.mm delete mode 100644 Libraries/Pressability/usePressability.js create mode 100644 Libraries/Renderer/shims/NativeMethodsMixin.js create mode 100644 Libraries/Renderer/shims/ReactTypes.js rename Libraries/{Image/ImageAnalyticsTagContext.js => StyleSheet/NativeOrDynamicColorType.js} (54%) delete mode 100644 Libraries/StyleSheet/PlatformColorValueTypes.android.js delete mode 100644 Libraries/StyleSheet/PlatformColorValueTypes.ios.js delete mode 100644 Libraries/StyleSheet/PlatformColorValueTypes.macos.js delete mode 100644 Libraries/StyleSheet/PlatformColorValueTypesAndroid.android.js delete mode 100644 Libraries/StyleSheet/PlatformColorValueTypesAndroid.js delete mode 100644 Libraries/StyleSheet/PlatformColorValueTypesIOS.ios.js delete mode 100644 Libraries/StyleSheet/PlatformColorValueTypesIOS.js delete mode 100644 Libraries/StyleSheet/PlatformColorValueTypesIOS.macos.js delete mode 100644 Libraries/StyleSheet/Rect.js create mode 100644 Libraries/StyleSheet/normalizeColorObject.android.js create mode 100644 Libraries/StyleSheet/normalizeColorObject.ios.js create mode 100644 Libraries/StyleSheet/normalizeColorObject.macos.js create mode 100644 Libraries/StyleSheet/processColorObject.android.js create mode 100644 Libraries/StyleSheet/processColorObject.ios.js create mode 100644 Libraries/StyleSheet/processColorObject.macos.js delete mode 100644 Libraries/Utilities/differ/__tests__/matricesDiffer-test.js create mode 100644 Libraries/YellowBox/Data/YellowBoxCategory.js create mode 100644 Libraries/YellowBox/Data/YellowBoxRegistry.js create mode 100644 Libraries/YellowBox/Data/YellowBoxSymbolication.js create mode 100644 Libraries/YellowBox/Data/YellowBoxWarning.js create mode 100644 Libraries/YellowBox/Data/__tests__/YellowBoxCategory-test.js create mode 100644 Libraries/YellowBox/Data/__tests__/YellowBoxRegistry-test.js create mode 100644 Libraries/YellowBox/Data/__tests__/YellowBoxSymbolication-test.js create mode 100644 Libraries/YellowBox/Data/__tests__/YellowBoxWarning-test.js create mode 100644 Libraries/YellowBox/Data/__tests__/__snapshots__/YellowBoxCategory-test.js.snap create mode 100644 Libraries/YellowBox/UI/YellowBoxButton.js create mode 100644 Libraries/YellowBox/UI/YellowBoxInspector.js create mode 100644 Libraries/YellowBox/UI/YellowBoxInspectorFooter.js create mode 100644 Libraries/YellowBox/UI/YellowBoxInspectorHeader.js create mode 100644 Libraries/YellowBox/UI/YellowBoxInspectorSourceMapStatus.js create mode 100644 Libraries/YellowBox/UI/YellowBoxInspectorStackFrame.js create mode 100644 Libraries/YellowBox/UI/YellowBoxList.js create mode 100644 Libraries/YellowBox/UI/YellowBoxListRow.js create mode 100644 Libraries/YellowBox/UI/YellowBoxPressable.js create mode 100644 Libraries/YellowBox/UI/YellowBoxStyle.js create mode 100644 Libraries/YellowBox/YellowBox.js create mode 100644 Libraries/YellowBox/YellowBoxContainer.js delete mode 100644 Libraries/YellowBox/YellowBoxDeprecated.js create mode 100644 Libraries/YellowBox/__tests__/YellowBox-test.js delete mode 100644 Libraries/YellowBox/__tests__/YellowBoxDeprecated-test.js create mode 100644 Libraries/YellowBox/__tests__/__snapshots__/YellowBox-test.js.snap create mode 100644 RNTester/RCTTest/RCTTestModule.m delete mode 100644 RNTester/RCTTest/RCTTestModule.mm delete mode 100644 RNTester/RCTTest/RCTTestPlugins.h delete mode 100644 RNTester/RCTTest/RCTTestPlugins.mm create mode 100644 RNTester/RNTester/Base.lproj/LaunchScreen.xib delete mode 100644 RNTester/RNTester/LaunchScreen.storyboard delete mode 100644 RNTester/android/app/src/androidTest/java/com/facebook/react/uiapp/DetoxTest.java delete mode 100644 RNTester/e2e/__tests__/TextInput-test.js delete mode 100644 RNTester/js/examples/PlatformColor/PlatformColorExample.js delete mode 100644 RNTester/js/examples/Pressable/PressableExample.js delete mode 100644 React/AccessibilityResources/en.lproj/Localizable.strings delete mode 100644 React/Base/RCTJSInvokerModule.h delete mode 100644 React/CoreModules/RCTDevLoadingView.h delete mode 100644 React/CxxBridge/RCTJSIExecutorRuntimeInstaller.h delete mode 100644 React/CxxBridge/RCTJSIExecutorRuntimeInstaller.mm rename React/DevSupport/{RCTDevLoadingViewProtocol.h => RCTDevLoadingView.h} (85%) rename React/{CoreModules/RCTDevLoadingView.mm => DevSupport/RCTDevLoadingView.m} (66%) delete mode 100644 React/DevSupport/RCTDevLoadingViewSetEnabled.h delete mode 100644 React/DevSupport/RCTDevLoadingViewSetEnabled.m delete mode 100644 React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.h delete mode 100644 React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm delete mode 100644 React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputNativeCommands.h delete mode 100644 React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputUtils.h delete mode 100644 React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputUtils.mm delete mode 100644 ReactAndroid/src/main/java/com/facebook/fbreact/specs/NativeJSCHeapCaptureSpec.java delete mode 100644 ReactAndroid/src/main/java/com/facebook/fbreact/specs/jni/FBReactNativeSpec-generated.cpp delete mode 100644 ReactAndroid/src/main/java/com/facebook/fbreact/specs/jni/FBReactNativeSpec.h delete mode 100644 ReactAndroid/src/main/java/com/facebook/hermes/.clang-tidy delete mode 100644 ReactAndroid/src/main/java/com/facebook/react/bridge/ColorPropConverter.java delete mode 100644 ReactAndroid/src/main/java/com/facebook/react/bridge/RetryableMountingLayerException.java delete mode 100644 ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerBase.java delete mode 100644 ReactAndroid/src/main/java/com/facebook/react/fabric/.clang-tidy delete mode 100644 ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/DispatchIntCommandMountItem.java delete mode 100644 ReactAndroid/src/main/java/com/facebook/react/modules/.clang-tidy delete mode 100644 ReactAndroid/src/main/java/com/facebook/react/turbomodule/.clang-tidy delete mode 100644 ReactAndroid/src/main/java/com/facebook/react/util/RCTLog.java delete mode 100644 ReactAndroid/src/main/java/com/facebook/react/util/RNLog.java create mode 100644 ReactAndroid/src/main/java/com/facebook/react/viewmanagers/PullToRefreshViewManagerDelegate.java create mode 100644 ReactAndroid/src/main/java/com/facebook/react/viewmanagers/PullToRefreshViewManagerInterface.java delete mode 100644 ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextViewManagerCallback.java delete mode 100644 ReactAndroid/src/main/jni/first-party/.clang-tidy delete mode 100644 ReactAndroid/src/main/jni/first-party/yogajni/.clang-tidy delete mode 100644 ReactAndroid/src/main/jni/react/jni/.clang-tidy delete mode 100644 ReactAndroid/src/main/jni/react/jni/NativeTime.cpp delete mode 100644 ReactAndroid/src/main/jni/react/jni/NativeTime.h delete mode 100644 ReactAndroid/src/test/java/com/facebook/react/bridge/JavaScriptModuleRegistryTest.java delete mode 100644 ReactCommon/better/.clang-tidy delete mode 100644 ReactCommon/callinvoker/.clang-tidy delete mode 100644 ReactCommon/callinvoker/React-callinvoker.podspec create mode 100644 ReactCommon/callinvoker/ReactCommon/BridgeJSCallInvoker.cpp create mode 100644 ReactCommon/callinvoker/ReactCommon/BridgeJSCallInvoker.h create mode 100644 ReactCommon/callinvoker/ReactCommon/MessageQueueThreadCallInvoker.cpp create mode 100644 ReactCommon/callinvoker/ReactCommon/MessageQueueThreadCallInvoker.h delete mode 100644 ReactCommon/config/.clang-tidy delete mode 100644 ReactCommon/cxxreact/.clang-tidy delete mode 100644 ReactCommon/cxxreact/ReactNativeVersion.h delete mode 100644 ReactCommon/fabric/.clang-tidy create mode 100644 ReactCommon/fabric/components/image/ImageLocalData.cpp create mode 100644 ReactCommon/fabric/components/image/ImageLocalData.h delete mode 100644 ReactCommon/fabric/components/image/ImageState.cpp delete mode 100644 ReactCommon/fabric/components/image/ImageState.h create mode 100644 ReactCommon/fabric/components/slider/SliderLocalData.cpp create mode 100644 ReactCommon/fabric/components/slider/SliderLocalData.h delete mode 100644 ReactCommon/fabric/components/slider/SliderState.cpp delete mode 100644 ReactCommon/fabric/components/slider/SliderState.h delete mode 100644 ReactCommon/fabric/components/textinput/iostextinput/BUCK delete mode 100644 ReactCommon/fabric/components/textinput/iostextinput/TextInputComponentDescriptor.h delete mode 100644 ReactCommon/fabric/components/textinput/iostextinput/TextInputEventEmitter.cpp delete mode 100644 ReactCommon/fabric/components/textinput/iostextinput/TextInputEventEmitter.h delete mode 100644 ReactCommon/fabric/components/textinput/iostextinput/TextInputProps.cpp delete mode 100644 ReactCommon/fabric/components/textinput/iostextinput/TextInputProps.h delete mode 100644 ReactCommon/fabric/components/textinput/iostextinput/TextInputShadowNode.cpp delete mode 100644 ReactCommon/fabric/components/textinput/iostextinput/TextInputShadowNode.h delete mode 100644 ReactCommon/fabric/components/textinput/iostextinput/TextInputState.cpp delete mode 100644 ReactCommon/fabric/components/textinput/iostextinput/TextInputState.h delete mode 100644 ReactCommon/fabric/components/textinput/iostextinput/conversions.h delete mode 100644 ReactCommon/fabric/components/textinput/iostextinput/primitives.h delete mode 100644 ReactCommon/fabric/components/textinput/iostextinput/propsConversions.h create mode 100644 ReactCommon/fabric/core/shadownode/LocalData.h delete mode 100644 ReactCommon/fabric/core/shadownode/ShadowNodeFamilyFragment.h create mode 100644 ReactCommon/fabric/core/state/StateCoordinator.cpp create mode 100644 ReactCommon/fabric/core/state/StateCoordinator.h create mode 100644 ReactCommon/fabric/core/state/StateTarget.cpp create mode 100644 ReactCommon/fabric/core/state/StateTarget.h delete mode 100644 ReactCommon/fabric/core/tests/FindNodeAtPointTest.cpp delete mode 100644 ReactCommon/fabric/core/tests/LayoutableShadowNodeTest.cpp delete mode 100644 ReactCommon/fabric/core/tests/ShadowNodeFamilyTest.cpp delete mode 100644 ReactCommon/fabric/core/tests/traitCastTest.cpp delete mode 100644 ReactCommon/fabric/element/BUCK delete mode 100644 ReactCommon/fabric/element/ComponentBuilder.cpp delete mode 100644 ReactCommon/fabric/element/ComponentBuilder.h delete mode 100644 ReactCommon/fabric/element/Element.cpp delete mode 100644 ReactCommon/fabric/element/Element.h delete mode 100644 ReactCommon/fabric/element/ElementFragment.cpp delete mode 100644 ReactCommon/fabric/element/ElementFragment.h delete mode 100644 ReactCommon/fabric/element/testUtils.h delete mode 100644 ReactCommon/fabric/element/tests/ElementTest.cpp delete mode 100644 ReactCommon/fabric/graphics/rounding.h delete mode 100644 ReactCommon/fabric/graphics/tests/TransformTest.cpp delete mode 100644 ReactCommon/fabric/imagemanager/ImageInstrumentation.h delete mode 100644 ReactCommon/fabric/imagemanager/platform/ios/RCTImageInstrumentationProxy.h delete mode 100644 ReactCommon/fabric/imagemanager/platform/ios/RCTImageInstrumentationProxy.mm delete mode 100644 ReactCommon/fabric/imagemanager/platform/ios/RCTImageManagerProtocol.h delete mode 100644 ReactCommon/fabric/imagemanager/platform/ios/RCTSyncImageManager.h delete mode 100644 ReactCommon/fabric/imagemanager/platform/ios/RCTSyncImageManager.mm delete mode 100644 ReactCommon/fabric/mounting/TreeStateReconciliation.cpp delete mode 100644 ReactCommon/fabric/mounting/TreeStateReconciliation.h delete mode 100644 ReactCommon/fabric/mounting/tests/Entropy.h delete mode 100644 ReactCommon/fabric/mounting/tests/MountingTelemetryTest.cpp delete mode 100644 ReactCommon/fabric/mounting/tests/ShadowTreeLifeCycleTest.cpp delete mode 100644 ReactCommon/fabric/mounting/tests/shadowTreeGeneration.h delete mode 100644 ReactCommon/hermes/.clang-tidy create mode 100644 ReactCommon/hermes/inspector/tools/msggen/.flowconfig delete mode 100644 ReactCommon/jscallinvoker/.clang-tidy delete mode 100644 ReactCommon/jsengineinstance/.clang-tidy delete mode 100644 ReactCommon/jsi/.clang-tidy delete mode 100644 ReactCommon/jsiexecutor/.clang-tidy delete mode 100644 ReactCommon/jsinspector/.clang-tidy delete mode 100644 ReactCommon/microprofiler/.clang-tidy delete mode 100644 ReactCommon/turbomodule/.clang-tidy delete mode 100644 ReactCommon/utils/.clang-tidy delete mode 100644 ReactCommon/utils/Telemetry.h create mode 100644 ReactCommon/utils/TimeUtils.h delete mode 100644 ReactCommon/yoga/.clang-tidy delete mode 100644 bots/datastore.js delete mode 100644 bots/make-comment.js delete mode 100644 bots/report-bundle-size.js create mode 100644 flow-typed/npm/create-react-class_v15.x.x.js delete mode 100644 flow-typed/npm/react-dom_v16.x.x.js delete mode 100644 jest/mockScrollView.js delete mode 100644 packages/eslint-plugin-react-native-community/__tests__/platform-colors-test.js delete mode 100644 packages/eslint-plugin-react-native-community/platform-colors.js delete mode 100644 packages/react-native-codegen/README.md rename scripts/{react_native_pods.rb => autolink-ios.rb} (88%) delete mode 100755 scripts/circleci/report-bundle-size.sh create mode 100755 scripts/ios-install-third-party.sh delete mode 100644 scripts/versiontemplates/ReactNativeVersion.h.template create mode 100644 template/ios/HelloWorld/Base.lproj/LaunchScreen.xib delete mode 100644 template/ios/HelloWorld/LaunchScreen.storyboard diff --git a/.ado/templates/apple-job-javascript.yml b/.ado/templates/apple-job-javascript.yml index 1eb7f5b9e400fc..0f0277e097aac1 100644 --- a/.ado/templates/apple-job-javascript.yml +++ b/.ado/templates/apple-job-javascript.yml @@ -17,6 +17,10 @@ steps: - template: apple-xcode-select.yml + - template: apple-droid-node-patching.yml + parameters: + apply_office_patches: $(apply_office_patches) + - script: 'yarn install' displayName: 'yarn install' @@ -38,4 +42,4 @@ steps: displayName: 'yarn lint' - script: 'yarn format-check' - displayName: 'yarn format-check' + displayName: 'yarn format-check' \ No newline at end of file diff --git a/.ado/templates/apple-job-react-native.yml b/.ado/templates/apple-job-react-native.yml index 70bdd2440fc00f..5ba1fc0dc98d08 100644 --- a/.ado/templates/apple-job-react-native.yml +++ b/.ado/templates/apple-job-react-native.yml @@ -28,9 +28,13 @@ steps: - script: brew link node@12 --overwrite --force displayName: 'ensure node 12' - # Task Group: Xcode select proper version + # Task Group: XCode select proper version - template: apple-xcode-select.yml + - template: apple-droid-node-patching.yml + parameters: + apply_office_patches: $(apply_office_patches) + - task: CmdLine@2 displayName: yarn install inputs: diff --git a/.appveyor/config.yml b/.appveyor/config.yml new file mode 100644 index 00000000000000..ed8162cf135899 --- /dev/null +++ b/.appveyor/config.yml @@ -0,0 +1,47 @@ +environment: + ANDROID_HOME: "C:\\android-sdk-windows" + ANDROID_NDK: "C:\\android-sdk-windows\\android-ndk-r19c" + ANDROID_BUILD_VERSION: 28 + ANDROID_TOOLS_VERSION: 28.0.3 + + GRADLE_OPTS: -Dorg.gradle.daemon=false + + SDK_TOOLS_URL: https://dl.google.com/android/repository/sdk-tools-windows-3859397.zip + NDK_TOOLS_URL: https://dl.google.com/android/repository/android-ndk-r19c-windows-x86_64.zip + + matrix: + - nodejs_version: 8 + - nodejs_version: 10 + +install: + # Install Android SDK Tools + - mkdir "%ANDROID_HOME%" + - appveyor DownloadFile "%SDK_TOOLS_URL%" -FileName "%TMP%/sdk-tools.zip" + - 7z x "%TMP%/sdk-tools.zip" -o"%ANDROID_HOME%" > nul + - set PATH=%PATH%;"%ANDROID_HOME%\tools\bin" + + - yes 2> nul | sdkmanager --licenses > nul + - yes 2> nul | sdkmanager "system-images;android-19;google_apis;armeabi-v7a" + - yes 2> nul | sdkmanager "platforms;android-%ANDROID_BUILD_VERSION%" + - yes 2> nul | sdkmanager "build-tools;%ANDROID_TOOLS_VERSION%" + - yes 2> nul | sdkmanager "add-ons;addon-google_apis-google-23" + - yes 2> nul | sdkmanager "extras;android;m2repository" + + - appveyor DownloadFile "%NDK_TOOLS_URL%" -FileName "%TMP%/ndk.zip" + - 7z x "%TMP%/ndk.zip" -o"%ANDROID_HOME%" > nul + + - ps: Install-Product node $env:nodejs_version x64 + - npx envinfo@latest + - appveyor-retry yarn install + +build_script: + - yarn run flow-check-android + - yarn run flow-check-ios + - yarn run test + # - gradlew.bat RNTester:android:app:assembleRelease + +cache: + - node_modules + - "%LOCALAPPDATA%/Yarn" + - "%USERPROFILE%/.gradle/caches" + - "%USERPROFILE%/.gradle/wrapper" diff --git a/.buckconfig b/.buckconfig index dc22ddc157f629..14ee0b460b6e1c 100644 --- a/.buckconfig +++ b/.buckconfig @@ -1,6 +1,6 @@ [android] - target = android-29 + target = android-28 [download] max_number_of_retries = 3 diff --git a/.circleci/Dockerfiles/Dockerfile.android b/.circleci/Dockerfiles/Dockerfile.android index 2fa8e3f8e0d240..6d7e400c534fc6 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:2019-10-18 +FROM reactnativecommunity/react-native-android:2019-9-4 LABEL Description="React Native Android Test Image" LABEL maintainer="Héctor Ramos " diff --git a/.circleci/config.yml b/.circleci/config.yml index e50d25cbc858dd..a749a0110bf58e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,12 +1,5 @@ version: 2.1 -# ------------------------- -# ORBS -# ------------------------- - -orbs: - win: circleci/windows@2.4.0 - # ------------------------- # DEFAULTS # ------------------------- @@ -14,29 +7,23 @@ defaults: &defaults working_directory: ~/react-native environment: - GIT_COMMIT_DESC: git log --format=oneline -n 1 $CIRCLE_SHA1 - # The public github tokens are publicly visible by design - - PUBLIC_PULLBOT_GITHUB_TOKEN_A: "a6edf8e8d40ce4e8b11a" - - PUBLIC_PULLBOT_GITHUB_TOKEN_B: "150e1341f4dd9c944d2a" - - PUBLIC_ANALYSISBOT_GITHUB_TOKEN_A: &github_token_a "78a72af35445ca3f8180" - - PUBLIC_ANALYSISBOT_GITHUB_TOKEN_B: &github_token_b "b1a98e0bbd56ff1ccba1" - # ------------------------- # EXECUTORS # ------------------------- executors: - nodelts: + node8: <<: *defaults docker: - - image: circleci/node:12 - nodeprevlts: + - image: circleci/node:8 + nodelts: <<: *defaults docker: - - image: circleci/node:10 + - image: circleci/node:lts reactnativeandroid: <<: *defaults docker: - - image: reactnativecommunity/react-native-android:2019-10-18 + - image: reactnativecommunity/react-native-android:2019-9-4 resource_class: "large" environment: - TERM: "dumb" @@ -44,13 +31,10 @@ executors: - _JAVA_OPTIONS: "-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap" - GRADLE_OPTS: '-Dorg.gradle.daemon=false -Dorg.gradle.jvmargs="-XX:+HeapDumpOnOutOfMemoryError"' - BUILD_THREADS: 2 - # Repeated here, as the environment key in this executor will overwrite the one in defaults - - PUBLIC_ANALYSISBOT_GITHUB_TOKEN_A: *github_token_a - - PUBLIC_ANALYSISBOT_GITHUB_TOKEN_B: *github_token_b reactnativeios: <<: *defaults macos: - xcode: &_XCODE_VERSION "11.3.1" + xcode: "10.3.0" # ------------------------- # COMMANDS @@ -69,7 +53,7 @@ commands: steps: - run: name: Initial Setup - command: mkdir -p ./reports/{buck,build,junit,outputs} + command: mkdir -p ~/reports/{buck,build,junit,outputs} run_yarn: steps: @@ -78,7 +62,7 @@ commands: - v4-yarn-cache-{{ arch }}-{{ checksum "yarn.lock" }} - v4-yarn-cache-{{ arch }} - run: - name: "Yarn: Install Dependencies" + name: Run Yarn command: | # Skip yarn install on metro bump commits as the package is not yet # available on npm @@ -110,21 +94,13 @@ commands: - ~/okbuck key: v3-buck-v2019.01.10.01-{{ checksum "scripts/circleci/buck_fetch.sh" }} - install_github_bot_deps: - steps: - - run: - name: "Yarn: Install dependencies (GitHub bots)" - command: cd bots && yarn install --non-interactive --cache-folder ~/.cache/yarn - brew_install: parameters: package: description: Homebrew package to install type: string steps: - - run: - name: "Brew: Install << parameters.package >>" - command: HOMEBREW_NO_AUTO_UPDATE=1 brew install << parameters.package >> >/dev/null + - run: HOMEBREW_NO_AUTO_UPDATE=1 brew install << parameters.package >> >/dev/null with_brew_cache_span: parameters: @@ -133,15 +109,15 @@ commands: steps: - restore_cache: keys: - - v3-brew + - v2-brew - steps: << parameters.steps >> - save_cache: paths: - /usr/local/Homebrew - ~/Library/Caches/Homebrew - key: v3-brew + key: v2-brew - with_rntester_pods_cache_span: + with_pods_cache_span: parameters: steps: type: steps @@ -182,33 +158,24 @@ commands: name: Download Dependencies Using Buck command: ./scripts/circleci/buck_fetch.sh - run_e2e: - parameters: - platform: - description: Target platform - type: enum - enum: ["android", "ios", "js"] - default: "js" - retries: - description: How many times the job should try to run these tests - type: integer - default: 3 + # ------------------------- + # COMMANDS: Disabled Tests + # ------------------------- + run_podspec_tests: steps: - run: - name: "Run Tests: << parameters.platform >> End-to-End Tests" - command: node ./scripts/run-ci-e2e-tests.js --<< parameters.platform >> --retries << parameters.retries >> - - report_bundle_size: - parameters: - platform: - description: Target platform - type: enum - enum: ["android", "ios"] + name: Test CocoaPods + command: ./scripts/process-podspecs.sh + run_e2e_tests: steps: - - install_github_bot_deps - run: - name: Report size of RNTester.app (analysis-bot) - command: GITHUB_TOKEN="$PUBLIC_ANALYSISBOT_GITHUB_TOKEN_A""$PUBLIC_ANALYSISBOT_GITHUB_TOKEN_B" scripts/circleci/report-bundle-size.sh << parameters.platform >> + name: Full End-to-End Test Suite + command: node ./scripts/run-ci-e2e-tests.js --android --ios --js --retries 3; + run_android_e2e_tests: + steps: + - run: + name: Android End-to-End Test Suite + command: node ./scripts/run-ci-e2e-tests.js --android --retries 3; # ------------------------- # JOBS @@ -218,7 +185,7 @@ jobs: parameters: executor: type: executor - default: nodelts + default: node8 checkout_type: type: string default: node @@ -238,16 +205,23 @@ jobs: # This workflow should only fail if the bots fail to run. analyze_pr: executor: nodelts + # The public github tokens are publicly visible by design + environment: + - PUBLIC_PULLBOT_GITHUB_TOKEN_A: "a6edf8e8d40ce4e8b11a" + - PUBLIC_PULLBOT_GITHUB_TOKEN_B: "150e1341f4dd9c944d2a" + - PUBLIC_ANALYSISBOT_GITHUB_TOKEN_A: "78a72af35445ca3f8180" + - PUBLIC_ANALYSISBOT_GITHUB_TOKEN_B: "b1a98e0bbd56ff1ccba1" + steps: - restore_cache_checkout: checkout_type: node - run_yarn - - install_github_bot_deps - - run: - name: Install additional GitHub bot dependencies - command: sudo apt update && sudo apt install -y shellcheck jq + name: Install dependencies + command: | + sudo apt update && sudo apt install -y shellcheck jq + cd bots && yarn install --non-interactive --cache-folder ~/.cache/yarn - run: name: Run linters against modified files (analysis-bot) @@ -265,7 +239,7 @@ jobs: # JOBS: Analyze Code # ------------------------- analyze_code: - executor: nodelts + executor: node8 steps: - restore_cache_checkout: checkout_type: node @@ -274,7 +248,7 @@ jobs: - run: name: Lint code - command: scripts/circleci/exec_swallow_error.sh yarn lint --format junit -o ./reports/junit/eslint/results.xml + command: scripts/circleci/exec_swallow_error.sh yarn lint --format junit -o ~/reports/junit/eslint/results.xml when: always - run: @@ -300,70 +274,42 @@ jobs: when: always - store_test_results: - path: ./reports/junit + path: ~/reports/junit # ------------------------- # JOBS: Test JavaScript # ------------------------- + # Runs JavaScript tests test_js: parameters: executor: type: executor - default: nodelts - run_disabled_tests: - type: boolean - default: false + default: node8 executor: << parameters.executor >> steps: - restore_cache_checkout: checkout_type: node - setup_artifacts - run_yarn - - run: - name: Install rsync - command: sudo apt-get install rsync - # ------------------------- - # Run JavaScript tests - run: - name: "Run Tests: JavaScript Tests" + name: JavaScript Test Suite command: node ./scripts/run-ci-javascript-tests.js --maxWorkers 2 - - run_e2e: - platform: js - - # Optionally, run disabled tests - - when: - condition: << parameters.run_disabled_tests >> - steps: - - run: echo "Failing tests may be moved here temporarily." - # ------------------------- - store_test_results: - path: ./reports/junit - + path: ~/reports/junit # ------------------------- # JOBS: Test iOS # ------------------------- + # Runs unit tests on iOS devices test_ios: executor: reactnativeios parameters: use_frameworks: type: boolean default: false - run_unit_tests: - description: Specifies whether unit tests should run. - type: boolean - default: false - run_detox_tests: - description: Specifies whether Detox e2e tests should run. - type: boolean - default: false - run_disabled_tests: - description: Specifies whether disabled tests should run. Set this to true to debug failing tests. - type: boolean - default: false environment: - - REPORTS_DIR: "./reports/junit" + - REPORTS_DIR: "./reports" steps: - restore_cache_checkout: checkout_type: ios @@ -378,26 +324,9 @@ jobs: command: source scripts/.tests.env && xcrun simctl boot "$IOS_DEVICE" || true - run: - name: Configure Environment Variables + name: Fetch CocoaPods Specs command: | - echo 'export PATH=/usr/local/opt/node@10/bin:$PATH' >> $BASH_ENV - source $BASH_ENV - - - with_brew_cache_span: - steps: - - brew_install: - package: watchman - - brew_install: - package: node@10 - - run: - name: "Brew: Tap wix/brew" - command: HOMEBREW_NO_AUTO_UPDATE=1 brew tap wix/brew >/dev/null - - brew_install: - package: applesimutils - - - run: - name: Configure Watchman - command: touch .watchmanconfig + curl https://cocoapods-specs.circleci.com/fetch-cocoapods-repo-from-s3.sh | bash -s cf - when: condition: << parameters.use_frameworks >> @@ -406,74 +335,107 @@ jobs: name: Set USE_FRAMEWORKS=1 command: echo "export USE_FRAMEWORKS=1" >> $BASH_ENV - - run: - name: Fetch CocoaPods Specs - command: | - curl https://cocoapods-specs.circleci.com/fetch-cocoapods-repo-from-s3.sh | bash -s cf - - run: - name: Setup the CocoaPods environment - command: pod setup - - - with_rntester_pods_cache_span: + - with_pods_cache_span: steps: - run: name: Generate RNTesterPods Workspace command: cd RNTester && pod install --verbose + - with_brew_cache_span: + steps: + - brew_install: + package: watchman + - run: touch .watchmanconfig + + - run: yarn test-ios + - store_test_results: + path: ~/reports/junit + + # Runs iOS end-to-end tests + test_ios_e2e: + executor: reactnativeios + steps: + - restore_cache_checkout: + checkout_type: ios + - setup_artifacts + - run_yarn + - run: - name: Generate RNTesterPods Xcode Workspace - command: pushd RNTester && pod install --verbose && popd + name: Boot iPhone Simulator + command: source scripts/.tests.env && xcrun simctl boot "$IOS_DEVICE" || true - # ------------------------- - # Runs iOS unit tests - - when: - condition: << parameters.run_unit_tests >> - steps: - - run: - name: "Run Tests: iOS Unit and Integration Tests" - command: yarn test-ios - # Runs iOS Detox e2e tests - - when: - condition: << parameters.run_detox_tests >> - steps: - - run: - name: "Run Tests: Detox iOS End-to-End Tests" - command: yarn run build-ios-e2e && yarn run test-ios-e2e + - run: + name: Configure Environment Variables + command: | + echo 'export PATH=/usr/local/opt/node@8/bin:$PATH' >> $BASH_ENV + source $BASH_ENV - # Optionally, run disabled tests - - when: - condition: << parameters.run_disabled_tests >> + # Brew + - with_brew_cache_span: steps: - - run: echo "Failing tests may be moved here temporarily." - - run: - name: "Run Tests: CocoaPods" - command: ./scripts/process-podspecs.sh - - run: - name: Free up port 8081 for iOS End-to-End Tests - command: | - # free up port 8081 for the packager before running tests - set +eo pipefail - lsof -i tcp:8081 | awk 'NR!=1 {print $2}' | xargs kill - set -eo pipefail - - run_e2e: - platform: ios - # ------------------------- + - brew_install: + package: node@8 + - run: HOMEBREW_NO_AUTO_UPDATE=1 brew tap wix/brew >/dev/null + - brew_install: + package: applesimutils + - brew_install: + package: watchman + # Configure Watchman + - run: touch .watchmanconfig + + - restore_cache: + keys: + - v1-cocoapods-{{ checksum "template/ios/Podfile" }} + - v1-cocoapods- + + - run: pod setup + + - run: + name: Generate RNTesterPods Workspace + command: pushd RNTester && pod install --verbose && popd + + - run: + name: Run Detox iOS End-to-End Tests + command: yarn run build-ios-e2e && yarn run test-ios-e2e + when: always + + - run: + name: Run iOS End-to-End Tests + command: | + # free up port 8081 for the packager before running tests + set +eo pipefail + lsof -i tcp:8081 | awk 'NR!=1 {print $2}' | xargs kill + set -eo pipefail + node ./scripts/run-ci-e2e-tests.js --ios --retries 3; + when: always + + - save_cache: + paths: + - ~/.cocoapods/repos + key: v1-cocoapods-{{ checksum "template/ios/Podfile" }} + + test_js_e2e: + executor: node8 + steps: + - restore_cache_checkout: + checkout_type: node + - setup_artifacts + - run_yarn + - run: sudo apt-get install rsync + + - run: + name: Run JavaScript End-to-End Tests + command: node ./scripts/run-ci-e2e-tests.js --js --retries 3 - # Collect Results - - report_bundle_size: - platform: ios - store_test_results: - path: ./reports/junit + path: ~/reports/junit # ------------------------- # JOBS: Test Android # ------------------------- + # Run Android tests test_android: executor: reactnativeandroid - parameters: - run_disabled_tests: - type: boolean - default: false steps: - restore_cache_checkout: checkout_type: android @@ -496,10 +458,6 @@ jobs: # Keep configuring Android dependencies while AVD boots up - - run: - name: Install rsync - command: apt-get update -y && apt-get install rsync -y - # Install Buck - install_buck_tooling @@ -532,48 +490,37 @@ jobs: name: Wait for Android Virtual Device command: source scripts/android-setup.sh && waitForAVD + # Test Suite - run: - name: Assemble RNTester App - command: ./gradlew RNTester:android:app:assembleRelease + name: Run Unit Tests + command: buck test ReactAndroid/src/test/... --config build.threads=$BUILD_THREADS --xml ~/reports/buck/all-results-raw.xml - # ------------------------- - # Run Android tests - - run: - name: "Run Tests: Android Unit Tests" - command: buck test ReactAndroid/src/test/... --config build.threads=$BUILD_THREADS --xml ./reports/buck/all-results-raw.xml - run: - name: "Run Tests: Android Instrumentation Tests" + name: Run Instrumentation Tests command: | if [[ ! -e ReactAndroid/src/androidTest/assets/AndroidTestBundle.js ]]; then echo "JavaScript bundle missing, cannot run instrumentation tests. Verify Build JavaScript Bundle step completed successfully."; exit 1; fi source scripts/android-setup.sh && NO_BUCKD=1 retry3 timeout 300 buck install ReactAndroid/src/androidTest/buck-runner:instrumentation-tests --config build.threads=$BUILD_THREADS - # Optionally, run disabled tests - - when: - condition: << parameters.run_disabled_tests >> - steps: - - run: echo "Failing tests may be moved here temporarily." - - run_e2e: - platform: android - # ------------------------- + - run: + name: Build Android RNTester App + command: ./gradlew RNTester:android:app:assembleRelease # Collect Results - - report_bundle_size: - platform: android - run: name: Collect Test Results command: | - find . -type f -regex ".*/build/test-results/debug/.*xml" -exec cp {} ./reports/build/ \; - find . -type f -regex ".*/outputs/androidTest-results/connected/.*xml" -exec cp {} ./reports/outputs/ \; - find . -type f -regex ".*/buck-out/gen/ReactAndroid/src/test/.*/.*xml" -exec cp {} ./reports/buck/ \; + find . -type f -regex ".*/build/test-results/debug/.*xml" -exec cp {} ~/reports/build/ \; + find . -type f -regex ".*/outputs/androidTest-results/connected/.*xml" -exec cp {} ~/reports/outputs/ \; + find . -type f -regex ".*/buck-out/gen/ReactAndroid/src/test/.*/.*xml" -exec cp {} ~/reports/buck/ \; if [ -f ~/react-native/reports/buck/all-results-raw.xml ]; then - cd ~/okbuck - ./tooling/junit/buck_to_junit.sh ~/react-native/reports/buck/all-results-raw.xml ~/react-native/reports/junit/results.xml + ./tooling/junit/buck_to_junit.sh ~/react-native/reports/buck/all-results-raw.xml ~/react-native/reports/junit/all-results-junit.xml fi when: always + - store_test_results: - path: ./reports/junit + path: ~/reports/junit # ------------------------- # JOBS: Test Docker @@ -592,89 +539,12 @@ jobs: yarn run docker-setup-android yarn run docker-build-android - # ------------------------- - # JOBS: Windows - # ------------------------- - test_windows: - executor: - name: win/default - parameters: - run_disabled_tests: - type: boolean - default: false - environment: - - ANDROID_HOME: "C:\\Android\\android-sdk" - - ANDROID_NDK: "C:\\Android\\android-sdk\\ndk\\19.2.5345600" - - ANDROID_BUILD_VERSION: 28 - - ANDROID_TOOLS_VERSION: 29.0.2 - - GRADLE_OPTS: -Dorg.gradle.daemon=false - - NDK_VERSION: 19.2.5345600 - steps: - - checkout - - # Setup Dependencies - - run: - name: Install Yarn - command: choco install yarn - - - run: - name: Display Environment info - command: npx envinfo@latest - - - restore_cache: - keys: - - v1-win-yarn-cache-{{ arch }}-{{ checksum "yarn.lock" }} - - v1-win-yarn-cache-{{ arch }}- - - run: - name: "Yarn: Install Dependencies" - command: yarn install --frozen-lockfile --non-interactive - - save_cache: - key: v1-win-yarn-cache-{{ arch }}-{{ checksum "yarn.lock" }} - paths: - - C:\Users\circleci\AppData\Local\Yarn - - - run: - name: Install Android SDK Tools - command: choco install android-sdk - - - run: - name: Setup Android SDKs - command: | - sdkmanager --licenses - sdkmanager "system-images;android-19;google_apis;armeabi-v7a" - sdkmanager "platforms;android-%ANDROID_BUILD_VERSION%" - sdkmanager "build-tools;%ANDROID_TOOLS_VERSION%" - sdkmanager "add-ons;addon-google_apis-google-23" - sdkmanager "extras;android;m2repository" - sdkmanager "ndk;%NDK_VERSION%" - - # ------------------------- - # Run Tests - - run: - name: "Flow: Check Android" - command: yarn flow-check-android - - run: - name: "Flow: Check iOS" - command: yarn flow-check-ios - - run: - name: "Run Tests: JavaScript Tests" - command: yarn test - - # Optionally, run disabled tests - - when: - condition: << parameters.run_disabled_tests >> - steps: - - run: echo "Failing tests may be moved here temporarily." - - run: - name: Android Build - command: ./gradlew.bat RNTester:android:app:assembleRelease - # ------------------------- # JOBS: Coverage # ------------------------- # Collect JavaScript test coverage js_coverage: - executor: nodelts + executor: node8 environment: - CI_BRANCH: $CIRCLE_BRANCH - CI_PULL_REQUEST: $CIRCLE_PULL_REQUEST @@ -686,12 +556,11 @@ jobs: - setup_artifacts - run_yarn - run: - name: Collect test coverage information + name: Test coverage command: | - scripts/circleci/exec_swallow_error.sh yarn test --coverage --maxWorkers=2 - if [[ -e ./coverage/lcov.info ]]; then - cat ./coverage/lcov.info | scripts/circleci/exec_swallow_error.sh ./node_modules/.bin/coveralls - fi + yarn test --coverage --maxWorkers=2 + cat ./coverage/lcov.info | ./node_modules/.bin/coveralls + when: always - store_artifacts: path: ~/react-native/coverage/ @@ -700,10 +569,6 @@ jobs: # ------------------------- # Publishes a new version onto npm publish_npm_package: - parameters: - publish_npm_args: - type: string - default: --nonightly executor: reactnativeandroid steps: - run: @@ -722,25 +587,12 @@ jobs: git config --global user.email "react-native-bot@users.noreply.github.com" git config --global user.name "npm Deployment Script" echo "machine github.com login react-native-bot password $GITHUB_TOKEN" > ~/.netrc - - run: node ./scripts/publish-npm.js << parameters.publish_npm_args >> - - # ------------------------- - # JOBS: Nightly - # ------------------------- - nightly_job: - machine: true - steps: - - run: - name: Nightly - command: | - echo "Nightly build run" + - run: node ./scripts/publish-npm.js # ------------------------- # WORK FLOWS # ------------------------- workflows: - version: 2 - tests: jobs: - setup: @@ -764,40 +616,35 @@ workflows: # TODO(macOS ISS#2323203): disable this test which is redundant to Azure Devops test and it requires a CCI plan with resource-class:large. ignore: /.*/ - test_js: - run_disabled_tests: false requires: - setup_js + - test_js_e2e: + requires: + - setup_js + - test_js + # [TODO(macOS ISS#2323203): disable this test which is redundant to Azure Devops test and it fails in the fork because it tries to 'npm install' the template. + filters: + branches: + ignore: /.*/ + # ]TODO(macOS ISS#2323203) - test_android: - run_disabled_tests: false requires: - setup_android - test_ios: - name: test_ios_unit - run_disabled_tests: false - run_unit_tests: true requires: - setup_ios - test_ios: - name: test_ios_unit_frameworks + name: test_ios_frameworks use_frameworks: true - run_unit_tests: true requires: - setup_ios - - test_ios: - name: test_ios_detox - run_disabled_tests: false - run_detox_tests: true - requires: - - setup_ios - - test_ios: - name: test_ios_detox_frameworks - use_frameworks: true - run_detox_tests: true + - test_ios_e2e: requires: - setup_ios + - test_js - test_js: - name: test_js_prev_lts - executor: nodeprevlts + name: test_js_lts + executor: nodelts requires: - setup_js - test_docker: @@ -805,12 +652,6 @@ workflows: branches: # TODO(macOS ISS#2323203): disable this test which is redundant to Azure Devops test and in the fork it fails because of Microsoft's V8 upgrade to Android ignore: /.*/ - - test_windows: - filters: - branches: - ignore: gh-pages - run_disabled_tests: false - releases: jobs: - setup: @@ -866,26 +707,3 @@ workflows: branches: ignore: /.*/ # ]TODO(macOS ISS#2323203) - nightly: - triggers: - - schedule: - cron: "0 0 * * *" - filters: - branches: - # [TODO(macOS ISS#2323203): disable this release. We never want to release anything from this fork via CCI. - ignore: /.*/ - # only: - # - master - # ]TODO(macOS ISS#2323203) - jobs: - - nightly_job - - - setup: - name: setup_android - checkout_type: android - executor: reactnativeandroid - - - publish_npm_package: - publish_npm_args: --nightly - requires: - - setup_android diff --git a/.eslintignore b/.eslintignore index 479b10a7655330..f485f90b89c3ca 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,16 +1,14 @@ # node_modules ignored by default -**/main.js **/staticBundle.js -bots/node_modules -docs/generatedComponentApiDocs.js -flow/ -Libraries/Renderer/* +**/main.js Libraries/vendor/**/* +Libraries/Renderer/* packages/*/node_modules packages/*/lib packages/*/lib-commonjs pr-inactivity-bookmarklet.js question-bookmarklet.js +flow/ bots/node_modules android-patches/ diff --git a/.eslintrc b/.eslintrc index 7795e95b40cd3c..9385a7481c3ce6 100644 --- a/.eslintrc +++ b/.eslintrc @@ -13,7 +13,6 @@ rules: { '@react-native-community/no-haste-imports': 2, '@react-native-community/error-subclass-name': 2, - '@react-native-community/platform-colors': 2, } }, { diff --git a/.flowconfig b/.flowconfig index 87fd42b63f3ac5..6c780e7543d1cd 100644 --- a/.flowconfig +++ b/.flowconfig @@ -75,10 +75,10 @@ untyped-type-import=warn nonstrict-import=warn deprecated-type=warn unsafe-getters-setters=warn +inexact-spread=warn unnecessary-invariant=warn signature-verification-failure=warn deprecated-utility=error -unsafe-addition=error [strict] deprecated-type @@ -90,4 +90,4 @@ untyped-import untyped-type-import [version] -^0.122.0 +^0.113.0 diff --git a/.flowconfig.android b/.flowconfig.android index 25c6ad92d010e2..f0aadb57289f21 100644 --- a/.flowconfig.android +++ b/.flowconfig.android @@ -78,10 +78,10 @@ untyped-type-import=warn nonstrict-import=warn deprecated-type=warn unsafe-getters-setters=warn +inexact-spread=warn unnecessary-invariant=warn signature-verification-failure=warn deprecated-utility=error -unsafe-addition=error [strict] deprecated-type @@ -93,4 +93,4 @@ untyped-import untyped-type-import [version] -^0.122.0 +^0.113.0 diff --git a/.flowconfig.macos b/.flowconfig.macos index 228c57f1770316..c13da62f1bad21 100644 --- a/.flowconfig.macos +++ b/.flowconfig.macos @@ -75,6 +75,7 @@ untyped-type-import=warn nonstrict-import=warn deprecated-type=warn unsafe-getters-setters=warn +inexact-spread=warn unnecessary-invariant=warn signature-verification-failure=warn deprecated-utility=error @@ -89,4 +90,4 @@ untyped-import untyped-type-import [version] -^0.122.0 +^0.113.0 diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index d16bc898be18a2..b18fb13e017294 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,3 +1,2 @@ ** @acoates-ms ** @tom-un -** @alloy diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 015f815215f18b..44f933bfbf8528 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1 +1,3 @@ GitHub Issues in the `microsoft/react-native-macos` repository are used exclusively for tracking bugs in the Microsoft/React Native for macOS fork. If the issue concerns Facebook's react-native, submit the issue to `facebook/react-native`. + +Note: to keep the backlog clean and actionable, issues may be immediately closed if they do not follow one of the above issue templates. diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml deleted file mode 100644 index 7821e038ec89ee..00000000000000 --- a/.github/ISSUE_TEMPLATE/config.yml +++ /dev/null @@ -1,14 +0,0 @@ -blank_issues_enabled: false -contact_links: - - name: 📃 Documentation Issue - url: https://github.com/facebook/react-native-website/issues - about: Please report documentation issues in the React Native website repository. - - name: ⤴️ Upgrade Issue - url: https://github.com/react-native-community/upgrade-support - about: Need help upgrading to a newer React Native version? Visit the Upgrade Support repository. - - name: 🤔 Questions and Help - url: https://reactnative.dev/help - about: Looking for help with your app? Please refer to the React Native community's support resources. - - name: 🚀 Discussions and Proposals - url: https://github.com/react-native-community/discussions-and-proposals - about: Discuss the future of React Native in the React Native community's discussions and proposals repository. diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md new file mode 100644 index 00000000000000..e82b973392fa06 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/question.md @@ -0,0 +1,9 @@ +--- +name: Question +about: I have a question +title: "'Question: [your question here]'" +labels: question +assignees: '' + +--- + diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index f34e5777e55052..dab90d600d4308 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -23,9 +23,7 @@ If you are making a new change then one of the following should be done: ## Changelog - + [CATEGORY] [TYPE] - Message diff --git a/.github/SUPPORT.md b/.github/SUPPORT.md index 4e313c997e3094..d229644aa40f9d 100644 --- a/.github/SUPPORT.md +++ b/.github/SUPPORT.md @@ -32,4 +32,4 @@ If you want to participate in casual discussions about the use of React Native, - [React Native Community Facebook Group](https://www.facebook.com/groups/react.native.community) -> For a full list of community resources, check out [React Native's Community page](https://reactnative.dev/help). +> For a full list of community resources, check out [React Native's Community page](https://facebook.github.io/react-native/help). diff --git a/.github/label-actions.yml b/.github/label-actions.yml deleted file mode 100644 index e0636f4c614438..00000000000000 --- a/.github/label-actions.yml +++ /dev/null @@ -1,52 +0,0 @@ -# Configuration for Label Actions - https://github.com/marketplace/actions/label-actions - -"Type: Invalid": - close: true -"Type: Question": - comment: > - We are using GitHub issues exclusively to track bugs in React Native. GitHub may not be the ideal place to ask a question, but you can try asking over on [Stack Overflow](http://stackoverflow.com/questions/tagged/react-native), or on [Reactiflux](https://www.reactiflux.com/). - close: true -"Type: Docs": - comment: > - Please report documentation issues in the [`react-native-website`](https://github.com/facebook/react-native-website/issues) repository. - close: true -"Resolution: For Stack Overflow": - comment: > - We are using GitHub issues exclusively to track bugs in the core React Native library. Please try asking over on [Stack Overflow](http://stackoverflow.com/questions/tagged/react-native) as it is better suited for this type of question. - close: true -"Needs: Issue Template": - comment: > -
:warning: - Missing Required Fields -
:information_source: - It looks like your issue may be missing some necessary information. GitHub provides an example template whenever a new issue is created. Could you go back and make sure to fill out the template? You may edit this issue, or close it and open a new one. -
- labels: - - "Needs: Author Feedback" -"Needs: Environment Info": - comment: > -
:warning: - Missing Environment Information -
:information_source: - Your issue may be missing information about your development environment. You can obtain the missing information by running react-native info in a console. -
- labels: - - "Needs: Author Feedback" -"Needs: Verify on Latest Version": - comment: > -
:warning: - Using Old Version -
:information_source: - It looks like you are using an older version of React Native. Please upgrade to the latest version, and verify if the issue persists. If it does not, please let us know so we can close out this issue. This helps us ensure we are looking at issues that still exist in the current release. -
- labels: - - "Needs: Author Feedback" -"Needs: Repro": - comment: > -
:warning: - Missing Reproducible Example -
:information_source: - It looks like your issue is missing a reproducible example. Please provide a Snack or a repository that demonstrates the issue you are reporting in a minimal, complete, and reproducible manner. -
- labels: - - "Needs: Author Feedback" diff --git a/.github/workflows/needs-attention.yml b/.github/workflows/needs-attention.yml deleted file mode 100644 index e5c1a979653171..00000000000000 --- a/.github/workflows/needs-attention.yml +++ /dev/null @@ -1,21 +0,0 @@ -name: Issue Needs Attention -# This workflow is triggered on issue comments. -on: - issue_comment: - types: created - -jobs: - applyNeedsAttentionLabel: - name: Apply Needs Attention Label - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Apply Needs Attention Label - uses: hramos/needs-attention@v1 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - response-required-label: "Needs: Author Feedback" - needs-attention-label: "Needs: Attention" - id: needs-attention - - name: Result - run: echo '${{ steps.needs-attention.outputs.result }}' diff --git a/.github/workflows/process-label-actions.yml b/.github/workflows/process-label-actions.yml deleted file mode 100644 index 2c63100f6e8392..00000000000000 --- a/.github/workflows/process-label-actions.yml +++ /dev/null @@ -1,16 +0,0 @@ -name: Label Actions -# This workflow is triggered when a label is added to an issue. -on: - issues: - types: labeled - -jobs: - processLabelAction: - name: Process Label Action - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Process Label Action - uses: hramos/label-actions@v1 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index b316422451ca77..90688e0daa381d 100644 --- a/.gitignore +++ b/.gitignore @@ -31,16 +31,14 @@ project.xcworkspace/* /RNTester/android/app/gradlew /RNTester/android/app/gradlew.bat /ReactAndroid/build/ -/ReactAndroid/gradle/ -/ReactAndroid/gradlew -/ReactAndroid/gradlew.bat /build_deps/ /ReactAndroid/packages/ # Buck .buckd buck-out -/ReactAndroid/src/main/jni/prebuilt/lib/ +/ReactAndroid/src/main/jni/prebuilt/lib/armeabi-v7a/ +/ReactAndroid/src/main/jni/prebuilt/lib/x86/ /ReactAndroid/src/main/gen # Android Studio diff --git a/IntegrationTests/IntegrationTestsApp.js b/IntegrationTests/IntegrationTestsApp.js index 1e52877b7b9908..c52fe515221ede 100644 --- a/IntegrationTests/IntegrationTestsApp.js +++ b/IntegrationTests/IntegrationTestsApp.js @@ -79,9 +79,6 @@ class IntegrationTestsApp extends React.Component<{...}, $FlowFixMeState> { {TESTS.map(test => [ this.setState({test})} - /* $FlowFixMe(>=0.115.0 site=react_native_fb) This comment - * suppresses an error found when Flow v0.115 was deployed. To - * see the error, delete this comment and run Flow. */ style={styles.row}> {test.displayName} , diff --git a/Libraries/ART/ARTSurfaceView.m b/Libraries/ART/ARTSurfaceView.m index 2e557b948103fa..93a9efee9fd04f 100644 --- a/Libraries/ART/ARTSurfaceView.m +++ b/Libraries/ART/ARTSurfaceView.m @@ -47,7 +47,9 @@ - (void)invalidate - (void)drawRect:(CGRect)rect { +// [TODO(OSS Candidate ISS#2710739): for macOS and iOS dark mode [super drawRect:rect]; +// ]TODO(OSS Candidate ISS#2710739) CGContextRef context = UIGraphicsGetCurrentContext(); for (ARTNode *node in self.subviews) { [node renderTo:context]; diff --git a/Libraries/ART/React-ART.podspec b/Libraries/ART/React-ART.podspec index e04351c9dca68a..23794a425375da 100644 --- a/Libraries/ART/React-ART.podspec +++ b/Libraries/ART/React-ART.podspec @@ -20,10 +20,10 @@ Pod::Spec.new do |s| s.name = "React-ART" s.version = version s.summary = "A library for drawing vector graphics." - s.homepage = "https://reactnative.dev/" + s.homepage = "http://facebook.github.io/react-native/" s.license = package["license"] s.author = "Facebook, Inc. and its affiliates" - s.platforms = { :ios => "10.0", :tvos => "10.0", :osx => "10.13" } # TODO(macOS GH#214) + s.platforms = { :ios => "9.0", :tvos => "9.2", :osx => "10.13" } # TODO(macOS GH#214) s.source = source s.source_files = "**/*.{m}" s.preserve_paths = "package.json", "LICENSE", "LICENSE-docs" diff --git a/Libraries/ActionSheetIOS/ActionSheetIOS.js b/Libraries/ActionSheetIOS/ActionSheetIOS.js index e330253df81b08..accb7e1abdb07c 100644 --- a/Libraries/ActionSheetIOS/ActionSheetIOS.js +++ b/Libraries/ActionSheetIOS/ActionSheetIOS.js @@ -14,13 +14,12 @@ import RCTActionSheetManager from './NativeActionSheetManager'; const invariant = require('invariant'); const processColor = require('../StyleSheet/processColor'); -import type {ColorValue} from '../StyleSheet/StyleSheetTypes'; -import type {ProcessedColorValue} from '../StyleSheet/processColor'; +import type {NativeOrDynamicColorType} from '../StyleSheet/NativeOrDynamicColorType'; // TODO(macOS ISS#2323203) /** * Display action sheets and share sheets on iOS. * - * See https://reactnative.dev/docs/actionsheetios.html + * See http://facebook.github.io/react-native/docs/actionsheetios.html */ const ActionSheetIOS = { /** @@ -37,7 +36,7 @@ const ActionSheetIOS = { * The 'callback' function takes one parameter, the zero-based index * of the selected item. * - * See https://reactnative.dev/docs/actionsheetios.html#showactionsheetwithoptions + * See http://facebook.github.io/react-native/docs/actionsheetios.html#showactionsheetwithoptions */ showActionSheetWithOptions( options: {| @@ -47,8 +46,7 @@ const ActionSheetIOS = { +destructiveButtonIndex?: ?number | ?Array, +cancelButtonIndex?: ?number, +anchor?: ?number, - +tintColor?: ColorValue | ProcessedColorValue, - +userInterfaceStyle?: string, + +tintColor?: number | string | NativeOrDynamicColorType, // TODO(macOS ISS#2323203) |}, callback: (buttonIndex: number) => void, ) { @@ -68,15 +66,10 @@ const ActionSheetIOS = { destructiveButtonIndices = [destructiveButtonIndex]; } - const processedTintColor = processColor(tintColor); - invariant( - processedTintColor == null || typeof processedTintColor === 'number', - 'Unexpected color given for ActionSheetIOS.showActionSheetWithOptions tintColor', - ); RCTActionSheetManager.showActionSheetWithOptions( { ...remainingOptions, - tintColor: processedTintColor, + tintColor: processColor(tintColor), destructiveButtonIndices, }, callback, @@ -104,7 +97,7 @@ const ActionSheetIOS = { * - a boolean value signifying success or failure * - a string that, in the case of success, indicates the method of sharing * - * See https://reactnative.dev/docs/actionsheetios.html#showshareactionsheetwithoptions + * See http://facebook.github.io/react-native/docs/actionsheetios.html#showshareactionsheetwithoptions */ showShareActionSheetWithOptions( options: Object, diff --git a/Libraries/ActionSheetIOS/NativeActionSheetManager.js b/Libraries/ActionSheetIOS/NativeActionSheetManager.js index be3b8c3afffdbe..f96fc7ec63aef7 100644 --- a/Libraries/ActionSheetIOS/NativeActionSheetManager.js +++ b/Libraries/ActionSheetIOS/NativeActionSheetManager.js @@ -12,7 +12,7 @@ import type {TurboModule} from '../TurboModule/RCTExport'; import * as TurboModuleRegistry from '../TurboModule/TurboModuleRegistry'; -import type {ProcessedColorValue} from '../StyleSheet/processColor'; // TODO(macOS ISS#2323203) +import type {NativeOrDynamicColorType} from '../StyleSheet/NativeOrDynamicColorType'; // TODO(macOS ISS#2323203) export interface Spec extends TurboModule { +getConstants: () => {||}; @@ -24,8 +24,7 @@ export interface Spec extends TurboModule { +destructiveButtonIndices?: ?Array, +cancelButtonIndex?: ?number, +anchor?: ?number, - +tintColor?: ?ProcessedColorValue, // TODO(macOS ISS#2323203) - +userInterfaceStyle?: ?string, + +tintColor?: ?(number | NativeOrDynamicColorType), // TODO(macOS ISS#2323203) |}, callback: (buttonIndex: number) => void, ) => void; @@ -35,9 +34,8 @@ export interface Spec extends TurboModule { +url?: ?string, +subject?: ?string, +anchor?: ?number, - +tintColor?: ?ProcessedColorValue, // TODO(macOS ISS#2323203) + +tintColor?: ?(number | NativeOrDynamicColorType), // TODO(macOS ISS#2323203) +excludedActivityTypes?: ?Array, - +userInterfaceStyle?: ?string, |}, failureCallback: (error: {| +domain: string, diff --git a/Libraries/ActionSheetIOS/React-RCTActionSheet.podspec b/Libraries/ActionSheetIOS/React-RCTActionSheet.podspec index 1ba2b9c8d4d284..9574165e410882 100644 --- a/Libraries/ActionSheetIOS/React-RCTActionSheet.podspec +++ b/Libraries/ActionSheetIOS/React-RCTActionSheet.podspec @@ -20,11 +20,11 @@ Pod::Spec.new do |s| s.name = "React-RCTActionSheet" s.version = version s.summary = "An API for displaying iOS action sheets and share sheets." - s.homepage = "https://reactnative.dev/" - s.documentation_url = "https://reactnative.dev/docs/actionsheetios" + s.homepage = "http://facebook.github.io/react-native/" + s.documentation_url = "https://facebook.github.io/react-native/docs/actionsheetios" s.license = package["license"] s.author = "Facebook, Inc. and its affiliates" - s.platforms = { :ios => "10.0", :tvos => "10.0", :osx => "10.13" } # TODO(macOS GH#214) + s.platforms = { :ios => "9.0", :tvos => "9.2", :osx => "10.13" } # TODO(macOS GH#214) s.source = source s.source_files = "*.{m}" s.preserve_paths = "package.json", "LICENSE", "LICENSE-docs" diff --git a/Libraries/Alert/Alert.js b/Libraries/Alert/Alert.js index 613d40c530f215..4f4f75d462b0ca 100644 --- a/Libraries/Alert/Alert.js +++ b/Libraries/Alert/Alert.js @@ -39,7 +39,7 @@ type Options = { /** * Launches an alert dialog with the specified title and message. * - * See https://reactnative.dev/docs/alert.html + * See http://facebook.github.io/react-native/docs/alert.html */ class Alert { static alert( @@ -115,6 +115,28 @@ class Alert { keyboardType?: string, ): void { if (Platform.OS === 'ios') { + if (typeof type === 'function') { + console.warn( + 'You passed a callback function as the "type" argument to Alert.prompt(). React Native is ' + + 'assuming you want to use the deprecated Alert.prompt(title, defaultValue, buttons, callback) ' + + 'signature. The current signature is Alert.prompt(title, message, callbackOrButtons, type, defaultValue, ' + + 'keyboardType) and the old syntax will be removed in a future version.', + ); + + const callback = type; + RCTAlertManager.alertWithArgs( + { + title: title || '', + type: 'plain-text', + defaultValue: message || '', + }, + (id, value) => { + callback(value); + }, + ); + return; + } + let callbacks = []; const buttons = []; let cancelButtonKey; diff --git a/Libraries/Animated/src/Animated.js b/Libraries/Animated/src/Animated.js index 450fc1c0264f13..a42c0d395ba25c 100644 --- a/Libraries/Animated/src/Animated.js +++ b/Libraries/Animated/src/Animated.js @@ -18,8 +18,7 @@ import type {AnimatedComponentType} from './createAnimatedComponent'; const AnimatedMock = require('./AnimatedMock'); const AnimatedImplementation = require('./AnimatedImplementation'); -//TODO(T57411659): Remove the bridgeless check when Animated perf regressions are fixed. -const Animated = ((Platform.isTesting || global.RN$Bridgeless +const Animated = ((Platform.isTesting ? AnimatedMock : AnimatedImplementation): typeof AnimatedMock); diff --git a/Libraries/Animated/src/AnimatedEvent.js b/Libraries/Animated/src/AnimatedEvent.js index 91eb29ce413e29..e3c0b814cf8888 100644 --- a/Libraries/Animated/src/AnimatedEvent.js +++ b/Libraries/Animated/src/AnimatedEvent.js @@ -22,13 +22,14 @@ export type Mapping = {[key: string]: Mapping, ...} | AnimatedValue; export type EventConfig = { listener?: ?Function, useNativeDriver: boolean, + ... }; function attachNativeEvent( viewRef: any, eventName: string, - argMapping: $ReadOnlyArray, -): {detach: () => void} { + argMapping: Array, +): {|detach: () => void|} { // Find animated values in `argMapping` and create an array representing their // key path inside the `nativeEvent` object. Ex.: ['contentOffset', 'x']. const eventMappings = []; @@ -57,6 +58,7 @@ function attachNativeEvent( traverse(argMapping[0].nativeEvent, []); const viewTag = ReactNative.findNodeHandle(viewRef); + if (viewTag != null) { eventMappings.forEach(mapping => { NativeAnimatedHelper.API.addAnimatedEventToView( @@ -82,64 +84,19 @@ function attachNativeEvent( }; } -function validateMapping(argMapping, args) { - const validate = (recMapping, recEvt, key) => { - if (recMapping instanceof AnimatedValue) { - invariant( - typeof recEvt === 'number', - 'Bad mapping of event key ' + - key + - ', should be number but got ' + - typeof recEvt, - ); - return; - } - if (typeof recEvt === 'number') { - invariant( - recMapping instanceof AnimatedValue, - 'Bad mapping of type ' + - typeof recMapping + - ' for key ' + - key + - ', event value must map to AnimatedValue', - ); - return; - } - invariant( - typeof recMapping === 'object', - 'Bad mapping of type ' + typeof recMapping + ' for key ' + key, - ); - invariant( - typeof recEvt === 'object', - 'Bad event of type ' + typeof recEvt + ' for key ' + key, - ); - for (const mappingKey in recMapping) { - validate(recMapping[mappingKey], recEvt[mappingKey], mappingKey); - } - }; - - invariant( - args.length >= argMapping.length, - 'Event has less arguments than mapping', - ); - argMapping.forEach((mapping, idx) => { - validate(mapping, args[idx], 'arg' + idx); - }); -} - class AnimatedEvent { - _argMapping: $ReadOnlyArray; + _argMapping: Array; _listeners: Array = []; _callListeners: Function; _attachedEvent: ?{detach: () => void, ...}; __isNative: boolean; - constructor(argMapping: $ReadOnlyArray, config: EventConfig) { + constructor(argMapping: Array, config: EventConfig) { this._argMapping = argMapping; if (config == null) { console.warn('Animated.event now requires a second argument for options'); - config = {useNativeDriver: false}; + config = {}; } if (config.listener) { @@ -148,6 +105,10 @@ class AnimatedEvent { this._callListeners = this._callListeners.bind(this); this._attachedEvent = null; this.__isNative = shouldUseNativeDriver(config); + + if (__DEV__) { + this._validateMapping(); + } } __addListener(callback: Function): void { @@ -182,45 +143,28 @@ class AnimatedEvent { __getHandler(): any | ((...args: any) => void) { if (this.__isNative) { - if (__DEV__) { - let validatedMapping = false; - return (...args: any) => { - if (!validatedMapping) { - validateMapping(this._argMapping, args); - validatedMapping = true; - } - this._callListeners(...args); - }; - } else { - return this._callListeners; - } + return this._callListeners; } - let validatedMapping = false; return (...args: any) => { - if (__DEV__ && !validatedMapping) { - validateMapping(this._argMapping, args); - validatedMapping = true; - } - const traverse = (recMapping, recEvt, key) => { - if (recMapping instanceof AnimatedValue) { - if (typeof recEvt === 'number') { - recMapping.setValue(recEvt); - } + if (typeof recEvt === 'number' && recMapping instanceof AnimatedValue) { + recMapping.setValue(recEvt); } else if (typeof recMapping === 'object') { for (const mappingKey in recMapping) { - /* $FlowFixMe(>=0.120.0) This comment suppresses an error found - * when Flow v0.120 was deployed. To see the error, delete this - * comment and run Flow. */ + /* $FlowFixMe(>=0.53.0 site=react_native_fb,react_native_oss) This + * comment suppresses an error when upgrading Flow's support for + * React. To see the error delete this comment and run Flow. */ traverse(recMapping[mappingKey], recEvt[mappingKey], mappingKey); } } }; - this._argMapping.forEach((mapping, idx) => { - traverse(mapping, args[idx], 'arg' + idx); - }); + if (!this.__isNative) { + this._argMapping.forEach((mapping, idx) => { + traverse(mapping, args[idx], 'arg' + idx); + }); + } this._callListeners(...args); }; } @@ -228,6 +172,33 @@ class AnimatedEvent { _callListeners(...args: any) { this._listeners.forEach(listener => listener(...args)); } + + _validateMapping() { + const traverse = (recMapping, recEvt, key) => { + if (typeof recEvt === 'number') { + invariant( + recMapping instanceof AnimatedValue, + 'Bad mapping of type ' + + typeof recMapping + + ' for key ' + + key + + ', event value must map to AnimatedValue', + ); + return; + } + invariant( + typeof recMapping === 'object', + 'Bad mapping of type ' + typeof recMapping + ' for key ' + key, + ); + invariant( + typeof recEvt === 'object', + 'Bad event of type ' + typeof recEvt + ' for key ' + key, + ); + for (const mappingKey in recMapping) { + traverse(recMapping[mappingKey], recEvt[mappingKey], mappingKey); + } + }; + } } module.exports = {AnimatedEvent, attachNativeEvent}; diff --git a/Libraries/Animated/src/AnimatedImplementation.js b/Libraries/Animated/src/AnimatedImplementation.js index 5045ed398ffa5b..a1ce333acd214e 100644 --- a/Libraries/Animated/src/AnimatedImplementation.js +++ b/Libraries/Animated/src/AnimatedImplementation.js @@ -91,7 +91,7 @@ const diffClamp = function( const _combineCallbacks = function( callback: ?EndCallback, - config: {...AnimationConfig, ...}, + config: AnimationConfig, ) { if (callback && config.onComplete) { return (...args) => { @@ -170,6 +170,9 @@ const spring = function( _startNativeLoop: function(iterations?: number): void { const singleConfig = {...config, iterations}; + /* $FlowFixMe(>=0.111.0 site=react_native_fb) This comment suppresses + * an error found when Flow v0.111 was deployed. To see the error, + * delete this comment and run Flow. */ start(value, singleConfig); }, @@ -224,6 +227,9 @@ const timing = function( _startNativeLoop: function(iterations?: number): void { const singleConfig = {...config, iterations}; + /* $FlowFixMe(>=0.111.0 site=react_native_fb) This comment suppresses + * an error found when Flow v0.111 was deployed. To see the error, + * delete this comment and run Flow. */ start(value, singleConfig); }, @@ -266,6 +272,9 @@ const decay = function( _startNativeLoop: function(iterations?: number): void { const singleConfig = {...config, iterations}; + /* $FlowFixMe(>=0.111.0 site=react_native_fb) This comment suppresses + * an error found when Flow v0.111 was deployed. To see the error, + * delete this comment and run Flow. */ start(value, singleConfig); }, @@ -513,10 +522,7 @@ function unforkEvent( } } -const event = function( - argMapping: $ReadOnlyArray, - config: EventConfig, -): any { +const event = function(argMapping: Array, config: EventConfig): any { const animatedEvent = new AnimatedEvent(argMapping, config); if (animatedEvent.__isNative) { return animatedEvent; @@ -533,33 +539,33 @@ const event = function( * If additional transforms are added, be sure to include them in * AnimatedMock.js as well. * - * See https://reactnative.dev/docs/animated.html + * See http://facebook.github.io/react-native/docs/animated.html */ module.exports = { /** * Standard value class for driving animations. Typically initialized with * `new Animated.Value(0);` * - * See https://reactnative.dev/docs/animated.html#value + * See http://facebook.github.io/react-native/docs/animated.html#value */ Value: AnimatedValue, /** * 2D value class for driving 2D animations, such as pan gestures. * - * See https://reactnative.dev/docs/animatedvaluexy.html + * See https://facebook.github.io/react-native/docs/animatedvaluexy.html */ ValueXY: AnimatedValueXY, /** * Exported to use the Interpolation type in flow. * - * See https://reactnative.dev/docs/animated.html#interpolation + * See http://facebook.github.io/react-native/docs/animated.html#interpolation */ Interpolation: AnimatedInterpolation, /** * Exported for ease of type checking. All animated values derive from this * class. * - * See https://reactnative.dev/docs/animated.html#node + * See http://facebook.github.io/react-native/docs/animated.html#node */ Node: AnimatedNode, @@ -567,21 +573,21 @@ module.exports = { * Animates a value from an initial velocity to zero based on a decay * coefficient. * - * See https://reactnative.dev/docs/animated.html#decay + * See http://facebook.github.io/react-native/docs/animated.html#decay */ decay, /** * Animates a value along a timed easing curve. The Easing module has tons of * predefined curves, or you can use your own function. * - * See https://reactnative.dev/docs/animated.html#timing + * See http://facebook.github.io/react-native/docs/animated.html#timing */ timing, /** * Animates a value according to an analytical spring model based on * damped harmonic oscillation. * - * See https://reactnative.dev/docs/animated.html#spring + * See http://facebook.github.io/react-native/docs/animated.html#spring */ spring, @@ -589,7 +595,7 @@ module.exports = { * Creates a new Animated value composed from two Animated values added * together. * - * See https://reactnative.dev/docs/animated.html#add + * See http://facebook.github.io/react-native/docs/animated.html#add */ add, @@ -597,7 +603,7 @@ module.exports = { * Creates a new Animated value composed by subtracting the second Animated * value from the first Animated value. * - * See https://reactnative.dev/docs/animated.html#subtract + * See http://facebook.github.io/react-native/docs/animated.html#subtract */ subtract, @@ -605,7 +611,7 @@ module.exports = { * Creates a new Animated value composed by dividing the first Animated value * by the second Animated value. * - * See https://reactnative.dev/docs/animated.html#divide + * See http://facebook.github.io/react-native/docs/animated.html#divide */ divide, @@ -613,7 +619,7 @@ module.exports = { * Creates a new Animated value composed from two Animated values multiplied * together. * - * See https://reactnative.dev/docs/animated.html#multiply + * See http://facebook.github.io/react-native/docs/animated.html#multiply */ multiply, @@ -621,7 +627,7 @@ module.exports = { * Creates a new Animated value that is the (non-negative) modulo of the * provided Animated value. * - * See https://reactnative.dev/docs/animated.html#modulo + * See http://facebook.github.io/react-native/docs/animated.html#modulo */ modulo, @@ -630,14 +636,14 @@ module.exports = { * difference between the last value so even if the value is far from the * bounds it will start changing when the value starts getting closer again. * - * See https://reactnative.dev/docs/animated.html#diffclamp + * See http://facebook.github.io/react-native/docs/animated.html#diffclamp */ diffClamp, /** * Starts an animation after the given delay. * - * See https://reactnative.dev/docs/animated.html#delay + * See http://facebook.github.io/react-native/docs/animated.html#delay */ delay, /** @@ -645,7 +651,7 @@ module.exports = { * before starting the next. If the current running animation is stopped, no * following animations will be started. * - * See https://reactnative.dev/docs/animated.html#sequence + * See http://facebook.github.io/react-native/docs/animated.html#sequence */ sequence, /** @@ -653,21 +659,21 @@ module.exports = { * of the animations is stopped, they will all be stopped. You can override * this with the `stopTogether` flag. * - * See https://reactnative.dev/docs/animated.html#parallel + * See http://facebook.github.io/react-native/docs/animated.html#parallel */ parallel, /** * Array of animations may run in parallel (overlap), but are started in * sequence with successive delays. Nice for doing trailing effects. * - * See https://reactnative.dev/docs/animated.html#stagger + * See http://facebook.github.io/react-native/docs/animated.html#stagger */ stagger, /** * Loops a given animation continuously, so that each time it reaches the * end, it resets and begins again from the start. * - * See https://reactnative.dev/docs/animated.html#loop + * See http://facebook.github.io/react-native/docs/animated.html#loop */ loop, @@ -675,14 +681,14 @@ module.exports = { * Takes an array of mappings and extracts values from each arg accordingly, * then calls `setValue` on the mapped outputs. * - * See https://reactnative.dev/docs/animated.html#event + * See http://facebook.github.io/react-native/docs/animated.html#event */ event, /** * Make any React component Animatable. Used to create `Animated.View`, etc. * - * See https://reactnative.dev/docs/animated.html#createanimatedcomponent + * See http://facebook.github.io/react-native/docs/animated.html#createanimatedcomponent */ createAnimatedComponent, @@ -690,7 +696,7 @@ module.exports = { * Imperative API to attach an animated value to an event on a view. Prefer * using `Animated.event` with `useNativeDrive: true` if possible. * - * See https://reactnative.dev/docs/animated.html#attachnativeevent + * See http://facebook.github.io/react-native/docs/animated.html#attachnativeevent */ attachNativeEvent, @@ -698,7 +704,7 @@ module.exports = { * Advanced imperative API for snooping on animated events that are passed in * through props. Use values directly where possible. * - * See https://reactnative.dev/docs/animated.html#forkevent + * See http://facebook.github.io/react-native/docs/animated.html#forkevent */ forkEvent, unforkEvent, diff --git a/Libraries/Animated/src/NativeAnimatedHelper.js b/Libraries/Animated/src/NativeAnimatedHelper.js index f21066bb07ff65..25fde53b6286a6 100644 --- a/Libraries/Animated/src/NativeAnimatedHelper.js +++ b/Libraries/Animated/src/NativeAnimatedHelper.js @@ -172,7 +172,6 @@ const STYLES_WHITELIST = { borderTopRightRadius: true, borderTopStartRadius: true, elevation: true, - zIndex: true, /* ios styles */ shadowOpacity: true, shadowRadius: true, @@ -277,9 +276,7 @@ function assertNativeAnimatedModule(): void { let _warnedMissingNativeAnimated = false; -function shouldUseNativeDriver( - config: {...AnimationConfig, ...} | EventConfig, -): boolean { +function shouldUseNativeDriver(config: AnimationConfig | EventConfig): boolean { if (config.useNativeDriver == null) { console.warn( 'Animated: `useNativeDriver` was not specified. This is a required ' + @@ -294,7 +291,7 @@ function shouldUseNativeDriver( 'animated module is missing. Falling back to JS-based animation. To ' + 'resolve this, add `RCTAnimation` module to this app, or remove ' + '`useNativeDriver`. ' + - 'Make sure to run `pod install` first. Read more about autolinking: https://github.com/react-native-community/cli/blob/master/docs/autolinking.md', + 'More info: https://github.com/facebook/react-native/issues/11094#issuecomment-263240420', ); _warnedMissingNativeAnimated = true; } diff --git a/Libraries/Animated/src/__tests__/AnimatedNative-test.js b/Libraries/Animated/src/__tests__/AnimatedNative-test.js index 89024cdb883fe4..c511638be6add8 100644 --- a/Libraries/Animated/src/__tests__/AnimatedNative-test.js +++ b/Libraries/Animated/src/__tests__/AnimatedNative-test.js @@ -260,9 +260,9 @@ describe('Native Animated', () => { listener, }); const handler = event.__getHandler(); - handler({nativeEvent: {foo: 42}}); + handler({foo: 42}); expect(listener).toHaveBeenCalledTimes(1); - expect(listener).toBeCalledWith({nativeEvent: {foo: 42}}); + expect(listener).toBeCalledWith({foo: 42}); }); }); diff --git a/Libraries/Animated/src/animations/Animation.js b/Libraries/Animated/src/animations/Animation.js index fd0c2218858452..4d2ac80752330a 100644 --- a/Libraries/Animated/src/animations/Animation.js +++ b/Libraries/Animated/src/animations/Animation.js @@ -22,6 +22,7 @@ export type AnimationConfig = { useNativeDriver: boolean, onComplete?: ?EndCallback, iterations?: number, + ... }; // Important note: start() and stop() will only be called at most once. diff --git a/Libraries/Animated/src/animations/DecayAnimation.js b/Libraries/Animated/src/animations/DecayAnimation.js index c3dce534f84baa..6f4039cf40e604 100644 --- a/Libraries/Animated/src/animations/DecayAnimation.js +++ b/Libraries/Animated/src/animations/DecayAnimation.js @@ -17,8 +17,7 @@ const {shouldUseNativeDriver} = require('../NativeAnimatedHelper'); import type AnimatedValue from '../nodes/AnimatedValue'; import type {AnimationConfig, EndCallback} from './Animation'; -export type DecayAnimationConfig = { - ...AnimationConfig, +export type DecayAnimationConfig = AnimationConfig & { velocity: | number | { @@ -27,12 +26,13 @@ export type DecayAnimationConfig = { ... }, deceleration?: number, + ... }; -export type DecayAnimationConfigSingle = { - ...AnimationConfig, +export type DecayAnimationConfigSingle = AnimationConfig & { velocity: number, deceleration?: number, + ... }; class DecayAnimation extends Animation { diff --git a/Libraries/Animated/src/animations/SpringAnimation.js b/Libraries/Animated/src/animations/SpringAnimation.js index aec87e5cecb732..61ff7cfa7cc0f5 100644 --- a/Libraries/Animated/src/animations/SpringAnimation.js +++ b/Libraries/Animated/src/animations/SpringAnimation.js @@ -12,7 +12,6 @@ const AnimatedValue = require('../nodes/AnimatedValue'); const AnimatedValueXY = require('../nodes/AnimatedValueXY'); -const AnimatedInterpolation = require('../nodes/AnimatedInterpolation'); const Animation = require('./Animation'); const SpringConfig = require('../SpringConfig'); @@ -22,8 +21,7 @@ const {shouldUseNativeDriver} = require('../NativeAnimatedHelper'); import type {AnimationConfig, EndCallback} from './Animation'; -export type SpringAnimationConfig = { - ...AnimationConfig, +export type SpringAnimationConfig = AnimationConfig & { toValue: | number | AnimatedValue @@ -32,8 +30,7 @@ export type SpringAnimationConfig = { y: number, ... } - | AnimatedValueXY - | AnimatedInterpolation, + | AnimatedValueXY, overshootClamping?: boolean, restDisplacementThreshold?: number, restSpeedThreshold?: number, @@ -52,11 +49,11 @@ export type SpringAnimationConfig = { damping?: number, mass?: number, delay?: number, + ... }; -export type SpringAnimationConfigSingle = { - ...AnimationConfig, - toValue: number | AnimatedValue | AnimatedInterpolation, +export type SpringAnimationConfigSingle = AnimationConfig & { + toValue: number | AnimatedValue, overshootClamping?: boolean, restDisplacementThreshold?: number, restSpeedThreshold?: number, @@ -69,6 +66,7 @@ export type SpringAnimationConfigSingle = { damping?: number, mass?: number, delay?: number, + ... }; class SpringAnimation extends Animation { diff --git a/Libraries/Animated/src/animations/TimingAnimation.js b/Libraries/Animated/src/animations/TimingAnimation.js index ffe8c8313be2f7..f88f7207e60d88 100644 --- a/Libraries/Animated/src/animations/TimingAnimation.js +++ b/Libraries/Animated/src/animations/TimingAnimation.js @@ -12,15 +12,13 @@ const AnimatedValue = require('../nodes/AnimatedValue'); const AnimatedValueXY = require('../nodes/AnimatedValueXY'); -const AnimatedInterpolation = require('../nodes/AnimatedInterpolation'); const Animation = require('./Animation'); const {shouldUseNativeDriver} = require('../NativeAnimatedHelper'); import type {AnimationConfig, EndCallback} from './Animation'; -export type TimingAnimationConfig = { - ...AnimationConfig, +export type TimingAnimationConfig = AnimationConfig & { toValue: | number | AnimatedValue @@ -29,19 +27,19 @@ export type TimingAnimationConfig = { y: number, ... } - | AnimatedValueXY - | AnimatedInterpolation, + | AnimatedValueXY, easing?: (value: number) => number, duration?: number, delay?: number, + ... }; -export type TimingAnimationConfigSingle = { - ...AnimationConfig, - toValue: number | AnimatedValue | AnimatedInterpolation, +export type TimingAnimationConfigSingle = AnimationConfig & { + toValue: number | AnimatedValue, easing?: (value: number) => number, duration?: number, delay?: number, + ... }; let _easeInOut; diff --git a/Libraries/Animated/src/components/AnimatedFlatList.js b/Libraries/Animated/src/components/AnimatedFlatList.js index ca2922aaf4cd5f..a17a13e9e9fcc4 100644 --- a/Libraries/Animated/src/components/AnimatedFlatList.js +++ b/Libraries/Animated/src/components/AnimatedFlatList.js @@ -13,9 +13,8 @@ import * as React from 'react'; const FlatList = require('../../../Lists/FlatList'); -const createAnimatedComponent = require('../createAnimatedComponent'); -import type {AnimatedComponentType} from '../createAnimatedComponent'; +const createAnimatedComponent = require('../createAnimatedComponent'); /** * @see https://github.com/facebook/react-native/commit/b8c8562 @@ -26,7 +25,4 @@ const FlatListWithEventThrottle = React.forwardRef((props, ref) => ( module.exports = (createAnimatedComponent( FlatListWithEventThrottle, -): AnimatedComponentType< - React.ElementConfig, - React.ElementRef, ->); +): $FlowFixMe); diff --git a/Libraries/Animated/src/components/AnimatedImage.js b/Libraries/Animated/src/components/AnimatedImage.js index f5e801845f32b2..89fee4d29ea8da 100644 --- a/Libraries/Animated/src/components/AnimatedImage.js +++ b/Libraries/Animated/src/components/AnimatedImage.js @@ -10,16 +10,8 @@ 'use strict'; -import * as React from 'react'; - const Image = require('../../../Image/Image'); -const createAnimatedComponent = require('../createAnimatedComponent'); -import type {AnimatedComponentType} from '../createAnimatedComponent'; +const createAnimatedComponent = require('../createAnimatedComponent'); -module.exports = (createAnimatedComponent( - (Image: $FlowFixMe), -): AnimatedComponentType< - React.ElementConfig, - React.ElementRef, ->); +module.exports = (createAnimatedComponent(Image): $FlowFixMe); diff --git a/Libraries/Animated/src/components/AnimatedScrollView.js b/Libraries/Animated/src/components/AnimatedScrollView.js index afed39b31cfa06..9938b594868881 100644 --- a/Libraries/Animated/src/components/AnimatedScrollView.js +++ b/Libraries/Animated/src/components/AnimatedScrollView.js @@ -13,9 +13,8 @@ import * as React from 'react'; const ScrollView = require('../../../Components/ScrollView/ScrollView'); -const createAnimatedComponent = require('../createAnimatedComponent'); -import type {AnimatedComponentType} from '../createAnimatedComponent'; +const createAnimatedComponent = require('../createAnimatedComponent'); /** * @see https://github.com/facebook/react-native/commit/b8c8562 @@ -26,7 +25,4 @@ const ScrollViewWithEventThrottle = React.forwardRef((props, ref) => ( module.exports = (createAnimatedComponent( ScrollViewWithEventThrottle, -): AnimatedComponentType< - React.ElementConfig, - React.ElementRef, ->); +): $FlowFixMe); diff --git a/Libraries/Animated/src/components/AnimatedSectionList.js b/Libraries/Animated/src/components/AnimatedSectionList.js index 002f8a14c7646b..49e95e4adc7431 100644 --- a/Libraries/Animated/src/components/AnimatedSectionList.js +++ b/Libraries/Animated/src/components/AnimatedSectionList.js @@ -13,9 +13,8 @@ import * as React from 'react'; const SectionList = require('../../../Lists/SectionList'); -const createAnimatedComponent = require('../createAnimatedComponent'); -import type {AnimatedComponentType} from '../createAnimatedComponent'; +const createAnimatedComponent = require('../createAnimatedComponent'); /** * @see https://github.com/facebook/react-native/commit/b8c8562 @@ -26,7 +25,4 @@ const SectionListWithEventThrottle = React.forwardRef((props, ref) => ( module.exports = (createAnimatedComponent( SectionListWithEventThrottle, -): AnimatedComponentType< - React.ElementConfig, - React.ElementRef, ->); +): $FlowFixMe); diff --git a/Libraries/Animated/src/components/AnimatedText.js b/Libraries/Animated/src/components/AnimatedText.js index 55b8fb8c42fd01..81b016cca18d41 100644 --- a/Libraries/Animated/src/components/AnimatedText.js +++ b/Libraries/Animated/src/components/AnimatedText.js @@ -10,16 +10,8 @@ 'use strict'; -import * as React from 'react'; - const Text = require('../../../Text/Text'); -const createAnimatedComponent = require('../createAnimatedComponent'); -import type {AnimatedComponentType} from '../createAnimatedComponent'; +const createAnimatedComponent = require('../createAnimatedComponent'); -module.exports = (createAnimatedComponent( - (Text: $FlowFixMe), -): AnimatedComponentType< - React.ElementConfig, - React.ElementRef, ->); +module.exports = (createAnimatedComponent(Text): $FlowFixMe); diff --git a/Libraries/Animated/src/components/AnimatedView.js b/Libraries/Animated/src/components/AnimatedView.js index 6e7badcced34d7..3396337eda3f50 100644 --- a/Libraries/Animated/src/components/AnimatedView.js +++ b/Libraries/Animated/src/components/AnimatedView.js @@ -10,11 +10,12 @@ 'use strict'; -import * as React from 'react'; - const View = require('../../../Components/View/View'); + const createAnimatedComponent = require('../createAnimatedComponent'); +const React = require('react'); + import type {AnimatedComponentType} from '../createAnimatedComponent'; module.exports = (createAnimatedComponent(View): AnimatedComponentType< diff --git a/Libraries/Animated/src/createAnimatedComponent.js b/Libraries/Animated/src/createAnimatedComponent.js index 099e71c8faaaaf..0672962354a97f 100644 --- a/Libraries/Animated/src/createAnimatedComponent.js +++ b/Libraries/Animated/src/createAnimatedComponent.js @@ -79,28 +79,7 @@ function createAnimatedComponent( typeof this._component.setNativeProps !== 'function' || // In Fabric, force animations to go through forceUpdate and skip setNativeProps // eslint-disable-next-line dot-notation - this._component['_internalInstanceHandle']?.stateNode?.canonical != - null || - // Some components have a setNativeProps function but aren't a host component - // such as lists like FlatList and SectionList. These should also use - // forceUpdate in Fabric since setNativeProps doesn't exist on the underlying - // host component. This crazy hack is essentially special casing those lists and - // ScrollView itself to use forceUpdate in Fabric. - // If these components end up using forwardRef then these hacks can go away - // as this._component would actually be the underlying host component and the above check - // would be sufficient. - (this._component.getNativeScrollRef != null && - this._component.getNativeScrollRef() != null && - // eslint-disable-next-line dot-notation - this._component.getNativeScrollRef()['_internalInstanceHandle'] - ?.stateNode?.canonical != null) || - (this._component.getScrollResponder != null && - this._component.getScrollResponder().getNativeScrollRef != null && - this._component.getScrollResponder().getNativeScrollRef() != null && - this._component.getScrollResponder().getNativeScrollRef()[ - // eslint-disable-next-line dot-notation - '_internalInstanceHandle' - ]?.stateNode?.canonical != null) + this._component['_internalInstanceHandle']?.stateNode?.canonical != null ) { this.forceUpdate(); } else if (!this._propsAnimated.__isNative) { diff --git a/Libraries/Animated/src/nodes/AnimatedInterpolation.js b/Libraries/Animated/src/nodes/AnimatedInterpolation.js index a32bb9c2a7c190..0fad54dc4085ca 100644 --- a/Libraries/Animated/src/nodes/AnimatedInterpolation.js +++ b/Libraries/Animated/src/nodes/AnimatedInterpolation.js @@ -22,12 +22,17 @@ const normalizeColor = require('../../../StyleSheet/normalizeColor'); type ExtrapolateType = 'extend' | 'identity' | 'clamp'; export type InterpolationConfigType = { - inputRange: $ReadOnlyArray, - outputRange: $ReadOnlyArray | $ReadOnlyArray, + inputRange: Array, + /* $FlowFixMe(>=0.38.0 site=react_native_fb,react_native_oss) - Flow error + * detected during the deployment of v0.38.0. To see the error, remove this + * comment and run flow + */ + outputRange: Array | Array, easing?: (input: number) => number, extrapolate?: ExtrapolateType, extrapolateLeft?: ExtrapolateType, extrapolateRight?: ExtrapolateType, + ... }; const linear = t => t; @@ -164,17 +169,20 @@ function interpolate( } function colorToRgba(input: string): string { - let normalizedColor = normalizeColor(input); - if (normalizedColor === null || typeof normalizedColor !== 'number') { + let int32Color = normalizeColor(input); + if ( + int32Color === null || + typeof int32Color !== 'number' /* TODO(macOS ISS#2323203) */ + ) { return input; } - normalizedColor = normalizedColor || 0; + int32Color = int32Color || 0; - const r = (normalizedColor & 0xff000000) >>> 24; - const g = (normalizedColor & 0x00ff0000) >>> 16; - const b = (normalizedColor & 0x0000ff00) >>> 8; - const a = (normalizedColor & 0x000000ff) / 255; + const r = (int32Color & 0xff000000) >>> 24; + const g = (int32Color & 0x00ff0000) >>> 16; + const b = (int32Color & 0x0000ff00) >>> 8; + const a = (int32Color & 0x000000ff) / 255; return `rgba(${r}, ${g}, ${b}, ${a})`; } @@ -218,10 +226,11 @@ function createInterpolationFromStringOutputRange( }); }); + /* $FlowFixMe(>=0.18.0): `outputRange[0].match()` can return `null`. Need to + * guard against this possibility. + */ const interpolations = outputRange[0] .match(stringShapeRegex) - /* $FlowFixMe(>=0.18.0): `outputRange[0].match()` can return `null`. Need - * to guard against this possibility. */ .map((value, i) => { return createInterpolation({ ...config, @@ -252,7 +261,7 @@ function isRgbOrRgba(range) { return typeof range === 'string' && range.startsWith('rgb'); } -function checkPattern(arr: $ReadOnlyArray) { +function checkPattern(arr: Array) { const pattern = arr[0].replace(stringShapeRegex, ''); for (let i = 1; i < arr.length; ++i) { invariant( @@ -262,7 +271,7 @@ function checkPattern(arr: $ReadOnlyArray) { } } -function findRange(input: number, inputRange: $ReadOnlyArray) { +function findRange(input: number, inputRange: Array) { let i; for (i = 1; i < inputRange.length - 1; ++i) { if (inputRange[i] >= input) { @@ -272,7 +281,7 @@ function findRange(input: number, inputRange: $ReadOnlyArray) { return i - 1; } -function checkValidInputRange(arr: $ReadOnlyArray) { +function checkValidInputRange(arr: Array) { invariant(arr.length >= 2, 'inputRange must have at least 2 elements'); for (let i = 1; i < arr.length; ++i) { invariant( @@ -288,7 +297,7 @@ function checkValidInputRange(arr: $ReadOnlyArray) { } } -function checkInfiniteRange(name: string, arr: $ReadOnlyArray) { +function checkInfiniteRange(name: string, arr: Array) { invariant(arr.length >= 2, name + ' must have at least 2 elements'); invariant( arr.length !== 2 || arr[0] !== -Infinity || arr[1] !== Infinity, @@ -358,8 +367,6 @@ class AnimatedInterpolation extends AnimatedWithChildren { return { inputRange: this._config.inputRange, // Only the `outputRange` can contain strings so we don't need to transform `inputRange` here - /* $FlowFixMe(>=0.38.0) - Flow error detected during the deployment of - * v0.38.0. To see the error, remove this comment and run flow */ outputRange: this.__transformDataType(this._config.outputRange), extrapolateLeft: this._config.extrapolateLeft || this._config.extrapolate || 'extend', diff --git a/Libraries/Animated/src/nodes/AnimatedNode.js b/Libraries/Animated/src/nodes/AnimatedNode.js index 7371d49fd5b355..4b6a079bf732ad 100644 --- a/Libraries/Animated/src/nodes/AnimatedNode.js +++ b/Libraries/Animated/src/nodes/AnimatedNode.js @@ -65,7 +65,7 @@ class AnimatedNode { * animations. This is useful because there is no way to * synchronously read the value because it might be driven natively. * - * See https://reactnative.dev/docs/animatedvalue.html#addlistener + * See http://facebook.github.io/react-native/docs/animatedvalue.html#addlistener */ addListener(callback: (value: any) => mixed): string { const id = String(_uniqueId++); @@ -80,7 +80,7 @@ class AnimatedNode { * Unregister a listener. The `id` param shall match the identifier * previously returned by `addListener()`. * - * See https://reactnative.dev/docs/animatedvalue.html#removelistener + * See http://facebook.github.io/react-native/docs/animatedvalue.html#removelistener */ removeListener(id: string): void { delete this._listeners[id]; @@ -92,7 +92,7 @@ class AnimatedNode { /** * Remove all registered listeners. * - * See https://reactnative.dev/docs/animatedvalue.html#removealllisteners + * See http://facebook.github.io/react-native/docs/animatedvalue.html#removealllisteners */ removeAllListeners(): void { this._listeners = {}; diff --git a/Libraries/Animated/src/nodes/AnimatedValue.js b/Libraries/Animated/src/nodes/AnimatedValue.js index 7306fc77b94c05..4fa35ed27c20ab 100644 --- a/Libraries/Animated/src/nodes/AnimatedValue.js +++ b/Libraries/Animated/src/nodes/AnimatedValue.js @@ -66,7 +66,7 @@ function _flush(rootNode: AnimatedValue): void { * mechanism at a time. Using a new mechanism (e.g. starting a new animation, * or calling `setValue`) will stop any previous ones. * - * See https://reactnative.dev/docs/animatedvalue.html + * See http://facebook.github.io/react-native/docs/animatedvalue.html */ class AnimatedValue extends AnimatedWithChildren { _value: number; @@ -77,9 +77,6 @@ class AnimatedValue extends AnimatedWithChildren { constructor(value: number) { super(); - if (typeof value !== 'number') { - throw new Error('AnimatedValue: Attempting to set value to undefined'); - } this._startingValue = this._value = value; this._offset = 0; this._animation = null; @@ -98,7 +95,7 @@ class AnimatedValue extends AnimatedWithChildren { * Directly set the value. This will stop any animations running on the value * and update all the bound properties. * - * See https://reactnative.dev/docs/animatedvalue.html#setvalue + * See http://facebook.github.io/react-native/docs/animatedvalue.html#setvalue */ setValue(value: number): void { if (this._animation) { @@ -119,7 +116,7 @@ class AnimatedValue extends AnimatedWithChildren { * `setValue`, an animation, or `Animated.event`. Useful for compensating * things like the start of a pan gesture. * - * See https://reactnative.dev/docs/animatedvalue.html#setoffset + * See http://facebook.github.io/react-native/docs/animatedvalue.html#setoffset */ setOffset(offset: number): void { this._offset = offset; @@ -132,7 +129,7 @@ class AnimatedValue extends AnimatedWithChildren { * Merges the offset value into the base value and resets the offset to zero. * The final output of the value is unchanged. * - * See https://reactnative.dev/docs/animatedvalue.html#flattenoffset + * See http://facebook.github.io/react-native/docs/animatedvalue.html#flattenoffset */ flattenOffset(): void { this._value += this._offset; @@ -146,7 +143,7 @@ class AnimatedValue extends AnimatedWithChildren { * Sets the offset value to the base value, and resets the base value to zero. * The final output of the value is unchanged. * - * See https://reactnative.dev/docs/animatedvalue.html#extractoffset + * See http://facebook.github.io/react-native/docs/animatedvalue.html#extractoffset */ extractOffset(): void { this._offset += this._value; @@ -161,7 +158,7 @@ class AnimatedValue extends AnimatedWithChildren { * final value after stopping the animation, which is useful for updating * state to match the animation position with layout. * - * See https://reactnative.dev/docs/animatedvalue.html#stopanimation + * See http://facebook.github.io/react-native/docs/animatedvalue.html#stopanimation */ stopAnimation(callback?: ?(value: number) => void): void { this.stopTracking(); @@ -173,7 +170,7 @@ class AnimatedValue extends AnimatedWithChildren { /** * Stops any animation and resets the value to its original. * - * See https://reactnative.dev/docs/animatedvalue.html#resetanimation + * See http://facebook.github.io/react-native/docs/animatedvalue.html#resetanimation */ resetAnimation(callback?: ?(value: number) => void): void { this.stopAnimation(callback); @@ -196,7 +193,7 @@ class AnimatedValue extends AnimatedWithChildren { * Typically only used internally, but could be used by a custom Animation * class. * - * See https://reactnative.dev/docs/animatedvalue.html#animate + * See http://facebook.github.io/react-native/docs/animatedvalue.html#animate */ animate(animation: Animation, callback: ?EndCallback): void { let handle = null; @@ -242,10 +239,6 @@ class AnimatedValue extends AnimatedWithChildren { } _updateValue(value: number, flush: boolean): void { - if (value === undefined) { - throw new Error('AnimatedValue: Attempting to set value to undefined'); - } - this._value = value; if (flush) { _flush(this); diff --git a/Libraries/Animated/src/nodes/AnimatedValueXY.js b/Libraries/Animated/src/nodes/AnimatedValueXY.js index 28d3395db8a802..2e845b26219d84 100644 --- a/Libraries/Animated/src/nodes/AnimatedValueXY.js +++ b/Libraries/Animated/src/nodes/AnimatedValueXY.js @@ -27,7 +27,7 @@ let _uniqueId = 1; * 2D Value for driving 2D animations, such as pan gestures. Almost identical * API to normal `Animated.Value`, but multiplexed. * - * See https://reactnative.dev/docs/animatedvaluexy.html + * See http://facebook.github.io/react-native/docs/animatedvaluexy.html */ class AnimatedValueXY extends AnimatedWithChildren { x: AnimatedValue; @@ -69,7 +69,7 @@ class AnimatedValueXY extends AnimatedWithChildren { * Directly set the value. This will stop any animations running on the value * and update all the bound properties. * - * See https://reactnative.dev/docs/animatedvaluexy.html#setvalue + * See http://facebook.github.io/react-native/docs/animatedvaluexy.html#setvalue */ setValue(value: {x: number, y: number, ...}) { this.x.setValue(value.x); @@ -81,7 +81,7 @@ class AnimatedValueXY extends AnimatedWithChildren { * via `setValue`, an animation, or `Animated.event`. Useful for compensating * things like the start of a pan gesture. * - * See https://reactnative.dev/docs/animatedvaluexy.html#setoffset + * See http://facebook.github.io/react-native/docs/animatedvaluexy.html#setoffset */ setOffset(offset: {x: number, y: number, ...}) { this.x.setOffset(offset.x); @@ -92,7 +92,7 @@ class AnimatedValueXY extends AnimatedWithChildren { * Merges the offset value into the base value and resets the offset to zero. * The final output of the value is unchanged. * - * See https://reactnative.dev/docs/animatedvaluexy.html#flattenoffset + * See http://facebook.github.io/react-native/docs/animatedvaluexy.html#flattenoffset */ flattenOffset(): void { this.x.flattenOffset(); @@ -103,7 +103,7 @@ class AnimatedValueXY extends AnimatedWithChildren { * Sets the offset value to the base value, and resets the base value to * zero. The final output of the value is unchanged. * - * See https://reactnative.dev/docs/animatedvaluexy.html#extractoffset + * See http://facebook.github.io/react-native/docs/animatedvaluexy.html#extractoffset */ extractOffset(): void { this.x.extractOffset(); @@ -124,7 +124,7 @@ class AnimatedValueXY extends AnimatedWithChildren { /** * Stops any animation and resets the value to its original. * - * See https://reactnative.dev/docs/animatedvaluexy.html#resetanimation + * See http://facebook.github.io/react-native/docs/animatedvaluexy.html#resetanimation */ resetAnimation( callback?: (value: { @@ -143,7 +143,7 @@ class AnimatedValueXY extends AnimatedWithChildren { * final value after stopping the animation, which is useful for updating * state to match the animation position with layout. * - * See https://reactnative.dev/docs/animatedvaluexy.html#stopanimation + * See http://facebook.github.io/react-native/docs/animatedvaluexy.html#stopanimation */ stopAnimation( callback?: (value: { @@ -164,7 +164,7 @@ class AnimatedValueXY extends AnimatedWithChildren { * * Returns a string that serves as an identifier for the listener. * - * See https://reactnative.dev/docs/animatedvaluexy.html#addlistener + * See http://facebook.github.io/react-native/docs/animatedvaluexy.html#addlistener */ addListener(callback: ValueXYListenerCallback): string { const id = String(_uniqueId++); @@ -182,7 +182,7 @@ class AnimatedValueXY extends AnimatedWithChildren { * Unregister a listener. The `id` param shall match the identifier * previously returned by `addListener()`. * - * See https://reactnative.dev/docs/animatedvaluexy.html#removelistener + * See http://facebook.github.io/react-native/docs/animatedvaluexy.html#removelistener */ removeListener(id: string): void { this.x.removeListener(this._listeners[id].x); @@ -193,7 +193,7 @@ class AnimatedValueXY extends AnimatedWithChildren { /** * Remove all registered listeners. * - * See https://reactnative.dev/docs/animatedvaluexy.html#removealllisteners + * See http://facebook.github.io/react-native/docs/animatedvaluexy.html#removealllisteners */ removeAllListeners(): void { this.x.removeAllListeners(); @@ -204,7 +204,7 @@ class AnimatedValueXY extends AnimatedWithChildren { /** * Converts `{x, y}` into `{left, top}` for use in style. * - * See https://reactnative.dev/docs/animatedvaluexy.html#getlayout + * See http://facebook.github.io/react-native/docs/animatedvaluexy.html#getlayout */ getLayout(): {[key: string]: AnimatedValue, ...} { return { @@ -216,7 +216,7 @@ class AnimatedValueXY extends AnimatedWithChildren { /** * Converts `{x, y}` into a useable translation transform. * - * See https://reactnative.dev/docs/animatedvaluexy.html#gettranslatetransform + * See http://facebook.github.io/react-native/docs/animatedvaluexy.html#gettranslatetransform */ getTranslateTransform(): Array<{[key: string]: AnimatedValue, ...}> { return [{translateX: this.x}, {translateY: this.y}]; diff --git a/Libraries/AppState/AppState.js b/Libraries/AppState/AppState.js index b5fb59bd9fd5db..30a0808f4400b3 100644 --- a/Libraries/AppState/AppState.js +++ b/Libraries/AppState/AppState.js @@ -22,7 +22,7 @@ import NativeAppState from './NativeAppState'; * `AppState` can tell you if the app is in the foreground or background, * and notify you when the state changes. * - * See https://reactnative.dev/docs/appstate.html + * See http://facebook.github.io/react-native/docs/appstate.html */ class AppState extends NativeEventEmitter { _eventHandlers: Object; @@ -73,7 +73,7 @@ class AppState extends NativeEventEmitter { * Add a handler to AppState changes by listening to the `change` event type * and providing the handler. * - * See https://reactnative.dev/docs/appstate.html#addeventlistener + * See http://facebook.github.io/react-native/docs/appstate.html#addeventlistener */ addEventListener(type: string, handler: Function) { invariant( @@ -120,7 +120,7 @@ class AppState extends NativeEventEmitter { /** * Remove a handler by passing the `change` event type and the handler. * - * See https://reactnative.dev/docs/appstate.html#removeeventlistener + * See http://facebook.github.io/react-native/docs/appstate.html#removeeventlistener */ removeEventListener(type: string, handler: Function) { invariant( diff --git a/Libraries/BatchedBridge/MessageQueue.js b/Libraries/BatchedBridge/MessageQueue.js index 3756b083fbd412..8c35ee9f8eaa95 100644 --- a/Libraries/BatchedBridge/MessageQueue.js +++ b/Libraries/BatchedBridge/MessageQueue.js @@ -15,7 +15,7 @@ const Systrace = require('../Performance/Systrace'); const deepFreezeAndThrowOnMutationInDev = require('../Utilities/deepFreezeAndThrowOnMutationInDev'); const invariant = require('invariant'); -const stringifySafe = require('../Utilities/stringifySafe').default; +const stringifySafe = require('../Utilities/stringifySafe'); const warnOnce = require('../Utilities/warnOnce'); export type SpyData = { @@ -74,6 +74,9 @@ class MessageQueue { (this: any).callFunctionReturnFlushedQueue = this.callFunctionReturnFlushedQueue.bind( this, ); + (this: any).callFunctionReturnResultAndFlushedQueue = this.callFunctionReturnResultAndFlushedQueue.bind( + this, + ); (this: any).flushedQueue = this.flushedQueue.bind(this); (this: any).invokeCallbackAndReturnFlushedQueue = this.invokeCallbackAndReturnFlushedQueue.bind( this, @@ -112,12 +115,18 @@ class MessageQueue { return this.flushedQueue(); } - // Deprecated. T61834641: Remove me once native clients have updated callFunctionReturnResultAndFlushedQueue( module: string, method: string, args: any[], - ): void {} + ): $TEMPORARY$array, Array, Array, number]> { + let result; + this.__guard(() => { + result = this.__callFunction(module, method, args); + }); + + return [result, this.flushedQueue()]; + } invokeCallbackAndReturnFlushedQueue( cbID: number, @@ -389,7 +398,7 @@ class MessageQueue { Systrace.endEvent(); } - __callFunction(module: string, method: string, args: any[]): void { + __callFunction(module: string, method: string, args: any[]): any { this._lastFlush = Date.now(); this._eventLoopStartTime = this._lastFlush; if (__DEV__ || this.__spy) { @@ -413,8 +422,9 @@ class MessageQueue { method, module, ); - moduleMethods[method].apply(moduleMethods, args); + const result = moduleMethods[method].apply(moduleMethods, args); Systrace.endEvent(); + return result; } __invokeCallback(cbID: number, args: any[]) { diff --git a/Libraries/Blob/FileReader.js b/Libraries/Blob/FileReader.js index 15a8b44d0bb522..fc769f8a544a72 100644 --- a/Libraries/Blob/FileReader.js +++ b/Libraries/Blob/FileReader.js @@ -85,15 +85,9 @@ class FileReader extends (EventTarget(...READER_EVENTS): any) { throw new Error('FileReader.readAsArrayBuffer is not implemented'); } - readAsDataURL(blob: ?Blob) { + readAsDataURL(blob: Blob) { this._aborted = false; - if (blob == null) { - throw new TypeError( - "Failed to execute 'readAsDataURL' on 'FileReader': parameter 1 is not of type 'Blob'", - ); - } - NativeFileReaderModule.readAsDataURL(blob.data).then( (text: string) => { if (this._aborted) { @@ -112,15 +106,9 @@ class FileReader extends (EventTarget(...READER_EVENTS): any) { ); } - readAsText(blob: ?Blob, encoding: string = 'UTF-8') { + readAsText(blob: Blob, encoding: string = 'UTF-8') { this._aborted = false; - if (blob == null) { - throw new TypeError( - "Failed to execute 'readAsText' on 'FileReader': parameter 1 is not of type 'Blob'", - ); - } - NativeFileReaderModule.readAsText(blob.data, encoding).then( (text: string) => { if (this._aborted) { diff --git a/Libraries/Blob/NativeBlobModule.js b/Libraries/Blob/NativeBlobModule.js index ab2572bd0ea8b7..4810cd89f88431 100644 --- a/Libraries/Blob/NativeBlobModule.js +++ b/Libraries/Blob/NativeBlobModule.js @@ -14,7 +14,7 @@ import type {TurboModule} from '../TurboModule/RCTExport'; import * as TurboModuleRegistry from '../TurboModule/TurboModuleRegistry'; export interface Spec extends TurboModule { - +getConstants: () => {|BLOB_URI_SCHEME: ?string, BLOB_URI_HOST: ?string|}; + +getConstants: () => {|BLOB_URI_SCHEME: string, BLOB_URI_HOST: ?string|}; +addNetworkingHandler: () => void; +addWebSocketHandler: (id: number) => void; +removeWebSocketHandler: (id: number) => void; diff --git a/Libraries/Blob/RCTBlobManager.mm b/Libraries/Blob/RCTBlobManager.mm index 1f68ec27aa5345..c4ab554f088faf 100755 --- a/Libraries/Blob/RCTBlobManager.mm +++ b/Libraries/Blob/RCTBlobManager.mm @@ -38,7 +38,6 @@ @implementation RCTBlobManager @synthesize bridge = _bridge; @synthesize methodQueue = _methodQueue; -@synthesize turboModuleLookupDelegate = _turboModuleLookupDelegate; - (void)setBridge:(RCTBridge *)bridge { @@ -140,17 +139,9 @@ - (void)remove:(NSString *)blobId RCT_EXPORT_METHOD(addNetworkingHandler) { - RCTNetworking *const networking = _bridge ? _bridge.networking : [_turboModuleLookupDelegate moduleForName:"RCTNetworking"]; - - // TODO(T63516227): Why can methodQueue be nil here? - // We don't want to do anything when methodQueue is nil. - if (!networking.methodQueue) { - return; - } - - dispatch_async(networking.methodQueue, ^{ - [networking addRequestHandler:self]; - [networking addResponseHandler:self]; + dispatch_async(_bridge.networking.methodQueue, ^{ + [self->_bridge.networking addRequestHandler:self]; + [self->_bridge.networking addResponseHandler:self]; }); } @@ -310,12 +301,9 @@ - (id)processWebsocketMessage:(id)message }; } -- (std::shared_ptr) - getTurboModuleWithJsInvoker:(std::shared_ptr)jsInvoker - nativeInvoker:(std::shared_ptr)nativeInvoker - perfLogger:(id)perfLogger +- (std::shared_ptr)getTurboModuleWithJsInvoker:(std::shared_ptr)jsInvoker { - return std::make_shared(self, jsInvoker, nativeInvoker, perfLogger); + return std::make_shared(self, jsInvoker); } @end diff --git a/Libraries/Blob/RCTFileReaderModule.mm b/Libraries/Blob/RCTFileReaderModule.mm index 7d6eda4d5c4f3b..5cf41adc991fd5 100644 --- a/Libraries/Blob/RCTFileReaderModule.mm +++ b/Libraries/Blob/RCTFileReaderModule.mm @@ -71,12 +71,10 @@ @implementation RCTFileReaderModule } } -- (std::shared_ptr) - getTurboModuleWithJsInvoker:(std::shared_ptr)jsInvoker - nativeInvoker:(std::shared_ptr)nativeInvoker - perfLogger:(id)perfLogger +- (std::shared_ptr)getTurboModuleWithJsInvoker: + (std::shared_ptr)jsInvoker { - return std::make_shared(self, jsInvoker, nativeInvoker, perfLogger); + return std::make_shared(self, jsInvoker); } @end diff --git a/Libraries/Blob/React-RCTBlob.podspec b/Libraries/Blob/React-RCTBlob.podspec index f13d6b5a403d42..8b295657043a94 100644 --- a/Libraries/Blob/React-RCTBlob.podspec +++ b/Libraries/Blob/React-RCTBlob.podspec @@ -17,16 +17,16 @@ else end folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32' -folly_version = '2020.01.13.00' +folly_version = '2018.10.22.00' Pod::Spec.new do |s| s.name = "React-RCTBlob" s.version = version s.summary = "An API for displaying iOS action sheets and share sheets." - s.homepage = "https://reactnative.dev/" + s.homepage = "http://facebook.github.io/react-native/" s.license = package["license"] s.author = "Facebook, Inc. and its affiliates" - s.platforms = { :ios => "10.0", :tvos => "10.0", :osx => "10.13" } # TODO(macOS GH#214) + s.platforms = { :ios => "9.0", :tvos => "9.2", :osx => "10.13" } # TODO(macOS GH#214) s.compiler_flags = folly_compiler_flags + ' -Wno-nullability-completeness' s.source = source s.source_files = "*.{m,mm}" @@ -41,7 +41,6 @@ Pod::Spec.new do |s| s.dependency "RCT-Folly", folly_version s.dependency "FBReactNativeSpec", version s.dependency "ReactCommon/turbomodule/core", version - s.dependency "React-jsi", version s.dependency "React-Core/RCTBlobHeaders", version s.dependency "React-Core/RCTWebSocket", version s.dependency "React-RCTNetwork", version diff --git a/Libraries/CameraRoll/RCTCameraRollManager.mm b/Libraries/CameraRoll/RCTCameraRollManager.mm index 279ca7218c589b..106d94d8475f07 100644 --- a/Libraries/CameraRoll/RCTCameraRollManager.mm +++ b/Libraries/CameraRoll/RCTCameraRollManager.mm @@ -8,6 +8,7 @@ #import "RCTCameraRollManager.h" #import +#import #import #import // TODO(macOS ISS#2323203) #import @@ -355,12 +356,9 @@ static void checkPhotoLibraryConfig() #endif } -- (std::shared_ptr) - getTurboModuleWithJsInvoker:(std::shared_ptr)jsInvoker - nativeInvoker:(std::shared_ptr)nativeInvoker - perfLogger:(id)perfLogger +- (std::shared_ptr)getTurboModuleWithJsInvoker:(std::shared_ptr)jsInvoker { - return std::make_shared(self, jsInvoker, nativeInvoker, perfLogger); + return std::make_shared(self, jsInvoker); } @end diff --git a/Libraries/CameraRoll/RCTImagePickerManager.mm b/Libraries/CameraRoll/RCTImagePickerManager.mm index 5319a856c9ceaf..5180a1365bdc63 100644 --- a/Libraries/CameraRoll/RCTImagePickerManager.mm +++ b/Libraries/CameraRoll/RCTImagePickerManager.mm @@ -236,9 +236,6 @@ - (void)_dismissPicker:(UIImagePickerController *)picker args:(NSArray *)args - (void)cameraChanged:(NSNotification *)notification { for (UIImagePickerController *picker in _pickers) { - if (picker.sourceType != UIImagePickerControllerSourceTypeCamera) { - continue; - } if ([picker isKindOfClass:[RCTImagePickerController class]] && ((RCTImagePickerController *)picker).unmirrorFrontFacingCamera && picker.cameraDevice == UIImagePickerControllerCameraDeviceFront) { @@ -249,12 +246,9 @@ - (void)cameraChanged:(NSNotification *)notification } } -- (std::shared_ptr) - getTurboModuleWithJsInvoker:(std::shared_ptr)jsInvoker - nativeInvoker:(std::shared_ptr)nativeInvoker - perfLogger:(id)perfLogger +- (std::shared_ptr)getTurboModuleWithJsInvoker:(std::shared_ptr)jsInvoker { - return std::make_shared(self, jsInvoker, nativeInvoker, perfLogger); + return std::make_shared(self, jsInvoker); } @end diff --git a/Libraries/Components/AccessibilityInfo/AccessibilityInfo.android.js b/Libraries/Components/AccessibilityInfo/AccessibilityInfo.android.js index 9a99eb6fb6bae9..1840dfce692a0d 100644 --- a/Libraries/Components/AccessibilityInfo/AccessibilityInfo.android.js +++ b/Libraries/Components/AccessibilityInfo/AccessibilityInfo.android.js @@ -34,7 +34,7 @@ const _subscriptions = new Map(); * well as to register to be notified when the state of the screen reader * changes. * - * See https://reactnative.dev/docs/accessibilityinfo.html + * See http://facebook.github.io/react-native/docs/accessibilityinfo.html */ const AccessibilityInfo = { @@ -93,7 +93,7 @@ const AccessibilityInfo = { */ get fetch(): () => Promise { console.warn( - 'AccessibilityInfo.fetch is deprecated, call AccessibilityInfo.isScreenReaderEnabled instead', + 'AccessibilityInfo.fetch is deprecated, call Accessibility.isScreenReaderEnabled instead', ); return this.isScreenReaderEnabled; }, @@ -138,7 +138,7 @@ const AccessibilityInfo = { /** * Set accessibility focus to a react component. * - * See https://reactnative.dev/docs/accessibilityinfo.html#setaccessibilityfocus + * See http://facebook.github.io/react-native/docs/accessibilityinfo.html#setaccessibilityfocus */ setAccessibilityFocus: function(reactTag: number): void { UIManager.sendAccessibilityEvent( @@ -150,7 +150,7 @@ const AccessibilityInfo = { /** * Post a string to be announced by the screen reader. * - * See https://reactnative.dev/docs/accessibilityinfo.html#announceforaccessibility + * See http://facebook.github.io/react-native/docs/accessibilityinfo.html#announceforaccessibility */ announceForAccessibility: function(announcement: string): void { if (NativeAccessibilityInfo) { diff --git a/Libraries/Components/AccessibilityInfo/AccessibilityInfo.ios.js b/Libraries/Components/AccessibilityInfo/AccessibilityInfo.ios.js index 9e721a776b75cc..4627b70d2ae003 100644 --- a/Libraries/Components/AccessibilityInfo/AccessibilityInfo.ios.js +++ b/Libraries/Components/AccessibilityInfo/AccessibilityInfo.ios.js @@ -46,7 +46,7 @@ const _subscriptions = new Map(); * well as to register to be notified when the state of the screen reader * changes. * - * See https://reactnative.dev/docs/accessibilityinfo.html + * See http://facebook.github.io/react-native/docs/accessibilityinfo.html */ const AccessibilityInfo = { /** @@ -55,7 +55,7 @@ const AccessibilityInfo = { * Returns a promise which resolves to a boolean. * The result is `true` when bold text is enabled and `false` otherwise. * - * See https://reactnative.dev/docs/accessibilityinfo.html#isBoldTextEnabled + * See http://facebook.github.io/react-native/docs/accessibilityinfo.html#isBoldTextEnabled */ isBoldTextEnabled: function(): Promise { return new Promise((resolve, reject) => { @@ -73,7 +73,7 @@ const AccessibilityInfo = { * Returns a promise which resolves to a boolean. * The result is `true` when grayscale is enabled and `false` otherwise. * - * See https://reactnative.dev/docs/accessibilityinfo.html#isGrayscaleEnabled + * See http://facebook.github.io/react-native/docs/accessibilityinfo.html#isGrayscaleEnabled */ isGrayscaleEnabled: function(): Promise { return new Promise((resolve, reject) => { @@ -91,7 +91,7 @@ const AccessibilityInfo = { * Returns a promise which resolves to a boolean. * The result is `true` when invert color is enabled and `false` otherwise. * - * See https://reactnative.dev/docs/accessibilityinfo.html#isInvertColorsEnabled + * See http://facebook.github.io/react-native/docs/accessibilityinfo.html#isInvertColorsEnabled */ isInvertColorsEnabled: function(): Promise { return new Promise((resolve, reject) => { @@ -109,7 +109,7 @@ const AccessibilityInfo = { * Returns a promise which resolves to a boolean. * The result is `true` when a reduce motion is enabled and `false` otherwise. * - * See https://reactnative.dev/docs/accessibilityinfo.html#isReduceMotionEnabled + * See http://facebook.github.io/react-native/docs/accessibilityinfo.html#isReduceMotionEnabled */ isReduceMotionEnabled: function(): Promise { return new Promise((resolve, reject) => { @@ -127,7 +127,7 @@ const AccessibilityInfo = { * Returns a promise which resolves to a boolean. * The result is `true` when a reduce transparency is enabled and `false` otherwise. * - * See https://reactnative.dev/docs/accessibilityinfo.html#isReduceTransparencyEnabled + * See http://facebook.github.io/react-native/docs/accessibilityinfo.html#isReduceTransparencyEnabled */ isReduceTransparencyEnabled: function(): Promise { return new Promise((resolve, reject) => { @@ -148,7 +148,7 @@ const AccessibilityInfo = { * Returns a promise which resolves to a boolean. * The result is `true` when a screen reader is enabled and `false` otherwise. * - * See https://reactnative.dev/docs/accessibilityinfo.html#isScreenReaderEnabled + * See http://facebook.github.io/react-native/docs/accessibilityinfo.html#isScreenReaderEnabled */ isScreenReaderEnabled: function(): Promise { return new Promise((resolve, reject) => { @@ -167,7 +167,7 @@ const AccessibilityInfo = { */ get fetch(): $FlowFixMe { console.warn( - 'AccessibilityInfo.fetch is deprecated, call AccessibilityInfo.isScreenReaderEnabled instead', + 'AccessibilityInfo.fetch is deprecated, call Accessibility.isScreenReaderEnabled instead', ); return this.isScreenReaderEnabled; }, @@ -201,7 +201,7 @@ const AccessibilityInfo = { * - `success`: A boolean indicating whether the announcement was * successfully made. * - * See https://reactnative.dev/docs/accessibilityinfo.html#addeventlistener + * See http://facebook.github.io/react-native/docs/accessibilityinfo.html#addeventlistener */ addEventListener: function( eventName: ChangeEventName, @@ -231,7 +231,7 @@ const AccessibilityInfo = { /** * Set accessibility focus to a react component. * - * See https://reactnative.dev/docs/accessibilityinfo.html#setaccessibilityfocus + * See http://facebook.github.io/react-native/docs/accessibilityinfo.html#setaccessibilityfocus */ setAccessibilityFocus: function(reactTag: number): void { if (NativeAccessibilityManager) { @@ -242,7 +242,7 @@ const AccessibilityInfo = { /** * Post a string to be announced by the screen reader. * - * See https://reactnative.dev/docs/accessibilityinfo.html#announceforaccessibility + * See http://facebook.github.io/react-native/docs/accessibilityinfo.html#announceforaccessibility */ announceForAccessibility: function(announcement: string): void { if (NativeAccessibilityManager) { @@ -253,7 +253,7 @@ const AccessibilityInfo = { /** * Remove an event handler. * - * See https://reactnative.dev/docs/accessibilityinfo.html#removeeventlistener + * See http://facebook.github.io/react-native/docs/accessibilityinfo.html#removeeventlistener */ removeEventListener: function( eventName: ChangeEventName, diff --git a/Libraries/Components/ActivityIndicator/ActivityIndicator.js b/Libraries/Components/ActivityIndicator/ActivityIndicator.js index 9d0df8f0a739e7..98c3c5313ebf29 100644 --- a/Libraries/Components/ActivityIndicator/ActivityIndicator.js +++ b/Libraries/Components/ActivityIndicator/ActivityIndicator.js @@ -16,7 +16,7 @@ const StyleSheet = require('../../StyleSheet/StyleSheet'); const View = require('../View/View'); import type {HostComponent} from '../../Renderer/shims/ReactNativeTypes'; import type {ViewProps} from '../View/ViewPropTypes'; -import type {ColorValue} from '../../StyleSheet/StyleSheetTypes'; +import type {NativeOrDynamicColorType} from '../../StyleSheet/NativeOrDynamicColorType'; // ]TODO(macOS ISS#2323203) const PlatformActivityIndicator = Platform.OS === 'android' @@ -31,7 +31,7 @@ type IOSProps = $ReadOnly<{| /** * Whether the indicator should hide when not animating (true by default). * - * See https://reactnative.dev/docs/activityindicator.html#hideswhenstopped + * See http://facebook.github.io/react-native/docs/activityindicator.html#hideswhenstopped */ hidesWhenStopped?: ?boolean, |}>; @@ -42,22 +42,22 @@ type Props = $ReadOnly<{| /** * Whether to show the indicator (true, the default) or hide it (false). * - * See https://reactnative.dev/docs/activityindicator.html#animating + * See http://facebook.github.io/react-native/docs/activityindicator.html#animating */ animating?: ?boolean, /** * The foreground color of the spinner (default is gray). * - * See https://reactnative.dev/docs/activityindicator.html#color + * See http://facebook.github.io/react-native/docs/activityindicator.html#color */ - color?: ?ColorValue, + color?: ?(string | NativeOrDynamicColorType), // TODO(macOS ISS#2323203) /** * Size of the indicator (default is 'small'). * Passing a number to the size prop is only supported on Android. * - * See https://reactnative.dev/docs/activityindicator.html#size + * See http://facebook.github.io/react-native/docs/activityindicator.html#size */ size?: ?IndicatorSize, |}>; @@ -65,7 +65,7 @@ type Props = $ReadOnly<{| /** * Displays a circular loading indicator. * - * See https://reactnative.dev/docs/activityindicator.html + * See http://facebook.github.io/react-native/docs/activityindicator.html */ const ActivityIndicator = (props: Props, forwardedRef?: any) => { const {onLayout, style, size, ...restProps} = props; diff --git a/Libraries/Components/ActivityIndicator/ActivityIndicatorViewNativeComponent.js b/Libraries/Components/ActivityIndicator/ActivityIndicatorViewNativeComponent.js index 37898d2607ae04..a91460f31fed94 100644 --- a/Libraries/Components/ActivityIndicator/ActivityIndicatorViewNativeComponent.js +++ b/Libraries/Components/ActivityIndicator/ActivityIndicatorViewNativeComponent.js @@ -24,21 +24,21 @@ type NativeProps = $ReadOnly<{| /** * Whether the indicator should hide when not animating (true by default). * - * See https://reactnative.dev/docs/activityindicator.html#hideswhenstopped + * See http://facebook.github.io/react-native/docs/activityindicator.html#hideswhenstopped */ hidesWhenStopped?: WithDefault, /** * Whether to show the indicator (true, the default) or hide it (false). * - * See https://reactnative.dev/docs/activityindicator.html#animating + * See http://facebook.github.io/react-native/docs/activityindicator.html#animating */ animating?: WithDefault, /** * The foreground color of the spinner (default is gray). * - * See https://reactnative.dev/docs/activityindicator.html#color + * See http://facebook.github.io/react-native/docs/activityindicator.html#color */ color?: ?ColorValue, @@ -46,7 +46,7 @@ type NativeProps = $ReadOnly<{| * Size of the indicator (default is 'small'). * Passing a number to the size prop is only supported on Android. * - * See https://reactnative.dev/docs/activityindicator.html#size + * See http://facebook.github.io/react-native/docs/activityindicator.html#size */ size?: WithDefault<'small' | 'large', 'small'>, |}>; diff --git a/Libraries/Components/Button.js b/Libraries/Components/Button.js index 73d32d1285fab0..3293d9a404c32d 100644 --- a/Libraries/Components/Button.js +++ b/Libraries/Components/Button.js @@ -22,7 +22,6 @@ const invariant = require('invariant'); import type {PressEvent} from '../Types/CoreEventTypes'; import type {FocusEvent, BlurEvent} from './TextInput/TextInput'; // TODO(OSS Candidate ISS#2710739) -import type {ColorValue} from '../StyleSheet/StyleSheetTypes'; type ButtonProps = $ReadOnly<{| /** @@ -43,7 +42,7 @@ type ButtonProps = $ReadOnly<{| /** * Color of the text (iOS), or background color of the button (Android) */ - color?: ?ColorValue, + color?: ?string, /** * TV preferred focus (see documentation for the View component). diff --git a/Libraries/Components/CheckBox/AndroidCheckBoxNativeComponent.js b/Libraries/Components/CheckBox/AndroidCheckBoxNativeComponent.js index 2afb9892690d05..29fd1d954a8d6a 100644 --- a/Libraries/Components/CheckBox/AndroidCheckBoxNativeComponent.js +++ b/Libraries/Components/CheckBox/AndroidCheckBoxNativeComponent.js @@ -19,7 +19,7 @@ const requireNativeComponent = require('../../ReactNative/requireNativeComponent import type {HostComponent} from '../../Renderer/shims/ReactNativeTypes'; import type {ViewProps} from '../View/ViewPropTypes'; import type {SyntheticEvent} from '../../Types/CoreEventTypes'; -import type {ProcessedColorValue} from '../../StyleSheet/processColor'; +import type {NativeOrDynamicColorType} from '../../StyleSheet/NativeOrDynamicColorType'; // TODO(macOS ISS#2323203) type CheckBoxEvent = SyntheticEvent< $ReadOnly<{| @@ -50,8 +50,8 @@ type NativeProps = $ReadOnly<{| enabled?: boolean, tintColors: | {| - true: ?ProcessedColorValue, - false: ?ProcessedColorValue, + true: ?(number | NativeOrDynamicColorType), // TODO(macOS ISS#2323203) + false: ?(number | NativeOrDynamicColorType), // TODO(macOS ISS#2323203) |} | typeof undefined, |}>; diff --git a/Libraries/Components/CheckBox/CheckBox.android.js b/Libraries/Components/CheckBox/CheckBox.android.js index aed9cd9eb389c4..b953fdc2a60ead 100644 --- a/Libraries/Components/CheckBox/CheckBox.android.js +++ b/Libraries/Components/CheckBox/CheckBox.android.js @@ -12,15 +12,12 @@ const React = require('react'); const StyleSheet = require('../../StyleSheet/StyleSheet'); -const invariant = require('invariant'); const processColor = require('../../StyleSheet/processColor'); const nullthrows = require('nullthrows'); const setAndForwardRef = require('../../Utilities/setAndForwardRef'); -import AndroidCheckBoxNativeComponent, { - Commands as AndroidCheckBoxCommands, -} from './AndroidCheckBoxNativeComponent'; +import AndroidCheckBoxNativeComponent from './AndroidCheckBoxNativeComponent'; import type {ViewProps} from '../View/ViewPropTypes'; import type {SyntheticEvent} from '../../Types/CoreEventTypes'; @@ -144,7 +141,7 @@ class CheckBox extends React.Component { _onChange = (event: CheckBoxEvent) => { const value = this.props.value ?? false; - AndroidCheckBoxCommands.setNativeValue(nullthrows(this._nativeRef), value); + nullthrows(this._nativeRef).setNativeProps({value: value}); // Change the props after the native props are set in case the props // change removes the component this.props.onChange && this.props.onChange(event); @@ -153,26 +150,12 @@ class CheckBox extends React.Component { }; _getTintColors(tintColors) { - if (tintColors) { - const processedTextColorTrue = processColor(tintColors.true); - invariant( - processedTextColorTrue == null || - typeof processedTextColorTrue === 'number', - 'Unexpected color given for tintColors.true', - ); - const processedTextColorFalse = processColor(tintColors.true); - invariant( - processedTextColorFalse == null || - typeof processedTextColorFalse === 'number', - 'Unexpected color given for tintColors.false', - ); - return { - true: processedTextColorTrue, - false: processedTextColorFalse, - }; - } else { - return undefined; - } + return tintColors + ? { + true: processColor(tintColors.true), + false: processColor(tintColors.false), + } + : undefined; } render() { diff --git a/Libraries/Components/DatePicker/RCTDatePickerNativeComponent.js b/Libraries/Components/DatePicker/RCTDatePickerNativeComponent.js index b569ae2bea5515..d4690e86945b43 100644 --- a/Libraries/Components/DatePicker/RCTDatePickerNativeComponent.js +++ b/Libraries/Components/DatePicker/RCTDatePickerNativeComponent.js @@ -11,6 +11,7 @@ 'use strict'; import type {HostComponent} from '../../Renderer/shims/ReactNativeTypes'; +import type {SyntheticEvent} from '../../Types/CoreEventTypes'; import type {ViewProps} from '../View/ViewPropTypes'; import codegenNativeCommands from 'react-native/Libraries/Utilities/codegenNativeCommands'; import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent'; diff --git a/Libraries/Components/DatePickerMacOS/RCTDatePickerNativeComponentMacOS.js b/Libraries/Components/DatePickerMacOS/RCTDatePickerNativeComponentMacOS.js index 0d6de69389714e..04ccdb8d78d061 100644 --- a/Libraries/Components/DatePickerMacOS/RCTDatePickerNativeComponentMacOS.js +++ b/Libraries/Components/DatePickerMacOS/RCTDatePickerNativeComponentMacOS.js @@ -16,7 +16,7 @@ const requireNativeComponent = require('../../ReactNative/requireNativeComponent import type {SyntheticEvent} from '../../Types/CoreEventTypes'; import type {ViewProps} from '../View/ViewPropTypes'; -import type {HostComponent} from '../../Renderer/shims/ReactNativeTypes'; +import type {NativeComponent} from '../../Renderer/shims/ReactNative'; type Event = SyntheticEvent< $ReadOnly<{| @@ -34,7 +34,7 @@ type NativeProps = $ReadOnly<{| pickerStyle?: ?['textfield-stepper', 'clock-calendar', 'textfield'], timeZoneOffsetInMinutes?: ?number, |}>; -type RCTDatePickerNativeType = HostComponent; +type RCTDatePickerNativeType = Class>; module.exports = ((requireNativeComponent( 'RCTDatePicker', diff --git a/Libraries/Components/DrawerAndroid/DrawerLayoutAndroid.android.js b/Libraries/Components/DrawerAndroid/DrawerLayoutAndroid.android.js index 3758c669fd1de6..b09f2fc8e8dd38 100644 --- a/Libraries/Components/DrawerAndroid/DrawerLayoutAndroid.android.js +++ b/Libraries/Components/DrawerAndroid/DrawerLayoutAndroid.android.js @@ -185,7 +185,7 @@ class DrawerLayoutAndroid extends React.Component { ...props } = this.props; const drawStatusBar = - Platform.Version >= 21 && this.props.statusBarBackgroundColor != null; + Platform.Version >= 21 && this.props.statusBarBackgroundColor; const drawerViewWrapper = ( ; type PickerItemSelectEvent = $ReadOnly<{| @@ -41,7 +41,6 @@ type NativeProps = $ReadOnly<{| // Props color?: ?ColorValue, - backgroundColor?: ?ColorValue, enabled?: WithDefault, items: $ReadOnlyArray, prompt?: WithDefault, diff --git a/Libraries/Components/Picker/AndroidDropdownPickerNativeComponent.js b/Libraries/Components/Picker/AndroidDropdownPickerNativeComponent.js index bf0b9e9ead63ec..e557859c322c2e 100644 --- a/Libraries/Components/Picker/AndroidDropdownPickerNativeComponent.js +++ b/Libraries/Components/Picker/AndroidDropdownPickerNativeComponent.js @@ -14,6 +14,7 @@ import * as React from 'react'; import codegenNativeCommands from '../../Utilities/codegenNativeCommands'; import requireNativeComponent from '../../ReactNative/requireNativeComponent'; +import type {NativeOrDynamicColorType} from '../../StyleSheet/NativeOrDynamicColorType'; // TODO(macOS ISS#2323203) import type { DirectEventHandler, @@ -23,12 +24,11 @@ import type { import type {HostComponent} from '../../Renderer/shims/ReactNativeTypes'; import type {TextStyleProp} from '../../StyleSheet/StyleSheet'; import type {ColorValue} from '../../StyleSheet/StyleSheetTypes'; -import type {ProcessedColorValue} from '../../StyleSheet/processColor'; import type {ViewProps} from '../../Components/View/ViewPropTypes'; type PickerItem = $ReadOnly<{| label: string, - color?: ?ProcessedColorValue, + color?: ?Int32 | ?NativeOrDynamicColorType, // TODO(macOS ISS#2323203) |}>; type PickerItemSelectEvent = $ReadOnly<{| @@ -41,7 +41,6 @@ type NativeProps = $ReadOnly<{| // Props color?: ?ColorValue, - backgroundColor?: ?ColorValue, enabled?: WithDefault, items: $ReadOnlyArray, prompt?: WithDefault, diff --git a/Libraries/Components/Picker/Picker.js b/Libraries/Components/Picker/Picker.js index edac8099e960a1..9547b2850632f9 100644 --- a/Libraries/Components/Picker/Picker.js +++ b/Libraries/Components/Picker/Picker.js @@ -96,12 +96,6 @@ type PickerProps = $ReadOnly<{| */ itemStyle?: ?TextStyleProp, - /** - * Color of the item background. - * @platform android - */ - backgroundColor?: ColorValue, - /** * Prompt string for this picker, used on Android in dialog mode as the title of the dialog. * @platform android @@ -112,10 +106,6 @@ type PickerProps = $ReadOnly<{| * Used to locate this view in end-to-end tests. */ testID?: ?string, - /** - * The string used for the accessibility label. Will be read once focused on the picker but not on change. - */ - accessibilityLabel?: ?string, |}>; /** diff --git a/Libraries/Components/Picker/PickerAndroid.android.js b/Libraries/Components/Picker/PickerAndroid.android.js index a47d29bd5ec6a7..4fddefb8014887 100644 --- a/Libraries/Components/Picker/PickerAndroid.android.js +++ b/Libraries/Components/Picker/PickerAndroid.android.js @@ -10,18 +10,12 @@ 'use strict'; -import AndroidDropdownPickerNativeComponent, { - Commands as AndroidDropdownPickerCommands, -} from './AndroidDropdownPickerNativeComponent'; -import AndroidDialogPickerNativeComponent, { - Commands as AndroidDialogPickerCommands, -} from './AndroidDialogPickerNativeComponent'; +import AndroidDropdownPickerNativeComponent from './AndroidDropdownPickerNativeComponent'; +import AndroidDialogPickerNativeComponent from './AndroidDialogPickerNativeComponent'; import * as React from 'react'; import StyleSheet from '../../StyleSheet/StyleSheet'; -import invariant from 'invariant'; import processColor from '../../StyleSheet/processColor'; -import type {ColorValue} from '../../StyleSheet/StyleSheetTypes'; import type {SyntheticEvent} from '../../Types/CoreEventTypes'; import type {TextStyleProp} from '../../StyleSheet/StyleSheet'; @@ -37,7 +31,6 @@ type Props = $ReadOnly<{| accessibilityLabel?: ?Stringish, children?: React.Node, style?: ?TextStyleProp, - backgroundColor?: ?ColorValue, selectedValue?: ?PickerItemValue, enabled?: ?boolean, mode?: ?('dialog' | 'dropdown'), @@ -64,13 +57,8 @@ function PickerAndroid(props: Props): React.Node { selected = index; } const {color, label} = child.props; - const processedColor = processColor(color); - invariant( - processedColor == null || typeof processedColor === 'number', - 'Unexpected color given for PickerAndroid color prop', - ); return { - color: color == null ? null : processedColor, + color: color == null ? null : processColor(color), label, }; }); @@ -95,22 +83,13 @@ function PickerAndroid(props: Props): React.Node { onValueChange(null, position); } } + const {current} = pickerRef; if (current != null && position !== selected) { - const Commands = - props.mode === 'dropdown' - ? AndroidDropdownPickerCommands - : AndroidDialogPickerCommands; - Commands.setNativeSelectedPosition(current, selected); + current.setNativeProps({selected}); } }, - [ - props.children, - props.onValueChange, - props.selectedValue, - props.mode, - selected, - ], + [props.children, props.onValueChange, props.selectedValue, selected], ); const rootProps = { @@ -125,7 +104,6 @@ function PickerAndroid(props: Props): React.Node { styles.pickerAndroid, props.style, ), - backgroundColor: props.backgroundColor, testID: props.testID, }; return props.mode === 'dropdown' ? ( diff --git a/Libraries/Components/Picker/PickerIOS.ios.js b/Libraries/Components/Picker/PickerIOS.ios.js index 9cdacdf3c86eac..90296128e6b279 100644 --- a/Libraries/Components/Picker/PickerIOS.ios.js +++ b/Libraries/Components/Picker/PickerIOS.ios.js @@ -16,8 +16,6 @@ const React = require('react'); const StyleSheet = require('../../StyleSheet/StyleSheet'); const View = require('../View/View'); const Platform = require('../../Utilities/Platform'); // TODO(macOS ISS#2323203) - -const invariant = require('invariant'); const processColor = require('../../StyleSheet/processColor'); import RCTPickerNativeComponent, { @@ -25,9 +23,9 @@ import RCTPickerNativeComponent, { } from './RCTPickerNativeComponent'; import type {TextStyleProp} from '../../StyleSheet/StyleSheet'; import type {ColorValue} from '../../StyleSheet/StyleSheetTypes'; -import type {ProcessedColorValue} from '../../StyleSheet/processColor'; import type {SyntheticEvent} from '../../Types/CoreEventTypes'; import type {ViewProps} from '../View/ViewPropTypes'; +import type {NativeOrDynamicColorType} from '../../StyleSheet/NativeOrDynamicColorType'; // TODO(macOS ISS#2323203) type PickerIOSChangeEvent = SyntheticEvent< $ReadOnly<{| @@ -39,7 +37,7 @@ type PickerIOSChangeEvent = SyntheticEvent< type RCTPickerIOSItemType = $ReadOnly<{| label: ?Label, value: ?(number | string), - textColor: ?ProcessedColorValue, + textColor: ?(number | NativeOrDynamicColorType), // TODO(macOS ISS#2323203) |}>; type Label = Stringish | number; @@ -51,7 +49,6 @@ type Props = $ReadOnly<{| onChange?: ?(event: PickerIOSChangeEvent) => mixed, onValueChange?: ?(itemValue: string | number, itemIndex: number) => mixed, selectedValue: ?(number | string), - accessibilityLabel?: ?string, |}>; type State = {| @@ -89,15 +86,10 @@ class PickerIOS extends React.Component { if (child.props.value === props.selectedValue) { selectedIndex = index; } - const processedTextColor = processColor(child.props.color); - invariant( - processedTextColor == null || typeof processedTextColor === 'number', - 'Unexpected color given for PickerIOSItem color', - ); items.push({ value: child.props.value, label: child.props.label, - textColor: processedTextColor, + textColor: processColor(child.props.color), }); }); return {selectedIndex, items}; @@ -115,7 +107,6 @@ class PickerIOS extends React.Component { items={this.state.items} selectedIndex={this.state.selectedIndex} onChange={this._onChange} - accessibilityLabel={this.props.accessibilityLabel} /> ); diff --git a/Libraries/Components/Picker/RCTPickerNativeComponent.js b/Libraries/Components/Picker/RCTPickerNativeComponent.js index ca42471b6025ce..ab95ab8aa81a3a 100644 --- a/Libraries/Components/Picker/RCTPickerNativeComponent.js +++ b/Libraries/Components/Picker/RCTPickerNativeComponent.js @@ -15,9 +15,9 @@ const requireNativeComponent = require('../../ReactNative/requireNativeComponent import type {HostComponent} from '../../Renderer/shims/ReactNativeTypes'; import type {SyntheticEvent} from '../../Types/CoreEventTypes'; import type {TextStyleProp} from '../../StyleSheet/StyleSheet'; -import type {ProcessedColorValue} from '../../StyleSheet/processColor'; import codegenNativeCommands from '../../Utilities/codegenNativeCommands'; import * as React from 'react'; +import type {NativeOrDynamicColorType} from '../../StyleSheet/NativeOrDynamicColorType'; // ]TODO(macOS ISS#2323203) type PickerIOSChangeEvent = SyntheticEvent< $ReadOnly<{| @@ -29,7 +29,7 @@ type PickerIOSChangeEvent = SyntheticEvent< type RCTPickerIOSItemType = $ReadOnly<{| label: ?Label, value: ?(number | string), - textColor: ?ProcessedColorValue, + textColor: ?(number | NativeOrDynamicColorType), // TODO(macOS ISS#2323203) |}>; type Label = Stringish | number; @@ -40,7 +40,6 @@ type NativeProps = $ReadOnly<{| selectedIndex: number, style?: ?TextStyleProp, testID?: ?string, - accessibilityLabel?: ?string, |}>; type ComponentType = HostComponent; diff --git a/Libraries/Components/Pressable/Pressable.js b/Libraries/Components/Pressable/Pressable.js deleted file mode 100644 index c35c9e3337a6d3..00000000000000 --- a/Libraries/Components/Pressable/Pressable.js +++ /dev/null @@ -1,240 +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. - * - * @flow strict-local - * @format - */ - -'use strict'; - -import * as React from 'react'; -import {useMemo, useState, useRef, useImperativeHandle} from 'react'; -import useAndroidRippleForView, { - type RippleConfig, -} from './useAndroidRippleForView'; -import type { - AccessibilityActionEvent, - AccessibilityActionInfo, - AccessibilityRole, - AccessibilityState, - AccessibilityValue, -} from '../View/ViewAccessibility'; -import {PressabilityDebugView} from '../../Pressability/PressabilityDebug'; -import usePressability from '../../Pressability/usePressability'; -import {normalizeRect, type RectOrSize} from '../../StyleSheet/Rect'; -import type {ColorValue} from '../../StyleSheet/StyleSheetTypes'; -import type {LayoutEvent, PressEvent} from '../../Types/CoreEventTypes'; -import View from '../View/View'; - -type ViewStyleProp = $ElementType, 'style'>; - -export type StateCallbackType = $ReadOnly<{| - pressed: boolean, -|}>; - -type Props = $ReadOnly<{| - /** - * Accessibility. - */ - accessibilityActions?: ?$ReadOnlyArray, - accessibilityElementsHidden?: ?boolean, - accessibilityHint?: ?Stringish, - accessibilityIgnoresInvertColors?: ?boolean, - accessibilityLabel?: ?Stringish, - accessibilityLiveRegion?: ?('none' | 'polite' | 'assertive'), - accessibilityRole?: ?AccessibilityRole, - accessibilityState?: ?AccessibilityState, - accessibilityValue?: ?AccessibilityValue, - accessibilityViewIsModal?: ?boolean, - accessible?: ?boolean, - focusable?: ?boolean, - importantForAccessibility?: ?('auto' | 'yes' | 'no' | 'no-hide-descendants'), - onAccessibilityAction?: ?(event: AccessibilityActionEvent) => mixed, - - /** - * Either children or a render prop that receives a boolean reflecting whether - * the component is currently pressed. - */ - children: React.Node | ((state: StateCallbackType) => React.Node), - - /** - * Duration (in milliseconds) from `onPressIn` before `onLongPress` is called. - */ - delayLongPress?: ?number, - - /** - * Whether the press behavior is disabled. - */ - disabled?: ?boolean, - - /** - * Additional distance outside of this view in which a press is detected. - */ - hitSlop?: ?RectOrSize, - - /** - * Additional distance outside of this view in which a touch is considered a - * press before `onPressOut` is triggered. - */ - pressRetentionOffset?: ?RectOrSize, - - /** - * Called when this view's layout changes. - */ - onLayout?: ?(event: LayoutEvent) => void, - - /** - * Called when a long-tap gesture is detected. - */ - onLongPress?: ?(event: PressEvent) => void, - - /** - * Called when a single tap gesture is detected. - */ - onPress?: ?(event: PressEvent) => void, - - /** - * Called when a touch is engaged before `onPress`. - */ - onPressIn?: ?(event: PressEvent) => void, - - /** - * Called when a touch is released before `onPress`. - */ - onPressOut?: ?(event: PressEvent) => void, - - /** - * Either view styles or a function that receives a boolean reflecting whether - * the component is currently pressed and returns view styles. - */ - style?: ViewStyleProp | ((state: StateCallbackType) => ViewStyleProp), - - /** - * Identifier used to find this view in tests. - */ - testID?: ?string, - - /** - * If true, doesn't play system sound on touch. - */ - android_disableSound?: ?boolean, - - /** - * Enables the Android ripple effect and configures its color. - */ - android_ripple?: ?RippleConfig, - - /** - * Used only for documentation or testing (e.g. snapshot testing). - */ - testOnly_pressed?: ?boolean, -|}>; - -/** - * Component used to build display components that should respond to whether the - * component is currently pressed or not. - */ -function Pressable(props: Props, forwardedRef): React.Node { - const { - accessible, - android_disableSound, - android_ripple, - children, - delayLongPress, - disabled, - focusable, - onLongPress, - onPress, - onPressIn, - onPressOut, - pressRetentionOffset, - style, - testOnly_pressed, - ...restProps - } = props; - - const viewRef = useRef | null>(null); - useImperativeHandle(forwardedRef, () => viewRef.current); - - const android_rippleConfig = useAndroidRippleForView(android_ripple, viewRef); - - const [pressed, setPressed] = usePressState(testOnly_pressed === true); - - const hitSlop = normalizeRect(props.hitSlop); - - const config = useMemo( - () => ({ - disabled, - hitSlop, - pressRectOffset: pressRetentionOffset, - android_disableSound, - delayLongPress, - onLongPress, - onPress, - onPressIn(event: PressEvent): void { - if (android_rippleConfig != null) { - android_rippleConfig.onPressIn(event); - } - setPressed(true); - if (onPressIn != null) { - onPressIn(event); - } - }, - onPressMove: android_rippleConfig?.onPressMove, - onPressOut(event: PressEvent): void { - if (android_rippleConfig != null) { - android_rippleConfig.onPressOut(event); - } - setPressed(false); - if (onPressOut != null) { - onPressOut(event); - } - }, - }), - [ - android_disableSound, - android_rippleConfig, - delayLongPress, - disabled, - hitSlop, - onLongPress, - onPress, - onPressIn, - onPressOut, - pressRetentionOffset, - setPressed, - ], - ); - const eventHandlers = usePressability(config); - - return ( - - {typeof children === 'function' ? children({pressed}) : children} - {__DEV__ ? : null} - - ); -} - -function usePressState(forcePressed: boolean): [boolean, (boolean) => void] { - const [pressed, setPressed] = useState(false); - return [pressed || forcePressed, setPressed]; -} - -const MemoedPressable = React.memo(React.forwardRef(Pressable)); -MemoedPressable.displayName = 'Pressable'; - -export default (MemoedPressable: React.AbstractComponent< - Props, - React.ElementRef, ->); diff --git a/Libraries/Components/Pressable/__tests__/Pressable-test.js b/Libraries/Components/Pressable/__tests__/Pressable-test.js deleted file mode 100644 index a8c5af535e8518..00000000000000 --- a/Libraries/Components/Pressable/__tests__/Pressable-test.js +++ /dev/null @@ -1,34 +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. - * - * @format - * @emails oncall+react_native - * @flow strict-local - */ - -'use strict'; - -import * as React from 'react'; - -import Pressable from '../Pressable'; -import View from '../../View/View'; -import {expectRendersMatchingSnapshot} from '../../../Utilities/ReactNativeTestTools'; - -describe('', () => { - it('should render as expected', () => { - expectRendersMatchingSnapshot( - 'Pressable', - () => ( - - - - ), - () => { - jest.dontMock('../Pressable'); - }, - ); - }); -}); diff --git a/Libraries/Components/Pressable/__tests__/__snapshots__/Pressable-test.js.snap b/Libraries/Components/Pressable/__tests__/__snapshots__/Pressable-test.js.snap deleted file mode 100644 index 5c82f9ab1c7e67..00000000000000 --- a/Libraries/Components/Pressable/__tests__/__snapshots__/Pressable-test.js.snap +++ /dev/null @@ -1,49 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[` should render as expected: should deep render when mocked (please verify output manually) 1`] = ` - - - -`; - -exports[` should render as expected: should deep render when not mocked (please verify output manually) 1`] = ` - - - -`; - -exports[` should render as expected: should shallow render as when mocked 1`] = ` - - - -`; - -exports[` should render as expected: should shallow render as when not mocked 1`] = ` - - - -`; diff --git a/Libraries/Components/Pressable/useAndroidRippleForView.js b/Libraries/Components/Pressable/useAndroidRippleForView.js deleted file mode 100644 index 44972fb860f669..00000000000000 --- a/Libraries/Components/Pressable/useAndroidRippleForView.js +++ /dev/null @@ -1,105 +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. - * - * @flow strict-local - * @format - */ - -'use strict'; - -import invariant from 'invariant'; -import {Commands} from '../View/ViewNativeComponent'; -import type {ColorValue} from '../../StyleSheet/StyleSheetTypes'; -import type {PressEvent} from '../../Types/CoreEventTypes'; -import {Platform, View, processColor} from 'react-native'; -import * as React from 'react'; -import {useMemo} from 'react'; - -type NativeBackgroundProp = $ReadOnly<{| - type: 'RippleAndroid', - color: ?number, - borderless: boolean, - rippleRadius: ?number, -|}>; - -export type RippleConfig = {| - color?: ?ColorValue, - borderless?: ?boolean, - radius?: ?number, -|}; - -/** - * Provides the event handlers and props for configuring the ripple effect on - * supported versions of Android. - */ -export default function useAndroidRippleForView( - rippleConfig: ?RippleConfig, - viewRef: {|current: null | React.ElementRef|}, -): ?$ReadOnly<{| - onPressIn: (event: PressEvent) => void, - onPressMove: (event: PressEvent) => void, - onPressOut: (event: PressEvent) => void, - viewProps: $ReadOnly<{| - nativeBackgroundAndroid: NativeBackgroundProp, - |}>, -|}> { - const {color, borderless, radius} = rippleConfig ?? {}; - const normalizedBorderless = borderless === true; - - return useMemo(() => { - if ( - Platform.OS === 'android' && - Platform.Version >= 21 && - (color != null || normalizedBorderless || radius != null) - ) { - const processedColor = processColor(color); - invariant( - processedColor == null || typeof processedColor === 'number', - 'Unexpected color given for Ripple color', - ); - - return { - viewProps: { - // Consider supporting `nativeForegroundAndroid` - nativeBackgroundAndroid: { - type: 'RippleAndroid', - color: processedColor, - borderless: normalizedBorderless, - rippleRadius: radius, - }, - }, - onPressIn(event: PressEvent): void { - const view = viewRef.current; - if (view != null) { - Commands.setPressed(view, true); - Commands.hotspotUpdate( - view, - event.nativeEvent.locationX ?? 0, - event.nativeEvent.locationY ?? 0, - ); - } - }, - onPressMove(event: PressEvent): void { - const view = viewRef.current; - if (view != null) { - Commands.hotspotUpdate( - view, - event.nativeEvent.locationX ?? 0, - event.nativeEvent.locationY ?? 0, - ); - } - }, - onPressOut(event: PressEvent): void { - const view = viewRef.current; - if (view != null) { - Commands.setPressed(view, false); - } - }, - }; - } - return null; - }, [color, normalizedBorderless, radius, viewRef]); -} diff --git a/Libraries/Components/ProgressBarAndroid/ProgressBarAndroid.android.js b/Libraries/Components/ProgressBarAndroid/ProgressBarAndroid.android.js index 7b10a0521522f1..a2651088bbdc39 100644 --- a/Libraries/Components/ProgressBarAndroid/ProgressBarAndroid.android.js +++ b/Libraries/Components/ProgressBarAndroid/ProgressBarAndroid.android.js @@ -15,7 +15,6 @@ const React = require('react'); import ProgressBarAndroidNativeComponent from './ProgressBarAndroidNativeComponent'; import type {ViewProps} from '../View/ViewPropTypes'; -import type {ColorValue} from '../../StyleSheet/StyleSheetTypes'; export type ProgressBarAndroidProps = $ReadOnly<{| ...ViewProps, @@ -50,7 +49,7 @@ export type ProgressBarAndroidProps = $ReadOnly<{| /** * Color of the progress bar. */ - color?: ?ColorValue, + color?: ?string, /** * Used to locate this view in end-to-end tests. */ diff --git a/Libraries/Components/RefreshControl/PullToRefreshViewNativeComponent.js b/Libraries/Components/RefreshControl/PullToRefreshViewNativeComponent.js index 8134b8a486fd7e..553a3a46ba0603 100644 --- a/Libraries/Components/RefreshControl/PullToRefreshViewNativeComponent.js +++ b/Libraries/Components/RefreshControl/PullToRefreshViewNativeComponent.js @@ -61,5 +61,4 @@ export const Commands: NativeCommands = codegenNativeCommands({ export default (codegenNativeComponent('PullToRefreshView', { paperComponentName: 'RCTRefreshControl', - excludedPlatform: 'android', }): HostComponent); diff --git a/Libraries/Components/RefreshControl/RefreshControl.js b/Libraries/Components/RefreshControl/RefreshControl.js index f3ffa4980d4fe3..43ebf012308822 100644 --- a/Libraries/Components/RefreshControl/RefreshControl.js +++ b/Libraries/Components/RefreshControl/RefreshControl.js @@ -15,12 +15,8 @@ const React = require('react'); import type {ColorValue} from '../../StyleSheet/StyleSheetTypes'; import type {ViewProps} from '../View/ViewPropTypes'; -import AndroidSwipeRefreshLayoutNativeComponent, { - Commands as AndroidSwipeRefreshLayoutCommands, -} from './AndroidSwipeRefreshLayoutNativeComponent'; -import PullToRefreshViewNativeComponent, { - Commands as PullToRefreshCommands, -} from './PullToRefreshViewNativeComponent'; +import AndroidSwipeRefreshLayoutNativeComponent from './AndroidSwipeRefreshLayoutNativeComponent'; +import PullToRefreshViewNativeComponent from './PullToRefreshViewNativeComponent'; let RefreshLayoutConsts: any; if (Platform.OS === 'android') { @@ -83,7 +79,7 @@ export type RefreshControlProps = $ReadOnly<{| /** * Called when the view starts refreshing. */ - onRefresh?: ?() => void | Promise, + onRefresh?: ?() => void, /** * Whether the view should be indicating an active refresh. @@ -139,10 +135,7 @@ export type RefreshControlProps = $ReadOnly<{| class RefreshControl extends React.Component { static SIZE: any = RefreshLayoutConsts.SIZE; - _nativeRef: ?React.ElementRef< - | typeof PullToRefreshViewNativeComponent - | typeof AndroidSwipeRefreshLayoutNativeComponent, - >; + _setNativePropsOnRef: ?({refreshing: boolean, ...}) => void; _lastNativeRefreshing = false; componentDidMount() { @@ -157,24 +150,18 @@ class RefreshControl extends React.Component { this._lastNativeRefreshing = this.props.refreshing; } else if ( this.props.refreshing !== this._lastNativeRefreshing && - this._nativeRef + this._setNativePropsOnRef ) { - if (Platform.OS === 'android') { - AndroidSwipeRefreshLayoutCommands.setNativeRefreshing( - this._nativeRef, - this.props.refreshing, - ); - } else { - PullToRefreshCommands.setNativeRefreshing( - this._nativeRef, - this.props.refreshing, - ); - } + this._setNativePropsOnRef({ + refreshing: this.props.refreshing, + }); this._lastNativeRefreshing = this.props.refreshing; } } render(): React.Node { + const setRef = ref => + (this._setNativePropsOnRef = ref ? ref.setNativeProps.bind(ref) : null); if (Platform.OS === 'ios') { const { enabled, @@ -187,7 +174,7 @@ class RefreshControl extends React.Component { return ( ); @@ -196,7 +183,7 @@ class RefreshControl extends React.Component { return ( ); @@ -212,15 +199,6 @@ class RefreshControl extends React.Component { // make sure it stays in sync with the js component. this.forceUpdate(); }; - - _setNativeRef = ( - ref: ?React.ElementRef< - | typeof PullToRefreshViewNativeComponent - | typeof AndroidSwipeRefreshLayoutNativeComponent, - >, - ) => { - this._nativeRef = ref; - }; } module.exports = RefreshControl; diff --git a/Libraries/Components/ScrollResponder.js b/Libraries/Components/ScrollResponder.js index a520d17d2875fd..fe8652ca65c016 100644 --- a/Libraries/Components/ScrollResponder.js +++ b/Libraries/Components/ScrollResponder.js @@ -183,12 +183,12 @@ const ScrollResponderMixin = { return false; } - const currentlyFocusedInput = TextInputState.currentlyFocusedInput(); + const currentlyFocusedTextInput = TextInputState.currentlyFocusedField(); if ( this.props.keyboardShouldPersistTaps === 'handled' && - currentlyFocusedInput != null && - e.target !== currentlyFocusedInput + currentlyFocusedTextInput != null && + ReactNative.findNodeHandle(e.target) !== currentlyFocusedTextInput ) { return true; } @@ -224,26 +224,17 @@ const ScrollResponderMixin = { // and a new touch starts with a non-textinput target (in which case the // first tap should be sent to the scroll view and dismiss the keyboard, // then the second tap goes to the actual interior view) - const currentlyFocusedTextInput = TextInputState.currentlyFocusedInput(); + const currentlyFocusedTextInput = TextInputState.currentlyFocusedField(); const {keyboardShouldPersistTaps} = this.props; const keyboardNeverPersistTaps = !keyboardShouldPersistTaps || keyboardShouldPersistTaps === 'never'; - if (typeof e.target === 'number') { - if (__DEV__) { - console.error( - 'Did not expect event target to be a number. Should have been a native component', - ); - } - - return false; - } - + const reactTag = ReactNative.findNodeHandle(e.target); if ( keyboardNeverPersistTaps && currentlyFocusedTextInput != null && - e.target != null && - !TextInputState.isTextInput(e.target) + reactTag && + !TextInputState.isTextInput(reactTag) ) { return true; } @@ -309,24 +300,14 @@ const ScrollResponderMixin = { scrollResponderHandleResponderRelease: function(e: PressEvent) { this.props.onResponderRelease && this.props.onResponderRelease(e); - if (typeof e.target === 'number') { - if (__DEV__) { - console.error( - 'Did not expect event target to be a number. Should have been a native component', - ); - } - - return; - } - // By default scroll views will unfocus a textField // if another touch occurs outside of it - const currentlyFocusedTextInput = TextInputState.currentlyFocusedInput(); + const currentlyFocusedTextInput = TextInputState.currentlyFocusedField(); if ( this.props.keyboardShouldPersistTaps !== true && this.props.keyboardShouldPersistTaps !== 'always' && currentlyFocusedTextInput != null && - e.target !== currentlyFocusedTextInput && + ReactNative.findNodeHandle(e.target) !== currentlyFocusedTextInput && !this.state.observedScrollSinceBecomingResponder && !this.state.becameResponderWhileAnimating ) { @@ -589,7 +570,10 @@ const ScrollResponderMixin = { * down to make it meet the keyboard's top. Default is false. */ scrollResponderScrollNativeHandleToKeyboard: function( - nodeHandle: number | React.ElementRef>, + nodeHandle: + | number + | React.ElementRef> + | React.ElementRef>>, additionalOffset?: number, preventNegativeScrollOffset?: boolean, ) { diff --git a/Libraries/Components/ScrollView/ScrollView.js b/Libraries/Components/ScrollView/ScrollView.js index fe43061b80826a..dc4cfa04ea7a2b 100644 --- a/Libraries/Components/ScrollView/ScrollView.js +++ b/Libraries/Components/ScrollView/ScrollView.js @@ -24,9 +24,9 @@ const dismissKeyboard = require('../../Utilities/dismissKeyboard'); const flattenStyle = require('../../StyleSheet/flattenStyle'); const invariant = require('invariant'); const processDecelerationRate = require('./processDecelerationRate'); +const requireNativeComponent = require('../../ReactNative/requireNativeComponent'); const resolveAssetSource = require('../../Image/resolveAssetSource'); const splitLayoutProps = require('../../StyleSheet/splitLayoutProps'); -const setAndForwardRef = require('../../Utilities/setAndForwardRef'); import type {EdgeInsetsProp} from '../../StyleSheet/EdgeInsetsPropType'; import type {PointProp} from '../../StyleSheet/PointPropType'; @@ -63,31 +63,25 @@ if (Platform.OS === 'android') { ) { RCTScrollView = ScrollViewNativeComponent; RCTScrollContentView = ScrollContentViewNativeComponent; +} else { + RCTScrollView = requireNativeComponent('RCTScrollView'); + RCTScrollContentView = requireNativeComponent('RCTScrollContentView'); } -// Public methods for ScrollView -export type ScrollViewImperativeMethods = $ReadOnly<{| - getScrollResponder: $PropertyType, +export type ScrollResponderType = { + // We'd like to do ...ScrollView here, however Flow doesn't seem + // to see the imperative methods of ScrollView that way. Workaround the + // issue by specifying them manually. getScrollableNode: $PropertyType, getInnerViewNode: $PropertyType, getInnerViewRef: $PropertyType, getNativeScrollRef: $PropertyType, + setNativeProps: $PropertyType, scrollTo: $PropertyType, - scrollToEnd: $PropertyType, flashScrollIndicators: $PropertyType, - - // ScrollResponder.Mixin public methods - scrollResponderZoomTo: $PropertyType< - typeof ScrollResponder.Mixin, - 'scrollResponderZoomTo', - >, - scrollResponderScrollNativeHandleToKeyboard: $PropertyType< - typeof ScrollResponder.Mixin, - 'scrollResponderScrollNativeHandleToKeyboard', - >, -|}>; - -export type ScrollResponderType = ScrollViewImperativeMethods; + ...typeof ScrollResponder.Mixin, + ... +}; type IOSProps = $ReadOnly<{| /** @@ -424,8 +418,8 @@ export type Props = $ReadOnly<{| /** * When true, the scroll view stops on the next index (in relation to scroll * position at release) regardless of how fast the gesture is. This can be - * used for pagination when the page is less than the width of the - * horizontal ScrollView or the height of the vertical ScrollView. The default value is false. + * used for horizontal pagination when the page is less than the width of + * the ScrollView. The default value is false. */ disableIntervalMomentum?: ?boolean, /** @@ -602,19 +596,6 @@ export type Props = $ReadOnly<{| // $FlowFixMe - how to handle generic type without existential operator? refreshControl?: ?React.Element, children?: React.Node, - /** - * A ref to the inner View element of the ScrollView. This should be used - * instead of calling `getInnerViewRef`. - */ - innerViewRef?: React.Ref, - /** - * A ref to the Native ScrollView component. This ref can be used to call - * all of ScrollView's public methods, in addition to native methods like - * measure, measureLayout, etc. - */ - scrollViewRef?: React.Ref< - typeof ScrollViewNativeComponent & ScrollViewImperativeMethods, - >, |}>; type State = {| @@ -638,14 +619,11 @@ function createScrollResponder( } type ContextType = {|horizontal: boolean|} | null; -const Context: React.Context = React.createContext(null); +const Context = React.createContext(null); const standardHorizontalContext: ContextType = Object.freeze({ horizontal: true, }); const standardVerticalContext: ContextType = Object.freeze({horizontal: false}); -type ScrollViewComponentStatics = $ReadOnly<{| - Context: typeof Context, -|}>; /** * Component that wraps platform ScrollView while providing @@ -663,7 +641,7 @@ type ScrollViewComponentStatics = $ReadOnly<{| * view from becoming the responder. * * - * `` vs [``](https://reactnative.dev/docs/flatlist.html) - which one to use? + * `` vs [``](/react-native/docs/flatlist.html) - which one to use? * * `ScrollView` simply renders all its react child components at once. That * makes it very easy to understand and use. @@ -755,9 +733,11 @@ class ScrollView extends React.Component { UNSAFE_componentWillMount() { this._scrollResponder.UNSAFE_componentWillMount(); this._scrollAnimatedValue = new AnimatedImplementation.Value( - this.props.contentOffset?.y ?? 0, + this.props.contentOffset ? this.props.contentOffset.y : 0, + ); + this._scrollAnimatedValue.setOffset( + this.props.contentInset ? this.props.contentInset.top || 0 : 0, ); - this._scrollAnimatedValue.setOffset(this.props.contentInset?.top ?? 0); this._stickyHeaderRefs = new Map(); this._headerLayoutYs = new Map(); } @@ -789,37 +769,9 @@ class ScrollView extends React.Component { } } - _setNativeRef = setAndForwardRef({ - getForwardedRef: () => this.props.scrollViewRef, - setLocalRef: ref => { - this._scrollViewRef = ref; - - /* - This is a hack. Ideally we would forwardRef to the underlying - host component. However, since ScrollView has it's own methods that can be - called as well, if we used the standard forwardRef then these - methods wouldn't be accessible and thus be a breaking change. - - Therefore we edit ref to include ScrollView's public methods so that - they are callable from the ref. - */ - if (ref) { - ref.getScrollResponder = this.getScrollResponder; - ref.getScrollableNode = this.getScrollableNode; - ref.getInnerViewNode = this.getInnerViewNode; - ref.getInnerViewRef = this.getInnerViewRef; - ref.getNativeScrollRef = this.getNativeScrollRef; - ref.scrollTo = this.scrollTo; - ref.scrollToEnd = this.scrollToEnd; - ref.flashScrollIndicators = this.flashScrollIndicators; - - // $FlowFixMe - This method was manually bound from ScrollResponder.mixin - ref.scrollResponderZoomTo = this.scrollResponderZoomTo; - // $FlowFixMe - This method was manually bound from ScrollResponder.mixin - ref.scrollResponderScrollNativeHandleToKeyboard = this.scrollResponderScrollNativeHandleToKeyboard; - } - }, - }); + setNativeProps(props: {[key: string]: mixed, ...}) { + this._scrollViewRef && this._scrollViewRef.setNativeProps(props); + } /** * Returns a reference to the underlying scroll responder, which supports @@ -827,26 +779,26 @@ class ScrollView extends React.Component { * implement this method so that they can be composed while providing access * to the underlying scroll responder's methods. */ - getScrollResponder: () => ScrollResponderType = () => { + getScrollResponder(): ScrollResponderType { // $FlowFixMe - overriding type to include ScrollResponder.Mixin return ((this: any): ScrollResponderType); - }; + } - getScrollableNode: () => ?number = () => { + getScrollableNode(): ?number { return ReactNative.findNodeHandle(this._scrollViewRef); - }; + } getInnerViewNode(): ?number { return ReactNative.findNodeHandle(this._innerViewRef); } - getInnerViewRef(): ?React.ElementRef { + getInnerViewRef(): ?React.ElementRef> { return this._innerViewRef; } - getNativeScrollRef: () => ?React.ElementRef> = () => { + getNativeScrollRef(): ?React.ElementRef> { return this._scrollViewRef; - }; + } /** * Scrolls to a given x, y offset, either immediately or with a smooth animation. @@ -859,7 +811,7 @@ class ScrollView extends React.Component { * the function also accepts separate arguments as an alternative to the options object. * This is deprecated due to ambiguity (y before x), and SHOULD NOT BE USED. */ - scrollTo: ( + scrollTo( options?: | { x?: number, @@ -870,18 +822,7 @@ class ScrollView extends React.Component { | number, deprecatedX?: number, deprecatedAnimated?: boolean, - ) => void = ( - options?: - | { - x?: number, - y?: number, - animated?: boolean, - ... - } - | number, - deprecatedX?: number, - deprecatedAnimated?: boolean, - ) => { + ) { let x, y, animated; if (typeof options === 'number') { console.warn( @@ -901,7 +842,7 @@ class ScrollView extends React.Component { y: y || 0, animated: animated !== false, }); - }; + } /** * If this is a vertical ScrollView scrolls to the bottom. @@ -911,24 +852,22 @@ class ScrollView extends React.Component { * `scrollToEnd({animated: false})` for immediate scrolling. * If no options are passed, `animated` defaults to true. */ - scrollToEnd: (options?: ?{animated?: boolean, ...}) => void = ( - options?: ?{animated?: boolean, ...}, - ) => { + scrollToEnd(options?: ?{animated?: boolean, ...}) { // Default to true const animated = (options && options.animated) !== false; this._scrollResponder.scrollResponderScrollToEnd({ animated: animated, }); - }; + } /** * Displays the scroll indicators momentarily. * * @platform ios */ - flashScrollIndicators: () => void = () => { + flashScrollIndicators() { this._scrollResponder.scrollResponderFlashScrollIndicators(); - }; + } _getKeyForIndex(index, childArray) { const child = childArray[index]; @@ -1112,14 +1051,14 @@ class ScrollView extends React.Component { }; _scrollViewRef: ?React.ElementRef> = null; + _setScrollViewRef = (ref: ?React.ElementRef>) => { + this._scrollViewRef = ref; + }; - _innerViewRef: ?React.ElementRef = null; - _setInnerViewRef = setAndForwardRef({ - getForwardedRef: () => this.props.innerViewRef, - setLocalRef: ref => { - this._innerViewRef = ref; - }, - }); + _innerViewRef: ?React.ElementRef> = null; + _setInnerViewRef = (ref: ?React.ElementRef>) => { + this._innerViewRef = ref; + }; render(): React.Node | React.Element { let ScrollViewClass; @@ -1338,10 +1277,7 @@ class ScrollView extends React.Component { // On iOS the RefreshControl is a child of the ScrollView. // tvOS lacks native support for RefreshControl, so don't include it in that case return ( - /* $FlowFixMe(>=0.117.0 site=react_native_fb) This comment suppresses - * an error found when Flow v0.117 was deployed. To see the error, - * delete this comment and run Flow. */ - + {Platform.isTV ? null : refreshControl} {contentContainer} @@ -1359,14 +1295,14 @@ class ScrollView extends React.Component { + ref={this._setScrollViewRef}> {contentContainer} , ); } } return ( - + {contentContainer} ); @@ -1391,22 +1327,4 @@ const styles = StyleSheet.create({ }, }); -function Wrapper(props, ref) { - return ; -} -Wrapper.displayName = 'ScrollView'; -const ForwardedScrollView = React.forwardRef(Wrapper); - -// $FlowFixMe Add static context to ForwardedScrollView -ForwardedScrollView.Context = Context; - -ForwardedScrollView.displayName = 'ScrollView'; - -module.exports = ((ForwardedScrollView: $FlowFixMe): React.AbstractComponent< - React.ElementConfig, - $ReadOnly<{| - ...$Exact>>, - ...ScrollViewImperativeMethods, - |}>, -> & - ScrollViewComponentStatics); +module.exports = ScrollView; diff --git a/Libraries/Components/ScrollView/__mocks__/ScrollViewMock.js b/Libraries/Components/ScrollView/__mocks__/ScrollViewMock.js new file mode 100644 index 00000000000000..30e8cee004192b --- /dev/null +++ b/Libraries/Components/ScrollView/__mocks__/ScrollViewMock.js @@ -0,0 +1,39 @@ +/** + * 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. + * + * @format + * @flow strict-local + */ + +/* eslint-env jest */ + +'use strict'; + +const React = require('react'); +const View = require('../../View/View'); + +const requireNativeComponent = require('../../../ReactNative/requireNativeComponent'); + +import type {HostComponent} from '../../../Renderer/shims/ReactNativeTypes'; + +const RCTScrollView: HostComponent = requireNativeComponent( + 'RCTScrollView', +); + +const ScrollViewComponent: $FlowFixMe = jest.genMockFromModule('../ScrollView'); + +class ScrollViewMock extends ScrollViewComponent { + render(): React.Element { + return ( + + {this.props.refreshControl} + {this.props.children} + + ); + } +} + +module.exports = ScrollViewMock; diff --git a/Libraries/Components/ScrollView/__tests__/ScrollView-test.js b/Libraries/Components/ScrollView/__tests__/ScrollView-test.js deleted file mode 100644 index fb7aa74a55703e..00000000000000 --- a/Libraries/Components/ScrollView/__tests__/ScrollView-test.js +++ /dev/null @@ -1,51 +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. - * - * @format - * @emails oncall+react_native - * @flow-strict - */ - -'use strict'; - -const React = require('react'); -const ScrollView = require('../ScrollView'); -const ReactNativeTestTools = require('../../../Utilities/ReactNativeTestTools'); -const ReactTestRenderer = require('react-test-renderer'); -const View = require('../../View/View'); -const Text = require('../../../Text/Text'); - -describe('', () => { - it('should render as expected', () => { - ReactNativeTestTools.expectRendersMatchingSnapshot( - 'ScrollView', - () => ( - - - Hello World! - - - ), - () => { - jest.dontMock('../ScrollView'); - }, - ); - }); - it('should mock native methods and instance methods when mocked', () => { - jest.resetModules(); - jest.mock('../ScrollView'); - const ref = React.createRef(); - - ReactTestRenderer.create(); - - expect(ref.current != null && ref.current.measure).toBeInstanceOf( - jest.fn().constructor, - ); - expect(ref.current != null && ref.current.scrollTo).toBeInstanceOf( - jest.fn().constructor, - ); - }); -}); diff --git a/Libraries/Components/ScrollView/__tests__/__snapshots__/ScrollView-test.js.snap b/Libraries/Components/ScrollView/__tests__/__snapshots__/ScrollView-test.js.snap deleted file mode 100644 index 4e91eb9ba4bf20..00000000000000 --- a/Libraries/Components/ScrollView/__tests__/__snapshots__/ScrollView-test.js.snap +++ /dev/null @@ -1,93 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[` should render as expected: should deep render when mocked (please verify output manually) 1`] = ` - - - - - Hello World! - - - - -`; - -exports[` should render as expected: should deep render when not mocked (please verify output manually) 1`] = ` - - - - - Hello World! - - - - -`; - -exports[` should render as expected: should shallow render as when mocked 1`] = ` - - - - Hello World! - - - -`; - -exports[` should render as expected: should shallow render as when not mocked 1`] = ` - - - - Hello World! - - - -`; diff --git a/Libraries/Components/SegmentedControlIOS/RCTSegmentedControlNativeComponent.js b/Libraries/Components/SegmentedControlIOS/RCTSegmentedControlNativeComponent.js index 8923582c394f74..405ab500acc589 100644 --- a/Libraries/Components/SegmentedControlIOS/RCTSegmentedControlNativeComponent.js +++ b/Libraries/Components/SegmentedControlIOS/RCTSegmentedControlNativeComponent.js @@ -33,8 +33,6 @@ type NativeProps = $ReadOnly<{| selectedIndex?: WithDefault, enabled?: WithDefault, tintColor?: ?ColorValue, - textColor?: ?ColorValue, - backgroundColor?: ?ColorValue, momentary?: WithDefault, // Events diff --git a/Libraries/Components/StaticContainer.react.js b/Libraries/Components/StaticContainer.react.js index a84731b08c8311..aab461272d19ff 100644 --- a/Libraries/Components/StaticContainer.react.js +++ b/Libraries/Components/StaticContainer.react.js @@ -32,7 +32,7 @@ type Props = $ReadOnly<{| /** * Whether or not this component should update. */ - shouldUpdate?: ?boolean, + shouldUpdate: ?boolean, /** * Content short-circuited by React reconciliation process. */ @@ -43,8 +43,11 @@ class StaticContainer extends React.Component { return !!nextProps.shouldUpdate; } - render(): React.Node { - return this.props.children; + render(): null | React$Node { + const child = this.props.children; + return child === null || child === false + ? null + : React.Children.only(child); } } diff --git a/Libraries/Components/StatusBar/NativeStatusBarManagerAndroid.js b/Libraries/Components/StatusBar/NativeStatusBarManagerAndroid.js index b04ef0ff552604..bff7570477c502 100644 --- a/Libraries/Components/StatusBar/NativeStatusBarManagerAndroid.js +++ b/Libraries/Components/StatusBar/NativeStatusBarManagerAndroid.js @@ -12,14 +12,17 @@ import type {TurboModule} from '../../TurboModule/RCTExport'; import * as TurboModuleRegistry from '../../TurboModule/TurboModuleRegistry'; -import type {ProcessedColorValue} from '../../StyleSheet/processColor'; // TODO(macOS ISS#2323203) +import type {NativeOrDynamicColorType} from '../../StyleSheet/NativeOrDynamicColorType'; // TODO(macOS ISS#2323203) export interface Spec extends TurboModule { +getConstants: () => {| +HEIGHT: number, +DEFAULT_BACKGROUND_COLOR: number, |}; - +setColor: (color: ProcessedColorValue, animated: boolean) => void; // TODO(macOS ISS#2323203) + +setColor: ( + color: number | NativeOrDynamicColorType, + animated: boolean, + ) => void; // TODO(macOS ISS#2323203) +setTranslucent: (translucent: boolean) => void; /** diff --git a/Libraries/Components/StatusBar/StatusBar.js b/Libraries/Components/StatusBar/StatusBar.js index 6c588584e29a91..e994f9fd5f00b6 100644 --- a/Libraries/Components/StatusBar/StatusBar.js +++ b/Libraries/Components/StatusBar/StatusBar.js @@ -13,12 +13,11 @@ const Platform = require('../../Utilities/Platform'); const React = require('react'); -const invariant = require('invariant'); const processColor = require('../../StyleSheet/processColor'); -import type {ColorValue} from '../../StyleSheet/StyleSheetTypes'; import NativeStatusBarManagerAndroid from './NativeStatusBarManagerAndroid'; import NativeStatusBarManagerIOS from './NativeStatusBarManagerIOS'; +import type {ColorValue} from '../../StyleSheet/StyleSheetTypes'; // TODO(macOS ISS#2323203) /** * Status bar style @@ -63,7 +62,7 @@ type AndroidProps = $ReadOnly<{| * The background color of the status bar. * @platform android */ - backgroundColor?: ?ColorValue, + backgroundColor?: ?ColorValue, // TODO(macOS ISS#2323203) /** * If the status bar is translucent. * When translucent is set to true, the app will draw under the status bar. @@ -324,10 +323,6 @@ class StatusBar extends React.Component { ); return; } - invariant( - typeof processedColor === 'number', - 'Unexpected color given for StatusBar.setBackgroundColor', - ); NativeStatusBarManagerAndroid.setColor(processedColor, animated); } @@ -461,25 +456,31 @@ class StatusBar extends React.Component { ); } } else if (Platform.OS === 'android') { - //todo(T60684787): Add back optimization to only update bar style and - //background color if the new value is different from the old value. - NativeStatusBarManagerAndroid.setStyle(mergedProps.barStyle.value); - const processedColor = processColor(mergedProps.backgroundColor.value); - if (processedColor == null) { - console.warn( - `\`StatusBar._updatePropsStack\`: Color ${ - mergedProps.backgroundColor.value - } parsed to null or undefined`, - ); - } else { - invariant( - typeof processedColor === 'number', - 'Unexpected color given in StatusBar._updatePropsStack', - ); - NativeStatusBarManagerAndroid.setColor( - processedColor, - mergedProps.backgroundColor.animated, + if ( + !oldProps || + oldProps.barStyle.value !== mergedProps.barStyle.value + ) { + NativeStatusBarManagerAndroid.setStyle(mergedProps.barStyle.value); + } + if ( + !oldProps || + oldProps.backgroundColor.value !== mergedProps.backgroundColor.value + ) { + const processedColor = processColor( + mergedProps.backgroundColor.value, ); + if (processedColor == null) { + console.warn( + `\`StatusBar._updatePropsStack\`: Color ${ + mergedProps.backgroundColor.value + } parsed to null or undefined`, + ); + } else { + NativeStatusBarManagerAndroid.setColor( + processedColor, + mergedProps.backgroundColor.animated, + ); + } } if (!oldProps || oldProps.hidden.value !== mergedProps.hidden.value) { NativeStatusBarManagerAndroid.setHidden(mergedProps.hidden.value); diff --git a/Libraries/Components/Switch/AndroidSwitchNativeComponent.js b/Libraries/Components/Switch/AndroidSwitchNativeComponent.js index eddc96080e8632..b5adfc8c5b050f 100644 --- a/Libraries/Components/Switch/AndroidSwitchNativeComponent.js +++ b/Libraries/Components/Switch/AndroidSwitchNativeComponent.js @@ -11,6 +11,7 @@ 'use strict'; import * as React from 'react'; +import type {NativeOrDynamicColorType} from '../../StyleSheet/NativeOrDynamicColorType'; // TODO(macOS ISS#2323203) import type { WithDefault, @@ -21,7 +22,7 @@ import codegenNativeCommands from 'react-native/Libraries/Utilities/codegenNativ import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent'; import type {HostComponent} from 'react-native/Libraries/Renderer/shims/ReactNativeTypes'; -import type {ProcessedColorValue} from '../../StyleSheet/processColor'; // TODO(macOS ISS#2323203) +import type {ColorValue} from '../../StyleSheet/StyleSheetTypes'; import type {ViewProps} from '../View/ViewPropTypes'; type SwitchChangeEvent = $ReadOnly<{| @@ -34,13 +35,13 @@ type NativeProps = $ReadOnly<{| // Props disabled?: WithDefault, enabled?: WithDefault, - thumbColor?: ?(string | ProcessedColorValue), // TODO(macOS ISS#2323203) - trackColorForFalse?: ?(string | ProcessedColorValue), // TODO(macOS ISS#2323203) - trackColorForTrue?: ?(string | ProcessedColorValue), // TODO(macOS ISS#2323203) + thumbColor?: ?(string | NativeOrDynamicColorType), // TODO(macOS ISS#2323203) + trackColorForFalse?: ?(string | NativeOrDynamicColorType), // TODO(macOS ISS#2323203) + trackColorForTrue?: ?(string | NativeOrDynamicColorType), // TODO(macOS ISS#2323203) value?: WithDefault, on?: WithDefault, - thumbTintColor?: ?(string | ProcessedColorValue), // TODO(macOS ISS#2323203) - trackTintColor?: ?(string | ProcessedColorValue), // TODO(macOS ISS#2323203) + thumbTintColor?: ?(string | NativeOrDynamicColorType), // TODO(macOS ISS#2323203) + trackTintColor?: ?(string | NativeOrDynamicColorType), // TODO(macOS ISS#2323203) // Events onChange?: BubblingEventHandler, diff --git a/Libraries/Components/Switch/Switch.js b/Libraries/Components/Switch/Switch.js index caf191c74a917e..36fba9446b8d1f 100644 --- a/Libraries/Components/Switch/Switch.js +++ b/Libraries/Components/Switch/Switch.js @@ -11,9 +11,9 @@ 'use strict'; -import Platform from '../../Utilities/Platform'; -import * as React from 'react'; -import StyleSheet from '../../StyleSheet/StyleSheet'; +const Platform = require('../../Utilities/Platform'); +const React = require('react'); +const StyleSheet = require('../../StyleSheet/StyleSheet'); import AndroidSwitchNativeComponent, { Commands as AndroidSwitchCommands, @@ -113,18 +113,48 @@ class Switch extends React.Component { ...props } = this.props; - const trackColorForFalse = trackColor?.false; - const trackColorForTrue = trackColor?.true; + // Support deprecated color props. + let _thumbColor = thumbColor; + let _trackColorForFalse = trackColor?.false; + let _trackColorForTrue = trackColor?.true; + + // TODO: Remove support for these props after a couple releases. + const {thumbTintColor, tintColor, onTintColor} = (props: $FlowFixMe); + if (thumbTintColor != null) { + _thumbColor = thumbTintColor; + if (__DEV__) { + console.warn( + 'Switch: `thumbTintColor` is deprecated, use `thumbColor` instead.', + ); + } + } + if (tintColor != null) { + _trackColorForFalse = tintColor; + if (__DEV__) { + console.warn( + 'Switch: `tintColor` is deprecated, use `trackColor` instead.', + ); + } + } + if (onTintColor != null) { + _trackColorForTrue = onTintColor; + if (__DEV__) { + console.warn( + 'Switch: `onTintColor` is deprecated, use `trackColor` instead.', + ); + } + } if (Platform.OS === 'android') { const platformProps = { enabled: disabled !== true, on: value === true, style, - thumbTintColor: thumbColor, - trackColorForFalse: trackColorForFalse, - trackColorForTrue: trackColorForTrue, - trackTintColor: value === true ? trackColorForTrue : trackColorForFalse, + thumbTintColor: _thumbColor, + trackColorForFalse: _trackColorForFalse, + trackColorForTrue: _trackColorForTrue, + trackTintColor: + value === true ? _trackColorForTrue : _trackColorForFalse, }; return ( @@ -142,7 +172,7 @@ class Switch extends React.Component { const platformProps = { disabled, - onTintColor: trackColorForTrue, + onTintColor: _trackColorForTrue, style: StyleSheet.compose( {height: 31, width: 51}, StyleSheet.compose( @@ -155,8 +185,8 @@ class Switch extends React.Component { }, ), ), - thumbTintColor: thumbColor, - tintColor: trackColorForFalse, + thumbTintColor: _thumbColor, + tintColor: _trackColorForFalse, value: value === true, }; diff --git a/Libraries/Components/Switch/SwitchNativeComponent.js b/Libraries/Components/Switch/SwitchNativeComponent.js index 4e1ced169fb2de..c1916e10839574 100644 --- a/Libraries/Components/Switch/SwitchNativeComponent.js +++ b/Libraries/Components/Switch/SwitchNativeComponent.js @@ -12,13 +12,13 @@ import type {BubblingEventHandler, WithDefault} from '../../Types/CodegenTypes'; import type {ColorValue} from '../../StyleSheet/StyleSheetTypes'; -import type {ProcessedColorValue} from '../../StyleSheet/processColor'; // TODO(macOS ISS#2323203) import type {ViewProps} from '../View/ViewPropTypes'; import * as React from 'react'; import codegenNativeComponent from '../../Utilities/codegenNativeComponent'; import codegenNativeCommands from 'react-native/Libraries/Utilities/codegenNativeCommands'; import type {HostComponent} from '../../Renderer/shims/ReactNativeTypes'; +import type {NativeOrDynamicColorType} from '../../StyleSheet/NativeOrDynamicColorType'; // TODO(macOS ISS#2323203) type SwitchChangeEvent = $ReadOnly<{| value: boolean, @@ -30,14 +30,14 @@ type NativeProps = $ReadOnly<{| // Props disabled?: WithDefault, value?: WithDefault, - tintColor?: ?(ColorValue | ProcessedColorValue), // TODO(macOS ISS#2323203) - onTintColor?: ?(ColorValue | ProcessedColorValue), // TODO(macOS ISS#2323203) - thumbTintColor?: ?(ColorValue | ProcessedColorValue), // TODO(macOS ISS#2323203) + tintColor?: ?(ColorValue | NativeOrDynamicColorType), // TODO(macOS ISS#2323203) + onTintColor?: ?(ColorValue | NativeOrDynamicColorType), // TODO(macOS ISS#2323203) + thumbTintColor?: ?(ColorValue | NativeOrDynamicColorType), // TODO(macOS ISS#2323203) // Deprecated props - thumbColor?: ?(ColorValue | ProcessedColorValue), // TODO(macOS ISS#2323203) - trackColorForFalse?: ?(ColorValue | ProcessedColorValue), // TODO(macOS ISS#2323203) - trackColorForTrue?: ?(ColorValue | ProcessedColorValue), // TODO(macOS ISS#2323203) + thumbColor?: ?(ColorValue | NativeOrDynamicColorType), // TODO(macOS ISS#2323203) + trackColorForFalse?: ?(ColorValue | NativeOrDynamicColorType), // TODO(macOS ISS#2323203) + trackColorForTrue?: ?(ColorValue | NativeOrDynamicColorType), // TODO(macOS ISS#2323203) // Events onChange?: ?BubblingEventHandler, diff --git a/Libraries/Components/TextInput/AndroidTextInputNativeComponent.js b/Libraries/Components/TextInput/AndroidTextInputNativeComponent.js index 2ac53e759b825d..c14b13ea10ab21 100644 --- a/Libraries/Components/TextInput/AndroidTextInputNativeComponent.js +++ b/Libraries/Components/TextInput/AndroidTextInputNativeComponent.js @@ -24,10 +24,7 @@ import type {TextStyleProp, ViewStyleProp} from '../../StyleSheet/StyleSheet'; import type {ColorValue} from '../../StyleSheet/StyleSheetTypes'; import requireNativeComponent from '../../ReactNative/requireNativeComponent'; import codegenNativeCommands from '../../Utilities/codegenNativeCommands'; -import type {TextInputNativeCommands} from './TextInputNativeCommands'; import * as React from 'react'; -import AndroidTextInputViewConfig from './AndroidTextInputViewConfig'; -const ReactNativeViewConfigRegistry = require('../../Renderer/shims/ReactNativeViewConfigRegistry'); export type KeyboardType = // Cross Platform @@ -541,23 +538,33 @@ export type NativeProps = $ReadOnly<{| type NativeType = HostComponent; -type NativeCommands = TextInputNativeCommands; +interface NativeCommands { + +focus: (viewRef: React.ElementRef) => void; + +blur: (viewRef: React.ElementRef) => void; + +setMostRecentEventCount: ( + viewRef: React.ElementRef, + eventCount: Int32, + ) => void; + +setTextAndSelection: ( + viewRef: React.ElementRef, + mostRecentEventCount: Int32, + value: ?string, // in theory this is nullable + start: Int32, + end: Int32, + ) => void; +} export const Commands: NativeCommands = codegenNativeCommands({ - supportedCommands: ['focus', 'blur', 'setTextAndSelection'], + supportedCommands: [ + 'focus', + 'blur', + 'setMostRecentEventCount', + 'setTextAndSelection', + ], }); -let AndroidTextInputNativeComponent; -if (global.RN$Bridgeless) { - ReactNativeViewConfigRegistry.register('AndroidTextInput', () => { - return AndroidTextInputViewConfig; - }); - AndroidTextInputNativeComponent = 'AndroidTextInput'; -} else { - AndroidTextInputNativeComponent = requireNativeComponent( - 'AndroidTextInput', - ); -} +const AndroidTextInputNativeComponent: HostComponent = requireNativeComponent( + 'AndroidTextInput', +); -// flowlint-next-line unclear-type:off -export default ((AndroidTextInputNativeComponent: any): HostComponent); +export default AndroidTextInputNativeComponent; diff --git a/Libraries/Components/TextInput/AndroidTextInputViewConfig.js b/Libraries/Components/TextInput/AndroidTextInputViewConfig.js deleted file mode 100644 index c4a43a773398cb..00000000000000 --- a/Libraries/Components/TextInput/AndroidTextInputViewConfig.js +++ /dev/null @@ -1,84 +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. - * - * @flow strict-local - * @format - */ - -'use strict'; - -import ReactNativeViewViewConfig from '../../Components/View/ReactNativeViewViewConfig'; -import type {ReactNativeBaseComponentViewConfig} from '../../Renderer/shims/ReactNativeTypes'; - -const AndroidTextInputViewConfig = { - uiViewClassName: 'AndroidTextInput', - bubblingEventTypes: { - topTextInput: { - phasedRegistrationNames: { - bubbled: 'onTextInput', - captured: 'onTextInputCapture', - }, - }, - }, - directEventTypes: {}, - validAttributes: { - ...ReactNativeViewViewConfig.validAttributes, - - maxFontSizeMultiplier: true, - placeholder: true, - inlineImagePadding: true, - contextMenuHidden: true, - textShadowColor: {process: require('../../StyleSheet/processColor')}, - maxLength: true, - selectTextOnFocus: true, - textShadowRadius: true, - underlineColorAndroid: {process: require('../../StyleSheet/processColor')}, - textDecorationLine: true, - blurOnSubmit: true, - textAlignVertical: true, - fontStyle: true, - textShadowOffset: true, - selectionColor: {process: require('../../StyleSheet/processColor')}, - selection: true, - placeholderTextColor: {process: require('../../StyleSheet/processColor')}, - importantForAutofill: true, - lineHeight: true, - textTransform: true, - returnKeyType: true, - keyboardType: true, - multiline: true, - color: true, - autoCompleteType: true, - numberOfLines: true, - letterSpacing: true, - returnKeyLabel: true, - fontSize: true, - onKeyPress: true, - cursorColor: {process: require('../../StyleSheet/processColor')}, - text: true, - showSoftInputOnFocus: true, - textAlign: true, - autoCapitalize: true, - autoCorrect: true, - caretHidden: true, - secureTextEntry: true, - textBreakStrategy: true, - onScroll: true, - onContentSizeChange: true, - disableFullscreenUI: true, - includeFontPadding: true, - fontWeight: true, - fontFamily: true, - allowFontScaling: true, - onSelectionChange: true, - mostRecentEventCount: true, - inlineImageLeft: true, - editable: true, - fontVariant: true, - }, -}; - -module.exports = (AndroidTextInputViewConfig: ReactNativeBaseComponentViewConfig<>); diff --git a/Libraries/Components/TextInput/InputAccessoryView.js b/Libraries/Components/TextInput/InputAccessoryView.js index b35920d5bcb23d..67d314ca5a6c30 100644 --- a/Libraries/Components/TextInput/InputAccessoryView.js +++ b/Libraries/Components/TextInput/InputAccessoryView.js @@ -10,6 +10,7 @@ 'use strict'; +const DeprecatedColorPropType = require('../../DeprecatedPropTypes/DeprecatedColorPropType'); const Platform = require('../../Utilities/Platform'); const React = require('react'); const StyleSheet = require('../../StyleSheet/StyleSheet'); @@ -17,7 +18,6 @@ const StyleSheet = require('../../StyleSheet/StyleSheet'); import RCTInputAccessoryViewNativeComponent from './RCTInputAccessoryViewNativeComponent'; import type {ViewStyleProp} from '../../StyleSheet/StyleSheet'; -import type {ColorValue} from '../../StyleSheet/StyleSheetTypes'; /** * Note: iOS only @@ -85,7 +85,7 @@ type Props = $ReadOnly<{| */ nativeID?: ?string, style?: ?ViewStyleProp, - backgroundColor?: ?ColorValue, + backgroundColor?: ?DeprecatedColorPropType, |}>; class InputAccessoryView extends React.Component { diff --git a/Libraries/Components/TextInput/RCTMultilineTextInputNativeComponent.js b/Libraries/Components/TextInput/RCTMultilineTextInputNativeComponent.js deleted file mode 100644 index a0dd8841123f6d..00000000000000 --- a/Libraries/Components/TextInput/RCTMultilineTextInputNativeComponent.js +++ /dev/null @@ -1,32 +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. - * - * @flow strict-local - * @format - */ - -'use strict'; - -import type {HostComponent} from '../../Renderer/shims/ReactNativeTypes'; -import requireNativeComponent from '../../ReactNative/requireNativeComponent'; -import codegenNativeCommands from '../../Utilities/codegenNativeCommands'; -import type {Int32} from '../../Types/CodegenTypes'; -import type {TextInputNativeCommands} from './TextInputNativeCommands'; -import * as React from 'react'; - -type NativeType = HostComponent; - -type NativeCommands = TextInputNativeCommands; - -export const Commands: NativeCommands = codegenNativeCommands({ - supportedCommands: ['focus', 'blur', 'setTextAndSelection'], -}); - -const SinglelineTextInputNativeComponent: HostComponent = requireNativeComponent( - 'RCTMultilineTextInputView', -); - -export default SinglelineTextInputNativeComponent; diff --git a/Libraries/Components/TextInput/RCTSingelineTextInputNativeComponent.js b/Libraries/Components/TextInput/RCTSingelineTextInputNativeComponent.js deleted file mode 100644 index 8a6f85756a6af6..00000000000000 --- a/Libraries/Components/TextInput/RCTSingelineTextInputNativeComponent.js +++ /dev/null @@ -1,43 +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. - * - * @flow strict-local - * @format - */ - -'use strict'; - -import type {HostComponent} from '../../Renderer/shims/ReactNativeTypes'; -import requireNativeComponent from '../../ReactNative/requireNativeComponent'; -import codegenNativeCommands from '../../Utilities/codegenNativeCommands'; -import type {Int32} from '../../Types/CodegenTypes'; -import * as React from 'react'; -import type {TextInputNativeCommands} from './TextInputNativeCommands'; -import RCTSinglelineTextInputViewConfig from './RCTSinglelineTextInputViewConfig'; -const ReactNativeViewConfigRegistry = require('../../Renderer/shims/ReactNativeViewConfigRegistry'); - -type NativeType = HostComponent; - -type NativeCommands = TextInputNativeCommands; - -export const Commands: NativeCommands = codegenNativeCommands({ - supportedCommands: ['focus', 'blur', 'setTextAndSelection'], -}); - -let SinglelineTextInputNativeComponent; -if (global.RN$Bridgeless) { - ReactNativeViewConfigRegistry.register('RCTSinglelineTextInputView', () => { - return RCTSinglelineTextInputViewConfig; - }); - SinglelineTextInputNativeComponent = 'RCTSinglelineTextInputView'; -} else { - SinglelineTextInputNativeComponent = requireNativeComponent( - 'RCTSinglelineTextInputView', - ); -} - -// flowlint-next-line unclear-type:off -export default ((SinglelineTextInputNativeComponent: any): HostComponent); diff --git a/Libraries/Components/TextInput/RCTSinglelineTextInputViewConfig.js b/Libraries/Components/TextInput/RCTSinglelineTextInputViewConfig.js deleted file mode 100644 index 4836323d1a3615..00000000000000 --- a/Libraries/Components/TextInput/RCTSinglelineTextInputViewConfig.js +++ /dev/null @@ -1,134 +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. - * - * @flow strict-local - * @format - */ - -'use strict'; - -import ReactNativeViewViewConfig from '../../Components/View/ReactNativeViewViewConfig'; -import type {ReactNativeBaseComponentViewConfig} from '../../Renderer/shims/ReactNativeTypes'; - -const RCTSinglelineTextInputViewConfig = { - uiViewClassName: 'RCTSinglelineTextInputView', - bubblingEventTypes: { - topBlur: { - phasedRegistrationNames: { - bubbled: 'onBlur', - captured: 'onBlurCapture', - }, - }, - topChange: { - phasedRegistrationNames: { - bubbled: 'onChange', - captured: 'onChangeCapture', - }, - }, - topEndEditing: { - phasedRegistrationNames: { - bubbled: 'onEndEditing', - captured: 'onEndEditingCapture', - }, - }, - topFocus: { - phasedRegistrationNames: { - bubbled: 'onFocus', - captured: 'onFocusCapture', - }, - }, - topKeyPress: { - phasedRegistrationNames: { - bubbled: 'onKeyPress', - captured: 'onKeyPressCapture', - }, - }, - topSubmitEditing: { - phasedRegistrationNames: { - bubbled: 'onSubmitEditing', - captured: 'onSubmitEditingCapture', - }, - }, - topTouchCancel: { - phasedRegistrationNames: { - bubbled: 'onTouchCancel', - captured: 'onTouchCancelCapture', - }, - }, - topTouchEnd: { - phasedRegistrationNames: { - bubbled: 'onTouchEnd', - captured: 'onTouchEndCapture', - }, - }, - - topTouchMove: { - phasedRegistrationNames: { - bubbled: 'onTouchMove', - captured: 'onTouchMoveCapture', - }, - }, - }, - directEventTypes: {}, - validAttributes: { - ...ReactNativeViewViewConfig.validAttributes, - fontSize: true, - fontWeight: true, - fontVariant: true, - // flowlint-next-line untyped-import:off - textShadowOffset: {diff: require('../../Utilities/differ/sizesDiffer')}, - allowFontScaling: true, - fontStyle: true, - textTransform: true, - textAlign: true, - fontFamily: true, - lineHeight: true, - isHighlighted: true, - writingDirection: true, - textDecorationLine: true, - textShadowRadius: true, - letterSpacing: true, - textDecorationStyle: true, - textDecorationColor: {process: require('../../StyleSheet/processColor')}, - color: {process: require('../../StyleSheet/processColor')}, - maxFontSizeMultiplier: true, - textShadowColor: {process: require('../../StyleSheet/processColor')}, - editable: true, - inputAccessoryViewID: true, - caretHidden: true, - enablesReturnKeyAutomatically: true, - placeholderTextColor: {process: require('../../StyleSheet/processColor')}, - onSelectionChange: true, - clearButtonMode: true, - onContentSizeChange: true, - keyboardType: true, - selection: true, - returnKeyType: true, - blurOnSubmit: true, - mostRecentEventCount: true, - onChange: true, - scrollEnabled: true, - selectionColor: {process: require('../../StyleSheet/processColor')}, - contextMenuHidden: true, - secureTextEntry: true, - onTextInput: true, - placeholder: true, - autoCorrect: true, - onScroll: true, - multiline: true, - textContentType: true, - maxLength: true, - autoCapitalize: true, - keyboardAppearance: true, - passwordRules: true, - spellCheck: true, - selectTextOnFocus: true, - text: true, - clearTextOnFocus: true, - }, -}; - -module.exports = (RCTSinglelineTextInputViewConfig: ReactNativeBaseComponentViewConfig<>); diff --git a/Libraries/Components/TextInput/TextInput.js b/Libraries/Components/TextInput/TextInput.js index 585738e8105d18..dc65b89fd4387e 100644 --- a/Libraries/Components/TextInput/TextInput.js +++ b/Libraries/Components/TextInput/TextInput.js @@ -22,6 +22,7 @@ const TouchableWithoutFeedback = require('../Touchable/TouchableWithoutFeedback' const invariant = require('invariant'); const nullthrows = require('nullthrows'); +const requireNativeComponent = require('../../ReactNative/requireNativeComponent'); const setAndForwardRef = require('../../Utilities/setAndForwardRef'); import type {TextStyleProp, ViewStyleProp} from '../../StyleSheet/StyleSheet'; @@ -30,35 +31,27 @@ import type {ViewProps} from '../View/ViewPropTypes'; import type {SyntheticEvent, ScrollEvent} from '../../Types/CoreEventTypes'; import type {PressEvent} from '../../Types/CoreEventTypes'; import type {HostComponent} from '../../Renderer/shims/ReactNativeTypes'; -import type {TextInputNativeCommands} from './TextInputNativeCommands'; const {useEffect, useRef, useState} = React; type ReactRefSetter = {current: null | T, ...} | ((ref: null | T) => mixed); let AndroidTextInput; -let AndroidTextInputCommands; -let RCTSinglelineTextInputView; -let RCTSinglelineTextInputNativeCommands; let RCTMultilineTextInputView; -let RCTMultilineTextInputNativeCommands; +let RCTSinglelineTextInputView; if (Platform.OS === 'android') { AndroidTextInput = require('./AndroidTextInputNativeComponent').default; - AndroidTextInputCommands = require('./AndroidTextInputNativeComponent') - .Commands; } else if ( Platform.OS === 'ios' || Platform.OS === 'macos' /* TODO(macOS ISS#2323203) */ ) { - RCTSinglelineTextInputView = require('./RCTSingelineTextInputNativeComponent') - .default; - RCTSinglelineTextInputNativeCommands = require('./RCTSingelineTextInputNativeComponent') - .Commands; - RCTMultilineTextInputView = require('./RCTMultilineTextInputNativeComponent') - .default; - RCTMultilineTextInputNativeCommands = require('./RCTMultilineTextInputNativeComponent') - .Commands; + RCTMultilineTextInputView = requireNativeComponent( + 'RCTMultilineTextInputView', + ); + RCTSinglelineTextInputView = requireNativeComponent( + 'RCTSinglelineTextInputView', + ); } export type ChangeEvent = SyntheticEvent< @@ -292,19 +285,9 @@ type IOSProps = $ReadOnly<{| */ textContentType?: ?TextContentType, - /** - * Provide rules for your password. - * For example, say you want to require a password with at least eight characters consisting of a mix of uppercase and lowercase letters, at least one number, and at most two consecutive characters. - * "required: upper; required: lower; required: digit; max-consecutive: 2; minlength: 8;" - * @platform ios - */ - passwordRules?: ?PasswordRules, + PasswordRules?: ?PasswordRules, /* - * If `true`, allows TextInput to pass touch events to the parent component. - * This allows components to be swipeable from the TextInput on iOS, - * as is the case on Android by default. - * If `false`, TextInput always asks to handle the input (except when disabled). * @platform ios */ rejectResponderTermination?: ?boolean, @@ -721,6 +704,42 @@ type ImperativeMethods = $ReadOnly<{| const emptyFunctionThatReturnsTrue = () => true; +function useFocusOnMount( + initialAutoFocus: ?boolean, + inputRef: {| + current: null | React.ElementRef>, + |}, +) { + const initialAutoFocusValue = useRef(initialAutoFocus); + + useEffect(() => { + // We only want to autofocus on initial mount. + // Since initialAutoFocusValue and inputRef will never change + // this should match the expected behavior + if (initialAutoFocusValue.current) { + const focus = () => { + if (inputRef.current != null) { + inputRef.current.focus(); + } + }; + + let rafId; + if (Platform.OS === 'android') { + // On Android this needs to be executed in a rAF callback + // otherwise the keyboard opens then closes immediately. + rafId = requestAnimationFrame(focus); + } else { + focus(); + } + + return () => { + if (rafId != null) { + cancelAnimationFrame(rafId); + } + }; + } + }, [initialAutoFocusValue, inputRef]); +} /** * A foundational component for inputting text into the app via a * keyboard. Props provide configurability for several features, such as @@ -848,15 +867,7 @@ const emptyFunctionThatReturnsTrue = () => true; function InternalTextInput(props: Props): React.Node { const inputRef = useRef>>(null); - // Android sends a "onTextChanged" event followed by a "onSelectionChanged" event, for - // the same "most recent event count". - // For controlled selection, that means that immediately after text is updated, - // a controlled component will pass in the *previous* selection, even if the controlled - // component didn't mean to modify the selection at all. - // Therefore, we ignore selections and pass them through until the selection event has - // been sent. - // Note that this mitigation is NOT needed for Fabric. - let selection: ?Selection = + const selection: ?Selection = props.selection == null ? null : { @@ -864,37 +875,10 @@ function InternalTextInput(props: Props): React.Node { end: props.selection.end ?? props.selection.start, }; - const [mostRecentEventCount, setMostRecentEventCount] = useState(0); - const [lastNativeText, setLastNativeText] = useState(props.value); - const [lastNativeSelectionState, setLastNativeSelection] = useState<{| - selection: ?Selection, - mostRecentEventCount: number, - |}>({selection, mostRecentEventCount}); - - const lastNativeSelection = lastNativeSelectionState.selection; - const lastNativeSelectionEventCount = - lastNativeSelectionState.mostRecentEventCount; - - if (lastNativeSelectionEventCount < mostRecentEventCount) { - selection = null; - } - - let viewCommands: TextInputNativeCommands>; - if (AndroidTextInputCommands) { - viewCommands = AndroidTextInputCommands; - } else { - viewCommands = props.multiline - ? RCTMultilineTextInputNativeCommands - : RCTSinglelineTextInputNativeCommands; - } - - const text = - typeof props.value === 'string' - ? props.value - : typeof props.defaultValue === 'string' - ? props.defaultValue - : ''; + const [lastNativeSelection, setLastNativeSelection] = useState( + selection, + ); // This is necessary in case native updates the text and JS decides // that the update should be ignored and we should stick with the value @@ -914,42 +898,23 @@ function InternalTextInput(props: Props): React.Node { lastNativeSelection.end !== selection.end) ) { nativeUpdate.selection = selection; - setLastNativeSelection({selection, mostRecentEventCount}); + setLastNativeSelection(selection); } - if (Object.keys(nativeUpdate).length === 0) { - return; + if (Object.keys(nativeUpdate).length > 0 && inputRef.current) { + inputRef.current.setNativeProps(nativeUpdate); } + }, [inputRef, props.value, lastNativeText, selection, lastNativeSelection]); - if (inputRef.current != null) { - viewCommands.setTextAndSelection( - inputRef.current, - mostRecentEventCount, - text, - selection?.start ?? -1, - selection?.end ?? -1, - ); - } - }, [ - mostRecentEventCount, - inputRef, - props.value, - props.defaultValue, - lastNativeText, - selection, - lastNativeSelection, - text, - viewCommands, - ]); + useFocusOnMount(props.autoFocus, inputRef); useEffect(() => { - const inputRefValue = inputRef.current; - - if (inputRefValue != null) { - TextInputState.registerInput(inputRefValue); + const tag = ReactNative.findNodeHandle(inputRef.current); + if (tag != null) { + TextInputState.registerInput(tag); return () => { - TextInputState.unregisterInput(inputRefValue); + TextInputState.unregisterInput(tag); }; } }, [inputRef]); @@ -965,25 +930,30 @@ function InternalTextInput(props: Props): React.Node { function clear(): void { if (inputRef.current != null) { - viewCommands.setTextAndSelection( - inputRef.current, - mostRecentEventCount, - '', - 0, - 0, - ); + inputRef.current.setNativeProps({text: ''}); } } // TODO: Fix this returning true on null === null, when no input is focused function isFocused(): boolean { - return TextInputState.currentlyFocusedInput() === inputRef.current; + return ( + TextInputState.currentlyFocusedField() === + ReactNative.findNodeHandle(inputRef.current) + ); } function getNativeRef(): ?React.ElementRef> { return inputRef.current; } + function _getText(): ?string { + return typeof props.value === 'string' + ? props.value + : typeof props.defaultValue === 'string' + ? props.defaultValue + : ''; + } + const _setNativeRef = setAndForwardRef({ getForwardedRef: () => props.forwardedRef, setLocalRef: ref => { @@ -1026,48 +996,48 @@ function InternalTextInput(props: Props): React.Node { }; const _onChange = (event: ChangeEvent) => { + // Make sure to fire the mostRecentEventCount first so it is already set on + // native when the text value is set. + if (inputRef.current) { + inputRef.current.setNativeProps({ + mostRecentEventCount: event.nativeEvent.eventCount, + }); + } + const text = event.nativeEvent.text; props.onChange && props.onChange(event); props.onChangeText && props.onChangeText(text); - if (inputRef.current == null) { + if (!inputRef.current) { // calling `props.onChange` or `props.onChangeText` // may clean up the input itself. Exits here. return; } setLastNativeText(text); - // This must happen last, after we call setLastNativeText. - // Different ordering can cause bugs when editing AndroidTextInputs - // with multiple Fragments. - // We must update this so that controlled input updates work. - setMostRecentEventCount(event.nativeEvent.eventCount); }; const _onSelectionChange = (event: SelectionChangeEvent) => { props.onSelectionChange && props.onSelectionChange(event); - if (inputRef.current == null) { + if (!inputRef.current) { // calling `props.onSelectionChange` // may clean up the input itself. Exits here. return; } - setLastNativeSelection({ - selection: event.nativeEvent.selection, - mostRecentEventCount, - }); + setLastNativeSelection(event.nativeEvent.selection); }; const _onFocus = (event: FocusEvent) => { - TextInputState.focusInput(inputRef.current); + TextInputState.focusField(ReactNative.findNodeHandle(inputRef.current)); if (props.onFocus) { props.onFocus(event); } }; const _onBlur = (event: BlurEvent) => { - TextInputState.blurInput(inputRef.current); + TextInputState.blurField(ReactNative.findNodeHandle(inputRef.current)); if (props.onBlur) { props.onBlur(event); } @@ -1106,7 +1076,6 @@ function InternalTextInput(props: Props): React.Node { ref={_setNativeRef} {...props} dataDetectorTypes={props.dataDetectorTypes} - mostRecentEventCount={mostRecentEventCount} onBlur={_onBlur} onChange={_onChange} onContentSizeChange={props.onContentSizeChange} @@ -1116,7 +1085,7 @@ function InternalTextInput(props: Props): React.Node { onSelectionChangeShouldSetResponder={emptyFunctionThatReturnsTrue} selection={selection} style={style} - text={text} + text={_getText()} /> ); } else if (Platform.OS === 'android') { @@ -1142,17 +1111,15 @@ function InternalTextInput(props: Props): React.Node { autoCapitalize={autoCapitalize} children={children} disableFullscreenUI={props.disableFullscreenUI} - mostRecentEventCount={mostRecentEventCount} + mostRecentEventCount={0} onBlur={_onBlur} onChange={_onChange} onFocus={_onFocus} - /* $FlowFixMe the types for AndroidTextInput don't match up exactly - * with the props for TextInput. This will need to get fixed */ onScroll={_onScroll} onSelectionChange={_onSelectionChange} selection={selection} style={style} - text={text} + text={_getText()} textBreakStrategy={props.textBreakStrategy} /> ); @@ -1203,8 +1170,6 @@ ExportedForwardRef.propTypes = DeprecatedTextInputPropTypes; // $FlowFixMe ExportedForwardRef.State = { - currentlyFocusedInput: TextInputState.currentlyFocusedInput, - currentlyFocusedField: TextInputState.currentlyFocusedField, focusTextInput: TextInputState.focusTextInput, blurTextInput: TextInputState.blurTextInput, @@ -1212,7 +1177,6 @@ ExportedForwardRef.State = { type TextInputComponentStatics = $ReadOnly<{| State: $ReadOnly<{| - currentlyFocusedInput: typeof TextInputState.currentlyFocusedInput, currentlyFocusedField: typeof TextInputState.currentlyFocusedField, focusTextInput: typeof TextInputState.focusTextInput, blurTextInput: typeof TextInputState.blurTextInput, diff --git a/Libraries/Components/TextInput/TextInputNativeCommands.js b/Libraries/Components/TextInput/TextInputNativeCommands.js deleted file mode 100644 index 2584b7516c804b..00000000000000 --- a/Libraries/Components/TextInput/TextInputNativeCommands.js +++ /dev/null @@ -1,31 +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. - * - * @flow strict-local - * @format - */ - -'use strict'; - -import * as React from 'react'; - -import type {Int32} from '../../Types/CodegenTypes'; - -export interface TextInputNativeCommands { - +focus: (viewRef: React.ElementRef) => void; - +blur: (viewRef: React.ElementRef) => void; - +setTextAndSelection: ( - viewRef: React.ElementRef, - mostRecentEventCount: Int32, - value: ?string, // in theory this is nullable - start: Int32, - end: Int32, - ) => void; -} - -const supportedCommands = ['focus', 'blur', 'setTextAndSelection']; - -export default supportedCommands; diff --git a/Libraries/Components/TextInput/TextInputState.js b/Libraries/Components/TextInput/TextInputState.js index 8d16b0ca1c6e0b..2f68e612a46604 100644 --- a/Libraries/Components/TextInput/TextInputState.js +++ b/Libraries/Components/TextInput/TextInputState.js @@ -14,62 +14,30 @@ 'use strict'; -const React = require('react'); const Platform = require('../../Utilities/Platform'); -const {findNodeHandle} = require('../../Renderer/shims/ReactNative'); -import {Commands as AndroidTextInputCommands} from '../../Components/TextInput/AndroidTextInputNativeComponent'; -import {Commands as iOSTextInputCommands} from '../../Components/TextInput/RCTSingelineTextInputNativeComponent'; +const UIManager = require('../../ReactNative/UIManager'); -import type {HostComponent} from '../../Renderer/shims/ReactNativeTypes'; -type ComponentRef = React.ElementRef>; - -let currentlyFocusedInputRef: ?ComponentRef = null; +let currentlyFocusedID: ?number = null; const inputs = new Set(); -function currentlyFocusedInput(): ?ComponentRef { - return currentlyFocusedInputRef; -} - /** * Returns the ID of the currently focused text field, if one exists * If no text field is focused it returns null */ function currentlyFocusedField(): ?number { - if (__DEV__) { - console.error( - 'currentlyFocusedField is deprecated and will be removed in a future release. Use currentlyFocusedInput', - ); - } - - return findNodeHandle(currentlyFocusedInputRef); -} - -function focusInput(textField: ?ComponentRef): void { - if (currentlyFocusedInputRef !== textField && textField != null) { - currentlyFocusedInputRef = textField; - } -} - -function blurInput(textField: ?ComponentRef): void { - if (currentlyFocusedInputRef === textField && textField != null) { - currentlyFocusedInputRef = null; - } + return currentlyFocusedID; } function focusField(textFieldID: ?number): void { - if (__DEV__) { - console.error('focusField no longer works. Use focusInput'); + if (currentlyFocusedID !== textFieldID && textFieldID != null) { + currentlyFocusedID = textFieldID; } - - return; } function blurField(textFieldID: ?number) { - if (__DEV__) { - console.error('blurField no longer works. Use blurInput'); + if (currentlyFocusedID === textFieldID && textFieldID != null) { + currentlyFocusedID = null; } - - return; } /** @@ -77,31 +45,21 @@ function blurField(textFieldID: ?number) { * Focuses the specified text field * noop if the text field was already focused */ -function focusTextInput(textField: ?ComponentRef) { - if (typeof textField === 'number') { - if (__DEV__) { - console.error( - 'focusTextInput must be called with a host component. Passing a react tag is deprecated.', - ); - } - - return; - } - - if (currentlyFocusedInputRef !== textField && textField != null) { - focusInput(textField); +function focusTextInput(textFieldID: ?number) { + if (currentlyFocusedID !== textFieldID && textFieldID != null) { + focusField(textFieldID); if ( Platform.OS === 'ios' || Platform.OS === 'macos' /* TODO(macOS ISS#2323203) */ ) { - // This isn't necessarily a single line text input - // But commands don't actually care as long as the thing being passed in - // actually has a command with that name. So this should work with single - // and multiline text inputs. Ideally we'll merge them into one component - // in the future. - iOSTextInputCommands.focus(textField); + UIManager.focus(textFieldID); } else if (Platform.OS === 'android') { - AndroidTextInputCommands.focus(textField); + UIManager.dispatchViewManagerCommand( + textFieldID, + UIManager.getViewManagerConfig('AndroidTextInput').Commands + .focusTextInput, + null, + ); } } } @@ -111,81 +69,38 @@ function focusTextInput(textField: ?ComponentRef) { * Unfocuses the specified text field * noop if it wasn't focused */ -function blurTextInput(textField: ?ComponentRef) { - if (typeof textField === 'number') { - if (__DEV__) { - console.error( - 'focusTextInput must be called with a host component. Passing a react tag is deprecated.', - ); - } - - return; - } - - if (currentlyFocusedInputRef === textField && textField != null) { - blurInput(textField); +function blurTextInput(textFieldID: ?number) { + if (currentlyFocusedID === textFieldID && textFieldID != null) { + blurField(textFieldID); if ( Platform.OS === 'ios' || Platform.OS === 'macos' /* TODO(macOS ISS#2323203) */ ) { - // This isn't necessarily a single line text input - // But commands don't actually care as long as the thing being passed in - // actually has a command with that name. So this should work with single - // and multiline text inputs. Ideally we'll merge them into one component - // in the future. - iOSTextInputCommands.blur(textField); + UIManager.blur(textFieldID); } else if (Platform.OS === 'android') { - AndroidTextInputCommands.blur(textField); - } - } -} - -function registerInput(textField: ComponentRef) { - if (typeof textField === 'number') { - if (__DEV__) { - console.error( - 'registerInput must be called with a host component. Passing a react tag is deprecated.', + UIManager.dispatchViewManagerCommand( + textFieldID, + UIManager.getViewManagerConfig('AndroidTextInput').Commands + .blurTextInput, + null, ); } - - return; } - - inputs.add(textField); } -function unregisterInput(textField: ComponentRef) { - if (typeof textField === 'number') { - if (__DEV__) { - console.error( - 'unregisterInput must be called with a host component. Passing a react tag is deprecated.', - ); - } - - return; - } - inputs.delete(textField); +function registerInput(textFieldID: number) { + inputs.add(textFieldID); } -function isTextInput(textField: ComponentRef): boolean { - if (typeof textField === 'number') { - if (__DEV__) { - console.error( - 'isTextInput must be called with a host component. Passing a react tag is deprecated.', - ); - } - - return false; - } +function unregisterInput(textFieldID: number) { + inputs.delete(textFieldID); +} - return inputs.has(textField); +function isTextInput(textFieldID: number): boolean { + return inputs.has(textFieldID); } module.exports = { - currentlyFocusedInput, - focusInput, - blurInput, - currentlyFocusedField, focusField, blurField, diff --git a/Libraries/Components/TextInput/__tests__/TextInput-test.js b/Libraries/Components/TextInput/__tests__/TextInput-test.js index 38a64dccb6936c..8eb8a477185dc8 100644 --- a/Libraries/Components/TextInput/__tests__/TextInput-test.js +++ b/Libraries/Components/TextInput/__tests__/TextInput-test.js @@ -87,10 +87,6 @@ describe('TextInput tests', () => { expect(textInputRef.current.isFocused()).toBe(false); ReactNative.findNodeHandle = jest.fn().mockImplementation(ref => { - if (ref == null) { - return null; - } - if ( ref === textInputRef.current || ref === textInputRef.current.getNativeRef() @@ -101,17 +97,13 @@ describe('TextInput tests', () => { return 2; }); - TextInput.State.focusTextInput(textInputRef.current); + const inputTag = ReactNative.findNodeHandle(textInputRef.current); + + TextInput.State.focusTextInput(inputTag); expect(textInputRef.current.isFocused()).toBe(true); - expect(TextInput.State.currentlyFocusedInput()).toBe(textInputRef.current); - // This function is currently deprecated and will be removed in the future - expect(TextInput.State.currentlyFocusedField()).toBe( - ReactNative.findNodeHandle(textInputRef.current), - ); - TextInput.State.blurTextInput(textInputRef.current); + expect(TextInput.State.currentlyFocusedField()).toBe(inputTag); + TextInput.State.blurTextInput(inputTag); expect(textInputRef.current.isFocused()).toBe(false); - expect(TextInput.State.currentlyFocusedInput()).toBe(null); - // This function is currently deprecated and will be removed in the future expect(TextInput.State.currentlyFocusedField()).toBe(null); }); @@ -149,20 +141,16 @@ describe('TextInput tests', () => { const inputTag1 = ReactNative.findNodeHandle(textInputRe1.current); const inputTag2 = ReactNative.findNodeHandle(textInputRe2.current); - TextInput.State.focusTextInput(textInputRe1.current); + TextInput.State.focusTextInput(inputTag1); expect(textInputRe1.current.isFocused()).toBe(true); expect(textInputRe2.current.isFocused()).toBe(false); - expect(TextInput.State.currentlyFocusedInput()).toBe(textInputRe1.current); - // This function is currently deprecated and will be removed in the future expect(TextInput.State.currentlyFocusedField()).toBe(inputTag1); - TextInput.State.focusTextInput(textInputRe2.current); + TextInput.State.focusTextInput(inputTag2); expect(textInputRe1.current.isFocused()).toBe(false); expect(textInputRe2.current.isFocused()).toBe(true); - expect(TextInput.State.currentlyFocusedInput()).toBe(textInputRe2.current); - // This function is currently deprecated and will be removed in the future expect(TextInput.State.currentlyFocusedField()).toBe(inputTag2); }); diff --git a/Libraries/Components/TextInput/__tests__/__snapshots__/TextInput-test.js.snap b/Libraries/Components/TextInput/__tests__/__snapshots__/TextInput-test.js.snap index 6e14c9f23e84d5..0f2f841dc5a432 100644 --- a/Libraries/Components/TextInput/__tests__/__snapshots__/TextInput-test.js.snap +++ b/Libraries/Components/TextInput/__tests__/__snapshots__/TextInput-test.js.snap @@ -8,7 +8,6 @@ exports[`TextInput tests should render as expected: should deep render when mock enableFocusRing={true} focusable={true} forwardedRef={null} - mostRecentEventCount={0} onBlur={[Function]} onChange={[Function]} onClick={[Function]} @@ -37,7 +36,6 @@ exports[`TextInput tests should render as expected: should deep render when not enableFocusRing={true} focusable={true} forwardedRef={null} - mostRecentEventCount={0} onBlur={[Function]} onChange={[Function]} onClick={[Function]} diff --git a/Libraries/Components/Touchable/TVTouchable.js b/Libraries/Components/Touchable/TVTouchable.js index 01e51ba766509a..8b827d0810846a 100644 --- a/Libraries/Components/Touchable/TVTouchable.js +++ b/Libraries/Components/Touchable/TVTouchable.js @@ -11,7 +11,7 @@ 'use strict'; import invariant from 'invariant'; -import ReactNative from '../../Renderer/shims/ReactNative'; +import ReactNative from '../../Renderer/shims/ReactNative.js'; import type { BlurEvent, FocusEvent, diff --git a/Libraries/Components/Touchable/TouchableBounce.js b/Libraries/Components/Touchable/TouchableBounce.js index af315ce36d60b4..2d24a59fcfa775 100644 --- a/Libraries/Components/Touchable/TouchableBounce.js +++ b/Libraries/Components/Touchable/TouchableBounce.js @@ -10,13 +10,11 @@ 'use strict'; -import Pressability, { - type PressabilityConfig, -} from '../../Pressability/Pressability'; -import {PressabilityDebugView} from '../../Pressability/PressabilityDebug'; -import type {ViewStyleProp} from '../../StyleSheet/StyleSheet'; -import TVTouchable from './TVTouchable'; -import typeof TouchableWithoutFeedback from './TouchableWithoutFeedback'; +import Pressability from '../../Pressability/Pressability.js'; +import {PressabilityDebugView} from '../../Pressability/PressabilityDebug.js'; +import type {ViewStyleProp} from '../../StyleSheet/StyleSheet.js'; +import TVTouchable from './TVTouchable.js'; +import typeof TouchableWithoutFeedback from './TouchableWithoutFeedback.js'; import {Animated, Platform} from 'react-native'; import * as React from 'react'; @@ -41,20 +39,21 @@ class TouchableBounce extends React.Component { _tvTouchable: ?TVTouchable; state: State = { - pressability: new Pressability(this._createPressabilityConfig()), - scale: new Animated.Value(1), - }; - - _createPressabilityConfig(): PressabilityConfig { - return { - cancelable: !this.props.rejectResponderTermination, - disabled: this.props.disabled, - hitSlop: this.props.hitSlop, - delayLongPress: this.props.delayLongPress, - delayPressIn: this.props.delayPressIn, - delayPressOut: this.props.delayPressOut, - pressRectOffset: this.props.pressRetentionOffset, - android_disableSound: this.props.touchSoundDisabled, + pressability: new Pressability({ + getHitSlop: () => this.props.hitSlop, + getLongPressDelayMS: () => { + if (this.props.delayLongPress != null) { + const maybeNumber = this.props.delayLongPress; + if (typeof maybeNumber === 'number') { + return maybeNumber; + } + } + return 500; + }, + getPressDelayMS: () => this.props.delayPressIn, + getPressOutDelayMS: () => this.props.delayPressOut, + getPressRectOffset: () => this.props.pressRetentionOffset, + getTouchSoundDisabled: () => this.props.touchSoundDisabled, onBlur: event => { if (Platform.isTV) { this._bounceTo(1, 0.4, 0); @@ -116,8 +115,12 @@ class TouchableBounce extends React.Component { this.props.onPressOut(event); } }, - }; - } + onResponderTerminationRequest: () => + !this.props.rejectResponderTermination, + onStartShouldSetResponder: () => !this.props.disabled, + }), + scale: new Animated.Value(1), + }; _bounceTo( toValue: number, @@ -219,10 +222,6 @@ class TouchableBounce extends React.Component { } } - componentDidUpdate(prevProps: Props, prevState: State) { - this.state.pressability.configure(this._createPressabilityConfig()); - } - componentWillUnmount(): void { if (Platform.isTV) { if (this._tvTouchable != null) { diff --git a/Libraries/Components/Touchable/TouchableHighlight.js b/Libraries/Components/Touchable/TouchableHighlight.js index 5e2f9c0b6f1341..476a90c41f46fe 100644 --- a/Libraries/Components/Touchable/TouchableHighlight.js +++ b/Libraries/Components/Touchable/TouchableHighlight.js @@ -10,14 +10,12 @@ 'use strict'; -import Pressability, { - type PressabilityConfig, -} from '../../Pressability/Pressability'; -import {PressabilityDebugView} from '../../Pressability/PressabilityDebug'; -import StyleSheet, {type ViewStyleProp} from '../../StyleSheet/StyleSheet'; -import type {ColorValue} from '../../StyleSheet/StyleSheetTypes'; -import TVTouchable from './TVTouchable'; -import typeof TouchableWithoutFeedback from './TouchableWithoutFeedback'; +import Pressability from '../../Pressability/Pressability.js'; +import {PressabilityDebugView} from '../../Pressability/PressabilityDebug.js'; +import StyleSheet, {type ViewStyleProp} from '../../StyleSheet/StyleSheet.js'; +import type {ColorValue} from '../../StyleSheet/StyleSheetTypes.js'; +import TVTouchable from './TVTouchable.js'; +import typeof TouchableWithoutFeedback from './TouchableWithoutFeedback.js'; import Platform from '../../Utilities/Platform'; import View from '../../Components/View/View'; import * as React from 'react'; @@ -161,21 +159,21 @@ class TouchableHighlight extends React.Component { _tvTouchable: ?TVTouchable; state: State = { - pressability: new Pressability(this._createPressabilityConfig()), - extraStyles: - this.props.testOnly_pressed === true ? this._createExtraStyles() : null, - }; - - _createPressabilityConfig(): PressabilityConfig { - return { - cancelable: !this.props.rejectResponderTermination, - disabled: this.props.disabled, - hitSlop: this.props.hitSlop, - delayLongPress: this.props.delayLongPress, - delayPressIn: this.props.delayPressIn, - delayPressOut: this.props.delayPressOut, - pressRectOffset: this.props.pressRetentionOffset, - android_disableSound: this.props.touchSoundDisabled, + pressability: new Pressability({ + getHitSlop: () => this.props.hitSlop, + getLongPressDelayMS: () => { + if (this.props.delayLongPress != null) { + const maybeNumber = this.props.delayLongPress; + if (typeof maybeNumber === 'number') { + return maybeNumber; + } + } + return 500; + }, + getPressDelayMS: () => this.props.delayPressIn, + getPressOutDelayMS: () => this.props.delayPressOut, + getPressRectOffset: () => this.props.pressRetentionOffset, + getTouchSoundDisabled: () => this.props.touchSoundDisabled, onBlur: event => { if (Platform.isTV) { this._hideUnderlay(); @@ -229,8 +227,13 @@ class TouchableHighlight extends React.Component { this.props.onPressOut(event); } }, - }; - } + onResponderTerminationRequest: () => + !this.props.rejectResponderTermination, + onStartShouldSetResponder: () => !this.props.disabled, + }), + extraStyles: + this.props.testOnly_pressed === true ? this._createExtraStyles() : null, + }; _createExtraStyles(): ExtraStyles { return { @@ -381,10 +384,6 @@ class TouchableHighlight extends React.Component { } } - componentDidUpdate(prevProps: Props, prevState: State) { - this.state.pressability.configure(this._createPressabilityConfig()); - } - componentWillUnmount(): void { this._isMounted = false; if (this._hideTimeout != null) { diff --git a/Libraries/Components/Touchable/TouchableNativeFeedback.js b/Libraries/Components/Touchable/TouchableNativeFeedback.js index 2911c785c17d00..691cce92eaeaeb 100644 --- a/Libraries/Components/Touchable/TouchableNativeFeedback.js +++ b/Libraries/Components/Touchable/TouchableNativeFeedback.js @@ -10,22 +10,18 @@ 'use strict'; -import Pressability, { - type PressabilityConfig, -} from '../../Pressability/Pressability'; -import {PressabilityDebugView} from '../../Pressability/PressabilityDebug'; -import TVTouchable from './TVTouchable'; -import typeof TouchableWithoutFeedback from './TouchableWithoutFeedback'; +import Pressability from '../../Pressability/Pressability.js'; +import {PressabilityDebugView} from '../../Pressability/PressabilityDebug.js'; +import TVTouchable from './TVTouchable.js'; +import typeof TouchableWithoutFeedback from './TouchableWithoutFeedback.js'; import {Commands} from 'react-native/Libraries/Components/View/ViewNativeComponent'; import ReactNative from 'react-native/Libraries/Renderer/shims/ReactNative'; import type {PressEvent} from 'react-native/Libraries/Types/CoreEventTypes'; import Platform from '../../Utilities/Platform'; import View from '../../Components/View/View'; import processColor from '../../StyleSheet/processColor'; +import type {NativeOrDynamicColorType} from '../../StyleSheet/NativeOrDynamicColorType'; // TODO(macOS ISS#2323203) import * as React from 'react'; -import invariant from 'invariant'; - -import type {ProcessedColorValue} from '../../StyleSheet/processColor'; type Props = $ReadOnly<{| ...React.ElementConfig, @@ -42,13 +38,11 @@ type Props = $ReadOnly<{| attribute: | 'selectableItemBackground' | 'selectableItemBackgroundBorderless', - rippleRadius: ?number, |}> | $ReadOnly<{| type: 'RippleAndroid', color: ?number, borderless: boolean, - rippleRadius: ?number, |}> ), @@ -104,32 +98,24 @@ class TouchableNativeFeedback extends React.Component { * Creates a value for the `background` prop that uses the Android theme's * default background for selectable elements. */ - static SelectableBackground: ( - rippleRadius: ?number, - ) => $ReadOnly<{| + static SelectableBackground: () => $ReadOnly<{| attribute: 'selectableItemBackground', type: 'ThemeAttrAndroid', - rippleRadius: ?number, - |}> = (rippleRadius: ?number) => ({ + |}> = () => ({ type: 'ThemeAttrAndroid', attribute: 'selectableItemBackground', - rippleRadius, }); /** * Creates a value for the `background` prop that uses the Android theme's * default background for borderless selectable elements. Requires API 21+. */ - static SelectableBackgroundBorderless: ( - rippleRadius: ?number, - ) => $ReadOnly<{| + static SelectableBackgroundBorderless: () => $ReadOnly<{| attribute: 'selectableItemBackgroundBorderless', type: 'ThemeAttrAndroid', - rippleRadius: ?number, - |}> = (rippleRadius: ?number) => ({ + |}> = () => ({ type: 'ThemeAttrAndroid', attribute: 'selectableItemBackgroundBorderless', - rippleRadius, }); /** @@ -140,25 +126,15 @@ class TouchableNativeFeedback extends React.Component { static Ripple: ( color: string, borderless: boolean, - rippleRadius: ?number, ) => $ReadOnly<{| borderless: boolean, - color: ?number, - rippleRadius: ?number, + color: ?(number | NativeOrDynamicColorType) /* TODO(macOS ISS#2323203) */, type: 'RippleAndroid', - |}> = (color: string, borderless: boolean, rippleRadius: ?number) => { - const processedColor = processColor(color); - invariant( - processedColor == null || typeof processedColor === 'number', - 'Unexpected color given for Ripple color', - ); - return { - type: 'RippleAndroid', - color: processedColor, - borderless, - rippleRadius, - }; - }; + |}> = (color: string, borderless: boolean) => ({ + type: 'RippleAndroid', + color: processColor(color), + borderless, + }); /** * Whether `useForeground` is supported. @@ -169,21 +145,31 @@ class TouchableNativeFeedback extends React.Component { _tvTouchable: ?TVTouchable; state: State = { - pressability: new Pressability(this._createPressabilityConfig()), - }; - - _createPressabilityConfig(): PressabilityConfig { - return { - cancelable: !this.props.rejectResponderTermination, - disabled: this.props.disabled, - hitSlop: this.props.hitSlop, - delayLongPress: this.props.delayLongPress, - delayPressIn: this.props.delayPressIn, - delayPressOut: this.props.delayPressOut, - pressRectOffset: this.props.pressRetentionOffset, - android_disableSound: this.props.touchSoundDisabled, - onLongPress: this.props.onLongPress, - onPress: this.props.onPress, + pressability: new Pressability({ + getHitSlop: () => this.props.hitSlop, + getLongPressDelayMS: () => { + if (this.props.delayLongPress != null) { + const maybeNumber = this.props.delayLongPress; + if (typeof maybeNumber === 'number') { + return maybeNumber; + } + } + return 500; + }, + getPressDelayMS: () => this.props.delayPressIn, + getPressOutDelayMS: () => this.props.delayPressOut, + getPressRectOffset: () => this.props.pressRetentionOffset, + getTouchSoundDisabled: () => this.props.touchSoundDisabled, + onLongPress: event => { + if (this.props.onLongPress != null) { + this.props.onLongPress(event); + } + }, + onPress: event => { + if (this.props.onPress != null) { + this.props.onPress(event); + } + }, onPressIn: event => { if (Platform.OS === 'android') { this._dispatchPressedStateChange(true); @@ -206,8 +192,11 @@ class TouchableNativeFeedback extends React.Component { this.props.onPressOut(event); } }, - }; - } + onResponderTerminationRequest: () => + !this.props.rejectResponderTermination, + onStartShouldSetResponder: () => !this.props.disabled, + }), + }; _dispatchPressedStateChange(pressed: boolean): void { if (Platform.OS === 'android') { @@ -324,10 +313,6 @@ class TouchableNativeFeedback extends React.Component { } } - componentDidUpdate(prevProps: Props, prevState: State) { - this.state.pressability.configure(this._createPressabilityConfig()); - } - componentWillUnmount(): void { if (Platform.isTV) { if (this._tvTouchable != null) { diff --git a/Libraries/Components/Touchable/TouchableOpacity.js b/Libraries/Components/Touchable/TouchableOpacity.js index 248ddd6ed6848f..53d9cab5ed7590 100644 --- a/Libraries/Components/Touchable/TouchableOpacity.js +++ b/Libraries/Components/Touchable/TouchableOpacity.js @@ -10,12 +10,10 @@ 'use strict'; -import Pressability, { - type PressabilityConfig, -} from '../../Pressability/Pressability'; -import {PressabilityDebugView} from '../../Pressability/PressabilityDebug'; -import TVTouchable from './TVTouchable'; -import typeof TouchableWithoutFeedback from './TouchableWithoutFeedback'; +import Pressability from '../../Pressability/Pressability.js'; +import {PressabilityDebugView} from '../../Pressability/PressabilityDebug.js'; +import TVTouchable from './TVTouchable.js'; +import typeof TouchableWithoutFeedback from './TouchableWithoutFeedback.js'; import Animated from 'react-native/Libraries/Animated/src/Animated'; import Easing from 'react-native/Libraries/Animated/src/Easing'; import type {ViewStyleProp} from 'react-native/Libraries/StyleSheet/StyleSheet'; @@ -136,18 +134,20 @@ class TouchableOpacity extends React.Component { state: State = { anim: new Animated.Value(this._getChildStyleOpacityWithDefault()), - pressability: new Pressability(this._createPressabilityConfig()), - }; - - _createPressabilityConfig(): PressabilityConfig { - return { - cancelable: !this.props.rejectResponderTermination, - disabled: this.props.disabled, - hitSlop: this.props.hitSlop, - delayLongPress: this.props.delayLongPress, - delayPressIn: this.props.delayPressIn, - delayPressOut: this.props.delayPressOut, - pressRectOffset: this.props.pressRetentionOffset, + pressability: new Pressability({ + getHitSlop: () => this.props.hitSlop, + getLongPressDelayMS: () => { + if (this.props.delayLongPress != null) { + const maybeNumber = this.props.delayLongPress; + if (typeof maybeNumber === 'number') { + return maybeNumber; + } + } + return 500; + }, + getPressDelayMS: () => this.props.delayPressIn, + getPressOutDelayMS: () => this.props.delayPressOut, + getPressRectOffset: () => this.props.pressRetentionOffset, onBlur: event => { if (Platform.isTV) { this._opacityInactive(250); @@ -164,8 +164,16 @@ class TouchableOpacity extends React.Component { this.props.onFocus(event); } }, - onLongPress: this.props.onLongPress, - onPress: this.props.onPress, + onLongPress: event => { + if (this.props.onLongPress != null) { + this.props.onLongPress(event); + } + }, + onPress: event => { + if (this.props.onPress != null) { + this.props.onPress(event); + } + }, onPressIn: event => { this._opacityActive( event.dispatchConfig.registrationName === 'onResponderGrant' @@ -182,8 +190,11 @@ class TouchableOpacity extends React.Component { this.props.onPressOut(event); } }, - }; - } + onResponderTerminationRequest: () => + !this.props.rejectResponderTermination, + onStartShouldSetResponder: () => !this.props.disabled, + }), + }; /** * Animate the touchable to a new opacity. @@ -302,7 +313,6 @@ class TouchableOpacity extends React.Component { } componentDidUpdate(prevProps: Props, prevState: State) { - this.state.pressability.configure(this._createPressabilityConfig()); if (this.props.disabled !== prevProps.disabled) { this._opacityInactive(250); } diff --git a/Libraries/Components/Touchable/TouchableWithoutFeedback.js b/Libraries/Components/Touchable/TouchableWithoutFeedback.js index 4157b18db2ee97..5e3d8216eb79f6 100755 --- a/Libraries/Components/Touchable/TouchableWithoutFeedback.js +++ b/Libraries/Components/Touchable/TouchableWithoutFeedback.js @@ -10,11 +10,9 @@ 'use strict'; -import Pressability, { - type PressabilityConfig, -} from '../../Pressability/Pressability'; -import {PressabilityDebugView} from '../../Pressability/PressabilityDebug'; -import TVTouchable from './TVTouchable'; +import Pressability from '../../Pressability/Pressability.js'; +import {PressabilityDebugView} from '../../Pressability/PressabilityDebug.js'; +import TVTouchable from './TVTouchable.js'; import type { AccessibilityActionEvent, AccessibilityActionInfo, @@ -120,7 +118,55 @@ class TouchableWithoutFeedback extends React.Component { _tvTouchable: ?TVTouchable; state: State = { - pressability: new Pressability(createPressabilityConfig(this.props)), + pressability: new Pressability({ + getHitSlop: () => this.props.hitSlop, + getLongPressDelayMS: () => { + if (this.props.delayLongPress != null) { + const maybeNumber = this.props.delayLongPress; + if (typeof maybeNumber === 'number') { + return maybeNumber; + } + } + return 500; + }, + getPressDelayMS: () => this.props.delayPressIn, + getPressOutDelayMS: () => this.props.delayPressOut, + getPressRectOffset: () => this.props.pressRetentionOffset, + getTouchSoundDisabled: () => this.props.touchSoundDisabled, + onBlur: event => { + if (this.props.onBlur != null) { + this.props.onBlur(event); + } + }, + onFocus: event => { + if (this.props.onFocus != null) { + this.props.onFocus(event); + } + }, + onLongPress: event => { + if (this.props.onLongPress != null) { + this.props.onLongPress(event); + } + }, + onPress: event => { + if (this.props.onPress != null) { + this.props.onPress(event); + } + }, + onPressIn: event => { + if (this.props.onPressIn != null) { + this.props.onPressIn(event); + } + }, + onPressOut: event => { + if (this.props.onPressOut != null) { + this.props.onPressOut(event); + } + }, + onResponderTerminationRequest: () => + !this.props.rejectResponderTermination, + onStartShouldSetResponder: () => !this.props.disabled, + }), }; render(): React.Node { @@ -186,10 +232,6 @@ class TouchableWithoutFeedback extends React.Component { } } - componentDidUpdate(): void { - this.state.pressability.configure(createPressabilityConfig(this.props)); - } - componentWillUnmount(): void { if (Platform.isTV) { if (this._tvTouchable != null) { @@ -200,23 +242,4 @@ class TouchableWithoutFeedback extends React.Component { } } -function createPressabilityConfig(props: Props): PressabilityConfig { - return { - cancelable: !props.rejectResponderTermination, - disabled: props.disabled, - hitSlop: props.hitSlop, - delayLongPress: props.delayLongPress, - delayPressIn: props.delayPressIn, - delayPressOut: props.delayPressOut, - pressRectOffset: props.pressRetentionOffset, - android_disableSound: props.touchSoundDisabled, - onBlur: props.onBlur, - onFocus: props.onFocus, - onLongPress: props.onLongPress, - onPress: props.onPress, - onPressIn: props.onPressIn, - onPressOut: props.onPressOut, - }; -} - module.exports = TouchableWithoutFeedback; diff --git a/Libraries/Components/View/ReactNativeViewViewConfig.js b/Libraries/Components/View/ReactNativeViewViewConfig.js index 8858f62d5b0be4..1d17f3e3bac1a5 100644 --- a/Libraries/Components/View/ReactNativeViewViewConfig.js +++ b/Libraries/Components/View/ReactNativeViewViewConfig.js @@ -11,7 +11,6 @@ 'use strict'; import ReactNativeViewViewConfigAndroid from './ReactNativeViewViewConfigAndroid'; import ReactNativeViewViewConfigMacOS from './ReactNativeViewViewConfigMacOS'; // TODO(macOS ISS#2323203) -import {Platform} from 'react-native'; const ReactNativeViewConfig = { uiViewClassName: 'RCTView', @@ -326,9 +325,7 @@ const ReactNativeViewConfig = { textTransform: true, tintColor: {process: require('../../StyleSheet/processColor')}, top: true, - transform: ((Platform.OS === 'ios' || Platform.OS === 'macos' // TODO(macOS ISS#2323203) - ? {diff: require('../../Utilities/differ/matricesDiffer')} - : {process: require('../../StyleSheet/processTransform')}): any), + transform: {diff: require('../../Utilities/differ/matricesDiffer')}, transformMatrix: true, translateX: true, translateY: true, @@ -338,9 +335,7 @@ const ReactNativeViewConfig = { }, testID: true, top: true, - transform: ((Platform.OS === 'ios' || Platform.OS === 'macos' // TODO(macOS ISS#2323203) - ? {diff: require('../../Utilities/differ/matricesDiffer')} - : {process: require('../../StyleSheet/processTransform')}): any), + transform: {diff: require('../../Utilities/differ/matricesDiffer')}, translateX: true, translateY: true, width: true, diff --git a/Libraries/Components/View/View.js b/Libraries/Components/View/View.js index 0fd0d938676524..bd2c26f0e5d7d0 100644 --- a/Libraries/Components/View/View.js +++ b/Libraries/Components/View/View.js @@ -11,10 +11,7 @@ 'use strict'; import type {ViewProps} from './ViewPropTypes'; - -const React = require('react'); -import ViewNativeComponent from './ViewNativeComponent'; -const TextAncestor = require('../../Text/TextAncestor'); +import type {ViewNativeComponentType} from './ViewNativeComponent'; export type Props = ViewProps; @@ -23,19 +20,7 @@ export type Props = ViewProps; * supports layout with flexbox, style, some touch handling, and accessibility * controls. * - * @see https://reactnative.dev/docs/view.html + * @see http://facebook.github.io/react-native/docs/view.html */ -const View: React.AbstractComponent< - ViewProps, - React.ElementRef, -> = React.forwardRef((props: ViewProps, forwardedRef) => { - return ( - - - - ); -}); - -View.displayName = 'View'; - -module.exports = View; +module.exports = (require('./ViewNativeComponent') + .default: ViewNativeComponentType); diff --git a/Libraries/Components/View/ViewNativeComponent.js b/Libraries/Components/View/ViewNativeComponent.js index 902414c4eb45e3..568f38f7fda9a3 100644 --- a/Libraries/Components/View/ViewNativeComponent.js +++ b/Libraries/Components/View/ViewNativeComponent.js @@ -53,7 +53,8 @@ let viewConfig: }, |}; -if (__DEV__ || global.RN$Bridgeless) { +// Only use the JS view config in DEV +if (__DEV__) { // On Android, View extends the base component with additional view-only props // On iOS, the base component is View if (Platform.OS === 'android') { diff --git a/Libraries/Components/View/ViewPropTypes.js b/Libraries/Components/View/ViewPropTypes.js index 395901478ae312..a481193fceb285 100644 --- a/Libraries/Components/View/ViewPropTypes.js +++ b/Libraries/Components/View/ViewPropTypes.js @@ -55,7 +55,7 @@ type DirectEventProps = $ReadOnly<{| * When `accessible` is true, the system will try to invoke this function * when the user performs accessibility tap gesture. * - * See https://reactnative.dev/docs/view.html#onaccessibilitytap + * See http://facebook.github.io/react-native/docs/view.html#onaccessibilitytap */ onAccessibilityTap?: ?() => mixed, @@ -86,7 +86,7 @@ type DirectEventProps = $ReadOnly<{| * the new layout may not yet be reflected on the screen at the time the * event is received, especially if a layout animation is in progress. * - * See https://reactnative.dev/docs/view.html#onlayout + * See http://facebook.github.io/react-native/docs/view.html#onlayout */ onLayout?: ?(event: LayoutEvent) => mixed, @@ -94,7 +94,7 @@ type DirectEventProps = $ReadOnly<{| * When `accessible` is `true`, the system will invoke this function when the * user performs the magic tap gesture. * - * See https://reactnative.dev/docs/view.html#onmagictap + * See http://facebook.github.io/react-native/docs/view.html#onmagictap */ onMagicTap?: ?() => mixed, @@ -102,7 +102,7 @@ type DirectEventProps = $ReadOnly<{| * When `accessible` is `true`, the system will invoke this function when the * user performs the escape gesture. * - * See https://reactnative.dev/docs/view.html#onaccessibilityescape + * See http://facebook.github.io/react-native/docs/view.html#onaccessibilityescape */ onAccessibilityEscape?: ?() => mixed, |}>; @@ -136,7 +136,7 @@ type GestureResponderEventProps = $ReadOnly<{| * `View.props.onMoveShouldSetResponder: (event) => [true | false]`, where * `event` is a synthetic touch event as described above. * - * See https://reactnative.dev/docs/view.html#onmoveshouldsetresponder + * See http://facebook.github.io/react-native/docs/view.html#onmoveshouldsetresponder */ onMoveShouldSetResponder?: ?(e: PressEvent) => boolean, @@ -147,7 +147,7 @@ type GestureResponderEventProps = $ReadOnly<{| * `View.props.onMoveShouldSetResponderCapture: (event) => [true | false]`, * where `event` is a synthetic touch event as described above. * - * See https://reactnative.dev/docs/view.html#onMoveShouldsetrespondercapture + * See http://facebook.github.io/react-native/docs/view.html#onMoveShouldsetrespondercapture */ onMoveShouldSetResponderCapture?: ?(e: PressEvent) => boolean, @@ -161,7 +161,7 @@ type GestureResponderEventProps = $ReadOnly<{| * PanResponder includes a note `// TODO: t7467124 investigate if this can be removed` that * should help fixing this return type. * - * See https://reactnative.dev/docs/view.html#onrespondergrant + * See http://facebook.github.io/react-native/docs/view.html#onrespondergrant */ onResponderGrant?: ?(e: PressEvent) => void | boolean, @@ -171,7 +171,7 @@ type GestureResponderEventProps = $ReadOnly<{| * `View.props.onResponderMove: (event) => {}`, where `event` is a synthetic * touch event as described above. * - * See https://reactnative.dev/docs/view.html#onrespondermove + * See http://facebook.github.io/react-native/docs/view.html#onrespondermove */ onResponderMove?: ?(e: PressEvent) => void, @@ -182,7 +182,7 @@ type GestureResponderEventProps = $ReadOnly<{| * `View.props.onResponderReject: (event) => {}`, where `event` is a * synthetic touch event as described above. * - * See https://reactnative.dev/docs/view.html#onresponderreject + * See http://facebook.github.io/react-native/docs/view.html#onresponderreject */ onResponderReject?: ?(e: PressEvent) => void, @@ -192,7 +192,7 @@ type GestureResponderEventProps = $ReadOnly<{| * `View.props.onResponderRelease: (event) => {}`, where `event` is a * synthetic touch event as described above. * - * See https://reactnative.dev/docs/view.html#onresponderrelease + * See http://facebook.github.io/react-native/docs/view.html#onresponderrelease */ onResponderRelease?: ?(e: PressEvent) => void, @@ -208,7 +208,7 @@ type GestureResponderEventProps = $ReadOnly<{| * `View.props.onResponderTerminate: (event) => {}`, where `event` is a * synthetic touch event as described above. * - * See https://reactnative.dev/docs/view.html#onresponderterminate + * See http://facebook.github.io/react-native/docs/view.html#onresponderterminate */ onResponderTerminate?: ?(e: PressEvent) => void, @@ -219,7 +219,7 @@ type GestureResponderEventProps = $ReadOnly<{| * `View.props.onResponderTerminationRequest: (event) => {}`, where `event` * is a synthetic touch event as described above. * - * See https://reactnative.dev/docs/view.html#onresponderterminationrequest + * See http://facebook.github.io/react-native/docs/view.html#onresponderterminationrequest */ onResponderTerminationRequest?: ?(e: PressEvent) => boolean, @@ -229,7 +229,7 @@ type GestureResponderEventProps = $ReadOnly<{| * `View.props.onStartShouldSetResponder: (event) => [true | false]`, where * `event` is a synthetic touch event as described above. * - * See https://reactnative.dev/docs/view.html#onstartshouldsetresponder + * See http://facebook.github.io/react-native/docs/view.html#onstartshouldsetresponder */ onStartShouldSetResponder?: ?(e: PressEvent) => boolean, @@ -240,7 +240,7 @@ type GestureResponderEventProps = $ReadOnly<{| * `View.props.onStartShouldSetResponderCapture: (event) => [true | false]`, * where `event` is a synthetic touch event as described above. * - * See https://reactnative.dev/docs/view.html#onstartshouldsetrespondercapture + * See http://facebook.github.io/react-native/docs/view.html#onstartshouldsetrespondercapture */ onStartShouldSetResponderCapture?: ?(e: PressEvent) => boolean, |}>; @@ -254,7 +254,6 @@ type AndroidDrawableRipple = $ReadOnly<{| type: 'RippleAndroid', color?: ?number, borderless?: ?boolean, - rippleRadius?: ?number, |}>; type AndroidDrawable = AndroidDrawableThemeAttr | AndroidDrawableRipple; @@ -269,7 +268,7 @@ type AndroidViewProps = $ReadOnly<{| * * @platform android * - * See https://reactnative.dev/docs/view.html#rendertohardwaretextureandroid + * See http://facebook.github.io/react-native/docs/view.html#rendertohardwaretextureandroid */ renderToHardwareTextureAndroid?: ?boolean, @@ -281,7 +280,7 @@ type AndroidViewProps = $ReadOnly<{| * * @platform android * - * See https://reactnative.dev/docs/view.html#collapsable + * See http://facebook.github.io/react-native/docs/view.html#collapsable */ collapsable?: ?boolean, @@ -291,7 +290,7 @@ type AndroidViewProps = $ReadOnly<{| * * @platform android * - * See https://reactnative.dev/docs/view.html#needsoffscreenalphacompositing + * See http://facebook.github.io/react-native/docs/view.html#needsoffscreenalphacompositing */ needsOffscreenAlphaCompositing?: ?boolean, @@ -318,7 +317,7 @@ type AndroidViewProps = $ReadOnly<{| * * @platform android * - * See https://reactnative.dev/docs/view.html#accessibilityliveregion + * See http://facebook.github.io/react-native/docs/view.html#accessibilityliveregion */ accessibilityLiveRegion?: ?('none' | 'polite' | 'assertive'), @@ -336,7 +335,7 @@ type AndroidViewProps = $ReadOnly<{| * * @platform android * - * See https://reactnative.dev/docs/view.html#importantforaccessibility + * See http://facebook.github.io/react-native/docs/view.html#importantforaccessibility */ importantForAccessibility?: ?('auto' | 'yes' | 'no' | 'no-hide-descendants'), @@ -414,7 +413,7 @@ type IOSViewProps = $ReadOnly<{| * * @platform ios * - * See https://reactnative.dev/docs/view.html#accessibilityviewismodal + * See http://facebook.github.io/react-native/docs/view.html#accessibilityviewismodal */ accessibilityViewIsModal?: ?boolean, @@ -424,7 +423,7 @@ type IOSViewProps = $ReadOnly<{| * * @platform ios * - * See https://reactnative.dev/docs/view.html#accessibilityElementsHidden + * See http://facebook.github.io/react-native/docs/view.html#accessibilityElementsHidden */ accessibilityElementsHidden?: ?boolean, @@ -442,7 +441,7 @@ type IOSViewProps = $ReadOnly<{| * When `accessible` is `true`, the system will invoke this function when the * user performs the magic tap gesture. * - * See https://reactnative.dev/docs/view.html#shouldrasterizeios + * See http://facebook.github.io/react-native/docs/view.html#shouldrasterizeios */ shouldRasterizeIOS?: ?boolean, |}>; @@ -463,7 +462,7 @@ export type ViewProps = $ReadOnly<{| * When `true`, indicates that the view is an accessibility element. * By default, all the touchable elements are accessible. * - * See https://reactnative.dev/docs/view.html#accessible + * See http://facebook.github.io/react-native/docs/view.html#accessible */ accessible?: ?boolean, @@ -472,7 +471,7 @@ export type ViewProps = $ReadOnly<{| * with the element. By default, the label is constructed by traversing all * the children and accumulating all the `Text` nodes separated by space. * - * See https://reactnative.dev/docs/view.html#accessibilitylabel + * See http://facebook.github.io/react-native/docs/view.html#accessibilitylabel */ accessibilityLabel?: ?Stringish, @@ -482,7 +481,7 @@ export type ViewProps = $ReadOnly<{| * accessibility label. * * - * See https://reactnative.dev/docs/view.html#accessibilityHint + * See http://facebook.github.io/react-native/docs/view.html#accessibilityHint */ accessibilityHint?: ?Stringish, @@ -508,7 +507,7 @@ export type ViewProps = $ReadOnly<{| * * > This disables the 'layout-only view removal' optimization for this view! * - * See https://reactnative.dev/docs/view.html#testid + * See http://facebook.github.io/react-native/docs/view.html#testid */ testID?: ?string, @@ -517,7 +516,7 @@ export type ViewProps = $ReadOnly<{| * * > This disables the 'layout-only view removal' optimization for this view! * - * See https://reactnative.dev/docs/view.html#nativeid + * See http://facebook.github.io/react-native/docs/view.html#nativeid */ nativeID?: ?string, @@ -530,14 +529,14 @@ export type ViewProps = $ReadOnly<{| * > of sibling views always takes precedence if a touch hits two overlapping * > views. * - * See https://reactnative.dev/docs/view.html#hitslop + * See http://facebook.github.io/react-native/docs/view.html#hitslop */ hitSlop?: ?EdgeInsetsProp, /** * Controls whether the `View` can be the target of touch events. * - * See https://reactnative.dev/docs/view.html#pointerevents + * See http://facebook.github.io/react-native/docs/view.html#pointerevents */ pointerEvents?: ?('auto' | 'box-none' | 'box-only' | 'none'), @@ -549,7 +548,7 @@ export type ViewProps = $ReadOnly<{| * subviews must also have `overflow: hidden`, as should the containing view * (or one of its superviews). * - * See https://reactnative.dev/docs/view.html#removeclippedsubviews + * See http://facebook.github.io/react-native/docs/view.html#removeclippedsubviews */ removeClippedSubviews?: ?boolean, diff --git a/Libraries/Core/ExceptionsManager.js b/Libraries/Core/ExceptionsManager.js index fd6ce28ad6e732..d26f824ab5c280 100644 --- a/Libraries/Core/ExceptionsManager.js +++ b/Libraries/Core/ExceptionsManager.js @@ -52,11 +52,7 @@ function preprocessException(data: ExceptionData): ExceptionData { * Handles the developer-visible aspect of errors and exceptions */ let exceptionID = 0; -function reportException( - e: ExtendedError, - isFatal: boolean, - reportToConsole: boolean, // only true when coming from handleException; the error has not yet been logged -) { +function reportException(e: ExtendedError, isFatal: boolean) { const NativeExceptionsManager = require('./NativeExceptionsManager').default; if (NativeExceptionsManager) { const parseErrorStack = require('./Devtools/parseErrorStack'); @@ -68,15 +64,26 @@ function reportException( message += `\n\nThis error is located at:${e.componentStack}`; } const namePrefix = e.name == null || e.name === '' ? '' : `${e.name}: `; + const isFromConsoleError = e.name === 'console.error'; if (!message.startsWith(namePrefix)) { message = namePrefix + message; } + // Errors created by `console.error` have already been printed. + if (!isFromConsoleError) { + if (console._errorOriginal) { + console._errorOriginal(message); + } else { + console.error(message); + } + } + message = e.jsEngine == null ? message : `${message}, js engine: ${e.jsEngine}`; - const isHandledByLogBox = e.forceRedbox !== true; + const isHandledByLogBox = + e.forceRedbox !== true && global.__unstable_isLogBoxEnabled === true; const data = preprocessException({ message, @@ -97,13 +104,6 @@ function reportException( }, }); - if (reportToConsole) { - // we feed back into console.error, to make sure any methods that are - // monkey patched on top of console.error are called when coming from - // handleException - console.error(data.message); - } - if (isHandledByLogBox) { LogBoxData.addException({ ...data, @@ -134,11 +134,6 @@ function reportException( console.log('Unable to symbolicate stack trace: ' + error.message); }); } - } else if (reportToConsole) { - // we feed back into console.error, to make sure any methods that are - // monkey patched on top of console.error are called when coming from - // handleException - console.error(e); } } @@ -148,10 +143,6 @@ declare var console: typeof console & { ... }; -// If we trigger console.error _from_ handleException, -// we do want to make sure that console.error doesn't trigger error reporting again -let inExceptionHandler = false; - /** * Logs exceptions to the (native) console and displays them */ @@ -166,61 +157,21 @@ function handleException(e: mixed, isFatal: boolean) { // `throw ''` somewhere in your codebase. error = new SyntheticError(e); } - try { - inExceptionHandler = true; - reportException(error, isFatal, /*reportToConsole*/ true); - } finally { - inExceptionHandler = false; - } + reportException(error, isFatal); } function reactConsoleErrorHandler() { - // bubble up to any original handlers - console._errorOriginal.apply(console, arguments); if (!console.reportErrorsAsExceptions) { - return; - } - if (inExceptionHandler) { - // The fundamental trick here is that are multiple entry point to logging errors: - // (see D19743075 for more background) - // - // 1. An uncaught exception being caught by the global handler - // 2. An error being logged throw console.error - // - // However, console.error is monkey patched multiple times: by this module, and by the - // DevTools setup that sends messages to Metro. - // The patching order cannot be relied upon. - // - // So, some scenarios that are handled by this flag: - // - // Logging an error: - // 1. console.error called from user code - // 2. (possibly) arrives _first_ at DevTool handler, send to Metro - // 3. Bubbles to here - // 4. goes into report Exception. - // 5. should not trigger console.error again, to avoid looping / logging twice - // 6. should still bubble up to original console - // (which might either be console.log, or the DevTools handler in case it patched _earlier_ and (2) didn't happen) - // - // Throwing an uncaught exception: - // 1. exception thrown - // 2. picked up by handleException - // 3. should be send to console.error (not console._errorOriginal, as DevTools might have patched _later_ and it needs to send it to Metro) - // 4. that _might_ bubble again to the `reactConsoleErrorHandle` defined here - // -> should not handle exception _again_, to avoid looping / showing twice (this code branch) - // 5. should still bubble up to original console (which might either be console.log, or the DevTools handler in case that one patched _earlier_) + console._errorOriginal.apply(console, arguments); return; } if (arguments[0] && arguments[0].stack) { // reportException will console.error this with high enough fidelity. - reportException( - arguments[0], - /* isFatal */ false, - /*reportToConsole*/ false, - ); + reportException(arguments[0], /* isFatal */ false); } else { - const stringifySafe = require('../Utilities/stringifySafe').default; + console._errorOriginal.apply(console, arguments); + const stringifySafe = require('../Utilities/stringifySafe'); const str = Array.prototype.map .call(arguments, value => typeof value === 'string' ? value : stringifySafe(value), @@ -235,7 +186,7 @@ function reactConsoleErrorHandler() { } const error: ExtendedError = new SyntheticError(str); error.name = 'console.error'; - reportException(error, /* isFatal */ false, /*reportToConsole*/ false); + reportException(error, /* isFatal */ false); } } diff --git a/Libraries/Core/InitializeCore.js b/Libraries/Core/InitializeCore.js index e00120aa4b48a5..8f12f11b8612db 100644 --- a/Libraries/Core/InitializeCore.js +++ b/Libraries/Core/InitializeCore.js @@ -29,7 +29,6 @@ const start = Date.now(); require('./setUpGlobals'); -require('./setUpPerformance'); require('./setUpSystrace'); require('./setUpErrorHandling'); require('./polyfillPromise'); diff --git a/Libraries/Core/ReactFiberErrorDialog.js b/Libraries/Core/ReactFiberErrorDialog.js index d329e2d27bd4cb..a247a2ad6ca889 100644 --- a/Libraries/Core/ReactFiberErrorDialog.js +++ b/Libraries/Core/ReactFiberErrorDialog.js @@ -9,9 +9,13 @@ */ export type CapturedError = { + +componentName: ?string, +componentStack: string, +error: mixed, +errorBoundary: ?{...}, + +errorBoundaryFound: boolean, + +errorBoundaryName: string | null, + +willRetry: boolean, ... }; diff --git a/Libraries/Core/ReactNativeVersion.js b/Libraries/Core/ReactNativeVersion.js index bf4b32f41b0ac3..0c88a4c9abd4fa 100644 --- a/Libraries/Core/ReactNativeVersion.js +++ b/Libraries/Core/ReactNativeVersion.js @@ -11,7 +11,7 @@ exports.version = { major: 0, - minor: 63, + minor: 62, patch: 2, prerelease: null, }; diff --git a/Libraries/Core/Timers/JSTimers.js b/Libraries/Core/Timers/JSTimers.js index 4c154db519deb2..feaeddf89a0c94 100644 --- a/Libraries/Core/Timers/JSTimers.js +++ b/Libraries/Core/Timers/JSTimers.js @@ -113,11 +113,16 @@ function _callTimer(timerID: number, frameTime: number, didTimeout: ?boolean) { } if (__DEV__) { - Systrace.beginEvent(type + ' [invoke]'); + Systrace.beginEvent('Systrace.callTimer: ' + type); } // Clear the metadata - if (type !== 'setInterval') { + if ( + type === 'setTimeout' || + type === 'setImmediate' || + type === 'requestAnimationFrame' || + type === 'requestIdleCallback' + ) { _clearIndex(timerIndex); } @@ -162,23 +167,21 @@ function _callTimer(timerID: number, frameTime: number, didTimeout: ?boolean) { * more immediates are queued up (can be used as a condition a while loop). */ function _callImmediatesPass() { - if (immediates.length === 0) { - return false; - } - if (__DEV__) { Systrace.beginEvent('callImmediatesPass()'); } // The main reason to extract a single pass is so that we can track // in the system trace - const passImmediates = immediates; - immediates = []; - - // Use for loop rather than forEach as per @vjeux's advice - // https://github.com/facebook/react-native/commit/c8fd9f7588ad02d2293cac7224715f4af7b0f352#commitcomment-14570051 - for (let i = 0; i < passImmediates.length; ++i) { - _callTimer(passImmediates[i], 0); + if (immediates.length > 0) { + const passImmediates = immediates.slice(); + immediates = []; + + // Use for loop rather than forEach as per @vjeux's advice + // https://github.com/facebook/react-native/commit/c8fd9f7588ad02d2293cac7224715f4af7b0f352#commitcomment-14570051 + for (let i = 0; i < passImmediates.length; ++i) { + _callTimer(passImmediates[i], 0); + } } if (__DEV__) { @@ -378,7 +381,8 @@ const JSTimers = { 'Cannot call `callTimers` with an empty list of IDs.', ); - errors = (null: ?Array); + // $FlowFixMe: optionals do not allow assignment from null + errors = null; for (let i = 0; i < timersToCall.length; i++) { _callTimer(timersToCall[i], 0); } @@ -409,9 +413,10 @@ const JSTimers = { return; } - errors = (null: ?Array); + // $FlowFixMe: optionals do not allow assignment from null + errors = null; if (requestIdleCallbacks.length > 0) { - const passIdleCallbacks = requestIdleCallbacks; + const passIdleCallbacks = requestIdleCallbacks.slice(); requestIdleCallbacks = []; for (let i = 0; i < passIdleCallbacks.length; ++i) { @@ -437,7 +442,7 @@ const JSTimers = { * before we hand control back to native. */ callImmediates() { - errors = (null: ?Array); + errors = null; while (_callImmediatesPass()) {} if (errors) { errors.forEach(error => @@ -496,7 +501,6 @@ let ExportedJSTimers: {| setInterval: (func: any, duration: number, ...args: any) => number, setTimeout: (func: any, duration: number, ...args: any) => number, |}; - if (!NativeTiming) { console.warn("Timing native module is not available, can't set timers."); // $FlowFixMe: we can assume timers are generally available @@ -508,6 +512,8 @@ if (!NativeTiming) { ExportedJSTimers = JSTimers; } -BatchedBridge.setImmediatesCallback(JSTimers.callImmediates); +BatchedBridge.setImmediatesCallback( + ExportedJSTimers.callImmediates.bind(ExportedJSTimers), +); module.exports = ExportedJSTimers; diff --git a/Libraries/Core/Timers/__tests__/JSTimers-test.js b/Libraries/Core/Timers/__tests__/JSTimers-test.js deleted file mode 100644 index baa281f03e6bcd..00000000000000 --- a/Libraries/Core/Timers/__tests__/JSTimers-test.js +++ /dev/null @@ -1,413 +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. - * - * @format - * @emails oncall+react_native - */ - -'use strict'; - -const NativeTiming = { - createTimer: jest.fn(), - deleteTimer: jest.fn(), - setSendIdleEvents: jest.fn(), -}; - -const warning = jest.fn(); - -jest - .enableAutomock() - .mock('fbjs/lib/warning', () => warning, {virtual: true}) - .mock('../NativeTiming', () => ({ - __esModule: true, - default: NativeTiming, - })) - .unmock('../JSTimers'); - -const JSTimers = require('../JSTimers'); - -describe('JSTimers', function() { - const firstArgumentOfTheLastCallTo = function(func) { - return func.mock.calls[func.mock.calls.length - 1][0]; - }; - - beforeEach(function() { - global.setTimeout = JSTimers.setTimeout; - }); - - it('should call function with setTimeout', function() { - let didCall = false; - const id = JSTimers.setTimeout(function() { - didCall = true; - }); - JSTimers.callTimers([id]); - expect(didCall).toBe(true); - }); - - it('should call nested setTimeout when cleared', function() { - let id1, id2, id3; - let callCount = 0; - - id1 = JSTimers.setTimeout(function() { - JSTimers.clearTimeout(id1); - id2 = JSTimers.setTimeout(function() { - JSTimers.clearTimeout(id2); - id3 = JSTimers.setTimeout(function() { - callCount += 1; - }); - }); - }); - JSTimers.callTimers([id1]); - JSTimers.callTimers([id2]); - JSTimers.callTimers([id3]); - - expect(callCount).toBe(1); - }); - - it('should call nested setImmediate when cleared', function() { - let id1, id2, id3; - let callCount = 0; - - id1 = JSTimers.setImmediate(function() { - JSTimers.clearImmediate(id1); - id2 = JSTimers.setImmediate(function() { - JSTimers.clearImmediate(id2); - id3 = JSTimers.setImmediate(function() { - callCount += 1; - }); - }); - }); - JSTimers.callTimers([id1]); - JSTimers.callTimers([id2]); - JSTimers.callTimers([id3]); - - expect(callCount).toBe(1); - }); - - it('should call nested requestAnimationFrame when cleared', function() { - let id1, id2, id3; - let callCount = 0; - - id1 = JSTimers.requestAnimationFrame(function() { - JSTimers.cancelAnimationFrame(id1); - id2 = JSTimers.requestAnimationFrame(function() { - JSTimers.cancelAnimationFrame(id2); - id3 = JSTimers.requestAnimationFrame(function() { - callCount += 1; - }); - }); - }); - JSTimers.callTimers([id1]); - JSTimers.callTimers([id2]); - JSTimers.callTimers([id3]); - - expect(callCount).toBe(1); - }); - - it('should call nested setInterval when cleared', function() { - let id1, id2, id3; - let callCount = 0; - - id1 = JSTimers.setInterval(function() { - JSTimers.clearInterval(id1); - id2 = JSTimers.setInterval(function() { - JSTimers.clearInterval(id2); - id3 = JSTimers.setInterval(function() { - callCount += 1; - }); - }); - }); - JSTimers.callTimers([id1]); - JSTimers.callTimers([id2]); - JSTimers.callTimers([id3]); - - expect(callCount).toBe(1); - }); - - it('should call function with setInterval', function() { - const callback = jest.fn(); - const id = JSTimers.setInterval(callback); - JSTimers.callTimers([id]); - expect(callback).toBeCalledTimes(1); - }); - - it('should call function with setImmediate', function() { - const callback = jest.fn(); - JSTimers.setImmediate(callback); - JSTimers.callImmediates(); - expect(callback).toBeCalledTimes(1); - }); - - it('should not call function with clearImmediate', function() { - const callback = jest.fn(); - const id = JSTimers.setImmediate(callback); - JSTimers.clearImmediate(id); - JSTimers.callImmediates(); - expect(callback).not.toBeCalled(); - }); - - it('should call functions in the right order with setImmediate', function() { - let count = 0; - let firstCalled = null; - let secondCalled = null; - JSTimers.setImmediate(function() { - firstCalled = count++; - }); - JSTimers.setImmediate(function() { - secondCalled = count++; - }); - JSTimers.callImmediates(); - expect(firstCalled).toBe(0); - expect(secondCalled).toBe(1); - }); - - it('should call functions in the right order with nested setImmediate', function() { - let count = 0; - let firstCalled = null; - let secondCalled = null; - let thirdCalled = null; - JSTimers.setImmediate(function() { - firstCalled = count++; - JSTimers.setImmediate(function() { - thirdCalled = count++; - }); - secondCalled = count++; - }); - JSTimers.callImmediates(); - expect(firstCalled).toBe(0); - expect(secondCalled).toBe(1); - expect(thirdCalled).toBe(2); - }); - - it('should call nested setImmediate', function() { - let firstCalled = false; - let secondCalled = false; - JSTimers.setImmediate(function() { - firstCalled = true; - JSTimers.setImmediate(function() { - secondCalled = true; - }); - }); - JSTimers.callImmediates(); - expect(firstCalled).toBe(true); - expect(secondCalled).toBe(true); - }); - - it('should call function with requestAnimationFrame', function() { - const callback = jest.fn(); - const id = JSTimers.requestAnimationFrame(callback); - JSTimers.callTimers([id]); - expect(callback).toBeCalledTimes(1); - }); - - it("should not call function if we don't callTimers", function() { - const callback = jest.fn(); - JSTimers.setTimeout(callback, 10); - expect(callback).not.toBeCalled(); - JSTimers.setInterval(callback, 10); - expect(callback).not.toBeCalled(); - JSTimers.requestAnimationFrame(callback); - expect(callback).not.toBeCalled(); - }); - - it('should call setInterval as many times as callTimers is called', function() { - const callback = jest.fn(); - const id = JSTimers.setInterval(callback, 10); - JSTimers.callTimers([id]); - JSTimers.callTimers([id]); - JSTimers.callTimers([id]); - JSTimers.callTimers([id]); - expect(callback).toBeCalledTimes(4); - }); - - it("should only call the function who's id we pass in", function() { - let firstCalled = false; - let secondCalled = false; - JSTimers.setTimeout(function() { - firstCalled = true; - }); - const secondID = JSTimers.setTimeout(function() { - secondCalled = true; - }); - JSTimers.callTimers([secondID]); - expect(firstCalled).toBe(false); - expect(secondCalled).toBe(true); - }); - - it('should work with calling multiple timers', function() { - let firstCalled = false; - let secondCalled = false; - const firstID = JSTimers.setTimeout(function() { - firstCalled = true; - }); - const secondID = JSTimers.setTimeout(function() { - secondCalled = true; - }); - JSTimers.callTimers([firstID, secondID]); - expect(firstCalled).toBe(true); - expect(secondCalled).toBe(true); - }); - - it('should still execute all callbacks even if one throws', function() { - const firstID = JSTimers.setTimeout(function() { - throw new Error('error'); - }, 10); - let secondCalled = false; - const secondID = JSTimers.setTimeout(function() { - secondCalled = true; - }, 10); - expect(JSTimers.callTimers.bind(null, [firstID, secondID])).toThrow(); - expect(secondCalled).toBe(true); - }); - - it('should clear timers even if callback throws', function() { - const timerID = JSTimers.setTimeout(function() { - throw new Error('error'); - }, 10); - expect(JSTimers.callTimers.bind(null, [timerID])).toThrow('error'); - JSTimers.callTimers.bind(null, [timerID]); - }); - - it('should not warn if callback is called on cancelled timer', function() { - const callback = jest.fn(); - const timerID = JSTimers.setTimeout(callback, 10); - JSTimers.clearTimeout(timerID); - JSTimers.callTimers([timerID]); - expect(callback).not.toBeCalled(); - expect(firstArgumentOfTheLastCallTo(warning)).toBe(true); - }); - - it('should warn when callTimers is called with garbage timer id', function() { - JSTimers.callTimers([1337]); - expect(firstArgumentOfTheLastCallTo(warning)).toBe(false); - }); - - it('should only call callback once for setTimeout', function() { - const callback = jest.fn(); - const timerID = JSTimers.setTimeout(callback, 10); - // First time the timer fires, should call callback - JSTimers.callTimers([timerID]); - expect(callback).toBeCalledTimes(1); - // Second time it should be ignored - JSTimers.callTimers([timerID]); - expect(callback).toBeCalledTimes(1); - expect(firstArgumentOfTheLastCallTo(warning)).toBe(true); - }); - - it('should only call callback once for requestAnimationFrame', function() { - const callback = jest.fn(); - const timerID = JSTimers.requestAnimationFrame(callback, 10); - // First time the timer fires, should call callback - JSTimers.callTimers([timerID]); - expect(callback).toBeCalledTimes(1); - // Second time it should be ignored - JSTimers.callTimers([timerID]); - expect(callback).toBeCalledTimes(1); - expect(firstArgumentOfTheLastCallTo(warning)).toBe(true); - }); - - it('should re-throw first exception', function() { - const timerID1 = JSTimers.setTimeout(function() { - throw new Error('first error'); - }); - const timerID2 = JSTimers.setTimeout(function() { - throw new Error('second error'); - }); - expect(JSTimers.callTimers.bind(null, [timerID1, timerID2])).toThrowError( - 'first error', - ); - }); - - it('should pass along errors thrown from setImmediate', function() { - JSTimers.setImmediate(function() { - throw new Error('error within setImmediate'); - }); - - NativeTiming.createTimer = jest.fn(); - JSTimers.callImmediates(); - - // The remaining errors should be called within setTimeout, in case there - // are a series of them - expect(NativeTiming.createTimer).toBeCalled(); - const timerID = NativeTiming.createTimer.mock.calls[0][0]; - expect(JSTimers.callTimers.bind(null, [timerID])).toThrowError( - 'error within setImmediate', - ); - }); - - it('should throw all errors from setImmediate', function() { - JSTimers.setImmediate(function() { - throw new Error('first error'); - }); - - JSTimers.setImmediate(function() { - throw new Error('second error'); - }); - - NativeTiming.createTimer = jest.fn(); - JSTimers.callImmediates(); - - expect(NativeTiming.createTimer.mock.calls.length).toBe(2); - - const firstTimerID = NativeTiming.createTimer.mock.calls[0][0]; - expect(JSTimers.callTimers.bind(null, [firstTimerID])).toThrowError( - 'first error', - ); - - const secondTimerID = NativeTiming.createTimer.mock.calls[1][0]; - expect(JSTimers.callTimers.bind(null, [secondTimerID])).toThrowError( - 'second error', - ); - }); - - it('should pass along errors thrown from setTimeout', function() { - const timerID = JSTimers.setTimeout(function() { - throw new Error('error within setTimeout'); - }); - - expect(JSTimers.callTimers.bind(null, [timerID])).toThrowError( - 'error within setTimeout', - ); - }); - - it('should throw all errors from setTimeout', function() { - const firstTimerID = JSTimers.setTimeout(function() { - throw new Error('first error'); - }); - const secondTimerID = JSTimers.setTimeout(function() { - throw new Error('second error'); - }); - - NativeTiming.createTimer = jest.fn(); - expect( - JSTimers.callTimers.bind(null, [firstTimerID, secondTimerID]), - ).toThrowError('first error'); - - expect(NativeTiming.createTimer.mock.calls.length).toBe(1); - const thirdTimerID = NativeTiming.createTimer.mock.calls[0][0]; - expect(JSTimers.callTimers.bind(null, [thirdTimerID])).toThrowError( - 'second error', - ); - }); - - it('should pass along errors thrown from setInterval', function() { - const timerID = JSTimers.setInterval(function() { - throw new Error('error within setInterval'); - }); - expect(JSTimers.callTimers.bind(null, [timerID])).toThrowError( - 'error within setInterval', - ); - }); - - it('should not call to native when clearing a null timer', function() { - const timerID = JSTimers.setTimeout(() => {}); - JSTimers.clearTimeout(timerID); - NativeTiming.deleteTimer = jest.fn(); - - JSTimers.clearTimeout(null); - expect(NativeTiming.deleteTimer.mock.calls.length).toBe(0); - }); -}); diff --git a/Libraries/Core/__tests__/ExceptionsManager-test.js b/Libraries/Core/__tests__/ExceptionsManager-test.js index 71e3be3cb94164..a34fc2d06f168b 100644 --- a/Libraries/Core/__tests__/ExceptionsManager-test.js +++ b/Libraries/Core/__tests__/ExceptionsManager-test.js @@ -137,9 +137,8 @@ describe('ExceptionsManager', () => { message + '\n\n' + 'This error is located at:' + - capturedErrorDefaults.componentStack + - ', js engine: ' + - jsEngine, + capturedErrorDefaults.componentStack, + // JS engine omitted here! ); }); @@ -294,8 +293,7 @@ describe('ExceptionsManager', () => { ); expect(exceptionData.isFatal).toBe(false); expect(mockError.mock.calls[0]).toHaveLength(1); - expect(mockError.mock.calls[0][0]).toBeInstanceOf(Error); - expect(mockError.mock.calls[0][0].toString()).toBe(formattedMessage); + expect(mockError.mock.calls[0][0]).toBe(formattedMessage); }); test('logging a string', () => { @@ -463,23 +461,6 @@ describe('ExceptionsManager', () => { }); describe('unstable_setExceptionDecorator', () => { - let mockError; - beforeEach(() => { - // NOTE: We initialise a fresh mock every time using spyOn, above. - // We can't use `console._errorOriginal` for this, because that's a bound - // (=wrapped) version of the mock and Jest does not approve. - mockError = console.error; - ExceptionsManager.installConsoleErrorReporter(); - }); - - afterEach(() => { - // There is no uninstallConsoleErrorReporter. Do this so the next install - // works. - console.error = console._errorOriginal; - delete console._errorOriginal; - delete console.reportErrorsAsExceptions; - }); - test('modifying the exception data', () => { const error = new Error('Some error happened'); const decorator = jest.fn().mockImplementation(data => ({ @@ -528,7 +509,7 @@ describe('ExceptionsManager', () => { expect(nativeReportException).toHaveBeenCalled(); }); - test('prevents decorator recursion from error handler', () => { + test('prevents decorator recursion', () => { const error = new Error('Some error happened'); const decorator = jest.fn().mockImplementation(data => { console.error('Logging an error within the decorator'); @@ -538,35 +519,11 @@ describe('ExceptionsManager', () => { }; }); + ExceptionsManager.installConsoleErrorReporter(); ExceptionsManager.unstable_setExceptionDecorator(decorator); ExceptionsManager.handleException(error, true); - expect(nativeReportException).toHaveBeenCalledTimes(1); - expect(nativeReportException.mock.calls[0][0].message).toMatch( - /decorated: .*Some error happened/, - ); - expect(mockError).toHaveBeenCalledTimes(2); - expect(mockError.mock.calls[0][0]).toMatch( - /Logging an error within the decorator/, - ); - expect(mockError.mock.calls[1][0]).toMatch( - /decorated: .*Some error happened/, - ); - }); - - test('prevents decorator recursion from console.error', () => { - const error = new Error('Some error happened'); - const decorator = jest.fn().mockImplementation(data => { - console.error('Logging an error within the decorator'); - return { - ...data, - message: 'decorated: ' + data.message, - }; - }); - - ExceptionsManager.unstable_setExceptionDecorator(decorator); - console.error(error); - + expect(decorator).toHaveBeenCalled(); expect(nativeReportException).toHaveBeenCalledTimes(2); expect(nativeReportException.mock.calls[0][0].message).toMatch( /Logging an error within the decorator/, @@ -574,52 +531,6 @@ describe('ExceptionsManager', () => { expect(nativeReportException.mock.calls[1][0].message).toMatch( /decorated: .*Some error happened/, ); - expect(mockError).toHaveBeenCalledTimes(2); - // console.error calls are chained without exception pre-processing, so decorator doesn't apply - expect(mockError.mock.calls[0][0].toString()).toMatch( - /Error: Some error happened/, - ); - expect(mockError.mock.calls[1][0]).toMatch( - /Logging an error within the decorator/, - ); - }); - - test('can handle throwing decorators recursion when exception is thrown', () => { - const error = new Error('Some error happened'); - const decorator = jest.fn().mockImplementation(data => { - throw new Error('Throwing an error within the decorator'); - }); - - ExceptionsManager.unstable_setExceptionDecorator(decorator); - ExceptionsManager.handleException(error, true); - - expect(nativeReportException).toHaveBeenCalledTimes(1); - // Exceptions in decorators are ignored and the decorator is not applied - expect(nativeReportException.mock.calls[0][0].message).toMatch( - /Error: Some error happened/, - ); - expect(mockError).toHaveBeenCalledTimes(1); - expect(mockError.mock.calls[0][0]).toMatch(/Error: Some error happened/); - }); - - test('can handle throwing decorators recursion when exception is logged', () => { - const error = new Error('Some error happened'); - const decorator = jest.fn().mockImplementation(data => { - throw new Error('Throwing an error within the decorator'); - }); - - ExceptionsManager.unstable_setExceptionDecorator(decorator); - console.error(error); - - expect(nativeReportException).toHaveBeenCalledTimes(1); - // Exceptions in decorators are ignored and the decorator is not applied - expect(nativeReportException.mock.calls[0][0].message).toMatch( - /Error: Some error happened/, - ); - expect(mockError).toHaveBeenCalledTimes(1); - expect(mockError.mock.calls[0][0].toString()).toMatch( - /Error: Some error happened/, - ); }); }); }); diff --git a/Libraries/Core/setUpBatchedBridge.js b/Libraries/Core/setUpBatchedBridge.js index d718f3c8355f50..8f6db0ec2f1e2a 100644 --- a/Libraries/Core/setUpBatchedBridge.js +++ b/Libraries/Core/setUpBatchedBridge.js @@ -10,37 +10,52 @@ 'use strict'; -let registerModule; -if (global.RN$Bridgeless && global.RN$registerCallableModule) { - registerModule = global.RN$registerCallableModule; -} else { +/** + * We don't set up the batched bridge in bridgeless mode. Once we've migrated + * everything over to bridgeless we can just delete this file. + */ +if (!global.RN$Bridgeless) { + /** + * Set up the BatchedBridge. This must be done after the other steps in + * InitializeCore to ensure that the JS environment has been initialized. + * You can use this module directly, or just require InitializeCore. + */ const BatchedBridge = require('../BatchedBridge/BatchedBridge'); - registerModule = (moduleName, factory) => - BatchedBridge.registerLazyCallableModule(moduleName, factory); -} - -registerModule('Systrace', () => require('../Performance/Systrace')); -registerModule('JSTimers', () => require('./Timers/JSTimers')); -registerModule('HeapCapture', () => require('../HeapCapture/HeapCapture')); -registerModule('SamplingProfiler', () => - require('../Performance/SamplingProfiler'), -); -registerModule('RCTLog', () => require('../Utilities/RCTLog')); -registerModule('RCTDeviceEventEmitter', () => - require('../EventEmitter/RCTDeviceEventEmitter'), -); -registerModule('RCTNativeAppEventEmitter', () => - require('../EventEmitter/RCTNativeAppEventEmitter'), -); -registerModule('GlobalPerformanceLogger', () => - require('../Utilities/GlobalPerformanceLogger'), -); -registerModule('JSDevSupportModule', () => - require('../Utilities/JSDevSupportModule'), -); + BatchedBridge.registerLazyCallableModule('Systrace', () => + require('../Performance/Systrace'), + ); + BatchedBridge.registerLazyCallableModule('JSTimers', () => + require('./Timers/JSTimers'), + ); + BatchedBridge.registerLazyCallableModule('HeapCapture', () => + require('../HeapCapture/HeapCapture'), + ); + BatchedBridge.registerLazyCallableModule('SamplingProfiler', () => + require('../Performance/SamplingProfiler'), + ); + BatchedBridge.registerLazyCallableModule('RCTLog', () => + require('../Utilities/RCTLog'), + ); + BatchedBridge.registerLazyCallableModule('RCTDeviceEventEmitter', () => + require('../EventEmitter/RCTDeviceEventEmitter'), + ); + BatchedBridge.registerLazyCallableModule('RCTNativeAppEventEmitter', () => + require('../EventEmitter/RCTNativeAppEventEmitter'), + ); + BatchedBridge.registerLazyCallableModule('GlobalPerformanceLogger', () => + require('../Utilities/GlobalPerformanceLogger'), + ); + BatchedBridge.registerLazyCallableModule('JSDevSupportModule', () => + require('../Utilities/JSDevSupportModule'), + ); -if (__DEV__ && !global.__RCTProfileIsProfiling) { - registerModule('HMRClient', () => require('../Utilities/HMRClient')); -} else { - registerModule('HMRClient', () => require('../Utilities/HMRClientProdShim')); + if (__DEV__ && !global.__RCTProfileIsProfiling) { + BatchedBridge.registerLazyCallableModule('HMRClient', () => + require('../Utilities/HMRClient'), + ); + } else { + BatchedBridge.registerLazyCallableModule('HMRClient', () => + require('../Utilities/HMRClientProdShim'), + ); + } } diff --git a/Libraries/Core/setUpDeveloperTools.js b/Libraries/Core/setUpDeveloperTools.js index 3ee84d8727349d..6fe91a5f0b9a1f 100644 --- a/Libraries/Core/setUpDeveloperTools.js +++ b/Libraries/Core/setUpDeveloperTools.js @@ -54,7 +54,6 @@ if (__DEV__) { 'trace', 'info', 'warn', - 'error', 'log', 'group', 'groupCollapsed', diff --git a/Libraries/Core/setUpPerformance.js b/Libraries/Core/setUpPerformance.js deleted file mode 100644 index 6fd0a1e42b8213..00000000000000 --- a/Libraries/Core/setUpPerformance.js +++ /dev/null @@ -1,26 +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. - * - * @flow strict-local - * @format - */ - -'use strict'; - -if (!global.performance) { - global.performance = {}; -} - -/** - * Returns a double, measured in milliseconds. - * https://developer.mozilla.org/en-US/docs/Web/API/Performance/now - */ -if (typeof global.performance.now !== 'function') { - global.performance.now = function() { - const performanceNow = global.nativePerformanceNow || Date.now; - return performanceNow(); - }; -} diff --git a/Libraries/Core/setUpReactDevTools.js b/Libraries/Core/setUpReactDevTools.js index 2ba4c5dc6a41b0..084b2c7f577ca9 100644 --- a/Libraries/Core/setUpReactDevTools.js +++ b/Libraries/Core/setUpReactDevTools.js @@ -41,7 +41,7 @@ if (__DEV__) { const WebSocket = require('../WebSocket/WebSocket'); const ws = new WebSocket('ws://' + host + ':' + port); - const viewConfig = require('../Components/View/ReactNativeViewViewConfig'); + const viewConfig = require('../Components/View/ReactNativeViewViewConfig.js'); reactDevTools.connectToDevTools({ isAppActive, resolveRNStyle: require('../StyleSheet/flattenStyle'), diff --git a/Libraries/DeprecatedPropTypes/DeprecatedTextPropTypes.js b/Libraries/DeprecatedPropTypes/DeprecatedTextPropTypes.js index f14635ab3a8cfe..f053e8e283d6ce 100644 --- a/Libraries/DeprecatedPropTypes/DeprecatedTextPropTypes.js +++ b/Libraries/DeprecatedPropTypes/DeprecatedTextPropTypes.js @@ -27,7 +27,7 @@ module.exports = { * When `numberOfLines` is set, this prop defines how text will be * truncated. * - * See https://reactnative.dev/docs/text.html#ellipsizemode + * See https://facebook.github.io/react-native/docs/text.html#ellipsizemode */ ellipsizeMode: (PropTypes.oneOf([ 'head', @@ -38,13 +38,13 @@ module.exports = { /** * Used to truncate the text with an ellipsis. * - * See https://reactnative.dev/docs/text.html#numberoflines + * See https://facebook.github.io/react-native/docs/text.html#numberoflines */ numberOfLines: PropTypes.number, /** * Set text break strategy on Android. * - * See https://reactnative.dev/docs/text.html#textbreakstrategy + * See https://facebook.github.io/react-native/docs/text.html#textbreakstrategy */ textBreakStrategy: (PropTypes.oneOf([ 'simple', @@ -54,63 +54,63 @@ module.exports = { /** * Invoked on mount and layout changes. * - * See https://reactnative.dev/docs/text.html#onlayout + * See https://facebook.github.io/react-native/docs/text.html#onlayout */ onLayout: PropTypes.func, /** * This function is called on press. * - * See https://reactnative.dev/docs/text.html#onpress + * See https://facebook.github.io/react-native/docs/text.html#onpress */ onPress: PropTypes.func, /** * This function is called on long press. * - * See https://reactnative.dev/docs/text.html#onlongpress + * See https://facebook.github.io/react-native/docs/text.html#onlongpress */ onLongPress: PropTypes.func, /** * Defines how far your touch may move off of the button, before * deactivating the button. * - * See https://reactnative.dev/docs/text.html#pressretentionoffset + * See https://facebook.github.io/react-native/docs/text.html#pressretentionoffset */ pressRetentionOffset: DeprecatedEdgeInsetsPropType, /** * Lets the user select text. * - * See https://reactnative.dev/docs/text.html#selectable + * See https://facebook.github.io/react-native/docs/text.html#selectable */ selectable: PropTypes.bool, /** * The highlight color of the text. * - * See https://reactnative.dev/docs/text.html#selectioncolor + * See https://facebook.github.io/react-native/docs/text.html#selectioncolor */ selectionColor: DeprecatedColorPropType, /** * When `true`, no visual change is made when text is pressed down. * - * See https://reactnative.dev/docs/text.html#supperhighlighting + * See https://facebook.github.io/react-native/docs/text.html#supperhighlighting */ suppressHighlighting: PropTypes.bool, style: stylePropType, /** * Used to locate this view in end-to-end tests. * - * See https://reactnative.dev/docs/text.html#testid + * See https://facebook.github.io/react-native/docs/text.html#testid */ testID: PropTypes.string, /** * Used to locate this view from native code. * - * See https://reactnative.dev/docs/text.html#nativeid + * See https://facebook.github.io/react-native/docs/text.html#nativeid */ nativeID: PropTypes.string, /** * Whether fonts should scale to respect Text Size accessibility settings. * - * See https://reactnative.dev/docs/text.html#allowfontscaling + * See https://facebook.github.io/react-native/docs/text.html#allowfontscaling */ allowFontScaling: PropTypes.bool, /** @@ -124,31 +124,31 @@ module.exports = { /** * Indicates whether the view is an accessibility element. * - * See https://reactnative.dev/docs/text.html#accessible + * See https://facebook.github.io/react-native/docs/text.html#accessible */ accessible: PropTypes.bool, /** * Whether font should be scaled down automatically. * - * See https://reactnative.dev/docs/text.html#adjustsfontsizetofit + * See https://facebook.github.io/react-native/docs/text.html#adjustsfontsizetofit */ adjustsFontSizeToFit: PropTypes.bool, /** * Smallest possible scale a font can reach. * - * See https://reactnative.dev/docs/text.html#minimumfontscale + * See https://facebook.github.io/react-native/docs/text.html#minimumfontscale */ minimumFontScale: PropTypes.number, /** * Specifies the disabled state of the text view for testing purposes. * - * See https://reactnative.dev/docs/text.html#disabled + * See https://facebook.github.io/react-native/docs/text.html#disabled */ disabled: PropTypes.bool, /** * Determines the types of data converted to clickable URLs in text. * - * See https://reactnative.dev/docs/text.html#dataDetectorType + * See https://facebook.github.io/react-native/docs/text.html#dataDetectorType */ dataDetectorType: (PropTypes.oneOf( DataDetectorTypes, diff --git a/Libraries/DeprecatedPropTypes/DeprecatedViewPropTypes.js b/Libraries/DeprecatedPropTypes/DeprecatedViewPropTypes.js index c008361311a7a2..6268a7f3faedf1 100644 --- a/Libraries/DeprecatedPropTypes/DeprecatedViewPropTypes.js +++ b/Libraries/DeprecatedPropTypes/DeprecatedViewPropTypes.js @@ -26,7 +26,7 @@ module.exports = { * When `true`, indicates that the view is an accessibility element. * By default, all the touchable elements are accessible. * - * See https://reactnative.dev/docs/view.html#accessible + * See http://facebook.github.io/react-native/docs/view.html#accessible */ accessible: PropTypes.bool, @@ -35,7 +35,7 @@ module.exports = { * with the element. By default, the label is constructed by traversing all * the children and accumulating all the `Text` nodes separated by space. * - * See https://reactnative.dev/docs/view.html#accessibilitylabel + * See http://facebook.github.io/react-native/docs/view.html#accessibilitylabel */ accessibilityLabel: PropTypes.node, @@ -45,7 +45,7 @@ module.exports = { * accessibility label. * * - * See https://reactnative.dev/docs/view.html#accessibilityHint + * See http://facebook.github.io/react-native/docs/view.html#accessibilityHint */ accessibilityHint: PropTypes.string, @@ -108,7 +108,7 @@ module.exports = { * * @platform android * - * See https://reactnative.dev/docs/view.html#accessibilityliveregion + * See http://facebook.github.io/react-native/docs/view.html#accessibilityliveregion */ accessibilityLiveRegion: (PropTypes.oneOf([ 'none', @@ -123,7 +123,7 @@ module.exports = { * * @platform android * - * See https://reactnative.dev/docs/view.html#importantforaccessibility + * See http://facebook.github.io/react-native/docs/view.html#importantforaccessibility */ importantForAccessibility: (PropTypes.oneOf([ 'auto', @@ -139,7 +139,7 @@ module.exports = { * * @platform ios * - * See https://reactnative.dev/docs/view.html#accessibilityviewismodal + * See http://facebook.github.io/react-native/docs/view.html#accessibilityviewismodal */ accessibilityViewIsModal: PropTypes.bool, @@ -149,7 +149,7 @@ module.exports = { * * @platform ios * - * See https://reactnative.dev/docs/view.html#accessibilityElementsHidden + * See http://facebook.github.io/react-native/docs/view.html#accessibilityElementsHidden */ accessibilityElementsHidden: PropTypes.bool, @@ -165,7 +165,7 @@ module.exports = { * When `accessible` is true, the system will try to invoke this function * when the user performs accessibility tap gesture. * - * See https://reactnative.dev/docs/view.html#onaccessibilitytap + * See http://facebook.github.io/react-native/docs/view.html#onaccessibilitytap */ onAccessibilityTap: PropTypes.func, @@ -173,7 +173,7 @@ module.exports = { * When `accessible` is `true`, the system will invoke this function when the * user performs the magic tap gesture. * - * See https://reactnative.dev/docs/view.html#onmagictap + * See http://facebook.github.io/react-native/docs/view.html#onmagictap */ onMagicTap: PropTypes.func, @@ -182,7 +182,7 @@ module.exports = { * * > This disables the 'layout-only view removal' optimization for this view! * - * See https://reactnative.dev/docs/view.html#testid + * See http://facebook.github.io/react-native/docs/view.html#testid */ testID: PropTypes.string, @@ -191,7 +191,7 @@ module.exports = { * * > This disables the 'layout-only view removal' optimization for this view! * - * See https://reactnative.dev/docs/view.html#nativeid + * See http://facebook.github.io/react-native/docs/view.html#nativeid */ nativeID: PropTypes.string, @@ -208,7 +208,7 @@ module.exports = { * `View.props.onResponderGrant: (event) => {}`, where `event` is a synthetic * touch event as described above. * - * See https://reactnative.dev/docs/view.html#onrespondergrant + * See http://facebook.github.io/react-native/docs/view.html#onrespondergrant */ onResponderGrant: PropTypes.func, @@ -218,7 +218,7 @@ module.exports = { * `View.props.onResponderMove: (event) => {}`, where `event` is a synthetic * touch event as described above. * - * See https://reactnative.dev/docs/view.html#onrespondermove + * See http://facebook.github.io/react-native/docs/view.html#onrespondermove */ onResponderMove: PropTypes.func, @@ -229,7 +229,7 @@ module.exports = { * `View.props.onResponderReject: (event) => {}`, where `event` is a * synthetic touch event as described above. * - * See https://reactnative.dev/docs/view.html#onresponderreject + * See http://facebook.github.io/react-native/docs/view.html#onresponderreject */ onResponderReject: PropTypes.func, @@ -239,7 +239,7 @@ module.exports = { * `View.props.onResponderRelease: (event) => {}`, where `event` is a * synthetic touch event as described above. * - * See https://reactnative.dev/docs/view.html#onresponderrelease + * See http://facebook.github.io/react-native/docs/view.html#onresponderrelease */ onResponderRelease: PropTypes.func, @@ -252,7 +252,7 @@ module.exports = { * `View.props.onResponderTerminate: (event) => {}`, where `event` is a * synthetic touch event as described above. * - * See https://reactnative.dev/docs/view.html#onresponderterminate + * See http://facebook.github.io/react-native/docs/view.html#onresponderterminate */ onResponderTerminate: PropTypes.func, @@ -263,7 +263,7 @@ module.exports = { * `View.props.onResponderTerminationRequest: (event) => {}`, where `event` * is a synthetic touch event as described above. * - * See https://reactnative.dev/docs/view.html#onresponderterminationrequest + * See http://facebook.github.io/react-native/docs/view.html#onresponderterminationrequest */ onResponderTerminationRequest: PropTypes.func, @@ -273,7 +273,7 @@ module.exports = { * `View.props.onStartShouldSetResponder: (event) => [true | false]`, where * `event` is a synthetic touch event as described above. * - * See https://reactnative.dev/docs/view.html#onstartshouldsetresponder + * See http://facebook.github.io/react-native/docs/view.html#onstartshouldsetresponder */ onStartShouldSetResponder: PropTypes.func, @@ -284,7 +284,7 @@ module.exports = { * `View.props.onStartShouldSetResponderCapture: (event) => [true | false]`, * where `event` is a synthetic touch event as described above. * - * See https://reactnative.dev/docs/view.html#onstartshouldsetrespondercapture + * See http://facebook.github.io/react-native/docs/view.html#onstartshouldsetrespondercapture */ onStartShouldSetResponderCapture: PropTypes.func, @@ -295,7 +295,7 @@ module.exports = { * `View.props.onMoveShouldSetResponder: (event) => [true | false]`, where * `event` is a synthetic touch event as described above. * - * See https://reactnative.dev/docs/view.html#onmoveshouldsetresponder + * See http://facebook.github.io/react-native/docs/view.html#onmoveshouldsetresponder */ onMoveShouldSetResponder: PropTypes.func, @@ -306,7 +306,7 @@ module.exports = { * `View.props.onMoveShouldSetResponderCapture: (event) => [true | false]`, * where `event` is a synthetic touch event as described above. * - * See https://reactnative.dev/docs/view.html#onMoveShouldsetrespondercapture + * See http://facebook.github.io/react-native/docs/view.html#onMoveShouldsetrespondercapture */ onMoveShouldSetResponderCapture: PropTypes.func, @@ -319,7 +319,7 @@ module.exports = { * > of sibling views always takes precedence if a touch hits two overlapping * > views. * - * See https://reactnative.dev/docs/view.html#hitslop + * See http://facebook.github.io/react-native/docs/view.html#hitslop */ hitSlop: DeprecatedEdgeInsetsPropType, @@ -332,14 +332,14 @@ module.exports = { * the new layout may not yet be reflected on the screen at the time the * event is received, especially if a layout animation is in progress. * - * See https://reactnative.dev/docs/view.html#onlayout + * See http://facebook.github.io/react-native/docs/view.html#onlayout */ onLayout: PropTypes.func, /** * Controls whether the `View` can be the target of touch events. * - * See https://reactnative.dev/docs/view.html#pointerevents + * See http://facebook.github.io/react-native/docs/view.html#pointerevents */ pointerEvents: (PropTypes.oneOf([ 'box-none', @@ -349,7 +349,7 @@ module.exports = { ]): React$PropType$Primitive<'box-none' | 'none' | 'box-only' | 'auto'>), /** - * See https://reactnative.dev/docs/style.html + * See http://facebook.github.io/react-native/docs/style.html */ style: stylePropType, @@ -361,7 +361,7 @@ module.exports = { * subviews must also have `overflow: hidden`, as should the containing view * (or one of its superviews). * - * See https://reactnative.dev/docs/view.html#removeclippedsubviews + * See http://facebook.github.io/react-native/docs/view.html#removeclippedsubviews */ removeClippedSubviews: PropTypes.bool, @@ -371,7 +371,7 @@ module.exports = { * * @platform android * - * See https://reactnative.dev/docs/view.html#rendertohardwaretextureandroid + * See http://facebook.github.io/react-native/docs/view.html#rendertohardwaretextureandroid */ renderToHardwareTextureAndroid: PropTypes.bool, @@ -380,7 +380,7 @@ module.exports = { * * @platform ios * - * See https://reactnative.dev/docs/view.html#shouldrasterizeios + * See http://facebook.github.io/react-native/docs/view.html#shouldrasterizeios */ shouldRasterizeIOS: PropTypes.bool, @@ -392,7 +392,7 @@ module.exports = { * * @platform android * - * See https://reactnative.dev/docs/view.html#collapsable + * See http://facebook.github.io/react-native/docs/view.html#collapsable */ collapsable: PropTypes.bool, @@ -402,7 +402,7 @@ module.exports = { * * @platform android * - * See https://reactnative.dev/docs/view.html#needsoffscreenalphacompositing + * See http://facebook.github.io/react-native/docs/view.html#needsoffscreenalphacompositing */ needsOffscreenAlphaCompositing: PropTypes.bool, }; diff --git a/Libraries/Experimental/Incremental.js b/Libraries/Experimental/Incremental.js new file mode 100644 index 00000000000000..11174c0c833294 --- /dev/null +++ b/Libraries/Experimental/Incremental.js @@ -0,0 +1,198 @@ +/** + * 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. + * + * @format + * @flow + */ + +'use strict'; + +const InteractionManager = require('../Interaction/InteractionManager'); +const PropTypes = require('prop-types'); +const React = require('react'); + +const infoLog = require('../Utilities/infoLog'); + +const DEBUG = false; + +/** + * WARNING: EXPERIMENTAL. Breaking changes will probably happen a lot and will + * not be reliably announced. The whole thing might be deleted, who knows? Use + * at your own risk. + * + * React Native helps make apps smooth by doing all the heavy lifting off the + * main thread, in JavaScript. That works great a lot of the time, except that + * heavy operations like rendering may block the JS thread from responding + * quickly to events like taps, making the app feel sluggish. + * + * `` solves this by slicing up rendering into chunks that are + * spread across multiple event loops. Expensive components can be sliced up + * recursively by wrapping pieces of them and their descendants in + * `` components. `` can be used to make sure + * everything in the group is rendered recursively before calling `onDone` and + * moving on to another sibling group (e.g. render one row at a time, even if + * rendering the top level row component produces more `` chunks). + * `` is a type of `` that keeps it's + * children invisible and out of the layout tree until all rendering completes + * recursively. This means the group will be presented to the user as one unit, + * rather than pieces popping in sequentially. + * + * `` only affects initial render - `setState` and other render + * updates are unaffected. + * + * The chunks are rendered sequentially using the `InteractionManager` queue, + * which means that rendering will pause if it's interrupted by an interaction, + * such as an animation or gesture. + * + * Note there is some overhead, so you don't want to slice things up too much. + * A target of 100-200ms of total work per event loop on old/slow devices might + * be a reasonable place to start. + * + * Below is an example that will incrementally render all the parts of `Row` one + * first, then present them together, then repeat the process for `Row` two, and + * so on: + * + * render: function() { + * return ( + * + * {Array(10).fill().map((rowIdx) => ( + * + * + * {Array(20).fill().map((widgetIdx) => ( + * + * + * + * ))} + * + * + * ))} + * + * ); + * }; + * + * If SlowWidget takes 30ms to render, then without `Incremental`, this would + * block the JS thread for at least `10 * 20 * 30ms = 6000ms`, but with + * `Incremental` it will probably not block for more than 50-100ms at a time, + * allowing user interactions to take place which might even unmount this + * component, saving us from ever doing the remaining rendering work. + */ +export type Props = { + /** + * Called when all the descendants have finished rendering and mounting + * recursively. + */ + onDone?: () => void, + /** + * Tags instances and associated tasks for easier debugging. + */ + name: string, + children: React.Node, + ... +}; +type State = {doIncrementalRender: boolean, ...}; + +class Incremental extends React.Component { + props: Props; + state: State; + context: Context; + _incrementId: number; + _mounted: boolean; + _rendered: boolean; + + static defaultProps: {|name: string|} = { + name: '', + }; + + static contextTypes: + | any + | {| + incrementalGroup: React$PropType$Primitive, + incrementalGroupEnabled: React$PropType$Primitive, + |} = { + incrementalGroup: PropTypes.object, + incrementalGroupEnabled: PropTypes.bool, + }; + + constructor(props: Props, context: Context) { + super(props, context); + this._mounted = false; + this.state = { + doIncrementalRender: false, + }; + } + + getName(): string { + const ctx = this.context.incrementalGroup || {}; + return ctx.groupId + ':' + this._incrementId + '-' + this.props.name; + } + + UNSAFE_componentWillMount() { + const ctx = this.context.incrementalGroup; + if (!ctx) { + return; + } + this._incrementId = ++ctx.incrementalCount; + InteractionManager.runAfterInteractions({ + name: 'Incremental:' + this.getName(), + gen: () => + new Promise(resolve => { + if (!this._mounted || this._rendered) { + resolve(); + return; + } + DEBUG && infoLog('set doIncrementalRender for ' + this.getName()); + this.setState({doIncrementalRender: true}, resolve); + }), + }) + .then(() => { + DEBUG && infoLog('call onDone for ' + this.getName()); + this._mounted && this.props.onDone && this.props.onDone(); + }) + .catch(ex => { + ex.message = `Incremental render failed for ${this.getName()}: ${ + ex.message + }`; + throw ex; + }) + .done(); + } + + render(): React.Node { + if ( + this._rendered || // Make sure that once we render once, we stay rendered even if incrementalGroupEnabled gets flipped. + !this.context.incrementalGroupEnabled || + this.state.doIncrementalRender + ) { + DEBUG && infoLog('render ' + this.getName()); + this._rendered = true; + return this.props.children; + } + return null; + } + + componentDidMount() { + this._mounted = true; + if (!this.context.incrementalGroup) { + this.props.onDone && this.props.onDone(); + } + } + + componentWillUnmount() { + this._mounted = false; + } +} + +export type Context = { + incrementalGroupEnabled: boolean, + incrementalGroup: ?{ + groupId: string, + incrementalCount: number, + ... + }, + ... +}; + +module.exports = Incremental; diff --git a/Libraries/FBLazyVector/BUCK b/Libraries/FBLazyVector/BUCK index ea6c50f49ffb9e..6c3c798d9ca06b 100644 --- a/Libraries/FBLazyVector/BUCK +++ b/Libraries/FBLazyVector/BUCK @@ -3,12 +3,10 @@ load("//tools/build_defs/oss:rn_defs.bzl", "fb_apple_library") fb_apple_library( name = "FBLazyVector", autoglob = True, - complete_nullability = True, contacts = ["oncall+react_native@xmail.facebook.com"], enable_exceptions = False, - extension_api_only = True, frameworks = [], - labels = ["supermodule:ios/default/public.react_native.infra"], + labels = ["supermodule:ios/isolation/infra.react_native"], link_whole = False, visibility = ["PUBLIC"], ) diff --git a/Libraries/FBLazyVector/FBLazyVector.podspec b/Libraries/FBLazyVector/FBLazyVector.podspec index 2589deedb00f28..7fd46967222772 100644 --- a/Libraries/FBLazyVector/FBLazyVector.podspec +++ b/Libraries/FBLazyVector/FBLazyVector.podspec @@ -20,10 +20,10 @@ Pod::Spec.new do |s| s.name = "FBLazyVector" s.version = version s.summary = "-" # TODO - s.homepage = "https://reactnative.dev/" + s.homepage = "http://facebook.github.io/react-native/" s.license = package["license"] s.author = "Facebook, Inc. and its affiliates" - s.platforms = { :ios => "10.0", :tvos => "10.0", :osx => "10.13" } # TODO(macOS ISS#2323203) + s.platforms = { :ios => "9.0", :tvos => "9.2", :osx => "10.13" } # TODO(macOS ISS#2323203) s.source = source s.source_files = "**/*.{c,h,m,mm,cpp}" s.header_dir = "FBLazyVector" diff --git a/Libraries/FBReactNativeSpec/BUCK b/Libraries/FBReactNativeSpec/BUCK index dcef02f8165068..72cb95bac5beb6 100644 --- a/Libraries/FBReactNativeSpec/BUCK +++ b/Libraries/FBReactNativeSpec/BUCK @@ -10,16 +10,15 @@ fb_apple_library( prefix = "FBReactNativeSpec", ), contacts = ["oncall+react_native@xmail.facebook.com"], - extension_api_only = True, frameworks = [ "Foundation", "UIKit", ], - labels = ["supermodule:ios/default/public.react_native.infra"], + labels = ["supermodule:ios/isolation/infra.react_native"], reexport_all_header_dependencies = True, deps = [ - "//xplat/js/react-native-github:RCTTypeSafety", - "//xplat/js/react-native-github/Libraries/RCTRequired:RCTRequired", + "fbsource//xplat/js/react-native-github:RCTTypeSafety", + "fbsource//xplat/js/react-native-github/Libraries/RCTRequired:RCTRequired", react_native_xplat_target_apple("turbomodule/core:core"), ], ) diff --git a/Libraries/FBReactNativeSpec/FBReactNativeSpec.podspec b/Libraries/FBReactNativeSpec/FBReactNativeSpec.podspec index 918eb2f371c314..b31fd71130016a 100644 --- a/Libraries/FBReactNativeSpec/FBReactNativeSpec.podspec +++ b/Libraries/FBReactNativeSpec/FBReactNativeSpec.podspec @@ -17,16 +17,16 @@ else end folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32' -folly_version = '2020.01.13.00' +folly_version = '2018.10.22.00' Pod::Spec.new do |s| s.name = "FBReactNativeSpec" s.version = version s.summary = "-" # TODO - s.homepage = "https://reactnative.dev/" + s.homepage = "http://facebook.github.io/react-native/" s.license = package["license"] s.author = "Facebook, Inc. and its affiliates" - s.platforms = { :ios => "10.0", :tvos => "10.0", :osx => "10.13" } # TODO(macOS ISS#2323203) + s.platforms = { :ios => "9.0", :tvos => "9.2", :osx => "10.13" } # TODO(macOS ISS#2323203) s.compiler_flags = folly_compiler_flags + ' -Wno-nullability-completeness' s.source = source s.source_files = "**/*.{c,h,m,mm,cpp}" diff --git a/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec-generated.mm b/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec-generated.mm index 1856699aa3f140..bce1dea35f5dce 100644 --- a/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec-generated.mm +++ b/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec-generated.mm @@ -36,8 +36,8 @@ } - NativeAccessibilityInfoSpecJSI::NativeAccessibilityInfoSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("AccessibilityInfo", instance, jsInvoker, nativeInvoker, perfLogger) { + NativeAccessibilityInfoSpecJSI::NativeAccessibilityInfoSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("AccessibilityInfo", instance, jsInvoker) { methodMap_["isReduceMotionEnabled"] = MethodMetadata {1, __hostFunction_NativeAccessibilityInfoSpecJSI_isReduceMotionEnabled}; @@ -103,8 +103,8 @@ + (RCTManagedPointer *)JS_NativeAccessibilityManager_SpecSetAccessibilityContent } - NativeAccessibilityManagerSpecJSI::NativeAccessibilityManagerSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("AccessibilityManager", instance, jsInvoker, nativeInvoker, perfLogger) { + NativeAccessibilityManagerSpecJSI::NativeAccessibilityManagerSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("AccessibilityManager", instance, jsInvoker) { methodMap_["getCurrentBoldTextState"] = MethodMetadata {2, __hostFunction_NativeAccessibilityManagerSpecJSI_getCurrentBoldTextState}; @@ -170,8 +170,8 @@ + (RCTManagedPointer *)JS_NativeActionSheetManager_SpecShowShareActionSheetWithO } - NativeActionSheetManagerSpecJSI::NativeActionSheetManagerSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("ActionSheetManager", instance, jsInvoker, nativeInvoker, perfLogger) { + NativeActionSheetManagerSpecJSI::NativeActionSheetManagerSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("ActionSheetManager", instance, jsInvoker) { methodMap_["showActionSheetWithOptions"] = MethodMetadata {2, __hostFunction_NativeActionSheetManagerSpecJSI_showActionSheetWithOptions}; @@ -201,8 +201,8 @@ + (RCTManagedPointer *)JS_NativeAlertManager_Args:(id)json } - NativeAlertManagerSpecJSI::NativeAlertManagerSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("AlertManager", instance, jsInvoker, nativeInvoker, perfLogger) { + NativeAlertManagerSpecJSI::NativeAlertManagerSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("AlertManager", instance, jsInvoker) { methodMap_["alertWithArgs"] = MethodMetadata {2, __hostFunction_NativeAlertManagerSpecJSI_alertWithArgs}; @@ -306,8 +306,8 @@ + (RCTManagedPointer *)JS_NativeAnimatedModule_EventMapping:(id)json } - NativeAnimatedModuleSpecJSI::NativeAnimatedModuleSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("AnimatedModule", instance, jsInvoker, nativeInvoker, perfLogger) { + NativeAnimatedModuleSpecJSI::NativeAnimatedModuleSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("AnimatedModule", instance, jsInvoker) { methodMap_["createAnimatedNode"] = MethodMetadata {2, __hostFunction_NativeAnimatedModuleSpecJSI_createAnimatedNode}; @@ -385,8 +385,8 @@ + (RCTManagedPointer *)JS_NativeAnimatedModule_EventMapping:(id)json } - NativeAnimationsDebugModuleSpecJSI::NativeAnimationsDebugModuleSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("AnimationsDebugModule", instance, jsInvoker, nativeInvoker, perfLogger) { + NativeAnimationsDebugModuleSpecJSI::NativeAnimationsDebugModuleSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("AnimationsDebugModule", instance, jsInvoker) { methodMap_["startRecordingFps"] = MethodMetadata {0, __hostFunction_NativeAnimationsDebugModuleSpecJSI_startRecordingFps}; @@ -426,8 +426,8 @@ + (RCTManagedPointer *)JS_NativeAppState_SpecGetCurrentAppStateSuccessAppState:( } - NativeAppStateSpecJSI::NativeAppStateSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("AppState", instance, jsInvoker, nativeInvoker, perfLogger) { + NativeAppStateSpecJSI::NativeAppStateSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("AppState", instance, jsInvoker) { methodMap_["getCurrentAppState"] = MethodMetadata {2, __hostFunction_NativeAppStateSpecJSI_getCurrentAppState}; @@ -463,8 +463,8 @@ + (RCTManagedPointer *)JS_NativeAppState_SpecGetCurrentAppStateSuccessAppState:( } - NativeAppearanceSpecJSI::NativeAppearanceSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("Appearance", instance, jsInvoker, nativeInvoker, perfLogger) { + NativeAppearanceSpecJSI::NativeAppearanceSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("Appearance", instance, jsInvoker) { methodMap_["getColorScheme"] = MethodMetadata {0, __hostFunction_NativeAppearanceSpecJSI_getColorScheme}; @@ -574,8 +574,8 @@ + (RCTManagedPointer *)JS_NativeAsyncStorage_SpecGetAllKeysCallbackError:(id)jso } - NativeAsyncStorageSpecJSI::NativeAsyncStorageSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("AsyncStorage", instance, jsInvoker, nativeInvoker, perfLogger) { + NativeAsyncStorageSpecJSI::NativeAsyncStorageSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("AsyncStorage", instance, jsInvoker) { methodMap_["multiGet"] = MethodMetadata {2, __hostFunction_NativeAsyncStorageSpecJSI_multiGet}; @@ -633,8 +633,8 @@ + (RCTManagedPointer *)JS_NativeAsyncStorage_SpecGetAllKeysCallbackError:(id)jso } - NativeBlobModuleSpecJSI::NativeBlobModuleSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("BlobModule", instance, jsInvoker, nativeInvoker, perfLogger) { + NativeBlobModuleSpecJSI::NativeBlobModuleSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("BlobModule", instance, jsInvoker) { methodMap_["addNetworkingHandler"] = MethodMetadata {0, __hostFunction_NativeBlobModuleSpecJSI_addNetworkingHandler}; @@ -679,8 +679,8 @@ + (RCTManagedPointer *)JS_NativeAsyncStorage_SpecGetAllKeysCallbackError:(id)jso } - NativeBugReportingSpecJSI::NativeBugReportingSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("BugReporting", instance, jsInvoker, nativeInvoker, perfLogger) { + NativeBugReportingSpecJSI::NativeBugReportingSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("BugReporting", instance, jsInvoker) { methodMap_["startReportAProblemFlow"] = MethodMetadata {0, __hostFunction_NativeBugReportingSpecJSI_startReportAProblemFlow}; @@ -719,8 +719,8 @@ + (RCTManagedPointer *)JS_NativeCameraRollManager_GetPhotosParams:(id)json } - NativeCameraRollManagerSpecJSI::NativeCameraRollManagerSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("CameraRollManager", instance, jsInvoker, nativeInvoker, perfLogger) { + NativeCameraRollManagerSpecJSI::NativeCameraRollManagerSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("CameraRollManager", instance, jsInvoker) { methodMap_["getPhotos"] = MethodMetadata {1, __hostFunction_NativeCameraRollManagerSpecJSI_getPhotos}; @@ -786,8 +786,8 @@ + (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifiersPage:(id)json } - NativeClipboardSpecJSI::NativeClipboardSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("Clipboard", instance, jsInvoker, nativeInvoker, perfLogger) { + NativeClipboardSpecJSI::NativeClipboardSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("Clipboard", instance, jsInvoker) { methodMap_["getString"] = MethodMetadata {0, __hostFunction_NativeClipboardSpecJSI_getString}; @@ -809,8 +809,8 @@ + (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifiersPage:(id)json } - NativeDatePickerAndroidSpecJSI::NativeDatePickerAndroidSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("DatePickerAndroid", instance, jsInvoker, nativeInvoker, perfLogger) { + NativeDatePickerAndroidSpecJSI::NativeDatePickerAndroidSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("DatePickerAndroid", instance, jsInvoker) { methodMap_["open"] = MethodMetadata {1, __hostFunction_NativeDatePickerAndroidSpecJSI_open}; @@ -825,7 +825,7 @@ + (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifiersPage:(id)json static facebook::jsi::Value __hostFunction_NativeDevLoadingViewSpecJSI_showMessage(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, "showMessage", @selector(showMessage:withColor:withBackgroundColor:), args, count); + return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, "showMessage", @selector(showMessage:color:backgroundColor:), args, count); } static facebook::jsi::Value __hostFunction_NativeDevLoadingViewSpecJSI_hide(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { @@ -833,8 +833,8 @@ + (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifiersPage:(id)json } - NativeDevLoadingViewSpecJSI::NativeDevLoadingViewSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("DevLoadingView", instance, jsInvoker, nativeInvoker, perfLogger) { + NativeDevLoadingViewSpecJSI::NativeDevLoadingViewSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("DevLoadingView", instance, jsInvoker) { methodMap_["showMessage"] = MethodMetadata {3, __hostFunction_NativeDevLoadingViewSpecJSI_showMessage}; @@ -872,8 +872,8 @@ + (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifiersPage:(id)json } - NativeDevMenuSpecJSI::NativeDevMenuSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("DevMenu", instance, jsInvoker, nativeInvoker, perfLogger) { + NativeDevMenuSpecJSI::NativeDevMenuSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("DevMenu", instance, jsInvoker) { methodMap_["show"] = MethodMetadata {0, __hostFunction_NativeDevMenuSpecJSI_show}; @@ -931,21 +931,13 @@ + (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifiersPage:(id)json return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, "addMenuItem", @selector(addMenuItem:), args, count); } - static facebook::jsi::Value __hostFunction_NativeDevSettingsSpecJSI_addListener(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, "addListener", @selector(addListener:), args, count); - } - - static facebook::jsi::Value __hostFunction_NativeDevSettingsSpecJSI_removeListeners(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, "removeListeners", @selector(removeListeners:), args, count); - } - static facebook::jsi::Value __hostFunction_NativeDevSettingsSpecJSI_setIsShakeToShowDevMenuEnabled(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, "setIsShakeToShowDevMenuEnabled", @selector(setIsShakeToShowDevMenuEnabled:), args, count); } - NativeDevSettingsSpecJSI::NativeDevSettingsSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("DevSettings", instance, jsInvoker, nativeInvoker, perfLogger) { + NativeDevSettingsSpecJSI::NativeDevSettingsSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("DevSettings", instance, jsInvoker) { methodMap_["reload"] = MethodMetadata {0, __hostFunction_NativeDevSettingsSpecJSI_reload}; @@ -971,12 +963,6 @@ + (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifiersPage:(id)json methodMap_["addMenuItem"] = MethodMetadata {1, __hostFunction_NativeDevSettingsSpecJSI_addMenuItem}; - methodMap_["addListener"] = MethodMetadata {1, __hostFunction_NativeDevSettingsSpecJSI_addListener}; - - - methodMap_["removeListeners"] = MethodMetadata {1, __hostFunction_NativeDevSettingsSpecJSI_removeListeners}; - - methodMap_["setIsShakeToShowDevMenuEnabled"] = MethodMetadata {1, __hostFunction_NativeDevSettingsSpecJSI_setIsShakeToShowDevMenuEnabled}; @@ -994,8 +980,8 @@ + (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifiersPage:(id)json } - NativeDeviceEventManagerSpecJSI::NativeDeviceEventManagerSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("DeviceEventManager", instance, jsInvoker, nativeInvoker, perfLogger) { + NativeDeviceEventManagerSpecJSI::NativeDeviceEventManagerSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("DeviceEventManager", instance, jsInvoker) { methodMap_["invokeDefaultBackPressHandler"] = MethodMetadata {0, __hostFunction_NativeDeviceEventManagerSpecJSI_invokeDefaultBackPressHandler}; @@ -1014,8 +1000,8 @@ + (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifiersPage:(id)json } - NativeDeviceInfoSpecJSI::NativeDeviceInfoSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("DeviceInfo", instance, jsInvoker, nativeInvoker, perfLogger) { + NativeDeviceInfoSpecJSI::NativeDeviceInfoSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("DeviceInfo", instance, jsInvoker) { methodMap_["getConstants"] = MethodMetadata {0, __hostFunction_NativeDeviceInfoSpecJSI_getConstants}; @@ -1044,8 +1030,8 @@ + (RCTManagedPointer *)JS_NativeDialogManagerAndroid_DialogOptions:(id)json } - NativeDialogManagerAndroidSpecJSI::NativeDialogManagerAndroidSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("DialogManagerAndroid", instance, jsInvoker, nativeInvoker, perfLogger) { + NativeDialogManagerAndroidSpecJSI::NativeDialogManagerAndroidSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("DialogManagerAndroid", instance, jsInvoker) { methodMap_["showAlert"] = MethodMetadata {3, __hostFunction_NativeDialogManagerAndroidSpecJSI_showAlert}; @@ -1096,8 +1082,8 @@ + (RCTManagedPointer *)JS_NativeExceptionsManager_ExceptionData:(id)json } - NativeExceptionsManagerSpecJSI::NativeExceptionsManagerSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("ExceptionsManager", instance, jsInvoker, nativeInvoker, perfLogger) { + NativeExceptionsManagerSpecJSI::NativeExceptionsManagerSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("ExceptionsManager", instance, jsInvoker) { methodMap_["reportFatalException"] = MethodMetadata {3, __hostFunction_NativeExceptionsManagerSpecJSI_reportFatalException}; @@ -1133,8 +1119,8 @@ + (RCTManagedPointer *)JS_NativeExceptionsManager_ExceptionData:(id)json } - NativeFileReaderModuleSpecJSI::NativeFileReaderModuleSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("FileReaderModule", instance, jsInvoker, nativeInvoker, perfLogger) { + NativeFileReaderModuleSpecJSI::NativeFileReaderModuleSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("FileReaderModule", instance, jsInvoker) { methodMap_["readAsDataURL"] = MethodMetadata {1, __hostFunction_NativeFileReaderModuleSpecJSI_readAsDataURL}; @@ -1174,8 +1160,8 @@ + (RCTManagedPointer *)JS_NativeFrameRateLogger_SpecSetGlobalOptionsOptions:(id) } - NativeFrameRateLoggerSpecJSI::NativeFrameRateLoggerSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("FrameRateLogger", instance, jsInvoker, nativeInvoker, perfLogger) { + NativeFrameRateLoggerSpecJSI::NativeFrameRateLoggerSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("FrameRateLogger", instance, jsInvoker) { methodMap_["setGlobalOptions"] = MethodMetadata {1, __hostFunction_NativeFrameRateLoggerSpecJSI_setGlobalOptions}; @@ -1208,8 +1194,8 @@ + (RCTManagedPointer *)JS_NativeFrameRateLogger_SpecSetGlobalOptionsOptions:(id) } - NativeHeadlessJsTaskSupportSpecJSI::NativeHeadlessJsTaskSupportSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("HeadlessJsTaskSupport", instance, jsInvoker, nativeInvoker, perfLogger) { + NativeHeadlessJsTaskSupportSpecJSI::NativeHeadlessJsTaskSupportSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("HeadlessJsTaskSupport", instance, jsInvoker) { methodMap_["notifyTaskFinished"] = MethodMetadata {1, __hostFunction_NativeHeadlessJsTaskSupportSpecJSI_notifyTaskFinished}; @@ -1218,6 +1204,33 @@ + (RCTManagedPointer *)JS_NativeFrameRateLogger_SpecSetGlobalOptionsOptions:(id) + } + + } // namespace react +} // namespace facebook +namespace facebook { + namespace react { + + + static facebook::jsi::Value __hostFunction_NativeHeapCaptureSpecJSI_captureHeap(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, "captureHeap", @selector(captureHeap:), args, count); + } + + static facebook::jsi::Value __hostFunction_NativeHeapCaptureSpecJSI_captureComplete(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, "captureComplete", @selector(captureComplete:error:), args, count); + } + + + NativeHeapCaptureSpecJSI::NativeHeapCaptureSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("HeapCapture", instance, jsInvoker) { + + methodMap_["captureHeap"] = MethodMetadata {1, __hostFunction_NativeHeapCaptureSpecJSI_captureHeap}; + + + methodMap_["captureComplete"] = MethodMetadata {2, __hostFunction_NativeHeapCaptureSpecJSI_captureComplete}; + + + } } // namespace react @@ -1243,8 +1256,8 @@ + (RCTManagedPointer *)JS_NativeFrameRateLogger_SpecSetGlobalOptionsOptions:(id) } - NativeI18nManagerSpecJSI::NativeI18nManagerSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("I18nManager", instance, jsInvoker, nativeInvoker, perfLogger) { + NativeI18nManagerSpecJSI::NativeI18nManagerSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("I18nManager", instance, jsInvoker) { methodMap_["allowRTL"] = MethodMetadata {1, __hostFunction_NativeI18nManagerSpecJSI_allowRTL}; @@ -1296,8 +1309,8 @@ + (RCTManagedPointer *)JS_NativeImageEditor_Options:(id)json } - NativeImageEditorSpecJSI::NativeImageEditorSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("ImageEditor", instance, jsInvoker, nativeInvoker, perfLogger) { + NativeImageEditorSpecJSI::NativeImageEditorSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("ImageEditor", instance, jsInvoker) { methodMap_["cropImage"] = MethodMetadata {4, __hostFunction_NativeImageEditorSpecJSI_cropImage}; @@ -1333,8 +1346,8 @@ + (RCTManagedPointer *)JS_NativeImageEditor_Options:(id)json } - NativeImageLoaderAndroidSpecJSI::NativeImageLoaderAndroidSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("ImageLoaderAndroid", instance, jsInvoker, nativeInvoker, perfLogger) { + NativeImageLoaderAndroidSpecJSI::NativeImageLoaderAndroidSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("ImageLoaderAndroid", instance, jsInvoker) { methodMap_["abortRequest"] = MethodMetadata {1, __hostFunction_NativeImageLoaderAndroidSpecJSI_abortRequest}; @@ -1377,8 +1390,8 @@ + (RCTManagedPointer *)JS_NativeImageEditor_Options:(id)json } - NativeImageLoaderIOSSpecJSI::NativeImageLoaderIOSSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("ImageLoaderIOS", instance, jsInvoker, nativeInvoker, perfLogger) { + NativeImageLoaderIOSSpecJSI::NativeImageLoaderIOSSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("ImageLoaderIOS", instance, jsInvoker) { methodMap_["getSize"] = MethodMetadata {1, __hostFunction_NativeImageLoaderIOSSpecJSI_getSize}; @@ -1438,8 +1451,8 @@ + (RCTManagedPointer *)JS_NativeImagePickerIOS_SpecOpenSelectDialogConfig:(id)js } - NativeImagePickerIOSSpecJSI::NativeImagePickerIOSSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("ImagePickerIOS", instance, jsInvoker, nativeInvoker, perfLogger) { + NativeImagePickerIOSSpecJSI::NativeImagePickerIOSSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("ImagePickerIOS", instance, jsInvoker) { methodMap_["canRecordVideos"] = MethodMetadata {1, __hostFunction_NativeImagePickerIOSSpecJSI_canRecordVideos}; @@ -1493,8 +1506,8 @@ + (RCTManagedPointer *)JS_NativeImageStore_SpecAddImageFromBase64ErrorCallbackEr } - NativeImageStoreSpecJSI::NativeImageStoreSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("ImageStore", instance, jsInvoker, nativeInvoker, perfLogger) { + NativeImageStoreSpecJSI::NativeImageStoreSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("ImageStore", instance, jsInvoker) { methodMap_["getBase64ForTag"] = MethodMetadata {3, __hostFunction_NativeImageStoreSpecJSI_getBase64ForTag}; @@ -1509,26 +1522,6 @@ + (RCTManagedPointer *)JS_NativeImageStore_SpecAddImageFromBase64ErrorCallbackEr - } - - } // namespace react -} // namespace facebook -namespace facebook { - namespace react { - - - static facebook::jsi::Value __hostFunction_NativeJSCHeapCaptureSpecJSI_captureComplete(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, "captureComplete", @selector(captureComplete:error:), args, count); - } - - - NativeJSCHeapCaptureSpecJSI::NativeJSCHeapCaptureSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("JSCHeapCapture", instance, jsInvoker, nativeInvoker, perfLogger) { - - methodMap_["captureComplete"] = MethodMetadata {2, __hostFunction_NativeJSCHeapCaptureSpecJSI_captureComplete}; - - - } } // namespace react @@ -1542,8 +1535,8 @@ + (RCTManagedPointer *)JS_NativeImageStore_SpecAddImageFromBase64ErrorCallbackEr } - NativeJSCSamplingProfilerSpecJSI::NativeJSCSamplingProfilerSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("JSCSamplingProfiler", instance, jsInvoker, nativeInvoker, perfLogger) { + NativeJSCSamplingProfilerSpecJSI::NativeJSCSamplingProfilerSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("JSCSamplingProfiler", instance, jsInvoker) { methodMap_["operationComplete"] = MethodMetadata {3, __hostFunction_NativeJSCSamplingProfilerSpecJSI_operationComplete}; @@ -1570,8 +1563,8 @@ + (RCTManagedPointer *)JS_NativeImageStore_SpecAddImageFromBase64ErrorCallbackEr } - NativeJSDevSupportSpecJSI::NativeJSDevSupportSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("JSDevSupport", instance, jsInvoker, nativeInvoker, perfLogger) { + NativeJSDevSupportSpecJSI::NativeJSDevSupportSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("JSDevSupport", instance, jsInvoker) { methodMap_["onSuccess"] = MethodMetadata {1, __hostFunction_NativeJSDevSupportSpecJSI_onSuccess}; @@ -1600,8 +1593,8 @@ + (RCTManagedPointer *)JS_NativeImageStore_SpecAddImageFromBase64ErrorCallbackEr } - NativeKeyboardObserverSpecJSI::NativeKeyboardObserverSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("KeyboardObserver", instance, jsInvoker, nativeInvoker, perfLogger) { + NativeKeyboardObserverSpecJSI::NativeKeyboardObserverSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("KeyboardObserver", instance, jsInvoker) { methodMap_["addListener"] = MethodMetadata {1, __hostFunction_NativeKeyboardObserverSpecJSI_addListener}; @@ -1653,8 +1646,8 @@ + (RCTManagedPointer *)JS_NativeLinking_SpecSendIntentExtrasElement:(id)json } - NativeLinkingSpecJSI::NativeLinkingSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("Linking", instance, jsInvoker, nativeInvoker, perfLogger) { + NativeLinkingSpecJSI::NativeLinkingSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("Linking", instance, jsInvoker) { methodMap_["getInitialURL"] = MethodMetadata {0, __hostFunction_NativeLinkingSpecJSI_getInitialURL}; @@ -1695,8 +1688,8 @@ + (RCTManagedPointer *)JS_NativeLinking_SpecSendIntentExtrasElement:(id)json } - NativeLogBoxSpecJSI::NativeLogBoxSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("LogBox", instance, jsInvoker, nativeInvoker, perfLogger) { + NativeLogBoxSpecJSI::NativeLogBoxSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("LogBox", instance, jsInvoker) { methodMap_["show"] = MethodMetadata {0, __hostFunction_NativeLogBoxSpecJSI_show}; @@ -1722,8 +1715,8 @@ + (RCTManagedPointer *)JS_NativeLinking_SpecSendIntentExtrasElement:(id)json } - NativeModalManagerSpecJSI::NativeModalManagerSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("ModalManager", instance, jsInvoker, nativeInvoker, perfLogger) { + NativeModalManagerSpecJSI::NativeModalManagerSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("ModalManager", instance, jsInvoker) { methodMap_["addListener"] = MethodMetadata {1, __hostFunction_NativeModalManagerSpecJSI_addListener}; @@ -1736,6 +1729,12 @@ + (RCTManagedPointer *)JS_NativeLinking_SpecSendIntentExtrasElement:(id)json } // namespace react } // namespace facebook +@implementation RCTCxxConvert (NativeNetworkingAndroid_Header) ++ (RCTManagedPointer *)JS_NativeNetworkingAndroid_Header:(id)json +{ + return facebook::react::managedPointer(json); +} +@end namespace facebook { namespace react { @@ -1761,8 +1760,8 @@ + (RCTManagedPointer *)JS_NativeLinking_SpecSendIntentExtrasElement:(id)json } - NativeNetworkingAndroidSpecJSI::NativeNetworkingAndroidSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("NetworkingAndroid", instance, jsInvoker, nativeInvoker, perfLogger) { + NativeNetworkingAndroidSpecJSI::NativeNetworkingAndroidSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("NetworkingAndroid", instance, jsInvoker) { methodMap_["sendRequest"] = MethodMetadata {9, __hostFunction_NativeNetworkingAndroidSpecJSI_sendRequest}; @@ -1815,8 +1814,8 @@ + (RCTManagedPointer *)JS_NativeNetworkingIOS_SpecSendRequestQuery:(id)json } - NativeNetworkingIOSSpecJSI::NativeNetworkingIOSSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("NetworkingIOS", instance, jsInvoker, nativeInvoker, perfLogger) { + NativeNetworkingIOSSpecJSI::NativeNetworkingIOSSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("NetworkingIOS", instance, jsInvoker) { methodMap_["sendRequest"] = MethodMetadata {2, __hostFunction_NativeNetworkingIOSSpecJSI_sendRequest}; @@ -1860,8 +1859,8 @@ + (RCTManagedPointer *)JS_NativeNetworkingIOS_SpecSendRequestQuery:(id)json } - NativePermissionsAndroidSpecJSI::NativePermissionsAndroidSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("PermissionsAndroid", instance, jsInvoker, nativeInvoker, perfLogger) { + NativePermissionsAndroidSpecJSI::NativePermissionsAndroidSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("PermissionsAndroid", instance, jsInvoker) { methodMap_["checkPermission"] = MethodMetadata {1, __hostFunction_NativePermissionsAndroidSpecJSI_checkPermission}; @@ -1893,8 +1892,8 @@ + (RCTManagedPointer *)JS_NativeNetworkingIOS_SpecSendRequestQuery:(id)json } - NativePlatformConstantsAndroidSpecJSI::NativePlatformConstantsAndroidSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("PlatformConstantsAndroid", instance, jsInvoker, nativeInvoker, perfLogger) { + NativePlatformConstantsAndroidSpecJSI::NativePlatformConstantsAndroidSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("PlatformConstantsAndroid", instance, jsInvoker) { methodMap_["getAndroidID"] = MethodMetadata {0, __hostFunction_NativePlatformConstantsAndroidSpecJSI_getAndroidID}; @@ -1916,8 +1915,8 @@ + (RCTManagedPointer *)JS_NativeNetworkingIOS_SpecSendRequestQuery:(id)json } - NativePlatformConstantsIOSSpecJSI::NativePlatformConstantsIOSSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("PlatformConstantsIOS", instance, jsInvoker, nativeInvoker, perfLogger) { + NativePlatformConstantsIOSSpecJSI::NativePlatformConstantsIOSSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("PlatformConstantsIOS", instance, jsInvoker) { methodMap_["getConstants"] = MethodMetadata {0, __hostFunction_NativePlatformConstantsIOSSpecJSI_getConstants}; @@ -2018,8 +2017,8 @@ + (RCTManagedPointer *)JS_NativePushNotificationManagerIOS_Notification:(id)json } - NativePushNotificationManagerIOSSpecJSI::NativePushNotificationManagerIOSSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("PushNotificationManagerIOS", instance, jsInvoker, nativeInvoker, perfLogger) { + NativePushNotificationManagerIOSSpecJSI::NativePushNotificationManagerIOSSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("PushNotificationManagerIOS", instance, jsInvoker) { methodMap_["onFinishRemoteNotification"] = MethodMetadata {2, __hostFunction_NativePushNotificationManagerIOSSpecJSI_onFinishRemoteNotification}; @@ -2093,8 +2092,8 @@ + (RCTManagedPointer *)JS_NativePushNotificationManagerIOS_Notification:(id)json } - NativeRedBoxSpecJSI::NativeRedBoxSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("RedBox", instance, jsInvoker, nativeInvoker, perfLogger) { + NativeRedBoxSpecJSI::NativeRedBoxSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("RedBox", instance, jsInvoker) { methodMap_["setExtraData"] = MethodMetadata {2, __hostFunction_NativeRedBoxSpecJSI_setExtraData}; @@ -2120,8 +2119,8 @@ + (RCTManagedPointer *)JS_NativePushNotificationManagerIOS_Notification:(id)json } - NativeSegmentFetcherSpecJSI::NativeSegmentFetcherSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("SegmentFetcher", instance, jsInvoker, nativeInvoker, perfLogger) { + NativeSegmentFetcherSpecJSI::NativeSegmentFetcherSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("SegmentFetcher", instance, jsInvoker) { methodMap_["fetchSegment"] = MethodMetadata {3, __hostFunction_NativeSegmentFetcherSpecJSI_fetchSegment}; @@ -2151,8 +2150,8 @@ + (RCTManagedPointer *)JS_NativePushNotificationManagerIOS_Notification:(id)json } - NativeSettingsManagerSpecJSI::NativeSettingsManagerSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("SettingsManager", instance, jsInvoker, nativeInvoker, perfLogger) { + NativeSettingsManagerSpecJSI::NativeSettingsManagerSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("SettingsManager", instance, jsInvoker) { methodMap_["setValues"] = MethodMetadata {1, __hostFunction_NativeSettingsManagerSpecJSI_setValues}; @@ -2183,8 +2182,8 @@ + (RCTManagedPointer *)JS_NativeShareModule_SpecShareContent:(id)json } - NativeShareModuleSpecJSI::NativeShareModuleSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("ShareModule", instance, jsInvoker, nativeInvoker, perfLogger) { + NativeShareModuleSpecJSI::NativeShareModuleSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("ShareModule", instance, jsInvoker) { methodMap_["share"] = MethodMetadata {2, __hostFunction_NativeShareModuleSpecJSI_share}; @@ -2204,8 +2203,8 @@ + (RCTManagedPointer *)JS_NativeShareModule_SpecShareContent:(id)json } - NativeSoundManagerSpecJSI::NativeSoundManagerSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("SoundManager", instance, jsInvoker, nativeInvoker, perfLogger) { + NativeSoundManagerSpecJSI::NativeSoundManagerSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("SoundManager", instance, jsInvoker) { methodMap_["playTouchSound"] = MethodMetadata {0, __hostFunction_NativeSoundManagerSpecJSI_playTouchSound}; @@ -2224,8 +2223,8 @@ + (RCTManagedPointer *)JS_NativeShareModule_SpecShareContent:(id)json } - NativeSourceCodeSpecJSI::NativeSourceCodeSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("SourceCode", instance, jsInvoker, nativeInvoker, perfLogger) { + NativeSourceCodeSpecJSI::NativeSourceCodeSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("SourceCode", instance, jsInvoker) { methodMap_["getConstants"] = MethodMetadata {0, __hostFunction_NativeSourceCodeSpecJSI_getConstants}; @@ -2260,8 +2259,8 @@ + (RCTManagedPointer *)JS_NativeShareModule_SpecShareContent:(id)json } - NativeStatusBarManagerAndroidSpecJSI::NativeStatusBarManagerAndroidSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("StatusBarManagerAndroid", instance, jsInvoker, nativeInvoker, perfLogger) { + NativeStatusBarManagerAndroidSpecJSI::NativeStatusBarManagerAndroidSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("StatusBarManagerAndroid", instance, jsInvoker) { methodMap_["setColor"] = MethodMetadata {2, __hostFunction_NativeStatusBarManagerAndroidSpecJSI_setColor}; @@ -2322,8 +2321,8 @@ + (RCTManagedPointer *)JS_NativeStatusBarManagerIOS_SpecGetHeightCallbackResult: } - NativeStatusBarManagerIOSSpecJSI::NativeStatusBarManagerIOSSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("StatusBarManagerIOS", instance, jsInvoker, nativeInvoker, perfLogger) { + NativeStatusBarManagerIOSSpecJSI::NativeStatusBarManagerIOSSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("StatusBarManagerIOS", instance, jsInvoker) { methodMap_["getHeight"] = MethodMetadata {1, __hostFunction_NativeStatusBarManagerIOSSpecJSI_getHeight}; @@ -2364,8 +2363,8 @@ + (RCTManagedPointer *)JS_NativeStatusBarManagerIOS_SpecGetHeightCallbackResult: } - NativeTVNavigationEventEmitterSpecJSI::NativeTVNavigationEventEmitterSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("TVNavigationEventEmitter", instance, jsInvoker, nativeInvoker, perfLogger) { + NativeTVNavigationEventEmitterSpecJSI::NativeTVNavigationEventEmitterSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("TVNavigationEventEmitter", instance, jsInvoker) { methodMap_["addListener"] = MethodMetadata {1, __hostFunction_NativeTVNavigationEventEmitterSpecJSI_addListener}; @@ -2393,8 +2392,8 @@ + (RCTManagedPointer *)JS_NativeTimePickerAndroid_TimePickerOptions:(id)json } - NativeTimePickerAndroidSpecJSI::NativeTimePickerAndroidSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("TimePickerAndroid", instance, jsInvoker, nativeInvoker, perfLogger) { + NativeTimePickerAndroidSpecJSI::NativeTimePickerAndroidSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("TimePickerAndroid", instance, jsInvoker) { methodMap_["open"] = MethodMetadata {1, __hostFunction_NativeTimePickerAndroidSpecJSI_open}; @@ -2428,8 +2427,8 @@ + (RCTManagedPointer *)JS_NativeTimePickerAndroid_TimePickerResult:(id)json } - NativeTimingSpecJSI::NativeTimingSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("Timing", instance, jsInvoker, nativeInvoker, perfLogger) { + NativeTimingSpecJSI::NativeTimingSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("Timing", instance, jsInvoker) { methodMap_["createTimer"] = MethodMetadata {4, __hostFunction_NativeTimingSpecJSI_createTimer}; @@ -2466,8 +2465,8 @@ + (RCTManagedPointer *)JS_NativeTimePickerAndroid_TimePickerResult:(id)json } - NativeToastAndroidSpecJSI::NativeToastAndroidSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("ToastAndroid", instance, jsInvoker, nativeInvoker, perfLogger) { + NativeToastAndroidSpecJSI::NativeToastAndroidSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("ToastAndroid", instance, jsInvoker) { methodMap_["show"] = MethodMetadata {2, __hostFunction_NativeToastAndroidSpecJSI_show}; @@ -2599,8 +2598,8 @@ + (RCTManagedPointer *)JS_NativeTimePickerAndroid_TimePickerResult:(id)json } - NativeUIManagerSpecJSI::NativeUIManagerSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("UIManager", instance, jsInvoker, nativeInvoker, perfLogger) { + NativeUIManagerSpecJSI::NativeUIManagerSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("UIManager", instance, jsInvoker) { methodMap_["getConstantsForViewManager"] = MethodMetadata {1, __hostFunction_NativeUIManagerSpecJSI_getConstantsForViewManager}; @@ -2705,8 +2704,8 @@ + (RCTManagedPointer *)JS_NativeTimePickerAndroid_TimePickerResult:(id)json } - NativeVibrationSpecJSI::NativeVibrationSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("Vibration", instance, jsInvoker, nativeInvoker, perfLogger) { + NativeVibrationSpecJSI::NativeVibrationSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("Vibration", instance, jsInvoker) { methodMap_["vibrate"] = MethodMetadata {1, __hostFunction_NativeVibrationSpecJSI_vibrate}; @@ -2761,8 +2760,8 @@ + (RCTManagedPointer *)JS_NativeWebSocketModule_SpecConnectOptions:(id)json } - NativeWebSocketModuleSpecJSI::NativeWebSocketModuleSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("WebSocketModule", instance, jsInvoker, nativeInvoker, perfLogger) { + NativeWebSocketModuleSpecJSI::NativeWebSocketModuleSpecJSI(id instance, std::shared_ptr jsInvoker) + : ObjCTurboModule("WebSocketModule", instance, jsInvoker) { methodMap_["connect"] = MethodMetadata {4, __hostFunction_NativeWebSocketModuleSpecJSI_connect}; diff --git a/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec.h b/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec.h index c3a848b06e9354..2bb267d5a7b175 100644 --- a/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec.h +++ b/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec.h @@ -42,7 +42,7 @@ namespace facebook { class JSI_EXPORT NativeAccessibilityInfoSpecJSI : public ObjCTurboModule { public: - NativeAccessibilityInfoSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativeAccessibilityInfoSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react @@ -101,7 +101,7 @@ namespace facebook { class JSI_EXPORT NativeAccessibilityManagerSpecJSI : public ObjCTurboModule { public: - NativeAccessibilityManagerSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativeAccessibilityManagerSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react @@ -117,7 +117,6 @@ namespace JS { folly::Optional cancelButtonIndex() const; folly::Optional anchor() const; folly::Optional tintColor() const; - NSString *userInterfaceStyle() const; SpecShowActionSheetWithOptionsOptions(NSDictionary *const v) : _v(v) {} private: @@ -139,7 +138,6 @@ namespace JS { folly::Optional anchor() const; folly::Optional tintColor() const; folly::Optional> excludedActivityTypes() const; - NSString *userInterfaceStyle() const; SpecShowShareActionSheetWithOptionsOptions(NSDictionary *const v) : _v(v) {} private: @@ -187,7 +185,7 @@ namespace facebook { class JSI_EXPORT NativeActionSheetManagerSpecJSI : public ObjCTurboModule { public: - NativeActionSheetManagerSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativeActionSheetManagerSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react @@ -234,7 +232,7 @@ namespace facebook { class JSI_EXPORT NativeAlertManagerSpecJSI : public ObjCTurboModule { public: - NativeAlertManagerSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativeAlertManagerSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react @@ -317,7 +315,7 @@ namespace facebook { class JSI_EXPORT NativeAnimatedModuleSpecJSI : public ObjCTurboModule { public: - NativeAnimatedModuleSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativeAnimatedModuleSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react @@ -336,7 +334,7 @@ namespace facebook { class JSI_EXPORT NativeAnimationsDebugModuleSpecJSI : public ObjCTurboModule { public: - NativeAnimationsDebugModuleSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativeAnimationsDebugModuleSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react @@ -403,7 +401,7 @@ namespace facebook { class JSI_EXPORT NativeAppStateSpecJSI : public ObjCTurboModule { public: - NativeAppStateSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativeAppStateSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react @@ -423,7 +421,7 @@ namespace facebook { class JSI_EXPORT NativeAppearanceSpecJSI : public ObjCTurboModule { public: - NativeAppearanceSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativeAppearanceSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react @@ -569,7 +567,7 @@ namespace facebook { class JSI_EXPORT NativeAsyncStorageSpecJSI : public ObjCTurboModule { public: - NativeAsyncStorageSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativeAsyncStorageSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react @@ -625,7 +623,7 @@ namespace facebook { class JSI_EXPORT NativeBlobModuleSpecJSI : public ObjCTurboModule { public: - NativeBlobModuleSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativeBlobModuleSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react @@ -646,7 +644,7 @@ namespace facebook { class JSI_EXPORT NativeBugReportingSpecJSI : public ObjCTurboModule { public: - NativeBugReportingSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativeBugReportingSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react @@ -695,7 +693,7 @@ namespace facebook { class JSI_EXPORT NativeCameraRollManagerSpecJSI : public ObjCTurboModule { public: - NativeCameraRollManagerSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativeCameraRollManagerSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react @@ -827,7 +825,7 @@ namespace facebook { class JSI_EXPORT NativeClipboardSpecJSI : public ObjCTurboModule { public: - NativeClipboardSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativeClipboardSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react @@ -847,7 +845,7 @@ namespace facebook { class JSI_EXPORT NativeDatePickerAndroidSpecJSI : public ObjCTurboModule { public: - NativeDatePickerAndroidSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativeDatePickerAndroidSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react @@ -855,8 +853,8 @@ namespace facebook { @protocol NativeDevLoadingViewSpec - (void)showMessage:(NSString *)message - withColor:(NSNumber *)withColor -withBackgroundColor:(NSNumber *)withBackgroundColor; + color:(NSDictionary *)color + backgroundColor:(NSDictionary *)backgroundColor; - (void)hide; @end @@ -868,7 +866,7 @@ namespace facebook { class JSI_EXPORT NativeDevLoadingViewSpecJSI : public ObjCTurboModule { public: - NativeDevLoadingViewSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativeDevLoadingViewSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react @@ -890,7 +888,7 @@ namespace facebook { class JSI_EXPORT NativeDevMenuSpecJSI : public ObjCTurboModule { public: - NativeDevMenuSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativeDevMenuSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react @@ -905,8 +903,6 @@ namespace facebook { - (void)setProfilingEnabled:(BOOL)isProfilingEnabled; - (void)toggleElementInspector; - (void)addMenuItem:(NSString *)title; -- (void)addListener:(NSString *)eventName; -- (void)removeListeners:(double)count; - (void)setIsShakeToShowDevMenuEnabled:(BOOL)enabled; - (void)setIsSecondaryClickToShowDevMenuEnabled:(BOOL)enabled; @@ -919,7 +915,7 @@ namespace facebook { class JSI_EXPORT NativeDevSettingsSpecJSI : public ObjCTurboModule { public: - NativeDevSettingsSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativeDevSettingsSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react @@ -937,7 +933,7 @@ namespace facebook { class JSI_EXPORT NativeDeviceEventManagerSpecJSI : public ObjCTurboModule { public: - NativeDeviceEventManagerSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativeDeviceEventManagerSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react @@ -1079,7 +1075,7 @@ namespace facebook { class JSI_EXPORT NativeDeviceInfoSpecJSI : public ObjCTurboModule { public: - NativeDeviceInfoSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativeDeviceInfoSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react @@ -1155,7 +1151,7 @@ namespace facebook { class JSI_EXPORT NativeDialogManagerAndroidSpecJSI : public ObjCTurboModule { public: - NativeDialogManagerAndroidSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativeDialogManagerAndroidSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react @@ -1226,7 +1222,7 @@ namespace facebook { class JSI_EXPORT NativeExceptionsManagerSpecJSI : public ObjCTurboModule { public: - NativeExceptionsManagerSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativeExceptionsManagerSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react @@ -1250,7 +1246,7 @@ namespace facebook { class JSI_EXPORT NativeFileReaderModuleSpecJSI : public ObjCTurboModule { public: - NativeFileReaderModuleSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativeFileReaderModuleSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react @@ -1288,7 +1284,7 @@ namespace facebook { class JSI_EXPORT NativeFrameRateLoggerSpecJSI : public ObjCTurboModule { public: - NativeFrameRateLoggerSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativeFrameRateLoggerSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react @@ -1309,7 +1305,27 @@ namespace facebook { class JSI_EXPORT NativeHeadlessJsTaskSupportSpecJSI : public ObjCTurboModule { public: - NativeHeadlessJsTaskSupportSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativeHeadlessJsTaskSupportSpecJSI(id instance, std::shared_ptr jsInvoker); + + }; + } // namespace react +} // namespace facebook +@protocol NativeHeapCaptureSpec + +- (void)captureHeap:(NSString *)path; +- (void)captureComplete:(NSString *)path + error:(NSString * _Nullable)error; + +@end +namespace facebook { + namespace react { + /** + * ObjC++ class for module 'HeapCapture' + */ + + class JSI_EXPORT NativeHeapCaptureSpecJSI : public ObjCTurboModule { + public: + NativeHeapCaptureSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react @@ -1360,7 +1376,7 @@ namespace facebook { class JSI_EXPORT NativeI18nManagerSpecJSI : public ObjCTurboModule { public: - NativeI18nManagerSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativeI18nManagerSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react @@ -1424,7 +1440,6 @@ namespace JS { JS::NativeImageEditor::OptionsSize size() const; folly::Optional displaySize() const; NSString *resizeMode() const; - folly::Optional allowExternalStorage() const; Options(NSDictionary *const v) : _v(v) {} private: @@ -1452,7 +1467,7 @@ namespace facebook { class JSI_EXPORT NativeImageEditorSpecJSI : public ObjCTurboModule { public: - NativeImageEditorSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativeImageEditorSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react @@ -1484,7 +1499,7 @@ namespace facebook { class JSI_EXPORT NativeImageLoaderAndroidSpecJSI : public ObjCTurboModule { public: - NativeImageLoaderAndroidSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativeImageLoaderAndroidSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react @@ -1514,7 +1529,7 @@ namespace facebook { class JSI_EXPORT NativeImageLoaderIOSSpecJSI : public ObjCTurboModule { public: - NativeImageLoaderIOSSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativeImageLoaderIOSSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react @@ -1575,7 +1590,7 @@ namespace facebook { class JSI_EXPORT NativeImagePickerIOSSpecJSI : public ObjCTurboModule { public: - NativeImagePickerIOSSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativeImagePickerIOSSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react @@ -1617,26 +1632,7 @@ namespace facebook { class JSI_EXPORT NativeImageStoreSpecJSI : public ObjCTurboModule { public: - NativeImageStoreSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); - - }; - } // namespace react -} // namespace facebook -@protocol NativeJSCHeapCaptureSpec - -- (void)captureComplete:(NSString *)path - error:(NSString * _Nullable)error; - -@end -namespace facebook { - namespace react { - /** - * ObjC++ class for module 'JSCHeapCapture' - */ - - class JSI_EXPORT NativeJSCHeapCaptureSpecJSI : public ObjCTurboModule { - public: - NativeJSCHeapCaptureSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativeImageStoreSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react @@ -1656,7 +1652,7 @@ namespace facebook { class JSI_EXPORT NativeJSCSamplingProfilerSpecJSI : public ObjCTurboModule { public: - NativeJSCSamplingProfilerSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativeJSCSamplingProfilerSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react @@ -1692,7 +1688,7 @@ namespace JS { } @protocol NativeJSDevSupportSpec -- (void)onSuccess:(NSString *)data; +- (void)onSuccess:(NSDictionary *)data; - (void)onFailure:(double)errorCode error:(NSString *)error; - (facebook::react::ModuleConstants)constantsToExport; @@ -1707,7 +1703,7 @@ namespace facebook { class JSI_EXPORT NativeJSDevSupportSpecJSI : public ObjCTurboModule { public: - NativeJSDevSupportSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativeJSDevSupportSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react @@ -1726,7 +1722,7 @@ namespace facebook { class JSI_EXPORT NativeKeyboardObserverSpecJSI : public ObjCTurboModule { public: - NativeKeyboardObserverSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativeKeyboardObserverSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react @@ -1776,7 +1772,7 @@ namespace facebook { class JSI_EXPORT NativeLinkingSpecJSI : public ObjCTurboModule { public: - NativeLinkingSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativeLinkingSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react @@ -1795,7 +1791,7 @@ namespace facebook { class JSI_EXPORT NativeLogBoxSpecJSI : public ObjCTurboModule { public: - NativeLogBoxSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativeLogBoxSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react @@ -1814,11 +1810,28 @@ namespace facebook { class JSI_EXPORT NativeModalManagerSpecJSI : public ObjCTurboModule { public: - NativeModalManagerSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativeModalManagerSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react } // namespace facebook + +namespace JS { + namespace NativeNetworkingAndroid { + struct Header { + NSString *first() const; + NSString *second() const; + + Header(NSArray *const v) : _v(v) {} + private: + NSArray *_v; + }; + } +} + +@interface RCTCxxConvert (NativeNetworkingAndroid_Header) ++ (RCTManagedPointer *)JS_NativeNetworkingAndroid_Header:(id)json; +@end @protocol NativeNetworkingAndroidSpec - (void)sendRequest:(NSString *)method @@ -1844,7 +1857,7 @@ namespace facebook { class JSI_EXPORT NativeNetworkingAndroidSpecJSI : public ObjCTurboModule { public: - NativeNetworkingAndroidSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativeNetworkingAndroidSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react @@ -1890,7 +1903,7 @@ namespace facebook { class JSI_EXPORT NativeNetworkingIOSSpecJSI : public ObjCTurboModule { public: - NativeNetworkingIOSSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativeNetworkingIOSSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react @@ -1919,7 +1932,7 @@ namespace facebook { class JSI_EXPORT NativePermissionsAndroidSpecJSI : public ObjCTurboModule { public: - NativePermissionsAndroidSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativePermissionsAndroidSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react @@ -1969,7 +1982,7 @@ namespace JS { RCTRequired Serial; RCTRequired Fingerprint; RCTRequired Model; - NSString *ServerHost; + RCTRequired ServerHost; RCTRequired uiMode; }; @@ -2006,7 +2019,7 @@ namespace facebook { class JSI_EXPORT NativePlatformConstantsAndroidSpecJSI : public ObjCTurboModule { public: - NativePlatformConstantsAndroidSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativePlatformConstantsAndroidSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react @@ -2089,7 +2102,7 @@ namespace facebook { class JSI_EXPORT NativePlatformConstantsIOSSpecJSI : public ObjCTurboModule { public: - NativePlatformConstantsIOSSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativePlatformConstantsIOSSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react @@ -2187,7 +2200,7 @@ namespace facebook { class JSI_EXPORT NativePushNotificationManagerIOSSpecJSI : public ObjCTurboModule { public: - NativePushNotificationManagerIOSSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativePushNotificationManagerIOSSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react @@ -2207,7 +2220,7 @@ namespace facebook { class JSI_EXPORT NativeRedBoxSpecJSI : public ObjCTurboModule { public: - NativeRedBoxSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativeRedBoxSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react @@ -2230,7 +2243,7 @@ namespace facebook { class JSI_EXPORT NativeSegmentFetcherSpecJSI : public ObjCTurboModule { public: - NativeSegmentFetcherSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativeSegmentFetcherSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react @@ -2279,7 +2292,7 @@ namespace facebook { class JSI_EXPORT NativeSettingsManagerSpecJSI : public ObjCTurboModule { public: - NativeSettingsManagerSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativeSettingsManagerSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react @@ -2317,7 +2330,7 @@ namespace facebook { class JSI_EXPORT NativeShareModuleSpecJSI : public ObjCTurboModule { public: - NativeShareModuleSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativeShareModuleSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react @@ -2335,7 +2348,7 @@ namespace facebook { class JSI_EXPORT NativeSoundManagerSpecJSI : public ObjCTurboModule { public: - NativeSoundManagerSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativeSoundManagerSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react @@ -2382,7 +2395,7 @@ namespace facebook { class JSI_EXPORT NativeSourceCodeSpecJSI : public ObjCTurboModule { public: - NativeSourceCodeSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativeSourceCodeSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react @@ -2435,7 +2448,7 @@ namespace facebook { class JSI_EXPORT NativeStatusBarManagerAndroidSpecJSI : public ObjCTurboModule { public: - NativeStatusBarManagerAndroidSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativeStatusBarManagerAndroidSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react @@ -2507,7 +2520,7 @@ namespace facebook { class JSI_EXPORT NativeStatusBarManagerIOSSpecJSI : public ObjCTurboModule { public: - NativeStatusBarManagerIOSSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativeStatusBarManagerIOSSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react @@ -2526,7 +2539,7 @@ namespace facebook { class JSI_EXPORT NativeTVNavigationEventEmitterSpecJSI : public ObjCTurboModule { public: - NativeTVNavigationEventEmitterSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativeTVNavigationEventEmitterSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react @@ -2565,7 +2578,7 @@ namespace facebook { class JSI_EXPORT NativeTimePickerAndroidSpecJSI : public ObjCTurboModule { public: - NativeTimePickerAndroidSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativeTimePickerAndroidSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react @@ -2606,7 +2619,7 @@ namespace facebook { class JSI_EXPORT NativeTimingSpecJSI : public ObjCTurboModule { public: - NativeTimingSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativeTimingSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react @@ -2667,7 +2680,7 @@ namespace facebook { class JSI_EXPORT NativeToastAndroidSpecJSI : public ObjCTurboModule { public: - NativeToastAndroidSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativeToastAndroidSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react @@ -2771,7 +2784,7 @@ namespace facebook { class JSI_EXPORT NativeUIManagerSpecJSI : public ObjCTurboModule { public: - NativeUIManagerSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativeUIManagerSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react @@ -2792,7 +2805,7 @@ namespace facebook { class JSI_EXPORT NativeVibrationSpecJSI : public ObjCTurboModule { public: - NativeVibrationSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativeVibrationSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react @@ -2839,7 +2852,7 @@ namespace facebook { class JSI_EXPORT NativeWebSocketModuleSpecJSI : public ObjCTurboModule { public: - NativeWebSocketModuleSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); + NativeWebSocketModuleSpecJSI(id instance, std::shared_ptr jsInvoker); }; } // namespace react @@ -2943,11 +2956,6 @@ inline folly::Optional JS::NativeActionSheetManager::SpecShowActionSheet id const p = _v[@"tintColor"]; return RCTBridgingToOptionalDouble(p); } -inline NSString *JS::NativeActionSheetManager::SpecShowActionSheetWithOptionsOptions::userInterfaceStyle() const -{ - id const p = _v[@"userInterfaceStyle"]; - return RCTBridgingToString(p); -} inline NSString *JS::NativeActionSheetManager::SpecShowShareActionSheetWithOptionsOptions::message() const { id const p = _v[@"message"]; @@ -2978,11 +2986,6 @@ inline folly::Optional> JS::NativeAction id const p = _v[@"excludedActivityTypes"]; return RCTBridgingToOptionalVec(p, ^NSString *(id itemValue_0) { return RCTBridgingToString(itemValue_0); }); } -inline NSString *JS::NativeActionSheetManager::SpecShowShareActionSheetWithOptionsOptions::userInterfaceStyle() const -{ - id const p = _v[@"userInterfaceStyle"]; - return RCTBridgingToString(p); -} inline NSString *JS::NativeActionSheetManager::SpecShowShareActionSheetWithOptionsFailureCallbackError::domain() const { id const p = _v[@"domain"]; @@ -3526,11 +3529,6 @@ inline NSString *JS::NativeImageEditor::Options::resizeMode() const id const p = _v[@"resizeMode"]; return RCTBridgingToString(p); } -inline folly::Optional JS::NativeImageEditor::Options::allowExternalStorage() const -{ - id const p = _v[@"allowExternalStorage"]; - return RCTBridgingToOptionalBool(p); -} inline bool JS::NativeImagePickerIOS::SpecOpenCameraDialogConfig::unmirrorFrontFacingCamera() const { id const p = _v[@"unmirrorFrontFacingCamera"]; @@ -3577,6 +3575,16 @@ inline id JS::NativeLinking::SpecSendIntentExtrasElement::value() cons id const p = _v[@"value"]; return p; } +inline NSString *JS::NativeNetworkingAndroid::Header::first() const +{ + id const p = _v[0]; + return RCTBridgingToString(p); +} +inline NSString *JS::NativeNetworkingAndroid::Header::second() const +{ + id const p = _v[1]; + return RCTBridgingToString(p); +} inline NSString *JS::NativeNetworkingIOS::SpecSendRequestQuery::method() const { id const p = _v[@"method"]; @@ -3648,7 +3656,7 @@ inline JS::NativePlatformConstantsAndroid::Constants::Builder::Builder(const Inp d[@"Fingerprint"] = Fingerprint; auto Model = i.Model.get(); d[@"Model"] = Model; - auto ServerHost = i.ServerHost; + auto ServerHost = i.ServerHost.get(); d[@"ServerHost"] = ServerHost; auto uiMode = i.uiMode.get(); d[@"uiMode"] = uiMode; diff --git a/Libraries/HeapCapture/HeapCapture.js b/Libraries/HeapCapture/HeapCapture.js index 903343a05b0601..9cbabc60417487 100644 --- a/Libraries/HeapCapture/HeapCapture.js +++ b/Libraries/HeapCapture/HeapCapture.js @@ -10,7 +10,7 @@ 'use strict'; -import NativeJSCHeapCapture from './NativeJSCHeapCapture'; +import NativeHeapCapture from './NativeHeapCapture'; const HeapCapture = { captureHeap: function(path: string) { @@ -22,8 +22,8 @@ const HeapCapture = { console.log('HeapCapture.captureHeap error: ' + e.toString()); error = e.toString(); } - if (NativeJSCHeapCapture) { - NativeJSCHeapCapture.captureComplete(path, error); + if (NativeHeapCapture) { + NativeHeapCapture.captureComplete(path, error); } }, }; diff --git a/Libraries/HeapCapture/NativeJSCHeapCapture.js b/Libraries/HeapCapture/NativeHeapCapture.js similarity index 76% rename from Libraries/HeapCapture/NativeJSCHeapCapture.js rename to Libraries/HeapCapture/NativeHeapCapture.js index 05e941f17e7b83..5d778e44771467 100644 --- a/Libraries/HeapCapture/NativeJSCHeapCapture.js +++ b/Libraries/HeapCapture/NativeHeapCapture.js @@ -14,7 +14,11 @@ import type {TurboModule} from '../TurboModule/RCTExport'; import * as TurboModuleRegistry from '../TurboModule/TurboModuleRegistry'; export interface Spec extends TurboModule { + // Common interface + +captureHeap: (path: string) => void; + + // Android only +captureComplete: (path: string, error: ?string) => void; } -export default (TurboModuleRegistry.get('JSCHeapCapture'): ?Spec); +export default (TurboModuleRegistry.get('HeapCapture'): ?Spec); diff --git a/Libraries/Image/AssetSourceResolver.js b/Libraries/Image/AssetSourceResolver.js index bc671090b25b5f..624c6225c2008f 100644 --- a/Libraries/Image/AssetSourceResolver.js +++ b/Libraries/Image/AssetSourceResolver.js @@ -114,12 +114,7 @@ class AssetSourceResolver { */ scaledAssetURLNearBundle(): ResolvedAssetSource { const path = this.jsbundleUrl || 'file://'; - return this.fromSource( - // Assets can have relative paths outside of the project root. - // When bundling them we replace `../` with `_` to make sure they - // don't end up outside of the expected assets directory. - path + getScaledAssetPath(this.asset).replace(/\.\.\//g, '_'), - ); + return this.fromSource(path + getScaledAssetPath(this.asset)); } /** diff --git a/Libraries/Image/Image.android.js b/Libraries/Image/Image.android.js index 5e57732a855424..fec14e0487f7ea 100644 --- a/Libraries/Image/Image.android.js +++ b/Libraries/Image/Image.android.js @@ -13,14 +13,13 @@ const DeprecatedImageStylePropTypes = require('../DeprecatedPropTypes/DeprecatedImageStylePropTypes'); const DeprecatedStyleSheetPropType = require('../DeprecatedPropTypes/DeprecatedStyleSheetPropType'); const DeprecatedViewPropTypes = require('../DeprecatedPropTypes/DeprecatedViewPropTypes'); -import ImageViewNativeComponent from './ImageViewNativeComponent'; +const ImageViewNativeComponent = require('./ImageViewNativeComponent'); const PropTypes = require('prop-types'); const React = require('react'); const ReactNative = require('../Renderer/shims/ReactNative'); // eslint-disable-line no-unused-vars const StyleSheet = require('../StyleSheet/StyleSheet'); const TextAncestor = require('../Text/TextAncestor'); -const ImageAnalyticsTagContext = require('./ImageAnalyticsTagContext').default; const flattenStyle = require('../StyleSheet/flattenStyle'); const resolveAssetSource = require('./resolveAssetSource'); @@ -41,7 +40,7 @@ const ImageProps = { DeprecatedImageStylePropTypes, ): ReactPropsCheckType), /** - * See https://reactnative.dev/docs/image.html#source + * See https://facebook.github.io/react-native/docs/image.html#source */ source: (PropTypes.oneOfType([ PropTypes.shape({ @@ -77,15 +76,15 @@ const ImageProps = { /** * blurRadius: the blur radius of the blur filter added to the image * - * See https://reactnative.dev/docs/image.html#blurradius + * See https://facebook.github.io/react-native/docs/image.html#blurradius */ blurRadius: PropTypes.number, /** - * See https://reactnative.dev/docs/image.html#defaultsource + * See https://facebook.github.io/react-native/docs/image.html#defaultsource */ defaultSource: PropTypes.number, /** - * See https://reactnative.dev/docs/image.html#loadingindicatorsource + * See https://facebook.github.io/react-native/docs/image.html#loadingindicatorsource */ loadingIndicatorSource: (PropTypes.oneOfType([ PropTypes.shape({ @@ -96,10 +95,6 @@ const ImageProps = { ]): React$PropType$Primitive<{uri?: string, ...} | number>), progressiveRenderingEnabled: PropTypes.bool, fadeDuration: PropTypes.number, - /** - * Analytics Tag used by this Image - */ - internal_analyticTag: PropTypes.string, /** * Invoked on load start */ @@ -124,7 +119,7 @@ const ImageProps = { * The mechanism that should be used to resize the image when the image's dimensions * differ from the image view's dimensions. Defaults to `auto`. * - * See https://reactnative.dev/docs/image.html#resizemethod + * See https://facebook.github.io/react-native/docs/image.html#resizemethod */ resizeMethod: (PropTypes.oneOf([ 'auto', @@ -135,7 +130,7 @@ const ImageProps = { * Determines how to resize the image when the frame doesn't match the raw * image dimensions. * - * See https://reactnative.dev/docs/image.html#resizemode + * See https://facebook.github.io/react-native/docs/image.html#resizemode */ resizeMode: (PropTypes.oneOf([ 'cover', @@ -151,7 +146,7 @@ const ImageProps = { /** * Retrieve the width and height (in pixels) of an image prior to displaying it * - * See https://reactnative.dev/docs/image.html#getsize + * See https://facebook.github.io/react-native/docs/image.html#getsize */ function getSize( url: string, @@ -174,7 +169,7 @@ function getSize( * Retrieve the width and height (in pixels) of an image prior to displaying it * with the ability to provide the headers for the request * - * See https://reactnative.dev/docs/image.html#getsizewithheaders + * See https://facebook.github.io/react-native/docs/image.html#getsizewithheaders */ function getSizeWithHeaders( url: string, @@ -207,7 +202,7 @@ function abortPrefetch(requestId: number) { /** * Perform cache interrogation. * - * See https://reactnative.dev/docs/image.html#querycache + * See https://facebook.github.io/react-native/docs/image.html#querycache */ async function queryCache( urls: Array, @@ -230,7 +225,7 @@ type ImageComponentStatics = $ReadOnly<{| * including network images, static resources, temporary local images, and * images from local disk, such as the camera roll. * - * See https://reactnative.dev/docs/image.html + * See https://facebook.github.io/react-native/docs/image.html */ let Image = (props: ImagePropsType, forwardedRef) => { let source = resolveAssetSource(props.source); @@ -268,8 +263,12 @@ let Image = (props: ImagePropsType, forwardedRef) => { let style; let sources; if (source?.uri != null) { + /* $FlowFixMe(>=0.78.0 site=react_native_android_fb) This issue was found + * when making Flow check .android.js files. */ const {width, height} = source; style = flattenStyle([{width, height}, styles.base, props.style]); + /* $FlowFixMe(>=0.78.0 site=react_native_android_fb) This issue was found + * when making Flow check .android.js files. */ sources = [{uri: source.uri}]; } else { style = flattenStyle([styles.base, props.style]); @@ -293,28 +292,15 @@ let Image = (props: ImagePropsType, forwardedRef) => { }; return ( - - {analyticTag => { - const nativePropsWithAnalytics = - analyticTag !== null - ? { - ...nativeProps, - internal_analyticTag: analyticTag, - } - : nativeProps; - return ( - - {hasTextAncestor => - hasTextAncestor ? ( - - ) : ( - - ) - } - - ); - }} - + + {hasTextAncestor => + hasTextAncestor ? ( + + ) : ( + + ) + } + ); }; @@ -329,7 +315,7 @@ Image.displayName = 'Image'; /** * Retrieve the width and height (in pixels) of an image prior to displaying it * - * See https://reactnative.dev/docs/image.html#getsize + * See https://facebook.github.io/react-native/docs/image.html#getsize */ /* $FlowFixMe(>=0.89.0 site=react_native_android_fb) This comment suppresses an * error found when Flow v0.89 was deployed. To see the error, delete this @@ -340,7 +326,7 @@ Image.getSize = getSize; * Retrieve the width and height (in pixels) of an image prior to displaying it * with the ability to provide the headers for the request * - * See https://reactnative.dev/docs/image.html#getsizewithheaders + * See https://facebook.github.io/react-native/docs/image.html#getsizewithheaders */ /* $FlowFixMe(>=0.89.0 site=react_native_android_fb) This comment suppresses an * error found when Flow v0.89 was deployed. To see the error, delete this @@ -351,7 +337,7 @@ Image.getSizeWithHeaders = getSizeWithHeaders; * Prefetches a remote image for later use by downloading it to the disk * cache * - * See https://reactnative.dev/docs/image.html#prefetch + * See https://facebook.github.io/react-native/docs/image.html#prefetch */ /* $FlowFixMe(>=0.89.0 site=react_native_android_fb) This comment suppresses an * error found when Flow v0.89 was deployed. To see the error, delete this @@ -361,7 +347,7 @@ Image.prefetch = prefetch; /** * Abort prefetch request. * - * See https://reactnative.dev/docs/image.html#abortprefetch + * See https://facebook.github.io/react-native/docs/image.html#abortprefetch */ /* $FlowFixMe(>=0.89.0 site=react_native_android_fb) This comment suppresses an * error found when Flow v0.89 was deployed. To see the error, delete this @@ -371,7 +357,7 @@ Image.abortPrefetch = abortPrefetch; /** * Perform cache interrogation. * - * See https://reactnative.dev/docs/image.html#querycache + * See https://facebook.github.io/react-native/docs/image.html#querycache */ /* $FlowFixMe(>=0.89.0 site=react_native_android_fb) This comment suppresses an * error found when Flow v0.89 was deployed. To see the error, delete this @@ -381,7 +367,7 @@ Image.queryCache = queryCache; /** * Resolves an asset reference into an object. * - * See https://reactnative.dev/docs/image.html#resolveassetsource + * See https://facebook.github.io/react-native/docs/image.html#resolveassetsource */ /* $FlowFixMe(>=0.89.0 site=react_native_android_fb) This comment suppresses an * error found when Flow v0.89 was deployed. To see the error, delete this diff --git a/Libraries/Image/Image.ios.js b/Libraries/Image/Image.ios.js index 22b28309076ee1..5cd788918f7b40 100644 --- a/Libraries/Image/Image.ios.js +++ b/Libraries/Image/Image.ios.js @@ -23,7 +23,7 @@ import type {ImageProps as ImagePropsType} from './ImageProps'; import type {ImageStyleProp} from '../StyleSheet/StyleSheet'; import NativeImageLoaderIOS from './NativeImageLoaderIOS'; -import ImageViewNativeComponent from './ImageViewNativeComponent'; +const RCTImageView = require('./ImageViewNativeComponent'); function getSize( uri: string, @@ -82,7 +82,7 @@ type ImageComponentStatics = $ReadOnly<{| * including network images, static resources, temporary local images, and * images from local disk, such as the camera roll. * - * See https://reactnative.dev/docs/image.html + * See https://facebook.github.io/react-native/docs/image.html */ let Image = (props: ImagePropsType, forwardedRef) => { const source = resolveAssetSource(props.source) || { @@ -124,7 +124,7 @@ let Image = (props: ImagePropsType, forwardedRef) => { } return ( - { ); }; -Image = React.forwardRef< - ImagePropsType, - React.ElementRef, ->(Image); +Image = React.forwardRef>( + Image, +); Image.displayName = 'Image'; /** * Retrieve the width and height (in pixels) of an image prior to displaying it. * - * See https://reactnative.dev/docs/image.html#getsize + * See https://facebook.github.io/react-native/docs/image.html#getsize */ /* $FlowFixMe(>=0.89.0 site=react_native_ios_fb) This comment suppresses an * error found when Flow v0.89 was deployed. To see the error, delete this @@ -155,7 +154,7 @@ Image.getSize = getSize; * Retrieve the width and height (in pixels) of an image prior to displaying it * with the ability to provide the headers for the request. * - * See https://reactnative.dev/docs/image.html#getsizewithheaders + * See https://facebook.github.io/react-native/docs/image.html#getsizewithheaders */ /* $FlowFixMe(>=0.89.0 site=react_native_ios_fb) This comment suppresses an * error found when Flow v0.89 was deployed. To see the error, delete this @@ -166,7 +165,7 @@ Image.getSizeWithHeaders = getSizeWithHeaders; * Prefetches a remote image for later use by downloading it to the disk * cache. * - * See https://reactnative.dev/docs/image.html#prefetch + * See https://facebook.github.io/react-native/docs/image.html#prefetch */ /* $FlowFixMe(>=0.89.0 site=react_native_ios_fb) This comment suppresses an * error found when Flow v0.89 was deployed. To see the error, delete this @@ -176,7 +175,7 @@ Image.prefetch = prefetch; /** * Performs cache interrogation. * - * See https://reactnative.dev/docs/image.html#querycache + * See https://facebook.github.io/react-native/docs/image.html#querycache */ /* $FlowFixMe(>=0.89.0 site=react_native_ios_fb) This comment suppresses an * error found when Flow v0.89 was deployed. To see the error, delete this @@ -186,7 +185,7 @@ Image.queryCache = queryCache; /** * Resolves an asset reference into an object. * - * See https://reactnative.dev/docs/image.html#resolveassetsource + * See https://facebook.github.io/react-native/docs/image.html#resolveassetsource */ /* $FlowFixMe(>=0.89.0 site=react_native_ios_fb) This comment suppresses an * error found when Flow v0.89 was deployed. To see the error, delete this @@ -206,6 +205,6 @@ const styles = StyleSheet.create({ module.exports = ((Image: any): React.AbstractComponent< ImagePropsType, - React.ElementRef, + React.ElementRef, > & ImageComponentStatics); diff --git a/Libraries/Image/ImageBackground.js b/Libraries/Image/ImageBackground.js index b4b6223b846b61..d9c849c5270e30 100644 --- a/Libraries/Image/ImageBackground.js +++ b/Libraries/Image/ImageBackground.js @@ -27,7 +27,7 @@ const View = require('../Components/View/View'); * return ( * * React * diff --git a/Libraries/Image/ImageProps.js b/Libraries/Image/ImageProps.js index 8f8512e06cb861..b3098a814debeb 100644 --- a/Libraries/Image/ImageProps.js +++ b/Libraries/Image/ImageProps.js @@ -14,6 +14,7 @@ import type {SyntheticEvent, LayoutEvent} from '../Types/CoreEventTypes'; import type {EdgeInsetsProp} from '../StyleSheet/EdgeInsetsPropType'; import type {ImageSource} from './ImageSource'; import type {ViewStyleProp, ImageStyleProp} from '../StyleSheet/StyleSheet'; +import type {DimensionValue} from '../StyleSheet/StyleSheetTypes'; import type {ViewProps} from '../Components/View/ViewPropTypes'; export type ImageLoadEvent = SyntheticEvent< @@ -31,19 +32,19 @@ type IOSImageProps = $ReadOnly<{| /** * A static image to display while loading the image source. * - * See https://reactnative.dev/docs/image.html#defaultsource + * See https://facebook.github.io/react-native/docs/image.html#defaultsource */ defaultSource?: ?ImageSource, /** * Invoked when a partial load of the image is complete. * - * See https://reactnative.dev/docs/image.html#onpartialload + * See https://facebook.github.io/react-native/docs/image.html#onpartialload */ onPartialLoad?: ?() => void, /** * Invoked on download progress with `{nativeEvent: {loaded, total}}`. * - * See https://reactnative.dev/docs/image.html#onprogress + * See https://facebook.github.io/react-native/docs/image.html#onprogress */ onProgress?: ?( event: SyntheticEvent<$ReadOnly<{|loaded: number, total: number|}>>, @@ -64,39 +65,34 @@ export type ImageProps = {| /** * When true, indicates the image is an accessibility element. * - * See https://reactnative.dev/docs/image.html#accessible + * See https://facebook.github.io/react-native/docs/image.html#accessible */ accessible?: ?boolean, - /** - * Internal prop to set an "Analytics Tag" that can will be set on the Image - */ - internal_analyticTag?: ?string, - /** * The text that's read by the screen reader when the user interacts with * the image. * - * See https://reactnative.dev/docs/image.html#accessibilitylabel + * See https://facebook.github.io/react-native/docs/image.html#accessibilitylabel */ accessibilityLabel?: ?Stringish, /** * blurRadius: the blur radius of the blur filter added to the image * - * See https://reactnative.dev/docs/image.html#blurradius + * See https://facebook.github.io/react-native/docs/image.html#blurradius */ blurRadius?: ?number, /** - * See https://reactnative.dev/docs/image.html#capinsets + * See https://facebook.github.io/react-native/docs/image.html#capinsets */ capInsets?: ?EdgeInsetsProp, /** * Invoked on load error with `{nativeEvent: {error}}`. * - * See https://reactnative.dev/docs/image.html#onerror + * See https://facebook.github.io/react-native/docs/image.html#onerror */ onError?: ?( event: SyntheticEvent< @@ -110,7 +106,7 @@ export type ImageProps = {| * Invoked on mount and layout changes with * `{nativeEvent: {layout: {x, y, width, height}}}`. * - * See https://reactnative.dev/docs/image.html#onlayout + * See https://facebook.github.io/react-native/docs/image.html#onlayout */ onLayout?: ?(event: LayoutEvent) => mixed, @@ -118,46 +114,50 @@ export type ImageProps = {| /** * Invoked when load completes successfully. * - * See https://reactnative.dev/docs/image.html#onload + * See https://facebook.github.io/react-native/docs/image.html#onload */ onLoad?: ?(event: ImageLoadEvent) => void, /** * Invoked when load either succeeds or fails. * - * See https://reactnative.dev/docs/image.html#onloadend + * See https://facebook.github.io/react-native/docs/image.html#onloadend */ onLoadEnd?: ?() => void, /** * Invoked on load start. * - * See https://reactnative.dev/docs/image.html#onloadstart + * See https://facebook.github.io/react-native/docs/image.html#onloadstart */ onLoadStart?: ?() => void, /** - * See https://reactnative.dev/docs/image.html#resizemethod + * See https://facebook.github.io/react-native/docs/image.html#resizemethod */ resizeMethod?: ?('auto' | 'resize' | 'scale'), /** * The image source (either a remote URL or a local file resource). * - * See https://reactnative.dev/docs/image.html#source + * See https://facebook.github.io/react-native/docs/image.html#source */ source?: ?ImageSource, /** - * See https://reactnative.dev/docs/image.html#style + * See https://facebook.github.io/react-native/docs/image.html#style */ style?: ?ImageStyleProp, + // Can be set via props or style, for now + height?: ?DimensionValue, + width?: ?DimensionValue, + /** * Determines how to resize the image when the frame doesn't match the raw * image dimensions. * - * See https://reactnative.dev/docs/image.html#resizemode + * See https://facebook.github.io/react-native/docs/image.html#resizemode */ resizeMode?: ?('cover' | 'contain' | 'stretch' | 'repeat' | 'center'), @@ -165,7 +165,7 @@ export type ImageProps = {| * A unique identifier for this element to be used in UI Automation * testing scripts. * - * See https://reactnative.dev/docs/image.html#testid + * See https://facebook.github.io/react-native/docs/image.html#testid */ testID?: ?string, diff --git a/Libraries/Image/ImageViewNativeComponent.js b/Libraries/Image/ImageViewNativeComponent.js index b5dea64e6f19f7..a2f9bd587677e3 100644 --- a/Libraries/Image/ImageViewNativeComponent.js +++ b/Libraries/Image/ImageViewNativeComponent.js @@ -12,6 +12,8 @@ const requireNativeComponent = require('../ReactNative/requireNativeComponent'); +import codegenNativeComponent from '../Utilities/codegenNativeComponent'; + import type {DangerouslyImpreciseStyle} from '../StyleSheet/StyleSheet'; import type {ResolvedAssetSource} from './AssetSourceResolver'; import type {HostComponent} from '../Renderer/shims/ReactNativeTypes'; @@ -20,9 +22,6 @@ import type {ViewProps} from '../Components/View/ViewPropTypes'; import type {ImageStyleProp} from '../StyleSheet/StyleSheet'; import type {ColorValue} from '../StyleSheet/StyleSheetTypes'; -import ImageViewViewConfig from './ImageViewViewConfig'; -const ReactNativeViewConfigRegistry = require('../Renderer/shims/ReactNativeViewConfigRegistry'); - type NativeProps = $ReadOnly<{| ...ImageProps, ...ViewProps, @@ -41,16 +40,15 @@ type NativeProps = $ReadOnly<{| |}>; let ImageViewNativeComponent; + if (global.RN$Bridgeless) { - ReactNativeViewConfigRegistry.register('RCTImageView', () => { - return ImageViewViewConfig; - }); - ImageViewNativeComponent = 'RCTImageView'; + ImageViewNativeComponent = codegenNativeComponent( + 'RCTImageView', + ); } else { ImageViewNativeComponent = requireNativeComponent( 'RCTImageView', ); } -// flowlint-next-line unclear-type:off -export default ((ImageViewNativeComponent: any): HostComponent); +module.exports = (ImageViewNativeComponent: HostComponent); diff --git a/Libraries/Image/ImageViewViewConfig.js b/Libraries/Image/ImageViewViewConfig.js deleted file mode 100644 index 5870038e97d584..00000000000000 --- a/Libraries/Image/ImageViewViewConfig.js +++ /dev/null @@ -1,68 +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. - * - * @format - * @flow strict-local - */ - -'use strict'; - -import ReactNativeViewViewConfig from '../Components/View/ReactNativeViewViewConfig'; -import type {ReactNativeBaseComponentViewConfig} from '../Renderer/shims/ReactNativeTypes'; - -const ImageViewViewConfig = { - uiViewClassName: 'RCTImageView', - bubblingEventTypes: {}, - directEventTypes: { - topLoadStart: { - registrationName: 'onLoadStart', - }, - topProgress: { - registrationName: 'onProgress', - }, - topError: { - registrationName: 'onError', - }, - topPartialLoad: { - registrationName: 'onPartialLoad', - }, - topLoad: { - registrationName: 'onLoad', - }, - topLoadEnd: { - registrationName: 'onLoadEnd', - }, - }, - validAttributes: { - ...ReactNativeViewViewConfig.validAttributes, - blurRadius: true, - // flowlint-next-line unclear-type:off - capInsets: {diff: (require('../Utilities/differ/insetsDiffer'): any)}, - defaultSource: { - process: require('./resolveAssetSource'), - }, - defaultSrc: true, - fadeDuration: true, - headers: true, - loadingIndicatorSrc: true, - onError: true, - onLoad: true, - onLoadEnd: true, - onLoadStart: true, - onPartialLoad: true, - onProgress: true, - overlayColor: {process: require('../StyleSheet/processColor')}, - progressiveRenderingEnabled: true, - resizeMethod: true, - resizeMode: true, - shouldNotifyLoadEvents: true, - source: true, - src: true, - tintColor: {process: require('../StyleSheet/processColor')}, - }, -}; - -module.exports = (ImageViewViewConfig: ReactNativeBaseComponentViewConfig<>); diff --git a/Libraries/Image/RCTAnimatedImage.m b/Libraries/Image/RCTAnimatedImage.m index 67c206d6ef0187..9343787912e9b9 100644 --- a/Libraries/Image/RCTAnimatedImage.m +++ b/Libraries/Image/RCTAnimatedImage.m @@ -111,7 +111,7 @@ - (float)frameDurationAtIndex:(NSUInteger)index source:(CGImageSourceRef)source NSDictionary *gifProperties = frameProperties[(NSString *)kCGImagePropertyGIFDictionary]; NSNumber *delayTimeUnclampedProp = gifProperties[(NSString *)kCGImagePropertyGIFUnclampedDelayTime]; - if (delayTimeUnclampedProp != nil && [delayTimeUnclampedProp floatValue] != 0.0f) { + if (delayTimeUnclampedProp != nil) { frameDuration = [delayTimeUnclampedProp floatValue]; } else { NSNumber *delayTimeProp = gifProperties[(NSString *)kCGImagePropertyGIFDelayTime]; diff --git a/Libraries/Image/RCTDisplayWeakRefreshable.h b/Libraries/Image/RCTDisplayWeakRefreshable.h deleted file mode 100644 index a6a05059fb7a37..00000000000000 --- a/Libraries/Image/RCTDisplayWeakRefreshable.h +++ /dev/null @@ -1,24 +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. - */ - -#import - -#import // TODO(macOS ISS#2323203) - -@protocol RCTDisplayRefreshable - -- (void)displayDidRefresh:(RCTPlatformDisplayLink *)displayLink; // TODO(macOS ISS#2323203) - -@end - -@interface RCTDisplayWeakRefreshable : NSObject - -@property (nonatomic, weak) id refreshable; - -+ (RCTPlatformDisplayLink *)displayLinkWithWeakRefreshable:(id)refreshable; // TODO(macOS ISS#2323203) - -@end diff --git a/Libraries/Image/RCTDisplayWeakRefreshable.m b/Libraries/Image/RCTDisplayWeakRefreshable.m deleted file mode 100644 index e8d8bfc3b88f76..00000000000000 --- a/Libraries/Image/RCTDisplayWeakRefreshable.m +++ /dev/null @@ -1,29 +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. - */ - -#import "RCTDisplayWeakRefreshable.h" - -@implementation RCTDisplayWeakRefreshable - -+ (RCTPlatformDisplayLink *)displayLinkWithWeakRefreshable:(id)refreshable { // TODO(macOS ISS#2323203) - RCTDisplayWeakRefreshable *target = [[RCTDisplayWeakRefreshable alloc] initWithRefreshable:refreshable]; - return [RCTPlatformDisplayLink displayLinkWithTarget:target selector:@selector(displayDidRefresh:)]; // TODO(macOS ISS#2323203) -} - -- (instancetype)initWithRefreshable:(id)refreshable -{ - if (self = [super init]) { - _refreshable = refreshable; - } - return self; -} - -- (void)displayDidRefresh:(RCTPlatformDisplayLink *)displayLink { // TODO(macOS ISS#2323203) - [_refreshable displayDidRefresh:displayLink]; -} - -@end diff --git a/Libraries/Image/RCTImageEditingManager.mm b/Libraries/Image/RCTImageEditingManager.mm index 3dda1241161715..f2786873654dd4 100644 --- a/Libraries/Image/RCTImageEditingManager.mm +++ b/Libraries/Image/RCTImageEditingManager.mm @@ -92,12 +92,10 @@ @implementation RCTImageEditingManager }]; } -- (std::shared_ptr) - getTurboModuleWithJsInvoker:(std::shared_ptr)jsInvoker - nativeInvoker:(std::shared_ptr)nativeInvoker - perfLogger:(id)perfLogger +- (std::shared_ptr)getTurboModuleWithJsInvoker: + (std::shared_ptr)jsInvoker { - return std::make_shared(self, jsInvoker, nativeInvoker, perfLogger); + return std::make_shared(self, jsInvoker); } @end diff --git a/Libraries/Image/RCTImageLoader.h b/Libraries/Image/RCTImageLoader.h index 4272fbd13544e4..000d6ecbe98755 100644 --- a/Libraries/Image/RCTImageLoader.h +++ b/Libraries/Image/RCTImageLoader.h @@ -16,6 +16,11 @@ #import #import +RCT_EXTERN BOOL RCTImageLoadingInstrumentationEnabled(void); +RCT_EXTERN BOOL RCTImageLoadingPerfInstrumentationEnabled(void); +RCT_EXTERN void RCTEnableImageLoadingInstrumentation(BOOL enabled); +RCT_EXTERN void RCTEnableImageLoadingPerfInstrumentation(BOOL enabled); + @interface RCTImageLoader : NSObject - (instancetype)init; - (instancetype)initWithRedirectDelegate:(id)redirectDelegate NS_DESIGNATED_INITIALIZER; diff --git a/Libraries/Image/RCTImageLoader.mm b/Libraries/Image/RCTImageLoader.mm index 483d46f19db126..9bb1f3d12666a6 100644 --- a/Libraries/Image/RCTImageLoader.mm +++ b/Libraries/Image/RCTImageLoader.mm @@ -7,7 +7,6 @@ #import #import -#import #import @@ -22,19 +21,29 @@ #import #import #import -#import // TODO(macOS ISS#2323203) #import "RCTImagePlugins.h" using namespace facebook::react; +static BOOL imageInstrumentationEnabled = NO; static BOOL imagePerfInstrumentationEnabled = NO; +BOOL RCTImageLoadingInstrumentationEnabled(void) +{ + return imageInstrumentationEnabled; +} + BOOL RCTImageLoadingPerfInstrumentationEnabled(void) { return imagePerfInstrumentationEnabled; } +void RCTEnableImageLoadingInstrumentation(BOOL enabled) +{ + imageInstrumentationEnabled = enabled; +} + void RCTEnableImageLoadingPerfInstrumentation(BOOL enabled) { imagePerfInstrumentationEnabled = enabled; @@ -69,18 +78,6 @@ static NSInteger RCTImageBytesForImage(UIImage *image) } #endif // TARGET_OS_OSX -static uint64_t monotonicTimeGetCurrentNanoseconds(void) -{ - static struct mach_timebase_info tb_info = {0}; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - __unused int ret = mach_timebase_info(&tb_info); - assert(0 == ret); - }); - - return (mach_absolute_time() * tb_info.numer) / tb_info.denom; -} - @interface RCTImageLoader() @end @@ -124,7 +121,6 @@ @implementation RCTImageLoader @synthesize maxConcurrentLoadingTasks = _maxConcurrentLoadingTasks; @synthesize maxConcurrentDecodingTasks = _maxConcurrentDecodingTasks; @synthesize maxConcurrentDecodingBytes = _maxConcurrentDecodingBytes; -@synthesize turboModuleLookupDelegate = _turboModuleLookupDelegate; RCT_EXPORT_MODULE() @@ -197,11 +193,11 @@ - (void)setImageCache:(id)cache if (!_loaders) { // Get loaders, sorted in reverse priority order (highest priority first) + RCTAssert(_bridge, @"Bridge not set"); if (_loadersProvider) { _loaders = _loadersProvider(); } else { - RCTAssert(_bridge, @"Trying to find RCTImageURLLoaders and bridge not set."); _loaders = [_bridge modulesConformingToProtocol:@protocol(RCTImageURLLoader)]; } @@ -261,11 +257,11 @@ - (void)setImageCache:(id)cache if (!_decoders) { // Get decoders, sorted in reverse priority order (highest priority first) + RCTAssert(_bridge, @"Bridge not set"); if (_decodersProvider) { _decoders = _decodersProvider(); } else { - RCTAssert(_bridge, @"Trying to find RCTImageDataDecoders and bridge not set."); _decoders = [_bridge modulesConformingToProtocol:@protocol(RCTImageDataDecoder)]; } @@ -342,6 +338,7 @@ - (RCTImageLoaderCancellationBlock) loadImageWithURLRequest:(NSURLRequest *)imag scale:1 clipped:YES resizeMode:RCTResizeModeStretch + attribution:{} progressBlock:nil partialLoadBlock:nil completionBlock:callback]; @@ -356,18 +353,15 @@ - (RCTImageLoaderCancellationBlock)loadImageWithURLRequest:(NSURLRequest *)image partialLoadBlock:(RCTImageLoaderPartialLoadBlock)partialLoadBlock completionBlock:(RCTImageLoaderCompletionBlock)completionBlock { - RCTImageURLLoaderRequest *request = [self loadImageWithURLRequest:imageURLRequest - size:size - scale:scale - clipped:clipped - resizeMode:resizeMode - attribution:{} - progressBlock:progressBlock - partialLoadBlock:partialLoadBlock - completionBlock:completionBlock]; - return ^{ - [request cancel]; - }; + return [self loadImageWithURLRequest:imageURLRequest + size:size + scale:scale + clipped:clipped + resizeMode:resizeMode + attribution:{} + progressBlock:progressBlock + partialLoadBlock:partialLoadBlock + completionBlock:completionBlock]; } - (void)dequeueTasks @@ -442,14 +436,14 @@ - (NSInteger)activeTasks { * path taken. This is useful if you want to skip decoding, e.g. when preloading * the image, or retrieving metadata. */ -- (RCTImageURLLoaderRequest *)_loadImageOrDataWithURLRequest:(NSURLRequest *)request - size:(CGSize)size - scale:(CGFloat)scale - resizeMode:(RCTResizeMode)resizeMode - attribution:(const ImageURLLoaderAttribution &)attribution - progressBlock:(RCTImageLoaderProgressBlock)progressHandler - partialLoadBlock:(RCTImageLoaderPartialLoadBlock)partialLoadHandler - completionBlock:(void (^)(NSError *error, id imageOrData, BOOL cacheResult, NSURLResponse *response))completionBlock +- (RCTImageLoaderCancellationBlock)_loadImageOrDataWithURLRequest:(NSURLRequest *)request + size:(CGSize)size + scale:(CGFloat)scale + resizeMode:(RCTResizeMode)resizeMode + attribution:(const ImageURLLoaderAttribution &)attribution + progressBlock:(RCTImageLoaderProgressBlock)progressHandler + partialLoadBlock:(RCTImageLoaderPartialLoadBlock)partialLoadHandler + completionBlock:(void (^)(NSError *error, id imageOrData, BOOL cacheResult, NSURLResponse *response))completionBlock { { NSMutableURLRequest *mutableRequest = [request mutableCopy]; @@ -481,8 +475,6 @@ - (RCTImageURLLoaderRequest *)_loadImageOrDataWithURLRequest:(NSURLRequest *)req auto cancelled = std::make_shared>(0); __block dispatch_block_t cancelLoad = nil; __block NSLock *cancelLoadLock = [NSLock new]; - NSString *requestId = [NSString stringWithFormat:@"%@-%llu",[[NSUUID UUID] UUIDString], monotonicTimeGetCurrentNanoseconds()]; - void (^completionHandler)(NSError *, id, NSURLResponse *) = ^(NSError *error, id imageOrData, NSURLResponse *response) { [cancelLoadLock lock]; cancelLoad = nil; @@ -511,7 +503,6 @@ - (RCTImageURLLoaderRequest *)_loadImageOrDataWithURLRequest:(NSURLRequest *)req size:size scale:scale resizeMode:resizeMode - requestId:requestId attribution:attributionCopy progressHandler:progressHandler partialLoadHandler:partialLoadHandler @@ -519,16 +510,15 @@ - (RCTImageURLLoaderRequest *)_loadImageOrDataWithURLRequest:(NSURLRequest *)req completionHandler(error, image, nil); }]; } - RCTImageLoaderCancellationBlock cb = [loadHandler loadImageForURL:request.URL - size:size - scale:scale - resizeMode:resizeMode - progressHandler:progressHandler - partialLoadHandler:partialLoadHandler - completionHandler:^(NSError *error, UIImage *image) { - completionHandler(error, image, nil); - }]; - return [[RCTImageURLLoaderRequest alloc] initWithRequestId:nil imageURL:request.URL cancellationBlock:cb]; + return [loadHandler loadImageForURL:request.URL + size:size + scale:scale + resizeMode:resizeMode + progressHandler:progressHandler + partialLoadHandler:partialLoadHandler + completionHandler:^(NSError *error, UIImage *image) { + completionHandler(error, image, nil); + }]; } // All access to URL cache must be serialized @@ -546,18 +536,16 @@ - (RCTImageURLLoaderRequest *)_loadImageOrDataWithURLRequest:(NSURLRequest *)req if (loadHandler) { dispatch_block_t cancelLoadLocal; if ([loadHandler conformsToProtocol:@protocol(RCTImageURLLoaderWithAttribution)]) { - RCTImageURLLoaderRequest *loaderRequest = [(id)loadHandler loadImageForURL:request.URL - size:size - scale:scale - resizeMode:resizeMode - requestId:requestId - attribution:attributionCopy - progressHandler:progressHandler - partialLoadHandler:partialLoadHandler - completionHandler:^(NSError *error, UIImage *image) { - completionHandler(error, image, nil); - }]; - cancelLoadLocal = loaderRequest.cancellationBlock; + cancelLoadLocal = [(id)loadHandler loadImageForURL:request.URL + size:size + scale:scale + resizeMode:resizeMode + attribution:attributionCopy + progressHandler:progressHandler + partialLoadHandler:partialLoadHandler + completionHandler:^(NSError *error, UIImage *image) { + completionHandler(error, image, nil); + }]; } else { cancelLoadLocal = [loadHandler loadImageForURL:request.URL size:size @@ -595,7 +583,7 @@ - (RCTImageURLLoaderRequest *)_loadImageOrDataWithURLRequest:(NSURLRequest *)req } }); - return [[RCTImageURLLoaderRequest alloc] initWithRequestId:requestId imageURL:request.URL cancellationBlock:^{ + return ^{ BOOL alreadyCancelled = atomic_fetch_or(cancelled.get(), 1); if (alreadyCancelled) { return; @@ -607,7 +595,7 @@ - (RCTImageURLLoaderRequest *)_loadImageOrDataWithURLRequest:(NSURLRequest *)req if (cancelLoadLocal) { cancelLoadLocal(); } - }]; + }; } - (RCTImageLoaderCancellationBlock)_loadURLRequest:(NSURLRequest *)request @@ -615,8 +603,7 @@ - (RCTImageLoaderCancellationBlock)_loadURLRequest:(NSURLRequest *)request completionBlock:(void (^)(NSError *error, id imageOrData, NSURLResponse *response))completionHandler { // Check if networking module is available - if (RCT_DEBUG && ![_bridge respondsToSelector:@selector(networking)] - && ![_turboModuleLookupDelegate moduleForName:"RCTNetworking"]) { + if (RCT_DEBUG && ![_bridge respondsToSelector:@selector(networking)]) { RCTLogError(@"No suitable image URL loader found for %@. You may need to " " import the RCTNetwork library in order to load images.", request.URL.absoluteString); @@ -624,9 +611,6 @@ - (RCTImageLoaderCancellationBlock)_loadURLRequest:(NSURLRequest *)request } RCTNetworking *networking = [_bridge networking]; - if (!networking) { - networking = [_turboModuleLookupDelegate moduleForName:"RCTNetworking"]; - } // Check if networking module can load image if (RCT_DEBUG && ![networking canHandleRequest:request]) { @@ -725,17 +709,15 @@ - (RCTImageLoaderCancellationBlock)_loadURLRequest:(NSURLRequest *)request }; } -#pragma mark - RCTImageLoaderWithAttributionProtocol - -- (RCTImageURLLoaderRequest *)loadImageWithURLRequest:(NSURLRequest *)imageURLRequest - size:(CGSize)size - scale:(CGFloat)scale - clipped:(BOOL)clipped - resizeMode:(RCTResizeMode)resizeMode - attribution:(const ImageURLLoaderAttribution &)attribution - progressBlock:(RCTImageLoaderProgressBlock)progressBlock - partialLoadBlock:(RCTImageLoaderPartialLoadBlock)partialLoadBlock - completionBlock:(RCTImageLoaderCompletionBlock)completionBlock +- (RCTImageLoaderCancellationBlock)loadImageWithURLRequest:(NSURLRequest *)imageURLRequest + size:(CGSize)size + scale:(CGFloat)scale + clipped:(BOOL)clipped + resizeMode:(RCTResizeMode)resizeMode + attribution:(const ImageURLLoaderAttribution &)attribution + progressBlock:(RCTImageLoaderProgressBlock)progressBlock + partialLoadBlock:(RCTImageLoaderPartialLoadBlock)partialLoadBlock + completionBlock:(RCTImageLoaderCompletionBlock)completionBlock { auto cancelled = std::make_shared>(0); __block dispatch_block_t cancelLoad = nil; @@ -795,51 +777,15 @@ - (RCTImageURLLoaderRequest *)loadImageWithURLRequest:(NSURLRequest *)imageURLRe [cancelLoadLock unlock]; }; - RCTImageURLLoaderRequest *loaderRequest = [self _loadImageOrDataWithURLRequest:imageURLRequest - size:size - scale:scale - resizeMode:resizeMode - attribution:attribution - progressBlock:progressBlock - partialLoadBlock:partialLoadBlock - completionBlock:completionHandler]; - cancelLoad = loaderRequest.cancellationBlock; - return [[RCTImageURLLoaderRequest alloc] initWithRequestId:loaderRequest.requestId imageURL:imageURLRequest.URL cancellationBlock:cancellationBlock]; -} - -- (void)trackURLImageContentDidSetForRequest:(RCTImageURLLoaderRequest *)loaderRequest -{ - if (!loaderRequest) { - return; - } - - id loadHandler = [self imageURLLoaderForURL:loaderRequest.imageURL]; - if ([loadHandler respondsToSelector:@selector(trackURLImageContentDidSetForRequest:)]) { - [(id)loadHandler trackURLImageContentDidSetForRequest:loaderRequest]; - } -} - -- (void)trackURLImageVisibilityForRequest:(RCTImageURLLoaderRequest *)loaderRequest imageView:(RCTUIView *)imageView // TODO(macOS ISS#2323203) -{ - if (!loaderRequest || !imageView) { - return; - } - - id loadHandler = [self imageURLLoaderForURL:loaderRequest.imageURL]; - if ([loadHandler respondsToSelector:@selector(trackURLImageVisibilityForRequest:imageView:)]) { - [(id)loadHandler trackURLImageVisibilityForRequest:loaderRequest imageView:imageView]; - } -} - -- (void)trackURLImageDidDestroy:(RCTImageURLLoaderRequest *)loaderRequest -{ - if (!loaderRequest) { - return; - } - id loadHandler = [self imageURLLoaderForURL:loaderRequest.imageURL]; - if ([loadHandler respondsToSelector:@selector(trackURLImageDidDestroy:)]) { - [(id)loadHandler trackURLImageDidDestroy:loaderRequest]; - } + cancelLoad = [self _loadImageOrDataWithURLRequest:imageURLRequest + size:size + scale:scale + resizeMode:resizeMode + attribution:attribution + progressBlock:progressBlock + partialLoadBlock:partialLoadBlock + completionBlock:completionHandler]; + return cancellationBlock; } - (RCTImageLoaderCancellationBlock)decodeImageData:(NSData *)data @@ -997,15 +943,14 @@ - (RCTImageLoaderCancellationBlock)getImageSizeForURLRequest:(NSURLRequest *)ima callback(error, size); }; - RCTImageURLLoaderRequest *loaderRequest = [self _loadImageOrDataWithURLRequest:imageURLRequest - size:CGSizeZero - scale:1 - resizeMode:RCTResizeModeStretch - attribution:{} - progressBlock:NULL - partialLoadBlock:NULL - completionBlock:completion]; - return loaderRequest.cancellationBlock; + return [self _loadImageOrDataWithURLRequest:imageURLRequest + size:CGSizeZero + scale:1 + resizeMode:RCTResizeModeStretch + attribution:{} + progressBlock:NULL + partialLoadBlock:NULL + completionBlock:completion]; } - (NSDictionary *)getImageCacheStatus:(NSArray *)requests @@ -1126,12 +1071,10 @@ - (void)cancelRequest:(id)requestToken } } -- (std::shared_ptr) - getTurboModuleWithJsInvoker:(std::shared_ptr)jsInvoker - nativeInvoker:(std::shared_ptr)nativeInvoker - perfLogger:(id)perfLogger +- (std::shared_ptr)getTurboModuleWithJsInvoker: + (std::shared_ptr)jsInvoker { - return std::make_shared(self, jsInvoker, nativeInvoker, perfLogger); + return std::make_shared(self, jsInvoker); } RCT_EXPORT_METHOD(getSize:(NSString *)uri resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) diff --git a/Libraries/Image/RCTImageLoaderWithAttributionProtocol.h b/Libraries/Image/RCTImageLoaderWithAttributionProtocol.h index 1b73db119895b5..3bd8604949f85e 100644 --- a/Libraries/Image/RCTImageLoaderWithAttributionProtocol.h +++ b/Libraries/Image/RCTImageLoaderWithAttributionProtocol.h @@ -10,11 +10,6 @@ #import #import -RCT_EXTERN BOOL RCTImageLoadingInstrumentationEnabled(void); -RCT_EXTERN BOOL RCTImageLoadingPerfInstrumentationEnabled(void); -RCT_EXTERN void RCTEnableImageLoadingInstrumentation(BOOL enabled); -RCT_EXTERN void RCTEnableImageLoadingPerfInstrumentation(BOOL enabled); - @protocol RCTImageLoaderWithAttributionProtocol // TODO (T61325135): Remove C++ checks @@ -23,30 +18,15 @@ RCT_EXTERN void RCTEnableImageLoadingPerfInstrumentation(BOOL enabled); * Same as the variant in RCTImageURLLoaderProtocol, but allows passing attribution * information that each image URL loader can process. */ -- (RCTImageURLLoaderRequest *)loadImageWithURLRequest:(NSURLRequest *)imageURLRequest - size:(CGSize)size - scale:(CGFloat)scale - clipped:(BOOL)clipped - resizeMode:(RCTResizeMode)resizeMode - attribution:(const facebook::react::ImageURLLoaderAttribution &)attribution - progressBlock:(RCTImageLoaderProgressBlock)progressBlock - partialLoadBlock:(RCTImageLoaderPartialLoadBlock)partialLoadBlock - completionBlock:(RCTImageLoaderCompletionBlock)completionBlock; +- (RCTImageLoaderCancellationBlock)loadImageWithURLRequest:(NSURLRequest *)imageURLRequest + size:(CGSize)size + scale:(CGFloat)scale + clipped:(BOOL)clipped + resizeMode:(RCTResizeMode)resizeMode + attribution:(const facebook::react::ImageURLLoaderAttribution &)attribution + progressBlock:(RCTImageLoaderProgressBlock)progressBlock + partialLoadBlock:(RCTImageLoaderPartialLoadBlock)partialLoadBlock + completionBlock:(RCTImageLoaderCompletionBlock)completionBlock; #endif -/** - * Image instrumentation - notify that the image content (UIImage) has been set on the native view. - */ -- (void)trackURLImageContentDidSetForRequest:(RCTImageURLLoaderRequest *)loaderRequest; - -/** - * Image instrumentation - start tracking the on-screen visibility of the native image view. - */ -- (void)trackURLImageVisibilityForRequest:(RCTImageURLLoaderRequest *)loaderRequest imageView:(RCTUIView *)imageView; // TODO(macOS ISS#2323203) - -/** - * Image instrumentation - notify that the native image view was destroyed. - */ -- (void)trackURLImageDidDestroy:(RCTImageURLLoaderRequest *)loaderRequest; - @end diff --git a/Libraries/Image/RCTImageStoreManager.mm b/Libraries/Image/RCTImageStoreManager.mm index 5fd1691854b24d..453590ee26dadb 100644 --- a/Libraries/Image/RCTImageStoreManager.mm +++ b/Libraries/Image/RCTImageStoreManager.mm @@ -236,12 +236,10 @@ - (void)getImageForTag:(NSString *)imageTag withBlock:(void (^)(UIImage *image)) }); } -- (std::shared_ptr) - getTurboModuleWithJsInvoker:(std::shared_ptr)jsInvoker - nativeInvoker:(std::shared_ptr)nativeInvoker - perfLogger:(id)perfLogger +- (std::shared_ptr)getTurboModuleWithJsInvoker: + (std::shared_ptr)jsInvoker { - return std::make_shared(self, jsInvoker, nativeInvoker, perfLogger); + return std::make_shared(self, jsInvoker); } @end diff --git a/Libraries/Image/RCTImageURLLoaderWithAttribution.h b/Libraries/Image/RCTImageURLLoaderWithAttribution.h index 9480b0e113cbb2..f5ee3e0c4f9e2c 100644 --- a/Libraries/Image/RCTImageURLLoaderWithAttribution.h +++ b/Libraries/Image/RCTImageURLLoaderWithAttribution.h @@ -7,8 +7,6 @@ #import -#import // TODO(macOS ISS#2323203) - // TODO (T61325135): Remove C++ checks #ifdef __cplusplus namespace facebook { @@ -23,17 +21,6 @@ struct ImageURLLoaderAttribution { } // namespace facebook #endif -@interface RCTImageURLLoaderRequest : NSObject - -@property (nonatomic, strong, readonly) NSString *requestId; -@property (nonatomic, strong, readonly) NSURL *imageURL; -@property (nonatomic, copy, readonly) RCTImageLoaderCancellationBlock cancellationBlock; - -- (instancetype)initWithRequestId:(NSString *)requestId imageURL:(NSURL *)imageURL cancellationBlock:(RCTImageLoaderCancellationBlock)cancellationBlock; -- (void)cancel; - -@end - /** * Same as the RCTImageURLLoader interface, but allows passing in optional `attribution` information. * This is useful for per-app logging and other instrumentation. @@ -44,32 +31,15 @@ struct ImageURLLoaderAttribution { #ifdef __cplusplus /** * Same as the RCTImageURLLoader variant above, but allows optional `attribution` information. - * Caller may also specify a preferred requestId for tracking purpose. */ -- (RCTImageURLLoaderRequest *)loadImageForURL:(NSURL *)imageURL - size:(CGSize)size - scale:(CGFloat)scale - resizeMode:(RCTResizeMode)resizeMode - requestId:(NSString *)requestId - attribution:(const facebook::react::ImageURLLoaderAttribution &)attribution - progressHandler:(RCTImageLoaderProgressBlock)progressHandler - partialLoadHandler:(RCTImageLoaderPartialLoadBlock)partialLoadHandler - completionHandler:(RCTImageLoaderCompletionBlock)completionHandler; +- (RCTImageLoaderCancellationBlock)loadImageForURL:(NSURL *)imageURL + size:(CGSize)size + scale:(CGFloat)scale + resizeMode:(RCTResizeMode)resizeMode + attribution:(const facebook::react::ImageURLLoaderAttribution &)attribution + progressHandler:(RCTImageLoaderProgressBlock)progressHandler + partialLoadHandler:(RCTImageLoaderPartialLoadBlock)partialLoadHandler + completionHandler:(RCTImageLoaderCompletionBlock)completionHandler; #endif -/** - * Image instrumentation - notify that the image content (UIImage) has been set on the native view. - */ -- (void)trackURLImageContentDidSetForRequest:(RCTImageURLLoaderRequest *)loaderRequest; - -/** - * Image instrumentation - start tracking the on-screen visibility of the native image view. - */ -- (void)trackURLImageVisibilityForRequest:(RCTImageURLLoaderRequest *)loaderRequest imageView:(RCTUIView *)imageView; // TODO(macOS ISS#2323203) - -/** - * Image instrumentation - notify that the native image view was destroyed. - */ -- (void)trackURLImageDidDestroy:(RCTImageURLLoaderRequest *)loaderRequest; - @end diff --git a/Libraries/Image/RCTImageURLLoaderWithAttribution.mm b/Libraries/Image/RCTImageURLLoaderWithAttribution.mm deleted file mode 100644 index 61baa4aafee979..00000000000000 --- a/Libraries/Image/RCTImageURLLoaderWithAttribution.mm +++ /dev/null @@ -1,30 +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. - */ - -#import "RCTImageURLLoaderWithAttribution.h" - -@implementation RCTImageURLLoaderRequest - -- (instancetype)initWithRequestId:(NSString *)requestId imageURL:(NSURL *)imageURL cancellationBlock:(RCTImageLoaderCancellationBlock)cancellationBlock -{ - if (self = [super init]) { - _requestId = requestId; - _imageURL = imageURL; - _cancellationBlock = cancellationBlock; - } - - return self; -} - -- (void)cancel -{ - if (_cancellationBlock) { - _cancellationBlock(); - } -} - -@end diff --git a/Libraries/Image/RCTImageView.mm b/Libraries/Image/RCTImageView.mm index c2b0b1fe53ff22..656f6196a32dbf 100644 --- a/Libraries/Image/RCTImageView.mm +++ b/Libraries/Image/RCTImageView.mm @@ -146,11 +146,7 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge #if TARGET_OS_OSX // [TODO(macOS ISS#2323203) self.wantsLayer = YES; #endif -#if !TARGET_OS_OSX // [TODO(macOS ISS#2323203) - _imageView = [[RCTUIImageViewAnimated alloc] init]; - _imageView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; - [self addSubview:_imageView]; - +#if !TARGET_OS_OSX NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; [center addObserver:self selector:@selector(clearImageIfDetached) @@ -160,16 +156,10 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge selector:@selector(clearImageIfDetached) name:UIApplicationDidEnterBackgroundNotification object:nil]; -#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 - if (@available(iOS 13.0, *)) { - [center addObserver:self - selector:@selector(clearImageIfDetached) - - name:UISceneDidEnterBackgroundNotification - object:nil]; - } #endif -#endif // ]TODO(macOS ISS#2323203) + _imageView = [[RCTUIImageViewAnimated alloc] init]; + _imageView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + [self addSubview:_imageView]; } return self; } @@ -440,19 +430,18 @@ - (void)reloadImage id imageLoader = [_bridge moduleForName:@"ImageLoader" lazilyLoadIfNecessary:YES]; - RCTImageURLLoaderRequest *loaderRequest = [imageLoader loadImageWithURLRequest:source.request - size:imageSize - scale:imageScale - clipped:NO - resizeMode:_resizeMode - attribution:{ - .nativeViewTag = [self.reactTag intValue], - .surfaceId = [self.rootTag intValue], - } - progressBlock:progressHandler - partialLoadBlock:partialLoadHandler - completionBlock:completionHandler]; - _reloadImageCancellationBlock = loaderRequest.cancellationBlock; + _reloadImageCancellationBlock = [imageLoader loadImageWithURLRequest:source.request + size:imageSize + scale:imageScale + clipped:NO + resizeMode:_resizeMode + attribution:{ + .nativeViewTag = [self.reactTag intValue], + .surfaceId = [self.rootTag intValue], + } + progressBlock:progressHandler + partialLoadBlock:partialLoadHandler + completionBlock:completionHandler]; } else { [self clearImage]; } diff --git a/Libraries/Image/RCTLocalAssetImageLoader.mm b/Libraries/Image/RCTLocalAssetImageLoader.mm index 8669ad3615d82c..7a550581c4d3a7 100644 --- a/Libraries/Image/RCTLocalAssetImageLoader.mm +++ b/Libraries/Image/RCTLocalAssetImageLoader.mm @@ -49,19 +49,28 @@ - (RCTImageLoaderCancellationBlock)loadImageForURL:(NSURL *)imageURL partialLoadHandler:(RCTImageLoaderPartialLoadBlock)partialLoadHandler completionHandler:(RCTImageLoaderCompletionBlock)completionHandler { - UIImage *image = RCTImageFromLocalAssetURL(imageURL); - if (image) { - if (progressHandler) { - progressHandler(1, 1); + __block auto cancelled = std::make_shared>(false); + RCTExecuteOnMainQueue(^{ + if (cancelled->load()) { + return; } - completionHandler(nil, image); - } else { - NSString *message = [NSString stringWithFormat:@"Could not find image %@", imageURL]; - RCTLogWarn(@"%@", message); - completionHandler(RCTErrorWithMessage(message), nil); - } - - return nil; + + UIImage *image = RCTImageFromLocalAssetURL(imageURL); + if (image) { + if (progressHandler) { + progressHandler(1, 1); + } + completionHandler(nil, image); + } else { + NSString *message = [NSString stringWithFormat:@"Could not find image %@", imageURL]; + RCTLogWarn(@"%@", message); + completionHandler(RCTErrorWithMessage(message), nil); + } + }); + + return ^{ + cancelled->store(true); + }; } @end diff --git a/Libraries/Image/RCTUIImageViewAnimated.m b/Libraries/Image/RCTUIImageViewAnimated.m index 0f3bd362c3ebc0..cd74208bdd43dd 100644 --- a/Libraries/Image/RCTUIImageViewAnimated.m +++ b/Libraries/Image/RCTUIImageViewAnimated.m @@ -6,7 +6,7 @@ */ #import -#import +#import #import #import @@ -28,7 +28,7 @@ static NSUInteger RCTDeviceFreeMemory() { return (vm_stat.free_count - vm_stat.speculative_count) * page_size; } -@interface RCTUIImageViewAnimated () +@interface RCTUIImageViewAnimated () @property (nonatomic, assign) NSUInteger maxBufferSize; @property (nonatomic, strong, readwrite) UIImage *currentFrame; @@ -160,7 +160,7 @@ - (CADisplayLink *)displayLink } if (!_displayLink) { - _displayLink = [RCTDisplayWeakRefreshable displayLinkWithWeakRefreshable:self]; + _displayLink = [CADisplayLink displayLinkWithTarget:[RCTWeakProxy weakProxyWithTarget:self] selector:@selector(displayDidRefresh:)]; NSString *runLoopMode = [NSProcessInfo processInfo].activeProcessorCount > 1 ? NSRunLoopCommonModes : NSDefaultRunLoopMode; [_displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:runLoopMode]; } @@ -277,8 +277,8 @@ - (void)displayLayer:(CALayer *)layer if (_currentFrame) { layer.contentsScale = self.animatedImageScale; layer.contents = (__bridge id)_currentFrame.CGImage; - } else { - [super displayLayer:layer]; + } else { + [super displayLayer:layer]; } } diff --git a/Libraries/Image/React-RCTImage.podspec b/Libraries/Image/React-RCTImage.podspec index 3cfb96ee430476..18270b5379e725 100644 --- a/Libraries/Image/React-RCTImage.podspec +++ b/Libraries/Image/React-RCTImage.podspec @@ -17,17 +17,17 @@ else end folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32' -folly_version = '2020.01.13.00' +folly_version = '2018.10.22.00' Pod::Spec.new do |s| s.name = "React-RCTImage" s.version = version s.summary = "A React component for displaying different types of images." - s.homepage = "https://reactnative.dev/" - s.documentation_url = "https://reactnative.dev/docs/image" + s.homepage = "http://facebook.github.io/react-native/" + s.documentation_url = "https://facebook.github.io/react-native/docs/image" s.license = package["license"] s.author = "Facebook, Inc. and its affiliates" - s.platforms = { :ios => "10.0", :tvos => "10.0", :osx => "10.13" } # TODO(macOS GH#214) + s.platforms = { :ios => "9.0", :tvos => "9.2", :osx => "10.13" } # TODO(macOS GH#214) s.compiler_flags = folly_compiler_flags + ' -Wno-nullability-completeness' s.source = source s.source_files = "*.{m,mm}" @@ -43,7 +43,6 @@ Pod::Spec.new do |s| s.dependency "FBReactNativeSpec", version s.dependency "RCTTypeSafety", version s.dependency "ReactCommon/turbomodule/core", version - s.dependency "React-jsi", version s.dependency "React-Core/RCTImageHeaders", version s.dependency "React-RCTNetwork", version end diff --git a/Libraries/Image/__tests__/resolveAssetSource-test.js b/Libraries/Image/__tests__/resolveAssetSource-test.js index ee752bd7322c4a..287e0657beb5ac 100644 --- a/Libraries/Image/__tests__/resolveAssetSource-test.js +++ b/Libraries/Image/__tests__/resolveAssetSource-test.js @@ -143,29 +143,6 @@ describe('resolveAssetSource', () => { }, ); }); - - it('resolves an image with a relative path outside of root', () => { - expectResolvesAsset( - { - __packager_asset: true, - fileSystemLocation: '/module/a', - httpServerLocation: '/assets/../../module/a', - width: 100, - height: 200, - scales: [1], - hash: '5b6f00f', - name: 'logo', - type: 'png', - }, - { - __packager_asset: true, - width: 100, - height: 200, - uri: 'file:///Path/To/Sample.app/assets/__module/a/logo.png', - scale: 1, - }, - ); - }); }); describe('bundle was loaded from assets on Android', () => { @@ -198,29 +175,6 @@ describe('resolveAssetSource', () => { }, ); }); - - it('resolves an image with a relative path outside of root', () => { - expectResolvesAsset( - { - __packager_asset: true, - fileSystemLocation: '/module/a', - httpServerLocation: '/assets/../../module/a', - width: 100, - height: 200, - scales: [1], - hash: '5b6f00f', - name: 'logo', - type: 'png', - }, - { - __packager_asset: true, - width: 100, - height: 200, - uri: '__module_a_logo', - scale: 1, - }, - ); - }); }); describe('bundle was loaded from file on Android', () => { diff --git a/Libraries/Image/nativeImageSource.js b/Libraries/Image/nativeImageSource.js index 739c9ca4586ab0..564c77d1c0b2b3 100644 --- a/Libraries/Image/nativeImageSource.js +++ b/Libraries/Image/nativeImageSource.js @@ -21,7 +21,7 @@ type NativeImageSourceSpec = $ReadOnly<{| default?: string, // For more details on width and height, see - // https://reactnative.dev/docs/images.html#why-not-automatically-size-everything + // http://facebook.github.io/react-native/docs/images.html#why-not-automatically-size-everything height: number, width: number, |}>; @@ -39,7 +39,7 @@ type NativeImageSourceSpec = $ReadOnly<{| * automates measurements and allows adding new images without rebuilding the * native app. For more details visit: * - * https://reactnative.dev/docs/images.html + * http://facebook.github.io/react-native/docs/images.html * */ function nativeImageSource(spec: NativeImageSourceSpec): ImageURISource { diff --git a/Libraries/Inspector/Inspector.js b/Libraries/Inspector/Inspector.js index 2394a3dded98a1..a68160ad86dfcd 100644 --- a/Libraries/Inspector/Inspector.js +++ b/Libraries/Inspector/Inspector.js @@ -18,27 +18,14 @@ const React = require('react'); const ReactNative = require('../Renderer/shims/ReactNative'); const StyleSheet = require('../StyleSheet/StyleSheet'); const Touchable = require('../Components/Touchable/Touchable'); +const UIManager = require('../ReactNative/UIManager'); const View = require('../Components/View/View'); const invariant = require('invariant'); -import type { - HostComponent, - TouchedViewDataAtPoint, -} from '../Renderer/shims/ReactNativeTypes'; - -type HostRef = React.ElementRef>; - export type ReactRenderer = { - rendererConfig: { - getInspectorDataForViewAtPoint: ( - inspectedView: ?HostRef, - locationX: number, - locationY: number, - callback: Function, - ) => void, - ... - }, + getInspectorDataForViewTag: (viewTag: number) => Object, + ... }; const hook = window.__REACT_DEVTOOLS_GLOBAL_HOOK__; @@ -47,7 +34,7 @@ const renderers = findRenderers(); // Required for React DevTools to view/edit React Native styles in Flipper. // Flipper doesn't inject these values when initializing DevTools. hook.resolveRNStyle = require('../StyleSheet/flattenStyle'); -const viewConfig = require('../Components/View/ReactNativeViewViewConfig'); +const viewConfig = require('../Components/View/ReactNativeViewViewConfig.js'); hook.nativeStyleEditorValidAttributes = Object.keys( viewConfig.validAttributes.style, ); @@ -61,35 +48,27 @@ function findRenderers(): $ReadOnlyArray { return allRenderers; } -function getInspectorDataForViewAtPoint( - inspectedView: ?HostRef, - locationX: number, - locationY: number, - callback: (viewData: TouchedViewDataAtPoint) => void, -) { - // Check all renderers for inspector data. +function getInspectorDataForViewTag(touchedViewTag: number) { for (let i = 0; i < renderers.length; i++) { const renderer = renderers[i]; - if (renderer?.rendererConfig?.getInspectorDataForViewAtPoint != null) { - renderer.rendererConfig.getInspectorDataForViewAtPoint( - inspectedView, - locationX, - locationY, - viewData => { - // Only return with non-empty view data since only one renderer will have this view. - if (viewData && viewData.hierarchy.length > 0) { - callback(viewData); - } - }, - ); + if ( + Object.prototype.hasOwnProperty.call( + renderer, + 'getInspectorDataForViewTag', + ) + ) { + const inspectorData = renderer.getInspectorDataForViewTag(touchedViewTag); + if (inspectorData.hierarchy.length > 0) { + return inspectorData; + } } } + throw new Error('Expected to find at least one React renderer.'); } - class Inspector extends React.Component< { - inspectedView: ?HostRef, - onRequestRerenderApp: (callback: (instance: ?HostRef) => void) => void, + inspectedViewTag: ?number, + onRequestRerenderApp: (callback: (tag: ?number) => void) => void, ... }, { @@ -100,14 +79,13 @@ class Inspector extends React.Component< selection: ?number, perfing: boolean, inspected: any, - inspectedView: ?HostRef, + inspectedViewTag: any, networking: boolean, ... }, > { _hideTimeoutID: TimeoutID | null = null; _subs: ?Array<() => void>; - _setTouchedViewData: ?(TouchedViewDataAtPoint) => void; constructor(props: Object) { super(props); @@ -120,7 +98,7 @@ class Inspector extends React.Component< perfing: false, inspected: null, selection: null, - inspectedView: this.props.inspectedView, + inspectedViewTag: this.props.inspectedViewTag, networking: false, }; } @@ -138,11 +116,10 @@ class Inspector extends React.Component< this._subs.map(fn => fn()); } hook.off('react-devtools', this._attachToDevtools); - this._setTouchedViewData = null; } UNSAFE_componentWillReceiveProps(newProps: Object) { - this.setState({inspectedView: newProps.inspectedView}); + this.setState({inspectedViewTag: newProps.inspectedViewTag}); } _attachToDevtools = (agent: Object) => { @@ -170,7 +147,11 @@ class Inspector extends React.Component< _onAgentShowNativeHighlight = node => { clearTimeout(this._hideTimeoutID); - node.measure((x, y, width, height, left, top) => { + if (typeof node !== 'number') { + node = ReactNative.findNodeHandle(node); + } + + UIManager.measure(node, (x, y, width, height, left, top) => { this.setState({ hierarchy: [], inspected: { @@ -216,50 +197,30 @@ class Inspector extends React.Component< }); } - onTouchPoint(locationX: number, locationY: number) { - this._setTouchedViewData = viewData => { - const { - hierarchy, - props, - selectedIndex, - source, - frame, - pointerY, - touchedViewTag, - } = viewData; - - // Sync the touched view with React DevTools. - // Note: This is Paper only. To support Fabric, - // DevTools needs to be updated to not rely on view tags. - if (this.state.devtoolsAgent && touchedViewTag) { - this.state.devtoolsAgent.selectNode( - ReactNative.findNodeHandle(touchedViewTag), - ); - } + onTouchViewTag(touchedViewTag: number, frame: Object, pointerY: number) { + // Most likely the touched instance is a native wrapper (like RCTView) + // which is not very interesting. Most likely user wants a composite + // instance that contains it (like View) + const {hierarchy, props, selection, source} = getInspectorDataForViewTag( + touchedViewTag, + ); - this.setState({ - panelPos: - pointerY > Dimensions.get('window').height / 2 ? 'top' : 'bottom', - selection: selectedIndex, - hierarchy, - inspected: { - style: props.style, - frame, - source, - }, - }); - }; - getInspectorDataForViewAtPoint( - this.state.inspectedView, - locationX, - locationY, - viewData => { - if (this._setTouchedViewData != null) { - this._setTouchedViewData(viewData); - this._setTouchedViewData = null; - } + if (this.state.devtoolsAgent) { + // Skip host leafs + this.state.devtoolsAgent.selectNode(touchedViewTag); + } + + this.setState({ + panelPos: + pointerY > Dimensions.get('window').height / 2 ? 'top' : 'bottom', + selection, + hierarchy, + inspected: { + style: props.style, + frame, + source, }, - ); + }); } setPerfing(val: boolean) { @@ -280,8 +241,8 @@ class Inspector extends React.Component< setTouchTargeting(val: boolean) { Touchable.TOUCH_TARGET_DEBUG = val; - this.props.onRequestRerenderApp(inspectedView => { - this.setState({inspectedView}); + this.props.onRequestRerenderApp(inspectedViewTag => { + this.setState({inspectedViewTag}); }); } @@ -304,7 +265,8 @@ class Inspector extends React.Component< {this.state.inspecting && ( )} diff --git a/Libraries/Inspector/InspectorOverlay.js b/Libraries/Inspector/InspectorOverlay.js index 51a1ce55607cf8..878ee5e6ca1591 100644 --- a/Libraries/Inspector/InspectorOverlay.js +++ b/Libraries/Inspector/InspectorOverlay.js @@ -14,6 +14,7 @@ const Dimensions = require('../Utilities/Dimensions'); const ElementBox = require('./ElementBox'); const React = require('react'); const StyleSheet = require('../StyleSheet/StyleSheet'); +const UIManager = require('../ReactNative/UIManager'); const View = require('../Components/View/View'); import type {ViewStyleProp} from '../StyleSheet/StyleSheet'; @@ -26,14 +27,24 @@ type Inspected = $ReadOnly<{| type Props = $ReadOnly<{| inspected?: Inspected, - onTouchPoint: (locationX: number, locationY: number) => void, + inspectedViewTag?: ?number, + onTouchViewTag: (tag: number, frame: Object, pointerY: number) => mixed, |}>; class InspectorOverlay extends React.Component { findViewForTouchEvent: (e: PressEvent) => void = (e: PressEvent) => { const {locationX, locationY} = e.nativeEvent.touches[0]; - - this.props.onTouchPoint(locationX, locationY); + UIManager.findSubviewIn( + this.props.inspectedViewTag, + [locationX, locationY], + (nativeViewTag, left, top, width, height) => { + this.props.onTouchViewTag( + nativeViewTag, + {left, top, width, height}, + locationY, + ); + }, + ); }; shouldSetResponser: (e: PressEvent) => boolean = (e: PressEvent): boolean => { diff --git a/Libraries/LayoutAnimation/LayoutAnimation.js b/Libraries/LayoutAnimation/LayoutAnimation.js index ba4632eb712404..4cf9b0db4c4708 100644 --- a/Libraries/LayoutAnimation/LayoutAnimation.js +++ b/Libraries/LayoutAnimation/LayoutAnimation.js @@ -33,7 +33,7 @@ type AnimationConfig = $ReadOnly<{| property?: Property, |}>; -export type LayoutAnimationConfig = $ReadOnly<{| +type LayoutAnimationConfig = $ReadOnly<{| duration: number, create?: AnimationConfig, update?: AnimationConfig, diff --git a/Libraries/Linking/Linking.js b/Libraries/Linking/Linking.js index dd6fc76f152fe4..8c7dfa9b0c09d2 100644 --- a/Libraries/Linking/Linking.js +++ b/Libraries/Linking/Linking.js @@ -22,7 +22,7 @@ import NativeLinking from './NativeLinking'; * `Linking` gives you a general interface to interact with both incoming * and outgoing app links. * - * See https://reactnative.dev/docs/linking.html + * See https://facebook.github.io/react-native/docs/linking.html */ class Linking extends NativeEventEmitter { constructor() { @@ -33,7 +33,7 @@ class Linking extends NativeEventEmitter { * Add a handler to Linking changes by listening to the `url` event type * and providing the handler * - * See https://reactnative.dev/docs/linking.html#addeventlistener + * See https://facebook.github.io/react-native/docs/linking.html#addeventlistener */ addEventListener(type: string, handler: Function) { this.addListener(type, handler); @@ -42,7 +42,7 @@ class Linking extends NativeEventEmitter { /** * Remove a handler by passing the `url` event type and the handler. * - * See https://reactnative.dev/docs/linking.html#removeeventlistener + * See https://facebook.github.io/react-native/docs/linking.html#removeeventlistener */ removeEventListener(type: string, handler: Function) { this.removeListener(type, handler); @@ -51,7 +51,7 @@ class Linking extends NativeEventEmitter { /** * Try to open the given `url` with any of the installed apps. * - * See https://reactnative.dev/docs/linking.html#openurl + * See https://facebook.github.io/react-native/docs/linking.html#openurl */ openURL(url: string): Promise { this._validateURL(url); @@ -61,7 +61,7 @@ class Linking extends NativeEventEmitter { /** * Determine whether or not an installed app can handle a given URL. * - * See https://reactnative.dev/docs/linking.html#canopenurl + * See https://facebook.github.io/react-native/docs/linking.html#canopenurl */ canOpenURL(url: string): Promise { this._validateURL(url); @@ -71,7 +71,7 @@ class Linking extends NativeEventEmitter { /** * Open app settings. * - * See https://reactnative.dev/docs/linking.html#opensettings + * See https://facebook.github.io/react-native/docs/linking.html#opensettings */ openSettings(): Promise { return NativeLinking.openSettings(); @@ -81,7 +81,7 @@ class Linking extends NativeEventEmitter { * If the app launch was triggered by an app link, * it will give the link url, otherwise it will give `null` * - * See https://reactnative.dev/docs/linking.html#getinitialurl + * See https://facebook.github.io/react-native/docs/linking.html#getinitialurl */ getInitialURL(): Promise { return Platform.OS === 'android' @@ -96,7 +96,7 @@ class Linking extends NativeEventEmitter { * * @platform android * - * See https://reactnative.dev/docs/linking.html#sendintent + * See https://facebook.github.io/react-native/docs/linking.html#sendintent */ sendIntent( action: string, diff --git a/Libraries/LinkingIOS/RCTLinkingManager.mm b/Libraries/LinkingIOS/RCTLinkingManager.mm index 0f14b40d1b70d3..85b9aa7a0bd0ec 100644 --- a/Libraries/LinkingIOS/RCTLinkingManager.mm +++ b/Libraries/LinkingIOS/RCTLinkingManager.mm @@ -99,8 +99,30 @@ - (void)handleOpenURLNotification:(NSNotification *)notification resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) { - [RCTSharedApplication() openURL:URL options:@{} completionHandler:^(BOOL success) { - if (success) { + if (@available(iOS 10.0, *)) { + [RCTSharedApplication() openURL:URL options:@{} completionHandler:^(BOOL success) { + if (success) { + resolve(@YES); + } else { + #if TARGET_OS_SIMULATOR + // Simulator-specific code + if([URL.absoluteString hasPrefix:@"tel:"]){ + RCTLogWarn(@"Unable to open the Phone app in the simulator for telephone URLs. URL: %@", URL); + resolve(@NO); + } else { + reject(RCTErrorUnspecified, [NSString stringWithFormat:@"Unable to open URL: %@", URL], nil); + } + #else + // Device-specific code + reject(RCTErrorUnspecified, [NSString stringWithFormat:@"Unable to open URL: %@", URL], nil); + #endif + } + }]; + } else { +#if !TARGET_OS_UIKITFORMAC + // Note: this branch will never be taken on UIKitForMac + BOOL opened = [RCTSharedApplication() openURL:URL]; + if (opened) { resolve(@YES); } else { #if TARGET_OS_SIMULATOR @@ -116,7 +138,9 @@ - (void)handleOpenURLNotification:(NSNotification *)notification reject(RCTErrorUnspecified, [NSString stringWithFormat:@"Unable to open URL: %@", URL], nil); #endif } - }]; +#endif + } + } RCT_EXPORT_METHOD(canOpenURL:(NSURL *)URL @@ -169,13 +193,25 @@ - (void)handleOpenURLNotification:(NSNotification *)notification reject:(__unused RCTPromiseRejectBlock)reject) { NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString]; - [RCTSharedApplication() openURL:url options:@{} completionHandler:^(BOOL success) { - if (success) { - resolve(nil); - } else { - reject(RCTErrorUnspecified, @"Unable to open app settings", nil); - } - }]; + if (@available(iOS 10.0, *)) { + [RCTSharedApplication() openURL:url options:@{} completionHandler:^(BOOL success) { + if (success) { + resolve(nil); + } else { + reject(RCTErrorUnspecified, @"Unable to open app settings", nil); + } + }]; + } else { +#if !TARGET_OS_UIKITFORMAC + // Note: This branch will never be taken on UIKitForMac + BOOL opened = [RCTSharedApplication() openURL:url]; + if (opened) { + resolve(nil); + } else { + reject(RCTErrorUnspecified, @"Unable to open app settings", nil); + } +#endif + } } RCT_EXPORT_METHOD(sendIntent:(NSString *)action @@ -186,12 +222,9 @@ - (void)handleOpenURLNotification:(NSNotification *)notification RCTLogError(@"Not implemented: %@", NSStringFromSelector(_cmd)); } -- (std::shared_ptr) - getTurboModuleWithJsInvoker:(std::shared_ptr)jsInvoker - nativeInvoker:(std::shared_ptr)nativeInvoker - perfLogger:(id)perfLogger +- (std::shared_ptr)getTurboModuleWithJsInvoker:(std::shared_ptr)jsInvoker { - return std::make_shared(self, jsInvoker, nativeInvoker, perfLogger); + return std::make_shared(self, jsInvoker); } @end diff --git a/Libraries/LinkingIOS/React-RCTLinking.podspec b/Libraries/LinkingIOS/React-RCTLinking.podspec index a7748dc8bb78fd..73df19b95a1aa2 100644 --- a/Libraries/LinkingIOS/React-RCTLinking.podspec +++ b/Libraries/LinkingIOS/React-RCTLinking.podspec @@ -17,17 +17,17 @@ else end folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32' -folly_version = '2020.01.13.00' +folly_version = '2018.10.22.00' Pod::Spec.new do |s| s.name = "React-RCTLinking" s.version = version s.summary = "A general interface to interact with both incoming and outgoing app links." - s.homepage = "https://reactnative.dev/" - s.documentation_url = "https://reactnative.dev/docs/linking" + s.homepage = "http://facebook.github.io/react-native/" + s.documentation_url = "https://facebook.github.io/react-native/docs/linking" s.license = package["license"] s.author = "Facebook, Inc. and its affiliates" - s.platforms = { :ios => "10.0", :tvos => "10.0", :osx => "10.13" } # TODO(macOS GH#214) + s.platforms = { :ios => "9.0", :tvos => "9.2", :osx => "10.13" } # TODO(macOS GH#214) s.compiler_flags = folly_compiler_flags + ' -Wno-nullability-completeness' s.source = source s.source_files = "*.{m,mm}" @@ -46,5 +46,4 @@ Pod::Spec.new do |s| s.dependency "FBReactNativeSpec", version s.dependency "React-Core/RCTLinkingHeaders", version s.dependency "ReactCommon/turbomodule/core", version - s.dependency "React-jsi", version end diff --git a/Libraries/Lists/FlatList.js b/Libraries/Lists/FlatList.js index 806c69f210cf2d..808738ebd9a666 100644 --- a/Libraries/Lists/FlatList.js +++ b/Libraries/Lists/FlatList.js @@ -19,7 +19,9 @@ const StyleSheet = require('../StyleSheet/StyleSheet'); const invariant = require('invariant'); -import {type ScrollResponderType} from '../Components/ScrollView/ScrollView'; +import ScrollView, { + type ScrollResponderType, +} from '../Components/ScrollView/ScrollView'; import type {ScrollViewNativeComponentType} from '../Components/ScrollView/ScrollViewNativeComponentType.js'; import type {ViewStyleProp} from '../StyleSheet/StyleSheet'; import type { @@ -374,7 +376,14 @@ class FlatList extends React.PureComponent, void> { | ?React.ElementRef | ?React.ElementRef { if (this._listRef) { - return this._listRef.getScrollRef(); + const scrollRef = this._listRef.getScrollRef(); + if (scrollRef != null) { + if (scrollRef instanceof ScrollView) { + return scrollRef.getNativeScrollRef(); + } else { + return scrollRef; + } + } } } @@ -403,10 +412,10 @@ class FlatList extends React.PureComponent, void> { }), ); } else if (this.props.onViewableItemsChanged) { + /* $FlowFixMe(>=0.63.0 site=react_native_fb) This comment suppresses an + * error found when Flow v0.63 was deployed. To see the error delete this + * comment and run Flow. */ this._virtualizedListPairs.push({ - /* $FlowFixMe(>=0.63.0 site=react_native_fb) This comment suppresses an - * error found when Flow v0.63 was deployed. To see the error delete - * this comment and run Flow. */ viewabilityConfig: this.props.viewabilityConfig, onViewableItemsChanged: this._createOnViewableItemsChanged( this.props.onViewableItemsChanged, diff --git a/Libraries/Lists/SectionList.js b/Libraries/Lists/SectionList.js index a20d4af954d9c8..b6322986902fb9 100644 --- a/Libraries/Lists/SectionList.js +++ b/Libraries/Lists/SectionList.js @@ -27,7 +27,7 @@ export type SectionBase = _SectionBase; type RequiredProps> = {| /** - * The actual data to render, akin to the `data` prop in [``](https://reactnative.dev/docs/flatlist.html). + * The actual data to render, akin to the `data` prop in [``](/react-native/docs/flatlist.html). * * General shape: * @@ -135,7 +135,7 @@ type DefaultProps = typeof defaultProps; * - Scroll loading. * * If you don't need section support and want a simpler interface, use - * [``](https://reactnative.dev/docs/flatlist.html). + * [``](/react-native/docs/flatlist.html). * * Simple Examples: * diff --git a/Libraries/Lists/ViewabilityHelper.js b/Libraries/Lists/ViewabilityHelper.js index 48425b00707776..1ea6b880dad9fc 100644 --- a/Libraries/Lists/ViewabilityHelper.js +++ b/Libraries/Lists/ViewabilityHelper.js @@ -75,6 +75,9 @@ export type ViewabilityConfig = {| class ViewabilityHelper { _config: ViewabilityConfig; _hasInteracted: boolean = false; + /* $FlowFixMe(>=0.63.0 site=react_native_fb) This comment suppresses an error + * found when Flow v0.63 was deployed. To see the error delete this comment + * and run Flow. */ _timers: Set = new Set(); _viewableIndices: Array = []; _viewableItems: Map = new Map(); @@ -89,9 +92,6 @@ class ViewabilityHelper { * Cleanup, e.g. on unmount. Clears any pending timers. */ dispose() { - /* $FlowFixMe(>=0.63.0 site=react_native_fb) This comment suppresses an - * error found when Flow v0.63 was deployed. To see the error delete this - * comment and run Flow. */ this._timers.forEach(clearTimeout); } @@ -227,9 +227,6 @@ class ViewabilityHelper { this._viewableIndices = viewableIndices; if (this._config.minimumViewTime) { const handle = setTimeout(() => { - /* $FlowFixMe(>=0.63.0 site=react_native_fb) This comment suppresses an - * error found when Flow v0.63 was deployed. To see the error delete - * this comment and run Flow. */ this._timers.delete(handle); this._onUpdateSync( viewableIndices, @@ -237,9 +234,6 @@ class ViewabilityHelper { createViewToken, ); }, this._config.minimumViewTime); - /* $FlowFixMe(>=0.63.0 site=react_native_fb) This comment suppresses an - * error found when Flow v0.63 was deployed. To see the error delete this - * comment and run Flow. */ this._timers.add(handle); } else { this._onUpdateSync( diff --git a/Libraries/Lists/VirtualizedList.js b/Libraries/Lists/VirtualizedList.js index 240589ebd22bee..1b416d5c6158d7 100644 --- a/Libraries/Lists/VirtualizedList.js +++ b/Libraries/Lists/VirtualizedList.js @@ -373,21 +373,9 @@ type State = { ... }; -// Data propagated through nested lists (regardless of orientation) that is -// useful for producing diagnostics for usage errors involving nesting (e.g -// missing/duplicate keys). -type ListDebugInfo = { - cellKey: string, - listKey: string, - parent: ?ListDebugInfo, - // We include all ancestors regardless of orientation, so this is not always - // identical to the child's orientation. - horizontal: boolean, -}; - /** - * Base implementation for the more convenient [``](https://reactnative.dev/docs/flatlist.html) - * and [``](https://reactnative.dev/docs/sectionlist.html) components, which are also better + * Base implementation for the more convenient [``](/react-native/docs/flatlist.html) + * and [``](/react-native/docs/sectionlist.html) components, which are also better * documented. In general, this should only really be used if you need more flexibility than * `FlatList` provides, e.g. for use with immutable data instead of plain arrays. * @@ -668,10 +656,6 @@ class VirtualizedList extends React.PureComponent { getNestedChildState: React$PropType$Primitive, registerAsNestedChild: React$PropType$Primitive, unregisterAsNestedChild: React$PropType$Primitive, - debugInfo: {| - listKey: React$PropType$Primitive, - cellKey: React$PropType$Primitive, - |}, |}, |} = { virtualizedCell: PropTypes.shape({ @@ -684,10 +668,6 @@ class VirtualizedList extends React.PureComponent { getNestedChildState: PropTypes.func, registerAsNestedChild: PropTypes.func, unregisterAsNestedChild: PropTypes.func, - debugInfo: PropTypes.shape({ - listKey: PropTypes.string, - cellKey: PropTypes.string, - }), }), }; @@ -730,7 +710,6 @@ class VirtualizedList extends React.PureComponent { cellKey: string, key: string, ref: VirtualizedList, - parentDebugInfo: ListDebugInfo, ... }) => ?ChildListState, unregisterAsNestedChild: ({ @@ -738,7 +717,6 @@ class VirtualizedList extends React.PureComponent { state: ChildListState, ... }) => void, - debugInfo: ListDebugInfo, ... }, |} { @@ -750,7 +728,6 @@ class VirtualizedList extends React.PureComponent { getNestedChildState: this._getNestedChildState, registerAsNestedChild: this._registerAsNestedChild, unregisterAsNestedChild: this._unregisterAsNestedChild, - debugInfo: this._getDebugInfo(), }, }; } @@ -762,21 +739,6 @@ class VirtualizedList extends React.PureComponent { ); } - _getListKey(): string { - return this.props.listKey || this._getCellKey(); - } - - _getDebugInfo(): ListDebugInfo { - return { - listKey: this._getListKey(), - cellKey: this._getCellKey(), - horizontal: !!this.props.horizontal, - parent: this.context.virtualizedList - ? this.context.virtualizedList.debugInfo - : null, - }; - } - _getScrollMetrics = () => { return this._scrollMetrics; }; @@ -802,7 +764,6 @@ class VirtualizedList extends React.PureComponent { cellKey: string, key: string, ref: VirtualizedList, - parentDebugInfo: ListDebugInfo, ... }): ?ChildListState => { // Register the mapping between this child key and the cellKey for its cell @@ -810,18 +771,13 @@ class VirtualizedList extends React.PureComponent { this._cellKeysToChildListKeys.get(childList.cellKey) || new Set(); childListsInCell.add(childList.key); this._cellKeysToChildListKeys.set(childList.cellKey, childListsInCell); + const existingChildData = this._nestedChildLists.get(childList.key); if (existingChildData && existingChildData.ref !== null) { console.error( 'A VirtualizedList contains a cell which itself contains ' + 'more than one VirtualizedList of the same orientation as the parent ' + - 'list. You must pass a unique listKey prop to each sibling list.\n\n' + - describeNestedLists({ - ...childList, - // We're called from the child's componentDidMount, so it's safe to - // read the child's props here (albeit weird). - horizontal: !!childList.ref.props.horizontal, - }), + 'list. You must pass a unique listKey prop to each sibling list.', ); } this._nestedChildLists.set(childList.key, { @@ -893,7 +849,7 @@ class VirtualizedList extends React.PureComponent { if (this._isNestedWithSameOrientation()) { const storedState = this.context.virtualizedList.getNestedChildState( - this._getListKey(), + this.props.listKey || this._getCellKey(), ); if (storedState) { initialState = storedState; @@ -909,13 +865,8 @@ class VirtualizedList extends React.PureComponent { if (this._isNestedWithSameOrientation()) { this.context.virtualizedList.registerAsNestedChild({ cellKey: this._getCellKey(), - key: this._getListKey(), + key: this.props.listKey || this._getCellKey(), ref: this, - // NOTE: When the child mounts (here) it's not necessarily safe to read - // the parent's props. This is why we explicitly propagate debugInfo - // "down" via context and "up" again via this method call on the - // parent. - parentDebugInfo: this.context.virtualizedList.debugInfo, }); } } @@ -923,7 +874,7 @@ class VirtualizedList extends React.PureComponent { componentWillUnmount() { if (this._isNestedWithSameOrientation()) { this.context.virtualizedList.unregisterAsNestedChild({ - key: this._getListKey(), + key: this.props.listKey || this._getCellKey(), state: { first: this.state.first, last: this.state.last, @@ -1222,7 +1173,7 @@ class VirtualizedList extends React.PureComponent { ); cells.push( { this._frames[cellKey].inLayout = true; } - this._triggerRemeasureForChildListsInCell(cellKey); + const childListKeys = this._cellKeysToChildListKeys.get(cellKey); + if (childListKeys) { + for (let childKey of childListKeys) { + const childList = this._nestedChildLists.get(childKey); + childList && + childList.ref && + childList.ref.measureLayoutRelativeToContainingList(); + } + } this._computeBlankness(); this._updateViewableItems(this.props.data); @@ -1480,18 +1439,6 @@ class VirtualizedList extends React.PureComponent { } }; - _triggerRemeasureForChildListsInCell(cellKey: string): void { - const childListKeys = this._cellKeysToChildListKeys.get(cellKey); - if (childListKeys) { - for (let childKey of childListKeys) { - const childList = this._nestedChildLists.get(childKey); - childList && - childList.ref && - childList.ref.measureLayoutRelativeToContainingList(); - } - } - } - measureLayoutRelativeToContainingList(): void { // TODO (T35574538): findNodeHandle sometimes crashes with "Unable to find // node on an unmounted component" during scrolling @@ -1502,7 +1449,10 @@ class VirtualizedList extends React.PureComponent { // We are assuming that getOutermostParentListRef().getScrollRef() // is a non-null reference to a ScrollView this._scrollRef.measureLayout( - this.context.virtualizedList.getOutermostParentListRef().getScrollRef(), + this.context.virtualizedList + .getOutermostParentListRef() + .getScrollRef() + .getNativeScrollRef(), (x, y, width, height) => { this._offsetFromParentVirtualizedList = this._selectOffset({x, y}); this._scrollMetrics.contentLength = this._selectLength({ @@ -1549,12 +1499,7 @@ class VirtualizedList extends React.PureComponent { this.props.onLayout && this.props.onLayout(e); }; - _getFooterCellKey(): string { - return this._getCellKey() + '-footer'; - } - _onLayoutFooter = e => { - this._triggerRemeasureForChildListsInCell(this._getFooterCellKey()); this._footerLength = this._selectLength(e.nativeEvent.layout); }; @@ -1950,13 +1895,12 @@ class VirtualizedList extends React.PureComponent { } this.setState(state => { let newState; - const {contentLength, offset, visibleLength} = this._scrollMetrics; if (!isVirtualizationDisabled) { // If we run this with bogus data, we'll force-render window {first: 0, last: 0}, // and wipe out the initialNumToRender rendered elements. // So let's wait until the scroll view metrics have been set up. And until then, // we will trust the initialNumToRender suggestion - if (visibleLength > 0 && contentLength > 0) { + if (this._scrollMetrics.visibleLength) { // If we have a non-zero initialScrollIndex and run this before we've scrolled, // we'll wipe out the initialNumToRender rendered elements starting at initialScrollIndex. // So let's wait until we've scrolled the view to the right place. And until then, @@ -1971,6 +1915,7 @@ class VirtualizedList extends React.PureComponent { } } } else { + const {contentLength, offset, visibleLength} = this._scrollMetrics; const distanceFromEnd = contentLength - visibleLength - offset; const renderAhead = /* $FlowFixMe(>=0.63.0 site=react_native_fb) This comment suppresses @@ -2014,13 +1959,6 @@ class VirtualizedList extends React.PureComponent { } } } - if ( - newState != null && - newState.first === state.first && - newState.last === state.last - ) { - newState = null; - } return newState; }); }; @@ -2357,31 +2295,6 @@ class VirtualizedCellWrapper extends React.Component<{ } } -function describeNestedLists(childList: { - +cellKey: string, - +key: string, - +ref: VirtualizedList, - +parentDebugInfo: ListDebugInfo, - +horizontal: boolean, - ... -}) { - let trace = - 'VirtualizedList trace:\n' + - ` Child (${childList.horizontal ? 'horizontal' : 'vertical'}):\n` + - ` listKey: ${childList.key}\n` + - ` cellKey: ${childList.cellKey}`; - - let debugInfo = childList.parentDebugInfo; - while (debugInfo) { - trace += - `\n Parent (${debugInfo.horizontal ? 'horizontal' : 'vertical'}):\n` + - ` listKey: ${debugInfo.listKey}\n` + - ` cellKey: ${debugInfo.cellKey}`; - debugInfo = debugInfo.parent; - } - return trace; -} - const styles = StyleSheet.create({ verticallyInverted: { transform: [{scaleY: -1}], diff --git a/Libraries/Lists/__flowtests__/FlatList-flowtest.js b/Libraries/Lists/__flowtests__/FlatList-flowtest.js index 912289cbf0043d..5be4c1eebcd22a 100644 --- a/Libraries/Lists/__flowtests__/FlatList-flowtest.js +++ b/Libraries/Lists/__flowtests__/FlatList-flowtest.js @@ -35,11 +35,11 @@ module.exports = { testBadDataWithTypicalItem(): React.Node { const data = [ { + // $FlowExpectedError - bad title type 6, should be string title: 6, key: 1, }, ]; - // $FlowExpectedError - bad title type 6, should be string return ; }, @@ -97,7 +97,6 @@ module.exports = { />, // EverythingIsFine } data={data} />, diff --git a/Libraries/Lists/__flowtests__/SectionList-flowtest.js b/Libraries/Lists/__flowtests__/SectionList-flowtest.js index 9425bacd5cf8a5..79a92a88a39098 100644 --- a/Libraries/Lists/__flowtests__/SectionList-flowtest.js +++ b/Libraries/Lists/__flowtests__/SectionList-flowtest.js @@ -57,8 +57,8 @@ module.exports = { }, ]; return [ + // $FlowExpectedError - title should be inside `item` } sections={sections} />, @@ -94,6 +94,9 @@ module.exports = { testBadSectionsShape(): React.Element<*> { const sections = [ + /* $FlowFixMe(>=0.63.0 site=react_native_fb) This comment suppresses an + * error found when Flow v0.63 was deployed. To see the error delete this + * comment and run Flow. */ { key: 'a', items: [ @@ -112,6 +115,7 @@ module.exports = { const sections = [ { key: 'a', + // $FlowExpectedError - section has bad meta data `fooNumber` field of type string fooNumber: 'string', data: [ { @@ -125,8 +129,6 @@ module.exports = { ); diff --git a/Libraries/Lists/__tests__/VirtualizedList-test.js b/Libraries/Lists/__tests__/VirtualizedList-test.js index e99215a2d867d1..5cee6bca2cbcdc 100644 --- a/Libraries/Lists/__tests__/VirtualizedList-test.js +++ b/Libraries/Lists/__tests__/VirtualizedList-test.js @@ -69,12 +69,11 @@ describe('VirtualizedList', () => { it('throws if no renderItem or ListItemComponent', () => { // Silence the React error boundary warning; we expect an uncaught error. - const consoleError = console.error; jest.spyOn(console, 'error').mockImplementation(message => { if (message.startsWith('The above error occured in the ')) { return; } - consoleError(message); + console.errorDebug(message); }); const componentFactory = () => @@ -300,7 +299,7 @@ describe('VirtualizedList', () => { // This is checking if the ref acts like a ScrollView. If we had an // `isScrollView(ref)` method, that would be preferred. - expect(scrollRef.scrollTo).toBeInstanceOf(jest.fn().constructor); + expect(scrollRef.scrollTo).toBeInstanceOf(Function); }); it('getScrollRef for case where it returns a View', () => { @@ -335,125 +334,4 @@ describe('VirtualizedList', () => { expect(scrollRef.measureLayout).toBeInstanceOf(jest.fn().constructor); expect(scrollRef.measureInWindow).toBeInstanceOf(jest.fn().constructor); }); - it('does not call onEndReached when onContentSizeChange happens after onLayout', () => { - const ITEM_HEIGHT = 40; - const layout = {width: 300, height: 600}; - let data = Array(20) - .fill() - .map((_, key) => ({key: String(key)})); - const onEndReached = jest.fn(); - const props = { - data, - initialNumToRender: 10, - onEndReachedThreshold: 2, - windowSize: 21, - renderItem: ({item}) => , - getItem: (items, index) => items[index], - getItemCount: items => items.length, - getItemLayout: (items, index) => ({ - length: ITEM_HEIGHT, - offset: ITEM_HEIGHT * index, - index, - }), - onEndReached, - }; - - const component = ReactTestRenderer.create(); - - const instance = component.getInstance(); - - instance._onLayout({nativeEvent: {layout}}); - - const initialContentHeight = props.initialNumToRender * ITEM_HEIGHT; - - // We want to test the unusual case of onContentSizeChange firing after - // onLayout, which can cause https://github.com/facebook/react-native/issues/16067 - instance._onContentSizeChange(300, initialContentHeight); - instance._onContentSizeChange(300, data.length * ITEM_HEIGHT); - jest.runAllTimers(); - - expect(onEndReached).not.toHaveBeenCalled(); - - instance._onScroll({ - timeStamp: 1000, - nativeEvent: { - contentOffset: {y: initialContentHeight, x: 0}, - layoutMeasurement: layout, - contentSize: {...layout, height: data.length * ITEM_HEIGHT}, - zoomScale: 1, - contentInset: {right: 0, top: 0, left: 0, bottom: 0}, - }, - }); - jest.runAllTimers(); - - expect(onEndReached).toHaveBeenCalled(); - }); - - it('provides a trace when a listKey collision occurs', () => { - const errors = []; - jest.spyOn(console, 'error').mockImplementation((...args) => { - // Silence the DEV-only React error boundary warning. - if ((args[0] || '').startsWith('The above error occured in the ')) { - return; - } - errors.push(args); - }); - const commonProps = { - data: [{key: 'cell0'}], - getItem: (data, index) => data[index], - getItemCount: data => data.length, - renderItem: ({item}) => , - }; - try { - ReactTestRenderer.create( - ( - ( - <> - {/* Force a collision */} - - - - )} - /> - )} - />, - ); - expect(errors).toMatchInlineSnapshot(` - Array [ - Array [ - "A VirtualizedList contains a cell which itself contains more than one VirtualizedList of the same orientation as the parent list. You must pass a unique listKey prop to each sibling list. - - VirtualizedList trace: - Child (horizontal): - listKey: level2 - cellKey: cell0 - Parent (horizontal): - listKey: level1 - cellKey: cell0 - Parent (vertical): - listKey: level0 - cellKey: rootList", - ], - ] - `); - } finally { - console.error.mockRestore(); - } - }); }); diff --git a/Libraries/LogBox/Data/LogBoxData.js b/Libraries/LogBox/Data/LogBoxData.js index 1076d26661f448..83e64356facc75 100644 --- a/Libraries/LogBox/Data/LogBoxData.js +++ b/Libraries/LogBox/Data/LogBoxData.js @@ -60,7 +60,6 @@ export type WarningFilter = (format: string) => WarningInfo; type AppInfo = $ReadOnly<{| appVersion: string, engine: string, - onPress?: ?() => void, |}>; const observers: Set<{observer: Observer, ...}> = new Set(); diff --git a/Libraries/LogBox/Data/LogBoxLog.js b/Libraries/LogBox/Data/LogBoxLog.js index 2d019518306d76..f2f64f5647585e 100644 --- a/Libraries/LogBox/Data/LogBoxLog.js +++ b/Libraries/LogBox/Data/LogBoxLog.js @@ -26,7 +26,6 @@ export type LogLevel = 'warn' | 'error' | 'fatal' | 'syntax'; export type LogBoxLogData = $ReadOnly<{| level: LogLevel, - type?: ?string, message: Message, stack: Stack, category: string, @@ -37,7 +36,6 @@ export type LogBoxLogData = $ReadOnly<{| class LogBoxLog { message: Message; - type: ?string; category: Category; componentStack: ComponentStack; stack: Stack; @@ -57,7 +55,6 @@ class LogBoxLog { constructor(data: LogBoxLogData) { this.level = data.level; - this.type = data.type; this.message = data.message; this.stack = data.stack; this.category = data.category; diff --git a/Libraries/LogBox/Data/__tests__/parseLogBoxLog-test.js b/Libraries/LogBox/Data/__tests__/parseLogBoxLog-test.js index 30c489a3445a49..f4025dcc176d06 100644 --- a/Libraries/LogBox/Data/__tests__/parseLogBoxLog-test.js +++ b/Libraries/LogBox/Data/__tests__/parseLogBoxLog-test.js @@ -143,32 +143,6 @@ describe('parseLogBoxLog', () => { }); }); - it('detects a component stack in the first argument', () => { - expect( - parseLogBoxLog([ - 'Some kind of message\n in MyComponent (at filename.js:1)\n in MyOtherComponent (at filename2.js:1)', - ]), - ).toEqual({ - componentStack: [ - { - content: 'MyComponent', - fileName: 'filename.js', - location: {column: -1, row: 1}, - }, - { - content: 'MyOtherComponent', - fileName: 'filename2.js', - location: {column: -1, row: 1}, - }, - ], - category: 'Some kind of message', - message: { - content: 'Some kind of message', - substitutions: [], - }, - }); - }); - it('detects a component stack in the second argument', () => { expect( parseLogBoxLog([ @@ -298,74 +272,6 @@ describe('parseLogBoxLog', () => { }); }); - it('parses an invalid require syntax error', () => { - const error = { - message: `Unable to resolve module \`ListCellx\` from /path/to/file.js: ListCellx could not be found within the project. - -If you are sure the module exists, try these steps: - 1. Clear watchman watches: watchman watch-del-all - 2. Delete node_modules and run yarn install - 3. Reset Metro's cache: yarn start --reset-cache - 4. Remove the cache: rm -rf /tmp/metro-* -\u001b[0m \u001b[90m 10 | \u001b[39m\u001b[36mimport\u001b[39m \u001b[33mColor\u001b[39m from \u001b[32m'Color'\u001b[39m\u001b[33m;\u001b[39m\u001b[0m -\u001b[0m \u001b[90m 11 | \u001b[39m\u001b[36mimport\u001b[39m \u001b[33mList\u001b[39m from \u001b[32m'List'\u001b[39m\u001b[33m;\u001b[39m\u001b[0m -\u001b[0m\u001b[31m\u001b[1m>\u001b[22m\u001b[39m\u001b[90m 12 | \u001b[39m\u001b[36mimport\u001b[39m \u001b[33mListCell\u001b[39m from \u001b[32m'ListCellx'\u001b[39m\u001b[33m;\u001b[39m\u001b[0m -\u001b[0m \u001b[90m | \u001b[39m \u001b[31m\u001b[1m^\u001b[22m\u001b[39m\u001b[0m -\u001b[0m \u001b[90m 13 | \u001b[39m\u001b[36mimport\u001b[39m \u001b[33mNullState\u001b[39m from \u001b[32m'NullState'\u001b[39m\u001b[33m;\u001b[39m\u001b[0m -\u001b[0m \u001b[90m 14 | \u001b[39m\u001b[36mimport\u001b[39m \u001b[33mUnitHeader\u001b[39m from \u001b[32m'UnitHeader'\u001b[39m\u001b[33m;\u001b[39m\u001b[0m -\u001b[0m \u001b[90m 15 | \u001b[39m\u001b[36mimport\u001b[39m fbRemoteAsset from \u001b[32m'fbRemoteAsset'\u001b[39m\u001b[33m;\u001b[39m\u001b[0m`, - originalMessage: `Unable to resolve module \`ListCellx\` from /path/to/file.js: ListCellx could not be found within the project. - -If you are sure the module exists, try these steps: - 1. Clear watchman watches: watchman watch-del-all - 2. Delete node_modules and run yarn install - 3. Reset Metro's cache: yarn start --reset-cache - 4. Remove the cache: rm -rf /tmp/metro-* -\u001b[0m \u001b[90m 10 | \u001b[39m\u001b[36mimport\u001b[39m \u001b[33mColor\u001b[39m from \u001b[32m'Color'\u001b[39m\u001b[33m;\u001b[39m\u001b[0m -\u001b[0m \u001b[90m 11 | \u001b[39m\u001b[36mimport\u001b[39m \u001b[33mList\u001b[39m from \u001b[32m'List'\u001b[39m\u001b[33m;\u001b[39m\u001b[0m -\u001b[0m\u001b[31m\u001b[1m>\u001b[22m\u001b[39m\u001b[90m 12 | \u001b[39m\u001b[36mimport\u001b[39m \u001b[33mListCell\u001b[39m from \u001b[32m'ListCellx'\u001b[39m\u001b[33m;\u001b[39m\u001b[0m -\u001b[0m \u001b[90m | \u001b[39m \u001b[31m\u001b[1m^\u001b[22m\u001b[39m\u001b[0m -\u001b[0m \u001b[90m 13 | \u001b[39m\u001b[36mimport\u001b[39m \u001b[33mNullState\u001b[39m from \u001b[32m'NullState'\u001b[39m\u001b[33m;\u001b[39m\u001b[0m -\u001b[0m \u001b[90m 14 | \u001b[39m\u001b[36mimport\u001b[39m \u001b[33mUnitHeader\u001b[39m from \u001b[32m'UnitHeader'\u001b[39m\u001b[33m;\u001b[39m\u001b[0m -\u001b[0m \u001b[90m 15 | \u001b[39m\u001b[36mimport\u001b[39m fbRemoteAsset from \u001b[32m'fbRemoteAsset'\u001b[39m\u001b[33m;\u001b[39m\u001b[0m`, - name: '', - isComponentError: false, - componentStack: '', - stack: [], - id: 0, - isFatal: true, - }; - - expect(parseLogBoxException(error)).toEqual({ - level: 'syntax', - isComponentError: false, - codeFrame: { - fileName: '/path/to/file.js', - location: null, - content: `\u001b[0m \u001b[90m 10 | \u001b[39m\u001b[36mimport\u001b[39m \u001b[33mColor\u001b[39m from \u001b[32m'Color'\u001b[39m\u001b[33m;\u001b[39m\u001b[0m -\u001b[0m \u001b[90m 11 | \u001b[39m\u001b[36mimport\u001b[39m \u001b[33mList\u001b[39m from \u001b[32m'List'\u001b[39m\u001b[33m;\u001b[39m\u001b[0m -\u001b[0m\u001b[31m\u001b[1m>\u001b[22m\u001b[39m\u001b[90m 12 | \u001b[39m\u001b[36mimport\u001b[39m \u001b[33mListCell\u001b[39m from \u001b[32m'ListCellx'\u001b[39m\u001b[33m;\u001b[39m\u001b[0m -\u001b[0m \u001b[90m | \u001b[39m \u001b[31m\u001b[1m^\u001b[22m\u001b[39m\u001b[0m -\u001b[0m \u001b[90m 13 | \u001b[39m\u001b[36mimport\u001b[39m \u001b[33mNullState\u001b[39m from \u001b[32m'NullState'\u001b[39m\u001b[33m;\u001b[39m\u001b[0m -\u001b[0m \u001b[90m 14 | \u001b[39m\u001b[36mimport\u001b[39m \u001b[33mUnitHeader\u001b[39m from \u001b[32m'UnitHeader'\u001b[39m\u001b[33m;\u001b[39m\u001b[0m -\u001b[0m \u001b[90m 15 | \u001b[39m\u001b[36mimport\u001b[39m fbRemoteAsset from \u001b[32m'fbRemoteAsset'\u001b[39m\u001b[33m;\u001b[39m\u001b[0m`, - }, - message: { - content: `ListCellx could not be found within the project. - -If you are sure the module exists, try these steps: - 1. Clear watchman watches: watchman watch-del-all - 2. Delete node_modules and run yarn install - 3. Reset Metro's cache: yarn start --reset-cache - 4. Remove the cache: rm -rf /tmp/metro-*`, - substitutions: [], - }, - stack: [], - componentStack: [], - category: '/path/to/file.js-1-1', - }); - }); - it('parses a reference error', () => { const error = { message: ` @@ -505,7 +411,7 @@ Please follow the instructions at: fburl.com/rn-remote-assets`, }); }); - it('parses an error log with `error.componentStack`', () => { + it('parses a error log', () => { const error = { id: 0, isFatal: false, @@ -558,59 +464,6 @@ Please follow the instructions at: fburl.com/rn-remote-assets`, }); }); - it('parses an error log with a component stack in the message', () => { - const error = { - id: 0, - isFatal: false, - isComponentError: false, - message: - 'Some kind of message\n in MyComponent (at filename.js:1)\n in MyOtherComponent (at filename2.js:1)', - originalMessage: - 'Some kind of message\n in MyComponent (at filename.js:1)\n in MyOtherComponent (at filename2.js:1)', - name: '', - componentStack: null, - stack: [ - { - column: 1, - file: 'foo.js', - lineNumber: 1, - methodName: 'bar', - collapse: false, - }, - ], - }; - expect(parseLogBoxException(error)).toEqual({ - level: 'error', - isComponentError: false, - stack: [ - { - collapse: false, - column: 1, - file: 'foo.js', - lineNumber: 1, - methodName: 'bar', - }, - ], - componentStack: [ - { - content: 'MyComponent', - fileName: 'filename.js', - location: {column: -1, row: 1}, - }, - { - content: 'MyOtherComponent', - fileName: 'filename2.js', - location: {column: -1, row: 1}, - }, - ], - category: 'Some kind of message', - message: { - content: 'Some kind of message', - substitutions: [], - }, - }); - }); - it('parses a fatal exception', () => { const error = { id: 0, diff --git a/Libraries/LogBox/Data/parseLogBoxLog.js b/Libraries/LogBox/Data/parseLogBoxLog.js index 0d7c83d3755270..a65bd5d531ee51 100644 --- a/Libraries/LogBox/Data/parseLogBoxLog.js +++ b/Libraries/LogBox/Data/parseLogBoxLog.js @@ -16,8 +16,7 @@ import type {ExceptionData} from '../../Core/NativeExceptionsManager'; import type {LogBoxLogData} from './LogBoxLog'; const BABEL_TRANSFORM_ERROR_FORMAT = /^(?:TransformError )?(?:SyntaxError: |ReferenceError: )(.*): (.*) \((\d+):(\d+)\)\n\n([\s\S]+)/; -const BABEL_CODE_FRAME_ERROR_FORMAT = /^(?:TransformError )?(?:.*):? (?:.*?)(\/.*): ([\s\S]+?)\n([ >]{2}[\d\s]+ \|[\s\S]+|\u{001b}[\s\S]+)/u; -const METRO_ERROR_FORMAT = /^(?:InternalError Metro has encountered an error:) (.*): (.*) \((\d+):(\d+)\)\n\n([\s\S]+)/u; +const BABEL_CODE_FRAME_ERROR_FORMAT = /^(?:TransformError )?(?:.*): (.*): ([\s\S]+?)\n([ >]{2}[\d\s]+ \|[\s\S]+|\u{001b}[\s\S]+)/u; export type ExtendedExceptionData = ExceptionData & { isComponentError: boolean, @@ -47,7 +46,7 @@ export type ComponentStack = $ReadOnlyArray; const SUBSTITUTION = UTFSequence.BOM + '%s'; -export function parseInterpolation( +export function parseCategory( args: $ReadOnlyArray, ): $ReadOnly<{| category: Category, @@ -152,38 +151,6 @@ export function parseLogBoxException( const message = error.originalMessage != null ? error.originalMessage : 'Unknown'; - const metroInternalError = message.match(METRO_ERROR_FORMAT); - if (metroInternalError) { - const [ - content, - fileName, - row, - column, - codeFrame, - ] = metroInternalError.slice(1); - - return { - level: 'fatal', - type: 'Metro Error', - stack: [], - isComponentError: false, - componentStack: [], - codeFrame: { - fileName, - location: { - row: parseInt(row, 10), - column: parseInt(column, 10), - }, - content: codeFrame, - }, - message: { - content, - substitutions: [], - }, - category: `${fileName}-${row}-${column}`, - }; - } - const babelTransformError = message.match(BABEL_TRANSFORM_ERROR_FORMAT); if (babelTransformError) { // Transform errors are thrown from inside the Babel transformer. @@ -239,50 +206,21 @@ export function parseLogBoxException( }; } - if (message.match(/^TransformError /)) { - return { - level: 'syntax', - stack: error.stack, - isComponentError: error.isComponentError, - componentStack: [], - message: { - content: message, - substitutions: [], - }, - category: message, - }; - } - - const componentStack = error.componentStack; - if (error.isFatal || error.isComponentError) { - return { - level: 'fatal', - stack: error.stack, - isComponentError: error.isComponentError, - componentStack: - componentStack != null ? parseComponentStack(componentStack) : [], - ...parseInterpolation([message]), - }; - } + const level = message.match(/^TransformError /) + ? 'syntax' + : error.isFatal || error.isComponentError + ? 'fatal' + : 'error'; - if (componentStack != null) { - // It is possible that console errors have a componentStack. - return { - level: 'error', - stack: error.stack, - isComponentError: error.isComponentError, - componentStack: parseComponentStack(componentStack), - ...parseInterpolation([message]), - }; - } - - // Most `console.error` calls won't have a componentStack. We parse them like - // regular logs which have the component stack burried in the message. return { - level: 'error', + level: level, stack: error.stack, isComponentError: error.isComponentError, - ...parseLogBoxLog([message]), + componentStack: + error.componentStack != null + ? parseComponentStack(error.componentStack) + : [], + ...parseCategory([message]), }; } @@ -315,13 +253,7 @@ export function parseLogBoxLog( if (componentStack.length === 0) { // Try finding the component stack elsewhere. for (const arg of args) { - if (typeof arg === 'string' && /\n {4}in /.exec(arg)) { - // Strip out any messages before the component stack. - const messageEndIndex = arg.indexOf('\n in '); - if (messageEndIndex > 0) { - argsWithoutComponentStack.push(arg.slice(0, messageEndIndex)); - } - + if (typeof arg === 'string' && /^\n {4}in/.exec(arg)) { componentStack = parseComponentStack(arg); } else { argsWithoutComponentStack.push(arg); @@ -330,7 +262,7 @@ export function parseLogBoxLog( } return { - ...parseInterpolation(argsWithoutComponentStack), + ...parseCategory(argsWithoutComponentStack), componentStack, }; } diff --git a/Libraries/LogBox/LogBox.js b/Libraries/LogBox/LogBox.js index 913dfa8daa3e58..b231b9396ad184 100644 --- a/Libraries/LogBox/LogBox.js +++ b/Libraries/LogBox/LogBox.js @@ -13,7 +13,7 @@ import Platform from '../Utilities/Platform'; import RCTLog from '../Utilities/RCTLog'; import * as LogBoxData from './Data/LogBoxData'; -import {parseLogBoxLog, parseInterpolation} from './Data/parseLogBoxLog'; +import {parseLogBoxLog} from './Data/parseLogBoxLog'; import type {IgnorePattern} from './Data/LogBoxData'; @@ -37,12 +37,13 @@ if (__DEV__) { }; LogBox = { - ignoreLogs: (patterns: $ReadOnlyArray): void => { - LogBoxData.addIgnorePatterns(patterns); + // TODO: deprecated, replace with ignoreLogs + ignoreWarnings: (patterns: $ReadOnlyArray): void => { + LogBox.ignoreLogs(patterns); }, - ignoreAllLogs: (value?: ?boolean): void => { - LogBoxData.setDisabled(value == null ? true : value); + ignoreLogs: (patterns: $ReadOnlyArray): void => { + LogBoxData.addIgnorePatterns(patterns); }, uninstall: (): void => { @@ -63,26 +64,18 @@ if (__DEV__) { registerWarning(...args); }; - if ((console: any).disableYellowBox === true) { + if ((console: any).disableLogBox === true) { LogBoxData.setDisabled(true); - console.warn( - 'console.disableYellowBox has been deprecated and will be removed in a future release. Please use LogBox.ignoreAllLogs(value) instead.', - ); } - (Object.defineProperty: any)(console, 'disableYellowBox', { + (Object.defineProperty: any)(console, 'disableLogBox', { configurable: true, get: () => LogBoxData.isDisabled(), - set: value => { - LogBoxData.setDisabled(value); - console.warn( - 'console.disableYellowBox has been deprecated and will be removed in a future release. Please use LogBox.ignoreAllLogs(value) instead.', - ); - }, + set: value => LogBoxData.setDisabled(value), }); if (Platform.isTesting) { - LogBoxData.setDisabled(true); + (console: any).disableLogBox = true; } RCTLog.setWarningHandler((...args) => { @@ -102,12 +95,6 @@ if (__DEV__) { }; const registerWarning = (...args): void => { - // Let warnings within LogBox itself fall through. - if (LogBoxData.isLogBoxErrorMessage(String(args[0]))) { - error.call(console, ...args); - return; - } - try { if (!isRCTLogAdviceWarning(...args)) { const {category, message, componentStack} = parseLogBoxLog(args); @@ -116,12 +103,14 @@ if (__DEV__) { // Be sure to pass LogBox warnings through. warn.call(console, ...args); - LogBoxData.addLog({ - level: 'warn', - category, - message, - componentStack, - }); + if (!LogBoxData.isLogBoxErrorMessage(message.content)) { + LogBoxData.addLog({ + level: 'warn', + category, + message, + componentStack, + }); + } } } } catch (err) { @@ -130,21 +119,9 @@ if (__DEV__) { }; const registerError = (...args): void => { - // Let errors within LogBox itself fall through. - if (LogBoxData.isLogBoxErrorMessage(args[0])) { - error.call(console, ...args); - return; - } - try { if (!isWarningModuleWarning(...args)) { - // Only show LogBox for the 'warning' module, otherwise pass through. - // By passing through, this will get picked up by the React console override, - // potentially adding the component stack. React then passes it back to the - // React Native ExceptionsManager, which reports it to LogBox as an error. - // - // The 'warning' module needs to be handled here because React internally calls - // `console.error('Warning: ')` with the component stack already included. + // Only show LogBox for the `warning` module, otherwise pass through and skip. error.call(console, ...args); return; } @@ -167,17 +144,17 @@ if (__DEV__) { const {category, message, componentStack} = parseLogBoxLog(args); if (!LogBoxData.isMessageIgnored(message.content)) { - // Interpolate the message so they are formatted for adb and other CLIs. - // This is different than the message.content above because it includes component stacks. - const interpolated = parseInterpolation(args); - error.call(console, interpolated.message.content); - - LogBoxData.addLog({ - level, - category, - message, - componentStack, - }); + // Be sure to pass LogBox errors through. + error.call(console, ...args); + + if (!LogBoxData.isLogBoxErrorMessage(message.content)) { + LogBoxData.addLog({ + level, + category, + message, + componentStack, + }); + } } } catch (err) { LogBoxData.reportLogBoxError(err); @@ -185,11 +162,12 @@ if (__DEV__) { }; } else { LogBox = { - ignoreLogs: (patterns: $ReadOnlyArray): void => { + // TODO: deprecated, replace with ignoreLogs + ignoreWarnings: (patterns: $ReadOnlyArray): void => { // Do nothing. }, - ignoreAllLogs: (value?: ?boolean): void => { + ignoreLogs: (patterns: $ReadOnlyArray): void => { // Do nothing. }, @@ -204,8 +182,9 @@ if (__DEV__) { } module.exports = (LogBox: { + // TODO: deprecated, replace with ignoreLogs + ignoreWarnings($ReadOnlyArray): void, ignoreLogs($ReadOnlyArray): void, - ignoreAllLogs(?boolean): void, install(): void, uninstall(): void, ... diff --git a/Libraries/LogBox/UI/AnsiHighlight.js b/Libraries/LogBox/UI/AnsiHighlight.js index 101b14258264b2..616a88ca47a61e 100644 --- a/Libraries/LogBox/UI/AnsiHighlight.js +++ b/Libraries/LogBox/UI/AnsiHighlight.js @@ -58,7 +58,7 @@ export default function Ansi({ // We are looking for the least amount of common whitespace to trim all lines. // Example: Array [" ", " 96 |", " text", ...] const match = lines[2] && lines[2]?.content?.match(/^ +/); - const whitespaceLength = (match && match[0]?.length) || 0; + const whitespaceLength = (match && match[0]?.length) || Infinity; if (whitespaceLength < commonWhitespaceLength) { commonWhitespaceLength = whitespaceLength; } diff --git a/Libraries/LogBox/UI/LogBoxInspector.js b/Libraries/LogBox/UI/LogBoxInspector.js index 9c2983264b04b7..62900e5b47ca2d 100644 --- a/Libraries/LogBox/UI/LogBoxInspector.js +++ b/Libraries/LogBox/UI/LogBoxInspector.js @@ -102,7 +102,6 @@ function LogBoxInspectorBody(props) { }, [props.log]); const headerTitle = - props.log.type ?? headerTitleMap[props.log.isComponentError ? 'component' : props.log.level]; if (collapsed) { diff --git a/Libraries/LogBox/UI/LogBoxInspectorCodeFrame.js b/Libraries/LogBox/UI/LogBoxInspectorCodeFrame.js index 2c4e1036a17761..b9e8f483c1dd31 100644 --- a/Libraries/LogBox/UI/LogBoxInspectorCodeFrame.js +++ b/Libraries/LogBox/UI/LogBoxInspectorCodeFrame.js @@ -87,19 +87,9 @@ function AppInfo() { } return ( - - - {appInfo.appVersion} ({appInfo.engine}) - - + + {appInfo.appVersion} ({appInfo.engine}) + ); } @@ -108,14 +98,8 @@ const appInfoStyles = StyleSheet.create({ color: LogBoxStyle.getTextColor(0.4), fontSize: 12, lineHeight: 12, - }, - buildButton: { flex: 0, flexGrow: 0, - paddingVertical: 4, - paddingHorizontal: 5, - borderRadius: 5, - marginRight: -8, }, }); diff --git a/Libraries/LogBox/UI/LogBoxInspectorSourceMapStatus.js b/Libraries/LogBox/UI/LogBoxInspectorSourceMapStatus.js index 3ca8ebfcd9e105..88ee3374bde603 100644 --- a/Libraries/LogBox/UI/LogBoxInspectorSourceMapStatus.js +++ b/Libraries/LogBox/UI/LogBoxInspectorSourceMapStatus.js @@ -47,9 +47,6 @@ function LogBoxInspectorSourceMapStatus(props: Props): React.Node { animation, rotate: animated.interpolate({ inputRange: [0, 1], - /* $FlowFixMe(>=0.38.0) - Flow error detected during the deployment - * of v0.38.0. To see the error, remove this comment and run flow - */ outputRange: ['0deg', '360deg'], }), }); diff --git a/Libraries/LogBox/UI/LogBoxNotification.js b/Libraries/LogBox/UI/LogBoxNotification.js index 26264ecb5e1cb7..bb668d391e63c6 100644 --- a/Libraries/LogBox/UI/LogBoxNotification.js +++ b/Libraries/LogBox/UI/LogBoxNotification.js @@ -59,8 +59,6 @@ function LogBoxLogNotification(props: Props): React.Node { function CountBadge(props) { return ( - {/* $FlowFixMe(>=0.114.0) This suppression was added when fixing the type - * of `StyleSheet.create`. Remove this comment to see the error. */} {props.count <= 1 ? '!' : props.count} diff --git a/Libraries/LogBox/UI/__tests__/__snapshots__/LogBoxInspector-test.js.snap b/Libraries/LogBox/UI/__tests__/__snapshots__/LogBoxInspector-test.js.snap index 8259c01b67d4ff..3a8b8b933c4d29 100644 --- a/Libraries/LogBox/UI/__tests__/__snapshots__/LogBoxInspector-test.js.snap +++ b/Libraries/LogBox/UI/__tests__/__snapshots__/LogBoxInspector-test.js.snap @@ -34,7 +34,6 @@ exports[`LogBoxContainer should render fatal with selectedIndex 2 1`] = ` "stack": null, "status": "NONE", }, - "type": undefined, } } onRetry={[Function]} @@ -83,7 +82,6 @@ exports[`LogBoxContainer should render warning with selectedIndex 0 1`] = ` "stack": null, "status": "NONE", }, - "type": undefined, } } onRetry={[Function]} diff --git a/Libraries/LogBox/UI/__tests__/__snapshots__/LogBoxInspectorCodeFrame-test.js.snap b/Libraries/LogBox/UI/__tests__/__snapshots__/LogBoxInspectorCodeFrame-test.js.snap index c847ccd0872e63..6fc9fda0cf8d2c 100644 --- a/Libraries/LogBox/UI/__tests__/__snapshots__/LogBoxInspectorCodeFrame-test.js.snap +++ b/Libraries/LogBox/UI/__tests__/__snapshots__/LogBoxInspectorCodeFrame-test.js.snap @@ -25,7 +25,7 @@ exports[`LogBoxInspectorCodeFrame should render a code frame 1`] = ` } } > - - + - - + { jest.resetModules(); console.error = jest.fn(); console.warn = jest.fn(); - console.disableYellowBox = false; }); afterEach(() => { @@ -45,51 +44,27 @@ describe('LogBox', () => { console.warn = warn; }); - it('can call `ignoreAllLogs` after installing', () => { - expect(LogBoxData.isDisabled()).toBe(false); + it('can set `disableLogBox` after installing', () => { + expect(console.disableLogBox).toBe(undefined); LogBox.install(); + expect(console.disableLogBox).toBe(false); expect(LogBoxData.isDisabled()).toBe(false); - LogBox.ignoreAllLogs(true); + console.disableLogBox = true; + expect(console.disableLogBox).toBe(true); expect(LogBoxData.isDisabled()).toBe(true); }); - it('can call `ignoreAllLogs` before installing', () => { - expect(LogBoxData.isDisabled()).toBe(false); - - LogBox.ignoreAllLogs(true); - - expect(LogBoxData.isDisabled()).toBe(true); + it('can set `disableLogBox` before installing', () => { + expect(console.disableLogBox).toBe(undefined); + console.disableLogBox = true; LogBox.install(); - expect(LogBoxData.isDisabled()).toBe(true); - }); - - it('will not ignore logs for `ignoreAllLogs(false)`', () => { - expect(LogBoxData.isDisabled()).toBe(false); - - LogBox.install(); - - expect(LogBoxData.isDisabled()).toBe(false); - - LogBox.ignoreAllLogs(false); - - expect(LogBoxData.isDisabled()).toBe(false); - }); - - it('will ignore logs for `ignoreAllLogs()`', () => { - expect(LogBoxData.isDisabled()).toBe(false); - - LogBox.install(); - - expect(LogBoxData.isDisabled()).toBe(false); - - LogBox.ignoreAllLogs(); - + expect(console.disableLogBox).toBe(true); expect(LogBoxData.isDisabled()).toBe(true); }); diff --git a/Libraries/LogBox/__tests__/__snapshots__/LogBoxInspectorContainer-test.js.snap b/Libraries/LogBox/__tests__/__snapshots__/LogBoxInspectorContainer-test.js.snap index 99c5f74e76ad37..7182e10482b899 100644 --- a/Libraries/LogBox/__tests__/__snapshots__/LogBoxInspectorContainer-test.js.snap +++ b/Libraries/LogBox/__tests__/__snapshots__/LogBoxInspectorContainer-test.js.snap @@ -40,7 +40,6 @@ exports[`LogBoxNotificationContainer should render both an error and warning not "stack": null, "status": "NONE", }, - "type": undefined, } } onPressDismiss={[Function]} @@ -77,7 +76,6 @@ exports[`LogBoxNotificationContainer should render both an error and warning not "stack": null, "status": "NONE", }, - "type": undefined, } } onPressDismiss={[Function]} @@ -136,7 +134,6 @@ exports[`LogBoxNotificationContainer should render the latest error notification "stack": null, "status": "NONE", }, - "type": undefined, } } onPressDismiss={[Function]} @@ -187,7 +184,6 @@ exports[`LogBoxNotificationContainer should render the latest warning notificati "stack": null, "status": "NONE", }, - "type": undefined, } } onPressDismiss={[Function]} diff --git a/Libraries/LogBox/__tests__/__snapshots__/LogBoxNotificationContainer-test.js.snap b/Libraries/LogBox/__tests__/__snapshots__/LogBoxNotificationContainer-test.js.snap index c512ee317f257c..2c2253ad83b26b 100644 --- a/Libraries/LogBox/__tests__/__snapshots__/LogBoxNotificationContainer-test.js.snap +++ b/Libraries/LogBox/__tests__/__snapshots__/LogBoxNotificationContainer-test.js.snap @@ -32,7 +32,6 @@ exports[`LogBoxNotificationContainer should render inspector with logs, even whe "stack": null, "status": "NONE", }, - "type": undefined, }, LogBoxLog { "category": "Some kind of message (latest)", @@ -51,7 +50,6 @@ exports[`LogBoxNotificationContainer should render inspector with logs, even whe "stack": null, "status": "NONE", }, - "type": undefined, }, ] } diff --git a/Libraries/Modal/Modal.js b/Libraries/Modal/Modal.js index 9217732197bfb2..426988d33b3602 100644 --- a/Libraries/Modal/Modal.js +++ b/Libraries/Modal/Modal.js @@ -34,7 +34,7 @@ const ModalEventEmitter = /** * The Modal component is a simple way to present content above an enclosing view. * - * See https://reactnative.dev/docs/modal.html + * See https://facebook.github.io/react-native/docs/modal.html */ // In order to route onDismiss callbacks, we need to uniquely identifier each @@ -53,14 +53,14 @@ export type Props = $ReadOnly<{| /** * The `animationType` prop controls how the modal animates. * - * See https://reactnative.dev/docs/modal.html#animationtype + * See https://facebook.github.io/react-native/docs/modal.html#animationtype */ animationType?: ?('none' | 'slide' | 'fade'), /** * The `presentationStyle` prop controls how the modal appears. * - * See https://reactnative.dev/docs/modal.html#presentationstyle + * See https://facebook.github.io/react-native/docs/modal.html#presentationstyle */ presentationStyle?: ?( | 'fullScreen' @@ -73,7 +73,7 @@ export type Props = $ReadOnly<{| * The `transparent` prop determines whether your modal will fill the * entire view. * - * See https://reactnative.dev/docs/modal.html#transparent + * See https://facebook.github.io/react-native/docs/modal.html#transparent */ transparent?: ?boolean, @@ -81,7 +81,7 @@ export type Props = $ReadOnly<{| * The `statusBarTranslucent` prop determines whether your modal should go under * the system statusbar. * - * See https://reactnative.dev/docs/modal.html#transparent + * See https://facebook.github.io/react-native/docs/modal.html#transparent */ statusBarTranslucent?: ?boolean, @@ -89,16 +89,16 @@ export type Props = $ReadOnly<{| * The `hardwareAccelerated` prop controls whether to force hardware * acceleration for the underlying window. * - * This prop works only on Android. + * This prop works inly on Android. * - * See https://reactnative.dev/docs/modal.html#hardwareaccelerated + * See https://facebook.github.io/react-native/docs/modal.html#hardwareaccelerated */ hardwareAccelerated?: ?boolean, /** * The `visible` prop determines whether your modal is visible. * - * See https://reactnative.dev/docs/modal.html#visible + * See https://facebook.github.io/react-native/docs/modal.html#visible */ visible?: ?boolean, @@ -108,7 +108,7 @@ export type Props = $ReadOnly<{| * * This is required on Apple TV and Android. * - * See https://reactnative.dev/docs/modal.html#onrequestclose + * See https://facebook.github.io/react-native/docs/modal.html#onrequestclose */ onRequestClose?: ?DirectEventHandler, @@ -116,7 +116,7 @@ export type Props = $ReadOnly<{| * The `onShow` prop allows passing a function that will be called once the * modal has been shown. * - * See https://reactnative.dev/docs/modal.html#onshow + * See https://facebook.github.io/react-native/docs/modal.html#onshow */ onShow?: ?DirectEventHandler, @@ -124,14 +124,19 @@ export type Props = $ReadOnly<{| * The `onDismiss` prop allows passing a function that will be called once * the modal has been dismissed. * - * See https://reactnative.dev/docs/modal.html#ondismiss + * See https://facebook.github.io/react-native/docs/modal.html#ondismiss */ onDismiss?: ?() => mixed, + /** + * Deprecated. Use the `animationType` prop instead. + */ + animated?: ?boolean, + /** * The `supportedOrientations` prop allows the modal to be rotated to any of the specified orientations. * - * See https://reactnative.dev/docs/modal.html#supportedorientations + * See https://facebook.github.io/react-native/docs/modal.html#supportedorientations */ supportedOrientations?: ?$ReadOnlyArray< | 'portrait' @@ -144,7 +149,7 @@ export type Props = $ReadOnly<{| /** * The `onOrientationChange` callback is called when the orientation changes while the modal is being displayed. * - * See https://reactnative.dev/docs/modal.html#onorientationchange + * See https://facebook.github.io/react-native/docs/modal.html#onorientationchange */ onOrientationChange?: ?DirectEventHandler, |}>; @@ -228,7 +233,14 @@ class Modal extends React.Component { backgroundColor: this.props.transparent ? 'transparent' : 'white', }; - let animationType = this.props.animationType || 'none'; + let animationType = this.props.animationType; + if (!animationType) { + // manually setting default prop here to keep support for the deprecated 'animated' prop + animationType = 'none'; + if (this.props.animated) { + animationType = 'slide'; + } + } let presentationStyle = this.props.presentationStyle; if (!presentationStyle) { diff --git a/Libraries/Modal/RCTModalHostViewNativeComponent.js b/Libraries/Modal/RCTModalHostViewNativeComponent.js index ebc154146c7f54..907acd07d1a4c2 100644 --- a/Libraries/Modal/RCTModalHostViewNativeComponent.js +++ b/Libraries/Modal/RCTModalHostViewNativeComponent.js @@ -31,14 +31,14 @@ type NativeProps = $ReadOnly<{| /** * The `animationType` prop controls how the modal animates. * - * See https://reactnative.dev/docs/modal.html#animationtype + * See https://facebook.github.io/react-native/docs/modal.html#animationtype */ animationType?: WithDefault<'none' | 'slide' | 'fade', 'none'>, /** * The `presentationStyle` prop controls how the modal appears. * - * See https://reactnative.dev/docs/modal.html#presentationstyle + * See https://facebook.github.io/react-native/docs/modal.html#presentationstyle */ presentationStyle?: WithDefault< 'fullScreen' | 'pageSheet' | 'formSheet' | 'overFullScreen', @@ -49,7 +49,7 @@ type NativeProps = $ReadOnly<{| * The `transparent` prop determines whether your modal will fill the * entire view. * - * See https://reactnative.dev/docs/modal.html#transparent + * See https://facebook.github.io/react-native/docs/modal.html#transparent */ transparent?: WithDefault, @@ -57,7 +57,7 @@ type NativeProps = $ReadOnly<{| * The `statusBarTranslucent` prop determines whether your modal should go under * the system statusbar. * - * See https://reactnative.dev/docs/modal.html#statusBarTranslucent + * See https://facebook.github.io/react-native/docs/modal.html#statusBarTranslucent */ statusBarTranslucent?: WithDefault, @@ -65,7 +65,7 @@ type NativeProps = $ReadOnly<{| * The `hardwareAccelerated` prop controls whether to force hardware * acceleration for the underlying window. * - * See https://reactnative.dev/docs/modal.html#hardwareaccelerated + * See https://facebook.github.io/react-native/docs/modal.html#hardwareaccelerated */ hardwareAccelerated?: WithDefault, @@ -75,7 +75,7 @@ type NativeProps = $ReadOnly<{| * * This is required on Apple TV and Android. * - * See https://reactnative.dev/docs/modal.html#onrequestclose + * See https://facebook.github.io/react-native/docs/modal.html#onrequestclose */ onRequestClose?: ?DirectEventHandler, @@ -83,7 +83,7 @@ type NativeProps = $ReadOnly<{| * The `onShow` prop allows passing a function that will be called once the * modal has been shown. * - * See https://reactnative.dev/docs/modal.html#onshow + * See https://facebook.github.io/react-native/docs/modal.html#onshow */ onShow?: ?DirectEventHandler, @@ -103,7 +103,7 @@ type NativeProps = $ReadOnly<{| /** * The `supportedOrientations` prop allows the modal to be rotated to any of the specified orientations. * - * See https://reactnative.dev/docs/modal.html#supportedorientations + * See https://facebook.github.io/react-native/docs/modal.html#supportedorientations */ supportedOrientations?: WithDefault< $ReadOnlyArray< @@ -119,7 +119,7 @@ type NativeProps = $ReadOnly<{| /** * The `onOrientationChange` callback is called when the orientation changes while the modal is being displayed. * - * See https://reactnative.dev/docs/modal.html#onorientationchange + * See https://facebook.github.io/react-native/docs/modal.html#onorientationchange */ onOrientationChange?: ?DirectEventHandler, diff --git a/Libraries/NativeAnimation/RCTNativeAnimatedModule.mm b/Libraries/NativeAnimation/RCTNativeAnimatedModule.mm index e0316f6fec2729..f0677e813fb742 100644 --- a/Libraries/NativeAnimation/RCTNativeAnimatedModule.mm +++ b/Libraries/NativeAnimation/RCTNativeAnimatedModule.mm @@ -15,9 +15,6 @@ typedef void (^AnimatedOperation)(RCTNativeAnimatedNodesManager *nodesManager); -@interface RCTNativeAnimatedModule() -@end - @implementation RCTNativeAnimatedModule { RCTNativeAnimatedNodesManager *_nodesManager; @@ -335,14 +332,6 @@ - (void)eventDispatcherWillDispatchEvent:(id)event }); } -- (std::shared_ptr) - getTurboModuleWithJsInvoker:(std::shared_ptr)jsInvoker - nativeInvoker:(std::shared_ptr)nativeInvoker - perfLogger:(id)perfLogger -{ - return std::make_shared(self, jsInvoker, nativeInvoker, perfLogger); -} - @end Class RCTNativeAnimatedModuleCls(void) { diff --git a/Libraries/NativeAnimation/React-RCTAnimation.podspec b/Libraries/NativeAnimation/React-RCTAnimation.podspec index f79a098a76fa33..391d520acd0676 100644 --- a/Libraries/NativeAnimation/React-RCTAnimation.podspec +++ b/Libraries/NativeAnimation/React-RCTAnimation.podspec @@ -17,16 +17,16 @@ else end folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32' -folly_version = '2020.01.13.00' +folly_version = '2018.10.22.00' Pod::Spec.new do |s| s.name = "React-RCTAnimation" s.version = version s.summary = "A native driver for the Animated API." - s.homepage = "https://reactnative.dev/" + s.homepage = "http://facebook.github.io/react-native/" s.license = package["license"] s.author = "Facebook, Inc. and its affiliates" - s.platforms = { :ios => "10.0", :tvos => "10.0", :osx => "10.13" } # TODO(macOS GH#214) + s.platforms = { :ios => "9.0", :tvos => "9.2", :osx => "10.13" } # TODO(macOS GH#214) s.compiler_flags = folly_compiler_flags + ' -Wno-nullability-completeness' s.source = source s.source_files = "{Drivers/*,Nodes/*,*}.{m,mm}" @@ -41,7 +41,6 @@ Pod::Spec.new do |s| s.dependency "RCT-Folly", folly_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/Libraries/NativeModules/specs/NativeDevSettings.js b/Libraries/NativeModules/specs/NativeDevSettings.js index 2e092a2d682baa..8f6afeaa39d752 100644 --- a/Libraries/NativeModules/specs/NativeDevSettings.js +++ b/Libraries/NativeModules/specs/NativeDevSettings.js @@ -23,10 +23,6 @@ export interface Spec extends TurboModule { +toggleElementInspector: () => void; +addMenuItem: (title: string) => void; - // Events - +addListener: (eventName: string) => void; - +removeListeners: (count: number) => void; - // iOS only. +setIsShakeToShowDevMenuEnabled: (enabled: boolean) => void; diff --git a/Libraries/Network/RCTNetworking.mm b/Libraries/Network/RCTNetworking.mm index 2989276aca93b2..36383741fc7ca8 100644 --- a/Libraries/Network/RCTNetworking.mm +++ b/Libraries/Network/RCTNetworking.mm @@ -714,12 +714,10 @@ - (RCTNetworkTask *)networkTaskWithRequest:(NSURLRequest *)request completionBlo responseSender(@[@YES]); } -- (std::shared_ptr) - getTurboModuleWithJsInvoker:(std::shared_ptr)jsInvoker - nativeInvoker:(std::shared_ptr)nativeInvoker - perfLogger:(id)perfLogger +- (std::shared_ptr)getTurboModuleWithJsInvoker: + (std::shared_ptr)jsInvoker { - return std::make_shared(self, jsInvoker, nativeInvoker, perfLogger); + return std::make_shared(self, jsInvoker); } @end diff --git a/Libraries/Network/React-RCTNetwork.podspec b/Libraries/Network/React-RCTNetwork.podspec index f2275bcb9cd6af..d5c99c966531a8 100644 --- a/Libraries/Network/React-RCTNetwork.podspec +++ b/Libraries/Network/React-RCTNetwork.podspec @@ -17,16 +17,16 @@ else end folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32' -folly_version = '2020.01.13.00' +folly_version = '2018.10.22.00' Pod::Spec.new do |s| s.name = "React-RCTNetwork" s.version = version s.summary = "The networking library of React Native." - s.homepage = "https://reactnative.dev/" + s.homepage = "http://facebook.github.io/react-native/" s.license = package["license"] s.author = "Facebook, Inc. and its affiliates" - s.platforms = { :ios => "10.0", :tvos => "10.0", :osx => "10.13" } # TODO(macOS GH#214) + s.platforms = { :ios => "9.0", :tvos => "9.2", :osx => "10.13" } # TODO(macOS GH#214) s.compiler_flags = folly_compiler_flags + ' -Wno-nullability-completeness' s.source = source s.source_files = "*.{m,mm}" @@ -43,6 +43,5 @@ Pod::Spec.new do |s| s.dependency "FBReactNativeSpec", version s.dependency "RCTTypeSafety", version s.dependency "ReactCommon/turbomodule/core", version - s.dependency "React-jsi", version s.dependency "React-Core/RCTNetworkHeaders", version end diff --git a/Libraries/Network/XMLHttpRequest.js b/Libraries/Network/XMLHttpRequest.js index 7bfb0ffa35830d..e25e876e814828 100644 --- a/Libraries/Network/XMLHttpRequest.js +++ b/Libraries/Network/XMLHttpRequest.js @@ -12,15 +12,12 @@ const BlobManager = require('../Blob/BlobManager'); const EventTarget = require('event-target-shim'); -const GlobalPerformanceLogger = require('react-native/Libraries/Utilities/GlobalPerformanceLogger'); const RCTNetworking = require('./RCTNetworking'); const base64 = require('base64-js'); const invariant = require('invariant'); const warning = require('fbjs/lib/warning'); -const DEBUG_NETWORK_SEND_DELAY: false = false; // Set to a number of milliseconds when debugging - export type NativeResponseType = 'base64' | 'blob' | 'text'; export type ResponseType = | '' @@ -133,7 +130,6 @@ class XMLHttpRequest extends (EventTarget(...XHR_EVENTS): any) { _headers: Object; _lowerCaseResponseHeaders: Object; _method: ?string = null; - _perfKey: ?string = null; _response: string | ?Object; _responseType: ResponseType; _response: string = ''; @@ -246,7 +242,7 @@ class XMLHttpRequest extends (EventTarget(...XHR_EVENTS): any) { if (typeof this._response === 'object' && this._response) { this._cachedResponse = BlobManager.createFromOptions(this._response); } else if (this._response === '') { - this._cachedResponse = BlobManager.createFromParts([]); + this._cachedResponse = null; } else { throw new Error(`Invalid response for blob: ${this._response}`); } @@ -303,8 +299,6 @@ class XMLHttpRequest extends (EventTarget(...XHR_EVENTS): any) { responseURL: ?string, ): void { if (requestId === this._requestId) { - this._perfKey != null && - GlobalPerformanceLogger.stopTimespan(this._perfKey); this.status = status; this.setResponseHeaders(responseHeaders); this.setReadyState(this.HEADERS_RECEIVED); @@ -517,41 +511,22 @@ class XMLHttpRequest extends (EventTarget(...XHR_EVENTS): any) { nativeResponseType = 'blob'; } - const doSend = () => { - const friendlyName = - this._trackingName !== 'unknown' ? this._trackingName : this._url; - this._perfKey = 'network_XMLHttpRequest_' + String(friendlyName); - GlobalPerformanceLogger.startTimespan(this._perfKey); - invariant( - this._method, - 'XMLHttpRequest method needs to be defined (%s).', - friendlyName, - ); - invariant( - this._url, - 'XMLHttpRequest URL needs to be defined (%s).', - friendlyName, - ); - RCTNetworking.sendRequest( - this._method, - this._trackingName, - this._url, - this._headers, - data, - /* $FlowFixMe(>=0.78.0 site=react_native_android_fb) This issue was found - * when making Flow check .android.js files. */ - nativeResponseType, - incrementalEvents, - this.timeout, - this.__didCreateRequest.bind(this), - this.withCredentials, - ); - }; - if (DEBUG_NETWORK_SEND_DELAY) { - setTimeout(doSend, DEBUG_NETWORK_SEND_DELAY); - } else { - doSend(); - } + invariant(this._method, 'Request method needs to be defined.'); + invariant(this._url, 'Request URL needs to be defined.'); + RCTNetworking.sendRequest( + this._method, + this._trackingName, + this._url, + this._headers, + data, + /* $FlowFixMe(>=0.78.0 site=react_native_android_fb) This issue was found + * when making Flow check .android.js files. */ + nativeResponseType, + incrementalEvents, + this.timeout, + this.__didCreateRequest.bind(this), + this.withCredentials, + ); } abort(): void { diff --git a/Libraries/NewAppScreen/components/LearnMoreLinks.js b/Libraries/NewAppScreen/components/LearnMoreLinks.js index 9effd49e172093..6db3a1970fe8de 100644 --- a/Libraries/NewAppScreen/components/LearnMoreLinks.js +++ b/Libraries/NewAppScreen/components/LearnMoreLinks.js @@ -19,45 +19,45 @@ const links = [ { id: 1, title: 'The Basics', - link: 'https://reactnative.dev/docs/tutorial', + link: 'https://facebook.github.io/react-native/docs/tutorial', description: 'Explains a Hello World for React Native.', }, { id: 2, title: 'Style', - link: 'https://reactnative.dev/docs/style', + link: 'https://facebook.github.io/react-native/docs/style', description: 'Covers how to use the prop named style which controls the visuals.', }, { id: 3, title: 'Layout', - link: 'https://reactnative.dev/docs/flexbox', + link: 'https://facebook.github.io/react-native/docs/flexbox', description: 'React Native uses flexbox for layout, learn how it works.', }, { id: 4, title: 'Components', - link: 'https://reactnative.dev/docs/components-and-apis', + link: 'https://facebook.github.io/react-native/docs/components-and-apis', description: 'The full list of components and APIs inside React Native.', }, { id: 5, title: 'Navigation', - link: 'https://reactnative.dev/docs/navigation', + link: 'https://facebook.github.io/react-native/docs/navigation', description: 'How to handle moving between screens inside your application.', }, { id: 6, title: 'Networking', - link: 'https://reactnative.dev/docs/network', + link: 'https://facebook.github.io/react-native/docs/network', description: 'How to use the Fetch API in React Native.', }, { id: 7, title: 'Help', - link: 'https://reactnative.dev/help', + link: 'https://facebook.github.io/react-native/help', description: 'Need more help? There are many other React Native developers who may have the answer.', }, diff --git a/Libraries/Performance/QuickPerformanceLogger.js b/Libraries/Performance/QuickPerformanceLogger.js index 6dfed3cdbd0328..23ae5b30d25ed4 100644 --- a/Libraries/Performance/QuickPerformanceLogger.js +++ b/Libraries/Performance/QuickPerformanceLogger.js @@ -81,15 +81,6 @@ const QuickPerformanceLogger = { } }, - markerDrop( - markerId: number, - instanceKey?: number = DUMMY_INSTANCE_KEY, - ): void { - if (global.nativeQPLMarkerDrop) { - global.nativeQPLMarkerDrop(markerId, instanceKey); - } - }, - currentTimestamp(): number { if (global.nativeQPLTimestamp) { return global.nativeQPLTimestamp(); diff --git a/Libraries/Performance/Systrace.js b/Libraries/Performance/Systrace.js index e1db39bbfc5bbc..dcc8555c9a55c2 100644 --- a/Libraries/Performance/Systrace.js +++ b/Libraries/Performance/Systrace.js @@ -87,25 +87,11 @@ const userTimingPolyfill = __DEV__ } : null; -function installPerformanceHooks(polyfill) { - if (polyfill) { - if (global.performance === undefined) { - global.performance = {}; - } - - Object.keys(polyfill).forEach(methodName => { - if (typeof global.performance[methodName] !== 'function') { - global.performance[methodName] = polyfill[methodName]; - } - }); - } -} - const Systrace = { installReactHook() { if (_enabled) { if (__DEV__) { - installPerformanceHooks(userTimingPolyfill); + global.performance = userTimingPolyfill; } } _canInstallReactHook = true; @@ -122,8 +108,8 @@ const Systrace = { global.nativeTraceEndLegacy(TRACE_TAG_JS_VM_CALLS); } if (_canInstallReactHook) { - if (enabled) { - installPerformanceHooks(userTimingPolyfill); + if (enabled && global.performance === undefined) { + global.performance = userTimingPolyfill; } } } diff --git a/Libraries/PermissionsAndroid/PermissionsAndroid.js b/Libraries/PermissionsAndroid/PermissionsAndroid.js index 83124ccc24bd05..66694c2f320d2f 100644 --- a/Libraries/PermissionsAndroid/PermissionsAndroid.js +++ b/Libraries/PermissionsAndroid/PermissionsAndroid.js @@ -66,7 +66,7 @@ const PERMISSIONS = Object.freeze({ /** * `PermissionsAndroid` provides access to Android M's new permissions model. * - * See https://reactnative.dev/docs/permissionsandroid.html + * See https://facebook.github.io/react-native/docs/permissionsandroid.html */ class PermissionsAndroid { @@ -134,7 +134,7 @@ class PermissionsAndroid { * Returns a promise resolving to a boolean value as to whether the specified * permissions has been granted * - * See https://reactnative.dev/docs/permissionsandroid.html#check + * See https://facebook.github.io/react-native/docs/permissionsandroid.html#check */ check(permission: PermissionType): Promise { if (Platform.OS !== 'android') { @@ -188,7 +188,7 @@ class PermissionsAndroid { * Prompts the user to enable a permission and returns a promise resolving to a * string value indicating whether the user allowed or denied the request * - * See https://reactnative.dev/docs/permissionsandroid.html#request + * See https://facebook.github.io/react-native/docs/permissionsandroid.html#request */ async request( permission: PermissionType, @@ -236,7 +236,7 @@ class PermissionsAndroid { * returns an object with the permissions as keys and strings as values * indicating whether the user allowed or denied the request * - * See https://reactnative.dev/docs/permissionsandroid.html#requestmultiple + * See https://facebook.github.io/react-native/docs/permissionsandroid.html#requestmultiple */ requestMultiple( permissions: Array, diff --git a/Libraries/Pressability/Pressability.js b/Libraries/Pressability/Pressability.js index 37555d5df735ae..42ee68d23eca0f 100644 --- a/Libraries/Pressability/Pressability.js +++ b/Libraries/Pressability/Pressability.js @@ -10,16 +10,16 @@ 'use strict'; -import {isHoverEnabled} from './HoverState'; +import {isHoverEnabled} from './HoverState.js'; import invariant from 'invariant'; -import SoundManager from '../Components/Sound/SoundManager'; -import {normalizeRect, type RectOrSize} from '../StyleSheet/Rect'; +import SoundManager from '../Components/Sound/SoundManager.js'; +import type {EdgeInsetsProp} from '../StyleSheet/EdgeInsetsPropType.js'; import type { BlurEvent, FocusEvent, PressEvent, MouseEvent, -} from '../Types/CoreEventTypes'; +} from '../Types/CoreEventTypes.js'; import Platform from '../Utilities/Platform'; import UIManager from '../ReactNative/UIManager'; import type {HostComponent} from '../Renderer/shims/ReactNativeTypes'; @@ -27,132 +27,110 @@ import * as React from 'react'; export type PressabilityConfig = $ReadOnly<{| /** - * Whether a press gesture can be interrupted by a parent gesture such as a - * scroll event. Defaults to true. + * Returns the amount to extend the `VisualRect` by to create `HitRect`. */ - cancelable?: ?boolean, + getHitSlop?: ?() => ?EdgeInsetsProp, /** - * Whether to disable initialization of the press gesture. + * Returns the duration to wait after hover in before activation. */ - disabled?: ?boolean, + getHoverInDelayMS?: ?() => ?number, /** - * Amount to extend the `VisualRect` by to create `HitRect`. + * Returns the duration to wait after hover out before deactivation. */ - hitSlop?: ?RectOrSize, + getHoverOutDelayMS?: ?() => ?number, /** - * Amount to extend the `HitRect` by to create `PressRect`. + * Returns the duration (in addition to the value from `getPressDelayMS`) + * after which a press gesture becomes a long press gesture. */ - pressRectOffset?: ?RectOrSize, + getLongPressDelayMS?: ?() => ?number, /** - * Whether to disable the systemm sound when `onPress` fires on Android. - **/ - android_disableSound?: ?boolean, - - /** - * Duration to wait after hover in before calling `onHoverIn`. - */ - delayHoverIn?: ?number, - - /** - * Duration to wait after hover out before calling `onHoverOut`. - */ - delayHoverOut?: ?number, - - /** - * Duration (in addition to `delayPressIn`) after which a press gesture is - * considered a long press gesture. Defaults to 500 (milliseconds). + * Returns the duration to wait after press down before activation. */ - delayLongPress?: ?number, + getPressDelayMS?: ?() => ?number, /** - * Duration to wait after press down before calling `onPressIn`. + * Returns the duration to wait after letting up before deactivation. */ - delayPressIn?: ?number, + getPressOutDelayMS?: ?() => ?number, /** - * Duration to wait after letting up before calling `onPressOut`. + * Returns the amount to extend the `HitRect` by to create `PressRect`. */ - delayPressOut?: ?number, + getPressRectOffset?: ?() => ?EdgeInsetsProp, /** - * Minimum duration to wait between calling `onPressIn` and `onPressOut`. - */ - minPressDuration?: ?number, + * Returns true to disable playing system sound on touch (Android Only) + **/ + getTouchSoundDisabled?: ?() => ?boolean, /** * Called after the element loses focus. */ - onBlur?: ?(event: BlurEvent) => mixed, + onBlur?: ?(event: BlurEvent) => void, /** * Called after the element is focused. */ - onFocus?: ?(event: FocusEvent) => mixed, + onFocus?: ?(event: FocusEvent) => void, /** * Called when the hover is activated to provide visual feedback. */ - onHoverIn?: ?(event: MouseEvent) => mixed, + onHoverIn?: ?(event: MouseEvent) => void, /** * Called when the hover is deactivated to undo visual feedback. */ - onHoverOut?: ?(event: MouseEvent) => mixed, + onHoverOut?: ?(event: MouseEvent) => void, /** * Called when a long press gesture has been triggered. */ - onLongPress?: ?(event: PressEvent) => mixed, + onLongPress?: ?(event: PressEvent) => void, + + /** + * Returns whether a long press gesture should cancel the press gesture. + * Defaults to true. + */ + onLongPressShouldCancelPress?: ?() => boolean, /** * Called when a press gestute has been triggered. */ - onPress?: ?(event: PressEvent) => mixed, + onPress?: ?(event: PressEvent) => void, /** * Called when the press is activated to provide visual feedback. */ - onPressIn?: ?(event: PressEvent) => mixed, + onPressIn?: ?(event: PressEvent) => void, /** * Called when the press location moves. (This should rarely be used.) */ - onPressMove?: ?(event: PressEvent) => mixed, + onPressMove?: ?(event: PressEvent) => void, /** * Called when the press is deactivated to undo visual feedback. */ - onPressOut?: ?(event: PressEvent) => mixed, + onPressOut?: ?(event: PressEvent) => void, /** - * Returns whether a long press gesture should cancel the press gesture. - * Defaults to true. - */ - onLongPressShouldCancelPress_DEPRECATED?: ?() => boolean, - - /** - * If `cancelable` is set, this will be ignored. - * * Returns whether to yield to a lock termination request (e.g. if a native * scroll gesture attempts to steal the responder lock). */ - onResponderTerminationRequest_DEPRECATED?: ?() => boolean, + onResponderTerminationRequest?: ?() => boolean, /** - * If `disabled` is set, this will be ignored. - * * Returns whether to start a press gesture. - * - * @deprecated */ - onStartShouldSetResponder_DEPRECATED?: ?() => boolean, + onStartShouldSetResponder?: ?() => boolean, |}>; -export type EventHandlers = $ReadOnly<{| +type EventHandlers = $ReadOnly<{| onBlur: (event: BlurEvent) => void, onClick: (event: PressEvent) => void, onFocus: (event: FocusEvent) => void, @@ -276,15 +254,14 @@ const isPressInSignal = signal => const isTerminalSignal = signal => signal === 'RESPONDER_TERMINATED' || signal === 'RESPONDER_RELEASE'; -const DEFAULT_LONG_PRESS_DELAY_MS = 370; // 500 - 130 -const DEFAULT_PRESS_DELAY_MS = 130; +const DEFAULT_LONG_PRESS_DELAY_MS = 500; +const DEFAULT_PRESS_DELAY_MS = 0; const DEFAULT_PRESS_RECT_OFFSETS = { bottom: 30, left: 20, right: 20, top: 20, }; -const DEFAULT_MIN_PRESS_DURATION = 130; /** * Pressability implements press handling capabilities. @@ -338,7 +315,7 @@ const DEFAULT_MIN_PRESS_DURATION = 130; * * ┌────────────────────────┐ * │ ┌──────────────────┐ │ - Presses start anywhere within `HitRect`, which - * │ │ ┌────────────┐ │ │ is expanded via the prop `hitSlop`. + * │ │ ┌────────────┐ │ │ is expanded via the prop `getHitSlop`. * │ │ │ VisualRect │ │ │ * │ │ └────────────┘ │ │ - When pressed down for sufficient amount of time * │ │ HitRect │ │ before letting up, `VisualRect` activates for @@ -346,7 +323,7 @@ const DEFAULT_MIN_PRESS_DURATION = 130; * │ PressRect o │ * └────────────────────│───┘ * Out Region └────── `PressRect`, which is expanded via the prop - * `pressRectOffset`, allows presses to move + * `getPressRectOffset`, allows presses to move * beyond `HitRect` while maintaining activation * and being eligible for a "press". * @@ -399,14 +376,9 @@ export default class Pressability { pageX: number, pageY: number, |}>; - _touchActivateTime: ?number; _touchState: TouchState = 'NOT_RESPONDER'; constructor(config: PressabilityConfig) { - this.configure(config); - } - - configure(config: PressabilityConfig): void { this._config = config; } @@ -448,15 +420,11 @@ export default class Pressability { }; const responderEventHandlers = { - onStartShouldSetResponder: (): boolean => { - const {disabled} = this._config; - if (disabled == null) { - const {onStartShouldSetResponder_DEPRECATED} = this._config; - return onStartShouldSetResponder_DEPRECATED == null - ? true - : onStartShouldSetResponder_DEPRECATED(); - } - return !disabled; + onStartShouldSetResponder: () => { + const {onStartShouldSetResponder} = this._config; + return onStartShouldSetResponder == null + ? true + : onStartShouldSetResponder(); }, onResponderGrant: (event: PressEvent): void => { @@ -468,28 +436,29 @@ export default class Pressability { this._touchState = 'NOT_RESPONDER'; this._receiveSignal('RESPONDER_GRANT', event); - const delayPressIn = normalizeDelay( - this._config.delayPressIn, + const {getLongPressDelayMS, getPressDelayMS} = this._config; + + const pressDelay = getDelayMS( + getPressDelayMS, 0, DEFAULT_PRESS_DELAY_MS, ); - - if (delayPressIn > 0) { + if (pressDelay > 0) { this._pressDelayTimeout = setTimeout(() => { this._receiveSignal('DELAY', event); - }, delayPressIn); + }, pressDelay); } else { this._receiveSignal('DELAY', event); } - const delayLongPress = normalizeDelay( - this._config.delayLongPress, + const longPressDelay = getDelayMS( + getLongPressDelayMS, 10, DEFAULT_LONG_PRESS_DELAY_MS, ); this._longPressDelayTimeout = setTimeout(() => { this._handleLongPress(event); - }, delayLongPress + delayPressIn); + }, longPressDelay + pressDelay); }, onResponderMove: (event: PressEvent): void => { @@ -535,17 +504,13 @@ export default class Pressability { }, onResponderTerminationRequest: (): boolean => { - const {cancelable} = this._config; - if (cancelable == null) { - const {onResponderTerminationRequest_DEPRECATED} = this._config; - return onResponderTerminationRequest_DEPRECATED == null - ? true - : onResponderTerminationRequest_DEPRECATED(); - } - return cancelable; + const {onResponderTerminationRequest} = this._config; + return onResponderTerminationRequest == null + ? true + : onResponderTerminationRequest(); }, - onClick: (event: PressEvent): void => { + onClick: (event: PressEvent) => { const {onPress} = this._config; if (onPress != null) { onPress(event); @@ -553,12 +518,6 @@ export default class Pressability { }, }; - if (process.env.NODE_ENV === 'test') { - // We are setting this in order to find this node in ReactNativeTestTools - responderEventHandlers.onStartShouldSetResponder.testOnly_pressabilityConfig = () => - this._config; - } - const mouseEventHandlers = Platform.OS === 'ios' || Platform.OS === 'android' ? null @@ -567,15 +526,13 @@ export default class Pressability { if (isHoverEnabled()) { this._isHovered = true; this._cancelHoverOutDelayTimeout(); - const {onHoverIn} = this._config; + const {onHoverIn, getHoverInDelayMS} = this._config; if (onHoverIn != null) { - const delayHoverIn = normalizeDelay( - this._config.delayHoverIn, - ); - if (delayHoverIn > 0) { + const delay = getDelayMS(getHoverInDelayMS); + if (delay > 0) { this._hoverInDelayTimeout = setTimeout(() => { onHoverIn(event); - }, delayHoverIn); + }, delay); } else { onHoverIn(event); } @@ -587,15 +544,13 @@ export default class Pressability { if (this._isHovered) { this._isHovered = false; this._cancelHoverInDelayTimeout(); - const {onHoverOut} = this._config; + const {onHoverOut, getHoverOutDelayMS} = this._config; if (onHoverOut != null) { - const delayHoverOut = normalizeDelay( - this._config.delayHoverOut, - ); - if (delayHoverOut > 0) { + const delay = getDelayMS(getHoverOutDelayMS); + if (delay > 0) { this._hoverInDelayTimeout = setTimeout(() => { onHoverOut(event); - }, delayHoverOut); + }, delay); } else { onHoverOut(event); } @@ -679,7 +634,7 @@ export default class Pressability { } if (isPressInSignal(prevState) && signal === 'RESPONDER_RELEASE') { - const {onLongPress, onPress, android_disableSound} = this._config; + const {onLongPress, onPress, getTouchSoundDisabled} = this._config; if (onPress != null) { const isPressCanceledByLongPress = onLongPress != null && @@ -691,7 +646,10 @@ export default class Pressability { this._activate(event); this._deactivate(event); } - if (Platform.OS === 'android' && android_disableSound !== true) { + const isTouchSoundDisabled = + (getTouchSoundDisabled == null ? null : getTouchSoundDisabled()) ?? + false; + if (Platform.OS === 'android' && !isTouchSoundDisabled) { SoundManager.playTouchSound(); } onPress(event); @@ -709,34 +667,23 @@ export default class Pressability { pageX: touch.pageX, pageY: touch.pageY, }; - this._touchActivateTime = Date.now(); if (onPressIn != null) { onPressIn(event); } } _deactivate(event: PressEvent): void { - const {onPressOut} = this._config; + const {onPressOut, getPressOutDelayMS} = this._config; if (onPressOut != null) { - const minPressDuration = normalizeDelay( - this._config.minPressDuration, - 0, - DEFAULT_MIN_PRESS_DURATION, - ); - const pressDuration = Date.now() - (this._touchActivateTime ?? 0); - const delayPressOut = Math.max( - minPressDuration - pressDuration, - normalizeDelay(this._config.delayPressOut), - ); - if (delayPressOut > 0) { + const delay = getDelayMS(getPressOutDelayMS); + if (delay > 0) { this._pressOutDelayTimeout = setTimeout(() => { onPressOut(event); - }, delayPressOut); + }, delay); } else { onPressOut(event); } } - this._touchActivateTime = null; } _measureResponderRegion(): void { @@ -772,14 +719,14 @@ export default class Pressability { top: number, |}>, ): boolean { - const hitSlop = normalizeRect(this._config.hitSlop); - const pressRectOffset = normalizeRect(this._config.pressRectOffset); + const {getHitSlop, getPressRectOffset} = this._config; let regionBottom = responderRegion.bottom; let regionLeft = responderRegion.left; let regionRight = responderRegion.right; let regionTop = responderRegion.top; + const hitSlop = getHitSlop == null ? null : getHitSlop(); if (hitSlop != null) { if (hitSlop.bottom != null) { regionBottom += hitSlop.bottom; @@ -795,11 +742,23 @@ export default class Pressability { } } + const rectOffset = getPressRectOffset == null ? null : getPressRectOffset(); regionBottom += - pressRectOffset?.bottom ?? DEFAULT_PRESS_RECT_OFFSETS.bottom; - regionLeft -= pressRectOffset?.left ?? DEFAULT_PRESS_RECT_OFFSETS.left; - regionRight += pressRectOffset?.right ?? DEFAULT_PRESS_RECT_OFFSETS.right; - regionTop -= pressRectOffset?.top ?? DEFAULT_PRESS_RECT_OFFSETS.top; + rectOffset == null || rectOffset.bottom == null + ? DEFAULT_PRESS_RECT_OFFSETS.bottom + : rectOffset.bottom; + regionLeft -= + rectOffset == null || rectOffset.left == null + ? DEFAULT_PRESS_RECT_OFFSETS.left + : rectOffset.left; + regionRight += + rectOffset == null || rectOffset.right == null + ? DEFAULT_PRESS_RECT_OFFSETS.right + : rectOffset.right; + regionTop -= + rectOffset == null || rectOffset.top == null + ? DEFAULT_PRESS_RECT_OFFSETS.top + : rectOffset.top; return ( touch.pageX > regionLeft && @@ -820,8 +779,8 @@ export default class Pressability { _shouldLongPressCancelPress(): boolean { return ( - this._config.onLongPressShouldCancelPress_DEPRECATED == null || - this._config.onLongPressShouldCancelPress_DEPRECATED() + this._config.onLongPressShouldCancelPress == null || + this._config.onLongPressShouldCancelPress() ); } @@ -861,9 +820,9 @@ export default class Pressability { } } -function normalizeDelay(delay: ?number, min = 0, fallback = 0): number { - return Math.max(min, delay ?? fallback); -} +const getDelayMS = (getDelay: ?() => ?number, min = 0, fallback = 0) => { + return Math.max(min, (getDelay == null ? null : getDelay()) ?? fallback); +}; const getTouchFromPressEvent = (event: PressEvent) => { const {changedTouches, touches} = event.nativeEvent; diff --git a/Libraries/Pressability/PressabilityDebug.js b/Libraries/Pressability/PressabilityDebug.js index 168a8c1d110163..d593c58587e96a 100644 --- a/Libraries/Pressability/PressabilityDebug.js +++ b/Libraries/Pressability/PressabilityDebug.js @@ -10,15 +10,13 @@ 'use strict'; -import normalizeColor from '../StyleSheet/normalizeColor'; -import type {ColorValue} from '../StyleSheet/StyleSheetTypes'; - +import normalizeColor from '../StyleSheet/normalizeColor.js'; import Touchable from '../Components/Touchable/Touchable'; import View from '../Components/View/View'; import * as React from 'react'; type Props = $ReadOnly<{| - color: ColorValue, + color: string, hitSlop: ?$ReadOnly<{| bottom?: ?number, left?: ?number, @@ -45,12 +43,12 @@ type Props = $ReadOnly<{| export function PressabilityDebugView({color, hitSlop}: Props): React.Node { if (__DEV__) { if (isEnabled()) { - const normalizedColor = normalizeColor(color); - if (typeof normalizedColor !== 'number') { - return null; - } + const processedColor = normalizeColor(color); const baseColor = - '#' + (normalizedColor ?? 0).toString(16).padStart(8, '0'); + '#' + + (typeof processedColor === 'number' ? processedColor : 0) + .toString(16) + .padStart(8, '0'); return ( , TReturn>( const createMockPressability = overrides => { const config = { - cancelable: null, - disabled: null, - hitSlop: null, - pressRectOffset: null, - delayHoverIn: null, - delayHoverOut: null, - delayLongPress: null, - delayPressIn: null, - delayPressOut: null, + getHitSlop: jest.fn(), + getHoverInDelayMS: jest.fn(() => null), + getHoverOutDelayMS: jest.fn(() => null), + getLongPressDelayMS: jest.fn(() => null), + getPressDelayMS: jest.fn(() => null), + getPressOutDelayMS: jest.fn(() => null), + getPressRectOffset: jest.fn(), onBlur: jest.fn(), onFocus: jest.fn(), onHoverIn: jest.fn(), onHoverOut: jest.fn(), onLongPress: jest.fn(), + onLongPressShouldCancelPress: jest.fn(), onPress: jest.fn(), onPressIn: jest.fn(), onPressOut: jest.fn(), - onLongPressShouldCancelPress_DEPRECATED: jest.fn(), - onResponderTerminationRequest_DEPRECATED: jest.fn(() => true), - onStartShouldSetResponder_DEPRECATED: jest.fn(() => true), + onResponderTerminationRequest: jest.fn(() => true), + onStartShouldSetResponder: jest.fn(() => true), ...overrides, }; const touchable = new Pressability(config); @@ -232,7 +230,6 @@ const createMockPressEvent = ( describe('Pressability', () => { beforeEach(() => { jest.resetModules(); - jest.spyOn(Date, 'now'); jest.spyOn(HoverState, 'isHoverEnabled'); }); @@ -285,7 +282,7 @@ describe('Pressability', () => { it('is called after no delay by default', () => { const {config, handlers} = createMockPressability({ - delayHoverIn: null, + getHoverInDelayMS: () => null, }); invariant( typeof handlers.onMouseEnter === 'function', @@ -296,9 +293,9 @@ describe('Pressability', () => { expect(config.onHoverIn).toBeCalled(); }); - it('falls back to no delay if `delayHoverIn` is omitted', () => { + it('falls back to no delay if `getHoverInDelayMS` is omitted', () => { const {config, handlers} = createMockPressability({ - delayHoverIn: null, + getHoverInDelayMS: null, }); invariant( typeof handlers.onMouseEnter === 'function', @@ -311,7 +308,7 @@ describe('Pressability', () => { it('is called after a configured delay', () => { const {config, handlers} = createMockPressability({ - delayHoverIn: 500, + getHoverInDelayMS: () => 500, }); invariant( typeof handlers.onMouseEnter === 'function', @@ -327,7 +324,7 @@ describe('Pressability', () => { it('is called synchronously if delay is 0ms', () => { const {config, handlers} = createMockPressability({ - delayHoverIn: 0, + getHoverInDelayMS: () => 0, }); invariant( typeof handlers.onMouseEnter === 'function', @@ -355,16 +352,16 @@ describe('Pressability', () => { expect(config.onLongPress).toBeCalled(); }); - it('is called if pressed for 370ms after the press delay', () => { + it('is called if pressed for 500ms after the press delay', () => { const {config, handlers} = createMockPressability({ - delayPressIn: 100, + getPressDelayMS: () => 100, }); handlers.onStartShouldSetResponder(); handlers.onResponderGrant(createMockPressEvent('onResponderGrant')); handlers.onResponderMove(createMockPressEvent('onResponderMove')); - jest.advanceTimersByTime(469); + jest.advanceTimersByTime(599); expect(config.onLongPress).not.toBeCalled(); jest.advanceTimersByTime(1); expect(config.onLongPress).toBeCalled(); @@ -386,14 +383,14 @@ describe('Pressability', () => { it('falls back to a minimum of 10ms before calling `onLongPress`', () => { const {config, handlers} = createMockPressability({ - delayLongPress: 0, + getLongPressDelayMS: () => 0, }); handlers.onStartShouldSetResponder(); handlers.onResponderGrant(createMockPressEvent('onResponderGrant')); handlers.onResponderMove(createMockPressEvent('onResponderMove')); - jest.advanceTimersByTime(139); + jest.advanceTimersByTime(9); expect(config.onLongPress).not.toBeCalled(); jest.advanceTimersByTime(1); expect(config.onLongPress).toBeCalled(); @@ -455,7 +452,8 @@ describe('Pressability', () => { expect(config.onLongPress).not.toBeCalled(); }); - it('is called independent of preceding long touch gesture', () => { + // TODO: disable failing test. This test is failing upstream as well in 0.62-stable. + it.skip('is called independent of preceding long touch gesture', () => { mockUIManagerMeasure(); const {config, handlers} = createMockPressability(); @@ -506,7 +504,6 @@ describe('Pressability', () => { handlers.onResponderRelease(createMockPressEvent('onResponderRelease')); expect(config.onPress).toBeCalled(); - jest.runOnlyPendingTimers(); expect(config.onPressOut).toBeCalled(); }); }); @@ -522,39 +519,33 @@ describe('Pressability', () => { expect(config.onPressIn).toBeCalled(); }); - it('is called after the default delay by default', () => { + it('is called after no delay by default', () => { const {config, handlers} = createMockPressability({ - delayPressIn: null, + getPressDelayMS: () => null, }); handlers.onStartShouldSetResponder(); handlers.onResponderGrant(createMockPressEvent('onResponderGrant')); handlers.onResponderMove(createMockPressEvent('onResponderMove')); - jest.advanceTimersByTime(129); - expect(config.onPressIn).not.toBeCalled(); - jest.advanceTimersByTime(1); expect(config.onPressIn).toBeCalled(); }); - it('falls back to the default delay if `delayPressIn` is omitted', () => { + it('falls back to no delay if `getPressDelayMS` is omitted', () => { const {config, handlers} = createMockPressability({ - delayPressIn: null, + getPressDelayMS: null, }); handlers.onStartShouldSetResponder(); handlers.onResponderGrant(createMockPressEvent('onResponderGrant')); handlers.onResponderMove(createMockPressEvent('onResponderMove')); - jest.advanceTimersByTime(129); - expect(config.onPressIn).not.toBeCalled(); - jest.advanceTimersByTime(1); expect(config.onPressIn).toBeCalled(); }); it('is called after a configured delay', () => { const {config, handlers} = createMockPressability({ - delayPressIn: 500, + getPressDelayMS: () => 500, }); handlers.onStartShouldSetResponder(); @@ -569,7 +560,7 @@ describe('Pressability', () => { it('is called synchronously if delay is 0ms', () => { const {config, handlers} = createMockPressability({ - delayPressIn: 0, + getPressDelayMS: () => 0, }); handlers.onStartShouldSetResponder(); @@ -580,125 +571,14 @@ describe('Pressability', () => { }); }); - describe('onPressOut', () => { - it('is called after `onResponderRelease` before `delayPressIn`', () => { - const {config, handlers} = createMockPressability(); - - handlers.onStartShouldSetResponder(); - handlers.onResponderGrant(createMockPressEvent('onResponderGrant')); - handlers.onResponderMove(createMockPressEvent('onResponderMove')); - expect(config.onPressIn).not.toBeCalled(); - handlers.onResponderRelease(createMockPressEvent('onResponderRelease')); - - expect(config.onPressOut).not.toBeCalled(); - jest.runOnlyPendingTimers(); - expect(config.onPressOut).toBeCalled(); - }); - - it('is called after `onResponderRelease` after `delayPressIn`', () => { - const {config, handlers} = createMockPressability(); - - handlers.onStartShouldSetResponder(); - handlers.onResponderGrant(createMockPressEvent('onResponderGrant')); - handlers.onResponderMove(createMockPressEvent('onResponderMove')); - jest.runOnlyPendingTimers(); - expect(config.onPressIn).toBeCalled(); - handlers.onResponderRelease(createMockPressEvent('onResponderRelease')); - - expect(config.onPressOut).not.toBeCalled(); - jest.runOnlyPendingTimers(); - expect(config.onPressOut).toBeCalled(); - }); - - it('is not called after `onResponderTerminate` before `delayPressIn`', () => { - const {config, handlers} = createMockPressability(); - - handlers.onStartShouldSetResponder(); - handlers.onResponderGrant(createMockPressEvent('onResponderGrant')); - handlers.onResponderMove(createMockPressEvent('onResponderMove')); - handlers.onResponderTerminate( - createMockPressEvent('onResponderTerminate'), - ); - - expect(config.onPressOut).not.toBeCalled(); - jest.runOnlyPendingTimers(); - expect(config.onPressOut).not.toBeCalled(); - }); - - it('is not called after `onResponderTerminate` after `delayPressIn`', () => { - const {config, handlers} = createMockPressability(); - - handlers.onStartShouldSetResponder(); - handlers.onResponderGrant(createMockPressEvent('onResponderGrant')); - handlers.onResponderMove(createMockPressEvent('onResponderMove')); - jest.runOnlyPendingTimers(); - expect(config.onPressIn).toBeCalled(); - handlers.onResponderTerminate( - createMockPressEvent('onResponderTerminate'), - ); - - expect(config.onPressOut).not.toBeCalled(); - jest.runOnlyPendingTimers(); - expect(config.onPressOut).toBeCalled(); - }); - - it('is called after the minimum press duration by default', () => { - const {config, handlers} = createMockPressability(); - - handlers.onStartShouldSetResponder(); - handlers.onResponderGrant(createMockPressEvent('onResponderGrant')); - handlers.onResponderMove(createMockPressEvent('onResponderMove')); - jest.runOnlyPendingTimers(); - expect(config.onPressIn).toBeCalled(); - handlers.onResponderRelease(createMockPressEvent('onResponderRelease')); - - jest.advanceTimersByTime(120); - expect(config.onPressOut).not.toBeCalled(); - jest.advanceTimersByTime(10); - expect(config.onPressOut).toBeCalled(); - }); - - it('is called after only after the remaining minimum press duration', () => { - const {config, handlers} = createMockPressability(); - - handlers.onStartShouldSetResponder(); - handlers.onResponderGrant(createMockPressEvent('onResponderGrant')); - handlers.onResponderMove(createMockPressEvent('onResponderMove')); - jest.runOnlyPendingTimers(); - expect(config.onPressIn).toBeCalled(); - // WORKAROUND: Jest does not advance `Date.now()`. - const touchActivateTime = Date.now(); - jest.advanceTimersByTime(120); - Date.now.mockReturnValue(touchActivateTime + 120); - handlers.onResponderRelease(createMockPressEvent('onResponderRelease')); - - expect(config.onPressOut).not.toBeCalled(); - jest.advanceTimersByTime(10); - expect(config.onPressOut).toBeCalled(); - }); - - it('is called synchronously if minimum press duration is 0ms', () => { - const {config, handlers} = createMockPressability({ - minPressDuration: 0, - }); - - handlers.onStartShouldSetResponder(); - handlers.onResponderGrant(createMockPressEvent('onResponderGrant')); - handlers.onResponderMove(createMockPressEvent('onResponderMove')); - jest.runOnlyPendingTimers(); - expect(config.onPressIn).toBeCalled(); - handlers.onResponderRelease(createMockPressEvent('onResponderRelease')); - - expect(config.onPressOut).toBeCalled(); - }); - }); + // TODO: onPressOut tests describe('`onPress*` with movement', () => { describe('within bounds of hit rect', () => { it('`onPress*` are called when no delay', () => { mockUIManagerMeasure(); const {config, handlers} = createMockPressability({ - hitSlop: mockSlop, + getHitSlop: () => mockSlop, }); handlers.onStartShouldSetResponder(); @@ -724,15 +604,14 @@ describe('Pressability', () => { expect(config.onPressIn).toBeCalled(); expect(config.onPress).toBeCalled(); - jest.runOnlyPendingTimers(); expect(config.onPressOut).toBeCalled(); }); it('`onPress*` are called after a delay', () => { mockUIManagerMeasure(); const {config, handlers} = createMockPressability({ - hitSlop: mockSlop, - delayPressIn: 500, + getHitSlop: () => mockSlop, + getPressDelayMS: () => 500, }); handlers.onStartShouldSetResponder(); @@ -762,7 +641,6 @@ describe('Pressability', () => { handlers.onResponderRelease(createMockPressEvent('onResponderRelease')); expect(config.onPress).toBeCalled(); - jest.runOnlyPendingTimers(); expect(config.onPressOut).toBeCalled(); }); }); @@ -770,9 +648,7 @@ describe('Pressability', () => { describe('beyond bounds of hit rect', () => { it('`onPress` only is not called when no delay', () => { mockUIManagerMeasure(); - const {config, handlers} = createMockPressability({ - delayPressIn: 0, - }); + const {config, handlers} = createMockPressability(); handlers.onStartShouldSetResponder(); handlers.onResponderGrant(createMockPressEvent('onResponderGrant')); @@ -791,14 +667,13 @@ describe('Pressability', () => { handlers.onResponderRelease(createMockPressEvent('onResponderRelease')); expect(config.onPress).not.toBeCalled(); - jest.runOnlyPendingTimers(); expect(config.onPressOut).toBeCalled(); }); it('`onPress*` are not called after a delay', () => { mockUIManagerMeasure(); const {config, handlers} = createMockPressability({ - delayPressIn: 500, + getPressDelayMS: () => 500, }); handlers.onStartShouldSetResponder(); @@ -825,7 +700,7 @@ describe('Pressability', () => { it('`onPress*` are called when press is released before measure completes', () => { mockUIManagerMeasure({delay: 1000}); const {config, handlers} = createMockPressability({ - delayPressIn: 500, + getPressDelayMS: () => 500, }); handlers.onStartShouldSetResponder(); @@ -849,7 +724,6 @@ describe('Pressability', () => { handlers.onResponderRelease(createMockPressEvent('onResponderRelease')); expect(config.onPress).toBeCalled(); - jest.runOnlyPendingTimers(); expect(config.onPressOut).toBeCalled(); }); }); @@ -858,7 +732,7 @@ describe('Pressability', () => { describe('onStartShouldSetResponder', () => { it('if omitted the responder is set by default', () => { const {handlers} = createMockPressability({ - onStartShouldSetResponder_DEPRECATED: null, + onStartShouldSetResponder: null, }); expect(handlers.onStartShouldSetResponder()).toBe(true); @@ -866,14 +740,11 @@ describe('Pressability', () => { it('if supplied it is called', () => { const {config, handlers} = createMockPressability(); - const onStartShouldSetResponder_DEPRECATED = nullthrows( - config.onStartShouldSetResponder_DEPRECATED, - ); - onStartShouldSetResponder_DEPRECATED.mockReturnValue(false); + nullthrows(config.onStartShouldSetResponder).mockReturnValue(false); expect(handlers.onStartShouldSetResponder()).toBe(false); - onStartShouldSetResponder_DEPRECATED.mockReturnValue(true); + nullthrows(config.onStartShouldSetResponder).mockReturnValue(true); expect(handlers.onStartShouldSetResponder()).toBe(true); }); }); diff --git a/Libraries/Pressability/usePressability.js b/Libraries/Pressability/usePressability.js deleted file mode 100644 index 3538524239387b..00000000000000 --- a/Libraries/Pressability/usePressability.js +++ /dev/null @@ -1,43 +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. - * - * @flow strict-local - * @format - */ - -'use strict'; - -import Pressability, { - type EventHandlers, - type PressabilityConfig, -} from './Pressability'; -import {useEffect, useRef} from 'react'; - -export default function usePressability( - config: PressabilityConfig, -): EventHandlers { - const pressabilityRef = useRef(null); - if (pressabilityRef.current == null) { - pressabilityRef.current = new Pressability(config); - } - const pressability = pressabilityRef.current; - - // On the initial mount, this is a no-op. On updates, `pressability` will be - // re-configured to use the new configuration. - useEffect(() => { - pressability.configure(config); - }, [config, pressability]); - - // On unmount, reset pending state and timers inside `pressability`. This is - // a separate effect because we do not want to reset when `config` changes. - useEffect(() => { - return () => { - pressability.reset(); - }; - }, [pressability]); - - return pressability.getEventHandlers(); -} diff --git a/Libraries/PushNotificationIOS/PushNotificationIOS.js b/Libraries/PushNotificationIOS/PushNotificationIOS.js index 88f0b0812ff7c8..922e0173c60495 100644 --- a/Libraries/PushNotificationIOS/PushNotificationIOS.js +++ b/Libraries/PushNotificationIOS/PushNotificationIOS.js @@ -68,7 +68,7 @@ export type PushNotificationEventName = $Keys<{ * Handle push notifications for your app, including permission handling and * icon badge number. * - * See https://reactnative.dev/docs/pushnotificationios.html + * See https://facebook.github.io/react-native/docs/pushnotificationios.html */ class PushNotificationIOS { _data: Object; @@ -91,7 +91,7 @@ class PushNotificationIOS { /** * Schedules the localNotification for immediate presentation. * - * See https://reactnative.dev/docs/pushnotificationios.html#presentlocalnotification + * See https://facebook.github.io/react-native/docs/pushnotificationios.html#presentlocalnotification */ static presentLocalNotification(details: Object) { invariant( @@ -104,7 +104,7 @@ class PushNotificationIOS { /** * Schedules the localNotification for future presentation. * - * See https://reactnative.dev/docs/pushnotificationios.html#schedulelocalnotification + * See https://facebook.github.io/react-native/docs/pushnotificationios.html#schedulelocalnotification */ static scheduleLocalNotification(details: Object) { invariant( @@ -117,7 +117,7 @@ class PushNotificationIOS { /** * Cancels all scheduled localNotifications. * - * See https://reactnative.dev/docs/pushnotificationios.html#cancelalllocalnotifications + * See https://facebook.github.io/react-native/docs/pushnotificationios.html#cancelalllocalnotifications */ static cancelAllLocalNotifications() { invariant( @@ -130,7 +130,7 @@ class PushNotificationIOS { /** * Remove all delivered notifications from Notification Center. * - * See https://reactnative.dev/docs/pushnotificationios.html#removealldeliverednotifications + * See https://facebook.github.io/react-native/docs/pushnotificationios.html#removealldeliverednotifications */ static removeAllDeliveredNotifications(): void { invariant( @@ -143,7 +143,7 @@ class PushNotificationIOS { /** * Provides you with a list of the app’s notifications that are still displayed in Notification Center. * - * See https://reactnative.dev/docs/pushnotificationios.html#getdeliverednotifications + * See https://facebook.github.io/react-native/docs/pushnotificationios.html#getdeliverednotifications */ static getDeliveredNotifications( callback: (notifications: Array) => void, @@ -158,7 +158,7 @@ class PushNotificationIOS { /** * Removes the specified notifications from Notification Center * - * See https://reactnative.dev/docs/pushnotificationios.html#removedeliverednotifications + * See https://facebook.github.io/react-native/docs/pushnotificationios.html#removedeliverednotifications */ static removeDeliveredNotifications(identifiers: Array): void { invariant( @@ -171,7 +171,7 @@ class PushNotificationIOS { /** * Sets the badge number for the app icon on the home screen. * - * See https://reactnative.dev/docs/pushnotificationios.html#setapplicationiconbadgenumber + * See https://facebook.github.io/react-native/docs/pushnotificationios.html#setapplicationiconbadgenumber */ static setApplicationIconBadgeNumber(number: number) { invariant( @@ -184,7 +184,7 @@ class PushNotificationIOS { /** * Gets the current badge number for the app icon on the home screen. * - * See https://reactnative.dev/docs/pushnotificationios.html#getapplicationiconbadgenumber + * See https://facebook.github.io/react-native/docs/pushnotificationios.html#getapplicationiconbadgenumber */ static getApplicationIconBadgeNumber(callback: Function) { invariant( @@ -197,7 +197,7 @@ class PushNotificationIOS { /** * Cancel local notifications. * - * See https://reactnative.dev/docs/pushnotificationios.html#cancellocalnotification + * See https://facebook.github.io/react-native/docs/pushnotificationios.html#cancellocalnotification */ static cancelLocalNotifications(userInfo: Object) { invariant( @@ -210,7 +210,7 @@ class PushNotificationIOS { /** * Gets the local notifications that are currently scheduled. * - * See https://reactnative.dev/docs/pushnotificationios.html#getscheduledlocalnotifications + * See https://facebook.github.io/react-native/docs/pushnotificationios.html#getscheduledlocalnotifications */ static getScheduledLocalNotifications(callback: Function) { invariant( @@ -224,7 +224,7 @@ class PushNotificationIOS { * Attaches a listener to remote or local notification events while the app * is running in the foreground or the background. * - * See https://reactnative.dev/docs/pushnotificationios.html#addeventlistener + * See https://facebook.github.io/react-native/docs/pushnotificationios.html#addeventlistener */ static addEventListener(type: PushNotificationEventName, handler: Function) { invariant( @@ -271,7 +271,7 @@ class PushNotificationIOS { * Removes the event listener. Do this in `componentWillUnmount` to prevent * memory leaks. * - * See https://reactnative.dev/docs/pushnotificationios.html#removeeventlistener + * See https://facebook.github.io/react-native/docs/pushnotificationios.html#removeeventlistener */ static removeEventListener( type: PushNotificationEventName, @@ -298,7 +298,7 @@ class PushNotificationIOS { * a subset of these can be requested by passing a map of requested * permissions. * - * See https://reactnative.dev/docs/pushnotificationios.html#requestpermissions + * See https://facebook.github.io/react-native/docs/pushnotificationios.html#requestpermissions */ static requestPermissions(permissions?: { alert?: boolean, @@ -335,7 +335,7 @@ class PushNotificationIOS { /** * Unregister for all remote notifications received via Apple Push Notification service. * - * See https://reactnative.dev/docs/pushnotificationios.html#abandonpermissions + * See https://facebook.github.io/react-native/docs/pushnotificationios.html#abandonpermissions */ static abandonPermissions() { invariant( @@ -349,7 +349,7 @@ class PushNotificationIOS { * See what push permissions are currently enabled. `callback` will be * invoked with a `permissions` object. * - * See https://reactnative.dev/docs/pushnotificationios.html#checkpermissions + * See https://facebook.github.io/react-native/docs/pushnotificationios.html#checkpermissions */ static checkPermissions(callback: Function) { invariant(typeof callback === 'function', 'Must provide a valid callback'); @@ -364,7 +364,7 @@ class PushNotificationIOS { * This method returns a promise that resolves to either the notification * object if the app was launched by a push notification, or `null` otherwise. * - * See https://reactnative.dev/docs/pushnotificationios.html#getinitialnotification + * See https://facebook.github.io/react-native/docs/pushnotificationios.html#getinitialnotification */ static getInitialNotification(): Promise { invariant( @@ -422,7 +422,7 @@ class PushNotificationIOS { * This method is available for remote notifications that have been received via: * `application:didReceiveRemoteNotification:fetchCompletionHandler:` * - * See https://reactnative.dev/docs/pushnotificationios.html#finish + * See https://facebook.github.io/react-native/docs/pushnotificationios.html#finish */ finish(fetchResult: string) { if ( @@ -456,7 +456,7 @@ class PushNotificationIOS { /** * Gets the sound string from the `aps` object * - * See https://reactnative.dev/docs/pushnotificationios.html#getsound + * See https://facebook.github.io/react-native/docs/pushnotificationios.html#getsound */ getSound(): ?string { return this._sound; @@ -465,7 +465,7 @@ class PushNotificationIOS { /** * Gets the category string from the `aps` object * - * See https://reactnative.dev/docs/pushnotificationios.html#getcategory + * See https://facebook.github.io/react-native/docs/pushnotificationios.html#getcategory */ getCategory(): ?string { return this._category; @@ -474,7 +474,7 @@ class PushNotificationIOS { /** * Gets the notification's main message from the `aps` object * - * See https://reactnative.dev/docs/pushnotificationios.html#getalert + * See https://facebook.github.io/react-native/docs/pushnotificationios.html#getalert */ getAlert(): ?string | ?Object { return this._alert; @@ -483,7 +483,7 @@ class PushNotificationIOS { /** * Gets the content-available number from the `aps` object * - * See https://reactnative.dev/docs/pushnotificationios.html#getcontentavailable + * See https://facebook.github.io/react-native/docs/pushnotificationios.html#getcontentavailable */ getContentAvailable(): ContentAvailable { return this._contentAvailable; @@ -492,7 +492,7 @@ class PushNotificationIOS { /** * Gets the badge count number from the `aps` object * - * See https://reactnative.dev/docs/pushnotificationios.html#getbadgecount + * See https://facebook.github.io/react-native/docs/pushnotificationios.html#getbadgecount */ getBadgeCount(): ?number { return this._badgeCount; @@ -501,7 +501,7 @@ class PushNotificationIOS { /** * Gets the data object on the notif * - * See https://reactnative.dev/docs/pushnotificationios.html#getdata + * See https://facebook.github.io/react-native/docs/pushnotificationios.html#getdata */ getData(): ?Object { return this._data; @@ -510,7 +510,7 @@ class PushNotificationIOS { /** * Gets the thread ID on the notif * - * See https://reactnative.dev/docs/pushnotificationios.html#getthreadid + * See https://facebook.github.io/react-native/docs/pushnotificationios.html#getthreadid */ getThreadID(): ?string { return this._threadID; diff --git a/Libraries/PushNotificationIOS/RCTPushNotificationManager.mm b/Libraries/PushNotificationIOS/RCTPushNotificationManager.mm index eca5613721e646..b699e1880fb413 100644 --- a/Libraries/PushNotificationIOS/RCTPushNotificationManager.mm +++ b/Libraries/PushNotificationIOS/RCTPushNotificationManager.mm @@ -23,11 +23,12 @@ static NSString *const kLocalNotificationReceived = @"LocalNotificationReceived"; static NSString *const kRemoteNotificationsRegistered = @"RemoteNotificationsRegistered"; +static NSString *const kRegisterUserNotificationSettings = @"RegisterUserNotificationSettings"; static NSString *const kRemoteNotificationRegistrationFailed = @"RemoteNotificationRegistrationFailed"; static NSString *const kErrorUnableToRequestPermissions = @"E_UNABLE_TO_REQUEST_PERMISSIONS"; -#if !TARGET_OS_TV +#if !TARGET_OS_TV && !TARGET_OS_UIKITFORMAC @implementation RCTConvert (NSCalendarUnit) RCT_ENUM_CONVERTER(NSCalendarUnit, @@ -123,6 +124,9 @@ @interface RCTPushNotificationManager () #endif //TARGET_OS_TV / TARGET_OS_UIKITFORMAC @implementation RCTPushNotificationManager +{ + RCTPromiseResolveBlock _requestPermissionsResolveBlock; +} #if !TARGET_OS_TV && !TARGET_OS_UIKITFORMAC && !TARGET_OS_OSX @@ -209,6 +213,10 @@ - (void)startObserving selector:@selector(handleRemoteNotificationReceived:) name:RCTRemoteNotificationReceived object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(handleRegisterUserNotificationSettings:) + name:kRegisterUserNotificationSettings + object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleRemoteNotificationsRegistered:) name:kRemoteNotificationsRegistered @@ -235,11 +243,23 @@ - (void)stopObserving #if !TARGET_OS_OSX // TODO(macOS ISS#2323203) + (void)didRegisterUserNotificationSettings:(__unused UIUserNotificationSettings *)notificationSettings { + if ([UIApplication instancesRespondToSelector:@selector(registerForRemoteNotifications)]) { + [RCTSharedApplication() registerForRemoteNotifications]; + [[NSNotificationCenter defaultCenter] postNotificationName:kRegisterUserNotificationSettings + object:self + userInfo:@{@"notificationSettings": notificationSettings}]; + } } #endif // TODO(macOS ISS#2323203) + (void)didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { +#if TARGET_OS_OSX // [TODO(macOS ISS#2323203) + [[NSNotificationCenter defaultCenter] postNotificationName:kRegisterUserNotificationSettings + object:self + userInfo:@{@"notificationSettings": @(RCTSharedApplication().enabledRemoteNotificationTypes)}]; +#endif // ]TODO(macOS ISS#2323203) + NSMutableString *hexString = [NSMutableString string]; NSUInteger deviceTokenLength = deviceToken.length; const unsigned char *bytes = reinterpret_cast(deviceToken.bytes); @@ -339,6 +359,34 @@ - (void)handleRemoteNotificationRegistrationError:(NSNotification *)notification [self sendEventWithName:@"remoteNotificationRegistrationError" body:errorDetails]; } +- (void)handleRegisterUserNotificationSettings:(NSNotification *)notification +{ + if (_requestPermissionsResolveBlock == nil) { + return; + } + +#if !TARGET_OS_OSX // TODO(macOS ISS#2323203) + UIUserNotificationSettings *notificationSettings = notification.userInfo[@"notificationSettings"]; + NSDictionary *notificationTypes = @{ + @"alert": @((notificationSettings.types & UIUserNotificationTypeAlert) > 0), + @"sound": @((notificationSettings.types & UIUserNotificationTypeSound) > 0), + @"badge": @((notificationSettings.types & UIUserNotificationTypeBadge) > 0), + }; +#else // [TODO(macOS ISS#2323203) + NSRemoteNotificationType remoteNotificationType = [notification.userInfo[@"notificationSettings"] unsignedIntegerValue]; + NSDictionary *notificationTypes = @{ + @"alert": @((remoteNotificationType & NSRemoteNotificationTypeAlert) > 0), + @"sound": @((remoteNotificationType & NSRemoteNotificationTypeSound) > 0), + @"badge": @((remoteNotificationType & NSRemoteNotificationTypeBadge) > 0), + }; +#endif // ]TODO(macOS ISS#2323203) + + _requestPermissionsResolveBlock(notificationTypes); + // Clean up listener added in requestPermissions + [self removeListeners:1]; + _requestPermissionsResolveBlock = nil; +} + #if !TARGET_OS_OSX // TODO(macOS ISS#2323203) RCT_EXPORT_METHOD(onFinishRemoteNotification:(NSString *)notificationId fetchResult:(NSString *)fetchResult) { UIBackgroundFetchResult result = [RCTConvert UIBackgroundFetchResult:fetchResult]; @@ -389,8 +437,14 @@ - (void)handleRemoteNotificationRegistrationError:(NSNotification *)notification } #endif // TODO(macOS ISS#2323203) + if (_requestPermissionsResolveBlock != nil) { + RCTLogError(@"Cannot call requestPermissions twice before the first has returned."); + return; + } + // Add a listener to make sure that startObserving has been called [self addListener:@"remoteNotificationsRegistered"]; + _requestPermissionsResolveBlock = resolve; #if !TARGET_OS_OSX // TODO(macOS ISS#2323203) UIUserNotificationType types = UIUserNotificationTypeNone; @@ -405,18 +459,9 @@ - (void)handleRemoteNotificationRegistrationError:(NSNotification *)notification types |= UIUserNotificationTypeSound; } - [UNUserNotificationCenter.currentNotificationCenter - requestAuthorizationWithOptions:types - completionHandler:^(BOOL granted, NSError *_Nullable error) { - if (error != NULL) { - reject(@"-1", @"Error - Push authorization request failed.", error); - } else { - [RCTSharedApplication() registerForRemoteNotifications]; - [UNUserNotificationCenter.currentNotificationCenter getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) { - resolve(RCTPromiseResolveValueForUNNotificationSettings(settings)); - }]; - } - }]; + UIUserNotificationSettings *notificationSettings = + [UIUserNotificationSettings settingsForTypes:types categories:nil]; + [RCTSharedApplication() registerUserNotificationSettings:notificationSettings]; #else // [TODO(macOS ISS#2323203) NSRemoteNotificationType types = NSRemoteNotificationTypeNone; if (permissions.alert()) { @@ -441,15 +486,18 @@ - (void)handleRemoteNotificationRegistrationError:(NSNotification *)notification { #if !TARGET_OS_OSX // TODO(macOS ISS#2323203) if (RCTRunningInAppExtension()) { - callback(@[RCTSettingsDictForUNNotificationSettings(NO, NO, NO)]); + callback(@[@{@"alert": @NO, @"badge": @NO, @"sound": @NO}]); return; } #endif // TODO(macOS ISS#2323203) #if !TARGET_OS_OSX // TODO(macOS ISS#2323203) - [UNUserNotificationCenter.currentNotificationCenter getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) { - callback(@[RCTPromiseResolveValueForUNNotificationSettings(settings)]); - }]; + NSUInteger types = [RCTSharedApplication() currentUserNotificationSettings].types; + callback(@[@{ + @"alert": @((types & UIUserNotificationTypeAlert) > 0), + @"badge": @((types & UIUserNotificationTypeBadge) > 0), + @"sound": @((types & UIUserNotificationTypeSound) > 0), + }]); #else // [TODO(macOS ISS#2323203) NSRemoteNotificationType types = RCTSharedApplication().enabledRemoteNotificationTypes; callback(@[@{ @@ -460,18 +508,6 @@ - (void)handleRemoteNotificationRegistrationError:(NSNotification *)notification #endif // ]TODO(macOS ISS#2323203) } -#if !TARGET_OS_OSX // TODO(macOS ISS#2323203) -static inline NSDictionary *RCTPromiseResolveValueForUNNotificationSettings(UNNotificationSettings* _Nonnull settings) { - return RCTSettingsDictForUNNotificationSettings(settings.alertSetting == UNNotificationSettingEnabled, - settings.badgeSetting == UNNotificationSettingEnabled, - settings.soundSetting == UNNotificationSettingEnabled); -} -#endif - -static inline NSDictionary *RCTSettingsDictForUNNotificationSettings(BOOL alert, BOOL badge, BOOL sound) { - return @{@"alert": @(alert), @"badge": @(badge), @"sound": @(sound)}; -} - #if !TARGET_OS_OSX RCT_EXPORT_METHOD(presentLocalNotification:(JS::NativePushNotificationManagerIOS::Notification &)notification) { @@ -619,8 +655,11 @@ - (void)handleRemoteNotificationRegistrationError:(NSNotification *)notification RCT_EXPORT_METHOD(removeAllDeliveredNotifications) { #if !TARGET_OS_OSX // TODO(macOS ISS#2323203) - UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; - [center removeAllDeliveredNotifications]; + // TODO: T56867629 + if (@available(iOS 10.0, tvOS 10.0, *)) { + UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; + [center removeAllDeliveredNotifications]; + } #else // [TODO(macOS ISS#2323203) [[NSUserNotificationCenter defaultUserNotificationCenter] removeAllDeliveredNotifications]; #endif // ]TODO(macOS ISS#2323203) @@ -629,8 +668,11 @@ - (void)handleRemoteNotificationRegistrationError:(NSNotification *)notification RCT_EXPORT_METHOD(removeDeliveredNotifications:(NSArray *)identifiers) { #if !TARGET_OS_OSX // TODO(macOS ISS#2323203) - UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; - [center removeDeliveredNotificationsWithIdentifiers:identifiers]; + // TODO: T56867629 + if (@available(iOS 10.0, tvOS 10.0, *)) { + UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; + [center removeDeliveredNotificationsWithIdentifiers:identifiers]; + } #else // [TODO(macOS ISS#2323203) NSArray *notificationsToRemove = [[NSUserNotificationCenter defaultUserNotificationCenter].deliveredNotifications filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(NSUserNotification* evaluatedObject, NSDictionary * _Nullable bindings) { return [identifiers containsObject:evaluatedObject.identifier]; @@ -644,15 +686,18 @@ - (void)handleRemoteNotificationRegistrationError:(NSNotification *)notification RCT_EXPORT_METHOD(getDeliveredNotifications:(RCTResponseSenderBlock)callback) { #if !TARGET_OS_OSX // TODO(macOS ISS#2323203) - UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; - [center getDeliveredNotificationsWithCompletionHandler:^(NSArray *_Nonnull notifications) { - NSMutableArray *formattedNotifications = [NSMutableArray new]; - - for (UNNotification *notification in notifications) { - [formattedNotifications addObject:RCTFormatUNNotification(notification)]; - } - callback(@[formattedNotifications]); - }]; + // TODO: T56867629 + if (@available(iOS 10.0, tvOS 10.0, *)) { + UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; + [center getDeliveredNotificationsWithCompletionHandler:^(NSArray *_Nonnull notifications) { + NSMutableArray *formattedNotifications = [NSMutableArray new]; + + for (UNNotification *notification in notifications) { + [formattedNotifications addObject:RCTFormatUNNotification(notification)]; + } + callback(@[formattedNotifications]); + }]; + } #else // [TODO(macOS ISS#2323203) NSMutableArray *formattedNotifications = [NSMutableArray new]; for (NSUserNotification *notification in [NSUserNotificationCenter defaultUserNotificationCenter].deliveredNotifications) { @@ -749,12 +794,9 @@ - (void)handleRemoteNotificationRegistrationError:(NSNotification *)notification #endif //TARGET_OS_TV / TARGET_OS_UIKITFORMAC -- (std::shared_ptr) - getTurboModuleWithJsInvoker:(std::shared_ptr)jsInvoker - nativeInvoker:(std::shared_ptr)nativeInvoker - perfLogger:(id)perfLogger +- (std::shared_ptr)getTurboModuleWithJsInvoker:(std::shared_ptr)jsInvoker { - return std::make_shared(self, jsInvoker, nativeInvoker, perfLogger); + return std::make_shared(self, jsInvoker); } @end diff --git a/Libraries/PushNotificationIOS/React-RCTPushNotification.podspec b/Libraries/PushNotificationIOS/React-RCTPushNotification.podspec index 05c056cfea415a..48bbc07bb438dd 100644 --- a/Libraries/PushNotificationIOS/React-RCTPushNotification.podspec +++ b/Libraries/PushNotificationIOS/React-RCTPushNotification.podspec @@ -17,17 +17,17 @@ else end folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32' -folly_version = '2020.01.13.00' +folly_version = '2018.10.22.00' Pod::Spec.new do |s| s.name = "React-RCTPushNotification" s.version = version s.summary = "A library for handling push notifications for your app, including permission handling and icon badge number." - s.homepage = "https://reactnative.dev/" - s.documentation_url = "https://reactnative.dev/docs/pushnotificationios" + s.homepage = "http://facebook.github.io/react-native/" + s.documentation_url = "https://facebook.github.io/react-native/docs/pushnotificationios" s.license = package["license"] s.author = "Facebook, Inc. and its affiliates" - s.platforms = { :ios => "10.0", :tvos => "10.0", :osx => "10.13" } # TODO(macOS GH#214) + s.platforms = { :ios => "9.0", :tvos => "9.2", :osx => "10.13" } # TODO(macOS GH#214) s.compiler_flags = folly_compiler_flags + ' -Wno-nullability-completeness' s.source = source s.source_files = "*.{m,mm}" @@ -44,5 +44,4 @@ Pod::Spec.new do |s| s.dependency "RCTTypeSafety", version s.dependency "React-Core/RCTPushNotificationHeaders", version s.dependency "ReactCommon/turbomodule/core", version - s.dependency "React-jsi", version end diff --git a/Libraries/RCTRequired/BUCK b/Libraries/RCTRequired/BUCK index 396f41b3f98e50..d061b9e31e92aa 100644 --- a/Libraries/RCTRequired/BUCK +++ b/Libraries/RCTRequired/BUCK @@ -3,9 +3,7 @@ load("//tools/build_defs/oss:rn_defs.bzl", "fb_apple_library") fb_apple_library( name = "RCTRequired", autoglob = True, - complete_nullability = True, contacts = ["oncall+react_native@xmail.facebook.com"], - extension_api_only = True, frameworks = ["Foundation"], - labels = ["supermodule:ios/default/public.react_native.infra"], + labels = ["supermodule:ios/isolation/infra.react_native"], ) diff --git a/Libraries/RCTRequired/RCTRequired.podspec b/Libraries/RCTRequired/RCTRequired.podspec index 063d4fce0b2f45..0b8335b533f56a 100644 --- a/Libraries/RCTRequired/RCTRequired.podspec +++ b/Libraries/RCTRequired/RCTRequired.podspec @@ -20,10 +20,10 @@ Pod::Spec.new do |s| s.name = "RCTRequired" s.version = version s.summary = "-" # TODO - s.homepage = "https://reactnative.dev/" + s.homepage = "http://facebook.github.io/react-native/" s.license = package["license"] s.author = "Facebook, Inc. and its affiliates" - s.platforms = { :ios => "10.0", :tvos => "10.0", :osx => "10.13" } # TODO(macOS ISS#2323203) + s.platforms = { :ios => "9.0", :tvos => "9.2", :osx => "10.13" } # TODO(macOS ISS#2323203) s.source = source s.source_files = "**/*.{c,h,m,mm,cpp}" s.header_dir = "RCTRequired" diff --git a/Libraries/ReactNative/AppContainer.js b/Libraries/ReactNative/AppContainer.js index 22e3bd3bef1883..eab3b420958363 100644 --- a/Libraries/ReactNative/AppContainer.js +++ b/Libraries/ReactNative/AppContainer.js @@ -14,6 +14,7 @@ const EmitterSubscription = require('../vendor/emitter/EmitterSubscription'); const PropTypes = require('prop-types'); const RCTDeviceEventEmitter = require('../EventEmitter/RCTDeviceEventEmitter'); const React = require('react'); +const ReactNative = require('../Renderer/shims/ReactNative'); const RootTagContext = require('./RootTagContext'); const StyleSheet = require('../StyleSheet/StyleSheet'); const View = require('../Components/View/View'); @@ -67,11 +68,14 @@ class AppContainer extends React.Component { const Inspector = require('../Inspector/Inspector'); const inspector = this.state.inspector ? null : ( { + inspectedViewTag={ReactNative.findNodeHandle(this._mainRef)} + onRequestRerenderApp={updateInspectedViewTag => { this.setState( s => ({mainKey: s.mainKey + 1}), - () => updateInspectedView(this._mainRef), + () => + updateInspectedViewTag( + ReactNative.findNodeHandle(this._mainRef), + ), ); }} /> @@ -90,15 +94,14 @@ class AppContainer extends React.Component { } render(): React.Node { - let logBox = null; + let yellowBox = null; if (__DEV__) { if ( !global.__RCTProfileIsProfiling && !this.props.internal_excludeLogBox ) { - const LogBoxNotificationContainer = require('../LogBox/LogBoxNotificationContainer') - .default; - logBox = ; + const YellowBox = require('../YellowBox/YellowBox'); + yellowBox = ; } } @@ -132,7 +135,7 @@ class AppContainer extends React.Component { {!this.state.hasError && innerView} {this.state.inspector} - {logBox} + {yellowBox} ); @@ -147,8 +150,8 @@ const styles = StyleSheet.create({ if (__DEV__) { if (!global.__RCTProfileIsProfiling) { - const LogBox = require('../LogBox/LogBox'); - LogBox.install(); + const YellowBox = require('../YellowBox/YellowBox'); + YellowBox.install(); } } diff --git a/Libraries/ReactNative/AppRegistry.js b/Libraries/ReactNative/AppRegistry.js index 99abee3e0d792e..6dc813731327ac 100644 --- a/Libraries/ReactNative/AppRegistry.js +++ b/Libraries/ReactNative/AppRegistry.js @@ -69,7 +69,7 @@ let showArchitectureIndicator = false; /** * `AppRegistry` is the JavaScript entry point to running all React Native apps. * - * See https://reactnative.dev/docs/appregistry.html + * See http://facebook.github.io/react-native/docs/appregistry.html */ const AppRegistry = { setWrapperComponentProvider(provider: WrapperComponentProvider) { @@ -103,7 +103,7 @@ const AppRegistry = { /** * Registers an app's root component. * - * See https://reactnative.dev/docs/appregistry.html#registercomponent + * See http://facebook.github.io/react-native/docs/appregistry.html#registercomponent */ registerComponent( appKey: string, @@ -178,7 +178,7 @@ const AppRegistry = { /** * Loads the JavaScript bundle and runs the app. * - * See https://reactnative.dev/docs/appregistry.html#runapplication + * See http://facebook.github.io/react-native/docs/appregistry.html#runapplication */ runApplication(appKey: string, appParameters: any): void { if (appKey !== 'LogBox') { @@ -205,7 +205,7 @@ const AppRegistry = { /** * Stops an application when a view should be destroyed. * - * See https://reactnative.dev/docs/appregistry.html#unmountapplicationcomponentatroottag + * See http://facebook.github.io/react-native/docs/appregistry.html#unmountapplicationcomponentatroottag */ unmountApplicationComponentAtRootTag(rootTag: number): void { ReactNative.unmountComponentAtNodeAndRemoveContainer(rootTag); @@ -214,7 +214,7 @@ const AppRegistry = { /** * Register a headless task. A headless task is a bit of code that runs without a UI. * - * See https://reactnative.dev/docs/appregistry.html#registerheadlesstask + * See http://facebook.github.io/react-native/docs/appregistry.html#registerheadlesstask */ registerHeadlessTask(taskKey: string, taskProvider: TaskProvider): void { this.registerCancellableHeadlessTask(taskKey, taskProvider, () => () => { @@ -225,7 +225,7 @@ const AppRegistry = { /** * Register a cancellable headless task. A headless task is a bit of code that runs without a UI. * - * See https://reactnative.dev/docs/appregistry.html#registercancellableheadlesstask + * See http://facebook.github.io/react-native/docs/appregistry.html#registercancellableheadlesstask */ registerCancellableHeadlessTask( taskKey: string, @@ -244,7 +244,7 @@ const AppRegistry = { /** * Only called from native code. Starts a headless task. * - * See https://reactnative.dev/docs/appregistry.html#startheadlesstask + * See http://facebook.github.io/react-native/docs/appregistry.html#startheadlesstask */ startHeadlessTask(taskId: number, taskKey: string, data: any): void { const taskProvider = taskProviders.get(taskKey); @@ -282,7 +282,7 @@ const AppRegistry = { /** * Only called from native code. Cancels a headless task. * - * See https://reactnative.dev/docs/appregistry.html#cancelheadlesstask + * See http://facebook.github.io/react-native/docs/appregistry.html#cancelheadlesstask */ cancelHeadlessTask(taskId: number, taskKey: string): void { const taskCancelProvider = taskCancelProviders.get(taskKey); diff --git a/Libraries/ReactNative/DummyUIManager.js b/Libraries/ReactNative/DummyUIManager.js index bf918219c79496..a6ae78a9624566 100644 --- a/Libraries/ReactNative/DummyUIManager.js +++ b/Libraries/ReactNative/DummyUIManager.js @@ -10,13 +10,10 @@ 'use strict'; module.exports = { - getViewManagerConfig: (viewManagerName: string): mixed => { + getViewManagerConfig: (viewManagerName: string): null => { console.warn( 'Attempting to get config for view manager: ' + viewManagerName, ); - if (viewManagerName === 'RCTVirtualText') { - return {}; - } return null; }, getConstants: (): {...} => ({}), diff --git a/Libraries/ReactNative/FabricUIManager.js b/Libraries/ReactNative/FabricUIManager.js index 0aeecb4b8c9948..7424d51d45b308 100644 --- a/Libraries/ReactNative/FabricUIManager.js +++ b/Libraries/ReactNative/FabricUIManager.js @@ -49,6 +49,7 @@ type Spec = {| onFail: () => void, onSuccess: MeasureLayoutOnSuccessCallback, ) => void, + +findShadowNodeByTag_DEPRECATED: (reactTag: number) => ?Node, |}; const FabricUIManager: ?Spec = global.nativeFabricUIManager; diff --git a/Libraries/ReactNative/ReactFabricInternals.js b/Libraries/ReactNative/ReactFabricInternals.js index 4be6f784a2904d..592f4359e44202 100644 --- a/Libraries/ReactNative/ReactFabricInternals.js +++ b/Libraries/ReactNative/ReactFabricInternals.js @@ -10,8 +10,16 @@ 'use strict'; +const { + __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED, +} = require('../Renderer/shims/ReactFabric'); const createReactNativeComponentClass = require('../Renderer/shims/createReactNativeComponentClass'); +import type {NativeMethodsMixinType} from '../Renderer/shims/ReactNativeTypes'; + +const {NativeMethodsMixin} = __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; + module.exports = { + NativeMethodsMixin: ((NativeMethodsMixin: any): $Exact), createReactNativeComponentClass, }; diff --git a/Libraries/ReactPrivate/ReactNativePrivateInterface.js b/Libraries/ReactPrivate/ReactNativePrivateInterface.js index d67720d28fe1a7..3d2f7b06f789e4 100644 --- a/Libraries/ReactPrivate/ReactNativePrivateInterface.js +++ b/Libraries/ReactPrivate/ReactNativePrivateInterface.js @@ -8,7 +8,7 @@ * @flow strict-local */ -import typeof BatchedBridge from '../BatchedBridge/BatchedBridge'; +import typeof BatchedBridge from '../BatchedBridge/BatchedBridge.js'; import typeof ExceptionsManager from '../Core/ExceptionsManager'; import typeof Platform from '../Utilities/Platform'; import typeof RCTEventEmitter from '../EventEmitter/RCTEventEmitter'; @@ -23,7 +23,7 @@ import typeof ReactFiberErrorDialog from '../Core/ReactFiberErrorDialog'; // flowlint unsafe-getters-setters:off module.exports = { get BatchedBridge(): BatchedBridge { - return require('../BatchedBridge/BatchedBridge'); + return require('../BatchedBridge/BatchedBridge.js'); }, get ExceptionsManager(): ExceptionsManager { return require('../Core/ExceptionsManager'); diff --git a/Libraries/Renderer/REVISION b/Libraries/Renderer/REVISION index 55c9a60f3d6303..d45d99aeb1adb8 100644 --- a/Libraries/Renderer/REVISION +++ b/Libraries/Renderer/REVISION @@ -1 +1 @@ -b5c6dd2de557428974855b5aa88bf9c6595beb2b \ No newline at end of file +6cff70a740d1e6ad10070ebf88514bd3a49d0f0d diff --git a/Libraries/Renderer/implementations/ReactFabric-dev.fb.js b/Libraries/Renderer/implementations/ReactFabric-dev.fb.js index 2a462f48ee41d0..52d8fc3dbd9e50 100644 --- a/Libraries/Renderer/implementations/ReactFabric-dev.fb.js +++ b/Libraries/Renderer/implementations/ReactFabric-dev.fb.js @@ -5,7 +5,6 @@ * LICENSE file in the root directory of this source tree. * * @noflow - * @nolint * @preventMunge * @generated */ @@ -16,234 +15,253 @@ if (__DEV__) { (function() { "use strict"; -var React = require("react"); require("react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore"); var ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/ReactNativePrivateInterface"); +var React = require("react"); var Scheduler = require("scheduler"); +var checkPropTypes = require("prop-types/checkPropTypes"); var tracing = require("scheduler/tracing"); -var ReactSharedInternals = - React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; // Prevent newer renderers from RTE when used with older react package versions. -// Current owner and dispatcher used to share the same ref, -// but PR #14548 split them out to better support the react-debug-tools package. +/** + * Use invariant() to assert state which your program assumes to be true. + * + * Provide sprintf-style format (only %s is supported) and arguments + * to provide information about what broke and what you were + * expecting. + * + * The invariant message will be stripped in production, but the invariant + * will remain to ensure logic does not differ in production. + */ -if (!ReactSharedInternals.hasOwnProperty("ReactCurrentDispatcher")) { - ReactSharedInternals.ReactCurrentDispatcher = { - current: null - }; -} +/** + * Injectable ordering of event plugins. + */ +var eventPluginOrder = null; +/** + * Injectable mapping from names to event plugin modules. + */ -if (!ReactSharedInternals.hasOwnProperty("ReactCurrentBatchConfig")) { - ReactSharedInternals.ReactCurrentBatchConfig = { - suspense: null - }; -} +var namesToPlugins = {}; +/** + * Recomputes the plugin list using the injected plugins and plugin ordering. + * + * @private + */ +function recomputePluginOrdering() { + if (!eventPluginOrder) { + // Wait until an `eventPluginOrder` is injected. + return; + } -// by calls to these methods by a Babel plugin. -// -// In PROD (or in packages without access to React internals), -// they are left as they are instead. + for (var pluginName in namesToPlugins) { + var pluginModule = namesToPlugins[pluginName]; + var pluginIndex = eventPluginOrder.indexOf(pluginName); -function warn(format) { - { - for ( - var _len = arguments.length, - args = new Array(_len > 1 ? _len - 1 : 0), - _key = 1; - _key < _len; - _key++ - ) { - args[_key - 1] = arguments[_key]; + if (!(pluginIndex > -1)) { + throw Error( + "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + + pluginName + + "`." + ); } - printWarning("warn", format, args); - } -} -function error(format) { - { - for ( - var _len2 = arguments.length, - args = new Array(_len2 > 1 ? _len2 - 1 : 0), - _key2 = 1; - _key2 < _len2; - _key2++ - ) { - args[_key2 - 1] = arguments[_key2]; + if (plugins[pluginIndex]) { + continue; } - printWarning("error", format, args); - } -} - -function printWarning(level, format, args) { - // When changing this logic, you might want to also - // update consoleWithStackDev.www.js as well. - { - var hasExistingStack = - args.length > 0 && - typeof args[args.length - 1] === "string" && - args[args.length - 1].indexOf("\n in") === 0; + if (!pluginModule.extractEvents) { + throw Error( + "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + + pluginName + + "` does not." + ); + } - if (!hasExistingStack) { - var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; - var stack = ReactDebugCurrentFrame.getStackAddendum(); + plugins[pluginIndex] = pluginModule; + var publishedEvents = pluginModule.eventTypes; - if (stack !== "") { - format += "%s"; - args = args.concat([stack]); + for (var eventName in publishedEvents) { + if ( + !publishEventForPlugin( + publishedEvents[eventName], + pluginModule, + eventName + ) + ) { + throw Error( + "EventPluginRegistry: Failed to publish event `" + + eventName + + "` for plugin `" + + pluginName + + "`." + ); } } - - var argsWithFormat = args.map(function(item) { - return "" + item; - }); // Careful: RN currently depends on this prefix - - argsWithFormat.unshift("Warning: " + format); // We intentionally don't use spread (or .apply) directly because it - // breaks IE9: https://github.com/facebook/react/issues/13610 - // eslint-disable-next-line react-internal/no-production-logging - - Function.prototype.apply.call(console[level], console, argsWithFormat); - - try { - // --- Welcome to debugging React --- - // This error was thrown as a convenience so that you can use this stack - // to find the callsite that caused this warning to fire. - var argIndex = 0; - var message = - "Warning: " + - format.replace(/%s/g, function() { - return args[argIndex++]; - }); - throw new Error(message); - } catch (x) {} } } +/** + * Publishes an event so that it can be dispatched by the supplied plugin. + * + * @param {object} dispatchConfig Dispatch configuration for the event. + * @param {object} PluginModule Plugin publishing the event. + * @return {boolean} True if the event was successfully published. + * @private + */ -var FunctionComponent = 0; -var ClassComponent = 1; -var IndeterminateComponent = 2; // Before we know whether it is function or class - -var HostRoot = 3; // Root of a host tree. Could be nested inside another node. - -var HostPortal = 4; // A subtree. Could be an entry point to a different renderer. - -var HostComponent = 5; -var HostText = 6; -var Fragment = 7; -var Mode = 8; -var ContextConsumer = 9; -var ContextProvider = 10; -var ForwardRef = 11; -var Profiler = 12; -var SuspenseComponent = 13; -var MemoComponent = 14; -var SimpleMemoComponent = 15; -var LazyComponent = 16; -var IncompleteClassComponent = 17; -var DehydratedFragment = 18; -var SuspenseListComponent = 19; -var FundamentalComponent = 20; -var ScopeComponent = 21; -var Block = 22; +function publishEventForPlugin(dispatchConfig, pluginModule, eventName) { + if (!!eventNameDispatchConfigs.hasOwnProperty(eventName)) { + throw Error( + "EventPluginHub: More than one plugin attempted to publish the same event name, `" + + eventName + + "`." + ); + } -function getParent(inst) { - do { - inst = inst.return; // TODO: If this is a HostRoot we might want to bail out. - // That is depending on if we want nested subtrees (layers) to bubble - // events to their parent. We could also go through parentNode on the - // host node but that wouldn't work for React Native and doesn't let us - // do the portal feature. - } while (inst && inst.tag !== HostComponent); + eventNameDispatchConfigs[eventName] = dispatchConfig; + var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; - if (inst) { - return inst; + if (phasedRegistrationNames) { + for (var phaseName in phasedRegistrationNames) { + if (phasedRegistrationNames.hasOwnProperty(phaseName)) { + var phasedRegistrationName = phasedRegistrationNames[phaseName]; + publishRegistrationName( + phasedRegistrationName, + pluginModule, + eventName + ); + } + } + return true; + } else if (dispatchConfig.registrationName) { + publishRegistrationName( + dispatchConfig.registrationName, + pluginModule, + eventName + ); + return true; } - return null; + return false; } /** - * Return the lowest common ancestor of A and B, or null if they are in - * different trees. + * Publishes a registration name that is used to identify dispatched events. + * + * @param {string} registrationName Registration name to add. + * @param {object} PluginModule Plugin publishing the event. + * @private */ -function getLowestCommonAncestor(instA, instB) { - var depthA = 0; - - for (var tempA = instA; tempA; tempA = getParent(tempA)) { - depthA++; +function publishRegistrationName(registrationName, pluginModule, eventName) { + if (!!registrationNameModules[registrationName]) { + throw Error( + "EventPluginHub: More than one plugin attempted to publish the same registration name, `" + + registrationName + + "`." + ); } - var depthB = 0; - - for (var tempB = instB; tempB; tempB = getParent(tempB)) { - depthB++; - } // If A is deeper, crawl up. - - while (depthA - depthB > 0) { - instA = getParent(instA); - depthA--; - } // If B is deeper, crawl up. - - while (depthB - depthA > 0) { - instB = getParent(instB); - depthB--; - } // Walk in lockstep until we find a match. - - var depth = depthA; - - while (depth--) { - if (instA === instB || instA === instB.alternate) { - return instA; - } + registrationNameModules[registrationName] = pluginModule; + registrationNameDependencies[registrationName] = + pluginModule.eventTypes[eventName].dependencies; - instA = getParent(instA); - instB = getParent(instB); + { + var lowerCasedName = registrationName.toLowerCase(); } - - return null; } /** - * Return if A is an ancestor of B. + * Registers plugins so that they can extract and dispatch events. + * + * @see {EventPluginHub} */ -function isAncestor(instA, instB) { - while (instB) { - if (instA === instB || instA === instB.alternate) { - return true; - } - - instB = getParent(instB); - } +/** + * Ordered list of injected plugins. + */ - return false; -} +var plugins = []; /** - * Return the parent instance of the passed-in instance. + * Mapping from event name to dispatch config */ -function getParentInstance(inst) { - return getParent(inst); -} +var eventNameDispatchConfigs = {}; /** - * Simulates the traversal of a two-phase, capture/bubble event dispatch. + * Mapping from registration name to plugin module */ -function traverseTwoPhase(inst, fn, arg) { - var path = []; +var registrationNameModules = {}; +/** + * Mapping from registration name to event name + */ - while (inst) { - path.push(inst); - inst = getParent(inst); - } +var registrationNameDependencies = {}; +/** + * Mapping from lowercase registration names to the properly cased version, + * used to warn in the case of missing event handlers. Available + * only in true. + * @type {Object} + */ - var i; +// Trust the developer to only use possibleRegistrationNames in true - for (i = path.length; i-- > 0; ) { - fn(path[i], "captured", arg); - } +/** + * Injects an ordering of plugins (by plugin name). This allows the ordering + * to be decoupled from injection of the actual plugins so that ordering is + * always deterministic regardless of packaging, on-the-fly injection, etc. + * + * @param {array} InjectedEventPluginOrder + * @internal + * @see {EventPluginHub.injection.injectEventPluginOrder} + */ - for (i = 0; i < path.length; i++) { - fn(path[i], "bubbled", arg); +function injectEventPluginOrder(injectedEventPluginOrder) { + if (!!eventPluginOrder) { + throw Error( + "EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React." + ); + } // Clone the ordering so it cannot be dynamically mutated. + + eventPluginOrder = Array.prototype.slice.call(injectedEventPluginOrder); + recomputePluginOrdering(); +} +/** + * Injects plugins to be used by `EventPluginHub`. The plugin names must be + * in the ordering injected by `injectEventPluginOrder`. + * + * Plugins can be injected as part of page initialization or on-the-fly. + * + * @param {object} injectedNamesToPlugins Map from names to plugin modules. + * @internal + * @see {EventPluginHub.injection.injectEventPluginsByName} + */ + +function injectEventPluginsByName(injectedNamesToPlugins) { + var isOrderingDirty = false; + + for (var pluginName in injectedNamesToPlugins) { + if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) { + continue; + } + + var pluginModule = injectedNamesToPlugins[pluginName]; + + if ( + !namesToPlugins.hasOwnProperty(pluginName) || + namesToPlugins[pluginName] !== pluginModule + ) { + if (!!namesToPlugins[pluginName]) { + throw Error( + "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + + pluginName + + "`." + ); + } + + namesToPlugins[pluginName] = pluginModule; + isOrderingDirty = true; + } + } + if (isOrderingDirty) { + recomputePluginOrdering(); } } @@ -259,7 +277,6 @@ var invokeGuardedCallbackImpl = function( f ) { var funcArgs = Array.prototype.slice.call(arguments, 3); - try { func.apply(context, funcArgs); } catch (error) { @@ -468,7 +485,6 @@ var reporter = { * @param {*} context The context to use when calling the function * @param {...*} args Arguments for function */ - function invokeGuardedCallback(name, func, context, a, b, c, d, e, f) { hasError = false; caughtError = null; @@ -484,7 +500,6 @@ function invokeGuardedCallback(name, func, context, a, b, c, d, e, f) { * @param {*} context The context to use when calling the function * @param {...*} args Arguments for function */ - function invokeGuardedCallbackAndCatchFirstError( name, func, @@ -511,7 +526,6 @@ function invokeGuardedCallbackAndCatchFirstError( * During execution of guarded functions we will capture the first error which * we will rethrow to be handled by the top level error handler. */ - function rethrowCaughtError() { if (hasRethrowError) { var error = rethrowError; @@ -538,6 +552,70 @@ function clearCaughtError() { } } +/** + * Similar to invariant but only logs a warning if the condition is not met. + * This can be used to log issues in development environments in critical + * paths. Removing the logging code for production environments will keep the + * same logic and follow the same code paths. + */ +var warningWithoutStack = function() {}; + +{ + warningWithoutStack = function(condition, format) { + for ( + var _len = arguments.length, + args = new Array(_len > 2 ? _len - 2 : 0), + _key = 2; + _key < _len; + _key++ + ) { + args[_key - 2] = arguments[_key]; + } + + if (format === undefined) { + throw new Error( + "`warningWithoutStack(condition, format, ...args)` requires a warning " + + "message argument" + ); + } + if (args.length > 8) { + // Check before the condition to catch violations early. + throw new Error( + "warningWithoutStack() currently supports at most 8 arguments." + ); + } + + if (condition) { + return; + } + + if (typeof console !== "undefined") { + var argsWithFormat = args.map(function(item) { + return "" + item; + }); + argsWithFormat.unshift("Warning: " + format); // We intentionally don't use spread (or .apply) directly because it + // breaks IE9: https://github.com/facebook/react/issues/13610 + + Function.prototype.apply.call(console.error, console, argsWithFormat); + } + + try { + // --- Welcome to debugging React --- + // This error was thrown as a convenience so that you can use this stack + // to find the callsite that caused this warning to fire. + var argIndex = 0; + var message = + "Warning: " + + format.replace(/%s/g, function() { + return args[argIndex++]; + }); + throw new Error(message); + } catch (x) {} + }; +} + +var warningWithoutStack$1 = warningWithoutStack; + var getFiberCurrentPropsFromNode = null; var getInstanceFromNode = null; var getNodeFromInstance = null; @@ -549,14 +627,14 @@ function setComponentTree( getFiberCurrentPropsFromNode = getFiberCurrentPropsFromNodeImpl; getInstanceFromNode = getInstanceFromNodeImpl; getNodeFromInstance = getNodeFromInstanceImpl; - { - if (!getNodeFromInstance || !getInstanceFromNode) { - error( - "EventPluginUtils.setComponentTree(...): Injected " + - "module is missing getNodeFromInstance or getInstanceFromNode." - ); - } + !(getNodeFromInstance && getInstanceFromNode) + ? warningWithoutStack$1( + false, + "EventPluginUtils.setComponentTree(...): Injected " + + "module is missing getNodeFromInstance or getInstanceFromNode." + ) + : void 0; } } var validateEventDispatches; @@ -569,18 +647,17 @@ var validateEventDispatches; var listenersLen = listenersIsArr ? dispatchListeners.length : dispatchListeners - ? 1 - : 0; + ? 1 + : 0; var instancesIsArr = Array.isArray(dispatchInstances); var instancesLen = instancesIsArr ? dispatchInstances.length : dispatchInstances - ? 1 - : 0; - - if (instancesIsArr !== listenersIsArr || instancesLen !== listenersLen) { - error("EventPluginUtils: Invalid `event`."); - } + ? 1 + : 0; + !(instancesIsArr === listenersIsArr && instancesLen === listenersLen) + ? warningWithoutStack$1(false, "EventPluginUtils: Invalid `event`.") + : void 0; }; } /** @@ -589,7 +666,6 @@ var validateEventDispatches; * @param {function} listener Application-level callback * @param {*} inst Internal component instance */ - function executeDispatch(event, listener, inst) { var type = event.type || "unknown-event"; event.currentTarget = getNodeFromInstance(inst); @@ -676,7 +752,6 @@ function executeDispatchesInOrderStopAtTrue(event) { * * @return {*} The return value of executing the single dispatch. */ - function executeDirectDispatch(event) { { validateEventDispatches(event); @@ -702,82 +777,10 @@ function executeDirectDispatch(event) { * @param {SyntheticEvent} event * @return {boolean} True iff number of dispatches accumulated is greater than 0. */ - function hasDispatches(event) { return !!event._dispatchListeners; } -function isInteractive(tag) { - return ( - tag === "button" || - tag === "input" || - tag === "select" || - tag === "textarea" - ); -} - -function shouldPreventMouseEvent(name, type, props) { - switch (name) { - case "onClick": - case "onClickCapture": - case "onDoubleClick": - case "onDoubleClickCapture": - case "onMouseDown": - case "onMouseDownCapture": - case "onMouseMove": - case "onMouseMoveCapture": - case "onMouseUp": - case "onMouseUpCapture": - case "onMouseEnter": - return !!(props.disabled && isInteractive(type)); - - default: - return false; - } -} -/** - * @param {object} inst The instance, which is the source of events. - * @param {string} registrationName Name of listener (e.g. `onClick`). - * @return {?function} The stored callback. - */ - -function getListener(inst, registrationName) { - var listener; // TODO: shouldPreventMouseEvent is DOM-specific and definitely should not - // live here; needs to be moved to a better place soon - - var stateNode = inst.stateNode; - - if (!stateNode) { - // Work in progress (ex: onload events in incremental mode). - return null; - } - - var props = getFiberCurrentPropsFromNode(stateNode); - - if (!props) { - // Work in progress. - return null; - } - - listener = props[registrationName]; - - if (shouldPreventMouseEvent(registrationName, inst.type, props)) { - return null; - } - - if (!(!listener || typeof listener === "function")) { - throw Error( - "Expected `" + - registrationName + - "` listener to be a function, instead got a value of `" + - typeof listener + - "` type." - ); - } - - return listener; -} - /** * Accumulates items that must not be null or undefined into the first one. This * is used to conserve memory by avoiding array allocations, and thus sacrifices @@ -808,7 +811,6 @@ function accumulateInto(current, next) { current.push.apply(current, next); return current; } - current.push(next); return current; } @@ -839,807 +841,1120 @@ function forEachAccumulated(arr, cb, scope) { } /** - * Some event types have a notion of different registration names for different - * "phases" of propagation. This finds listeners by a given phase. - */ -function listenerAtPhase(inst, event, propagationPhase) { - var registrationName = - event.dispatchConfig.phasedRegistrationNames[propagationPhase]; - return getListener(inst, registrationName); -} -/** - * A small set of propagation patterns, each of which will accept a small amount - * of information, and generate a set of "dispatch ready event objects" - which - * are sets of events that have already been annotated with a set of dispatched - * listener functions/ids. The API is designed this way to discourage these - * propagation strategies from actually executing the dispatches, since we - * always want to collect the entire set of dispatches before executing even a - * single one. + * Internal queue of events that have accumulated their dispatches and are + * waiting to have their dispatches executed. */ +var eventQueue = null; /** - * Tags a `SyntheticEvent` with dispatched listeners. Creating this function - * here, allows us to not have to bind or create functions for each event. - * Mutating the event's members allows us to not have to create a wrapping - * "dispatch" object that pairs the event with the listener. + * Dispatches an event and releases it back into the pool, unless persistent. + * + * @param {?object} event Synthetic event to be dispatched. + * @private */ +var executeDispatchesAndRelease = function(event) { + if (event) { + executeDispatchesInOrder(event); -function accumulateDirectionalDispatches(inst, phase, event) { - { - if (!inst) { - error("Dispatching inst must not be null"); + if (!event.isPersistent()) { + event.constructor.release(event); } } +}; +var executeDispatchesAndReleaseTopLevel = function(e) { + return executeDispatchesAndRelease(e); +}; - var listener = listenerAtPhase(inst, event, phase); +function runEventsInBatch(events) { + if (events !== null) { + eventQueue = accumulateInto(eventQueue, events); + } // Set `eventQueue` to null before processing it so that we can tell if more + // events get enqueued while processing. - if (listener) { - event._dispatchListeners = accumulateInto( - event._dispatchListeners, - listener - ); - event._dispatchInstances = accumulateInto(event._dispatchInstances, inst); + var processingEventQueue = eventQueue; + eventQueue = null; + + if (!processingEventQueue) { + return; } -} -/** - * Collect dispatches (must be entirely collected before dispatching - see unit - * tests). Lazily allocate the array to conserve memory. We must loop through - * each event and perform the traversal for each one. We cannot perform a - * single traversal for the entire collection of events because each event may - * have a different target. - */ -function accumulateTwoPhaseDispatchesSingle(event) { - if (event && event.dispatchConfig.phasedRegistrationNames) { - traverseTwoPhase(event._targetInst, accumulateDirectionalDispatches, event); - } + forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseTopLevel); + + if (!!eventQueue) { + throw Error( + "processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented." + ); + } // This would be a good time to rethrow if any of the event handlers threw. + + rethrowCaughtError(); } -/** - * Same as `accumulateTwoPhaseDispatchesSingle`, but skips over the targetID. - */ -function accumulateTwoPhaseDispatchesSingleSkipTarget(event) { - if (event && event.dispatchConfig.phasedRegistrationNames) { - var targetInst = event._targetInst; - var parentInst = targetInst ? getParentInstance(targetInst) : null; - traverseTwoPhase(parentInst, accumulateDirectionalDispatches, event); +function isInteractive(tag) { + return ( + tag === "button" || + tag === "input" || + tag === "select" || + tag === "textarea" + ); +} + +function shouldPreventMouseEvent(name, type, props) { + switch (name) { + case "onClick": + case "onClickCapture": + case "onDoubleClick": + case "onDoubleClickCapture": + case "onMouseDown": + case "onMouseDownCapture": + case "onMouseMove": + case "onMouseMoveCapture": + case "onMouseUp": + case "onMouseUpCapture": + return !!(props.disabled && isInteractive(type)); + default: + return false; } } /** - * Accumulates without regard to direction, does not look for phased - * registration names. Same as `accumulateDirectDispatchesSingle` but without - * requiring that the `dispatchMarker` be the same as the dispatched ID. + * This is a unified interface for event plugins to be installed and configured. + * + * Event plugins can implement the following properties: + * + * `extractEvents` {function(string, DOMEventTarget, string, object): *} + * Required. When a top-level event is fired, this method is expected to + * extract synthetic events that will in turn be queued and dispatched. + * + * `eventTypes` {object} + * Optional, plugins that fire events must publish a mapping of registration + * names that are used to register listeners. Values of this mapping must + * be objects that contain `registrationName` or `phasedRegistrationNames`. + * + * `executeDispatch` {function(object, function, string)} + * Optional, allows plugins to override how an event gets dispatched. By + * default, the listener is simply invoked. + * + * Each plugin that is injected into `EventsPluginHub` is immediately operable. + * + * @public */ -function accumulateDispatches(inst, ignoredDirection, event) { - if (inst && event && event.dispatchConfig.registrationName) { - var registrationName = event.dispatchConfig.registrationName; - var listener = getListener(inst, registrationName); +/** + * Methods for injecting dependencies. + */ +var injection = { + /** + * @param {array} InjectedEventPluginOrder + * @public + */ + injectEventPluginOrder: injectEventPluginOrder, - if (listener) { - event._dispatchListeners = accumulateInto( - event._dispatchListeners, - listener - ); - event._dispatchInstances = accumulateInto(event._dispatchInstances, inst); - } - } -} + /** + * @param {object} injectedNamesToPlugins Map from names to plugin modules. + */ + injectEventPluginsByName: injectEventPluginsByName +}; /** - * Accumulates dispatches on an `SyntheticEvent`, but only for the - * `dispatchMarker`. - * @param {SyntheticEvent} event + * @param {object} inst The instance, which is the source of events. + * @param {string} registrationName Name of listener (e.g. `onClick`). + * @return {?function} The stored callback. */ -function accumulateDirectDispatchesSingle(event) { - if (event && event.dispatchConfig.registrationName) { - accumulateDispatches(event._targetInst, null, event); +function getListener(inst, registrationName) { + var listener; // TODO: shouldPreventMouseEvent is DOM-specific and definitely should not + // live here; needs to be moved to a better place soon + + var stateNode = inst.stateNode; + + if (!stateNode) { + // Work in progress (ex: onload events in incremental mode). + return null; } -} -function accumulateTwoPhaseDispatches(events) { - forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle); -} -function accumulateTwoPhaseDispatchesSkipTarget(events) { - forEachAccumulated(events, accumulateTwoPhaseDispatchesSingleSkipTarget); -} -function accumulateDirectDispatches(events) { - forEachAccumulated(events, accumulateDirectDispatchesSingle); -} + var props = getFiberCurrentPropsFromNode(stateNode); -var EVENT_POOL_SIZE = 10; -/** - * @interface Event - * @see http://www.w3.org/TR/DOM-Level-3-Events/ - */ + if (!props) { + // Work in progress. + return null; + } -var EventInterface = { - type: null, - target: null, - // currentTarget is set when dispatching; no use in copying it here - currentTarget: function() { + listener = props[registrationName]; + + if (shouldPreventMouseEvent(registrationName, inst.type, props)) { return null; - }, - eventPhase: null, - bubbles: null, - cancelable: null, - timeStamp: function(event) { - return event.timeStamp || Date.now(); - }, - defaultPrevented: null, - isTrusted: null -}; + } -function functionThatReturnsTrue() { - return true; -} + if (!(!listener || typeof listener === "function")) { + throw Error( + "Expected `" + + registrationName + + "` listener to be a function, instead got a value of `" + + typeof listener + + "` type." + ); + } -function functionThatReturnsFalse() { - return false; + return listener; } /** - * Synthetic events are dispatched by event plugins, typically in response to a - * top-level event delegation handler. - * - * These systems should generally use pooling to reduce the frequency of garbage - * collection. The system should check `isPersistent` to determine whether the - * event should be released into the pool after being dispatched. Users that - * need a persisted event should invoke `persist`. - * - * Synthetic events (and subclasses) implement the DOM Level 3 Events API by - * normalizing browser quirks. Subclasses do not necessarily have to implement a - * DOM interface; custom application-specific events can also subclass this. + * Allows registered plugins an opportunity to extract events from top-level + * native browser events. * - * @param {object} dispatchConfig Configuration used to dispatch this event. - * @param {*} targetInst Marker identifying the event target. - * @param {object} nativeEvent Native browser event. - * @param {DOMEventTarget} nativeEventTarget Target node. + * @return {*} An accumulation of synthetic events. + * @internal */ - -function SyntheticEvent( - dispatchConfig, +function extractPluginEvents( + topLevelType, targetInst, nativeEvent, - nativeEventTarget + nativeEventTarget, + eventSystemFlags ) { - { - // these have a getter/setter for warnings - delete this.nativeEvent; - delete this.preventDefault; - delete this.stopPropagation; - delete this.isDefaultPrevented; - delete this.isPropagationStopped; - } - - this.dispatchConfig = dispatchConfig; - this._targetInst = targetInst; - this.nativeEvent = nativeEvent; - var Interface = this.constructor.Interface; - - for (var propName in Interface) { - if (!Interface.hasOwnProperty(propName)) { - continue; - } + var events = null; - { - delete this[propName]; // this has a getter/setter for warnings - } + for (var i = 0; i < plugins.length; i++) { + // Not every plugin in the ordering may be loaded at runtime. + var possiblePlugin = plugins[i]; - var normalize = Interface[propName]; + if (possiblePlugin) { + var extractedEvents = possiblePlugin.extractEvents( + topLevelType, + targetInst, + nativeEvent, + nativeEventTarget, + eventSystemFlags + ); - if (normalize) { - this[propName] = normalize(nativeEvent); - } else { - if (propName === "target") { - this.target = nativeEventTarget; - } else { - this[propName] = nativeEvent[propName]; + if (extractedEvents) { + events = accumulateInto(events, extractedEvents); } } } + return events; +} - var defaultPrevented = - nativeEvent.defaultPrevented != null - ? nativeEvent.defaultPrevented - : nativeEvent.returnValue === false; - - if (defaultPrevented) { - this.isDefaultPrevented = functionThatReturnsTrue; - } else { - this.isDefaultPrevented = functionThatReturnsFalse; - } - - this.isPropagationStopped = functionThatReturnsFalse; - return this; +function runExtractedPluginEventsInBatch( + topLevelType, + targetInst, + nativeEvent, + nativeEventTarget, + eventSystemFlags +) { + var events = extractPluginEvents( + topLevelType, + targetInst, + nativeEvent, + nativeEventTarget, + eventSystemFlags + ); + runEventsInBatch(events); } -Object.assign(SyntheticEvent.prototype, { - preventDefault: function() { - this.defaultPrevented = true; - var event = this.nativeEvent; +var FunctionComponent = 0; +var ClassComponent = 1; +var IndeterminateComponent = 2; // Before we know whether it is function or class - if (!event) { - return; - } +var HostRoot = 3; // Root of a host tree. Could be nested inside another node. - if (event.preventDefault) { - event.preventDefault(); - } else if (typeof event.returnValue !== "unknown") { - event.returnValue = false; - } +var HostPortal = 4; // A subtree. Could be an entry point to a different renderer. - this.isDefaultPrevented = functionThatReturnsTrue; - }, - stopPropagation: function() { - var event = this.nativeEvent; +var HostComponent = 5; +var HostText = 6; +var Fragment = 7; +var Mode = 8; +var ContextConsumer = 9; +var ContextProvider = 10; +var ForwardRef = 11; +var Profiler = 12; +var SuspenseComponent = 13; +var MemoComponent = 14; +var SimpleMemoComponent = 15; +var LazyComponent = 16; +var IncompleteClassComponent = 17; +var DehydratedFragment = 18; +var SuspenseListComponent = 19; +var FundamentalComponent = 20; +var ScopeComponent = 21; - if (!event) { - return; - } +function getParent(inst) { + do { + inst = inst.return; // TODO: If this is a HostRoot we might want to bail out. + // That is depending on if we want nested subtrees (layers) to bubble + // events to their parent. We could also go through parentNode on the + // host node but that wouldn't work for React Native and doesn't let us + // do the portal feature. + } while (inst && inst.tag !== HostComponent); - if (event.stopPropagation) { - event.stopPropagation(); - } else if (typeof event.cancelBubble !== "unknown") { - // The ChangeEventPlugin registers a "propertychange" event for - // IE. This event does not support bubbling or cancelling, and - // any references to cancelBubble throw "Member not found". A - // typeof check of "unknown" circumvents this issue (and is also - // IE specific). - event.cancelBubble = true; - } + if (inst) { + return inst; + } - this.isPropagationStopped = functionThatReturnsTrue; - }, + return null; +} +/** + * Return the lowest common ancestor of A and B, or null if they are in + * different trees. + */ - /** - * We release all dispatched `SyntheticEvent`s after each event loop, adding - * them back into the pool. This allows a way to hold onto a reference that - * won't be added back into the pool. - */ - persist: function() { - this.isPersistent = functionThatReturnsTrue; - }, +function getLowestCommonAncestor(instA, instB) { + var depthA = 0; - /** - * Checks if this event should be released back into the pool. - * - * @return {boolean} True if this should not be released, false otherwise. - */ - isPersistent: functionThatReturnsFalse, + for (var tempA = instA; tempA; tempA = getParent(tempA)) { + depthA++; + } - /** - * `PooledClass` looks for `destructor` on each instance it releases. - */ - destructor: function() { - var Interface = this.constructor.Interface; + var depthB = 0; - for (var propName in Interface) { - { - Object.defineProperty( - this, - propName, - getPooledWarningPropertyDefinition(propName, Interface[propName]) - ); - } - } + for (var tempB = instB; tempB; tempB = getParent(tempB)) { + depthB++; + } // If A is deeper, crawl up. - this.dispatchConfig = null; - this._targetInst = null; - this.nativeEvent = null; - this.isDefaultPrevented = functionThatReturnsFalse; - this.isPropagationStopped = functionThatReturnsFalse; - this._dispatchListeners = null; - this._dispatchInstances = null; + while (depthA - depthB > 0) { + instA = getParent(instA); + depthA--; + } // If B is deeper, crawl up. - { - Object.defineProperty( - this, - "nativeEvent", - getPooledWarningPropertyDefinition("nativeEvent", null) - ); - Object.defineProperty( - this, - "isDefaultPrevented", - getPooledWarningPropertyDefinition( - "isDefaultPrevented", - functionThatReturnsFalse - ) - ); - Object.defineProperty( - this, - "isPropagationStopped", - getPooledWarningPropertyDefinition( - "isPropagationStopped", - functionThatReturnsFalse - ) - ); - Object.defineProperty( - this, - "preventDefault", - getPooledWarningPropertyDefinition("preventDefault", function() {}) - ); - Object.defineProperty( - this, - "stopPropagation", - getPooledWarningPropertyDefinition("stopPropagation", function() {}) - ); + while (depthB - depthA > 0) { + instB = getParent(instB); + depthB--; + } // Walk in lockstep until we find a match. + + var depth = depthA; + + while (depth--) { + if (instA === instB || instA === instB.alternate) { + return instA; } + + instA = getParent(instA); + instB = getParent(instB); } -}); -SyntheticEvent.Interface = EventInterface; + + return null; +} /** - * Helper to reduce boilerplate when creating subclasses. + * Return if A is an ancestor of B. */ -SyntheticEvent.extend = function(Interface) { - var Super = this; - - var E = function() {}; - - E.prototype = Super.prototype; - var prototype = new E(); +function isAncestor(instA, instB) { + while (instB) { + if (instA === instB || instA === instB.alternate) { + return true; + } - function Class() { - return Super.apply(this, arguments); + instB = getParent(instB); } - Object.assign(prototype, Class.prototype); - Class.prototype = prototype; - Class.prototype.constructor = Class; - Class.Interface = Object.assign({}, Super.Interface, Interface); - Class.extend = Super.extend; - addEventPoolingTo(Class); - return Class; -}; + return false; +} +/** + * Return the parent instance of the passed-in instance. + */ -addEventPoolingTo(SyntheticEvent); +function getParentInstance(inst) { + return getParent(inst); +} /** - * Helper to nullify syntheticEvent instance properties when destructing - * - * @param {String} propName - * @param {?object} getVal - * @return {object} defineProperty object + * Simulates the traversal of a two-phase, capture/bubble event dispatch. */ -function getPooledWarningPropertyDefinition(propName, getVal) { - var isFunction = typeof getVal === "function"; - return { - configurable: true, - set: set, - get: get - }; +function traverseTwoPhase(inst, fn, arg) { + var path = []; - function set(val) { - var action = isFunction ? "setting the method" : "setting the property"; - warn(action, "This is effectively a no-op"); - return val; + while (inst) { + path.push(inst); + inst = getParent(inst); } - function get() { - var action = isFunction ? "accessing the method" : "accessing the property"; - var result = isFunction - ? "This is a no-op function" - : "This is set to null"; - warn(action, result); - return getVal; - } + var i; - function warn(action, result) { - { - error( - "This synthetic event is reused for performance reasons. If you're seeing this, " + - "you're %s `%s` on a released/nullified synthetic event. %s. " + - "If you must keep the original synthetic event around, use event.persist(). " + - "See https://fb.me/react-event-pooling for more information.", - action, - propName, - result - ); - } + for (i = path.length; i-- > 0; ) { + fn(path[i], "captured", arg); } -} - -function getPooledEvent(dispatchConfig, targetInst, nativeEvent, nativeInst) { - var EventConstructor = this; - if (EventConstructor.eventPool.length) { - var instance = EventConstructor.eventPool.pop(); - EventConstructor.call( - instance, - dispatchConfig, - targetInst, - nativeEvent, - nativeInst - ); - return instance; + for (i = 0; i < path.length; i++) { + fn(path[i], "bubbled", arg); } - - return new EventConstructor( - dispatchConfig, - targetInst, - nativeEvent, - nativeInst - ); } +/** + * Traverses the ID hierarchy and invokes the supplied `cb` on any IDs that + * should would receive a `mouseEnter` or `mouseLeave` event. + * + * Does not invoke the callback on the nearest common ancestor because nothing + * "entered" or "left" that element. + */ -function releasePooledEvent(event) { - var EventConstructor = this; - - if (!(event instanceof EventConstructor)) { - throw Error( - "Trying to release an event instance into a pool of a different type." - ); +/** + * Some event types have a notion of different registration names for different + * "phases" of propagation. This finds listeners by a given phase. + */ +function listenerAtPhase(inst, event, propagationPhase) { + var registrationName = + event.dispatchConfig.phasedRegistrationNames[propagationPhase]; + return getListener(inst, registrationName); +} +/** + * A small set of propagation patterns, each of which will accept a small amount + * of information, and generate a set of "dispatch ready event objects" - which + * are sets of events that have already been annotated with a set of dispatched + * listener functions/ids. The API is designed this way to discourage these + * propagation strategies from actually executing the dispatches, since we + * always want to collect the entire set of dispatches before executing even a + * single one. + */ + +/** + * Tags a `SyntheticEvent` with dispatched listeners. Creating this function + * here, allows us to not have to bind or create functions for each event. + * Mutating the event's members allows us to not have to create a wrapping + * "dispatch" object that pairs the event with the listener. + */ +function accumulateDirectionalDispatches(inst, phase, event) { + { + !inst + ? warningWithoutStack$1(false, "Dispatching inst must not be null") + : void 0; } - event.destructor(); + var listener = listenerAtPhase(inst, event, phase); - if (EventConstructor.eventPool.length < EVENT_POOL_SIZE) { - EventConstructor.eventPool.push(event); + if (listener) { + event._dispatchListeners = accumulateInto( + event._dispatchListeners, + listener + ); + event._dispatchInstances = accumulateInto(event._dispatchInstances, inst); } } - -function addEventPoolingTo(EventConstructor) { - EventConstructor.eventPool = []; - EventConstructor.getPooled = getPooledEvent; - EventConstructor.release = releasePooledEvent; +/** + * Collect dispatches (must be entirely collected before dispatching - see unit + * tests). Lazily allocate the array to conserve memory. We must loop through + * each event and perform the traversal for each one. We cannot perform a + * single traversal for the entire collection of events because each event may + * have a different target. + */ +function accumulateTwoPhaseDispatchesSingle(event) { + if (event && event.dispatchConfig.phasedRegistrationNames) { + traverseTwoPhase(event._targetInst, accumulateDirectionalDispatches, event); + } } - /** - * `touchHistory` isn't actually on the native event, but putting it in the - * interface will ensure that it is cleaned up when pooled/destroyed. The - * `ResponderEventPlugin` will populate it appropriately. + * Same as `accumulateTwoPhaseDispatchesSingle`, but skips over the targetID. */ -var ResponderSyntheticEvent = SyntheticEvent.extend({ - touchHistory: function(nativeEvent) { - return null; // Actually doesn't even look at the native event. +function accumulateTwoPhaseDispatchesSingleSkipTarget(event) { + if (event && event.dispatchConfig.phasedRegistrationNames) { + var targetInst = event._targetInst; + var parentInst = targetInst ? getParentInstance(targetInst) : null; + traverseTwoPhase(parentInst, accumulateDirectionalDispatches, event); } -}); +} +/** + * Accumulates without regard to direction, does not look for phased + * registration names. Same as `accumulateDirectDispatchesSingle` but without + * requiring that the `dispatchMarker` be the same as the dispatched ID. + */ +function accumulateDispatches(inst, ignoredDirection, event) { + if (inst && event && event.dispatchConfig.registrationName) { + var registrationName = event.dispatchConfig.registrationName; + var listener = getListener(inst, registrationName); + if (listener) { + event._dispatchListeners = accumulateInto( + event._dispatchListeners, + listener + ); + event._dispatchInstances = accumulateInto(event._dispatchInstances, inst); + } + } +} +/** + * Accumulates dispatches on an `SyntheticEvent`, but only for the + * `dispatchMarker`. + * @param {SyntheticEvent} event + */ +function accumulateDirectDispatchesSingle(event) { + if (event && event.dispatchConfig.registrationName) { + accumulateDispatches(event._targetInst, null, event); + } +} -var TOP_TOUCH_START = "topTouchStart"; -var TOP_TOUCH_MOVE = "topTouchMove"; -var TOP_TOUCH_END = "topTouchEnd"; -var TOP_TOUCH_CANCEL = "topTouchCancel"; -var TOP_SCROLL = "topScroll"; -var TOP_SELECTION_CHANGE = "topSelectionChange"; -function isStartish(topLevelType) { - return topLevelType === TOP_TOUCH_START; +function accumulateTwoPhaseDispatches(events) { + forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle); } -function isMoveish(topLevelType) { - return topLevelType === TOP_TOUCH_MOVE; +function accumulateTwoPhaseDispatchesSkipTarget(events) { + forEachAccumulated(events, accumulateTwoPhaseDispatchesSingleSkipTarget); } -function isEndish(topLevelType) { - return topLevelType === TOP_TOUCH_END || topLevelType === TOP_TOUCH_CANCEL; + +function accumulateDirectDispatches(events) { + forEachAccumulated(events, accumulateDirectDispatchesSingle); } -var startDependencies = [TOP_TOUCH_START]; -var moveDependencies = [TOP_TOUCH_MOVE]; -var endDependencies = [TOP_TOUCH_CANCEL, TOP_TOUCH_END]; +/* eslint valid-typeof: 0 */ +var EVENT_POOL_SIZE = 10; /** - * Tracks the position and time of each active touch by `touch.identifier`. We - * should typically only see IDs in the range of 1-20 because IDs get recycled - * when touches end and start again. + * @interface Event + * @see http://www.w3.org/TR/DOM-Level-3-Events/ */ - -var MAX_TOUCH_BANK = 20; -var touchBank = []; -var touchHistory = { - touchBank: touchBank, - numberActiveTouches: 0, - // If there is only one active touch, we remember its location. This prevents - // us having to loop through all of the touches all the time in the most - // common case. - indexOfSingleActiveTouch: -1, - mostRecentTimeStamp: 0 +var EventInterface = { + type: null, + target: null, + // currentTarget is set when dispatching; no use in copying it here + currentTarget: function() { + return null; + }, + eventPhase: null, + bubbles: null, + cancelable: null, + timeStamp: function(event) { + return event.timeStamp || Date.now(); + }, + defaultPrevented: null, + isTrusted: null }; -function timestampForTouch(touch) { - // The legacy internal implementation provides "timeStamp", which has been - // renamed to "timestamp". Let both work for now while we iron it out - // TODO (evv): rename timeStamp to timestamp in internal code - return touch.timeStamp || touch.timestamp; +function functionThatReturnsTrue() { + return true; +} + +function functionThatReturnsFalse() { + return false; } /** - * TODO: Instead of making gestures recompute filtered velocity, we could - * include a built in velocity computation that can be reused globally. + * Synthetic events are dispatched by event plugins, typically in response to a + * top-level event delegation handler. + * + * These systems should generally use pooling to reduce the frequency of garbage + * collection. The system should check `isPersistent` to determine whether the + * event should be released into the pool after being dispatched. Users that + * need a persisted event should invoke `persist`. + * + * Synthetic events (and subclasses) implement the DOM Level 3 Events API by + * normalizing browser quirks. Subclasses do not necessarily have to implement a + * DOM interface; custom application-specific events can also subclass this. + * + * @param {object} dispatchConfig Configuration used to dispatch this event. + * @param {*} targetInst Marker identifying the event target. + * @param {object} nativeEvent Native browser event. + * @param {DOMEventTarget} nativeEventTarget Target node. */ +function SyntheticEvent( + dispatchConfig, + targetInst, + nativeEvent, + nativeEventTarget +) { + { + // these have a getter/setter for warnings + delete this.nativeEvent; + delete this.preventDefault; + delete this.stopPropagation; + delete this.isDefaultPrevented; + delete this.isPropagationStopped; + } -function createTouchRecord(touch) { - return { - touchActive: true, - startPageX: touch.pageX, - startPageY: touch.pageY, - startTimeStamp: timestampForTouch(touch), - currentPageX: touch.pageX, - currentPageY: touch.pageY, - currentTimeStamp: timestampForTouch(touch), - previousPageX: touch.pageX, - previousPageY: touch.pageY, - previousTimeStamp: timestampForTouch(touch) - }; -} + this.dispatchConfig = dispatchConfig; + this._targetInst = targetInst; + this.nativeEvent = nativeEvent; + var Interface = this.constructor.Interface; -function resetTouchRecord(touchRecord, touch) { - touchRecord.touchActive = true; - touchRecord.startPageX = touch.pageX; - touchRecord.startPageY = touch.pageY; - touchRecord.startTimeStamp = timestampForTouch(touch); - touchRecord.currentPageX = touch.pageX; - touchRecord.currentPageY = touch.pageY; - touchRecord.currentTimeStamp = timestampForTouch(touch); - touchRecord.previousPageX = touch.pageX; - touchRecord.previousPageY = touch.pageY; - touchRecord.previousTimeStamp = timestampForTouch(touch); -} + for (var propName in Interface) { + if (!Interface.hasOwnProperty(propName)) { + continue; + } -function getTouchIdentifier(_ref) { - var identifier = _ref.identifier; + { + delete this[propName]; // this has a getter/setter for warnings + } - if (!(identifier != null)) { - throw Error("Touch object is missing identifier."); - } + var normalize = Interface[propName]; - { - if (identifier > MAX_TOUCH_BANK) { - error( - "Touch identifier %s is greater than maximum supported %s which causes " + - "performance issues backfilling array locations for all of the indices.", - identifier, - MAX_TOUCH_BANK - ); + if (normalize) { + this[propName] = normalize(nativeEvent); + } else { + if (propName === "target") { + this.target = nativeEventTarget; + } else { + this[propName] = nativeEvent[propName]; + } } } - return identifier; -} - -function recordTouchStart(touch) { - var identifier = getTouchIdentifier(touch); - var touchRecord = touchBank[identifier]; - - if (touchRecord) { - resetTouchRecord(touchRecord, touch); + var defaultPrevented = + nativeEvent.defaultPrevented != null + ? nativeEvent.defaultPrevented + : nativeEvent.returnValue === false; + if (defaultPrevented) { + this.isDefaultPrevented = functionThatReturnsTrue; } else { - touchBank[identifier] = createTouchRecord(touch); + this.isDefaultPrevented = functionThatReturnsFalse; } - - touchHistory.mostRecentTimeStamp = timestampForTouch(touch); + this.isPropagationStopped = functionThatReturnsFalse; + return this; } -function recordTouchMove(touch) { - var touchRecord = touchBank[getTouchIdentifier(touch)]; +Object.assign(SyntheticEvent.prototype, { + preventDefault: function() { + this.defaultPrevented = true; + var event = this.nativeEvent; + if (!event) { + return; + } - if (touchRecord) { - touchRecord.touchActive = true; - touchRecord.previousPageX = touchRecord.currentPageX; - touchRecord.previousPageY = touchRecord.currentPageY; - touchRecord.previousTimeStamp = touchRecord.currentTimeStamp; - touchRecord.currentPageX = touch.pageX; - touchRecord.currentPageY = touch.pageY; - touchRecord.currentTimeStamp = timestampForTouch(touch); - touchHistory.mostRecentTimeStamp = timestampForTouch(touch); - } else { - { - warn( - "Cannot record touch move without a touch start.\n" + - "Touch Move: %s\n" + - "Touch Bank: %s", - printTouch(touch), - printTouchBank() - ); + if (event.preventDefault) { + event.preventDefault(); + } else if (typeof event.returnValue !== "unknown") { + event.returnValue = false; } - } -} -function recordTouchEnd(touch) { - var touchRecord = touchBank[getTouchIdentifier(touch)]; + this.isDefaultPrevented = functionThatReturnsTrue; + }, + stopPropagation: function() { + var event = this.nativeEvent; - if (touchRecord) { - touchRecord.touchActive = false; - touchRecord.previousPageX = touchRecord.currentPageX; - touchRecord.previousPageY = touchRecord.currentPageY; - touchRecord.previousTimeStamp = touchRecord.currentTimeStamp; - touchRecord.currentPageX = touch.pageX; - touchRecord.currentPageY = touch.pageY; - touchRecord.currentTimeStamp = timestampForTouch(touch); - touchHistory.mostRecentTimeStamp = timestampForTouch(touch); - } else { - { - warn( - "Cannot record touch end without a touch start.\n" + - "Touch End: %s\n" + - "Touch Bank: %s", - printTouch(touch), - printTouchBank() - ); + if (!event) { + return; } - } -} - -function printTouch(touch) { - return JSON.stringify({ - identifier: touch.identifier, - pageX: touch.pageX, - pageY: touch.pageY, - timestamp: timestampForTouch(touch) - }); -} -function printTouchBank() { - var printed = JSON.stringify(touchBank.slice(0, MAX_TOUCH_BANK)); + if (event.stopPropagation) { + event.stopPropagation(); + } else if (typeof event.cancelBubble !== "unknown") { + // The ChangeEventPlugin registers a "propertychange" event for + // IE. This event does not support bubbling or cancelling, and + // any references to cancelBubble throw "Member not found". A + // typeof check of "unknown" circumvents this issue (and is also + // IE specific). + event.cancelBubble = true; + } - if (touchBank.length > MAX_TOUCH_BANK) { - printed += " (original size: " + touchBank.length + ")"; - } + this.isPropagationStopped = functionThatReturnsTrue; + }, - return printed; -} + /** + * We release all dispatched `SyntheticEvent`s after each event loop, adding + * them back into the pool. This allows a way to hold onto a reference that + * won't be added back into the pool. + */ + persist: function() { + this.isPersistent = functionThatReturnsTrue; + }, -var ResponderTouchHistoryStore = { - recordTouchTrack: function(topLevelType, nativeEvent) { - if (isMoveish(topLevelType)) { - nativeEvent.changedTouches.forEach(recordTouchMove); - } else if (isStartish(topLevelType)) { - nativeEvent.changedTouches.forEach(recordTouchStart); - touchHistory.numberActiveTouches = nativeEvent.touches.length; + /** + * Checks if this event should be released back into the pool. + * + * @return {boolean} True if this should not be released, false otherwise. + */ + isPersistent: functionThatReturnsFalse, - if (touchHistory.numberActiveTouches === 1) { - touchHistory.indexOfSingleActiveTouch = - nativeEvent.touches[0].identifier; + /** + * `PooledClass` looks for `destructor` on each instance it releases. + */ + destructor: function() { + var Interface = this.constructor.Interface; + for (var propName in Interface) { + { + Object.defineProperty( + this, + propName, + getPooledWarningPropertyDefinition(propName, Interface[propName]) + ); } - } else if (isEndish(topLevelType)) { - nativeEvent.changedTouches.forEach(recordTouchEnd); - touchHistory.numberActiveTouches = nativeEvent.touches.length; + } + this.dispatchConfig = null; + this._targetInst = null; + this.nativeEvent = null; + this.isDefaultPrevented = functionThatReturnsFalse; + this.isPropagationStopped = functionThatReturnsFalse; + this._dispatchListeners = null; + this._dispatchInstances = null; + { + Object.defineProperty( + this, + "nativeEvent", + getPooledWarningPropertyDefinition("nativeEvent", null) + ); + Object.defineProperty( + this, + "isDefaultPrevented", + getPooledWarningPropertyDefinition( + "isDefaultPrevented", + functionThatReturnsFalse + ) + ); + Object.defineProperty( + this, + "isPropagationStopped", + getPooledWarningPropertyDefinition( + "isPropagationStopped", + functionThatReturnsFalse + ) + ); + Object.defineProperty( + this, + "preventDefault", + getPooledWarningPropertyDefinition("preventDefault", function() {}) + ); + Object.defineProperty( + this, + "stopPropagation", + getPooledWarningPropertyDefinition("stopPropagation", function() {}) + ); + } + } +}); +SyntheticEvent.Interface = EventInterface; +/** + * Helper to reduce boilerplate when creating subclasses. + */ - if (touchHistory.numberActiveTouches === 1) { - for (var i = 0; i < touchBank.length; i++) { - var touchTrackToCheck = touchBank[i]; +SyntheticEvent.extend = function(Interface) { + var Super = this; - if (touchTrackToCheck != null && touchTrackToCheck.touchActive) { - touchHistory.indexOfSingleActiveTouch = i; - break; - } - } + var E = function() {}; + E.prototype = Super.prototype; + var prototype = new E(); - { - var activeRecord = touchBank[touchHistory.indexOfSingleActiveTouch]; + function Class() { + return Super.apply(this, arguments); + } - if (activeRecord == null || !activeRecord.touchActive) { - error("Cannot find single active touch."); - } - } - } - } - }, - touchHistory: touchHistory + Object.assign(prototype, Class.prototype); + Class.prototype = prototype; + Class.prototype.constructor = Class; + Class.Interface = Object.assign({}, Super.Interface, Interface); + Class.extend = Super.extend; + addEventPoolingTo(Class); + return Class; }; +addEventPoolingTo(SyntheticEvent); /** - * Accumulates items that must not be null or undefined. - * - * This is used to conserve memory by avoiding array allocations. + * Helper to nullify syntheticEvent instance properties when destructing * - * @return {*|array<*>} An accumulation of items. + * @param {String} propName + * @param {?object} getVal + * @return {object} defineProperty object */ +function getPooledWarningPropertyDefinition(propName, getVal) { + var isFunction = typeof getVal === "function"; + return { + configurable: true, + set: set, + get: get + }; -function accumulate(current, next) { - if (!(next != null)) { - throw Error( - "accumulate(...): Accumulated items must not be null or undefined." - ); + function set(val) { + var action = isFunction ? "setting the method" : "setting the property"; + warn(action, "This is effectively a no-op"); + return val; } - if (current == null) { - return next; - } // Both are not empty. Warning: Never call x.concat(y) when you are not - // certain that x is an Array (x could be a string with concat method). - - if (Array.isArray(current)) { - return current.concat(next); + function get() { + var action = isFunction ? "accessing the method" : "accessing the property"; + var result = isFunction + ? "This is a no-op function" + : "This is set to null"; + warn(action, result); + return getVal; } - if (Array.isArray(next)) { - return [current].concat(next); - } + function warn(action, result) { + var warningCondition = false; + !warningCondition + ? warningWithoutStack$1( + false, + "This synthetic event is reused for performance reasons. If you're seeing this, " + + "you're %s `%s` on a released/nullified synthetic event. %s. " + + "If you must keep the original synthetic event around, use event.persist(). " + + "See https://fb.me/react-event-pooling for more information.", + action, + propName, + result + ) + : void 0; + } +} - return [current, next]; +function getPooledEvent(dispatchConfig, targetInst, nativeEvent, nativeInst) { + var EventConstructor = this; + if (EventConstructor.eventPool.length) { + var instance = EventConstructor.eventPool.pop(); + EventConstructor.call( + instance, + dispatchConfig, + targetInst, + nativeEvent, + nativeInst + ); + return instance; + } + return new EventConstructor( + dispatchConfig, + targetInst, + nativeEvent, + nativeInst + ); +} + +function releasePooledEvent(event) { + var EventConstructor = this; + + if (!(event instanceof EventConstructor)) { + throw Error( + "Trying to release an event instance into a pool of a different type." + ); + } + + event.destructor(); + + if (EventConstructor.eventPool.length < EVENT_POOL_SIZE) { + EventConstructor.eventPool.push(event); + } +} + +function addEventPoolingTo(EventConstructor) { + EventConstructor.eventPool = []; + EventConstructor.getPooled = getPooledEvent; + EventConstructor.release = releasePooledEvent; } /** - * Instance of element that should respond to touch/move types of interactions, - * as indicated explicitly by relevant callbacks. + * `touchHistory` isn't actually on the native event, but putting it in the + * interface will ensure that it is cleaned up when pooled/destroyed. The + * `ResponderEventPlugin` will populate it appropriately. */ +var ResponderSyntheticEvent = SyntheticEvent.extend({ + touchHistory: function(nativeEvent) { + return null; // Actually doesn't even look at the native event. + } +}); + +var TOP_TOUCH_START = "topTouchStart"; +var TOP_TOUCH_MOVE = "topTouchMove"; +var TOP_TOUCH_END = "topTouchEnd"; +var TOP_TOUCH_CANCEL = "topTouchCancel"; +var TOP_SCROLL = "topScroll"; +var TOP_SELECTION_CHANGE = "topSelectionChange"; +function isStartish(topLevelType) { + return topLevelType === TOP_TOUCH_START; +} +function isMoveish(topLevelType) { + return topLevelType === TOP_TOUCH_MOVE; +} +function isEndish(topLevelType) { + return topLevelType === TOP_TOUCH_END || topLevelType === TOP_TOUCH_CANCEL; +} +var startDependencies = [TOP_TOUCH_START]; +var moveDependencies = [TOP_TOUCH_MOVE]; +var endDependencies = [TOP_TOUCH_CANCEL, TOP_TOUCH_END]; -var responderInst = null; /** - * Count of current touches. A textInput should become responder iff the - * selection changes while there is a touch on the screen. + * Tracks the position and time of each active touch by `touch.identifier`. We + * should typically only see IDs in the range of 1-20 because IDs get recycled + * when touches end and start again. */ -var trackedTouchCount = 0; +var MAX_TOUCH_BANK = 20; +var touchBank = []; +var touchHistory = { + touchBank: touchBank, + numberActiveTouches: 0, + // If there is only one active touch, we remember its location. This prevents + // us having to loop through all of the touches all the time in the most + // common case. + indexOfSingleActiveTouch: -1, + mostRecentTimeStamp: 0 +}; -var changeResponder = function(nextResponderInst, blockHostResponder) { - var oldResponderInst = responderInst; - responderInst = nextResponderInst; +function timestampForTouch(touch) { + // The legacy internal implementation provides "timeStamp", which has been + // renamed to "timestamp". Let both work for now while we iron it out + // TODO (evv): rename timeStamp to timestamp in internal code + return touch.timeStamp || touch.timestamp; +} +/** + * TODO: Instead of making gestures recompute filtered velocity, we could + * include a built in velocity computation that can be reused globally. + */ +function createTouchRecord(touch) { + return { + touchActive: true, + startPageX: touch.pageX, + startPageY: touch.pageY, + startTimeStamp: timestampForTouch(touch), + currentPageX: touch.pageX, + currentPageY: touch.pageY, + currentTimeStamp: timestampForTouch(touch), + previousPageX: touch.pageX, + previousPageY: touch.pageY, + previousTimeStamp: timestampForTouch(touch) + }; +} - if (ResponderEventPlugin.GlobalResponderHandler !== null) { - ResponderEventPlugin.GlobalResponderHandler.onChange( - oldResponderInst, - nextResponderInst, - blockHostResponder - ); +function resetTouchRecord(touchRecord, touch) { + touchRecord.touchActive = true; + touchRecord.startPageX = touch.pageX; + touchRecord.startPageY = touch.pageY; + touchRecord.startTimeStamp = timestampForTouch(touch); + touchRecord.currentPageX = touch.pageX; + touchRecord.currentPageY = touch.pageY; + touchRecord.currentTimeStamp = timestampForTouch(touch); + touchRecord.previousPageX = touch.pageX; + touchRecord.previousPageY = touch.pageY; + touchRecord.previousTimeStamp = timestampForTouch(touch); +} + +function getTouchIdentifier(_ref) { + var identifier = _ref.identifier; + + if (!(identifier != null)) { + throw Error("Touch object is missing identifier."); } -}; -var eventTypes = { - /** - * On a `touchStart`/`mouseDown`, is it desired that this element become the - * responder? - */ - startShouldSetResponder: { - phasedRegistrationNames: { - bubbled: "onStartShouldSetResponder", - captured: "onStartShouldSetResponderCapture" - }, - dependencies: startDependencies - }, + { + !(identifier <= MAX_TOUCH_BANK) + ? warningWithoutStack$1( + false, + "Touch identifier %s is greater than maximum supported %s which causes " + + "performance issues backfilling array locations for all of the indices.", + identifier, + MAX_TOUCH_BANK + ) + : void 0; + } + return identifier; +} - /** - * On a `scroll`, is it desired that this element become the responder? This - * is usually not needed, but should be used to retroactively infer that a - * `touchStart` had occurred during momentum scroll. During a momentum scroll, - * a touch start will be immediately followed by a scroll event if the view is - * currently scrolling. - * - * TODO: This shouldn't bubble. - */ - scrollShouldSetResponder: { - phasedRegistrationNames: { - bubbled: "onScrollShouldSetResponder", - captured: "onScrollShouldSetResponderCapture" - }, - dependencies: [TOP_SCROLL] - }, +function recordTouchStart(touch) { + var identifier = getTouchIdentifier(touch); + var touchRecord = touchBank[identifier]; + if (touchRecord) { + resetTouchRecord(touchRecord, touch); + } else { + touchBank[identifier] = createTouchRecord(touch); + } + touchHistory.mostRecentTimeStamp = timestampForTouch(touch); +} - /** - * On text selection change, should this element become the responder? This - * is needed for text inputs or other views with native selection, so the - * JS view can claim the responder. - * - * TODO: This shouldn't bubble. - */ - selectionChangeShouldSetResponder: { - phasedRegistrationNames: { - bubbled: "onSelectionChangeShouldSetResponder", - captured: "onSelectionChangeShouldSetResponderCapture" - }, - dependencies: [TOP_SELECTION_CHANGE] - }, +function recordTouchMove(touch) { + var touchRecord = touchBank[getTouchIdentifier(touch)]; + if (touchRecord) { + touchRecord.touchActive = true; + touchRecord.previousPageX = touchRecord.currentPageX; + touchRecord.previousPageY = touchRecord.currentPageY; + touchRecord.previousTimeStamp = touchRecord.currentTimeStamp; + touchRecord.currentPageX = touch.pageX; + touchRecord.currentPageY = touch.pageY; + touchRecord.currentTimeStamp = timestampForTouch(touch); + touchHistory.mostRecentTimeStamp = timestampForTouch(touch); + } else { + console.warn( + "Cannot record touch move without a touch start.\n" + "Touch Move: %s\n", + "Touch Bank: %s", + printTouch(touch), + printTouchBank() + ); + } +} - /** - * On a `touchMove`/`mouseMove`, is it desired that this element become the - * responder? - */ - moveShouldSetResponder: { - phasedRegistrationNames: { - bubbled: "onMoveShouldSetResponder", - captured: "onMoveShouldSetResponderCapture" - }, - dependencies: moveDependencies - }, +function recordTouchEnd(touch) { + var touchRecord = touchBank[getTouchIdentifier(touch)]; + if (touchRecord) { + touchRecord.touchActive = false; + touchRecord.previousPageX = touchRecord.currentPageX; + touchRecord.previousPageY = touchRecord.currentPageY; + touchRecord.previousTimeStamp = touchRecord.currentTimeStamp; + touchRecord.currentPageX = touch.pageX; + touchRecord.currentPageY = touch.pageY; + touchRecord.currentTimeStamp = timestampForTouch(touch); + touchHistory.mostRecentTimeStamp = timestampForTouch(touch); + } else { + console.warn( + "Cannot record touch end without a touch start.\n" + "Touch End: %s\n", + "Touch Bank: %s", + printTouch(touch), + printTouchBank() + ); + } +} - /** - * Direct responder events dispatched directly to responder. Do not bubble. - */ - responderStart: { - registrationName: "onResponderStart", - dependencies: startDependencies - }, - responderMove: { - registrationName: "onResponderMove", - dependencies: moveDependencies - }, - responderEnd: { +function printTouch(touch) { + return JSON.stringify({ + identifier: touch.identifier, + pageX: touch.pageX, + pageY: touch.pageY, + timestamp: timestampForTouch(touch) + }); +} + +function printTouchBank() { + var printed = JSON.stringify(touchBank.slice(0, MAX_TOUCH_BANK)); + + if (touchBank.length > MAX_TOUCH_BANK) { + printed += " (original size: " + touchBank.length + ")"; + } + + return printed; +} + +var ResponderTouchHistoryStore = { + recordTouchTrack: function(topLevelType, nativeEvent) { + if (isMoveish(topLevelType)) { + nativeEvent.changedTouches.forEach(recordTouchMove); + } else if (isStartish(topLevelType)) { + nativeEvent.changedTouches.forEach(recordTouchStart); + touchHistory.numberActiveTouches = nativeEvent.touches.length; + if (touchHistory.numberActiveTouches === 1) { + touchHistory.indexOfSingleActiveTouch = + nativeEvent.touches[0].identifier; + } + } else if (isEndish(topLevelType)) { + nativeEvent.changedTouches.forEach(recordTouchEnd); + touchHistory.numberActiveTouches = nativeEvent.touches.length; + + if (touchHistory.numberActiveTouches === 1) { + for (var i = 0; i < touchBank.length; i++) { + var touchTrackToCheck = touchBank[i]; + + if (touchTrackToCheck != null && touchTrackToCheck.touchActive) { + touchHistory.indexOfSingleActiveTouch = i; + break; + } + } + { + var activeRecord = touchBank[touchHistory.indexOfSingleActiveTouch]; + !(activeRecord != null && activeRecord.touchActive) + ? warningWithoutStack$1(false, "Cannot find single active touch.") + : void 0; + } + } + } + }, + touchHistory: touchHistory +}; + +/** + * Accumulates items that must not be null or undefined. + * + * This is used to conserve memory by avoiding array allocations. + * + * @return {*|array<*>} An accumulation of items. + */ + +function accumulate(current, next) { + if (!(next != null)) { + throw Error( + "accumulate(...): Accumulated items must not be null or undefined." + ); + } + + if (current == null) { + return next; + } // Both are not empty. Warning: Never call x.concat(y) when you are not + // certain that x is an Array (x could be a string with concat method). + + if (Array.isArray(current)) { + return current.concat(next); + } + + if (Array.isArray(next)) { + return [current].concat(next); + } + + return [current, next]; +} + +/** + * Instance of element that should respond to touch/move types of interactions, + * as indicated explicitly by relevant callbacks. + */ + +var responderInst = null; +/** + * Count of current touches. A textInput should become responder iff the + * selection changes while there is a touch on the screen. + */ +var trackedTouchCount = 0; + +var changeResponder = function(nextResponderInst, blockHostResponder) { + var oldResponderInst = responderInst; + responderInst = nextResponderInst; + if (ResponderEventPlugin.GlobalResponderHandler !== null) { + ResponderEventPlugin.GlobalResponderHandler.onChange( + oldResponderInst, + nextResponderInst, + blockHostResponder + ); + } +}; + +var eventTypes = { + /** + * On a `touchStart`/`mouseDown`, is it desired that this element become the + * responder? + */ + startShouldSetResponder: { + phasedRegistrationNames: { + bubbled: "onStartShouldSetResponder", + captured: "onStartShouldSetResponderCapture" + }, + dependencies: startDependencies + }, + + /** + * On a `scroll`, is it desired that this element become the responder? This + * is usually not needed, but should be used to retroactively infer that a + * `touchStart` had occurred during momentum scroll. During a momentum scroll, + * a touch start will be immediately followed by a scroll event if the view is + * currently scrolling. + * + * TODO: This shouldn't bubble. + */ + scrollShouldSetResponder: { + phasedRegistrationNames: { + bubbled: "onScrollShouldSetResponder", + captured: "onScrollShouldSetResponderCapture" + }, + dependencies: [TOP_SCROLL] + }, + + /** + * On text selection change, should this element become the responder? This + * is needed for text inputs or other views with native selection, so the + * JS view can claim the responder. + * + * TODO: This shouldn't bubble. + */ + selectionChangeShouldSetResponder: { + phasedRegistrationNames: { + bubbled: "onSelectionChangeShouldSetResponder", + captured: "onSelectionChangeShouldSetResponderCapture" + }, + dependencies: [TOP_SELECTION_CHANGE] + }, + + /** + * On a `touchMove`/`mouseMove`, is it desired that this element become the + * responder? + */ + moveShouldSetResponder: { + phasedRegistrationNames: { + bubbled: "onMoveShouldSetResponder", + captured: "onMoveShouldSetResponderCapture" + }, + dependencies: moveDependencies + }, + + /** + * Direct responder events dispatched directly to responder. Do not bubble. + */ + responderStart: { + registrationName: "onResponderStart", + dependencies: startDependencies + }, + responderMove: { + registrationName: "onResponderMove", + dependencies: moveDependencies + }, + responderEnd: { registrationName: "onResponderEnd", dependencies: endDependencies }, @@ -1795,7 +2110,7 @@ to return true:wantsResponderID| | + + */ /** - * A note about event ordering in the `EventPluginRegistry`. + * A note about event ordering in the `EventPluginHub`. * * Suppose plugins are injected in the following order: * @@ -1814,7 +2129,7 @@ to return true:wantsResponderID| | * - When returned from `extractEvents`, deferred-dispatched events contain an * "accumulation" of deferred dispatches. * - These deferred dispatches are accumulated/collected before they are - * returned, but processed at a later time by the `EventPluginRegistry` (hence the + * returned, but processed at a later time by the `EventPluginHub` (hence the * name deferred). * * In the process of returning their deferred-dispatched events, event plugins @@ -1838,9 +2153,9 @@ to return true:wantsResponderID| | * - `R`s on-demand events (if any) (dispatched by `R` on-demand) * - `S`s on-demand events (if any) (dispatched by `S` on-demand) * - `C`s on-demand events (if any) (dispatched by `C` on-demand) - * - `R`s extracted events (if any) (dispatched by `EventPluginRegistry`) - * - `S`s extracted events (if any) (dispatched by `EventPluginRegistry`) - * - `C`s extracted events (if any) (dispatched by `EventPluginRegistry`) + * - `R`s extracted events (if any) (dispatched by `EventPluginHub`) + * - `S`s extracted events (if any) (dispatched by `EventPluginHub`) + * - `C`s extracted events (if any) (dispatched by `EventPluginHub`) * * In the case of `ResponderEventPlugin`: If the `startShouldSetResponder` * on-demand dispatch returns `true` (and some other details are satisfied) the @@ -1849,9 +2164,9 @@ to return true:wantsResponderID| | * will appear as follows: * * - `startShouldSetResponder` (`ResponderEventPlugin` dispatches on-demand) - * - `touchStartCapture` (`EventPluginRegistry` dispatches as usual) - * - `touchStart` (`EventPluginRegistry` dispatches as usual) - * - `responderGrant/Reject` (`EventPluginRegistry` dispatches as usual) + * - `touchStartCapture` (`EventPluginHub` dispatches as usual) + * - `touchStart` (`EventPluginHub` dispatches as usual) + * - `responderGrant/Reject` (`EventPluginHub` dispatches as usual) */ function setResponderAndExtractTransfer( @@ -1863,10 +2178,10 @@ function setResponderAndExtractTransfer( var shouldSetEventType = isStartish(topLevelType) ? eventTypes.startShouldSetResponder : isMoveish(topLevelType) - ? eventTypes.moveShouldSetResponder - : topLevelType === TOP_SELECTION_CHANGE - ? eventTypes.selectionChangeShouldSetResponder - : eventTypes.scrollShouldSetResponder; // TODO: stop one short of the current responder. + ? eventTypes.moveShouldSetResponder + : topLevelType === TOP_SELECTION_CHANGE + ? eventTypes.selectionChangeShouldSetResponder + : eventTypes.scrollShouldSetResponder; // TODO: stop one short of the current responder. var bubbleShouldSetFrom = !responderInst ? targetInst @@ -1883,7 +2198,6 @@ function setResponderAndExtractTransfer( nativeEventTarget ); shouldSetEvent.touchHistory = ResponderTouchHistoryStore.touchHistory; - if (skipOverBubbleShouldSetFrom) { accumulateTwoPhaseDispatchesSkipTarget(shouldSetEvent); } else { @@ -1924,7 +2238,6 @@ function setResponderAndExtractTransfer( var shouldSwitch = !hasDispatches(terminationRequestEvent) || executeDirectDispatch(terminationRequestEvent); - if (!terminationRequestEvent.isPersistent()) { terminationRequestEvent.constructor.release(terminationRequestEvent); } @@ -2006,7 +2319,6 @@ function noResponderTouches(nativeEvent) { } } } - return true; } @@ -2035,12 +2347,9 @@ var ResponderEventPlugin = { if (trackedTouchCount >= 0) { trackedTouchCount -= 1; } else { - { - warn( - "Ended a touch event which was not counted in `trackedTouchCount`." - ); - } - + console.warn( + "Ended a touch event which was not counted in `trackedTouchCount`." + ); return null; } } @@ -2063,17 +2372,16 @@ var ResponderEventPlugin = { // These multiple individual change touch events are are always bookended // by `onResponderGrant`, and one of // (`onResponderRelease/onResponderTerminate`). - var isResponderTouchStart = responderInst && isStartish(topLevelType); var isResponderTouchMove = responderInst && isMoveish(topLevelType); var isResponderTouchEnd = responderInst && isEndish(topLevelType); var incrementalTouch = isResponderTouchStart ? eventTypes.responderStart : isResponderTouchMove - ? eventTypes.responderMove - : isResponderTouchEnd - ? eventTypes.responderEnd - : null; + ? eventTypes.responderMove + : isResponderTouchEnd + ? eventTypes.responderEnd + : null; if (incrementalTouch) { var gesture = ResponderSyntheticEvent.getPooled( @@ -2097,9 +2405,8 @@ var ResponderEventPlugin = { var finalTouch = isResponderTerminate ? eventTypes.responderTerminate : isResponderRelease - ? eventTypes.responderRelease - : null; - + ? eventTypes.responderRelease + : null; if (finalTouch) { var finalEvent = ResponderSyntheticEvent.getPooled( finalTouch, @@ -2128,276 +2435,55 @@ var ResponderEventPlugin = { } }; -/** - * Injectable ordering of event plugins. - */ -var eventPluginOrder = null; -/** - * Injectable mapping from names to event plugin modules. - */ - -var namesToPlugins = {}; -/** - * Recomputes the plugin list using the injected plugins and plugin ordering. - * - * @private - */ +var customBubblingEventTypes = + ReactNativePrivateInterface.ReactNativeViewConfigRegistry + .customBubblingEventTypes; +var customDirectEventTypes = + ReactNativePrivateInterface.ReactNativeViewConfigRegistry + .customDirectEventTypes; +var ReactNativeBridgeEventPlugin = { + eventTypes: {}, -function recomputePluginOrdering() { - if (!eventPluginOrder) { - // Wait until an `eventPluginOrder` is injected. - return; - } + /** + * @see {EventPluginHub.extractEvents} + */ + extractEvents: function( + topLevelType, + targetInst, + nativeEvent, + nativeEventTarget, + eventSystemFlags + ) { + if (targetInst == null) { + // Probably a node belonging to another renderer's tree. + return null; + } - for (var pluginName in namesToPlugins) { - var pluginModule = namesToPlugins[pluginName]; - var pluginIndex = eventPluginOrder.indexOf(pluginName); + var bubbleDispatchConfig = customBubblingEventTypes[topLevelType]; + var directDispatchConfig = customDirectEventTypes[topLevelType]; - if (!(pluginIndex > -1)) { + if (!(bubbleDispatchConfig || directDispatchConfig)) { throw Error( - "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + - pluginName + - "`." + 'Unsupported top level event type "' + topLevelType + '" dispatched' ); } - if (plugins[pluginIndex]) { - continue; + var event = SyntheticEvent.getPooled( + bubbleDispatchConfig || directDispatchConfig, + targetInst, + nativeEvent, + nativeEventTarget + ); + if (bubbleDispatchConfig) { + accumulateTwoPhaseDispatches(event); + } else if (directDispatchConfig) { + accumulateDirectDispatches(event); + } else { + return null; } - - if (!pluginModule.extractEvents) { - throw Error( - "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + - pluginName + - "` does not." - ); - } - - plugins[pluginIndex] = pluginModule; - var publishedEvents = pluginModule.eventTypes; - - for (var eventName in publishedEvents) { - if ( - !publishEventForPlugin( - publishedEvents[eventName], - pluginModule, - eventName - ) - ) { - throw Error( - "EventPluginRegistry: Failed to publish event `" + - eventName + - "` for plugin `" + - pluginName + - "`." - ); - } - } - } -} -/** - * Publishes an event so that it can be dispatched by the supplied plugin. - * - * @param {object} dispatchConfig Dispatch configuration for the event. - * @param {object} PluginModule Plugin publishing the event. - * @return {boolean} True if the event was successfully published. - * @private - */ - -function publishEventForPlugin(dispatchConfig, pluginModule, eventName) { - if (!!eventNameDispatchConfigs.hasOwnProperty(eventName)) { - throw Error( - "EventPluginRegistry: More than one plugin attempted to publish the same event name, `" + - eventName + - "`." - ); - } - - eventNameDispatchConfigs[eventName] = dispatchConfig; - var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; - - if (phasedRegistrationNames) { - for (var phaseName in phasedRegistrationNames) { - if (phasedRegistrationNames.hasOwnProperty(phaseName)) { - var phasedRegistrationName = phasedRegistrationNames[phaseName]; - publishRegistrationName( - phasedRegistrationName, - pluginModule, - eventName - ); - } - } - - return true; - } else if (dispatchConfig.registrationName) { - publishRegistrationName( - dispatchConfig.registrationName, - pluginModule, - eventName - ); - return true; - } - - return false; -} -/** - * Publishes a registration name that is used to identify dispatched events. - * - * @param {string} registrationName Registration name to add. - * @param {object} PluginModule Plugin publishing the event. - * @private - */ - -function publishRegistrationName(registrationName, pluginModule, eventName) { - if (!!registrationNameModules[registrationName]) { - throw Error( - "EventPluginRegistry: More than one plugin attempted to publish the same registration name, `" + - registrationName + - "`." - ); - } - - registrationNameModules[registrationName] = pluginModule; - registrationNameDependencies[registrationName] = - pluginModule.eventTypes[eventName].dependencies; - - { - var lowerCasedName = registrationName.toLowerCase(); - } -} -/** - * Registers plugins so that they can extract and dispatch events. - */ - -/** - * Ordered list of injected plugins. - */ - -var plugins = []; -/** - * Mapping from event name to dispatch config - */ - -var eventNameDispatchConfigs = {}; -/** - * Mapping from registration name to plugin module - */ - -var registrationNameModules = {}; -/** - * Mapping from registration name to event name - */ - -var registrationNameDependencies = {}; - -/** - * Injects an ordering of plugins (by plugin name). This allows the ordering - * to be decoupled from injection of the actual plugins so that ordering is - * always deterministic regardless of packaging, on-the-fly injection, etc. - * - * @param {array} InjectedEventPluginOrder - * @internal - */ - -function injectEventPluginOrder(injectedEventPluginOrder) { - if (!!eventPluginOrder) { - throw Error( - "EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React." - ); - } // Clone the ordering so it cannot be dynamically mutated. - - eventPluginOrder = Array.prototype.slice.call(injectedEventPluginOrder); - recomputePluginOrdering(); -} -/** - * Injects plugins to be used by plugin event system. The plugin names must be - * in the ordering injected by `injectEventPluginOrder`. - * - * Plugins can be injected as part of page initialization or on-the-fly. - * - * @param {object} injectedNamesToPlugins Map from names to plugin modules. - * @internal - */ - -function injectEventPluginsByName(injectedNamesToPlugins) { - var isOrderingDirty = false; - - for (var pluginName in injectedNamesToPlugins) { - if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) { - continue; - } - - var pluginModule = injectedNamesToPlugins[pluginName]; - - if ( - !namesToPlugins.hasOwnProperty(pluginName) || - namesToPlugins[pluginName] !== pluginModule - ) { - if (!!namesToPlugins[pluginName]) { - throw Error( - "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - pluginName + - "`." - ); - } - - namesToPlugins[pluginName] = pluginModule; - isOrderingDirty = true; - } - } - - if (isOrderingDirty) { - recomputePluginOrdering(); - } -} - -var customBubblingEventTypes = - ReactNativePrivateInterface.ReactNativeViewConfigRegistry - .customBubblingEventTypes, - customDirectEventTypes = - ReactNativePrivateInterface.ReactNativeViewConfigRegistry - .customDirectEventTypes; -var ReactNativeBridgeEventPlugin = { - eventTypes: {}, - extractEvents: function( - topLevelType, - targetInst, - nativeEvent, - nativeEventTarget, - eventSystemFlags - ) { - if (targetInst == null) { - // Probably a node belonging to another renderer's tree. - return null; - } - - var bubbleDispatchConfig = customBubblingEventTypes[topLevelType]; - var directDispatchConfig = customDirectEventTypes[topLevelType]; - - if (!(bubbleDispatchConfig || directDispatchConfig)) { - throw Error( - 'Unsupported top level event type "' + topLevelType + '" dispatched' - ); - } - - var event = SyntheticEvent.getPooled( - bubbleDispatchConfig || directDispatchConfig, - targetInst, - nativeEvent, - nativeEventTarget - ); - - if (bubbleDispatchConfig) { - accumulateTwoPhaseDispatches(event); - } else if (directDispatchConfig) { - accumulateDirectDispatches(event); - } else { - return null; - } - - return event; - } -}; + return event; + } +}; var ReactNativeEventPluginOrder = [ "ResponderEventPlugin", @@ -2410,34 +2496,73 @@ var ReactNativeEventPluginOrder = [ * ensures it exists in the dependency graph and can be `require`d. * TODO: require this in packager, not in React #10932517 */ +// Module provided by RN: /** * Inject module for resolving DOM hierarchy and plugin ordering. */ -injectEventPluginOrder(ReactNativeEventPluginOrder); +injection.injectEventPluginOrder(ReactNativeEventPluginOrder); /** * Some important event plugins included by default (without having to require * them). */ - -injectEventPluginsByName({ +injection.injectEventPluginsByName({ ResponderEventPlugin: ResponderEventPlugin, ReactNativeBridgeEventPlugin: ReactNativeBridgeEventPlugin }); +// Uncomment to re-export dynamic flags from the fbsource version. +var _require = require("../shims/ReactFeatureFlags"); +var enableNativeTargetAsInstance = _require.enableNativeTargetAsInstance; // The rest of the flags are static for better dead code elimination. + +var enableUserTimingAPI = true; +var enableProfilerTimer = true; +var enableSchedulerTracing = true; +var enableSuspenseServerRenderer = false; + +var debugRenderPhaseSideEffectsForStrictMode = true; + +var replayFailedUnitOfWorkWithInvokeGuardedCallback = true; +var warnAboutDeprecatedLifecycles = true; +var enableFlareAPI = false; +var enableFundamentalAPI = false; +var enableScopeAPI = false; + +var warnAboutUnmockedScheduler = true; +var flushSuspenseFallbacksInTests = true; +var enableSuspenseCallback = false; +var warnAboutDefaultPropsOnFunctionComponents = false; +var warnAboutStringRefs = false; +var disableLegacyContext = false; +var disableSchedulerTimeoutBasedOnReactExpirationTime = false; +// Only used in www builds. + +// Flow magic to verify the exports of this file match the original version. + function getInstanceFromInstance(instanceHandle) { return instanceHandle; } function getTagFromInstance(inst) { - var nativeInstance = inst.stateNode.canonical; + if (enableNativeTargetAsInstance) { + var nativeInstance = inst.stateNode.canonical; - if (!nativeInstance._nativeTag) { - throw Error("All native instances should have a tag."); - } + if (!nativeInstance._nativeTag) { + throw Error("All native instances should have a tag."); + } + + return nativeInstance; + } else { + var tag = inst.stateNode.canonical._nativeTag; - return nativeInstance; + if (!tag) { + throw Error("All native instances should have a tag."); + } + + return tag; + } } + function getFiberCurrentPropsFromNode$1(inst) { return inst.canonical.currentProps; } @@ -2475,25 +2600,51 @@ ResponderEventPlugin.injection.injectGlobalResponderHandler( * Note that this module is currently shared and assumed to be stateless. * If this becomes an actual Map, that will break. */ + +/** + * This API should be called `delete` but we'd have to make sure to always + * transform these to strings for IE support. When this transform is fully + * supported we can rename it. + */ + function get(key) { return key._reactInternalFiber; } + function set(key, value) { key._reactInternalFiber = value; } -// The Symbol used to tag the ReactElement-like types. If there is no native Symbol -// nor polyfill, then a plain number is used for performance. -var hasSymbol = typeof Symbol === "function" && Symbol.for; -var REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for("react.element") : 0xeac7; -var REACT_PORTAL_TYPE = hasSymbol ? Symbol.for("react.portal") : 0xeaca; -var REACT_FRAGMENT_TYPE = hasSymbol ? Symbol.for("react.fragment") : 0xeacb; -var REACT_STRICT_MODE_TYPE = hasSymbol - ? Symbol.for("react.strict_mode") - : 0xeacc; -var REACT_PROFILER_TYPE = hasSymbol ? Symbol.for("react.profiler") : 0xead2; -var REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for("react.provider") : 0xeacd; +var ReactSharedInternals = + React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; // Prevent newer renderers from RTE when used with older react package versions. +// Current owner and dispatcher used to share the same ref, +// but PR #14548 split them out to better support the react-debug-tools package. + +if (!ReactSharedInternals.hasOwnProperty("ReactCurrentDispatcher")) { + ReactSharedInternals.ReactCurrentDispatcher = { + current: null + }; +} +if (!ReactSharedInternals.hasOwnProperty("ReactCurrentBatchConfig")) { + ReactSharedInternals.ReactCurrentBatchConfig = { + suspense: null + }; +} + +// The Symbol used to tag the ReactElement-like types. If there is no native Symbol +// nor polyfill, then a plain number is used for performance. +var hasSymbol = typeof Symbol === "function" && Symbol.for; +var REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for("react.element") : 0xeac7; +var REACT_PORTAL_TYPE = hasSymbol ? Symbol.for("react.portal") : 0xeaca; +var REACT_FRAGMENT_TYPE = hasSymbol ? Symbol.for("react.fragment") : 0xeacb; +var REACT_STRICT_MODE_TYPE = hasSymbol + ? Symbol.for("react.strict_mode") + : 0xeacc; +var REACT_PROFILER_TYPE = hasSymbol ? Symbol.for("react.profiler") : 0xead2; +var REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for("react.provider") : 0xeacd; var REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for("react.context") : 0xeace; // TODO: We don't use AsyncMode or ConcurrentMode anymore. They were temporary +// (unstable) APIs that have been removed. Can we remove the symbols? + var REACT_CONCURRENT_MODE_TYPE = hasSymbol ? Symbol.for("react.concurrent_mode") : 0xeacf; @@ -2506,7 +2657,11 @@ var REACT_SUSPENSE_LIST_TYPE = hasSymbol : 0xead8; var REACT_MEMO_TYPE = hasSymbol ? Symbol.for("react.memo") : 0xead3; var REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 0xead4; -var REACT_BLOCK_TYPE = hasSymbol ? Symbol.for("react.block") : 0xead9; +var REACT_FUNDAMENTAL_TYPE = hasSymbol + ? Symbol.for("react.fundamental") + : 0xead5; +var REACT_RESPONDER_TYPE = hasSymbol ? Symbol.for("react.responder") : 0xead6; +var REACT_SCOPE_TYPE = hasSymbol ? Symbol.for("react.scope") : 0xead7; var MAYBE_ITERATOR_SYMBOL = typeof Symbol === "function" && Symbol.iterator; var FAUX_ITERATOR_SYMBOL = "@@iterator"; function getIteratorFn(maybeIterable) { @@ -2525,29 +2680,56 @@ function getIteratorFn(maybeIterable) { return null; } -// TODO: Move this to "react" once we can import from externals. +/** + * Similar to invariant but only logs a warning if the condition is not met. + * This can be used to log issues in development environments in critical + * paths. Removing the logging code for production environments will keep the + * same logic and follow the same code paths. + */ + +var warning = warningWithoutStack$1; + +{ + warning = function(condition, format) { + if (condition) { + return; + } + + var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; + var stack = ReactDebugCurrentFrame.getStackAddendum(); // eslint-disable-next-line react-internal/warning-and-invariant-args + + for ( + var _len = arguments.length, + args = new Array(_len > 2 ? _len - 2 : 0), + _key = 2; + _key < _len; + _key++ + ) { + args[_key - 2] = arguments[_key]; + } + + warningWithoutStack$1.apply( + void 0, + [false, format + "%s"].concat(args, [stack]) + ); + }; +} + +var warning$1 = warning; + var Uninitialized = -1; var Pending = 0; var Resolved = 1; var Rejected = 2; - function refineResolvedLazyComponent(lazyComponent) { return lazyComponent._status === Resolved ? lazyComponent._result : null; } function initializeLazyComponentType(lazyComponent) { if (lazyComponent._status === Uninitialized) { - var ctor = lazyComponent._result; - - if (!ctor) { - // TODO: Remove this later. THis only exists in case you use an older "react" package. - ctor = lazyComponent._ctor; - } - - var thenable = ctor(); // Transition to the next state. - - var pending = lazyComponent; - pending._status = Pending; - pending._result = thenable; + lazyComponent._status = Pending; + var ctor = lazyComponent._ctor; + var thenable = ctor(); + lazyComponent._result = thenable; thenable.then( function(moduleObject) { if (lazyComponent._status === Pending) { @@ -2555,27 +2737,24 @@ function initializeLazyComponentType(lazyComponent) { { if (defaultExport === undefined) { - error( + warning$1( + false, "lazy: Expected the result of a dynamic import() call. " + - "Instead received: %s\n\nYour code should look like: \n " + // Break up imports to avoid accidentally parsing them as dependencies. - "const MyComponent = lazy(() => imp" + - "ort('./MyComponent'))", + "Instead received: %s\n\nYour code should look like: \n " + + "const MyComponent = lazy(() => import('./MyComponent'))", moduleObject ); } - } // Transition to the next state. + } - var resolved = lazyComponent; - resolved._status = Resolved; - resolved._result = defaultExport; + lazyComponent._status = Resolved; + lazyComponent._result = defaultExport; } }, function(error) { if (lazyComponent._status === Pending) { - // Transition to the next state. - var rejected = lazyComponent; - rejected._status = Rejected; - rejected._result = error; + lazyComponent._status = Rejected; + lazyComponent._result = error; } } ); @@ -2590,19 +2769,15 @@ function getWrappedName(outerType, innerType, wrapperName) { ); } -function getContextName(type) { - return type.displayName || "Context"; -} - function getComponentName(type) { if (type == null) { // Host root, text node or just invalid type. return null; } - { if (typeof type.tag === "number") { - error( + warningWithoutStack$1( + false, "Received an unexpected object in getComponentName(). " + "This is likely a bug in React. Please file an issue." ); @@ -2640,12 +2815,10 @@ function getComponentName(type) { if (typeof type === "object") { switch (type.$$typeof) { case REACT_CONTEXT_TYPE: - var context = type; - return getContextName(context) + ".Consumer"; + return "Context.Consumer"; case REACT_PROVIDER_TYPE: - var provider = type; - return getContextName(provider._context) + ".Provider"; + return "Context.Provider"; case REACT_FORWARD_REF_TYPE: return getWrappedName(type, type.render, "ForwardRef"); @@ -2653,9 +2826,6 @@ function getComponentName(type) { case REACT_MEMO_TYPE: return getComponentName(type.type); - case REACT_BLOCK_TYPE: - return getComponentName(type.render); - case REACT_LAZY_TYPE: { var thenable = type; var resolvedThenable = refineResolvedLazyComponent(thenable); @@ -2668,7 +2838,6 @@ function getComponentName(type) { } } } - return null; } @@ -2731,10 +2900,7 @@ var ShouldCapture = /* */ 4096; -var enableProfilerTimer = true; -var warnAboutStringRefs = false; - -var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner; +var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner; function getNearestMountedFiber(fiber) { var node = fiber; var nearestMounted = fiber; @@ -2771,28 +2937,28 @@ function getNearestMountedFiber(fiber) { return null; } + function isFiberMounted(fiber) { return getNearestMountedFiber(fiber) === fiber; } function isMounted(component) { { - var owner = ReactCurrentOwner.current; + var owner = ReactCurrentOwner$1.current; if (owner !== null && owner.tag === ClassComponent) { var ownerFiber = owner; var instance = ownerFiber.stateNode; - - if (!instance._warnedAboutRefsInRender) { - error( - "%s is accessing isMounted inside its render() function. " + - "render() should be a pure function of props and state. It should " + - "never access something that requires stale data from the previous " + - "render, such as refs. Move this logic to componentDidMount and " + - "componentDidUpdate instead.", - getComponentName(ownerFiber.type) || "A component" - ); - } - + !instance._warnedAboutRefsInRender + ? warningWithoutStack$1( + false, + "%s is accessing isMounted inside its render() function. " + + "render() should be a pure function of props and state. It should " + + "never access something that requires stale data from the previous " + + "render, such as refs. Move this logic to componentDidMount and " + + "componentDidUpdate instead.", + getComponentName(ownerFiber.type) || "A component" + ) + : void 0; instance._warnedAboutRefsInRender = true; } } @@ -2871,7 +3037,6 @@ function findCurrentFiberUsingSlowPath(fiber) { assertIsMounted(parentA); return fiber; } - if (child === b) { // We've determined that B is the current branch. assertIsMounted(parentA); @@ -2902,7 +3067,6 @@ function findCurrentFiberUsingSlowPath(fiber) { // Search parent A's child set var didFindChild = false; var _child = parentA.child; - while (_child) { if (_child === a) { didFindChild = true; @@ -2910,7 +3074,6 @@ function findCurrentFiberUsingSlowPath(fiber) { b = parentB; break; } - if (_child === b) { didFindChild = true; b = parentA; @@ -2932,7 +3095,6 @@ function findCurrentFiberUsingSlowPath(fiber) { b = parentA; break; } - if (_child === b) { didFindChild = true; b = parentB; @@ -3038,6 +3200,41 @@ function mountSafeCallback_NOT_REALLY_SAFE(context, callback) { return callback.apply(context, arguments); }; } +function throwOnStylesProp(component, props) { + if (props.styles !== undefined) { + var owner = component._owner || null; + var name = component.constructor.displayName; + var msg = + "`styles` is not a supported property of `" + + name + + "`, did " + + "you mean `style` (singular)?"; + if (owner && owner.constructor && owner.constructor.displayName) { + msg += + "\n\nCheck the `" + + owner.constructor.displayName + + "` parent " + + " component."; + } + + throw new Error(msg); + } +} +function warnForStyleProps(props, validAttributes) { + for (var key in validAttributes.style) { + if (!(validAttributes[key] || props[key] === undefined)) { + console.error( + "You are setting the style `{ " + + key + + ": ... }` as a prop. You " + + "should nest it in a style object. " + + "E.g. `{ style: { " + + key + + ": ... } }`" + ); + } + } +} // Modules provided by RN: var emptyObject = {}; @@ -3078,7 +3275,6 @@ function restoreDeletedValuesInNestedArray( ) { if (Array.isArray(node)) { var i = node.length; - while (i-- && removedKeyCount > 0) { restoreDeletedValuesInNestedArray( updatePayload, @@ -3088,7 +3284,6 @@ function restoreDeletedValuesInNestedArray( } } else if (node && removedKeyCount > 0) { var obj = node; - for (var propKey in removedKeys) { if (!removedKeys[propKey]) { continue; @@ -3101,7 +3296,6 @@ function restoreDeletedValuesInNestedArray( } var attributeConfig = validAttributes[propKey]; - if (!attributeConfig) { continue; // not a valid native prop } @@ -3109,7 +3303,6 @@ function restoreDeletedValuesInNestedArray( if (typeof nextProp === "function") { nextProp = true; } - if (typeof nextProp === "undefined") { nextProp = null; } @@ -3128,7 +3321,6 @@ function restoreDeletedValuesInNestedArray( : nextProp; updatePayload[propKey] = nextValue; } - removedKeys[propKey] = false; removedKeyCount--; } @@ -3155,7 +3347,6 @@ function diffNestedArrayProperty( validAttributes ); } - for (; i < prevArray.length; i++) { // Clear out all remaining properties. updatePayload = clearNestedProperty( @@ -3164,7 +3355,6 @@ function diffNestedArrayProperty( validAttributes ); } - for (; i < nextArray.length; i++) { // Add all remaining properties. updatePayload = addNestedProperty( @@ -3173,7 +3363,6 @@ function diffNestedArrayProperty( validAttributes ); } - return updatePayload; } @@ -3237,7 +3426,6 @@ function diffNestedProperty( * attribute configurations. It processes each prop and adds it to the * updatePayload. */ - function addNestedProperty(updatePayload, nextProp, validAttributes) { if (!nextProp) { return updatePayload; @@ -3263,7 +3451,6 @@ function addNestedProperty(updatePayload, nextProp, validAttributes) { * clearNestedProperty takes a single set of props and valid attributes. It * adds a null sentinel to the updatePayload, for each prop key. */ - function clearNestedProperty(updatePayload, prevProp, validAttributes) { if (!prevProp) { return updatePayload; @@ -3350,7 +3537,6 @@ function diffProperties(updatePayload, prevProps, nextProps, validAttributes) { : nextProp; updatePayload[propKey] = nextValue; } - continue; } @@ -3374,13 +3560,11 @@ function diffProperties(updatePayload, prevProps, nextProps, validAttributes) { (typeof attributeConfig.diff === "function" ? attributeConfig.diff(prevProp, nextProp) : defaultDiffer(prevProp, nextProp)); - if (shouldUpdate) { var _nextValue = typeof attributeConfig.process === "function" ? attributeConfig.process(nextProp) : nextProp; - (updatePayload || (updatePayload = {}))[propKey] = _nextValue; } } else { @@ -3395,7 +3579,6 @@ function diffProperties(updatePayload, prevProps, nextProps, validAttributes) { nextProp, attributeConfig ); - if (removedKeyCount > 0 && updatePayload) { restoreDeletedValuesInNestedArray( updatePayload, @@ -3474,7 +3657,6 @@ function addProperties(updatePayload, props, validAttributes) { * clearProperties clears all the previous props by adding a null sentinel * to the payload for each valid key. */ - function clearProperties(updatePayload, prevProps, validAttributes) { // TODO: Fast path return diffProperties(updatePayload, prevProps, emptyObject, validAttributes); @@ -3498,6 +3680,49 @@ function diff(prevProps, nextProps, validAttributes) { var PLUGIN_EVENT_SYSTEM = 1; +var restoreImpl = null; +var restoreTarget = null; +var restoreQueue = null; + +function restoreStateOfTarget(target) { + // We perform this translation at the end of the event loop so that we + // always receive the correct fiber here + var internalInstance = getInstanceFromNode(target); + if (!internalInstance) { + // Unmounted + return; + } + + if (!(typeof restoreImpl === "function")) { + throw Error( + "setRestoreImplementation() needs to be called to handle a target for controlled events. This error is likely caused by a bug in React. Please file an issue." + ); + } + + var props = getFiberCurrentPropsFromNode(internalInstance.stateNode); + restoreImpl(internalInstance.stateNode, internalInstance.type, props); +} + +function needsStateRestore() { + return restoreTarget !== null || restoreQueue !== null; +} +function restoreStateIfNeeded() { + if (!restoreTarget) { + return; + } + var target = restoreTarget; + var queuedTargets = restoreQueue; + restoreTarget = null; + restoreQueue = null; + restoreStateOfTarget(target); + + if (queuedTargets) { + for (var i = 0; i < queuedTargets.length; i++) { + restoreStateOfTarget(queuedTargets[i]); + } + } +} + // the renderer. Such as when we're dispatching events or if third party // libraries need to call batchedUpdates. Eventually, this API will go away when // everything is batched by default. We'll then have a similar API to opt-out of @@ -3507,7 +3732,31 @@ var PLUGIN_EVENT_SYSTEM = 1; var batchedUpdatesImpl = function(fn, bookkeeping) { return fn(bookkeeping); }; + +var discreteUpdatesImpl = function(fn, a, b, c) { + return fn(a, b, c); +}; + +var flushDiscreteUpdatesImpl = function() {}; + +var batchedEventUpdatesImpl = batchedUpdatesImpl; var isInsideEventHandler = false; +var isBatchingEventUpdates = false; + +function finishEventHandler() { + // Here we wait until all updates have propagated, which is important + // when using controlled components within layers: + // https://github.com/facebook/react/issues/1698 + // Then we restore state of any controlled component. + var controlledComponentsHavePendingUpdates = needsStateRestore(); + if (controlledComponentsHavePendingUpdates) { + // If a controlled event was fired, we may need to restore the state of + // the DOM node back to the controlled value. This is necessary when React + // bails out of the update without touching the DOM. + flushDiscreteUpdatesImpl(); + restoreStateIfNeeded(); + } +} function batchedUpdates(fn, bookkeeping) { if (isInsideEventHandler) { @@ -3522,6 +3771,72 @@ function batchedUpdates(fn, bookkeeping) { return batchedUpdatesImpl(fn, bookkeeping); } finally { isInsideEventHandler = false; + finishEventHandler(); + } +} +function batchedEventUpdates(fn, a, b) { + if (isBatchingEventUpdates) { + // If we are currently inside another batch, we need to wait until it + // fully completes before restoring state. + return fn(a, b); + } + + isBatchingEventUpdates = true; + + try { + return batchedEventUpdatesImpl(fn, a, b); + } finally { + isBatchingEventUpdates = false; + finishEventHandler(); + } +} // This is for the React Flare event system + +function executeUserEventHandler(fn, value) { + var previouslyInEventHandler = isInsideEventHandler; + + try { + isInsideEventHandler = true; + var type = typeof value === "object" && value !== null ? value.type : ""; + invokeGuardedCallbackAndCatchFirstError(type, fn, undefined, value); + } finally { + isInsideEventHandler = previouslyInEventHandler; + } +} +function discreteUpdates(fn, a, b, c) { + var prevIsInsideEventHandler = isInsideEventHandler; + isInsideEventHandler = true; + + try { + return discreteUpdatesImpl(fn, a, b, c); + } finally { + isInsideEventHandler = prevIsInsideEventHandler; + if (!isInsideEventHandler) { + finishEventHandler(); + } + } +} +var lastFlushedEventTimeStamp = 0; +function flushDiscreteUpdatesIfNeeded(timeStamp) { + // event.timeStamp isn't overly reliable due to inconsistencies in + // how different browsers have historically provided the time stamp. + // Some browsers provide high-resolution time stamps for all events, + // some provide low-resolution time stamps for all events. FF < 52 + // even mixes both time stamps together. Some browsers even report + // negative time stamps or time stamps that are 0 (iOS9) in some cases. + // Given we are only comparing two time stamps with equality (!==), + // we are safe from the resolution differences. If the time stamp is 0 + // we bail-out of preventing the flush, which can affect semantics, + // such as if an earlier flush removes or adds event listeners that + // are fired in the subsequent flush. However, this is the same + // behaviour as we had before this change, so the risks are low. + if ( + !isInsideEventHandler && + (!enableFlareAPI || + timeStamp === 0 || + lastFlushedEventTimeStamp !== timeStamp) + ) { + lastFlushedEventTimeStamp = timeStamp; + flushDiscreteUpdatesImpl(); } } function setBatchingImplementation( @@ -3531,125 +3846,466 @@ function setBatchingImplementation( _batchedEventUpdatesImpl ) { batchedUpdatesImpl = _batchedUpdatesImpl; + discreteUpdatesImpl = _discreteUpdatesImpl; + flushDiscreteUpdatesImpl = _flushDiscreteUpdatesImpl; + batchedEventUpdatesImpl = _batchedEventUpdatesImpl; } -/** - * Internal queue of events that have accumulated their dispatches and are - * waiting to have their dispatches executed. - */ +function _inheritsLoose(subClass, superClass) { + subClass.prototype = Object.create(superClass.prototype); + subClass.prototype.constructor = subClass; + subClass.__proto__ = superClass; +} -var eventQueue = null; /** - * Dispatches an event and releases it back into the pool, unless persistent. - * - * @param {?object} event Synthetic event to be dispatched. - * @private + * Class only exists for its Flow type. */ +var ReactNativeComponent = + /*#__PURE__*/ + (function(_React$Component) { + _inheritsLoose(ReactNativeComponent, _React$Component); -var executeDispatchesAndRelease = function(event) { - if (event) { - executeDispatchesInOrder(event); - - if (!event.isPersistent()) { - event.constructor.release(event); + function ReactNativeComponent() { + return _React$Component.apply(this, arguments) || this; } - } -}; -var executeDispatchesAndReleaseTopLevel = function(e) { - return executeDispatchesAndRelease(e); -}; + var _proto = ReactNativeComponent.prototype; -function runEventsInBatch(events) { - if (events !== null) { - eventQueue = accumulateInto(eventQueue, events); - } // Set `eventQueue` to null before processing it so that we can tell if more - // events get enqueued while processing. + _proto.blur = function blur() {}; - var processingEventQueue = eventQueue; - eventQueue = null; + _proto.focus = function focus() {}; - if (!processingEventQueue) { - return; - } + _proto.measure = function measure(callback) {}; - forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseTopLevel); + _proto.measureInWindow = function measureInWindow(callback) {}; - if (!!eventQueue) { - throw Error( - "processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented." - ); - } // This would be a good time to rethrow if any of the event handlers threw. + _proto.measureLayout = function measureLayout( + relativeToNativeNode, + onSuccess, + onFail + ) {}; + + _proto.setNativeProps = function setNativeProps(nativeProps) {}; + + return ReactNativeComponent; + })(React.Component); // This type is only used for FlowTests. It shouldn't be imported directly + +var DiscreteEvent = 0; +var UserBlockingEvent = 1; +var ContinuousEvent = 2; + +// CommonJS interop named imports. + +var UserBlockingPriority = Scheduler.unstable_UserBlockingPriority; +var runWithPriority = Scheduler.unstable_runWithPriority; +var _nativeFabricUIManage$2 = nativeFabricUIManager; +var measureInWindow = _nativeFabricUIManage$2.measureInWindow; +var rootEventTypesToEventResponderInstances = new Map(); +var currentTimeStamp = 0; +var currentInstance = null; +var eventResponderContext = { + dispatchEvent: function(eventValue, eventListener, eventPriority) { + validateResponderContext(); + validateEventValue(eventValue); + + switch (eventPriority) { + case DiscreteEvent: { + flushDiscreteUpdatesIfNeeded(currentTimeStamp); + discreteUpdates(function() { + return executeUserEventHandler(eventListener, eventValue); + }); + break; + } - rethrowCaughtError(); -} + case UserBlockingEvent: { + runWithPriority(UserBlockingPriority, function() { + return executeUserEventHandler(eventListener, eventValue); + }); + break; + } -/** - * Allows registered plugins an opportunity to extract events from top-level - * native browser events. - * - * @return {*} An accumulation of synthetic events. - * @internal - */ + case ContinuousEvent: { + executeUserEventHandler(eventListener, eventValue); + break; + } + } + }, + isTargetWithinNode: function(childTarget, parentTarget) { + validateResponderContext(); + var childFiber = getFiberFromTarget(childTarget); + var parentFiber = getFiberFromTarget(parentTarget); + var node = childFiber; -function extractPluginEvents( - topLevelType, - targetInst, - nativeEvent, - nativeEventTarget, - eventSystemFlags -) { - var events = null; + while (node !== null) { + if (node === parentFiber) { + return true; + } - for (var i = 0; i < plugins.length; i++) { - // Not every plugin in the ordering may be loaded at runtime. - var possiblePlugin = plugins[i]; + node = node.return; + } - if (possiblePlugin) { - var extractedEvents = possiblePlugin.extractEvents( - topLevelType, - targetInst, - nativeEvent, - nativeEventTarget, - eventSystemFlags + return false; + }, + getTargetBoundingRect: function(target, callback) { + measureInWindow(target.node, function(x, y, width, height) { + callback({ + left: x, + right: x + width, + top: y, + bottom: y + height + }); + }); + }, + addRootEventTypes: function(rootEventTypes) { + validateResponderContext(); + for (var i = 0; i < rootEventTypes.length; i++) { + var rootEventType = rootEventTypes[i]; + var eventResponderInstance = currentInstance; + registerRootEventType(rootEventType, eventResponderInstance); + } + }, + removeRootEventTypes: function(rootEventTypes) { + validateResponderContext(); + + for (var i = 0; i < rootEventTypes.length; i++) { + var rootEventType = rootEventTypes[i]; + var rootEventResponders = rootEventTypesToEventResponderInstances.get( + rootEventType ); + var rootEventTypesSet = currentInstance.rootEventTypes; - if (extractedEvents) { - events = accumulateInto(events, extractedEvents); + if (rootEventTypesSet !== null) { + rootEventTypesSet.delete(rootEventType); + } + + if (rootEventResponders !== undefined) { + rootEventResponders.delete(currentInstance); } } + }, + getTimeStamp: function() { + validateResponderContext(); + return currentTimeStamp; + }, + getResponderNode: function() { + validateResponderContext(); + var responderFiber = currentInstance.fiber; + + if (responderFiber.tag === ScopeComponent) { + return null; + } + + return responderFiber.stateNode; } +}; - return events; -} +function validateEventValue(eventValue) { + if (typeof eventValue === "object" && eventValue !== null) { + var target = eventValue.target, + type = eventValue.type, + timeStamp = eventValue.timeStamp; -function runExtractedPluginEventsInBatch( - topLevelType, - targetInst, - nativeEvent, - nativeEventTarget, - eventSystemFlags -) { - var events = extractPluginEvents( - topLevelType, - targetInst, + if (target == null || type == null || timeStamp == null) { + throw new Error( + 'context.dispatchEvent: "target", "timeStamp", and "type" fields on event object are required.' + ); + } + var showWarning = function(name) { + { + warning$1( + false, + "%s is not available on event objects created from event responder modules (React Flare). " + + 'Try wrapping in a conditional, i.e. `if (event.type !== "press") { event.%s }`', + name, + name + ); + } + }; + eventValue.preventDefault = function() { + { + showWarning("preventDefault()"); + } + }; + eventValue.stopPropagation = function() { + { + showWarning("stopPropagation()"); + } + }; + eventValue.isDefaultPrevented = function() { + { + showWarning("isDefaultPrevented()"); + } + }; + eventValue.isPropagationStopped = function() { + { + showWarning("isPropagationStopped()"); + } + }; // $FlowFixMe: we don't need value, Flow thinks we do + + Object.defineProperty(eventValue, "nativeEvent", { + get: function() { + { + showWarning("nativeEvent"); + } + } + }); + } +} + +function getFiberFromTarget(target) { + if (target === null) { + return null; + } + + return target.canonical._internalInstanceHandle || null; +} + +function createFabricResponderEvent(topLevelType, nativeEvent, target) { + return { + nativeEvent: nativeEvent, + target: target, + type: topLevelType + }; +} + +function validateResponderContext() { + if (!currentInstance) { + throw Error( + "An event responder context was used outside of an event cycle." + ); + } +} // TODO this function is almost an exact copy of the DOM version, we should +// somehow share the logic + +function responderEventTypesContainType(eventTypes, type) { + for (var i = 0, len = eventTypes.length; i < len; i++) { + if (eventTypes[i] === type) { + return true; + } + } + return false; +} + +function validateResponderTargetEventTypes(eventType, responder) { + var targetEventTypes = responder.targetEventTypes; // Validate the target event type exists on the responder + + if (targetEventTypes !== null) { + return responderEventTypesContainType(targetEventTypes, eventType); + } + + return false; +} // TODO this function is almost an exact copy of the DOM version, we should +// somehow share the logic + +function traverseAndHandleEventResponderInstances( + eventType, + targetFiber, + nativeEvent +) { + // Trigger event responders in this order: + // - Bubble target responder phase + // - Root responder phase + var responderEvent = createFabricResponderEvent( + eventType, nativeEvent, - nativeEventTarget, - eventSystemFlags + targetFiber !== null ? targetFiber.stateNode : null ); - runEventsInBatch(events); + var visitedResponders = new Set(); + var node = targetFiber; + while (node !== null) { + var _node = node, + dependencies = _node.dependencies, + tag = _node.tag; + + if ( + (tag === HostComponent || tag === ScopeComponent) && + dependencies !== null + ) { + var respondersMap = dependencies.responders; + + if (respondersMap !== null) { + var responderInstances = Array.from(respondersMap.values()); + + for (var i = 0, length = responderInstances.length; i < length; i++) { + var responderInstance = responderInstances[i]; + var props = responderInstance.props, + responder = responderInstance.responder, + state = responderInstance.state; + + if ( + !visitedResponders.has(responder) && + validateResponderTargetEventTypes(eventType, responder) + ) { + var onEvent = responder.onEvent; + visitedResponders.add(responder); + + if (onEvent !== null) { + currentInstance = responderInstance; + onEvent(responderEvent, eventResponderContext, props, state); + } + } + } + } + } + + node = node.return; + } // Root phase + + var rootEventResponderInstances = rootEventTypesToEventResponderInstances.get( + eventType + ); + + if (rootEventResponderInstances !== undefined) { + var _responderInstances = Array.from(rootEventResponderInstances); + + for (var _i = 0; _i < _responderInstances.length; _i++) { + var _responderInstance = _responderInstances[_i]; + var props = _responderInstance.props, + responder = _responderInstance.responder, + state = _responderInstance.state; + var onRootEvent = responder.onRootEvent; + + if (onRootEvent !== null) { + currentInstance = _responderInstance; + onRootEvent(responderEvent, eventResponderContext, props, state); + } + } + } +} // TODO this function is almost an exact copy of the DOM version, we should +// somehow share the logic + +function dispatchEventForResponderEventSystem( + topLevelType, + targetFiber, + nativeEvent +) { + var previousInstance = currentInstance; + var previousTimeStamp = currentTimeStamp; // We might want to control timeStamp another way here + + currentTimeStamp = Date.now(); + + try { + batchedEventUpdates(function() { + traverseAndHandleEventResponderInstances( + topLevelType, + targetFiber, + nativeEvent + ); + }); + } finally { + currentInstance = previousInstance; + currentTimeStamp = previousTimeStamp; + } +} // TODO this function is almost an exact copy of the DOM version, we should +// somehow share the logic + +function mountEventResponder(responder, responderInstance, props, state) { + var onMount = responder.onMount; + + if (onMount !== null) { + currentInstance = responderInstance; + + try { + batchedEventUpdates(function() { + onMount(eventResponderContext, props, state); + }); + } finally { + currentInstance = null; + } + } +} // TODO this function is almost an exact copy of the DOM version, we should +// somehow share the logic + +function unmountEventResponder(responderInstance) { + var responder = responderInstance.responder; + var onUnmount = responder.onUnmount; + + if (onUnmount !== null) { + var props = responderInstance.props, + state = responderInstance.state; + currentInstance = responderInstance; + + try { + batchedEventUpdates(function() { + onUnmount(eventResponderContext, props, state); + }); + } finally { + currentInstance = null; + } + } + + var rootEventTypesSet = responderInstance.rootEventTypes; + + if (rootEventTypesSet !== null) { + var rootEventTypes = Array.from(rootEventTypesSet); + + for (var i = 0; i < rootEventTypes.length; i++) { + var topLevelEventType = rootEventTypes[i]; + var rootEventResponderInstances = rootEventTypesToEventResponderInstances.get( + topLevelEventType + ); + if (rootEventResponderInstances !== undefined) { + rootEventResponderInstances.delete(responderInstance); + } + } + } +} + +function registerRootEventType(rootEventType, responderInstance) { + var rootEventResponderInstances = rootEventTypesToEventResponderInstances.get( + rootEventType + ); + if (rootEventResponderInstances === undefined) { + rootEventResponderInstances = new Set(); + rootEventTypesToEventResponderInstances.set( + rootEventType, + rootEventResponderInstances + ); + } + + var rootEventTypesSet = responderInstance.rootEventTypes; + + if (rootEventTypesSet === null) { + rootEventTypesSet = responderInstance.rootEventTypes = new Set(); + } + + if (!!rootEventTypesSet.has(rootEventType)) { + throw Error( + 'addRootEventTypes() found a duplicate root event type of "' + + rootEventType + + '". This might be because the event type exists in the event responder "rootEventTypes" array or because of a previous addRootEventTypes() using this root event type.' + ); + } + + rootEventTypesSet.add(rootEventType); + rootEventResponderInstances.add(responderInstance); +} + +function addRootEventTypesForResponderInstance( + responderInstance, + rootEventTypes +) { + for (var i = 0; i < rootEventTypes.length; i++) { + var rootEventType = rootEventTypes[i]; + registerRootEventType(rootEventType, responderInstance); + } } function dispatchEvent(target, topLevelType, nativeEvent) { var targetFiber = target; - var eventTarget = null; + if (enableFlareAPI) { + // React Flare event system + dispatchEventForResponderEventSystem(topLevelType, target, nativeEvent); + } - if (targetFiber != null) { - var stateNode = targetFiber.stateNode; // Guard against Fiber being unmounted + var eventTarget = null; - if (stateNode != null) { - eventTarget = stateNode.canonical; + if (enableNativeTargetAsInstance) { + if (targetFiber != null) { + eventTarget = targetFiber.stateNode.canonical; } + } else { + eventTarget = nativeEvent.target; } batchedUpdates(function() { @@ -3676,7 +4332,20 @@ function shim() { } // Mutation (when unsupported) var supportsMutation = false; +var appendChild = shim; +var appendChildToContainer = shim; +var commitTextUpdate = shim; var commitMount = shim; +var commitUpdate = shim; +var insertBefore = shim; +var insertInContainerBefore = shim; +var removeChild = shim; +var removeChildFromContainer = shim; +var resetTextContent = shim; +var hideInstance = shim; +var hideTextInstance = shim; +var unhideInstance = shim; +var unhideTextInstance = shim; // can re-export everything from this module. @@ -3687,25 +4356,50 @@ function shim$1() { ); } } // Hydration (when unsupported) + +var supportsHydration = false; +var canHydrateInstance = shim$1; +var canHydrateTextInstance = shim$1; +var canHydrateSuspenseInstance = shim$1; var isSuspenseInstancePending = shim$1; var isSuspenseInstanceFallback = shim$1; +var registerSuspenseInstanceRetry = shim$1; +var getNextHydratableSibling = shim$1; +var getFirstHydratableChild = shim$1; +var hydrateInstance = 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 hydrateSuspenseInstance = shim$1; +var getNextHydratableInstanceAfterSuspenseInstance = shim$1; +var commitHydratedContainer = shim$1; +var commitHydratedSuspenseInstance = shim$1; +var clearSuspenseBoundary = shim$1; +var clearSuspenseBoundaryFromContainer = shim$1; +var didNotMatchHydratedContainerTextInstance = shim$1; +var didNotMatchHydratedTextInstance = shim$1; +var didNotHydrateContainerInstance = shim$1; +var didNotHydrateInstance = shim$1; +var didNotFindHydratableContainerInstance = shim$1; +var didNotFindHydratableContainerTextInstance = shim$1; +var didNotFindHydratableContainerSuspenseInstance = shim$1; +var didNotFindHydratableInstance = shim$1; +var didNotFindHydratableTextInstance = shim$1; +var didNotFindHydratableSuspenseInstance = shim$1; + +var _nativeFabricUIManage$1 = nativeFabricUIManager; +var createNode = _nativeFabricUIManage$1.createNode; +var cloneNode = _nativeFabricUIManage$1.cloneNode; +var cloneNodeWithNewChildren = _nativeFabricUIManage$1.cloneNodeWithNewChildren; +var cloneNodeWithNewChildrenAndProps = + _nativeFabricUIManage$1.cloneNodeWithNewChildrenAndProps; +var cloneNodeWithNewProps = _nativeFabricUIManage$1.cloneNodeWithNewProps; +var createChildNodeSet = _nativeFabricUIManage$1.createChildSet; +var appendChildNode = _nativeFabricUIManage$1.appendChild; +var appendChildNodeToSet = _nativeFabricUIManage$1.appendChildToSet; +var completeRoot = _nativeFabricUIManage$1.completeRoot; +var registerEventHandler = _nativeFabricUIManage$1.registerEventHandler; +var fabricMeasure = _nativeFabricUIManage$1.measure; +var fabricMeasureInWindow = _nativeFabricUIManage$1.measureInWindow; +var fabricMeasureLayout = _nativeFabricUIManage$1.measureLayout; var getViewConfigForType = ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get; // Counter for uniquely identifying views. // % 10 === 1 means it is a rootTag. @@ -3743,11 +4437,13 @@ var ReactFabricHostComponent = var _proto = ReactFabricHostComponent.prototype; _proto.blur = function blur() { - ReactNativePrivateInterface.TextInputState.blurTextInput(this); + ReactNativePrivateInterface.TextInputState.blurTextInput(this._nativeTag); }; _proto.focus = function focus() { - ReactNativePrivateInterface.TextInputState.focusTextInput(this); + ReactNativePrivateInterface.TextInputState.focusTextInput( + this._nativeTag + ); }; _proto.measure = function measure(callback) { @@ -3774,12 +4470,10 @@ var ReactFabricHostComponent = typeof relativeToNativeNode === "number" || !(relativeToNativeNode instanceof ReactFabricHostComponent) ) { - { - error( - "Warning: ref.measureLayout must be called with a ref to a native component." - ); - } - + warningWithoutStack$1( + false, + "Warning: ref.measureLayout must be called with a ref to a native component." + ); return; } @@ -3792,15 +4486,16 @@ var ReactFabricHostComponent = }; _proto.setNativeProps = function setNativeProps(nativeProps) { - { - error("Warning: setNativeProps is not currently supported in Fabric"); - } - + warningWithoutStack$1( + false, + "Warning: setNativeProps is not currently supported in Fabric" + ); return; }; return ReactFabricHostComponent; })(); // eslint-disable-next-line no-unused-expressions + function appendInitialChild(parentInstance, child) { appendChildNode(parentInstance.node, child.node); } @@ -3869,6 +4564,15 @@ function createTextInstance( node: node }; } +function finalizeInitialChildren( + parentInstance, + type, + props, + rootContainerInstance, + hostContext +) { + return false; +} function getRootHostContext(rootContainerInstance) { return { isInAParentText: false @@ -3928,9 +4632,17 @@ function shouldSetTextContent(type, props) { // More context @ github.com/facebook/react/pull/8560#discussion_r92111303 return false; } // The Fabric renderer is secondary to the existing React Native renderer. + +var isPrimaryRenderer = false; // The Fabric renderer shouldn't trigger missing act() warnings + +var warnsIfNotActing = false; var scheduleTimeout = setTimeout; var cancelTimeout = clearTimeout; var noTimeout = -1; // ------------------- +// Persistence +// ------------------- + +var supportsPersistence = true; function cloneInstance( instance, updatePayload, @@ -3957,7 +4669,6 @@ function cloneInstance( clone = cloneNodeWithNewChildren(node); } } - return { node: clone, canonical: instance.canonical @@ -3992,105 +4703,191 @@ function finalizeContainerChildren(container, newChildren) { completeRoot(container, newChildren); } -var loggedTypeFailures = {}; -function checkPropTypes(typeSpecs, values, location, componentName) { - { - // $FlowFixMe This is okay but Flow doesn't know it. - var has = Function.call.bind(Object.prototype.hasOwnProperty); +function mountResponderInstance( + responder, + responderInstance, + props, + state, + instance +) { + if (enableFlareAPI) { + var rootEventTypes = responder.rootEventTypes; - 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 (rootEventTypes !== null) { + addRootEventTypesForResponderInstance(responderInstance, rootEventTypes); + } - 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; - } + mountEventResponder(responder, responderInstance, props, state); + } +} +function unmountResponderInstance(responderInstance) { + if (enableFlareAPI) { + // TODO stop listening to targetEventTypes + unmountEventResponder(responderInstance); + } +} +function getFundamentalComponentInstance(fundamentalInstance) { + throw new Error("Not yet implemented."); +} +function mountFundamentalComponent(fundamentalInstance) { + throw new Error("Not yet implemented."); +} +function shouldUpdateFundamentalComponent(fundamentalInstance) { + throw new Error("Not yet implemented."); +} +function updateFundamentalComponent(fundamentalInstance) { + throw new Error("Not yet implemented."); +} +function unmountFundamentalComponent(fundamentalInstance) { + throw new Error("Not yet implemented."); +} +function cloneFundamentalInstance(fundamentalInstance) { + throw new Error("Not yet implemented."); +} +function getInstanceFromNode$1(node) { + throw new Error("Not yet implemented."); +} - 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 BEFORE_SLASH_RE = /^(.*)[\\\/]/; +var describeComponentFrame = function(name, source, ownerName) { + var sourceInfo = ""; - if (error$1 && !(error$1 instanceof Error)) { - 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 (source) { + var path = source.fileName; + var fileName = path.replace(BEFORE_SLASH_RE, ""); - 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; + { + // 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]; - error("Failed %s type: %s", location, error$1.message); + if (pathBeforeSlash) { + var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, ""); + fileName = folderName + "/" + fileName; + } } } } + sourceInfo = " (at " + fileName + ":" + source.lineNumber + ")"; + } else if (ownerName) { + sourceInfo = " (created by " + ownerName + ")"; } -} + return "\n in " + (name || "Unknown") + sourceInfo; +}; -// Prefix measurements so that it's possible to filter them. -// Longer prefixes are hard to read in DevTools. -var reactEmoji = "\u269B"; -var warningEmoji = "\u26D4"; -var supportsUserTiming = - typeof performance !== "undefined" && - typeof performance.mark === "function" && - typeof performance.clearMarks === "function" && - typeof performance.measure === "function" && - typeof performance.clearMeasures === "function"; // Keep track of current fiber so that we know the path to unwind on pause. -// TODO: this looks the same as nextUnitOfWork in scheduler. Can we unify them? +var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; -var currentFiber = null; // If we're in the middle of user code, which fiber and method is it? -// Reusing `currentFiber` would be confusing for this because user code fiber -// can change during commit phase too, but we don't need to unwind it (since -// lifecycles in the commit phase don't resemble a tree). +function describeFiber(fiber) { + switch (fiber.tag) { + case HostRoot: + case HostPortal: + case HostText: + case Fragment: + case ContextProvider: + case ContextConsumer: + return ""; + default: + var owner = fiber._debugOwner; + var source = fiber._debugSource; + var name = getComponentName(fiber.type); + var ownerName = null; -var currentPhase = null; -var currentPhaseFiber = null; // Did lifecycle hook schedule an update? This is often a performance problem, -// so we will keep track of it, and include it in the report. -// Track commits caused by cascading updates. + if (owner) { + ownerName = getComponentName(owner.type); + } -var isCommitting = false; -var hasScheduledUpdateInCurrentCommit = false; -var hasScheduledUpdateInCurrentPhase = false; + return describeComponentFrame(name, source, ownerName); + } +} + +function getStackByFiberInDevAndProd(workInProgress) { + var info = ""; + var node = workInProgress; + do { + info += describeFiber(node); + node = node.return; + } while (node); + + return info; +} +var current = null; +var phase = null; +function getCurrentFiberOwnerNameInDevOrNull() { + { + if (current === null) { + return null; + } + + var owner = current._debugOwner; + + if (owner !== null && typeof owner !== "undefined") { + return getComponentName(owner.type); + } + } + + return null; +} +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. + + return getStackByFiberInDevAndProd(current); + } + + return ""; +} +function resetCurrentFiber() { + { + ReactDebugCurrentFrame.getCurrentStack = null; + current = null; + phase = null; + } +} +function setCurrentFiber(fiber) { + { + ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackInDev; + current = fiber; + phase = null; + } +} +function setCurrentPhase(lifeCyclePhase) { + { + phase = lifeCyclePhase; + } +} + +// Prefix measurements so that it's possible to filter them. +// Longer prefixes are hard to read in DevTools. +var reactEmoji = "\u269B"; +var warningEmoji = "\u26D4"; +var supportsUserTiming = + typeof performance !== "undefined" && + typeof performance.mark === "function" && + typeof performance.clearMarks === "function" && + typeof performance.measure === "function" && + typeof performance.clearMeasures === "function"; // Keep track of current fiber so that we know the path to unwind on pause. +// TODO: this looks the same as nextUnitOfWork in scheduler. Can we unify them? + +var currentFiber = null; // If we're in the middle of user code, which fiber and method is it? +// Reusing `currentFiber` would be confusing for this because user code fiber +// can change during commit phase too, but we don't need to unwind it (since +// lifecycles in the commit phase don't resemble a tree). + +var currentPhase = null; +var currentPhaseFiber = null; // Did lifecycle hook schedule an update? This is often a performance problem, +// so we will keep track of it, and include it in the report. +// Track commits caused by cascading updates. + +var isCommitting = false; +var hasScheduledUpdateInCurrentCommit = false; +var hasScheduledUpdateInCurrentPhase = false; var commitCountInCurrentWorkLoop = 0; var effectCountInCurrentCommit = 0; // to avoid stretch the commit phase with measurement overhead. @@ -4194,7 +4991,6 @@ var shouldIgnoreFiber = function(fiber) { case ContextConsumer: case Mode: return true; - default: return false; } @@ -4204,7 +5000,6 @@ var clearPendingPhaseMeasurement = function() { if (currentPhase !== null && currentPhaseFiber !== null) { clearFiberMark(currentPhaseFiber, currentPhase); } - currentPhaseFiber = null; currentPhase = null; hasScheduledUpdateInCurrentPhase = false; @@ -4214,12 +5009,10 @@ var pauseTimers = function() { // Stops all currently active measurements so that they can be resumed // if we continue in a later deferred loop from the same unit of work. var fiber = currentFiber; - while (fiber) { if (fiber._debugIsCurrentlyTiming) { endFiberMark(fiber, null, null); } - fiber = fiber.return; } }; @@ -4228,7 +5021,6 @@ var resumeTimersRecursively = function(fiber) { if (fiber.return !== null) { resumeTimersRecursively(fiber.return); } - if (fiber._debugIsCurrentlyTiming) { beginFiberMark(fiber, null); } @@ -4242,16 +5034,15 @@ var resumeTimers = function() { }; function recordEffect() { - { + if (enableUserTimingAPI) { effectCountInCurrentCommit++; } } function recordScheduleUpdate() { - { + if (enableUserTimingAPI) { if (isCommitting) { hasScheduledUpdateInCurrentCommit = true; } - if ( currentPhase !== null && currentPhase !== "componentWillMount" && @@ -4261,8 +5052,9 @@ function recordScheduleUpdate() { } } } + function startWorkTimer(fiber) { - { + if (enableUserTimingAPI) { if (!supportsUserTiming || shouldIgnoreFiber(fiber)) { return; } // If we pause, this is the fiber to unwind from. @@ -4277,7 +5069,7 @@ function startWorkTimer(fiber) { } } function cancelWorkTimer(fiber) { - { + if (enableUserTimingAPI) { if (!supportsUserTiming || shouldIgnoreFiber(fiber)) { return; } // Remember we shouldn't complete measurement for this fiber. @@ -4288,7 +5080,7 @@ function cancelWorkTimer(fiber) { } } function stopWorkTimer(fiber) { - { + if (enableUserTimingAPI) { if (!supportsUserTiming || shouldIgnoreFiber(fiber)) { return; } // If we pause, its parent is the fiber to unwind from. @@ -4304,7 +5096,7 @@ function stopWorkTimer(fiber) { } } function stopFailedWorkTimer(fiber) { - { + if (enableUserTimingAPI) { if (!supportsUserTiming || shouldIgnoreFiber(fiber)) { return; } // If we pause, its parent is the fiber to unwind from. @@ -4324,7 +5116,7 @@ function stopFailedWorkTimer(fiber) { } } function startPhaseTimer(fiber, phase) { - { + if (enableUserTimingAPI) { if (!supportsUserTiming) { return; } @@ -4340,24 +5132,22 @@ function startPhaseTimer(fiber, phase) { } } function stopPhaseTimer() { - { + if (enableUserTimingAPI) { if (!supportsUserTiming) { return; } - if (currentPhase !== null && currentPhaseFiber !== null) { var warning = hasScheduledUpdateInCurrentPhase ? "Scheduled a cascading update" : null; endFiberMark(currentPhaseFiber, currentPhase, warning); } - currentPhase = null; currentPhaseFiber = null; } } function startWorkLoopTimer(nextUnitOfWork) { - { + if (enableUserTimingAPI) { currentFiber = nextUnitOfWork; if (!supportsUserTiming) { @@ -4373,7 +5163,7 @@ function startWorkLoopTimer(nextUnitOfWork) { } } function stopWorkLoopTimer(interruptedBy, didCompleteRoot) { - { + if (enableUserTimingAPI) { if (!supportsUserTiming) { return; } @@ -4402,11 +5192,10 @@ function stopWorkLoopTimer(interruptedBy, didCompleteRoot) { } } function startCommitTimer() { - { + if (enableUserTimingAPI) { if (!supportsUserTiming) { return; } - isCommitting = true; hasScheduledUpdateInCurrentCommit = false; labelsInCurrentCommit.clear(); @@ -4414,19 +5203,17 @@ function startCommitTimer() { } } function stopCommitTimer() { - { + if (enableUserTimingAPI) { if (!supportsUserTiming) { return; } var warning = null; - if (hasScheduledUpdateInCurrentCommit) { warning = "Lifecycle hook scheduled a cascading update"; } else if (commitCountInCurrentWorkLoop > 0) { warning = "Caused by a cascading update in earlier commit"; } - hasScheduledUpdateInCurrentCommit = false; commitCountInCurrentWorkLoop++; isCommitting = false; @@ -4435,21 +5222,19 @@ function stopCommitTimer() { } } function startCommitSnapshotEffectsTimer() { - { + if (enableUserTimingAPI) { if (!supportsUserTiming) { return; } - effectCountInCurrentCommit = 0; beginMark("(Committing Snapshot Effects)"); } } function stopCommitSnapshotEffectsTimer() { - { + if (enableUserTimingAPI) { if (!supportsUserTiming) { return; } - var count = effectCountInCurrentCommit; effectCountInCurrentCommit = 0; endMark( @@ -4460,21 +5245,19 @@ function stopCommitSnapshotEffectsTimer() { } } function startCommitHostEffectsTimer() { - { + if (enableUserTimingAPI) { if (!supportsUserTiming) { return; } - effectCountInCurrentCommit = 0; beginMark("(Committing Host Effects)"); } } function stopCommitHostEffectsTimer() { - { + if (enableUserTimingAPI) { if (!supportsUserTiming) { return; } - var count = effectCountInCurrentCommit; effectCountInCurrentCommit = 0; endMark( @@ -4485,21 +5268,19 @@ function stopCommitHostEffectsTimer() { } } function startCommitLifeCyclesTimer() { - { + if (enableUserTimingAPI) { if (!supportsUserTiming) { return; } - effectCountInCurrentCommit = 0; beginMark("(Calling Lifecycle Methods)"); } } function stopCommitLifeCyclesTimer() { - { + if (enableUserTimingAPI) { if (!supportsUserTiming) { return; } - var count = effectCountInCurrentCommit; effectCountInCurrentCommit = 0; endMark( @@ -4528,15 +5309,14 @@ function createCursor(defaultValue) { function pop(cursor, fiber) { if (index < 0) { { - error("Unexpected pop."); + warningWithoutStack$1(false, "Unexpected pop."); } - return; } { if (fiber !== fiberStack[index]) { - error("Unexpected Fiber popped."); + warningWithoutStack$1(false, "Unexpected Fiber popped."); } } @@ -4586,7 +5366,9 @@ function getUnmaskedContext( Component, didPushOwnContextIfProvider ) { - { + if (disableLegacyContext) { + return emptyContextObject; + } else { 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 @@ -4594,13 +5376,14 @@ function getUnmaskedContext( // previous (parent) context instead for a context provider. return previousContext; } - return contextStackCursor.current; } } function cacheContext(workInProgress, unmaskedContext, maskedContext) { - { + if (disableLegacyContext) { + return; + } else { var instance = workInProgress.stateNode; instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext; instance.__reactInternalMemoizedMaskedChildContext = maskedContext; @@ -4608,7 +5391,9 @@ function cacheContext(workInProgress, unmaskedContext, maskedContext) { } function getMaskedContext(workInProgress, unmaskedContext) { - { + if (disableLegacyContext) { + return emptyContextObject; + } else { var type = workInProgress.type; var contextTypes = type.contextTypes; @@ -4628,14 +5413,19 @@ function getMaskedContext(workInProgress, unmaskedContext) { } var context = {}; - for (var key in contextTypes) { context[key] = unmaskedContext[key]; } { var name = getComponentName(type) || "Unknown"; - checkPropTypes(contextTypes, context, "context", name); + checkPropTypes( + contextTypes, + context, + "context", + name, + getCurrentFiberStackInDev + ); } // 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. @@ -4648,34 +5438,44 @@ function getMaskedContext(workInProgress, unmaskedContext) { } function hasContextChanged() { - { + if (disableLegacyContext) { + return false; + } else { return didPerformWorkStackCursor.current; } } function isContextProvider(type) { - { + if (disableLegacyContext) { + return false; + } else { var childContextTypes = type.childContextTypes; return childContextTypes !== null && childContextTypes !== undefined; } } function popContext(fiber) { - { + if (disableLegacyContext) { + return; + } else { pop(didPerformWorkStackCursor, fiber); pop(contextStackCursor, fiber); } } function popTopLevelContextObject(fiber) { - { + if (disableLegacyContext) { + return; + } else { pop(didPerformWorkStackCursor, fiber); pop(contextStackCursor, fiber); } } function pushTopLevelContextObject(fiber, context, didChange) { - { + if (disableLegacyContext) { + return; + } else { 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." @@ -4688,7 +5488,9 @@ function pushTopLevelContextObject(fiber, context, didChange) { } function processChildContext(fiber, type, parentContext) { - { + if (disableLegacyContext) { + return parentContext; + } else { 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. @@ -4699,8 +5501,8 @@ function processChildContext(fiber, type, parentContext) { if (!warnedAboutMissingGetChildContext[componentName]) { warnedAboutMissingGetChildContext[componentName] = true; - - error( + warningWithoutStack$1( + false, "%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.", @@ -4714,10 +5516,19 @@ function processChildContext(fiber, type, parentContext) { } var childContext; + + { + setCurrentPhase("getChildContext"); + } + startPhaseTimer(fiber, "getChildContext"); childContext = instance.getChildContext(); stopPhaseTimer(); + { + setCurrentPhase(null); + } + for (var contextKey in childContext) { if (!(contextKey in childContextTypes)) { throw Error( @@ -4731,7 +5542,17 @@ function processChildContext(fiber, type, parentContext) { { var name = getComponentName(type) || "Unknown"; - checkPropTypes(childContextTypes, childContext, "child context", name); + checkPropTypes( + childContextTypes, + childContext, + "child context", + name, // In practice, there is one case in which we won't get a stack. It's when + // somebody calls unstable_renderSubtreeIntoContainer() and we process + // context from the parent component instance. The stack will be missing + // because it's outside of the reconciliation, and so the pointer has not + // been set. This is rare and doesn't matter. We'll also remove that API. + getCurrentFiberStackInDev + ); } return Object.assign({}, parentContext, {}, childContext); @@ -4739,7 +5560,9 @@ function processChildContext(fiber, type, parentContext) { } function pushContextProvider(workInProgress) { - { + if (disableLegacyContext) { + return false; + } else { 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. @@ -4761,7 +5584,9 @@ function pushContextProvider(workInProgress) { } function invalidateContextProvider(workInProgress, type, didChange) { - { + if (disableLegacyContext) { + return; + } else { var instance = workInProgress.stateNode; if (!instance) { @@ -4795,7 +5620,9 @@ function invalidateContextProvider(workInProgress, type, didChange) { } function findCurrentUnmaskedContext(fiber) { - { + if (disableLegacyContext) { + return emptyContextObject; + } else { // Currently this is only used with renderSubtreeIntoContainer; not sure if it // makes sense elsewhere if (!(isFiberMounted(fiber) && fiber.tag === ClassComponent)) { @@ -4838,21 +5665,22 @@ var BlockingRoot = 1; var ConcurrentRoot = 2; // 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; - -{ +// CommonJS interop named imports. +var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority; +var Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback; +var Scheduler_cancelCallback = Scheduler.unstable_cancelCallback; +var Scheduler_shouldYield = Scheduler.unstable_shouldYield; +var Scheduler_requestPaint = Scheduler.unstable_requestPaint; +var Scheduler_now = Scheduler.unstable_now; +var Scheduler_getCurrentPriorityLevel = + Scheduler.unstable_getCurrentPriorityLevel; +var Scheduler_ImmediatePriority = Scheduler.unstable_ImmediatePriority; +var Scheduler_UserBlockingPriority = Scheduler.unstable_UserBlockingPriority; +var Scheduler_NormalPriority = Scheduler.unstable_NormalPriority; +var Scheduler_LowPriority = Scheduler.unstable_LowPriority; +var Scheduler_IdlePriority = Scheduler.unstable_IdlePriority; + +if (enableSchedulerTracing) { // Provide explicit error message when production+profiling bundle of e.g. // react-dom is used with production (non-profiling) bundle of // scheduler/tracing @@ -4873,7 +5701,7 @@ var fakeCallbackNode = {}; // Except for NoPriority, these correspond to Schedul // avoid clashing with Scheduler's priorities. var ImmediatePriority = 99; -var UserBlockingPriority = 98; +var UserBlockingPriority$1 = 98; var NormalPriority = 97; var LowPriority = 96; var IdlePriority = 95; // NoPriority is the absence of priority. Also React-only. @@ -4892,7 +5720,6 @@ var initialTimeMs = Scheduler_now(); // If the initial timestamp is reasonably s // 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 @@ -4905,7 +5732,7 @@ function getCurrentPriorityLevel() { return ImmediatePriority; case Scheduler_UserBlockingPriority: - return UserBlockingPriority; + return UserBlockingPriority$1; case Scheduler_NormalPriority: return NormalPriority; @@ -4927,7 +5754,7 @@ function reactPriorityToSchedulerPriority(reactPriorityLevel) { case ImmediatePriority: return Scheduler_ImmediatePriority; - case UserBlockingPriority: + case UserBlockingPriority$1: return Scheduler_UserBlockingPriority; case NormalPriority: @@ -4945,7 +5772,7 @@ function reactPriorityToSchedulerPriority(reactPriorityLevel) { } } -function runWithPriority(reactPriorityLevel, fn) { +function runWithPriority$1(reactPriorityLevel, fn) { var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); return Scheduler_runWithPriority(priorityLevel, fn); } @@ -4991,14 +5818,12 @@ function flushSyncCallbackQueueImpl() { // Prevent re-entrancy. isFlushingSyncQueue = true; var i = 0; - try { var _isSync = true; var queue = syncQueue; - runWithPriority(ImmediatePriority, function() { + runWithPriority$1(ImmediatePriority, function() { for (; i < queue.length; i++) { var callback = queue[i]; - do { callback = callback(_isSync); } while (callback !== null); @@ -5046,14 +5871,14 @@ var NoWork = 0; // TODO: Think of a better name for Never. The key difference wi var Never = 1; // Idle is slightly higher priority than Never. It must completely finish in // order to be consistent. -var Idle = 2; // Continuous Hydration is slightly higher than Idle and is used to increase +var Idle = 2; // Continuous Hydration is a moving priority. It is slightly higher than Idle var Sync = MAX_SIGNED_31_BIT_INT; var Batched = Sync - 1; var UNIT_SIZE = 10; var MAGIC_NUMBER_OFFSET = Batched - 1; // 1 unit of expiration time represents 10ms. function msToExpirationTime(ms) { - // Always subtract from the offset so that we don't clash with the magic number for NoWork. + // Always add an offset so that we don't clash with the magic number for NoWork. return MAGIC_NUMBER_OFFSET - ((ms / UNIT_SIZE) | 0); } function expirationTimeToMs(expirationTime) { @@ -5112,6 +5937,7 @@ function computeInteractiveExpiration(currentTime) { HIGH_PRIORITY_BATCH_SIZE ); } + function inferPriorityFromExpirationTime(currentTime, expirationTime) { if (expirationTime === Sync) { return ImmediatePriority; @@ -5129,7 +5955,7 @@ function inferPriorityFromExpirationTime(currentTime, expirationTime) { } if (msUntil <= HIGH_PRIORITY_EXPIRATION + HIGH_PRIORITY_BATCH_SIZE) { - return UserBlockingPriority; + return UserBlockingPriority$1; } if (msUntil <= LOW_PRIORITY_EXPIRATION + LOW_PRIORITY_BATCH_SIZE) { @@ -5150,7 +5976,7 @@ function is(x, y) { ); } -var objectIs = typeof Object.is === "function" ? Object.is : is; +var is$1 = typeof Object.is === "function" ? Object.is : is; var hasOwnProperty = Object.prototype.hasOwnProperty; /** @@ -5160,7 +5986,7 @@ var hasOwnProperty = Object.prototype.hasOwnProperty; */ function shallowEqual(objA, objB) { - if (objectIs(objA, objB)) { + if (is$1(objA, objB)) { return true; } @@ -5183,7 +6009,7 @@ function shallowEqual(objA, objB) { for (var i = 0; i < keysA.length; i++) { if ( !hasOwnProperty.call(objB, keysA[i]) || - !objectIs(objA[keysA[i]], objB[keysA[i]]) + !is$1(objA[keysA[i]], objB[keysA[i]]) ) { return false; } @@ -5192,122 +6018,77 @@ function shallowEqual(objA, objB) { return true; } -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]; +/** + * Forked from fbjs/warning: + * https://github.com/facebook/fbjs/blob/e66ba20ad5be433eb54423f2b097d829324d9de6/packages/fbjs/src/__forks__/warning.js + * + * Only change is we use console.warn instead of console.error, + * and do nothing when 'console' is not supported. + * This really simplifies the code. + * --- + * Similar to invariant but only logs a warning if the condition is not met. + * This can be used to log issues in development environments in critical + * paths. Removing the logging code for production environments will keep the + * same logic and follow the same code paths. + */ +var lowPriorityWarningWithoutStack = function() {}; - if (pathBeforeSlash) { - var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, ""); - fileName = folderName + "/" + fileName; - } - } - } +{ + var printWarning = function(format) { + for ( + var _len = arguments.length, + args = new Array(_len > 1 ? _len - 1 : 0), + _key = 1; + _key < _len; + _key++ + ) { + args[_key - 1] = arguments[_key]; } - sourceInfo = " (at " + fileName + ":" + source.lineNumber + ")"; - } else if (ownerName) { - sourceInfo = " (created by " + ownerName + ")"; - } - - return "\n in " + (name || "Unknown") + sourceInfo; -} + var argIndex = 0; + var message = + "Warning: " + + format.replace(/%s/g, function() { + return args[argIndex++]; + }); -var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; + if (typeof console !== "undefined") { + console.warn(message); + } -function describeFiber(fiber) { - switch (fiber.tag) { - case HostRoot: - case HostPortal: - case HostText: - case Fragment: - case ContextProvider: - case ContextConsumer: - return ""; + try { + // --- Welcome to debugging React --- + // This error was thrown as a convenience so that you can use this stack + // to find the callsite that caused this warning to fire. + throw new Error(message); + } catch (x) {} + }; - default: - var owner = fiber._debugOwner; - var source = fiber._debugSource; - var name = getComponentName(fiber.type); - var ownerName = null; + lowPriorityWarningWithoutStack = function(condition, format) { + if (format === undefined) { + throw new Error( + "`lowPriorityWarningWithoutStack(condition, format, ...args)` requires a warning " + + "message argument" + ); + } - if (owner) { - ownerName = getComponentName(owner.type); + if (!condition) { + for ( + var _len2 = arguments.length, + args = new Array(_len2 > 2 ? _len2 - 2 : 0), + _key2 = 2; + _key2 < _len2; + _key2++ + ) { + args[_key2 - 2] = arguments[_key2]; } - return describeComponentFrame(name, source, ownerName); - } + printWarning.apply(void 0, [format].concat(args)); + } + }; } -function getStackByFiberInDevAndProd(workInProgress) { - var info = ""; - var node = workInProgress; - - do { - info += describeFiber(node); - node = node.return; - } while (node); - - return info; -} -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); - } - } - - return null; -} -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. - - return getStackByFiberInDevAndProd(current); - } -} -function resetCurrentFiber() { - { - ReactDebugCurrentFrame.getCurrentStack = null; - current = null; - isRendering = false; - } -} -function setCurrentFiber(fiber) { - { - ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackInDev; - current = fiber; - isRendering = false; - } -} -function setIsRendering(rendering) { - { - isRendering = rendering; - } -} +var lowPriorityWarningWithoutStack$1 = lowPriorityWarningWithoutStack; var ReactStrictModeWarnings = { recordUnsafeLifecycleWarnings: function(fiber, instance) {}, @@ -5326,7 +6107,6 @@ var ReactStrictModeWarnings = { if (node.mode & StrictMode) { maybeStrictRoot = node; } - node = node.return; } @@ -5405,7 +6185,6 @@ var ReactStrictModeWarnings = { ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function() { // We do an initial pass to gather component names var componentWillMountUniqueNames = new Set(); - if (pendingComponentWillMountWarnings.length > 0) { pendingComponentWillMountWarnings.forEach(function(fiber) { componentWillMountUniqueNames.add( @@ -5417,7 +6196,6 @@ var ReactStrictModeWarnings = { } var UNSAFE_componentWillMountUniqueNames = new Set(); - if (pendingUNSAFE_ComponentWillMountWarnings.length > 0) { pendingUNSAFE_ComponentWillMountWarnings.forEach(function(fiber) { UNSAFE_componentWillMountUniqueNames.add( @@ -5429,7 +6207,6 @@ var ReactStrictModeWarnings = { } var componentWillReceivePropsUniqueNames = new Set(); - if (pendingComponentWillReceivePropsWarnings.length > 0) { pendingComponentWillReceivePropsWarnings.forEach(function(fiber) { componentWillReceivePropsUniqueNames.add( @@ -5441,7 +6218,6 @@ var ReactStrictModeWarnings = { } var UNSAFE_componentWillReceivePropsUniqueNames = new Set(); - if (pendingUNSAFE_ComponentWillReceivePropsWarnings.length > 0) { pendingUNSAFE_ComponentWillReceivePropsWarnings.forEach(function(fiber) { UNSAFE_componentWillReceivePropsUniqueNames.add( @@ -5453,7 +6229,6 @@ var ReactStrictModeWarnings = { } var componentWillUpdateUniqueNames = new Set(); - if (pendingComponentWillUpdateWarnings.length > 0) { pendingComponentWillUpdateWarnings.forEach(function(fiber) { componentWillUpdateUniqueNames.add( @@ -5465,7 +6240,6 @@ var ReactStrictModeWarnings = { } var UNSAFE_componentWillUpdateUniqueNames = new Set(); - if (pendingUNSAFE_ComponentWillUpdateWarnings.length > 0) { pendingUNSAFE_ComponentWillUpdateWarnings.forEach(function(fiber) { UNSAFE_componentWillUpdateUniqueNames.add( @@ -5479,8 +6253,8 @@ var ReactStrictModeWarnings = { if (UNSAFE_componentWillMountUniqueNames.size > 0) { var sortedNames = setToSortedString(UNSAFE_componentWillMountUniqueNames); - - error( + warningWithoutStack$1( + false, "Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. " + "See https://fb.me/react-unsafe-component-lifecycles for details.\n\n" + "* Move code with side effects to componentDidMount, and set initial state in the constructor.\n" + @@ -5493,8 +6267,8 @@ var ReactStrictModeWarnings = { var _sortedNames = setToSortedString( UNSAFE_componentWillReceivePropsUniqueNames ); - - error( + warningWithoutStack$1( + false, "Using UNSAFE_componentWillReceiveProps in strict mode is not recommended " + "and may indicate bugs in your code. " + "See https://fb.me/react-unsafe-component-lifecycles for details.\n\n" + @@ -5511,8 +6285,8 @@ var ReactStrictModeWarnings = { var _sortedNames2 = setToSortedString( UNSAFE_componentWillUpdateUniqueNames ); - - error( + warningWithoutStack$1( + false, "Using UNSAFE_componentWillUpdate in strict mode is not recommended " + "and may indicate bugs in your code. " + "See https://fb.me/react-unsafe-component-lifecycles for details.\n\n" + @@ -5525,7 +6299,8 @@ var ReactStrictModeWarnings = { if (componentWillMountUniqueNames.size > 0) { var _sortedNames3 = setToSortedString(componentWillMountUniqueNames); - warn( + lowPriorityWarningWithoutStack$1( + false, "componentWillMount has been renamed, and is not recommended for use. " + "See https://fb.me/react-unsafe-component-lifecycles for details.\n\n" + "* Move code with side effects to componentDidMount, and set initial state in the constructor.\n" + @@ -5543,7 +6318,8 @@ var ReactStrictModeWarnings = { componentWillReceivePropsUniqueNames ); - warn( + lowPriorityWarningWithoutStack$1( + false, "componentWillReceiveProps has been renamed, and is not recommended for use. " + "See https://fb.me/react-unsafe-component-lifecycles for details.\n\n" + "* Move data fetching code or side effects to componentDidUpdate.\n" + @@ -5562,7 +6338,8 @@ var ReactStrictModeWarnings = { if (componentWillUpdateUniqueNames.size > 0) { var _sortedNames5 = setToSortedString(componentWillUpdateUniqueNames); - warn( + lowPriorityWarningWithoutStack$1( + false, "componentWillUpdate has been renamed, and is not recommended for use. " + "See https://fb.me/react-unsafe-component-lifecycles for details.\n\n" + "* Move data fetching code or side effects to componentDidUpdate.\n" + @@ -5585,13 +6362,12 @@ var ReactStrictModeWarnings = { instance ) { var strictRoot = findStrictRoot(fiber); - if (strictRoot === null) { - error( + warningWithoutStack$1( + false, "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." ); - return; } // Dedup strategy: Warn once per component. @@ -5610,27 +6386,21 @@ var ReactStrictModeWarnings = { warningsForRoot = []; pendingLegacyContextWarning.set(strictRoot, warningsForRoot); } - warningsForRoot.push(fiber); } }; ReactStrictModeWarnings.flushLegacyContextWarning = function() { pendingLegacyContextWarning.forEach(function(fiberArray, strictRoot) { - if (fiberArray.length === 0) { - return; - } - - 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); - var firstComponentStack = getStackByFiberInDevAndProd(firstFiber); - - error( + var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot); + warningWithoutStack$1( + false, "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." + @@ -5638,7 +6408,7 @@ var ReactStrictModeWarnings = { "\n\nLearn more about this warning here: https://fb.me/react-legacy-context" + "%s", sortedNames, - firstComponentStack + strictRootComponentStack ); }); }; @@ -5702,7 +6472,6 @@ function resolveForwardRefForHotReloading(type) { // but it's possible that we only have its inner render function in the map. // If that inner render function is different, we'll build a new forwardRef type. var currentRender = resolveFunctionForHotReloading(type.render); - if (type.render !== currentRender) { var syntheticType = { $$typeof: REACT_FORWARD_REF_TYPE, @@ -5796,7 +6565,6 @@ function isCompatibleFamilyForHotReloading(fiber, element) { // then we would risk falsely saying two separate memo(Foo) // calls are equivalent because they wrap the same Foo function. var prevFamily = resolveFamily(prevType); - if (prevFamily !== undefined && prevFamily === resolveFamily(nextType)) { return true; } @@ -5881,6 +6649,9 @@ function scheduleFibersWithFamiliesRecursively( case ForwardRef: candidateType = type.render; break; + + default: + break; } if (resolveFamily === null) { @@ -5905,7 +6676,6 @@ function scheduleFibersWithFamiliesRecursively( } } } - if (failedBoundaries !== null) { if ( failedBoundaries.has(fiber) || @@ -5930,7 +6700,6 @@ function scheduleFibersWithFamiliesRecursively( staleFamilies ); } - if (sibling !== null) { scheduleFibersWithFamiliesRecursively( sibling, @@ -5980,10 +6749,12 @@ function findHostInstancesForMatchingFibersRecursively( case ForwardRef: candidateType = type.render; break; + + default: + break; } var didMatch = false; - if (candidateType !== null) { if (types.has(candidateType)) { didMatch = true; @@ -6057,7 +6828,6 @@ function findChildHostInstancesForFiberShallowly(fiber, hostInstances) { { var node = fiber; var foundHostInstances = false; - while (true) { if (node.tag === HostComponent) { // We got a match. @@ -6085,7 +6855,6 @@ function findChildHostInstancesForFiberShallowly(fiber, hostInstances) { node = node.sibling; } } - return false; } @@ -6094,7 +6863,6 @@ function resolveDefaultProps(Component, baseProps) { // 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]; @@ -6134,7 +6902,6 @@ function resetContextDependencies() { currentlyRenderingFiber = null; lastContextDependency = null; lastContextWithAllBitsObserved = null; - { isDisallowedContextReadInDEV = false; } @@ -6152,22 +6919,40 @@ function exitDisallowedContextReadInDEV() { function pushProvider(providerFiber, nextValue) { var context = providerFiber.type._context; - { + if (isPrimaryRenderer) { + push(valueCursor, context._currentValue, providerFiber); + context._currentValue = nextValue; + + { + !( + context._currentRenderer === undefined || + context._currentRenderer === null || + context._currentRenderer === rendererSigil + ) + ? warningWithoutStack$1( + false, + "Detected multiple renderers concurrently rendering the " + + "same context provider. This is currently unsupported." + ) + : void 0; + context._currentRenderer = rendererSigil; + } + } else { 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 === undefined || + context._currentRenderer2 === null || + context._currentRenderer2 === rendererSigil + ) + ? warningWithoutStack$1( + false, + "Detected multiple renderers concurrently rendering the " + + "same context provider. This is currently unsupported." + ) + : void 0; context._currentRenderer2 = rendererSigil; } } @@ -6177,12 +6962,14 @@ function popProvider(providerFiber) { pop(valueCursor, providerFiber); var context = providerFiber.type._context; - { + if (isPrimaryRenderer) { + context._currentValue = currentValue; + } else { context._currentValue2 = currentValue; } } function calculateChangedBits(context, newValue, oldValue) { - if (objectIs(oldValue, newValue)) { + if (is$1(oldValue, newValue)) { // No change return 0; } else { @@ -6192,13 +6979,14 @@ function calculateChangedBits(context, newValue, oldValue) { : MAX_SIGNED_31_BIT_INT; { - if ((changedBits & MAX_SIGNED_31_BIT_INT) !== changedBits) { - error( - "calculateChangedBits: Expected the return value to be a " + - "31-bit integer. Instead received: %s", - changedBits - ); - } + !((changedBits & MAX_SIGNED_31_BIT_INT) === changedBits) + ? warning$1( + false, + "calculateChangedBits: Expected the return value to be a " + + "31-bit integer. Instead received: %s", + changedBits + ) + : void 0; } return changedBits | 0; @@ -6242,7 +7030,6 @@ function propagateContextChange( renderExpirationTime ) { var fiber = workInProgress.child; - if (fiber !== null) { // Set the return pointer of the child to the work-in-progress fiber. fiber.return = workInProgress; @@ -6303,6 +7090,39 @@ function propagateContextChange( } else if (fiber.tag === ContextProvider) { // Don't scan deeper if this is a matching provider nextFiber = fiber.type === workInProgress.type ? null : fiber.child; + } else if ( + enableSuspenseServerRenderer && + fiber.tag === DehydratedFragment + ) { + // If a dehydrated suspense bounudary is in this subtree, we don't know + // if it will have any context consumers in it. The best we can do is + // mark it as having updates. + var parentSuspense = fiber.return; + + if (!(parentSuspense !== null)) { + throw Error( + "We just came from a parent so we must have had a parent. This is a bug in React." + ); + } + + if (parentSuspense.expirationTime < renderExpirationTime) { + parentSuspense.expirationTime = renderExpirationTime; + } + + var _alternate = parentSuspense.alternate; + + if ( + _alternate !== null && + _alternate.expirationTime < renderExpirationTime + ) { + _alternate.expirationTime = renderExpirationTime; + } // This is intentionally passing this fiber as the parent + // because we want to schedule this fiber as having work + // on its children. We'll use the childExpirationTime on + // this fiber to indicate that a context has changed. + + scheduleWorkOnParentPath(parentSuspense, renderExpirationTime); + nextFiber = fiber.sibling; } else { // Traverse down. nextFiber = fiber.child; @@ -6314,7 +7134,6 @@ function propagateContextChange( } 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. @@ -6361,19 +7180,22 @@ 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()." - ); - } + !!isDisallowedContextReadInDEV + ? warning$1( + false, + "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()." + ) + : void 0; } - if (lastContextWithAllBitsObserved === context); - else if (observedBits === false || observedBits === 0); - else { + if (lastContextWithAllBitsObserved === context) { + // Nothing to do. We already observe everything in this context. + } else if (observedBits === false || observedBits === 0) { + // Do not observe any updates. + } else { var resolvedObservedBits; // Avoid deopting on observable arguments or heterogeneous types. if ( @@ -6411,10 +7233,85 @@ function readContext(context, observedBits) { lastContextDependency = lastContextDependency.next = contextItem; } } - - return context._currentValue2; + return isPrimaryRenderer ? context._currentValue : context._currentValue2; } +// UpdateQueue is a linked list of prioritized updates. +// +// Like fibers, update queues come in pairs: a current queue, which represents +// the visible state of the screen, and a work-in-progress queue, which can be +// mutated and processed asynchronously before it is committed — a form of +// double buffering. If a work-in-progress render is discarded before finishing, +// we create a new work-in-progress by cloning the current queue. +// +// Both queues share a persistent, singly-linked list structure. To schedule an +// update, we append it to the end of both queues. Each queue maintains a +// pointer to first update in the persistent list that hasn't been processed. +// The work-in-progress pointer always has a position equal to or greater than +// the current queue, since we always work on that one. The current queue's +// pointer is only updated during the commit phase, when we swap in the +// work-in-progress. +// +// For example: +// +// Current pointer: A - B - C - D - E - F +// Work-in-progress pointer: D - E - F +// ^ +// The work-in-progress queue has +// processed more updates than current. +// +// The reason we append to both queues is because otherwise we might drop +// updates without ever processing them. For example, if we only add updates to +// the work-in-progress queue, some updates could be lost whenever a work-in +// -progress render restarts by cloning from current. Similarly, if we only add +// updates to the current queue, the updates will be lost whenever an already +// in-progress queue commits and swaps with the current queue. However, by +// adding to both queues, we guarantee that the update will be part of the next +// work-in-progress. (And because the work-in-progress queue becomes the +// current queue once it commits, there's no danger of applying the same +// update twice.) +// +// Prioritization +// -------------- +// +// Updates are not sorted by priority, but by insertion; new updates are always +// appended to the end of the list. +// +// The priority is still important, though. When processing the update queue +// during the render phase, only the updates with sufficient priority are +// included in the result. If we skip an update because it has insufficient +// priority, it remains in the queue to be processed later, during a lower +// priority render. Crucially, all updates subsequent to a skipped update also +// remain in the queue *regardless of their priority*. That means high priority +// updates are sometimes processed twice, at two separate priorities. We also +// keep track of a base state, that represents the state before the first +// update in the queue is applied. +// +// For example: +// +// Given a base state of '', and the following queue of updates +// +// A1 - B2 - C1 - D2 +// +// where the number indicates the priority, and the update is applied to the +// previous state by appending a letter, React will process these updates as +// two separate renders, one per distinct priority level: +// +// First render, at priority 1: +// Base state: '' +// Updates: [A1, C1] +// Result state: 'AC' +// +// Second render, at priority 2: +// Base state: 'A' <- The base state does not include C1, +// because B2 was skipped. +// Updates: [B2, C1, D2] <- C1 was rebased on top of B2 +// Result state: 'ABCD' +// +// Because we process updates in insertion order, and rebase high priority +// updates when preceding updates are skipped, the final result is deterministic +// regardless of priority. Intermediate state may vary according to system +// resources, but the final state is always the same. var UpdateState = 0; var ReplaceState = 1; var ForceUpdate = 2; @@ -6431,32 +7328,38 @@ var currentlyProcessingQueue; currentlyProcessingQueue = null; } -function initializeUpdateQueue(fiber) { +function createUpdateQueue(baseState) { var queue = { - baseState: fiber.memoizedState, - baseQueue: null, - shared: { - pending: null - }, - effects: null + baseState: baseState, + firstUpdate: null, + lastUpdate: null, + firstCapturedUpdate: null, + lastCapturedUpdate: null, + firstEffect: null, + lastEffect: null, + firstCapturedEffect: null, + lastCapturedEffect: 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; - - if (queue === currentQueue) { - var clone = { - baseState: currentQueue.baseState, - baseQueue: currentQueue.baseQueue, - shared: currentQueue.shared, - effects: currentQueue.effects - }; - workInProgress.updateQueue = clone; - } + return queue; } + +function cloneUpdateQueue(currentQueue) { + var queue = { + baseState: currentQueue.baseState, + firstUpdate: currentQueue.firstUpdate, + lastUpdate: currentQueue.lastUpdate, + // TODO: With resuming, if we bail out and resuse the child tree, we should + // keep these effects. + firstCapturedUpdate: null, + lastCapturedUpdate: null, + firstEffect: null, + lastEffect: null, + firstCapturedEffect: null, + lastCapturedEffect: null + }; + return queue; +} + function createUpdate(expirationTime, suspenseConfig) { var update = { expirationTime: expirationTime, @@ -6464,9 +7367,9 @@ function createUpdate(expirationTime, suspenseConfig) { tag: UpdateState, payload: null, callback: null, - next: null + next: null, + nextEffect: null }; - update.next = update; { update.priority = getCurrentPriorityLevel(); @@ -6474,62 +7377,130 @@ function createUpdate(expirationTime, suspenseConfig) { return update; } -function enqueueUpdate(fiber, update) { - var updateQueue = fiber.updateQueue; - if (updateQueue === null) { - // Only occurs if the fiber has been unmounted. - return; +function appendUpdateToQueue(queue, update) { + // Append the update to the end of the list. + if (queue.lastUpdate === null) { + // Queue is empty + queue.firstUpdate = queue.lastUpdate = update; + } else { + queue.lastUpdate.next = update; + queue.lastUpdate = update; } +} - var sharedQueue = updateQueue.shared; - var pending = sharedQueue.pending; +function enqueueUpdate(fiber, update) { + // Update queues are created lazily. + var alternate = fiber.alternate; + var queue1; + var queue2; - if (pending === null) { - // This is the first update. Create a circular list. - update.next = update; + if (alternate === null) { + // There's only one fiber. + queue1 = fiber.updateQueue; + queue2 = null; + if (queue1 === null) { + queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState); + } } else { - update.next = pending.next; - pending.next = update; + // There are two owners. + queue1 = fiber.updateQueue; + queue2 = alternate.updateQueue; + if (queue1 === null) { + if (queue2 === null) { + // Neither fiber has an update queue. Create new ones. + queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState); + queue2 = alternate.updateQueue = createUpdateQueue( + alternate.memoizedState + ); + } else { + // Only one fiber has an update queue. Clone to create a new one. + queue1 = fiber.updateQueue = cloneUpdateQueue(queue2); + } + } else { + if (queue2 === null) { + // Only one fiber has an update queue. Clone to create a new one. + queue2 = alternate.updateQueue = cloneUpdateQueue(queue1); + } else { + // Both owners have an update queue. + } + } } + if (queue2 === null || queue1 === queue2) { + // There's only a single queue. + appendUpdateToQueue(queue1, update); + } else { + // There are two queues. We need to append the update to both queues, + // while accounting for the persistent structure of the list — we don't + // want the same update to be added multiple times. + if (queue1.lastUpdate === null || queue2.lastUpdate === null) { + // One of the queues is not empty. We must add the update to both queues. + appendUpdateToQueue(queue1, update); + appendUpdateToQueue(queue2, update); + } else { + // Both queues are non-empty. The last update is the same in both lists, + // because of structural sharing. So, only append to one of the lists. + appendUpdateToQueue(queue1, update); // But we still need to update the `lastUpdate` pointer of queue2. - sharedQueue.pending = update; + queue2.lastUpdate = update; + } + } { if ( - currentlyProcessingQueue === sharedQueue && + fiber.tag === ClassComponent && + (currentlyProcessingQueue === queue1 || + (queue2 !== null && currentlyProcessingQueue === queue2)) && !didWarnUpdateInsideUpdate ) { - error( + warningWithoutStack$1( + false, "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, update) { - var current = workInProgress.alternate; - - if (current !== null) { - // Ensure the work-in-progress queue is a clone - cloneUpdateQueue(current, workInProgress); - } // Captured updates go only on the work-in-progress queue. - - var queue = workInProgress.updateQueue; // Append the update to the end of the list. - - var last = queue.baseQueue; + // Captured updates go into a separate list, and only on the work-in- + // progress queue. + var workInProgressQueue = workInProgress.updateQueue; + if (workInProgressQueue === null) { + workInProgressQueue = workInProgress.updateQueue = createUpdateQueue( + workInProgress.memoizedState + ); + } else { + // TODO: I put this here rather than createWorkInProgress so that we don't + // clone the queue unnecessarily. There's probably a better way to + // structure this. + workInProgressQueue = ensureWorkInProgressQueueIsAClone( + workInProgress, + workInProgressQueue + ); + } // Append the update to the end of the list. - if (last === null) { - queue.baseQueue = update.next = update; - update.next = update; + if (workInProgressQueue.lastCapturedUpdate === null) { + // This is the first render phase update + workInProgressQueue.firstCapturedUpdate = workInProgressQueue.lastCapturedUpdate = update; } else { - update.next = last.next; - last.next = update; + workInProgressQueue.lastCapturedUpdate.next = update; + workInProgressQueue.lastCapturedUpdate = update; + } +} + +function ensureWorkInProgressQueueIsAClone(workInProgress, queue) { + var current = workInProgress.alternate; + if (current !== null) { + // If the work-in-progress queue is equal to the current queue, + // we need to clone it first. + if (queue === current.updateQueue) { + queue = workInProgress.updateQueue = cloneUpdateQueue(queue); + } } + return queue; } function getStateFromUpdate( @@ -6549,7 +7520,10 @@ function getStateFromUpdate( { enterDisallowedContextReadInDEV(); - if (workInProgress.mode & StrictMode) { + if ( + debugRenderPhaseSideEffectsForStrictMode && + workInProgress.mode & StrictMode + ) { payload.call(instance, prevState, nextProps); } } @@ -6581,7 +7555,10 @@ function getStateFromUpdate( { enterDisallowedContextReadInDEV(); - if (workInProgress.mode & StrictMode) { + if ( + debugRenderPhaseSideEffectsForStrictMode && + workInProgress.mode & StrictMode + ) { _payload.call(instance, prevState, nextProps); } } @@ -6609,176 +7586,164 @@ function getStateFromUpdate( return prevState; } } - return prevState; } function processUpdateQueue( workInProgress, + queue, props, instance, renderExpirationTime ) { - // This is always non-null on a ClassComponent or HostRoot - var queue = workInProgress.updateQueue; hasForceUpdate = false; + queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue); { - currentlyProcessingQueue = queue.shared; - } // The last rebase update that is NOT part of the base state. - - var baseQueue = queue.baseQueue; // The last pending update that hasn't been processed yet. + currentlyProcessingQueue = queue; + } // These values may change as we process the queue. - var pendingQueue = queue.shared.pending; + var newBaseState = queue.baseState; + var newFirstUpdate = null; + var newExpirationTime = NoWork; // Iterate through the list of updates to compute the result. - if (pendingQueue !== null) { - // We have new updates that haven't been processed yet. - // We'll add them to the base queue. - if (baseQueue !== null) { - // Merge the pending queue and the base queue. - var baseFirst = baseQueue.next; - var pendingFirst = pendingQueue.next; - baseQueue.next = pendingFirst; - pendingQueue.next = baseFirst; - } + var update = queue.firstUpdate; + var resultState = newBaseState; - baseQueue = pendingQueue; - queue.shared.pending = null; // TODO: Pass `current` as argument + while (update !== null) { + var updateExpirationTime = update.expirationTime; - var current = workInProgress.alternate; + if (updateExpirationTime < renderExpirationTime) { + // This update does not have sufficient priority. Skip it. + if (newFirstUpdate === null) { + // This is the first skipped update. It will be the first update in + // the new list. + newFirstUpdate = update; // Since this is the first update that was skipped, the current result + // is the new base state. - if (current !== null) { - var currentQueue = current.updateQueue; + newBaseState = resultState; + } // Since this update will remain in the list, update the remaining + // expiration time. - if (currentQueue !== null) { - currentQueue.baseQueue = pendingQueue; + if (newExpirationTime < updateExpirationTime) { + newExpirationTime = updateExpirationTime; } - } - } // These values may change as we process the queue. + } else { + // This update does have sufficient priority. + // Mark the event time of this update as relevant to this render pass. + // TODO: This should ideally use the true event time of this update rather than + // its priority which is a derived and not reverseable value. + // TODO: We should skip this update if it was already committed but currently + // we have no way of detecting the difference between a committed and suspended + // update here. + markRenderEventTimeAndConfig(updateExpirationTime, update.suspenseConfig); // Process it and compute a new result. + + resultState = getStateFromUpdate( + workInProgress, + queue, + update, + resultState, + props, + instance + ); + var callback = update.callback; - if (baseQueue !== null) { - var first = baseQueue.next; // Iterate through the list of updates to compute the result. + if (callback !== null) { + workInProgress.effectTag |= Callback; // Set this to null, in case it was mutated during an aborted render. - var newState = queue.baseState; - var newExpirationTime = NoWork; - var newBaseState = null; - var newBaseQueueFirst = null; - var newBaseQueueLast = null; + update.nextEffect = null; - if (first !== null) { - var update = first; + if (queue.lastEffect === null) { + queue.firstEffect = queue.lastEffect = update; + } else { + queue.lastEffect.nextEffect = update; + queue.lastEffect = update; + } + } + } // Continue to the next update. - do { - var updateExpirationTime = update.expirationTime; - - if (updateExpirationTime < renderExpirationTime) { - // 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 = { - expirationTime: update.expirationTime, - suspenseConfig: update.suspenseConfig, - tag: update.tag, - payload: update.payload, - callback: update.callback, - next: null - }; + update = update.next; + } // Separately, iterate though the list of captured updates. - if (newBaseQueueLast === null) { - newBaseQueueFirst = newBaseQueueLast = clone; - newBaseState = newState; - } else { - newBaseQueueLast = newBaseQueueLast.next = clone; - } // Update the remaining priority in the queue. + var newFirstCapturedUpdate = null; + update = queue.firstCapturedUpdate; - if (updateExpirationTime > newExpirationTime) { - newExpirationTime = updateExpirationTime; - } - } else { - // This update does have sufficient priority. - if (newBaseQueueLast !== null) { - var _clone = { - expirationTime: Sync, - // This update is going to be committed so we never want uncommit it. - suspenseConfig: update.suspenseConfig, - tag: update.tag, - payload: update.payload, - callback: update.callback, - next: null - }; - newBaseQueueLast = newBaseQueueLast.next = _clone; - } // Mark the event time of this update as relevant to this render pass. - // TODO: This should ideally use the true event time of this update rather than - // its priority which is a derived and not reverseable value. - // TODO: We should skip this update if it was already committed but currently - // we have no way of detecting the difference between a committed and suspended - // update here. - - markRenderEventTimeAndConfig( - updateExpirationTime, - update.suspenseConfig - ); // Process this update. - - newState = getStateFromUpdate( - workInProgress, - queue, - update, - newState, - props, - instance - ); - var callback = update.callback; + while (update !== null) { + var _updateExpirationTime = update.expirationTime; - if (callback !== null) { - workInProgress.effectTag |= Callback; - var effects = queue.effects; + if (_updateExpirationTime < renderExpirationTime) { + // This update does not have sufficient priority. Skip it. + if (newFirstCapturedUpdate === null) { + // This is the first skipped captured update. It will be the first + // update in the new list. + newFirstCapturedUpdate = update; // If this is the first update that was skipped, the current result is + // the new base state. - if (effects === null) { - queue.effects = [update]; - } else { - effects.push(update); - } - } + if (newFirstUpdate === null) { + newBaseState = resultState; } + } // Since this update will remain in the list, update the remaining + // expiration time. - update = update.next; + if (newExpirationTime < _updateExpirationTime) { + newExpirationTime = _updateExpirationTime; + } + } else { + // This update does have sufficient priority. Process it and compute + // a new result. + resultState = getStateFromUpdate( + workInProgress, + queue, + update, + resultState, + props, + instance + ); + var _callback = update.callback; - if (update === null || update === first) { - pendingQueue = queue.shared.pending; + if (_callback !== null) { + workInProgress.effectTag |= Callback; // Set this to null, in case it was mutated during an aborted render. - 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. - update = baseQueue.next = pendingQueue.next; - pendingQueue.next = first; - queue.baseQueue = baseQueue = pendingQueue; - queue.shared.pending = null; - } + update.nextEffect = null; + + if (queue.lastCapturedEffect === null) { + queue.firstCapturedEffect = queue.lastCapturedEffect = update; + } else { + queue.lastCapturedEffect.nextEffect = update; + queue.lastCapturedEffect = update; } - } while (true); + } } + update = update.next; + } - if (newBaseQueueLast === null) { - newBaseState = newState; - } else { - newBaseQueueLast.next = newBaseQueueFirst; - } + if (newFirstUpdate === null) { + queue.lastUpdate = null; + } + if (newFirstCapturedUpdate === null) { + queue.lastCapturedUpdate = null; + } else { + workInProgress.effectTag |= Callback; + } + if (newFirstUpdate === null && newFirstCapturedUpdate === null) { + // We processed every update, without skipping. That means the new base + // state is the same as the result state. + newBaseState = resultState; + } - queue.baseState = newBaseState; - queue.baseQueue = newBaseQueueLast; // 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. + queue.baseState = newBaseState; + queue.firstUpdate = newFirstUpdate; + queue.firstCapturedUpdate = newFirstCapturedUpdate; // 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. - markUnprocessedUpdateTime(newExpirationTime); - workInProgress.expirationTime = newExpirationTime; - workInProgress.memoizedState = newState; - } + markUnprocessedUpdateTime(newExpirationTime); + workInProgress.expirationTime = newExpirationTime; + workInProgress.memoizedState = resultState; { currentlyProcessingQueue = null; @@ -6802,21 +7767,42 @@ function resetHasForceUpdateBeforeProcessing() { function checkHasForceUpdateAfterProcessing() { return hasForceUpdate; } -function commitUpdateQueue(finishedWork, finishedQueue, instance) { - // Commit the effects - var effects = finishedQueue.effects; - finishedQueue.effects = null; +function commitUpdateQueue( + finishedWork, + finishedQueue, + instance, + renderExpirationTime +) { + // If the finished render included captured updates, and there are still + // lower priority updates left over, we need to keep the captured updates + // in the queue so that they are rebased and not dropped once we process the + // queue again at the lower priority. + if (finishedQueue.firstCapturedUpdate !== null) { + // Join the captured update list to the end of the normal list. + if (finishedQueue.lastUpdate !== null) { + finishedQueue.lastUpdate.next = finishedQueue.firstCapturedUpdate; + finishedQueue.lastUpdate = finishedQueue.lastCapturedUpdate; + } // Clear the list of captured updates. + + finishedQueue.firstCapturedUpdate = finishedQueue.lastCapturedUpdate = null; + } // Commit the effects + + commitUpdateEffects(finishedQueue.firstEffect, instance); + finishedQueue.firstEffect = finishedQueue.lastEffect = null; + commitUpdateEffects(finishedQueue.firstCapturedEffect, instance); + finishedQueue.firstCapturedEffect = finishedQueue.lastCapturedEffect = null; +} - if (effects !== null) { - for (var i = 0; i < effects.length; i++) { - var effect = effects[i]; - var callback = effect.callback; +function commitUpdateEffects(effect, instance) { + while (effect !== null) { + var callback = effect.callback; - if (callback !== null) { - effect.callback = null; - callCallback(callback, instance); - } + if (callback !== null) { + effect.callback = null; + callCallback(callback, instance); } + + effect = effect.nextEffect; } } @@ -6826,7 +7812,7 @@ function requestCurrentSuspenseConfig() { } var fakeInternalInstance = {}; -var isArray = Array.isArray; // React.Component uses a shared frozen object by default. +var isArray$1 = Array.isArray; // React.Component uses a shared frozen object by default. // We'll use it to determine whether we need to initialize legacy refs. var emptyRefsObject = new React.Component().refs; @@ -6861,8 +7847,8 @@ var didWarnAboutInvalidateContextType; if (!didWarnOnInvalidCallback.has(key)) { didWarnOnInvalidCallback.add(key); - - error( + warningWithoutStack$1( + false, "%s(...): Expected the last optional `callback` argument to be a " + "function. Instead received: %s.", callerName, @@ -6874,11 +7860,10 @@ var didWarnAboutInvalidateContextType; warnOnUndefinedDerivedState = function(type, partialState) { if (partialState === undefined) { var componentName = getComponentName(type) || "Component"; - if (!didWarnAboutUndefinedDerivedState.has(componentName)) { didWarnAboutUndefinedDerivedState.add(componentName); - - error( + warningWithoutStack$1( + false, "%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. " + "You have returned undefined.", componentName @@ -6913,7 +7898,10 @@ function applyDerivedStateFromProps( var prevState = workInProgress.memoizedState; { - if (workInProgress.mode & StrictMode) { + if ( + debugRenderPhaseSideEffectsForStrictMode && + workInProgress.mode & StrictMode + ) { // Invoke the function an extra time to help detect side-effects. getDerivedStateFromProps(nextProps, prevState); } @@ -6932,9 +7920,9 @@ function applyDerivedStateFromProps( workInProgress.memoizedState = memoizedState; // Once the update queue is empty, persist the derived state onto the // base state. - if (workInProgress.expirationTime === NoWork) { - // Queue is always non-null for classes - var updateQueue = workInProgress.updateQueue; + var updateQueue = workInProgress.updateQueue; + + if (updateQueue !== null && workInProgress.expirationTime === NoWork) { updateQueue.baseState = memoizedState; } } @@ -7022,15 +8010,7 @@ function checkShouldComponentUpdate( nextContext ) { var instance = workInProgress.stateNode; - if (typeof instance.shouldComponentUpdate === "function") { - { - if (workInProgress.mode & StrictMode) { - // Invoke the function an extra time to help detect side-effects. - instance.shouldComponentUpdate(newProps, newState, nextContext); - } - } - startPhaseTimer(workInProgress, "shouldComponentUpdate"); var shouldUpdate = instance.shouldComponentUpdate( newProps, @@ -7040,13 +8020,14 @@ function checkShouldComponentUpdate( stopPhaseTimer(); { - if (shouldUpdate === undefined) { - error( - "%s.shouldComponentUpdate(): Returned undefined instead of a " + - "boolean value. Make sure to return true or false.", - getComponentName(ctor) || "Component" - ); - } + !(shouldUpdate !== undefined) + ? warningWithoutStack$1( + false, + "%s.shouldComponentUpdate(): Returned undefined instead of a " + + "boolean value. Make sure to return true or false.", + getComponentName(ctor) || "Component" + ) + : void 0; } return shouldUpdate; @@ -7063,20 +8044,21 @@ function checkShouldComponentUpdate( 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( + warningWithoutStack$1( + false, "%s(...): No `render` method found on the returned component " + "instance: did you accidentally return an object from the constructor?", name ); } else { - error( + warningWithoutStack$1( + false, "%s(...): No `render` method found on the returned component " + "instance: you may have forgotten to define `render`.", name @@ -7084,55 +8066,77 @@ function checkClassInstance(workInProgress, ctor, newProps) { } } - 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.", + var noGetInitialStateOnES6 = + !instance.getInitialState || + instance.getInitialState.isReactClassApproved || + instance.state; + !noGetInitialStateOnES6 + ? warningWithoutStack$1( + false, + "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 + ) + : void 0; + var noGetDefaultPropsOnES6 = + !instance.getDefaultProps || + instance.getDefaultProps.isReactClassApproved; + !noGetDefaultPropsOnES6 + ? warningWithoutStack$1( + false, + "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 + ) + : void 0; + var noInstancePropTypes = !instance.propTypes; + !noInstancePropTypes + ? warningWithoutStack$1( + false, + "propTypes was defined as an instance property on %s. Use a static " + + "property to define propTypes instead.", + name + ) + : void 0; + var noInstanceContextType = !instance.contextType; + !noInstanceContextType + ? warningWithoutStack$1( + false, + "contextType was defined as an instance property on %s. Use a static " + + "property to define contextType instead.", + name + ) + : void 0; + + if (disableLegacyContext) { + if (ctor.childContextTypes) { + warningWithoutStack$1( + false, + "%s uses the legacy childContextTypes API which is no longer supported. " + + "Use React.createContext() instead.", + name + ); + } + if (ctor.contextTypes) { + warningWithoutStack$1( + false, + "%s uses the legacy contextTypes API which is no longer supported. " + + "Use React.createContext() with static contextType instead.", name ); } + } else { + var noInstanceContextTypes = !instance.contextTypes; + !noInstanceContextTypes + ? warningWithoutStack$1( + false, + "contextTypes was defined as an instance property on %s. Use a static " + + "property to define contextTypes instead.", + name + ) + : void 0; if ( ctor.contextType && @@ -7140,8 +8144,8 @@ function checkClassInstance(workInProgress, ctor, newProps) { !didWarnAboutContextTypeAndContextTypes.has(ctor) ) { didWarnAboutContextTypeAndContextTypes.add(ctor); - - error( + warningWithoutStack$1( + false, "%s declares both contextTypes and contextType static properties. " + "The legacy contextTypes property will be ignored.", name @@ -7149,84 +8153,95 @@ function checkClassInstance(workInProgress, ctor, newProps) { } } - if (typeof instance.componentShouldUpdate === "function") { - error( - "%s has a method called " + - "componentShouldUpdate(). Did you mean shouldComponentUpdate()? " + - "The name is phrased as a question because the function is " + - "expected to return a value.", - name - ); - } - + var noComponentShouldUpdate = + typeof instance.componentShouldUpdate !== "function"; + !noComponentShouldUpdate + ? warningWithoutStack$1( + false, + "%s has a method called " + + "componentShouldUpdate(). Did you mean shouldComponentUpdate()? " + + "The name is phrased as a question because the function is " + + "expected to return a value.", + name + ) + : void 0; if ( ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== "undefined" ) { - error( + warningWithoutStack$1( + false, "%s has a method called shouldComponentUpdate(). " + "shouldComponentUpdate should not be used when extending React.PureComponent. " + "Please extend React.Component if shouldComponentUpdate is used.", getComponentName(ctor) || "A pure component" ); } - - if (typeof instance.componentDidUnmount === "function") { - error( - "%s has a method called " + - "componentDidUnmount(). But there is no such lifecycle method. " + - "Did you mean componentWillUnmount()?", - name - ); - } - - if (typeof instance.componentDidReceiveProps === "function") { - error( - "%s has a method called " + - "componentDidReceiveProps(). But there is no such lifecycle method. " + - "If you meant to update the state in response to changing props, " + - "use componentWillReceiveProps(). If you meant to fetch data or " + - "run side-effects or mutations after React has updated the UI, use componentDidUpdate().", - name - ); - } - - if (typeof instance.componentWillRecieveProps === "function") { - error( - "%s has a method called " + - "componentWillRecieveProps(). Did you mean componentWillReceiveProps()?", - name - ); - } - - if (typeof instance.UNSAFE_componentWillRecieveProps === "function") { - error( - "%s has a method called " + - "UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?", - name - ); - } - + var noComponentDidUnmount = + typeof instance.componentDidUnmount !== "function"; + !noComponentDidUnmount + ? warningWithoutStack$1( + false, + "%s has a method called " + + "componentDidUnmount(). But there is no such lifecycle method. " + + "Did you mean componentWillUnmount()?", + name + ) + : void 0; + var noComponentDidReceiveProps = + typeof instance.componentDidReceiveProps !== "function"; + !noComponentDidReceiveProps + ? warningWithoutStack$1( + false, + "%s has a method called " + + "componentDidReceiveProps(). But there is no such lifecycle method. " + + "If you meant to update the state in response to changing props, " + + "use componentWillReceiveProps(). If you meant to fetch data or " + + "run side-effects or mutations after React has updated the UI, use componentDidUpdate().", + name + ) + : void 0; + var noComponentWillRecieveProps = + typeof instance.componentWillRecieveProps !== "function"; + !noComponentWillRecieveProps + ? warningWithoutStack$1( + false, + "%s has a method called " + + "componentWillRecieveProps(). Did you mean componentWillReceiveProps()?", + name + ) + : void 0; + var noUnsafeComponentWillRecieveProps = + typeof instance.UNSAFE_componentWillRecieveProps !== "function"; + !noUnsafeComponentWillRecieveProps + ? warningWithoutStack$1( + false, + "%s has a method called " + + "UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?", + name + ) + : void 0; var hasMutatedProps = instance.props !== newProps; - - if (instance.props !== undefined && hasMutatedProps) { - error( - "%s(...): When calling super() in `%s`, make sure to pass " + - "up the same props that your component's constructor was passed.", - name, - name - ); - } - - if (instance.defaultProps) { - error( - "Setting defaultProps as an instance property on %s is not supported and will be ignored." + - " Instead, define defaultProps as a static property on %s.", - name, - name - ); - } + !(instance.props === undefined || !hasMutatedProps) + ? warningWithoutStack$1( + false, + "%s(...): When calling super() in `%s`, make sure to pass " + + "up the same props that your component's constructor was passed.", + name, + name + ) + : void 0; + var noInstanceDefaultProps = !instance.defaultProps; + !noInstanceDefaultProps + ? warningWithoutStack$1( + false, + "Setting defaultProps as an instance property on %s is not supported and will be ignored." + + " Instead, define defaultProps as a static property on %s.", + name, + name + ) + : void 0; if ( typeof instance.getSnapshotBeforeUpdate === "function" && @@ -7234,54 +8249,62 @@ function checkClassInstance(workInProgress, ctor, newProps) { !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor) ) { didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor); - - error( + warningWithoutStack$1( + false, "%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). " + "This component defines getSnapshotBeforeUpdate() only.", getComponentName(ctor) ); } - if (typeof instance.getDerivedStateFromProps === "function") { - error( - "%s: getDerivedStateFromProps() is defined as an instance method " + - "and will be ignored. Instead, declare it as a static method.", - name - ); - } - - if (typeof instance.getDerivedStateFromError === "function") { - error( - "%s: getDerivedStateFromError() is defined as an instance method " + - "and will be ignored. Instead, declare it as a static method.", - name - ); - } - - if (typeof ctor.getSnapshotBeforeUpdate === "function") { - error( - "%s: getSnapshotBeforeUpdate() is defined as a static method " + - "and will be ignored. Instead, declare it as an instance method.", - name - ); - } - + var noInstanceGetDerivedStateFromProps = + typeof instance.getDerivedStateFromProps !== "function"; + !noInstanceGetDerivedStateFromProps + ? warningWithoutStack$1( + false, + "%s: getDerivedStateFromProps() is defined as an instance method " + + "and will be ignored. Instead, declare it as a static method.", + name + ) + : void 0; + var noInstanceGetDerivedStateFromCatch = + typeof instance.getDerivedStateFromError !== "function"; + !noInstanceGetDerivedStateFromCatch + ? warningWithoutStack$1( + false, + "%s: getDerivedStateFromError() is defined as an instance method " + + "and will be ignored. Instead, declare it as a static method.", + name + ) + : void 0; + var noStaticGetSnapshotBeforeUpdate = + typeof ctor.getSnapshotBeforeUpdate !== "function"; + !noStaticGetSnapshotBeforeUpdate + ? warningWithoutStack$1( + false, + "%s: getSnapshotBeforeUpdate() is defined as a static method " + + "and will be ignored. Instead, declare it as an instance method.", + name + ) + : void 0; var _state = instance.state; - - if (_state && (typeof _state !== "object" || isArray(_state))) { - error("%s.state: must be set to an object or null", name); - } - - if ( - typeof instance.getChildContext === "function" && - typeof ctor.childContextTypes !== "object" - ) { - error( - "%s.getChildContext(): childContextTypes must be defined in order to " + - "use getChildContext().", + if (_state && (typeof _state !== "object" || isArray$1(_state))) { + warningWithoutStack$1( + false, + "%s.state: must be set to an object or null", name ); } + if (typeof instance.getChildContext === "function") { + !(typeof ctor.childContextTypes === "object") + ? warningWithoutStack$1( + false, + "%s.getChildContext(): childContextTypes must be defined in order to " + + "use getChildContext().", + name + ) + : void 0; + } } } @@ -7296,7 +8319,12 @@ function adoptClassInstance(workInProgress, instance) { } } -function constructClassInstance(workInProgress, ctor, props) { +function constructClassInstance( + workInProgress, + ctor, + props, + renderExpirationTime +) { var isLegacyContextConsumer = false; var unmaskedContext = emptyContextObject; var context = emptyContextObject; @@ -7333,8 +8361,8 @@ function constructClassInstance(workInProgress, ctor, props) { Object.keys(contextType).join(", ") + "}."; } - - error( + warningWithoutStack$1( + false, "%s defines an invalid contextType. " + "contextType should point to the Context object returned by React.createContext().%s", getComponentName(ctor) || "Component", @@ -7346,7 +8374,7 @@ function constructClassInstance(workInProgress, ctor, props) { if (typeof contextType === "object" && contextType !== null) { context = readContext(contextType); - } else { + } else if (!disableLegacyContext) { unmaskedContext = getUnmaskedContext(workInProgress, ctor, true); var contextTypes = ctor.contextTypes; isLegacyContextConsumer = @@ -7357,7 +8385,10 @@ function constructClassInstance(workInProgress, ctor, props) { } // Instantiate twice to help detect side-effects. { - if (workInProgress.mode & StrictMode) { + if ( + debugRenderPhaseSideEffectsForStrictMode && + workInProgress.mode & StrictMode + ) { new ctor(props, context); // eslint-disable-line no-new } } @@ -7372,11 +8403,10 @@ function constructClassInstance(workInProgress, ctor, props) { { if (typeof ctor.getDerivedStateFromProps === "function" && state === null) { var componentName = getComponentName(ctor) || "Component"; - if (!didWarnAboutUninitializedState.has(componentName)) { didWarnAboutUninitializedState.add(componentName); - - error( + warningWithoutStack$1( + false, "`%s` uses `getDerivedStateFromProps` but its initial state is " + "%s. This is not recommended. Instead, define the initial state by " + "assigning an object to `this.state` in the constructor of `%s`. " + @@ -7397,7 +8427,6 @@ function constructClassInstance(workInProgress, ctor, props) { var foundWillMountName = null; var foundWillReceivePropsName = null; var foundWillUpdateName = null; - if ( typeof instance.componentWillMount === "function" && instance.componentWillMount.__suppressDeprecationWarning !== true @@ -7406,7 +8435,6 @@ function constructClassInstance(workInProgress, ctor, props) { } else if (typeof instance.UNSAFE_componentWillMount === "function") { foundWillMountName = "UNSAFE_componentWillMount"; } - if ( typeof instance.componentWillReceiveProps === "function" && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true @@ -7417,7 +8445,6 @@ function constructClassInstance(workInProgress, ctor, props) { ) { foundWillReceivePropsName = "UNSAFE_componentWillReceiveProps"; } - if ( typeof instance.componentWillUpdate === "function" && instance.componentWillUpdate.__suppressDeprecationWarning !== true @@ -7426,23 +8453,20 @@ function constructClassInstance(workInProgress, ctor, props) { } else if (typeof instance.UNSAFE_componentWillUpdate === "function") { foundWillUpdateName = "UNSAFE_componentWillUpdate"; } - if ( foundWillMountName !== null || foundWillReceivePropsName !== null || foundWillUpdateName !== null ) { var _componentName = getComponentName(ctor) || "Component"; - var newApiName = typeof ctor.getDerivedStateFromProps === "function" ? "getDerivedStateFromProps()" : "getSnapshotBeforeUpdate()"; - if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName)) { didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName); - - error( + warningWithoutStack$1( + false, "Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n" + "%s uses %s but also contains the following legacy lifecycles:%s%s%s\n\n" + "The above lifecycles should be removed. Learn more about this warning here:\n" + @@ -7475,7 +8499,6 @@ function callComponentWillMount(workInProgress, instance) { if (typeof instance.componentWillMount === "function") { instance.componentWillMount(); } - if (typeof instance.UNSAFE_componentWillMount === "function") { instance.UNSAFE_componentWillMount(); } @@ -7484,14 +8507,14 @@ function callComponentWillMount(workInProgress, instance) { if (oldState !== instance.state) { { - error( + warningWithoutStack$1( + false, "%s.componentWillMount(): Assigning directly to this.state is " + "deprecated (except inside a component's " + "constructor). Use setState instead.", getComponentName(workInProgress.type) || "Component" ); } - classComponentUpdater.enqueueReplaceState(instance, instance.state, null); } } @@ -7518,11 +8541,10 @@ function callComponentWillReceiveProps( if (instance.state !== oldState) { { var componentName = getComponentName(workInProgress.type) || "Component"; - if (!didWarnAboutStateAssignmentForComponent.has(componentName)) { didWarnAboutStateAssignmentForComponent.add(componentName); - - error( + warningWithoutStack$1( + false, "%s.componentWillReceiveProps(): Assigning directly to " + "this.state is deprecated (except inside a component's " + "constructor). Use setState instead.", @@ -7549,11 +8571,12 @@ function mountClassInstance( instance.props = newProps; instance.state = workInProgress.memoizedState; instance.refs = emptyRefsObject; - initializeUpdateQueue(workInProgress); var contextType = ctor.contextType; if (typeof contextType === "object" && contextType !== null) { instance.context = readContext(contextType); + } else if (disableLegacyContext) { + instance.context = emptyContextObject; } else { var unmaskedContext = getUnmaskedContext(workInProgress, ctor, true); instance.context = getMaskedContext(workInProgress, unmaskedContext); @@ -7562,11 +8585,10 @@ function mountClassInstance( { if (instance.state === newProps) { var componentName = getComponentName(ctor) || "Component"; - if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) { didWarnAboutDirectlyAssigningPropsToState.add(componentName); - - error( + warningWithoutStack$1( + false, "%s: It is not recommended to assign props directly to state " + "because updates to props won't be reflected in state. " + "In most cases, it is better to use props directly.", @@ -7582,7 +8604,7 @@ function mountClassInstance( ); } - { + if (warnAboutDeprecatedLifecycles) { ReactStrictModeWarnings.recordUnsafeLifecycleWarnings( workInProgress, instance @@ -7590,10 +8612,19 @@ function mountClassInstance( } } - processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); - instance.state = workInProgress.memoizedState; - var getDerivedStateFromProps = ctor.getDerivedStateFromProps; + var updateQueue = workInProgress.updateQueue; + if (updateQueue !== null) { + processUpdateQueue( + workInProgress, + updateQueue, + newProps, + instance, + renderExpirationTime + ); + instance.state = workInProgress.memoizedState; + } + var getDerivedStateFromProps = ctor.getDerivedStateFromProps; if (typeof getDerivedStateFromProps === "function") { applyDerivedStateFromProps( workInProgress, @@ -7614,13 +8645,18 @@ function mountClassInstance( callComponentWillMount(workInProgress, instance); // If we had additional state updates during this life-cycle, let's // process them now. - processUpdateQueue( - workInProgress, - newProps, - instance, - renderExpirationTime - ); - instance.state = workInProgress.memoizedState; + updateQueue = workInProgress.updateQueue; + + if (updateQueue !== null) { + processUpdateQueue( + workInProgress, + updateQueue, + newProps, + instance, + renderExpirationTime + ); + instance.state = workInProgress.memoizedState; + } } if (typeof instance.componentDidMount === "function") { @@ -7643,7 +8679,7 @@ function resumeMountClassInstance( if (typeof contextType === "object" && contextType !== null) { nextContext = readContext(contextType); - } else { + } else if (!disableLegacyContext) { var nextLegacyUnmaskedContext = getUnmaskedContext( workInProgress, ctor, @@ -7679,9 +8715,18 @@ function resumeMountClassInstance( resetHasForceUpdateBeforeProcessing(); var oldState = workInProgress.memoizedState; var newState = (instance.state = oldState); - processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); - newState = workInProgress.memoizedState; + var updateQueue = workInProgress.updateQueue; + if (updateQueue !== null) { + processUpdateQueue( + workInProgress, + updateQueue, + newProps, + instance, + renderExpirationTime + ); + newState = workInProgress.memoizedState; + } if ( oldProps === newProps && oldState === newState && @@ -7693,7 +8738,6 @@ function resumeMountClassInstance( if (typeof instance.componentDidMount === "function") { workInProgress.effectTag |= Update; } - return false; } @@ -7770,7 +8814,6 @@ function updateClassInstance( renderExpirationTime ) { var instance = workInProgress.stateNode; - cloneUpdateQueue(current, workInProgress); var oldProps = workInProgress.memoizedProps; instance.props = workInProgress.type === workInProgress.elementType @@ -7782,7 +8825,7 @@ function updateClassInstance( if (typeof contextType === "object" && contextType !== null) { nextContext = readContext(contextType); - } else { + } else if (!disableLegacyContext) { var nextUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true); nextContext = getMaskedContext(workInProgress, nextUnmaskedContext); } @@ -7814,8 +8857,18 @@ function updateClassInstance( resetHasForceUpdateBeforeProcessing(); var oldState = workInProgress.memoizedState; var newState = (instance.state = oldState); - processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); - newState = workInProgress.memoizedState; + var updateQueue = workInProgress.updateQueue; + + if (updateQueue !== null) { + processUpdateQueue( + workInProgress, + updateQueue, + newProps, + instance, + renderExpirationTime + ); + newState = workInProgress.memoizedState; + } if ( oldProps === newProps && @@ -7833,7 +8886,6 @@ function updateClassInstance( workInProgress.effectTag |= Update; } } - if (typeof instance.getSnapshotBeforeUpdate === "function") { if ( oldProps !== current.memoizedProps || @@ -7842,7 +8894,6 @@ function updateClassInstance( workInProgress.effectTag |= Snapshot; } } - return false; } @@ -7907,7 +8958,6 @@ function updateClassInstance( workInProgress.effectTag |= Update; } } - if (typeof instance.getSnapshotBeforeUpdate === "function") { if ( oldProps !== current.memoizedProps || @@ -7946,7 +8996,6 @@ var warnForMissingKey = function(child) {}; * object keys are not valid. This allows us to keep track of children between * updates. */ - ownerHasKeyUseWarning = {}; ownerHasFunctionTypeWarning = {}; @@ -7977,8 +9026,8 @@ var warnForMissingKey = function(child) {}; } ownerHasKeyUseWarning[currentComponentErrorInfo] = true; - - error( + warning$1( + false, "Each child in a list should have a unique " + '"key" prop. See https://fb.me/react-warning-keys for ' + "more information." @@ -7986,11 +9035,10 @@ var warnForMissingKey = function(child) {}; }; } -var isArray$1 = Array.isArray; +var isArray = Array.isArray; -function coerceRef(returnFiber, current, element) { +function coerceRef(returnFiber, current$$1, element) { var mixedRef = element.ref; - if ( mixedRef !== null && typeof mixedRef !== "function" && @@ -7999,21 +9047,24 @@ 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 - // because these cannot be automatically converted to an arrow function - // using a codemod. Therefore, we don't have to warn about string refs again. - !( - element._owner && - element._self && - element._owner.stateNode !== element._self - ) - ) { + if (returnFiber.mode & StrictMode || warnAboutStringRefs) { var componentName = getComponentName(returnFiber.type) || "Component"; - if (!didWarnAboutStringRefs[componentName]) { - { - error( + if (warnAboutStringRefs) { + warningWithoutStack$1( + false, + 'Component "%s" contains the string ref "%s". Support for string refs ' + + "will be removed in a future major release. We recommend using " + + "useRef() or createRef() instead. " + + "Learn more about using refs safely here: " + + "https://fb.me/react-strict-mode-string-ref%s", + componentName, + mixedRef, + getStackByFiberInDevAndProd(returnFiber) + ); + } else { + warningWithoutStack$1( + false, 'A string ref, "%s", has been found within a strict mode tree. ' + "String refs are a source of potential bugs and should be avoided. " + "We recommend using useRef() or createRef() instead. " + @@ -8023,7 +9074,6 @@ function coerceRef(returnFiber, current, element) { getStackByFiberInDevAndProd(returnFiber) ); } - didWarnAboutStringRefs[componentName] = true; } } @@ -8038,7 +9088,7 @@ function coerceRef(returnFiber, current, element) { if (!(ownerFiber.tag === ClassComponent)) { throw Error( - "Function components cannot have string refs. We recommend using useRef() instead. Learn more about using refs safely here: https://fb.me/react-strict-mode-string-ref" + "Function components cannot have refs. Did you mean to use React.forwardRef()?" ); } @@ -8056,12 +9106,12 @@ function coerceRef(returnFiber, current, element) { var stringRef = "" + mixedRef; // Check if previous string ref matches new string ref if ( - current !== null && - current.ref !== null && - typeof current.ref === "function" && - current.ref._stringRef === stringRef + current$$1 !== null && + current$$1.ref !== null && + typeof current$$1.ref === "function" && + current$$1.ref._stringRef === stringRef ) { - return current.ref; + return current$$1.ref; } var ref = function(value) { @@ -8071,7 +9121,6 @@ function coerceRef(returnFiber, current, element) { // This is a lazy pooled frozen object, so we need to initialize. refs = inst.refs = {}; } - if (value === null) { delete refs[stringRef]; } else { @@ -8104,7 +9153,6 @@ function coerceRef(returnFiber, current, element) { function throwOnInvalidObjectType(returnFiber, newChild) { if (returnFiber.type !== "textarea") { var addendum = ""; - { addendum = " If you meant to render a collection of children, use an array " + @@ -8126,25 +9174,23 @@ function throwOnInvalidObjectType(returnFiber, newChild) { } function warnOnFunctionType() { - { - var currentComponentErrorInfo = - "Functions are not valid as a React child. This may happen if " + - "you return a Component instead of from render. " + - "Or maybe you meant to call this function rather than return it." + - getCurrentFiberStackInDev(); - - if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) { - return; - } + var currentComponentErrorInfo = + "Functions are not valid as a React child. This may happen if " + + "you return a Component instead of from render. " + + "Or maybe you meant to call this function rather than return it." + + getCurrentFiberStackInDev(); - ownerHasFunctionTypeWarning[currentComponentErrorInfo] = true; - - error( - "Functions are not valid as a React child. This may happen if " + - "you return a Component instead of from render. " + - "Or maybe you meant to call this function rather than return it." - ); + if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) { + return; } + + ownerHasFunctionTypeWarning[currentComponentErrorInfo] = true; + warning$1( + false, + "Functions are not valid as a React child. This may happen if " + + "you return a Component instead of from render. " + + "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 @@ -8169,7 +9215,6 @@ function ChildReconciler(shouldTrackSideEffects) { } else { returnFiber.firstEffect = returnFiber.lastEffect = childToDelete; } - childToDelete.nextEffect = null; childToDelete.effectTag = Deletion; } @@ -8187,7 +9232,6 @@ function ChildReconciler(shouldTrackSideEffects) { deleteChild(returnFiber, childToDelete); childToDelete = childToDelete.sibling; } - return null; } @@ -8211,10 +9255,10 @@ function ChildReconciler(shouldTrackSideEffects) { return existingChildren; } - function useFiber(fiber, pendingProps) { + function useFiber(fiber, pendingProps, expirationTime) { // We currently set sibling to null and index to 0 here because it is easy // to forget to do before returning it. E.g. for the single child case. - var clone = createWorkInProgress(fiber, pendingProps); + var clone = createWorkInProgress(fiber, pendingProps, expirationTime); clone.index = 0; clone.sibling = null; return clone; @@ -8222,16 +9266,15 @@ function ChildReconciler(shouldTrackSideEffects) { function placeChild(newFiber, lastPlacedIndex, newIndex) { newFiber.index = newIndex; - if (!shouldTrackSideEffects) { // Noop. return lastPlacedIndex; } - var current = newFiber.alternate; + var current$$1 = newFiber.alternate; - if (current !== null) { - var oldIndex = current.index; + if (current$$1 !== null) { + var oldIndex = current$$1.index; if (oldIndex < lastPlacedIndex) { // This is a move. @@ -8254,12 +9297,16 @@ function ChildReconciler(shouldTrackSideEffects) { if (shouldTrackSideEffects && newFiber.alternate === null) { newFiber.effectTag = Placement; } - return newFiber; } - function updateTextNode(returnFiber, current, textContent, expirationTime) { - if (current === null || current.tag !== HostText) { + function updateTextNode( + returnFiber, + current$$1, + textContent, + expirationTime + ) { + if (current$$1 === null || current$$1.tag !== HostText) { // Insert var created = createFiberFromText( textContent, @@ -8270,48 +9317,46 @@ function ChildReconciler(shouldTrackSideEffects) { return created; } else { // Update - var existing = useFiber(current, textContent); + var existing = useFiber(current$$1, textContent, expirationTime); existing.return = returnFiber; return existing; } } - function updateElement(returnFiber, current, element, expirationTime) { - if (current !== null) { - if ( - 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); - existing.ref = coerceRef(returnFiber, current, element); - existing.return = returnFiber; - - { - existing._debugSource = element._source; - existing._debugOwner = element._owner; - } - - return existing; + function updateElement(returnFiber, current$$1, element, expirationTime) { + if ( + current$$1 !== null && + (current$$1.elementType === element.type || // Keep this check inline so it only runs on the false path: + isCompatibleFamilyForHotReloading(current$$1, element)) + ) { + // Move based on index + var existing = useFiber(current$$1, element.props, expirationTime); + existing.ref = coerceRef(returnFiber, current$$1, element); + existing.return = returnFiber; + { + existing._debugSource = element._source; + existing._debugOwner = element._owner; } - } // Insert - - var created = createFiberFromElement( - element, - returnFiber.mode, - expirationTime - ); - created.ref = coerceRef(returnFiber, current, element); - created.return = returnFiber; - return created; + return existing; + } else { + // Insert + var created = createFiberFromElement( + element, + returnFiber.mode, + expirationTime + ); + created.ref = coerceRef(returnFiber, current$$1, element); + created.return = returnFiber; + return created; + } } - function updatePortal(returnFiber, current, portal, expirationTime) { + function updatePortal(returnFiber, current$$1, portal, expirationTime) { if ( - current === null || - current.tag !== HostPortal || - current.stateNode.containerInfo !== portal.containerInfo || - current.stateNode.implementation !== portal.implementation + current$$1 === null || + current$$1.tag !== HostPortal || + current$$1.stateNode.containerInfo !== portal.containerInfo || + current$$1.stateNode.implementation !== portal.implementation ) { // Insert var created = createFiberFromPortal( @@ -8323,14 +9368,24 @@ function ChildReconciler(shouldTrackSideEffects) { return created; } else { // Update - var existing = useFiber(current, portal.children || []); + var existing = useFiber( + current$$1, + portal.children || [], + expirationTime + ); existing.return = returnFiber; return existing; } } - function updateFragment(returnFiber, current, fragment, expirationTime, key) { - if (current === null || current.tag !== Fragment) { + function updateFragment( + returnFiber, + current$$1, + fragment, + expirationTime, + key + ) { + if (current$$1 === null || current$$1.tag !== Fragment) { // Insert var created = createFiberFromFragment( fragment, @@ -8342,7 +9397,7 @@ function ChildReconciler(shouldTrackSideEffects) { return created; } else { // Update - var existing = useFiber(current, fragment); + var existing = useFiber(current$$1, fragment, expirationTime); existing.return = returnFiber; return existing; } @@ -8370,32 +9425,28 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime ); - _created.ref = coerceRef(returnFiber, null, newChild); _created.return = returnFiber; return _created; } - case REACT_PORTAL_TYPE: { var _created2 = createFiberFromPortal( newChild, returnFiber.mode, expirationTime ); - _created2.return = returnFiber; return _created2; } } - if (isArray$1(newChild) || getIteratorFn(newChild)) { + if (isArray(newChild) || getIteratorFn(newChild)) { var _created3 = createFiberFromFragment( newChild, returnFiber.mode, expirationTime, null ); - _created3.return = returnFiber; return _created3; } @@ -8423,7 +9474,6 @@ function ChildReconciler(shouldTrackSideEffects) { if (key !== null) { return null; } - return updateTextNode( returnFiber, oldFiber, @@ -8445,7 +9495,6 @@ function ChildReconciler(shouldTrackSideEffects) { key ); } - return updateElement( returnFiber, oldFiber, @@ -8456,7 +9505,6 @@ function ChildReconciler(shouldTrackSideEffects) { return null; } } - case REACT_PORTAL_TYPE: { if (newChild.key === key) { return updatePortal( @@ -8471,7 +9519,7 @@ function ChildReconciler(shouldTrackSideEffects) { } } - if (isArray$1(newChild) || getIteratorFn(newChild)) { + if (isArray(newChild) || getIteratorFn(newChild)) { if (key !== null) { return null; } @@ -8523,7 +9571,6 @@ function ChildReconciler(shouldTrackSideEffects) { existingChildren.get( newChild.key === null ? newIdx : newChild.key ) || null; - if (newChild.type === REACT_FRAGMENT_TYPE) { return updateFragment( returnFiber, @@ -8533,7 +9580,6 @@ function ChildReconciler(shouldTrackSideEffects) { newChild.key ); } - return updateElement( returnFiber, _matchedFiber, @@ -8541,13 +9587,11 @@ function ChildReconciler(shouldTrackSideEffects) { expirationTime ); } - case REACT_PORTAL_TYPE: { var _matchedFiber2 = existingChildren.get( newChild.key === null ? newIdx : newChild.key ) || null; - return updatePortal( returnFiber, _matchedFiber2, @@ -8557,9 +9601,8 @@ function ChildReconciler(shouldTrackSideEffects) { } } - if (isArray$1(newChild) || getIteratorFn(newChild)) { + if (isArray(newChild) || getIteratorFn(newChild)) { var _matchedFiber3 = existingChildren.get(newIdx) || null; - return updateFragment( returnFiber, _matchedFiber3, @@ -8589,7 +9632,6 @@ function ChildReconciler(shouldTrackSideEffects) { if (typeof child !== "object" || child === null) { return knownKeys; } - switch (child.$$typeof) { case REACT_ELEMENT_TYPE: case REACT_PORTAL_TYPE: @@ -8605,13 +9647,12 @@ function ChildReconciler(shouldTrackSideEffects) { knownKeys.add(key); break; } - if (!knownKeys.has(key)) { knownKeys.add(key); break; } - - error( + warning$1( + false, "Encountered two children with the same key, `%s`. " + "Keys should be unique so that components maintain their identity " + "across updates. Non-unique keys may cause children to be " + @@ -8619,11 +9660,11 @@ function ChildReconciler(shouldTrackSideEffects) { "could change in a future version.", key ); - + break; + default: break; } } - return knownKeys; } @@ -8664,7 +9705,6 @@ function ChildReconciler(shouldTrackSideEffects) { var lastPlacedIndex = 0; var newIdx = 0; var nextOldFiber = null; - for (; oldFiber !== null && newIdx < newChildren.length; newIdx++) { if (oldFiber.index > newIdx) { nextOldFiber = oldFiber; @@ -8672,14 +9712,12 @@ function ChildReconciler(shouldTrackSideEffects) { } else { nextOldFiber = oldFiber.sibling; } - var newFiber = updateSlot( returnFiber, oldFiber, newChildren[newIdx], expirationTime ); - if (newFiber === null) { // TODO: This breaks on empty slots like null children. That's // unfortunate because it triggers the slow path all the time. We need @@ -8712,7 +9750,6 @@ function ChildReconciler(shouldTrackSideEffects) { // with the previous one. previousNewFiber.sibling = newFiber; } - previousNewFiber = newFiber; oldFiber = nextOldFiber; } @@ -8762,7 +9799,6 @@ function ChildReconciler(shouldTrackSideEffects) { newChildren[newIdx], expirationTime ); - if (_newFiber2 !== null) { if (shouldTrackSideEffects) { if (_newFiber2.alternate !== null) { @@ -8783,7 +9819,6 @@ function ChildReconciler(shouldTrackSideEffects) { } else { previousNewFiber.sibling = _newFiber2; } - previousNewFiber = _newFiber2; } } @@ -8822,28 +9857,28 @@ function ChildReconciler(shouldTrackSideEffects) { typeof Symbol === "function" && // $FlowFixMe Flow doesn't know about toStringTag newChildrenIterable[Symbol.toStringTag] === "Generator" ) { - if (!didWarnAboutGenerators) { - error( - "Using Generators as children is unsupported and will likely yield " + - "unexpected results because enumerating a generator mutates it. " + - "You may convert it to an array with `Array.from()` or the " + - "`[...spread]` operator before rendering. Keep in mind " + - "you might need to polyfill these features for older browsers." - ); - } - + !didWarnAboutGenerators + ? warning$1( + false, + "Using Generators as children is unsupported and will likely yield " + + "unexpected results because enumerating a generator mutates it. " + + "You may convert it to an array with `Array.from()` or the " + + "`[...spread]` operator before rendering. Keep in mind " + + "you might need to polyfill these features for older browsers." + ) + : void 0; didWarnAboutGenerators = true; } // Warn about using Maps as children if (newChildrenIterable.entries === iteratorFn) { - if (!didWarnAboutMaps) { - error( - "Using Maps as children is unsupported and will likely yield " + - "unexpected results. Convert it to a sequence/iterable of keyed " + - "ReactElements instead." - ); - } - + !didWarnAboutMaps + ? warning$1( + false, + "Using Maps as children is unsupported and will likely yield " + + "unexpected results. Convert it to a sequence/iterable of keyed " + + "ReactElements instead." + ) + : void 0; didWarnAboutMaps = true; } // First, validate keys. // We'll get a different iterator later for the main pass. @@ -8887,14 +9922,12 @@ function ChildReconciler(shouldTrackSideEffects) { } else { nextOldFiber = oldFiber.sibling; } - var newFiber = updateSlot( returnFiber, oldFiber, step.value, expirationTime ); - if (newFiber === null) { // TODO: This breaks on empty slots like null children. That's // unfortunate because it triggers the slow path all the time. We need @@ -8927,7 +9960,6 @@ function ChildReconciler(shouldTrackSideEffects) { // with the previous one. previousNewFiber.sibling = newFiber; } - previousNewFiber = newFiber; oldFiber = nextOldFiber; } @@ -8973,7 +10005,6 @@ function ChildReconciler(shouldTrackSideEffects) { step.value, expirationTime ); - if (_newFiber4 !== null) { if (shouldTrackSideEffects) { if (_newFiber4.alternate !== null) { @@ -8994,7 +10025,6 @@ function ChildReconciler(shouldTrackSideEffects) { } else { previousNewFiber.sibling = _newFiber4; } - previousNewFiber = _newFiber4; } } @@ -9022,7 +10052,7 @@ function ChildReconciler(shouldTrackSideEffects) { // We already have an existing node so let's just update it and delete // the rest. deleteRemainingChildren(returnFiber, currentFirstChild.sibling); - var existing = useFiber(currentFirstChild, textContent); + var existing = useFiber(currentFirstChild, textContent, expirationTime); existing.return = returnFiber; return existing; } // The existing first child is not a text node so we need to create one @@ -9046,64 +10076,38 @@ function ChildReconciler(shouldTrackSideEffects) { ) { var key = element.key; var child = currentFirstChild; - while (child !== null) { // 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; - - { - existing._debugSource = element._source; - existing._debugOwner = element._owner; - } - - return existing; - } - - break; - } - - case Block: - - // We intentionally fallthrough here if enableBlocksAPI is not on. - // eslint-disable-next-lined no-fallthrough - - default: { - if ( - child.elementType === element.type || // Keep this check inline so it only runs on the false path: + if ( + child.tag === Fragment + ? element.type === REACT_FRAGMENT_TYPE + : child.elementType === element.type || // Keep this check inline so it only runs on the false path: isCompatibleFamilyForHotReloading(child, element) - ) { - deleteRemainingChildren(returnFiber, child.sibling); - - var _existing3 = useFiber(child, element.props); - - _existing3.ref = coerceRef(returnFiber, child, element); - _existing3.return = returnFiber; - - { - _existing3._debugSource = element._source; - _existing3._debugOwner = element._owner; - } - - return _existing3; - } - - break; + ) { + deleteRemainingChildren(returnFiber, child.sibling); + var existing = useFiber( + child, + element.type === REACT_FRAGMENT_TYPE + ? element.props.children + : element.props, + expirationTime + ); + existing.ref = coerceRef(returnFiber, child, element); + existing.return = returnFiber; + { + existing._debugSource = element._source; + existing._debugOwner = element._owner; } - } // Didn't match. - - deleteRemainingChildren(returnFiber, child); - break; + return existing; + } else { + deleteRemainingChildren(returnFiber, child); + break; + } } else { deleteChild(returnFiber, child); } - child = child.sibling; } @@ -9122,7 +10126,6 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime ); - _created4.ref = coerceRef(returnFiber, currentFirstChild, element); _created4.return = returnFiber; return _created4; @@ -9137,7 +10140,6 @@ function ChildReconciler(shouldTrackSideEffects) { ) { var key = portal.key; var child = currentFirstChild; - while (child !== null) { // TODO: If key === null and child.key === null, then this only applies to // the first item in the list. @@ -9148,7 +10150,7 @@ function ChildReconciler(shouldTrackSideEffects) { child.stateNode.implementation === portal.implementation ) { deleteRemainingChildren(returnFiber, child.sibling); - var existing = useFiber(child, portal.children || []); + var existing = useFiber(child, portal.children || [], expirationTime); existing.return = returnFiber; return existing; } else { @@ -9158,7 +10160,6 @@ function ChildReconciler(shouldTrackSideEffects) { } else { deleteChild(returnFiber, child); } - child = child.sibling; } @@ -9209,7 +10210,6 @@ function ChildReconciler(shouldTrackSideEffects) { expirationTime ) ); - case REACT_PORTAL_TYPE: return placeSingleChild( reconcileSinglePortal( @@ -9233,7 +10233,7 @@ function ChildReconciler(shouldTrackSideEffects) { ); } - if (isArray$1(newChild)) { + if (isArray(newChild)) { return reconcileChildrenArray( returnFiber, currentFirstChild, @@ -9260,7 +10260,6 @@ function ChildReconciler(shouldTrackSideEffects) { warnOnFunctionType(); } } - if (typeof newChild === "undefined" && !isUnkeyedTopLevelFragment) { // If the new child is undefined, and the return fiber is a composite // component, throw an error. If Fiber return types are disabled, @@ -9269,7 +10268,6 @@ function ChildReconciler(shouldTrackSideEffects) { case ClassComponent: { { var instance = returnFiber.stateNode; - if (instance.render._isMockFunction) { // We allow auto-mocks to proceed as if they're returning null. break; @@ -9301,8 +10299,8 @@ function ChildReconciler(shouldTrackSideEffects) { var reconcileChildFibers = ChildReconciler(true); var mountChildFibers = ChildReconciler(false); -function cloneChildFibers(current, workInProgress) { - if (!(current === null || workInProgress.child === current.child)) { +function cloneChildFibers(current$$1, workInProgress) { + if (!(current$$1 === null || workInProgress.child === current$$1.child)) { throw Error("Resuming work not yet implemented."); } @@ -9311,7 +10309,11 @@ function cloneChildFibers(current, workInProgress) { } var currentChild = workInProgress.child; - var newChild = createWorkInProgress(currentChild, currentChild.pendingProps); + var newChild = createWorkInProgress( + currentChild, + currentChild.pendingProps, + currentChild.expirationTime + ); workInProgress.child = newChild; newChild.return = workInProgress; @@ -9319,7 +10321,8 @@ function cloneChildFibers(current, workInProgress) { currentChild = currentChild.sibling; newChild = newChild.sibling = createWorkInProgress( currentChild, - currentChild.pendingProps + currentChild.pendingProps, + currentChild.expirationTime ); newChild.return = workInProgress; } @@ -9369,7 +10372,7 @@ function pushHostContainer(fiber, nextRootInstance) { // So we push an empty value first. This lets us safely unwind on errors. push(contextStackCursor$1, NO_CONTEXT, fiber); - var nextRootContext = getRootHostContext(); // Now that we know this function doesn't throw, replace it. + var nextRootContext = getRootHostContext(nextRootInstance); // Now that we know this function doesn't throw, replace it. pop(contextStackCursor$1, fiber); push(contextStackCursor$1, nextRootContext, fiber); @@ -9389,7 +10392,7 @@ function getHostContext() { function pushHostContext(fiber) { var rootInstance = requiredContext(rootInstanceStackCursor.current); var context = requiredContext(contextStackCursor$1.current); - var nextContext = getChildHostContext(context, fiber.type); // Don't push this Fiber's context unless it's unique. + var nextContext = getChildHostContext(context, fiber.type, rootInstance); // Don't push this Fiber's context unless it's unique. if (context === nextContext) { return; @@ -9492,8 +10495,8 @@ function findFirstSuspended(row) { if ( dehydrated === null || - isSuspenseInstancePending() || - isSuspenseInstanceFallback() + isSuspenseInstancePending(dehydrated) || + isSuspenseInstanceFallback(dehydrated) ) { return node; } @@ -9504,7 +10507,6 @@ function findFirstSuspended(row) { node.memoizedProps.revealOrder !== undefined ) { var didSuspend = (node.effectTag & DidCapture) !== NoEffect; - if (didSuspend) { return node; } @@ -9533,7 +10535,191 @@ function findFirstSuspended(row) { return null; } -function createDeprecatedResponderListener(responder, props) { +var emptyObject$1 = {}; +var isArray$2 = Array.isArray; +function createResponderInstance( + responder, + responderProps, + responderState, + fiber +) { + return { + fiber: fiber, + props: responderProps, + responder: responder, + rootEventTypes: null, + state: responderState + }; +} + +function mountEventResponder$1( + responder, + responderProps, + fiber, + respondersMap, + rootContainerInstance +) { + var responderState = emptyObject$1; + var getInitialState = responder.getInitialState; + + if (getInitialState !== null) { + responderState = getInitialState(responderProps); + } + + var responderInstance = createResponderInstance( + responder, + responderProps, + responderState, + fiber + ); + + if (!rootContainerInstance) { + var node = fiber; + + while (node !== null) { + var tag = node.tag; + + if (tag === HostComponent) { + rootContainerInstance = node.stateNode; + break; + } else if (tag === HostRoot) { + rootContainerInstance = node.stateNode.containerInfo; + break; + } + + node = node.return; + } + } + + mountResponderInstance( + responder, + responderInstance, + responderProps, + responderState, + rootContainerInstance + ); + respondersMap.set(responder, responderInstance); +} + +function updateEventListener( + listener, + fiber, + visistedResponders, + respondersMap, + rootContainerInstance +) { + var responder; + var props; + + if (listener) { + responder = listener.responder; + props = listener.props; + } + + if (!(responder && responder.$$typeof === REACT_RESPONDER_TYPE)) { + throw Error( + "An invalid value was used as an event listener. Expect one or many event listeners created via React.unstable_useResponder()." + ); + } + + var listenerProps = props; + + if (visistedResponders.has(responder)) { + // show warning + { + warning$1( + false, + 'Duplicate event responder "%s" found in event listeners. ' + + "Event listeners passed to elements cannot use the same event responder more than once.", + responder.displayName + ); + } + + return; + } + + visistedResponders.add(responder); + var responderInstance = respondersMap.get(responder); + + if (responderInstance === undefined) { + // Mount (happens in either complete or commit phase) + mountEventResponder$1( + responder, + listenerProps, + fiber, + respondersMap, + rootContainerInstance + ); + } else { + // Update (happens during commit phase only) + responderInstance.props = listenerProps; + responderInstance.fiber = fiber; + } +} + +function updateEventListeners(listeners, fiber, rootContainerInstance) { + var visistedResponders = new Set(); + var dependencies = fiber.dependencies; + + if (listeners != null) { + if (dependencies === null) { + dependencies = fiber.dependencies = { + expirationTime: NoWork, + firstContext: null, + responders: new Map() + }; + } + + var respondersMap = dependencies.responders; + + if (respondersMap === null) { + respondersMap = new Map(); + } + + if (isArray$2(listeners)) { + for (var i = 0, length = listeners.length; i < length; i++) { + var listener = listeners[i]; + updateEventListener( + listener, + fiber, + visistedResponders, + respondersMap, + rootContainerInstance + ); + } + } else { + updateEventListener( + listeners, + fiber, + visistedResponders, + respondersMap, + rootContainerInstance + ); + } + } + + if (dependencies !== null) { + var _respondersMap = dependencies.responders; + + if (_respondersMap !== null) { + // Unmount + var mountedResponders = Array.from(_respondersMap.keys()); + + for (var _i = 0, _length = mountedResponders.length; _i < _length; _i++) { + var mountedResponder = mountedResponders[_i]; + + if (!visistedResponders.has(mountedResponder)) { + var responderInstance = _respondersMap.get(mountedResponder); + + unmountResponderInstance(responderInstance); + + _respondersMap.delete(mountedResponder); + } + } + } + } +} +function createResponderListener(responder, props) { var eventResponderListener = { responder: responder, props: props @@ -9546,19 +10732,33 @@ function createDeprecatedResponderListener(responder, props) { return eventResponderListener; } -var HasEffect = - /* */ - 1; // Represents the phase in which the effect (not the clean-up) fires. - -var Layout = - /* */ +var NoEffect$1 = + /* */ + 0; +var UnmountSnapshot = + /* */ 2; -var Passive$1 = - /* */ +var UnmountMutation = + /* */ 4; +var MountMutation = + /* */ + 8; +var UnmountLayout = + /* */ + 16; +var MountLayout = + /* */ + 32; +var MountPassive = + /* */ + 64; +var UnmountPassive = + /* */ + 128; -var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher, - ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig; +var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher; +var ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig; var didWarnAboutMismatchedHooksForComponent; { @@ -9566,7 +10766,7 @@ var didWarnAboutMismatchedHooksForComponent; } // These are set right before calling the component. -var renderExpirationTime = NoWork; // The work-in-progress fiber. I've named it differently to distinguish it from +var renderExpirationTime$1 = NoWork; // The work-in-progress fiber. I've named it differently to distinguish it from // the work-in-progress hook. var currentlyRenderingFiber$1 = null; // Hooks are stored as a linked list on the fiber's memoizedState field. The @@ -9575,12 +10775,26 @@ var currentlyRenderingFiber$1 = null; // Hooks are stored as a linked list on th // work-in-progress fiber. var currentHook = null; -var workInProgressHook = null; // Whether an update was scheduled at any point during the render phase. This -// does not get reset if we do another render pass; only when we're completely -// finished evaluating this component. This is an optimization so we know -// whether we need to clear render phase updates after a throw. - -var didScheduleRenderPhaseUpdate = false; +var nextCurrentHook = null; +var firstWorkInProgressHook = null; +var workInProgressHook = null; +var nextWorkInProgressHook = null; +var remainingExpirationTime = NoWork; +var componentUpdateQueue = null; +var sideEffectTag = 0; // Updates scheduled during render will trigger an immediate re-render at the +// end of the current pass. We can't store these updates on the normal queue, +// because if the work is aborted, they should be discarded. Because this is +// a relatively rare case, we also don't want to add an additional field to +// either the hook or queue object types. So we store them in a lazily create +// map of queue -> render-phase updates, which are discarded once the component +// completes without re-rendering. +// Whether an update was scheduled during the currently executing render pass. + +var didScheduleRenderPhaseUpdate = false; // Lazily created map of render-phase updates + +var renderPhaseUpdates = null; // Counter to prevent infinite loops. + +var numberOfReRenders = 0; var RE_RENDER_LIMIT = 25; // In DEV, this is the name of the currently executing primitive hook var currentHookNameInDev = null; // In DEV, this list ensures that hooks are called in the same order between renders. @@ -9612,7 +10826,6 @@ function updateHookTypesDev() { if (hookTypesDev !== null) { hookTypesUpdateIndexDev++; - if (hookTypesDev[hookTypesUpdateIndexDev] !== hookName) { warnOnHookMismatchInDev(hookName); } @@ -9625,7 +10838,8 @@ function checkDepsAreArrayDev(deps) { if (deps !== undefined && deps !== null && !Array.isArray(deps)) { // Verify deps, but only on mount to avoid extra checks. // It's unlikely their type would change as usually you define them inline. - error( + warning$1( + false, "%s received a final argument that is not an array (instead, received `%s`). When " + "specified, the final argument must be an array.", currentHookNameInDev, @@ -9638,7 +10852,6 @@ function checkDepsAreArrayDev(deps) { function warnOnHookMismatchInDev(currentHookName) { { var componentName = getComponentName(currentlyRenderingFiber$1.type); - if (!didWarnAboutMismatchedHooksForComponent.has(componentName)) { didWarnAboutMismatchedHooksForComponent.add(componentName); @@ -9661,7 +10874,8 @@ function warnOnHookMismatchInDev(currentHookName) { table += row; } - error( + warning$1( + false, "React has detected a change in the order of Hooks called by %s. " + "This will lead to bugs and errors if not fixed. " + "For more information, read the Rules of Hooks: https://fb.me/rules-of-hooks\n\n" + @@ -9695,14 +10909,14 @@ function areHookInputsEqual(nextDeps, prevDeps) { if (prevDeps === null) { { - error( + warning$1( + false, "%s received a final argument during this render, but not during " + "the previous render. Even though the final argument is optional, " + "its type cannot change between renders.", currentHookNameInDev ); } - return false; } @@ -9710,7 +10924,8 @@ function areHookInputsEqual(nextDeps, prevDeps) { // Don't bother comparing lengths in prod because these arrays should be // passed inline. if (nextDeps.length !== prevDeps.length) { - error( + warning$1( + false, "The final argument passed to %s changed size between renders. The " + "order and size of this array must remain constant.\n\n" + "Previous: %s\n" + @@ -9723,7 +10938,7 @@ function areHookInputsEqual(nextDeps, prevDeps) { } for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) { - if (objectIs(nextDeps[i], prevDeps[i])) { + if (is$1(nextDeps[i], prevDeps[i])) { continue; } @@ -9738,11 +10953,12 @@ function renderWithHooks( workInProgress, Component, props, - secondArg, + refOrContext, nextRenderExpirationTime ) { - renderExpirationTime = nextRenderExpirationTime; + renderExpirationTime$1 = nextRenderExpirationTime; currentlyRenderingFiber$1 = workInProgress; + nextCurrentHook = current !== null ? current.memoizedState : null; { hookTypesDev = current !== null ? current._debugHookTypes : null; @@ -9750,87 +10966,89 @@ function renderWithHooks( ignorePreviousDependencies = current !== null && current.type !== workInProgress.type; - } - - workInProgress.memoizedState = null; - workInProgress.updateQueue = null; - workInProgress.expirationTime = NoWork; // The following should have already been reset + } // The following should have already been reset // currentHook = null; // workInProgressHook = null; + // remainingExpirationTime = NoWork; + // componentUpdateQueue = null; // didScheduleRenderPhaseUpdate = false; + // renderPhaseUpdates = null; + // numberOfReRenders = 0; + // sideEffectTag = 0; // TODO Warn if no hooks are used at all during mount, then some are used during update. - // Currently we will identify the update render as a mount because memoizedState === null. + // Currently we will identify the update render as a mount because nextCurrentHook === null. // This is tricky because it's valid for certain types of components (e.g. React.lazy) - // Using memoizedState to differentiate between mount/update only works if at least one stateful hook is used. + // Using nextCurrentHook to differentiate between mount/update only works if at least one stateful hook is used. // Non-stateful hooks (e.g. context) don't get added to memoizedState, - // so memoizedState would be null during updates and mounts. + // so nextCurrentHook would be null during updates and mounts. { - if (current !== null && current.memoizedState !== null) { - ReactCurrentDispatcher.current = HooksDispatcherOnUpdateInDEV; + if (nextCurrentHook !== null) { + ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV; } else if (hookTypesDev !== null) { // This dispatcher handles an edge case where a component is updating, // but no stateful hooks have been used. // We want to match the production code behavior (which will use HooksDispatcherOnMount), // but with the extra DEV validation to ensure hooks ordering hasn't changed. // This dispatcher does that. - ReactCurrentDispatcher.current = HooksDispatcherOnMountWithHookTypesInDEV; + ReactCurrentDispatcher$1.current = HooksDispatcherOnMountWithHookTypesInDEV; } else { - ReactCurrentDispatcher.current = HooksDispatcherOnMountInDEV; + ReactCurrentDispatcher$1.current = HooksDispatcherOnMountInDEV; } } - var children = Component(props, secondArg); // Check if there was a render phase update - - if (workInProgress.expirationTime === renderExpirationTime) { - // Keep rendering in a loop for as long as render phase updates continue to - // be scheduled. Use a counter to prevent infinite loops. - var numberOfReRenders = 0; + var children = Component(props, refOrContext); + if (didScheduleRenderPhaseUpdate) { do { - workInProgress.expirationTime = NoWork; - - if (!(numberOfReRenders < RE_RENDER_LIMIT)) { - throw Error( - "Too many re-renders. React limits the number of renders to prevent an infinite loop." - ); - } - + didScheduleRenderPhaseUpdate = false; numberOfReRenders += 1; - { // Even when hot reloading, allow dependencies to stabilize // after first render to prevent infinite render phase updates. ignorePreviousDependencies = false; } // Start over from the beginning of the list + nextCurrentHook = current !== null ? current.memoizedState : null; + nextWorkInProgressHook = firstWorkInProgressHook; currentHook = null; workInProgressHook = null; - workInProgress.updateQueue = null; + componentUpdateQueue = null; { // Also validate hook order for cascading updates. hookTypesUpdateIndexDev = -1; } - ReactCurrentDispatcher.current = HooksDispatcherOnRerenderInDEV; - children = Component(props, secondArg); - } while (workInProgress.expirationTime === renderExpirationTime); + ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV; + children = Component(props, refOrContext); + } while (didScheduleRenderPhaseUpdate); + + renderPhaseUpdates = null; + numberOfReRenders = 0; } // We can assume the previous dispatcher is always this one, since we set it // at the beginning of the render phase and there's no re-entrancy. - ReactCurrentDispatcher.current = ContextOnlyDispatcher; + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; + var renderedWork = currentlyRenderingFiber$1; + renderedWork.memoizedState = firstWorkInProgressHook; + renderedWork.expirationTime = remainingExpirationTime; + renderedWork.updateQueue = componentUpdateQueue; + renderedWork.effectTag |= sideEffectTag; { - workInProgress._debugHookTypes = hookTypesDev; + renderedWork._debugHookTypes = hookTypesDev; } // This check uses currentHook so that it works the same in DEV and prod bundles. // hookTypesDev could catch more cases (e.g. context) but only in DEV bundles. var didRenderTooFewHooks = currentHook !== null && currentHook.next !== null; - renderExpirationTime = NoWork; + renderExpirationTime$1 = NoWork; currentlyRenderingFiber$1 = null; currentHook = null; + nextCurrentHook = null; + firstWorkInProgressHook = null; workInProgressHook = null; + nextWorkInProgressHook = null; { currentHookNameInDev = null; @@ -9838,7 +11056,12 @@ function renderWithHooks( hookTypesUpdateIndexDev = -1; } - didScheduleRenderPhaseUpdate = false; + remainingExpirationTime = NoWork; + componentUpdateQueue = null; + sideEffectTag = 0; // These were reset above + // didScheduleRenderPhaseUpdate = false; + // renderPhaseUpdates = null; + // numberOfReRenders = 0; if (!!didRenderTooFewHooks) { throw Error( @@ -9856,37 +11079,20 @@ function bailoutHooks(current, workInProgress, expirationTime) { current.expirationTime = NoWork; } } -function resetHooksAfterThrow() { +function resetHooks() { // We can assume the previous dispatcher is always this one, since we set it // at the beginning of the render phase and there's no re-entrancy. - ReactCurrentDispatcher.current = ContextOnlyDispatcher; - - if (didScheduleRenderPhaseUpdate) { - // There were render phase updates. These are only valid for this render - // phase, which we are now aborting. Remove the updates from the queues so - // they do not persist to the next render. Do not remove updates from hooks - // that weren't processed. - // - // Only reset the updates from the queue if it has a clone. If it does - // not have a clone, that means it wasn't processed, and the updates were - // scheduled before we entered the render phase. - var hook = currentlyRenderingFiber$1.memoizedState; - - while (hook !== null) { - var queue = hook.queue; + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; // This is used to reset the state of this module when a component throws. + // It's also called inside mountIndeterminateComponent if we determine the + // component is a module-style component. - if (queue !== null) { - queue.pending = null; - } - - hook = hook.next; - } - } - - renderExpirationTime = NoWork; + renderExpirationTime$1 = NoWork; currentlyRenderingFiber$1 = null; currentHook = null; + nextCurrentHook = null; + firstWorkInProgressHook = null; workInProgressHook = null; + nextWorkInProgressHook = null; { hookTypesDev = null; @@ -9894,26 +11100,30 @@ function resetHooksAfterThrow() { currentHookNameInDev = null; } + remainingExpirationTime = NoWork; + componentUpdateQueue = null; + sideEffectTag = 0; didScheduleRenderPhaseUpdate = false; + renderPhaseUpdates = null; + numberOfReRenders = 0; } function mountWorkInProgressHook() { var hook = { memoizedState: null, baseState: null, - baseQueue: null, queue: null, + baseUpdate: null, next: null }; if (workInProgressHook === null) { // This is the first hook in the list - currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook; + firstWorkInProgressHook = workInProgressHook = hook; } else { // Append to the end of the list workInProgressHook = workInProgressHook.next = hook; } - return workInProgressHook; } @@ -9923,33 +11133,12 @@ function updateWorkInProgressHook() { // clone, or a work-in-progress hook from a previous render pass that we can // use as a base. When we reach the end of the base list, we must switch to // the dispatcher used for mounts. - var nextCurrentHook; - - if (currentHook === null) { - var current = currentlyRenderingFiber$1.alternate; - - if (current !== null) { - nextCurrentHook = current.memoizedState; - } else { - nextCurrentHook = null; - } - } else { - nextCurrentHook = currentHook.next; - } - - var nextWorkInProgressHook; - - if (workInProgressHook === null) { - nextWorkInProgressHook = currentlyRenderingFiber$1.memoizedState; - } else { - nextWorkInProgressHook = workInProgressHook.next; - } - if (nextWorkInProgressHook !== null) { // There's already a work-in-progress. Reuse it. workInProgressHook = nextWorkInProgressHook; nextWorkInProgressHook = workInProgressHook.next; currentHook = nextCurrentHook; + nextCurrentHook = currentHook !== null ? currentHook.next : null; } else { // Clone from the current hook. if (!(nextCurrentHook !== null)) { @@ -9960,18 +11149,20 @@ function updateWorkInProgressHook() { var newHook = { memoizedState: currentHook.memoizedState, baseState: currentHook.baseState, - baseQueue: currentHook.baseQueue, queue: currentHook.queue, + baseUpdate: currentHook.baseUpdate, next: null }; if (workInProgressHook === null) { // This is the first hook in the list. - currentlyRenderingFiber$1.memoizedState = workInProgressHook = newHook; + workInProgressHook = firstWorkInProgressHook = newHook; } else { // Append to the end of the list. workInProgressHook = workInProgressHook.next = newHook; } + + nextCurrentHook = currentHook.next; } return workInProgressHook; @@ -9984,7 +11175,6 @@ function createFunctionComponentUpdateQueue() { } function basicStateReducer(state, action) { - // $FlowFixMe: Flow doesn't like mixed types return typeof action === "function" ? action(state) : action; } @@ -9997,16 +11187,15 @@ function mountReducer(reducer, initialArg, init) { } else { initialState = initialArg; } - hook.memoizedState = hook.baseState = initialState; var queue = (hook.queue = { - pending: null, + last: null, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialState }); var dispatch = (queue.dispatch = dispatchAction.bind( - null, + null, // Flow doesn't know this is non-null, but we do. currentlyRenderingFiber$1, queue )); @@ -10024,191 +11213,157 @@ function updateReducer(reducer, initialArg, init) { } queue.lastRenderedReducer = reducer; - var current = currentHook; // The last rebase update that is NOT part of the base state. - var baseQueue = current.baseQueue; // The last pending update that hasn't been processed yet. + if (numberOfReRenders > 0) { + // This is a re-render. Apply the new render phase updates to the previous + // work-in-progress hook. + var _dispatch = queue.dispatch; + + if (renderPhaseUpdates !== null) { + // Render phase updates are stored in a map of queue -> linked list + var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue); + + if (firstRenderPhaseUpdate !== undefined) { + renderPhaseUpdates.delete(queue); + var newState = hook.memoizedState; + var update = firstRenderPhaseUpdate; + do { + // Process this render phase update. We don't have to check the + // priority because it will always be the same as the current + // render's. + var action = update.action; + newState = reducer(newState, action); + update = update.next; + } while (update !== null); // Mark that the fiber performed work, but only if the new state is + // different from the current state. + + if (!is$1(newState, hook.memoizedState)) { + markWorkInProgressReceivedUpdate(); + } - var pendingQueue = queue.pending; + hook.memoizedState = newState; // Don't persist the state accumulated from the render phase updates to + // the base state unless the queue is empty. + // TODO: Not sure if this is the desired semantics, but it's what we + // do for gDSFP. I can't remember why. - if (pendingQueue !== null) { - // We have new updates that haven't been processed yet. - // We'll add them to the base queue. - if (baseQueue !== null) { - // Merge the pending queue and the base queue. - var baseFirst = baseQueue.next; - var pendingFirst = pendingQueue.next; - baseQueue.next = pendingFirst; - pendingQueue.next = baseFirst; + if (hook.baseUpdate === queue.last) { + hook.baseState = newState; + } + + queue.lastRenderedState = newState; + return [newState, _dispatch]; + } } - current.baseQueue = baseQueue = pendingQueue; - queue.pending = null; - } + return [hook.memoizedState, _dispatch]; + } // The last update in the entire queue - if (baseQueue !== null) { - // We have a queue to process. - var first = baseQueue.next; - var newState = current.baseState; + var last = queue.last; // The last update that is part of the base state. + + var baseUpdate = hook.baseUpdate; + var baseState = hook.baseState; // Find the first unprocessed update. + + var first; + + if (baseUpdate !== null) { + if (last !== null) { + // For the first update, the queue is a circular linked list where + // `queue.last.next = queue.first`. Once the first update commits, and + // the `baseUpdate` is no longer empty, we can unravel the list. + last.next = null; + } + first = baseUpdate.next; + } else { + first = last !== null ? last.next : null; + } + if (first !== null) { + var _newState = baseState; var newBaseState = null; - var newBaseQueueFirst = null; - var newBaseQueueLast = null; - var update = first; + var newBaseUpdate = null; + var prevUpdate = baseUpdate; + var _update = first; + var didSkip = false; do { - var updateExpirationTime = update.expirationTime; + var updateExpirationTime = _update.expirationTime; - if (updateExpirationTime < renderExpirationTime) { + if (updateExpirationTime < renderExpirationTime$1) { // 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 = { - expirationTime: update.expirationTime, - suspenseConfig: update.suspenseConfig, - action: update.action, - eagerReducer: update.eagerReducer, - eagerState: update.eagerState, - next: null - }; - - if (newBaseQueueLast === null) { - newBaseQueueFirst = newBaseQueueLast = clone; - newBaseState = newState; - } else { - newBaseQueueLast = newBaseQueueLast.next = clone; + if (!didSkip) { + didSkip = true; + newBaseUpdate = prevUpdate; + newBaseState = _newState; } // Update the remaining priority in the queue. - if (updateExpirationTime > currentlyRenderingFiber$1.expirationTime) { - currentlyRenderingFiber$1.expirationTime = updateExpirationTime; - markUnprocessedUpdateTime(updateExpirationTime); + if (updateExpirationTime > remainingExpirationTime) { + remainingExpirationTime = updateExpirationTime; + markUnprocessedUpdateTime(remainingExpirationTime); } } else { // This update does have sufficient priority. - if (newBaseQueueLast !== null) { - var _clone = { - expirationTime: Sync, - // This update is going to be committed so we never want uncommit it. - suspenseConfig: update.suspenseConfig, - action: update.action, - eagerReducer: update.eagerReducer, - eagerState: update.eagerState, - next: null - }; - newBaseQueueLast = newBaseQueueLast.next = _clone; - } // Mark the event time of this update as relevant to this render pass. + // Mark the event time of this update as relevant to this render pass. // TODO: This should ideally use the true event time of this update rather than // its priority which is a derived and not reverseable value. // TODO: We should skip this update if it was already committed but currently // we have no way of detecting the difference between a committed and suspended // update here. - markRenderEventTimeAndConfig( updateExpirationTime, - update.suspenseConfig + _update.suspenseConfig ); // Process this update. - if (update.eagerReducer === reducer) { + if (_update.eagerReducer === reducer) { // If this update was processed eagerly, and its reducer matches the // current reducer, we can use the eagerly computed state. - newState = update.eagerState; + _newState = _update.eagerState; } else { - var action = update.action; - newState = reducer(newState, action); + var _action = _update.action; + _newState = reducer(_newState, _action); } } - update = update.next; - } while (update !== null && update !== first); + prevUpdate = _update; + _update = _update.next; + } while (_update !== null && _update !== first); - if (newBaseQueueLast === null) { - newBaseState = newState; - } else { - newBaseQueueLast.next = newBaseQueueFirst; + if (!didSkip) { + newBaseUpdate = prevUpdate; + newBaseState = _newState; } // Mark that the fiber performed work, but only if the new state is // different from the current state. - if (!objectIs(newState, hook.memoizedState)) { + if (!is$1(_newState, hook.memoizedState)) { markWorkInProgressReceivedUpdate(); } - hook.memoizedState = newState; + hook.memoizedState = _newState; + hook.baseUpdate = newBaseUpdate; hook.baseState = newBaseState; - hook.baseQueue = newBaseQueueLast; - queue.lastRenderedState = newState; + queue.lastRenderedState = _newState; } var dispatch = queue.dispatch; return [hook.memoizedState, dispatch]; } -function rerenderReducer(reducer, initialArg, init) { - var hook = updateWorkInProgressHook(); - var queue = hook.queue; +function mountState(initialState) { + var hook = mountWorkInProgressHook(); - if (!(queue !== null)) { - throw Error( - "Should have a queue. This is likely a bug in React. Please file an issue." - ); - } - - queue.lastRenderedReducer = reducer; // This is a re-render. Apply the new render phase updates to the previous - // work-in-progress hook. - - var dispatch = queue.dispatch; - var lastRenderPhaseUpdate = queue.pending; - var newState = hook.memoizedState; - - if (lastRenderPhaseUpdate !== null) { - // The queue doesn't persist past this render pass. - queue.pending = null; - var firstRenderPhaseUpdate = lastRenderPhaseUpdate.next; - var update = firstRenderPhaseUpdate; - - do { - // Process this render phase update. We don't have to check the - // priority because it will always be the same as the current - // render's. - var action = update.action; - newState = reducer(newState, action); - update = update.next; - } while (update !== firstRenderPhaseUpdate); // Mark that the fiber performed work, but only if the new state is - // different from the current state. - - if (!objectIs(newState, hook.memoizedState)) { - markWorkInProgressReceivedUpdate(); - } - - hook.memoizedState = newState; // Don't persist the state accumulated from the render phase updates to - // the base state unless the queue is empty. - // TODO: Not sure if this is the desired semantics, but it's what we - // do for gDSFP. I can't remember why. - - if (hook.baseQueue === null) { - hook.baseState = newState; - } - - queue.lastRenderedState = newState; - } - - return [newState, dispatch]; -} - -function mountState(initialState) { - var hook = mountWorkInProgressHook(); - - if (typeof initialState === "function") { - // $FlowFixMe: Flow doesn't like mixed types - initialState = initialState(); + if (typeof initialState === "function") { + initialState = initialState(); } hook.memoizedState = hook.baseState = initialState; var queue = (hook.queue = { - pending: null, + last: null, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState }); var dispatch = (queue.dispatch = dispatchAction.bind( - null, + null, // Flow doesn't know this is non-null, but we do. currentlyRenderingFiber$1, queue )); @@ -10216,11 +11371,7 @@ function mountState(initialState) { } function updateState(initialState) { - return updateReducer(basicStateReducer); -} - -function rerenderState(initialState) { - return rerenderReducer(basicStateReducer); + return updateReducer(basicStateReducer, initialState); } function pushEffect(tag, create, destroy, deps) { @@ -10232,11 +11383,8 @@ function pushEffect(tag, create, destroy, deps) { // Circular next: null }; - var componentUpdateQueue = currentlyRenderingFiber$1.updateQueue; - if (componentUpdateQueue === null) { componentUpdateQueue = createFunctionComponentUpdateQueue(); - currentlyRenderingFiber$1.updateQueue = componentUpdateQueue; componentUpdateQueue.lastEffect = effect.next = effect; } else { var lastEffect = componentUpdateQueue.lastEffect; @@ -10250,7 +11398,6 @@ function pushEffect(tag, create, destroy, deps) { componentUpdateQueue.lastEffect = effect; } } - return effect; } @@ -10276,13 +11423,8 @@ function updateRef(initialValue) { function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var hook = mountWorkInProgressHook(); var nextDeps = deps === undefined ? null : deps; - currentlyRenderingFiber$1.effectTag |= fiberEffectTag; - hook.memoizedState = pushEffect( - HasEffect | hookEffectTag, - create, - undefined, - nextDeps - ); + sideEffectTag |= fiberEffectTag; + hook.memoizedState = pushEffect(hookEffectTag, create, undefined, nextDeps); } function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { @@ -10298,35 +11440,52 @@ function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var prevDeps = prevEffect.deps; if (areHookInputsEqual(nextDeps, prevDeps)) { - pushEffect(hookEffectTag, create, destroy, nextDeps); + pushEffect(NoEffect$1, create, destroy, nextDeps); return; } } } - currentlyRenderingFiber$1.effectTag |= fiberEffectTag; - hook.memoizedState = pushEffect( - HasEffect | hookEffectTag, - create, - destroy, - nextDeps - ); + sideEffectTag |= fiberEffectTag; + hook.memoizedState = pushEffect(hookEffectTag, create, destroy, nextDeps); } function mountEffect(create, deps) { - return mountEffectImpl(Update | Passive, Passive$1, create, deps); + { + // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests + if ("undefined" !== typeof jest) { + warnIfNotCurrentlyActingEffectsInDEV(currentlyRenderingFiber$1); + } + } + return mountEffectImpl( + Update | Passive, + UnmountPassive | MountPassive, + create, + deps + ); } function updateEffect(create, deps) { - return updateEffectImpl(Update | Passive, Passive$1, create, deps); + { + // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests + if ("undefined" !== typeof jest) { + warnIfNotCurrentlyActingEffectsInDEV(currentlyRenderingFiber$1); + } + } + return updateEffectImpl( + Update | Passive, + UnmountPassive | MountPassive, + create, + deps + ); } function mountLayoutEffect(create, deps) { - return mountEffectImpl(Update, Layout, create, deps); + return mountEffectImpl(Update, UnmountMutation | MountLayout, create, deps); } function updateLayoutEffect(create, deps) { - return updateEffectImpl(Update, Layout, create, deps); + return updateEffectImpl(Update, UnmountMutation | MountLayout, create, deps); } function imperativeHandleEffect(create, ref) { @@ -10341,15 +11500,15 @@ function imperativeHandleEffect(create, ref) { }; } else if (ref !== null && ref !== undefined) { var refObject = ref; - { - if (!refObject.hasOwnProperty("current")) { - error( - "Expected useImperativeHandle() first argument to either be a " + - "ref callback or React.createRef() object. Instead received: %s.", - "an object with keys {" + Object.keys(refObject).join(", ") + "}" - ); - } + !refObject.hasOwnProperty("current") + ? warning$1( + false, + "Expected useImperativeHandle() first argument to either be a " + + "ref callback or React.createRef() object. Instead received: %s.", + "an object with keys {" + Object.keys(refObject).join(", ") + "}" + ) + : void 0; } var _inst2 = create(); @@ -10363,20 +11522,21 @@ function imperativeHandleEffect(create, ref) { function mountImperativeHandle(ref, create, deps) { { - if (typeof create !== "function") { - error( - "Expected useImperativeHandle() second argument to be a function " + - "that creates a handle. Instead received: %s.", - create !== null ? typeof create : "null" - ); - } + !(typeof create === "function") + ? warning$1( + false, + "Expected useImperativeHandle() second argument to be a function " + + "that creates a handle. Instead received: %s.", + create !== null ? typeof create : "null" + ) + : void 0; } // TODO: If deps are provided, should we skip comparing the ref itself? var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null; return mountEffectImpl( Update, - Layout, + UnmountMutation | MountLayout, imperativeHandleEffect.bind(null, create, ref), effectDeps ); @@ -10384,20 +11544,21 @@ function mountImperativeHandle(ref, create, deps) { function updateImperativeHandle(ref, create, deps) { { - if (typeof create !== "function") { - error( - "Expected useImperativeHandle() second argument to be a function " + - "that creates a handle. Instead received: %s.", - create !== null ? typeof create : "null" - ); - } + !(typeof create === "function") + ? warning$1( + false, + "Expected useImperativeHandle() second argument to be a function " + + "that creates a handle. Instead received: %s.", + create !== null ? typeof create : "null" + ) + : void 0; } // TODO: If deps are provided, should we skip comparing the ref itself? var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null; return updateEffectImpl( Update, - Layout, + UnmountMutation | MountLayout, imperativeHandleEffect.bind(null, create, ref), effectDeps ); @@ -10432,7 +11593,6 @@ function updateCallback(callback, deps) { } } } - hook.memoizedState = [callback, nextDeps]; return callback; } @@ -10449,18 +11609,15 @@ function updateMemo(nextCreate, deps) { var hook = updateWorkInProgressHook(); var nextDeps = deps === undefined ? null : deps; var prevState = hook.memoizedState; - if (prevState !== null) { // Assume these are defined. If they're not, areHookInputsEqual will warn. if (nextDeps !== null) { var prevDeps = prevState[1]; - if (areHookInputsEqual(nextDeps, prevDeps)) { return prevState[0]; } } } - var nextValue = nextCreate(); hook.memoizedState = [nextValue, nextDeps]; return nextValue; @@ -10473,14 +11630,17 @@ function mountDeferredValue(value, config) { mountEffect( function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config; + Scheduler.unstable_next(function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + config === undefined ? null : config; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }); }, [value, config] ); @@ -10488,151 +11648,100 @@ function mountDeferredValue(value, config) { } function updateDeferredValue(value, config) { - var _updateState = updateState(), + var _updateState = updateState(value), prevValue = _updateState[0], setValue = _updateState[1]; updateEffect( function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config; - - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }, - [value, config] - ); - return prevValue; -} - -function rerenderDeferredValue(value, config) { - var _rerenderState = rerenderState(), - prevValue = _rerenderState[0], - setValue = _rerenderState[1]; - - updateEffect( - function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config; + Scheduler.unstable_next(function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + config === undefined ? null : config; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }); }, [value, config] ); return prevValue; } -function startTransition(setPending, config, callback) { - var priorityLevel = getCurrentPriorityLevel(); - runWithPriority( - priorityLevel < UserBlockingPriority ? UserBlockingPriority : priorityLevel, - function() { - setPending(true); - } - ); - runWithPriority( - priorityLevel > NormalPriority ? NormalPriority : priorityLevel, - function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config; - - try { - setPending(false); - callback(); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - } - ); -} - function mountTransition(config) { var _mountState2 = mountState(false), isPending = _mountState2[0], setPending = _mountState2[1]; - var start = mountCallback(startTransition.bind(null, setPending, config), [ - setPending, - config - ]); - return [start, isPending]; + var startTransition = mountCallback( + function(callback) { + setPending(true); + Scheduler.unstable_next(function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + config === undefined ? null : config; + + try { + setPending(false); + callback(); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }); + }, + [config, isPending] + ); + return [startTransition, isPending]; } function updateTransition(config) { - var _updateState2 = updateState(), + var _updateState2 = updateState(false), isPending = _updateState2[0], setPending = _updateState2[1]; - var start = updateCallback(startTransition.bind(null, setPending, config), [ - setPending, - config - ]); - return [start, isPending]; -} - -function rerenderTransition(config) { - var _rerenderState2 = rerenderState(), - isPending = _rerenderState2[0], - setPending = _rerenderState2[1]; + var startTransition = updateCallback( + function(callback) { + setPending(true); + Scheduler.unstable_next(function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + config === undefined ? null : config; - var start = updateCallback(startTransition.bind(null, setPending, config), [ - setPending, - config - ]); - return [start, isPending]; + try { + setPending(false); + callback(); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }); + }, + [config, isPending] + ); + return [startTransition, isPending]; } function dispatchAction(fiber, queue, action) { - { - if (typeof arguments[3] === "function") { - error( - "State updates from the useState() and useReducer() Hooks don't support the " + - "second callback argument. To execute a side effect after " + - "rendering, declare it in the component body with useEffect()." - ); - } + if (!(numberOfReRenders < RE_RENDER_LIMIT)) { + throw Error( + "Too many re-renders. React limits the number of renders to prevent an infinite loop." + ); } - var currentTime = requestCurrentTimeForUpdate(); - var suspenseConfig = requestCurrentSuspenseConfig(); - var expirationTime = computeExpirationForFiber( - currentTime, - fiber, - suspenseConfig - ); - var update = { - expirationTime: expirationTime, - suspenseConfig: suspenseConfig, - action: action, - eagerReducer: null, - eagerState: null, - next: null - }; - { - update.priority = getCurrentPriorityLevel(); - } // 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; + !(typeof arguments[3] !== "function") + ? warning$1( + false, + "State updates from the useState() and useReducer() Hooks don't support the " + + "second callback argument. To execute a side effect after " + + "rendering, declare it in the component body with useEffect()." + ) + : void 0; } - queue.pending = update; var alternate = fiber.alternate; - if ( fiber === currentlyRenderingFiber$1 || (alternate !== null && alternate === currentlyRenderingFiber$1) @@ -10641,9 +11750,76 @@ 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. didScheduleRenderPhaseUpdate = true; - update.expirationTime = renderExpirationTime; - currentlyRenderingFiber$1.expirationTime = renderExpirationTime; + var update = { + expirationTime: renderExpirationTime$1, + suspenseConfig: null, + action: action, + eagerReducer: null, + eagerState: null, + next: null + }; + + { + update.priority = getCurrentPriorityLevel(); + } + + if (renderPhaseUpdates === null) { + renderPhaseUpdates = new Map(); + } + + var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue); + + if (firstRenderPhaseUpdate === undefined) { + renderPhaseUpdates.set(queue, update); + } else { + // Append the update to the end of the list. + var lastRenderPhaseUpdate = firstRenderPhaseUpdate; + + while (lastRenderPhaseUpdate.next !== null) { + lastRenderPhaseUpdate = lastRenderPhaseUpdate.next; + } + + lastRenderPhaseUpdate.next = update; + } } else { + var currentTime = requestCurrentTimeForUpdate(); + var suspenseConfig = requestCurrentSuspenseConfig(); + var expirationTime = computeExpirationForFiber( + currentTime, + fiber, + suspenseConfig + ); + var _update2 = { + expirationTime: expirationTime, + suspenseConfig: suspenseConfig, + action: action, + eagerReducer: null, + eagerState: null, + next: null + }; + + { + _update2.priority = getCurrentPriorityLevel(); + } // Append the update to the end of the list. + + var last = queue.last; + + if (last === null) { + // This is the first update. Create a circular list. + _update2.next = _update2; + } else { + var first = last.next; + + if (first !== null) { + // Still circular. + _update2.next = first; + } + + last.next = _update2; + } + + queue.last = _update2; + if ( fiber.expirationTime === NoWork && (alternate === null || alternate.expirationTime === NoWork) @@ -10657,8 +11833,8 @@ function dispatchAction(fiber, queue, action) { var prevDispatcher; { - prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; } try { @@ -10668,10 +11844,10 @@ function dispatchAction(fiber, queue, action) { // time we enter the render phase, then the eager state can be used // without calling the reducer again. - update.eagerReducer = lastRenderedReducer; - update.eagerState = eagerState; + _update2.eagerReducer = lastRenderedReducer; + _update2.eagerState = eagerState; - if (objectIs(eagerState, currentState)) { + if (is$1(eagerState, currentState)) { // Fast path. We can bail out without scheduling React to re-render. // It's still possible that we'll need to rebase this update later, // if the component re-renders for a different reason and by that @@ -10682,24 +11858,23 @@ function dispatchAction(fiber, queue, action) { // Suppress the error. It will throw again in the render phase. } finally { { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } } } } + { + // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests + if ("undefined" !== typeof jest) { + warnIfNotScopedWithMatchingAct(fiber); + warnIfNotCurrentlyActingUpdatesInDev(fiber); + } + } scheduleWork(fiber, expirationTime); } } -function mountEventListener(event) { - return undefined; -} - -function updateEventListener(event) { - return undefined; -} - var ContextOnlyDispatcher = { readContext: readContext, useCallback: throwInvalidHookError, @@ -10714,20 +11889,18 @@ var ContextOnlyDispatcher = { useDebugValue: throwInvalidHookError, useResponder: throwInvalidHookError, useDeferredValue: throwInvalidHookError, - useTransition: throwInvalidHookError, - useEvent: throwInvalidHookError + useTransition: throwInvalidHookError }; var HooksDispatcherOnMountInDEV = null; var HooksDispatcherOnMountWithHookTypesInDEV = null; var HooksDispatcherOnUpdateInDEV = null; -var HooksDispatcherOnRerenderInDEV = null; var InvalidNestedHooksDispatcherOnMountInDEV = null; var InvalidNestedHooksDispatcherOnUpdateInDEV = null; -var InvalidNestedHooksDispatcherOnRerenderInDEV = null; { var warnInvalidContextAccess = function() { - error( + warning$1( + false, "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 " + @@ -10736,7 +11909,8 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; }; var warnInvalidHookAccess = function() { - error( + warning$1( + false, "Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks. " + "You can only call Hooks at the top level of your React function. " + "For more information, see " + @@ -10781,25 +11955,23 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; currentHookNameInDev = "useMemo"; mountHookTypesDev(); checkDepsAreArrayDev(deps); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; - + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; try { return mountMemo(create, deps); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useReducer: function(reducer, initialArg, init) { currentHookNameInDev = "useReducer"; mountHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; - + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; try { return mountReducer(reducer, initialArg, init); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useRef: function(initialValue) { @@ -10810,24 +11982,23 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; useState: function(initialState) { currentHookNameInDev = "useState"; mountHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; - + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; try { return mountState(initialState); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useDebugValue: function(value, formatterFn) { currentHookNameInDev = "useDebugValue"; mountHookTypesDev(); - return mountDebugValue(); + return mountDebugValue(value, formatterFn); }, useResponder: function(responder, props) { currentHookNameInDev = "useResponder"; mountHookTypesDev(); - return createDeprecatedResponderListener(responder, props); + return createResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; @@ -10838,11 +12009,6 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; currentHookNameInDev = "useTransition"; mountHookTypesDev(); return mountTransition(config); - }, - useEvent: function(event) { - currentHookNameInDev = "useEvent"; - mountHookTypesDev(); - return mountEventListener(); } }; HooksDispatcherOnMountWithHookTypesInDEV = { @@ -10877,25 +12043,23 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; useMemo: function(create, deps) { currentHookNameInDev = "useMemo"; updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; - + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; try { return mountMemo(create, deps); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useReducer: function(reducer, initialArg, init) { currentHookNameInDev = "useReducer"; updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; - + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; try { return mountReducer(reducer, initialArg, init); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useRef: function(initialValue) { @@ -10906,24 +12070,23 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; useState: function(initialState) { currentHookNameInDev = "useState"; updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; - + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; try { return mountState(initialState); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useDebugValue: function(value, formatterFn) { currentHookNameInDev = "useDebugValue"; updateHookTypesDev(); - return mountDebugValue(); + return mountDebugValue(value, formatterFn); }, useResponder: function(responder, props) { currentHookNameInDev = "useResponder"; updateHookTypesDev(); - return createDeprecatedResponderListener(responder, props); + return createResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; @@ -10934,11 +12097,6 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; currentHookNameInDev = "useTransition"; updateHookTypesDev(); return mountTransition(config); - }, - useEvent: function(event) { - currentHookNameInDev = "useEvent"; - updateHookTypesDev(); - return mountEventListener(); } }; HooksDispatcherOnUpdateInDEV = { @@ -10973,53 +12131,50 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; useMemo: function(create, deps) { currentHookNameInDev = "useMemo"; updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; - + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; try { return updateMemo(create, deps); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useReducer: function(reducer, initialArg, init) { currentHookNameInDev = "useReducer"; updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; - + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; try { return updateReducer(reducer, initialArg, init); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useRef: function(initialValue) { currentHookNameInDev = "useRef"; updateHookTypesDev(); - return updateRef(); + return updateRef(initialValue); }, useState: function(initialState) { currentHookNameInDev = "useState"; updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; - + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; try { return updateState(initialState); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useDebugValue: function(value, formatterFn) { currentHookNameInDev = "useDebugValue"; updateHookTypesDev(); - return updateDebugValue(); + return updateDebugValue(value, formatterFn); }, useResponder: function(responder, props) { currentHookNameInDev = "useResponder"; updateHookTypesDev(); - return createDeprecatedResponderListener(responder, props); + return createResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; @@ -11030,221 +12185,111 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; currentHookNameInDev = "useTransition"; updateHookTypesDev(); return updateTransition(config); - }, - useEvent: function(event) { - currentHookNameInDev = "useEvent"; - updateHookTypesDev(); - return updateEventListener(); } }; - HooksDispatcherOnRerenderInDEV = { + InvalidNestedHooksDispatcherOnMountInDEV = { readContext: function(context, observedBits) { + warnInvalidContextAccess(); return readContext(context, observedBits); }, useCallback: function(callback, deps) { currentHookNameInDev = "useCallback"; - updateHookTypesDev(); - return updateCallback(callback, deps); + warnInvalidHookAccess(); + mountHookTypesDev(); + return mountCallback(callback, deps); }, useContext: function(context, observedBits) { currentHookNameInDev = "useContext"; - updateHookTypesDev(); + warnInvalidHookAccess(); + mountHookTypesDev(); return readContext(context, observedBits); }, useEffect: function(create, deps) { currentHookNameInDev = "useEffect"; - updateHookTypesDev(); - return updateEffect(create, deps); + warnInvalidHookAccess(); + mountHookTypesDev(); + return mountEffect(create, deps); }, useImperativeHandle: function(ref, create, deps) { currentHookNameInDev = "useImperativeHandle"; - updateHookTypesDev(); - return updateImperativeHandle(ref, create, deps); + warnInvalidHookAccess(); + mountHookTypesDev(); + return mountImperativeHandle(ref, create, deps); }, useLayoutEffect: function(create, deps) { currentHookNameInDev = "useLayoutEffect"; - updateHookTypesDev(); - return updateLayoutEffect(create, deps); + warnInvalidHookAccess(); + mountHookTypesDev(); + return mountLayoutEffect(create, deps); }, useMemo: function(create, deps) { currentHookNameInDev = "useMemo"; - updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnRerenderInDEV; - + warnInvalidHookAccess(); + mountHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; try { - return updateMemo(create, deps); + return mountMemo(create, deps); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useReducer: function(reducer, initialArg, init) { currentHookNameInDev = "useReducer"; - updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnRerenderInDEV; - + warnInvalidHookAccess(); + mountHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; try { - return rerenderReducer(reducer, initialArg, init); + return mountReducer(reducer, initialArg, init); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useRef: function(initialValue) { currentHookNameInDev = "useRef"; - updateHookTypesDev(); - return updateRef(); + warnInvalidHookAccess(); + mountHookTypesDev(); + return mountRef(initialValue); }, useState: function(initialState) { currentHookNameInDev = "useState"; - updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnRerenderInDEV; - + warnInvalidHookAccess(); + mountHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; try { - return rerenderState(initialState); + return mountState(initialState); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useDebugValue: function(value, formatterFn) { currentHookNameInDev = "useDebugValue"; - updateHookTypesDev(); - return updateDebugValue(); + warnInvalidHookAccess(); + mountHookTypesDev(); + return mountDebugValue(value, formatterFn); }, useResponder: function(responder, props) { currentHookNameInDev = "useResponder"; - updateHookTypesDev(); - return createDeprecatedResponderListener(responder, props); + warnInvalidHookAccess(); + mountHookTypesDev(); + return createResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; - updateHookTypesDev(); - return rerenderDeferredValue(value, config); + warnInvalidHookAccess(); + mountHookTypesDev(); + return mountDeferredValue(value, config); }, useTransition: function(config) { currentHookNameInDev = "useTransition"; - updateHookTypesDev(); - return rerenderTransition(config); - }, - useEvent: function(event) { - currentHookNameInDev = "useEvent"; - updateHookTypesDev(); - return updateEventListener(); + warnInvalidHookAccess(); + mountHookTypesDev(); + return mountTransition(config); } }; - InvalidNestedHooksDispatcherOnMountInDEV = { - readContext: function(context, observedBits) { - warnInvalidContextAccess(); - return readContext(context, observedBits); - }, - useCallback: function(callback, deps) { - currentHookNameInDev = "useCallback"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountCallback(callback, deps); - }, - useContext: function(context, observedBits) { - currentHookNameInDev = "useContext"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return readContext(context, observedBits); - }, - useEffect: function(create, deps) { - currentHookNameInDev = "useEffect"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountEffect(create, deps); - }, - useImperativeHandle: function(ref, create, deps) { - currentHookNameInDev = "useImperativeHandle"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountImperativeHandle(ref, create, deps); - }, - useLayoutEffect: function(create, deps) { - currentHookNameInDev = "useLayoutEffect"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountLayoutEffect(create, deps); - }, - useMemo: function(create, deps) { - currentHookNameInDev = "useMemo"; - warnInvalidHookAccess(); - mountHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; - - try { - return mountMemo(create, deps); - } finally { - ReactCurrentDispatcher.current = prevDispatcher; - } - }, - useReducer: function(reducer, initialArg, init) { - currentHookNameInDev = "useReducer"; - warnInvalidHookAccess(); - mountHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; - - try { - return mountReducer(reducer, initialArg, init); - } finally { - ReactCurrentDispatcher.current = prevDispatcher; - } - }, - useRef: function(initialValue) { - currentHookNameInDev = "useRef"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountRef(initialValue); - }, - useState: function(initialState) { - currentHookNameInDev = "useState"; - warnInvalidHookAccess(); - mountHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; - - try { - return mountState(initialState); - } finally { - ReactCurrentDispatcher.current = prevDispatcher; - } - }, - useDebugValue: function(value, formatterFn) { - currentHookNameInDev = "useDebugValue"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountDebugValue(); - }, - useResponder: function(responder, props) { - currentHookNameInDev = "useResponder"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return createDeprecatedResponderListener(responder, props); - }, - useDeferredValue: function(value, config) { - currentHookNameInDev = "useDeferredValue"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountDeferredValue(value, config); - }, - useTransition: function(config) { - currentHookNameInDev = "useTransition"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountTransition(config); - }, - useEvent: function(event) { - currentHookNameInDev = "useEvent"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountEventListener(); - } - }; - InvalidNestedHooksDispatcherOnUpdateInDEV = { + InvalidNestedHooksDispatcherOnUpdateInDEV = { readContext: function(context, observedBits) { warnInvalidContextAccess(); return readContext(context, observedBits); @@ -11283,58 +12328,55 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; currentHookNameInDev = "useMemo"; warnInvalidHookAccess(); updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; - + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; try { return updateMemo(create, deps); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useReducer: function(reducer, initialArg, init) { currentHookNameInDev = "useReducer"; warnInvalidHookAccess(); updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; - + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; try { return updateReducer(reducer, initialArg, init); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useRef: function(initialValue) { currentHookNameInDev = "useRef"; warnInvalidHookAccess(); updateHookTypesDev(); - return updateRef(); + return updateRef(initialValue); }, useState: function(initialState) { currentHookNameInDev = "useState"; warnInvalidHookAccess(); updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; - + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; try { return updateState(initialState); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useDebugValue: function(value, formatterFn) { currentHookNameInDev = "useDebugValue"; warnInvalidHookAccess(); updateHookTypesDev(); - return updateDebugValue(); + return updateDebugValue(value, formatterFn); }, useResponder: function(responder, props) { currentHookNameInDev = "useResponder"; warnInvalidHookAccess(); updateHookTypesDev(); - return createDeprecatedResponderListener(responder, props); + return createResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; @@ -11347,127 +12389,12 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; warnInvalidHookAccess(); updateHookTypesDev(); return updateTransition(config); - }, - useEvent: function(event) { - currentHookNameInDev = "useEvent"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateEventListener(); - } - }; - 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.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; - - try { - return updateMemo(create, deps); - } finally { - ReactCurrentDispatcher.current = prevDispatcher; - } - }, - useReducer: function(reducer, initialArg, init) { - currentHookNameInDev = "useReducer"; - warnInvalidHookAccess(); - updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; - - try { - return rerenderReducer(reducer, initialArg, init); - } finally { - ReactCurrentDispatcher.current = prevDispatcher; - } - }, - useRef: function(initialValue) { - currentHookNameInDev = "useRef"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateRef(); - }, - useState: function(initialState) { - currentHookNameInDev = "useState"; - warnInvalidHookAccess(); - updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; - - try { - return rerenderState(initialState); - } finally { - ReactCurrentDispatcher.current = prevDispatcher; - } - }, - useDebugValue: function(value, formatterFn) { - currentHookNameInDev = "useDebugValue"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateDebugValue(); - }, - useResponder: function(responder, props) { - currentHookNameInDev = "useResponder"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return createDeprecatedResponderListener(responder, props); - }, - useDeferredValue: function(value, config) { - currentHookNameInDev = "useDeferredValue"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return rerenderDeferredValue(value, config); - }, - useTransition: function(config) { - currentHookNameInDev = "useTransition"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return rerenderTransition(config); - }, - useEvent: function(event) { - currentHookNameInDev = "useEvent"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateEventListener(); } }; } +// CommonJS interop named imports. + var now$1 = Scheduler.unstable_now; var commitTime = 0; var profilerStartTime = -1; @@ -11477,878 +12404,2239 @@ function getCommitTime() { } function recordCommitTime() { + if (!enableProfilerTimer) { + return; + } commitTime = now$1(); } -function startProfilerTimer(fiber) { - profilerStartTime = now$1(); +function startProfilerTimer(fiber) { + if (!enableProfilerTimer) { + return; + } + + profilerStartTime = now$1(); + + if (fiber.actualStartTime < 0) { + fiber.actualStartTime = now$1(); + } +} + +function stopProfilerTimerIfRunning(fiber) { + if (!enableProfilerTimer) { + return; + } + profilerStartTime = -1; +} + +function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) { + if (!enableProfilerTimer) { + return; + } + + if (profilerStartTime >= 0) { + var elapsedTime = now$1() - profilerStartTime; + fiber.actualDuration += elapsedTime; + + if (overrideBaseTime) { + fiber.selfBaseDuration = elapsedTime; + } + + profilerStartTime = -1; + } +} + +// This may have been an insertion or a hydration. + +var hydrationParentFiber = null; +var nextHydratableInstance = null; +var isHydrating = false; + +function warnIfHydrating() { + { + !!isHydrating + ? warning$1( + false, + "We should not be hydrating here. This is a bug in React. Please file a bug." + ) + : void 0; + } +} + +function enterHydrationState(fiber) { + if (!supportsHydration) { + return false; + } + + var parentInstance = fiber.stateNode.containerInfo; + nextHydratableInstance = getFirstHydratableChild(parentInstance); + hydrationParentFiber = fiber; + isHydrating = true; + return true; +} + +function reenterHydrationStateFromDehydratedSuspenseInstance( + fiber, + suspenseInstance +) { + if (!supportsHydration) { + return false; + } + + nextHydratableInstance = getNextHydratableSibling(suspenseInstance); + popToNextHostParent(fiber); + isHydrating = true; + return true; +} + +function deleteHydratableInstance(returnFiber, instance) { + { + switch (returnFiber.tag) { + case HostRoot: + didNotHydrateContainerInstance( + returnFiber.stateNode.containerInfo, + instance + ); + break; + case HostComponent: + didNotHydrateInstance( + returnFiber.type, + returnFiber.memoizedProps, + returnFiber.stateNode, + instance + ); + break; + } + } + + var childToDelete = createFiberFromHostInstanceForDeletion(); + childToDelete.stateNode = instance; + childToDelete.return = returnFiber; + childToDelete.effectTag = Deletion; // This might seem like it belongs on progressedFirstDeletion. However, + // these children are not part of the reconciliation list of children. + // Even if we abort and rereconcile the children, that will try to hydrate + // again and the nodes are still in the host tree so these will be + // recreated. + if (returnFiber.lastEffect !== null) { + returnFiber.lastEffect.nextEffect = childToDelete; + returnFiber.lastEffect = childToDelete; + } else { + returnFiber.firstEffect = returnFiber.lastEffect = childToDelete; + } +} + +function insertNonHydratedInstance(returnFiber, fiber) { + fiber.effectTag = (fiber.effectTag & ~Hydrating) | Placement; + + { + switch (returnFiber.tag) { + case HostRoot: { + var parentContainer = returnFiber.stateNode.containerInfo; + switch (fiber.tag) { + case HostComponent: + var type = fiber.type; + var props = fiber.pendingProps; + didNotFindHydratableContainerInstance(parentContainer, type, props); + break; + case HostText: + var text = fiber.pendingProps; + didNotFindHydratableContainerTextInstance(parentContainer, text); + break; + case SuspenseComponent: + didNotFindHydratableContainerSuspenseInstance(parentContainer); + break; + } + + break; + } + + case HostComponent: { + var parentType = returnFiber.type; + var parentProps = returnFiber.memoizedProps; + var parentInstance = returnFiber.stateNode; + switch (fiber.tag) { + case HostComponent: + var _type = fiber.type; + var _props = fiber.pendingProps; + didNotFindHydratableInstance( + parentType, + parentProps, + parentInstance, + _type, + _props + ); + break; + case HostText: + var _text = fiber.pendingProps; + didNotFindHydratableTextInstance( + parentType, + parentProps, + parentInstance, + _text + ); + break; + case SuspenseComponent: + didNotFindHydratableSuspenseInstance( + parentType, + parentProps, + parentInstance + ); + break; + } + + break; + } + + default: + return; + } + } +} + +function tryHydrate(fiber, nextInstance) { + switch (fiber.tag) { + case HostComponent: { + var type = fiber.type; + var props = fiber.pendingProps; + var instance = canHydrateInstance(nextInstance, type, props); + if (instance !== null) { + fiber.stateNode = instance; + return true; + } + + return false; + } + + case HostText: { + var text = fiber.pendingProps; + var textInstance = canHydrateTextInstance(nextInstance, text); + + if (textInstance !== null) { + fiber.stateNode = textInstance; + return true; + } + + return false; + } + + case SuspenseComponent: { + if (enableSuspenseServerRenderer) { + var suspenseInstance = canHydrateSuspenseInstance(nextInstance); + + if (suspenseInstance !== null) { + var suspenseState = { + dehydrated: suspenseInstance, + retryTime: Never + }; + fiber.memoizedState = suspenseState; // Store the dehydrated fragment as a child fiber. + // This simplifies the code for getHostSibling and deleting nodes, + // since it doesn't have to consider all Suspense boundaries and + // check if they're dehydrated ones or not. + + var dehydratedFragment = createFiberFromDehydratedFragment( + suspenseInstance + ); + dehydratedFragment.return = fiber; + fiber.child = dehydratedFragment; + return true; + } + } + + return false; + } + + default: + return false; + } +} + +function tryToClaimNextHydratableInstance(fiber) { + if (!isHydrating) { + return; + } + + var nextInstance = nextHydratableInstance; + + if (!nextInstance) { + // Nothing to hydrate. Make it an insertion. + insertNonHydratedInstance(hydrationParentFiber, fiber); + isHydrating = false; + hydrationParentFiber = fiber; + return; + } + + var firstAttemptedInstance = nextInstance; + + if (!tryHydrate(fiber, nextInstance)) { + // If we can't hydrate this instance let's try the next one. + // We use this as a heuristic. It's based on intuition and not data so it + // might be flawed or unnecessary. + nextInstance = getNextHydratableSibling(firstAttemptedInstance); + if (!nextInstance || !tryHydrate(fiber, nextInstance)) { + // Nothing to hydrate. Make it an insertion. + insertNonHydratedInstance(hydrationParentFiber, fiber); + isHydrating = false; + hydrationParentFiber = fiber; + return; + } // We matched the next one, we'll now assume that the first one was + // superfluous and we'll delete it. Since we can't eagerly delete it + // we'll have to schedule a deletion. To do that, this node needs a dummy + // fiber associated with it. + + deleteHydratableInstance(hydrationParentFiber, firstAttemptedInstance); + } + + hydrationParentFiber = fiber; + nextHydratableInstance = getFirstHydratableChild(nextInstance); +} + +function prepareToHydrateHostInstance( + fiber, + rootContainerInstance, + hostContext +) { + if (!supportsHydration) { + { + throw Error( + "Expected prepareToHydrateHostInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." + ); + } + } + + var instance = fiber.stateNode; + var updatePayload = hydrateInstance( + instance, + fiber.type, + fiber.memoizedProps, + rootContainerInstance, + hostContext, + fiber + ); // TODO: Type this specific to this type of component. + + fiber.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. + + if (updatePayload !== null) { + return true; + } + + return false; +} + +function prepareToHydrateHostTextInstance(fiber) { + if (!supportsHydration) { + { + throw Error( + "Expected prepareToHydrateHostTextInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." + ); + } + } + + var textInstance = fiber.stateNode; + var textContent = fiber.memoizedProps; + var shouldUpdate = hydrateTextInstance(textInstance, textContent, fiber); + { + if (shouldUpdate) { + // We assume that prepareToHydrateHostTextInstance is called in a context where the + // hydration parent is the parent host component of this host text. + var returnFiber = hydrationParentFiber; + if (returnFiber !== null) { + switch (returnFiber.tag) { + case HostRoot: { + var parentContainer = returnFiber.stateNode.containerInfo; + didNotMatchHydratedContainerTextInstance( + parentContainer, + textInstance, + textContent + ); + break; + } + case HostComponent: { + var parentType = returnFiber.type; + var parentProps = returnFiber.memoizedProps; + var parentInstance = returnFiber.stateNode; + didNotMatchHydratedTextInstance( + parentType, + parentProps, + parentInstance, + textInstance, + textContent + ); + break; + } + } + } + } + } + + return shouldUpdate; +} + +function prepareToHydrateHostSuspenseInstance(fiber) { + if (!supportsHydration) { + { + throw Error( + "Expected prepareToHydrateHostSuspenseInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." + ); + } + } + + var suspenseState = fiber.memoizedState; + var suspenseInstance = + suspenseState !== null ? suspenseState.dehydrated : null; + + if (!suspenseInstance) { + throw Error( + "Expected to have a hydrated suspense instance. This error is likely caused by a bug in React. Please file an issue." + ); + } + + hydrateSuspenseInstance(suspenseInstance, fiber); +} + +function skipPastDehydratedSuspenseInstance(fiber) { + if (!supportsHydration) { + { + throw Error( + "Expected skipPastDehydratedSuspenseInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." + ); + } + } + + var suspenseState = fiber.memoizedState; + var suspenseInstance = + suspenseState !== null ? suspenseState.dehydrated : null; + + if (!suspenseInstance) { + throw Error( + "Expected to have a hydrated suspense instance. This error is likely caused by a bug in React. Please file an issue." + ); + } + + return getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance); +} + +function popToNextHostParent(fiber) { + var parent = fiber.return; + while ( + parent !== null && + parent.tag !== HostComponent && + parent.tag !== HostRoot && + parent.tag !== SuspenseComponent + ) { + parent = parent.return; + } + + hydrationParentFiber = parent; +} + +function popHydrationState(fiber) { + if (!supportsHydration) { + return false; + } + if (fiber !== hydrationParentFiber) { + // We're deeper than the current hydration context, inside an inserted + // tree. + return false; + } + if (!isHydrating) { + // If we're not currently hydrating but we're in a hydration context, then + // we were an insertion and now need to pop up reenter hydration of our + // siblings. + popToNextHostParent(fiber); + isHydrating = true; + return false; + } + + var type = fiber.type; // If we have any remaining hydratable nodes, we need to delete them now. + // We only do this deeper than head and body since they tend to have random + // other nodes in them. We also ignore components with pure text content in + // side of them. + // TODO: Better heuristic. + if ( + fiber.tag !== HostComponent || + (type !== "head" && + type !== "body" && + !shouldSetTextContent(type, fiber.memoizedProps)) + ) { + var nextInstance = nextHydratableInstance; + while (nextInstance) { + deleteHydratableInstance(fiber, nextInstance); + nextInstance = getNextHydratableSibling(nextInstance); + } + } + + popToNextHostParent(fiber); + + if (fiber.tag === SuspenseComponent) { + nextHydratableInstance = skipPastDehydratedSuspenseInstance(fiber); + } else { + nextHydratableInstance = hydrationParentFiber + ? getNextHydratableSibling(fiber.stateNode) + : null; + } + + return true; +} + +function resetHydrationState() { + if (!supportsHydration) { + return; + } + + hydrationParentFiber = null; + nextHydratableInstance = null; + isHydrating = false; +} + +var ReactCurrentOwner$3 = ReactSharedInternals.ReactCurrentOwner; +var didReceiveUpdate = false; +var didWarnAboutBadClass; +var didWarnAboutModulePatternComponent; +var didWarnAboutContextTypeOnFunctionComponent; +var didWarnAboutGetDerivedStateOnFunctionComponent; +var didWarnAboutFunctionRefs; +var didWarnAboutReassigningProps; +var didWarnAboutMaxDuration; +var didWarnAboutRevealOrder; +var didWarnAboutTailOptions; +var didWarnAboutDefaultPropsOnFunctionComponent; + +{ + didWarnAboutBadClass = {}; + didWarnAboutModulePatternComponent = {}; + didWarnAboutContextTypeOnFunctionComponent = {}; + didWarnAboutGetDerivedStateOnFunctionComponent = {}; + didWarnAboutFunctionRefs = {}; + didWarnAboutReassigningProps = false; + didWarnAboutMaxDuration = false; + didWarnAboutRevealOrder = {}; + didWarnAboutTailOptions = {}; + didWarnAboutDefaultPropsOnFunctionComponent = {}; +} + +function reconcileChildren( + current$$1, + workInProgress, + nextChildren, + renderExpirationTime +) { + if (current$$1 === 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, + renderExpirationTime + ); + } 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$$1.child, + nextChildren, + renderExpirationTime + ); + } +} + +function forceUnmountCurrentAndReconcile( + current$$1, + workInProgress, + nextChildren, + renderExpirationTime +) { + // 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$$1.child, + null, + renderExpirationTime + ); // 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 their + // identity matches. + + workInProgress.child = reconcileChildFibers( + workInProgress, + null, + nextChildren, + renderExpirationTime + ); +} + +function updateForwardRef( + current$$1, + workInProgress, + Component, + nextProps, + renderExpirationTime +) { + // 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), + getCurrentFiberStackInDev + ); + } + } + } + + var render = Component.render; + var ref = workInProgress.ref; // The rest is a fork of updateFunctionComponent + + var nextChildren; + prepareToReadContext(workInProgress, renderExpirationTime); + + { + ReactCurrentOwner$3.current = workInProgress; + setCurrentPhase("render"); + nextChildren = renderWithHooks( + current$$1, + workInProgress, + render, + nextProps, + ref, + renderExpirationTime + ); + + if ( + debugRenderPhaseSideEffectsForStrictMode && + workInProgress.mode & StrictMode + ) { + // Only double-render components with Hooks + if (workInProgress.memoizedState !== null) { + nextChildren = renderWithHooks( + current$$1, + workInProgress, + render, + nextProps, + ref, + renderExpirationTime + ); + } + } + setCurrentPhase(null); + } + + if (current$$1 !== null && !didReceiveUpdate) { + bailoutHooks(current$$1, workInProgress, renderExpirationTime); + return bailoutOnAlreadyFinishedWork( + current$$1, + workInProgress, + renderExpirationTime + ); + } // React DevTools reads this flag. + + workInProgress.effectTag |= PerformedWork; + reconcileChildren( + current$$1, + workInProgress, + nextChildren, + renderExpirationTime + ); + return workInProgress.child; +} + +function updateMemoComponent( + current$$1, + workInProgress, + Component, + nextProps, + updateExpirationTime, + renderExpirationTime +) { + if (current$$1 === 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$$1, + workInProgress, + resolvedType, + nextProps, + updateExpirationTime, + renderExpirationTime + ); + } + + { + 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), + getCurrentFiberStackInDev + ); + } + } + var child = createFiberFromTypeAndProps( + Component.type, + null, + nextProps, + null, + workInProgress.mode, + renderExpirationTime + ); + 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), + getCurrentFiberStackInDev + ); + } + } + + var currentChild = current$$1.child; // This is always exactly one child + + if (updateExpirationTime < renderExpirationTime) { + // 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$$1.ref === workInProgress.ref + ) { + return bailoutOnAlreadyFinishedWork( + current$$1, + workInProgress, + renderExpirationTime + ); + } + } // React DevTools reads this flag. + + workInProgress.effectTag |= PerformedWork; + var newChild = createWorkInProgress( + currentChild, + nextProps, + renderExpirationTime + ); + newChild.ref = workInProgress.ref; + newChild.return = workInProgress; + workInProgress.child = newChild; + return newChild; +} + +function updateSimpleMemoComponent( + current$$1, + workInProgress, + Component, + nextProps, + updateExpirationTime, + renderExpirationTime +) { + // 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. + outerMemoType = refineResolvedLazyComponent(outerMemoType); + } + + var outerPropTypes = outerMemoType && outerMemoType.propTypes; + + if (outerPropTypes) { + checkPropTypes( + outerPropTypes, + nextProps, // Resolved (SimpleMemoComponent has no defaultProps) + "prop", + getComponentName(outerMemoType), + getCurrentFiberStackInDev + ); + } // Inner propTypes will be validated in the function component path. + } + } + + if (current$$1 !== null) { + var prevProps = current$$1.memoizedProps; + + if ( + shallowEqual(prevProps, nextProps) && + current$$1.ref === workInProgress.ref && // Prevent bailout if the implementation changed due to hot reload: + workInProgress.type === current$$1.type + ) { + didReceiveUpdate = false; + + if (updateExpirationTime < renderExpirationTime) { + return bailoutOnAlreadyFinishedWork( + current$$1, + workInProgress, + renderExpirationTime + ); + } + } + } + return updateFunctionComponent( + current$$1, + workInProgress, + Component, + nextProps, + renderExpirationTime + ); +} + +function updateFragment(current$$1, workInProgress, renderExpirationTime) { + var nextChildren = workInProgress.pendingProps; + reconcileChildren( + current$$1, + workInProgress, + nextChildren, + renderExpirationTime + ); + return workInProgress.child; +} + +function updateMode(current$$1, workInProgress, renderExpirationTime) { + var nextChildren = workInProgress.pendingProps.children; + reconcileChildren( + current$$1, + workInProgress, + nextChildren, + renderExpirationTime + ); + return workInProgress.child; +} + +function updateProfiler(current$$1, workInProgress, renderExpirationTime) { + if (enableProfilerTimer) { + workInProgress.effectTag |= Update; + } + var nextProps = workInProgress.pendingProps; + var nextChildren = nextProps.children; + reconcileChildren( + current$$1, + workInProgress, + nextChildren, + renderExpirationTime + ); + return workInProgress.child; +} + +function markRef(current$$1, workInProgress) { + var ref = workInProgress.ref; + if ( + (current$$1 === null && ref !== null) || + (current$$1 !== null && current$$1.ref !== ref) + ) { + // Schedule a Ref effect + workInProgress.effectTag |= Ref; + } +} + +function updateFunctionComponent( + current$$1, + workInProgress, + Component, + nextProps, + renderExpirationTime +) { + { + 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), + getCurrentFiberStackInDev + ); + } + } + } + + var context; + + if (!disableLegacyContext) { + var unmaskedContext = getUnmaskedContext(workInProgress, Component, true); + context = getMaskedContext(workInProgress, unmaskedContext); + } + + var nextChildren; + prepareToReadContext(workInProgress, renderExpirationTime); + + { + ReactCurrentOwner$3.current = workInProgress; + setCurrentPhase("render"); + nextChildren = renderWithHooks( + current$$1, + workInProgress, + Component, + nextProps, + context, + renderExpirationTime + ); + + if ( + debugRenderPhaseSideEffectsForStrictMode && + workInProgress.mode & StrictMode + ) { + // Only double-render components with Hooks + if (workInProgress.memoizedState !== null) { + nextChildren = renderWithHooks( + current$$1, + workInProgress, + Component, + nextProps, + context, + renderExpirationTime + ); + } + } + setCurrentPhase(null); + } + + if (current$$1 !== null && !didReceiveUpdate) { + bailoutHooks(current$$1, workInProgress, renderExpirationTime); + return bailoutOnAlreadyFinishedWork( + current$$1, + workInProgress, + renderExpirationTime + ); + } // React DevTools reads this flag. + + workInProgress.effectTag |= PerformedWork; + reconcileChildren( + current$$1, + workInProgress, + nextChildren, + renderExpirationTime + ); + return workInProgress.child; +} + +function updateClassComponent( + current$$1, + workInProgress, + Component, + nextProps, + renderExpirationTime +) { + { + 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), + getCurrentFiberStackInDev + ); + } + } + } // 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 (fiber.actualStartTime < 0) { - fiber.actualStartTime = now$1(); + if (isContextProvider(Component)) { + hasContext = true; + pushContextProvider(workInProgress); + } else { + hasContext = false; } -} -function stopProfilerTimerIfRunning(fiber) { - profilerStartTime = -1; -} + prepareToReadContext(workInProgress, renderExpirationTime); + var instance = workInProgress.stateNode; + var shouldUpdate; -function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) { - if (profilerStartTime >= 0) { - var elapsedTime = now$1() - profilerStartTime; - fiber.actualDuration += elapsedTime; + if (instance === null) { + if (current$$1 !== null) { + // An class component without an instance only mounts if it suspended + // inside a non- concurrent tree, in an inconsistent state. We want to + // tree it like a new mount, even though an empty version of it already + // committed. Disconnect the alternate pointers. + current$$1.alternate = null; + workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect - if (overrideBaseTime) { - fiber.selfBaseDuration = elapsedTime; - } + workInProgress.effectTag |= Placement; + } // In the initial pass we might need to construct the instance. - profilerStartTime = -1; + constructClassInstance( + workInProgress, + Component, + nextProps, + renderExpirationTime + ); + mountClassInstance( + workInProgress, + Component, + nextProps, + renderExpirationTime + ); + shouldUpdate = true; + } else if (current$$1 === null) { + // In a resume, we'll already have an instance we can reuse. + shouldUpdate = resumeMountClassInstance( + workInProgress, + Component, + nextProps, + renderExpirationTime + ); + } else { + shouldUpdate = updateClassInstance( + current$$1, + workInProgress, + Component, + nextProps, + renderExpirationTime + ); } -} + var nextUnitOfWork = finishClassComponent( + current$$1, + workInProgress, + Component, + shouldUpdate, + hasContext, + renderExpirationTime + ); -function enterHydrationState(fiber) { { - return false; + var inst = workInProgress.stateNode; + + if (inst.props !== nextProps) { + !didWarnAboutReassigningProps + ? warning$1( + false, + "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" + ) + : void 0; + didWarnAboutReassigningProps = true; + } } + return nextUnitOfWork; } -function prepareToHydrateHostInstance( - fiber, - rootContainerInstance, - hostContext +function finishClassComponent( + current$$1, + workInProgress, + Component, + shouldUpdate, + hasContext, + renderExpirationTime ) { - { - { - throw Error( - "Expected prepareToHydrateHostInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." - ); + // Refs should update even if shouldComponentUpdate returns false + markRef(current$$1, workInProgress); + var didCaptureError = (workInProgress.effectTag & DidCapture) !== NoEffect; + + if (!shouldUpdate && !didCaptureError) { + // Context providers should defer to sCU for rendering + if (hasContext) { + invalidateContextProvider(workInProgress, Component, false); } + + return bailoutOnAlreadyFinishedWork( + current$$1, + workInProgress, + renderExpirationTime + ); } -} -function prepareToHydrateHostTextInstance(fiber) { - { + var instance = workInProgress.stateNode; // Rerender + + ReactCurrentOwner$3.current = workInProgress; + var nextChildren; + + if ( + didCaptureError && + typeof Component.getDerivedStateFromError !== "function" + ) { + // If we captured an error, but getDerivedStateFrom catch 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 (enableProfilerTimer) { + stopProfilerTimerIfRunning(workInProgress); + } + } else { { - throw Error( - "Expected prepareToHydrateHostTextInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." - ); + setCurrentPhase("render"); + nextChildren = instance.render(); + + if ( + debugRenderPhaseSideEffectsForStrictMode && + workInProgress.mode & StrictMode + ) { + instance.render(); + } + + setCurrentPhase(null); } + } // React DevTools reads this flag. + + workInProgress.effectTag |= PerformedWork; + + if (current$$1 !== 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$$1, + workInProgress, + nextChildren, + renderExpirationTime + ); + } else { + reconcileChildren( + current$$1, + workInProgress, + nextChildren, + renderExpirationTime + ); + } // 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); } - var shouldUpdate = hydrateTextInstance(); + + return workInProgress.child; } -function popHydrationState(fiber) { - { - return false; +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); } -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 updateHostRoot(current$$1, workInProgress, renderExpirationTime) { + pushHostRootContext(workInProgress); + var updateQueue = workInProgress.updateQueue; -{ - didWarnAboutBadClass = {}; - didWarnAboutModulePatternComponent = {}; - didWarnAboutContextTypeOnFunctionComponent = {}; - didWarnAboutGetDerivedStateOnFunctionComponent = {}; - didWarnAboutFunctionRefs = {}; - didWarnAboutReassigningProps = false; - didWarnAboutRevealOrder = {}; - didWarnAboutTailOptions = {}; -} + if (!(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." + ); + } -function reconcileChildren( - current, - workInProgress, - nextChildren, - renderExpirationTime -) { - 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( + var nextProps = workInProgress.pendingProps; + var prevState = workInProgress.memoizedState; + var prevChildren = prevState !== null ? prevState.element : null; + processUpdateQueue( + workInProgress, + updateQueue, + nextProps, + null, + renderExpirationTime + ); + var nextState = workInProgress.memoizedState; // Caution: React DevTools currently depends on this property + // being called "element". + + var nextChildren = nextState.element; + + if (nextChildren === prevChildren) { + // If the state is the same as before, that's a bailout because we had + // no work that expires at this time. + resetHydrationState(); + return bailoutOnAlreadyFinishedWork( + current$$1, + workInProgress, + renderExpirationTime + ); + } + + var root = workInProgress.stateNode; + + if (root.hydrate && enterHydrationState(workInProgress)) { + // If we don't have any current children this might be the first pass. + // We always try to hydrate. If this isn't a hydration pass there won't + // be any children to hydrate which is effectively the same thing as + // not hydrating. + var child = mountChildFibers( workInProgress, null, nextChildren, renderExpirationTime ); - } 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.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.effectTag = (node.effectTag & ~Placement) | Hydrating; + node = node.sibling; + } + } else { + // Otherwise reset hydration state in case we aborted and resumed another + // root. + reconcileChildren( + current$$1, workInProgress, - current.child, nextChildren, renderExpirationTime ); + resetHydrationState(); } + return workInProgress.child; } -function forceUnmountCurrentAndReconcile( - current, - workInProgress, - nextChildren, - renderExpirationTime -) { - // 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, - renderExpirationTime - ); // 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 updateHostComponent(current$$1, workInProgress, renderExpirationTime) { + pushHostContext(workInProgress); - workInProgress.child = reconcileChildFibers( + if (current$$1 === null) { + tryToClaimNextHydratableInstance(workInProgress); + } + + var type = workInProgress.type; + var nextProps = workInProgress.pendingProps; + var prevProps = current$$1 !== null ? current$$1.memoizedProps : null; + var nextChildren = nextProps.children; + var isDirectTextChild = shouldSetTextContent(type, nextProps); + + if (isDirectTextChild) { + // We special case a direct text child of a host node. This is a common + // case. We won't handle it as a reified child. We will instead handle + // this in the host environment that also have access to this prop. That + // avoids allocating another HostText fiber and traversing it. + nextChildren = null; + } else if (prevProps !== null && shouldSetTextContent(type, prevProps)) { + // 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.effectTag |= ContentReset; + } + + markRef(current$$1, workInProgress); // Check the host config to see if the children are offscreen/hidden. + + if ( + workInProgress.mode & ConcurrentMode && + renderExpirationTime !== Never && + shouldDeprioritizeSubtree(type, nextProps) + ) { + if (enableSchedulerTracing) { + markSpawnedWork(Never); + } // Schedule this fiber to re-render at offscreen priority. Then bailout. + + workInProgress.expirationTime = workInProgress.childExpirationTime = Never; + return null; + } + + reconcileChildren( + current$$1, workInProgress, - null, nextChildren, renderExpirationTime ); + return workInProgress.child; } -function updateForwardRef( - current, +function updateHostText(current$$1, workInProgress) { + if (current$$1 === null) { + tryToClaimNextHydratableInstance(workInProgress); + } // Nothing to do here. This is terminal. We'll do the completion step + // immediately after. + + return null; +} + +function mountLazyComponent( + _current, workInProgress, - Component, - nextProps, + elementType, + updateExpirationTime, renderExpirationTime ) { - // 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 (_current !== null) { + // An 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.effectTag |= Placement; } - var render = Component.render; - var ref = workInProgress.ref; // The rest is a fork of updateFunctionComponent + var props = workInProgress.pendingProps; // We can't start a User Timing measurement with correct label yet. + // Cancel and resume right after we know the tag. - var nextChildren; - prepareToReadContext(workInProgress, renderExpirationTime); + cancelWorkTimer(workInProgress); + var Component = readLazyComponentType(elementType); // Store the unwrapped component in the type. - { - ReactCurrentOwner$1.current = workInProgress; - setIsRendering(true); - nextChildren = renderWithHooks( - current, - workInProgress, - render, - nextProps, - ref, - renderExpirationTime - ); + workInProgress.type = Component; + var resolvedTag = (workInProgress.tag = resolveLazyComponentTag(Component)); + startWorkTimer(workInProgress); + var resolvedProps = resolveDefaultProps(Component, props); + var child; - if (workInProgress.mode & StrictMode) { - // Only double-render components with Hooks - if (workInProgress.memoizedState !== null) { - nextChildren = renderWithHooks( - current, - workInProgress, - render, - nextProps, - ref, - renderExpirationTime + switch (resolvedTag) { + case FunctionComponent: { + { + validateFunctionComponentInDev(workInProgress, Component); + workInProgress.type = Component = resolveFunctionForHotReloading( + Component + ); + } + child = updateFunctionComponent( + null, + workInProgress, + Component, + resolvedProps, + renderExpirationTime + ); + break; + } + case ClassComponent: { + { + workInProgress.type = Component = resolveClassForHotReloading( + Component + ); + } + child = updateClassComponent( + null, + workInProgress, + Component, + resolvedProps, + renderExpirationTime + ); + break; + } + case ForwardRef: { + { + workInProgress.type = Component = resolveForwardRefForHotReloading( + Component ); } + child = updateForwardRef( + null, + workInProgress, + Component, + resolvedProps, + renderExpirationTime + ); + break; + } + case MemoComponent: { + { + if (workInProgress.type !== workInProgress.elementType) { + var outerPropTypes = Component.propTypes; + if (outerPropTypes) { + checkPropTypes( + outerPropTypes, + resolvedProps, // Resolved for outer only + "prop", + getComponentName(Component), + getCurrentFiberStackInDev + ); + } + } + } + child = updateMemoComponent( + null, + workInProgress, + Component, + resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too + updateExpirationTime, + renderExpirationTime + ); + break; } - setIsRendering(false); + default: { + 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 + ); + } + } } - if (current !== null && !didReceiveUpdate) { - bailoutHooks(current, workInProgress, renderExpirationTime); - return bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderExpirationTime - ); - } // React DevTools reads this flag. + return child; +} - workInProgress.effectTag |= PerformedWork; - reconcileChildren( - current, +function mountIncompleteClassComponent( + _current, + workInProgress, + Component, + nextProps, + renderExpirationTime +) { + 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.effectTag |= 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, renderExpirationTime); + constructClassInstance( + workInProgress, + Component, + nextProps, + renderExpirationTime + ); + mountClassInstance( + workInProgress, + Component, + nextProps, + renderExpirationTime + ); + return finishClassComponent( + null, workInProgress, - nextChildren, + Component, + true, + hasContext, renderExpirationTime ); - return workInProgress.child; } -function updateMemoComponent( - current, +function mountIndeterminateComponent( + _current, workInProgress, Component, - nextProps, - updateExpirationTime, renderExpirationTime ) { - 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; + 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 - { - 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.effectTag |= Placement; + } - workInProgress.tag = SimpleMemoComponent; - workInProgress.type = resolvedType; + var props = workInProgress.pendingProps; + var context; - { - validateFunctionComponentInDev(workInProgress, type); - } + if (!disableLegacyContext) { + var unmaskedContext = getUnmaskedContext(workInProgress, Component, false); + context = getMaskedContext(workInProgress, unmaskedContext); + } - return updateSimpleMemoComponent( - current, - workInProgress, - resolvedType, - nextProps, - updateExpirationTime, - renderExpirationTime - ); - } + prepareToReadContext(workInProgress, renderExpirationTime); + var value; - { - var innerPropTypes = type.propTypes; + { + if ( + Component.prototype && + typeof Component.prototype.render === "function" + ) { + var componentName = getComponentName(Component) || "Unknown"; - 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 (!didWarnAboutBadClass[componentName]) { + warningWithoutStack$1( + false, + "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; } } - var child = createFiberFromTypeAndProps( - Component.type, - null, - nextProps, + if (workInProgress.mode & StrictMode) { + ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null); + } + + ReactCurrentOwner$3.current = workInProgress; + value = renderWithHooks( null, - workInProgress.mode, + workInProgress, + Component, + props, + context, renderExpirationTime ); - child.ref = workInProgress.ref; - child.return = workInProgress; - workInProgress.child = child; - return child; - } + } // React DevTools reads this flag. - { - var _type = Component.type; - var _innerPropTypes = _type.propTypes; + workInProgress.effectTag |= PerformedWork; - 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 ( + typeof value === "object" && + value !== null && + typeof value.render === "function" && + value.$$typeof === undefined + ) { + { + var _componentName = getComponentName(Component) || "Unknown"; + if (!didWarnAboutModulePatternComponent[_componentName]) { + warningWithoutStack$1( + false, + "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; + } + } // Proceed under the assumption that this is a class instance - var currentChild = current.child; // This is always exactly one child + workInProgress.tag = ClassComponent; // Throw out any hooks that were used. - if (updateExpirationTime < renderExpirationTime) { - // 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 + resetHooks(); // 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 compare = Component.compare; - compare = compare !== null ? compare : shallowEqual; + var hasContext = false; - if (compare(prevProps, nextProps) && current.ref === workInProgress.ref) { - return bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderExpirationTime - ); + if (isContextProvider(Component)) { + hasContext = true; + pushContextProvider(workInProgress); + } else { + hasContext = false; } - } // React DevTools reads this flag. - workInProgress.effectTag |= PerformedWork; - var newChild = createWorkInProgress(currentChild, nextProps); - newChild.ref = workInProgress.ref; - newChild.return = workInProgress; - workInProgress.child = newChild; - return newChild; -} + workInProgress.memoizedState = + value.state !== null && value.state !== undefined ? value.state : null; + var getDerivedStateFromProps = Component.getDerivedStateFromProps; -function updateSimpleMemoComponent( - current, - workInProgress, - Component, - nextProps, - updateExpirationTime, - renderExpirationTime -) { - // 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 (typeof getDerivedStateFromProps === "function") { + applyDerivedStateFromProps( + workInProgress, + Component, + getDerivedStateFromProps, + props + ); + } - 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. - outerMemoType = refineResolvedLazyComponent(outerMemoType); + adoptClassInstance(workInProgress, value); + mountClassInstance(workInProgress, Component, props, renderExpirationTime); + return finishClassComponent( + null, + workInProgress, + Component, + true, + hasContext, + renderExpirationTime + ); + } else { + // Proceed under the assumption that this is a function component + workInProgress.tag = FunctionComponent; + { + if (disableLegacyContext && Component.contextTypes) { + warningWithoutStack$1( + false, + "%s uses the legacy contextTypes API which is no longer supported. " + + "Use React.createContext() with React.useContext() instead.", + getComponentName(Component) || "Unknown" + ); } - var outerPropTypes = outerMemoType && outerMemoType.propTypes; - - if (outerPropTypes) { - checkPropTypes( - outerPropTypes, - nextProps, // Resolved (SimpleMemoComponent has no defaultProps) - "prop", - getComponentName(outerMemoType) - ); - } // Inner propTypes will be validated in the function component path. + if ( + debugRenderPhaseSideEffectsForStrictMode && + workInProgress.mode & StrictMode + ) { + // Only double-render components with Hooks + if (workInProgress.memoizedState !== null) { + value = renderWithHooks( + null, + workInProgress, + Component, + props, + context, + renderExpirationTime + ); + } + } } - } - - 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; + reconcileChildren(null, workInProgress, value, renderExpirationTime); - if (updateExpirationTime < renderExpirationTime) { - // The pending update priority was cleared at the beginning of - // beginWork. We're about to bail out, but there might be additional - // updates at a lower priority. 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.expirationTime = current.expirationTime; - return bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderExpirationTime - ); - } + { + validateFunctionComponentInDev(workInProgress, Component); } - } - return updateFunctionComponent( - current, - workInProgress, - Component, - nextProps, - renderExpirationTime - ); + return workInProgress.child; + } } -function updateFragment(current, workInProgress, renderExpirationTime) { - var nextChildren = workInProgress.pendingProps; - reconcileChildren( - current, - workInProgress, - nextChildren, - renderExpirationTime - ); - return workInProgress.child; -} +function validateFunctionComponentInDev(workInProgress, Component) { + if (Component) { + !!Component.childContextTypes + ? warningWithoutStack$1( + false, + "%s(...): childContextTypes cannot be defined on a function component.", + Component.displayName || Component.name || "Component" + ) + : void 0; + } -function updateMode(current, workInProgress, renderExpirationTime) { - var nextChildren = workInProgress.pendingProps.children; - reconcileChildren( - current, - workInProgress, - nextChildren, - renderExpirationTime - ); - return workInProgress.child; -} + if (workInProgress.ref !== null) { + var info = ""; + var ownerName = getCurrentFiberOwnerNameInDevOrNull(); -function updateProfiler(current, workInProgress, renderExpirationTime) { - { - workInProgress.effectTag |= 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 (ownerName) { + info += "\n\nCheck the render method of `" + ownerName + "`."; + } + + var warningKey = ownerName || workInProgress._debugID || ""; + var debugSource = workInProgress._debugSource; + + if (debugSource) { + warningKey = debugSource.fileName + ":" + debugSource.lineNumber; + } - var stateNode = workInProgress.stateNode; - stateNode.effectDuration = 0; - stateNode.passiveEffectDuration = 0; + if (!didWarnAboutFunctionRefs[warningKey]) { + didWarnAboutFunctionRefs[warningKey] = true; + warning$1( + false, + "Function components cannot be given refs. " + + "Attempts to access this ref will fail. " + + "Did you mean to use React.forwardRef()?%s", + info + ); + } } - var nextProps = workInProgress.pendingProps; - var nextChildren = nextProps.children; - reconcileChildren( - current, - workInProgress, - nextChildren, - renderExpirationTime - ); - return workInProgress.child; -} + if ( + warnAboutDefaultPropsOnFunctionComponents && + Component.defaultProps !== undefined + ) { + var componentName = getComponentName(Component) || "Unknown"; + + if (!didWarnAboutDefaultPropsOnFunctionComponent[componentName]) { + warningWithoutStack$1( + false, + "%s: Support for defaultProps will be removed from function components " + + "in a future major release. Use JavaScript default parameters instead.", + componentName + ); + didWarnAboutDefaultPropsOnFunctionComponent[componentName] = true; + } + } -function markRef(current, workInProgress) { - var ref = workInProgress.ref; + if (typeof Component.getDerivedStateFromProps === "function") { + var _componentName2 = getComponentName(Component) || "Unknown"; + + if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2]) { + warningWithoutStack$1( + false, + "%s: Function components do not support getDerivedStateFromProps.", + _componentName2 + ); + didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2] = true; + } + } if ( - (current === null && ref !== null) || - (current !== null && current.ref !== ref) + typeof Component.contextType === "object" && + Component.contextType !== null ) { - // Schedule a Ref effect - workInProgress.effectTag |= Ref; + var _componentName3 = getComponentName(Component) || "Unknown"; + + if (!didWarnAboutContextTypeOnFunctionComponent[_componentName3]) { + warningWithoutStack$1( + false, + "%s: Function components do not support contextType.", + _componentName3 + ); + didWarnAboutContextTypeOnFunctionComponent[_componentName3] = true; + } } } -function updateFunctionComponent( - current, +var SUSPENDED_MARKER = { + dehydrated: null, + retryTime: NoWork +}; + +function shouldRemainOnFallback(suspenseContext, current$$1, workInProgress) { + // If the context is telling us that we should show a fallback, and we're not + // already showing content, then we should show the fallback instead. + return ( + hasSuspenseContext(suspenseContext, ForceSuspenseFallback) && + (current$$1 === null || current$$1.memoizedState !== null) + ); +} + +function updateSuspenseComponent( + current$$1, workInProgress, - Component, - nextProps, renderExpirationTime ) { + var mode = workInProgress.mode; + var nextProps = workInProgress.pendingProps; // This is used by DevTools to force a boundary to suspend. + { - 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 (shouldSuspend(workInProgress)) { + workInProgress.effectTag |= DidCapture; + } + } - if (innerPropTypes) { - checkPropTypes( - innerPropTypes, - nextProps, // Resolved props - "prop", - getComponentName(Component) + var suspenseContext = suspenseStackCursor.current; + var nextDidTimeout = false; + var didSuspend = (workInProgress.effectTag & DidCapture) !== NoEffect; + + if ( + didSuspend || + shouldRemainOnFallback(suspenseContext, current$$1, workInProgress) + ) { + // Something in this boundary's subtree already suspended. Switch to + // rendering the fallback children. + nextDidTimeout = true; + workInProgress.effectTag &= ~DidCapture; + } else { + // Attempting the main content + if (current$$1 === null || current$$1.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 context; + suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); + pushSuspenseContext(workInProgress, suspenseContext); { - var unmaskedContext = getUnmaskedContext(workInProgress, Component, true); - context = getMaskedContext(workInProgress, unmaskedContext); - } + if ("maxDuration" in nextProps) { + if (!didWarnAboutMaxDuration) { + didWarnAboutMaxDuration = true; + warning$1( + false, + "maxDuration has been removed from React. " + + "Remove the maxDuration prop." + ); + } + } + } // This next part is a bit confusing. If the children timeout, we switch to + // showing the fallback children in place of the "primary" children. + // However, we don't want to delete the primary children because then their + // state will be lost (both the React state and the host state, e.g. + // uncontrolled form inputs). Instead we keep them mounted and hide them. + // Both the fallback children AND the primary children are rendered at the + // same time. Once the primary children are un-suspended, we can delete + // the fallback children — don't need to preserve their state. + // + // The two sets of children are siblings in the host environment, but + // semantically, for purposes of reconciliation, they are two separate sets. + // So we store them using two fragment fibers. + // + // However, we want to avoid allocating extra fibers for every placeholder. + // They're only necessary when the children time out, because that's the + // only time when both sets are mounted. + // + // So, the extra fragment fibers are only used if the children time out. + // Otherwise, we render the primary children directly. This requires some + // custom reconciliation logic to preserve the state of the primary + // children. It's essentially a very basic form of re-parenting. - var nextChildren; - prepareToReadContext(workInProgress, renderExpirationTime); + if (current$$1 === null) { + // If we're currently hydrating, try to hydrate this boundary. + // But only if this has a fallback. + if (nextProps.fallback !== undefined) { + tryToClaimNextHydratableInstance(workInProgress); // This could've been a dehydrated suspense component. - { - ReactCurrentOwner$1.current = workInProgress; - setIsRendering(true); - nextChildren = renderWithHooks( - current, - workInProgress, - Component, - nextProps, - context, - renderExpirationTime - ); + if (enableSuspenseServerRenderer) { + var suspenseState = workInProgress.memoizedState; - if (workInProgress.mode & StrictMode) { - // Only double-render components with Hooks - if (workInProgress.memoizedState !== null) { - nextChildren = renderWithHooks( - current, - workInProgress, - Component, - nextProps, - context, - renderExpirationTime - ); + if (suspenseState !== null) { + var dehydrated = suspenseState.dehydrated; + + if (dehydrated !== null) { + return mountDehydratedSuspenseComponent( + workInProgress, + dehydrated, + renderExpirationTime + ); + } + } } - } + } // This is the initial mount. This branch is pretty simple because there's + // no previous state that needs to be preserved. - setIsRendering(false); - } + if (nextDidTimeout) { + // Mount separate fragments for primary and fallback children. + var nextFallbackChildren = nextProps.fallback; + var primaryChildFragment = createFiberFromFragment( + null, + mode, + NoWork, + null + ); + primaryChildFragment.return = workInProgress; - if (current !== null && !didReceiveUpdate) { - bailoutHooks(current, workInProgress, renderExpirationTime); - return bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderExpirationTime - ); - } // React DevTools reads this flag. + if ((workInProgress.mode & BlockingMode) === NoMode) { + // Outside of blocking mode, we commit the effects from the + // partially completed, timed-out tree, too. + var progressedState = workInProgress.memoizedState; + var progressedPrimaryChild = + progressedState !== null + ? workInProgress.child.child + : workInProgress.child; + primaryChildFragment.child = progressedPrimaryChild; + var progressedChild = progressedPrimaryChild; + while (progressedChild !== null) { + progressedChild.return = primaryChildFragment; + progressedChild = progressedChild.sibling; + } + } - workInProgress.effectTag |= PerformedWork; - reconcileChildren( - current, - workInProgress, - nextChildren, - renderExpirationTime - ); - return workInProgress.child; -} + var fallbackChildFragment = createFiberFromFragment( + nextFallbackChildren, + mode, + renderExpirationTime, + null + ); + fallbackChildFragment.return = workInProgress; + primaryChildFragment.sibling = fallbackChildFragment; // Skip the primary children, and continue working on the + // fallback children. -function updateClassComponent( - current, - workInProgress, - Component, - nextProps, - renderExpirationTime -) { - { - 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.memoizedState = SUSPENDED_MARKER; + workInProgress.child = primaryChildFragment; + return fallbackChildFragment; + } else { + // Mount the primary children without an intermediate fragment fiber. + var nextPrimaryChildren = nextProps.children; + workInProgress.memoizedState = null; + return (workInProgress.child = mountChildFibers( + workInProgress, + null, + nextPrimaryChildren, + renderExpirationTime + )); + } + } else { + // This is an update. This branch is more complicated because we need to + // ensure the state of the primary children is preserved. + var prevState = current$$1.memoizedState; + + if (prevState !== null) { + if (enableSuspenseServerRenderer) { + var _dehydrated = prevState.dehydrated; + + if (_dehydrated !== null) { + if (!didSuspend) { + return updateDehydratedSuspenseComponent( + current$$1, + workInProgress, + _dehydrated, + prevState, + renderExpirationTime + ); + } else if (workInProgress.memoizedState !== null) { + // Something suspended and we should still be in dehydrated mode. + // Leave the existing child in place. + workInProgress.child = current$$1.child; // The dehydrated completion pass expects this flag to be there + // but the normal suspense pass doesn't. + + workInProgress.effectTag |= DidCapture; + return null; + } else { + // Suspended but we should no longer be in dehydrated mode. + // Therefore we now have to render the fallback. Wrap the children + // in a fragment fiber to keep them separate from the fallback + // children. + var _nextFallbackChildren = nextProps.fallback; + + var _primaryChildFragment = createFiberFromFragment( + // It shouldn't matter what the pending props are because we aren't + // going to render this fragment. + null, + mode, + NoWork, + null + ); - 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. + _primaryChildFragment.return = workInProgress; // This is always null since we never want the previous child + // that we're not going to hydrate. - var hasContext; + _primaryChildFragment.child = null; - if (isContextProvider(Component)) { - hasContext = true; - pushContextProvider(workInProgress); - } else { - hasContext = false; - } + if ((workInProgress.mode & BlockingMode) === NoMode) { + // Outside of blocking mode, we commit the effects from the + // partially completed, timed-out tree, too. + var _progressedChild = (_primaryChildFragment.child = + workInProgress.child); - prepareToReadContext(workInProgress, renderExpirationTime); - var instance = workInProgress.stateNode; - var shouldUpdate; + while (_progressedChild !== null) { + _progressedChild.return = _primaryChildFragment; + _progressedChild = _progressedChild.sibling; + } + } else { + // We will have dropped the effect list which contains the deletion. + // We need to reconcile to delete the current child. + reconcileChildFibers( + workInProgress, + current$$1.child, + null, + renderExpirationTime + ); + } // Because primaryChildFragment is a new fiber that we're inserting as the + // parent of a new tree, we need to set its treeBaseDuration. - 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 (enableProfilerTimer && workInProgress.mode & ProfileMode) { + // treeBaseDuration is the sum of all the child tree base durations. + var treeBaseDuration = 0; + var hiddenChild = _primaryChildFragment.child; - workInProgress.effectTag |= Placement; - } // In the initial pass we might need to construct the instance. + while (hiddenChild !== null) { + treeBaseDuration += hiddenChild.treeBaseDuration; + hiddenChild = hiddenChild.sibling; + } - constructClassInstance(workInProgress, Component, nextProps); - mountClassInstance( - workInProgress, - Component, - nextProps, - renderExpirationTime - ); - shouldUpdate = true; - } else if (current === null) { - // In a resume, we'll already have an instance we can reuse. - shouldUpdate = resumeMountClassInstance( - workInProgress, - Component, - nextProps, - renderExpirationTime - ); - } else { - shouldUpdate = updateClassInstance( - current, - workInProgress, - Component, - nextProps, - renderExpirationTime - ); - } + _primaryChildFragment.treeBaseDuration = treeBaseDuration; + } // Create a fragment from the fallback children, too. - var nextUnitOfWork = finishClassComponent( - current, - workInProgress, - Component, - shouldUpdate, - hasContext, - renderExpirationTime - ); + var _fallbackChildFragment = createFiberFromFragment( + _nextFallbackChildren, + mode, + renderExpirationTime, + null + ); - { - var inst = workInProgress.stateNode; + _fallbackChildFragment.return = workInProgress; + _primaryChildFragment.sibling = _fallbackChildFragment; + _fallbackChildFragment.effectTag |= Placement; + _primaryChildFragment.childExpirationTime = NoWork; + workInProgress.memoizedState = SUSPENDED_MARKER; + workInProgress.child = _primaryChildFragment; // Skip the primary children, and continue working on the + // fallback children. - if (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" - ); - } + return _fallbackChildFragment; + } + } + } // The current tree already timed out. That means each child set is + // wrapped in a fragment fiber. - didWarnAboutReassigningProps = true; - } - } + var currentPrimaryChildFragment = current$$1.child; + var currentFallbackChildFragment = currentPrimaryChildFragment.sibling; - return nextUnitOfWork; -} + if (nextDidTimeout) { + // Still timed out. Reuse the current primary children by cloning + // its fragment. We're going to skip over these entirely. + var _nextFallbackChildren2 = nextProps.fallback; -function finishClassComponent( - current, - workInProgress, - Component, - shouldUpdate, - hasContext, - renderExpirationTime -) { - // Refs should update even if shouldComponentUpdate returns false - markRef(current, workInProgress); - var didCaptureError = (workInProgress.effectTag & DidCapture) !== NoEffect; + var _primaryChildFragment2 = createWorkInProgress( + currentPrimaryChildFragment, + currentPrimaryChildFragment.pendingProps, + NoWork + ); - if (!shouldUpdate && !didCaptureError) { - // Context providers should defer to sCU for rendering - if (hasContext) { - invalidateContextProvider(workInProgress, Component, false); - } + _primaryChildFragment2.return = workInProgress; - return bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderExpirationTime - ); - } + if ((workInProgress.mode & BlockingMode) === NoMode) { + // Outside of blocking mode, we commit the effects from the + // partially completed, timed-out tree, too. + var _progressedState = workInProgress.memoizedState; - var instance = workInProgress.stateNode; // Rerender + var _progressedPrimaryChild = + _progressedState !== null + ? workInProgress.child.child + : workInProgress.child; - ReactCurrentOwner$1.current = workInProgress; - var nextChildren; + if (_progressedPrimaryChild !== currentPrimaryChildFragment.child) { + _primaryChildFragment2.child = _progressedPrimaryChild; + var _progressedChild2 = _progressedPrimaryChild; - if ( - didCaptureError && - typeof Component.getDerivedStateFromError !== "function" - ) { - // If we captured an error, but getDerivedStateFromError is not defined, - // unmount all the children. componentDidCatch will schedule an update to - // re-render a fallback. This is temporary until we migrate everyone to - // the new API. - // TODO: Warn in a future release. - nextChildren = null; + while (_progressedChild2 !== null) { + _progressedChild2.return = _primaryChildFragment2; + _progressedChild2 = _progressedChild2.sibling; + } + } + } // Because primaryChildFragment is a new fiber that we're inserting as the + // parent of a new tree, we need to set its treeBaseDuration. - { - stopProfilerTimerIfRunning(); - } - } else { - { - setIsRendering(true); - nextChildren = instance.render(); + if (enableProfilerTimer && workInProgress.mode & ProfileMode) { + // treeBaseDuration is the sum of all the child tree base durations. + var _treeBaseDuration = 0; + var _hiddenChild = _primaryChildFragment2.child; - if (workInProgress.mode & StrictMode) { - instance.render(); - } + while (_hiddenChild !== null) { + _treeBaseDuration += _hiddenChild.treeBaseDuration; + _hiddenChild = _hiddenChild.sibling; + } - setIsRendering(false); - } - } // React DevTools reads this flag. + _primaryChildFragment2.treeBaseDuration = _treeBaseDuration; + } // Clone the fallback child fragment, too. These we'll continue + // working on. - workInProgress.effectTag |= PerformedWork; + var _fallbackChildFragment2 = createWorkInProgress( + currentFallbackChildFragment, + _nextFallbackChildren2, + currentFallbackChildFragment.expirationTime + ); - 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, - renderExpirationTime - ); - } else { - reconcileChildren( - current, - workInProgress, - nextChildren, - renderExpirationTime - ); - } // Memoize state using the values we just used to render. - // TODO: Restructure so we never read values from the instance. + _fallbackChildFragment2.return = workInProgress; + _primaryChildFragment2.sibling = _fallbackChildFragment2; + _primaryChildFragment2.childExpirationTime = NoWork; // Skip the primary children, and continue working on the + // fallback children. - workInProgress.memoizedState = instance.state; // The context might have changed so we need to recalculate it. + workInProgress.memoizedState = SUSPENDED_MARKER; + workInProgress.child = _primaryChildFragment2; + return _fallbackChildFragment2; + } else { + // No longer suspended. Switch back to showing the primary children, + // and remove the intermediate fragment fiber. + var _nextPrimaryChildren = nextProps.children; + var currentPrimaryChild = currentPrimaryChildFragment.child; + var primaryChild = reconcileChildFibers( + workInProgress, + currentPrimaryChild, + _nextPrimaryChildren, + renderExpirationTime + ); // If this render doesn't suspend, we need to delete the fallback + // children. Wait until the complete phase, after we've confirmed the + // fallback is no longer needed. + // TODO: Would it be better to store the fallback fragment on + // the stateNode? + // Continue rendering the children, like we normally do. - if (hasContext) { - invalidateContextProvider(workInProgress, Component, true); - } + workInProgress.memoizedState = null; + return (workInProgress.child = primaryChild); + } + } else { + // The current tree has not already timed out. That means the primary + // children are not wrapped in a fragment fiber. + var _currentPrimaryChild = current$$1.child; - return workInProgress.child; -} + if (nextDidTimeout) { + // Timed out. Wrap the children in a fragment fiber to keep them + // separate from the fallback children. + var _nextFallbackChildren3 = nextProps.fallback; -function pushHostRootContext(workInProgress) { - var root = workInProgress.stateNode; + var _primaryChildFragment3 = createFiberFromFragment( + // It shouldn't matter what the pending props are because we aren't + // going to render this fragment. + null, + mode, + NoWork, + null + ); - if (root.pendingContext) { - pushTopLevelContextObject( - workInProgress, - root.pendingContext, - root.pendingContext !== root.context - ); - } else if (root.context) { - // Should always be set - pushTopLevelContextObject(workInProgress, root.context, false); - } + _primaryChildFragment3.return = workInProgress; + _primaryChildFragment3.child = _currentPrimaryChild; - pushHostContainer(workInProgress, root.containerInfo); -} + if (_currentPrimaryChild !== null) { + _currentPrimaryChild.return = _primaryChildFragment3; + } // Even though we're creating a new fiber, there are no new children, + // because we're reusing an already mounted tree. So we don't need to + // schedule a placement. + // primaryChildFragment.effectTag |= Placement; + + if ((workInProgress.mode & BlockingMode) === NoMode) { + // Outside of blocking mode, we commit the effects from the + // partially completed, timed-out tree, too. + var _progressedState2 = workInProgress.memoizedState; + + var _progressedPrimaryChild2 = + _progressedState2 !== null + ? workInProgress.child.child + : workInProgress.child; -function updateHostRoot(current, workInProgress, renderExpirationTime) { - pushHostRootContext(workInProgress); - var updateQueue = workInProgress.updateQueue; + _primaryChildFragment3.child = _progressedPrimaryChild2; + var _progressedChild3 = _progressedPrimaryChild2; - 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 (_progressedChild3 !== null) { + _progressedChild3.return = _primaryChildFragment3; + _progressedChild3 = _progressedChild3.sibling; + } + } // Because primaryChildFragment is a new fiber that we're inserting as the + // parent of a new tree, we need to set its treeBaseDuration. - var nextProps = workInProgress.pendingProps; - var prevState = workInProgress.memoizedState; - var prevChildren = prevState !== null ? prevState.element : null; - cloneUpdateQueue(current, workInProgress); - processUpdateQueue(workInProgress, nextProps, null, renderExpirationTime); - var nextState = workInProgress.memoizedState; // Caution: React DevTools currently depends on this property - // being called "element". + if (enableProfilerTimer && workInProgress.mode & ProfileMode) { + // treeBaseDuration is the sum of all the child tree base durations. + var _treeBaseDuration2 = 0; + var _hiddenChild2 = _primaryChildFragment3.child; - var nextChildren = nextState.element; + while (_hiddenChild2 !== null) { + _treeBaseDuration2 += _hiddenChild2.treeBaseDuration; + _hiddenChild2 = _hiddenChild2.sibling; + } - if (nextChildren === prevChildren) { - return bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderExpirationTime - ); - } + _primaryChildFragment3.treeBaseDuration = _treeBaseDuration2; + } // Create a fragment from the fallback children, too. - var root = workInProgress.stateNode; + var _fallbackChildFragment3 = createFiberFromFragment( + _nextFallbackChildren3, + mode, + renderExpirationTime, + null + ); - if (root.hydrate && enterHydrationState()) { - // If we don't have any current children this might be the first pass. - // We always try to hydrate. If this isn't a hydration pass there won't - // be any children to hydrate which is effectively the same thing as - // not hydrating. - var child = mountChildFibers( - workInProgress, - null, - nextChildren, - renderExpirationTime - ); - workInProgress.child = child; - var node = child; + _fallbackChildFragment3.return = workInProgress; + _primaryChildFragment3.sibling = _fallbackChildFragment3; + _fallbackChildFragment3.effectTag |= Placement; + _primaryChildFragment3.childExpirationTime = NoWork; // Skip the primary children, and continue working on the + // fallback children. - 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.effectTag = (node.effectTag & ~Placement) | Hydrating; - node = node.sibling; + workInProgress.memoizedState = SUSPENDED_MARKER; + workInProgress.child = _primaryChildFragment3; + return _fallbackChildFragment3; + } else { + // Still haven't timed out. Continue rendering the children, like we + // normally do. + workInProgress.memoizedState = null; + var _nextPrimaryChildren2 = nextProps.children; + return (workInProgress.child = reconcileChildFibers( + workInProgress, + _currentPrimaryChild, + _nextPrimaryChildren2, + renderExpirationTime + )); + } } - } else { - // Otherwise reset hydration state in case we aborted and resumed another - // root. - reconcileChildren( - current, - workInProgress, - nextChildren, - renderExpirationTime - ); } - - return workInProgress.child; } -function updateHostComponent(current, workInProgress, renderExpirationTime) { - pushHostContext(workInProgress); +function retrySuspenseComponentWithoutHydrating( + current$$1, + workInProgress, + renderExpirationTime +) { + // We're now not suspended nor dehydrated. + workInProgress.memoizedState = null; // Retry with the full children. - 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.effectTag |= ContentReset; - } - - markRef(current, workInProgress); // Check the host config to see if the children are offscreen/hidden. - - if ( - workInProgress.mode & ConcurrentMode && - renderExpirationTime !== Never && - shouldDeprioritizeSubtree() - ) { - { - markSpawnedWork(Never); - } // Schedule this fiber to re-render at offscreen priority. Then bailout. - - workInProgress.expirationTime = workInProgress.childExpirationTime = Never; - return null; - } + var nextChildren = nextProps.children; // This will ensure that the children get Placement effects and + // that the old child gets a Deletion effect. + // We could also call forceUnmountCurrentAndReconcile. reconcileChildren( - current, + current$$1, workInProgress, nextChildren, renderExpirationTime @@ -12356,3557 +14644,4293 @@ function updateHostComponent(current, workInProgress, renderExpirationTime) { return workInProgress.child; } -function updateHostText(current, workInProgress) { - // immediately after. - - return null; -} - -function mountLazyComponent( - _current, +function mountDehydratedSuspenseComponent( workInProgress, - elementType, - updateExpirationTime, + suspenseInstance, renderExpirationTime ) { - 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.effectTag |= Placement; - } - - var props = workInProgress.pendingProps; // We can't start a User Timing measurement with correct label yet. - // Cancel and resume right after we know the tag. - - cancelWorkTimer(workInProgress); - var Component = readLazyComponentType(elementType); // Store the unwrapped component in the type. - - workInProgress.type = Component; - var resolvedTag = (workInProgress.tag = resolveLazyComponentTag(Component)); - startWorkTimer(workInProgress); - 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, - renderExpirationTime + // During the first pass, we'll bail out and not drill into the children. + // Instead, we'll leave the content in place and try to hydrate it later. + if ((workInProgress.mode & BlockingMode) === NoMode) { + { + warning$1( + false, + "Cannot hydrate Suspense in legacy mode. Switch from " + + "ReactDOM.hydrate(element, container) to " + + "ReactDOM.createBlockingRoot(container, { hydrate: true })" + + ".render(element) or remove the Suspense components from " + + "the server rendered components." ); - return child; } - case ClassComponent: { - { - workInProgress.type = Component = resolveClassForHotReloading( - Component - ); - } + workInProgress.expirationTime = Sync; + } else if (isSuspenseInstanceFallback(suspenseInstance)) { + // This is a client-only boundary. Since we won't get any content from the server + // for this, we need to schedule that at a higher priority based on when it would + // have timed out. In theory we could render it in this pass but it would have the + // wrong priority associated with it and will prevent hydration of parent path. + // Instead, we'll leave work left on it to render it in a separate commit. + // TODO This time should be the time at which the server rendered response that is + // a parent to this boundary was displayed. However, since we currently don't have + // a protocol to transfer that time, we'll just estimate it by using the current + // time. This will mean that Suspense timeouts are slightly shifted to later than + // they should be. + var serverDisplayTime = requestCurrentTimeForUpdate(); // Schedule a normal pri update to render this content. - child = updateClassComponent( - null, - workInProgress, - Component, - resolvedProps, - renderExpirationTime - ); - return child; + var newExpirationTime = computeAsyncExpiration(serverDisplayTime); + + if (enableSchedulerTracing) { + markSpawnedWork(newExpirationTime); } - case ForwardRef: { - { - workInProgress.type = Component = resolveForwardRefForHotReloading( - Component - ); - } + workInProgress.expirationTime = newExpirationTime; + } else { + // We'll continue hydrating the rest at offscreen priority since we'll already + // be showing the right content coming from the server, it is no rush. + workInProgress.expirationTime = Never; - child = updateForwardRef( - null, - workInProgress, - Component, - resolvedProps, - renderExpirationTime - ); - return child; + if (enableSchedulerTracing) { + markSpawnedWork(Never); } + } - case MemoComponent: { - { - if (workInProgress.type !== workInProgress.elementType) { - var outerPropTypes = Component.propTypes; + return null; +} - if (outerPropTypes) { - checkPropTypes( - outerPropTypes, - resolvedProps, // Resolved for outer only - "prop", - getComponentName(Component) - ); - } - } - } +function updateDehydratedSuspenseComponent( + current$$1, + workInProgress, + suspenseInstance, + suspenseState, + renderExpirationTime +) { + // We should never be hydrating at this point because it is the first pass, + // but after we've already committed once. + warnIfHydrating(); - child = updateMemoComponent( - null, - workInProgress, - Component, - resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too - updateExpirationTime, - renderExpirationTime - ); - return child; - } + if ((workInProgress.mode & BlockingMode) === NoMode) { + return retrySuspenseComponentWithoutHydrating( + current$$1, + workInProgress, + renderExpirationTime + ); } - var hint = ""; + if (isSuspenseInstanceFallback(suspenseInstance)) { + // This boundary is in a permanent fallback state. In this case, we'll never + // get an update and we'll never be able to hydrate the final content. Let's just try the + // client side render instead. + return retrySuspenseComponentWithoutHydrating( + current$$1, + workInProgress, + renderExpirationTime + ); + } // We use childExpirationTime to indicate that a child might depend on context, so if + // any context has changed, we need to treat is as if the input might have changed. + + var hasContextChanged$$1 = + current$$1.childExpirationTime >= renderExpirationTime; + + if (didReceiveUpdate || hasContextChanged$$1) { + // This boundary has changed since the first render. This means that we are now unable to + // hydrate it. We might still be able to hydrate it using an earlier expiration time, if + // we are rendering at lower expiration than sync. + if (renderExpirationTime < Sync) { + if (suspenseState.retryTime <= renderExpirationTime) { + // This render is even higher pri than we've seen before, let's try again + // at even higher pri. + var attemptHydrationAtExpirationTime = renderExpirationTime + 1; + suspenseState.retryTime = attemptHydrationAtExpirationTime; + scheduleWork(current$$1, attemptHydrationAtExpirationTime); // TODO: Early abort this render. + } else { + // We have already tried to ping at a higher priority than we're rendering with + // so if we got here, we must have failed to hydrate at those levels. We must + // now give up. Instead, we're going to delete the whole subtree and instead inject + // a new real Suspense boundary to take its place, which may render content + // or fallback. This might suspend for a while and if it does we might still have + // an opportunity to hydrate before this pass commits. + } + } // If we have scheduled higher pri work above, this will probably just abort the render + // since we now have higher priority work, but in case it doesn't, we need to prepare to + // render something, if we time out. Even if that requires us to delete everything and + // skip hydration. + // Delay having to do this as long as the suspense timeout allows us. + + renderDidSuspendDelayIfPossible(); + return retrySuspenseComponentWithoutHydrating( + current$$1, + workInProgress, + renderExpirationTime + ); + } else if (isSuspenseInstancePending(suspenseInstance)) { + // This component is still pending more data from the server, so we can't hydrate its + // content. We treat it as if this component suspended itself. It might seem as if + // we could just try to render it client-side instead. However, this will perform a + // lot of unnecessary work and is unlikely to complete since it often will suspend + // on missing data anyway. Additionally, the server might be able to render more + // than we can on the client yet. In that case we'd end up with more fallback states + // on the client than if we just leave it alone. If the server times out or errors + // these should update this boundary to the permanent Fallback state instead. + // Mark it as having captured (i.e. suspended). + workInProgress.effectTag |= DidCapture; // Leave the child in place. I.e. the dehydrated fragment. + + workInProgress.child = current$$1.child; // Register a callback to retry this boundary once the server has sent the result. + + registerSuspenseInstanceRetry( + suspenseInstance, + retryDehydratedSuspenseBoundary.bind(null, current$$1) + ); + return null; + } else { + // This is the first attempt. + reenterHydrationStateFromDehydratedSuspenseInstance( + workInProgress, + suspenseInstance + ); + var nextProps = workInProgress.pendingProps; + var nextChildren = nextProps.children; + var child = mountChildFibers( + workInProgress, + null, + nextChildren, + renderExpirationTime + ); + var node = child; - { - if ( - Component !== null && - typeof Component === "object" && - Component.$$typeof === REACT_LAZY_TYPE - ) { - hint = " Did you wrap a component in React.lazy() more than once?"; + 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.effectTag |= Hydrating; + node = node.sibling; } - } // 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 - ); + workInProgress.child = child; + return workInProgress.child; } } -function mountIncompleteClassComponent( - _current, - workInProgress, - Component, - nextProps, - renderExpirationTime -) { - 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.effectTag |= 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. +function scheduleWorkOnFiber(fiber, renderExpirationTime) { + if (fiber.expirationTime < renderExpirationTime) { + fiber.expirationTime = renderExpirationTime; + } - var hasContext; + var alternate = fiber.alternate; - if (isContextProvider(Component)) { - hasContext = true; - pushContextProvider(workInProgress); - } else { - hasContext = false; + if (alternate !== null && alternate.expirationTime < renderExpirationTime) { + alternate.expirationTime = renderExpirationTime; } - prepareToReadContext(workInProgress, renderExpirationTime); - constructClassInstance(workInProgress, Component, nextProps); - mountClassInstance( - workInProgress, - Component, - nextProps, - renderExpirationTime - ); - return finishClassComponent( - null, - workInProgress, - Component, - true, - hasContext, - renderExpirationTime - ); + scheduleWorkOnParentPath(fiber.return, renderExpirationTime); } -function mountIndeterminateComponent( - _current, +function propagateSuspenseContextChange( workInProgress, - Component, + firstChild, renderExpirationTime ) { - 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.effectTag |= Placement; - } - - var props = workInProgress.pendingProps; - var context; - - { - var unmaskedContext = getUnmaskedContext(workInProgress, Component, false); - context = getMaskedContext(workInProgress, unmaskedContext); - } - - prepareToReadContext(workInProgress, renderExpirationTime); - var value; - - { - if ( - Component.prototype && - typeof Component.prototype.render === "function" - ) { - var componentName = getComponentName(Component) || "Unknown"; + // 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 (!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 - ); + while (node !== null) { + if (node.tag === SuspenseComponent) { + var state = node.memoizedState; - didWarnAboutBadClass[componentName] = true; + if (state !== null) { + scheduleWorkOnFiber(node, renderExpirationTime); } + } 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, renderExpirationTime); + } else if (node.child !== null) { + node.child.return = node; + node = node.child; + continue; } - if (workInProgress.mode & StrictMode) { - ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null); + if (node === workInProgress) { + return; } - ReactCurrentOwner$1.current = workInProgress; - value = renderWithHooks( - null, - workInProgress, - Component, - props, - context, - renderExpirationTime - ); - } // React DevTools reads this flag. + while (node.sibling === null) { + if (node.return === null || node.return === workInProgress) { + return; + } - workInProgress.effectTag |= PerformedWork; + node = node.return; + } - if ( - typeof value === "object" && - value !== null && - typeof value.render === "function" && - value.$$typeof === undefined - ) { - { - var _componentName = getComponentName(Component) || "Unknown"; + node.sibling.return = node.return; + node = node.sibling; + } +} - 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 - ); +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; - didWarnAboutModulePatternComponent[_componentName] = true; - } - } // Proceed under the assumption that this is a class instance + while (row !== null) { + var currentRow = row.alternate; // New rows can't be content rows. - workInProgress.tag = ClassComponent; // Throw out any hooks that were used. + if (currentRow !== null && findFirstSuspended(currentRow) === null) { + lastContentRow = row; + } - 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. + row = row.sibling; + } - var hasContext = false; + return lastContentRow; +} - if (isContextProvider(Component)) { - hasContext = true; - pushContextProvider(workInProgress); - } else { - hasContext = false; +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": { + warning$1( + false, + '"%s" is not a valid value for revealOrder on . ' + + 'Use lowercase "%s" instead.', + revealOrder, + revealOrder.toLowerCase() + ); + break; + } + case "forward": + case "backward": { + warning$1( + false, + '"%s" is not a valid value for revealOrder on . ' + + 'React uses the -s suffix in the spelling. Use "%ss" instead.', + revealOrder, + revealOrder.toLowerCase() + ); + break; + } + default: + warning$1( + false, + '"%s" is not a supported revealOrder on . ' + + 'Did you mean "together", "forwards" or "backwards"?', + revealOrder + ); + break; + } + } else { + warning$1( + false, + "%s is not a supported value for revealOrder on . " + + 'Did you mean "together", "forwards" or "backwards"?', + revealOrder + ); + } } + } +} - workInProgress.memoizedState = - value.state !== null && value.state !== undefined ? value.state : null; - initializeUpdateQueue(workInProgress); - var getDerivedStateFromProps = Component.getDerivedStateFromProps; +function validateTailOptions(tailMode, revealOrder) { + { + if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) { + if (tailMode !== "collapsed" && tailMode !== "hidden") { + didWarnAboutTailOptions[tailMode] = true; + warning$1( + false, + '"%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; + warning$1( + false, + ' is only valid if revealOrder is ' + + '"forwards" or "backwards". ' + + 'Did you mean to specify revealOrder="forwards"?', + tailMode + ); + } + } + } +} - if (typeof getDerivedStateFromProps === "function") { - applyDerivedStateFromProps( - workInProgress, - Component, - getDerivedStateFromProps, - props +function validateSuspenseListNestedChild(childSlot, index) { + { + var isArray = Array.isArray(childSlot); + var isIterable = !isArray && typeof getIteratorFn(childSlot) === "function"; + if (isArray || isIterable) { + var type = isArray ? "array" : "iterable"; + warning$1( + false, + "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; } + } + return true; +} - adoptClassInstance(workInProgress, value); - mountClassInstance(workInProgress, Component, props, renderExpirationTime); - return finishClassComponent( - null, - workInProgress, - Component, - true, - hasContext, - renderExpirationTime - ); - } else { - // Proceed under the assumption that this is a function component - workInProgress.tag = FunctionComponent; +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 (workInProgress.mode & StrictMode) { - // Only double-render components with Hooks - if (workInProgress.memoizedState !== null) { - value = renderWithHooks( - null, - workInProgress, - Component, - props, - context, - renderExpirationTime + if (typeof iteratorFn === "function") { + var childrenIterator = iteratorFn.call(children); + + if (childrenIterator) { + var step = childrenIterator.next(); + var _i = 0; + + for (; !step.done; step = childrenIterator.next()) { + if (!validateSuspenseListNestedChild(step.value, _i)) { + return; + } + _i++; + } + } + } else { + warning$1( + false, + '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 ); } } } + } +} - reconcileChildren(null, workInProgress, value, renderExpirationTime); +function initSuspenseListRenderState( + workInProgress, + isBackwards, + tail, + lastContentRow, + tailMode, + lastEffectBeforeRendering +) { + var renderState = workInProgress.memoizedState; - { - validateFunctionComponentInDev(workInProgress, Component); + if (renderState === null) { + workInProgress.memoizedState = { + isBackwards: isBackwards, + rendering: null, + last: lastContentRow, + tail: tail, + tailExpiration: 0, + tailMode: tailMode, + lastEffect: lastEffectBeforeRendering + }; + } else { + // We can reuse the existing object from previous renders. + renderState.isBackwards = isBackwards; + renderState.rendering = null; + renderState.last = lastContentRow; + renderState.tail = tail; + renderState.tailExpiration = 0; + 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$$1, + workInProgress, + renderExpirationTime +) { + 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$$1, + workInProgress, + newChildren, + renderExpirationTime + ); + var suspenseContext = suspenseStackCursor.current; + var shouldForceFallback = hasSuspenseContext( + suspenseContext, + ForceSuspenseFallback + ); + if (shouldForceFallback) { + suspenseContext = setShallowSuspenseContext( + suspenseContext, + ForceSuspenseFallback + ); + workInProgress.effectTag |= DidCapture; + } else { + var didSuspendBefore = + current$$1 !== null && (current$$1.effectTag & DidCapture) !== NoEffect; + 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, + renderExpirationTime + ); } - return workInProgress.child; + suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); } -} -function validateFunctionComponentInDev(workInProgress, Component) { - { - if (Component) { - if (Component.childContextTypes) { - error( - "%s(...): childContextTypes cannot be defined on a function component.", - Component.displayName || Component.name || "Component" - ); - } - } + pushSuspenseContext(workInProgress, suspenseContext); - if (workInProgress.ref !== null) { - var info = ""; - var ownerName = getCurrentFiberOwnerNameInDevOrNull(); + if ((workInProgress.mode & BlockingMode) === NoMode) { + // Outside of blocking 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 (ownerName) { - info += "\n\nCheck the render method of `" + ownerName + "`."; + 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; } - var warningKey = ownerName || workInProgress._debugID || ""; - var debugSource = workInProgress._debugSource; + 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 (debugSource) { - warningKey = debugSource.fileName + ":" + debugSource.lineNumber; - } + while (row !== null) { + var currentRow = row.alternate; // New rows can't be content rows. - if (!didWarnAboutFunctionRefs[warningKey]) { - didWarnAboutFunctionRefs[warningKey] = true; + 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. - error( - "Function components cannot be given refs. " + - "Attempts to access this ref will fail. " + - "Did you mean to use React.forwardRef()?%s", - info + initSuspenseListRenderState( + workInProgress, + true, // isBackwards + _tail, + null, // last + tailMode, + workInProgress.lastEffect ); + break; } - } - if (typeof Component.getDerivedStateFromProps === "function") { - var _componentName2 = getComponentName(Component) || "Unknown"; - - if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2]) { - error( - "%s: Function components do not support getDerivedStateFromProps.", - _componentName2 + case "together": { + initSuspenseListRenderState( + workInProgress, + false, // isBackwards + null, // tail + null, // last + undefined, + workInProgress.lastEffect ); - - didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2] = true; + break; } - } - if ( - typeof Component.contextType === "object" && - Component.contextType !== null - ) { - var _componentName3 = getComponentName(Component) || "Unknown"; - - if (!didWarnAboutContextTypeOnFunctionComponent[_componentName3]) { - error( - "%s: Function components do not support contextType.", - _componentName3 - ); - - didWarnAboutContextTypeOnFunctionComponent[_componentName3] = true; + default: { + // The default reveal order is the same as not having + // a boundary. + workInProgress.memoizedState = null; } } } + return workInProgress.child; } -var SUSPENDED_MARKER = { - dehydrated: null, - retryTime: NoWork -}; - -function shouldRemainOnFallback(suspenseContext, current, workInProgress) { - // If the context is telling us that we should show a fallback, and we're not - // already showing content, then we should show the fallback instead. - return ( - hasSuspenseContext(suspenseContext, ForceSuspenseFallback) && - (current === null || current.memoizedState !== null) - ); +function updatePortalComponent( + current$$1, + workInProgress, + renderExpirationTime +) { + pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); + var nextChildren = workInProgress.pendingProps; + if (current$$1 === 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, + renderExpirationTime + ); + } else { + reconcileChildren( + current$$1, + workInProgress, + nextChildren, + renderExpirationTime + ); + } + return workInProgress.child; } -function updateSuspenseComponent( - current, +function updateContextProvider( + current$$1, workInProgress, renderExpirationTime ) { - var mode = workInProgress.mode; - var nextProps = workInProgress.pendingProps; // This is used by DevTools to force a boundary to suspend. + var providerType = workInProgress.type; + var context = providerType._context; + var newProps = workInProgress.pendingProps; + var oldProps = workInProgress.memoizedProps; + var newValue = newProps.value; { - if (shouldSuspend(workInProgress)) { - workInProgress.effectTag |= DidCapture; + var providerPropTypes = workInProgress.type.propTypes; + + if (providerPropTypes) { + checkPropTypes( + providerPropTypes, + newProps, + "prop", + "Context.Provider", + getCurrentFiberStackInDev + ); } } - var suspenseContext = suspenseStackCursor.current; - var nextDidTimeout = false; - var didSuspend = (workInProgress.effectTag & DidCapture) !== NoEffect; + pushProvider(workInProgress, newValue); - if (didSuspend || shouldRemainOnFallback(suspenseContext, current)) { - // Something in this boundary's subtree already suspended. Switch to - // rendering the fallback children. - nextDidTimeout = true; - workInProgress.effectTag &= ~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 + 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$$1, + workInProgress, + renderExpirationTime ); } + } else { + // The context value changed. Search for matching consumers and schedule + // them to update. + propagateContextChange( + workInProgress, + context, + changedBits, + renderExpirationTime + ); } } - suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); - pushSuspenseContext(workInProgress, suspenseContext); // This next part is a bit confusing. If the children timeout, we switch to - // showing the fallback children in place of the "primary" children. - // However, we don't want to delete the primary children because then their - // state will be lost (both the React state and the host state, e.g. - // uncontrolled form inputs). Instead we keep them mounted and hide them. - // Both the fallback children AND the primary children are rendered at the - // same time. Once the primary children are un-suspended, we can delete - // the fallback children — don't need to preserve their state. - // - // The two sets of children are siblings in the host environment, but - // semantically, for purposes of reconciliation, they are two separate sets. - // So we store them using two fragment fibers. - // - // However, we want to avoid allocating extra fibers for every placeholder. - // They're only necessary when the children time out, because that's the - // only time when both sets are mounted. - // - // So, the extra fragment fibers are only used if the children time out. - // Otherwise, we render the primary children directly. This requires some - // custom reconciliation logic to preserve the state of the primary - // children. It's essentially a very basic form of re-parenting. - - if (current === null) { - // If we're currently hydrating, try to hydrate this boundary. - // But only if this has a fallback. - if (nextProps.fallback !== undefined); // This is the initial mount. This branch is pretty simple because there's - // no previous state that needs to be preserved. - - if (nextDidTimeout) { - // Mount separate fragments for primary and fallback children. - var nextFallbackChildren = nextProps.fallback; - var primaryChildFragment = createFiberFromFragment( - null, - mode, - NoWork, - null - ); - primaryChildFragment.return = workInProgress; + var newChildren = newProps.children; + reconcileChildren( + current$$1, + workInProgress, + newChildren, + renderExpirationTime + ); + return workInProgress.child; +} - if ((workInProgress.mode & BlockingMode) === NoMode) { - // Outside of blocking mode, we commit the effects from the - // partially completed, timed-out tree, too. - var progressedState = workInProgress.memoizedState; - var progressedPrimaryChild = - progressedState !== null - ? workInProgress.child.child - : workInProgress.child; - primaryChildFragment.child = progressedPrimaryChild; - var progressedChild = progressedPrimaryChild; +var hasWarnedAboutUsingContextAsConsumer = false; - while (progressedChild !== null) { - progressedChild.return = primaryChildFragment; - progressedChild = progressedChild.sibling; +function updateContextConsumer( + current$$1, + workInProgress, + renderExpirationTime +) { + 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; + warning$1( + false, + "Rendering directly is not supported and will be removed in " + + "a future major release. Did you mean to render instead?" + ); } } - - var fallbackChildFragment = createFiberFromFragment( - nextFallbackChildren, - mode, - renderExpirationTime, - null - ); - fallbackChildFragment.return = workInProgress; - primaryChildFragment.sibling = fallbackChildFragment; // Skip the primary children, and continue working on the - // fallback children. - - workInProgress.memoizedState = SUSPENDED_MARKER; - workInProgress.child = primaryChildFragment; - return fallbackChildFragment; } else { - // Mount the primary children without an intermediate fragment fiber. - var nextPrimaryChildren = nextProps.children; - workInProgress.memoizedState = null; - return (workInProgress.child = mountChildFibers( - workInProgress, - null, - nextPrimaryChildren, - renderExpirationTime - )); + context = context._context; } - } else { - // This is an update. This branch is more complicated because we need to - // ensure the state of the primary children is preserved. - var prevState = current.memoizedState; - - if (prevState !== null) { - // wrapped in a fragment fiber. - - var currentPrimaryChildFragment = current.child; - var currentFallbackChildFragment = currentPrimaryChildFragment.sibling; - - if (nextDidTimeout) { - // Still timed out. Reuse the current primary children by cloning - // its fragment. We're going to skip over these entirely. - var _nextFallbackChildren2 = nextProps.fallback; + } + var newProps = workInProgress.pendingProps; + var render = newProps.children; - var _primaryChildFragment2 = createWorkInProgress( - currentPrimaryChildFragment, - currentPrimaryChildFragment.pendingProps - ); + { + !(typeof render === "function") + ? warningWithoutStack$1( + false, + "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." + ) + : void 0; + } - _primaryChildFragment2.return = workInProgress; + prepareToReadContext(workInProgress, renderExpirationTime); + var newValue = readContext(context, newProps.unstable_observedBits); + var newChildren; - if ((workInProgress.mode & BlockingMode) === NoMode) { - // Outside of blocking mode, we commit the effects from the - // partially completed, timed-out tree, too. - var _progressedState = workInProgress.memoizedState; + { + ReactCurrentOwner$3.current = workInProgress; + setCurrentPhase("render"); + newChildren = render(newValue); + setCurrentPhase(null); + } // React DevTools reads this flag. - var _progressedPrimaryChild = - _progressedState !== null - ? workInProgress.child.child - : workInProgress.child; + workInProgress.effectTag |= PerformedWork; + reconcileChildren( + current$$1, + workInProgress, + newChildren, + renderExpirationTime + ); + return workInProgress.child; +} - if (_progressedPrimaryChild !== currentPrimaryChildFragment.child) { - _primaryChildFragment2.child = _progressedPrimaryChild; - var _progressedChild2 = _progressedPrimaryChild; +function updateFundamentalComponent$1( + current$$1, + workInProgress, + renderExpirationTime +) { + var fundamentalImpl = workInProgress.type.impl; - while (_progressedChild2 !== null) { - _progressedChild2.return = _primaryChildFragment2; - _progressedChild2 = _progressedChild2.sibling; - } - } - } // Because primaryChildFragment is a new fiber that we're inserting as the - // parent of a new tree, we need to set its treeBaseDuration. + if (fundamentalImpl.reconcileChildren === false) { + return null; + } - if (workInProgress.mode & ProfileMode) { - // treeBaseDuration is the sum of all the child tree base durations. - var _treeBaseDuration = 0; - var _hiddenChild = _primaryChildFragment2.child; + var nextProps = workInProgress.pendingProps; + var nextChildren = nextProps.children; + reconcileChildren( + current$$1, + workInProgress, + nextChildren, + renderExpirationTime + ); + return workInProgress.child; +} - while (_hiddenChild !== null) { - _treeBaseDuration += _hiddenChild.treeBaseDuration; - _hiddenChild = _hiddenChild.sibling; - } +function updateScopeComponent( + current$$1, + workInProgress, + renderExpirationTime +) { + var nextProps = workInProgress.pendingProps; + var nextChildren = nextProps.children; + reconcileChildren( + current$$1, + workInProgress, + nextChildren, + renderExpirationTime + ); + return workInProgress.child; +} - _primaryChildFragment2.treeBaseDuration = _treeBaseDuration; - } // Clone the fallback child fragment, too. These we'll continue - // working on. +function markWorkInProgressReceivedUpdate() { + didReceiveUpdate = true; +} - var _fallbackChildFragment2 = createWorkInProgress( - currentFallbackChildFragment, - _nextFallbackChildren2 - ); +function bailoutOnAlreadyFinishedWork( + current$$1, + workInProgress, + renderExpirationTime +) { + cancelWorkTimer(workInProgress); - _fallbackChildFragment2.return = workInProgress; - _primaryChildFragment2.sibling = _fallbackChildFragment2; - _primaryChildFragment2.childExpirationTime = NoWork; // Skip the primary children, and continue working on the - // fallback children. + if (current$$1 !== null) { + // Reuse previous dependencies + workInProgress.dependencies = current$$1.dependencies; + } - workInProgress.memoizedState = SUSPENDED_MARKER; - workInProgress.child = _primaryChildFragment2; - return _fallbackChildFragment2; - } else { - // No longer suspended. Switch back to showing the primary children, - // and remove the intermediate fragment fiber. - var _nextPrimaryChildren = nextProps.children; - var currentPrimaryChild = currentPrimaryChildFragment.child; - var primaryChild = reconcileChildFibers( - workInProgress, - currentPrimaryChild, - _nextPrimaryChildren, - renderExpirationTime - ); // If this render doesn't suspend, we need to delete the fallback - // children. Wait until the complete phase, after we've confirmed the - // fallback is no longer needed. - // TODO: Would it be better to store the fallback fragment on - // the stateNode? - // Continue rendering the children, like we normally do. + if (enableProfilerTimer) { + // Don't update "base" render times for bailouts. + stopProfilerTimerIfRunning(workInProgress); + } - workInProgress.memoizedState = null; - return (workInProgress.child = primaryChild); - } - } else { - // The current tree has not already timed out. That means the primary - // children are not wrapped in a fragment fiber. - var _currentPrimaryChild = current.child; + var updateExpirationTime = workInProgress.expirationTime; - if (nextDidTimeout) { - // Timed out. Wrap the children in a fragment fiber to keep them - // separate from the fallback children. - var _nextFallbackChildren3 = nextProps.fallback; + if (updateExpirationTime !== NoWork) { + markUnprocessedUpdateTime(updateExpirationTime); + } // Check if the children have any pending work. - var _primaryChildFragment3 = createFiberFromFragment( - // It shouldn't matter what the pending props are because we aren't - // going to render this fragment. - null, - mode, - NoWork, - null - ); + var childExpirationTime = workInProgress.childExpirationTime; - _primaryChildFragment3.return = workInProgress; - _primaryChildFragment3.child = _currentPrimaryChild; + if (childExpirationTime < renderExpirationTime) { + // 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$$1, workInProgress); + return workInProgress.child; + } +} - if (_currentPrimaryChild !== null) { - _currentPrimaryChild.return = _primaryChildFragment3; - } // Even though we're creating a new fiber, there are no new children, - // because we're reusing an already mounted tree. So we don't need to - // schedule a placement. - // primaryChildFragment.effectTag |= Placement; +function remountFiber(current$$1, oldWorkInProgress, newWorkInProgress) { + { + var returnFiber = oldWorkInProgress.return; - if ((workInProgress.mode & BlockingMode) === NoMode) { - // Outside of blocking mode, we commit the effects from the - // partially completed, timed-out tree, too. - var _progressedState2 = workInProgress.memoizedState; + if (returnFiber === null) { + throw new Error("Cannot swap the root fiber."); + } // Disconnect from the old current. + // It will get deleted. - var _progressedPrimaryChild2 = - _progressedState2 !== null - ? workInProgress.child.child - : workInProgress.child; + current$$1.alternate = null; + oldWorkInProgress.alternate = null; // Connect to the new tree. - _primaryChildFragment3.child = _progressedPrimaryChild2; - var _progressedChild3 = _progressedPrimaryChild2; + newWorkInProgress.index = oldWorkInProgress.index; + newWorkInProgress.sibling = oldWorkInProgress.sibling; + newWorkInProgress.return = oldWorkInProgress.return; + newWorkInProgress.ref = oldWorkInProgress.ref; // Replace the child/sibling pointers above it. - while (_progressedChild3 !== null) { - _progressedChild3.return = _primaryChildFragment3; - _progressedChild3 = _progressedChild3.sibling; - } - } // Because primaryChildFragment is a new fiber that we're inserting as the - // parent of a new tree, we need to set its treeBaseDuration. + if (oldWorkInProgress === returnFiber.child) { + returnFiber.child = newWorkInProgress; + } else { + var prevSibling = returnFiber.child; - if (workInProgress.mode & ProfileMode) { - // treeBaseDuration is the sum of all the child tree base durations. - var _treeBaseDuration2 = 0; - var _hiddenChild2 = _primaryChildFragment3.child; + if (prevSibling === null) { + throw new Error("Expected parent to have a child."); + } - while (_hiddenChild2 !== null) { - _treeBaseDuration2 += _hiddenChild2.treeBaseDuration; - _hiddenChild2 = _hiddenChild2.sibling; - } + while (prevSibling.sibling !== oldWorkInProgress) { + prevSibling = prevSibling.sibling; - _primaryChildFragment3.treeBaseDuration = _treeBaseDuration2; - } // Create a fragment from the fallback children, too. + if (prevSibling === null) { + throw new Error("Expected to find the previous sibling."); + } + } - var _fallbackChildFragment3 = createFiberFromFragment( - _nextFallbackChildren3, - mode, - renderExpirationTime, - null - ); + prevSibling.sibling = newWorkInProgress; + } // Delete the old fiber and place the new one. + // Since the old fiber is disconnected, we have to schedule it manually. - _fallbackChildFragment3.return = workInProgress; - _primaryChildFragment3.sibling = _fallbackChildFragment3; - _fallbackChildFragment3.effectTag |= Placement; - _primaryChildFragment3.childExpirationTime = NoWork; // Skip the primary children, and continue working on the - // fallback children. + var last = returnFiber.lastEffect; - workInProgress.memoizedState = SUSPENDED_MARKER; - workInProgress.child = _primaryChildFragment3; - return _fallbackChildFragment3; - } else { - // Still haven't timed out. Continue rendering the children, like we - // normally do. - workInProgress.memoizedState = null; - var _nextPrimaryChildren2 = nextProps.children; - return (workInProgress.child = reconcileChildFibers( - workInProgress, - _currentPrimaryChild, - _nextPrimaryChildren2, - renderExpirationTime - )); - } + if (last !== null) { + last.nextEffect = current$$1; + returnFiber.lastEffect = current$$1; + } else { + returnFiber.firstEffect = returnFiber.lastEffect = current$$1; } + + current$$1.nextEffect = null; + current$$1.effectTag = Deletion; + newWorkInProgress.effectTag |= Placement; // Restart work from the new fiber. + + return newWorkInProgress; } } -function scheduleWorkOnFiber(fiber, renderExpirationTime) { - if (fiber.expirationTime < renderExpirationTime) { - fiber.expirationTime = renderExpirationTime; +function beginWork$1(current$$1, workInProgress, renderExpirationTime) { + var updateExpirationTime = workInProgress.expirationTime; + + { + if (workInProgress._debugNeedsRemount && current$$1 !== null) { + // This will restart the begin phase with a new fiber. + return remountFiber( + current$$1, + workInProgress, + createFiberFromTypeAndProps( + workInProgress.type, + workInProgress.key, + workInProgress.pendingProps, + workInProgress._debugOwner || null, + workInProgress.mode, + workInProgress.expirationTime + ) + ); + } } - var alternate = fiber.alternate; + if (current$$1 !== null) { + var oldProps = current$$1.memoizedProps; + var newProps = workInProgress.pendingProps; - if (alternate !== null && alternate.expirationTime < renderExpirationTime) { - alternate.expirationTime = renderExpirationTime; - } + if ( + oldProps !== newProps || + hasContextChanged() || // Force a re-render if the implementation changed due to hot reload: + workInProgress.type !== current$$1.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 (updateExpirationTime < renderExpirationTime) { + 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. - scheduleWorkOnParentPath(fiber.return, renderExpirationTime); -} + switch (workInProgress.tag) { + case HostRoot: + pushHostRootContext(workInProgress); + resetHydrationState(); + break; -function propagateSuspenseContextChange( - workInProgress, - firstChild, - renderExpirationTime -) { - // 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; + case HostComponent: + pushHostContext(workInProgress); + + if ( + workInProgress.mode & ConcurrentMode && + renderExpirationTime !== Never && + shouldDeprioritizeSubtree(workInProgress.type, newProps) + ) { + if (enableSchedulerTracing) { + markSpawnedWork(Never); + } // Schedule this fiber to re-render at offscreen priority. Then bailout. - while (node !== null) { - if (node.tag === SuspenseComponent) { - var state = node.memoizedState; + workInProgress.expirationTime = workInProgress.childExpirationTime = Never; + return null; + } - if (state !== null) { - scheduleWorkOnFiber(node, renderExpirationTime); - } - } 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, renderExpirationTime); - } else if (node.child !== null) { - node.child.return = node; - node = node.child; - continue; - } + break; - if (node === workInProgress) { - return; - } + case ClassComponent: { + var Component = workInProgress.type; - while (node.sibling === null) { - if (node.return === null || node.return === workInProgress) { - return; - } + if (isContextProvider(Component)) { + pushContextProvider(workInProgress); + } - node = node.return; - } + break; + } - node.sibling.return = node.return; - node = node.sibling; - } -} + case HostPortal: + pushHostContainer( + workInProgress, + workInProgress.stateNode.containerInfo + ); + break; + case ContextProvider: { + var newValue = workInProgress.memoizedProps.value; + pushProvider(workInProgress, newValue); + break; + } -function findLastContentRow(firstChild) { - // This is going to find the last row among these children that is already - // showing content on the screen, as opposed to being in fallback state or - // new. If a row has multiple Suspense boundaries, any of them being in the - // fallback state, counts as the whole row being in a fallback state. - // Note that the "rows" will be workInProgress, but any nested children - // will still be current since we haven't rendered them yet. The mounted - // order may not be the same as the new order. We use the new order. - var row = firstChild; - var lastContentRow = null; + case Profiler: + if (enableProfilerTimer) { + // Profiler should only call onRender when one of its descendants actually rendered. + var hasChildWork = + workInProgress.childExpirationTime >= renderExpirationTime; - while (row !== null) { - var currentRow = row.alternate; // New rows can't be content rows. + if (hasChildWork) { + workInProgress.effectTag |= Update; + } + } - if (currentRow !== null && findFirstSuspended(currentRow) === null) { - lastContentRow = row; - } + break; - row = row.sibling; - } + case SuspenseComponent: { + var state = workInProgress.memoizedState; - return lastContentRow; -} + if (state !== null) { + if (enableSuspenseServerRenderer) { + if (state.dehydrated !== null) { + pushSuspenseContext( + workInProgress, + setDefaultShallowSuspenseContext(suspenseStackCursor.current) + ); // We know that this component will suspend again because if it has + // been unsuspended it has committed as a resolved Suspense component. + // If it needs to be retried, it should have work scheduled on it. -function validateRevealOrder(revealOrder) { - { - if ( - revealOrder !== undefined && - revealOrder !== "forwards" && - revealOrder !== "backwards" && - revealOrder !== "together" && - !didWarnAboutRevealOrder[revealOrder] - ) { - didWarnAboutRevealOrder[revealOrder] = true; + workInProgress.effectTag |= DidCapture; + break; + } + } // If this boundary is currently timed out, we need to decide + // 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 (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 primaryChildFragment = workInProgress.child; + var primaryChildExpirationTime = + primaryChildFragment.childExpirationTime; - break; - } + if ( + primaryChildExpirationTime !== NoWork && + primaryChildExpirationTime >= renderExpirationTime + ) { + // The primary children have pending work. Use the normal path + // to attempt to render the primary children again. + return updateSuspenseComponent( + current$$1, + workInProgress, + renderExpirationTime + ); + } else { + pushSuspenseContext( + workInProgress, + setDefaultShallowSuspenseContext(suspenseStackCursor.current) + ); // The primary children do not have pending work with sufficient + // priority. Bailout. - 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 child = bailoutOnAlreadyFinishedWork( + current$$1, + workInProgress, + renderExpirationTime + ); + 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; } - 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; - 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 SuspenseListComponent: { + var didSuspendBefore = + (current$$1.effectTag & DidCapture) !== NoEffect; - error( - ' is only valid if revealOrder is ' + - '"forwards" or "backwards". ' + - 'Did you mean to specify revealOrder="forwards"?', - tailMode - ); - } - } - } -} + var _hasChildWork = + workInProgress.childExpirationTime >= renderExpirationTime; -function validateSuspenseListNestedChild(childSlot, index) { - { - var isArray = Array.isArray(childSlot); - var isIterable = !isArray && typeof getIteratorFn(childSlot) === "function"; + 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$$1, + workInProgress, + renderExpirationTime + ); + } // 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 (isArray || isIterable) { - var type = isArray ? "array" : "iterable"; + workInProgress.effectTag |= 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. - error( - "A nested %s was passed to row #%s in . Wrap it in " + - "an additional SuspenseList to configure its revealOrder: " + - " ... " + - "{%s} ... " + - "", - type, - index, - type - ); + var renderState = workInProgress.memoizedState; - return false; - } - } + 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; + } - return true; -} + pushSuspenseContext(workInProgress, suspenseStackCursor.current); -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; + 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 { - var iteratorFn = getIteratorFn(children); + } + return bailoutOnAlreadyFinishedWork( + current$$1, + workInProgress, + renderExpirationTime + ); + } 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 the expiration time. - if (typeof iteratorFn === "function") { - var childrenIterator = iteratorFn.call(children); + workInProgress.expirationTime = NoWork; - if (childrenIterator) { - var step = childrenIterator.next(); - var _i = 0; + switch (workInProgress.tag) { + case IndeterminateComponent: { + return mountIndeterminateComponent( + current$$1, + workInProgress, + workInProgress.type, + renderExpirationTime + ); + } + case LazyComponent: { + var elementType = workInProgress.elementType; + return mountLazyComponent( + current$$1, + workInProgress, + elementType, + updateExpirationTime, + renderExpirationTime + ); + } + case FunctionComponent: { + var _Component = workInProgress.type; + var unresolvedProps = workInProgress.pendingProps; + var resolvedProps = + workInProgress.elementType === _Component + ? unresolvedProps + : resolveDefaultProps(_Component, unresolvedProps); + return updateFunctionComponent( + current$$1, + workInProgress, + _Component, + resolvedProps, + renderExpirationTime + ); + } - for (; !step.done; step = childrenIterator.next()) { - if (!validateSuspenseListNestedChild(step.value, _i)) { - return; - } + case ClassComponent: { + var _Component2 = workInProgress.type; + var _unresolvedProps = workInProgress.pendingProps; - _i++; - } - } - } else { - error( - 'A single row was passed to a . ' + - "This is not useful since it needs multiple rows. " + - "Did you mean to pass multiple children or an array?", - revealOrder - ); - } - } + var _resolvedProps = + workInProgress.elementType === _Component2 + ? _unresolvedProps + : resolveDefaultProps(_Component2, _unresolvedProps); + return updateClassComponent( + current$$1, + workInProgress, + _Component2, + _resolvedProps, + renderExpirationTime + ); } - } -} -function initSuspenseListRenderState( - workInProgress, - isBackwards, - tail, - lastContentRow, - tailMode, - lastEffectBeforeRendering -) { - var renderState = workInProgress.memoizedState; + case HostRoot: + return updateHostRoot(current$$1, workInProgress, renderExpirationTime); - if (renderState === null) { - workInProgress.memoizedState = { - isBackwards: isBackwards, - rendering: null, - renderingStartTime: 0, - last: lastContentRow, - tail: tail, - tailExpiration: 0, - 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.tailExpiration = 0; - 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 HostComponent: + return updateHostComponent( + current$$1, + workInProgress, + renderExpirationTime + ); -function updateSuspenseListComponent( - current, - workInProgress, - renderExpirationTime -) { - 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, renderExpirationTime); - var suspenseContext = suspenseStackCursor.current; - var shouldForceFallback = hasSuspenseContext( - suspenseContext, - ForceSuspenseFallback - ); + case HostText: + return updateHostText(current$$1, workInProgress); - if (shouldForceFallback) { - suspenseContext = setShallowSuspenseContext( - suspenseContext, - ForceSuspenseFallback - ); - workInProgress.effectTag |= DidCapture; - } else { - var didSuspendBefore = - current !== null && (current.effectTag & DidCapture) !== NoEffect; + case SuspenseComponent: + return updateSuspenseComponent( + current$$1, + workInProgress, + renderExpirationTime + ); + case HostPortal: + return updatePortalComponent( + current$$1, + workInProgress, + renderExpirationTime + ); - 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( + case ForwardRef: { + var type = workInProgress.type; + var _unresolvedProps2 = workInProgress.pendingProps; + + var _resolvedProps2 = + workInProgress.elementType === type + ? _unresolvedProps2 + : resolveDefaultProps(type, _unresolvedProps2); + return updateForwardRef( + current$$1, workInProgress, - workInProgress.child, + type, + _resolvedProps2, renderExpirationTime ); } - suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); - } + case Fragment: + return updateFragment(current$$1, workInProgress, renderExpirationTime); - pushSuspenseContext(workInProgress, suspenseContext); + case Mode: + return updateMode(current$$1, workInProgress, renderExpirationTime); - if ((workInProgress.mode & BlockingMode) === NoMode) { - // Outside of blocking 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 Profiler: + return updateProfiler(current$$1, workInProgress, renderExpirationTime); - 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 ContextProvider: + return updateContextProvider( + current$$1, + workInProgress, + renderExpirationTime + ); + case ContextConsumer: + return updateContextConsumer( + current$$1, + workInProgress, + renderExpirationTime + ); - initSuspenseListRenderState( - workInProgress, - false, // isBackwards - tail, - lastContentRow, - tailMode, - workInProgress.lastEffect - ); - break; - } + case MemoComponent: { + var _type2 = workInProgress.type; + var _unresolvedProps3 = workInProgress.pendingProps; // Resolve outer props first, then resolve inner props. - 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 _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3); - while (row !== null) { - var currentRow = row.alternate; // New rows can't be content rows. + { + if (workInProgress.type !== workInProgress.elementType) { + var outerPropTypes = _type2.propTypes; - if (currentRow !== null && findFirstSuspended(currentRow) === null) { - // This is the beginning of the main content. - workInProgress.child = row; - break; + if (outerPropTypes) { + checkPropTypes( + outerPropTypes, + _resolvedProps3, // Resolved for outer only + "prop", + getComponentName(_type2), + getCurrentFiberStackInDev + ); } + } + } + _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3); + return updateMemoComponent( + current$$1, + workInProgress, + _type2, + _resolvedProps3, + updateExpirationTime, + renderExpirationTime + ); + } + case SimpleMemoComponent: { + return updateSimpleMemoComponent( + current$$1, + workInProgress, + workInProgress.type, + workInProgress.pendingProps, + updateExpirationTime, + renderExpirationTime + ); + } - 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 IncompleteClassComponent: { + var _Component3 = workInProgress.type; + var _unresolvedProps4 = workInProgress.pendingProps; - initSuspenseListRenderState( + var _resolvedProps4 = + workInProgress.elementType === _Component3 + ? _unresolvedProps4 + : resolveDefaultProps(_Component3, _unresolvedProps4); + return mountIncompleteClassComponent( + current$$1, + workInProgress, + _Component3, + _resolvedProps4, + renderExpirationTime + ); + } + case SuspenseListComponent: { + return updateSuspenseListComponent( + current$$1, + workInProgress, + renderExpirationTime + ); + } + case FundamentalComponent: { + if (enableFundamentalAPI) { + return updateFundamentalComponent$1( + current$$1, workInProgress, - true, // isBackwards - _tail, - null, // last - tailMode, - workInProgress.lastEffect + renderExpirationTime ); - break; } - case "together": { - initSuspenseListRenderState( + break; + } + + case ScopeComponent: { + if (enableScopeAPI) { + return updateScopeComponent( + current$$1, workInProgress, - false, // isBackwards - null, // tail - null, // last - undefined, - workInProgress.lastEffect + renderExpirationTime ); - break; } - default: { - // The default reveal order is the same as not having - // a boundary. - workInProgress.memoizedState = null; - } + break; } } - return 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." + ); + } } -function updatePortalComponent(current, workInProgress, renderExpirationTime) { - pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); - var nextChildren = workInProgress.pendingProps; +function createFundamentalStateInstance(currentFiber, props, impl, state) { + return { + currentFiber: currentFiber, + impl: impl, + instance: null, + prevProps: null, + props: props, + state: state + }; +} - 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, - renderExpirationTime - ); - } else { - reconcileChildren( - current, - workInProgress, - nextChildren, - renderExpirationTime - ); - } +function isFiberSuspenseAndTimedOut(fiber) { + return fiber.tag === SuspenseComponent && fiber.memoizedState !== null; +} - return workInProgress.child; +function getSuspenseFallbackChild(fiber) { + return fiber.child.sibling.child; } -function updateContextProvider(current, workInProgress, renderExpirationTime) { - var providerType = workInProgress.type; - var context = providerType._context; - var newProps = workInProgress.pendingProps; - var oldProps = workInProgress.memoizedProps; - var newValue = newProps.value; +var emptyObject$2 = {}; - { - var providerPropTypes = workInProgress.type.propTypes; +function collectScopedNodes(node, fn, scopedNodes) { + if (enableScopeAPI) { + if (node.tag === HostComponent) { + var _type = node.type, + memoizedProps = node.memoizedProps, + stateNode = node.stateNode; - if (providerPropTypes) { - checkPropTypes(providerPropTypes, newProps, "prop", "Context.Provider"); + var _instance = getPublicInstance(stateNode); + + if ( + _instance !== null && + fn(_type, memoizedProps || emptyObject$2, _instance) === true + ) { + scopedNodes.push(_instance); + } } - } - pushProvider(workInProgress, newValue); + var child = node.child; - if (oldProps !== null) { - var oldValue = oldProps.value; - var changedBits = calculateChangedBits(context, newValue, oldValue); + if (isFiberSuspenseAndTimedOut(node)) { + child = getSuspenseFallbackChild(node); + } - if (changedBits === 0) { - // No change. Bailout early if children are the same. - if (oldProps.children === newProps.children && !hasContextChanged()) { - return bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderExpirationTime - ); - } - } else { - // The context value changed. Search for matching consumers and schedule - // them to update. - propagateContextChange( - workInProgress, - context, - changedBits, - renderExpirationTime - ); + if (child !== null) { + collectScopedNodesFromChildren(child, fn, scopedNodes); } } - - var newChildren = newProps.children; - reconcileChildren(current, workInProgress, newChildren, renderExpirationTime); - return workInProgress.child; } -var hasWarnedAboutUsingContextAsConsumer = false; - -function updateContextConsumer(current, workInProgress, renderExpirationTime) { - 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 collectFirstScopedNode(node, fn) { + if (enableScopeAPI) { + if (node.tag === HostComponent) { + var _type2 = node.type, + memoizedProps = node.memoizedProps, + stateNode = node.stateNode; - { - 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 _instance2 = getPublicInstance(stateNode); - error( - "Rendering directly is not supported and will be removed in " + - "a future major release. Did you mean to render instead?" - ); - } + if ( + _instance2 !== null && + fn(_type2, memoizedProps, _instance2) === true + ) { + return _instance2; } - } else { - context = context._context; } - } - var newProps = workInProgress.pendingProps; - var render = newProps.children; + var child = node.child; - { - 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 (isFiberSuspenseAndTimedOut(node)) { + child = getSuspenseFallbackChild(node); + } + + if (child !== null) { + return collectFirstScopedNodeFromChildren(child, fn); } } - prepareToReadContext(workInProgress, renderExpirationTime); - var newValue = readContext(context, newProps.unstable_observedBits); - var newChildren; + return null; +} - { - ReactCurrentOwner$1.current = workInProgress; - setIsRendering(true); - newChildren = render(newValue); - setIsRendering(false); - } // React DevTools reads this flag. +function collectScopedNodesFromChildren(startingChild, fn, scopedNodes) { + var child = startingChild; - workInProgress.effectTag |= PerformedWork; - reconcileChildren(current, workInProgress, newChildren, renderExpirationTime); - return workInProgress.child; + while (child !== null) { + collectScopedNodes(child, fn, scopedNodes); + child = child.sibling; + } } -function markWorkInProgressReceivedUpdate() { - didReceiveUpdate = true; -} +function collectFirstScopedNodeFromChildren(startingChild, fn) { + var child = startingChild; -function bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderExpirationTime -) { - cancelWorkTimer(workInProgress); + while (child !== null) { + var scopedNode = collectFirstScopedNode(child, fn); - if (current !== null) { - // Reuse previous dependencies - workInProgress.dependencies = current.dependencies; - } + if (scopedNode !== null) { + return scopedNode; + } - { - // Don't update "base" render times for bailouts. - stopProfilerTimerIfRunning(); + child = child.sibling; } - var updateExpirationTime = workInProgress.expirationTime; + return null; +} - if (updateExpirationTime !== NoWork) { - markUnprocessedUpdateTime(updateExpirationTime); - } // Check if the children have any pending work. +function collectNearestScopeMethods(node, scope, childrenScopes) { + if (isValidScopeNode(node, scope)) { + childrenScopes.push(node.stateNode.methods); + } else { + var child = node.child; - var childExpirationTime = workInProgress.childExpirationTime; + if (isFiberSuspenseAndTimedOut(node)) { + child = getSuspenseFallbackChild(node); + } - if (childExpirationTime < renderExpirationTime) { - // 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 (child !== null) { + collectNearestChildScopeMethods(child, scope, childrenScopes); + } } } -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. +function collectNearestChildScopeMethods(startingChild, scope, childrenScopes) { + var child = startingChild; - current.alternate = null; - oldWorkInProgress.alternate = null; // Connect to the new tree. + while (child !== null) { + collectNearestScopeMethods(child, scope, childrenScopes); + child = child.sibling; + } +} - newWorkInProgress.index = oldWorkInProgress.index; - newWorkInProgress.sibling = oldWorkInProgress.sibling; - newWorkInProgress.return = oldWorkInProgress.return; - newWorkInProgress.ref = oldWorkInProgress.ref; // Replace the child/sibling pointers above it. +function isValidScopeNode(node, scope) { + return ( + node.tag === ScopeComponent && + node.type === scope && + node.stateNode !== null + ); +} - if (oldWorkInProgress === returnFiber.child) { - returnFiber.child = newWorkInProgress; - } else { - var prevSibling = returnFiber.child; +function createScopeMethods(scope, instance) { + return { + getChildren: function() { + var currentFiber = instance.fiber; + var child = currentFiber.child; + var childrenScopes = []; - if (prevSibling === null) { - throw new Error("Expected parent to have a child."); + if (child !== null) { + collectNearestChildScopeMethods(child, scope, childrenScopes); } - while (prevSibling.sibling !== oldWorkInProgress) { - prevSibling = prevSibling.sibling; + return childrenScopes.length === 0 ? null : childrenScopes; + }, + getChildrenFromRoot: function() { + var currentFiber = instance.fiber; + var node = currentFiber; + + while (node !== null) { + var parent = node.return; - if (prevSibling === null) { - throw new Error("Expected to find the previous sibling."); + if (parent === null) { + break; + } + + node = parent; + + if (node.tag === ScopeComponent && node.type === scope) { + break; } } - 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 childrenScopes = []; + collectNearestChildScopeMethods(node.child, scope, childrenScopes); + return childrenScopes.length === 0 ? null : childrenScopes; + }, + getParent: function() { + var node = instance.fiber.return; - var last = returnFiber.lastEffect; + while (node !== null) { + if (node.tag === ScopeComponent && node.type === scope) { + return node.stateNode.methods; + } - if (last !== null) { - last.nextEffect = current; - returnFiber.lastEffect = current; - } else { - returnFiber.firstEffect = returnFiber.lastEffect = current; - } + node = node.return; + } - current.nextEffect = null; - current.effectTag = Deletion; - newWorkInProgress.effectTag |= Placement; // Restart work from the new fiber. + return null; + }, + getProps: function() { + var currentFiber = instance.fiber; + return currentFiber.memoizedProps; + }, + queryAllNodes: function(fn) { + var currentFiber = instance.fiber; + var child = currentFiber.child; + var scopedNodes = []; - return newWorkInProgress; - } -} + if (child !== null) { + collectScopedNodesFromChildren(child, fn, scopedNodes); + } -function beginWork(current, workInProgress, renderExpirationTime) { - var updateExpirationTime = workInProgress.expirationTime; + return scopedNodes.length === 0 ? null : scopedNodes; + }, + queryFirstNode: function(fn) { + var currentFiber = instance.fiber; + var child = currentFiber.child; - { - 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.expirationTime - ) - ); - } - } + if (child !== null) { + return collectFirstScopedNodeFromChildren(child, fn); + } - if (current !== null) { - var oldProps = current.memoizedProps; - var newProps = workInProgress.pendingProps; + return null; + }, + containsNode: function(node) { + var fiber = getInstanceFromNode$1(node); - 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 (updateExpirationTime < renderExpirationTime) { - 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 (fiber !== null) { + if ( + fiber.tag === ScopeComponent && + fiber.type === scope && + fiber.stateNode === instance + ) { + return true; + } - switch (workInProgress.tag) { - case HostRoot: - pushHostRootContext(workInProgress); - break; + fiber = fiber.return; + } - case HostComponent: - pushHostContext(workInProgress); + return false; + } + }; +} - if ( - workInProgress.mode & ConcurrentMode && - renderExpirationTime !== Never && - shouldDeprioritizeSubtree(workInProgress.type) - ) { - { - markSpawnedWork(Never); - } // Schedule this fiber to re-render at offscreen priority. Then bailout. +function markUpdate(workInProgress) { + // Tag the fiber with an update effect. This turns a Placement into + // a PlacementAndUpdate. + workInProgress.effectTag |= Update; +} - workInProgress.expirationTime = workInProgress.childExpirationTime = Never; - return null; - } +function markRef$1(workInProgress) { + workInProgress.effectTag |= Ref; +} - break; +var appendAllChildren; +var updateHostContainer; +var updateHostComponent$1; +var updateHostText$1; - case ClassComponent: { - var Component = workInProgress.type; +if (supportsMutation) { + // 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 (enableFundamentalAPI && node.tag === FundamentalComponent) { + appendInitialChild(parent, node.stateNode.instance); + } else if (node.tag === HostPortal) { + // If we have a portal child, then we don't want to traverse + // down its children. Instead, we'll get insertions from each child in + // the portal directly. + } else if (node.child !== null) { + node.child.return = node; + node = node.child; + continue; + } - if (isContextProvider(Component)) { - pushContextProvider(workInProgress); - } + if (node === workInProgress) { + return; + } - break; + while (node.sibling === null) { + if (node.return === null || node.return === workInProgress) { + return; } - case HostPortal: - pushHostContainer( - workInProgress, - workInProgress.stateNode.containerInfo - ); - break; + node = node.return; + } - case ContextProvider: { - var newValue = workInProgress.memoizedProps.value; - pushProvider(workInProgress, newValue); - break; - } + node.sibling.return = node.return; + node = node.sibling; + } + }; - case Profiler: - { - // Profiler should only call onRender when one of its descendants actually rendered. - var hasChildWork = - workInProgress.childExpirationTime >= renderExpirationTime; + updateHostContainer = function(workInProgress) { + // Noop + }; + 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 (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 (hasChildWork) { - workInProgress.effectTag |= 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 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`. - var stateNode = workInProgress.stateNode; - stateNode.effectDuration = 0; - stateNode.passiveEffectDuration = 0; - } + var updatePayload = prepareUpdate( + instance, + type, + oldProps, + newProps, + rootContainerInstance, + currentHostContext + ); // TODO: Type this specific to this type of component. - break; + 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. - case SuspenseComponent: { - var state = workInProgress.memoizedState; + if (updatePayload) { + markUpdate(workInProgress); + } + }; + 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); + } + }; +} else if (supportsPersistence) { + // 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 + branches: 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, type, props, node); + } - 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. + appendInitialChild(parent, instance); + } else if (node.tag === HostText) { + var _instance = node.stateNode; - var primaryChildFragment = workInProgress.child; - var primaryChildExpirationTime = - primaryChildFragment.childExpirationTime; + if (needsVisibilityToggle && isHidden) { + // This child is inside a timed out tree. Hide it. + var text = node.memoizedProps; + _instance = cloneHiddenTextInstance(_instance, text, node); + } - if ( - primaryChildExpirationTime !== NoWork && - primaryChildExpirationTime >= renderExpirationTime - ) { - // The primary children have pending work. Use the normal path - // to attempt to render the primary children again. - return updateSuspenseComponent( - current, - workInProgress, - renderExpirationTime - ); - } else { - pushSuspenseContext( - workInProgress, - setDefaultShallowSuspenseContext(suspenseStackCursor.current) - ); // The primary children do not have pending work with sufficient - // priority. Bailout. + appendInitialChild(parent, _instance); + } else if (enableFundamentalAPI && node.tag === FundamentalComponent) { + var _instance2 = node.stateNode.instance; - var child = bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderExpirationTime - ); + if (needsVisibilityToggle && isHidden) { + // This child is inside a timed out tree. Hide it. + var _props = node.memoizedProps; + var _type = node.type; + _instance2 = cloneHiddenInstance(_instance2, _type, _props, node); + } + appendInitialChild(parent, _instance2); + } else if (node.tag === HostPortal) { + // If we have a portal child, then we don't want to traverse + // down its children. Instead, we'll get insertions from each child in + // the portal directly. + } else if (node.tag === SuspenseComponent) { + if ((node.effectTag & Update) !== NoEffect) { + // Need to toggle the visibility of the primary children. + var newIsHidden = node.memoizedState !== null; - 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; + 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; + + if (fallbackChildParent !== null) { + fallbackChildParent.return = node; + node = fallbackChildParent; + continue; } } - } else { - pushSuspenseContext( - workInProgress, - setDefaultShallowSuspenseContext(suspenseStackCursor.current) - ); } - - 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 SuspenseListComponent: { - var didSuspendBefore = (current.effectTag & DidCapture) !== NoEffect; + node = node; - var _hasChildWork = - workInProgress.childExpirationTime >= renderExpirationTime; + if (node === workInProgress) { + return; + } - 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, - renderExpirationTime - ); - } // 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 (node.sibling === null) { + if (node.return === null || node.return === workInProgress) { + return; + } - workInProgress.effectTag |= 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. + node = node.return; + } - var renderState = workInProgress.memoizedState; + node.sibling.return = node.return; + node = node.sibling; + } + }; // An unfortunate fork of appendAllChildren because we have two different parent types. - 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; - } + 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; + while (node !== null) { + // eslint-disable-next-line no-labels + branches: 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, type, props, node); + } - pushSuspenseContext(workInProgress, suspenseStackCursor.current); + appendChildToContainerChildSet(containerChildSet, instance); + } else if (node.tag === HostText) { + var _instance3 = node.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; - } + if (needsVisibilityToggle && isHidden) { + // This child is inside a timed out tree. Hide it. + var text = node.memoizedProps; + _instance3 = cloneHiddenTextInstance(_instance3, text, node); } - } - return bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderExpirationTime - ); - } 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. + appendChildToContainerChildSet(containerChildSet, _instance3); + } else if (enableFundamentalAPI && node.tag === FundamentalComponent) { + var _instance4 = node.stateNode.instance; - workInProgress.expirationTime = NoWork; + if (needsVisibilityToggle && isHidden) { + // This child is inside a timed out tree. Hide it. + var _props2 = node.memoizedProps; + var _type2 = node.type; + _instance4 = cloneHiddenInstance(_instance4, _type2, _props2, node); + } + appendChildToContainerChildSet(containerChildSet, _instance4); + } else if (node.tag === HostPortal) { + // If we have a portal child, then we don't want to traverse + // down its children. Instead, we'll get insertions from each child in + // the portal directly. + } else if (node.tag === SuspenseComponent) { + if ((node.effectTag & Update) !== NoEffect) { + // Need to toggle the visibility of the primary children. + var newIsHidden = node.memoizedState !== null; - switch (workInProgress.tag) { - case IndeterminateComponent: { - return mountIndeterminateComponent( - current, - workInProgress, - workInProgress.type, - renderExpirationTime - ); - } + if (newIsHidden) { + var primaryChildParent = node.child; - case LazyComponent: { - var elementType = workInProgress.elementType; - return mountLazyComponent( - current, - workInProgress, - elementType, - updateExpirationTime, - renderExpirationTime - ); - } + if (primaryChildParent !== null) { + if (primaryChildParent.child !== null) { + primaryChildParent.child.return = primaryChildParent; + appendAllChildrenToContainer( + containerChildSet, + primaryChildParent, + true, + newIsHidden + ); + } - 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, - renderExpirationTime - ); - } + var fallbackChildParent = primaryChildParent.sibling; - case ClassComponent: { - var _Component2 = workInProgress.type; - var _unresolvedProps = workInProgress.pendingProps; + if (fallbackChildParent !== null) { + fallbackChildParent.return = node; + node = fallbackChildParent; + continue; + } + } + } + } + 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 _resolvedProps = - workInProgress.elementType === _Component2 - ? _unresolvedProps - : resolveDefaultProps(_Component2, _unresolvedProps); + node = node; - return updateClassComponent( - current, - workInProgress, - _Component2, - _resolvedProps, - renderExpirationTime - ); + if (node === workInProgress) { + return; + } + + while (node.sibling === null) { + if (node.return === null || node.return === workInProgress) { + return; + } + + node = node.return; + } + + node.sibling.return = node.return; + node = node.sibling; } + }; - case HostRoot: - return updateHostRoot(current, workInProgress, renderExpirationTime); + updateHostContainer = function(workInProgress) { + var portalOrRoot = workInProgress.stateNode; + var childrenUnchanged = workInProgress.firstEffect === null; - case HostComponent: - return updateHostComponent(current, workInProgress, renderExpirationTime); + if (childrenUnchanged) { + // No changes, just reuse the existing instance. + } else { + var container = portalOrRoot.containerInfo; + var newChildSet = createContainerChildSet(container); // If children might have changed, we have to add them all to the set. - case HostText: - return updateHostText(); + appendAllChildrenToContainer(newChildSet, workInProgress, false, false); + portalOrRoot.pendingChildren = newChildSet; // Schedule an update on the container to swap out the container. - case SuspenseComponent: - return updateSuspenseComponent( - current, - workInProgress, - renderExpirationTime - ); + markUpdate(workInProgress); + finalizeContainerChildren(container, newChildSet); + } + }; + 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. - case HostPortal: - return updatePortalComponent( - current, - workInProgress, - renderExpirationTime - ); + var childrenUnchanged = workInProgress.firstEffect === null; - case ForwardRef: { - var type = workInProgress.type; - var _unresolvedProps2 = workInProgress.pendingProps; + if (childrenUnchanged && oldProps === newProps) { + // No changes, just reuse the existing instance. + // Note that this might release a previous clone. + workInProgress.stateNode = currentInstance; + return; + } - var _resolvedProps2 = - workInProgress.elementType === type - ? _unresolvedProps2 - : resolveDefaultProps(type, _unresolvedProps2); + var recyclableInstance = workInProgress.stateNode; + var currentHostContext = getHostContext(); + var updatePayload = null; - return updateForwardRef( - current, - workInProgress, + if (oldProps !== newProps) { + updatePayload = prepareUpdate( + recyclableInstance, type, - _resolvedProps2, - renderExpirationTime + oldProps, + newProps, + rootContainerInstance, + currentHostContext ); } + if (childrenUnchanged && updatePayload === null) { + // No changes, just reuse the existing instance. + // Note that this might release a previous clone. + workInProgress.stateNode = currentInstance; + return; + } + var newInstance = cloneInstance( + currentInstance, + updatePayload, + type, + oldProps, + newProps, + workInProgress, + childrenUnchanged, + recyclableInstance + ); + if ( + finalizeInitialChildren( + newInstance, + type, + newProps, + rootContainerInstance, + currentHostContext + ) + ) { + markUpdate(workInProgress); + } - case Fragment: - return updateFragment(current, workInProgress, renderExpirationTime); + workInProgress.stateNode = newInstance; - case Mode: - return updateMode(current, workInProgress, renderExpirationTime); + 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); + } + }; + 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 Profiler: - return updateProfiler(current, workInProgress, renderExpirationTime); + markUpdate(workInProgress); + } + }; +} else { + // No host operations + updateHostContainer = function(workInProgress) { + // Noop + }; + updateHostComponent$1 = function( + current, + workInProgress, + type, + newProps, + rootContainerInstance + ) { + // Noop + }; + updateHostText$1 = function(current, workInProgress, oldText, newText) { + // Noop + }; +} - case ContextProvider: - return updateContextProvider( - current, - workInProgress, - renderExpirationTime - ); +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 (tailNode !== null) { + if (tailNode.alternate !== null) { + lastTailNode = tailNode; + } - case ContextConsumer: - return updateContextConsumer( - current, - workInProgress, - renderExpirationTime - ); + tailNode = tailNode.sibling; + } // Next we're simply going to delete all insertions after the + // last rendered item. - case MemoComponent: { - var _type2 = workInProgress.type; - var _unresolvedProps3 = workInProgress.pendingProps; // Resolve outer props first, then resolve inner props. + 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 _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3); + break; + } - { - if (workInProgress.type !== workInProgress.elementType) { - var outerPropTypes = _type2.propTypes; + 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 (outerPropTypes) { - checkPropTypes( - outerPropTypes, - _resolvedProps3, // Resolved for outer only - "prop", - getComponentName(_type2) - ); - } + _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; } - - _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3); - return updateMemoComponent( - current, - workInProgress, - _type2, - _resolvedProps3, - updateExpirationTime, - renderExpirationTime - ); + break; } + } +} - case SimpleMemoComponent: { - return updateSimpleMemoComponent( - current, - workInProgress, - workInProgress.type, - workInProgress.pendingProps, - updateExpirationTime, - renderExpirationTime - ); - } +function completeWork(current, workInProgress, renderExpirationTime) { + var newProps = workInProgress.pendingProps; - case IncompleteClassComponent: { - var _Component3 = workInProgress.type; - var _unresolvedProps4 = workInProgress.pendingProps; + switch (workInProgress.tag) { + case IndeterminateComponent: + break; - var _resolvedProps4 = - workInProgress.elementType === _Component3 - ? _unresolvedProps4 - : resolveDefaultProps(_Component3, _unresolvedProps4); + case LazyComponent: + break; - return mountIncompleteClassComponent( - current, - workInProgress, - _Component3, - _resolvedProps4, - renderExpirationTime - ); - } + case SimpleMemoComponent: + case FunctionComponent: + break; - case SuspenseListComponent: { - return updateSuspenseListComponent( - current, - workInProgress, - renderExpirationTime - ); + case ClassComponent: { + var Component = workInProgress.type; + + if (isContextProvider(Component)) { + popContext(workInProgress); + } + + break; } - } - { - throw Error( - "Unknown unit of work tag (" + - workInProgress.tag + - "). This error is likely caused by a bug in React. Please file an issue." - ); - } -} + case HostRoot: { + popHostContainer(workInProgress); + popTopLevelContextObject(workInProgress); + var fiberRoot = workInProgress.stateNode; + if (fiberRoot.pendingContext) { + fiberRoot.context = fiberRoot.pendingContext; + fiberRoot.pendingContext = null; + } -function markUpdate(workInProgress) { - // Tag the fiber with an update effect. This turns a Placement into - // a PlacementAndUpdate. - workInProgress.effectTag |= Update; -} + 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); -function markRef$1(workInProgress) { - workInProgress.effectTag |= Ref; -} + if (wasHydrated) { + // If we hydrated, then we'll need to schedule an update for + // the commit side-effects on the root. + markUpdate(workInProgress); + } + } -var appendAllChildren; -var updateHostContainer; -var updateHostComponent$1; -var updateHostText$1; + updateHostContainer(workInProgress); + break; + } -{ - // 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; + case HostComponent: { + popHostContext(workInProgress); + var rootContainerInstance = getRootHostContainer(); + var type = workInProgress.type; + if (current !== null && workInProgress.stateNode != null) { + updateHostComponent$1( + current, + workInProgress, + type, + newProps, + rootContainerInstance + ); - while (node !== null) { - // eslint-disable-next-line no-labels - if (node.tag === HostComponent) { - var instance = node.stateNode; + if (enableFlareAPI) { + var prevListeners = current.memoizedProps.listeners; + var nextListeners = newProps.listeners; - 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 (prevListeners !== nextListeners) { + markUpdate(workInProgress); + } } - appendInitialChild(parent, instance); - } else if (node.tag === HostText) { - var _instance = node.stateNode; + 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 (needsVisibilityToggle && isHidden) { - // This child is inside a timed out tree. Hide it. - var text = node.memoizedProps; - _instance = cloneHiddenTextInstance(); + break; } - appendInitialChild(parent, _instance); - } else if (node.tag === HostPortal); - else if (node.tag === SuspenseComponent) { - if ((node.effectTag & Update) !== NoEffect) { - // Need to toggle the visibility of the primary children. - var newIsHidden = node.memoizedState !== null; + 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 we want to add then top->down or + // bottom->up. Top->down is faster in IE11. - if (newIsHidden) { - var primaryChildParent = node.child; + var _wasHydrated = popHydrationState(workInProgress); - if (primaryChildParent !== null) { - if (primaryChildParent.child !== null) { - primaryChildParent.child.return = primaryChildParent; - appendAllChildren( - parent, - primaryChildParent, - true, - newIsHidden - ); - } + if (_wasHydrated) { + // TODO: Move this and createInstance step into the beginPhase + // to consolidate. + if ( + prepareToHydrateHostInstance( + workInProgress, + rootContainerInstance, + currentHostContext + ) + ) { + // If changes to the hydrated node needs to be applied at the + // commit-phase we mark this as such. + markUpdate(workInProgress); + } - var fallbackChildParent = primaryChildParent.sibling; + if (enableFlareAPI) { + var listeners = newProps.listeners; - if (fallbackChildParent !== null) { - fallbackChildParent.return = node; - node = fallbackChildParent; - continue; - } + if (listeners != null) { + updateEventListeners( + listeners, + workInProgress, + rootContainerInstance + ); + } + } + } else { + var instance = createInstance( + type, + newProps, + rootContainerInstance, + currentHostContext, + workInProgress + ); + appendAllChildren(instance, workInProgress, false, false); // This needs to be set before we mount Flare event listeners + + workInProgress.stateNode = instance; + + if (enableFlareAPI) { + var _listeners = newProps.listeners; + + if (_listeners != null) { + updateEventListeners( + _listeners, + workInProgress, + rootContainerInstance + ); } + } // Certain renderers require commit-time effects for initial mount. + // (eg DOM renderer supports auto-focus for certain elements). + // Make sure such renderers get scheduled for later work. + + if ( + finalizeInitialChildren( + instance, + type, + newProps, + rootContainerInstance, + currentHostContext + ) + ) { + markUpdate(workInProgress); } } - if (node.child !== null) { - // Continue traversing like normal - node.child.return = node; - node = node.child; - continue; + if (workInProgress.ref !== null) { + // If there is a ref on a host node we need to schedule a callback + markRef$1(workInProgress); } - } 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; + break; + } - if (node === workInProgress) { - return; - } + case HostText: { + var newText = newProps; - while (node.sibling === null) { - if (node.return === null || node.return === workInProgress) { - return; + if (current && workInProgress.stateNode != null) { + var oldText = current.memoizedProps; // If we have an alternate, that means this is an update and we need + // to schedule a side-effect to do the updates. + + updateHostText$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. } - node = node.return; + var _rootContainerInstance = getRootHostContainer(); + + var _currentHostContext = getHostContext(); + + var _wasHydrated2 = popHydrationState(workInProgress); + + if (_wasHydrated2) { + if (prepareToHydrateHostTextInstance(workInProgress)) { + markUpdate(workInProgress); + } + } else { + workInProgress.stateNode = createTextInstance( + newText, + _rootContainerInstance, + _currentHostContext, + workInProgress + ); + } } - node.sibling.return = node.return; - node = node.sibling; + break; } - }; // 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 ForwardRef: + break; - while (node !== null) { - // eslint-disable-next-line no-labels - if (node.tag === HostComponent) { - var instance = node.stateNode; + case SuspenseComponent: { + popSuspenseContext(workInProgress); + var nextState = workInProgress.memoizedState; - 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 (enableSuspenseServerRenderer) { + if (nextState !== null && nextState.dehydrated !== null) { + if (current === null) { + var _wasHydrated3 = popHydrationState(workInProgress); - appendChildToContainerChildSet(containerChildSet, instance); - } else if (node.tag === HostText) { - var _instance3 = node.stateNode; + if (!_wasHydrated3) { + throw Error( + "A dehydrated suspense component was completed without a hydrated node. This is probably a bug in React." + ); + } - if (needsVisibilityToggle && isHidden) { - // This child is inside a timed out tree. Hide it. - var text = node.memoizedProps; - _instance3 = cloneHiddenTextInstance(); + prepareToHydrateHostSuspenseInstance(workInProgress); + + if (enableSchedulerTracing) { + markSpawnedWork(Never); + } + + return null; + } else { + // We should never have been in a hydration state if we didn't have a current. + // However, in some of those paths, we might have reentered a hydration state + // and then we might be inside a hydration state. In that case, we'll need to + // exit out of it. + resetHydrationState(); + + if ((workInProgress.effectTag & DidCapture) === NoEffect) { + // This boundary did not suspend so it's now hydrated and unsuspended. + workInProgress.memoizedState = null; + } // If nothing suspended, we need to schedule an effect to mark this boundary + // as having hydrated so events know that they're free be invoked. + // It's also a signal to replay events and the suspense callback. + // If something suspended, schedule an effect to attach retry listeners. + // So we might as well always mark this. + + workInProgress.effectTag |= Update; + return null; + } } + } - appendChildToContainerChildSet(containerChildSet, _instance3); - } else if (node.tag === HostPortal); - else if (node.tag === SuspenseComponent) { - if ((node.effectTag & Update) !== NoEffect) { - // Need to toggle the visibility of the primary children. - var newIsHidden = node.memoizedState !== null; + if ((workInProgress.effectTag & DidCapture) !== NoEffect) { + // Something suspended. Re-render with the fallback children. + workInProgress.expirationTime = renderExpirationTime; // Do not reset the effect list. - if (newIsHidden) { - var primaryChildParent = node.child; + return workInProgress; + } - if (primaryChildParent !== null) { - if (primaryChildParent.child !== null) { - primaryChildParent.child.return = primaryChildParent; - appendAllChildrenToContainer( - containerChildSet, - primaryChildParent, - true, - newIsHidden - ); - } + var nextDidTimeout = nextState !== null; + var prevDidTimeout = false; - var fallbackChildParent = primaryChildParent.sibling; + if (current === null) { + if (workInProgress.memoizedProps.fallback !== undefined) { + popHydrationState(workInProgress); + } + } else { + var prevState = current.memoizedState; + prevDidTimeout = prevState !== null; - if (fallbackChildParent !== null) { - fallbackChildParent.return = node; - node = fallbackChildParent; - continue; - } + if (!nextDidTimeout && prevState !== null) { + // We just switched from the fallback to the normal children. + // Delete the fallback. + // TODO: Would it be better to store the fallback fragment on + // the stateNode during the begin phase? + var currentFallbackChild = current.child.sibling; + + if (currentFallbackChild !== null) { + // Deletions go at the beginning of the return fiber's effect list + var first = workInProgress.firstEffect; + + if (first !== null) { + workInProgress.firstEffect = currentFallbackChild; + currentFallbackChild.nextEffect = first; + } else { + workInProgress.firstEffect = workInProgress.lastEffect = currentFallbackChild; + currentFallbackChild.nextEffect = null; } + currentFallbackChild.effectTag = Deletion; } } + } - if (node.child !== null) { - // Continue traversing like normal - node.child.return = node; - node = node.child; - continue; + 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(); + } } - } 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; + if (supportsPersistence) { + // 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 proimse. This flag is also used to hide the + // primary children. + workInProgress.effectTag |= Update; + } + } + if (supportsMutation) { + // 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 proimse. 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 the + // is currently timed out, too. + workInProgress.effectTag |= Update; } - - node = node.return; + } + if ( + enableSuspenseCallback && + workInProgress.updateQueue !== null && + workInProgress.memoizedProps.suspenseCallback != null + ) { + // Always notify the callback + workInProgress.effectTag |= Update; } - node.sibling.return = node.return; - node = node.sibling; + break; } - }; - updateHostContainer = function(workInProgress) { - var portalOrRoot = workInProgress.stateNode; - var childrenUnchanged = workInProgress.firstEffect === null; - - 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. + case Fragment: + break; - appendAllChildrenToContainer(newChildSet, workInProgress, false, false); - portalOrRoot.pendingChildren = newChildSet; // Schedule an update on the container to swap out the container. + case Mode: + break; - markUpdate(workInProgress); - finalizeContainerChildren(container, newChildSet); - } - }; + case Profiler: + break; - 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. + case HostPortal: + popHostContainer(workInProgress); + updateHostContainer(workInProgress); + break; + case ContextProvider: + // Pop provider fiber + popProvider(workInProgress); + break; - var childrenUnchanged = workInProgress.firstEffect === null; + case ContextConsumer: + 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 MemoComponent: + break; - var recyclableInstance = workInProgress.stateNode; - var currentHostContext = getHostContext(); - var updatePayload = null; + case IncompleteClassComponent: { + // Same as class component case. I put it down here so that the tags are + // sequential to ensure this switch is compiled to a jump table. + var _Component = workInProgress.type; - if (oldProps !== newProps) { - updatePayload = prepareUpdate( - recyclableInstance, - type, - oldProps, - newProps - ); - } + if (isContextProvider(_Component)) { + popContext(workInProgress); + } - if (childrenUnchanged && updatePayload === null) { - // No changes, just reuse the existing instance. - // Note that this might release a previous clone. - workInProgress.stateNode = currentInstance; - return; + break; } - var newInstance = cloneInstance( - currentInstance, - updatePayload, - type, - oldProps, - newProps, - workInProgress, - childrenUnchanged - ); - - workInProgress.stateNode = newInstance; - - if (childrenUnchanged) { - // If there are no other effects in this tree, we need to flag this node as having one. - // Even though we're not going to use it for anything. - // Otherwise parents won't know that there are new children to propagate upwards. - markUpdate(workInProgress); - } else { - // If children might have changed, we have to add them all to the set. - appendAllChildren(newInstance, workInProgress, false, false); - } - }; + case SuspenseListComponent: { + popSuspenseContext(workInProgress); + var renderState = workInProgress.memoizedState; - 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 (renderState === null) { + // We're running in the default, "independent" mode. We don't do anything + // in this mode. + break; + } - markUpdate(workInProgress); - } else { - workInProgress.stateNode = current.stateNode; - } - }; -} + var didSuspendAlready = + (workInProgress.effectTag & DidCapture) !== NoEffect; + var renderedTail = renderState.rendering; -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 (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.effectTag & DidCapture) === NoEffect); - while (tailNode !== null) { - if (tailNode.alternate !== null) { - lastTailNode = tailNode; - } + if (!cannotBeSuspended) { + var row = workInProgress.child; - tailNode = tailNode.sibling; - } // Next we're simply going to delete all insertions after the - // last rendered item. + while (row !== null) { + var suspended = findFirstSuspended(row); - 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 (suspended !== null) { + didSuspendAlready = true; + workInProgress.effectTag |= 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. - break; - } + var newThennables = suspended.updateQueue; - 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 (newThennables !== null) { + workInProgress.updateQueue = newThennables; + workInProgress.effectTag |= 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. - while (_tailNode !== null) { - if (_tailNode.alternate !== null) { - _lastTailNode = _tailNode; - } + if (renderState.lastEffect === null) { + workInProgress.firstEffect = null; + } - _tailNode = _tailNode.sibling; - } // Next we're simply going to delete all insertions after the - // last rendered item. + workInProgress.lastEffect = renderState.lastEffect; // Reset the child fibers to their original state. - 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; + resetChildFibers(workInProgress, renderExpirationTime); // Set up the Suspense Context to force suspense and immediately + // rerender the children. + + pushSuspenseContext( + workInProgress, + setShallowSuspenseContext( + suspenseStackCursor.current, + ForceSuspenseFallback + ) + ); + return workInProgress.child; + } + row = row.sibling; + } + } } else { - renderState.tail = null; - } + cutOffTailIfNeeded(renderState, false); + } // Next we're going to render the tail. } else { - // Detach the insertion after the last node that was already - // inserted. - _lastTailNode.sibling = null; - } - - break; - } - } -} - -function completeWork(current, workInProgress, renderExpirationTime) { - var newProps = workInProgress.pendingProps; + // Append the rendered row to the child list. + if (!didSuspendAlready) { + var _suspended = findFirstSuspended(renderedTail); - 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; + if (_suspended !== null) { + workInProgress.effectTag |= DidCapture; + didSuspendAlready = true; // Ensure we transfer the update queue to the parent so that it doesn't + // get lost if this row ends up dropped during a second pass. - case ClassComponent: { - var Component = workInProgress.type; + var _newThennables = _suspended.updateQueue; - if (isContextProvider(Component)) { - popContext(workInProgress); - } + if (_newThennables !== null) { + workInProgress.updateQueue = _newThennables; + workInProgress.effectTag |= Update; + } - return null; - } + cutOffTailIfNeeded(renderState, true); // This might have been modified. - case HostRoot: { - popHostContainer(workInProgress); - popTopLevelContextObject(workInProgress); - var fiberRoot = workInProgress.stateNode; + if ( + renderState.tail === null && + renderState.tailMode === "hidden" && + !renderedTail.alternate + ) { + // 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. - if (fiberRoot.pendingContext) { - fiberRoot.context = fiberRoot.pendingContext; - fiberRoot.pendingContext = null; - } + if (lastEffect !== null) { + lastEffect.nextEffect = null; + } // We're done. - 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(); + return null; + } + } else if ( + now() > renderState.tailExpiration && + renderExpirationTime > Never + ) { + // 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.effectTag |= 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. If we can show + // them, then they really have the same priority as this render. + // So we'll pick it back up the very next render pass once we've had + // an opportunity to yield for paint. - if (wasHydrated) { - // If we hydrated, then we'll need to schedule an update for - // the commit side-effects on the root. - markUpdate(workInProgress); + var nextPriority = renderExpirationTime - 1; + workInProgress.expirationTime = workInProgress.childExpirationTime = nextPriority; + if (enableSchedulerTracing) { + markSpawnedWork(nextPriority); + } + } + } + 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; } } - updateHostContainer(workInProgress); - return null; - } + if (renderState.tail !== null) { + // We still have tail rows to render. + if (renderState.tailExpiration === 0) { + // Heuristic for how long we're willing to spend rendering rows + // until we just give up and show what we have so far. + var TAIL_EXPIRATION_TIMEOUT_MS = 500; + renderState.tailExpiration = now() + TAIL_EXPIRATION_TIMEOUT_MS; + } // Pop a row. - case HostComponent: { - popHostContext(workInProgress); - var rootContainerInstance = getRootHostContainer(); - var type = workInProgress.type; + var next = renderState.tail; + renderState.rendering = next; + renderState.tail = next.sibling; + renderState.lastEffect = workInProgress.lastEffect; + 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. - if (current !== null && workInProgress.stateNode != null) { - updateHostComponent$1( - current, - workInProgress, - type, - newProps, - rootContainerInstance - ); + var suspenseContext = suspenseStackCursor.current; - if (current.ref !== workInProgress.ref) { - markRef$1(workInProgress); + if (didSuspendAlready) { + suspenseContext = setShallowSuspenseContext( + suspenseContext, + ForceSuspenseFallback + ); + } else { + suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); } - } 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 null; - } + pushSuspenseContext(workInProgress, suspenseContext); // Do a pass over the next row. - 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. + return next; + } - var _wasHydrated = popHydrationState(); + 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); + case FundamentalComponent: { + if (enableFundamentalAPI) { + var fundamentalImpl = workInProgress.type.impl; + var fundamentalInstance = workInProgress.stateNode; + + if (fundamentalInstance === null) { + var getInitialState = fundamentalImpl.getInitialState; + var fundamentalState; + + if (getInitialState !== undefined) { + fundamentalState = getInitialState(newProps); } - } else { - var instance = createInstance( - type, + + fundamentalInstance = workInProgress.stateNode = createFundamentalStateInstance( + workInProgress, newProps, - rootContainerInstance, - currentHostContext, - workInProgress + fundamentalImpl, + fundamentalState || {} ); - appendAllChildren(instance, workInProgress, false, false); // This needs to be set before we mount Flare event listeners - workInProgress.stateNode = instance; - } + var _instance5 = getFundamentalComponentInstance(fundamentalInstance); - if (workInProgress.ref !== null) { - // If there is a ref on a host node we need to schedule a callback - markRef$1(workInProgress); - } - } + fundamentalInstance.instance = _instance5; - return null; - } + if (fundamentalImpl.reconcileChildren === false) { + return null; + } - case HostText: { - var newText = newProps; + appendAllChildren(_instance5, workInProgress, false, false); + mountFundamentalComponent(fundamentalInstance); + } else { + // We fire update in commit phase + var prevProps = fundamentalInstance.props; + fundamentalInstance.prevProps = prevProps; + fundamentalInstance.props = newProps; + fundamentalInstance.currentFiber = workInProgress; - 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. + if (supportsPersistence) { + var _instance6 = cloneFundamentalInstance(fundamentalInstance); + + fundamentalInstance.instance = _instance6; + appendAllChildren(_instance6, workInProgress, false, false); + } + + var shouldUpdate = shouldUpdateFundamentalComponent( + fundamentalInstance + ); - updateHostText$1(current, workInProgress, oldText, newText); - } else { - if (typeof newText !== "string") { - if (!(workInProgress.stateNode !== null)) { - throw Error( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." - ); - } // This can happen when we abort work. + if (shouldUpdate) { + markUpdate(workInProgress); + } } + } - var _rootContainerInstance = getRootHostContainer(); + break; + } - var _currentHostContext = getHostContext(); + case ScopeComponent: { + if (enableScopeAPI) { + if (current === null) { + var _type3 = workInProgress.type; + var scopeInstance = { + fiber: workInProgress, + methods: null + }; + workInProgress.stateNode = scopeInstance; + scopeInstance.methods = createScopeMethods(_type3, scopeInstance); - var _wasHydrated2 = popHydrationState(); + if (enableFlareAPI) { + var _listeners2 = newProps.listeners; - if (_wasHydrated2) { - if (prepareToHydrateHostTextInstance()) { + if (_listeners2 != null) { + var _rootContainerInstance2 = getRootHostContainer(); + + updateEventListeners( + _listeners2, + workInProgress, + _rootContainerInstance2 + ); + } + } + + if (workInProgress.ref !== null) { + markRef$1(workInProgress); markUpdate(workInProgress); } } else { - workInProgress.stateNode = createTextInstance( - newText, - _rootContainerInstance, - _currentHostContext, - workInProgress - ); + if (enableFlareAPI) { + var _prevListeners = current.memoizedProps.listeners; + var _nextListeners = newProps.listeners; + + if ( + _prevListeners !== _nextListeners || + workInProgress.ref !== null + ) { + markUpdate(workInProgress); + } + } else { + if (workInProgress.ref !== null) { + markUpdate(workInProgress); + } + } + + if (current.ref !== workInProgress.ref) { + markRef$1(workInProgress); + } } } - return null; + break; } - case SuspenseComponent: { - popSuspenseContext(workInProgress); - var nextState = workInProgress.memoizedState; + default: { + throw Error( + "Unknown unit of work tag (" + + workInProgress.tag + + "). This error is likely caused by a bug in React. Please file an issue." + ); + } + } - if ((workInProgress.effectTag & DidCapture) !== NoEffect) { - // Something suspended. Re-render with the fallback children. - workInProgress.expirationTime = renderExpirationTime; // Do not reset the effect list. + return null; +} + +function unwindWork(workInProgress, renderExpirationTime) { + switch (workInProgress.tag) { + case ClassComponent: { + var Component = workInProgress.type; + + if (isContextProvider(Component)) { + popContext(workInProgress); + } + var effectTag = workInProgress.effectTag; + + if (effectTag & ShouldCapture) { + workInProgress.effectTag = (effectTag & ~ShouldCapture) | DidCapture; return workInProgress; } - var nextDidTimeout = nextState !== null; - var prevDidTimeout = false; + return null; + } - if (current === null) { - if (workInProgress.memoizedProps.fallback !== undefined); - } else { - var prevState = current.memoizedState; - prevDidTimeout = prevState !== null; + case HostRoot: { + popHostContainer(workInProgress); + popTopLevelContextObject(workInProgress); + var _effectTag = workInProgress.effectTag; - if (!nextDidTimeout && prevState !== null) { - // We just switched from the fallback to the normal children. - // Delete the fallback. - // TODO: Would it be better to store the fallback fragment on - // the stateNode during the begin phase? - var currentFallbackChild = current.child.sibling; + if (!((_effectTag & DidCapture) === NoEffect)) { + throw Error( + "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." + ); + } - if (currentFallbackChild !== null) { - // Deletions go at the beginning of the return fiber's effect list - var first = workInProgress.firstEffect; + workInProgress.effectTag = (_effectTag & ~ShouldCapture) | DidCapture; + return workInProgress; + } - if (first !== null) { - workInProgress.firstEffect = currentFallbackChild; - currentFallbackChild.nextEffect = first; - } else { - workInProgress.firstEffect = workInProgress.lastEffect = currentFallbackChild; - currentFallbackChild.nextEffect = null; - } + case HostComponent: { + // TODO: popHydrationState + popHostContext(workInProgress); + return null; + } - currentFallbackChild.effectTag = Deletion; - } - } - } + case SuspenseComponent: { + popSuspenseContext(workInProgress); - 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 (enableSuspenseServerRenderer) { + var suspenseState = workInProgress.memoizedState; - 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 (suspenseState !== null && suspenseState.dehydrated !== null) { + if (!(workInProgress.alternate !== null)) { + throw Error( + "Threw in newly mounted dehydrated component. This is likely a bug in React. Please file an issue." + ); } + + resetHydrationState(); } } - { - // 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.effectTag |= Update; - } + var _effectTag2 = workInProgress.effectTag; + + if (_effectTag2 & ShouldCapture) { + workInProgress.effectTag = (_effectTag2 & ~ShouldCapture) | DidCapture; // Captured a suspense effect. Re-render the boundary. + + return 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); - updateHostContainer(workInProgress); return null; case ContextProvider: - // Pop provider fiber popProvider(workInProgress); return null; - case IncompleteClassComponent: { - // Same as class component case. I put it down here so that the tags are - // sequential to ensure this switch is compiled to a jump table. - var _Component = workInProgress.type; - - if (isContextProvider(_Component)) { - popContext(workInProgress); - } - + default: return null; - } + } +} - case SuspenseListComponent: { - popSuspenseContext(workInProgress); - var renderState = workInProgress.memoizedState; +function unwindInterruptedWork(interruptedWork) { + switch (interruptedWork.tag) { + case ClassComponent: { + var childContextTypes = interruptedWork.type.childContextTypes; - if (renderState === null) { - // We're running in the default, "independent" mode. - // We don't do anything in this mode. - return null; + if (childContextTypes !== null && childContextTypes !== undefined) { + popContext(interruptedWork); } - var didSuspendAlready = - (workInProgress.effectTag & DidCapture) !== NoEffect; - 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.effectTag & DidCapture) === NoEffect); - - if (!cannotBeSuspended) { - var row = workInProgress.child; - - while (row !== null) { - var suspended = findFirstSuspended(row); + break; + } - if (suspended !== null) { - didSuspendAlready = true; - workInProgress.effectTag |= 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 HostRoot: { + popHostContainer(interruptedWork); + popTopLevelContextObject(interruptedWork); + break; + } + case HostComponent: { + popHostContext(interruptedWork); + break; + } - var newThennables = suspended.updateQueue; + case HostPortal: + popHostContainer(interruptedWork); + break; - if (newThennables !== null) { - workInProgress.updateQueue = newThennables; - workInProgress.effectTag |= 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. + case SuspenseComponent: + popSuspenseContext(interruptedWork); + break; - if (renderState.lastEffect === null) { - workInProgress.firstEffect = null; - } + case SuspenseListComponent: + popSuspenseContext(interruptedWork); + break; - workInProgress.lastEffect = renderState.lastEffect; // Reset the child fibers to their original state. + case ContextProvider: + popProvider(interruptedWork); + break; - resetChildFibers(workInProgress, renderExpirationTime); // Set up the Suspense Context to force suspense and immediately - // rerender the children. + default: + break; + } +} - pushSuspenseContext( - workInProgress, - setShallowSuspenseContext( - suspenseStackCursor.current, - ForceSuspenseFallback - ) - ); - return workInProgress.child; - } +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) + }; +} - row = row.sibling; - } - } - } 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); +// Module provided by RN: +if ( + !( + typeof ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog === + "function" + ) +) { + throw Error( + "Expected ReactFiberErrorDialog.showErrorDialog to be a function." + ); +} - if (_suspended !== null) { - workInProgress.effectTag |= 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. +function showErrorDialog(capturedError) { + return ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog( + capturedError + ); +} - var _newThennables = _suspended.updateQueue; +function logCapturedError(capturedError) { + var logError = showErrorDialog(capturedError); // Allow injected showErrorDialog() to prevent default console.error logging. + // This enables renderers like ReactNative to better manage redbox behavior. - if (_newThennables !== null) { - workInProgress.updateQueue = _newThennables; - workInProgress.effectTag |= Update; - } + if (logError === false) { + return; + } - cutOffTailIfNeeded(renderState, true); // This might have been modified. + var error = capturedError.error; + { + var componentName = capturedError.componentName, + componentStack = capturedError.componentStack, + errorBoundaryName = capturedError.errorBoundaryName, + errorBoundaryFound = capturedError.errorBoundaryFound, + willRetry = capturedError.willRetry; // Browsers support silencing uncaught errors by calling + // `preventDefault()` in window `error` handler. + // We record this information as an expando on the error. - if ( - renderState.tail === null && - renderState.tailMode === "hidden" && - !renderedTail.alternate - ) { - // 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. + if (error != null && error._suppressLogging) { + if (errorBoundaryFound && willRetry) { + // 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 (lastEffect !== null) { - lastEffect.nextEffect = null; - } // We're done. + console.error(error); // For a more detailed description of this block, see: + // https://github.com/facebook/react/pull/13384 + } - return null; - } - } else if ( - // The time it took to render last row is greater than time until - // the expiration. - now() * 2 - renderState.renderingStartTime > - renderState.tailExpiration && - renderExpirationTime > Never - ) { - // 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.effectTag |= 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. If we can show - // them, then they really have the same priority as this render. - // So we'll pick it back up the very next render pass once we've had - // an opportunity to yield for paint. + var componentNameMessage = componentName + ? "The above error occurred in the <" + componentName + "> component:" + : "The above error occurred in one of your React components:"; + var errorBoundaryMessage; // errorBoundaryFound check is sufficient; errorBoundaryName check is to satisfy Flow. - var nextPriority = renderExpirationTime - 1; - workInProgress.expirationTime = workInProgress.childExpirationTime = nextPriority; + if (errorBoundaryFound && errorBoundaryName) { + if (willRetry) { + errorBoundaryMessage = + "React will try to recreate this component tree from scratch " + + ("using the error boundary you provided, " + errorBoundaryName + "."); + } else { + errorBoundaryMessage = + "This error was initially handled by the error boundary " + + errorBoundaryName + + ".\n" + + "Recreating the tree from scratch failed so React will unmount the tree."; + } + } else { + errorBoundaryMessage = + "Consider adding an error boundary to your tree to customize error handling behavior.\n" + + "Visit https://fb.me/react-error-boundaries to learn more about error boundaries."; + } + var combinedMessage = + "" + + componentNameMessage + + 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. - { - markSpawnedWork(nextPriority); - } - } - } + console.error(combinedMessage); + } +} - 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 didWarnAboutUndefinedSnapshotBeforeUpdate = null; +{ + didWarnAboutUndefinedSnapshotBeforeUpdate = new Set(); +} - if (previousSibling !== null) { - previousSibling.sibling = renderedTail; - } else { - workInProgress.child = renderedTail; - } +var PossiblyWeakSet = typeof WeakSet === "function" ? WeakSet : Set; +function logError(boundary, errorInfo) { + var source = errorInfo.source; + var stack = errorInfo.stack; - renderState.last = renderedTail; - } - } + if (stack === null && source !== null) { + stack = getStackByFiberInDevAndProd(source); + } - if (renderState.tail !== null) { - // We still have tail rows to render. - if (renderState.tailExpiration === 0) { - // Heuristic for how long we're willing to spend rendering rows - // until we just give up and show what we have so far. - var TAIL_EXPIRATION_TIMEOUT_MS = 500; - renderState.tailExpiration = now() + TAIL_EXPIRATION_TIMEOUT_MS; // TODO: This is meant to mimic the train model or JND but this - // is a per component value. It should really be since the start - // of the total render or last commit. Consider using something like - // globalMostRecentFallbackTime. That doesn't account for being - // suspended for part of the time or when it's a new render. - // It should probably use a global start time value instead. - } // Pop a row. + var capturedError = { + componentName: source !== null ? getComponentName(source.type) : null, + componentStack: stack !== null ? stack : "", + error: errorInfo.value, + errorBoundary: null, + errorBoundaryName: null, + errorBoundaryFound: false, + willRetry: false + }; - 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. + if (boundary !== null && boundary.tag === ClassComponent) { + capturedError.errorBoundary = boundary.stateNode; + capturedError.errorBoundaryName = getComponentName(boundary.type); + capturedError.errorBoundaryFound = true; + capturedError.willRetry = true; + } - var suspenseContext = suspenseStackCursor.current; + try { + logCapturedError(capturedError); + } 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; + }); + } +} - if (didSuspendAlready) { - suspenseContext = setShallowSuspenseContext( - suspenseContext, - ForceSuspenseFallback - ); - } else { - suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); - } +var callComponentWillUnmountWithTimer = function(current$$1, instance) { + startPhaseTimer(current$$1, "componentWillUnmount"); + instance.props = current$$1.memoizedProps; + instance.state = current$$1.memoizedState; + instance.componentWillUnmount(); + stopPhaseTimer(); +}; // Capture errors so they don't interrupt unmounting. - pushSuspenseContext(workInProgress, suspenseContext); // Do a pass over the next row. +function safelyCallComponentWillUnmount(current$$1, instance) { + { + invokeGuardedCallback( + null, + callComponentWillUnmountWithTimer, + null, + current$$1, + instance + ); + if (hasCaughtError()) { + var unmountError = clearCaughtError(); + captureCommitPhaseError(current$$1, unmountError); + } + } +} - return next; +function safelyDetachRef(current$$1) { + var ref = current$$1.ref; + if (ref !== null) { + if (typeof ref === "function") { + { + invokeGuardedCallback(null, ref, null, null); + if (hasCaughtError()) { + var refError = clearCaughtError(); + captureCommitPhaseError(current$$1, refError); + } } - - return null; + } else { + ref.current = null; } } +} +function safelyCallDestroy(current$$1, destroy) { { - 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, destroy, null); + if (hasCaughtError()) { + var error = clearCaughtError(); + captureCommitPhaseError(current$$1, error); + } } } -function unwindWork(workInProgress, renderExpirationTime) { - switch (workInProgress.tag) { +function commitBeforeMutationLifeCycles(current$$1, finishedWork) { + switch (finishedWork.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + commitHookEffectList(UnmountSnapshot, NoEffect$1, finishedWork); + return; + } case ClassComponent: { - var Component = workInProgress.type; + if (finishedWork.effectTag & Snapshot) { + if (current$$1 !== null) { + var prevProps = current$$1.memoizedProps; + var prevState = current$$1.memoizedState; + startPhaseTimer(finishedWork, "getSnapshotBeforeUpdate"); + 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 (isContextProvider(Component)) { - popContext(workInProgress); - } + { + if ( + finishedWork.type === finishedWork.elementType && + !didWarnAboutReassigningProps + ) { + !(instance.props === finishedWork.memoizedProps) + ? warning$1( + false, + "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" + ) + : void 0; + !(instance.state === finishedWork.memoizedState) + ? warning$1( + false, + "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.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ) + : void 0; + } + } + var snapshot = instance.getSnapshotBeforeUpdate( + finishedWork.elementType === finishedWork.type + ? prevProps + : resolveDefaultProps(finishedWork.type, prevProps), + prevState + ); - var effectTag = workInProgress.effectTag; + { + var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate; - if (effectTag & ShouldCapture) { - workInProgress.effectTag = (effectTag & ~ShouldCapture) | DidCapture; - return workInProgress; + if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) { + didWarnSet.add(finishedWork.type); + warningWithoutStack$1( + false, + "%s.getSnapshotBeforeUpdate(): A snapshot value (or null) " + + "must be returned. You have returned undefined.", + getComponentName(finishedWork.type) + ); + } + } + instance.__reactInternalSnapshotBeforeUpdate = snapshot; + stopPhaseTimer(); + } } - return null; + return; } - case HostRoot: { - popHostContainer(workInProgress); - popTopLevelContextObject(workInProgress); - var _effectTag = workInProgress.effectTag; + case HostRoot: + case HostComponent: + case HostText: + case HostPortal: + case IncompleteClassComponent: + // Nothing to do for these component types + return; - if (!((_effectTag & DidCapture) === NoEffect)) { + default: { + { throw Error( - "The root failed to unmount after an error. This is likely 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." ); } - - workInProgress.effectTag = (_effectTag & ~ShouldCapture) | DidCapture; - return workInProgress; - } - - case HostComponent: { - // TODO: popHydrationState - popHostContext(workInProgress); - return null; } + } +} - case SuspenseComponent: { - popSuspenseContext(workInProgress); - - var _effectTag2 = workInProgress.effectTag; +function commitHookEffectList(unmountTag, mountTag, finishedWork) { + var updateQueue = finishedWork.updateQueue; + var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; - if (_effectTag2 & ShouldCapture) { - workInProgress.effectTag = (_effectTag2 & ~ShouldCapture) | DidCapture; // Captured a suspense effect. Re-render the boundary. + if (lastEffect !== null) { + var firstEffect = lastEffect.next; + var effect = firstEffect; - return workInProgress; + do { + if ((effect.tag & unmountTag) !== NoEffect$1) { + // Unmount + var destroy = effect.destroy; + effect.destroy = undefined; + if (destroy !== undefined) { + destroy(); + } } + if ((effect.tag & mountTag) !== NoEffect$1) { + // Mount + var create = effect.create; + effect.destroy = create(); - 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; + { + var _destroy = effect.destroy; - case ContextProvider: - popProvider(workInProgress); - return null; + if (_destroy !== undefined && typeof _destroy !== "function") { + var addendum = void 0; - default: - return null; + 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://fb.me/react-hooks-data-fetching"; + } else { + addendum = " You returned: " + _destroy; + } + warningWithoutStack$1( + false, + "An effect function must not return anything besides a function, " + + "which is used for clean-up.%s%s", + addendum, + getStackByFiberInDevAndProd(finishedWork) + ); + } + } + } + effect = effect.next; + } while (effect !== firstEffect); } } -function unwindInterruptedWork(interruptedWork) { - switch (interruptedWork.tag) { - case ClassComponent: { - var childContextTypes = interruptedWork.type.childContextTypes; - - if (childContextTypes !== null && childContextTypes !== undefined) { - popContext(interruptedWork); +function commitPassiveHookEffects(finishedWork) { + if ((finishedWork.effectTag & Passive) !== NoEffect) { + switch (finishedWork.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + commitHookEffectList(UnmountPassive, NoEffect$1, finishedWork); + commitHookEffectList(NoEffect$1, MountPassive, finishedWork); + break; } - - break; - } - - case HostRoot: { - popHostContainer(interruptedWork); - popTopLevelContextObject(interruptedWork); - break; - } - - case HostComponent: { - popHostContext(interruptedWork); - break; + default: + break; } - - case HostPortal: - popHostContainer(interruptedWork); - break; - - case SuspenseComponent: - popSuspenseContext(interruptedWork); - break; - - case SuspenseListComponent: - popSuspenseContext(interruptedWork); - break; - - case ContextProvider: - popProvider(interruptedWork); - 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) - }; -} - -// Module provided by RN: - -if ( - !( - typeof ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog === - "function" - ) +function commitLifeCycles( + finishedRoot, + current$$1, + finishedWork, + committedExpirationTime ) { - throw Error( - "Expected ReactFiberErrorDialog.showErrorDialog to be a function." - ); -} + switch (finishedWork.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + commitHookEffectList(UnmountLayout, MountLayout, finishedWork); + break; + } -function showErrorDialog(capturedError) { - return ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog( - capturedError - ); -} + case ClassComponent: { + var instance = finishedWork.stateNode; -function logCapturedError(capturedError) { - var logError = showErrorDialog(capturedError); // Allow injected showErrorDialog() to prevent default console.error logging. - // This enables renderers like ReactNative to better manage redbox behavior. + if (finishedWork.effectTag & Update) { + if (current$$1 === null) { + startPhaseTimer(finishedWork, "componentDidMount"); // 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 (logError === false) { - return; - } + { + if ( + finishedWork.type === finishedWork.elementType && + !didWarnAboutReassigningProps + ) { + !(instance.props === finishedWork.memoizedProps) + ? warning$1( + false, + "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" + ) + : void 0; + !(instance.state === finishedWork.memoizedState) + ? warning$1( + false, + "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.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ) + : void 0; + } + } + instance.componentDidMount(); + stopPhaseTimer(); + } else { + var prevProps = + finishedWork.elementType === finishedWork.type + ? current$$1.memoizedProps + : resolveDefaultProps( + finishedWork.type, + current$$1.memoizedProps + ); + var prevState = current$$1.memoizedState; + startPhaseTimer(finishedWork, "componentDidUpdate"); // 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 error = capturedError.error; + { + if ( + finishedWork.type === finishedWork.elementType && + !didWarnAboutReassigningProps + ) { + !(instance.props === finishedWork.memoizedProps) + ? warning$1( + false, + "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" + ) + : void 0; + !(instance.state === finishedWork.memoizedState) + ? warning$1( + false, + "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.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ) + : void 0; + } + } + instance.componentDidUpdate( + prevProps, + prevState, + instance.__reactInternalSnapshotBeforeUpdate + ); + stopPhaseTimer(); + } + } - { - var componentName = capturedError.componentName, - componentStack = capturedError.componentStack, - errorBoundaryName = capturedError.errorBoundaryName, - errorBoundaryFound = capturedError.errorBoundaryFound, - willRetry = capturedError.willRetry; // Browsers support silencing uncaught errors by calling - // `preventDefault()` in window `error` handler. - // We record this information as an expando on the error. + var updateQueue = finishedWork.updateQueue; - if (error != null && error._suppressLogging) { - if (errorBoundaryFound && willRetry) { - // 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 (updateQueue !== null) { + { + if ( + finishedWork.type === finishedWork.elementType && + !didWarnAboutReassigningProps + ) { + !(instance.props === finishedWork.memoizedProps) + ? warning$1( + false, + "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" + ) + : void 0; + !(instance.state === finishedWork.memoizedState) + ? warning$1( + false, + "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.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ) + : void 0; + } + } // 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. - 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 + commitUpdateQueue( + finishedWork, + updateQueue, + instance, + committedExpirationTime + ); + } + + return; } - var componentNameMessage = componentName - ? "The above error occurred in the <" + componentName + "> component:" - : "The above error occurred in one of your React components:"; - var errorBoundaryMessage; // errorBoundaryFound check is sufficient; errorBoundaryName check is to satisfy Flow. + case HostRoot: { + var _updateQueue = finishedWork.updateQueue; - if (errorBoundaryFound && errorBoundaryName) { - if (willRetry) { - errorBoundaryMessage = - "React will try to recreate this component tree from scratch " + - ("using the error boundary you provided, " + errorBoundaryName + "."); - } else { - errorBoundaryMessage = - "This error was initially handled by the error boundary " + - errorBoundaryName + - ".\n" + - "Recreating the tree from scratch failed so React will unmount the tree."; + 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; + } + } + commitUpdateQueue( + finishedWork, + _updateQueue, + _instance, + committedExpirationTime + ); } - } else { - errorBoundaryMessage = - "Consider adding an error boundary to your tree to customize error handling behavior.\n" + - "Visit https://fb.me/react-error-boundaries to learn more about error boundaries."; - } - var combinedMessage = - "" + - componentNameMessage + - 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; + } - console["error"](combinedMessage); // Don't transform to our wrapper - } -} + 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 didWarnAboutUndefinedSnapshotBeforeUpdate = null; + if (current$$1 === null && finishedWork.effectTag & Update) { + var type = finishedWork.type; + var props = finishedWork.memoizedProps; + commitMount(_instance2, type, props, finishedWork); + } -{ - didWarnAboutUndefinedSnapshotBeforeUpdate = new Set(); -} + return; + } + case HostText: { + // We have no life-cycles associated with text. + return; + } + case HostPortal: { + // We have no life-cycles associated with portals. + return; + } + case Profiler: { + if (enableProfilerTimer) { + var onRender = finishedWork.memoizedProps.onRender; -var PossiblyWeakSet = typeof WeakSet === "function" ? WeakSet : Set; -function logError(boundary, errorInfo) { - var source = errorInfo.source; - var stack = errorInfo.stack; + if (typeof onRender === "function") { + if (enableSchedulerTracing) { + onRender( + finishedWork.memoizedProps.id, + current$$1 === null ? "mount" : "update", + finishedWork.actualDuration, + finishedWork.treeBaseDuration, + finishedWork.actualStartTime, + getCommitTime(), + finishedRoot.memoizedInteractions + ); + } else { + onRender( + finishedWork.memoizedProps.id, + current$$1 === null ? "mount" : "update", + finishedWork.actualDuration, + finishedWork.treeBaseDuration, + finishedWork.actualStartTime, + getCommitTime() + ); + } + } + } - if (stack === null && source !== null) { - stack = getStackByFiberInDevAndProd(source); - } + return; + } - var capturedError = { - componentName: source !== null ? getComponentName(source.type) : null, - componentStack: stack !== null ? stack : "", - error: errorInfo.value, - errorBoundary: null, - errorBoundaryName: null, - errorBoundaryFound: false, - willRetry: false - }; + case SuspenseComponent: { + commitSuspenseHydrationCallbacks(finishedRoot, finishedWork); + return; + } - if (boundary !== null && boundary.tag === ClassComponent) { - capturedError.errorBoundary = boundary.stateNode; - capturedError.errorBoundaryName = getComponentName(boundary.type); - capturedError.errorBoundaryFound = true; - capturedError.willRetry = true; - } + case SuspenseListComponent: + case IncompleteClassComponent: + case FundamentalComponent: + case ScopeComponent: + return; - try { - logCapturedError(capturedError); - } 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; - }); + 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." + ); + } + } } } -var callComponentWillUnmountWithTimer = function(current, instance) { - startPhaseTimer(current, "componentWillUnmount"); - instance.props = current.memoizedProps; - instance.state = current.memoizedState; +function hideOrUnhideAllChildren(finishedWork, isHidden) { + if (supportsMutation) { + // 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; - { - instance.componentWillUnmount(); - } + while (true) { + if (node.tag === HostComponent) { + var instance = node.stateNode; - stopPhaseTimer(); -}; // Capture errors so they don't interrupt unmounting. + if (isHidden) { + hideInstance(instance); + } else { + unhideInstance(node.stateNode, node.memoizedProps); + } + } else if (node.tag === HostText) { + var _instance3 = node.stateNode; + if (isHidden) { + hideTextInstance(_instance3); + } else { + unhideTextInstance(_instance3, node.memoizedProps); + } + } else if ( + node.tag === SuspenseComponent && + node.memoizedState !== null && + node.memoizedState.dehydrated === null + ) { + // Found a nested Suspense component that timed out. Skip over the + // primary child fragment, which should remain hidden. + var fallbackChildFragment = node.child.sibling; + fallbackChildFragment.return = node; + node = fallbackChildFragment; + continue; + } else if (node.child !== null) { + node.child.return = node; + node = node.child; + continue; + } -function safelyCallComponentWillUnmount(current, instance) { - { - invokeGuardedCallback( - null, - callComponentWillUnmountWithTimer, - null, - current, - instance - ); + if (node === finishedWork) { + return; + } - if (hasCaughtError()) { - var unmountError = clearCaughtError(); - captureCommitPhaseError(current, unmountError); + while (node.sibling === null) { + if (node.return === null || node.return === finishedWork) { + return; + } + + 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 (enableScopeAPI && finishedWork.tag === ScopeComponent) { + instanceToUse = instance.methods; + } + if (typeof ref === "function") { + ref(instanceToUse); + } else { { - invokeGuardedCallback(null, ref, null, null); - - if (hasCaughtError()) { - var refError = clearCaughtError(); - captureCommitPhaseError(current, refError); + if (!ref.hasOwnProperty("current")) { + warningWithoutStack$1( + false, + "Unexpected ref object provided for %s. " + + "Use either a ref-setter function or React.createRef().%s", + getComponentName(finishedWork.type), + getStackByFiberInDevAndProd(finishedWork) + ); } } - } else { - ref.current = null; + + ref.current = instanceToUse; } } } -function safelyCallDestroy(current, destroy) { - { - invokeGuardedCallback(null, destroy, null); - - if (hasCaughtError()) { - var error = clearCaughtError(); - captureCommitPhaseError(current, error); +function commitDetachRef(current$$1) { + var currentRef = current$$1.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 commitBeforeMutationLifeCycles(current, finishedWork) { - switch (finishedWork.tag) { +function commitUnmount(finishedRoot, current$$1, renderPriorityLevel) { + onCommitUnmount(current$$1); + + switch (current$$1.tag) { case FunctionComponent: case ForwardRef: - case SimpleMemoComponent: - case Block: { - return; + case MemoComponent: + case SimpleMemoComponent: { + var updateQueue = current$$1.updateQueue; + + if (updateQueue !== null) { + var lastEffect = updateQueue.lastEffect; + + if (lastEffect !== null) { + var firstEffect = lastEffect.next; // When the owner fiber is deleted, the destroy function of a passive + // effect hook is called during the synchronous commit phase. This is + // a concession to implementation complexity. Calling it in the + // passive effect phase (like they usually are, when dependencies + // change during an update) would require either traversing the + // children of the deleted fiber again, or including unmount effects + // as part of the fiber effect list. + // + // Because this is during the sync commit phase, we need to change + // the priority. + // + // TODO: Reconsider this implementation trade off. + var priorityLevel = + renderPriorityLevel > NormalPriority + ? NormalPriority + : renderPriorityLevel; + runWithPriority$1(priorityLevel, function() { + var effect = firstEffect; + + do { + var destroy = effect.destroy; + + if (destroy !== undefined) { + safelyCallDestroy(current$$1, destroy); + } + + effect = effect.next; + } while (effect !== firstEffect); + }); + } + } + + break; } case ClassComponent: { - if (finishedWork.effectTag & Snapshot) { - if (current !== null) { - var prevProps = current.memoizedProps; - var prevState = current.memoizedState; - startPhaseTimer(finishedWork, "getSnapshotBeforeUpdate"); - 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. + safelyDetachRef(current$$1); + var instance = current$$1.stateNode; - { - 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 instance.componentWillUnmount === "function") { + safelyCallComponentWillUnmount(current$$1, instance); + } - 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" - ); - } - } - } + return; + } - var snapshot = instance.getSnapshotBeforeUpdate( - finishedWork.elementType === finishedWork.type - ? prevProps - : resolveDefaultProps(finishedWork.type, prevProps), - prevState - ); + case HostComponent: { + if (enableFlareAPI) { + var dependencies = current$$1.dependencies; - { - var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate; + if (dependencies !== null) { + var respondersMap = dependencies.responders; - if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) { - didWarnSet.add(finishedWork.type); + if (respondersMap !== null) { + var responderInstances = Array.from(respondersMap.values()); - error( - "%s.getSnapshotBeforeUpdate(): A snapshot value (or null) " + - "must be returned. You have returned undefined.", - getComponentName(finishedWork.type) - ); + for ( + var i = 0, length = responderInstances.length; + i < length; + i++ + ) { + var responderInstance = responderInstances[i]; + unmountResponderInstance(responderInstance); } + dependencies.responders = null; } + } + } - instance.__reactInternalSnapshotBeforeUpdate = snapshot; - stopPhaseTimer(); + safelyDetachRef(current$$1); + return; + } + + case HostPortal: { + // TODO: this is recursive. + // We are also not using this parent because + // the portal will get pushed immediately. + if (supportsMutation) { + unmountHostComponents(finishedRoot, current$$1, renderPriorityLevel); + } else if (supportsPersistence) { + emptyPortalContainer(current$$1); + } + + return; + } + + case FundamentalComponent: { + if (enableFundamentalAPI) { + var fundamentalInstance = current$$1.stateNode; + + if (fundamentalInstance !== null) { + unmountFundamentalComponent(fundamentalInstance); + current$$1.stateNode = null; } } return; } - case HostRoot: - case HostComponent: - case HostText: - case HostPortal: - case IncompleteClassComponent: - // Nothing to do for these component types + case DehydratedFragment: { + if (enableSuspenseCallback) { + var hydrationCallbacks = finishedRoot.hydrationCallbacks; + + if (hydrationCallbacks !== null) { + var onDeleted = hydrationCallbacks.onDeleted; + + if (onDeleted) { + onDeleted(current$$1.stateNode); + } + } + } + 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: { + if (enableScopeAPI) { + safelyDetachRef(current$$1); + } + } } } -function commitHookEffectListUnmount(tag, finishedWork) { - var updateQueue = finishedWork.updateQueue; - var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; +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 (lastEffect !== null) { - var firstEffect = lastEffect.next; - var effect = firstEffect; + while (true) { + commitUnmount(finishedRoot, node, renderPriorityLevel); // 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. + (!supportsMutation || 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 commitHookEffectListMount(tag, finishedWork) { - var updateQueue = finishedWork.updateQueue; - var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; +function detachFiber(current$$1) { + var alternate = current$$1.alternate; // 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. + current$$1.return = null; + current$$1.child = null; + current$$1.memoizedState = null; + current$$1.updateQueue = null; + current$$1.dependencies = null; + current$$1.alternate = null; + current$$1.firstEffect = null; + current$$1.lastEffect = null; + current$$1.pendingProps = null; + current$$1.memoizedProps = null; + if (alternate !== null) { + detachFiber(alternate); + } +} - if (lastEffect !== null) { - var firstEffect = lastEffect.next; - var effect = firstEffect; +function emptyPortalContainer(current$$1) { + if (!supportsPersistence) { + return; + } - do { - if ((effect.tag & tag) === tag) { - // Mount - var create = effect.create; - effect.destroy = create(); + var portal = current$$1.stateNode; + var containerInfo = portal.containerInfo; + var emptyChildSet = createContainerChildSet(containerInfo); +} + +function commitContainer(finishedWork) { + if (!supportsPersistence) { + return; + } + + switch (finishedWork.tag) { + case ClassComponent: + case HostComponent: + case HostText: + case FundamentalComponent: { + return; + } + case HostRoot: + case HostPortal: { + var portalOrRoot = finishedWork.stateNode; + var containerInfo = portalOrRoot.containerInfo, + pendingChildren = portalOrRoot.pendingChildren; + return; + } + + 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." + ); + } + } + } +} + +function getHostParentFiber(fiber) { + var parent = fiber.return; + while (parent !== null) { + if (isHostParent(parent)) { + return parent; + } + + 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://fb.me/react-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%s", - addendum, - getStackByFiberInDevAndProd(finishedWork) - ); - } - } + 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); - } -} + node = node.return; + } -function commitPassiveHookEffects(finishedWork) { - if ((finishedWork.effectTag & Passive) !== NoEffect) { - switch (finishedWork.tag) { - case FunctionComponent: - case ForwardRef: - case SimpleMemoComponent: - case Block: { - // TODO (#17945) We should call all passive destroy functions (for all fibers) - // before calling any create functions. The current approach only serializes - // these for a single fiber. - { - commitHookEffectListUnmount(Passive$1 | HasEffect, finishedWork); - commitHookEffectListMount(Passive$1 | HasEffect, finishedWork); - } + node.sibling.return = node.return; + node = node.sibling; - break; + 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.effectTag & 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 (!(node.effectTag & Placement)) { + // Found it! + return node.stateNode; } } } -function commitLifeCycles( - finishedRoot, - current, - finishedWork, - committedExpirationTime -) { - switch (finishedWork.tag) { - case FunctionComponent: - case ForwardRef: - case SimpleMemoComponent: - case Block: { - // 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) { + if (!supportsMutation) { + return; + } // Recursively insert all host nodes into the parent. - return; - } + var parentFiber = getHostParentFiber(finishedWork); // Note: these two variables *must* always be updated together. - case ClassComponent: { - var instance = finishedWork.stateNode; + var parent; + var isContainer; + var parentStateNode = parentFiber.stateNode; - if (finishedWork.effectTag & Update) { - if (current === null) { - startPhaseTimer(finishedWork, "componentDidMount"); // 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. + 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: + if (enableFundamentalAPI) { + parent = parentStateNode.instance; + isContainer = false; + } - { - 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" - ); - } + // eslint-disable-next-line-no-fallthrough - 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" - ); - } - } - } + default: { + throw Error( + "Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue." + ); + } + } - { - instance.componentDidMount(); - } + if (parentFiber.effectTag & ContentReset) { + // Reset the text content of the parent before doing any insertions + resetTextContent(parent); // Clear ContentReset from the effect tag - stopPhaseTimer(); - } else { - var prevProps = - finishedWork.elementType === finishedWork.type - ? current.memoizedProps - : resolveDefaultProps(finishedWork.type, current.memoizedProps); - var prevState = current.memoizedState; - startPhaseTimer(finishedWork, "componentDidUpdate"); // 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. + parentFiber.effectTag &= ~ContentReset; + } - { - 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" - ); - } + 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 (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 node = finishedWork; - { - instance.componentDidUpdate( - prevProps, - prevState, - instance.__reactInternalSnapshotBeforeUpdate - ); - } + while (true) { + var isHost = node.tag === HostComponent || node.tag === HostText; - stopPhaseTimer(); + if (isHost || (enableFundamentalAPI && node.tag === FundamentalComponent)) { + var stateNode = isHost ? node.stateNode : node.stateNode.instance; + + if (before) { + if (isContainer) { + insertInContainerBefore(parent, stateNode, before); + } else { + insertBefore(parent, stateNode, before); + } + } else { + if (isContainer) { + appendChildToContainer(parent, stateNode); + } else { + appendChild(parent, stateNode); } } + } else if (node.tag === HostPortal) { + // If the insertion itself is a portal, then we don't want to traverse + // down its children. Instead, we'll get insertions from each child in + // the portal directly. + } else if (node.child !== null) { + node.child.return = node; + node = node.child; + continue; + } - 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. + if (node === finishedWork) { + return; + } - commitUpdateQueue(finishedWork, updateQueue, instance); + while (node.sibling === null) { + if (node.return === null || node.return === finishedWork) { + return; } - return; + node = node.return; } - case HostRoot: { - var _updateQueue = finishedWork.updateQueue; + node.sibling.return = node.return; + node = node.sibling; + } +} - if (_updateQueue !== null) { - var _instance = null; +function unmountHostComponents(finishedRoot, current$$1, 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$$1; // Each iteration, currentParent is populated with node's host parent if not + // currentParentIsValid. - if (finishedWork.child !== null) { - switch (finishedWork.child.tag) { - case HostComponent: - _instance = getPublicInstance(finishedWork.child.stateNode); - break; + var currentParentIsValid = false; // Note: these two variables *must* always be updated together. - case ClassComponent: - _instance = finishedWork.child.stateNode; - break; - } - } + var currentParent; + var currentParentIsContainer; - commitUpdateQueue(finishedWork, _updateQueue, _instance); - } + while (true) { + if (!currentParentIsValid) { + var parent = node.return; - 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 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 parentStateNode = parent.stateNode; + + switch (parent.tag) { + case HostComponent: + currentParent = parentStateNode; + currentParentIsContainer = false; + break findParent; + case HostRoot: + currentParent = parentStateNode.containerInfo; + currentParentIsContainer = true; + break findParent; + case HostPortal: + currentParent = parentStateNode.containerInfo; + currentParentIsContainer = true; + break findParent; + case FundamentalComponent: + if (enableFundamentalAPI) { + currentParent = parentStateNode.instance; + currentParentIsContainer = false; + } + } - if (current === null && finishedWork.effectTag & Update) { - var type = finishedWork.type; - var props = finishedWork.memoizedProps; - commitMount(); + parent = parent.return; } - return; + currentParentIsValid = true; } - case HostText: { - // We have no life-cycles associated with text. - return; - } + if (node.tag === HostComponent || node.tag === HostText) { + commitNestedUnmounts(finishedRoot, node, renderPriorityLevel); // After all the children have unmounted, it is now safe to remove the + // node from the tree. - case HostPortal: { - // We have no life-cycles associated with portals. - return; - } + if (currentParentIsContainer) { + removeChildFromContainer(currentParent, node.stateNode); + } else { + removeChild(currentParent, node.stateNode); + } // Don't visit children because we already visited them. + } else if (enableFundamentalAPI && node.tag === FundamentalComponent) { + var fundamentalNode = node.stateNode.instance; + commitNestedUnmounts(finishedRoot, node, renderPriorityLevel); // After all the children have unmounted, it is now safe to remove the + // node from the tree. + + if (currentParentIsContainer) { + removeChildFromContainer(currentParent, fundamentalNode); + } else { + removeChild(currentParent, fundamentalNode); + } + } else if ( + enableSuspenseServerRenderer && + node.tag === DehydratedFragment + ) { + if (enableSuspenseCallback) { + var hydrationCallbacks = finishedRoot.hydrationCallbacks; - case Profiler: { - { - var _finishedWork$memoize2 = finishedWork.memoizedProps, - onCommit = _finishedWork$memoize2.onCommit, - onRender = _finishedWork$memoize2.onRender; - var effectDuration = finishedWork.stateNode.effectDuration; - var commitTime = getCommitTime(); + if (hydrationCallbacks !== null) { + var onDeleted = hydrationCallbacks.onDeleted; - if (typeof onRender === "function") { - { - onRender( - finishedWork.memoizedProps.id, - current === null ? "mount" : "update", - finishedWork.actualDuration, - finishedWork.treeBaseDuration, - finishedWork.actualStartTime, - commitTime, - finishedRoot.memoizedInteractions - ); + if (onDeleted) { + onDeleted(node.stateNode); } } + } // Delete the dehydrated suspense boundary and all of its content. + + if (currentParentIsContainer) { + clearSuspenseBoundaryFromContainer(currentParent, node.stateNode); + } else { + clearSuspenseBoundary(currentParent, node.stateNode); + } + } 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. + + node.child.return = node; + node = node.child; + continue; + } + } else { + commitUnmount(finishedRoot, node, renderPriorityLevel); // Visit children because we may find more host components below. + + if (node.child !== null) { + node.child.return = node; + node = node.child; + continue; } - - return; } - case SuspenseComponent: { + if (node === current$$1) { return; } - case SuspenseListComponent: - case IncompleteClassComponent: - case FundamentalComponent: - case ScopeComponent: - return; - } + while (node.sibling === null) { + if (node.return === null || node.return === current$$1) { + 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." - ); + 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; } } -function commitAttachRef(finishedWork) { - var ref = finishedWork.ref; +function commitDeletion(finishedRoot, current$$1, renderPriorityLevel) { + if (supportsMutation) { + // Recursively delete all host nodes from the parent. + // Detach refs and call componentWillUnmount() on the whole subtree. + unmountHostComponents(finishedRoot, current$$1, renderPriorityLevel); + } else { + // Detach refs and call componentWillUnmount() on the whole subtree. + commitNestedUnmounts(finishedRoot, current$$1, renderPriorityLevel); + } - if (ref !== null) { - var instance = finishedWork.stateNode; - var instanceToUse; + detachFiber(current$$1); +} +function commitWork(current$$1, finishedWork) { + if (!supportsMutation) { switch (finishedWork.tag) { - case HostComponent: - instanceToUse = getPublicInstance(instance); - break; + case FunctionComponent: + case ForwardRef: + case MemoComponent: + case SimpleMemoComponent: { + // Note: We currently never use MountMutation, but useLayout uses + // UnmountMutation. + commitHookEffectList(UnmountMutation, MountMutation, finishedWork); + return; + } - default: - instanceToUse = instance; - } // Moved outside to ensure DCE works with this flag + case Profiler: { + return; + } - 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().%s", - getComponentName(finishedWork.type), - getStackByFiberInDevAndProd(finishedWork) - ); - } + case SuspenseComponent: { + commitSuspenseComponent(finishedWork); + attachSuspenseRetryListeners(finishedWork); + return; + } + case SuspenseListComponent: { + attachSuspenseRetryListeners(finishedWork); + return; } - ref.current = instanceToUse; - } - } -} + case HostRoot: { + if (supportsHydration) { + var root = finishedWork.stateNode; -function commitDetachRef(current) { - var currentRef = current.ref; + if (root.hydrate) { + // We've just hydrated. No need to hydrate again. + root.hydrate = false; + commitHydratedContainer(root.containerInfo); + } + } - if (currentRef !== null) { - if (typeof currentRef === "function") { - currentRef(null); - } else { - currentRef.current = null; + break; + } } - } -} // 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); + commitContainer(finishedWork); + return; + } - switch (current.tag) { + switch (finishedWork.tag) { case FunctionComponent: case ForwardRef: case MemoComponent: - case SimpleMemoComponent: - case Block: { - var updateQueue = current.updateQueue; + case SimpleMemoComponent: { + // Note: We currently never use MountMutation, but useLayout uses + // UnmountMutation. + commitHookEffectList(UnmountMutation, MountMutation, finishedWork); + return; + } - if (updateQueue !== null) { - var lastEffect = updateQueue.lastEffect; + case ClassComponent: { + return; + } - if (lastEffect !== null) { - var firstEffect = lastEffect.next; + case HostComponent: { + var instance = finishedWork.stateNode; - { - // When the owner fiber is deleted, the destroy function of a passive - // effect hook is called during the synchronous commit phase. This is - // a concession to implementation complexity. Calling it in the - // passive effect phase (like they usually are, when dependencies - // change during an update) would require either traversing the - // children of the deleted fiber again, or including unmount effects - // as part of the fiber effect list. - // - // Because this is during the sync commit phase, we need to change - // the priority. - // - // TODO: Reconsider this implementation trade off. - var priorityLevel = - renderPriorityLevel > NormalPriority - ? NormalPriority - : renderPriorityLevel; - runWithPriority(priorityLevel, function() { - var effect = firstEffect; - - do { - var _effect3 = effect, - _destroy = _effect3.destroy, - _tag = _effect3.tag; - - if (_destroy !== undefined) { - { - safelyCallDestroy(current, _destroy); - } - } + 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. + + var oldProps = + current$$1 !== null ? current$$1.memoizedProps : newProps; + var type = finishedWork.type; // TODO: Type the updateQueue to be specific to host components. - effect = effect.next; - } while (effect !== firstEffect); - }); + var updatePayload = finishedWork.updateQueue; + finishedWork.updateQueue = null; + + if (updatePayload !== null) { + commitUpdate( + instance, + updatePayload, + type, + oldProps, + newProps, + finishedWork + ); + } + + if (enableFlareAPI) { + var prevListeners = oldProps.listeners; + var nextListeners = newProps.listeners; + + if (prevListeners !== nextListeners) { + updateEventListeners(nextListeners, finishedWork, null); } } } @@ -15914,199 +18938,164 @@ function commitUnmount(finishedRoot, current, renderPriorityLevel) { 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." + ); } - return; - } + 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. - case HostComponent: { - safelyDetachRef(current); + var oldText = current$$1 !== null ? current$$1.memoizedProps : newText; + commitTextUpdate(textInstance, oldText, newText); return; } - case HostPortal: { - // TODO: this is recursive. - // We are also not using this parent because - // the portal will get pushed immediately. - { - emptyPortalContainer(current); + case HostRoot: { + if (supportsHydration) { + var _root = finishedWork.stateNode; + + if (_root.hydrate) { + // We've just hydrated. No need to hydrate again. + _root.hydrate = false; + commitHydratedContainer(_root.containerInfo); + } } return; } - case FundamentalComponent: { + case Profiler: { return; } - case DehydratedFragment: { + case SuspenseComponent: { + commitSuspenseComponent(finishedWork); + attachSuspenseRetryListeners(finishedWork); return; } - - case ScopeComponent: { + case SuspenseListComponent: { + attachSuspenseRetryListeners(finishedWork); return; } - } -} - -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, renderPriorityLevel); // 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 IncompleteClassComponent: { return; } - while (node.sibling === null) { - if (node.return === null || node.return === root) { - return; + case FundamentalComponent: { + if (enableFundamentalAPI) { + var fundamentalInstance = finishedWork.stateNode; + updateFundamentalComponent(fundamentalInstance); } - node = node.return; + return; } - node.sibling.return = node.return; - node = node.sibling; - } -} + case ScopeComponent: { + if (enableScopeAPI) { + var scopeInstance = finishedWork.stateNode; + scopeInstance.fiber = finishedWork; -function detachFiber(current) { - var alternate = current.alternate; // 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. + if (enableFlareAPI) { + var _newProps = finishedWork.memoizedProps; - current.return = null; - current.child = null; - current.memoizedState = null; - current.updateQueue = null; - current.dependencies = null; - current.alternate = null; - current.firstEffect = null; - current.lastEffect = null; - current.pendingProps = null; - current.memoizedProps = null; - current.stateNode = null; + var _oldProps = + current$$1 !== null ? current$$1.memoizedProps : _newProps; - if (alternate !== null) { - detachFiber(alternate); - } -} + var _prevListeners = _oldProps.listeners; + var _nextListeners = _newProps.listeners; -function emptyPortalContainer(current) { - var portal = current.stateNode; - var containerInfo = portal.containerInfo; - var emptyChildSet = createContainerChildSet(containerInfo); -} + if (_prevListeners !== _nextListeners) { + updateEventListeners(_nextListeners, finishedWork, null); + } + } + } -function commitContainer(finishedWork) { - switch (finishedWork.tag) { - case ClassComponent: - case HostComponent: - case HostText: - case FundamentalComponent: { return; } - case HostRoot: - case HostPortal: { - var portalOrRoot = finishedWork.stateNode; - var containerInfo = portalOrRoot.containerInfo, - pendingChildren = portalOrRoot.pendingChildren; - return; + 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." + ); + } } } - - { - 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, renderPriorityLevel) { - { - // Detach refs and call componentWillUnmount() on the whole subtree. - commitNestedUnmounts(finishedRoot, current, renderPriorityLevel); - } +function commitSuspenseComponent(finishedWork) { + var newState = finishedWork.memoizedState; + var newDidTimeout; + var primaryChildParent = finishedWork; - detachFiber(current); -} + if (newState === null) { + newDidTimeout = false; + } else { + newDidTimeout = true; + primaryChildParent = finishedWork.child; + markCommitTimeOfFallback(); + } -function commitWork(current, finishedWork) { - { - switch (finishedWork.tag) { - case FunctionComponent: - case ForwardRef: - case MemoComponent: - case SimpleMemoComponent: - case Block: { - // 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); - } + if (supportsMutation && primaryChildParent !== null) { + hideOrUnhideAllChildren(primaryChildParent, newDidTimeout); + } - return; - } + if (enableSuspenseCallback && newState !== null) { + var suspenseCallback = finishedWork.memoizedProps.suspenseCallback; - case Profiler: { - return; - } + if (typeof suspenseCallback === "function") { + var thenables = finishedWork.updateQueue; - case SuspenseComponent: { - commitSuspenseComponent(finishedWork); - attachSuspenseRetryListeners(finishedWork); - return; + if (thenables !== null) { + suspenseCallback(new Set(thenables)); } - - case SuspenseListComponent: { - attachSuspenseRetryListeners(finishedWork); - return; + } else { + if (suspenseCallback !== undefined) { + warning$1(false, "Unexpected type for suspenseCallback."); } } + } +} - commitContainer(finishedWork); +function commitSuspenseHydrationCallbacks(finishedRoot, finishedWork) { + if (!supportsHydration) { return; } -} -function commitSuspenseComponent(finishedWork) { var newState = finishedWork.memoizedState; - var primaryChildParent = finishedWork; - if (newState === null); - else { - primaryChildParent = finishedWork.child; - markCommitTimeOfFallback(); + if (newState === null) { + var current$$1 = finishedWork.alternate; + + if (current$$1 !== null) { + var prevState = current$$1.memoizedState; + + if (prevState !== null) { + var suspenseInstance = prevState.dehydrated; + + if (suspenseInstance !== null) { + commitHydratedSuspenseInstance(suspenseInstance); + + if (enableSuspenseCallback) { + var hydrationCallbacks = finishedRoot.hydrationCallbacks; + + if (hydrationCallbacks !== null) { + var onHydrated = hydrationCallbacks.onHydrated; + + if (onHydrated) { + onHydrated(suspenseInstance); + } + } + } + } + } + } } } @@ -16129,7 +19118,7 @@ function attachSuspenseRetryListeners(finishedWork) { var retry = resolveRetryThenable.bind(null, finishedWork, thenable); if (!retryCache.has(thenable)) { - { + if (enableSchedulerTracing) { if (thenable.__reactDoNotTraceInteractions !== true) { retry = tracing.unstable_wrap(retry); } @@ -16142,6 +19131,14 @@ function attachSuspenseRetryListeners(finishedWork) { } } +function commitResetTextContent(current$$1) { + if (!supportsMutation) { + return; + } + + resetTextContent(current$$1.stateNode); +} + var PossiblyWeakMap = typeof WeakMap === "function" ? WeakMap : Map; function createRootErrorUpdate(fiber, errorInfo, expirationTime) { @@ -16159,7 +19156,6 @@ function createRootErrorUpdate(fiber, errorInfo, expirationTime) { onUncaughtError(error); logError(fiber, errorInfo); }; - return update; } @@ -16169,22 +19165,20 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { var getDerivedStateFromError = fiber.type.getDerivedStateFromError; if (typeof getDerivedStateFromError === "function") { - var error$1 = errorInfo.value; + var error = errorInfo.value; update.payload = function() { logError(fiber, errorInfo); - return getDerivedStateFromError(error$1); + return getDerivedStateFromError(error); }; } var inst = fiber.stateNode; - if (inst !== null && typeof inst.componentDidCatch === "function") { update.callback = function callback() { { markFailedErrorBoundaryForHotReloading(fiber); } - if (typeof getDerivedStateFromError !== "function") { // To preserve the preexisting retry behavior of error boundaries, // we keep track of which ones already failed during this batch. @@ -16196,24 +19190,24 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { logError(fiber, errorInfo); } - var error$1 = errorInfo.value; + var error = errorInfo.value; var stack = errorInfo.stack; - this.componentDidCatch(error$1, { + this.componentDidCatch(error, { 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 (fiber.expirationTime !== Sync) { - 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" - ); - } + !(fiber.expirationTime === Sync) + ? warningWithoutStack$1( + false, + "%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" + ) + : void 0; } } }; @@ -16222,7 +19216,6 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { markFailedErrorBoundaryForHotReloading(fiber); }; } - return update; } @@ -16239,13 +19232,11 @@ function attachPingListener(root, renderExpirationTime, thenable) { pingCache.set(thenable, threadIDs); } else { threadIDs = pingCache.get(thenable); - if (threadIDs === undefined) { threadIDs = new Set(); pingCache.set(thenable, threadIDs); } } - if (!threadIDs.has(renderExpirationTime)) { // Memoize using the thread ID to prevent redundant listeners. threadIDs.add(renderExpirationTime); @@ -16278,22 +19269,7 @@ function throwException( ) { // This is a thenable. var thenable = 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.expirationTime = currentSource.expirationTime; - } else { - sourceFiber.updateQueue = null; - sourceFiber.memoizedState = null; - } - } - + checkForWrongSuspensePriorityInDEV(sourceFiber); var hasInvisibleParentBoundary = hasSuspenseContext( suspenseStackCursor.current, InvisibleParentSuspenseContext @@ -16335,7 +19311,6 @@ function throwException( 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 @@ -16429,7 +19404,6 @@ function throwException( var _errorInfo = value; workInProgress.effectTag |= ShouldCapture; workInProgress.expirationTime = renderExpirationTime; - var _update = createRootErrorUpdate( workInProgress, _errorInfo, @@ -16445,7 +19419,6 @@ function throwException( var errorInfo = value; var ctor = workInProgress.type; var instance = workInProgress.stateNode; - if ( (workInProgress.effectTag & DidCapture) === NoEffect && (typeof ctor.getDerivedStateFromError === "function" || @@ -16467,6 +19440,9 @@ function throwException( } break; + + default: + break; } workInProgress = workInProgress.return; @@ -16474,15 +19450,18 @@ function throwException( } var ceil = Math.ceil; -var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, - ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, - IsSomeRendererActing = ReactSharedInternals.IsSomeRendererActing; +var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher; +var ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner; +var IsSomeRendererActing = ReactSharedInternals.IsSomeRendererActing; var NoContext = /* */ 0; var BatchedContext = /* */ 1; +var EventContext = + /* */ + 2; var DiscreteEventContext = /* */ 4; @@ -16508,7 +19487,7 @@ var workInProgressRoot = null; // The fiber we're working on var workInProgress = null; // The expiration time we're rendering -var renderExpirationTime$1 = NoWork; // Whether to root completed, errored, suspended, etc. +var renderExpirationTime = NoWork; // Whether to root completed, errored, suspended, etc. var workInProgressRootExitStatus = RootIncomplete; // A fatal error, if one is thrown @@ -16585,7 +19564,6 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { } var priorityLevel = getCurrentPriorityLevel(); - if ((mode & ConcurrentMode) === NoMode) { return priorityLevel === ImmediatePriority ? Sync : Batched; } @@ -16593,7 +19571,7 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { if ((executionContext & RenderContext) !== NoContext) { // Use whatever time we're already rendering // TODO: Should there be a way to opt out, like with `runWithPriority`? - return renderExpirationTime$1; + return renderExpirationTime; } var expirationTime; @@ -16610,12 +19588,10 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { case ImmediatePriority: expirationTime = Sync; break; - - case UserBlockingPriority: + case UserBlockingPriority$1: // TODO: Rename this to computeUserBlockingExpiration expirationTime = computeInteractiveExpiration(currentTime); break; - case NormalPriority: case LowPriority: // TODO: Handle LowPriority @@ -16636,11 +19612,7 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { // TODO: We shouldn't have to do this if the update is on a different root. // Refactor computeExpirationForFiber + scheduleUpdate so we have access to // the root when we check for this condition. - - if ( - workInProgressRoot !== null && - expirationTime === renderExpirationTime$1 - ) { + if (workInProgressRoot !== null && expirationTime === renderExpirationTime) { // This is a trick to move this update into a separate batch expirationTime -= 1; } @@ -16649,7 +19621,7 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { } function scheduleUpdateOnFiber(fiber, expirationTime) { checkForNestedUpdates(); - warnAboutRenderPhaseUpdatesInDEV(fiber); + warnAboutInvalidUpdatesOnClassComponentsInDEV(fiber); var root = markUpdateTimeFromFiberToRoot(fiber, expirationTime); if (root === null) { @@ -16696,7 +19668,7 @@ function scheduleUpdateOnFiber(fiber, expirationTime) { if ( (executionContext & DiscreteEventContext) !== NoContext && // Only updates at user-blocking priority or greater are considered // discrete, even inside a discrete event. - (priorityLevel === UserBlockingPriority || + (priorityLevel === UserBlockingPriority$1 || priorityLevel === ImmediatePriority) ) { // This is the result of a discrete event. Track the lowest priority @@ -16705,7 +19677,6 @@ function scheduleUpdateOnFiber(fiber, expirationTime) { rootsWithPendingDiscreteUpdates = new Map([[root, expirationTime]]); } else { var lastDiscreteTime = rootsWithPendingDiscreteUpdates.get(root); - if (lastDiscreteTime === undefined || lastDiscreteTime > expirationTime) { rootsWithPendingDiscreteUpdates.set(root, expirationTime); } @@ -16753,12 +19724,10 @@ function markUpdateTimeFromFiberToRoot(fiber, expirationTime) { ) { alternate.childExpirationTime = expirationTime; } - if (node.return === null && node.tag === HostRoot) { root = node.stateNode; break; } - node = node.return; } } @@ -16783,7 +19752,7 @@ function markUpdateTimeFromFiberToRoot(fiber, expirationTime) { // scheduled before the root started rendering. Need to track the next // pending expiration time (perhaps by backtracking the return path) and // then trigger a restart in the `renderDidSuspendDelayIfPossible` path. - markRootSuspendedAtTime(root, renderExpirationTime$1); + markRootSuspendedAtTime(root, renderExpirationTime); } } // Mark that the root has a pending update. @@ -16815,17 +19784,9 @@ function getNextRootExpirationTimeToWorkOn(root) { var lastPingedTime = root.lastPingedTime; var nextKnownPendingLevel = root.nextKnownPendingLevel; - var nextLevel = - lastPingedTime > nextKnownPendingLevel - ? lastPingedTime - : nextKnownPendingLevel; - - if (nextLevel <= Idle && firstPendingTime !== nextLevel) { - // Don't work on Idle/Never priority unless everything else is committed. - return NoWork; - } - - return nextLevel; + return lastPingedTime > nextKnownPendingLevel + ? lastPingedTime + : nextKnownPendingLevel; } // 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 // expiration time of the existing task is the same as the expiration time of @@ -16892,6 +19853,11 @@ function ensureRootIsScheduled(root) { if (expirationTime === Sync) { // Sync React callbacks are scheduled on a special internal queue callbackNode = scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root)); + } else if (disableSchedulerTimeoutBasedOnReactExpirationTime) { + callbackNode = scheduleCallback( + priorityLevel, + performConcurrentWorkOnRoot.bind(null, root) + ); } else { callbackNode = scheduleCallback( priorityLevel, @@ -16910,7 +19876,7 @@ function ensureRootIsScheduled(root) { function performConcurrentWorkOnRoot(root, didTimeout) { // 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 = NoWork; // Check if the render expired. + currentEventTime = NoWork; if (didTimeout) { // The render task took too long to complete. Mark the current time as @@ -16925,50 +19891,83 @@ function performConcurrentWorkOnRoot(root, didTimeout) { var expirationTime = getNextRootExpirationTimeToWorkOn(root); - if (expirationTime === NoWork) { - return null; - } + if (expirationTime !== NoWork) { + var originalCallbackNode = root.callbackNode; - var originalCallbackNode = root.callbackNode; + if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { + throw Error("Should not already be working."); + } - if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { - throw Error("Should not already be working."); - } + flushPassiveEffects(); // If the root or expiration time have changed, throw out the existing stack + // and prepare a fresh one. Otherwise we'll continue where we left off. - flushPassiveEffects(); - var exitStatus = renderRootConcurrent(root, expirationTime); + if ( + root !== workInProgressRoot || + expirationTime !== renderExpirationTime + ) { + prepareFreshStack(root, expirationTime); + startWorkOnPendingInteractions(root, expirationTime); + } // If we have a work-in-progress fiber, it means there's still work to do + // in this root. - if (exitStatus !== RootIncomplete) { - if (exitStatus === RootErrored) { - // If something threw an error, try rendering one more time. We'll - // render synchronously to block concurrent data mutations, and we'll - // render at Idle (or lower) so that all pending updates are included. - // If it still fails after the second attempt, we'll give up and commit - // the resulting tree. - expirationTime = expirationTime > Idle ? Idle : expirationTime; - exitStatus = renderRootSync(root, expirationTime); - } + if (workInProgress !== null) { + var prevExecutionContext = executionContext; + executionContext |= RenderContext; + var prevDispatcher = pushDispatcher(root); + var prevInteractions = pushInteractions(root); + startWorkLoopTimer(workInProgress); - if (exitStatus === RootFatalErrored) { - var fatalError = workInProgressRootFatalError; - prepareFreshStack(root, expirationTime); - markRootSuspendedAtTime(root, expirationTime); - ensureRootIsScheduled(root); - throw fatalError; - } // We now have a consistent tree. The next step is either to commit it, - // or, if something suspended, wait to commit it after a timeout. + do { + try { + workLoopConcurrent(); + break; + } catch (thrownValue) { + handleError(root, thrownValue); + } + } while (true); - var finishedWork = (root.finishedWork = root.current.alternate); - root.finishedExpirationTime = expirationTime; - finishConcurrentRender(root, finishedWork, exitStatus, expirationTime); - } + resetContextDependencies(); + executionContext = prevExecutionContext; + popDispatcher(prevDispatcher); - ensureRootIsScheduled(root); + if (enableSchedulerTracing) { + popInteractions(prevInteractions); + } + + if (workInProgressRootExitStatus === RootFatalErrored) { + var fatalError = workInProgressRootFatalError; + stopInterruptedWorkLoopTimer(); + prepareFreshStack(root, expirationTime); + markRootSuspendedAtTime(root, expirationTime); + ensureRootIsScheduled(root); + throw fatalError; + } + + if (workInProgress !== null) { + // There's still work left over. Exit without committing. + stopInterruptedWorkLoopTimer(); + } else { + // We now have a consistent tree. The next step is either to commit it, + // or, if something suspended, wait to commit it after a timeout. + stopFinishedWorkLoopTimer(); + var finishedWork = (root.finishedWork = root.current.alternate); + root.finishedExpirationTime = expirationTime; + finishConcurrentRender( + root, + finishedWork, + workInProgressRootExitStatus, + expirationTime + ); + } + + ensureRootIsScheduled(root); - if (root.callbackNode === originalCallbackNode) { - // The task node scheduled for this root is the same one that's - // currently executed. Need to return a continuation. - return performConcurrentWorkOnRoot.bind(null, root); + if (root.callbackNode === originalCallbackNode) { + // The task node scheduled for this root is the same one that's + // currently executed. Need to return a continuation. + return performConcurrentWorkOnRoot.bind(null, root); + } + } } return null; @@ -16980,6 +19979,9 @@ function finishConcurrentRender( exitStatus, expirationTime ) { + // Set this to null to indicate there's no in-progress render. + workInProgressRoot = null; + switch (exitStatus) { case RootIncomplete: case RootFatalErrored: { @@ -16992,9 +19994,19 @@ function finishConcurrentRender( // if I do. eslint-disable-next-line no-fallthrough case RootErrored: { - // We should have already attempted to retry this tree. If we reached - // this point, it errored again. Commit it. - commitRoot(root); + // If this was an async render, the error may have happened due to + // a mutation in a concurrent event. Try rendering one more time, + // synchronously, to see if the error goes away. If there are + // lower priority updates, let's include those, too, in case they + // fix the inconsistency. Render at Idle to include all updates. + // If it was Idle or Never or some not-yet-invented time, render + // at that time. + markRootExpiredAtTime( + root, + expirationTime > Idle ? Idle : expirationTime + ); // We assume that this second render pass will be synchronous + // and therefore not hit this path again. + break; } @@ -17004,7 +20016,9 @@ function finishConcurrentRender( if (expirationTime === lastSuspendedTime) { root.nextKnownPendingLevel = getRemainingExpirationTime(finishedWork); - } // We have an acceptable loading state. We need to figure out if we + } + + flushSuspensePriorityWarningInDEV(); // We have an acceptable loading state. We need to figure out if we // should immediately commit it or wait a bit. // If we have processed new updates during this render, we may now // have a new loading state ready. We want to ensure that we commit @@ -17015,7 +20029,7 @@ function finishConcurrentRender( if ( hasNotProcessedNewUpdates && // do not delay if we're inside an act() scope - !IsThisRendererActing.current + !(true && flushSuspenseFallbacksInTests && IsThisRendererActing.current) ) { // If we have not processed any new updates during this pass, then // this is either a retry of an existing fallback state or a @@ -17079,7 +20093,12 @@ function finishConcurrentRender( root.nextKnownPendingLevel = getRemainingExpirationTime(finishedWork); } - { + flushSuspensePriorityWarningInDEV(); + + if ( + // do not delay if we're inside an act() scope + !(true && flushSuspenseFallbacksInTests && IsThisRendererActing.current) + ) { // We're suspended in a state that should be avoided. We'll try to // avoid committing it for as long as the timeouts let us. if (workInProgressRootHasPendingPing) { @@ -17134,7 +20153,6 @@ function finishConcurrentRender( var timeUntilExpirationMs = expirationTimeToMs(expirationTime) - currentTimeMs; var timeElapsed = currentTimeMs - eventTimeMs; - if (timeElapsed < 0) { // We get this wrong some time since we estimate the time. timeElapsed = 0; @@ -17169,6 +20187,11 @@ function finishConcurrentRender( // The work completed. Ready to commit. if ( // do not delay if we're inside an act() scope + !( + true && + flushSuspenseFallbacksInTests && + IsThisRendererActing.current + ) && workInProgressRootLatestProcessedExpirationTime !== Sync && workInProgressRootCanSuspendUsingConfig !== null ) { @@ -17206,65 +20229,147 @@ function finishConcurrentRender( // through Scheduler function performSyncWorkOnRoot(root) { - if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { - throw Error("Should not already be working."); - } - - flushPassiveEffects(); + // Check if there's expired work on this root. Otherwise, render at Sync. var lastExpiredTime = root.lastExpiredTime; - var expirationTime; + var expirationTime = lastExpiredTime !== NoWork ? lastExpiredTime : Sync; + + if (root.finishedExpirationTime === expirationTime) { + // There's already a pending commit at this expiration time. + // TODO: This is poorly factored. This case only exists for the + // batch.commit() API. + commitRoot(root); + } else { + if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { + throw Error("Should not already be working."); + } + + flushPassiveEffects(); // If the root or expiration time have changed, throw out the existing stack + // and prepare a fresh one. Otherwise we'll continue where we left off. - if (lastExpiredTime !== NoWork) { - // There's expired work on this root. Check if we have a partial tree - // that we can reuse. if ( - root === workInProgressRoot && - renderExpirationTime$1 >= lastExpiredTime + root !== workInProgressRoot || + expirationTime !== renderExpirationTime ) { - // There's a partial tree with equal or greater than priority than the - // expired level. Finish rendering it before rendering the rest of the - // expired work. - expirationTime = renderExpirationTime$1; - } else { - // Start a fresh tree. - expirationTime = lastExpiredTime; + prepareFreshStack(root, expirationTime); + startWorkOnPendingInteractions(root, expirationTime); + } // If we have a work-in-progress fiber, it means there's still work to do + // in this root. + + if (workInProgress !== null) { + var prevExecutionContext = executionContext; + executionContext |= RenderContext; + var prevDispatcher = pushDispatcher(root); + var prevInteractions = pushInteractions(root); + startWorkLoopTimer(workInProgress); + + do { + try { + workLoopSync(); + break; + } catch (thrownValue) { + handleError(root, thrownValue); + } + } while (true); + + resetContextDependencies(); + executionContext = prevExecutionContext; + popDispatcher(prevDispatcher); + + if (enableSchedulerTracing) { + popInteractions(prevInteractions); + } + + if (workInProgressRootExitStatus === RootFatalErrored) { + var fatalError = workInProgressRootFatalError; + stopInterruptedWorkLoopTimer(); + prepareFreshStack(root, expirationTime); + markRootSuspendedAtTime(root, expirationTime); + ensureRootIsScheduled(root); + throw fatalError; + } + + if (workInProgress !== null) { + // This is a sync render, so we should have finished the whole tree. + { + throw Error( + "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." + ); + } + } else { + // We now have a consistent tree. Because this is a sync render, we + // will commit it even if something suspended. + stopFinishedWorkLoopTimer(); + root.finishedWork = root.current.alternate; + root.finishedExpirationTime = expirationTime; + finishSyncRender(root, workInProgressRootExitStatus, expirationTime); + } // Before exiting, make sure there's a callback scheduled for the next + // pending level. + + ensureRootIsScheduled(root); } - } else { - // There's no expired work. This must be a new, synchronous render. - expirationTime = Sync; } - var exitStatus = renderRootSync(root, expirationTime); + return null; +} + +function finishSyncRender(root, exitStatus, expirationTime) { + // Set this to null to indicate there's no in-progress render. + workInProgressRoot = null; - if (root.tag !== LegacyRoot && exitStatus === RootErrored) { - // If something threw an error, try rendering one more time. We'll - // render synchronously to block concurrent data mutations, and we'll - // render at Idle (or lower) so that all pending updates are included. - // If it still fails after the second attempt, we'll give up and commit - // the resulting tree. - expirationTime = expirationTime > Idle ? Idle : expirationTime; - exitStatus = renderRootSync(root, expirationTime); + { + if (exitStatus === RootSuspended || exitStatus === RootSuspendedWithDelay) { + flushSuspensePriorityWarningInDEV(); + } } - if (exitStatus === RootFatalErrored) { - var fatalError = workInProgressRootFatalError; - prepareFreshStack(root, expirationTime); - markRootSuspendedAtTime(root, expirationTime); - ensureRootIsScheduled(root); - throw fatalError; - } // We now have a consistent tree. Because this is a sync render, we - // will commit it even if something suspended. + commitRoot(root); +} + +function flushDiscreteUpdates() { + // TODO: Should be able to flush inside batchedUpdates, but not inside `act`. + // However, `act` uses `batchedUpdates`, so there's no way to distinguish + // those two cases. Need to fix this before exposing flushDiscreteUpdates + // as a public API. + if ( + (executionContext & (BatchedContext | RenderContext | CommitContext)) !== + NoContext + ) { + if (true && (executionContext & RenderContext) !== NoContext) { + warning$1( + false, + "unstable_flushDiscreteUpdates: Cannot flush updates when React is " + + "already rendering." + ); + } // We're already rendering, so we can't synchronously flush pending work. + // This is probably a nested event dispatch triggered by a lifecycle/effect, + // like `el.focus()`. Exit. + + return; + } - root.finishedWork = root.current.alternate; - root.finishedExpirationTime = expirationTime; - commitRoot(root); // Before exiting, make sure there's a callback scheduled for the next - // pending level. + flushPendingDiscreteUpdates(); // If the discrete updates scheduled passive effects, flush them now so that + // they fire before the next serial event. - ensureRootIsScheduled(root); - return null; + flushPassiveEffects(); } + function syncUpdates(fn, a, b, c) { - return runWithPriority(ImmediatePriority, fn.bind(null, a, b, c)); + return runWithPriority$1(ImmediatePriority, fn.bind(null, a, b, c)); +} + +function flushPendingDiscreteUpdates() { + if (rootsWithPendingDiscreteUpdates !== null) { + // For each root with pending discrete updates, schedule a callback to + // immediately flush them. + var roots = rootsWithPendingDiscreteUpdates; + rootsWithPendingDiscreteUpdates = null; + roots.forEach(function(expirationTime, root) { + markRootExpiredAtTime(root, expirationTime); + ensureRootIsScheduled(root); + }); // Now flush the immediate queue. + + flushSyncCallbackQueue(); + } } function batchedUpdates$1(fn, a) { @@ -17282,6 +20387,38 @@ function batchedUpdates$1(fn, a) { } } } +function batchedEventUpdates$1(fn, a) { + var prevExecutionContext = executionContext; + executionContext |= EventContext; + + try { + return fn(a); + } finally { + executionContext = prevExecutionContext; + + if (executionContext === NoContext) { + // Flush the immediate callbacks that were scheduled during this batch + flushSyncCallbackQueue(); + } + } +} +function discreteUpdates$1(fn, a, b, c) { + var prevExecutionContext = executionContext; + executionContext |= DiscreteEventContext; + + try { + // Should this + return runWithPriority$1(UserBlockingPriority$1, fn.bind(null, a, b, c)); + } finally { + executionContext = prevExecutionContext; + + if (executionContext === NoContext) { + // Flush the immediate callbacks that were scheduled during this batch + flushSyncCallbackQueue(); + } + } +} + function flushSync(fn, a) { if ((executionContext & (RenderContext | CommitContext)) !== NoContext) { { @@ -17295,7 +20432,7 @@ function flushSync(fn, a) { executionContext |= BatchedContext; try { - return runWithPriority(ImmediatePriority, fn.bind(null, a)); + return runWithPriority$1(ImmediatePriority, fn.bind(null, a)); } finally { executionContext = prevExecutionContext; // Flush the immediate callbacks that were scheduled during this batch. // Note that this will happen even if batchedUpdates is higher up @@ -17328,8 +20465,8 @@ function prepareFreshStack(root, expirationTime) { } workInProgressRoot = root; - workInProgress = createWorkInProgress(root.current, null); - renderExpirationTime$1 = expirationTime; + workInProgress = createWorkInProgress(root.current, null, expirationTime); + renderExpirationTime = expirationTime; workInProgressRootExitStatus = RootIncomplete; workInProgressRootFatalError = null; workInProgressRootLatestProcessedExpirationTime = Sync; @@ -17338,12 +20475,13 @@ function prepareFreshStack(root, expirationTime) { workInProgressRootNextUnprocessedUpdateTime = NoWork; workInProgressRootHasPendingPing = false; - { + if (enableSchedulerTracing) { spawnedWorkDuringRender = null; } { ReactStrictModeWarnings.discardPendingWarnings(); + componentsThatTriggeredHighPriSuspend = null; } } @@ -17352,7 +20490,7 @@ function handleError(root, thrownValue) { try { // Reset module-level state that was set during the render phase. resetContextDependencies(); - resetHooksAfterThrow(); + resetHooks(); resetCurrentFiber(); if (workInProgress === null || workInProgress.return === null) { @@ -17361,14 +20499,7 @@ function handleError(root, thrownValue) { // supposed to capture all errors that weren't caught by an error // boundary. workInProgressRootExitStatus = RootFatalErrored; - workInProgressRootFatalError = thrownValue; // Set `workInProgress` to null. This represents advancing to the next - // sibling, or the parent if there are no siblings. But since the root - // has no siblings nor a parent, we set it to null. Usually this is - // handled by `completeUnitOfWork` or `unwindWork`, but since we're - // interntionally not calling those, we need set it here. - // TODO: Consider calling `unwindWork` to pop the contexts. - - workInProgress = null; + workInProgressRootFatalError = thrownValue; return null; } @@ -17384,7 +20515,7 @@ function handleError(root, thrownValue) { workInProgress.return, workInProgress, thrownValue, - renderExpirationTime$1 + renderExpirationTime ); workInProgress = completeUnitOfWork(workInProgress); } catch (yetAnotherThrownValue) { @@ -17398,8 +20529,8 @@ function handleError(root, thrownValue) { } function pushDispatcher(root) { - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = ContextOnlyDispatcher; if (prevDispatcher === null) { // The React isomorphic package does not include a default dispatcher. @@ -17412,19 +20543,21 @@ function pushDispatcher(root) { } function popDispatcher(prevDispatcher) { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } function pushInteractions(root) { - { + if (enableSchedulerTracing) { var prevInteractions = tracing.__interactionsRef.current; tracing.__interactionsRef.current = root.memoizedInteractions; return prevInteractions; } + + return null; } function popInteractions(prevInteractions) { - { + if (enableSchedulerTracing) { tracing.__interactionsRef.current = prevInteractions; } } @@ -17477,7 +20610,7 @@ function renderDidSuspendDelayIfPossible() { // pending update. // TODO: This should immediately interrupt the current render, instead // of waiting until the next time we yield. - markRootSuspendedAtTime(workInProgressRoot, renderExpirationTime$1); + markRootSuspendedAtTime(workInProgressRoot, renderExpirationTime); markRootUpdatedAtTime( workInProgressRoot, workInProgressRootNextUnprocessedUpdateTime @@ -17516,113 +20649,14 @@ function inferTimeFromExpirationTimeWithSuspenseConfig( earliestExpirationTimeMs - (suspenseConfig.timeoutMs | 0 || LOW_PRIORITY_EXPIRATION) ); -} - -function renderRootSync(root, expirationTime) { - var prevExecutionContext = executionContext; - executionContext |= RenderContext; - var prevDispatcher = pushDispatcher(); // If the root or expiration time have changed, throw out the existing stack - // and prepare a fresh one. Otherwise we'll continue where we left off. - - if ( - root !== workInProgressRoot || - expirationTime !== renderExpirationTime$1 - ) { - prepareFreshStack(root, expirationTime); - startWorkOnPendingInteractions(root, expirationTime); - } - - var prevInteractions = pushInteractions(root); - startWorkLoopTimer(workInProgress); - - do { - try { - workLoopSync(); - break; - } catch (thrownValue) { - handleError(root, thrownValue); - } - } while (true); - - resetContextDependencies(); - - { - popInteractions(prevInteractions); - } - - executionContext = prevExecutionContext; - popDispatcher(prevDispatcher); - - if (workInProgress !== null) { - // This is a sync render, so we should have finished the whole tree. - { - throw Error( - "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." - ); - } - } - - stopFinishedWorkLoopTimer(); // Set this to null to indicate there's no in-progress render. - - workInProgressRoot = null; - return workInProgressRootExitStatus; } // The work loop is an extremely hot path. Tell Closure not to inline it. -/** @noinline */ - -function workLoopSync() { - // Already timed out, so perform work without checking if we need to yield. - while (workInProgress !== null) { - workInProgress = performUnitOfWork(workInProgress); - } -} - -function renderRootConcurrent(root, expirationTime) { - var prevExecutionContext = executionContext; - executionContext |= RenderContext; - var prevDispatcher = pushDispatcher(); // If the root or expiration time have changed, throw out the existing stack - // and prepare a fresh one. Otherwise we'll continue where we left off. - - if ( - root !== workInProgressRoot || - expirationTime !== renderExpirationTime$1 - ) { - prepareFreshStack(root, expirationTime); - startWorkOnPendingInteractions(root, expirationTime); - } - - var prevInteractions = pushInteractions(root); - startWorkLoopTimer(workInProgress); - - do { - try { - workLoopConcurrent(); - break; - } catch (thrownValue) { - handleError(root, thrownValue); - } - } while (true); - - resetContextDependencies(); - - { - popInteractions(prevInteractions); - } - - popDispatcher(prevDispatcher); - executionContext = prevExecutionContext; // Check if the tree has completed. - - if (workInProgress !== null) { - // Still work remaining. - stopInterruptedWorkLoopTimer(); - return RootIncomplete; - } else { - // Completed the tree. - stopFinishedWorkLoopTimer(); // Set this to null to indicate there's no in-progress render. - - workInProgressRoot = null; // Return the final exit status. +/** @noinline */ - return workInProgressRootExitStatus; +function workLoopSync() { + // Already timed out, so perform work without checking if we need to yield. + while (workInProgress !== null) { + workInProgress = performUnitOfWork(workInProgress); } } /** @noinline */ @@ -17638,22 +20672,21 @@ function performUnitOfWork(unitOfWork) { // The current, flushed, state of this fiber is the alternate. Ideally // nothing should rely on this, but relying on it here means that we don't // need an additional field on the work in progress. - var current = unitOfWork.alternate; + var current$$1 = unitOfWork.alternate; startWorkTimer(unitOfWork); setCurrentFiber(unitOfWork); var next; - if ((unitOfWork.mode & ProfileMode) !== NoMode) { + if (enableProfilerTimer && (unitOfWork.mode & ProfileMode) !== NoMode) { startProfilerTimer(unitOfWork); - next = beginWork$1(current, unitOfWork, renderExpirationTime$1); + next = beginWork$$1(current$$1, unitOfWork, renderExpirationTime); stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true); } else { - next = beginWork$1(current, unitOfWork, renderExpirationTime$1); + next = beginWork$$1(current$$1, unitOfWork, renderExpirationTime); } resetCurrentFiber(); unitOfWork.memoizedProps = unitOfWork.pendingProps; - if (next === null) { // If this doesn't spawn new work, complete the current work. next = completeUnitOfWork(unitOfWork); @@ -17667,23 +20700,25 @@ function completeUnitOfWork(unitOfWork) { // Attempt to complete the current unit of work, then move to the next // sibling. If there are no more siblings, return to the parent fiber. workInProgress = unitOfWork; - do { // The current, flushed, state of this fiber is the alternate. Ideally // nothing should rely on this, but relying on it here means that we don't // need an additional field on the work in progress. - var current = workInProgress.alternate; + var current$$1 = workInProgress.alternate; var returnFiber = workInProgress.return; // Check if the work completed or if something threw. if ((workInProgress.effectTag & Incomplete) === NoEffect) { setCurrentFiber(workInProgress); var next = void 0; - if ((workInProgress.mode & ProfileMode) === NoMode) { - next = completeWork(current, workInProgress, renderExpirationTime$1); + if ( + !enableProfilerTimer || + (workInProgress.mode & ProfileMode) === NoMode + ) { + next = completeWork(current$$1, workInProgress, renderExpirationTime); } else { startProfilerTimer(workInProgress); - next = completeWork(current, workInProgress, renderExpirationTime$1); // Update render duration assuming we didn't error. + next = completeWork(current$$1, workInProgress, renderExpirationTime); // Update render duration assuming we didn't error. stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false); } @@ -17707,7 +20742,6 @@ function completeUnitOfWork(unitOfWork) { if (returnFiber.firstEffect === null) { returnFiber.firstEffect = workInProgress.firstEffect; } - if (workInProgress.lastEffect !== null) { if (returnFiber.lastEffect !== null) { returnFiber.lastEffect.nextEffect = workInProgress.firstEffect; @@ -17731,7 +20765,6 @@ function completeUnitOfWork(unitOfWork) { } else { returnFiber.firstEffect = workInProgress; } - returnFiber.lastEffect = workInProgress; } } @@ -17739,9 +20772,12 @@ function completeUnitOfWork(unitOfWork) { // This fiber did not complete because something threw. Pop values off // the stack without entering the complete phase. If this is a boundary, // capture values if possible. - var _next = unwindWork(workInProgress); // Because this fiber did not complete, don't reset its expiration time. + var _next = unwindWork(workInProgress, renderExpirationTime); // Because this fiber did not complete, don't reset its expiration time. - if ((workInProgress.mode & ProfileMode) !== NoMode) { + if ( + enableProfilerTimer && + (workInProgress.mode & ProfileMode) !== NoMode + ) { // Record the render duration for the fiber that errored. stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false); // Include the time spent working on failed children before continuing. @@ -17752,7 +20788,6 @@ function completeUnitOfWork(unitOfWork) { actualDuration += child.actualDuration; child = child.sibling; } - workInProgress.actualDuration = actualDuration; } @@ -17767,7 +20802,6 @@ function completeUnitOfWork(unitOfWork) { _next.effectTag &= HostEffectMask; return _next; } - stopWorkTimer(workInProgress); if (returnFiber !== null) { @@ -17804,7 +20838,7 @@ function getRemainingExpirationTime(fiber) { function resetChildExpirationTime(completedWork) { if ( - renderExpirationTime$1 !== Never && + renderExpirationTime !== Never && completedWork.childExpirationTime === Never ) { // The children of this component are hidden. Don't bubble their @@ -17814,7 +20848,7 @@ function resetChildExpirationTime(completedWork) { var newChildExpirationTime = NoWork; // Bubble up the earliest expiration time. - if ((completedWork.mode & ProfileMode) !== NoMode) { + if (enableProfilerTimer && (completedWork.mode & ProfileMode) !== NoMode) { // In profiling mode, resetChildExpirationTime is also used to reset // profiler durations. var actualDuration = completedWork.actualDuration; @@ -17877,7 +20911,7 @@ function resetChildExpirationTime(completedWork) { function commitRoot(root) { var renderPriorityLevel = getCurrentPriorityLevel(); - runWithPriority( + runWithPriority$1( ImmediatePriority, commitRootImpl.bind(null, root, renderPriorityLevel) ); @@ -17885,16 +20919,7 @@ function commitRoot(root) { } function commitRootImpl(root, renderPriorityLevel) { - do { - // `flushPassiveEffects` will call `flushSyncUpdateQueue` at the end, which - // means `flushPassiveEffects` will sometimes result in additional - // passive effects. So we need to keep flushing in a loop until there are - // no more pending effects. - // TODO: Might be better if `flushPassiveEffects` did not automatically - // flush synchronous work at the end, to avoid factoring hazards like this. - flushPassiveEffects(); - } while (rootWithPendingPassiveEffects !== null); - + flushPassiveEffects(); flushRenderPhaseStrictModeWarningsInDEV(); if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { @@ -17938,7 +20963,8 @@ function commitRootImpl(root, renderPriorityLevel) { // We can reset these now that they are finished. workInProgressRoot = null; workInProgress = null; - renderExpirationTime$1 = NoWork; + renderExpirationTime = NoWork; + } else { } // This indicates that the last root we worked on is not the same one that // we're committing now. This most commonly happens when a suspended root // times out. @@ -17993,10 +21019,9 @@ function commitRootImpl(root, renderPriorityLevel) { } } } while (nextEffect !== null); - stopCommitSnapshotEffectsTimer(); - { + if (enableProfilerTimer) { // Mark the current commit time to be shared by all Profilers in this // batch. This enables them to be grouped later. recordCommitTime(); @@ -18070,7 +21095,7 @@ function commitRootImpl(root, renderPriorityLevel) { requestPaint(); - { + if (enableSchedulerTracing) { popInteractions(prevInteractions); } @@ -18084,7 +21109,7 @@ function commitRootImpl(root, renderPriorityLevel) { startCommitSnapshotEffectsTimer(); stopCommitSnapshotEffectsTimer(); - { + if (enableProfilerTimer) { recordCommitTime(); } @@ -18109,7 +21134,6 @@ function commitRootImpl(root, renderPriorityLevel) { // 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; @@ -18120,11 +21144,10 @@ function commitRootImpl(root, renderPriorityLevel) { var remainingExpirationTime = root.firstPendingTime; if (remainingExpirationTime !== NoWork) { - { + if (enableSchedulerTracing) { if (spawnedWorkDuringRender !== null) { var expirationTimes = spawnedWorkDuringRender; spawnedWorkDuringRender = null; - for (var i = 0; i < expirationTimes.length; i++) { scheduleInteractions( root, @@ -18142,7 +21165,7 @@ function commitRootImpl(root, renderPriorityLevel) { legacyErrorBoundariesThatAlreadyFailed = null; } - { + if (enableSchedulerTracing) { if (!rootDidHavePassiveEffects) { // If there are no passive effects, then we can complete the pending interactions. // Otherwise, we'll wait until after the passive effects are flushed. @@ -18196,8 +21219,8 @@ function commitBeforeMutationEffects() { if ((effectTag & Snapshot) !== NoEffect) { setCurrentFiber(nextEffect); recordEffect(); - var current = nextEffect.alternate; - commitBeforeMutationLifeCycles(current, nextEffect); + var current$$1 = nextEffect.alternate; + commitBeforeMutationLifeCycles(current$$1, nextEffect); resetCurrentFiber(); } @@ -18223,11 +21246,15 @@ function commitMutationEffects(root, renderPriorityLevel) { setCurrentFiber(nextEffect); var effectTag = nextEffect.effectTag; + if (effectTag & ContentReset) { + commitResetTextContent(nextEffect); + } + if (effectTag & Ref) { - var current = nextEffect.alternate; + var current$$1 = nextEffect.alternate; - if (current !== null) { - commitDetachRef(current); + if (current$$1 !== null) { + commitDetachRef(current$$1); } } // The following switch statement is only concerned about placement, // updates, and deletions. To avoid needing to add a case for every possible @@ -18239,6 +21266,7 @@ function commitMutationEffects(root, renderPriorityLevel) { switch (primaryEffectTag) { 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. @@ -18248,6 +21276,8 @@ function commitMutationEffects(root, renderPriorityLevel) { } 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.effectTag &= ~Placement; // Update @@ -18296,8 +21326,8 @@ function commitLayoutEffects(root, committedExpirationTime) { if (effectTag & (Update | Callback)) { recordEffect(); - var current = nextEffect.alternate; - commitLifeCycles(root, current, nextEffect); + var current$$1 = nextEffect.alternate; + commitLifeCycles(root, current$$1, nextEffect, committedExpirationTime); } if (effectTag & Ref) { @@ -18317,7 +21347,7 @@ function flushPassiveEffects() { ? NormalPriority : pendingPassiveEffectsRenderPriority; pendingPassiveEffectsRenderPriority = NoPriority; - return runWithPriority(priorityLevel, flushPassiveEffectsImpl); + return runWithPriority$1(priorityLevel, flushPassiveEffectsImpl); } } @@ -18337,40 +21367,36 @@ function flushPassiveEffectsImpl() { var prevExecutionContext = executionContext; executionContext |= CommitContext; - var prevInteractions = pushInteractions(root); - - { - // 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 _effect2 = root.current.firstEffect; - - while (_effect2 !== null) { - { - setCurrentFiber(_effect2); - invokeGuardedCallback(null, commitPassiveHookEffects, null, _effect2); + var prevInteractions = pushInteractions(root); // 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. - if (hasCaughtError()) { - if (!(_effect2 !== null)) { - throw Error("Should be working on an effect."); - } + var effect = root.current.firstEffect; - var _error5 = clearCaughtError(); + while (effect !== null) { + { + setCurrentFiber(effect); + invokeGuardedCallback(null, commitPassiveHookEffects, null, effect); - captureCommitPhaseError(_effect2, _error5); + if (hasCaughtError()) { + if (!(effect !== null)) { + throw Error("Should be working on an effect."); } - resetCurrentFiber(); + var error = clearCaughtError(); + captureCommitPhaseError(effect, error); } - var nextNextEffect = _effect2.nextEffect; // Remove nextEffect pointer to assist GC - - _effect2.nextEffect = null; - _effect2 = nextNextEffect; + resetCurrentFiber(); } + + var nextNextEffect = effect.nextEffect; // Remove nextEffect pointer to assist GC + + effect.nextEffect = null; + effect = nextNextEffect; } - { + if (enableSchedulerTracing) { popInteractions(prevInteractions); finishPendingInteractions(root, expirationTime); } @@ -18404,7 +21430,6 @@ function prepareToThrowUncaughtError(error) { firstUncaughtError = error; } } - var onUncaughtError = prepareToThrowUncaughtError; function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { @@ -18428,7 +21453,6 @@ function captureCommitPhaseError(sourceFiber, error) { } var fiber = sourceFiber.return; - while (fiber !== null) { if (fiber.tag === HostRoot) { captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error); @@ -18436,7 +21460,6 @@ function captureCommitPhaseError(sourceFiber, error) { } else if (fiber.tag === ClassComponent) { var ctor = fiber.type; var instance = fiber.stateNode; - if ( typeof ctor.getDerivedStateFromError === "function" || (typeof instance.componentDidCatch === "function" && @@ -18472,7 +21495,7 @@ function pingSuspendedRoot(root, thenable, suspendedTime) { pingCache.delete(thenable); } - if (workInProgressRoot === root && renderExpirationTime$1 === suspendedTime) { + if (workInProgressRoot === root && renderExpirationTime === suspendedTime) { // Received a ping at the same priority level at which we're currently // rendering. We might want to restart this render. This should mirror // the logic of whether or not a root suspends once it completes. @@ -18492,7 +21515,7 @@ function pingSuspendedRoot(root, thenable, suspendedTime) { ) { // Restart from the root. Don't need to schedule a ping because // we're already working on this tree. - prepareFreshStack(root, renderExpirationTime$1); + prepareFreshStack(root, renderExpirationTime); } else { // Even though we can't restart right now, we might get an // opportunity later. So we mark this render as having a ping. @@ -18515,6 +21538,13 @@ function pingSuspendedRoot(root, thenable, suspendedTime) { } // Mark the time at which this ping was scheduled. root.lastPingedTime = suspendedTime; + + if (root.finishedExpirationTime === suspendedTime) { + // If there's a pending fallback waiting to commit, throw it away. + root.finishedExpirationTime = NoWork; + root.finishedWork = null; + } + ensureRootIsScheduled(root); schedulePendingInteractions(root, suspendedTime); } @@ -18542,12 +21572,45 @@ function retryTimedOutBoundary(boundaryFiber, retryTime) { schedulePendingInteractions(root, retryTime); } } + +function retryDehydratedSuspenseBoundary(boundaryFiber) { + var suspenseState = boundaryFiber.memoizedState; + var retryTime = NoWork; + + if (suspenseState !== null) { + retryTime = suspenseState.retryTime; + } + + retryTimedOutBoundary(boundaryFiber, retryTime); +} function resolveRetryThenable(boundaryFiber, thenable) { var retryTime = NoWork; // Default var retryCache; - { + if (enableSuspenseServerRenderer) { + switch (boundaryFiber.tag) { + case SuspenseComponent: + retryCache = boundaryFiber.stateNode; + var suspenseState = boundaryFiber.memoizedState; + + if (suspenseState !== null) { + retryTime = suspenseState.retryTime; + } + + break; + + case SuspenseListComponent: + retryCache = boundaryFiber.stateNode; + break; + + default: { + throw Error( + "Pinged unknown suspense boundary type. This is probably a bug in React." + ); + } + } + } else { retryCache = boundaryFiber.stateNode; } @@ -18567,21 +21630,20 @@ function resolveRetryThenable(boundaryFiber, thenable) { // the longer we can wait additionally. At some point we have to give up though. // We pick a train model where the next boundary commits at a consistent schedule. // These particular numbers are vague estimates. We expect to adjust them based on research. - function jnd(timeElapsed) { return timeElapsed < 120 ? 120 : timeElapsed < 480 - ? 480 - : timeElapsed < 1080 - ? 1080 - : timeElapsed < 1920 - ? 1920 - : timeElapsed < 3000 - ? 3000 - : timeElapsed < 4320 - ? 4320 - : ceil(timeElapsed / 1960) * 1960; + ? 480 + : timeElapsed < 1080 + ? 1080 + : timeElapsed < 1920 + ? 1920 + : timeElapsed < 3000 + ? 3000 + : timeElapsed < 4320 + ? 4320 + : ceil(timeElapsed / 1960) * 1960; } function computeMsUntilSuspenseLoadingDelay( @@ -18603,7 +21665,6 @@ function computeMsUntilSuspenseLoadingDelay( suspenseConfig ); var timeElapsed = currentTimeMs - eventTimeMs; - if (timeElapsed <= busyDelayMs) { // If we haven't yet waited longer than the initial delay, we don't // have to wait any additional time. @@ -18630,8 +21691,8 @@ function checkForNestedUpdates() { { if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) { nestedPassiveUpdateCount = 0; - - error( + warning$1( + false, "Maximum update depth exceeded. This can happen when a component " + "calls setState inside useEffect, but useEffect either doesn't " + "have a dependency array, or one of the dependencies changes on " + @@ -18645,7 +21706,7 @@ function flushRenderPhaseStrictModeWarningsInDEV() { { ReactStrictModeWarnings.flushLegacyContextWarning(); - { + if (warnAboutDeprecatedLifecycles) { ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings(); } } @@ -18666,8 +21727,9 @@ function stopInterruptedWorkLoopTimer() { function checkForInterruption(fiberThatReceivedUpdate, updateExpirationTime) { if ( + enableUserTimingAPI && workInProgressRoot !== null && - updateExpirationTime > renderExpirationTime$1 + updateExpirationTime > renderExpirationTime ) { interruptedBy = fiberThatReceivedUpdate; } @@ -18685,12 +21747,11 @@ function warnAboutUpdateOnUnmountedFiberInDEV(fiber) { tag !== FunctionComponent && tag !== ForwardRef && tag !== MemoComponent && - tag !== SimpleMemoComponent && - tag !== Block + tag !== SimpleMemoComponent ) { // Only warn for user-defined components, not internal ones like Suspense. return; - } + } // We show the whole stack but dedupe on the top component's name because // the problematic code almost always lies inside that component. var componentName = getComponentName(fiber.type) || "ReactComponent"; @@ -18699,13 +21760,12 @@ function warnAboutUpdateOnUnmountedFiberInDEV(fiber) { if (didWarnStateUpdateForUnmountedComponent.has(componentName)) { return; } - didWarnStateUpdateForUnmountedComponent.add(componentName); } else { didWarnStateUpdateForUnmountedComponent = new Set([componentName]); } - - error( + warningWithoutStack$1( + false, "Can't perform a React state update on an unmounted component. This " + "is a no-op, but it indicates a memory leak in your application. To " + "fix, cancel all subscriptions and asynchronous tasks in %s.%s", @@ -18717,12 +21777,12 @@ function warnAboutUpdateOnUnmountedFiberInDEV(fiber) { } } -var beginWork$1; +var beginWork$$1; -{ +if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) { var dummyFiber = null; - beginWork$1 = function(current, unitOfWork, expirationTime) { + beginWork$$1 = function(current$$1, unitOfWork, expirationTime) { // If a component throws an error, we replay it again in a synchronously // dispatched event, so that the debugger will treat it as an uncaught // error See ReactErrorUtils for more information. @@ -18732,9 +21792,8 @@ var beginWork$1; dummyFiber, unitOfWork ); - try { - return beginWork(current, unitOfWork, expirationTime); + return beginWork$1(current$$1, unitOfWork, expirationTime); } catch (originalError) { if ( originalError !== null && @@ -18747,7 +21806,7 @@ var beginWork$1; // corresponding changes there. resetContextDependencies(); - resetHooksAfterThrow(); // Don't reset current debug fiber, since we're about to work on the + resetHooks(); // Don't reset current debug fiber, since we're about to work on the // same fiber again. // Unwind the failed stack frame @@ -18755,16 +21814,16 @@ var beginWork$1; assignFiberPropertiesInDEV(unitOfWork, originalWorkInProgressCopy); - if (unitOfWork.mode & ProfileMode) { + if (enableProfilerTimer && unitOfWork.mode & ProfileMode) { // Reset the profiler timer. startProfilerTimer(unitOfWork); } // Run beginWork again. invokeGuardedCallback( null, - beginWork, + beginWork$1, null, - current, + current$$1, unitOfWork, expirationTime ); @@ -18780,37 +21839,38 @@ var beginWork$1; } } }; +} else { + beginWork$$1 = beginWork$1; } var didWarnAboutUpdateInRender = false; - -function warnAboutRenderPhaseUpdatesInDEV(fiber) { +var didWarnAboutUpdateInGetChildContext = false; +function warnAboutInvalidUpdatesOnClassComponentsInDEV(fiber) { { - if ((executionContext & RenderContext) !== NoContext) { - switch (fiber.tag) { - case FunctionComponent: - case ForwardRef: - case SimpleMemoComponent: { - error( - "Cannot update a component from inside the function body of a " + - "different component." + if (fiber.tag === ClassComponent) { + switch (phase) { + case "getChildContext": + if (didWarnAboutUpdateInGetChildContext) { + return; + } + warningWithoutStack$1( + false, + "setState(...): Cannot call setState() inside getChildContext()" ); - + didWarnAboutUpdateInGetChildContext = true; break; - } - - case ClassComponent: { - if (isRendering && !didWarnAboutUpdateInRender) { - error( - "Cannot update during an existing state transition (such as " + - "within `render`). Render methods should be a pure " + - "function of props and state." - ); - - didWarnAboutUpdateInRender = true; - break; + case "render": + if (didWarnAboutUpdateInRender) { + return; } - } + warningWithoutStack$1( + false, + "Cannot update during an existing state transition (such as " + + "within `render`). Render methods should be a pure function of " + + "props and state." + ); + didWarnAboutUpdateInRender = true; + break; } } } @@ -18819,6 +21879,89 @@ function warnAboutRenderPhaseUpdatesInDEV(fiber) { var IsThisRendererActing = { current: false }; +function warnIfNotScopedWithMatchingAct(fiber) { + { + if ( + warnsIfNotActing === true && + IsSomeRendererActing.current === true && + IsThisRendererActing.current !== true + ) { + warningWithoutStack$1( + false, + "It looks like you're using the wrong act() around your test interactions.\n" + + "Be sure to use the matching version of act() corresponding to your renderer:\n\n" + + "// for react-dom:\n" + + "import {act} from 'react-dom/test-utils';\n" + + "// ...\n" + + "act(() => ...);\n\n" + + "// for react-test-renderer:\n" + + "import TestRenderer from 'react-test-renderer';\n" + + "const {act} = TestRenderer;\n" + + "// ...\n" + + "act(() => ...);" + + "%s", + getStackByFiberInDevAndProd(fiber) + ); + } + } +} +function warnIfNotCurrentlyActingEffectsInDEV(fiber) { + { + if ( + warnsIfNotActing === true && + (fiber.mode & StrictMode) !== NoMode && + IsSomeRendererActing.current === false && + IsThisRendererActing.current === false + ) { + warningWithoutStack$1( + false, + "An update to %s ran an effect, but was not wrapped in act(...).\n\n" + + "When testing, code that causes React state updates should be " + + "wrapped into act(...):\n\n" + + "act(() => {\n" + + " /* fire events that update state */\n" + + "});\n" + + "/* assert on the output */\n\n" + + "This ensures that you're testing the behavior the user would see " + + "in the browser." + + " Learn more at https://fb.me/react-wrap-tests-with-act" + + "%s", + getComponentName(fiber.type), + getStackByFiberInDevAndProd(fiber) + ); + } + } +} + +function warnIfNotCurrentlyActingUpdatesInDEV(fiber) { + { + if ( + warnsIfNotActing === true && + executionContext === NoContext && + IsSomeRendererActing.current === false && + IsThisRendererActing.current === false + ) { + warningWithoutStack$1( + false, + "An update to %s inside a test was not wrapped in act(...).\n\n" + + "When testing, code that causes React state updates should be " + + "wrapped into act(...):\n\n" + + "act(() => {\n" + + " /* fire events that update state */\n" + + "});\n" + + "/* assert on the output */\n\n" + + "This ensures that you're testing the behavior the user would see " + + "in the browser." + + " Learn more at https://fb.me/react-wrap-tests-with-act" + + "%s", + getComponentName(fiber.type), + getStackByFiberInDevAndProd(fiber) + ); + } + } +} + +var warnIfNotCurrentlyActingUpdatesInDev = warnIfNotCurrentlyActingUpdatesInDEV; // In tests, we want to enforce a mocked scheduler. var didWarnAboutUnmockedScheduler = false; // TODO Before we release concurrent mode, revisit this and decide whether a mocked // scheduler is the actual recommendation. The alternative could be a testing build, @@ -18833,30 +21976,159 @@ function warnIfUnmockedScheduler(fiber) { ) { if (fiber.mode & BlockingMode || fiber.mode & ConcurrentMode) { didWarnAboutUnmockedScheduler = true; - - error( + warningWithoutStack$1( + false, 'In Concurrent or Sync modes, the "scheduler" module needs to be mocked ' + - "to guarantee consistent behaviour across tests and browsers. " + - "For example, with jest: \n" + // Break up requires to avoid accidentally parsing them as dependencies. - "jest.mock('scheduler', () => require" + - "('scheduler/unstable_mock'));\n\n" + + "to guarantee consistent behaviour across tests and browsers. " + + "For example, with jest: \n" + + "jest.mock('scheduler', () => require('scheduler/unstable_mock'));\n\n" + "For more info, visit https://fb.me/react-mock-scheduler" ); - } else { + } else if (warnAboutUnmockedScheduler === true) { didWarnAboutUnmockedScheduler = true; - - error( + warningWithoutStack$1( + false, 'Starting from React v17, the "scheduler" module will need to be mocked ' + - "to guarantee consistent behaviour across tests and browsers. " + - "For example, with jest: \n" + // Break up requires to avoid accidentally parsing them as dependencies. - "jest.mock('scheduler', () => require" + - "('scheduler/unstable_mock'));\n\n" + + "to guarantee consistent behaviour across tests and browsers. " + + "For example, with jest: \n" + + "jest.mock('scheduler', () => require('scheduler/unstable_mock'));\n\n" + "For more info, visit https://fb.me/react-mock-scheduler" ); } } } } +var componentsThatTriggeredHighPriSuspend = null; +function checkForWrongSuspensePriorityInDEV(sourceFiber) { + { + var currentPriorityLevel = getCurrentPriorityLevel(); + if ( + (sourceFiber.mode & ConcurrentMode) !== NoEffect && + (currentPriorityLevel === UserBlockingPriority$1 || + currentPriorityLevel === ImmediatePriority) + ) { + var workInProgressNode = sourceFiber; + + while (workInProgressNode !== null) { + // Add the component that triggered the suspense + var current$$1 = workInProgressNode.alternate; + + if (current$$1 !== null) { + // TODO: warn component that triggers the high priority + // suspend is the HostRoot + switch (workInProgressNode.tag) { + case ClassComponent: + // Loop through the component's update queue and see whether the component + // has triggered any high priority updates + var updateQueue = current$$1.updateQueue; + + if (updateQueue !== null) { + var update = updateQueue.firstUpdate; + + while (update !== null) { + var priorityLevel = update.priority; + + if ( + priorityLevel === UserBlockingPriority$1 || + priorityLevel === ImmediatePriority + ) { + if (componentsThatTriggeredHighPriSuspend === null) { + componentsThatTriggeredHighPriSuspend = new Set([ + getComponentName(workInProgressNode.type) + ]); + } else { + componentsThatTriggeredHighPriSuspend.add( + getComponentName(workInProgressNode.type) + ); + } + + break; + } + + update = update.next; + } + } + + break; + + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: + if ( + workInProgressNode.memoizedState !== null && + workInProgressNode.memoizedState.baseUpdate !== null + ) { + var _update = workInProgressNode.memoizedState.baseUpdate; // Loop through the functional component's memoized state to see whether + // the component has triggered any high pri updates + + while (_update !== null) { + var priority = _update.priority; + + if ( + priority === UserBlockingPriority$1 || + priority === ImmediatePriority + ) { + if (componentsThatTriggeredHighPriSuspend === null) { + componentsThatTriggeredHighPriSuspend = new Set([ + getComponentName(workInProgressNode.type) + ]); + } else { + componentsThatTriggeredHighPriSuspend.add( + getComponentName(workInProgressNode.type) + ); + } + + break; + } + + if ( + _update.next === workInProgressNode.memoizedState.baseUpdate + ) { + break; + } + + _update = _update.next; + } + } + + break; + + default: + break; + } + } + workInProgressNode = workInProgressNode.return; + } + } + } +} + +function flushSuspensePriorityWarningInDEV() { + { + if (componentsThatTriggeredHighPriSuspend !== null) { + var componentNames = []; + componentsThatTriggeredHighPriSuspend.forEach(function(name) { + return componentNames.push(name); + }); + componentsThatTriggeredHighPriSuspend = null; + + if (componentNames.length > 0) { + warningWithoutStack$1( + false, + "%s triggered a user-blocking update that suspended." + + "\n\n" + + "The fix is to split the update into multiple parts: a user-blocking " + + "update to provide immediate feedback, and another update that " + + "triggers the bulk of the changes." + + "\n\n" + + "Refer to the documentation for useTransition to learn how " + + "to implement this pattern.", // TODO: Add link to React docs with more information, once it exists + componentNames.sort().join(", ") + ); + } + } + } +} function computeThreadID(root, expirationTime) { // Interaction threads are unique per root and expiration time. @@ -18864,6 +22136,9 @@ function computeThreadID(root, expirationTime) { } function markSpawnedWork(expirationTime) { + if (!enableSchedulerTracing) { + return; + } if (spawnedWorkDuringRender === null) { spawnedWorkDuringRender = [expirationTime]; } else { @@ -18872,10 +22147,13 @@ function markSpawnedWork(expirationTime) { } function scheduleInteractions(root, expirationTime, interactions) { + if (!enableSchedulerTracing) { + return; + } + if (interactions.size > 0) { var pendingInteractionMap = root.pendingInteractionMap; var pendingInteractions = pendingInteractionMap.get(expirationTime); - if (pendingInteractions != null) { interactions.forEach(function(interaction) { if (!pendingInteractions.has(interaction)) { @@ -18894,7 +22172,6 @@ function scheduleInteractions(root, expirationTime, interactions) { } var subscriber = tracing.__subscriberRef.current; - if (subscriber !== null) { var threadID = computeThreadID(root, expirationTime); subscriber.onWorkScheduled(interactions, threadID); @@ -18903,10 +22180,21 @@ function scheduleInteractions(root, expirationTime, interactions) { } function schedulePendingInteractions(root, expirationTime) { + // This is called when work is scheduled on a root. + // It associates the current interactions with the newly-scheduled expiration. + // They will be restored when that expiration is later committed. + if (!enableSchedulerTracing) { + return; + } + scheduleInteractions(root, expirationTime, tracing.__interactionsRef.current); } function startWorkOnPendingInteractions(root, expirationTime) { + // This is called when new work is started on a root. + if (!enableSchedulerTracing) { + return; + } // Determine which interactions this batch of work currently includes, So that // we can accurately attribute time spent working on it, And so that cascading // work triggered during the render phase will be associated with it. @@ -18947,6 +22235,10 @@ function startWorkOnPendingInteractions(root, expirationTime) { } function finishPendingInteractions(root, committedExpirationTime) { + if (!enableSchedulerTracing) { + return; + } + var earliestRemainingTimeAfterCommit = root.firstPendingTime; var subscriber; @@ -18995,7 +22287,6 @@ function finishPendingInteractions(root, committedExpirationTime) { } } -var onScheduleFiberRoot = null; var onCommitFiberRoot = null; var onCommitFiberUnmount = null; var hasLoggedError = false; @@ -19014,10 +22305,10 @@ function injectInternals(internals) { // https://github.com/facebook/react/issues/3877 return true; } - if (!hook.supportsFiber) { { - error( + warningWithoutStack$1( + false, "The installed version of React DevTools is too old and will not work " + "with the current version of React. Please update React DevTools. " + "https://fb.me/react-devtools" @@ -19030,23 +22321,6 @@ function injectInternals(internals) { try { var rendererID = hook.inject(internals); // We have successfully injected, so now it is safe to set up hooks. - if (true) { - // Only used by Fast Refresh - if (typeof hook.onScheduleFiberRoot === "function") { - onScheduleFiberRoot = function(root, children) { - try { - hook.onScheduleFiberRoot(rendererID, root, children); - } catch (err) { - if (true && !hasLoggedError) { - hasLoggedError = true; - - error("React instrumentation encountered an error: %s", err); - } - } - }; - } - } - onCommitFiberRoot = function(root, expirationTime) { try { var didError = (root.current.effectTag & DidCapture) === DidCapture; @@ -19062,43 +22336,43 @@ function injectInternals(internals) { hook.onCommitFiberRoot(rendererID, root, undefined, didError); } } catch (err) { - if (true) { - if (!hasLoggedError) { - hasLoggedError = true; - - error("React instrumentation encountered an error: %s", err); - } + if (true && !hasLoggedError) { + hasLoggedError = true; + warningWithoutStack$1( + false, + "React DevTools encountered an error: %s", + err + ); } } }; - onCommitFiberUnmount = function(fiber) { try { hook.onCommitFiberUnmount(rendererID, fiber); } catch (err) { - if (true) { - if (!hasLoggedError) { - hasLoggedError = true; - - error("React instrumentation encountered an error: %s", err); - } + if (true && !hasLoggedError) { + hasLoggedError = true; + warningWithoutStack$1( + false, + "React DevTools encountered an error: %s", + err + ); } } }; } catch (err) { // Catch all errors because it is unsafe to throw during initialization. { - error("React instrumentation encountered an error: %s.", err); + warningWithoutStack$1( + false, + "React DevTools encountered an error: %s.", + err + ); } } // DevTools exists return true; } -function onScheduleRoot(root, children) { - if (typeof onScheduleFiberRoot === "function") { - onScheduleFiberRoot(root, children); - } -} function onCommitRoot(root, expirationTime) { if (typeof onCommitFiberRoot === "function") { onCommitFiberRoot(root, expirationTime); @@ -19160,7 +22434,7 @@ function FiberNode(tag, pendingProps, key, mode) { this.childExpirationTime = NoWork; this.alternate = null; - { + if (enableProfilerTimer) { // Note: The following is done to avoid a v8 performance cliff. // // Initializing the fields below to smis and later updating them with @@ -19187,7 +22461,7 @@ function FiberNode(tag, pendingProps, key, mode) { } // This is normally DEV-only except www when it adds listeners. // TODO: remove the User Timing integration in favor of Root Events. - { + if (enableUserTimingAPI) { this._debugID = debugCounter++; this._debugIsCurrentlyTiming = false; } @@ -19215,7 +22489,6 @@ function FiberNode(tag, pendingProps, key, mode) { // is faster. // 5) It should be easy to port this to a C struct and keep a C implementation // compatible. - var createFiber = function(tag, pendingProps, key, mode) { // $FlowFixMe: the shapes are exact here but Flow doesn't like constructors return new FiberNode(tag, pendingProps, key, mode); @@ -19251,7 +22524,7 @@ function resolveLazyComponentTag(Component) { return IndeterminateComponent; } // This is used to create an alternate fiber to do work on. -function createWorkInProgress(current, pendingProps) { +function createWorkInProgress(current, pendingProps, expirationTime) { var workInProgress = current.alternate; if (workInProgress === null) { @@ -19272,10 +22545,7 @@ function createWorkInProgress(current, pendingProps) { { // DEV-only fields - { - workInProgress._debugID = current._debugID; - } - + workInProgress._debugID = current._debugID; workInProgress._debugSource = current._debugSource; workInProgress._debugOwner = current._debugOwner; workInProgress._debugHookTypes = current._debugHookTypes; @@ -19293,7 +22563,7 @@ function createWorkInProgress(current, pendingProps) { workInProgress.firstEffect = null; workInProgress.lastEffect = null; - { + if (enableProfilerTimer) { // We intentionally reset, rather than copy, actualDuration & actualStartTime. // This prevents time from endlessly accumulating in new commits. // This has the downside of resetting values for different priority renders, @@ -19303,19 +22573,6 @@ function createWorkInProgress(current, pendingProps) { } } - { - // Trying to debug a mysterious internal-only production failure. - // See D20130868 and t62461245. - // This is only on for RN FB builds. - if (current == null) { - throw Error("current is " + current + " but it can't be"); - } - - if (workInProgress == null) { - throw Error("workInProgress is " + workInProgress + " but it can't be"); - } - } - workInProgress.childExpirationTime = current.childExpirationTime; workInProgress.expirationTime = current.expirationTime; workInProgress.child = current.child; @@ -19338,14 +22595,13 @@ function createWorkInProgress(current, pendingProps) { workInProgress.index = current.index; workInProgress.ref = current.ref; - { + if (enableProfilerTimer) { workInProgress.selfBaseDuration = current.selfBaseDuration; workInProgress.treeBaseDuration = current.treeBaseDuration; } { workInProgress._debugNeedsRemount = current._debugNeedsRemount; - switch (workInProgress.tag) { case IndeterminateComponent: case FunctionComponent: @@ -19360,6 +22616,9 @@ function createWorkInProgress(current, pendingProps) { case ForwardRef: workInProgress.type = resolveForwardRefForHotReloading(current.type); break; + + default: + break; } } @@ -19392,7 +22651,7 @@ function resetWorkInProgress(workInProgress, renderExpirationTime) { workInProgress.updateQueue = null; workInProgress.dependencies = null; - { + if (enableProfilerTimer) { // Note: We don't reset the actualTime counts. It's useful to accumulate // actual time across multiple render passes. workInProgress.selfBaseDuration = 0; @@ -19418,7 +22677,7 @@ function resetWorkInProgress(workInProgress, renderExpirationTime) { responders: currentDependencies.responders }; - { + if (enableProfilerTimer) { // Note: We don't reset the actualTime counts. It's useful to accumulate // actual time across multiple render passes. workInProgress.selfBaseDuration = current.selfBaseDuration; @@ -19439,7 +22698,7 @@ function createHostRootFiber(tag) { mode = NoMode; } - if (isDevToolsPresent) { + if (enableProfilerTimer && isDevToolsPresent) { // Always collect profile timings when DevTools are present. // This enables DevTools to start capturing timing at any point– // Without some nodes in the tree having empty base times. @@ -19508,14 +22767,12 @@ function createFiberFromTypeAndProps( expirationTime, key ); - default: { if (typeof type === "object" && type !== null) { switch (type.$$typeof) { case REACT_PROVIDER_TYPE: fiberTag = ContextProvider; break getTag; - case REACT_CONTEXT_TYPE: // This is a consumer fiberTag = ContextConsumer; @@ -19538,10 +22795,29 @@ function createFiberFromTypeAndProps( fiberTag = LazyComponent; resolvedType = null; break getTag; + case REACT_FUNDAMENTAL_TYPE: + if (enableFundamentalAPI) { + return createFiberFromFundamental( + type, + pendingProps, + mode, + expirationTime, + key + ); + } - case REACT_BLOCK_TYPE: - fiberTag = Block; - break getTag; + break; + + case REACT_SCOPE_TYPE: + if (enableScopeAPI) { + return createFiberFromScope( + type, + pendingProps, + mode, + expirationTime, + key + ); + } } } @@ -19603,7 +22879,6 @@ function createFiberFromElement(element, mode, expirationTime) { mode, expirationTime ); - { fiber._debugSource = element._source; fiber._debugOwner = element._owner; @@ -19616,11 +22891,38 @@ function createFiberFromFragment(elements, mode, expirationTime, key) { fiber.expirationTime = expirationTime; return fiber; } +function createFiberFromFundamental( + fundamentalComponent, + pendingProps, + mode, + expirationTime, + key +) { + var fiber = createFiber(FundamentalComponent, pendingProps, key, mode); + fiber.elementType = fundamentalComponent; + fiber.type = fundamentalComponent; + fiber.expirationTime = expirationTime; + return fiber; +} + +function createFiberFromScope(scope, pendingProps, mode, expirationTime, key) { + var fiber = createFiber(ScopeComponent, pendingProps, key, mode); + fiber.type = scope; + fiber.elementType = scope; + fiber.expirationTime = expirationTime; + return fiber; +} function createFiberFromProfiler(pendingProps, mode, expirationTime, key) { { - if (typeof pendingProps.id !== "string") { - error('Profiler must specify an "id" as a prop'); + if ( + typeof pendingProps.id !== "string" || + typeof pendingProps.onRender !== "function" + ) { + warningWithoutStack$1( + false, + 'Profiler must specify an "id" string and "onRender" function as props' + ); } } @@ -19629,14 +22931,6 @@ function createFiberFromProfiler(pendingProps, mode, expirationTime, key) { fiber.elementType = REACT_PROFILER_TYPE; fiber.type = REACT_PROFILER_TYPE; fiber.expirationTime = expirationTime; - - { - fiber.stateNode = { - effectDuration: 0, - passiveEffectDuration: 0 - }; - } - return fiber; } @@ -19659,7 +22953,6 @@ function createFiberFromSuspenseList(pendingProps, mode, expirationTime, key) { // instead. fiber.type = REACT_SUSPENSE_LIST_TYPE; } - fiber.elementType = REACT_SUSPENSE_LIST_TYPE; fiber.expirationTime = expirationTime; return fiber; @@ -19669,6 +22962,18 @@ function createFiberFromText(content, mode, expirationTime) { fiber.expirationTime = expirationTime; return fiber; } +function createFiberFromHostInstanceForDeletion() { + var fiber = createFiber(HostComponent, null, null, NoMode); // TODO: These should not need a type. + + fiber.elementType = "DELETED"; + fiber.type = "DELETED"; + return fiber; +} +function createFiberFromDehydratedFragment(dehydratedNode) { + var fiber = createFiber(DehydratedFragment, null, null, NoMode); + fiber.stateNode = dehydratedNode; + return fiber; +} function createFiberFromPortal(portal, mode, expirationTime) { var pendingProps = portal.children !== null ? portal.children : []; var fiber = createFiber(HostPortal, pendingProps, portal.key, mode); @@ -19716,21 +23021,16 @@ function assignFiberPropertiesInDEV(target, source) { target.expirationTime = source.expirationTime; target.childExpirationTime = source.childExpirationTime; target.alternate = source.alternate; - - { + if (enableProfilerTimer) { target.actualDuration = source.actualDuration; target.actualStartTime = source.actualStartTime; target.selfBaseDuration = source.selfBaseDuration; target.treeBaseDuration = source.treeBaseDuration; } - - { - target._debugID = source._debugID; - target._debugIsCurrentlyTiming = source._debugIsCurrentlyTiming; - } - + target._debugID = source._debugID; target._debugSource = source._debugSource; target._debugOwner = source._debugOwner; + target._debugIsCurrentlyTiming = source._debugIsCurrentlyTiming; target._debugNeedsRemount = source._debugNeedsRemount; target._debugHookTypes = source._debugHookTypes; return target; @@ -19757,21 +23057,28 @@ function FiberRootNode(containerInfo, tag, hydrate) { this.lastPingedTime = NoWork; this.lastExpiredTime = NoWork; - { + if (enableSchedulerTracing) { this.interactionThreadID = tracing.unstable_getThreadID(); this.memoizedInteractions = new Set(); this.pendingInteractionMap = new Map(); } + + if (enableSuspenseCallback) { + this.hydrationCallbacks = null; + } } function createFiberRoot(containerInfo, tag, hydrate, hydrationCallbacks) { var root = new FiberRootNode(containerInfo, tag, hydrate); + + if (enableSuspenseCallback) { + root.hydrationCallbacks = hydrationCallbacks; + } // Cyclic construction. This cheats the type system right now because // stateNode is any. var uninitializedFiber = createHostRootFiber(tag); root.current = uninitializedFiber; uninitializedFiber.stateNode = root; - initializeUpdateQueue(uninitializedFiber); return root; } function isRootSuspendedAtTime(root, expirationTime) { @@ -19865,6 +23172,15 @@ function markRootExpiredAtTime(root, expirationTime) { } } +// This lets us hook into Fiber to debug what it's doing. +// See https://github.com/facebook/react/pull/8033. +// This is not part of the public API, not even for React DevTools. +// You may only inject a debugTool if you work on React Fiber itself. +var ReactFiberInstrumentation = { + debugTool: null +}; +var ReactFiberInstrumentation_1 = ReactFiberInstrumentation; + var didWarnAboutNestedUpdates; var didWarnAboutFindNodeInStrictMode; @@ -19883,7 +23199,6 @@ function getContextForSubtree(parentComponent) { if (fiber.tag === ClassComponent) { var Component = fiber.type; - if (isContextProvider(Component)) { return processChildContext(fiber, Component, parentContext); } @@ -19892,6 +23207,33 @@ function getContextForSubtree(parentComponent) { return parentContext; } +function findHostInstance(component) { + var fiber = get(component); + + if (fiber === undefined) { + if (typeof component.render === "function") { + { + throw Error("Unable to find node on an unmounted component."); + } + } else { + { + throw Error( + "Argument appears to not be a ReactComponent. Keys: " + + Object.keys(component) + ); + } + } + } + + var hostFiber = findCurrentHostFiber(fiber); + + if (hostFiber === null) { + return null; + } + + return hostFiber.stateNode; +} + function findHostInstanceWithWarning(component, methodName) { { var fiber = get(component); @@ -19924,7 +23266,8 @@ function findHostInstanceWithWarning(component, methodName) { didWarnAboutFindNodeInStrictMode[componentName] = true; if (fiber.mode & StrictMode) { - error( + warningWithoutStack$1( + false, "%s is deprecated in StrictMode. " + "%s was passed an instance of %s which is inside StrictMode. " + "Instead, add a ref directly to the element you want to reference. " + @@ -19936,7 +23279,8 @@ function findHostInstanceWithWarning(component, methodName) { getStackByFiberInDevAndProd(hostFiber) ); } else { - error( + warningWithoutStack$1( + false, "%s is deprecated in StrictMode. " + "%s was passed an instance of %s which renders StrictMode children. " + "Instead, add a ref directly to the element you want to reference. " + @@ -19953,32 +23297,43 @@ function findHostInstanceWithWarning(component, methodName) { return hostFiber.stateNode; } + + return findHostInstance(component); } function createContainer(containerInfo, tag, hydrate, hydrationCallbacks) { - return createFiberRoot(containerInfo, tag, hydrate); + return createFiberRoot(containerInfo, tag, hydrate, hydrationCallbacks); } function updateContainer(element, container, parentComponent, callback) { - { - onScheduleRoot(container, element); - } - - var current$1 = container.current; + var current$$1 = container.current; var currentTime = requestCurrentTimeForUpdate(); { // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests if ("undefined" !== typeof jest) { - warnIfUnmockedScheduler(current$1); + warnIfUnmockedScheduler(current$$1); + warnIfNotScopedWithMatchingAct(current$$1); } } - var suspenseConfig = requestCurrentSuspenseConfig(); var expirationTime = computeExpirationForFiber( currentTime, - current$1, + current$$1, suspenseConfig ); + + { + if (ReactFiberInstrumentation_1.debugTool) { + if (current$$1.alternate === null) { + ReactFiberInstrumentation_1.debugTool.onMountContainer(container); + } else if (element === null) { + ReactFiberInstrumentation_1.debugTool.onUnmountContainer(container); + } else { + ReactFiberInstrumentation_1.debugTool.onUpdateContainer(container); + } + } + } + var context = getContextForSubtree(parentComponent); if (container.context === null) { @@ -19988,10 +23343,10 @@ function updateContainer(element, container, parentComponent, callback) { } { - if (isRendering && current !== null && !didWarnAboutNestedUpdates) { + if (phase === "render" && current !== null && !didWarnAboutNestedUpdates) { didWarnAboutNestedUpdates = true; - - error( + warningWithoutStack$1( + false, "Render methods should be a pure function of props and state; " + "triggering nested component updates from render is not allowed. " + "If necessary, trigger nested updates in componentDidUpdate.\n\n" + @@ -20010,21 +23365,19 @@ function updateContainer(element, container, parentComponent, callback) { callback = callback === undefined ? null : callback; if (callback !== null) { - { - if (typeof callback !== "function") { - error( + !(typeof callback === "function") + ? warningWithoutStack$1( + false, "render(...): Expected the last optional `callback` argument to be a " + "function. Instead received: %s.", callback - ); - } - } - + ) + : void 0; update.callback = callback; } - enqueueUpdate(current$1, update); - scheduleWork(current$1, expirationTime); + enqueueUpdate(current$$1, update); + scheduleWork(current$$1, expirationTime); return expirationTime; } function getPublicRootInstance(container) { @@ -20038,145 +23391,693 @@ function getPublicRootInstance(container) { case HostComponent: return getPublicInstance(containerFiber.child.stateNode); - default: - return containerFiber.child.stateNode; + default: + return containerFiber.child.stateNode; + } +} + +var shouldSuspendImpl = function(fiber) { + return false; +}; + +function shouldSuspend(fiber) { + return shouldSuspendImpl(fiber); +} +var overrideHookState = null; +var overrideProps = null; +var scheduleUpdate = null; +var setSuspenseHandler = null; + +{ + var copyWithSetImpl = function(obj, path, idx, value) { + if (idx >= path.length) { + return value; + } + + var key = path[idx]; + var updated = Array.isArray(obj) ? obj.slice() : Object.assign({}, obj); // $FlowFixMe number or string is fine here + + updated[key] = copyWithSetImpl(obj[key], path, idx + 1, value); + return updated; + }; + + var copyWithSet = function(obj, path, value) { + return copyWithSetImpl(obj, path, 0, value); + }; // Support DevTools editable values for useState and useReducer. + + overrideHookState = function(fiber, id, path, value) { + // For now, the "id" of stateful hooks is just the stateful hook index. + // This may change in the future with e.g. nested hooks. + var currentHook = fiber.memoizedState; + while (currentHook !== null && id > 0) { + currentHook = currentHook.next; + id--; + } + + if (currentHook !== null) { + var newState = copyWithSet(currentHook.memoizedState, path, value); + currentHook.memoizedState = newState; + currentHook.baseState = newState; // We aren't actually adding an update to the queue, + // because there is no update we can add for useReducer hooks that won't trigger an error. + // (There's no appropriate action type for DevTools overrides.) + // As a result though, React will see the scheduled update as a noop and bailout. + // Shallow cloning props works as a workaround for now to bypass the bailout check. + + fiber.memoizedProps = Object.assign({}, fiber.memoizedProps); + scheduleWork(fiber, Sync); + } + }; // Support DevTools props for function components, forwardRef, memo, host components, etc. + + overrideProps = function(fiber, path, value) { + fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value); + + if (fiber.alternate) { + fiber.alternate.pendingProps = fiber.pendingProps; + } + + scheduleWork(fiber, Sync); + }; + + scheduleUpdate = function(fiber) { + scheduleWork(fiber, Sync); + }; + + setSuspenseHandler = function(newShouldSuspendImpl) { + shouldSuspendImpl = newShouldSuspendImpl; + }; +} + +function injectIntoDevTools(devToolsConfig) { + var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance; + var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher; + return injectInternals( + Object.assign({}, devToolsConfig, { + overrideHookState: overrideHookState, + overrideProps: overrideProps, + setSuspenseHandler: setSuspenseHandler, + scheduleUpdate: scheduleUpdate, + currentDispatcherRef: ReactCurrentDispatcher, + findHostInstanceByFiber: function(fiber) { + var hostFiber = findCurrentHostFiber(fiber); + + if (hostFiber === null) { + return null; + } + + return hostFiber.stateNode; + }, + findFiberByHostInstance: function(instance) { + if (!findFiberByHostInstance) { + // Might not be implemented by the renderer. + return null; + } + + return findFiberByHostInstance(instance); + }, + // React Refresh + findHostInstancesForRefresh: findHostInstancesForRefresh, + scheduleRefresh: scheduleRefresh, + scheduleRoot: scheduleRoot, + setRefreshHandler: setRefreshHandler, + // Enables DevTools to append owner stacks to error messages in DEV mode. + getCurrentFiber: function() { + return current; + } + }) + ); +} + +// This file intentionally does *not* have the Flow annotation. +// Don't add it. See `./inline-typed.js` for an explanation. + +function createPortal( + children, + containerInfo, // TODO: figure out the API for cross-renderer implementation. + implementation +) { + var key = + arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null; + return { + // This tag allow us to uniquely identify this as a React Portal + $$typeof: REACT_PORTAL_TYPE, + key: key == null ? null : "" + key, + children: children, + containerInfo: containerInfo, + implementation: implementation + }; +} + +// TODO: this is special because it gets imported during build. + +var ReactVersion = "16.11.0"; + +var NativeMethodsMixin = function(findNodeHandle, findHostInstance) { + /** + * `NativeMethodsMixin` provides methods to access the underlying native + * component directly. This can be useful in cases when you want to focus + * a view or measure its on-screen dimensions, for example. + * + * The methods described here are available on most of the default components + * provided by React Native. Note, however, that they are *not* available on + * composite components that aren't directly backed by a native view. This will + * generally include most components that you define in your own app. For more + * information, see [Direct + * Manipulation](docs/direct-manipulation.html). + * + * Note the Flow $Exact<> syntax is required to support mixins. + * React createClass mixins can only be used with exact types. + */ + var NativeMethodsMixin = { + /** + * Determines the location on screen, width, and height of the given view and + * returns the values via an async callback. If successful, the callback will + * be called with the following arguments: + * + * - x + * - y + * - width + * - height + * - pageX + * - pageY + * + * Note that these measurements are not available until after the rendering + * has been completed in native. If you need the measurements as soon as + * possible, consider using the [`onLayout` + * prop](docs/view.html#onlayout) instead. + */ + measure: function(callback) { + var maybeInstance; // Fiber errors if findNodeHandle is called for an umounted component. + // Tests using ReactTestRenderer will trigger this case indirectly. + // Mimicking stack behavior, we should silently ignore this case. + // TODO Fix ReactTestRenderer so we can remove this try/catch. + + try { + maybeInstance = findHostInstance(this); + } catch (error) {} // If there is no host component beneath this we should fail silently. + // This is not an error; it could mean a class component rendered null. + + if (maybeInstance == null) { + return; + } + + if (maybeInstance.canonical) { + // We can't call FabricUIManager here because it won't be loaded in paper + // at initialization time. See https://github.com/facebook/react/pull/15490 + // for more info. + nativeFabricUIManager.measure( + maybeInstance.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ); + } else { + ReactNativePrivateInterface.UIManager.measure( + findNodeHandle(this), + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ); + } + }, + + /** + * Determines the location of the given view in the window and returns the + * values via an async callback. If the React root view is embedded in + * another native view, this will give you the absolute coordinates. If + * successful, the callback will be called with the following + * arguments: + * + * - x + * - y + * - width + * - height + * + * Note that these measurements are not available until after the rendering + * has been completed in native. + */ + measureInWindow: function(callback) { + var maybeInstance; // Fiber errors if findNodeHandle is called for an umounted component. + // Tests using ReactTestRenderer will trigger this case indirectly. + // Mimicking stack behavior, we should silently ignore this case. + // TODO Fix ReactTestRenderer so we can remove this try/catch. + + try { + maybeInstance = findHostInstance(this); + } catch (error) {} // If there is no host component beneath this we should fail silently. + // This is not an error; it could mean a class component rendered null. + + if (maybeInstance == null) { + return; + } + + if (maybeInstance.canonical) { + // We can't call FabricUIManager here because it won't be loaded in paper + // at initialization time. See https://github.com/facebook/react/pull/15490 + // for more info. + nativeFabricUIManager.measureInWindow( + maybeInstance.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ); + } else { + ReactNativePrivateInterface.UIManager.measureInWindow( + findNodeHandle(this), + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ); + } + }, + + /** + * Like [`measure()`](#measure), but measures the view relative an ancestor, + * specified as `relativeToNativeNode`. This means that the returned x, y + * are relative to the origin x, y of the ancestor view. + * + * As always, to obtain a native node handle for a component, you can use + * `findNodeHandle(component)`. + */ + measureLayout: function( + relativeToNativeNode, + onSuccess, + onFail + ) /* currently unused */ + { + var maybeInstance; // Fiber errors if findNodeHandle is called for an umounted component. + // Tests using ReactTestRenderer will trigger this case indirectly. + // Mimicking stack behavior, we should silently ignore this case. + // TODO Fix ReactTestRenderer so we can remove this try/catch. + + try { + maybeInstance = findHostInstance(this); + } catch (error) {} // If there is no host component beneath this we should fail silently. + // This is not an error; it could mean a class component rendered null. + + if (maybeInstance == null) { + return; + } + + if (maybeInstance.canonical) { + warningWithoutStack$1( + false, + "Warning: measureLayout on components using NativeMethodsMixin " + + "or ReactNative.NativeComponent is not currently supported in Fabric. " + + "measureLayout must be called on a native ref. Consider using forwardRef." + ); + return; + } else { + var relativeNode; + + if (typeof relativeToNativeNode === "number") { + // Already a node handle + relativeNode = relativeToNativeNode; + } else if (relativeToNativeNode._nativeTag) { + relativeNode = relativeToNativeNode._nativeTag; + } + + if (relativeNode == null) { + warningWithoutStack$1( + false, + "Warning: ref.measureLayout must be called with a node handle or a ref to a native component." + ); + return; + } + + ReactNativePrivateInterface.UIManager.measureLayout( + findNodeHandle(this), + relativeNode, + mountSafeCallback_NOT_REALLY_SAFE(this, onFail), + mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) + ); + } + }, + + /** + * This function sends props straight to native. They will not participate in + * future diff process - this means that if you do not include them in the + * next render, they will remain active (see [Direct + * Manipulation](docs/direct-manipulation.html)). + */ + setNativeProps: function(nativeProps) { + // Class components don't have viewConfig -> validateAttributes. + // Nor does it make sense to set native props on a non-native component. + // Instead, find the nearest host component and set props on it. + // Use findNodeHandle() rather than findNodeHandle() because + // We want the instance/wrapper (not the native tag). + var maybeInstance; // Fiber errors if findNodeHandle is called for an umounted component. + // Tests using ReactTestRenderer will trigger this case indirectly. + // Mimicking stack behavior, we should silently ignore this case. + // TODO Fix ReactTestRenderer so we can remove this try/catch. + + try { + maybeInstance = findHostInstance(this); + } catch (error) {} // If there is no host component beneath this we should fail silently. + // This is not an error; it could mean a class component rendered null. + + if (maybeInstance == null) { + return; + } + + if (maybeInstance.canonical) { + warningWithoutStack$1( + false, + "Warning: setNativeProps is not currently supported in Fabric" + ); + return; + } + + var nativeTag = + maybeInstance._nativeTag || maybeInstance.canonical._nativeTag; + var viewConfig = + maybeInstance.viewConfig || maybeInstance.canonical.viewConfig; + + { + warnForStyleProps(nativeProps, viewConfig.validAttributes); + } + + var updatePayload = create(nativeProps, 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( + nativeTag, + viewConfig.uiViewClassName, + updatePayload + ); + } + }, + + /** + * Requests focus for the given input or view. The exact behavior triggered + * will depend on the platform and type of view. + */ + focus: function() { + ReactNativePrivateInterface.TextInputState.focusTextInput( + findNodeHandle(this) + ); + }, + + /** + * Removes focus from an input or view. This is the opposite of `focus()`. + */ + blur: function() { + ReactNativePrivateInterface.TextInputState.blurTextInput( + findNodeHandle(this) + ); + } + }; + + { + // hide this from Flow since we can't define these properties outside of + // true without actually implementing them (setting them to undefined + // isn't allowed by ReactClass) + var NativeMethodsMixin_DEV = NativeMethodsMixin; + + if ( + !( + !NativeMethodsMixin_DEV.componentWillMount && + !NativeMethodsMixin_DEV.componentWillReceiveProps && + !NativeMethodsMixin_DEV.UNSAFE_componentWillMount && + !NativeMethodsMixin_DEV.UNSAFE_componentWillReceiveProps + ) + ) { + throw Error("Do not override existing functions."); + } // TODO (bvaughn) Remove cWM and cWRP in a future version of React Native, + // Once these lifecycles have been remove from the reconciler. + + NativeMethodsMixin_DEV.componentWillMount = function() { + throwOnStylesProp(this, this.props); + }; + + NativeMethodsMixin_DEV.componentWillReceiveProps = function(newProps) { + throwOnStylesProp(this, newProps); + }; + + NativeMethodsMixin_DEV.UNSAFE_componentWillMount = function() { + throwOnStylesProp(this, this.props); + }; + + NativeMethodsMixin_DEV.UNSAFE_componentWillReceiveProps = function( + newProps + ) { + throwOnStylesProp(this, newProps); + }; // React may warn about cWM/cWRP/cWU methods being deprecated. + // Add a flag to suppress these warnings for this special case. + // TODO (bvaughn) Remove this flag once the above methods have been removed. + + NativeMethodsMixin_DEV.componentWillMount.__suppressDeprecationWarning = true; + NativeMethodsMixin_DEV.componentWillReceiveProps.__suppressDeprecationWarning = true; } -} -var shouldSuspendImpl = function(fiber) { - return false; + return NativeMethodsMixin; }; -function shouldSuspend(fiber) { - return shouldSuspendImpl(fiber); -} -var overrideHookState = null; -var overrideProps = null; -var scheduleUpdate = null; -var setSuspenseHandler = null; +var ReactNativeComponent$1 = function(findNodeHandle, findHostInstance) { + /** + * Superclass that provides methods to access the underlying native component. + * This can be useful when you want to focus a view or measure its dimensions. + * + * Methods implemented by this class are available on most default components + * provided by React Native. However, they are *not* available on composite + * components that are not directly backed by a native view. For more + * information, see [Direct Manipulation](docs/direct-manipulation.html). + * + * @abstract + */ + var ReactNativeComponent = + /*#__PURE__*/ + (function(_React$Component) { + _inheritsLoose(ReactNativeComponent, _React$Component); -{ - var copyWithSetImpl = function(obj, path, idx, value) { - if (idx >= path.length) { - return value; - } + function ReactNativeComponent() { + return _React$Component.apply(this, arguments) || this; + } - var key = path[idx]; - var updated = Array.isArray(obj) ? obj.slice() : Object.assign({}, obj); // $FlowFixMe number or string is fine here + var _proto = ReactNativeComponent.prototype; - updated[key] = copyWithSetImpl(obj[key], path, idx + 1, value); - return updated; - }; + /** + * Due to bugs in Flow's handling of React.createClass, some fields already + * declared in the base class need to be redeclared below. + */ - var copyWithSet = function(obj, path, value) { - return copyWithSetImpl(obj, path, 0, value); - }; // Support DevTools editable values for useState and useReducer. + /** + * Removes focus. This is the opposite of `focus()`. + */ + _proto.blur = function blur() { + ReactNativePrivateInterface.TextInputState.blurTextInput( + findNodeHandle(this) + ); + }; + /** + * Requests focus. The exact behavior depends on the platform and view. + */ - overrideHookState = function(fiber, id, path, value) { - // For now, the "id" of stateful hooks is just the stateful hook index. - // This may change in the future with e.g. nested hooks. - var currentHook = fiber.memoizedState; + _proto.focus = function focus() { + ReactNativePrivateInterface.TextInputState.focusTextInput( + findNodeHandle(this) + ); + }; + /** + * Measures the on-screen location and dimensions. If successful, the callback + * will be called asynchronously with the following arguments: + * + * - x + * - y + * - width + * - height + * - pageX + * - pageY + * + * These values are not available until after natives rendering completes. If + * you need the measurements as soon as possible, consider using the + * [`onLayout` prop](docs/view.html#onlayout) instead. + */ + + _proto.measure = function measure(callback) { + var maybeInstance; // Fiber errors if findNodeHandle is called for an umounted component. + // Tests using ReactTestRenderer will trigger this case indirectly. + // Mimicking stack behavior, we should silently ignore this case. + // TODO Fix ReactTestRenderer so we can remove this try/catch. - while (currentHook !== null && id > 0) { - currentHook = currentHook.next; - id--; - } + try { + maybeInstance = findHostInstance(this); + } catch (error) {} // If there is no host component beneath this we should fail silently. + // This is not an error; it could mean a class component rendered null. - if (currentHook !== null) { - var newState = copyWithSet(currentHook.memoizedState, path, value); - currentHook.memoizedState = newState; - currentHook.baseState = newState; // We aren't actually adding an update to the queue, - // because there is no update we can add for useReducer hooks that won't trigger an error. - // (There's no appropriate action type for DevTools overrides.) - // As a result though, React will see the scheduled update as a noop and bailout. - // Shallow cloning props works as a workaround for now to bypass the bailout check. + if (maybeInstance == null) { + return; + } - fiber.memoizedProps = Object.assign({}, fiber.memoizedProps); - scheduleWork(fiber, Sync); - } - }; // Support DevTools props for function components, forwardRef, memo, host components, etc. + if (maybeInstance.canonical) { + // We can't call FabricUIManager here because it won't be loaded in paper + // at initialization time. See https://github.com/facebook/react/pull/15490 + // for more info. + nativeFabricUIManager.measure( + maybeInstance.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ); + } else { + ReactNativePrivateInterface.UIManager.measure( + findNodeHandle(this), + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ); + } + }; + /** + * Measures the on-screen location and dimensions. Even if the React Native + * root view is embedded within another native view, this method will give you + * the absolute coordinates measured from the window. If successful, the + * callback will be called asynchronously with the following arguments: + * + * - x + * - y + * - width + * - height + * + * These values are not available until after natives rendering completes. + */ + + _proto.measureInWindow = function measureInWindow(callback) { + var maybeInstance; // Fiber errors if findNodeHandle is called for an umounted component. + // Tests using ReactTestRenderer will trigger this case indirectly. + // Mimicking stack behavior, we should silently ignore this case. + // TODO Fix ReactTestRenderer so we can remove this try/catch. - overrideProps = function(fiber, path, value) { - fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value); + try { + maybeInstance = findHostInstance(this); + } catch (error) {} // If there is no host component beneath this we should fail silently. + // This is not an error; it could mean a class component rendered null. - if (fiber.alternate) { - fiber.alternate.pendingProps = fiber.pendingProps; - } + if (maybeInstance == null) { + return; + } - scheduleWork(fiber, Sync); - }; + if (maybeInstance.canonical) { + // We can't call FabricUIManager here because it won't be loaded in paper + // at initialization time. See https://github.com/facebook/react/pull/15490 + // for more info. + nativeFabricUIManager.measureInWindow( + maybeInstance.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ); + } else { + ReactNativePrivateInterface.UIManager.measureInWindow( + findNodeHandle(this), + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ); + } + }; + /** + * Similar to [`measure()`](#measure), but the resulting location will be + * relative to the supplied ancestor's location. + * + * Obtain a native node handle with `ReactNative.findNodeHandle(component)`. + */ + + _proto.measureLayout = function measureLayout( + relativeToNativeNode, + onSuccess, + onFail + ) { + var maybeInstance; // Fiber errors if findNodeHandle is called for an umounted component. + // Tests using ReactTestRenderer will trigger this case indirectly. + // Mimicking stack behavior, we should silently ignore this case. + // TODO Fix ReactTestRenderer so we can remove this try/catch. - scheduleUpdate = function(fiber) { - scheduleWork(fiber, Sync); - }; + try { + maybeInstance = findHostInstance(this); + } catch (error) {} // If there is no host component beneath this we should fail silently. + // This is not an error; it could mean a class component rendered null. - setSuspenseHandler = function(newShouldSuspendImpl) { - shouldSuspendImpl = newShouldSuspendImpl; - }; -} + if (maybeInstance == null) { + return; + } -function injectIntoDevTools(devToolsConfig) { - var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance; - var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher; - return injectInternals({ - bundleType: devToolsConfig.bundleType, - version: devToolsConfig.version, - rendererPackageName: devToolsConfig.rendererPackageName, - rendererConfig: devToolsConfig.rendererConfig, - overrideHookState: overrideHookState, - overrideProps: overrideProps, - setSuspenseHandler: setSuspenseHandler, - scheduleUpdate: scheduleUpdate, - currentDispatcherRef: ReactCurrentDispatcher, - findHostInstanceByFiber: function(fiber) { - var hostFiber = findCurrentHostFiber(fiber); - - if (hostFiber === null) { - return null; - } + if (maybeInstance.canonical) { + warningWithoutStack$1( + false, + "Warning: measureLayout on components using NativeMethodsMixin " + + "or ReactNative.NativeComponent is not currently supported in Fabric. " + + "measureLayout must be called on a native ref. Consider using forwardRef." + ); + return; + } else { + var relativeNode; - return hostFiber.stateNode; - }, - findFiberByHostInstance: function(instance) { - if (!findFiberByHostInstance) { - // Might not be implemented by the renderer. - return null; - } + if (typeof relativeToNativeNode === "number") { + // Already a node handle + relativeNode = relativeToNativeNode; + } else if (relativeToNativeNode._nativeTag) { + relativeNode = relativeToNativeNode._nativeTag; + } - return findFiberByHostInstance(instance); - }, - // React Refresh - findHostInstancesForRefresh: findHostInstancesForRefresh, - scheduleRefresh: scheduleRefresh, - scheduleRoot: scheduleRoot, - setRefreshHandler: setRefreshHandler, - // Enables DevTools to append owner stacks to error messages in DEV mode. - getCurrentFiber: function() { - return current; - } - }); -} -var IsSomeRendererActing$1 = ReactSharedInternals.IsSomeRendererActing; + if (relativeNode == null) { + warningWithoutStack$1( + false, + "Warning: ref.measureLayout must be called with a node handle or a ref to a native component." + ); + return; + } -function createPortal( - children, - containerInfo, // TODO: figure out the API for cross-renderer implementation. - implementation -) { - var key = - arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null; - return { - // This tag allow us to uniquely identify this as a React Portal - $$typeof: REACT_PORTAL_TYPE, - key: key == null ? null : "" + key, - children: children, - containerInfo: containerInfo, - implementation: implementation - }; -} + ReactNativePrivateInterface.UIManager.measureLayout( + findNodeHandle(this), + relativeNode, + mountSafeCallback_NOT_REALLY_SAFE(this, onFail), + mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) + ); + } + }; + /** + * This function sends props straight to native. They will not participate in + * future diff process - this means that if you do not include them in the + * next render, they will remain active (see [Direct + * Manipulation](docs/direct-manipulation.html)). + */ + + _proto.setNativeProps = function setNativeProps(nativeProps) { + // Class components don't have viewConfig -> validateAttributes. + // Nor does it make sense to set native props on a non-native component. + // Instead, find the nearest host component and set props on it. + // Use findNodeHandle() rather than ReactNative.findNodeHandle() because + // We want the instance/wrapper (not the native tag). + var maybeInstance; // Fiber errors if findNodeHandle is called for an umounted component. + // Tests using ReactTestRenderer will trigger this case indirectly. + // Mimicking stack behavior, we should silently ignore this case. + // TODO Fix ReactTestRenderer so we can remove this try/catch. -// TODO: this is special because it gets imported during build. -var ReactVersion = "16.13.0"; + try { + maybeInstance = findHostInstance(this); + } catch (error) {} // If there is no host component beneath this we should fail silently. + // This is not an error; it could mean a class component rendered null. + + if (maybeInstance == null) { + return; + } + + if (maybeInstance.canonical) { + warningWithoutStack$1( + false, + "Warning: setNativeProps is not currently supported in Fabric" + ); + return; + } + + var nativeTag = + maybeInstance._nativeTag || maybeInstance.canonical._nativeTag; + var viewConfig = + maybeInstance.viewConfig || maybeInstance.canonical.viewConfig; + var updatePayload = create(nativeProps, 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( + nativeTag, + viewConfig.uiViewClassName, + updatePayload + ); + } + }; + + return ReactNativeComponent; + })(React.Component); // eslint-disable-next-line no-unused-expressions + + return ReactNativeComponent; +}; var instanceCache = new Map(); @@ -20184,14 +24085,13 @@ function getInstanceFromTag(tag) { return instanceCache.get(tag) || null; } -var emptyObject$1 = {}; +var emptyObject$3 = {}; { - Object.freeze(emptyObject$1); + Object.freeze(emptyObject$3); } var getInspectorDataForViewTag; -var getInspectorDataForViewAtPoint; { var traverseOwnerTreeUp = function(hierarchy, instance) { @@ -20215,7 +24115,6 @@ var getInspectorDataForViewAtPoint; return instance; } } - return hierarchy[0]; }; @@ -20223,10 +24122,10 @@ var getInspectorDataForViewAtPoint; var host = findCurrentHostFiber(fiber); if (host) { - return host.memoizedProps || emptyObject$1; + return host.memoizedProps || emptyObject$3; } - return emptyObject$1; + return emptyObject$3; }; var getHostNode = function(fiber, findNodeHandle) { @@ -20254,65 +24153,28 @@ var getInspectorDataForViewAtPoint; name: getComponentName(fiber.type), getInspectorData: function(findNodeHandle) { return { - props: getHostProps(fiber), - source: fiber._debugSource, measure: function(callback) { - // If this is Fabric, we'll find a ShadowNode and use that to measure. - var hostFiber = findCurrentHostFiber(fiber); - var shadowNode = - hostFiber != null && - hostFiber.stateNode !== null && - hostFiber.stateNode.node; - - if (shadowNode) { - nativeFabricUIManager.measure(shadowNode, callback); - } else { - return ReactNativePrivateInterface.UIManager.measure( - getHostNode(fiber, findNodeHandle), - callback - ); - } - } + return ReactNativePrivateInterface.UIManager.measure( + getHostNode(fiber, findNodeHandle), + callback + ); + }, + props: getHostProps(fiber), + source: fiber._debugSource }; } }; }); }; - var getInspectorDataForInstance = function(closestInstance) { - // Handle case where user clicks outside of ReactNative - if (!closestInstance) { - return { - hierarchy: [], - props: emptyObject$1, - selectedIndex: null, - source: null - }; - } - - var fiber = findCurrentFiberUsingSlowPath(closestInstance); - var fiberHierarchy = getOwnerHierarchy(fiber); - var instance = lastNonHostInstance(fiberHierarchy); - var hierarchy = createHierarchy(fiberHierarchy); - var props = getHostProps(instance); - var source = instance._debugSource; - var selectedIndex = fiberHierarchy.indexOf(instance); - return { - hierarchy: hierarchy, - props: props, - selectedIndex: selectedIndex, - source: source - }; - }; - getInspectorDataForViewTag = function(viewTag) { var closestInstance = getInstanceFromTag(viewTag); // Handle case where user clicks outside of ReactNative if (!closestInstance) { return { hierarchy: [], - props: emptyObject$1, - selectedIndex: null, + props: emptyObject$3, + selection: null, source: null }; } @@ -20323,122 +24185,36 @@ var getInspectorDataForViewAtPoint; var hierarchy = createHierarchy(fiberHierarchy); var props = getHostProps(instance); var source = instance._debugSource; - var selectedIndex = fiberHierarchy.indexOf(instance); + var selection = fiberHierarchy.indexOf(instance); return { hierarchy: hierarchy, props: props, - selectedIndex: selectedIndex, + selection: selection, source: source }; }; - - getInspectorDataForViewAtPoint = function( - findNodeHandle, - inspectedView, - locationX, - locationY, - callback - ) { - var closestInstance = null; - - if (inspectedView._internalInstanceHandle != null) { - // For Fabric we can look up the instance handle directly and measure it. - nativeFabricUIManager.findNodeAtPoint( - inspectedView._internalInstanceHandle.stateNode.node, - locationX, - locationY, - function(internalInstanceHandle) { - if (internalInstanceHandle == null) { - callback( - Object.assign( - { - pointerY: locationY, - frame: { - left: 0, - top: 0, - width: 0, - height: 0 - } - }, - getInspectorDataForInstance(closestInstance) - ) - ); - } - - closestInstance = - internalInstanceHandle.stateNode.canonical._internalInstanceHandle; - nativeFabricUIManager.measure( - internalInstanceHandle.stateNode.node, - function(x, y, width, height, pageX, pageY) { - callback( - Object.assign( - { - pointerY: locationY, - frame: { - left: pageX, - top: pageY, - width: width, - height: height - } - }, - getInspectorDataForInstance(closestInstance) - ) - ); - } - ); - } - ); - } else if (inspectedView._internalFiberInstanceHandleDEV != null) { - // For Paper we fall back to the old strategy using the React tag. - ReactNativePrivateInterface.UIManager.findSubviewIn( - findNodeHandle(inspectedView), - [locationX, locationY], - function(nativeViewTag, left, top, width, height) { - var inspectorData = getInspectorDataForInstance( - getInstanceFromTag(nativeViewTag) - ); - callback( - Object.assign({}, inspectorData, { - pointerY: locationY, - frame: { - left: left, - top: top, - width: width, - height: height - }, - touchedViewTag: nativeViewTag - }) - ); - } - ); - } else { - error( - "getInspectorDataForViewAtPoint expects to receieve a host component" - ); - - return; - } - }; } -var ReactCurrentOwner$3 = ReactSharedInternals.ReactCurrentOwner; +var _nativeFabricUIManage = nativeFabricUIManager; +var fabricDispatchCommand = _nativeFabricUIManage.dispatchCommand; +var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner; function findHostInstance_DEPRECATED(componentOrHandle) { { - var owner = ReactCurrentOwner$3.current; + var owner = ReactCurrentOwner.current; if (owner !== null && owner.stateNode !== null) { - if (!owner.stateNode._warnedAboutRefsInRender) { - error( - "%s is accessing findNodeHandle inside its render(). " + - "render() should be a pure function of props and state. It should " + - "never access something that requires stale data from the previous " + - "render, such as refs. Move this logic to componentDidMount and " + - "componentDidUpdate instead.", - getComponentName(owner.type) || "A component" - ); - } - + !owner.stateNode._warnedAboutRefsInRender + ? warningWithoutStack$1( + false, + "%s is accessing findNodeHandle inside its render(). " + + "render() should be a pure function of props and state. It should " + + "never access something that requires stale data from the previous " + + "render, such as refs. Move this logic to componentDidMount and " + + "componentDidUpdate instead.", + getComponentName(owner.type) || "A component" + ) + : void 0; owner.stateNode._warnedAboutRefsInRender = true; } } @@ -20478,20 +24254,20 @@ function findHostInstance_DEPRECATED(componentOrHandle) { function findNodeHandle(componentOrHandle) { { - var owner = ReactCurrentOwner$3.current; + var owner = ReactCurrentOwner.current; if (owner !== null && owner.stateNode !== null) { - if (!owner.stateNode._warnedAboutRefsInRender) { - error( - "%s is accessing findNodeHandle inside its render(). " + - "render() should be a pure function of props and state. It should " + - "never access something that requires stale data from the previous " + - "render, such as refs. Move this logic to componentDidMount and " + - "componentDidUpdate instead.", - getComponentName(owner.type) || "A component" - ); - } - + !owner.stateNode._warnedAboutRefsInRender + ? warningWithoutStack$1( + false, + "%s is accessing findNodeHandle inside its render(). " + + "render() should be a pure function of props and state. It should " + + "never access something that requires stale data from the previous " + + "render, such as refs. Move this logic to componentDidMount and " + + "componentDidUpdate instead.", + getComponentName(owner.type) || "A component" + ) + : void 0; owner.stateNode._warnedAboutRefsInRender = true; } } @@ -20531,95 +24307,94 @@ function findNodeHandle(componentOrHandle) { // Fabric return hostInstance.canonical._nativeTag; } - return hostInstance._nativeTag; } -function dispatchCommand(handle, command, args) { - if (handle._nativeTag == null) { - { - error( - "dispatchCommand was called with a ref that isn't a " + - "native component. Use React.forwardRef to get access to the underlying native component" - ); +setBatchingImplementation( + batchedUpdates$1, + discreteUpdates$1, + flushDiscreteUpdates, + batchedEventUpdates$1 +); +var roots = new Map(); +var ReactFabric = { + NativeComponent: ReactNativeComponent$1(findNodeHandle, findHostInstance), + // This is needed for implementation details of TouchableNativeFeedback + // Remove this once TouchableNativeFeedback doesn't use cloneElement + findHostInstance_DEPRECATED: findHostInstance_DEPRECATED, + findNodeHandle: findNodeHandle, + dispatchCommand: function(handle, command, args) { + var invalid = + handle._nativeTag == null || handle._internalInstanceHandle == null; + + if (invalid) { + !!invalid + ? warningWithoutStack$1( + false, + "dispatchCommand was called with a ref that isn't a " + + "native component. Use React.forwardRef to get access to the underlying native component" + ) + : void 0; + return; } - return; - } - - if (handle._internalInstanceHandle) { - nativeFabricUIManager.dispatchCommand( + fabricDispatchCommand( handle._internalInstanceHandle.stateNode.node, command, args ); - } else { - ReactNativePrivateInterface.UIManager.dispatchViewManagerCommand( - handle._nativeTag, - command, - args - ); - } -} - -function render(element, containerTag, callback) { - var root = roots.get(containerTag); - - 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); - roots.set(containerTag, root); - } - - updateContainer(element, root, null, callback); - return getPublicRootInstance(root); -} - -function unmountComponentAtNode(containerTag) { - this.stopSurface(containerTag); -} + }, + render: function(element, containerTag, callback) { + var root = roots.get(containerTag); -function stopSurface(containerTag) { - var root = roots.get(containerTag); + 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); + roots.set(containerTag, root); + } - if (root) { - // TODO: Is it safe to reset this now or should I wait since this unmount could be deferred? - updateContainer(null, root, null, function() { - roots.delete(containerTag); - }); + updateContainer(element, root, null, callback); + return getPublicRootInstance(root); + }, + unmountComponentAtNode: function(containerTag) { + var root = roots.get(containerTag); + if (root) { + // TODO: Is it safe to reset this now or should I wait since this unmount could be deferred? + updateContainer(null, root, null, function() { + roots.delete(containerTag); + }); + } + }, + createPortal: function(children, containerTag) { + var key = + arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; + return createPortal(children, containerTag, null, key); + }, + __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: { + // Used as a mixin in many createClass-based components + NativeMethodsMixin: NativeMethodsMixin(findNodeHandle, findHostInstance) } -} - -function createPortal$1(children, containerTag) { - var key = - arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; - return createPortal(children, containerTag, null, key); -} - -setBatchingImplementation(batchedUpdates$1); -var roots = new Map(); +}; injectIntoDevTools({ findFiberByHostInstance: getInstanceFromInstance, + getInspectorDataForViewTag: getInspectorDataForViewTag, bundleType: 1, version: ReactVersion, - rendererPackageName: "react-native-renderer", - rendererConfig: { - getInspectorDataForViewTag: getInspectorDataForViewTag, - getInspectorDataForViewAtPoint: getInspectorDataForViewAtPoint.bind( - null, - findNodeHandle - ) - } + rendererPackageName: "react-native-renderer" }); -exports.createPortal = createPortal$1; -exports.dispatchCommand = dispatchCommand; -exports.findHostInstance_DEPRECATED = findHostInstance_DEPRECATED; -exports.findNodeHandle = findNodeHandle; -exports.render = render; -exports.stopSurface = stopSurface; -exports.unmountComponentAtNode = unmountComponentAtNode; +var ReactFabric$2 = Object.freeze({ + default: ReactFabric +}); + +var ReactFabric$3 = (ReactFabric$2 && ReactFabric) || ReactFabric$2; + +// TODO: decide on the top-level export form. +// This is hacky but makes it work with both Rollup and Jest. +var fabric = ReactFabric$3.default || ReactFabric$3; + +module.exports = fabric; })(); } diff --git a/Libraries/Renderer/implementations/ReactFabric-dev.js b/Libraries/Renderer/implementations/ReactFabric-dev.js index 8e2baedcc4efc4..a4cbef3535b812 100644 --- a/Libraries/Renderer/implementations/ReactFabric-dev.js +++ b/Libraries/Renderer/implementations/ReactFabric-dev.js @@ -5,7 +5,6 @@ * LICENSE file in the root directory of this source tree. * * @noflow - * @nolint * @providesModule ReactFabric-dev * @preventMunge * @generated @@ -17,234 +16,253 @@ if (__DEV__) { (function() { "use strict"; -var React = require("react"); require("react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore"); var ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/ReactNativePrivateInterface"); +var React = require("react"); var Scheduler = require("scheduler"); +var checkPropTypes = require("prop-types/checkPropTypes"); var tracing = require("scheduler/tracing"); -var ReactSharedInternals = - React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; // Prevent newer renderers from RTE when used with older react package versions. -// Current owner and dispatcher used to share the same ref, -// but PR #14548 split them out to better support the react-debug-tools package. +/** + * Use invariant() to assert state which your program assumes to be true. + * + * Provide sprintf-style format (only %s is supported) and arguments + * to provide information about what broke and what you were + * expecting. + * + * The invariant message will be stripped in production, but the invariant + * will remain to ensure logic does not differ in production. + */ -if (!ReactSharedInternals.hasOwnProperty("ReactCurrentDispatcher")) { - ReactSharedInternals.ReactCurrentDispatcher = { - current: null - }; -} +/** + * Injectable ordering of event plugins. + */ +var eventPluginOrder = null; +/** + * Injectable mapping from names to event plugin modules. + */ -if (!ReactSharedInternals.hasOwnProperty("ReactCurrentBatchConfig")) { - ReactSharedInternals.ReactCurrentBatchConfig = { - suspense: null - }; -} +var namesToPlugins = {}; +/** + * Recomputes the plugin list using the injected plugins and plugin ordering. + * + * @private + */ +function recomputePluginOrdering() { + if (!eventPluginOrder) { + // Wait until an `eventPluginOrder` is injected. + return; + } -// by calls to these methods by a Babel plugin. -// -// In PROD (or in packages without access to React internals), -// they are left as they are instead. + for (var pluginName in namesToPlugins) { + var pluginModule = namesToPlugins[pluginName]; + var pluginIndex = eventPluginOrder.indexOf(pluginName); -function warn(format) { - { - for ( - var _len = arguments.length, - args = new Array(_len > 1 ? _len - 1 : 0), - _key = 1; - _key < _len; - _key++ - ) { - args[_key - 1] = arguments[_key]; + if (!(pluginIndex > -1)) { + throw Error( + "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + + pluginName + + "`." + ); } - printWarning("warn", format, args); - } -} -function error(format) { - { - for ( - var _len2 = arguments.length, - args = new Array(_len2 > 1 ? _len2 - 1 : 0), - _key2 = 1; - _key2 < _len2; - _key2++ - ) { - args[_key2 - 1] = arguments[_key2]; + if (plugins[pluginIndex]) { + continue; } - printWarning("error", format, args); - } -} - -function printWarning(level, format, args) { - // When changing this logic, you might want to also - // update consoleWithStackDev.www.js as well. - { - var hasExistingStack = - args.length > 0 && - typeof args[args.length - 1] === "string" && - args[args.length - 1].indexOf("\n in") === 0; + if (!pluginModule.extractEvents) { + throw Error( + "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + + pluginName + + "` does not." + ); + } - if (!hasExistingStack) { - var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; - var stack = ReactDebugCurrentFrame.getStackAddendum(); + plugins[pluginIndex] = pluginModule; + var publishedEvents = pluginModule.eventTypes; - if (stack !== "") { - format += "%s"; - args = args.concat([stack]); + for (var eventName in publishedEvents) { + if ( + !publishEventForPlugin( + publishedEvents[eventName], + pluginModule, + eventName + ) + ) { + throw Error( + "EventPluginRegistry: Failed to publish event `" + + eventName + + "` for plugin `" + + pluginName + + "`." + ); } } - - var argsWithFormat = args.map(function(item) { - return "" + item; - }); // Careful: RN currently depends on this prefix - - argsWithFormat.unshift("Warning: " + format); // We intentionally don't use spread (or .apply) directly because it - // breaks IE9: https://github.com/facebook/react/issues/13610 - // eslint-disable-next-line react-internal/no-production-logging - - Function.prototype.apply.call(console[level], console, argsWithFormat); - - try { - // --- Welcome to debugging React --- - // This error was thrown as a convenience so that you can use this stack - // to find the callsite that caused this warning to fire. - var argIndex = 0; - var message = - "Warning: " + - format.replace(/%s/g, function() { - return args[argIndex++]; - }); - throw new Error(message); - } catch (x) {} } } +/** + * Publishes an event so that it can be dispatched by the supplied plugin. + * + * @param {object} dispatchConfig Dispatch configuration for the event. + * @param {object} PluginModule Plugin publishing the event. + * @return {boolean} True if the event was successfully published. + * @private + */ -var FunctionComponent = 0; -var ClassComponent = 1; -var IndeterminateComponent = 2; // Before we know whether it is function or class - -var HostRoot = 3; // Root of a host tree. Could be nested inside another node. - -var HostPortal = 4; // A subtree. Could be an entry point to a different renderer. - -var HostComponent = 5; -var HostText = 6; -var Fragment = 7; -var Mode = 8; -var ContextConsumer = 9; -var ContextProvider = 10; -var ForwardRef = 11; -var Profiler = 12; -var SuspenseComponent = 13; -var MemoComponent = 14; -var SimpleMemoComponent = 15; -var LazyComponent = 16; -var IncompleteClassComponent = 17; -var DehydratedFragment = 18; -var SuspenseListComponent = 19; -var FundamentalComponent = 20; -var ScopeComponent = 21; -var Block = 22; +function publishEventForPlugin(dispatchConfig, pluginModule, eventName) { + if (!!eventNameDispatchConfigs.hasOwnProperty(eventName)) { + throw Error( + "EventPluginHub: More than one plugin attempted to publish the same event name, `" + + eventName + + "`." + ); + } -function getParent(inst) { - do { - inst = inst.return; // TODO: If this is a HostRoot we might want to bail out. - // That is depending on if we want nested subtrees (layers) to bubble - // events to their parent. We could also go through parentNode on the - // host node but that wouldn't work for React Native and doesn't let us - // do the portal feature. - } while (inst && inst.tag !== HostComponent); + eventNameDispatchConfigs[eventName] = dispatchConfig; + var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; - if (inst) { - return inst; + if (phasedRegistrationNames) { + for (var phaseName in phasedRegistrationNames) { + if (phasedRegistrationNames.hasOwnProperty(phaseName)) { + var phasedRegistrationName = phasedRegistrationNames[phaseName]; + publishRegistrationName( + phasedRegistrationName, + pluginModule, + eventName + ); + } + } + return true; + } else if (dispatchConfig.registrationName) { + publishRegistrationName( + dispatchConfig.registrationName, + pluginModule, + eventName + ); + return true; } - return null; + return false; } /** - * Return the lowest common ancestor of A and B, or null if they are in - * different trees. + * Publishes a registration name that is used to identify dispatched events. + * + * @param {string} registrationName Registration name to add. + * @param {object} PluginModule Plugin publishing the event. + * @private */ -function getLowestCommonAncestor(instA, instB) { - var depthA = 0; - - for (var tempA = instA; tempA; tempA = getParent(tempA)) { - depthA++; +function publishRegistrationName(registrationName, pluginModule, eventName) { + if (!!registrationNameModules[registrationName]) { + throw Error( + "EventPluginHub: More than one plugin attempted to publish the same registration name, `" + + registrationName + + "`." + ); } - var depthB = 0; - - for (var tempB = instB; tempB; tempB = getParent(tempB)) { - depthB++; - } // If A is deeper, crawl up. - - while (depthA - depthB > 0) { - instA = getParent(instA); - depthA--; - } // If B is deeper, crawl up. - - while (depthB - depthA > 0) { - instB = getParent(instB); - depthB--; - } // Walk in lockstep until we find a match. - - var depth = depthA; - - while (depth--) { - if (instA === instB || instA === instB.alternate) { - return instA; - } + registrationNameModules[registrationName] = pluginModule; + registrationNameDependencies[registrationName] = + pluginModule.eventTypes[eventName].dependencies; - instA = getParent(instA); - instB = getParent(instB); + { + var lowerCasedName = registrationName.toLowerCase(); } - - return null; } /** - * Return if A is an ancestor of B. + * Registers plugins so that they can extract and dispatch events. + * + * @see {EventPluginHub} */ -function isAncestor(instA, instB) { - while (instB) { - if (instA === instB || instA === instB.alternate) { - return true; - } - - instB = getParent(instB); - } +/** + * Ordered list of injected plugins. + */ - return false; -} +var plugins = []; /** - * Return the parent instance of the passed-in instance. + * Mapping from event name to dispatch config */ -function getParentInstance(inst) { - return getParent(inst); -} +var eventNameDispatchConfigs = {}; /** - * Simulates the traversal of a two-phase, capture/bubble event dispatch. + * Mapping from registration name to plugin module */ -function traverseTwoPhase(inst, fn, arg) { - var path = []; +var registrationNameModules = {}; +/** + * Mapping from registration name to event name + */ - while (inst) { - path.push(inst); - inst = getParent(inst); - } +var registrationNameDependencies = {}; +/** + * Mapping from lowercase registration names to the properly cased version, + * used to warn in the case of missing event handlers. Available + * only in true. + * @type {Object} + */ - var i; +// Trust the developer to only use possibleRegistrationNames in true - for (i = path.length; i-- > 0; ) { - fn(path[i], "captured", arg); - } +/** + * Injects an ordering of plugins (by plugin name). This allows the ordering + * to be decoupled from injection of the actual plugins so that ordering is + * always deterministic regardless of packaging, on-the-fly injection, etc. + * + * @param {array} InjectedEventPluginOrder + * @internal + * @see {EventPluginHub.injection.injectEventPluginOrder} + */ - for (i = 0; i < path.length; i++) { - fn(path[i], "bubbled", arg); +function injectEventPluginOrder(injectedEventPluginOrder) { + if (!!eventPluginOrder) { + throw Error( + "EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React." + ); + } // Clone the ordering so it cannot be dynamically mutated. + + eventPluginOrder = Array.prototype.slice.call(injectedEventPluginOrder); + recomputePluginOrdering(); +} +/** + * Injects plugins to be used by `EventPluginHub`. The plugin names must be + * in the ordering injected by `injectEventPluginOrder`. + * + * Plugins can be injected as part of page initialization or on-the-fly. + * + * @param {object} injectedNamesToPlugins Map from names to plugin modules. + * @internal + * @see {EventPluginHub.injection.injectEventPluginsByName} + */ + +function injectEventPluginsByName(injectedNamesToPlugins) { + var isOrderingDirty = false; + + for (var pluginName in injectedNamesToPlugins) { + if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) { + continue; + } + + var pluginModule = injectedNamesToPlugins[pluginName]; + + if ( + !namesToPlugins.hasOwnProperty(pluginName) || + namesToPlugins[pluginName] !== pluginModule + ) { + if (!!namesToPlugins[pluginName]) { + throw Error( + "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + + pluginName + + "`." + ); + } + + namesToPlugins[pluginName] = pluginModule; + isOrderingDirty = true; + } + } + if (isOrderingDirty) { + recomputePluginOrdering(); } } @@ -260,7 +278,6 @@ var invokeGuardedCallbackImpl = function( f ) { var funcArgs = Array.prototype.slice.call(arguments, 3); - try { func.apply(context, funcArgs); } catch (error) { @@ -469,7 +486,6 @@ var reporter = { * @param {*} context The context to use when calling the function * @param {...*} args Arguments for function */ - function invokeGuardedCallback(name, func, context, a, b, c, d, e, f) { hasError = false; caughtError = null; @@ -485,7 +501,6 @@ function invokeGuardedCallback(name, func, context, a, b, c, d, e, f) { * @param {*} context The context to use when calling the function * @param {...*} args Arguments for function */ - function invokeGuardedCallbackAndCatchFirstError( name, func, @@ -512,7 +527,6 @@ function invokeGuardedCallbackAndCatchFirstError( * During execution of guarded functions we will capture the first error which * we will rethrow to be handled by the top level error handler. */ - function rethrowCaughtError() { if (hasRethrowError) { var error = rethrowError; @@ -539,6 +553,70 @@ function clearCaughtError() { } } +/** + * Similar to invariant but only logs a warning if the condition is not met. + * This can be used to log issues in development environments in critical + * paths. Removing the logging code for production environments will keep the + * same logic and follow the same code paths. + */ +var warningWithoutStack = function() {}; + +{ + warningWithoutStack = function(condition, format) { + for ( + var _len = arguments.length, + args = new Array(_len > 2 ? _len - 2 : 0), + _key = 2; + _key < _len; + _key++ + ) { + args[_key - 2] = arguments[_key]; + } + + if (format === undefined) { + throw new Error( + "`warningWithoutStack(condition, format, ...args)` requires a warning " + + "message argument" + ); + } + if (args.length > 8) { + // Check before the condition to catch violations early. + throw new Error( + "warningWithoutStack() currently supports at most 8 arguments." + ); + } + + if (condition) { + return; + } + + if (typeof console !== "undefined") { + var argsWithFormat = args.map(function(item) { + return "" + item; + }); + argsWithFormat.unshift("Warning: " + format); // We intentionally don't use spread (or .apply) directly because it + // breaks IE9: https://github.com/facebook/react/issues/13610 + + Function.prototype.apply.call(console.error, console, argsWithFormat); + } + + try { + // --- Welcome to debugging React --- + // This error was thrown as a convenience so that you can use this stack + // to find the callsite that caused this warning to fire. + var argIndex = 0; + var message = + "Warning: " + + format.replace(/%s/g, function() { + return args[argIndex++]; + }); + throw new Error(message); + } catch (x) {} + }; +} + +var warningWithoutStack$1 = warningWithoutStack; + var getFiberCurrentPropsFromNode = null; var getInstanceFromNode = null; var getNodeFromInstance = null; @@ -550,14 +628,14 @@ function setComponentTree( getFiberCurrentPropsFromNode = getFiberCurrentPropsFromNodeImpl; getInstanceFromNode = getInstanceFromNodeImpl; getNodeFromInstance = getNodeFromInstanceImpl; - { - if (!getNodeFromInstance || !getInstanceFromNode) { - error( - "EventPluginUtils.setComponentTree(...): Injected " + - "module is missing getNodeFromInstance or getInstanceFromNode." - ); - } + !(getNodeFromInstance && getInstanceFromNode) + ? warningWithoutStack$1( + false, + "EventPluginUtils.setComponentTree(...): Injected " + + "module is missing getNodeFromInstance or getInstanceFromNode." + ) + : void 0; } } var validateEventDispatches; @@ -570,18 +648,17 @@ var validateEventDispatches; var listenersLen = listenersIsArr ? dispatchListeners.length : dispatchListeners - ? 1 - : 0; + ? 1 + : 0; var instancesIsArr = Array.isArray(dispatchInstances); var instancesLen = instancesIsArr ? dispatchInstances.length : dispatchInstances - ? 1 - : 0; - - if (instancesIsArr !== listenersIsArr || instancesLen !== listenersLen) { - error("EventPluginUtils: Invalid `event`."); - } + ? 1 + : 0; + !(instancesIsArr === listenersIsArr && instancesLen === listenersLen) + ? warningWithoutStack$1(false, "EventPluginUtils: Invalid `event`.") + : void 0; }; } /** @@ -590,7 +667,6 @@ var validateEventDispatches; * @param {function} listener Application-level callback * @param {*} inst Internal component instance */ - function executeDispatch(event, listener, inst) { var type = event.type || "unknown-event"; event.currentTarget = getNodeFromInstance(inst); @@ -677,7 +753,6 @@ function executeDispatchesInOrderStopAtTrue(event) { * * @return {*} The return value of executing the single dispatch. */ - function executeDirectDispatch(event) { { validateEventDispatches(event); @@ -703,82 +778,10 @@ function executeDirectDispatch(event) { * @param {SyntheticEvent} event * @return {boolean} True iff number of dispatches accumulated is greater than 0. */ - function hasDispatches(event) { return !!event._dispatchListeners; } -function isInteractive(tag) { - return ( - tag === "button" || - tag === "input" || - tag === "select" || - tag === "textarea" - ); -} - -function shouldPreventMouseEvent(name, type, props) { - switch (name) { - case "onClick": - case "onClickCapture": - case "onDoubleClick": - case "onDoubleClickCapture": - case "onMouseDown": - case "onMouseDownCapture": - case "onMouseMove": - case "onMouseMoveCapture": - case "onMouseUp": - case "onMouseUpCapture": - case "onMouseEnter": - return !!(props.disabled && isInteractive(type)); - - default: - return false; - } -} -/** - * @param {object} inst The instance, which is the source of events. - * @param {string} registrationName Name of listener (e.g. `onClick`). - * @return {?function} The stored callback. - */ - -function getListener(inst, registrationName) { - var listener; // TODO: shouldPreventMouseEvent is DOM-specific and definitely should not - // live here; needs to be moved to a better place soon - - var stateNode = inst.stateNode; - - if (!stateNode) { - // Work in progress (ex: onload events in incremental mode). - return null; - } - - var props = getFiberCurrentPropsFromNode(stateNode); - - if (!props) { - // Work in progress. - return null; - } - - listener = props[registrationName]; - - if (shouldPreventMouseEvent(registrationName, inst.type, props)) { - return null; - } - - if (!(!listener || typeof listener === "function")) { - throw Error( - "Expected `" + - registrationName + - "` listener to be a function, instead got a value of `" + - typeof listener + - "` type." - ); - } - - return listener; -} - /** * Accumulates items that must not be null or undefined into the first one. This * is used to conserve memory by avoiding array allocations, and thus sacrifices @@ -809,7 +812,6 @@ function accumulateInto(current, next) { current.push.apply(current, next); return current; } - current.push(next); return current; } @@ -840,807 +842,1120 @@ function forEachAccumulated(arr, cb, scope) { } /** - * Some event types have a notion of different registration names for different - * "phases" of propagation. This finds listeners by a given phase. - */ -function listenerAtPhase(inst, event, propagationPhase) { - var registrationName = - event.dispatchConfig.phasedRegistrationNames[propagationPhase]; - return getListener(inst, registrationName); -} -/** - * A small set of propagation patterns, each of which will accept a small amount - * of information, and generate a set of "dispatch ready event objects" - which - * are sets of events that have already been annotated with a set of dispatched - * listener functions/ids. The API is designed this way to discourage these - * propagation strategies from actually executing the dispatches, since we - * always want to collect the entire set of dispatches before executing even a - * single one. + * Internal queue of events that have accumulated their dispatches and are + * waiting to have their dispatches executed. */ +var eventQueue = null; /** - * Tags a `SyntheticEvent` with dispatched listeners. Creating this function - * here, allows us to not have to bind or create functions for each event. - * Mutating the event's members allows us to not have to create a wrapping - * "dispatch" object that pairs the event with the listener. + * Dispatches an event and releases it back into the pool, unless persistent. + * + * @param {?object} event Synthetic event to be dispatched. + * @private */ +var executeDispatchesAndRelease = function(event) { + if (event) { + executeDispatchesInOrder(event); -function accumulateDirectionalDispatches(inst, phase, event) { - { - if (!inst) { - error("Dispatching inst must not be null"); + if (!event.isPersistent()) { + event.constructor.release(event); } } +}; +var executeDispatchesAndReleaseTopLevel = function(e) { + return executeDispatchesAndRelease(e); +}; - var listener = listenerAtPhase(inst, event, phase); +function runEventsInBatch(events) { + if (events !== null) { + eventQueue = accumulateInto(eventQueue, events); + } // Set `eventQueue` to null before processing it so that we can tell if more + // events get enqueued while processing. - if (listener) { - event._dispatchListeners = accumulateInto( - event._dispatchListeners, - listener - ); - event._dispatchInstances = accumulateInto(event._dispatchInstances, inst); + var processingEventQueue = eventQueue; + eventQueue = null; + + if (!processingEventQueue) { + return; } -} -/** - * Collect dispatches (must be entirely collected before dispatching - see unit - * tests). Lazily allocate the array to conserve memory. We must loop through - * each event and perform the traversal for each one. We cannot perform a - * single traversal for the entire collection of events because each event may - * have a different target. - */ -function accumulateTwoPhaseDispatchesSingle(event) { - if (event && event.dispatchConfig.phasedRegistrationNames) { - traverseTwoPhase(event._targetInst, accumulateDirectionalDispatches, event); - } + forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseTopLevel); + + if (!!eventQueue) { + throw Error( + "processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented." + ); + } // This would be a good time to rethrow if any of the event handlers threw. + + rethrowCaughtError(); } -/** - * Same as `accumulateTwoPhaseDispatchesSingle`, but skips over the targetID. - */ -function accumulateTwoPhaseDispatchesSingleSkipTarget(event) { - if (event && event.dispatchConfig.phasedRegistrationNames) { - var targetInst = event._targetInst; - var parentInst = targetInst ? getParentInstance(targetInst) : null; - traverseTwoPhase(parentInst, accumulateDirectionalDispatches, event); +function isInteractive(tag) { + return ( + tag === "button" || + tag === "input" || + tag === "select" || + tag === "textarea" + ); +} + +function shouldPreventMouseEvent(name, type, props) { + switch (name) { + case "onClick": + case "onClickCapture": + case "onDoubleClick": + case "onDoubleClickCapture": + case "onMouseDown": + case "onMouseDownCapture": + case "onMouseMove": + case "onMouseMoveCapture": + case "onMouseUp": + case "onMouseUpCapture": + return !!(props.disabled && isInteractive(type)); + default: + return false; } } /** - * Accumulates without regard to direction, does not look for phased - * registration names. Same as `accumulateDirectDispatchesSingle` but without - * requiring that the `dispatchMarker` be the same as the dispatched ID. + * This is a unified interface for event plugins to be installed and configured. + * + * Event plugins can implement the following properties: + * + * `extractEvents` {function(string, DOMEventTarget, string, object): *} + * Required. When a top-level event is fired, this method is expected to + * extract synthetic events that will in turn be queued and dispatched. + * + * `eventTypes` {object} + * Optional, plugins that fire events must publish a mapping of registration + * names that are used to register listeners. Values of this mapping must + * be objects that contain `registrationName` or `phasedRegistrationNames`. + * + * `executeDispatch` {function(object, function, string)} + * Optional, allows plugins to override how an event gets dispatched. By + * default, the listener is simply invoked. + * + * Each plugin that is injected into `EventsPluginHub` is immediately operable. + * + * @public */ -function accumulateDispatches(inst, ignoredDirection, event) { - if (inst && event && event.dispatchConfig.registrationName) { - var registrationName = event.dispatchConfig.registrationName; - var listener = getListener(inst, registrationName); +/** + * Methods for injecting dependencies. + */ +var injection = { + /** + * @param {array} InjectedEventPluginOrder + * @public + */ + injectEventPluginOrder: injectEventPluginOrder, - if (listener) { - event._dispatchListeners = accumulateInto( - event._dispatchListeners, - listener - ); - event._dispatchInstances = accumulateInto(event._dispatchInstances, inst); - } - } -} + /** + * @param {object} injectedNamesToPlugins Map from names to plugin modules. + */ + injectEventPluginsByName: injectEventPluginsByName +}; /** - * Accumulates dispatches on an `SyntheticEvent`, but only for the - * `dispatchMarker`. - * @param {SyntheticEvent} event + * @param {object} inst The instance, which is the source of events. + * @param {string} registrationName Name of listener (e.g. `onClick`). + * @return {?function} The stored callback. */ -function accumulateDirectDispatchesSingle(event) { - if (event && event.dispatchConfig.registrationName) { - accumulateDispatches(event._targetInst, null, event); +function getListener(inst, registrationName) { + var listener; // TODO: shouldPreventMouseEvent is DOM-specific and definitely should not + // live here; needs to be moved to a better place soon + + var stateNode = inst.stateNode; + + if (!stateNode) { + // Work in progress (ex: onload events in incremental mode). + return null; } -} -function accumulateTwoPhaseDispatches(events) { - forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle); -} -function accumulateTwoPhaseDispatchesSkipTarget(events) { - forEachAccumulated(events, accumulateTwoPhaseDispatchesSingleSkipTarget); -} -function accumulateDirectDispatches(events) { - forEachAccumulated(events, accumulateDirectDispatchesSingle); -} + var props = getFiberCurrentPropsFromNode(stateNode); -var EVENT_POOL_SIZE = 10; -/** - * @interface Event - * @see http://www.w3.org/TR/DOM-Level-3-Events/ - */ + if (!props) { + // Work in progress. + return null; + } -var EventInterface = { - type: null, - target: null, - // currentTarget is set when dispatching; no use in copying it here - currentTarget: function() { + listener = props[registrationName]; + + if (shouldPreventMouseEvent(registrationName, inst.type, props)) { return null; - }, - eventPhase: null, - bubbles: null, - cancelable: null, - timeStamp: function(event) { - return event.timeStamp || Date.now(); - }, - defaultPrevented: null, - isTrusted: null -}; + } -function functionThatReturnsTrue() { - return true; -} + if (!(!listener || typeof listener === "function")) { + throw Error( + "Expected `" + + registrationName + + "` listener to be a function, instead got a value of `" + + typeof listener + + "` type." + ); + } -function functionThatReturnsFalse() { - return false; + return listener; } /** - * Synthetic events are dispatched by event plugins, typically in response to a - * top-level event delegation handler. - * - * These systems should generally use pooling to reduce the frequency of garbage - * collection. The system should check `isPersistent` to determine whether the - * event should be released into the pool after being dispatched. Users that - * need a persisted event should invoke `persist`. - * - * Synthetic events (and subclasses) implement the DOM Level 3 Events API by - * normalizing browser quirks. Subclasses do not necessarily have to implement a - * DOM interface; custom application-specific events can also subclass this. + * Allows registered plugins an opportunity to extract events from top-level + * native browser events. * - * @param {object} dispatchConfig Configuration used to dispatch this event. - * @param {*} targetInst Marker identifying the event target. - * @param {object} nativeEvent Native browser event. - * @param {DOMEventTarget} nativeEventTarget Target node. + * @return {*} An accumulation of synthetic events. + * @internal */ - -function SyntheticEvent( - dispatchConfig, +function extractPluginEvents( + topLevelType, targetInst, nativeEvent, - nativeEventTarget + nativeEventTarget, + eventSystemFlags ) { - { - // these have a getter/setter for warnings - delete this.nativeEvent; - delete this.preventDefault; - delete this.stopPropagation; - delete this.isDefaultPrevented; - delete this.isPropagationStopped; - } - - this.dispatchConfig = dispatchConfig; - this._targetInst = targetInst; - this.nativeEvent = nativeEvent; - var Interface = this.constructor.Interface; - - for (var propName in Interface) { - if (!Interface.hasOwnProperty(propName)) { - continue; - } + var events = null; - { - delete this[propName]; // this has a getter/setter for warnings - } + for (var i = 0; i < plugins.length; i++) { + // Not every plugin in the ordering may be loaded at runtime. + var possiblePlugin = plugins[i]; - var normalize = Interface[propName]; + if (possiblePlugin) { + var extractedEvents = possiblePlugin.extractEvents( + topLevelType, + targetInst, + nativeEvent, + nativeEventTarget, + eventSystemFlags + ); - if (normalize) { - this[propName] = normalize(nativeEvent); - } else { - if (propName === "target") { - this.target = nativeEventTarget; - } else { - this[propName] = nativeEvent[propName]; + if (extractedEvents) { + events = accumulateInto(events, extractedEvents); } } } + return events; +} - var defaultPrevented = - nativeEvent.defaultPrevented != null - ? nativeEvent.defaultPrevented - : nativeEvent.returnValue === false; - - if (defaultPrevented) { - this.isDefaultPrevented = functionThatReturnsTrue; - } else { - this.isDefaultPrevented = functionThatReturnsFalse; - } - - this.isPropagationStopped = functionThatReturnsFalse; - return this; +function runExtractedPluginEventsInBatch( + topLevelType, + targetInst, + nativeEvent, + nativeEventTarget, + eventSystemFlags +) { + var events = extractPluginEvents( + topLevelType, + targetInst, + nativeEvent, + nativeEventTarget, + eventSystemFlags + ); + runEventsInBatch(events); } -Object.assign(SyntheticEvent.prototype, { - preventDefault: function() { - this.defaultPrevented = true; - var event = this.nativeEvent; +var FunctionComponent = 0; +var ClassComponent = 1; +var IndeterminateComponent = 2; // Before we know whether it is function or class - if (!event) { - return; - } +var HostRoot = 3; // Root of a host tree. Could be nested inside another node. - if (event.preventDefault) { - event.preventDefault(); - } else if (typeof event.returnValue !== "unknown") { - event.returnValue = false; - } +var HostPortal = 4; // A subtree. Could be an entry point to a different renderer. - this.isDefaultPrevented = functionThatReturnsTrue; - }, - stopPropagation: function() { - var event = this.nativeEvent; +var HostComponent = 5; +var HostText = 6; +var Fragment = 7; +var Mode = 8; +var ContextConsumer = 9; +var ContextProvider = 10; +var ForwardRef = 11; +var Profiler = 12; +var SuspenseComponent = 13; +var MemoComponent = 14; +var SimpleMemoComponent = 15; +var LazyComponent = 16; +var IncompleteClassComponent = 17; +var DehydratedFragment = 18; +var SuspenseListComponent = 19; +var FundamentalComponent = 20; +var ScopeComponent = 21; - if (!event) { - return; - } +function getParent(inst) { + do { + inst = inst.return; // TODO: If this is a HostRoot we might want to bail out. + // That is depending on if we want nested subtrees (layers) to bubble + // events to their parent. We could also go through parentNode on the + // host node but that wouldn't work for React Native and doesn't let us + // do the portal feature. + } while (inst && inst.tag !== HostComponent); - if (event.stopPropagation) { - event.stopPropagation(); - } else if (typeof event.cancelBubble !== "unknown") { - // The ChangeEventPlugin registers a "propertychange" event for - // IE. This event does not support bubbling or cancelling, and - // any references to cancelBubble throw "Member not found". A - // typeof check of "unknown" circumvents this issue (and is also - // IE specific). - event.cancelBubble = true; - } + if (inst) { + return inst; + } - this.isPropagationStopped = functionThatReturnsTrue; - }, + return null; +} +/** + * Return the lowest common ancestor of A and B, or null if they are in + * different trees. + */ - /** - * We release all dispatched `SyntheticEvent`s after each event loop, adding - * them back into the pool. This allows a way to hold onto a reference that - * won't be added back into the pool. - */ - persist: function() { - this.isPersistent = functionThatReturnsTrue; - }, +function getLowestCommonAncestor(instA, instB) { + var depthA = 0; - /** - * Checks if this event should be released back into the pool. - * - * @return {boolean} True if this should not be released, false otherwise. - */ - isPersistent: functionThatReturnsFalse, + for (var tempA = instA; tempA; tempA = getParent(tempA)) { + depthA++; + } - /** - * `PooledClass` looks for `destructor` on each instance it releases. - */ - destructor: function() { - var Interface = this.constructor.Interface; + var depthB = 0; - for (var propName in Interface) { - { - Object.defineProperty( - this, - propName, - getPooledWarningPropertyDefinition(propName, Interface[propName]) - ); - } - } + for (var tempB = instB; tempB; tempB = getParent(tempB)) { + depthB++; + } // If A is deeper, crawl up. - this.dispatchConfig = null; - this._targetInst = null; - this.nativeEvent = null; - this.isDefaultPrevented = functionThatReturnsFalse; - this.isPropagationStopped = functionThatReturnsFalse; - this._dispatchListeners = null; - this._dispatchInstances = null; + while (depthA - depthB > 0) { + instA = getParent(instA); + depthA--; + } // If B is deeper, crawl up. - { - Object.defineProperty( - this, - "nativeEvent", - getPooledWarningPropertyDefinition("nativeEvent", null) - ); - Object.defineProperty( - this, - "isDefaultPrevented", - getPooledWarningPropertyDefinition( - "isDefaultPrevented", - functionThatReturnsFalse - ) - ); - Object.defineProperty( - this, - "isPropagationStopped", - getPooledWarningPropertyDefinition( - "isPropagationStopped", - functionThatReturnsFalse - ) - ); - Object.defineProperty( - this, - "preventDefault", - getPooledWarningPropertyDefinition("preventDefault", function() {}) - ); - Object.defineProperty( - this, - "stopPropagation", - getPooledWarningPropertyDefinition("stopPropagation", function() {}) - ); + while (depthB - depthA > 0) { + instB = getParent(instB); + depthB--; + } // Walk in lockstep until we find a match. + + var depth = depthA; + + while (depth--) { + if (instA === instB || instA === instB.alternate) { + return instA; } + + instA = getParent(instA); + instB = getParent(instB); } -}); -SyntheticEvent.Interface = EventInterface; + + return null; +} /** - * Helper to reduce boilerplate when creating subclasses. + * Return if A is an ancestor of B. */ -SyntheticEvent.extend = function(Interface) { - var Super = this; - - var E = function() {}; - - E.prototype = Super.prototype; - var prototype = new E(); +function isAncestor(instA, instB) { + while (instB) { + if (instA === instB || instA === instB.alternate) { + return true; + } - function Class() { - return Super.apply(this, arguments); + instB = getParent(instB); } - Object.assign(prototype, Class.prototype); - Class.prototype = prototype; - Class.prototype.constructor = Class; - Class.Interface = Object.assign({}, Super.Interface, Interface); - Class.extend = Super.extend; - addEventPoolingTo(Class); - return Class; -}; + return false; +} +/** + * Return the parent instance of the passed-in instance. + */ -addEventPoolingTo(SyntheticEvent); +function getParentInstance(inst) { + return getParent(inst); +} /** - * Helper to nullify syntheticEvent instance properties when destructing - * - * @param {String} propName - * @param {?object} getVal - * @return {object} defineProperty object + * Simulates the traversal of a two-phase, capture/bubble event dispatch. */ -function getPooledWarningPropertyDefinition(propName, getVal) { - var isFunction = typeof getVal === "function"; - return { - configurable: true, - set: set, - get: get - }; +function traverseTwoPhase(inst, fn, arg) { + var path = []; - function set(val) { - var action = isFunction ? "setting the method" : "setting the property"; - warn(action, "This is effectively a no-op"); - return val; + while (inst) { + path.push(inst); + inst = getParent(inst); } - function get() { - var action = isFunction ? "accessing the method" : "accessing the property"; - var result = isFunction - ? "This is a no-op function" - : "This is set to null"; - warn(action, result); - return getVal; - } + var i; - function warn(action, result) { - { - error( - "This synthetic event is reused for performance reasons. If you're seeing this, " + - "you're %s `%s` on a released/nullified synthetic event. %s. " + - "If you must keep the original synthetic event around, use event.persist(). " + - "See https://fb.me/react-event-pooling for more information.", - action, - propName, - result - ); - } + for (i = path.length; i-- > 0; ) { + fn(path[i], "captured", arg); } -} - -function getPooledEvent(dispatchConfig, targetInst, nativeEvent, nativeInst) { - var EventConstructor = this; - if (EventConstructor.eventPool.length) { - var instance = EventConstructor.eventPool.pop(); - EventConstructor.call( - instance, - dispatchConfig, - targetInst, - nativeEvent, - nativeInst - ); - return instance; + for (i = 0; i < path.length; i++) { + fn(path[i], "bubbled", arg); } - - return new EventConstructor( - dispatchConfig, - targetInst, - nativeEvent, - nativeInst - ); } +/** + * Traverses the ID hierarchy and invokes the supplied `cb` on any IDs that + * should would receive a `mouseEnter` or `mouseLeave` event. + * + * Does not invoke the callback on the nearest common ancestor because nothing + * "entered" or "left" that element. + */ -function releasePooledEvent(event) { - var EventConstructor = this; - - if (!(event instanceof EventConstructor)) { - throw Error( - "Trying to release an event instance into a pool of a different type." - ); +/** + * Some event types have a notion of different registration names for different + * "phases" of propagation. This finds listeners by a given phase. + */ +function listenerAtPhase(inst, event, propagationPhase) { + var registrationName = + event.dispatchConfig.phasedRegistrationNames[propagationPhase]; + return getListener(inst, registrationName); +} +/** + * A small set of propagation patterns, each of which will accept a small amount + * of information, and generate a set of "dispatch ready event objects" - which + * are sets of events that have already been annotated with a set of dispatched + * listener functions/ids. The API is designed this way to discourage these + * propagation strategies from actually executing the dispatches, since we + * always want to collect the entire set of dispatches before executing even a + * single one. + */ + +/** + * Tags a `SyntheticEvent` with dispatched listeners. Creating this function + * here, allows us to not have to bind or create functions for each event. + * Mutating the event's members allows us to not have to create a wrapping + * "dispatch" object that pairs the event with the listener. + */ +function accumulateDirectionalDispatches(inst, phase, event) { + { + !inst + ? warningWithoutStack$1(false, "Dispatching inst must not be null") + : void 0; } - event.destructor(); + var listener = listenerAtPhase(inst, event, phase); - if (EventConstructor.eventPool.length < EVENT_POOL_SIZE) { - EventConstructor.eventPool.push(event); + if (listener) { + event._dispatchListeners = accumulateInto( + event._dispatchListeners, + listener + ); + event._dispatchInstances = accumulateInto(event._dispatchInstances, inst); } } - -function addEventPoolingTo(EventConstructor) { - EventConstructor.eventPool = []; - EventConstructor.getPooled = getPooledEvent; - EventConstructor.release = releasePooledEvent; +/** + * Collect dispatches (must be entirely collected before dispatching - see unit + * tests). Lazily allocate the array to conserve memory. We must loop through + * each event and perform the traversal for each one. We cannot perform a + * single traversal for the entire collection of events because each event may + * have a different target. + */ +function accumulateTwoPhaseDispatchesSingle(event) { + if (event && event.dispatchConfig.phasedRegistrationNames) { + traverseTwoPhase(event._targetInst, accumulateDirectionalDispatches, event); + } } - /** - * `touchHistory` isn't actually on the native event, but putting it in the - * interface will ensure that it is cleaned up when pooled/destroyed. The - * `ResponderEventPlugin` will populate it appropriately. + * Same as `accumulateTwoPhaseDispatchesSingle`, but skips over the targetID. */ -var ResponderSyntheticEvent = SyntheticEvent.extend({ - touchHistory: function(nativeEvent) { - return null; // Actually doesn't even look at the native event. +function accumulateTwoPhaseDispatchesSingleSkipTarget(event) { + if (event && event.dispatchConfig.phasedRegistrationNames) { + var targetInst = event._targetInst; + var parentInst = targetInst ? getParentInstance(targetInst) : null; + traverseTwoPhase(parentInst, accumulateDirectionalDispatches, event); } -}); +} +/** + * Accumulates without regard to direction, does not look for phased + * registration names. Same as `accumulateDirectDispatchesSingle` but without + * requiring that the `dispatchMarker` be the same as the dispatched ID. + */ +function accumulateDispatches(inst, ignoredDirection, event) { + if (inst && event && event.dispatchConfig.registrationName) { + var registrationName = event.dispatchConfig.registrationName; + var listener = getListener(inst, registrationName); + if (listener) { + event._dispatchListeners = accumulateInto( + event._dispatchListeners, + listener + ); + event._dispatchInstances = accumulateInto(event._dispatchInstances, inst); + } + } +} +/** + * Accumulates dispatches on an `SyntheticEvent`, but only for the + * `dispatchMarker`. + * @param {SyntheticEvent} event + */ +function accumulateDirectDispatchesSingle(event) { + if (event && event.dispatchConfig.registrationName) { + accumulateDispatches(event._targetInst, null, event); + } +} -var TOP_TOUCH_START = "topTouchStart"; -var TOP_TOUCH_MOVE = "topTouchMove"; -var TOP_TOUCH_END = "topTouchEnd"; -var TOP_TOUCH_CANCEL = "topTouchCancel"; -var TOP_SCROLL = "topScroll"; -var TOP_SELECTION_CHANGE = "topSelectionChange"; -function isStartish(topLevelType) { - return topLevelType === TOP_TOUCH_START; +function accumulateTwoPhaseDispatches(events) { + forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle); } -function isMoveish(topLevelType) { - return topLevelType === TOP_TOUCH_MOVE; +function accumulateTwoPhaseDispatchesSkipTarget(events) { + forEachAccumulated(events, accumulateTwoPhaseDispatchesSingleSkipTarget); } -function isEndish(topLevelType) { - return topLevelType === TOP_TOUCH_END || topLevelType === TOP_TOUCH_CANCEL; + +function accumulateDirectDispatches(events) { + forEachAccumulated(events, accumulateDirectDispatchesSingle); } -var startDependencies = [TOP_TOUCH_START]; -var moveDependencies = [TOP_TOUCH_MOVE]; -var endDependencies = [TOP_TOUCH_CANCEL, TOP_TOUCH_END]; +/* eslint valid-typeof: 0 */ +var EVENT_POOL_SIZE = 10; /** - * Tracks the position and time of each active touch by `touch.identifier`. We - * should typically only see IDs in the range of 1-20 because IDs get recycled - * when touches end and start again. + * @interface Event + * @see http://www.w3.org/TR/DOM-Level-3-Events/ */ - -var MAX_TOUCH_BANK = 20; -var touchBank = []; -var touchHistory = { - touchBank: touchBank, - numberActiveTouches: 0, - // If there is only one active touch, we remember its location. This prevents - // us having to loop through all of the touches all the time in the most - // common case. - indexOfSingleActiveTouch: -1, - mostRecentTimeStamp: 0 +var EventInterface = { + type: null, + target: null, + // currentTarget is set when dispatching; no use in copying it here + currentTarget: function() { + return null; + }, + eventPhase: null, + bubbles: null, + cancelable: null, + timeStamp: function(event) { + return event.timeStamp || Date.now(); + }, + defaultPrevented: null, + isTrusted: null }; -function timestampForTouch(touch) { - // The legacy internal implementation provides "timeStamp", which has been - // renamed to "timestamp". Let both work for now while we iron it out - // TODO (evv): rename timeStamp to timestamp in internal code - return touch.timeStamp || touch.timestamp; +function functionThatReturnsTrue() { + return true; +} + +function functionThatReturnsFalse() { + return false; } /** - * TODO: Instead of making gestures recompute filtered velocity, we could - * include a built in velocity computation that can be reused globally. + * Synthetic events are dispatched by event plugins, typically in response to a + * top-level event delegation handler. + * + * These systems should generally use pooling to reduce the frequency of garbage + * collection. The system should check `isPersistent` to determine whether the + * event should be released into the pool after being dispatched. Users that + * need a persisted event should invoke `persist`. + * + * Synthetic events (and subclasses) implement the DOM Level 3 Events API by + * normalizing browser quirks. Subclasses do not necessarily have to implement a + * DOM interface; custom application-specific events can also subclass this. + * + * @param {object} dispatchConfig Configuration used to dispatch this event. + * @param {*} targetInst Marker identifying the event target. + * @param {object} nativeEvent Native browser event. + * @param {DOMEventTarget} nativeEventTarget Target node. */ +function SyntheticEvent( + dispatchConfig, + targetInst, + nativeEvent, + nativeEventTarget +) { + { + // these have a getter/setter for warnings + delete this.nativeEvent; + delete this.preventDefault; + delete this.stopPropagation; + delete this.isDefaultPrevented; + delete this.isPropagationStopped; + } -function createTouchRecord(touch) { - return { - touchActive: true, - startPageX: touch.pageX, - startPageY: touch.pageY, - startTimeStamp: timestampForTouch(touch), - currentPageX: touch.pageX, - currentPageY: touch.pageY, - currentTimeStamp: timestampForTouch(touch), - previousPageX: touch.pageX, - previousPageY: touch.pageY, - previousTimeStamp: timestampForTouch(touch) - }; -} + this.dispatchConfig = dispatchConfig; + this._targetInst = targetInst; + this.nativeEvent = nativeEvent; + var Interface = this.constructor.Interface; -function resetTouchRecord(touchRecord, touch) { - touchRecord.touchActive = true; - touchRecord.startPageX = touch.pageX; - touchRecord.startPageY = touch.pageY; - touchRecord.startTimeStamp = timestampForTouch(touch); - touchRecord.currentPageX = touch.pageX; - touchRecord.currentPageY = touch.pageY; - touchRecord.currentTimeStamp = timestampForTouch(touch); - touchRecord.previousPageX = touch.pageX; - touchRecord.previousPageY = touch.pageY; - touchRecord.previousTimeStamp = timestampForTouch(touch); -} + for (var propName in Interface) { + if (!Interface.hasOwnProperty(propName)) { + continue; + } -function getTouchIdentifier(_ref) { - var identifier = _ref.identifier; + { + delete this[propName]; // this has a getter/setter for warnings + } - if (!(identifier != null)) { - throw Error("Touch object is missing identifier."); - } + var normalize = Interface[propName]; - { - if (identifier > MAX_TOUCH_BANK) { - error( - "Touch identifier %s is greater than maximum supported %s which causes " + - "performance issues backfilling array locations for all of the indices.", - identifier, - MAX_TOUCH_BANK - ); + if (normalize) { + this[propName] = normalize(nativeEvent); + } else { + if (propName === "target") { + this.target = nativeEventTarget; + } else { + this[propName] = nativeEvent[propName]; + } } } - return identifier; -} - -function recordTouchStart(touch) { - var identifier = getTouchIdentifier(touch); - var touchRecord = touchBank[identifier]; - - if (touchRecord) { - resetTouchRecord(touchRecord, touch); + var defaultPrevented = + nativeEvent.defaultPrevented != null + ? nativeEvent.defaultPrevented + : nativeEvent.returnValue === false; + if (defaultPrevented) { + this.isDefaultPrevented = functionThatReturnsTrue; } else { - touchBank[identifier] = createTouchRecord(touch); + this.isDefaultPrevented = functionThatReturnsFalse; } - - touchHistory.mostRecentTimeStamp = timestampForTouch(touch); + this.isPropagationStopped = functionThatReturnsFalse; + return this; } -function recordTouchMove(touch) { - var touchRecord = touchBank[getTouchIdentifier(touch)]; +Object.assign(SyntheticEvent.prototype, { + preventDefault: function() { + this.defaultPrevented = true; + var event = this.nativeEvent; + if (!event) { + return; + } - if (touchRecord) { - touchRecord.touchActive = true; - touchRecord.previousPageX = touchRecord.currentPageX; - touchRecord.previousPageY = touchRecord.currentPageY; - touchRecord.previousTimeStamp = touchRecord.currentTimeStamp; - touchRecord.currentPageX = touch.pageX; - touchRecord.currentPageY = touch.pageY; - touchRecord.currentTimeStamp = timestampForTouch(touch); - touchHistory.mostRecentTimeStamp = timestampForTouch(touch); - } else { - { - warn( - "Cannot record touch move without a touch start.\n" + - "Touch Move: %s\n" + - "Touch Bank: %s", - printTouch(touch), - printTouchBank() - ); + if (event.preventDefault) { + event.preventDefault(); + } else if (typeof event.returnValue !== "unknown") { + event.returnValue = false; } - } -} -function recordTouchEnd(touch) { - var touchRecord = touchBank[getTouchIdentifier(touch)]; + this.isDefaultPrevented = functionThatReturnsTrue; + }, + stopPropagation: function() { + var event = this.nativeEvent; - if (touchRecord) { - touchRecord.touchActive = false; - touchRecord.previousPageX = touchRecord.currentPageX; - touchRecord.previousPageY = touchRecord.currentPageY; - touchRecord.previousTimeStamp = touchRecord.currentTimeStamp; - touchRecord.currentPageX = touch.pageX; - touchRecord.currentPageY = touch.pageY; - touchRecord.currentTimeStamp = timestampForTouch(touch); - touchHistory.mostRecentTimeStamp = timestampForTouch(touch); - } else { - { - warn( - "Cannot record touch end without a touch start.\n" + - "Touch End: %s\n" + - "Touch Bank: %s", - printTouch(touch), - printTouchBank() - ); + if (!event) { + return; } - } -} - -function printTouch(touch) { - return JSON.stringify({ - identifier: touch.identifier, - pageX: touch.pageX, - pageY: touch.pageY, - timestamp: timestampForTouch(touch) - }); -} -function printTouchBank() { - var printed = JSON.stringify(touchBank.slice(0, MAX_TOUCH_BANK)); + if (event.stopPropagation) { + event.stopPropagation(); + } else if (typeof event.cancelBubble !== "unknown") { + // The ChangeEventPlugin registers a "propertychange" event for + // IE. This event does not support bubbling or cancelling, and + // any references to cancelBubble throw "Member not found". A + // typeof check of "unknown" circumvents this issue (and is also + // IE specific). + event.cancelBubble = true; + } - if (touchBank.length > MAX_TOUCH_BANK) { - printed += " (original size: " + touchBank.length + ")"; - } + this.isPropagationStopped = functionThatReturnsTrue; + }, - return printed; -} + /** + * We release all dispatched `SyntheticEvent`s after each event loop, adding + * them back into the pool. This allows a way to hold onto a reference that + * won't be added back into the pool. + */ + persist: function() { + this.isPersistent = functionThatReturnsTrue; + }, -var ResponderTouchHistoryStore = { - recordTouchTrack: function(topLevelType, nativeEvent) { - if (isMoveish(topLevelType)) { - nativeEvent.changedTouches.forEach(recordTouchMove); - } else if (isStartish(topLevelType)) { - nativeEvent.changedTouches.forEach(recordTouchStart); - touchHistory.numberActiveTouches = nativeEvent.touches.length; + /** + * Checks if this event should be released back into the pool. + * + * @return {boolean} True if this should not be released, false otherwise. + */ + isPersistent: functionThatReturnsFalse, - if (touchHistory.numberActiveTouches === 1) { - touchHistory.indexOfSingleActiveTouch = - nativeEvent.touches[0].identifier; + /** + * `PooledClass` looks for `destructor` on each instance it releases. + */ + destructor: function() { + var Interface = this.constructor.Interface; + for (var propName in Interface) { + { + Object.defineProperty( + this, + propName, + getPooledWarningPropertyDefinition(propName, Interface[propName]) + ); } - } else if (isEndish(topLevelType)) { - nativeEvent.changedTouches.forEach(recordTouchEnd); - touchHistory.numberActiveTouches = nativeEvent.touches.length; + } + this.dispatchConfig = null; + this._targetInst = null; + this.nativeEvent = null; + this.isDefaultPrevented = functionThatReturnsFalse; + this.isPropagationStopped = functionThatReturnsFalse; + this._dispatchListeners = null; + this._dispatchInstances = null; + { + Object.defineProperty( + this, + "nativeEvent", + getPooledWarningPropertyDefinition("nativeEvent", null) + ); + Object.defineProperty( + this, + "isDefaultPrevented", + getPooledWarningPropertyDefinition( + "isDefaultPrevented", + functionThatReturnsFalse + ) + ); + Object.defineProperty( + this, + "isPropagationStopped", + getPooledWarningPropertyDefinition( + "isPropagationStopped", + functionThatReturnsFalse + ) + ); + Object.defineProperty( + this, + "preventDefault", + getPooledWarningPropertyDefinition("preventDefault", function() {}) + ); + Object.defineProperty( + this, + "stopPropagation", + getPooledWarningPropertyDefinition("stopPropagation", function() {}) + ); + } + } +}); +SyntheticEvent.Interface = EventInterface; +/** + * Helper to reduce boilerplate when creating subclasses. + */ - if (touchHistory.numberActiveTouches === 1) { - for (var i = 0; i < touchBank.length; i++) { - var touchTrackToCheck = touchBank[i]; +SyntheticEvent.extend = function(Interface) { + var Super = this; - if (touchTrackToCheck != null && touchTrackToCheck.touchActive) { - touchHistory.indexOfSingleActiveTouch = i; - break; - } - } + var E = function() {}; + E.prototype = Super.prototype; + var prototype = new E(); - { - var activeRecord = touchBank[touchHistory.indexOfSingleActiveTouch]; + function Class() { + return Super.apply(this, arguments); + } - if (activeRecord == null || !activeRecord.touchActive) { - error("Cannot find single active touch."); - } - } - } - } - }, - touchHistory: touchHistory + Object.assign(prototype, Class.prototype); + Class.prototype = prototype; + Class.prototype.constructor = Class; + Class.Interface = Object.assign({}, Super.Interface, Interface); + Class.extend = Super.extend; + addEventPoolingTo(Class); + return Class; }; +addEventPoolingTo(SyntheticEvent); /** - * Accumulates items that must not be null or undefined. - * - * This is used to conserve memory by avoiding array allocations. + * Helper to nullify syntheticEvent instance properties when destructing * - * @return {*|array<*>} An accumulation of items. + * @param {String} propName + * @param {?object} getVal + * @return {object} defineProperty object */ +function getPooledWarningPropertyDefinition(propName, getVal) { + var isFunction = typeof getVal === "function"; + return { + configurable: true, + set: set, + get: get + }; -function accumulate(current, next) { - if (!(next != null)) { - throw Error( - "accumulate(...): Accumulated items must not be null or undefined." - ); + function set(val) { + var action = isFunction ? "setting the method" : "setting the property"; + warn(action, "This is effectively a no-op"); + return val; } - if (current == null) { - return next; - } // Both are not empty. Warning: Never call x.concat(y) when you are not - // certain that x is an Array (x could be a string with concat method). - - if (Array.isArray(current)) { - return current.concat(next); + function get() { + var action = isFunction ? "accessing the method" : "accessing the property"; + var result = isFunction + ? "This is a no-op function" + : "This is set to null"; + warn(action, result); + return getVal; } - if (Array.isArray(next)) { - return [current].concat(next); - } + function warn(action, result) { + var warningCondition = false; + !warningCondition + ? warningWithoutStack$1( + false, + "This synthetic event is reused for performance reasons. If you're seeing this, " + + "you're %s `%s` on a released/nullified synthetic event. %s. " + + "If you must keep the original synthetic event around, use event.persist(). " + + "See https://fb.me/react-event-pooling for more information.", + action, + propName, + result + ) + : void 0; + } +} - return [current, next]; +function getPooledEvent(dispatchConfig, targetInst, nativeEvent, nativeInst) { + var EventConstructor = this; + if (EventConstructor.eventPool.length) { + var instance = EventConstructor.eventPool.pop(); + EventConstructor.call( + instance, + dispatchConfig, + targetInst, + nativeEvent, + nativeInst + ); + return instance; + } + return new EventConstructor( + dispatchConfig, + targetInst, + nativeEvent, + nativeInst + ); +} + +function releasePooledEvent(event) { + var EventConstructor = this; + + if (!(event instanceof EventConstructor)) { + throw Error( + "Trying to release an event instance into a pool of a different type." + ); + } + + event.destructor(); + + if (EventConstructor.eventPool.length < EVENT_POOL_SIZE) { + EventConstructor.eventPool.push(event); + } +} + +function addEventPoolingTo(EventConstructor) { + EventConstructor.eventPool = []; + EventConstructor.getPooled = getPooledEvent; + EventConstructor.release = releasePooledEvent; } /** - * Instance of element that should respond to touch/move types of interactions, - * as indicated explicitly by relevant callbacks. + * `touchHistory` isn't actually on the native event, but putting it in the + * interface will ensure that it is cleaned up when pooled/destroyed. The + * `ResponderEventPlugin` will populate it appropriately. */ +var ResponderSyntheticEvent = SyntheticEvent.extend({ + touchHistory: function(nativeEvent) { + return null; // Actually doesn't even look at the native event. + } +}); + +var TOP_TOUCH_START = "topTouchStart"; +var TOP_TOUCH_MOVE = "topTouchMove"; +var TOP_TOUCH_END = "topTouchEnd"; +var TOP_TOUCH_CANCEL = "topTouchCancel"; +var TOP_SCROLL = "topScroll"; +var TOP_SELECTION_CHANGE = "topSelectionChange"; +function isStartish(topLevelType) { + return topLevelType === TOP_TOUCH_START; +} +function isMoveish(topLevelType) { + return topLevelType === TOP_TOUCH_MOVE; +} +function isEndish(topLevelType) { + return topLevelType === TOP_TOUCH_END || topLevelType === TOP_TOUCH_CANCEL; +} +var startDependencies = [TOP_TOUCH_START]; +var moveDependencies = [TOP_TOUCH_MOVE]; +var endDependencies = [TOP_TOUCH_CANCEL, TOP_TOUCH_END]; -var responderInst = null; /** - * Count of current touches. A textInput should become responder iff the - * selection changes while there is a touch on the screen. + * Tracks the position and time of each active touch by `touch.identifier`. We + * should typically only see IDs in the range of 1-20 because IDs get recycled + * when touches end and start again. */ -var trackedTouchCount = 0; +var MAX_TOUCH_BANK = 20; +var touchBank = []; +var touchHistory = { + touchBank: touchBank, + numberActiveTouches: 0, + // If there is only one active touch, we remember its location. This prevents + // us having to loop through all of the touches all the time in the most + // common case. + indexOfSingleActiveTouch: -1, + mostRecentTimeStamp: 0 +}; -var changeResponder = function(nextResponderInst, blockHostResponder) { - var oldResponderInst = responderInst; - responderInst = nextResponderInst; +function timestampForTouch(touch) { + // The legacy internal implementation provides "timeStamp", which has been + // renamed to "timestamp". Let both work for now while we iron it out + // TODO (evv): rename timeStamp to timestamp in internal code + return touch.timeStamp || touch.timestamp; +} +/** + * TODO: Instead of making gestures recompute filtered velocity, we could + * include a built in velocity computation that can be reused globally. + */ +function createTouchRecord(touch) { + return { + touchActive: true, + startPageX: touch.pageX, + startPageY: touch.pageY, + startTimeStamp: timestampForTouch(touch), + currentPageX: touch.pageX, + currentPageY: touch.pageY, + currentTimeStamp: timestampForTouch(touch), + previousPageX: touch.pageX, + previousPageY: touch.pageY, + previousTimeStamp: timestampForTouch(touch) + }; +} - if (ResponderEventPlugin.GlobalResponderHandler !== null) { - ResponderEventPlugin.GlobalResponderHandler.onChange( - oldResponderInst, - nextResponderInst, - blockHostResponder - ); +function resetTouchRecord(touchRecord, touch) { + touchRecord.touchActive = true; + touchRecord.startPageX = touch.pageX; + touchRecord.startPageY = touch.pageY; + touchRecord.startTimeStamp = timestampForTouch(touch); + touchRecord.currentPageX = touch.pageX; + touchRecord.currentPageY = touch.pageY; + touchRecord.currentTimeStamp = timestampForTouch(touch); + touchRecord.previousPageX = touch.pageX; + touchRecord.previousPageY = touch.pageY; + touchRecord.previousTimeStamp = timestampForTouch(touch); +} + +function getTouchIdentifier(_ref) { + var identifier = _ref.identifier; + + if (!(identifier != null)) { + throw Error("Touch object is missing identifier."); } -}; -var eventTypes = { - /** - * On a `touchStart`/`mouseDown`, is it desired that this element become the - * responder? - */ - startShouldSetResponder: { - phasedRegistrationNames: { - bubbled: "onStartShouldSetResponder", - captured: "onStartShouldSetResponderCapture" - }, - dependencies: startDependencies - }, + { + !(identifier <= MAX_TOUCH_BANK) + ? warningWithoutStack$1( + false, + "Touch identifier %s is greater than maximum supported %s which causes " + + "performance issues backfilling array locations for all of the indices.", + identifier, + MAX_TOUCH_BANK + ) + : void 0; + } + return identifier; +} - /** - * On a `scroll`, is it desired that this element become the responder? This - * is usually not needed, but should be used to retroactively infer that a - * `touchStart` had occurred during momentum scroll. During a momentum scroll, - * a touch start will be immediately followed by a scroll event if the view is - * currently scrolling. - * - * TODO: This shouldn't bubble. - */ - scrollShouldSetResponder: { - phasedRegistrationNames: { - bubbled: "onScrollShouldSetResponder", - captured: "onScrollShouldSetResponderCapture" - }, - dependencies: [TOP_SCROLL] - }, +function recordTouchStart(touch) { + var identifier = getTouchIdentifier(touch); + var touchRecord = touchBank[identifier]; + if (touchRecord) { + resetTouchRecord(touchRecord, touch); + } else { + touchBank[identifier] = createTouchRecord(touch); + } + touchHistory.mostRecentTimeStamp = timestampForTouch(touch); +} - /** - * On text selection change, should this element become the responder? This - * is needed for text inputs or other views with native selection, so the - * JS view can claim the responder. - * - * TODO: This shouldn't bubble. - */ - selectionChangeShouldSetResponder: { - phasedRegistrationNames: { - bubbled: "onSelectionChangeShouldSetResponder", - captured: "onSelectionChangeShouldSetResponderCapture" - }, - dependencies: [TOP_SELECTION_CHANGE] - }, +function recordTouchMove(touch) { + var touchRecord = touchBank[getTouchIdentifier(touch)]; + if (touchRecord) { + touchRecord.touchActive = true; + touchRecord.previousPageX = touchRecord.currentPageX; + touchRecord.previousPageY = touchRecord.currentPageY; + touchRecord.previousTimeStamp = touchRecord.currentTimeStamp; + touchRecord.currentPageX = touch.pageX; + touchRecord.currentPageY = touch.pageY; + touchRecord.currentTimeStamp = timestampForTouch(touch); + touchHistory.mostRecentTimeStamp = timestampForTouch(touch); + } else { + console.warn( + "Cannot record touch move without a touch start.\n" + "Touch Move: %s\n", + "Touch Bank: %s", + printTouch(touch), + printTouchBank() + ); + } +} - /** - * On a `touchMove`/`mouseMove`, is it desired that this element become the - * responder? - */ - moveShouldSetResponder: { - phasedRegistrationNames: { - bubbled: "onMoveShouldSetResponder", - captured: "onMoveShouldSetResponderCapture" - }, - dependencies: moveDependencies - }, +function recordTouchEnd(touch) { + var touchRecord = touchBank[getTouchIdentifier(touch)]; + if (touchRecord) { + touchRecord.touchActive = false; + touchRecord.previousPageX = touchRecord.currentPageX; + touchRecord.previousPageY = touchRecord.currentPageY; + touchRecord.previousTimeStamp = touchRecord.currentTimeStamp; + touchRecord.currentPageX = touch.pageX; + touchRecord.currentPageY = touch.pageY; + touchRecord.currentTimeStamp = timestampForTouch(touch); + touchHistory.mostRecentTimeStamp = timestampForTouch(touch); + } else { + console.warn( + "Cannot record touch end without a touch start.\n" + "Touch End: %s\n", + "Touch Bank: %s", + printTouch(touch), + printTouchBank() + ); + } +} - /** - * Direct responder events dispatched directly to responder. Do not bubble. - */ - responderStart: { - registrationName: "onResponderStart", - dependencies: startDependencies - }, - responderMove: { - registrationName: "onResponderMove", - dependencies: moveDependencies - }, - responderEnd: { +function printTouch(touch) { + return JSON.stringify({ + identifier: touch.identifier, + pageX: touch.pageX, + pageY: touch.pageY, + timestamp: timestampForTouch(touch) + }); +} + +function printTouchBank() { + var printed = JSON.stringify(touchBank.slice(0, MAX_TOUCH_BANK)); + + if (touchBank.length > MAX_TOUCH_BANK) { + printed += " (original size: " + touchBank.length + ")"; + } + + return printed; +} + +var ResponderTouchHistoryStore = { + recordTouchTrack: function(topLevelType, nativeEvent) { + if (isMoveish(topLevelType)) { + nativeEvent.changedTouches.forEach(recordTouchMove); + } else if (isStartish(topLevelType)) { + nativeEvent.changedTouches.forEach(recordTouchStart); + touchHistory.numberActiveTouches = nativeEvent.touches.length; + if (touchHistory.numberActiveTouches === 1) { + touchHistory.indexOfSingleActiveTouch = + nativeEvent.touches[0].identifier; + } + } else if (isEndish(topLevelType)) { + nativeEvent.changedTouches.forEach(recordTouchEnd); + touchHistory.numberActiveTouches = nativeEvent.touches.length; + + if (touchHistory.numberActiveTouches === 1) { + for (var i = 0; i < touchBank.length; i++) { + var touchTrackToCheck = touchBank[i]; + + if (touchTrackToCheck != null && touchTrackToCheck.touchActive) { + touchHistory.indexOfSingleActiveTouch = i; + break; + } + } + { + var activeRecord = touchBank[touchHistory.indexOfSingleActiveTouch]; + !(activeRecord != null && activeRecord.touchActive) + ? warningWithoutStack$1(false, "Cannot find single active touch.") + : void 0; + } + } + } + }, + touchHistory: touchHistory +}; + +/** + * Accumulates items that must not be null or undefined. + * + * This is used to conserve memory by avoiding array allocations. + * + * @return {*|array<*>} An accumulation of items. + */ + +function accumulate(current, next) { + if (!(next != null)) { + throw Error( + "accumulate(...): Accumulated items must not be null or undefined." + ); + } + + if (current == null) { + return next; + } // Both are not empty. Warning: Never call x.concat(y) when you are not + // certain that x is an Array (x could be a string with concat method). + + if (Array.isArray(current)) { + return current.concat(next); + } + + if (Array.isArray(next)) { + return [current].concat(next); + } + + return [current, next]; +} + +/** + * Instance of element that should respond to touch/move types of interactions, + * as indicated explicitly by relevant callbacks. + */ + +var responderInst = null; +/** + * Count of current touches. A textInput should become responder iff the + * selection changes while there is a touch on the screen. + */ +var trackedTouchCount = 0; + +var changeResponder = function(nextResponderInst, blockHostResponder) { + var oldResponderInst = responderInst; + responderInst = nextResponderInst; + if (ResponderEventPlugin.GlobalResponderHandler !== null) { + ResponderEventPlugin.GlobalResponderHandler.onChange( + oldResponderInst, + nextResponderInst, + blockHostResponder + ); + } +}; + +var eventTypes = { + /** + * On a `touchStart`/`mouseDown`, is it desired that this element become the + * responder? + */ + startShouldSetResponder: { + phasedRegistrationNames: { + bubbled: "onStartShouldSetResponder", + captured: "onStartShouldSetResponderCapture" + }, + dependencies: startDependencies + }, + + /** + * On a `scroll`, is it desired that this element become the responder? This + * is usually not needed, but should be used to retroactively infer that a + * `touchStart` had occurred during momentum scroll. During a momentum scroll, + * a touch start will be immediately followed by a scroll event if the view is + * currently scrolling. + * + * TODO: This shouldn't bubble. + */ + scrollShouldSetResponder: { + phasedRegistrationNames: { + bubbled: "onScrollShouldSetResponder", + captured: "onScrollShouldSetResponderCapture" + }, + dependencies: [TOP_SCROLL] + }, + + /** + * On text selection change, should this element become the responder? This + * is needed for text inputs or other views with native selection, so the + * JS view can claim the responder. + * + * TODO: This shouldn't bubble. + */ + selectionChangeShouldSetResponder: { + phasedRegistrationNames: { + bubbled: "onSelectionChangeShouldSetResponder", + captured: "onSelectionChangeShouldSetResponderCapture" + }, + dependencies: [TOP_SELECTION_CHANGE] + }, + + /** + * On a `touchMove`/`mouseMove`, is it desired that this element become the + * responder? + */ + moveShouldSetResponder: { + phasedRegistrationNames: { + bubbled: "onMoveShouldSetResponder", + captured: "onMoveShouldSetResponderCapture" + }, + dependencies: moveDependencies + }, + + /** + * Direct responder events dispatched directly to responder. Do not bubble. + */ + responderStart: { + registrationName: "onResponderStart", + dependencies: startDependencies + }, + responderMove: { + registrationName: "onResponderMove", + dependencies: moveDependencies + }, + responderEnd: { registrationName: "onResponderEnd", dependencies: endDependencies }, @@ -1796,7 +2111,7 @@ to return true:wantsResponderID| | + + */ /** - * A note about event ordering in the `EventPluginRegistry`. + * A note about event ordering in the `EventPluginHub`. * * Suppose plugins are injected in the following order: * @@ -1815,7 +2130,7 @@ to return true:wantsResponderID| | * - When returned from `extractEvents`, deferred-dispatched events contain an * "accumulation" of deferred dispatches. * - These deferred dispatches are accumulated/collected before they are - * returned, but processed at a later time by the `EventPluginRegistry` (hence the + * returned, but processed at a later time by the `EventPluginHub` (hence the * name deferred). * * In the process of returning their deferred-dispatched events, event plugins @@ -1839,9 +2154,9 @@ to return true:wantsResponderID| | * - `R`s on-demand events (if any) (dispatched by `R` on-demand) * - `S`s on-demand events (if any) (dispatched by `S` on-demand) * - `C`s on-demand events (if any) (dispatched by `C` on-demand) - * - `R`s extracted events (if any) (dispatched by `EventPluginRegistry`) - * - `S`s extracted events (if any) (dispatched by `EventPluginRegistry`) - * - `C`s extracted events (if any) (dispatched by `EventPluginRegistry`) + * - `R`s extracted events (if any) (dispatched by `EventPluginHub`) + * - `S`s extracted events (if any) (dispatched by `EventPluginHub`) + * - `C`s extracted events (if any) (dispatched by `EventPluginHub`) * * In the case of `ResponderEventPlugin`: If the `startShouldSetResponder` * on-demand dispatch returns `true` (and some other details are satisfied) the @@ -1850,9 +2165,9 @@ to return true:wantsResponderID| | * will appear as follows: * * - `startShouldSetResponder` (`ResponderEventPlugin` dispatches on-demand) - * - `touchStartCapture` (`EventPluginRegistry` dispatches as usual) - * - `touchStart` (`EventPluginRegistry` dispatches as usual) - * - `responderGrant/Reject` (`EventPluginRegistry` dispatches as usual) + * - `touchStartCapture` (`EventPluginHub` dispatches as usual) + * - `touchStart` (`EventPluginHub` dispatches as usual) + * - `responderGrant/Reject` (`EventPluginHub` dispatches as usual) */ function setResponderAndExtractTransfer( @@ -1864,10 +2179,10 @@ function setResponderAndExtractTransfer( var shouldSetEventType = isStartish(topLevelType) ? eventTypes.startShouldSetResponder : isMoveish(topLevelType) - ? eventTypes.moveShouldSetResponder - : topLevelType === TOP_SELECTION_CHANGE - ? eventTypes.selectionChangeShouldSetResponder - : eventTypes.scrollShouldSetResponder; // TODO: stop one short of the current responder. + ? eventTypes.moveShouldSetResponder + : topLevelType === TOP_SELECTION_CHANGE + ? eventTypes.selectionChangeShouldSetResponder + : eventTypes.scrollShouldSetResponder; // TODO: stop one short of the current responder. var bubbleShouldSetFrom = !responderInst ? targetInst @@ -1884,7 +2199,6 @@ function setResponderAndExtractTransfer( nativeEventTarget ); shouldSetEvent.touchHistory = ResponderTouchHistoryStore.touchHistory; - if (skipOverBubbleShouldSetFrom) { accumulateTwoPhaseDispatchesSkipTarget(shouldSetEvent); } else { @@ -1925,7 +2239,6 @@ function setResponderAndExtractTransfer( var shouldSwitch = !hasDispatches(terminationRequestEvent) || executeDirectDispatch(terminationRequestEvent); - if (!terminationRequestEvent.isPersistent()) { terminationRequestEvent.constructor.release(terminationRequestEvent); } @@ -2007,7 +2320,6 @@ function noResponderTouches(nativeEvent) { } } } - return true; } @@ -2036,12 +2348,9 @@ var ResponderEventPlugin = { if (trackedTouchCount >= 0) { trackedTouchCount -= 1; } else { - { - warn( - "Ended a touch event which was not counted in `trackedTouchCount`." - ); - } - + console.warn( + "Ended a touch event which was not counted in `trackedTouchCount`." + ); return null; } } @@ -2064,17 +2373,16 @@ var ResponderEventPlugin = { // These multiple individual change touch events are are always bookended // by `onResponderGrant`, and one of // (`onResponderRelease/onResponderTerminate`). - var isResponderTouchStart = responderInst && isStartish(topLevelType); var isResponderTouchMove = responderInst && isMoveish(topLevelType); var isResponderTouchEnd = responderInst && isEndish(topLevelType); var incrementalTouch = isResponderTouchStart ? eventTypes.responderStart : isResponderTouchMove - ? eventTypes.responderMove - : isResponderTouchEnd - ? eventTypes.responderEnd - : null; + ? eventTypes.responderMove + : isResponderTouchEnd + ? eventTypes.responderEnd + : null; if (incrementalTouch) { var gesture = ResponderSyntheticEvent.getPooled( @@ -2098,9 +2406,8 @@ var ResponderEventPlugin = { var finalTouch = isResponderTerminate ? eventTypes.responderTerminate : isResponderRelease - ? eventTypes.responderRelease - : null; - + ? eventTypes.responderRelease + : null; if (finalTouch) { var finalEvent = ResponderSyntheticEvent.getPooled( finalTouch, @@ -2129,276 +2436,55 @@ var ResponderEventPlugin = { } }; -/** - * Injectable ordering of event plugins. - */ -var eventPluginOrder = null; -/** - * Injectable mapping from names to event plugin modules. - */ - -var namesToPlugins = {}; -/** - * Recomputes the plugin list using the injected plugins and plugin ordering. - * - * @private - */ +var customBubblingEventTypes = + ReactNativePrivateInterface.ReactNativeViewConfigRegistry + .customBubblingEventTypes; +var customDirectEventTypes = + ReactNativePrivateInterface.ReactNativeViewConfigRegistry + .customDirectEventTypes; +var ReactNativeBridgeEventPlugin = { + eventTypes: {}, -function recomputePluginOrdering() { - if (!eventPluginOrder) { - // Wait until an `eventPluginOrder` is injected. - return; - } + /** + * @see {EventPluginHub.extractEvents} + */ + extractEvents: function( + topLevelType, + targetInst, + nativeEvent, + nativeEventTarget, + eventSystemFlags + ) { + if (targetInst == null) { + // Probably a node belonging to another renderer's tree. + return null; + } - for (var pluginName in namesToPlugins) { - var pluginModule = namesToPlugins[pluginName]; - var pluginIndex = eventPluginOrder.indexOf(pluginName); + var bubbleDispatchConfig = customBubblingEventTypes[topLevelType]; + var directDispatchConfig = customDirectEventTypes[topLevelType]; - if (!(pluginIndex > -1)) { + if (!(bubbleDispatchConfig || directDispatchConfig)) { throw Error( - "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + - pluginName + - "`." + 'Unsupported top level event type "' + topLevelType + '" dispatched' ); } - if (plugins[pluginIndex]) { - continue; + var event = SyntheticEvent.getPooled( + bubbleDispatchConfig || directDispatchConfig, + targetInst, + nativeEvent, + nativeEventTarget + ); + if (bubbleDispatchConfig) { + accumulateTwoPhaseDispatches(event); + } else if (directDispatchConfig) { + accumulateDirectDispatches(event); + } else { + return null; } - - if (!pluginModule.extractEvents) { - throw Error( - "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + - pluginName + - "` does not." - ); - } - - plugins[pluginIndex] = pluginModule; - var publishedEvents = pluginModule.eventTypes; - - for (var eventName in publishedEvents) { - if ( - !publishEventForPlugin( - publishedEvents[eventName], - pluginModule, - eventName - ) - ) { - throw Error( - "EventPluginRegistry: Failed to publish event `" + - eventName + - "` for plugin `" + - pluginName + - "`." - ); - } - } - } -} -/** - * Publishes an event so that it can be dispatched by the supplied plugin. - * - * @param {object} dispatchConfig Dispatch configuration for the event. - * @param {object} PluginModule Plugin publishing the event. - * @return {boolean} True if the event was successfully published. - * @private - */ - -function publishEventForPlugin(dispatchConfig, pluginModule, eventName) { - if (!!eventNameDispatchConfigs.hasOwnProperty(eventName)) { - throw Error( - "EventPluginRegistry: More than one plugin attempted to publish the same event name, `" + - eventName + - "`." - ); - } - - eventNameDispatchConfigs[eventName] = dispatchConfig; - var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; - - if (phasedRegistrationNames) { - for (var phaseName in phasedRegistrationNames) { - if (phasedRegistrationNames.hasOwnProperty(phaseName)) { - var phasedRegistrationName = phasedRegistrationNames[phaseName]; - publishRegistrationName( - phasedRegistrationName, - pluginModule, - eventName - ); - } - } - - return true; - } else if (dispatchConfig.registrationName) { - publishRegistrationName( - dispatchConfig.registrationName, - pluginModule, - eventName - ); - return true; - } - - return false; -} -/** - * Publishes a registration name that is used to identify dispatched events. - * - * @param {string} registrationName Registration name to add. - * @param {object} PluginModule Plugin publishing the event. - * @private - */ - -function publishRegistrationName(registrationName, pluginModule, eventName) { - if (!!registrationNameModules[registrationName]) { - throw Error( - "EventPluginRegistry: More than one plugin attempted to publish the same registration name, `" + - registrationName + - "`." - ); - } - - registrationNameModules[registrationName] = pluginModule; - registrationNameDependencies[registrationName] = - pluginModule.eventTypes[eventName].dependencies; - - { - var lowerCasedName = registrationName.toLowerCase(); - } -} -/** - * Registers plugins so that they can extract and dispatch events. - */ - -/** - * Ordered list of injected plugins. - */ - -var plugins = []; -/** - * Mapping from event name to dispatch config - */ - -var eventNameDispatchConfigs = {}; -/** - * Mapping from registration name to plugin module - */ - -var registrationNameModules = {}; -/** - * Mapping from registration name to event name - */ - -var registrationNameDependencies = {}; - -/** - * Injects an ordering of plugins (by plugin name). This allows the ordering - * to be decoupled from injection of the actual plugins so that ordering is - * always deterministic regardless of packaging, on-the-fly injection, etc. - * - * @param {array} InjectedEventPluginOrder - * @internal - */ - -function injectEventPluginOrder(injectedEventPluginOrder) { - if (!!eventPluginOrder) { - throw Error( - "EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React." - ); - } // Clone the ordering so it cannot be dynamically mutated. - - eventPluginOrder = Array.prototype.slice.call(injectedEventPluginOrder); - recomputePluginOrdering(); -} -/** - * Injects plugins to be used by plugin event system. The plugin names must be - * in the ordering injected by `injectEventPluginOrder`. - * - * Plugins can be injected as part of page initialization or on-the-fly. - * - * @param {object} injectedNamesToPlugins Map from names to plugin modules. - * @internal - */ - -function injectEventPluginsByName(injectedNamesToPlugins) { - var isOrderingDirty = false; - - for (var pluginName in injectedNamesToPlugins) { - if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) { - continue; - } - - var pluginModule = injectedNamesToPlugins[pluginName]; - - if ( - !namesToPlugins.hasOwnProperty(pluginName) || - namesToPlugins[pluginName] !== pluginModule - ) { - if (!!namesToPlugins[pluginName]) { - throw Error( - "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - pluginName + - "`." - ); - } - - namesToPlugins[pluginName] = pluginModule; - isOrderingDirty = true; - } - } - - if (isOrderingDirty) { - recomputePluginOrdering(); - } -} - -var customBubblingEventTypes = - ReactNativePrivateInterface.ReactNativeViewConfigRegistry - .customBubblingEventTypes, - customDirectEventTypes = - ReactNativePrivateInterface.ReactNativeViewConfigRegistry - .customDirectEventTypes; -var ReactNativeBridgeEventPlugin = { - eventTypes: {}, - extractEvents: function( - topLevelType, - targetInst, - nativeEvent, - nativeEventTarget, - eventSystemFlags - ) { - if (targetInst == null) { - // Probably a node belonging to another renderer's tree. - return null; - } - - var bubbleDispatchConfig = customBubblingEventTypes[topLevelType]; - var directDispatchConfig = customDirectEventTypes[topLevelType]; - - if (!(bubbleDispatchConfig || directDispatchConfig)) { - throw Error( - 'Unsupported top level event type "' + topLevelType + '" dispatched' - ); - } - - var event = SyntheticEvent.getPooled( - bubbleDispatchConfig || directDispatchConfig, - targetInst, - nativeEvent, - nativeEventTarget - ); - - if (bubbleDispatchConfig) { - accumulateTwoPhaseDispatches(event); - } else if (directDispatchConfig) { - accumulateDirectDispatches(event); - } else { - return null; - } - - return event; - } -}; + return event; + } +}; var ReactNativeEventPluginOrder = [ "ResponderEventPlugin", @@ -2411,34 +2497,69 @@ var ReactNativeEventPluginOrder = [ * ensures it exists in the dependency graph and can be `require`d. * TODO: require this in packager, not in React #10932517 */ +// Module provided by RN: /** * Inject module for resolving DOM hierarchy and plugin ordering. */ -injectEventPluginOrder(ReactNativeEventPluginOrder); +injection.injectEventPluginOrder(ReactNativeEventPluginOrder); /** * Some important event plugins included by default (without having to require * them). */ - -injectEventPluginsByName({ +injection.injectEventPluginsByName({ ResponderEventPlugin: ResponderEventPlugin, ReactNativeBridgeEventPlugin: ReactNativeBridgeEventPlugin }); +var debugRenderPhaseSideEffectsForStrictMode = false; +var enableUserTimingAPI = true; +var replayFailedUnitOfWorkWithInvokeGuardedCallback = true; +var warnAboutDeprecatedLifecycles = true; +var enableProfilerTimer = true; +var enableSchedulerTracing = true; +var enableSuspenseServerRenderer = false; + +var enableFlareAPI = false; +var enableFundamentalAPI = false; +var enableScopeAPI = false; + +var warnAboutUnmockedScheduler = false; +var flushSuspenseFallbacksInTests = true; +var enableSuspenseCallback = false; +var warnAboutDefaultPropsOnFunctionComponents = false; +var warnAboutStringRefs = false; +var disableLegacyContext = false; +var disableSchedulerTimeoutBasedOnReactExpirationTime = false; + +var enableNativeTargetAsInstance = false; // Only used in www builds. + +// Flow magic to verify the exports of this file match the original version. + function getInstanceFromInstance(instanceHandle) { return instanceHandle; } function getTagFromInstance(inst) { - var nativeInstance = inst.stateNode.canonical; + if (enableNativeTargetAsInstance) { + var nativeInstance = inst.stateNode.canonical; - if (!nativeInstance._nativeTag) { - throw Error("All native instances should have a tag."); - } + if (!nativeInstance._nativeTag) { + throw Error("All native instances should have a tag."); + } + + return nativeInstance; + } else { + var tag = inst.stateNode.canonical._nativeTag; + + if (!tag) { + throw Error("All native instances should have a tag."); + } - return nativeInstance; + return tag; + } } + function getFiberCurrentPropsFromNode$1(inst) { return inst.canonical.currentProps; } @@ -2476,25 +2597,51 @@ ResponderEventPlugin.injection.injectGlobalResponderHandler( * Note that this module is currently shared and assumed to be stateless. * If this becomes an actual Map, that will break. */ + +/** + * This API should be called `delete` but we'd have to make sure to always + * transform these to strings for IE support. When this transform is fully + * supported we can rename it. + */ + function get(key) { return key._reactInternalFiber; } + function set(key, value) { key._reactInternalFiber = value; } -// The Symbol used to tag the ReactElement-like types. If there is no native Symbol -// nor polyfill, then a plain number is used for performance. -var hasSymbol = typeof Symbol === "function" && Symbol.for; -var REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for("react.element") : 0xeac7; -var REACT_PORTAL_TYPE = hasSymbol ? Symbol.for("react.portal") : 0xeaca; -var REACT_FRAGMENT_TYPE = hasSymbol ? Symbol.for("react.fragment") : 0xeacb; -var REACT_STRICT_MODE_TYPE = hasSymbol - ? Symbol.for("react.strict_mode") - : 0xeacc; -var REACT_PROFILER_TYPE = hasSymbol ? Symbol.for("react.profiler") : 0xead2; -var REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for("react.provider") : 0xeacd; -var REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for("react.context") : 0xeace; // TODO: We don't use AsyncMode or ConcurrentMode anymore. They were temporary +var ReactSharedInternals = + React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; // Prevent newer renderers from RTE when used with older react package versions. +// Current owner and dispatcher used to share the same ref, +// but PR #14548 split them out to better support the react-debug-tools package. + +if (!ReactSharedInternals.hasOwnProperty("ReactCurrentDispatcher")) { + ReactSharedInternals.ReactCurrentDispatcher = { + current: null + }; +} +if (!ReactSharedInternals.hasOwnProperty("ReactCurrentBatchConfig")) { + ReactSharedInternals.ReactCurrentBatchConfig = { + suspense: null + }; +} + +// The Symbol used to tag the ReactElement-like types. If there is no native Symbol +// nor polyfill, then a plain number is used for performance. +var hasSymbol = typeof Symbol === "function" && Symbol.for; +var REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for("react.element") : 0xeac7; +var REACT_PORTAL_TYPE = hasSymbol ? Symbol.for("react.portal") : 0xeaca; +var REACT_FRAGMENT_TYPE = hasSymbol ? Symbol.for("react.fragment") : 0xeacb; +var REACT_STRICT_MODE_TYPE = hasSymbol + ? Symbol.for("react.strict_mode") + : 0xeacc; +var REACT_PROFILER_TYPE = hasSymbol ? Symbol.for("react.profiler") : 0xead2; +var REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for("react.provider") : 0xeacd; +var REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for("react.context") : 0xeace; // TODO: We don't use AsyncMode or ConcurrentMode anymore. They were temporary +// (unstable) APIs that have been removed. Can we remove the symbols? + var REACT_CONCURRENT_MODE_TYPE = hasSymbol ? Symbol.for("react.concurrent_mode") : 0xeacf; @@ -2507,7 +2654,11 @@ var REACT_SUSPENSE_LIST_TYPE = hasSymbol : 0xead8; var REACT_MEMO_TYPE = hasSymbol ? Symbol.for("react.memo") : 0xead3; var REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 0xead4; -var REACT_BLOCK_TYPE = hasSymbol ? Symbol.for("react.block") : 0xead9; +var REACT_FUNDAMENTAL_TYPE = hasSymbol + ? Symbol.for("react.fundamental") + : 0xead5; +var REACT_RESPONDER_TYPE = hasSymbol ? Symbol.for("react.responder") : 0xead6; +var REACT_SCOPE_TYPE = hasSymbol ? Symbol.for("react.scope") : 0xead7; var MAYBE_ITERATOR_SYMBOL = typeof Symbol === "function" && Symbol.iterator; var FAUX_ITERATOR_SYMBOL = "@@iterator"; function getIteratorFn(maybeIterable) { @@ -2526,29 +2677,56 @@ function getIteratorFn(maybeIterable) { return null; } -// TODO: Move this to "react" once we can import from externals. +/** + * Similar to invariant but only logs a warning if the condition is not met. + * This can be used to log issues in development environments in critical + * paths. Removing the logging code for production environments will keep the + * same logic and follow the same code paths. + */ + +var warning = warningWithoutStack$1; + +{ + warning = function(condition, format) { + if (condition) { + return; + } + + var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; + var stack = ReactDebugCurrentFrame.getStackAddendum(); // eslint-disable-next-line react-internal/warning-and-invariant-args + + for ( + var _len = arguments.length, + args = new Array(_len > 2 ? _len - 2 : 0), + _key = 2; + _key < _len; + _key++ + ) { + args[_key - 2] = arguments[_key]; + } + + warningWithoutStack$1.apply( + void 0, + [false, format + "%s"].concat(args, [stack]) + ); + }; +} + +var warning$1 = warning; + var Uninitialized = -1; var Pending = 0; var Resolved = 1; var Rejected = 2; - function refineResolvedLazyComponent(lazyComponent) { return lazyComponent._status === Resolved ? lazyComponent._result : null; } function initializeLazyComponentType(lazyComponent) { if (lazyComponent._status === Uninitialized) { - var ctor = lazyComponent._result; - - if (!ctor) { - // TODO: Remove this later. THis only exists in case you use an older "react" package. - ctor = lazyComponent._ctor; - } - - var thenable = ctor(); // Transition to the next state. - - var pending = lazyComponent; - pending._status = Pending; - pending._result = thenable; + lazyComponent._status = Pending; + var ctor = lazyComponent._ctor; + var thenable = ctor(); + lazyComponent._result = thenable; thenable.then( function(moduleObject) { if (lazyComponent._status === Pending) { @@ -2556,27 +2734,24 @@ function initializeLazyComponentType(lazyComponent) { { if (defaultExport === undefined) { - error( + warning$1( + false, "lazy: Expected the result of a dynamic import() call. " + - "Instead received: %s\n\nYour code should look like: \n " + // Break up imports to avoid accidentally parsing them as dependencies. - "const MyComponent = lazy(() => imp" + - "ort('./MyComponent'))", + "Instead received: %s\n\nYour code should look like: \n " + + "const MyComponent = lazy(() => import('./MyComponent'))", moduleObject ); } - } // Transition to the next state. + } - var resolved = lazyComponent; - resolved._status = Resolved; - resolved._result = defaultExport; + lazyComponent._status = Resolved; + lazyComponent._result = defaultExport; } }, function(error) { if (lazyComponent._status === Pending) { - // Transition to the next state. - var rejected = lazyComponent; - rejected._status = Rejected; - rejected._result = error; + lazyComponent._status = Rejected; + lazyComponent._result = error; } } ); @@ -2591,19 +2766,15 @@ function getWrappedName(outerType, innerType, wrapperName) { ); } -function getContextName(type) { - return type.displayName || "Context"; -} - function getComponentName(type) { if (type == null) { // Host root, text node or just invalid type. return null; } - { if (typeof type.tag === "number") { - error( + warningWithoutStack$1( + false, "Received an unexpected object in getComponentName(). " + "This is likely a bug in React. Please file an issue." ); @@ -2641,12 +2812,10 @@ function getComponentName(type) { if (typeof type === "object") { switch (type.$$typeof) { case REACT_CONTEXT_TYPE: - var context = type; - return getContextName(context) + ".Consumer"; + return "Context.Consumer"; case REACT_PROVIDER_TYPE: - var provider = type; - return getContextName(provider._context) + ".Provider"; + return "Context.Provider"; case REACT_FORWARD_REF_TYPE: return getWrappedName(type, type.render, "ForwardRef"); @@ -2654,9 +2823,6 @@ function getComponentName(type) { case REACT_MEMO_TYPE: return getComponentName(type.type); - case REACT_BLOCK_TYPE: - return getComponentName(type.render); - case REACT_LAZY_TYPE: { var thenable = type; var resolvedThenable = refineResolvedLazyComponent(thenable); @@ -2669,7 +2835,6 @@ function getComponentName(type) { } } } - return null; } @@ -2732,10 +2897,7 @@ var ShouldCapture = /* */ 4096; -var enableProfilerTimer = true; -var warnAboutStringRefs = false; - -var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner; +var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner; function getNearestMountedFiber(fiber) { var node = fiber; var nearestMounted = fiber; @@ -2772,28 +2934,28 @@ function getNearestMountedFiber(fiber) { return null; } + function isFiberMounted(fiber) { return getNearestMountedFiber(fiber) === fiber; } function isMounted(component) { { - var owner = ReactCurrentOwner.current; + var owner = ReactCurrentOwner$1.current; if (owner !== null && owner.tag === ClassComponent) { var ownerFiber = owner; var instance = ownerFiber.stateNode; - - if (!instance._warnedAboutRefsInRender) { - error( - "%s is accessing isMounted inside its render() function. " + - "render() should be a pure function of props and state. It should " + - "never access something that requires stale data from the previous " + - "render, such as refs. Move this logic to componentDidMount and " + - "componentDidUpdate instead.", - getComponentName(ownerFiber.type) || "A component" - ); - } - + !instance._warnedAboutRefsInRender + ? warningWithoutStack$1( + false, + "%s is accessing isMounted inside its render() function. " + + "render() should be a pure function of props and state. It should " + + "never access something that requires stale data from the previous " + + "render, such as refs. Move this logic to componentDidMount and " + + "componentDidUpdate instead.", + getComponentName(ownerFiber.type) || "A component" + ) + : void 0; instance._warnedAboutRefsInRender = true; } } @@ -2872,7 +3034,6 @@ function findCurrentFiberUsingSlowPath(fiber) { assertIsMounted(parentA); return fiber; } - if (child === b) { // We've determined that B is the current branch. assertIsMounted(parentA); @@ -2903,7 +3064,6 @@ function findCurrentFiberUsingSlowPath(fiber) { // Search parent A's child set var didFindChild = false; var _child = parentA.child; - while (_child) { if (_child === a) { didFindChild = true; @@ -2911,7 +3071,6 @@ function findCurrentFiberUsingSlowPath(fiber) { b = parentB; break; } - if (_child === b) { didFindChild = true; b = parentA; @@ -2933,7 +3092,6 @@ function findCurrentFiberUsingSlowPath(fiber) { b = parentA; break; } - if (_child === b) { didFindChild = true; b = parentB; @@ -3039,6 +3197,41 @@ function mountSafeCallback_NOT_REALLY_SAFE(context, callback) { return callback.apply(context, arguments); }; } +function throwOnStylesProp(component, props) { + if (props.styles !== undefined) { + var owner = component._owner || null; + var name = component.constructor.displayName; + var msg = + "`styles` is not a supported property of `" + + name + + "`, did " + + "you mean `style` (singular)?"; + if (owner && owner.constructor && owner.constructor.displayName) { + msg += + "\n\nCheck the `" + + owner.constructor.displayName + + "` parent " + + " component."; + } + + throw new Error(msg); + } +} +function warnForStyleProps(props, validAttributes) { + for (var key in validAttributes.style) { + if (!(validAttributes[key] || props[key] === undefined)) { + console.error( + "You are setting the style `{ " + + key + + ": ... }` as a prop. You " + + "should nest it in a style object. " + + "E.g. `{ style: { " + + key + + ": ... } }`" + ); + } + } +} // Modules provided by RN: var emptyObject = {}; @@ -3079,7 +3272,6 @@ function restoreDeletedValuesInNestedArray( ) { if (Array.isArray(node)) { var i = node.length; - while (i-- && removedKeyCount > 0) { restoreDeletedValuesInNestedArray( updatePayload, @@ -3089,7 +3281,6 @@ function restoreDeletedValuesInNestedArray( } } else if (node && removedKeyCount > 0) { var obj = node; - for (var propKey in removedKeys) { if (!removedKeys[propKey]) { continue; @@ -3102,7 +3293,6 @@ function restoreDeletedValuesInNestedArray( } var attributeConfig = validAttributes[propKey]; - if (!attributeConfig) { continue; // not a valid native prop } @@ -3110,7 +3300,6 @@ function restoreDeletedValuesInNestedArray( if (typeof nextProp === "function") { nextProp = true; } - if (typeof nextProp === "undefined") { nextProp = null; } @@ -3129,7 +3318,6 @@ function restoreDeletedValuesInNestedArray( : nextProp; updatePayload[propKey] = nextValue; } - removedKeys[propKey] = false; removedKeyCount--; } @@ -3156,7 +3344,6 @@ function diffNestedArrayProperty( validAttributes ); } - for (; i < prevArray.length; i++) { // Clear out all remaining properties. updatePayload = clearNestedProperty( @@ -3165,7 +3352,6 @@ function diffNestedArrayProperty( validAttributes ); } - for (; i < nextArray.length; i++) { // Add all remaining properties. updatePayload = addNestedProperty( @@ -3174,7 +3360,6 @@ function diffNestedArrayProperty( validAttributes ); } - return updatePayload; } @@ -3238,7 +3423,6 @@ function diffNestedProperty( * attribute configurations. It processes each prop and adds it to the * updatePayload. */ - function addNestedProperty(updatePayload, nextProp, validAttributes) { if (!nextProp) { return updatePayload; @@ -3264,7 +3448,6 @@ function addNestedProperty(updatePayload, nextProp, validAttributes) { * clearNestedProperty takes a single set of props and valid attributes. It * adds a null sentinel to the updatePayload, for each prop key. */ - function clearNestedProperty(updatePayload, prevProp, validAttributes) { if (!prevProp) { return updatePayload; @@ -3351,7 +3534,6 @@ function diffProperties(updatePayload, prevProps, nextProps, validAttributes) { : nextProp; updatePayload[propKey] = nextValue; } - continue; } @@ -3375,13 +3557,11 @@ function diffProperties(updatePayload, prevProps, nextProps, validAttributes) { (typeof attributeConfig.diff === "function" ? attributeConfig.diff(prevProp, nextProp) : defaultDiffer(prevProp, nextProp)); - if (shouldUpdate) { var _nextValue = typeof attributeConfig.process === "function" ? attributeConfig.process(nextProp) : nextProp; - (updatePayload || (updatePayload = {}))[propKey] = _nextValue; } } else { @@ -3396,7 +3576,6 @@ function diffProperties(updatePayload, prevProps, nextProps, validAttributes) { nextProp, attributeConfig ); - if (removedKeyCount > 0 && updatePayload) { restoreDeletedValuesInNestedArray( updatePayload, @@ -3475,7 +3654,6 @@ function addProperties(updatePayload, props, validAttributes) { * clearProperties clears all the previous props by adding a null sentinel * to the payload for each valid key. */ - function clearProperties(updatePayload, prevProps, validAttributes) { // TODO: Fast path return diffProperties(updatePayload, prevProps, emptyObject, validAttributes); @@ -3499,6 +3677,49 @@ function diff(prevProps, nextProps, validAttributes) { var PLUGIN_EVENT_SYSTEM = 1; +var restoreImpl = null; +var restoreTarget = null; +var restoreQueue = null; + +function restoreStateOfTarget(target) { + // We perform this translation at the end of the event loop so that we + // always receive the correct fiber here + var internalInstance = getInstanceFromNode(target); + if (!internalInstance) { + // Unmounted + return; + } + + if (!(typeof restoreImpl === "function")) { + throw Error( + "setRestoreImplementation() needs to be called to handle a target for controlled events. This error is likely caused by a bug in React. Please file an issue." + ); + } + + var props = getFiberCurrentPropsFromNode(internalInstance.stateNode); + restoreImpl(internalInstance.stateNode, internalInstance.type, props); +} + +function needsStateRestore() { + return restoreTarget !== null || restoreQueue !== null; +} +function restoreStateIfNeeded() { + if (!restoreTarget) { + return; + } + var target = restoreTarget; + var queuedTargets = restoreQueue; + restoreTarget = null; + restoreQueue = null; + restoreStateOfTarget(target); + + if (queuedTargets) { + for (var i = 0; i < queuedTargets.length; i++) { + restoreStateOfTarget(queuedTargets[i]); + } + } +} + // the renderer. Such as when we're dispatching events or if third party // libraries need to call batchedUpdates. Eventually, this API will go away when // everything is batched by default. We'll then have a similar API to opt-out of @@ -3508,7 +3729,31 @@ var PLUGIN_EVENT_SYSTEM = 1; var batchedUpdatesImpl = function(fn, bookkeeping) { return fn(bookkeeping); }; + +var discreteUpdatesImpl = function(fn, a, b, c) { + return fn(a, b, c); +}; + +var flushDiscreteUpdatesImpl = function() {}; + +var batchedEventUpdatesImpl = batchedUpdatesImpl; var isInsideEventHandler = false; +var isBatchingEventUpdates = false; + +function finishEventHandler() { + // Here we wait until all updates have propagated, which is important + // when using controlled components within layers: + // https://github.com/facebook/react/issues/1698 + // Then we restore state of any controlled component. + var controlledComponentsHavePendingUpdates = needsStateRestore(); + if (controlledComponentsHavePendingUpdates) { + // If a controlled event was fired, we may need to restore the state of + // the DOM node back to the controlled value. This is necessary when React + // bails out of the update without touching the DOM. + flushDiscreteUpdatesImpl(); + restoreStateIfNeeded(); + } +} function batchedUpdates(fn, bookkeeping) { if (isInsideEventHandler) { @@ -3523,6 +3768,72 @@ function batchedUpdates(fn, bookkeeping) { return batchedUpdatesImpl(fn, bookkeeping); } finally { isInsideEventHandler = false; + finishEventHandler(); + } +} +function batchedEventUpdates(fn, a, b) { + if (isBatchingEventUpdates) { + // If we are currently inside another batch, we need to wait until it + // fully completes before restoring state. + return fn(a, b); + } + + isBatchingEventUpdates = true; + + try { + return batchedEventUpdatesImpl(fn, a, b); + } finally { + isBatchingEventUpdates = false; + finishEventHandler(); + } +} // This is for the React Flare event system + +function executeUserEventHandler(fn, value) { + var previouslyInEventHandler = isInsideEventHandler; + + try { + isInsideEventHandler = true; + var type = typeof value === "object" && value !== null ? value.type : ""; + invokeGuardedCallbackAndCatchFirstError(type, fn, undefined, value); + } finally { + isInsideEventHandler = previouslyInEventHandler; + } +} +function discreteUpdates(fn, a, b, c) { + var prevIsInsideEventHandler = isInsideEventHandler; + isInsideEventHandler = true; + + try { + return discreteUpdatesImpl(fn, a, b, c); + } finally { + isInsideEventHandler = prevIsInsideEventHandler; + if (!isInsideEventHandler) { + finishEventHandler(); + } + } +} +var lastFlushedEventTimeStamp = 0; +function flushDiscreteUpdatesIfNeeded(timeStamp) { + // event.timeStamp isn't overly reliable due to inconsistencies in + // how different browsers have historically provided the time stamp. + // Some browsers provide high-resolution time stamps for all events, + // some provide low-resolution time stamps for all events. FF < 52 + // even mixes both time stamps together. Some browsers even report + // negative time stamps or time stamps that are 0 (iOS9) in some cases. + // Given we are only comparing two time stamps with equality (!==), + // we are safe from the resolution differences. If the time stamp is 0 + // we bail-out of preventing the flush, which can affect semantics, + // such as if an earlier flush removes or adds event listeners that + // are fired in the subsequent flush. However, this is the same + // behaviour as we had before this change, so the risks are low. + if ( + !isInsideEventHandler && + (!enableFlareAPI || + timeStamp === 0 || + lastFlushedEventTimeStamp !== timeStamp) + ) { + lastFlushedEventTimeStamp = timeStamp; + flushDiscreteUpdatesImpl(); } } function setBatchingImplementation( @@ -3532,125 +3843,466 @@ function setBatchingImplementation( _batchedEventUpdatesImpl ) { batchedUpdatesImpl = _batchedUpdatesImpl; + discreteUpdatesImpl = _discreteUpdatesImpl; + flushDiscreteUpdatesImpl = _flushDiscreteUpdatesImpl; + batchedEventUpdatesImpl = _batchedEventUpdatesImpl; } -/** - * Internal queue of events that have accumulated their dispatches and are - * waiting to have their dispatches executed. - */ +function _inheritsLoose(subClass, superClass) { + subClass.prototype = Object.create(superClass.prototype); + subClass.prototype.constructor = subClass; + subClass.__proto__ = superClass; +} -var eventQueue = null; /** - * Dispatches an event and releases it back into the pool, unless persistent. - * - * @param {?object} event Synthetic event to be dispatched. - * @private + * Class only exists for its Flow type. */ +var ReactNativeComponent = + /*#__PURE__*/ + (function(_React$Component) { + _inheritsLoose(ReactNativeComponent, _React$Component); -var executeDispatchesAndRelease = function(event) { - if (event) { - executeDispatchesInOrder(event); - - if (!event.isPersistent()) { - event.constructor.release(event); + function ReactNativeComponent() { + return _React$Component.apply(this, arguments) || this; } - } -}; -var executeDispatchesAndReleaseTopLevel = function(e) { - return executeDispatchesAndRelease(e); -}; + var _proto = ReactNativeComponent.prototype; -function runEventsInBatch(events) { - if (events !== null) { - eventQueue = accumulateInto(eventQueue, events); - } // Set `eventQueue` to null before processing it so that we can tell if more - // events get enqueued while processing. + _proto.blur = function blur() {}; - var processingEventQueue = eventQueue; - eventQueue = null; + _proto.focus = function focus() {}; - if (!processingEventQueue) { - return; - } + _proto.measure = function measure(callback) {}; - forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseTopLevel); + _proto.measureInWindow = function measureInWindow(callback) {}; - if (!!eventQueue) { - throw Error( - "processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented." - ); - } // This would be a good time to rethrow if any of the event handlers threw. + _proto.measureLayout = function measureLayout( + relativeToNativeNode, + onSuccess, + onFail + ) {}; + + _proto.setNativeProps = function setNativeProps(nativeProps) {}; + + return ReactNativeComponent; + })(React.Component); // This type is only used for FlowTests. It shouldn't be imported directly + +var DiscreteEvent = 0; +var UserBlockingEvent = 1; +var ContinuousEvent = 2; + +// CommonJS interop named imports. + +var UserBlockingPriority = Scheduler.unstable_UserBlockingPriority; +var runWithPriority = Scheduler.unstable_runWithPriority; +var _nativeFabricUIManage$2 = nativeFabricUIManager; +var measureInWindow = _nativeFabricUIManage$2.measureInWindow; +var rootEventTypesToEventResponderInstances = new Map(); +var currentTimeStamp = 0; +var currentInstance = null; +var eventResponderContext = { + dispatchEvent: function(eventValue, eventListener, eventPriority) { + validateResponderContext(); + validateEventValue(eventValue); + + switch (eventPriority) { + case DiscreteEvent: { + flushDiscreteUpdatesIfNeeded(currentTimeStamp); + discreteUpdates(function() { + return executeUserEventHandler(eventListener, eventValue); + }); + break; + } - rethrowCaughtError(); -} + case UserBlockingEvent: { + runWithPriority(UserBlockingPriority, function() { + return executeUserEventHandler(eventListener, eventValue); + }); + break; + } -/** - * Allows registered plugins an opportunity to extract events from top-level - * native browser events. - * - * @return {*} An accumulation of synthetic events. - * @internal - */ + case ContinuousEvent: { + executeUserEventHandler(eventListener, eventValue); + break; + } + } + }, + isTargetWithinNode: function(childTarget, parentTarget) { + validateResponderContext(); + var childFiber = getFiberFromTarget(childTarget); + var parentFiber = getFiberFromTarget(parentTarget); + var node = childFiber; -function extractPluginEvents( - topLevelType, - targetInst, - nativeEvent, - nativeEventTarget, - eventSystemFlags -) { - var events = null; + while (node !== null) { + if (node === parentFiber) { + return true; + } - for (var i = 0; i < plugins.length; i++) { - // Not every plugin in the ordering may be loaded at runtime. - var possiblePlugin = plugins[i]; + node = node.return; + } - if (possiblePlugin) { - var extractedEvents = possiblePlugin.extractEvents( - topLevelType, - targetInst, - nativeEvent, - nativeEventTarget, - eventSystemFlags + return false; + }, + getTargetBoundingRect: function(target, callback) { + measureInWindow(target.node, function(x, y, width, height) { + callback({ + left: x, + right: x + width, + top: y, + bottom: y + height + }); + }); + }, + addRootEventTypes: function(rootEventTypes) { + validateResponderContext(); + for (var i = 0; i < rootEventTypes.length; i++) { + var rootEventType = rootEventTypes[i]; + var eventResponderInstance = currentInstance; + registerRootEventType(rootEventType, eventResponderInstance); + } + }, + removeRootEventTypes: function(rootEventTypes) { + validateResponderContext(); + + for (var i = 0; i < rootEventTypes.length; i++) { + var rootEventType = rootEventTypes[i]; + var rootEventResponders = rootEventTypesToEventResponderInstances.get( + rootEventType ); + var rootEventTypesSet = currentInstance.rootEventTypes; - if (extractedEvents) { - events = accumulateInto(events, extractedEvents); + if (rootEventTypesSet !== null) { + rootEventTypesSet.delete(rootEventType); } + + if (rootEventResponders !== undefined) { + rootEventResponders.delete(currentInstance); + } + } + }, + getTimeStamp: function() { + validateResponderContext(); + return currentTimeStamp; + }, + getResponderNode: function() { + validateResponderContext(); + var responderFiber = currentInstance.fiber; + + if (responderFiber.tag === ScopeComponent) { + return null; } + + return responderFiber.stateNode; } +}; - return events; -} +function validateEventValue(eventValue) { + if (typeof eventValue === "object" && eventValue !== null) { + var target = eventValue.target, + type = eventValue.type, + timeStamp = eventValue.timeStamp; -function runExtractedPluginEventsInBatch( - topLevelType, - targetInst, - nativeEvent, - nativeEventTarget, - eventSystemFlags -) { - var events = extractPluginEvents( - topLevelType, - targetInst, + if (target == null || type == null || timeStamp == null) { + throw new Error( + 'context.dispatchEvent: "target", "timeStamp", and "type" fields on event object are required.' + ); + } + var showWarning = function(name) { + { + warning$1( + false, + "%s is not available on event objects created from event responder modules (React Flare). " + + 'Try wrapping in a conditional, i.e. `if (event.type !== "press") { event.%s }`', + name, + name + ); + } + }; + eventValue.preventDefault = function() { + { + showWarning("preventDefault()"); + } + }; + eventValue.stopPropagation = function() { + { + showWarning("stopPropagation()"); + } + }; + eventValue.isDefaultPrevented = function() { + { + showWarning("isDefaultPrevented()"); + } + }; + eventValue.isPropagationStopped = function() { + { + showWarning("isPropagationStopped()"); + } + }; // $FlowFixMe: we don't need value, Flow thinks we do + + Object.defineProperty(eventValue, "nativeEvent", { + get: function() { + { + showWarning("nativeEvent"); + } + } + }); + } +} + +function getFiberFromTarget(target) { + if (target === null) { + return null; + } + + return target.canonical._internalInstanceHandle || null; +} + +function createFabricResponderEvent(topLevelType, nativeEvent, target) { + return { + nativeEvent: nativeEvent, + target: target, + type: topLevelType + }; +} + +function validateResponderContext() { + if (!currentInstance) { + throw Error( + "An event responder context was used outside of an event cycle." + ); + } +} // TODO this function is almost an exact copy of the DOM version, we should +// somehow share the logic + +function responderEventTypesContainType(eventTypes, type) { + for (var i = 0, len = eventTypes.length; i < len; i++) { + if (eventTypes[i] === type) { + return true; + } + } + return false; +} + +function validateResponderTargetEventTypes(eventType, responder) { + var targetEventTypes = responder.targetEventTypes; // Validate the target event type exists on the responder + + if (targetEventTypes !== null) { + return responderEventTypesContainType(targetEventTypes, eventType); + } + + return false; +} // TODO this function is almost an exact copy of the DOM version, we should +// somehow share the logic + +function traverseAndHandleEventResponderInstances( + eventType, + targetFiber, + nativeEvent +) { + // Trigger event responders in this order: + // - Bubble target responder phase + // - Root responder phase + var responderEvent = createFabricResponderEvent( + eventType, nativeEvent, - nativeEventTarget, - eventSystemFlags + targetFiber !== null ? targetFiber.stateNode : null ); - runEventsInBatch(events); + var visitedResponders = new Set(); + var node = targetFiber; + while (node !== null) { + var _node = node, + dependencies = _node.dependencies, + tag = _node.tag; + + if ( + (tag === HostComponent || tag === ScopeComponent) && + dependencies !== null + ) { + var respondersMap = dependencies.responders; + + if (respondersMap !== null) { + var responderInstances = Array.from(respondersMap.values()); + + for (var i = 0, length = responderInstances.length; i < length; i++) { + var responderInstance = responderInstances[i]; + var props = responderInstance.props, + responder = responderInstance.responder, + state = responderInstance.state; + + if ( + !visitedResponders.has(responder) && + validateResponderTargetEventTypes(eventType, responder) + ) { + var onEvent = responder.onEvent; + visitedResponders.add(responder); + + if (onEvent !== null) { + currentInstance = responderInstance; + onEvent(responderEvent, eventResponderContext, props, state); + } + } + } + } + } + + node = node.return; + } // Root phase + + var rootEventResponderInstances = rootEventTypesToEventResponderInstances.get( + eventType + ); + + if (rootEventResponderInstances !== undefined) { + var _responderInstances = Array.from(rootEventResponderInstances); + + for (var _i = 0; _i < _responderInstances.length; _i++) { + var _responderInstance = _responderInstances[_i]; + var props = _responderInstance.props, + responder = _responderInstance.responder, + state = _responderInstance.state; + var onRootEvent = responder.onRootEvent; + + if (onRootEvent !== null) { + currentInstance = _responderInstance; + onRootEvent(responderEvent, eventResponderContext, props, state); + } + } + } +} // TODO this function is almost an exact copy of the DOM version, we should +// somehow share the logic + +function dispatchEventForResponderEventSystem( + topLevelType, + targetFiber, + nativeEvent +) { + var previousInstance = currentInstance; + var previousTimeStamp = currentTimeStamp; // We might want to control timeStamp another way here + + currentTimeStamp = Date.now(); + + try { + batchedEventUpdates(function() { + traverseAndHandleEventResponderInstances( + topLevelType, + targetFiber, + nativeEvent + ); + }); + } finally { + currentInstance = previousInstance; + currentTimeStamp = previousTimeStamp; + } +} // TODO this function is almost an exact copy of the DOM version, we should +// somehow share the logic + +function mountEventResponder(responder, responderInstance, props, state) { + var onMount = responder.onMount; + + if (onMount !== null) { + currentInstance = responderInstance; + + try { + batchedEventUpdates(function() { + onMount(eventResponderContext, props, state); + }); + } finally { + currentInstance = null; + } + } +} // TODO this function is almost an exact copy of the DOM version, we should +// somehow share the logic + +function unmountEventResponder(responderInstance) { + var responder = responderInstance.responder; + var onUnmount = responder.onUnmount; + + if (onUnmount !== null) { + var props = responderInstance.props, + state = responderInstance.state; + currentInstance = responderInstance; + + try { + batchedEventUpdates(function() { + onUnmount(eventResponderContext, props, state); + }); + } finally { + currentInstance = null; + } + } + + var rootEventTypesSet = responderInstance.rootEventTypes; + + if (rootEventTypesSet !== null) { + var rootEventTypes = Array.from(rootEventTypesSet); + + for (var i = 0; i < rootEventTypes.length; i++) { + var topLevelEventType = rootEventTypes[i]; + var rootEventResponderInstances = rootEventTypesToEventResponderInstances.get( + topLevelEventType + ); + if (rootEventResponderInstances !== undefined) { + rootEventResponderInstances.delete(responderInstance); + } + } + } +} + +function registerRootEventType(rootEventType, responderInstance) { + var rootEventResponderInstances = rootEventTypesToEventResponderInstances.get( + rootEventType + ); + if (rootEventResponderInstances === undefined) { + rootEventResponderInstances = new Set(); + rootEventTypesToEventResponderInstances.set( + rootEventType, + rootEventResponderInstances + ); + } + + var rootEventTypesSet = responderInstance.rootEventTypes; + + if (rootEventTypesSet === null) { + rootEventTypesSet = responderInstance.rootEventTypes = new Set(); + } + + if (!!rootEventTypesSet.has(rootEventType)) { + throw Error( + 'addRootEventTypes() found a duplicate root event type of "' + + rootEventType + + '". This might be because the event type exists in the event responder "rootEventTypes" array or because of a previous addRootEventTypes() using this root event type.' + ); + } + + rootEventTypesSet.add(rootEventType); + rootEventResponderInstances.add(responderInstance); +} + +function addRootEventTypesForResponderInstance( + responderInstance, + rootEventTypes +) { + for (var i = 0; i < rootEventTypes.length; i++) { + var rootEventType = rootEventTypes[i]; + registerRootEventType(rootEventType, responderInstance); + } } function dispatchEvent(target, topLevelType, nativeEvent) { var targetFiber = target; - var eventTarget = null; + if (enableFlareAPI) { + // React Flare event system + dispatchEventForResponderEventSystem(topLevelType, target, nativeEvent); + } - if (targetFiber != null) { - var stateNode = targetFiber.stateNode; // Guard against Fiber being unmounted + var eventTarget = null; - if (stateNode != null) { - eventTarget = stateNode.canonical; + if (enableNativeTargetAsInstance) { + if (targetFiber != null) { + eventTarget = targetFiber.stateNode.canonical; } + } else { + eventTarget = nativeEvent.target; } batchedUpdates(function() { @@ -3677,7 +4329,20 @@ function shim() { } // Mutation (when unsupported) var supportsMutation = false; +var appendChild = shim; +var appendChildToContainer = shim; +var commitTextUpdate = shim; var commitMount = shim; +var commitUpdate = shim; +var insertBefore = shim; +var insertInContainerBefore = shim; +var removeChild = shim; +var removeChildFromContainer = shim; +var resetTextContent = shim; +var hideInstance = shim; +var hideTextInstance = shim; +var unhideInstance = shim; +var unhideTextInstance = shim; // can re-export everything from this module. @@ -3688,25 +4353,50 @@ function shim$1() { ); } } // Hydration (when unsupported) + +var supportsHydration = false; +var canHydrateInstance = shim$1; +var canHydrateTextInstance = shim$1; +var canHydrateSuspenseInstance = shim$1; var isSuspenseInstancePending = shim$1; var isSuspenseInstanceFallback = shim$1; +var registerSuspenseInstanceRetry = shim$1; +var getNextHydratableSibling = shim$1; +var getFirstHydratableChild = shim$1; +var hydrateInstance = 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 hydrateSuspenseInstance = shim$1; +var getNextHydratableInstanceAfterSuspenseInstance = shim$1; +var commitHydratedContainer = shim$1; +var commitHydratedSuspenseInstance = shim$1; +var clearSuspenseBoundary = shim$1; +var clearSuspenseBoundaryFromContainer = shim$1; +var didNotMatchHydratedContainerTextInstance = shim$1; +var didNotMatchHydratedTextInstance = shim$1; +var didNotHydrateContainerInstance = shim$1; +var didNotHydrateInstance = shim$1; +var didNotFindHydratableContainerInstance = shim$1; +var didNotFindHydratableContainerTextInstance = shim$1; +var didNotFindHydratableContainerSuspenseInstance = shim$1; +var didNotFindHydratableInstance = shim$1; +var didNotFindHydratableTextInstance = shim$1; +var didNotFindHydratableSuspenseInstance = shim$1; + +var _nativeFabricUIManage$1 = nativeFabricUIManager; +var createNode = _nativeFabricUIManage$1.createNode; +var cloneNode = _nativeFabricUIManage$1.cloneNode; +var cloneNodeWithNewChildren = _nativeFabricUIManage$1.cloneNodeWithNewChildren; +var cloneNodeWithNewChildrenAndProps = + _nativeFabricUIManage$1.cloneNodeWithNewChildrenAndProps; +var cloneNodeWithNewProps = _nativeFabricUIManage$1.cloneNodeWithNewProps; +var createChildNodeSet = _nativeFabricUIManage$1.createChildSet; +var appendChildNode = _nativeFabricUIManage$1.appendChild; +var appendChildNodeToSet = _nativeFabricUIManage$1.appendChildToSet; +var completeRoot = _nativeFabricUIManage$1.completeRoot; +var registerEventHandler = _nativeFabricUIManage$1.registerEventHandler; +var fabricMeasure = _nativeFabricUIManage$1.measure; +var fabricMeasureInWindow = _nativeFabricUIManage$1.measureInWindow; +var fabricMeasureLayout = _nativeFabricUIManage$1.measureLayout; var getViewConfigForType = ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get; // Counter for uniquely identifying views. // % 10 === 1 means it is a rootTag. @@ -3744,11 +4434,13 @@ var ReactFabricHostComponent = var _proto = ReactFabricHostComponent.prototype; _proto.blur = function blur() { - ReactNativePrivateInterface.TextInputState.blurTextInput(this); + ReactNativePrivateInterface.TextInputState.blurTextInput(this._nativeTag); }; _proto.focus = function focus() { - ReactNativePrivateInterface.TextInputState.focusTextInput(this); + ReactNativePrivateInterface.TextInputState.focusTextInput( + this._nativeTag + ); }; _proto.measure = function measure(callback) { @@ -3775,12 +4467,10 @@ var ReactFabricHostComponent = typeof relativeToNativeNode === "number" || !(relativeToNativeNode instanceof ReactFabricHostComponent) ) { - { - error( - "Warning: ref.measureLayout must be called with a ref to a native component." - ); - } - + warningWithoutStack$1( + false, + "Warning: ref.measureLayout must be called with a ref to a native component." + ); return; } @@ -3793,15 +4483,16 @@ var ReactFabricHostComponent = }; _proto.setNativeProps = function setNativeProps(nativeProps) { - { - error("Warning: setNativeProps is not currently supported in Fabric"); - } - + warningWithoutStack$1( + false, + "Warning: setNativeProps is not currently supported in Fabric" + ); return; }; return ReactFabricHostComponent; })(); // eslint-disable-next-line no-unused-expressions + function appendInitialChild(parentInstance, child) { appendChildNode(parentInstance.node, child.node); } @@ -3870,6 +4561,15 @@ function createTextInstance( node: node }; } +function finalizeInitialChildren( + parentInstance, + type, + props, + rootContainerInstance, + hostContext +) { + return false; +} function getRootHostContext(rootContainerInstance) { return { isInAParentText: false @@ -3929,9 +4629,17 @@ function shouldSetTextContent(type, props) { // More context @ github.com/facebook/react/pull/8560#discussion_r92111303 return false; } // The Fabric renderer is secondary to the existing React Native renderer. + +var isPrimaryRenderer = false; // The Fabric renderer shouldn't trigger missing act() warnings + +var warnsIfNotActing = false; var scheduleTimeout = setTimeout; var cancelTimeout = clearTimeout; var noTimeout = -1; // ------------------- +// Persistence +// ------------------- + +var supportsPersistence = true; function cloneInstance( instance, updatePayload, @@ -3958,7 +4666,6 @@ function cloneInstance( clone = cloneNodeWithNewChildren(node); } } - return { node: clone, canonical: instance.canonical @@ -3993,104 +4700,190 @@ function finalizeContainerChildren(container, newChildren) { completeRoot(container, newChildren); } -var loggedTypeFailures = {}; -function checkPropTypes(typeSpecs, values, location, componentName) { - { - // $FlowFixMe This is okay but Flow doesn't know it. - var has = Function.call.bind(Object.prototype.hasOwnProperty); +function mountResponderInstance( + responder, + responderInstance, + props, + state, + instance +) { + if (enableFlareAPI) { + var rootEventTypes = responder.rootEventTypes; - 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 (rootEventTypes !== null) { + addRootEventTypesForResponderInstance(responderInstance, rootEventTypes); + } - 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; - } + mountEventResponder(responder, responderInstance, props, state); + } +} +function unmountResponderInstance(responderInstance) { + if (enableFlareAPI) { + // TODO stop listening to targetEventTypes + unmountEventResponder(responderInstance); + } +} +function getFundamentalComponentInstance(fundamentalInstance) { + throw new Error("Not yet implemented."); +} +function mountFundamentalComponent(fundamentalInstance) { + throw new Error("Not yet implemented."); +} +function shouldUpdateFundamentalComponent(fundamentalInstance) { + throw new Error("Not yet implemented."); +} +function updateFundamentalComponent(fundamentalInstance) { + throw new Error("Not yet implemented."); +} +function unmountFundamentalComponent(fundamentalInstance) { + throw new Error("Not yet implemented."); +} +function cloneFundamentalInstance(fundamentalInstance) { + throw new Error("Not yet implemented."); +} +function getInstanceFromNode$1(node) { + throw new Error("Not yet implemented."); +} - 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 BEFORE_SLASH_RE = /^(.*)[\\\/]/; +var describeComponentFrame = function(name, source, ownerName) { + var sourceInfo = ""; - if (error$1 && !(error$1 instanceof Error)) { - 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 (source) { + var path = source.fileName; + var fileName = path.replace(BEFORE_SLASH_RE, ""); - 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; + { + // 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); - error("Failed %s type: %s", location, error$1.message); + 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 + ")"; } -} + return "\n in " + (name || "Unknown") + sourceInfo; +}; -// Prefix measurements so that it's possible to filter them. -// Longer prefixes are hard to read in DevTools. -var reactEmoji = "\u269B"; -var warningEmoji = "\u26D4"; -var supportsUserTiming = - typeof performance !== "undefined" && - typeof performance.mark === "function" && - typeof performance.clearMarks === "function" && - typeof performance.measure === "function" && - typeof performance.clearMeasures === "function"; // Keep track of current fiber so that we know the path to unwind on pause. -// TODO: this looks the same as nextUnitOfWork in scheduler. Can we unify them? +var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; -var currentFiber = null; // If we're in the middle of user code, which fiber and method is it? -// Reusing `currentFiber` would be confusing for this because user code fiber -// can change during commit phase too, but we don't need to unwind it (since -// lifecycles in the commit phase don't resemble a tree). +function describeFiber(fiber) { + switch (fiber.tag) { + case HostRoot: + case HostPortal: + case HostText: + case Fragment: + case ContextProvider: + case ContextConsumer: + return ""; + default: + var owner = fiber._debugOwner; + var source = fiber._debugSource; + var name = getComponentName(fiber.type); + var ownerName = null; -var currentPhase = null; -var currentPhaseFiber = null; // Did lifecycle hook schedule an update? This is often a performance problem, -// so we will keep track of it, and include it in the report. -// Track commits caused by cascading updates. + if (owner) { + ownerName = getComponentName(owner.type); + } -var isCommitting = false; -var hasScheduledUpdateInCurrentCommit = false; + return describeComponentFrame(name, source, ownerName); + } +} + +function getStackByFiberInDevAndProd(workInProgress) { + var info = ""; + var node = workInProgress; + do { + info += describeFiber(node); + node = node.return; + } while (node); + + return info; +} +var current = null; +var phase = null; +function getCurrentFiberOwnerNameInDevOrNull() { + { + if (current === null) { + return null; + } + + var owner = current._debugOwner; + + if (owner !== null && typeof owner !== "undefined") { + return getComponentName(owner.type); + } + } + + return null; +} +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. + + return getStackByFiberInDevAndProd(current); + } + + return ""; +} +function resetCurrentFiber() { + { + ReactDebugCurrentFrame.getCurrentStack = null; + current = null; + phase = null; + } +} +function setCurrentFiber(fiber) { + { + ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackInDev; + current = fiber; + phase = null; + } +} +function setCurrentPhase(lifeCyclePhase) { + { + phase = lifeCyclePhase; + } +} + +// Prefix measurements so that it's possible to filter them. +// Longer prefixes are hard to read in DevTools. +var reactEmoji = "\u269B"; +var warningEmoji = "\u26D4"; +var supportsUserTiming = + typeof performance !== "undefined" && + typeof performance.mark === "function" && + typeof performance.clearMarks === "function" && + typeof performance.measure === "function" && + typeof performance.clearMeasures === "function"; // Keep track of current fiber so that we know the path to unwind on pause. +// TODO: this looks the same as nextUnitOfWork in scheduler. Can we unify them? + +var currentFiber = null; // If we're in the middle of user code, which fiber and method is it? +// Reusing `currentFiber` would be confusing for this because user code fiber +// can change during commit phase too, but we don't need to unwind it (since +// lifecycles in the commit phase don't resemble a tree). + +var currentPhase = null; +var currentPhaseFiber = null; // Did lifecycle hook schedule an update? This is often a performance problem, +// so we will keep track of it, and include it in the report. +// Track commits caused by cascading updates. + +var isCommitting = false; +var hasScheduledUpdateInCurrentCommit = false; var hasScheduledUpdateInCurrentPhase = false; var commitCountInCurrentWorkLoop = 0; var effectCountInCurrentCommit = 0; @@ -4195,7 +4988,6 @@ var shouldIgnoreFiber = function(fiber) { case ContextConsumer: case Mode: return true; - default: return false; } @@ -4205,7 +4997,6 @@ var clearPendingPhaseMeasurement = function() { if (currentPhase !== null && currentPhaseFiber !== null) { clearFiberMark(currentPhaseFiber, currentPhase); } - currentPhaseFiber = null; currentPhase = null; hasScheduledUpdateInCurrentPhase = false; @@ -4215,12 +5006,10 @@ var pauseTimers = function() { // Stops all currently active measurements so that they can be resumed // if we continue in a later deferred loop from the same unit of work. var fiber = currentFiber; - while (fiber) { if (fiber._debugIsCurrentlyTiming) { endFiberMark(fiber, null, null); } - fiber = fiber.return; } }; @@ -4229,7 +5018,6 @@ var resumeTimersRecursively = function(fiber) { if (fiber.return !== null) { resumeTimersRecursively(fiber.return); } - if (fiber._debugIsCurrentlyTiming) { beginFiberMark(fiber, null); } @@ -4243,16 +5031,15 @@ var resumeTimers = function() { }; function recordEffect() { - { + if (enableUserTimingAPI) { effectCountInCurrentCommit++; } } function recordScheduleUpdate() { - { + if (enableUserTimingAPI) { if (isCommitting) { hasScheduledUpdateInCurrentCommit = true; } - if ( currentPhase !== null && currentPhase !== "componentWillMount" && @@ -4262,8 +5049,9 @@ function recordScheduleUpdate() { } } } + function startWorkTimer(fiber) { - { + if (enableUserTimingAPI) { if (!supportsUserTiming || shouldIgnoreFiber(fiber)) { return; } // If we pause, this is the fiber to unwind from. @@ -4278,7 +5066,7 @@ function startWorkTimer(fiber) { } } function cancelWorkTimer(fiber) { - { + if (enableUserTimingAPI) { if (!supportsUserTiming || shouldIgnoreFiber(fiber)) { return; } // Remember we shouldn't complete measurement for this fiber. @@ -4289,7 +5077,7 @@ function cancelWorkTimer(fiber) { } } function stopWorkTimer(fiber) { - { + if (enableUserTimingAPI) { if (!supportsUserTiming || shouldIgnoreFiber(fiber)) { return; } // If we pause, its parent is the fiber to unwind from. @@ -4305,7 +5093,7 @@ function stopWorkTimer(fiber) { } } function stopFailedWorkTimer(fiber) { - { + if (enableUserTimingAPI) { if (!supportsUserTiming || shouldIgnoreFiber(fiber)) { return; } // If we pause, its parent is the fiber to unwind from. @@ -4325,7 +5113,7 @@ function stopFailedWorkTimer(fiber) { } } function startPhaseTimer(fiber, phase) { - { + if (enableUserTimingAPI) { if (!supportsUserTiming) { return; } @@ -4341,24 +5129,22 @@ function startPhaseTimer(fiber, phase) { } } function stopPhaseTimer() { - { + if (enableUserTimingAPI) { if (!supportsUserTiming) { return; } - if (currentPhase !== null && currentPhaseFiber !== null) { var warning = hasScheduledUpdateInCurrentPhase ? "Scheduled a cascading update" : null; endFiberMark(currentPhaseFiber, currentPhase, warning); } - currentPhase = null; currentPhaseFiber = null; } } function startWorkLoopTimer(nextUnitOfWork) { - { + if (enableUserTimingAPI) { currentFiber = nextUnitOfWork; if (!supportsUserTiming) { @@ -4374,7 +5160,7 @@ function startWorkLoopTimer(nextUnitOfWork) { } } function stopWorkLoopTimer(interruptedBy, didCompleteRoot) { - { + if (enableUserTimingAPI) { if (!supportsUserTiming) { return; } @@ -4403,11 +5189,10 @@ function stopWorkLoopTimer(interruptedBy, didCompleteRoot) { } } function startCommitTimer() { - { + if (enableUserTimingAPI) { if (!supportsUserTiming) { return; } - isCommitting = true; hasScheduledUpdateInCurrentCommit = false; labelsInCurrentCommit.clear(); @@ -4415,19 +5200,17 @@ function startCommitTimer() { } } function stopCommitTimer() { - { + if (enableUserTimingAPI) { if (!supportsUserTiming) { return; } var warning = null; - if (hasScheduledUpdateInCurrentCommit) { warning = "Lifecycle hook scheduled a cascading update"; } else if (commitCountInCurrentWorkLoop > 0) { warning = "Caused by a cascading update in earlier commit"; } - hasScheduledUpdateInCurrentCommit = false; commitCountInCurrentWorkLoop++; isCommitting = false; @@ -4436,21 +5219,19 @@ function stopCommitTimer() { } } function startCommitSnapshotEffectsTimer() { - { + if (enableUserTimingAPI) { if (!supportsUserTiming) { return; } - effectCountInCurrentCommit = 0; beginMark("(Committing Snapshot Effects)"); } } function stopCommitSnapshotEffectsTimer() { - { + if (enableUserTimingAPI) { if (!supportsUserTiming) { return; } - var count = effectCountInCurrentCommit; effectCountInCurrentCommit = 0; endMark( @@ -4461,21 +5242,19 @@ function stopCommitSnapshotEffectsTimer() { } } function startCommitHostEffectsTimer() { - { + if (enableUserTimingAPI) { if (!supportsUserTiming) { return; } - effectCountInCurrentCommit = 0; beginMark("(Committing Host Effects)"); } } function stopCommitHostEffectsTimer() { - { + if (enableUserTimingAPI) { if (!supportsUserTiming) { return; } - var count = effectCountInCurrentCommit; effectCountInCurrentCommit = 0; endMark( @@ -4486,21 +5265,19 @@ function stopCommitHostEffectsTimer() { } } function startCommitLifeCyclesTimer() { - { + if (enableUserTimingAPI) { if (!supportsUserTiming) { return; } - effectCountInCurrentCommit = 0; beginMark("(Calling Lifecycle Methods)"); } } function stopCommitLifeCyclesTimer() { - { + if (enableUserTimingAPI) { if (!supportsUserTiming) { return; } - var count = effectCountInCurrentCommit; effectCountInCurrentCommit = 0; endMark( @@ -4529,15 +5306,14 @@ function createCursor(defaultValue) { function pop(cursor, fiber) { if (index < 0) { { - error("Unexpected pop."); + warningWithoutStack$1(false, "Unexpected pop."); } - return; } { if (fiber !== fiberStack[index]) { - error("Unexpected Fiber popped."); + warningWithoutStack$1(false, "Unexpected Fiber popped."); } } @@ -4587,7 +5363,9 @@ function getUnmaskedContext( Component, didPushOwnContextIfProvider ) { - { + if (disableLegacyContext) { + return emptyContextObject; + } else { 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 @@ -4595,13 +5373,14 @@ function getUnmaskedContext( // previous (parent) context instead for a context provider. return previousContext; } - return contextStackCursor.current; } } function cacheContext(workInProgress, unmaskedContext, maskedContext) { - { + if (disableLegacyContext) { + return; + } else { var instance = workInProgress.stateNode; instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext; instance.__reactInternalMemoizedMaskedChildContext = maskedContext; @@ -4609,7 +5388,9 @@ function cacheContext(workInProgress, unmaskedContext, maskedContext) { } function getMaskedContext(workInProgress, unmaskedContext) { - { + if (disableLegacyContext) { + return emptyContextObject; + } else { var type = workInProgress.type; var contextTypes = type.contextTypes; @@ -4629,14 +5410,19 @@ function getMaskedContext(workInProgress, unmaskedContext) { } var context = {}; - for (var key in contextTypes) { context[key] = unmaskedContext[key]; } { var name = getComponentName(type) || "Unknown"; - checkPropTypes(contextTypes, context, "context", name); + checkPropTypes( + contextTypes, + context, + "context", + name, + getCurrentFiberStackInDev + ); } // 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. @@ -4649,34 +5435,44 @@ function getMaskedContext(workInProgress, unmaskedContext) { } function hasContextChanged() { - { + if (disableLegacyContext) { + return false; + } else { return didPerformWorkStackCursor.current; } } function isContextProvider(type) { - { + if (disableLegacyContext) { + return false; + } else { var childContextTypes = type.childContextTypes; return childContextTypes !== null && childContextTypes !== undefined; } } function popContext(fiber) { - { + if (disableLegacyContext) { + return; + } else { pop(didPerformWorkStackCursor, fiber); pop(contextStackCursor, fiber); } } function popTopLevelContextObject(fiber) { - { + if (disableLegacyContext) { + return; + } else { pop(didPerformWorkStackCursor, fiber); pop(contextStackCursor, fiber); } } function pushTopLevelContextObject(fiber, context, didChange) { - { + if (disableLegacyContext) { + return; + } else { 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." @@ -4689,7 +5485,9 @@ function pushTopLevelContextObject(fiber, context, didChange) { } function processChildContext(fiber, type, parentContext) { - { + if (disableLegacyContext) { + return parentContext; + } else { 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. @@ -4700,8 +5498,8 @@ function processChildContext(fiber, type, parentContext) { if (!warnedAboutMissingGetChildContext[componentName]) { warnedAboutMissingGetChildContext[componentName] = true; - - error( + warningWithoutStack$1( + false, "%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.", @@ -4715,10 +5513,19 @@ function processChildContext(fiber, type, parentContext) { } var childContext; + + { + setCurrentPhase("getChildContext"); + } + startPhaseTimer(fiber, "getChildContext"); childContext = instance.getChildContext(); stopPhaseTimer(); + { + setCurrentPhase(null); + } + for (var contextKey in childContext) { if (!(contextKey in childContextTypes)) { throw Error( @@ -4732,7 +5539,17 @@ function processChildContext(fiber, type, parentContext) { { var name = getComponentName(type) || "Unknown"; - checkPropTypes(childContextTypes, childContext, "child context", name); + checkPropTypes( + childContextTypes, + childContext, + "child context", + name, // In practice, there is one case in which we won't get a stack. It's when + // somebody calls unstable_renderSubtreeIntoContainer() and we process + // context from the parent component instance. The stack will be missing + // because it's outside of the reconciliation, and so the pointer has not + // been set. This is rare and doesn't matter. We'll also remove that API. + getCurrentFiberStackInDev + ); } return Object.assign({}, parentContext, {}, childContext); @@ -4740,7 +5557,9 @@ function processChildContext(fiber, type, parentContext) { } function pushContextProvider(workInProgress) { - { + if (disableLegacyContext) { + return false; + } else { 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. @@ -4762,7 +5581,9 @@ function pushContextProvider(workInProgress) { } function invalidateContextProvider(workInProgress, type, didChange) { - { + if (disableLegacyContext) { + return; + } else { var instance = workInProgress.stateNode; if (!instance) { @@ -4796,7 +5617,9 @@ function invalidateContextProvider(workInProgress, type, didChange) { } function findCurrentUnmaskedContext(fiber) { - { + if (disableLegacyContext) { + return emptyContextObject; + } else { // Currently this is only used with renderSubtreeIntoContainer; not sure if it // makes sense elsewhere if (!(isFiberMounted(fiber) && fiber.tag === ClassComponent)) { @@ -4839,21 +5662,22 @@ var BlockingRoot = 1; var ConcurrentRoot = 2; // 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; - -{ +// CommonJS interop named imports. +var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority; +var Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback; +var Scheduler_cancelCallback = Scheduler.unstable_cancelCallback; +var Scheduler_shouldYield = Scheduler.unstable_shouldYield; +var Scheduler_requestPaint = Scheduler.unstable_requestPaint; +var Scheduler_now = Scheduler.unstable_now; +var Scheduler_getCurrentPriorityLevel = + Scheduler.unstable_getCurrentPriorityLevel; +var Scheduler_ImmediatePriority = Scheduler.unstable_ImmediatePriority; +var Scheduler_UserBlockingPriority = Scheduler.unstable_UserBlockingPriority; +var Scheduler_NormalPriority = Scheduler.unstable_NormalPriority; +var Scheduler_LowPriority = Scheduler.unstable_LowPriority; +var Scheduler_IdlePriority = Scheduler.unstable_IdlePriority; + +if (enableSchedulerTracing) { // Provide explicit error message when production+profiling bundle of e.g. // react-dom is used with production (non-profiling) bundle of // scheduler/tracing @@ -4874,7 +5698,7 @@ var fakeCallbackNode = {}; // Except for NoPriority, these correspond to Schedul // avoid clashing with Scheduler's priorities. var ImmediatePriority = 99; -var UserBlockingPriority = 98; +var UserBlockingPriority$1 = 98; var NormalPriority = 97; var LowPriority = 96; var IdlePriority = 95; // NoPriority is the absence of priority. Also React-only. @@ -4893,7 +5717,6 @@ var initialTimeMs = Scheduler_now(); // If the initial timestamp is reasonably s // 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 @@ -4906,7 +5729,7 @@ function getCurrentPriorityLevel() { return ImmediatePriority; case Scheduler_UserBlockingPriority: - return UserBlockingPriority; + return UserBlockingPriority$1; case Scheduler_NormalPriority: return NormalPriority; @@ -4928,7 +5751,7 @@ function reactPriorityToSchedulerPriority(reactPriorityLevel) { case ImmediatePriority: return Scheduler_ImmediatePriority; - case UserBlockingPriority: + case UserBlockingPriority$1: return Scheduler_UserBlockingPriority; case NormalPriority: @@ -4946,7 +5769,7 @@ function reactPriorityToSchedulerPriority(reactPriorityLevel) { } } -function runWithPriority(reactPriorityLevel, fn) { +function runWithPriority$1(reactPriorityLevel, fn) { var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); return Scheduler_runWithPriority(priorityLevel, fn); } @@ -4992,14 +5815,12 @@ function flushSyncCallbackQueueImpl() { // Prevent re-entrancy. isFlushingSyncQueue = true; var i = 0; - try { var _isSync = true; var queue = syncQueue; - runWithPriority(ImmediatePriority, function() { + runWithPriority$1(ImmediatePriority, function() { for (; i < queue.length; i++) { var callback = queue[i]; - do { callback = callback(_isSync); } while (callback !== null); @@ -5047,14 +5868,14 @@ var NoWork = 0; // TODO: Think of a better name for Never. The key difference wi var Never = 1; // Idle is slightly higher priority than Never. It must completely finish in // order to be consistent. -var Idle = 2; // Continuous Hydration is slightly higher than Idle and is used to increase +var Idle = 2; // Continuous Hydration is a moving priority. It is slightly higher than Idle var Sync = MAX_SIGNED_31_BIT_INT; var Batched = Sync - 1; var UNIT_SIZE = 10; var MAGIC_NUMBER_OFFSET = Batched - 1; // 1 unit of expiration time represents 10ms. function msToExpirationTime(ms) { - // Always subtract from the offset so that we don't clash with the magic number for NoWork. + // Always add an offset so that we don't clash with the magic number for NoWork. return MAGIC_NUMBER_OFFSET - ((ms / UNIT_SIZE) | 0); } function expirationTimeToMs(expirationTime) { @@ -5113,6 +5934,7 @@ function computeInteractiveExpiration(currentTime) { HIGH_PRIORITY_BATCH_SIZE ); } + function inferPriorityFromExpirationTime(currentTime, expirationTime) { if (expirationTime === Sync) { return ImmediatePriority; @@ -5130,7 +5952,7 @@ function inferPriorityFromExpirationTime(currentTime, expirationTime) { } if (msUntil <= HIGH_PRIORITY_EXPIRATION + HIGH_PRIORITY_BATCH_SIZE) { - return UserBlockingPriority; + return UserBlockingPriority$1; } if (msUntil <= LOW_PRIORITY_EXPIRATION + LOW_PRIORITY_BATCH_SIZE) { @@ -5151,7 +5973,7 @@ function is(x, y) { ); } -var objectIs = typeof Object.is === "function" ? Object.is : is; +var is$1 = typeof Object.is === "function" ? Object.is : is; var hasOwnProperty = Object.prototype.hasOwnProperty; /** @@ -5161,7 +5983,7 @@ var hasOwnProperty = Object.prototype.hasOwnProperty; */ function shallowEqual(objA, objB) { - if (objectIs(objA, objB)) { + if (is$1(objA, objB)) { return true; } @@ -5184,7 +6006,7 @@ function shallowEqual(objA, objB) { for (var i = 0; i < keysA.length; i++) { if ( !hasOwnProperty.call(objB, keysA[i]) || - !objectIs(objA[keysA[i]], objB[keysA[i]]) + !is$1(objA[keysA[i]], objB[keysA[i]]) ) { return false; } @@ -5193,122 +6015,77 @@ function shallowEqual(objA, objB) { return true; } -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]; +/** + * Forked from fbjs/warning: + * https://github.com/facebook/fbjs/blob/e66ba20ad5be433eb54423f2b097d829324d9de6/packages/fbjs/src/__forks__/warning.js + * + * Only change is we use console.warn instead of console.error, + * and do nothing when 'console' is not supported. + * This really simplifies the code. + * --- + * Similar to invariant but only logs a warning if the condition is not met. + * This can be used to log issues in development environments in critical + * paths. Removing the logging code for production environments will keep the + * same logic and follow the same code paths. + */ +var lowPriorityWarningWithoutStack = function() {}; - if (pathBeforeSlash) { - var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, ""); - fileName = folderName + "/" + fileName; - } - } - } +{ + var printWarning = function(format) { + for ( + var _len = arguments.length, + args = new Array(_len > 1 ? _len - 1 : 0), + _key = 1; + _key < _len; + _key++ + ) { + args[_key - 1] = arguments[_key]; } - sourceInfo = " (at " + fileName + ":" + source.lineNumber + ")"; - } else if (ownerName) { - sourceInfo = " (created by " + ownerName + ")"; - } - - return "\n in " + (name || "Unknown") + sourceInfo; -} + var argIndex = 0; + var message = + "Warning: " + + format.replace(/%s/g, function() { + return args[argIndex++]; + }); -var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; + if (typeof console !== "undefined") { + console.warn(message); + } -function describeFiber(fiber) { - switch (fiber.tag) { - case HostRoot: - case HostPortal: - case HostText: - case Fragment: - case ContextProvider: - case ContextConsumer: - return ""; + try { + // --- Welcome to debugging React --- + // This error was thrown as a convenience so that you can use this stack + // to find the callsite that caused this warning to fire. + throw new Error(message); + } catch (x) {} + }; - default: - var owner = fiber._debugOwner; - var source = fiber._debugSource; - var name = getComponentName(fiber.type); - var ownerName = null; + lowPriorityWarningWithoutStack = function(condition, format) { + if (format === undefined) { + throw new Error( + "`lowPriorityWarningWithoutStack(condition, format, ...args)` requires a warning " + + "message argument" + ); + } - if (owner) { - ownerName = getComponentName(owner.type); + if (!condition) { + for ( + var _len2 = arguments.length, + args = new Array(_len2 > 2 ? _len2 - 2 : 0), + _key2 = 2; + _key2 < _len2; + _key2++ + ) { + args[_key2 - 2] = arguments[_key2]; } - return describeComponentFrame(name, source, ownerName); - } + printWarning.apply(void 0, [format].concat(args)); + } + }; } -function getStackByFiberInDevAndProd(workInProgress) { - var info = ""; - var node = workInProgress; - - do { - info += describeFiber(node); - node = node.return; - } while (node); - - return info; -} -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); - } - } - - return null; -} -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. - - return getStackByFiberInDevAndProd(current); - } -} -function resetCurrentFiber() { - { - ReactDebugCurrentFrame.getCurrentStack = null; - current = null; - isRendering = false; - } -} -function setCurrentFiber(fiber) { - { - ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackInDev; - current = fiber; - isRendering = false; - } -} -function setIsRendering(rendering) { - { - isRendering = rendering; - } -} +var lowPriorityWarningWithoutStack$1 = lowPriorityWarningWithoutStack; var ReactStrictModeWarnings = { recordUnsafeLifecycleWarnings: function(fiber, instance) {}, @@ -5327,7 +6104,6 @@ var ReactStrictModeWarnings = { if (node.mode & StrictMode) { maybeStrictRoot = node; } - node = node.return; } @@ -5406,7 +6182,6 @@ var ReactStrictModeWarnings = { ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function() { // We do an initial pass to gather component names var componentWillMountUniqueNames = new Set(); - if (pendingComponentWillMountWarnings.length > 0) { pendingComponentWillMountWarnings.forEach(function(fiber) { componentWillMountUniqueNames.add( @@ -5418,7 +6193,6 @@ var ReactStrictModeWarnings = { } var UNSAFE_componentWillMountUniqueNames = new Set(); - if (pendingUNSAFE_ComponentWillMountWarnings.length > 0) { pendingUNSAFE_ComponentWillMountWarnings.forEach(function(fiber) { UNSAFE_componentWillMountUniqueNames.add( @@ -5430,7 +6204,6 @@ var ReactStrictModeWarnings = { } var componentWillReceivePropsUniqueNames = new Set(); - if (pendingComponentWillReceivePropsWarnings.length > 0) { pendingComponentWillReceivePropsWarnings.forEach(function(fiber) { componentWillReceivePropsUniqueNames.add( @@ -5442,7 +6215,6 @@ var ReactStrictModeWarnings = { } var UNSAFE_componentWillReceivePropsUniqueNames = new Set(); - if (pendingUNSAFE_ComponentWillReceivePropsWarnings.length > 0) { pendingUNSAFE_ComponentWillReceivePropsWarnings.forEach(function(fiber) { UNSAFE_componentWillReceivePropsUniqueNames.add( @@ -5454,7 +6226,6 @@ var ReactStrictModeWarnings = { } var componentWillUpdateUniqueNames = new Set(); - if (pendingComponentWillUpdateWarnings.length > 0) { pendingComponentWillUpdateWarnings.forEach(function(fiber) { componentWillUpdateUniqueNames.add( @@ -5466,7 +6237,6 @@ var ReactStrictModeWarnings = { } var UNSAFE_componentWillUpdateUniqueNames = new Set(); - if (pendingUNSAFE_ComponentWillUpdateWarnings.length > 0) { pendingUNSAFE_ComponentWillUpdateWarnings.forEach(function(fiber) { UNSAFE_componentWillUpdateUniqueNames.add( @@ -5480,8 +6250,8 @@ var ReactStrictModeWarnings = { if (UNSAFE_componentWillMountUniqueNames.size > 0) { var sortedNames = setToSortedString(UNSAFE_componentWillMountUniqueNames); - - error( + warningWithoutStack$1( + false, "Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. " + "See https://fb.me/react-unsafe-component-lifecycles for details.\n\n" + "* Move code with side effects to componentDidMount, and set initial state in the constructor.\n" + @@ -5494,8 +6264,8 @@ var ReactStrictModeWarnings = { var _sortedNames = setToSortedString( UNSAFE_componentWillReceivePropsUniqueNames ); - - error( + warningWithoutStack$1( + false, "Using UNSAFE_componentWillReceiveProps in strict mode is not recommended " + "and may indicate bugs in your code. " + "See https://fb.me/react-unsafe-component-lifecycles for details.\n\n" + @@ -5512,8 +6282,8 @@ var ReactStrictModeWarnings = { var _sortedNames2 = setToSortedString( UNSAFE_componentWillUpdateUniqueNames ); - - error( + warningWithoutStack$1( + false, "Using UNSAFE_componentWillUpdate in strict mode is not recommended " + "and may indicate bugs in your code. " + "See https://fb.me/react-unsafe-component-lifecycles for details.\n\n" + @@ -5526,7 +6296,8 @@ var ReactStrictModeWarnings = { if (componentWillMountUniqueNames.size > 0) { var _sortedNames3 = setToSortedString(componentWillMountUniqueNames); - warn( + lowPriorityWarningWithoutStack$1( + false, "componentWillMount has been renamed, and is not recommended for use. " + "See https://fb.me/react-unsafe-component-lifecycles for details.\n\n" + "* Move code with side effects to componentDidMount, and set initial state in the constructor.\n" + @@ -5544,7 +6315,8 @@ var ReactStrictModeWarnings = { componentWillReceivePropsUniqueNames ); - warn( + lowPriorityWarningWithoutStack$1( + false, "componentWillReceiveProps has been renamed, and is not recommended for use. " + "See https://fb.me/react-unsafe-component-lifecycles for details.\n\n" + "* Move data fetching code or side effects to componentDidUpdate.\n" + @@ -5563,7 +6335,8 @@ var ReactStrictModeWarnings = { if (componentWillUpdateUniqueNames.size > 0) { var _sortedNames5 = setToSortedString(componentWillUpdateUniqueNames); - warn( + lowPriorityWarningWithoutStack$1( + false, "componentWillUpdate has been renamed, and is not recommended for use. " + "See https://fb.me/react-unsafe-component-lifecycles for details.\n\n" + "* Move data fetching code or side effects to componentDidUpdate.\n" + @@ -5586,13 +6359,12 @@ var ReactStrictModeWarnings = { instance ) { var strictRoot = findStrictRoot(fiber); - if (strictRoot === null) { - error( + warningWithoutStack$1( + false, "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." ); - return; } // Dedup strategy: Warn once per component. @@ -5611,27 +6383,21 @@ var ReactStrictModeWarnings = { warningsForRoot = []; pendingLegacyContextWarning.set(strictRoot, warningsForRoot); } - warningsForRoot.push(fiber); } }; ReactStrictModeWarnings.flushLegacyContextWarning = function() { pendingLegacyContextWarning.forEach(function(fiberArray, strictRoot) { - if (fiberArray.length === 0) { - return; - } - - 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); - var firstComponentStack = getStackByFiberInDevAndProd(firstFiber); - - error( + var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot); + warningWithoutStack$1( + false, "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." + @@ -5639,7 +6405,7 @@ var ReactStrictModeWarnings = { "\n\nLearn more about this warning here: https://fb.me/react-legacy-context" + "%s", sortedNames, - firstComponentStack + strictRootComponentStack ); }); }; @@ -5703,7 +6469,6 @@ function resolveForwardRefForHotReloading(type) { // but it's possible that we only have its inner render function in the map. // If that inner render function is different, we'll build a new forwardRef type. var currentRender = resolveFunctionForHotReloading(type.render); - if (type.render !== currentRender) { var syntheticType = { $$typeof: REACT_FORWARD_REF_TYPE, @@ -5797,7 +6562,6 @@ function isCompatibleFamilyForHotReloading(fiber, element) { // then we would risk falsely saying two separate memo(Foo) // calls are equivalent because they wrap the same Foo function. var prevFamily = resolveFamily(prevType); - if (prevFamily !== undefined && prevFamily === resolveFamily(nextType)) { return true; } @@ -5882,6 +6646,9 @@ function scheduleFibersWithFamiliesRecursively( case ForwardRef: candidateType = type.render; break; + + default: + break; } if (resolveFamily === null) { @@ -5906,7 +6673,6 @@ function scheduleFibersWithFamiliesRecursively( } } } - if (failedBoundaries !== null) { if ( failedBoundaries.has(fiber) || @@ -5931,7 +6697,6 @@ function scheduleFibersWithFamiliesRecursively( staleFamilies ); } - if (sibling !== null) { scheduleFibersWithFamiliesRecursively( sibling, @@ -5981,10 +6746,12 @@ function findHostInstancesForMatchingFibersRecursively( case ForwardRef: candidateType = type.render; break; + + default: + break; } var didMatch = false; - if (candidateType !== null) { if (types.has(candidateType)) { didMatch = true; @@ -6058,7 +6825,6 @@ function findChildHostInstancesForFiberShallowly(fiber, hostInstances) { { var node = fiber; var foundHostInstances = false; - while (true) { if (node.tag === HostComponent) { // We got a match. @@ -6086,7 +6852,6 @@ function findChildHostInstancesForFiberShallowly(fiber, hostInstances) { node = node.sibling; } } - return false; } @@ -6095,7 +6860,6 @@ function resolveDefaultProps(Component, baseProps) { // 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]; @@ -6135,7 +6899,6 @@ function resetContextDependencies() { currentlyRenderingFiber = null; lastContextDependency = null; lastContextWithAllBitsObserved = null; - { isDisallowedContextReadInDEV = false; } @@ -6153,22 +6916,40 @@ function exitDisallowedContextReadInDEV() { function pushProvider(providerFiber, nextValue) { var context = providerFiber.type._context; - { + if (isPrimaryRenderer) { + push(valueCursor, context._currentValue, providerFiber); + context._currentValue = nextValue; + + { + !( + context._currentRenderer === undefined || + context._currentRenderer === null || + context._currentRenderer === rendererSigil + ) + ? warningWithoutStack$1( + false, + "Detected multiple renderers concurrently rendering the " + + "same context provider. This is currently unsupported." + ) + : void 0; + context._currentRenderer = rendererSigil; + } + } else { 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 === undefined || + context._currentRenderer2 === null || + context._currentRenderer2 === rendererSigil + ) + ? warningWithoutStack$1( + false, + "Detected multiple renderers concurrently rendering the " + + "same context provider. This is currently unsupported." + ) + : void 0; context._currentRenderer2 = rendererSigil; } } @@ -6178,12 +6959,14 @@ function popProvider(providerFiber) { pop(valueCursor, providerFiber); var context = providerFiber.type._context; - { + if (isPrimaryRenderer) { + context._currentValue = currentValue; + } else { context._currentValue2 = currentValue; } } function calculateChangedBits(context, newValue, oldValue) { - if (objectIs(oldValue, newValue)) { + if (is$1(oldValue, newValue)) { // No change return 0; } else { @@ -6193,13 +6976,14 @@ function calculateChangedBits(context, newValue, oldValue) { : MAX_SIGNED_31_BIT_INT; { - if ((changedBits & MAX_SIGNED_31_BIT_INT) !== changedBits) { - error( - "calculateChangedBits: Expected the return value to be a " + - "31-bit integer. Instead received: %s", - changedBits - ); - } + !((changedBits & MAX_SIGNED_31_BIT_INT) === changedBits) + ? warning$1( + false, + "calculateChangedBits: Expected the return value to be a " + + "31-bit integer. Instead received: %s", + changedBits + ) + : void 0; } return changedBits | 0; @@ -6243,7 +7027,6 @@ function propagateContextChange( renderExpirationTime ) { var fiber = workInProgress.child; - if (fiber !== null) { // Set the return pointer of the child to the work-in-progress fiber. fiber.return = workInProgress; @@ -6304,6 +7087,39 @@ function propagateContextChange( } else if (fiber.tag === ContextProvider) { // Don't scan deeper if this is a matching provider nextFiber = fiber.type === workInProgress.type ? null : fiber.child; + } else if ( + enableSuspenseServerRenderer && + fiber.tag === DehydratedFragment + ) { + // If a dehydrated suspense bounudary is in this subtree, we don't know + // if it will have any context consumers in it. The best we can do is + // mark it as having updates. + var parentSuspense = fiber.return; + + if (!(parentSuspense !== null)) { + throw Error( + "We just came from a parent so we must have had a parent. This is a bug in React." + ); + } + + if (parentSuspense.expirationTime < renderExpirationTime) { + parentSuspense.expirationTime = renderExpirationTime; + } + + var _alternate = parentSuspense.alternate; + + if ( + _alternate !== null && + _alternate.expirationTime < renderExpirationTime + ) { + _alternate.expirationTime = renderExpirationTime; + } // This is intentionally passing this fiber as the parent + // because we want to schedule this fiber as having work + // on its children. We'll use the childExpirationTime on + // this fiber to indicate that a context has changed. + + scheduleWorkOnParentPath(parentSuspense, renderExpirationTime); + nextFiber = fiber.sibling; } else { // Traverse down. nextFiber = fiber.child; @@ -6315,7 +7131,6 @@ function propagateContextChange( } 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. @@ -6362,19 +7177,22 @@ 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()." - ); - } + !!isDisallowedContextReadInDEV + ? warning$1( + false, + "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()." + ) + : void 0; } - if (lastContextWithAllBitsObserved === context); - else if (observedBits === false || observedBits === 0); - else { + if (lastContextWithAllBitsObserved === context) { + // Nothing to do. We already observe everything in this context. + } else if (observedBits === false || observedBits === 0) { + // Do not observe any updates. + } else { var resolvedObservedBits; // Avoid deopting on observable arguments or heterogeneous types. if ( @@ -6412,10 +7230,85 @@ function readContext(context, observedBits) { lastContextDependency = lastContextDependency.next = contextItem; } } - - return context._currentValue2; + return isPrimaryRenderer ? context._currentValue : context._currentValue2; } +// UpdateQueue is a linked list of prioritized updates. +// +// Like fibers, update queues come in pairs: a current queue, which represents +// the visible state of the screen, and a work-in-progress queue, which can be +// mutated and processed asynchronously before it is committed — a form of +// double buffering. If a work-in-progress render is discarded before finishing, +// we create a new work-in-progress by cloning the current queue. +// +// Both queues share a persistent, singly-linked list structure. To schedule an +// update, we append it to the end of both queues. Each queue maintains a +// pointer to first update in the persistent list that hasn't been processed. +// The work-in-progress pointer always has a position equal to or greater than +// the current queue, since we always work on that one. The current queue's +// pointer is only updated during the commit phase, when we swap in the +// work-in-progress. +// +// For example: +// +// Current pointer: A - B - C - D - E - F +// Work-in-progress pointer: D - E - F +// ^ +// The work-in-progress queue has +// processed more updates than current. +// +// The reason we append to both queues is because otherwise we might drop +// updates without ever processing them. For example, if we only add updates to +// the work-in-progress queue, some updates could be lost whenever a work-in +// -progress render restarts by cloning from current. Similarly, if we only add +// updates to the current queue, the updates will be lost whenever an already +// in-progress queue commits and swaps with the current queue. However, by +// adding to both queues, we guarantee that the update will be part of the next +// work-in-progress. (And because the work-in-progress queue becomes the +// current queue once it commits, there's no danger of applying the same +// update twice.) +// +// Prioritization +// -------------- +// +// Updates are not sorted by priority, but by insertion; new updates are always +// appended to the end of the list. +// +// The priority is still important, though. When processing the update queue +// during the render phase, only the updates with sufficient priority are +// included in the result. If we skip an update because it has insufficient +// priority, it remains in the queue to be processed later, during a lower +// priority render. Crucially, all updates subsequent to a skipped update also +// remain in the queue *regardless of their priority*. That means high priority +// updates are sometimes processed twice, at two separate priorities. We also +// keep track of a base state, that represents the state before the first +// update in the queue is applied. +// +// For example: +// +// Given a base state of '', and the following queue of updates +// +// A1 - B2 - C1 - D2 +// +// where the number indicates the priority, and the update is applied to the +// previous state by appending a letter, React will process these updates as +// two separate renders, one per distinct priority level: +// +// First render, at priority 1: +// Base state: '' +// Updates: [A1, C1] +// Result state: 'AC' +// +// Second render, at priority 2: +// Base state: 'A' <- The base state does not include C1, +// because B2 was skipped. +// Updates: [B2, C1, D2] <- C1 was rebased on top of B2 +// Result state: 'ABCD' +// +// Because we process updates in insertion order, and rebase high priority +// updates when preceding updates are skipped, the final result is deterministic +// regardless of priority. Intermediate state may vary according to system +// resources, but the final state is always the same. var UpdateState = 0; var ReplaceState = 1; var ForceUpdate = 2; @@ -6432,32 +7325,38 @@ var currentlyProcessingQueue; currentlyProcessingQueue = null; } -function initializeUpdateQueue(fiber) { +function createUpdateQueue(baseState) { var queue = { - baseState: fiber.memoizedState, - baseQueue: null, - shared: { - pending: null - }, - effects: null + baseState: baseState, + firstUpdate: null, + lastUpdate: null, + firstCapturedUpdate: null, + lastCapturedUpdate: null, + firstEffect: null, + lastEffect: null, + firstCapturedEffect: null, + lastCapturedEffect: 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; - - if (queue === currentQueue) { - var clone = { - baseState: currentQueue.baseState, - baseQueue: currentQueue.baseQueue, - shared: currentQueue.shared, - effects: currentQueue.effects - }; - workInProgress.updateQueue = clone; - } + return queue; +} + +function cloneUpdateQueue(currentQueue) { + var queue = { + baseState: currentQueue.baseState, + firstUpdate: currentQueue.firstUpdate, + lastUpdate: currentQueue.lastUpdate, + // TODO: With resuming, if we bail out and resuse the child tree, we should + // keep these effects. + firstCapturedUpdate: null, + lastCapturedUpdate: null, + firstEffect: null, + lastEffect: null, + firstCapturedEffect: null, + lastCapturedEffect: null + }; + return queue; } + function createUpdate(expirationTime, suspenseConfig) { var update = { expirationTime: expirationTime, @@ -6465,9 +7364,9 @@ function createUpdate(expirationTime, suspenseConfig) { tag: UpdateState, payload: null, callback: null, - next: null + next: null, + nextEffect: null }; - update.next = update; { update.priority = getCurrentPriorityLevel(); @@ -6475,62 +7374,130 @@ function createUpdate(expirationTime, suspenseConfig) { return update; } -function enqueueUpdate(fiber, update) { - var updateQueue = fiber.updateQueue; - if (updateQueue === null) { - // Only occurs if the fiber has been unmounted. - return; +function appendUpdateToQueue(queue, update) { + // Append the update to the end of the list. + if (queue.lastUpdate === null) { + // Queue is empty + queue.firstUpdate = queue.lastUpdate = update; + } else { + queue.lastUpdate.next = update; + queue.lastUpdate = update; } +} - var sharedQueue = updateQueue.shared; - var pending = sharedQueue.pending; +function enqueueUpdate(fiber, update) { + // Update queues are created lazily. + var alternate = fiber.alternate; + var queue1; + var queue2; - if (pending === null) { - // This is the first update. Create a circular list. - update.next = update; + if (alternate === null) { + // There's only one fiber. + queue1 = fiber.updateQueue; + queue2 = null; + if (queue1 === null) { + queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState); + } } else { - update.next = pending.next; - pending.next = update; + // There are two owners. + queue1 = fiber.updateQueue; + queue2 = alternate.updateQueue; + if (queue1 === null) { + if (queue2 === null) { + // Neither fiber has an update queue. Create new ones. + queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState); + queue2 = alternate.updateQueue = createUpdateQueue( + alternate.memoizedState + ); + } else { + // Only one fiber has an update queue. Clone to create a new one. + queue1 = fiber.updateQueue = cloneUpdateQueue(queue2); + } + } else { + if (queue2 === null) { + // Only one fiber has an update queue. Clone to create a new one. + queue2 = alternate.updateQueue = cloneUpdateQueue(queue1); + } else { + // Both owners have an update queue. + } + } } + if (queue2 === null || queue1 === queue2) { + // There's only a single queue. + appendUpdateToQueue(queue1, update); + } else { + // There are two queues. We need to append the update to both queues, + // while accounting for the persistent structure of the list — we don't + // want the same update to be added multiple times. + if (queue1.lastUpdate === null || queue2.lastUpdate === null) { + // One of the queues is not empty. We must add the update to both queues. + appendUpdateToQueue(queue1, update); + appendUpdateToQueue(queue2, update); + } else { + // Both queues are non-empty. The last update is the same in both lists, + // because of structural sharing. So, only append to one of the lists. + appendUpdateToQueue(queue1, update); // But we still need to update the `lastUpdate` pointer of queue2. - sharedQueue.pending = update; + queue2.lastUpdate = update; + } + } { if ( - currentlyProcessingQueue === sharedQueue && + fiber.tag === ClassComponent && + (currentlyProcessingQueue === queue1 || + (queue2 !== null && currentlyProcessingQueue === queue2)) && !didWarnUpdateInsideUpdate ) { - error( + warningWithoutStack$1( + false, "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, update) { - var current = workInProgress.alternate; - - if (current !== null) { - // Ensure the work-in-progress queue is a clone - cloneUpdateQueue(current, workInProgress); - } // Captured updates go only on the work-in-progress queue. - - var queue = workInProgress.updateQueue; // Append the update to the end of the list. - - var last = queue.baseQueue; + // Captured updates go into a separate list, and only on the work-in- + // progress queue. + var workInProgressQueue = workInProgress.updateQueue; + if (workInProgressQueue === null) { + workInProgressQueue = workInProgress.updateQueue = createUpdateQueue( + workInProgress.memoizedState + ); + } else { + // TODO: I put this here rather than createWorkInProgress so that we don't + // clone the queue unnecessarily. There's probably a better way to + // structure this. + workInProgressQueue = ensureWorkInProgressQueueIsAClone( + workInProgress, + workInProgressQueue + ); + } // Append the update to the end of the list. - if (last === null) { - queue.baseQueue = update.next = update; - update.next = update; + if (workInProgressQueue.lastCapturedUpdate === null) { + // This is the first render phase update + workInProgressQueue.firstCapturedUpdate = workInProgressQueue.lastCapturedUpdate = update; } else { - update.next = last.next; - last.next = update; + workInProgressQueue.lastCapturedUpdate.next = update; + workInProgressQueue.lastCapturedUpdate = update; + } +} + +function ensureWorkInProgressQueueIsAClone(workInProgress, queue) { + var current = workInProgress.alternate; + if (current !== null) { + // If the work-in-progress queue is equal to the current queue, + // we need to clone it first. + if (queue === current.updateQueue) { + queue = workInProgress.updateQueue = cloneUpdateQueue(queue); + } } + return queue; } function getStateFromUpdate( @@ -6549,6 +7516,13 @@ function getStateFromUpdate( // Updater function { enterDisallowedContextReadInDEV(); + + if ( + debugRenderPhaseSideEffectsForStrictMode && + workInProgress.mode & StrictMode + ) { + payload.call(instance, prevState, nextProps); + } } var nextState = payload.call(instance, prevState, nextProps); @@ -6577,6 +7551,13 @@ function getStateFromUpdate( // Updater function { enterDisallowedContextReadInDEV(); + + if ( + debugRenderPhaseSideEffectsForStrictMode && + workInProgress.mode & StrictMode + ) { + _payload.call(instance, prevState, nextProps); + } } partialState = _payload.call(instance, prevState, nextProps); @@ -6602,176 +7583,164 @@ function getStateFromUpdate( return prevState; } } - return prevState; } function processUpdateQueue( workInProgress, + queue, props, instance, renderExpirationTime ) { - // This is always non-null on a ClassComponent or HostRoot - var queue = workInProgress.updateQueue; hasForceUpdate = false; + queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue); { - currentlyProcessingQueue = queue.shared; - } // The last rebase update that is NOT part of the base state. - - var baseQueue = queue.baseQueue; // The last pending update that hasn't been processed yet. + currentlyProcessingQueue = queue; + } // These values may change as we process the queue. - var pendingQueue = queue.shared.pending; + var newBaseState = queue.baseState; + var newFirstUpdate = null; + var newExpirationTime = NoWork; // Iterate through the list of updates to compute the result. - if (pendingQueue !== null) { - // We have new updates that haven't been processed yet. - // We'll add them to the base queue. - if (baseQueue !== null) { - // Merge the pending queue and the base queue. - var baseFirst = baseQueue.next; - var pendingFirst = pendingQueue.next; - baseQueue.next = pendingFirst; - pendingQueue.next = baseFirst; - } + var update = queue.firstUpdate; + var resultState = newBaseState; - baseQueue = pendingQueue; - queue.shared.pending = null; // TODO: Pass `current` as argument + while (update !== null) { + var updateExpirationTime = update.expirationTime; - var current = workInProgress.alternate; + if (updateExpirationTime < renderExpirationTime) { + // This update does not have sufficient priority. Skip it. + if (newFirstUpdate === null) { + // This is the first skipped update. It will be the first update in + // the new list. + newFirstUpdate = update; // Since this is the first update that was skipped, the current result + // is the new base state. - if (current !== null) { - var currentQueue = current.updateQueue; + newBaseState = resultState; + } // Since this update will remain in the list, update the remaining + // expiration time. - if (currentQueue !== null) { - currentQueue.baseQueue = pendingQueue; + if (newExpirationTime < updateExpirationTime) { + newExpirationTime = updateExpirationTime; } - } - } // These values may change as we process the queue. + } else { + // This update does have sufficient priority. + // Mark the event time of this update as relevant to this render pass. + // TODO: This should ideally use the true event time of this update rather than + // its priority which is a derived and not reverseable value. + // TODO: We should skip this update if it was already committed but currently + // we have no way of detecting the difference between a committed and suspended + // update here. + markRenderEventTimeAndConfig(updateExpirationTime, update.suspenseConfig); // Process it and compute a new result. + + resultState = getStateFromUpdate( + workInProgress, + queue, + update, + resultState, + props, + instance + ); + var callback = update.callback; - if (baseQueue !== null) { - var first = baseQueue.next; // Iterate through the list of updates to compute the result. + if (callback !== null) { + workInProgress.effectTag |= Callback; // Set this to null, in case it was mutated during an aborted render. - var newState = queue.baseState; - var newExpirationTime = NoWork; - var newBaseState = null; - var newBaseQueueFirst = null; - var newBaseQueueLast = null; + update.nextEffect = null; - if (first !== null) { - var update = first; + if (queue.lastEffect === null) { + queue.firstEffect = queue.lastEffect = update; + } else { + queue.lastEffect.nextEffect = update; + queue.lastEffect = update; + } + } + } // Continue to the next update. - do { - var updateExpirationTime = update.expirationTime; - - if (updateExpirationTime < renderExpirationTime) { - // 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 = { - expirationTime: update.expirationTime, - suspenseConfig: update.suspenseConfig, - tag: update.tag, - payload: update.payload, - callback: update.callback, - next: null - }; + update = update.next; + } // Separately, iterate though the list of captured updates. - if (newBaseQueueLast === null) { - newBaseQueueFirst = newBaseQueueLast = clone; - newBaseState = newState; - } else { - newBaseQueueLast = newBaseQueueLast.next = clone; - } // Update the remaining priority in the queue. + var newFirstCapturedUpdate = null; + update = queue.firstCapturedUpdate; - if (updateExpirationTime > newExpirationTime) { - newExpirationTime = updateExpirationTime; - } - } else { - // This update does have sufficient priority. - if (newBaseQueueLast !== null) { - var _clone = { - expirationTime: Sync, - // This update is going to be committed so we never want uncommit it. - suspenseConfig: update.suspenseConfig, - tag: update.tag, - payload: update.payload, - callback: update.callback, - next: null - }; - newBaseQueueLast = newBaseQueueLast.next = _clone; - } // Mark the event time of this update as relevant to this render pass. - // TODO: This should ideally use the true event time of this update rather than - // its priority which is a derived and not reverseable value. - // TODO: We should skip this update if it was already committed but currently - // we have no way of detecting the difference between a committed and suspended - // update here. - - markRenderEventTimeAndConfig( - updateExpirationTime, - update.suspenseConfig - ); // Process this update. - - newState = getStateFromUpdate( - workInProgress, - queue, - update, - newState, - props, - instance - ); - var callback = update.callback; + while (update !== null) { + var _updateExpirationTime = update.expirationTime; - if (callback !== null) { - workInProgress.effectTag |= Callback; - var effects = queue.effects; + if (_updateExpirationTime < renderExpirationTime) { + // This update does not have sufficient priority. Skip it. + if (newFirstCapturedUpdate === null) { + // This is the first skipped captured update. It will be the first + // update in the new list. + newFirstCapturedUpdate = update; // If this is the first update that was skipped, the current result is + // the new base state. - if (effects === null) { - queue.effects = [update]; - } else { - effects.push(update); - } - } + if (newFirstUpdate === null) { + newBaseState = resultState; } + } // Since this update will remain in the list, update the remaining + // expiration time. + + if (newExpirationTime < _updateExpirationTime) { + newExpirationTime = _updateExpirationTime; + } + } else { + // This update does have sufficient priority. Process it and compute + // a new result. + resultState = getStateFromUpdate( + workInProgress, + queue, + update, + resultState, + props, + instance + ); + var _callback = update.callback; - update = update.next; + if (_callback !== null) { + workInProgress.effectTag |= Callback; // Set this to null, in case it was mutated during an aborted render. - if (update === null || update === first) { - pendingQueue = queue.shared.pending; + update.nextEffect = null; - 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. - update = baseQueue.next = pendingQueue.next; - pendingQueue.next = first; - queue.baseQueue = baseQueue = pendingQueue; - queue.shared.pending = null; - } + if (queue.lastCapturedEffect === null) { + queue.firstCapturedEffect = queue.lastCapturedEffect = update; + } else { + queue.lastCapturedEffect.nextEffect = update; + queue.lastCapturedEffect = update; } - } while (true); + } } + update = update.next; + } - if (newBaseQueueLast === null) { - newBaseState = newState; - } else { - newBaseQueueLast.next = newBaseQueueFirst; - } + if (newFirstUpdate === null) { + queue.lastUpdate = null; + } + if (newFirstCapturedUpdate === null) { + queue.lastCapturedUpdate = null; + } else { + workInProgress.effectTag |= Callback; + } + if (newFirstUpdate === null && newFirstCapturedUpdate === null) { + // We processed every update, without skipping. That means the new base + // state is the same as the result state. + newBaseState = resultState; + } - queue.baseState = newBaseState; - queue.baseQueue = newBaseQueueLast; // 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. + queue.baseState = newBaseState; + queue.firstUpdate = newFirstUpdate; + queue.firstCapturedUpdate = newFirstCapturedUpdate; // 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. - markUnprocessedUpdateTime(newExpirationTime); - workInProgress.expirationTime = newExpirationTime; - workInProgress.memoizedState = newState; - } + markUnprocessedUpdateTime(newExpirationTime); + workInProgress.expirationTime = newExpirationTime; + workInProgress.memoizedState = resultState; { currentlyProcessingQueue = null; @@ -6795,21 +7764,42 @@ function resetHasForceUpdateBeforeProcessing() { function checkHasForceUpdateAfterProcessing() { return hasForceUpdate; } -function commitUpdateQueue(finishedWork, finishedQueue, instance) { - // Commit the effects - var effects = finishedQueue.effects; - finishedQueue.effects = null; +function commitUpdateQueue( + finishedWork, + finishedQueue, + instance, + renderExpirationTime +) { + // If the finished render included captured updates, and there are still + // lower priority updates left over, we need to keep the captured updates + // in the queue so that they are rebased and not dropped once we process the + // queue again at the lower priority. + if (finishedQueue.firstCapturedUpdate !== null) { + // Join the captured update list to the end of the normal list. + if (finishedQueue.lastUpdate !== null) { + finishedQueue.lastUpdate.next = finishedQueue.firstCapturedUpdate; + finishedQueue.lastUpdate = finishedQueue.lastCapturedUpdate; + } // Clear the list of captured updates. - if (effects !== null) { - for (var i = 0; i < effects.length; i++) { - var effect = effects[i]; - var callback = effect.callback; + finishedQueue.firstCapturedUpdate = finishedQueue.lastCapturedUpdate = null; + } // Commit the effects - if (callback !== null) { - effect.callback = null; - callCallback(callback, instance); - } + commitUpdateEffects(finishedQueue.firstEffect, instance); + finishedQueue.firstEffect = finishedQueue.lastEffect = null; + commitUpdateEffects(finishedQueue.firstCapturedEffect, instance); + finishedQueue.firstCapturedEffect = finishedQueue.lastCapturedEffect = null; +} + +function commitUpdateEffects(effect, instance) { + while (effect !== null) { + var callback = effect.callback; + + if (callback !== null) { + effect.callback = null; + callCallback(callback, instance); } + + effect = effect.nextEffect; } } @@ -6819,7 +7809,7 @@ function requestCurrentSuspenseConfig() { } var fakeInternalInstance = {}; -var isArray = Array.isArray; // React.Component uses a shared frozen object by default. +var isArray$1 = Array.isArray; // React.Component uses a shared frozen object by default. // We'll use it to determine whether we need to initialize legacy refs. var emptyRefsObject = new React.Component().refs; @@ -6854,8 +7844,8 @@ var didWarnAboutInvalidateContextType; if (!didWarnOnInvalidCallback.has(key)) { didWarnOnInvalidCallback.add(key); - - error( + warningWithoutStack$1( + false, "%s(...): Expected the last optional `callback` argument to be a " + "function. Instead received: %s.", callerName, @@ -6867,11 +7857,10 @@ var didWarnAboutInvalidateContextType; warnOnUndefinedDerivedState = function(type, partialState) { if (partialState === undefined) { var componentName = getComponentName(type) || "Component"; - if (!didWarnAboutUndefinedDerivedState.has(componentName)) { didWarnAboutUndefinedDerivedState.add(componentName); - - error( + warningWithoutStack$1( + false, "%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. " + "You have returned undefined.", componentName @@ -6905,6 +7894,16 @@ function applyDerivedStateFromProps( ) { var prevState = workInProgress.memoizedState; + { + if ( + debugRenderPhaseSideEffectsForStrictMode && + workInProgress.mode & StrictMode + ) { + // Invoke the function an extra time to help detect side-effects. + getDerivedStateFromProps(nextProps, prevState); + } + } + var partialState = getDerivedStateFromProps(nextProps, prevState); { @@ -6918,9 +7917,9 @@ function applyDerivedStateFromProps( workInProgress.memoizedState = memoizedState; // Once the update queue is empty, persist the derived state onto the // base state. - if (workInProgress.expirationTime === NoWork) { - // Queue is always non-null for classes - var updateQueue = workInProgress.updateQueue; + var updateQueue = workInProgress.updateQueue; + + if (updateQueue !== null && workInProgress.expirationTime === NoWork) { updateQueue.baseState = memoizedState; } } @@ -7008,7 +8007,6 @@ function checkShouldComponentUpdate( nextContext ) { var instance = workInProgress.stateNode; - if (typeof instance.shouldComponentUpdate === "function") { startPhaseTimer(workInProgress, "shouldComponentUpdate"); var shouldUpdate = instance.shouldComponentUpdate( @@ -7019,13 +8017,14 @@ function checkShouldComponentUpdate( stopPhaseTimer(); { - if (shouldUpdate === undefined) { - error( - "%s.shouldComponentUpdate(): Returned undefined instead of a " + - "boolean value. Make sure to return true or false.", - getComponentName(ctor) || "Component" - ); - } + !(shouldUpdate !== undefined) + ? warningWithoutStack$1( + false, + "%s.shouldComponentUpdate(): Returned undefined instead of a " + + "boolean value. Make sure to return true or false.", + getComponentName(ctor) || "Component" + ) + : void 0; } return shouldUpdate; @@ -7042,20 +8041,21 @@ function checkShouldComponentUpdate( 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( + warningWithoutStack$1( + false, "%s(...): No `render` method found on the returned component " + "instance: did you accidentally return an object from the constructor?", name ); } else { - error( + warningWithoutStack$1( + false, "%s(...): No `render` method found on the returned component " + "instance: you may have forgotten to define `render`.", name @@ -7063,55 +8063,77 @@ function checkClassInstance(workInProgress, ctor, newProps) { } } - 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.", + var noGetInitialStateOnES6 = + !instance.getInitialState || + instance.getInitialState.isReactClassApproved || + instance.state; + !noGetInitialStateOnES6 + ? warningWithoutStack$1( + false, + "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 + ) + : void 0; + var noGetDefaultPropsOnES6 = + !instance.getDefaultProps || + instance.getDefaultProps.isReactClassApproved; + !noGetDefaultPropsOnES6 + ? warningWithoutStack$1( + false, + "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 + ) + : void 0; + var noInstancePropTypes = !instance.propTypes; + !noInstancePropTypes + ? warningWithoutStack$1( + false, + "propTypes was defined as an instance property on %s. Use a static " + + "property to define propTypes instead.", + name + ) + : void 0; + var noInstanceContextType = !instance.contextType; + !noInstanceContextType + ? warningWithoutStack$1( + false, + "contextType was defined as an instance property on %s. Use a static " + + "property to define contextType instead.", + name + ) + : void 0; + + if (disableLegacyContext) { + if (ctor.childContextTypes) { + warningWithoutStack$1( + false, + "%s uses the legacy childContextTypes API which is no longer supported. " + + "Use React.createContext() instead.", + name + ); + } + if (ctor.contextTypes) { + warningWithoutStack$1( + false, + "%s uses the legacy contextTypes API which is no longer supported. " + + "Use React.createContext() with static contextType instead.", name ); } + } else { + var noInstanceContextTypes = !instance.contextTypes; + !noInstanceContextTypes + ? warningWithoutStack$1( + false, + "contextTypes was defined as an instance property on %s. Use a static " + + "property to define contextTypes instead.", + name + ) + : void 0; if ( ctor.contextType && @@ -7119,8 +8141,8 @@ function checkClassInstance(workInProgress, ctor, newProps) { !didWarnAboutContextTypeAndContextTypes.has(ctor) ) { didWarnAboutContextTypeAndContextTypes.add(ctor); - - error( + warningWithoutStack$1( + false, "%s declares both contextTypes and contextType static properties. " + "The legacy contextTypes property will be ignored.", name @@ -7128,84 +8150,95 @@ function checkClassInstance(workInProgress, ctor, newProps) { } } - if (typeof instance.componentShouldUpdate === "function") { - error( - "%s has a method called " + - "componentShouldUpdate(). Did you mean shouldComponentUpdate()? " + - "The name is phrased as a question because the function is " + - "expected to return a value.", - name - ); - } - + var noComponentShouldUpdate = + typeof instance.componentShouldUpdate !== "function"; + !noComponentShouldUpdate + ? warningWithoutStack$1( + false, + "%s has a method called " + + "componentShouldUpdate(). Did you mean shouldComponentUpdate()? " + + "The name is phrased as a question because the function is " + + "expected to return a value.", + name + ) + : void 0; if ( ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== "undefined" ) { - error( + warningWithoutStack$1( + false, "%s has a method called shouldComponentUpdate(). " + "shouldComponentUpdate should not be used when extending React.PureComponent. " + "Please extend React.Component if shouldComponentUpdate is used.", getComponentName(ctor) || "A pure component" ); } - - if (typeof instance.componentDidUnmount === "function") { - error( - "%s has a method called " + - "componentDidUnmount(). But there is no such lifecycle method. " + - "Did you mean componentWillUnmount()?", - name - ); - } - - if (typeof instance.componentDidReceiveProps === "function") { - error( - "%s has a method called " + - "componentDidReceiveProps(). But there is no such lifecycle method. " + - "If you meant to update the state in response to changing props, " + - "use componentWillReceiveProps(). If you meant to fetch data or " + - "run side-effects or mutations after React has updated the UI, use componentDidUpdate().", - name - ); - } - - if (typeof instance.componentWillRecieveProps === "function") { - error( - "%s has a method called " + - "componentWillRecieveProps(). Did you mean componentWillReceiveProps()?", - name - ); - } - - if (typeof instance.UNSAFE_componentWillRecieveProps === "function") { - error( - "%s has a method called " + - "UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?", - name - ); - } - + var noComponentDidUnmount = + typeof instance.componentDidUnmount !== "function"; + !noComponentDidUnmount + ? warningWithoutStack$1( + false, + "%s has a method called " + + "componentDidUnmount(). But there is no such lifecycle method. " + + "Did you mean componentWillUnmount()?", + name + ) + : void 0; + var noComponentDidReceiveProps = + typeof instance.componentDidReceiveProps !== "function"; + !noComponentDidReceiveProps + ? warningWithoutStack$1( + false, + "%s has a method called " + + "componentDidReceiveProps(). But there is no such lifecycle method. " + + "If you meant to update the state in response to changing props, " + + "use componentWillReceiveProps(). If you meant to fetch data or " + + "run side-effects or mutations after React has updated the UI, use componentDidUpdate().", + name + ) + : void 0; + var noComponentWillRecieveProps = + typeof instance.componentWillRecieveProps !== "function"; + !noComponentWillRecieveProps + ? warningWithoutStack$1( + false, + "%s has a method called " + + "componentWillRecieveProps(). Did you mean componentWillReceiveProps()?", + name + ) + : void 0; + var noUnsafeComponentWillRecieveProps = + typeof instance.UNSAFE_componentWillRecieveProps !== "function"; + !noUnsafeComponentWillRecieveProps + ? warningWithoutStack$1( + false, + "%s has a method called " + + "UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?", + name + ) + : void 0; var hasMutatedProps = instance.props !== newProps; - - if (instance.props !== undefined && hasMutatedProps) { - error( - "%s(...): When calling super() in `%s`, make sure to pass " + - "up the same props that your component's constructor was passed.", - name, - name - ); - } - - if (instance.defaultProps) { - error( - "Setting defaultProps as an instance property on %s is not supported and will be ignored." + - " Instead, define defaultProps as a static property on %s.", - name, - name - ); - } + !(instance.props === undefined || !hasMutatedProps) + ? warningWithoutStack$1( + false, + "%s(...): When calling super() in `%s`, make sure to pass " + + "up the same props that your component's constructor was passed.", + name, + name + ) + : void 0; + var noInstanceDefaultProps = !instance.defaultProps; + !noInstanceDefaultProps + ? warningWithoutStack$1( + false, + "Setting defaultProps as an instance property on %s is not supported and will be ignored." + + " Instead, define defaultProps as a static property on %s.", + name, + name + ) + : void 0; if ( typeof instance.getSnapshotBeforeUpdate === "function" && @@ -7213,54 +8246,62 @@ function checkClassInstance(workInProgress, ctor, newProps) { !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor) ) { didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor); - - error( + warningWithoutStack$1( + false, "%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). " + "This component defines getSnapshotBeforeUpdate() only.", getComponentName(ctor) ); } - if (typeof instance.getDerivedStateFromProps === "function") { - error( - "%s: getDerivedStateFromProps() is defined as an instance method " + - "and will be ignored. Instead, declare it as a static method.", - name - ); - } - - if (typeof instance.getDerivedStateFromError === "function") { - error( - "%s: getDerivedStateFromError() is defined as an instance method " + - "and will be ignored. Instead, declare it as a static method.", - name - ); - } - - if (typeof ctor.getSnapshotBeforeUpdate === "function") { - error( - "%s: getSnapshotBeforeUpdate() is defined as a static method " + - "and will be ignored. Instead, declare it as an instance method.", - name - ); - } - + var noInstanceGetDerivedStateFromProps = + typeof instance.getDerivedStateFromProps !== "function"; + !noInstanceGetDerivedStateFromProps + ? warningWithoutStack$1( + false, + "%s: getDerivedStateFromProps() is defined as an instance method " + + "and will be ignored. Instead, declare it as a static method.", + name + ) + : void 0; + var noInstanceGetDerivedStateFromCatch = + typeof instance.getDerivedStateFromError !== "function"; + !noInstanceGetDerivedStateFromCatch + ? warningWithoutStack$1( + false, + "%s: getDerivedStateFromError() is defined as an instance method " + + "and will be ignored. Instead, declare it as a static method.", + name + ) + : void 0; + var noStaticGetSnapshotBeforeUpdate = + typeof ctor.getSnapshotBeforeUpdate !== "function"; + !noStaticGetSnapshotBeforeUpdate + ? warningWithoutStack$1( + false, + "%s: getSnapshotBeforeUpdate() is defined as a static method " + + "and will be ignored. Instead, declare it as an instance method.", + name + ) + : void 0; var _state = instance.state; - - if (_state && (typeof _state !== "object" || isArray(_state))) { - error("%s.state: must be set to an object or null", name); - } - - if ( - typeof instance.getChildContext === "function" && - typeof ctor.childContextTypes !== "object" - ) { - error( - "%s.getChildContext(): childContextTypes must be defined in order to " + - "use getChildContext().", + if (_state && (typeof _state !== "object" || isArray$1(_state))) { + warningWithoutStack$1( + false, + "%s.state: must be set to an object or null", name ); } + if (typeof instance.getChildContext === "function") { + !(typeof ctor.childContextTypes === "object") + ? warningWithoutStack$1( + false, + "%s.getChildContext(): childContextTypes must be defined in order to " + + "use getChildContext().", + name + ) + : void 0; + } } } @@ -7275,7 +8316,12 @@ function adoptClassInstance(workInProgress, instance) { } } -function constructClassInstance(workInProgress, ctor, props) { +function constructClassInstance( + workInProgress, + ctor, + props, + renderExpirationTime +) { var isLegacyContextConsumer = false; var unmaskedContext = emptyContextObject; var context = emptyContextObject; @@ -7312,8 +8358,8 @@ function constructClassInstance(workInProgress, ctor, props) { Object.keys(contextType).join(", ") + "}."; } - - error( + warningWithoutStack$1( + false, "%s defines an invalid contextType. " + "contextType should point to the Context object returned by React.createContext().%s", getComponentName(ctor) || "Component", @@ -7325,7 +8371,7 @@ function constructClassInstance(workInProgress, ctor, props) { if (typeof contextType === "object" && contextType !== null) { context = readContext(contextType); - } else { + } else if (!disableLegacyContext) { unmaskedContext = getUnmaskedContext(workInProgress, ctor, true); var contextTypes = ctor.contextTypes; isLegacyContextConsumer = @@ -7335,6 +8381,15 @@ function constructClassInstance(workInProgress, ctor, props) { : emptyContextObject; } // Instantiate twice to help detect side-effects. + { + if ( + debugRenderPhaseSideEffectsForStrictMode && + workInProgress.mode & StrictMode + ) { + new ctor(props, context); // eslint-disable-line no-new + } + } + var instance = new ctor(props, context); var state = (workInProgress.memoizedState = instance.state !== null && instance.state !== undefined @@ -7345,11 +8400,10 @@ function constructClassInstance(workInProgress, ctor, props) { { if (typeof ctor.getDerivedStateFromProps === "function" && state === null) { var componentName = getComponentName(ctor) || "Component"; - if (!didWarnAboutUninitializedState.has(componentName)) { didWarnAboutUninitializedState.add(componentName); - - error( + warningWithoutStack$1( + false, "`%s` uses `getDerivedStateFromProps` but its initial state is " + "%s. This is not recommended. Instead, define the initial state by " + "assigning an object to `this.state` in the constructor of `%s`. " + @@ -7370,7 +8424,6 @@ function constructClassInstance(workInProgress, ctor, props) { var foundWillMountName = null; var foundWillReceivePropsName = null; var foundWillUpdateName = null; - if ( typeof instance.componentWillMount === "function" && instance.componentWillMount.__suppressDeprecationWarning !== true @@ -7379,7 +8432,6 @@ function constructClassInstance(workInProgress, ctor, props) { } else if (typeof instance.UNSAFE_componentWillMount === "function") { foundWillMountName = "UNSAFE_componentWillMount"; } - if ( typeof instance.componentWillReceiveProps === "function" && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true @@ -7390,7 +8442,6 @@ function constructClassInstance(workInProgress, ctor, props) { ) { foundWillReceivePropsName = "UNSAFE_componentWillReceiveProps"; } - if ( typeof instance.componentWillUpdate === "function" && instance.componentWillUpdate.__suppressDeprecationWarning !== true @@ -7399,23 +8450,20 @@ function constructClassInstance(workInProgress, ctor, props) { } else if (typeof instance.UNSAFE_componentWillUpdate === "function") { foundWillUpdateName = "UNSAFE_componentWillUpdate"; } - if ( foundWillMountName !== null || foundWillReceivePropsName !== null || foundWillUpdateName !== null ) { var _componentName = getComponentName(ctor) || "Component"; - var newApiName = typeof ctor.getDerivedStateFromProps === "function" ? "getDerivedStateFromProps()" : "getSnapshotBeforeUpdate()"; - if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName)) { didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName); - - error( + warningWithoutStack$1( + false, "Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n" + "%s uses %s but also contains the following legacy lifecycles:%s%s%s\n\n" + "The above lifecycles should be removed. Learn more about this warning here:\n" + @@ -7448,7 +8496,6 @@ function callComponentWillMount(workInProgress, instance) { if (typeof instance.componentWillMount === "function") { instance.componentWillMount(); } - if (typeof instance.UNSAFE_componentWillMount === "function") { instance.UNSAFE_componentWillMount(); } @@ -7457,14 +8504,14 @@ function callComponentWillMount(workInProgress, instance) { if (oldState !== instance.state) { { - error( + warningWithoutStack$1( + false, "%s.componentWillMount(): Assigning directly to this.state is " + "deprecated (except inside a component's " + "constructor). Use setState instead.", getComponentName(workInProgress.type) || "Component" ); } - classComponentUpdater.enqueueReplaceState(instance, instance.state, null); } } @@ -7491,11 +8538,10 @@ function callComponentWillReceiveProps( if (instance.state !== oldState) { { var componentName = getComponentName(workInProgress.type) || "Component"; - if (!didWarnAboutStateAssignmentForComponent.has(componentName)) { didWarnAboutStateAssignmentForComponent.add(componentName); - - error( + warningWithoutStack$1( + false, "%s.componentWillReceiveProps(): Assigning directly to " + "this.state is deprecated (except inside a component's " + "constructor). Use setState instead.", @@ -7522,11 +8568,12 @@ function mountClassInstance( instance.props = newProps; instance.state = workInProgress.memoizedState; instance.refs = emptyRefsObject; - initializeUpdateQueue(workInProgress); var contextType = ctor.contextType; if (typeof contextType === "object" && contextType !== null) { instance.context = readContext(contextType); + } else if (disableLegacyContext) { + instance.context = emptyContextObject; } else { var unmaskedContext = getUnmaskedContext(workInProgress, ctor, true); instance.context = getMaskedContext(workInProgress, unmaskedContext); @@ -7535,11 +8582,10 @@ function mountClassInstance( { if (instance.state === newProps) { var componentName = getComponentName(ctor) || "Component"; - if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) { didWarnAboutDirectlyAssigningPropsToState.add(componentName); - - error( + warningWithoutStack$1( + false, "%s: It is not recommended to assign props directly to state " + "because updates to props won't be reflected in state. " + "In most cases, it is better to use props directly.", @@ -7555,7 +8601,7 @@ function mountClassInstance( ); } - { + if (warnAboutDeprecatedLifecycles) { ReactStrictModeWarnings.recordUnsafeLifecycleWarnings( workInProgress, instance @@ -7563,10 +8609,19 @@ function mountClassInstance( } } - processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); - instance.state = workInProgress.memoizedState; - var getDerivedStateFromProps = ctor.getDerivedStateFromProps; + var updateQueue = workInProgress.updateQueue; + if (updateQueue !== null) { + processUpdateQueue( + workInProgress, + updateQueue, + newProps, + instance, + renderExpirationTime + ); + instance.state = workInProgress.memoizedState; + } + var getDerivedStateFromProps = ctor.getDerivedStateFromProps; if (typeof getDerivedStateFromProps === "function") { applyDerivedStateFromProps( workInProgress, @@ -7587,13 +8642,18 @@ function mountClassInstance( callComponentWillMount(workInProgress, instance); // If we had additional state updates during this life-cycle, let's // process them now. - processUpdateQueue( - workInProgress, - newProps, - instance, - renderExpirationTime - ); - instance.state = workInProgress.memoizedState; + updateQueue = workInProgress.updateQueue; + + if (updateQueue !== null) { + processUpdateQueue( + workInProgress, + updateQueue, + newProps, + instance, + renderExpirationTime + ); + instance.state = workInProgress.memoizedState; + } } if (typeof instance.componentDidMount === "function") { @@ -7616,7 +8676,7 @@ function resumeMountClassInstance( if (typeof contextType === "object" && contextType !== null) { nextContext = readContext(contextType); - } else { + } else if (!disableLegacyContext) { var nextLegacyUnmaskedContext = getUnmaskedContext( workInProgress, ctor, @@ -7652,9 +8712,18 @@ function resumeMountClassInstance( resetHasForceUpdateBeforeProcessing(); var oldState = workInProgress.memoizedState; var newState = (instance.state = oldState); - processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); - newState = workInProgress.memoizedState; + var updateQueue = workInProgress.updateQueue; + if (updateQueue !== null) { + processUpdateQueue( + workInProgress, + updateQueue, + newProps, + instance, + renderExpirationTime + ); + newState = workInProgress.memoizedState; + } if ( oldProps === newProps && oldState === newState && @@ -7666,7 +8735,6 @@ function resumeMountClassInstance( if (typeof instance.componentDidMount === "function") { workInProgress.effectTag |= Update; } - return false; } @@ -7743,7 +8811,6 @@ function updateClassInstance( renderExpirationTime ) { var instance = workInProgress.stateNode; - cloneUpdateQueue(current, workInProgress); var oldProps = workInProgress.memoizedProps; instance.props = workInProgress.type === workInProgress.elementType @@ -7755,7 +8822,7 @@ function updateClassInstance( if (typeof contextType === "object" && contextType !== null) { nextContext = readContext(contextType); - } else { + } else if (!disableLegacyContext) { var nextUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true); nextContext = getMaskedContext(workInProgress, nextUnmaskedContext); } @@ -7787,8 +8854,18 @@ function updateClassInstance( resetHasForceUpdateBeforeProcessing(); var oldState = workInProgress.memoizedState; var newState = (instance.state = oldState); - processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); - newState = workInProgress.memoizedState; + var updateQueue = workInProgress.updateQueue; + + if (updateQueue !== null) { + processUpdateQueue( + workInProgress, + updateQueue, + newProps, + instance, + renderExpirationTime + ); + newState = workInProgress.memoizedState; + } if ( oldProps === newProps && @@ -7806,7 +8883,6 @@ function updateClassInstance( workInProgress.effectTag |= Update; } } - if (typeof instance.getSnapshotBeforeUpdate === "function") { if ( oldProps !== current.memoizedProps || @@ -7815,7 +8891,6 @@ function updateClassInstance( workInProgress.effectTag |= Snapshot; } } - return false; } @@ -7880,7 +8955,6 @@ function updateClassInstance( workInProgress.effectTag |= Update; } } - if (typeof instance.getSnapshotBeforeUpdate === "function") { if ( oldProps !== current.memoizedProps || @@ -7919,7 +8993,6 @@ var warnForMissingKey = function(child) {}; * object keys are not valid. This allows us to keep track of children between * updates. */ - ownerHasKeyUseWarning = {}; ownerHasFunctionTypeWarning = {}; @@ -7950,8 +9023,8 @@ var warnForMissingKey = function(child) {}; } ownerHasKeyUseWarning[currentComponentErrorInfo] = true; - - error( + warning$1( + false, "Each child in a list should have a unique " + '"key" prop. See https://fb.me/react-warning-keys for ' + "more information." @@ -7959,11 +9032,10 @@ var warnForMissingKey = function(child) {}; }; } -var isArray$1 = Array.isArray; +var isArray = Array.isArray; -function coerceRef(returnFiber, current, element) { +function coerceRef(returnFiber, current$$1, element) { var mixedRef = element.ref; - if ( mixedRef !== null && typeof mixedRef !== "function" && @@ -7972,21 +9044,24 @@ 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 - // because these cannot be automatically converted to an arrow function - // using a codemod. Therefore, we don't have to warn about string refs again. - !( - element._owner && - element._self && - element._owner.stateNode !== element._self - ) - ) { + if (returnFiber.mode & StrictMode || warnAboutStringRefs) { var componentName = getComponentName(returnFiber.type) || "Component"; - if (!didWarnAboutStringRefs[componentName]) { - { - error( + if (warnAboutStringRefs) { + warningWithoutStack$1( + false, + 'Component "%s" contains the string ref "%s". Support for string refs ' + + "will be removed in a future major release. We recommend using " + + "useRef() or createRef() instead. " + + "Learn more about using refs safely here: " + + "https://fb.me/react-strict-mode-string-ref%s", + componentName, + mixedRef, + getStackByFiberInDevAndProd(returnFiber) + ); + } else { + warningWithoutStack$1( + false, 'A string ref, "%s", has been found within a strict mode tree. ' + "String refs are a source of potential bugs and should be avoided. " + "We recommend using useRef() or createRef() instead. " + @@ -7996,7 +9071,6 @@ function coerceRef(returnFiber, current, element) { getStackByFiberInDevAndProd(returnFiber) ); } - didWarnAboutStringRefs[componentName] = true; } } @@ -8011,7 +9085,7 @@ function coerceRef(returnFiber, current, element) { if (!(ownerFiber.tag === ClassComponent)) { throw Error( - "Function components cannot have string refs. We recommend using useRef() instead. Learn more about using refs safely here: https://fb.me/react-strict-mode-string-ref" + "Function components cannot have refs. Did you mean to use React.forwardRef()?" ); } @@ -8029,12 +9103,12 @@ function coerceRef(returnFiber, current, element) { var stringRef = "" + mixedRef; // Check if previous string ref matches new string ref if ( - current !== null && - current.ref !== null && - typeof current.ref === "function" && - current.ref._stringRef === stringRef + current$$1 !== null && + current$$1.ref !== null && + typeof current$$1.ref === "function" && + current$$1.ref._stringRef === stringRef ) { - return current.ref; + return current$$1.ref; } var ref = function(value) { @@ -8044,7 +9118,6 @@ function coerceRef(returnFiber, current, element) { // This is a lazy pooled frozen object, so we need to initialize. refs = inst.refs = {}; } - if (value === null) { delete refs[stringRef]; } else { @@ -8077,7 +9150,6 @@ function coerceRef(returnFiber, current, element) { function throwOnInvalidObjectType(returnFiber, newChild) { if (returnFiber.type !== "textarea") { var addendum = ""; - { addendum = " If you meant to render a collection of children, use an array " + @@ -8099,25 +9171,23 @@ function throwOnInvalidObjectType(returnFiber, newChild) { } function warnOnFunctionType() { - { - var currentComponentErrorInfo = - "Functions are not valid as a React child. This may happen if " + - "you return a Component instead of from render. " + - "Or maybe you meant to call this function rather than return it." + - getCurrentFiberStackInDev(); + var currentComponentErrorInfo = + "Functions are not valid as a React child. This may happen if " + + "you return a Component instead of from render. " + + "Or maybe you meant to call this function rather than return it." + + getCurrentFiberStackInDev(); - if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) { - return; - } - - ownerHasFunctionTypeWarning[currentComponentErrorInfo] = true; - - error( - "Functions are not valid as a React child. This may happen if " + - "you return a Component instead of from render. " + - "Or maybe you meant to call this function rather than return it." - ); + if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) { + return; } + + ownerHasFunctionTypeWarning[currentComponentErrorInfo] = true; + warning$1( + false, + "Functions are not valid as a React child. This may happen if " + + "you return a Component instead of from render. " + + "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 @@ -8142,7 +9212,6 @@ function ChildReconciler(shouldTrackSideEffects) { } else { returnFiber.firstEffect = returnFiber.lastEffect = childToDelete; } - childToDelete.nextEffect = null; childToDelete.effectTag = Deletion; } @@ -8160,7 +9229,6 @@ function ChildReconciler(shouldTrackSideEffects) { deleteChild(returnFiber, childToDelete); childToDelete = childToDelete.sibling; } - return null; } @@ -8184,10 +9252,10 @@ function ChildReconciler(shouldTrackSideEffects) { return existingChildren; } - function useFiber(fiber, pendingProps) { + function useFiber(fiber, pendingProps, expirationTime) { // We currently set sibling to null and index to 0 here because it is easy // to forget to do before returning it. E.g. for the single child case. - var clone = createWorkInProgress(fiber, pendingProps); + var clone = createWorkInProgress(fiber, pendingProps, expirationTime); clone.index = 0; clone.sibling = null; return clone; @@ -8195,16 +9263,15 @@ function ChildReconciler(shouldTrackSideEffects) { function placeChild(newFiber, lastPlacedIndex, newIndex) { newFiber.index = newIndex; - if (!shouldTrackSideEffects) { // Noop. return lastPlacedIndex; } - var current = newFiber.alternate; + var current$$1 = newFiber.alternate; - if (current !== null) { - var oldIndex = current.index; + if (current$$1 !== null) { + var oldIndex = current$$1.index; if (oldIndex < lastPlacedIndex) { // This is a move. @@ -8227,12 +9294,16 @@ function ChildReconciler(shouldTrackSideEffects) { if (shouldTrackSideEffects && newFiber.alternate === null) { newFiber.effectTag = Placement; } - return newFiber; } - function updateTextNode(returnFiber, current, textContent, expirationTime) { - if (current === null || current.tag !== HostText) { + function updateTextNode( + returnFiber, + current$$1, + textContent, + expirationTime + ) { + if (current$$1 === null || current$$1.tag !== HostText) { // Insert var created = createFiberFromText( textContent, @@ -8243,48 +9314,46 @@ function ChildReconciler(shouldTrackSideEffects) { return created; } else { // Update - var existing = useFiber(current, textContent); + var existing = useFiber(current$$1, textContent, expirationTime); existing.return = returnFiber; return existing; } } - function updateElement(returnFiber, current, element, expirationTime) { - if (current !== null) { - if ( - 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); - existing.ref = coerceRef(returnFiber, current, element); - existing.return = returnFiber; - - { - existing._debugSource = element._source; - existing._debugOwner = element._owner; - } - - return existing; + function updateElement(returnFiber, current$$1, element, expirationTime) { + if ( + current$$1 !== null && + (current$$1.elementType === element.type || // Keep this check inline so it only runs on the false path: + isCompatibleFamilyForHotReloading(current$$1, element)) + ) { + // Move based on index + var existing = useFiber(current$$1, element.props, expirationTime); + existing.ref = coerceRef(returnFiber, current$$1, element); + existing.return = returnFiber; + { + existing._debugSource = element._source; + existing._debugOwner = element._owner; } - } // Insert - - var created = createFiberFromElement( - element, - returnFiber.mode, - expirationTime - ); - created.ref = coerceRef(returnFiber, current, element); - created.return = returnFiber; - return created; + return existing; + } else { + // Insert + var created = createFiberFromElement( + element, + returnFiber.mode, + expirationTime + ); + created.ref = coerceRef(returnFiber, current$$1, element); + created.return = returnFiber; + return created; + } } - function updatePortal(returnFiber, current, portal, expirationTime) { + function updatePortal(returnFiber, current$$1, portal, expirationTime) { if ( - current === null || - current.tag !== HostPortal || - current.stateNode.containerInfo !== portal.containerInfo || - current.stateNode.implementation !== portal.implementation + current$$1 === null || + current$$1.tag !== HostPortal || + current$$1.stateNode.containerInfo !== portal.containerInfo || + current$$1.stateNode.implementation !== portal.implementation ) { // Insert var created = createFiberFromPortal( @@ -8296,14 +9365,24 @@ function ChildReconciler(shouldTrackSideEffects) { return created; } else { // Update - var existing = useFiber(current, portal.children || []); + var existing = useFiber( + current$$1, + portal.children || [], + expirationTime + ); existing.return = returnFiber; return existing; } } - function updateFragment(returnFiber, current, fragment, expirationTime, key) { - if (current === null || current.tag !== Fragment) { + function updateFragment( + returnFiber, + current$$1, + fragment, + expirationTime, + key + ) { + if (current$$1 === null || current$$1.tag !== Fragment) { // Insert var created = createFiberFromFragment( fragment, @@ -8315,7 +9394,7 @@ function ChildReconciler(shouldTrackSideEffects) { return created; } else { // Update - var existing = useFiber(current, fragment); + var existing = useFiber(current$$1, fragment, expirationTime); existing.return = returnFiber; return existing; } @@ -8343,32 +9422,28 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime ); - _created.ref = coerceRef(returnFiber, null, newChild); _created.return = returnFiber; return _created; } - case REACT_PORTAL_TYPE: { var _created2 = createFiberFromPortal( newChild, returnFiber.mode, expirationTime ); - _created2.return = returnFiber; return _created2; } } - if (isArray$1(newChild) || getIteratorFn(newChild)) { + if (isArray(newChild) || getIteratorFn(newChild)) { var _created3 = createFiberFromFragment( newChild, returnFiber.mode, expirationTime, null ); - _created3.return = returnFiber; return _created3; } @@ -8396,7 +9471,6 @@ function ChildReconciler(shouldTrackSideEffects) { if (key !== null) { return null; } - return updateTextNode( returnFiber, oldFiber, @@ -8418,7 +9492,6 @@ function ChildReconciler(shouldTrackSideEffects) { key ); } - return updateElement( returnFiber, oldFiber, @@ -8429,7 +9502,6 @@ function ChildReconciler(shouldTrackSideEffects) { return null; } } - case REACT_PORTAL_TYPE: { if (newChild.key === key) { return updatePortal( @@ -8444,7 +9516,7 @@ function ChildReconciler(shouldTrackSideEffects) { } } - if (isArray$1(newChild) || getIteratorFn(newChild)) { + if (isArray(newChild) || getIteratorFn(newChild)) { if (key !== null) { return null; } @@ -8496,7 +9568,6 @@ function ChildReconciler(shouldTrackSideEffects) { existingChildren.get( newChild.key === null ? newIdx : newChild.key ) || null; - if (newChild.type === REACT_FRAGMENT_TYPE) { return updateFragment( returnFiber, @@ -8506,7 +9577,6 @@ function ChildReconciler(shouldTrackSideEffects) { newChild.key ); } - return updateElement( returnFiber, _matchedFiber, @@ -8514,13 +9584,11 @@ function ChildReconciler(shouldTrackSideEffects) { expirationTime ); } - case REACT_PORTAL_TYPE: { var _matchedFiber2 = existingChildren.get( newChild.key === null ? newIdx : newChild.key ) || null; - return updatePortal( returnFiber, _matchedFiber2, @@ -8530,9 +9598,8 @@ function ChildReconciler(shouldTrackSideEffects) { } } - if (isArray$1(newChild) || getIteratorFn(newChild)) { + if (isArray(newChild) || getIteratorFn(newChild)) { var _matchedFiber3 = existingChildren.get(newIdx) || null; - return updateFragment( returnFiber, _matchedFiber3, @@ -8562,7 +9629,6 @@ function ChildReconciler(shouldTrackSideEffects) { if (typeof child !== "object" || child === null) { return knownKeys; } - switch (child.$$typeof) { case REACT_ELEMENT_TYPE: case REACT_PORTAL_TYPE: @@ -8578,13 +9644,12 @@ function ChildReconciler(shouldTrackSideEffects) { knownKeys.add(key); break; } - if (!knownKeys.has(key)) { knownKeys.add(key); break; } - - error( + warning$1( + false, "Encountered two children with the same key, `%s`. " + "Keys should be unique so that components maintain their identity " + "across updates. Non-unique keys may cause children to be " + @@ -8592,11 +9657,11 @@ function ChildReconciler(shouldTrackSideEffects) { "could change in a future version.", key ); - + break; + default: break; } } - return knownKeys; } @@ -8637,7 +9702,6 @@ function ChildReconciler(shouldTrackSideEffects) { var lastPlacedIndex = 0; var newIdx = 0; var nextOldFiber = null; - for (; oldFiber !== null && newIdx < newChildren.length; newIdx++) { if (oldFiber.index > newIdx) { nextOldFiber = oldFiber; @@ -8645,14 +9709,12 @@ function ChildReconciler(shouldTrackSideEffects) { } else { nextOldFiber = oldFiber.sibling; } - var newFiber = updateSlot( returnFiber, oldFiber, newChildren[newIdx], expirationTime ); - if (newFiber === null) { // TODO: This breaks on empty slots like null children. That's // unfortunate because it triggers the slow path all the time. We need @@ -8685,7 +9747,6 @@ function ChildReconciler(shouldTrackSideEffects) { // with the previous one. previousNewFiber.sibling = newFiber; } - previousNewFiber = newFiber; oldFiber = nextOldFiber; } @@ -8735,7 +9796,6 @@ function ChildReconciler(shouldTrackSideEffects) { newChildren[newIdx], expirationTime ); - if (_newFiber2 !== null) { if (shouldTrackSideEffects) { if (_newFiber2.alternate !== null) { @@ -8756,7 +9816,6 @@ function ChildReconciler(shouldTrackSideEffects) { } else { previousNewFiber.sibling = _newFiber2; } - previousNewFiber = _newFiber2; } } @@ -8795,28 +9854,28 @@ function ChildReconciler(shouldTrackSideEffects) { typeof Symbol === "function" && // $FlowFixMe Flow doesn't know about toStringTag newChildrenIterable[Symbol.toStringTag] === "Generator" ) { - if (!didWarnAboutGenerators) { - error( - "Using Generators as children is unsupported and will likely yield " + - "unexpected results because enumerating a generator mutates it. " + - "You may convert it to an array with `Array.from()` or the " + - "`[...spread]` operator before rendering. Keep in mind " + - "you might need to polyfill these features for older browsers." - ); - } - + !didWarnAboutGenerators + ? warning$1( + false, + "Using Generators as children is unsupported and will likely yield " + + "unexpected results because enumerating a generator mutates it. " + + "You may convert it to an array with `Array.from()` or the " + + "`[...spread]` operator before rendering. Keep in mind " + + "you might need to polyfill these features for older browsers." + ) + : void 0; didWarnAboutGenerators = true; } // Warn about using Maps as children if (newChildrenIterable.entries === iteratorFn) { - if (!didWarnAboutMaps) { - error( - "Using Maps as children is unsupported and will likely yield " + - "unexpected results. Convert it to a sequence/iterable of keyed " + - "ReactElements instead." - ); - } - + !didWarnAboutMaps + ? warning$1( + false, + "Using Maps as children is unsupported and will likely yield " + + "unexpected results. Convert it to a sequence/iterable of keyed " + + "ReactElements instead." + ) + : void 0; didWarnAboutMaps = true; } // First, validate keys. // We'll get a different iterator later for the main pass. @@ -8860,14 +9919,12 @@ function ChildReconciler(shouldTrackSideEffects) { } else { nextOldFiber = oldFiber.sibling; } - var newFiber = updateSlot( returnFiber, oldFiber, step.value, expirationTime ); - if (newFiber === null) { // TODO: This breaks on empty slots like null children. That's // unfortunate because it triggers the slow path all the time. We need @@ -8900,7 +9957,6 @@ function ChildReconciler(shouldTrackSideEffects) { // with the previous one. previousNewFiber.sibling = newFiber; } - previousNewFiber = newFiber; oldFiber = nextOldFiber; } @@ -8946,7 +10002,6 @@ function ChildReconciler(shouldTrackSideEffects) { step.value, expirationTime ); - if (_newFiber4 !== null) { if (shouldTrackSideEffects) { if (_newFiber4.alternate !== null) { @@ -8967,7 +10022,6 @@ function ChildReconciler(shouldTrackSideEffects) { } else { previousNewFiber.sibling = _newFiber4; } - previousNewFiber = _newFiber4; } } @@ -8995,7 +10049,7 @@ function ChildReconciler(shouldTrackSideEffects) { // We already have an existing node so let's just update it and delete // the rest. deleteRemainingChildren(returnFiber, currentFirstChild.sibling); - var existing = useFiber(currentFirstChild, textContent); + var existing = useFiber(currentFirstChild, textContent, expirationTime); existing.return = returnFiber; return existing; } // The existing first child is not a text node so we need to create one @@ -9019,64 +10073,38 @@ function ChildReconciler(shouldTrackSideEffects) { ) { var key = element.key; var child = currentFirstChild; - while (child !== null) { // 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; - - { - existing._debugSource = element._source; - existing._debugOwner = element._owner; - } - - return existing; - } - - break; - } - - case Block: - - // We intentionally fallthrough here if enableBlocksAPI is not on. - // eslint-disable-next-lined no-fallthrough - - default: { - if ( - child.elementType === element.type || // Keep this check inline so it only runs on the false path: + if ( + child.tag === Fragment + ? element.type === REACT_FRAGMENT_TYPE + : child.elementType === element.type || // Keep this check inline so it only runs on the false path: isCompatibleFamilyForHotReloading(child, element) - ) { - deleteRemainingChildren(returnFiber, child.sibling); - - var _existing3 = useFiber(child, element.props); - - _existing3.ref = coerceRef(returnFiber, child, element); - _existing3.return = returnFiber; - - { - _existing3._debugSource = element._source; - _existing3._debugOwner = element._owner; - } - - return _existing3; - } - - break; + ) { + deleteRemainingChildren(returnFiber, child.sibling); + var existing = useFiber( + child, + element.type === REACT_FRAGMENT_TYPE + ? element.props.children + : element.props, + expirationTime + ); + existing.ref = coerceRef(returnFiber, child, element); + existing.return = returnFiber; + { + existing._debugSource = element._source; + existing._debugOwner = element._owner; } - } // Didn't match. - - deleteRemainingChildren(returnFiber, child); - break; + return existing; + } else { + deleteRemainingChildren(returnFiber, child); + break; + } } else { deleteChild(returnFiber, child); } - child = child.sibling; } @@ -9095,7 +10123,6 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime ); - _created4.ref = coerceRef(returnFiber, currentFirstChild, element); _created4.return = returnFiber; return _created4; @@ -9110,7 +10137,6 @@ function ChildReconciler(shouldTrackSideEffects) { ) { var key = portal.key; var child = currentFirstChild; - while (child !== null) { // TODO: If key === null and child.key === null, then this only applies to // the first item in the list. @@ -9121,7 +10147,7 @@ function ChildReconciler(shouldTrackSideEffects) { child.stateNode.implementation === portal.implementation ) { deleteRemainingChildren(returnFiber, child.sibling); - var existing = useFiber(child, portal.children || []); + var existing = useFiber(child, portal.children || [], expirationTime); existing.return = returnFiber; return existing; } else { @@ -9131,7 +10157,6 @@ function ChildReconciler(shouldTrackSideEffects) { } else { deleteChild(returnFiber, child); } - child = child.sibling; } @@ -9182,7 +10207,6 @@ function ChildReconciler(shouldTrackSideEffects) { expirationTime ) ); - case REACT_PORTAL_TYPE: return placeSingleChild( reconcileSinglePortal( @@ -9206,7 +10230,7 @@ function ChildReconciler(shouldTrackSideEffects) { ); } - if (isArray$1(newChild)) { + if (isArray(newChild)) { return reconcileChildrenArray( returnFiber, currentFirstChild, @@ -9233,7 +10257,6 @@ function ChildReconciler(shouldTrackSideEffects) { warnOnFunctionType(); } } - if (typeof newChild === "undefined" && !isUnkeyedTopLevelFragment) { // If the new child is undefined, and the return fiber is a composite // component, throw an error. If Fiber return types are disabled, @@ -9242,7 +10265,6 @@ function ChildReconciler(shouldTrackSideEffects) { case ClassComponent: { { var instance = returnFiber.stateNode; - if (instance.render._isMockFunction) { // We allow auto-mocks to proceed as if they're returning null. break; @@ -9274,8 +10296,8 @@ function ChildReconciler(shouldTrackSideEffects) { var reconcileChildFibers = ChildReconciler(true); var mountChildFibers = ChildReconciler(false); -function cloneChildFibers(current, workInProgress) { - if (!(current === null || workInProgress.child === current.child)) { +function cloneChildFibers(current$$1, workInProgress) { + if (!(current$$1 === null || workInProgress.child === current$$1.child)) { throw Error("Resuming work not yet implemented."); } @@ -9284,7 +10306,11 @@ function cloneChildFibers(current, workInProgress) { } var currentChild = workInProgress.child; - var newChild = createWorkInProgress(currentChild, currentChild.pendingProps); + var newChild = createWorkInProgress( + currentChild, + currentChild.pendingProps, + currentChild.expirationTime + ); workInProgress.child = newChild; newChild.return = workInProgress; @@ -9292,7 +10318,8 @@ function cloneChildFibers(current, workInProgress) { currentChild = currentChild.sibling; newChild = newChild.sibling = createWorkInProgress( currentChild, - currentChild.pendingProps + currentChild.pendingProps, + currentChild.expirationTime ); newChild.return = workInProgress; } @@ -9342,7 +10369,7 @@ function pushHostContainer(fiber, nextRootInstance) { // So we push an empty value first. This lets us safely unwind on errors. push(contextStackCursor$1, NO_CONTEXT, fiber); - var nextRootContext = getRootHostContext(); // Now that we know this function doesn't throw, replace it. + var nextRootContext = getRootHostContext(nextRootInstance); // Now that we know this function doesn't throw, replace it. pop(contextStackCursor$1, fiber); push(contextStackCursor$1, nextRootContext, fiber); @@ -9362,7 +10389,7 @@ function getHostContext() { function pushHostContext(fiber) { var rootInstance = requiredContext(rootInstanceStackCursor.current); var context = requiredContext(contextStackCursor$1.current); - var nextContext = getChildHostContext(context, fiber.type); // Don't push this Fiber's context unless it's unique. + var nextContext = getChildHostContext(context, fiber.type, rootInstance); // Don't push this Fiber's context unless it's unique. if (context === nextContext) { return; @@ -9465,8 +10492,8 @@ function findFirstSuspended(row) { if ( dehydrated === null || - isSuspenseInstancePending() || - isSuspenseInstanceFallback() + isSuspenseInstancePending(dehydrated) || + isSuspenseInstanceFallback(dehydrated) ) { return node; } @@ -9477,7 +10504,6 @@ function findFirstSuspended(row) { node.memoizedProps.revealOrder !== undefined ) { var didSuspend = (node.effectTag & DidCapture) !== NoEffect; - if (didSuspend) { return node; } @@ -9506,7 +10532,191 @@ function findFirstSuspended(row) { return null; } -function createDeprecatedResponderListener(responder, props) { +var emptyObject$1 = {}; +var isArray$2 = Array.isArray; +function createResponderInstance( + responder, + responderProps, + responderState, + fiber +) { + return { + fiber: fiber, + props: responderProps, + responder: responder, + rootEventTypes: null, + state: responderState + }; +} + +function mountEventResponder$1( + responder, + responderProps, + fiber, + respondersMap, + rootContainerInstance +) { + var responderState = emptyObject$1; + var getInitialState = responder.getInitialState; + + if (getInitialState !== null) { + responderState = getInitialState(responderProps); + } + + var responderInstance = createResponderInstance( + responder, + responderProps, + responderState, + fiber + ); + + if (!rootContainerInstance) { + var node = fiber; + + while (node !== null) { + var tag = node.tag; + + if (tag === HostComponent) { + rootContainerInstance = node.stateNode; + break; + } else if (tag === HostRoot) { + rootContainerInstance = node.stateNode.containerInfo; + break; + } + + node = node.return; + } + } + + mountResponderInstance( + responder, + responderInstance, + responderProps, + responderState, + rootContainerInstance + ); + respondersMap.set(responder, responderInstance); +} + +function updateEventListener( + listener, + fiber, + visistedResponders, + respondersMap, + rootContainerInstance +) { + var responder; + var props; + + if (listener) { + responder = listener.responder; + props = listener.props; + } + + if (!(responder && responder.$$typeof === REACT_RESPONDER_TYPE)) { + throw Error( + "An invalid value was used as an event listener. Expect one or many event listeners created via React.unstable_useResponder()." + ); + } + + var listenerProps = props; + + if (visistedResponders.has(responder)) { + // show warning + { + warning$1( + false, + 'Duplicate event responder "%s" found in event listeners. ' + + "Event listeners passed to elements cannot use the same event responder more than once.", + responder.displayName + ); + } + + return; + } + + visistedResponders.add(responder); + var responderInstance = respondersMap.get(responder); + + if (responderInstance === undefined) { + // Mount (happens in either complete or commit phase) + mountEventResponder$1( + responder, + listenerProps, + fiber, + respondersMap, + rootContainerInstance + ); + } else { + // Update (happens during commit phase only) + responderInstance.props = listenerProps; + responderInstance.fiber = fiber; + } +} + +function updateEventListeners(listeners, fiber, rootContainerInstance) { + var visistedResponders = new Set(); + var dependencies = fiber.dependencies; + + if (listeners != null) { + if (dependencies === null) { + dependencies = fiber.dependencies = { + expirationTime: NoWork, + firstContext: null, + responders: new Map() + }; + } + + var respondersMap = dependencies.responders; + + if (respondersMap === null) { + respondersMap = new Map(); + } + + if (isArray$2(listeners)) { + for (var i = 0, length = listeners.length; i < length; i++) { + var listener = listeners[i]; + updateEventListener( + listener, + fiber, + visistedResponders, + respondersMap, + rootContainerInstance + ); + } + } else { + updateEventListener( + listeners, + fiber, + visistedResponders, + respondersMap, + rootContainerInstance + ); + } + } + + if (dependencies !== null) { + var _respondersMap = dependencies.responders; + + if (_respondersMap !== null) { + // Unmount + var mountedResponders = Array.from(_respondersMap.keys()); + + for (var _i = 0, _length = mountedResponders.length; _i < _length; _i++) { + var mountedResponder = mountedResponders[_i]; + + if (!visistedResponders.has(mountedResponder)) { + var responderInstance = _respondersMap.get(mountedResponder); + + unmountResponderInstance(responderInstance); + + _respondersMap.delete(mountedResponder); + } + } + } + } +} +function createResponderListener(responder, props) { var eventResponderListener = { responder: responder, props: props @@ -9519,19 +10729,33 @@ function createDeprecatedResponderListener(responder, props) { return eventResponderListener; } -var HasEffect = - /* */ - 1; // Represents the phase in which the effect (not the clean-up) fires. - -var Layout = - /* */ +var NoEffect$1 = + /* */ + 0; +var UnmountSnapshot = + /* */ 2; -var Passive$1 = - /* */ +var UnmountMutation = + /* */ 4; +var MountMutation = + /* */ + 8; +var UnmountLayout = + /* */ + 16; +var MountLayout = + /* */ + 32; +var MountPassive = + /* */ + 64; +var UnmountPassive = + /* */ + 128; -var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher, - ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig; +var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher; +var ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig; var didWarnAboutMismatchedHooksForComponent; { @@ -9539,7 +10763,7 @@ var didWarnAboutMismatchedHooksForComponent; } // These are set right before calling the component. -var renderExpirationTime = NoWork; // The work-in-progress fiber. I've named it differently to distinguish it from +var renderExpirationTime$1 = NoWork; // The work-in-progress fiber. I've named it differently to distinguish it from // the work-in-progress hook. var currentlyRenderingFiber$1 = null; // Hooks are stored as a linked list on the fiber's memoizedState field. The @@ -9548,12 +10772,26 @@ var currentlyRenderingFiber$1 = null; // Hooks are stored as a linked list on th // work-in-progress fiber. var currentHook = null; -var workInProgressHook = null; // Whether an update was scheduled at any point during the render phase. This -// does not get reset if we do another render pass; only when we're completely -// finished evaluating this component. This is an optimization so we know -// whether we need to clear render phase updates after a throw. - -var didScheduleRenderPhaseUpdate = false; +var nextCurrentHook = null; +var firstWorkInProgressHook = null; +var workInProgressHook = null; +var nextWorkInProgressHook = null; +var remainingExpirationTime = NoWork; +var componentUpdateQueue = null; +var sideEffectTag = 0; // Updates scheduled during render will trigger an immediate re-render at the +// end of the current pass. We can't store these updates on the normal queue, +// because if the work is aborted, they should be discarded. Because this is +// a relatively rare case, we also don't want to add an additional field to +// either the hook or queue object types. So we store them in a lazily create +// map of queue -> render-phase updates, which are discarded once the component +// completes without re-rendering. +// Whether an update was scheduled during the currently executing render pass. + +var didScheduleRenderPhaseUpdate = false; // Lazily created map of render-phase updates + +var renderPhaseUpdates = null; // Counter to prevent infinite loops. + +var numberOfReRenders = 0; var RE_RENDER_LIMIT = 25; // In DEV, this is the name of the currently executing primitive hook var currentHookNameInDev = null; // In DEV, this list ensures that hooks are called in the same order between renders. @@ -9585,7 +10823,6 @@ function updateHookTypesDev() { if (hookTypesDev !== null) { hookTypesUpdateIndexDev++; - if (hookTypesDev[hookTypesUpdateIndexDev] !== hookName) { warnOnHookMismatchInDev(hookName); } @@ -9598,7 +10835,8 @@ function checkDepsAreArrayDev(deps) { if (deps !== undefined && deps !== null && !Array.isArray(deps)) { // Verify deps, but only on mount to avoid extra checks. // It's unlikely their type would change as usually you define them inline. - error( + warning$1( + false, "%s received a final argument that is not an array (instead, received `%s`). When " + "specified, the final argument must be an array.", currentHookNameInDev, @@ -9611,7 +10849,6 @@ function checkDepsAreArrayDev(deps) { function warnOnHookMismatchInDev(currentHookName) { { var componentName = getComponentName(currentlyRenderingFiber$1.type); - if (!didWarnAboutMismatchedHooksForComponent.has(componentName)) { didWarnAboutMismatchedHooksForComponent.add(componentName); @@ -9634,7 +10871,8 @@ function warnOnHookMismatchInDev(currentHookName) { table += row; } - error( + warning$1( + false, "React has detected a change in the order of Hooks called by %s. " + "This will lead to bugs and errors if not fixed. " + "For more information, read the Rules of Hooks: https://fb.me/rules-of-hooks\n\n" + @@ -9668,14 +10906,14 @@ function areHookInputsEqual(nextDeps, prevDeps) { if (prevDeps === null) { { - error( + warning$1( + false, "%s received a final argument during this render, but not during " + "the previous render. Even though the final argument is optional, " + "its type cannot change between renders.", currentHookNameInDev ); } - return false; } @@ -9683,7 +10921,8 @@ function areHookInputsEqual(nextDeps, prevDeps) { // Don't bother comparing lengths in prod because these arrays should be // passed inline. if (nextDeps.length !== prevDeps.length) { - error( + warning$1( + false, "The final argument passed to %s changed size between renders. The " + "order and size of this array must remain constant.\n\n" + "Previous: %s\n" + @@ -9696,7 +10935,7 @@ function areHookInputsEqual(nextDeps, prevDeps) { } for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) { - if (objectIs(nextDeps[i], prevDeps[i])) { + if (is$1(nextDeps[i], prevDeps[i])) { continue; } @@ -9711,11 +10950,12 @@ function renderWithHooks( workInProgress, Component, props, - secondArg, + refOrContext, nextRenderExpirationTime ) { - renderExpirationTime = nextRenderExpirationTime; + renderExpirationTime$1 = nextRenderExpirationTime; currentlyRenderingFiber$1 = workInProgress; + nextCurrentHook = current !== null ? current.memoizedState : null; { hookTypesDev = current !== null ? current._debugHookTypes : null; @@ -9723,87 +10963,89 @@ function renderWithHooks( ignorePreviousDependencies = current !== null && current.type !== workInProgress.type; - } - - workInProgress.memoizedState = null; - workInProgress.updateQueue = null; - workInProgress.expirationTime = NoWork; // The following should have already been reset + } // The following should have already been reset // currentHook = null; // workInProgressHook = null; + // remainingExpirationTime = NoWork; + // componentUpdateQueue = null; // didScheduleRenderPhaseUpdate = false; + // renderPhaseUpdates = null; + // numberOfReRenders = 0; + // sideEffectTag = 0; // TODO Warn if no hooks are used at all during mount, then some are used during update. - // Currently we will identify the update render as a mount because memoizedState === null. + // Currently we will identify the update render as a mount because nextCurrentHook === null. // This is tricky because it's valid for certain types of components (e.g. React.lazy) - // Using memoizedState to differentiate between mount/update only works if at least one stateful hook is used. + // Using nextCurrentHook to differentiate between mount/update only works if at least one stateful hook is used. // Non-stateful hooks (e.g. context) don't get added to memoizedState, - // so memoizedState would be null during updates and mounts. + // so nextCurrentHook would be null during updates and mounts. { - if (current !== null && current.memoizedState !== null) { - ReactCurrentDispatcher.current = HooksDispatcherOnUpdateInDEV; + if (nextCurrentHook !== null) { + ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV; } else if (hookTypesDev !== null) { // This dispatcher handles an edge case where a component is updating, // but no stateful hooks have been used. // We want to match the production code behavior (which will use HooksDispatcherOnMount), // but with the extra DEV validation to ensure hooks ordering hasn't changed. // This dispatcher does that. - ReactCurrentDispatcher.current = HooksDispatcherOnMountWithHookTypesInDEV; + ReactCurrentDispatcher$1.current = HooksDispatcherOnMountWithHookTypesInDEV; } else { - ReactCurrentDispatcher.current = HooksDispatcherOnMountInDEV; + ReactCurrentDispatcher$1.current = HooksDispatcherOnMountInDEV; } } - var children = Component(props, secondArg); // Check if there was a render phase update - - if (workInProgress.expirationTime === renderExpirationTime) { - // Keep rendering in a loop for as long as render phase updates continue to - // be scheduled. Use a counter to prevent infinite loops. - var numberOfReRenders = 0; + var children = Component(props, refOrContext); + if (didScheduleRenderPhaseUpdate) { do { - workInProgress.expirationTime = NoWork; - - if (!(numberOfReRenders < RE_RENDER_LIMIT)) { - throw Error( - "Too many re-renders. React limits the number of renders to prevent an infinite loop." - ); - } - + didScheduleRenderPhaseUpdate = false; numberOfReRenders += 1; - { // Even when hot reloading, allow dependencies to stabilize // after first render to prevent infinite render phase updates. ignorePreviousDependencies = false; } // Start over from the beginning of the list + nextCurrentHook = current !== null ? current.memoizedState : null; + nextWorkInProgressHook = firstWorkInProgressHook; currentHook = null; workInProgressHook = null; - workInProgress.updateQueue = null; + componentUpdateQueue = null; { // Also validate hook order for cascading updates. hookTypesUpdateIndexDev = -1; } - ReactCurrentDispatcher.current = HooksDispatcherOnRerenderInDEV; - children = Component(props, secondArg); - } while (workInProgress.expirationTime === renderExpirationTime); + ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV; + children = Component(props, refOrContext); + } while (didScheduleRenderPhaseUpdate); + + renderPhaseUpdates = null; + numberOfReRenders = 0; } // We can assume the previous dispatcher is always this one, since we set it // at the beginning of the render phase and there's no re-entrancy. - ReactCurrentDispatcher.current = ContextOnlyDispatcher; + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; + var renderedWork = currentlyRenderingFiber$1; + renderedWork.memoizedState = firstWorkInProgressHook; + renderedWork.expirationTime = remainingExpirationTime; + renderedWork.updateQueue = componentUpdateQueue; + renderedWork.effectTag |= sideEffectTag; { - workInProgress._debugHookTypes = hookTypesDev; + renderedWork._debugHookTypes = hookTypesDev; } // This check uses currentHook so that it works the same in DEV and prod bundles. // hookTypesDev could catch more cases (e.g. context) but only in DEV bundles. var didRenderTooFewHooks = currentHook !== null && currentHook.next !== null; - renderExpirationTime = NoWork; + renderExpirationTime$1 = NoWork; currentlyRenderingFiber$1 = null; currentHook = null; + nextCurrentHook = null; + firstWorkInProgressHook = null; workInProgressHook = null; + nextWorkInProgressHook = null; { currentHookNameInDev = null; @@ -9811,7 +11053,12 @@ function renderWithHooks( hookTypesUpdateIndexDev = -1; } - didScheduleRenderPhaseUpdate = false; + remainingExpirationTime = NoWork; + componentUpdateQueue = null; + sideEffectTag = 0; // These were reset above + // didScheduleRenderPhaseUpdate = false; + // renderPhaseUpdates = null; + // numberOfReRenders = 0; if (!!didRenderTooFewHooks) { throw Error( @@ -9829,37 +11076,20 @@ function bailoutHooks(current, workInProgress, expirationTime) { current.expirationTime = NoWork; } } -function resetHooksAfterThrow() { +function resetHooks() { // We can assume the previous dispatcher is always this one, since we set it // at the beginning of the render phase and there's no re-entrancy. - ReactCurrentDispatcher.current = ContextOnlyDispatcher; - - if (didScheduleRenderPhaseUpdate) { - // There were render phase updates. These are only valid for this render - // phase, which we are now aborting. Remove the updates from the queues so - // they do not persist to the next render. Do not remove updates from hooks - // that weren't processed. - // - // Only reset the updates from the queue if it has a clone. If it does - // not have a clone, that means it wasn't processed, and the updates were - // scheduled before we entered the render phase. - var hook = currentlyRenderingFiber$1.memoizedState; - - while (hook !== null) { - var queue = hook.queue; - - if (queue !== null) { - queue.pending = null; - } - - hook = hook.next; - } - } + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; // This is used to reset the state of this module when a component throws. + // It's also called inside mountIndeterminateComponent if we determine the + // component is a module-style component. - renderExpirationTime = NoWork; + renderExpirationTime$1 = NoWork; currentlyRenderingFiber$1 = null; currentHook = null; + nextCurrentHook = null; + firstWorkInProgressHook = null; workInProgressHook = null; + nextWorkInProgressHook = null; { hookTypesDev = null; @@ -9867,26 +11097,30 @@ function resetHooksAfterThrow() { currentHookNameInDev = null; } + remainingExpirationTime = NoWork; + componentUpdateQueue = null; + sideEffectTag = 0; didScheduleRenderPhaseUpdate = false; + renderPhaseUpdates = null; + numberOfReRenders = 0; } function mountWorkInProgressHook() { var hook = { memoizedState: null, baseState: null, - baseQueue: null, queue: null, + baseUpdate: null, next: null }; if (workInProgressHook === null) { // This is the first hook in the list - currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook; + firstWorkInProgressHook = workInProgressHook = hook; } else { // Append to the end of the list workInProgressHook = workInProgressHook.next = hook; } - return workInProgressHook; } @@ -9896,33 +11130,12 @@ function updateWorkInProgressHook() { // clone, or a work-in-progress hook from a previous render pass that we can // use as a base. When we reach the end of the base list, we must switch to // the dispatcher used for mounts. - var nextCurrentHook; - - if (currentHook === null) { - var current = currentlyRenderingFiber$1.alternate; - - if (current !== null) { - nextCurrentHook = current.memoizedState; - } else { - nextCurrentHook = null; - } - } else { - nextCurrentHook = currentHook.next; - } - - var nextWorkInProgressHook; - - if (workInProgressHook === null) { - nextWorkInProgressHook = currentlyRenderingFiber$1.memoizedState; - } else { - nextWorkInProgressHook = workInProgressHook.next; - } - if (nextWorkInProgressHook !== null) { // There's already a work-in-progress. Reuse it. workInProgressHook = nextWorkInProgressHook; nextWorkInProgressHook = workInProgressHook.next; currentHook = nextCurrentHook; + nextCurrentHook = currentHook !== null ? currentHook.next : null; } else { // Clone from the current hook. if (!(nextCurrentHook !== null)) { @@ -9933,18 +11146,20 @@ function updateWorkInProgressHook() { var newHook = { memoizedState: currentHook.memoizedState, baseState: currentHook.baseState, - baseQueue: currentHook.baseQueue, queue: currentHook.queue, + baseUpdate: currentHook.baseUpdate, next: null }; if (workInProgressHook === null) { // This is the first hook in the list. - currentlyRenderingFiber$1.memoizedState = workInProgressHook = newHook; + workInProgressHook = firstWorkInProgressHook = newHook; } else { // Append to the end of the list. workInProgressHook = workInProgressHook.next = newHook; } + + nextCurrentHook = currentHook.next; } return workInProgressHook; @@ -9957,7 +11172,6 @@ function createFunctionComponentUpdateQueue() { } function basicStateReducer(state, action) { - // $FlowFixMe: Flow doesn't like mixed types return typeof action === "function" ? action(state) : action; } @@ -9970,16 +11184,15 @@ function mountReducer(reducer, initialArg, init) { } else { initialState = initialArg; } - hook.memoizedState = hook.baseState = initialState; var queue = (hook.queue = { - pending: null, + last: null, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialState }); var dispatch = (queue.dispatch = dispatchAction.bind( - null, + null, // Flow doesn't know this is non-null, but we do. currentlyRenderingFiber$1, queue )); @@ -9997,191 +11210,157 @@ function updateReducer(reducer, initialArg, init) { } queue.lastRenderedReducer = reducer; - var current = currentHook; // The last rebase update that is NOT part of the base state. - var baseQueue = current.baseQueue; // The last pending update that hasn't been processed yet. + if (numberOfReRenders > 0) { + // This is a re-render. Apply the new render phase updates to the previous + // work-in-progress hook. + var _dispatch = queue.dispatch; + + if (renderPhaseUpdates !== null) { + // Render phase updates are stored in a map of queue -> linked list + var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue); + + if (firstRenderPhaseUpdate !== undefined) { + renderPhaseUpdates.delete(queue); + var newState = hook.memoizedState; + var update = firstRenderPhaseUpdate; + do { + // Process this render phase update. We don't have to check the + // priority because it will always be the same as the current + // render's. + var action = update.action; + newState = reducer(newState, action); + update = update.next; + } while (update !== null); // Mark that the fiber performed work, but only if the new state is + // different from the current state. + + if (!is$1(newState, hook.memoizedState)) { + markWorkInProgressReceivedUpdate(); + } + + hook.memoizedState = newState; // Don't persist the state accumulated from the render phase updates to + // the base state unless the queue is empty. + // TODO: Not sure if this is the desired semantics, but it's what we + // do for gDSFP. I can't remember why. - var pendingQueue = queue.pending; + if (hook.baseUpdate === queue.last) { + hook.baseState = newState; + } - if (pendingQueue !== null) { - // We have new updates that haven't been processed yet. - // We'll add them to the base queue. - if (baseQueue !== null) { - // Merge the pending queue and the base queue. - var baseFirst = baseQueue.next; - var pendingFirst = pendingQueue.next; - baseQueue.next = pendingFirst; - pendingQueue.next = baseFirst; + queue.lastRenderedState = newState; + return [newState, _dispatch]; + } } - current.baseQueue = baseQueue = pendingQueue; - queue.pending = null; - } + return [hook.memoizedState, _dispatch]; + } // The last update in the entire queue + + var last = queue.last; // The last update that is part of the base state. + + var baseUpdate = hook.baseUpdate; + var baseState = hook.baseState; // Find the first unprocessed update. + + var first; - if (baseQueue !== null) { - // We have a queue to process. - var first = baseQueue.next; - var newState = current.baseState; + if (baseUpdate !== null) { + if (last !== null) { + // For the first update, the queue is a circular linked list where + // `queue.last.next = queue.first`. Once the first update commits, and + // the `baseUpdate` is no longer empty, we can unravel the list. + last.next = null; + } + first = baseUpdate.next; + } else { + first = last !== null ? last.next : null; + } + if (first !== null) { + var _newState = baseState; var newBaseState = null; - var newBaseQueueFirst = null; - var newBaseQueueLast = null; - var update = first; + var newBaseUpdate = null; + var prevUpdate = baseUpdate; + var _update = first; + var didSkip = false; do { - var updateExpirationTime = update.expirationTime; + var updateExpirationTime = _update.expirationTime; - if (updateExpirationTime < renderExpirationTime) { + if (updateExpirationTime < renderExpirationTime$1) { // 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 = { - expirationTime: update.expirationTime, - suspenseConfig: update.suspenseConfig, - action: update.action, - eagerReducer: update.eagerReducer, - eagerState: update.eagerState, - next: null - }; - - if (newBaseQueueLast === null) { - newBaseQueueFirst = newBaseQueueLast = clone; - newBaseState = newState; - } else { - newBaseQueueLast = newBaseQueueLast.next = clone; + if (!didSkip) { + didSkip = true; + newBaseUpdate = prevUpdate; + newBaseState = _newState; } // Update the remaining priority in the queue. - if (updateExpirationTime > currentlyRenderingFiber$1.expirationTime) { - currentlyRenderingFiber$1.expirationTime = updateExpirationTime; - markUnprocessedUpdateTime(updateExpirationTime); + if (updateExpirationTime > remainingExpirationTime) { + remainingExpirationTime = updateExpirationTime; + markUnprocessedUpdateTime(remainingExpirationTime); } } else { // This update does have sufficient priority. - if (newBaseQueueLast !== null) { - var _clone = { - expirationTime: Sync, - // This update is going to be committed so we never want uncommit it. - suspenseConfig: update.suspenseConfig, - action: update.action, - eagerReducer: update.eagerReducer, - eagerState: update.eagerState, - next: null - }; - newBaseQueueLast = newBaseQueueLast.next = _clone; - } // Mark the event time of this update as relevant to this render pass. + // Mark the event time of this update as relevant to this render pass. // TODO: This should ideally use the true event time of this update rather than // its priority which is a derived and not reverseable value. // TODO: We should skip this update if it was already committed but currently // we have no way of detecting the difference between a committed and suspended // update here. - markRenderEventTimeAndConfig( updateExpirationTime, - update.suspenseConfig + _update.suspenseConfig ); // Process this update. - if (update.eagerReducer === reducer) { + if (_update.eagerReducer === reducer) { // If this update was processed eagerly, and its reducer matches the // current reducer, we can use the eagerly computed state. - newState = update.eagerState; + _newState = _update.eagerState; } else { - var action = update.action; - newState = reducer(newState, action); + var _action = _update.action; + _newState = reducer(_newState, _action); } } - update = update.next; - } while (update !== null && update !== first); + prevUpdate = _update; + _update = _update.next; + } while (_update !== null && _update !== first); - if (newBaseQueueLast === null) { - newBaseState = newState; - } else { - newBaseQueueLast.next = newBaseQueueFirst; + if (!didSkip) { + newBaseUpdate = prevUpdate; + newBaseState = _newState; } // Mark that the fiber performed work, but only if the new state is // different from the current state. - if (!objectIs(newState, hook.memoizedState)) { + if (!is$1(_newState, hook.memoizedState)) { markWorkInProgressReceivedUpdate(); } - hook.memoizedState = newState; + hook.memoizedState = _newState; + hook.baseUpdate = newBaseUpdate; hook.baseState = newBaseState; - hook.baseQueue = newBaseQueueLast; - queue.lastRenderedState = newState; + queue.lastRenderedState = _newState; } var dispatch = queue.dispatch; return [hook.memoizedState, dispatch]; } -function rerenderReducer(reducer, initialArg, init) { - var hook = updateWorkInProgressHook(); - var queue = hook.queue; +function mountState(initialState) { + var hook = mountWorkInProgressHook(); - if (!(queue !== null)) { - throw Error( - "Should have a queue. This is likely a bug in React. Please file an issue." - ); - } - - queue.lastRenderedReducer = reducer; // This is a re-render. Apply the new render phase updates to the previous - // work-in-progress hook. - - var dispatch = queue.dispatch; - var lastRenderPhaseUpdate = queue.pending; - var newState = hook.memoizedState; - - if (lastRenderPhaseUpdate !== null) { - // The queue doesn't persist past this render pass. - queue.pending = null; - var firstRenderPhaseUpdate = lastRenderPhaseUpdate.next; - var update = firstRenderPhaseUpdate; - - do { - // Process this render phase update. We don't have to check the - // priority because it will always be the same as the current - // render's. - var action = update.action; - newState = reducer(newState, action); - update = update.next; - } while (update !== firstRenderPhaseUpdate); // Mark that the fiber performed work, but only if the new state is - // different from the current state. - - if (!objectIs(newState, hook.memoizedState)) { - markWorkInProgressReceivedUpdate(); - } - - hook.memoizedState = newState; // Don't persist the state accumulated from the render phase updates to - // the base state unless the queue is empty. - // TODO: Not sure if this is the desired semantics, but it's what we - // do for gDSFP. I can't remember why. - - if (hook.baseQueue === null) { - hook.baseState = newState; - } - - queue.lastRenderedState = newState; - } - - return [newState, dispatch]; -} - -function mountState(initialState) { - var hook = mountWorkInProgressHook(); - - if (typeof initialState === "function") { - // $FlowFixMe: Flow doesn't like mixed types - initialState = initialState(); + if (typeof initialState === "function") { + initialState = initialState(); } hook.memoizedState = hook.baseState = initialState; var queue = (hook.queue = { - pending: null, + last: null, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState }); var dispatch = (queue.dispatch = dispatchAction.bind( - null, + null, // Flow doesn't know this is non-null, but we do. currentlyRenderingFiber$1, queue )); @@ -10189,11 +11368,7 @@ function mountState(initialState) { } function updateState(initialState) { - return updateReducer(basicStateReducer); -} - -function rerenderState(initialState) { - return rerenderReducer(basicStateReducer); + return updateReducer(basicStateReducer, initialState); } function pushEffect(tag, create, destroy, deps) { @@ -10205,11 +11380,8 @@ function pushEffect(tag, create, destroy, deps) { // Circular next: null }; - var componentUpdateQueue = currentlyRenderingFiber$1.updateQueue; - if (componentUpdateQueue === null) { componentUpdateQueue = createFunctionComponentUpdateQueue(); - currentlyRenderingFiber$1.updateQueue = componentUpdateQueue; componentUpdateQueue.lastEffect = effect.next = effect; } else { var lastEffect = componentUpdateQueue.lastEffect; @@ -10223,7 +11395,6 @@ function pushEffect(tag, create, destroy, deps) { componentUpdateQueue.lastEffect = effect; } } - return effect; } @@ -10249,13 +11420,8 @@ function updateRef(initialValue) { function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var hook = mountWorkInProgressHook(); var nextDeps = deps === undefined ? null : deps; - currentlyRenderingFiber$1.effectTag |= fiberEffectTag; - hook.memoizedState = pushEffect( - HasEffect | hookEffectTag, - create, - undefined, - nextDeps - ); + sideEffectTag |= fiberEffectTag; + hook.memoizedState = pushEffect(hookEffectTag, create, undefined, nextDeps); } function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { @@ -10271,35 +11437,52 @@ function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var prevDeps = prevEffect.deps; if (areHookInputsEqual(nextDeps, prevDeps)) { - pushEffect(hookEffectTag, create, destroy, nextDeps); + pushEffect(NoEffect$1, create, destroy, nextDeps); return; } } } - currentlyRenderingFiber$1.effectTag |= fiberEffectTag; - hook.memoizedState = pushEffect( - HasEffect | hookEffectTag, - create, - destroy, - nextDeps - ); + sideEffectTag |= fiberEffectTag; + hook.memoizedState = pushEffect(hookEffectTag, create, destroy, nextDeps); } function mountEffect(create, deps) { - return mountEffectImpl(Update | Passive, Passive$1, create, deps); + { + // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests + if ("undefined" !== typeof jest) { + warnIfNotCurrentlyActingEffectsInDEV(currentlyRenderingFiber$1); + } + } + return mountEffectImpl( + Update | Passive, + UnmountPassive | MountPassive, + create, + deps + ); } function updateEffect(create, deps) { - return updateEffectImpl(Update | Passive, Passive$1, create, deps); + { + // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests + if ("undefined" !== typeof jest) { + warnIfNotCurrentlyActingEffectsInDEV(currentlyRenderingFiber$1); + } + } + return updateEffectImpl( + Update | Passive, + UnmountPassive | MountPassive, + create, + deps + ); } function mountLayoutEffect(create, deps) { - return mountEffectImpl(Update, Layout, create, deps); + return mountEffectImpl(Update, UnmountMutation | MountLayout, create, deps); } function updateLayoutEffect(create, deps) { - return updateEffectImpl(Update, Layout, create, deps); + return updateEffectImpl(Update, UnmountMutation | MountLayout, create, deps); } function imperativeHandleEffect(create, ref) { @@ -10314,15 +11497,15 @@ function imperativeHandleEffect(create, ref) { }; } else if (ref !== null && ref !== undefined) { var refObject = ref; - { - if (!refObject.hasOwnProperty("current")) { - error( - "Expected useImperativeHandle() first argument to either be a " + - "ref callback or React.createRef() object. Instead received: %s.", - "an object with keys {" + Object.keys(refObject).join(", ") + "}" - ); - } + !refObject.hasOwnProperty("current") + ? warning$1( + false, + "Expected useImperativeHandle() first argument to either be a " + + "ref callback or React.createRef() object. Instead received: %s.", + "an object with keys {" + Object.keys(refObject).join(", ") + "}" + ) + : void 0; } var _inst2 = create(); @@ -10336,20 +11519,21 @@ function imperativeHandleEffect(create, ref) { function mountImperativeHandle(ref, create, deps) { { - if (typeof create !== "function") { - error( - "Expected useImperativeHandle() second argument to be a function " + - "that creates a handle. Instead received: %s.", - create !== null ? typeof create : "null" - ); - } + !(typeof create === "function") + ? warning$1( + false, + "Expected useImperativeHandle() second argument to be a function " + + "that creates a handle. Instead received: %s.", + create !== null ? typeof create : "null" + ) + : void 0; } // TODO: If deps are provided, should we skip comparing the ref itself? var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null; return mountEffectImpl( Update, - Layout, + UnmountMutation | MountLayout, imperativeHandleEffect.bind(null, create, ref), effectDeps ); @@ -10357,20 +11541,21 @@ function mountImperativeHandle(ref, create, deps) { function updateImperativeHandle(ref, create, deps) { { - if (typeof create !== "function") { - error( - "Expected useImperativeHandle() second argument to be a function " + - "that creates a handle. Instead received: %s.", - create !== null ? typeof create : "null" - ); - } + !(typeof create === "function") + ? warning$1( + false, + "Expected useImperativeHandle() second argument to be a function " + + "that creates a handle. Instead received: %s.", + create !== null ? typeof create : "null" + ) + : void 0; } // TODO: If deps are provided, should we skip comparing the ref itself? var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null; return updateEffectImpl( Update, - Layout, + UnmountMutation | MountLayout, imperativeHandleEffect.bind(null, create, ref), effectDeps ); @@ -10405,7 +11590,6 @@ function updateCallback(callback, deps) { } } } - hook.memoizedState = [callback, nextDeps]; return callback; } @@ -10422,18 +11606,15 @@ function updateMemo(nextCreate, deps) { var hook = updateWorkInProgressHook(); var nextDeps = deps === undefined ? null : deps; var prevState = hook.memoizedState; - if (prevState !== null) { // Assume these are defined. If they're not, areHookInputsEqual will warn. if (nextDeps !== null) { var prevDeps = prevState[1]; - if (areHookInputsEqual(nextDeps, prevDeps)) { return prevState[0]; } } } - var nextValue = nextCreate(); hook.memoizedState = [nextValue, nextDeps]; return nextValue; @@ -10446,14 +11627,17 @@ function mountDeferredValue(value, config) { mountEffect( function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config; + Scheduler.unstable_next(function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + config === undefined ? null : config; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }); }, [value, config] ); @@ -10461,151 +11645,100 @@ function mountDeferredValue(value, config) { } function updateDeferredValue(value, config) { - var _updateState = updateState(), + var _updateState = updateState(value), prevValue = _updateState[0], setValue = _updateState[1]; updateEffect( function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config; - - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }, - [value, config] - ); - return prevValue; -} - -function rerenderDeferredValue(value, config) { - var _rerenderState = rerenderState(), - prevValue = _rerenderState[0], - setValue = _rerenderState[1]; - - updateEffect( - function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config; + Scheduler.unstable_next(function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + config === undefined ? null : config; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }); }, [value, config] ); return prevValue; } -function startTransition(setPending, config, callback) { - var priorityLevel = getCurrentPriorityLevel(); - runWithPriority( - priorityLevel < UserBlockingPriority ? UserBlockingPriority : priorityLevel, - function() { - setPending(true); - } - ); - runWithPriority( - priorityLevel > NormalPriority ? NormalPriority : priorityLevel, - function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config; - - try { - setPending(false); - callback(); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - } - ); -} - function mountTransition(config) { var _mountState2 = mountState(false), isPending = _mountState2[0], setPending = _mountState2[1]; - var start = mountCallback(startTransition.bind(null, setPending, config), [ - setPending, - config - ]); - return [start, isPending]; + var startTransition = mountCallback( + function(callback) { + setPending(true); + Scheduler.unstable_next(function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + config === undefined ? null : config; + + try { + setPending(false); + callback(); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }); + }, + [config, isPending] + ); + return [startTransition, isPending]; } function updateTransition(config) { - var _updateState2 = updateState(), + var _updateState2 = updateState(false), isPending = _updateState2[0], setPending = _updateState2[1]; - var start = updateCallback(startTransition.bind(null, setPending, config), [ - setPending, - config - ]); - return [start, isPending]; -} - -function rerenderTransition(config) { - var _rerenderState2 = rerenderState(), - isPending = _rerenderState2[0], - setPending = _rerenderState2[1]; + var startTransition = updateCallback( + function(callback) { + setPending(true); + Scheduler.unstable_next(function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + config === undefined ? null : config; - var start = updateCallback(startTransition.bind(null, setPending, config), [ - setPending, - config - ]); - return [start, isPending]; + try { + setPending(false); + callback(); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }); + }, + [config, isPending] + ); + return [startTransition, isPending]; } function dispatchAction(fiber, queue, action) { - { - if (typeof arguments[3] === "function") { - error( - "State updates from the useState() and useReducer() Hooks don't support the " + - "second callback argument. To execute a side effect after " + - "rendering, declare it in the component body with useEffect()." - ); - } + if (!(numberOfReRenders < RE_RENDER_LIMIT)) { + throw Error( + "Too many re-renders. React limits the number of renders to prevent an infinite loop." + ); } - var currentTime = requestCurrentTimeForUpdate(); - var suspenseConfig = requestCurrentSuspenseConfig(); - var expirationTime = computeExpirationForFiber( - currentTime, - fiber, - suspenseConfig - ); - var update = { - expirationTime: expirationTime, - suspenseConfig: suspenseConfig, - action: action, - eagerReducer: null, - eagerState: null, - next: null - }; - { - update.priority = getCurrentPriorityLevel(); - } // 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; + !(typeof arguments[3] !== "function") + ? warning$1( + false, + "State updates from the useState() and useReducer() Hooks don't support the " + + "second callback argument. To execute a side effect after " + + "rendering, declare it in the component body with useEffect()." + ) + : void 0; } - queue.pending = update; var alternate = fiber.alternate; - if ( fiber === currentlyRenderingFiber$1 || (alternate !== null && alternate === currentlyRenderingFiber$1) @@ -10614,9 +11747,76 @@ 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. didScheduleRenderPhaseUpdate = true; - update.expirationTime = renderExpirationTime; - currentlyRenderingFiber$1.expirationTime = renderExpirationTime; + var update = { + expirationTime: renderExpirationTime$1, + suspenseConfig: null, + action: action, + eagerReducer: null, + eagerState: null, + next: null + }; + + { + update.priority = getCurrentPriorityLevel(); + } + + if (renderPhaseUpdates === null) { + renderPhaseUpdates = new Map(); + } + + var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue); + + if (firstRenderPhaseUpdate === undefined) { + renderPhaseUpdates.set(queue, update); + } else { + // Append the update to the end of the list. + var lastRenderPhaseUpdate = firstRenderPhaseUpdate; + + while (lastRenderPhaseUpdate.next !== null) { + lastRenderPhaseUpdate = lastRenderPhaseUpdate.next; + } + + lastRenderPhaseUpdate.next = update; + } } else { + var currentTime = requestCurrentTimeForUpdate(); + var suspenseConfig = requestCurrentSuspenseConfig(); + var expirationTime = computeExpirationForFiber( + currentTime, + fiber, + suspenseConfig + ); + var _update2 = { + expirationTime: expirationTime, + suspenseConfig: suspenseConfig, + action: action, + eagerReducer: null, + eagerState: null, + next: null + }; + + { + _update2.priority = getCurrentPriorityLevel(); + } // Append the update to the end of the list. + + var last = queue.last; + + if (last === null) { + // This is the first update. Create a circular list. + _update2.next = _update2; + } else { + var first = last.next; + + if (first !== null) { + // Still circular. + _update2.next = first; + } + + last.next = _update2; + } + + queue.last = _update2; + if ( fiber.expirationTime === NoWork && (alternate === null || alternate.expirationTime === NoWork) @@ -10630,8 +11830,8 @@ function dispatchAction(fiber, queue, action) { var prevDispatcher; { - prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; } try { @@ -10641,10 +11841,10 @@ function dispatchAction(fiber, queue, action) { // time we enter the render phase, then the eager state can be used // without calling the reducer again. - update.eagerReducer = lastRenderedReducer; - update.eagerState = eagerState; + _update2.eagerReducer = lastRenderedReducer; + _update2.eagerState = eagerState; - if (objectIs(eagerState, currentState)) { + if (is$1(eagerState, currentState)) { // Fast path. We can bail out without scheduling React to re-render. // It's still possible that we'll need to rebase this update later, // if the component re-renders for a different reason and by that @@ -10655,24 +11855,23 @@ function dispatchAction(fiber, queue, action) { // Suppress the error. It will throw again in the render phase. } finally { { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } } } } + { + // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests + if ("undefined" !== typeof jest) { + warnIfNotScopedWithMatchingAct(fiber); + warnIfNotCurrentlyActingUpdatesInDev(fiber); + } + } scheduleWork(fiber, expirationTime); } } -function mountEventListener(event) { - return undefined; -} - -function updateEventListener(event) { - return undefined; -} - var ContextOnlyDispatcher = { readContext: readContext, useCallback: throwInvalidHookError, @@ -10687,20 +11886,18 @@ var ContextOnlyDispatcher = { useDebugValue: throwInvalidHookError, useResponder: throwInvalidHookError, useDeferredValue: throwInvalidHookError, - useTransition: throwInvalidHookError, - useEvent: throwInvalidHookError + useTransition: throwInvalidHookError }; var HooksDispatcherOnMountInDEV = null; var HooksDispatcherOnMountWithHookTypesInDEV = null; var HooksDispatcherOnUpdateInDEV = null; -var HooksDispatcherOnRerenderInDEV = null; var InvalidNestedHooksDispatcherOnMountInDEV = null; var InvalidNestedHooksDispatcherOnUpdateInDEV = null; -var InvalidNestedHooksDispatcherOnRerenderInDEV = null; { var warnInvalidContextAccess = function() { - error( + warning$1( + false, "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 " + @@ -10709,7 +11906,8 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; }; var warnInvalidHookAccess = function() { - error( + warning$1( + false, "Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks. " + "You can only call Hooks at the top level of your React function. " + "For more information, see " + @@ -10754,25 +11952,23 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; currentHookNameInDev = "useMemo"; mountHookTypesDev(); checkDepsAreArrayDev(deps); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; - + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; try { return mountMemo(create, deps); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useReducer: function(reducer, initialArg, init) { currentHookNameInDev = "useReducer"; mountHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; - + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; try { return mountReducer(reducer, initialArg, init); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useRef: function(initialValue) { @@ -10783,24 +11979,23 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; useState: function(initialState) { currentHookNameInDev = "useState"; mountHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; - + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; try { return mountState(initialState); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useDebugValue: function(value, formatterFn) { currentHookNameInDev = "useDebugValue"; mountHookTypesDev(); - return mountDebugValue(); + return mountDebugValue(value, formatterFn); }, useResponder: function(responder, props) { currentHookNameInDev = "useResponder"; mountHookTypesDev(); - return createDeprecatedResponderListener(responder, props); + return createResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; @@ -10811,11 +12006,6 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; currentHookNameInDev = "useTransition"; mountHookTypesDev(); return mountTransition(config); - }, - useEvent: function(event) { - currentHookNameInDev = "useEvent"; - mountHookTypesDev(); - return mountEventListener(); } }; HooksDispatcherOnMountWithHookTypesInDEV = { @@ -10850,25 +12040,23 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; useMemo: function(create, deps) { currentHookNameInDev = "useMemo"; updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; - + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; try { return mountMemo(create, deps); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useReducer: function(reducer, initialArg, init) { currentHookNameInDev = "useReducer"; updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; - + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; try { return mountReducer(reducer, initialArg, init); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useRef: function(initialValue) { @@ -10879,24 +12067,23 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; useState: function(initialState) { currentHookNameInDev = "useState"; updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; - + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; try { return mountState(initialState); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useDebugValue: function(value, formatterFn) { currentHookNameInDev = "useDebugValue"; updateHookTypesDev(); - return mountDebugValue(); + return mountDebugValue(value, formatterFn); }, useResponder: function(responder, props) { currentHookNameInDev = "useResponder"; updateHookTypesDev(); - return createDeprecatedResponderListener(responder, props); + return createResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; @@ -10907,11 +12094,6 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; currentHookNameInDev = "useTransition"; updateHookTypesDev(); return mountTransition(config); - }, - useEvent: function(event) { - currentHookNameInDev = "useEvent"; - updateHookTypesDev(); - return mountEventListener(); } }; HooksDispatcherOnUpdateInDEV = { @@ -10946,53 +12128,50 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; useMemo: function(create, deps) { currentHookNameInDev = "useMemo"; updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; - + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; try { return updateMemo(create, deps); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useReducer: function(reducer, initialArg, init) { currentHookNameInDev = "useReducer"; updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; - + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; try { return updateReducer(reducer, initialArg, init); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useRef: function(initialValue) { currentHookNameInDev = "useRef"; updateHookTypesDev(); - return updateRef(); + return updateRef(initialValue); }, useState: function(initialState) { currentHookNameInDev = "useState"; updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; - + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; try { return updateState(initialState); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useDebugValue: function(value, formatterFn) { currentHookNameInDev = "useDebugValue"; updateHookTypesDev(); - return updateDebugValue(); + return updateDebugValue(value, formatterFn); }, useResponder: function(responder, props) { currentHookNameInDev = "useResponder"; updateHookTypesDev(); - return createDeprecatedResponderListener(responder, props); + return createResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; @@ -11003,218 +12182,108 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; currentHookNameInDev = "useTransition"; updateHookTypesDev(); return updateTransition(config); - }, - useEvent: function(event) { - currentHookNameInDev = "useEvent"; - updateHookTypesDev(); - return updateEventListener(); } }; - HooksDispatcherOnRerenderInDEV = { + InvalidNestedHooksDispatcherOnMountInDEV = { readContext: function(context, observedBits) { + warnInvalidContextAccess(); return readContext(context, observedBits); }, useCallback: function(callback, deps) { currentHookNameInDev = "useCallback"; - updateHookTypesDev(); - return updateCallback(callback, deps); + warnInvalidHookAccess(); + mountHookTypesDev(); + return mountCallback(callback, deps); }, useContext: function(context, observedBits) { currentHookNameInDev = "useContext"; - updateHookTypesDev(); + warnInvalidHookAccess(); + mountHookTypesDev(); return readContext(context, observedBits); }, useEffect: function(create, deps) { currentHookNameInDev = "useEffect"; - updateHookTypesDev(); - return updateEffect(create, deps); + warnInvalidHookAccess(); + mountHookTypesDev(); + return mountEffect(create, deps); }, useImperativeHandle: function(ref, create, deps) { currentHookNameInDev = "useImperativeHandle"; - updateHookTypesDev(); - return updateImperativeHandle(ref, create, deps); + warnInvalidHookAccess(); + mountHookTypesDev(); + return mountImperativeHandle(ref, create, deps); }, useLayoutEffect: function(create, deps) { currentHookNameInDev = "useLayoutEffect"; - updateHookTypesDev(); - return updateLayoutEffect(create, deps); + warnInvalidHookAccess(); + mountHookTypesDev(); + return mountLayoutEffect(create, deps); }, useMemo: function(create, deps) { currentHookNameInDev = "useMemo"; - updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnRerenderInDEV; - + warnInvalidHookAccess(); + mountHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; try { - return updateMemo(create, deps); + return mountMemo(create, deps); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useReducer: function(reducer, initialArg, init) { currentHookNameInDev = "useReducer"; - updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnRerenderInDEV; - + warnInvalidHookAccess(); + mountHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; try { - return rerenderReducer(reducer, initialArg, init); + return mountReducer(reducer, initialArg, init); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useRef: function(initialValue) { currentHookNameInDev = "useRef"; - updateHookTypesDev(); - return updateRef(); + warnInvalidHookAccess(); + mountHookTypesDev(); + return mountRef(initialValue); }, useState: function(initialState) { currentHookNameInDev = "useState"; - updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnRerenderInDEV; - + warnInvalidHookAccess(); + mountHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; try { - return rerenderState(initialState); + return mountState(initialState); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useDebugValue: function(value, formatterFn) { currentHookNameInDev = "useDebugValue"; - updateHookTypesDev(); - return updateDebugValue(); + warnInvalidHookAccess(); + mountHookTypesDev(); + return mountDebugValue(value, formatterFn); }, useResponder: function(responder, props) { currentHookNameInDev = "useResponder"; - updateHookTypesDev(); - return createDeprecatedResponderListener(responder, props); + warnInvalidHookAccess(); + mountHookTypesDev(); + return createResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; - updateHookTypesDev(); - return rerenderDeferredValue(value, config); - }, - useTransition: function(config) { - currentHookNameInDev = "useTransition"; - updateHookTypesDev(); - return rerenderTransition(config); - }, - useEvent: function(event) { - currentHookNameInDev = "useEvent"; - updateHookTypesDev(); - return updateEventListener(); - } - }; - InvalidNestedHooksDispatcherOnMountInDEV = { - readContext: function(context, observedBits) { - warnInvalidContextAccess(); - return readContext(context, observedBits); - }, - useCallback: function(callback, deps) { - currentHookNameInDev = "useCallback"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountCallback(callback, deps); - }, - useContext: function(context, observedBits) { - currentHookNameInDev = "useContext"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return readContext(context, observedBits); - }, - useEffect: function(create, deps) { - currentHookNameInDev = "useEffect"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountEffect(create, deps); - }, - useImperativeHandle: function(ref, create, deps) { - currentHookNameInDev = "useImperativeHandle"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountImperativeHandle(ref, create, deps); - }, - useLayoutEffect: function(create, deps) { - currentHookNameInDev = "useLayoutEffect"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountLayoutEffect(create, deps); - }, - useMemo: function(create, deps) { - currentHookNameInDev = "useMemo"; - warnInvalidHookAccess(); - mountHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; - - try { - return mountMemo(create, deps); - } finally { - ReactCurrentDispatcher.current = prevDispatcher; - } - }, - useReducer: function(reducer, initialArg, init) { - currentHookNameInDev = "useReducer"; - warnInvalidHookAccess(); - mountHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; - - try { - return mountReducer(reducer, initialArg, init); - } finally { - ReactCurrentDispatcher.current = prevDispatcher; - } - }, - useRef: function(initialValue) { - currentHookNameInDev = "useRef"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountRef(initialValue); - }, - useState: function(initialState) { - currentHookNameInDev = "useState"; - warnInvalidHookAccess(); - mountHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; - - try { - return mountState(initialState); - } finally { - ReactCurrentDispatcher.current = prevDispatcher; - } - }, - useDebugValue: function(value, formatterFn) { - currentHookNameInDev = "useDebugValue"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountDebugValue(); - }, - useResponder: function(responder, props) { - currentHookNameInDev = "useResponder"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return createDeprecatedResponderListener(responder, props); - }, - useDeferredValue: function(value, config) { - currentHookNameInDev = "useDeferredValue"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountDeferredValue(value, config); + warnInvalidHookAccess(); + mountHookTypesDev(); + return mountDeferredValue(value, config); }, useTransition: function(config) { currentHookNameInDev = "useTransition"; warnInvalidHookAccess(); mountHookTypesDev(); return mountTransition(config); - }, - useEvent: function(event) { - currentHookNameInDev = "useEvent"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountEventListener(); } }; InvalidNestedHooksDispatcherOnUpdateInDEV = { @@ -11256,58 +12325,55 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; currentHookNameInDev = "useMemo"; warnInvalidHookAccess(); updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; - + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; try { return updateMemo(create, deps); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useReducer: function(reducer, initialArg, init) { currentHookNameInDev = "useReducer"; warnInvalidHookAccess(); updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; - + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; try { return updateReducer(reducer, initialArg, init); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useRef: function(initialValue) { currentHookNameInDev = "useRef"; warnInvalidHookAccess(); updateHookTypesDev(); - return updateRef(); + return updateRef(initialValue); }, useState: function(initialState) { currentHookNameInDev = "useState"; warnInvalidHookAccess(); updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; - + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; try { return updateState(initialState); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useDebugValue: function(value, formatterFn) { currentHookNameInDev = "useDebugValue"; warnInvalidHookAccess(); updateHookTypesDev(); - return updateDebugValue(); + return updateDebugValue(value, formatterFn); }, useResponder: function(responder, props) { currentHookNameInDev = "useResponder"; warnInvalidHookAccess(); updateHookTypesDev(); - return createDeprecatedResponderListener(responder, props); + return createResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; @@ -11320,339 +12386,982 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; warnInvalidHookAccess(); updateHookTypesDev(); return updateTransition(config); - }, - useEvent: function(event) { - currentHookNameInDev = "useEvent"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateEventListener(); } }; - 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.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; +} + +// CommonJS interop named imports. + +var now$1 = Scheduler.unstable_now; +var commitTime = 0; +var profilerStartTime = -1; + +function getCommitTime() { + return commitTime; +} + +function recordCommitTime() { + if (!enableProfilerTimer) { + return; + } + commitTime = now$1(); +} + +function startProfilerTimer(fiber) { + if (!enableProfilerTimer) { + return; + } + + profilerStartTime = now$1(); + + if (fiber.actualStartTime < 0) { + fiber.actualStartTime = now$1(); + } +} + +function stopProfilerTimerIfRunning(fiber) { + if (!enableProfilerTimer) { + return; + } + profilerStartTime = -1; +} + +function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) { + if (!enableProfilerTimer) { + return; + } + + if (profilerStartTime >= 0) { + var elapsedTime = now$1() - profilerStartTime; + fiber.actualDuration += elapsedTime; + + if (overrideBaseTime) { + fiber.selfBaseDuration = elapsedTime; + } + + profilerStartTime = -1; + } +} + +// This may have been an insertion or a hydration. + +var hydrationParentFiber = null; +var nextHydratableInstance = null; +var isHydrating = false; + +function warnIfHydrating() { + { + !!isHydrating + ? warning$1( + false, + "We should not be hydrating here. This is a bug in React. Please file a bug." + ) + : void 0; + } +} + +function enterHydrationState(fiber) { + if (!supportsHydration) { + return false; + } + + var parentInstance = fiber.stateNode.containerInfo; + nextHydratableInstance = getFirstHydratableChild(parentInstance); + hydrationParentFiber = fiber; + isHydrating = true; + return true; +} + +function reenterHydrationStateFromDehydratedSuspenseInstance( + fiber, + suspenseInstance +) { + if (!supportsHydration) { + return false; + } + + nextHydratableInstance = getNextHydratableSibling(suspenseInstance); + popToNextHostParent(fiber); + isHydrating = true; + return true; +} + +function deleteHydratableInstance(returnFiber, instance) { + { + switch (returnFiber.tag) { + case HostRoot: + didNotHydrateContainerInstance( + returnFiber.stateNode.containerInfo, + instance + ); + break; + case HostComponent: + didNotHydrateInstance( + returnFiber.type, + returnFiber.memoizedProps, + returnFiber.stateNode, + instance + ); + break; + } + } + + var childToDelete = createFiberFromHostInstanceForDeletion(); + childToDelete.stateNode = instance; + childToDelete.return = returnFiber; + childToDelete.effectTag = Deletion; // This might seem like it belongs on progressedFirstDeletion. However, + // these children are not part of the reconciliation list of children. + // Even if we abort and rereconcile the children, that will try to hydrate + // again and the nodes are still in the host tree so these will be + // recreated. + if (returnFiber.lastEffect !== null) { + returnFiber.lastEffect.nextEffect = childToDelete; + returnFiber.lastEffect = childToDelete; + } else { + returnFiber.firstEffect = returnFiber.lastEffect = childToDelete; + } +} + +function insertNonHydratedInstance(returnFiber, fiber) { + fiber.effectTag = (fiber.effectTag & ~Hydrating) | Placement; + + { + switch (returnFiber.tag) { + case HostRoot: { + var parentContainer = returnFiber.stateNode.containerInfo; + switch (fiber.tag) { + case HostComponent: + var type = fiber.type; + var props = fiber.pendingProps; + didNotFindHydratableContainerInstance(parentContainer, type, props); + break; + case HostText: + var text = fiber.pendingProps; + didNotFindHydratableContainerTextInstance(parentContainer, text); + break; + case SuspenseComponent: + didNotFindHydratableContainerSuspenseInstance(parentContainer); + break; + } + + break; + } + + case HostComponent: { + var parentType = returnFiber.type; + var parentProps = returnFiber.memoizedProps; + var parentInstance = returnFiber.stateNode; + switch (fiber.tag) { + case HostComponent: + var _type = fiber.type; + var _props = fiber.pendingProps; + didNotFindHydratableInstance( + parentType, + parentProps, + parentInstance, + _type, + _props + ); + break; + case HostText: + var _text = fiber.pendingProps; + didNotFindHydratableTextInstance( + parentType, + parentProps, + parentInstance, + _text + ); + break; + case SuspenseComponent: + didNotFindHydratableSuspenseInstance( + parentType, + parentProps, + parentInstance + ); + break; + } + + break; + } + + default: + return; + } + } +} + +function tryHydrate(fiber, nextInstance) { + switch (fiber.tag) { + case HostComponent: { + var type = fiber.type; + var props = fiber.pendingProps; + var instance = canHydrateInstance(nextInstance, type, props); + if (instance !== null) { + fiber.stateNode = instance; + return true; + } + + return false; + } + + case HostText: { + var text = fiber.pendingProps; + var textInstance = canHydrateTextInstance(nextInstance, text); + + if (textInstance !== null) { + fiber.stateNode = textInstance; + return true; + } + + return false; + } + + case SuspenseComponent: { + if (enableSuspenseServerRenderer) { + var suspenseInstance = canHydrateSuspenseInstance(nextInstance); + + if (suspenseInstance !== null) { + var suspenseState = { + dehydrated: suspenseInstance, + retryTime: Never + }; + fiber.memoizedState = suspenseState; // Store the dehydrated fragment as a child fiber. + // This simplifies the code for getHostSibling and deleting nodes, + // since it doesn't have to consider all Suspense boundaries and + // check if they're dehydrated ones or not. + + var dehydratedFragment = createFiberFromDehydratedFragment( + suspenseInstance + ); + dehydratedFragment.return = fiber; + fiber.child = dehydratedFragment; + return true; + } + } + + return false; + } + + default: + return false; + } +} + +function tryToClaimNextHydratableInstance(fiber) { + if (!isHydrating) { + return; + } + + var nextInstance = nextHydratableInstance; + + if (!nextInstance) { + // Nothing to hydrate. Make it an insertion. + insertNonHydratedInstance(hydrationParentFiber, fiber); + isHydrating = false; + hydrationParentFiber = fiber; + return; + } + + var firstAttemptedInstance = nextInstance; + + if (!tryHydrate(fiber, nextInstance)) { + // If we can't hydrate this instance let's try the next one. + // We use this as a heuristic. It's based on intuition and not data so it + // might be flawed or unnecessary. + nextInstance = getNextHydratableSibling(firstAttemptedInstance); + if (!nextInstance || !tryHydrate(fiber, nextInstance)) { + // Nothing to hydrate. Make it an insertion. + insertNonHydratedInstance(hydrationParentFiber, fiber); + isHydrating = false; + hydrationParentFiber = fiber; + return; + } // We matched the next one, we'll now assume that the first one was + // superfluous and we'll delete it. Since we can't eagerly delete it + // we'll have to schedule a deletion. To do that, this node needs a dummy + // fiber associated with it. + + deleteHydratableInstance(hydrationParentFiber, firstAttemptedInstance); + } + + hydrationParentFiber = fiber; + nextHydratableInstance = getFirstHydratableChild(nextInstance); +} + +function prepareToHydrateHostInstance( + fiber, + rootContainerInstance, + hostContext +) { + if (!supportsHydration) { + { + throw Error( + "Expected prepareToHydrateHostInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." + ); + } + } + + var instance = fiber.stateNode; + var updatePayload = hydrateInstance( + instance, + fiber.type, + fiber.memoizedProps, + rootContainerInstance, + hostContext, + fiber + ); // TODO: Type this specific to this type of component. + + fiber.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. + + if (updatePayload !== null) { + return true; + } + + return false; +} + +function prepareToHydrateHostTextInstance(fiber) { + if (!supportsHydration) { + { + throw Error( + "Expected prepareToHydrateHostTextInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." + ); + } + } + + var textInstance = fiber.stateNode; + var textContent = fiber.memoizedProps; + var shouldUpdate = hydrateTextInstance(textInstance, textContent, fiber); + { + if (shouldUpdate) { + // We assume that prepareToHydrateHostTextInstance is called in a context where the + // hydration parent is the parent host component of this host text. + var returnFiber = hydrationParentFiber; + if (returnFiber !== null) { + switch (returnFiber.tag) { + case HostRoot: { + var parentContainer = returnFiber.stateNode.containerInfo; + didNotMatchHydratedContainerTextInstance( + parentContainer, + textInstance, + textContent + ); + break; + } + case HostComponent: { + var parentType = returnFiber.type; + var parentProps = returnFiber.memoizedProps; + var parentInstance = returnFiber.stateNode; + didNotMatchHydratedTextInstance( + parentType, + parentProps, + parentInstance, + textInstance, + textContent + ); + break; + } + } + } + } + } + + return shouldUpdate; +} + +function prepareToHydrateHostSuspenseInstance(fiber) { + if (!supportsHydration) { + { + throw Error( + "Expected prepareToHydrateHostSuspenseInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." + ); + } + } + + var suspenseState = fiber.memoizedState; + var suspenseInstance = + suspenseState !== null ? suspenseState.dehydrated : null; + + if (!suspenseInstance) { + throw Error( + "Expected to have a hydrated suspense instance. This error is likely caused by a bug in React. Please file an issue." + ); + } + + hydrateSuspenseInstance(suspenseInstance, fiber); +} + +function skipPastDehydratedSuspenseInstance(fiber) { + if (!supportsHydration) { + { + throw Error( + "Expected skipPastDehydratedSuspenseInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." + ); + } + } + + var suspenseState = fiber.memoizedState; + var suspenseInstance = + suspenseState !== null ? suspenseState.dehydrated : null; + + if (!suspenseInstance) { + throw Error( + "Expected to have a hydrated suspense instance. This error is likely caused by a bug in React. Please file an issue." + ); + } + + return getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance); +} + +function popToNextHostParent(fiber) { + var parent = fiber.return; + while ( + parent !== null && + parent.tag !== HostComponent && + parent.tag !== HostRoot && + parent.tag !== SuspenseComponent + ) { + parent = parent.return; + } + + hydrationParentFiber = parent; +} + +function popHydrationState(fiber) { + if (!supportsHydration) { + return false; + } + if (fiber !== hydrationParentFiber) { + // We're deeper than the current hydration context, inside an inserted + // tree. + return false; + } + if (!isHydrating) { + // If we're not currently hydrating but we're in a hydration context, then + // we were an insertion and now need to pop up reenter hydration of our + // siblings. + popToNextHostParent(fiber); + isHydrating = true; + return false; + } + + var type = fiber.type; // If we have any remaining hydratable nodes, we need to delete them now. + // We only do this deeper than head and body since they tend to have random + // other nodes in them. We also ignore components with pure text content in + // side of them. + // TODO: Better heuristic. + if ( + fiber.tag !== HostComponent || + (type !== "head" && + type !== "body" && + !shouldSetTextContent(type, fiber.memoizedProps)) + ) { + var nextInstance = nextHydratableInstance; + while (nextInstance) { + deleteHydratableInstance(fiber, nextInstance); + nextInstance = getNextHydratableSibling(nextInstance); + } + } + + popToNextHostParent(fiber); + + if (fiber.tag === SuspenseComponent) { + nextHydratableInstance = skipPastDehydratedSuspenseInstance(fiber); + } else { + nextHydratableInstance = hydrationParentFiber + ? getNextHydratableSibling(fiber.stateNode) + : null; + } + + return true; +} + +function resetHydrationState() { + if (!supportsHydration) { + return; + } + + hydrationParentFiber = null; + nextHydratableInstance = null; + isHydrating = false; +} + +var ReactCurrentOwner$3 = ReactSharedInternals.ReactCurrentOwner; +var didReceiveUpdate = false; +var didWarnAboutBadClass; +var didWarnAboutModulePatternComponent; +var didWarnAboutContextTypeOnFunctionComponent; +var didWarnAboutGetDerivedStateOnFunctionComponent; +var didWarnAboutFunctionRefs; +var didWarnAboutReassigningProps; +var didWarnAboutMaxDuration; +var didWarnAboutRevealOrder; +var didWarnAboutTailOptions; +var didWarnAboutDefaultPropsOnFunctionComponent; + +{ + didWarnAboutBadClass = {}; + didWarnAboutModulePatternComponent = {}; + didWarnAboutContextTypeOnFunctionComponent = {}; + didWarnAboutGetDerivedStateOnFunctionComponent = {}; + didWarnAboutFunctionRefs = {}; + didWarnAboutReassigningProps = false; + didWarnAboutMaxDuration = false; + didWarnAboutRevealOrder = {}; + didWarnAboutTailOptions = {}; + didWarnAboutDefaultPropsOnFunctionComponent = {}; +} + +function reconcileChildren( + current$$1, + workInProgress, + nextChildren, + renderExpirationTime +) { + if (current$$1 === 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, + renderExpirationTime + ); + } 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$$1.child, + nextChildren, + renderExpirationTime + ); + } +} + +function forceUnmountCurrentAndReconcile( + current$$1, + workInProgress, + nextChildren, + renderExpirationTime +) { + // 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$$1.child, + null, + renderExpirationTime + ); // 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 their + // identity matches. - try { - return updateMemo(create, deps); - } finally { - ReactCurrentDispatcher.current = prevDispatcher; - } - }, - useReducer: function(reducer, initialArg, init) { - currentHookNameInDev = "useReducer"; - warnInvalidHookAccess(); - updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + workInProgress.child = reconcileChildFibers( + workInProgress, + null, + nextChildren, + renderExpirationTime + ); +} - try { - return rerenderReducer(reducer, initialArg, init); - } finally { - ReactCurrentDispatcher.current = prevDispatcher; +function updateForwardRef( + current$$1, + workInProgress, + Component, + nextProps, + renderExpirationTime +) { + // 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), + getCurrentFiberStackInDev + ); } - }, - useRef: function(initialValue) { - currentHookNameInDev = "useRef"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateRef(); - }, - useState: function(initialState) { - currentHookNameInDev = "useState"; - warnInvalidHookAccess(); - updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + } + } - try { - return rerenderState(initialState); - } finally { - ReactCurrentDispatcher.current = prevDispatcher; + var render = Component.render; + var ref = workInProgress.ref; // The rest is a fork of updateFunctionComponent + + var nextChildren; + prepareToReadContext(workInProgress, renderExpirationTime); + + { + ReactCurrentOwner$3.current = workInProgress; + setCurrentPhase("render"); + nextChildren = renderWithHooks( + current$$1, + workInProgress, + render, + nextProps, + ref, + renderExpirationTime + ); + + if ( + debugRenderPhaseSideEffectsForStrictMode && + workInProgress.mode & StrictMode + ) { + // Only double-render components with Hooks + if (workInProgress.memoizedState !== null) { + nextChildren = renderWithHooks( + current$$1, + workInProgress, + render, + nextProps, + ref, + renderExpirationTime + ); } - }, - useDebugValue: function(value, formatterFn) { - currentHookNameInDev = "useDebugValue"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateDebugValue(); - }, - useResponder: function(responder, props) { - currentHookNameInDev = "useResponder"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return createDeprecatedResponderListener(responder, props); - }, - useDeferredValue: function(value, config) { - currentHookNameInDev = "useDeferredValue"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return rerenderDeferredValue(value, config); - }, - useTransition: function(config) { - currentHookNameInDev = "useTransition"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return rerenderTransition(config); - }, - useEvent: function(event) { - currentHookNameInDev = "useEvent"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateEventListener(); } - }; -} + setCurrentPhase(null); + } -var now$1 = Scheduler.unstable_now; -var commitTime = 0; -var profilerStartTime = -1; + if (current$$1 !== null && !didReceiveUpdate) { + bailoutHooks(current$$1, workInProgress, renderExpirationTime); + return bailoutOnAlreadyFinishedWork( + current$$1, + workInProgress, + renderExpirationTime + ); + } // React DevTools reads this flag. -function getCommitTime() { - return commitTime; + workInProgress.effectTag |= PerformedWork; + reconcileChildren( + current$$1, + workInProgress, + nextChildren, + renderExpirationTime + ); + return workInProgress.child; } -function recordCommitTime() { - commitTime = now$1(); -} +function updateMemoComponent( + current$$1, + workInProgress, + Component, + nextProps, + updateExpirationTime, + renderExpirationTime +) { + if (current$$1 === null) { + var type = Component.type; -function startProfilerTimer(fiber) { - profilerStartTime = now$1(); + if ( + isSimpleFunctionComponent(type) && + Component.compare === null && // SimpleMemoComponent codepath doesn't resolve outer props either. + Component.defaultProps === undefined + ) { + var resolvedType = type; - if (fiber.actualStartTime < 0) { - fiber.actualStartTime = now$1(); - } -} + { + 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. -function stopProfilerTimerIfRunning(fiber) { - profilerStartTime = -1; -} + workInProgress.tag = SimpleMemoComponent; + workInProgress.type = resolvedType; -function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) { - if (profilerStartTime >= 0) { - var elapsedTime = now$1() - profilerStartTime; - fiber.actualDuration += elapsedTime; + { + validateFunctionComponentInDev(workInProgress, type); + } - if (overrideBaseTime) { - fiber.selfBaseDuration = elapsedTime; + return updateSimpleMemoComponent( + current$$1, + workInProgress, + resolvedType, + nextProps, + updateExpirationTime, + renderExpirationTime + ); } - profilerStartTime = -1; - } -} + { + var innerPropTypes = type.propTypes; -function enterHydrationState(fiber) { - { - return false; + 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), + getCurrentFiberStackInDev + ); + } + } + var child = createFiberFromTypeAndProps( + Component.type, + null, + nextProps, + null, + workInProgress.mode, + renderExpirationTime + ); + child.ref = workInProgress.ref; + child.return = workInProgress; + workInProgress.child = child; + return child; } -} -function prepareToHydrateHostInstance( - fiber, - rootContainerInstance, - hostContext -) { { - { - throw Error( - "Expected prepareToHydrateHostInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." + 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), + getCurrentFiberStackInDev ); } } + + var currentChild = current$$1.child; // This is always exactly one child + + if (updateExpirationTime < renderExpirationTime) { + // 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$$1.ref === workInProgress.ref + ) { + return bailoutOnAlreadyFinishedWork( + current$$1, + workInProgress, + renderExpirationTime + ); + } + } // React DevTools reads this flag. + + workInProgress.effectTag |= PerformedWork; + var newChild = createWorkInProgress( + currentChild, + nextProps, + renderExpirationTime + ); + newChild.ref = workInProgress.ref; + newChild.return = workInProgress; + workInProgress.child = newChild; + return newChild; } -function prepareToHydrateHostTextInstance(fiber) { - { - { - throw Error( - "Expected prepareToHydrateHostTextInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." - ); +function updateSimpleMemoComponent( + current$$1, + workInProgress, + Component, + nextProps, + updateExpirationTime, + renderExpirationTime +) { + // 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. + outerMemoType = refineResolvedLazyComponent(outerMemoType); + } + + var outerPropTypes = outerMemoType && outerMemoType.propTypes; + + if (outerPropTypes) { + checkPropTypes( + outerPropTypes, + nextProps, // Resolved (SimpleMemoComponent has no defaultProps) + "prop", + getComponentName(outerMemoType), + getCurrentFiberStackInDev + ); + } // Inner propTypes will be validated in the function component path. } } - var shouldUpdate = hydrateTextInstance(); -} -function popHydrationState(fiber) { - { - return false; - } -} + if (current$$1 !== null) { + var prevProps = current$$1.memoizedProps; -var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner; -var didReceiveUpdate = false; -var didWarnAboutBadClass; -var didWarnAboutModulePatternComponent; -var didWarnAboutContextTypeOnFunctionComponent; -var didWarnAboutGetDerivedStateOnFunctionComponent; -var didWarnAboutFunctionRefs; -var didWarnAboutReassigningProps; -var didWarnAboutRevealOrder; -var didWarnAboutTailOptions; + if ( + shallowEqual(prevProps, nextProps) && + current$$1.ref === workInProgress.ref && // Prevent bailout if the implementation changed due to hot reload: + workInProgress.type === current$$1.type + ) { + didReceiveUpdate = false; -{ - didWarnAboutBadClass = {}; - didWarnAboutModulePatternComponent = {}; - didWarnAboutContextTypeOnFunctionComponent = {}; - didWarnAboutGetDerivedStateOnFunctionComponent = {}; - didWarnAboutFunctionRefs = {}; - didWarnAboutReassigningProps = false; - didWarnAboutRevealOrder = {}; - didWarnAboutTailOptions = {}; + if (updateExpirationTime < renderExpirationTime) { + return bailoutOnAlreadyFinishedWork( + current$$1, + workInProgress, + renderExpirationTime + ); + } + } + } + return updateFunctionComponent( + current$$1, + workInProgress, + Component, + nextProps, + renderExpirationTime + ); } -function reconcileChildren( - current, - workInProgress, - nextChildren, - renderExpirationTime -) { - 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, - renderExpirationTime - ); - } 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, - renderExpirationTime - ); - } +function updateFragment(current$$1, workInProgress, renderExpirationTime) { + var nextChildren = workInProgress.pendingProps; + reconcileChildren( + current$$1, + workInProgress, + nextChildren, + renderExpirationTime + ); + return workInProgress.child; } -function forceUnmountCurrentAndReconcile( - current, - workInProgress, - nextChildren, - renderExpirationTime -) { - // 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( +function updateMode(current$$1, workInProgress, renderExpirationTime) { + var nextChildren = workInProgress.pendingProps.children; + reconcileChildren( + current$$1, workInProgress, - current.child, - null, + nextChildren, renderExpirationTime - ); // In the second pass, we mount the new children. The trick here is that we - // pass null in place of where we usually pass the current child set. This has - // the effect of remounting all children regardless of whether their - // identities match. + ); + return workInProgress.child; +} - workInProgress.child = reconcileChildFibers( +function updateProfiler(current$$1, workInProgress, renderExpirationTime) { + if (enableProfilerTimer) { + workInProgress.effectTag |= Update; + } + var nextProps = workInProgress.pendingProps; + var nextChildren = nextProps.children; + reconcileChildren( + current$$1, workInProgress, - null, nextChildren, renderExpirationTime ); + return workInProgress.child; } -function updateForwardRef( - current, +function markRef(current$$1, workInProgress) { + var ref = workInProgress.ref; + if ( + (current$$1 === null && ref !== null) || + (current$$1 !== null && current$$1.ref !== ref) + ) { + // Schedule a Ref effect + workInProgress.effectTag |= Ref; + } +} + +function updateFunctionComponent( + current$$1, workInProgress, Component, nextProps, renderExpirationTime ) { - // 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) + getComponentName(Component), + getCurrentFiberStackInDev ); } } } - var render = Component.render; - var ref = workInProgress.ref; // The rest is a fork of updateFunctionComponent + var context; + + if (!disableLegacyContext) { + var unmaskedContext = getUnmaskedContext(workInProgress, Component, true); + context = getMaskedContext(workInProgress, unmaskedContext); + } var nextChildren; prepareToReadContext(workInProgress, renderExpirationTime); { - ReactCurrentOwner$1.current = workInProgress; - setIsRendering(true); + ReactCurrentOwner$3.current = workInProgress; + setCurrentPhase("render"); nextChildren = renderWithHooks( - current, + current$$1, workInProgress, - render, + Component, nextProps, - ref, + context, renderExpirationTime ); - setIsRendering(false); + if ( + debugRenderPhaseSideEffectsForStrictMode && + workInProgress.mode & StrictMode + ) { + // Only double-render components with Hooks + if (workInProgress.memoizedState !== null) { + nextChildren = renderWithHooks( + current$$1, + workInProgress, + Component, + nextProps, + context, + renderExpirationTime + ); + } + } + setCurrentPhase(null); } - if (current !== null && !didReceiveUpdate) { - bailoutHooks(current, workInProgress, renderExpirationTime); + if (current$$1 !== null && !didReceiveUpdate) { + bailoutHooks(current$$1, workInProgress, renderExpirationTime); return bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -11660,7 +13369,7 @@ function updateForwardRef( workInProgress.effectTag |= PerformedWork; reconcileChildren( - current, + current$$1, workInProgress, nextChildren, renderExpirationTime @@ -11668,235 +13377,339 @@ function updateForwardRef( return workInProgress.child; } -function updateMemoComponent( - current, +function updateClassComponent( + current$$1, + workInProgress, + Component, + nextProps, + renderExpirationTime +) { + { + 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), + getCurrentFiberStackInDev + ); + } + } + } // 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, renderExpirationTime); + var instance = workInProgress.stateNode; + var shouldUpdate; + + if (instance === null) { + if (current$$1 !== null) { + // An class component without an instance only mounts if it suspended + // inside a non- concurrent tree, in an inconsistent state. We want to + // tree it like a new mount, even though an empty version of it already + // committed. Disconnect the alternate pointers. + current$$1.alternate = null; + workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect + + workInProgress.effectTag |= Placement; + } // In the initial pass we might need to construct the instance. + + constructClassInstance( + workInProgress, + Component, + nextProps, + renderExpirationTime + ); + mountClassInstance( + workInProgress, + Component, + nextProps, + renderExpirationTime + ); + shouldUpdate = true; + } else if (current$$1 === null) { + // In a resume, we'll already have an instance we can reuse. + shouldUpdate = resumeMountClassInstance( + workInProgress, + Component, + nextProps, + renderExpirationTime + ); + } else { + shouldUpdate = updateClassInstance( + current$$1, + workInProgress, + Component, + nextProps, + renderExpirationTime + ); + } + var nextUnitOfWork = finishClassComponent( + current$$1, + workInProgress, + Component, + shouldUpdate, + hasContext, + renderExpirationTime + ); + + { + var inst = workInProgress.stateNode; + + if (inst.props !== nextProps) { + !didWarnAboutReassigningProps + ? warning$1( + false, + "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" + ) + : void 0; + didWarnAboutReassigningProps = true; + } + } + return nextUnitOfWork; +} + +function finishClassComponent( + current$$1, workInProgress, Component, - nextProps, - updateExpirationTime, + shouldUpdate, + hasContext, renderExpirationTime ) { - 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, - updateExpirationTime, - renderExpirationTime - ); - } - - { - var innerPropTypes = type.propTypes; + // Refs should update even if shouldComponentUpdate returns false + markRef(current$$1, workInProgress); + var didCaptureError = (workInProgress.effectTag & DidCapture) !== NoEffect; - 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 (!shouldUpdate && !didCaptureError) { + // Context providers should defer to sCU for rendering + if (hasContext) { + invalidateContextProvider(workInProgress, Component, false); } - var child = createFiberFromTypeAndProps( - Component.type, - null, - nextProps, - null, - workInProgress.mode, + return bailoutOnAlreadyFinishedWork( + current$$1, + workInProgress, renderExpirationTime ); - child.ref = workInProgress.ref; - child.return = workInProgress; - workInProgress.child = child; - return child; } - { - var _type = Component.type; - var _innerPropTypes = _type.propTypes; + var instance = workInProgress.stateNode; // Rerender - 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) - ); - } - } + ReactCurrentOwner$3.current = workInProgress; + var nextChildren; - var currentChild = current.child; // This is always exactly one child + if ( + didCaptureError && + typeof Component.getDerivedStateFromError !== "function" + ) { + // If we captured an error, but getDerivedStateFrom catch 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 (updateExpirationTime < renderExpirationTime) { - // This will be the props with resolved defaultProps, - // unlike current.memoizedProps which will be the unresolved ones. - var prevProps = currentChild.memoizedProps; // Default to shallow comparison + if (enableProfilerTimer) { + stopProfilerTimerIfRunning(workInProgress); + } + } else { + { + setCurrentPhase("render"); + nextChildren = instance.render(); - var compare = Component.compare; - compare = compare !== null ? compare : shallowEqual; + if ( + debugRenderPhaseSideEffectsForStrictMode && + workInProgress.mode & StrictMode + ) { + instance.render(); + } - if (compare(prevProps, nextProps) && current.ref === workInProgress.ref) { - return bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderExpirationTime - ); + setCurrentPhase(null); } } // React DevTools reads this flag. workInProgress.effectTag |= PerformedWork; - var newChild = createWorkInProgress(currentChild, nextProps); - newChild.ref = workInProgress.ref; - newChild.return = workInProgress; - workInProgress.child = newChild; - return newChild; -} - -function updateSimpleMemoComponent( - current, - workInProgress, - Component, - nextProps, - updateExpirationTime, - renderExpirationTime -) { - // 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. - outerMemoType = refineResolvedLazyComponent(outerMemoType); - } + if (current$$1 !== 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$$1, + workInProgress, + nextChildren, + renderExpirationTime + ); + } else { + reconcileChildren( + current$$1, + workInProgress, + nextChildren, + renderExpirationTime + ); + } // Memoize state using the values we just used to render. + // TODO: Restructure so we never read values from the instance. - var outerPropTypes = outerMemoType && outerMemoType.propTypes; + workInProgress.memoizedState = instance.state; // The context might have changed so we need to recalculate it. - if (outerPropTypes) { - checkPropTypes( - outerPropTypes, - nextProps, // Resolved (SimpleMemoComponent has no defaultProps) - "prop", - getComponentName(outerMemoType) - ); - } // Inner propTypes will be validated in the function component path. - } + if (hasContext) { + invalidateContextProvider(workInProgress, Component, true); } - if (current !== null) { - var prevProps = current.memoizedProps; + return workInProgress.child; +} - if ( - shallowEqual(prevProps, nextProps) && - current.ref === workInProgress.ref && // Prevent bailout if the implementation changed due to hot reload. - workInProgress.type === current.type - ) { - didReceiveUpdate = false; +function 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); +} - if (updateExpirationTime < renderExpirationTime) { - // The pending update priority was cleared at the beginning of - // beginWork. We're about to bail out, but there might be additional - // updates at a lower priority. 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.expirationTime = current.expirationTime; - return bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderExpirationTime - ); - } - } +function updateHostRoot(current$$1, workInProgress, renderExpirationTime) { + pushHostRootContext(workInProgress); + var updateQueue = workInProgress.updateQueue; + + if (!(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." + ); } - return updateFunctionComponent( - current, + var nextProps = workInProgress.pendingProps; + var prevState = workInProgress.memoizedState; + var prevChildren = prevState !== null ? prevState.element : null; + processUpdateQueue( workInProgress, - Component, + updateQueue, nextProps, + null, renderExpirationTime ); -} + var nextState = workInProgress.memoizedState; // Caution: React DevTools currently depends on this property + // being called "element". -function updateFragment(current, workInProgress, renderExpirationTime) { - var nextChildren = workInProgress.pendingProps; - reconcileChildren( - current, - workInProgress, - nextChildren, - renderExpirationTime - ); - return workInProgress.child; -} + var nextChildren = nextState.element; -function updateMode(current, workInProgress, renderExpirationTime) { - var nextChildren = workInProgress.pendingProps.children; - reconcileChildren( - current, - workInProgress, - nextChildren, - renderExpirationTime - ); + if (nextChildren === prevChildren) { + // If the state is the same as before, that's a bailout because we had + // no work that expires at this time. + resetHydrationState(); + return bailoutOnAlreadyFinishedWork( + current$$1, + workInProgress, + renderExpirationTime + ); + } + + var root = workInProgress.stateNode; + + if (root.hydrate && enterHydrationState(workInProgress)) { + // If we don't have any current children this might be the first pass. + // We always try to hydrate. If this isn't a hydration pass there won't + // be any children to hydrate which is effectively the same thing as + // not hydrating. + var child = mountChildFibers( + workInProgress, + null, + nextChildren, + renderExpirationTime + ); + 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.effectTag = (node.effectTag & ~Placement) | Hydrating; + node = node.sibling; + } + } else { + // Otherwise reset hydration state in case we aborted and resumed another + // root. + reconcileChildren( + current$$1, + workInProgress, + nextChildren, + renderExpirationTime + ); + resetHydrationState(); + } return workInProgress.child; } -function updateProfiler(current, workInProgress, renderExpirationTime) { - { - workInProgress.effectTag |= 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 updateHostComponent(current$$1, workInProgress, renderExpirationTime) { + pushHostContext(workInProgress); - var stateNode = workInProgress.stateNode; - stateNode.effectDuration = 0; - stateNode.passiveEffectDuration = 0; + if (current$$1 === null) { + tryToClaimNextHydratableInstance(workInProgress); } + var type = workInProgress.type; var nextProps = workInProgress.pendingProps; + var prevProps = current$$1 !== null ? current$$1.memoizedProps : null; var nextChildren = nextProps.children; + var isDirectTextChild = shouldSetTextContent(type, nextProps); + + if (isDirectTextChild) { + // We special case a direct text child of a host node. This is a common + // case. We won't handle it as a reified child. We will instead handle + // this in the host environment that also have access to this prop. That + // avoids allocating another HostText fiber and traversing it. + nextChildren = null; + } else if (prevProps !== null && shouldSetTextContent(type, prevProps)) { + // 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.effectTag |= ContentReset; + } + + markRef(current$$1, workInProgress); // Check the host config to see if the children are offscreen/hidden. + + if ( + workInProgress.mode & ConcurrentMode && + renderExpirationTime !== Never && + shouldDeprioritizeSubtree(type, nextProps) + ) { + if (enableSchedulerTracing) { + markSpawnedWork(Never); + } // Schedule this fiber to re-render at offscreen priority. Then bailout. + + workInProgress.expirationTime = workInProgress.childExpirationTime = Never; + return null; + } + reconcileChildren( - current, + current$$1, workInProgress, nextChildren, renderExpirationTime @@ -11904,109 +13717,167 @@ function updateProfiler(current, workInProgress, renderExpirationTime) { return workInProgress.child; } -function markRef(current, workInProgress) { - var ref = workInProgress.ref; +function updateHostText(current$$1, workInProgress) { + if (current$$1 === null) { + tryToClaimNextHydratableInstance(workInProgress); + } // Nothing to do here. This is terminal. We'll do the completion step + // immediately after. - if ( - (current === null && ref !== null) || - (current !== null && current.ref !== ref) - ) { - // Schedule a Ref effect - workInProgress.effectTag |= Ref; - } + return null; } -function updateFunctionComponent( - current, +function mountLazyComponent( + _current, workInProgress, - Component, - nextProps, + elementType, + updateExpirationTime, renderExpirationTime ) { - { - 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 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.effectTag |= Placement; } - var context; + var props = workInProgress.pendingProps; // We can't start a User Timing measurement with correct label yet. + // Cancel and resume right after we know the tag. - { - var unmaskedContext = getUnmaskedContext(workInProgress, Component, true); - context = getMaskedContext(workInProgress, unmaskedContext); - } + cancelWorkTimer(workInProgress); + var Component = readLazyComponentType(elementType); // Store the unwrapped component in the type. - var nextChildren; - prepareToReadContext(workInProgress, renderExpirationTime); + workInProgress.type = Component; + var resolvedTag = (workInProgress.tag = resolveLazyComponentTag(Component)); + startWorkTimer(workInProgress); + var resolvedProps = resolveDefaultProps(Component, props); + var child; - { - ReactCurrentOwner$1.current = workInProgress; - setIsRendering(true); - nextChildren = renderWithHooks( - current, - workInProgress, - Component, - nextProps, - context, - renderExpirationTime - ); + switch (resolvedTag) { + case FunctionComponent: { + { + validateFunctionComponentInDev(workInProgress, Component); + workInProgress.type = Component = resolveFunctionForHotReloading( + Component + ); + } + child = updateFunctionComponent( + null, + workInProgress, + Component, + resolvedProps, + renderExpirationTime + ); + break; + } + case ClassComponent: { + { + workInProgress.type = Component = resolveClassForHotReloading( + Component + ); + } + child = updateClassComponent( + null, + workInProgress, + Component, + resolvedProps, + renderExpirationTime + ); + break; + } + case ForwardRef: { + { + workInProgress.type = Component = resolveForwardRefForHotReloading( + Component + ); + } + child = updateForwardRef( + null, + workInProgress, + Component, + resolvedProps, + renderExpirationTime + ); + break; + } + case MemoComponent: { + { + if (workInProgress.type !== workInProgress.elementType) { + var outerPropTypes = Component.propTypes; + if (outerPropTypes) { + checkPropTypes( + outerPropTypes, + resolvedProps, // Resolved for outer only + "prop", + getComponentName(Component), + getCurrentFiberStackInDev + ); + } + } + } + child = updateMemoComponent( + null, + workInProgress, + Component, + resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too + updateExpirationTime, + renderExpirationTime + ); + break; + } - setIsRendering(false); - } + default: { + var hint = ""; - if (current !== null && !didReceiveUpdate) { - bailoutHooks(current, workInProgress, renderExpirationTime); - return bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderExpirationTime - ); - } // React DevTools reads this flag. + { + 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. - workInProgress.effectTag |= PerformedWork; - reconcileChildren( - current, - workInProgress, - nextChildren, - renderExpirationTime - ); - return workInProgress.child; + { + throw Error( + "Element type is invalid. Received a promise that resolves to: " + + Component + + ". Lazy element type must resolve to a class or function." + + hint + ); + } + } + } + + return child; } -function updateClassComponent( - current, +function mountIncompleteClassComponent( + _current, workInProgress, Component, nextProps, renderExpirationTime ) { - { - 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.effectTag |= 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. @@ -12019,3819 +13890,5044 @@ function updateClassComponent( hasContext = false; } - prepareToReadContext(workInProgress, renderExpirationTime); - 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.effectTag |= Placement; - } // In the initial pass we might need to construct the instance. - - constructClassInstance(workInProgress, Component, nextProps); - mountClassInstance( - workInProgress, - Component, - nextProps, - renderExpirationTime - ); - shouldUpdate = true; - } else if (current === null) { - // In a resume, we'll already have an instance we can reuse. - shouldUpdate = resumeMountClassInstance( - workInProgress, - Component, - nextProps, - renderExpirationTime - ); - } else { - shouldUpdate = updateClassInstance( - current, - workInProgress, - Component, - nextProps, - renderExpirationTime - ); - } - - var nextUnitOfWork = finishClassComponent( - current, + prepareToReadContext(workInProgress, renderExpirationTime); + constructClassInstance( workInProgress, Component, - shouldUpdate, + nextProps, + renderExpirationTime + ); + mountClassInstance( + workInProgress, + Component, + nextProps, + renderExpirationTime + ); + return finishClassComponent( + null, + workInProgress, + Component, + true, hasContext, renderExpirationTime ); - - { - var inst = workInProgress.stateNode; - - if (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, +function mountIndeterminateComponent( + _current, workInProgress, Component, - shouldUpdate, - hasContext, renderExpirationTime ) { - // Refs should update even if shouldComponentUpdate returns false - markRef(current, workInProgress); - var didCaptureError = (workInProgress.effectTag & DidCapture) !== NoEffect; - - if (!shouldUpdate && !didCaptureError) { - // Context providers should defer to sCU for rendering - if (hasContext) { - invalidateContextProvider(workInProgress, Component, false); - } + 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 - return bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderExpirationTime - ); + workInProgress.effectTag |= Placement; } - var instance = workInProgress.stateNode; // Rerender + var props = workInProgress.pendingProps; + var context; - ReactCurrentOwner$1.current = workInProgress; - var nextChildren; + if (!disableLegacyContext) { + var unmaskedContext = getUnmaskedContext(workInProgress, Component, false); + context = getMaskedContext(workInProgress, unmaskedContext); + } - 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; + prepareToReadContext(workInProgress, renderExpirationTime); + var value; - { - stopProfilerTimerIfRunning(); - } - } else { - { - setIsRendering(true); - nextChildren = instance.render(); + { + if ( + Component.prototype && + typeof Component.prototype.render === "function" + ) { + var componentName = getComponentName(Component) || "Unknown"; - setIsRendering(false); + if (!didWarnAboutBadClass[componentName]) { + warningWithoutStack$1( + false, + "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; + } } - } // React DevTools reads this flag. - workInProgress.effectTag |= PerformedWork; + if (workInProgress.mode & StrictMode) { + ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null); + } - 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, - renderExpirationTime - ); - } else { - reconcileChildren( - current, + ReactCurrentOwner$3.current = workInProgress; + value = renderWithHooks( + null, workInProgress, - nextChildren, + Component, + props, + context, renderExpirationTime ); - } // 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; + } // React DevTools reads this flag. - 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.effectTag |= PerformedWork; - pushHostContainer(workInProgress, root.containerInfo); -} + if ( + typeof value === "object" && + value !== null && + typeof value.render === "function" && + value.$$typeof === undefined + ) { + { + var _componentName = getComponentName(Component) || "Unknown"; + if (!didWarnAboutModulePatternComponent[_componentName]) { + warningWithoutStack$1( + false, + "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; + } + } // Proceed under the assumption that this is a class instance -function updateHostRoot(current, workInProgress, renderExpirationTime) { - pushHostRootContext(workInProgress); - var updateQueue = workInProgress.updateQueue; + workInProgress.tag = ClassComponent; // Throw out any hooks that were used. - 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." - ); - } + resetHooks(); // 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 nextProps = workInProgress.pendingProps; - var prevState = workInProgress.memoizedState; - var prevChildren = prevState !== null ? prevState.element : null; - cloneUpdateQueue(current, workInProgress); - processUpdateQueue(workInProgress, nextProps, null, renderExpirationTime); - var nextState = workInProgress.memoizedState; // Caution: React DevTools currently depends on this property - // being called "element". + var hasContext = false; - var nextChildren = nextState.element; + if (isContextProvider(Component)) { + hasContext = true; + pushContextProvider(workInProgress); + } else { + hasContext = false; + } - if (nextChildren === prevChildren) { - return bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderExpirationTime - ); - } + workInProgress.memoizedState = + value.state !== null && value.state !== undefined ? value.state : null; + var getDerivedStateFromProps = Component.getDerivedStateFromProps; - var root = workInProgress.stateNode; + if (typeof getDerivedStateFromProps === "function") { + applyDerivedStateFromProps( + workInProgress, + Component, + getDerivedStateFromProps, + props + ); + } - if (root.hydrate && enterHydrationState()) { - // If we don't have any current children this might be the first pass. - // We always try to hydrate. If this isn't a hydration pass there won't - // be any children to hydrate which is effectively the same thing as - // not hydrating. - var child = mountChildFibers( - workInProgress, + adoptClassInstance(workInProgress, value); + mountClassInstance(workInProgress, Component, props, renderExpirationTime); + return finishClassComponent( null, - nextChildren, + workInProgress, + Component, + true, + hasContext, renderExpirationTime ); - workInProgress.child = child; - var node = child; + } else { + // Proceed under the assumption that this is a function component + workInProgress.tag = FunctionComponent; + { + if (disableLegacyContext && Component.contextTypes) { + warningWithoutStack$1( + false, + "%s uses the legacy contextTypes API which is no longer supported. " + + "Use React.createContext() with React.useContext() instead.", + getComponentName(Component) || "Unknown" + ); + } - 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.effectTag = (node.effectTag & ~Placement) | Hydrating; - node = node.sibling; + if ( + debugRenderPhaseSideEffectsForStrictMode && + workInProgress.mode & StrictMode + ) { + // Only double-render components with Hooks + if (workInProgress.memoizedState !== null) { + value = renderWithHooks( + null, + workInProgress, + Component, + props, + context, + renderExpirationTime + ); + } + } } - } else { - // Otherwise reset hydration state in case we aborted and resumed another - // root. - reconcileChildren( - current, - workInProgress, - nextChildren, - renderExpirationTime - ); - } - return workInProgress.child; + reconcileChildren(null, workInProgress, value, renderExpirationTime); + + { + validateFunctionComponentInDev(workInProgress, Component); + } + + return workInProgress.child; + } } -function updateHostComponent(current, workInProgress, renderExpirationTime) { - pushHostContext(workInProgress); +function validateFunctionComponentInDev(workInProgress, Component) { + if (Component) { + !!Component.childContextTypes + ? warningWithoutStack$1( + false, + "%s(...): childContextTypes cannot be defined on a function component.", + Component.displayName || Component.name || "Component" + ) + : void 0; + } - var type = workInProgress.type; - var nextProps = workInProgress.pendingProps; - var prevProps = current !== null ? current.memoizedProps : null; - var nextChildren = nextProps.children; + if (workInProgress.ref !== null) { + var info = ""; + var ownerName = getCurrentFiberOwnerNameInDevOrNull(); - 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.effectTag |= ContentReset; - } + if (ownerName) { + info += "\n\nCheck the render method of `" + ownerName + "`."; + } + + var warningKey = ownerName || workInProgress._debugID || ""; + var debugSource = workInProgress._debugSource; + + if (debugSource) { + warningKey = debugSource.fileName + ":" + debugSource.lineNumber; + } - markRef(current, workInProgress); // Check the host config to see if the children are offscreen/hidden. + if (!didWarnAboutFunctionRefs[warningKey]) { + didWarnAboutFunctionRefs[warningKey] = true; + warning$1( + false, + "Function components cannot be given refs. " + + "Attempts to access this ref will fail. " + + "Did you mean to use React.forwardRef()?%s", + info + ); + } + } if ( - workInProgress.mode & ConcurrentMode && - renderExpirationTime !== Never && - shouldDeprioritizeSubtree() + warnAboutDefaultPropsOnFunctionComponents && + Component.defaultProps !== undefined ) { - { - markSpawnedWork(Never); - } // Schedule this fiber to re-render at offscreen priority. Then bailout. + var componentName = getComponentName(Component) || "Unknown"; + + if (!didWarnAboutDefaultPropsOnFunctionComponent[componentName]) { + warningWithoutStack$1( + false, + "%s: Support for defaultProps will be removed from function components " + + "in a future major release. Use JavaScript default parameters instead.", + componentName + ); + didWarnAboutDefaultPropsOnFunctionComponent[componentName] = true; + } + } - workInProgress.expirationTime = workInProgress.childExpirationTime = Never; - return null; + if (typeof Component.getDerivedStateFromProps === "function") { + var _componentName2 = getComponentName(Component) || "Unknown"; + + if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2]) { + warningWithoutStack$1( + false, + "%s: Function components do not support getDerivedStateFromProps.", + _componentName2 + ); + didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2] = true; + } } - reconcileChildren( - current, - workInProgress, - nextChildren, - renderExpirationTime - ); - return workInProgress.child; + if ( + typeof Component.contextType === "object" && + Component.contextType !== null + ) { + var _componentName3 = getComponentName(Component) || "Unknown"; + + if (!didWarnAboutContextTypeOnFunctionComponent[_componentName3]) { + warningWithoutStack$1( + false, + "%s: Function components do not support contextType.", + _componentName3 + ); + didWarnAboutContextTypeOnFunctionComponent[_componentName3] = true; + } + } } -function updateHostText(current, workInProgress) { - // immediately after. +var SUSPENDED_MARKER = { + dehydrated: null, + retryTime: NoWork +}; - return null; +function shouldRemainOnFallback(suspenseContext, current$$1, workInProgress) { + // If the context is telling us that we should show a fallback, and we're not + // already showing content, then we should show the fallback instead. + return ( + hasSuspenseContext(suspenseContext, ForceSuspenseFallback) && + (current$$1 === null || current$$1.memoizedState !== null) + ); } -function mountLazyComponent( - _current, +function updateSuspenseComponent( + current$$1, workInProgress, - elementType, - updateExpirationTime, renderExpirationTime ) { - 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 + var mode = workInProgress.mode; + var nextProps = workInProgress.pendingProps; // This is used by DevTools to force a boundary to suspend. - workInProgress.effectTag |= Placement; + { + if (shouldSuspend(workInProgress)) { + workInProgress.effectTag |= DidCapture; + } } - var props = workInProgress.pendingProps; // We can't start a User Timing measurement with correct label yet. - // Cancel and resume right after we know the tag. + var suspenseContext = suspenseStackCursor.current; + var nextDidTimeout = false; + var didSuspend = (workInProgress.effectTag & DidCapture) !== NoEffect; - cancelWorkTimer(workInProgress); - var Component = readLazyComponentType(elementType); // Store the unwrapped component in the type. + if ( + didSuspend || + shouldRemainOnFallback(suspenseContext, current$$1, workInProgress) + ) { + // Something in this boundary's subtree already suspended. Switch to + // rendering the fallback children. + nextDidTimeout = true; + workInProgress.effectTag &= ~DidCapture; + } else { + // Attempting the main content + if (current$$1 === null || current$$1.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)); - startWorkTimer(workInProgress); - var resolvedProps = resolveDefaultProps(Component, props); - var child; + suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); + pushSuspenseContext(workInProgress, suspenseContext); - switch (resolvedTag) { - case FunctionComponent: { - { - validateFunctionComponentInDev(workInProgress, Component); - workInProgress.type = Component = resolveFunctionForHotReloading( - Component + { + if ("maxDuration" in nextProps) { + if (!didWarnAboutMaxDuration) { + didWarnAboutMaxDuration = true; + warning$1( + false, + "maxDuration has been removed from React. " + + "Remove the maxDuration prop." ); } + } + } // This next part is a bit confusing. If the children timeout, we switch to + // showing the fallback children in place of the "primary" children. + // However, we don't want to delete the primary children because then their + // state will be lost (both the React state and the host state, e.g. + // uncontrolled form inputs). Instead we keep them mounted and hide them. + // Both the fallback children AND the primary children are rendered at the + // same time. Once the primary children are un-suspended, we can delete + // the fallback children — don't need to preserve their state. + // + // The two sets of children are siblings in the host environment, but + // semantically, for purposes of reconciliation, they are two separate sets. + // So we store them using two fragment fibers. + // + // However, we want to avoid allocating extra fibers for every placeholder. + // They're only necessary when the children time out, because that's the + // only time when both sets are mounted. + // + // So, the extra fragment fibers are only used if the children time out. + // Otherwise, we render the primary children directly. This requires some + // custom reconciliation logic to preserve the state of the primary + // children. It's essentially a very basic form of re-parenting. + + if (current$$1 === null) { + // If we're currently hydrating, try to hydrate this boundary. + // But only if this has a fallback. + if (nextProps.fallback !== undefined) { + tryToClaimNextHydratableInstance(workInProgress); // This could've been a dehydrated suspense component. + + if (enableSuspenseServerRenderer) { + var suspenseState = workInProgress.memoizedState; + + if (suspenseState !== null) { + var dehydrated = suspenseState.dehydrated; + + if (dehydrated !== null) { + return mountDehydratedSuspenseComponent( + workInProgress, + dehydrated, + renderExpirationTime + ); + } + } + } + } // This is the initial mount. This branch is pretty simple because there's + // no previous state that needs to be preserved. - child = updateFunctionComponent( + if (nextDidTimeout) { + // Mount separate fragments for primary and fallback children. + var nextFallbackChildren = nextProps.fallback; + var primaryChildFragment = createFiberFromFragment( null, - workInProgress, - Component, - resolvedProps, - renderExpirationTime + mode, + NoWork, + null ); - return child; - } + primaryChildFragment.return = workInProgress; - case ClassComponent: { - { - workInProgress.type = Component = resolveClassForHotReloading( - Component - ); + if ((workInProgress.mode & BlockingMode) === NoMode) { + // Outside of blocking mode, we commit the effects from the + // partially completed, timed-out tree, too. + var progressedState = workInProgress.memoizedState; + var progressedPrimaryChild = + progressedState !== null + ? workInProgress.child.child + : workInProgress.child; + primaryChildFragment.child = progressedPrimaryChild; + var progressedChild = progressedPrimaryChild; + while (progressedChild !== null) { + progressedChild.return = primaryChildFragment; + progressedChild = progressedChild.sibling; + } } - child = updateClassComponent( - null, + var fallbackChildFragment = createFiberFromFragment( + nextFallbackChildren, + mode, + renderExpirationTime, + null + ); + fallbackChildFragment.return = workInProgress; + primaryChildFragment.sibling = fallbackChildFragment; // Skip the primary children, and continue working on the + // fallback children. + + workInProgress.memoizedState = SUSPENDED_MARKER; + workInProgress.child = primaryChildFragment; + return fallbackChildFragment; + } else { + // Mount the primary children without an intermediate fragment fiber. + var nextPrimaryChildren = nextProps.children; + workInProgress.memoizedState = null; + return (workInProgress.child = mountChildFibers( workInProgress, - Component, - resolvedProps, + null, + nextPrimaryChildren, renderExpirationTime - ); - return child; + )); } + } else { + // This is an update. This branch is more complicated because we need to + // ensure the state of the primary children is preserved. + var prevState = current$$1.memoizedState; + + if (prevState !== null) { + if (enableSuspenseServerRenderer) { + var _dehydrated = prevState.dehydrated; + + if (_dehydrated !== null) { + if (!didSuspend) { + return updateDehydratedSuspenseComponent( + current$$1, + workInProgress, + _dehydrated, + prevState, + renderExpirationTime + ); + } else if (workInProgress.memoizedState !== null) { + // Something suspended and we should still be in dehydrated mode. + // Leave the existing child in place. + workInProgress.child = current$$1.child; // The dehydrated completion pass expects this flag to be there + // but the normal suspense pass doesn't. + + workInProgress.effectTag |= DidCapture; + return null; + } else { + // Suspended but we should no longer be in dehydrated mode. + // Therefore we now have to render the fallback. Wrap the children + // in a fragment fiber to keep them separate from the fallback + // children. + var _nextFallbackChildren = nextProps.fallback; + + var _primaryChildFragment = createFiberFromFragment( + // It shouldn't matter what the pending props are because we aren't + // going to render this fragment. + null, + mode, + NoWork, + null + ); + + _primaryChildFragment.return = workInProgress; // This is always null since we never want the previous child + // that we're not going to hydrate. + + _primaryChildFragment.child = null; + + if ((workInProgress.mode & BlockingMode) === NoMode) { + // Outside of blocking mode, we commit the effects from the + // partially completed, timed-out tree, too. + var _progressedChild = (_primaryChildFragment.child = + workInProgress.child); + + while (_progressedChild !== null) { + _progressedChild.return = _primaryChildFragment; + _progressedChild = _progressedChild.sibling; + } + } else { + // We will have dropped the effect list which contains the deletion. + // We need to reconcile to delete the current child. + reconcileChildFibers( + workInProgress, + current$$1.child, + null, + renderExpirationTime + ); + } // Because primaryChildFragment is a new fiber that we're inserting as the + // parent of a new tree, we need to set its treeBaseDuration. + + if (enableProfilerTimer && workInProgress.mode & ProfileMode) { + // treeBaseDuration is the sum of all the child tree base durations. + var treeBaseDuration = 0; + var hiddenChild = _primaryChildFragment.child; + + while (hiddenChild !== null) { + treeBaseDuration += hiddenChild.treeBaseDuration; + hiddenChild = hiddenChild.sibling; + } + + _primaryChildFragment.treeBaseDuration = treeBaseDuration; + } // Create a fragment from the fallback children, too. + + var _fallbackChildFragment = createFiberFromFragment( + _nextFallbackChildren, + mode, + renderExpirationTime, + null + ); + + _fallbackChildFragment.return = workInProgress; + _primaryChildFragment.sibling = _fallbackChildFragment; + _fallbackChildFragment.effectTag |= Placement; + _primaryChildFragment.childExpirationTime = NoWork; + workInProgress.memoizedState = SUSPENDED_MARKER; + workInProgress.child = _primaryChildFragment; // Skip the primary children, and continue working on the + // fallback children. + + return _fallbackChildFragment; + } + } + } // The current tree already timed out. That means each child set is + // wrapped in a fragment fiber. + + var currentPrimaryChildFragment = current$$1.child; + var currentFallbackChildFragment = currentPrimaryChildFragment.sibling; + + if (nextDidTimeout) { + // Still timed out. Reuse the current primary children by cloning + // its fragment. We're going to skip over these entirely. + var _nextFallbackChildren2 = nextProps.fallback; - case ForwardRef: { - { - workInProgress.type = Component = resolveForwardRefForHotReloading( - Component + var _primaryChildFragment2 = createWorkInProgress( + currentPrimaryChildFragment, + currentPrimaryChildFragment.pendingProps, + NoWork ); - } - child = updateForwardRef( - null, - workInProgress, - Component, - resolvedProps, - renderExpirationTime - ); - return child; - } + _primaryChildFragment2.return = workInProgress; - case MemoComponent: { - { - if (workInProgress.type !== workInProgress.elementType) { - var outerPropTypes = Component.propTypes; + if ((workInProgress.mode & BlockingMode) === NoMode) { + // Outside of blocking mode, we commit the effects from the + // partially completed, timed-out tree, too. + var _progressedState = workInProgress.memoizedState; - if (outerPropTypes) { - checkPropTypes( - outerPropTypes, - resolvedProps, // Resolved for outer only - "prop", - getComponentName(Component) - ); + var _progressedPrimaryChild = + _progressedState !== null + ? workInProgress.child.child + : workInProgress.child; + + if (_progressedPrimaryChild !== currentPrimaryChildFragment.child) { + _primaryChildFragment2.child = _progressedPrimaryChild; + var _progressedChild2 = _progressedPrimaryChild; + + while (_progressedChild2 !== null) { + _progressedChild2.return = _primaryChildFragment2; + _progressedChild2 = _progressedChild2.sibling; + } } - } - } + } // Because primaryChildFragment is a new fiber that we're inserting as the + // parent of a new tree, we need to set its treeBaseDuration. - child = updateMemoComponent( - null, - workInProgress, - Component, - resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too - updateExpirationTime, - renderExpirationTime - ); - return child; - } - } + if (enableProfilerTimer && workInProgress.mode & ProfileMode) { + // treeBaseDuration is the sum of all the child tree base durations. + var _treeBaseDuration = 0; + var _hiddenChild = _primaryChildFragment2.child; - var hint = ""; + while (_hiddenChild !== null) { + _treeBaseDuration += _hiddenChild.treeBaseDuration; + _hiddenChild = _hiddenChild.sibling; + } - { - 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. + _primaryChildFragment2.treeBaseDuration = _treeBaseDuration; + } // Clone the fallback child fragment, too. These we'll continue + // working on. - { - throw Error( - "Element type is invalid. Received a promise that resolves to: " + - Component + - ". Lazy element type must resolve to a class or function." + - hint - ); - } -} + var _fallbackChildFragment2 = createWorkInProgress( + currentFallbackChildFragment, + _nextFallbackChildren2, + currentFallbackChildFragment.expirationTime + ); -function mountIncompleteClassComponent( - _current, - workInProgress, - Component, - nextProps, - renderExpirationTime -) { - 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 + _fallbackChildFragment2.return = workInProgress; + _primaryChildFragment2.sibling = _fallbackChildFragment2; + _primaryChildFragment2.childExpirationTime = NoWork; // Skip the primary children, and continue working on the + // fallback children. - workInProgress.effectTag |= Placement; - } // Promote the fiber to a class and try rendering again. + workInProgress.memoizedState = SUSPENDED_MARKER; + workInProgress.child = _primaryChildFragment2; + return _fallbackChildFragment2; + } else { + // No longer suspended. Switch back to showing the primary children, + // and remove the intermediate fragment fiber. + var _nextPrimaryChildren = nextProps.children; + var currentPrimaryChild = currentPrimaryChildFragment.child; + var primaryChild = reconcileChildFibers( + workInProgress, + currentPrimaryChild, + _nextPrimaryChildren, + renderExpirationTime + ); // If this render doesn't suspend, we need to delete the fallback + // children. Wait until the complete phase, after we've confirmed the + // fallback is no longer needed. + // TODO: Would it be better to store the fallback fragment on + // the stateNode? + // Continue rendering the children, like we normally do. - 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. + workInProgress.memoizedState = null; + return (workInProgress.child = primaryChild); + } + } else { + // The current tree has not already timed out. That means the primary + // children are not wrapped in a fragment fiber. + var _currentPrimaryChild = current$$1.child; - var hasContext; + if (nextDidTimeout) { + // Timed out. Wrap the children in a fragment fiber to keep them + // separate from the fallback children. + var _nextFallbackChildren3 = nextProps.fallback; - if (isContextProvider(Component)) { - hasContext = true; - pushContextProvider(workInProgress); - } else { - hasContext = false; - } + var _primaryChildFragment3 = createFiberFromFragment( + // It shouldn't matter what the pending props are because we aren't + // going to render this fragment. + null, + mode, + NoWork, + null + ); - prepareToReadContext(workInProgress, renderExpirationTime); - constructClassInstance(workInProgress, Component, nextProps); - mountClassInstance( - workInProgress, - Component, - nextProps, - renderExpirationTime - ); - return finishClassComponent( - null, - workInProgress, - Component, - true, - hasContext, - renderExpirationTime - ); -} + _primaryChildFragment3.return = workInProgress; + _primaryChildFragment3.child = _currentPrimaryChild; -function mountIndeterminateComponent( - _current, - workInProgress, - Component, - renderExpirationTime -) { - 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 (_currentPrimaryChild !== null) { + _currentPrimaryChild.return = _primaryChildFragment3; + } // Even though we're creating a new fiber, there are no new children, + // because we're reusing an already mounted tree. So we don't need to + // schedule a placement. + // primaryChildFragment.effectTag |= Placement; - workInProgress.effectTag |= Placement; - } + if ((workInProgress.mode & BlockingMode) === NoMode) { + // Outside of blocking mode, we commit the effects from the + // partially completed, timed-out tree, too. + var _progressedState2 = workInProgress.memoizedState; - var props = workInProgress.pendingProps; - var context; + var _progressedPrimaryChild2 = + _progressedState2 !== null + ? workInProgress.child.child + : workInProgress.child; - { - var unmaskedContext = getUnmaskedContext(workInProgress, Component, false); - context = getMaskedContext(workInProgress, unmaskedContext); - } + _primaryChildFragment3.child = _progressedPrimaryChild2; + var _progressedChild3 = _progressedPrimaryChild2; - prepareToReadContext(workInProgress, renderExpirationTime); - var value; + while (_progressedChild3 !== null) { + _progressedChild3.return = _primaryChildFragment3; + _progressedChild3 = _progressedChild3.sibling; + } + } // Because primaryChildFragment is a new fiber that we're inserting as the + // parent of a new tree, we need to set its treeBaseDuration. - { - if ( - Component.prototype && - typeof Component.prototype.render === "function" - ) { - var componentName = getComponentName(Component) || "Unknown"; + if (enableProfilerTimer && workInProgress.mode & ProfileMode) { + // treeBaseDuration is the sum of all the child tree base durations. + var _treeBaseDuration2 = 0; + var _hiddenChild2 = _primaryChildFragment3.child; - 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 + while (_hiddenChild2 !== null) { + _treeBaseDuration2 += _hiddenChild2.treeBaseDuration; + _hiddenChild2 = _hiddenChild2.sibling; + } + + _primaryChildFragment3.treeBaseDuration = _treeBaseDuration2; + } // Create a fragment from the fallback children, too. + + var _fallbackChildFragment3 = createFiberFromFragment( + _nextFallbackChildren3, + mode, + renderExpirationTime, + null ); - didWarnAboutBadClass[componentName] = true; + _fallbackChildFragment3.return = workInProgress; + _primaryChildFragment3.sibling = _fallbackChildFragment3; + _fallbackChildFragment3.effectTag |= Placement; + _primaryChildFragment3.childExpirationTime = NoWork; // Skip the primary children, and continue working on the + // fallback children. + + workInProgress.memoizedState = SUSPENDED_MARKER; + workInProgress.child = _primaryChildFragment3; + return _fallbackChildFragment3; + } else { + // Still haven't timed out. Continue rendering the children, like we + // normally do. + workInProgress.memoizedState = null; + var _nextPrimaryChildren2 = nextProps.children; + return (workInProgress.child = reconcileChildFibers( + workInProgress, + _currentPrimaryChild, + _nextPrimaryChildren2, + renderExpirationTime + )); } } + } +} - if (workInProgress.mode & StrictMode) { - ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null); - } +function retrySuspenseComponentWithoutHydrating( + current$$1, + workInProgress, + renderExpirationTime +) { + // We're now not suspended nor dehydrated. + workInProgress.memoizedState = null; // Retry with the full children. - ReactCurrentOwner$1.current = workInProgress; - value = renderWithHooks( - null, - workInProgress, - Component, - props, - context, - renderExpirationTime - ); - } // React DevTools reads this flag. + var nextProps = workInProgress.pendingProps; + var nextChildren = nextProps.children; // This will ensure that the children get Placement effects and + // that the old child gets a Deletion effect. + // We could also call forceUnmountCurrentAndReconcile. - workInProgress.effectTag |= PerformedWork; + reconcileChildren( + current$$1, + workInProgress, + nextChildren, + renderExpirationTime + ); + return workInProgress.child; +} - if ( - typeof value === "object" && - value !== null && - typeof value.render === "function" && - value.$$typeof === undefined - ) { +function mountDehydratedSuspenseComponent( + workInProgress, + suspenseInstance, + renderExpirationTime +) { + // During the first pass, we'll bail out and not drill into the children. + // Instead, we'll leave the content in place and try to hydrate it later. + if ((workInProgress.mode & BlockingMode) === NoMode) { { - 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 - ); + warning$1( + false, + "Cannot hydrate Suspense in legacy mode. Switch from " + + "ReactDOM.hydrate(element, container) to " + + "ReactDOM.createBlockingRoot(container, { hydrate: true })" + + ".render(element) or remove the Suspense components from " + + "the server rendered components." + ); + } - didWarnAboutModulePatternComponent[_componentName] = true; - } - } // Proceed under the assumption that this is a class instance + workInProgress.expirationTime = Sync; + } else if (isSuspenseInstanceFallback(suspenseInstance)) { + // This is a client-only boundary. Since we won't get any content from the server + // for this, we need to schedule that at a higher priority based on when it would + // have timed out. In theory we could render it in this pass but it would have the + // wrong priority associated with it and will prevent hydration of parent path. + // Instead, we'll leave work left on it to render it in a separate commit. + // TODO This time should be the time at which the server rendered response that is + // a parent to this boundary was displayed. However, since we currently don't have + // a protocol to transfer that time, we'll just estimate it by using the current + // time. This will mean that Suspense timeouts are slightly shifted to later than + // they should be. + var serverDisplayTime = requestCurrentTimeForUpdate(); // Schedule a normal pri update to render this content. - workInProgress.tag = ClassComponent; // Throw out any hooks that were used. + var newExpirationTime = computeAsyncExpiration(serverDisplayTime); - 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 (enableSchedulerTracing) { + markSpawnedWork(newExpirationTime); + } - var hasContext = false; + workInProgress.expirationTime = newExpirationTime; + } else { + // We'll continue hydrating the rest at offscreen priority since we'll already + // be showing the right content coming from the server, it is no rush. + workInProgress.expirationTime = Never; - if (isContextProvider(Component)) { - hasContext = true; - pushContextProvider(workInProgress); - } else { - hasContext = false; + if (enableSchedulerTracing) { + markSpawnedWork(Never); } + } - workInProgress.memoizedState = - value.state !== null && value.state !== undefined ? value.state : null; - initializeUpdateQueue(workInProgress); - var getDerivedStateFromProps = Component.getDerivedStateFromProps; + return null; +} - if (typeof getDerivedStateFromProps === "function") { - applyDerivedStateFromProps( - workInProgress, - Component, - getDerivedStateFromProps, - props - ); - } +function updateDehydratedSuspenseComponent( + current$$1, + workInProgress, + suspenseInstance, + suspenseState, + renderExpirationTime +) { + // We should never be hydrating at this point because it is the first pass, + // but after we've already committed once. + warnIfHydrating(); - adoptClassInstance(workInProgress, value); - mountClassInstance(workInProgress, Component, props, renderExpirationTime); - return finishClassComponent( - null, + if ((workInProgress.mode & BlockingMode) === NoMode) { + return retrySuspenseComponentWithoutHydrating( + current$$1, workInProgress, - Component, - true, - hasContext, renderExpirationTime ); - } else { - // Proceed under the assumption that this is a function component - workInProgress.tag = FunctionComponent; + } - reconcileChildren(null, workInProgress, value, renderExpirationTime); + if (isSuspenseInstanceFallback(suspenseInstance)) { + // This boundary is in a permanent fallback state. In this case, we'll never + // get an update and we'll never be able to hydrate the final content. Let's just try the + // client side render instead. + return retrySuspenseComponentWithoutHydrating( + current$$1, + workInProgress, + renderExpirationTime + ); + } // We use childExpirationTime to indicate that a child might depend on context, so if + // any context has changed, we need to treat is as if the input might have changed. + + var hasContextChanged$$1 = + current$$1.childExpirationTime >= renderExpirationTime; + + if (didReceiveUpdate || hasContextChanged$$1) { + // This boundary has changed since the first render. This means that we are now unable to + // hydrate it. We might still be able to hydrate it using an earlier expiration time, if + // we are rendering at lower expiration than sync. + if (renderExpirationTime < Sync) { + if (suspenseState.retryTime <= renderExpirationTime) { + // This render is even higher pri than we've seen before, let's try again + // at even higher pri. + var attemptHydrationAtExpirationTime = renderExpirationTime + 1; + suspenseState.retryTime = attemptHydrationAtExpirationTime; + scheduleWork(current$$1, attemptHydrationAtExpirationTime); // TODO: Early abort this render. + } else { + // We have already tried to ping at a higher priority than we're rendering with + // so if we got here, we must have failed to hydrate at those levels. We must + // now give up. Instead, we're going to delete the whole subtree and instead inject + // a new real Suspense boundary to take its place, which may render content + // or fallback. This might suspend for a while and if it does we might still have + // an opportunity to hydrate before this pass commits. + } + } // If we have scheduled higher pri work above, this will probably just abort the render + // since we now have higher priority work, but in case it doesn't, we need to prepare to + // render something, if we time out. Even if that requires us to delete everything and + // skip hydration. + // Delay having to do this as long as the suspense timeout allows us. + + renderDidSuspendDelayIfPossible(); + return retrySuspenseComponentWithoutHydrating( + current$$1, + workInProgress, + renderExpirationTime + ); + } else if (isSuspenseInstancePending(suspenseInstance)) { + // This component is still pending more data from the server, so we can't hydrate its + // content. We treat it as if this component suspended itself. It might seem as if + // we could just try to render it client-side instead. However, this will perform a + // lot of unnecessary work and is unlikely to complete since it often will suspend + // on missing data anyway. Additionally, the server might be able to render more + // than we can on the client yet. In that case we'd end up with more fallback states + // on the client than if we just leave it alone. If the server times out or errors + // these should update this boundary to the permanent Fallback state instead. + // Mark it as having captured (i.e. suspended). + workInProgress.effectTag |= DidCapture; // Leave the child in place. I.e. the dehydrated fragment. + + workInProgress.child = current$$1.child; // Register a callback to retry this boundary once the server has sent the result. + + registerSuspenseInstanceRetry( + suspenseInstance, + retryDehydratedSuspenseBoundary.bind(null, current$$1) + ); + return null; + } else { + // This is the first attempt. + reenterHydrationStateFromDehydratedSuspenseInstance( + workInProgress, + suspenseInstance + ); + var nextProps = workInProgress.pendingProps; + var nextChildren = nextProps.children; + var child = mountChildFibers( + workInProgress, + null, + nextChildren, + renderExpirationTime + ); + var node = child; - { - validateFunctionComponentInDev(workInProgress, Component); + 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.effectTag |= Hydrating; + node = node.sibling; } + workInProgress.child = child; return workInProgress.child; } } -function validateFunctionComponentInDev(workInProgress, Component) { - { - if (Component) { - if (Component.childContextTypes) { - error( - "%s(...): childContextTypes cannot be defined on a function component.", - Component.displayName || Component.name || "Component" - ); +function scheduleWorkOnFiber(fiber, renderExpirationTime) { + if (fiber.expirationTime < renderExpirationTime) { + fiber.expirationTime = renderExpirationTime; + } + + var alternate = fiber.alternate; + + if (alternate !== null && alternate.expirationTime < renderExpirationTime) { + alternate.expirationTime = renderExpirationTime; + } + + scheduleWorkOnParentPath(fiber.return, renderExpirationTime); +} + +function propagateSuspenseContextChange( + workInProgress, + firstChild, + renderExpirationTime +) { + // 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, renderExpirationTime); } + } 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, renderExpirationTime); + } else if (node.child !== null) { + node.child.return = node; + node = node.child; + continue; } - if (workInProgress.ref !== null) { - var info = ""; - var ownerName = getCurrentFiberOwnerNameInDevOrNull(); + if (node === workInProgress) { + return; + } - if (ownerName) { - info += "\n\nCheck the render method of `" + ownerName + "`."; + while (node.sibling === null) { + if (node.return === null || node.return === workInProgress) { + return; } - var warningKey = ownerName || workInProgress._debugID || ""; - var debugSource = workInProgress._debugSource; + node = node.return; + } - if (debugSource) { - warningKey = debugSource.fileName + ":" + debugSource.lineNumber; - } + node.sibling.return = node.return; + node = node.sibling; + } +} + +function findLastContentRow(firstChild) { + // This is going to find the last row among these children that is already + // showing content on the screen, as opposed to being in fallback state or + // new. If a row has multiple Suspense boundaries, any of them being in the + // fallback state, counts as the whole row being in a fallback state. + // Note that the "rows" will be workInProgress, but any nested children + // will still be current since we haven't rendered them yet. The mounted + // order may not be the same as the new order. We use the new order. + var row = firstChild; + var lastContentRow = null; + + while (row !== null) { + var currentRow = row.alternate; // New rows can't be content rows. + + if (currentRow !== null && findFirstSuspended(currentRow) === null) { + lastContentRow = row; + } + + row = row.sibling; + } - if (!didWarnAboutFunctionRefs[warningKey]) { - didWarnAboutFunctionRefs[warningKey] = true; + return lastContentRow; +} - error( - "Function components cannot be given refs. " + - "Attempts to access this ref will fail. " + - "Did you mean to use React.forwardRef()?%s", - info +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": { + warning$1( + false, + '"%s" is not a valid value for revealOrder on . ' + + 'Use lowercase "%s" instead.', + revealOrder, + revealOrder.toLowerCase() + ); + break; + } + case "forward": + case "backward": { + warning$1( + false, + '"%s" is not a valid value for revealOrder on . ' + + 'React uses the -s suffix in the spelling. Use "%ss" instead.', + revealOrder, + revealOrder.toLowerCase() + ); + break; + } + default: + warning$1( + false, + '"%s" is not a supported revealOrder on . ' + + 'Did you mean "together", "forwards" or "backwards"?', + revealOrder + ); + break; + } + } else { + warning$1( + false, + "%s is not a supported value for revealOrder on . " + + 'Did you mean "together", "forwards" or "backwards"?', + revealOrder ); } } + } +} - if (typeof Component.getDerivedStateFromProps === "function") { - var _componentName2 = getComponentName(Component) || "Unknown"; - - if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2]) { - error( - "%s: Function components do not support getDerivedStateFromProps.", - _componentName2 +function validateTailOptions(tailMode, revealOrder) { + { + if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) { + if (tailMode !== "collapsed" && tailMode !== "hidden") { + didWarnAboutTailOptions[tailMode] = true; + warning$1( + false, + '"%s" is not a supported value for tail on . ' + + 'Did you mean "collapsed" or "hidden"?', + tailMode ); - - didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2] = true; - } - } - - if ( - typeof Component.contextType === "object" && - Component.contextType !== null - ) { - var _componentName3 = getComponentName(Component) || "Unknown"; - - if (!didWarnAboutContextTypeOnFunctionComponent[_componentName3]) { - error( - "%s: Function components do not support contextType.", - _componentName3 + } else if (revealOrder !== "forwards" && revealOrder !== "backwards") { + didWarnAboutTailOptions[tailMode] = true; + warning$1( + false, + ' is only valid if revealOrder is ' + + '"forwards" or "backwards". ' + + 'Did you mean to specify revealOrder="forwards"?', + tailMode ); - - didWarnAboutContextTypeOnFunctionComponent[_componentName3] = true; } } } } -var SUSPENDED_MARKER = { - dehydrated: null, - retryTime: NoWork -}; - -function shouldRemainOnFallback(suspenseContext, current, workInProgress) { - // If the context is telling us that we should show a fallback, and we're not - // already showing content, then we should show the fallback instead. - return ( - hasSuspenseContext(suspenseContext, ForceSuspenseFallback) && - (current === null || current.memoizedState !== null) - ); -} - -function updateSuspenseComponent( - current, - workInProgress, - renderExpirationTime -) { - var mode = workInProgress.mode; - var nextProps = workInProgress.pendingProps; // This is used by DevTools to force a boundary to suspend. - +function validateSuspenseListNestedChild(childSlot, index) { { - if (shouldSuspend(workInProgress)) { - workInProgress.effectTag |= DidCapture; - } - } - - var suspenseContext = suspenseStackCursor.current; - var nextDidTimeout = false; - var didSuspend = (workInProgress.effectTag & DidCapture) !== NoEffect; - - if (didSuspend || shouldRemainOnFallback(suspenseContext, current)) { - // Something in this boundary's subtree already suspended. Switch to - // rendering the fallback children. - nextDidTimeout = true; - workInProgress.effectTag &= ~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 isArray = Array.isArray(childSlot); + var isIterable = !isArray && typeof getIteratorFn(childSlot) === "function"; + if (isArray || isIterable) { + var type = isArray ? "array" : "iterable"; + warning$1( + false, + "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; } } + return true; +} - suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); - pushSuspenseContext(workInProgress, suspenseContext); // This next part is a bit confusing. If the children timeout, we switch to - // showing the fallback children in place of the "primary" children. - // However, we don't want to delete the primary children because then their - // state will be lost (both the React state and the host state, e.g. - // uncontrolled form inputs). Instead we keep them mounted and hide them. - // Both the fallback children AND the primary children are rendered at the - // same time. Once the primary children are un-suspended, we can delete - // the fallback children — don't need to preserve their state. - // - // The two sets of children are siblings in the host environment, but - // semantically, for purposes of reconciliation, they are two separate sets. - // So we store them using two fragment fibers. - // - // However, we want to avoid allocating extra fibers for every placeholder. - // They're only necessary when the children time out, because that's the - // only time when both sets are mounted. - // - // So, the extra fragment fibers are only used if the children time out. - // Otherwise, we render the primary children directly. This requires some - // custom reconciliation logic to preserve the state of the primary - // children. It's essentially a very basic form of re-parenting. - - if (current === null) { - // If we're currently hydrating, try to hydrate this boundary. - // But only if this has a fallback. - if (nextProps.fallback !== undefined); // This is the initial mount. This branch is pretty simple because there's - // no previous state that needs to be preserved. +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 (nextDidTimeout) { - // Mount separate fragments for primary and fallback children. - var nextFallbackChildren = nextProps.fallback; - var primaryChildFragment = createFiberFromFragment( - null, - mode, - NoWork, - null - ); - primaryChildFragment.return = workInProgress; + if (typeof iteratorFn === "function") { + var childrenIterator = iteratorFn.call(children); - if ((workInProgress.mode & BlockingMode) === NoMode) { - // Outside of blocking mode, we commit the effects from the - // partially completed, timed-out tree, too. - var progressedState = workInProgress.memoizedState; - var progressedPrimaryChild = - progressedState !== null - ? workInProgress.child.child - : workInProgress.child; - primaryChildFragment.child = progressedPrimaryChild; - var progressedChild = progressedPrimaryChild; + if (childrenIterator) { + var step = childrenIterator.next(); + var _i = 0; - while (progressedChild !== null) { - progressedChild.return = primaryChildFragment; - progressedChild = progressedChild.sibling; + for (; !step.done; step = childrenIterator.next()) { + if (!validateSuspenseListNestedChild(step.value, _i)) { + return; + } + _i++; + } + } + } else { + warning$1( + false, + 'A single row was passed to a . ' + + "This is not useful since it needs multiple rows. " + + "Did you mean to pass multiple children or an array?", + revealOrder + ); } } + } + } +} - var fallbackChildFragment = createFiberFromFragment( - nextFallbackChildren, - mode, - renderExpirationTime, - null - ); - fallbackChildFragment.return = workInProgress; - primaryChildFragment.sibling = fallbackChildFragment; // Skip the primary children, and continue working on the - // fallback children. +function initSuspenseListRenderState( + workInProgress, + isBackwards, + tail, + lastContentRow, + tailMode, + lastEffectBeforeRendering +) { + var renderState = workInProgress.memoizedState; - workInProgress.memoizedState = SUSPENDED_MARKER; - workInProgress.child = primaryChildFragment; - return fallbackChildFragment; - } else { - // Mount the primary children without an intermediate fragment fiber. - var nextPrimaryChildren = nextProps.children; - workInProgress.memoizedState = null; - return (workInProgress.child = mountChildFibers( + if (renderState === null) { + workInProgress.memoizedState = { + isBackwards: isBackwards, + rendering: null, + last: lastContentRow, + tail: tail, + tailExpiration: 0, + tailMode: tailMode, + lastEffect: lastEffectBeforeRendering + }; + } else { + // We can reuse the existing object from previous renders. + renderState.isBackwards = isBackwards; + renderState.rendering = null; + renderState.last = lastContentRow; + renderState.tail = tail; + renderState.tailExpiration = 0; + 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$$1, + workInProgress, + renderExpirationTime +) { + 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$$1, + workInProgress, + newChildren, + renderExpirationTime + ); + var suspenseContext = suspenseStackCursor.current; + var shouldForceFallback = hasSuspenseContext( + suspenseContext, + ForceSuspenseFallback + ); + if (shouldForceFallback) { + suspenseContext = setShallowSuspenseContext( + suspenseContext, + ForceSuspenseFallback + ); + workInProgress.effectTag |= DidCapture; + } else { + var didSuspendBefore = + current$$1 !== null && (current$$1.effectTag & DidCapture) !== NoEffect; + 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, - null, - nextPrimaryChildren, + workInProgress.child, renderExpirationTime - )); + ); } - } else { - // This is an update. This branch is more complicated because we need to - // ensure the state of the primary children is preserved. - var prevState = current.memoizedState; - if (prevState !== null) { - // wrapped in a fragment fiber. + suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); + } - var currentPrimaryChildFragment = current.child; - var currentFallbackChildFragment = currentPrimaryChildFragment.sibling; + pushSuspenseContext(workInProgress, suspenseContext); - if (nextDidTimeout) { - // Still timed out. Reuse the current primary children by cloning - // its fragment. We're going to skip over these entirely. - var _nextFallbackChildren2 = nextProps.fallback; + if ((workInProgress.mode & BlockingMode) === NoMode) { + // Outside of blocking 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 _primaryChildFragment2 = createWorkInProgress( - currentPrimaryChildFragment, - currentPrimaryChildFragment.pendingProps + 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; + } - _primaryChildFragment2.return = workInProgress; + 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 & BlockingMode) === NoMode) { - // Outside of blocking mode, we commit the effects from the - // partially completed, timed-out tree, too. - var _progressedState = workInProgress.memoizedState; + while (row !== null) { + var currentRow = row.alternate; // New rows can't be content rows. - var _progressedPrimaryChild = - _progressedState !== null - ? workInProgress.child.child - : workInProgress.child; + 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. - if (_progressedPrimaryChild !== currentPrimaryChildFragment.child) { - _primaryChildFragment2.child = _progressedPrimaryChild; - var _progressedChild2 = _progressedPrimaryChild; + initSuspenseListRenderState( + workInProgress, + true, // isBackwards + _tail, + null, // last + tailMode, + workInProgress.lastEffect + ); + break; + } - while (_progressedChild2 !== null) { - _progressedChild2.return = _primaryChildFragment2; - _progressedChild2 = _progressedChild2.sibling; - } - } - } // Because primaryChildFragment is a new fiber that we're inserting as the - // parent of a new tree, we need to set its treeBaseDuration. + case "together": { + initSuspenseListRenderState( + workInProgress, + false, // isBackwards + null, // tail + null, // last + undefined, + workInProgress.lastEffect + ); + break; + } - if (workInProgress.mode & ProfileMode) { - // treeBaseDuration is the sum of all the child tree base durations. - var _treeBaseDuration = 0; - var _hiddenChild = _primaryChildFragment2.child; + default: { + // The default reveal order is the same as not having + // a boundary. + workInProgress.memoizedState = null; + } + } + } + return workInProgress.child; +} - while (_hiddenChild !== null) { - _treeBaseDuration += _hiddenChild.treeBaseDuration; - _hiddenChild = _hiddenChild.sibling; - } +function updatePortalComponent( + current$$1, + workInProgress, + renderExpirationTime +) { + pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); + var nextChildren = workInProgress.pendingProps; + if (current$$1 === 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, + renderExpirationTime + ); + } else { + reconcileChildren( + current$$1, + workInProgress, + nextChildren, + renderExpirationTime + ); + } + return workInProgress.child; +} - _primaryChildFragment2.treeBaseDuration = _treeBaseDuration; - } // Clone the fallback child fragment, too. These we'll continue - // working on. +function updateContextProvider( + current$$1, + workInProgress, + renderExpirationTime +) { + var providerType = workInProgress.type; + var context = providerType._context; + var newProps = workInProgress.pendingProps; + var oldProps = workInProgress.memoizedProps; + var newValue = newProps.value; - var _fallbackChildFragment2 = createWorkInProgress( - currentFallbackChildFragment, - _nextFallbackChildren2 - ); + { + var providerPropTypes = workInProgress.type.propTypes; - _fallbackChildFragment2.return = workInProgress; - _primaryChildFragment2.sibling = _fallbackChildFragment2; - _primaryChildFragment2.childExpirationTime = NoWork; // Skip the primary children, and continue working on the - // fallback children. + if (providerPropTypes) { + checkPropTypes( + providerPropTypes, + newProps, + "prop", + "Context.Provider", + getCurrentFiberStackInDev + ); + } + } - workInProgress.memoizedState = SUSPENDED_MARKER; - workInProgress.child = _primaryChildFragment2; - return _fallbackChildFragment2; - } else { - // No longer suspended. Switch back to showing the primary children, - // and remove the intermediate fragment fiber. - var _nextPrimaryChildren = nextProps.children; - var currentPrimaryChild = currentPrimaryChildFragment.child; - var primaryChild = reconcileChildFibers( + pushProvider(workInProgress, 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$$1, workInProgress, - currentPrimaryChild, - _nextPrimaryChildren, renderExpirationTime - ); // If this render doesn't suspend, we need to delete the fallback - // children. Wait until the complete phase, after we've confirmed the - // fallback is no longer needed. - // TODO: Would it be better to store the fallback fragment on - // the stateNode? - // Continue rendering the children, like we normally do. + ); + } + } else { + // The context value changed. Search for matching consumers and schedule + // them to update. + propagateContextChange( + workInProgress, + context, + changedBits, + renderExpirationTime + ); + } + } - workInProgress.memoizedState = null; - return (workInProgress.child = primaryChild); + var newChildren = newProps.children; + reconcileChildren( + current$$1, + workInProgress, + newChildren, + renderExpirationTime + ); + return workInProgress.child; +} + +var hasWarnedAboutUsingContextAsConsumer = false; + +function updateContextConsumer( + current$$1, + workInProgress, + renderExpirationTime +) { + 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; + warning$1( + false, + "Rendering directly is not supported and will be removed in " + + "a future major release. Did you mean to render instead?" + ); + } } } else { - // The current tree has not already timed out. That means the primary - // children are not wrapped in a fragment fiber. - var _currentPrimaryChild = current.child; + context = context._context; + } + } + var newProps = workInProgress.pendingProps; + var render = newProps.children; - if (nextDidTimeout) { - // Timed out. Wrap the children in a fragment fiber to keep them - // separate from the fallback children. - var _nextFallbackChildren3 = nextProps.fallback; + { + !(typeof render === "function") + ? warningWithoutStack$1( + false, + "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." + ) + : void 0; + } - var _primaryChildFragment3 = createFiberFromFragment( - // It shouldn't matter what the pending props are because we aren't - // going to render this fragment. - null, - mode, - NoWork, - null - ); + prepareToReadContext(workInProgress, renderExpirationTime); + var newValue = readContext(context, newProps.unstable_observedBits); + var newChildren; - _primaryChildFragment3.return = workInProgress; - _primaryChildFragment3.child = _currentPrimaryChild; + { + ReactCurrentOwner$3.current = workInProgress; + setCurrentPhase("render"); + newChildren = render(newValue); + setCurrentPhase(null); + } // React DevTools reads this flag. - if (_currentPrimaryChild !== null) { - _currentPrimaryChild.return = _primaryChildFragment3; - } // Even though we're creating a new fiber, there are no new children, - // because we're reusing an already mounted tree. So we don't need to - // schedule a placement. - // primaryChildFragment.effectTag |= Placement; + workInProgress.effectTag |= PerformedWork; + reconcileChildren( + current$$1, + workInProgress, + newChildren, + renderExpirationTime + ); + return workInProgress.child; +} - if ((workInProgress.mode & BlockingMode) === NoMode) { - // Outside of blocking mode, we commit the effects from the - // partially completed, timed-out tree, too. - var _progressedState2 = workInProgress.memoizedState; +function updateFundamentalComponent$1( + current$$1, + workInProgress, + renderExpirationTime +) { + var fundamentalImpl = workInProgress.type.impl; - var _progressedPrimaryChild2 = - _progressedState2 !== null - ? workInProgress.child.child - : workInProgress.child; + if (fundamentalImpl.reconcileChildren === false) { + return null; + } - _primaryChildFragment3.child = _progressedPrimaryChild2; - var _progressedChild3 = _progressedPrimaryChild2; + var nextProps = workInProgress.pendingProps; + var nextChildren = nextProps.children; + reconcileChildren( + current$$1, + workInProgress, + nextChildren, + renderExpirationTime + ); + return workInProgress.child; +} - while (_progressedChild3 !== null) { - _progressedChild3.return = _primaryChildFragment3; - _progressedChild3 = _progressedChild3.sibling; - } - } // Because primaryChildFragment is a new fiber that we're inserting as the - // parent of a new tree, we need to set its treeBaseDuration. +function updateScopeComponent( + current$$1, + workInProgress, + renderExpirationTime +) { + var nextProps = workInProgress.pendingProps; + var nextChildren = nextProps.children; + reconcileChildren( + current$$1, + workInProgress, + nextChildren, + renderExpirationTime + ); + return workInProgress.child; +} - if (workInProgress.mode & ProfileMode) { - // treeBaseDuration is the sum of all the child tree base durations. - var _treeBaseDuration2 = 0; - var _hiddenChild2 = _primaryChildFragment3.child; +function markWorkInProgressReceivedUpdate() { + didReceiveUpdate = true; +} - while (_hiddenChild2 !== null) { - _treeBaseDuration2 += _hiddenChild2.treeBaseDuration; - _hiddenChild2 = _hiddenChild2.sibling; - } +function bailoutOnAlreadyFinishedWork( + current$$1, + workInProgress, + renderExpirationTime +) { + cancelWorkTimer(workInProgress); - _primaryChildFragment3.treeBaseDuration = _treeBaseDuration2; - } // Create a fragment from the fallback children, too. + if (current$$1 !== null) { + // Reuse previous dependencies + workInProgress.dependencies = current$$1.dependencies; + } - var _fallbackChildFragment3 = createFiberFromFragment( - _nextFallbackChildren3, - mode, - renderExpirationTime, - null - ); + if (enableProfilerTimer) { + // Don't update "base" render times for bailouts. + stopProfilerTimerIfRunning(workInProgress); + } - _fallbackChildFragment3.return = workInProgress; - _primaryChildFragment3.sibling = _fallbackChildFragment3; - _fallbackChildFragment3.effectTag |= Placement; - _primaryChildFragment3.childExpirationTime = NoWork; // Skip the primary children, and continue working on the - // fallback children. + var updateExpirationTime = workInProgress.expirationTime; - workInProgress.memoizedState = SUSPENDED_MARKER; - workInProgress.child = _primaryChildFragment3; - return _fallbackChildFragment3; - } else { - // Still haven't timed out. Continue rendering the children, like we - // normally do. - workInProgress.memoizedState = null; - var _nextPrimaryChildren2 = nextProps.children; - return (workInProgress.child = reconcileChildFibers( - workInProgress, - _currentPrimaryChild, - _nextPrimaryChildren2, - renderExpirationTime - )); - } - } + if (updateExpirationTime !== NoWork) { + markUnprocessedUpdateTime(updateExpirationTime); + } // Check if the children have any pending work. + + var childExpirationTime = workInProgress.childExpirationTime; + + if (childExpirationTime < renderExpirationTime) { + // 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$$1, workInProgress); + return workInProgress.child; } } -function scheduleWorkOnFiber(fiber, renderExpirationTime) { - if (fiber.expirationTime < renderExpirationTime) { - fiber.expirationTime = renderExpirationTime; - } +function remountFiber(current$$1, oldWorkInProgress, newWorkInProgress) { + { + var returnFiber = oldWorkInProgress.return; - var alternate = fiber.alternate; + if (returnFiber === null) { + throw new Error("Cannot swap the root fiber."); + } // Disconnect from the old current. + // It will get deleted. - if (alternate !== null && alternate.expirationTime < renderExpirationTime) { - alternate.expirationTime = renderExpirationTime; - } + current$$1.alternate = null; + oldWorkInProgress.alternate = null; // Connect to the new tree. - scheduleWorkOnParentPath(fiber.return, renderExpirationTime); -} + newWorkInProgress.index = oldWorkInProgress.index; + newWorkInProgress.sibling = oldWorkInProgress.sibling; + newWorkInProgress.return = oldWorkInProgress.return; + newWorkInProgress.ref = oldWorkInProgress.ref; // Replace the child/sibling pointers above it. -function propagateSuspenseContextChange( - workInProgress, - firstChild, - renderExpirationTime -) { - // 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 (oldWorkInProgress === returnFiber.child) { + returnFiber.child = newWorkInProgress; + } else { + var prevSibling = returnFiber.child; - while (node !== null) { - if (node.tag === SuspenseComponent) { - var state = node.memoizedState; + if (prevSibling === null) { + throw new Error("Expected parent to have a child."); + } - if (state !== null) { - scheduleWorkOnFiber(node, renderExpirationTime); + while (prevSibling.sibling !== oldWorkInProgress) { + prevSibling = prevSibling.sibling; + + if (prevSibling === null) { + throw new Error("Expected to find the previous sibling."); + } } - } 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, renderExpirationTime); - } 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. + + var last = returnFiber.lastEffect; + + if (last !== null) { + last.nextEffect = current$$1; + returnFiber.lastEffect = current$$1; + } else { + returnFiber.firstEffect = returnFiber.lastEffect = current$$1; } - if (node === workInProgress) { - return; + current$$1.nextEffect = null; + current$$1.effectTag = Deletion; + newWorkInProgress.effectTag |= Placement; // Restart work from the new fiber. + + return newWorkInProgress; + } +} + +function beginWork$1(current$$1, workInProgress, renderExpirationTime) { + var updateExpirationTime = workInProgress.expirationTime; + + { + if (workInProgress._debugNeedsRemount && current$$1 !== null) { + // This will restart the begin phase with a new fiber. + return remountFiber( + current$$1, + workInProgress, + createFiberFromTypeAndProps( + workInProgress.type, + workInProgress.key, + workInProgress.pendingProps, + workInProgress._debugOwner || null, + workInProgress.mode, + workInProgress.expirationTime + ) + ); } + } + + if (current$$1 !== null) { + var oldProps = current$$1.memoizedProps; + var newProps = workInProgress.pendingProps; + + if ( + oldProps !== newProps || + hasContextChanged() || // Force a re-render if the implementation changed due to hot reload: + workInProgress.type !== current$$1.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 (updateExpirationTime < renderExpirationTime) { + 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 (node.sibling === null) { - if (node.return === null || node.return === workInProgress) { - return; - } + switch (workInProgress.tag) { + case HostRoot: + pushHostRootContext(workInProgress); + resetHydrationState(); + break; - node = node.return; - } + case HostComponent: + pushHostContext(workInProgress); - node.sibling.return = node.return; - node = node.sibling; - } -} + if ( + workInProgress.mode & ConcurrentMode && + renderExpirationTime !== Never && + shouldDeprioritizeSubtree(workInProgress.type, newProps) + ) { + if (enableSchedulerTracing) { + markSpawnedWork(Never); + } // Schedule this fiber to re-render at offscreen priority. Then bailout. -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; + workInProgress.expirationTime = workInProgress.childExpirationTime = Never; + return null; + } - while (row !== null) { - var currentRow = row.alternate; // New rows can't be content rows. + break; - if (currentRow !== null && findFirstSuspended(currentRow) === null) { - lastContentRow = row; - } + case ClassComponent: { + var Component = workInProgress.type; - row = row.sibling; - } + if (isContextProvider(Component)) { + pushContextProvider(workInProgress); + } - return lastContentRow; -} + break; + } -function validateRevealOrder(revealOrder) { - { - if ( - revealOrder !== undefined && - revealOrder !== "forwards" && - revealOrder !== "backwards" && - revealOrder !== "together" && - !didWarnAboutRevealOrder[revealOrder] - ) { - didWarnAboutRevealOrder[revealOrder] = true; + case HostPortal: + pushHostContainer( + workInProgress, + workInProgress.stateNode.containerInfo + ); + break; + case ContextProvider: { + var newValue = workInProgress.memoizedProps.value; + pushProvider(workInProgress, newValue); + break; + } - if (typeof revealOrder === "string") { - switch (revealOrder.toLowerCase()) { - case "together": - case "forwards": - case "backwards": { - error( - '"%s" is not a valid value for revealOrder on . ' + - 'Use lowercase "%s" instead.', - revealOrder, - revealOrder.toLowerCase() - ); + case Profiler: + if (enableProfilerTimer) { + // Profiler should only call onRender when one of its descendants actually rendered. + var hasChildWork = + workInProgress.childExpirationTime >= renderExpirationTime; - break; + if (hasChildWork) { + workInProgress.effectTag |= Update; + } } - 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() - ); + break; - break; - } + case SuspenseComponent: { + var state = workInProgress.memoizedState; - default: - error( - '"%s" is not a supported revealOrder on . ' + - 'Did you mean "together", "forwards" or "backwards"?', - revealOrder + if (state !== null) { + if (enableSuspenseServerRenderer) { + if (state.dehydrated !== null) { + pushSuspenseContext( + workInProgress, + setDefaultShallowSuspenseContext(suspenseStackCursor.current) + ); // We know that this component will suspend again because if it has + // been unsuspended it has committed as a resolved Suspense component. + // If it needs to be retried, it should have work scheduled on it. + + workInProgress.effectTag |= DidCapture; + break; + } + } // If this boundary is currently timed out, we need to decide + // 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 primaryChildExpirationTime = + primaryChildFragment.childExpirationTime; + + if ( + primaryChildExpirationTime !== NoWork && + primaryChildExpirationTime >= renderExpirationTime + ) { + // The primary children have pending work. Use the normal path + // to attempt to render the primary children again. + return updateSuspenseComponent( + current$$1, + workInProgress, + renderExpirationTime + ); + } else { + pushSuspenseContext( + workInProgress, + setDefaultShallowSuspenseContext(suspenseStackCursor.current) + ); // The primary children do not have pending work with sufficient + // priority. Bailout. + + var child = bailoutOnAlreadyFinishedWork( + current$$1, + workInProgress, + renderExpirationTime + ); + 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; + 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; - - 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 SuspenseListComponent: { + var didSuspendBefore = + (current$$1.effectTag & DidCapture) !== NoEffect; - error( - ' is only valid if revealOrder is ' + - '"forwards" or "backwards". ' + - 'Did you mean to specify revealOrder="forwards"?', - tailMode - ); - } - } - } -} + var _hasChildWork = + workInProgress.childExpirationTime >= renderExpirationTime; -function validateSuspenseListNestedChild(childSlot, index) { - { - var isArray = Array.isArray(childSlot); - var isIterable = !isArray && typeof getIteratorFn(childSlot) === "function"; + 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$$1, + workInProgress, + renderExpirationTime + ); + } // 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 (isArray || isIterable) { - var type = isArray ? "array" : "iterable"; + workInProgress.effectTag |= 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. - error( - "A nested %s was passed to row #%s in . Wrap it in " + - "an additional SuspenseList to configure its revealOrder: " + - " ... " + - "{%s} ... " + - "", - type, - index, - type - ); + var renderState = workInProgress.memoizedState; - return false; - } - } + 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; + } - return true; -} + pushSuspenseContext(workInProgress, suspenseStackCursor.current); -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; + 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 { - var iteratorFn = getIteratorFn(children); + } + return bailoutOnAlreadyFinishedWork( + current$$1, + workInProgress, + renderExpirationTime + ); + } 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 the expiration time. - if (typeof iteratorFn === "function") { - var childrenIterator = iteratorFn.call(children); + workInProgress.expirationTime = NoWork; - if (childrenIterator) { - var step = childrenIterator.next(); - var _i = 0; + switch (workInProgress.tag) { + case IndeterminateComponent: { + return mountIndeterminateComponent( + current$$1, + workInProgress, + workInProgress.type, + renderExpirationTime + ); + } + case LazyComponent: { + var elementType = workInProgress.elementType; + return mountLazyComponent( + current$$1, + workInProgress, + elementType, + updateExpirationTime, + renderExpirationTime + ); + } + case FunctionComponent: { + var _Component = workInProgress.type; + var unresolvedProps = workInProgress.pendingProps; + var resolvedProps = + workInProgress.elementType === _Component + ? unresolvedProps + : resolveDefaultProps(_Component, unresolvedProps); + return updateFunctionComponent( + current$$1, + workInProgress, + _Component, + resolvedProps, + renderExpirationTime + ); + } - for (; !step.done; step = childrenIterator.next()) { - if (!validateSuspenseListNestedChild(step.value, _i)) { - return; - } + case ClassComponent: { + var _Component2 = workInProgress.type; + var _unresolvedProps = workInProgress.pendingProps; - _i++; - } - } - } else { - error( - 'A single row was passed to a . ' + - "This is not useful since it needs multiple rows. " + - "Did you mean to pass multiple children or an array?", - revealOrder - ); - } - } + var _resolvedProps = + workInProgress.elementType === _Component2 + ? _unresolvedProps + : resolveDefaultProps(_Component2, _unresolvedProps); + return updateClassComponent( + current$$1, + workInProgress, + _Component2, + _resolvedProps, + renderExpirationTime + ); } - } -} -function initSuspenseListRenderState( - workInProgress, - isBackwards, - tail, - lastContentRow, - tailMode, - lastEffectBeforeRendering -) { - var renderState = workInProgress.memoizedState; + case HostRoot: + return updateHostRoot(current$$1, workInProgress, renderExpirationTime); - if (renderState === null) { - workInProgress.memoizedState = { - isBackwards: isBackwards, - rendering: null, - renderingStartTime: 0, - last: lastContentRow, - tail: tail, - tailExpiration: 0, - 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.tailExpiration = 0; - 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 HostComponent: + return updateHostComponent( + current$$1, + workInProgress, + renderExpirationTime + ); -function updateSuspenseListComponent( - current, - workInProgress, - renderExpirationTime -) { - 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, renderExpirationTime); - var suspenseContext = suspenseStackCursor.current; - var shouldForceFallback = hasSuspenseContext( - suspenseContext, - ForceSuspenseFallback - ); + case HostText: + return updateHostText(current$$1, workInProgress); - if (shouldForceFallback) { - suspenseContext = setShallowSuspenseContext( - suspenseContext, - ForceSuspenseFallback - ); - workInProgress.effectTag |= DidCapture; - } else { - var didSuspendBefore = - current !== null && (current.effectTag & DidCapture) !== NoEffect; + case SuspenseComponent: + return updateSuspenseComponent( + current$$1, + workInProgress, + renderExpirationTime + ); + case HostPortal: + return updatePortalComponent( + current$$1, + workInProgress, + renderExpirationTime + ); - 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( + case ForwardRef: { + var type = workInProgress.type; + var _unresolvedProps2 = workInProgress.pendingProps; + + var _resolvedProps2 = + workInProgress.elementType === type + ? _unresolvedProps2 + : resolveDefaultProps(type, _unresolvedProps2); + return updateForwardRef( + current$$1, workInProgress, - workInProgress.child, + type, + _resolvedProps2, renderExpirationTime ); } - suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); - } + case Fragment: + return updateFragment(current$$1, workInProgress, renderExpirationTime); - pushSuspenseContext(workInProgress, suspenseContext); + case Mode: + return updateMode(current$$1, workInProgress, renderExpirationTime); - if ((workInProgress.mode & BlockingMode) === NoMode) { - // Outside of blocking 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 Profiler: + return updateProfiler(current$$1, workInProgress, renderExpirationTime); - 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 ContextProvider: + return updateContextProvider( + current$$1, + workInProgress, + renderExpirationTime + ); + case ContextConsumer: + return updateContextConsumer( + current$$1, + workInProgress, + renderExpirationTime + ); - initSuspenseListRenderState( - workInProgress, - false, // isBackwards - tail, - lastContentRow, - tailMode, - workInProgress.lastEffect - ); - break; - } + case MemoComponent: { + var _type2 = workInProgress.type; + var _unresolvedProps3 = workInProgress.pendingProps; // Resolve outer props first, then resolve inner props. - 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 _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3); - while (row !== null) { - var currentRow = row.alternate; // New rows can't be content rows. + { + if (workInProgress.type !== workInProgress.elementType) { + var outerPropTypes = _type2.propTypes; - if (currentRow !== null && findFirstSuspended(currentRow) === null) { - // This is the beginning of the main content. - workInProgress.child = row; - break; + if (outerPropTypes) { + checkPropTypes( + outerPropTypes, + _resolvedProps3, // Resolved for outer only + "prop", + getComponentName(_type2), + getCurrentFiberStackInDev + ); } + } + } + _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3); + return updateMemoComponent( + current$$1, + workInProgress, + _type2, + _resolvedProps3, + updateExpirationTime, + renderExpirationTime + ); + } + case SimpleMemoComponent: { + return updateSimpleMemoComponent( + current$$1, + workInProgress, + workInProgress.type, + workInProgress.pendingProps, + updateExpirationTime, + renderExpirationTime + ); + } - 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 IncompleteClassComponent: { + var _Component3 = workInProgress.type; + var _unresolvedProps4 = workInProgress.pendingProps; - initSuspenseListRenderState( + var _resolvedProps4 = + workInProgress.elementType === _Component3 + ? _unresolvedProps4 + : resolveDefaultProps(_Component3, _unresolvedProps4); + return mountIncompleteClassComponent( + current$$1, + workInProgress, + _Component3, + _resolvedProps4, + renderExpirationTime + ); + } + case SuspenseListComponent: { + return updateSuspenseListComponent( + current$$1, + workInProgress, + renderExpirationTime + ); + } + case FundamentalComponent: { + if (enableFundamentalAPI) { + return updateFundamentalComponent$1( + current$$1, workInProgress, - true, // isBackwards - _tail, - null, // last - tailMode, - workInProgress.lastEffect + renderExpirationTime ); - break; } - case "together": { - initSuspenseListRenderState( + break; + } + + case ScopeComponent: { + if (enableScopeAPI) { + return updateScopeComponent( + current$$1, workInProgress, - false, // isBackwards - null, // tail - null, // last - undefined, - workInProgress.lastEffect + renderExpirationTime ); - break; } - default: { - // The default reveal order is the same as not having - // a boundary. - workInProgress.memoizedState = null; - } + break; } } - return 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." + ); + } } -function updatePortalComponent(current, workInProgress, renderExpirationTime) { - pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); - var nextChildren = workInProgress.pendingProps; +function createFundamentalStateInstance(currentFiber, props, impl, state) { + return { + currentFiber: currentFiber, + impl: impl, + instance: null, + prevProps: null, + props: props, + state: state + }; +} - 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, - renderExpirationTime - ); - } else { - reconcileChildren( - current, - workInProgress, - nextChildren, - renderExpirationTime - ); - } +function isFiberSuspenseAndTimedOut(fiber) { + return fiber.tag === SuspenseComponent && fiber.memoizedState !== null; +} - return workInProgress.child; +function getSuspenseFallbackChild(fiber) { + return fiber.child.sibling.child; } -function updateContextProvider(current, workInProgress, renderExpirationTime) { - var providerType = workInProgress.type; - var context = providerType._context; - var newProps = workInProgress.pendingProps; - var oldProps = workInProgress.memoizedProps; - var newValue = newProps.value; +var emptyObject$2 = {}; - { - var providerPropTypes = workInProgress.type.propTypes; +function collectScopedNodes(node, fn, scopedNodes) { + if (enableScopeAPI) { + if (node.tag === HostComponent) { + var _type = node.type, + memoizedProps = node.memoizedProps, + stateNode = node.stateNode; - if (providerPropTypes) { - checkPropTypes(providerPropTypes, newProps, "prop", "Context.Provider"); + var _instance = getPublicInstance(stateNode); + + if ( + _instance !== null && + fn(_type, memoizedProps || emptyObject$2, _instance) === true + ) { + scopedNodes.push(_instance); + } } - } - pushProvider(workInProgress, newValue); + var child = node.child; - if (oldProps !== null) { - var oldValue = oldProps.value; - var changedBits = calculateChangedBits(context, newValue, oldValue); + if (isFiberSuspenseAndTimedOut(node)) { + child = getSuspenseFallbackChild(node); + } - if (changedBits === 0) { - // No change. Bailout early if children are the same. - if (oldProps.children === newProps.children && !hasContextChanged()) { - return bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderExpirationTime - ); - } - } else { - // The context value changed. Search for matching consumers and schedule - // them to update. - propagateContextChange( - workInProgress, - context, - changedBits, - renderExpirationTime - ); + if (child !== null) { + collectScopedNodesFromChildren(child, fn, scopedNodes); } } - - var newChildren = newProps.children; - reconcileChildren(current, workInProgress, newChildren, renderExpirationTime); - return workInProgress.child; } -var hasWarnedAboutUsingContextAsConsumer = false; - -function updateContextConsumer(current, workInProgress, renderExpirationTime) { - 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 collectFirstScopedNode(node, fn) { + if (enableScopeAPI) { + if (node.tag === HostComponent) { + var _type2 = node.type, + memoizedProps = node.memoizedProps, + stateNode = node.stateNode; - { - 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 _instance2 = getPublicInstance(stateNode); - error( - "Rendering directly is not supported and will be removed in " + - "a future major release. Did you mean to render instead?" - ); - } + if ( + _instance2 !== null && + fn(_type2, memoizedProps, _instance2) === true + ) { + return _instance2; } - } else { - context = context._context; } - } - var newProps = workInProgress.pendingProps; - var render = newProps.children; + var child = node.child; - { - 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 (isFiberSuspenseAndTimedOut(node)) { + child = getSuspenseFallbackChild(node); + } + + if (child !== null) { + return collectFirstScopedNodeFromChildren(child, fn); } } - prepareToReadContext(workInProgress, renderExpirationTime); - var newValue = readContext(context, newProps.unstable_observedBits); - var newChildren; + return null; +} - { - ReactCurrentOwner$1.current = workInProgress; - setIsRendering(true); - newChildren = render(newValue); - setIsRendering(false); - } // React DevTools reads this flag. +function collectScopedNodesFromChildren(startingChild, fn, scopedNodes) { + var child = startingChild; - workInProgress.effectTag |= PerformedWork; - reconcileChildren(current, workInProgress, newChildren, renderExpirationTime); - return workInProgress.child; + while (child !== null) { + collectScopedNodes(child, fn, scopedNodes); + child = child.sibling; + } } -function markWorkInProgressReceivedUpdate() { - didReceiveUpdate = true; -} +function collectFirstScopedNodeFromChildren(startingChild, fn) { + var child = startingChild; -function bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderExpirationTime -) { - cancelWorkTimer(workInProgress); + while (child !== null) { + var scopedNode = collectFirstScopedNode(child, fn); - if (current !== null) { - // Reuse previous dependencies - workInProgress.dependencies = current.dependencies; - } + if (scopedNode !== null) { + return scopedNode; + } - { - // Don't update "base" render times for bailouts. - stopProfilerTimerIfRunning(); + child = child.sibling; } - var updateExpirationTime = workInProgress.expirationTime; + return null; +} - if (updateExpirationTime !== NoWork) { - markUnprocessedUpdateTime(updateExpirationTime); - } // Check if the children have any pending work. +function collectNearestScopeMethods(node, scope, childrenScopes) { + if (isValidScopeNode(node, scope)) { + childrenScopes.push(node.stateNode.methods); + } else { + var child = node.child; - var childExpirationTime = workInProgress.childExpirationTime; + if (isFiberSuspenseAndTimedOut(node)) { + child = getSuspenseFallbackChild(node); + } - if (childExpirationTime < renderExpirationTime) { - // 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 (child !== null) { + collectNearestChildScopeMethods(child, scope, childrenScopes); + } } } -function remountFiber(current, oldWorkInProgress, newWorkInProgress) { - { - var returnFiber = oldWorkInProgress.return; +function collectNearestChildScopeMethods(startingChild, scope, childrenScopes) { + var child = startingChild; - if (returnFiber === null) { - throw new Error("Cannot swap the root fiber."); - } // Disconnect from the old current. - // It will get deleted. + while (child !== null) { + collectNearestScopeMethods(child, scope, childrenScopes); + child = child.sibling; + } +} - current.alternate = null; - oldWorkInProgress.alternate = null; // Connect to the new tree. +function isValidScopeNode(node, scope) { + return ( + node.tag === ScopeComponent && + node.type === scope && + node.stateNode !== null + ); +} - newWorkInProgress.index = oldWorkInProgress.index; - newWorkInProgress.sibling = oldWorkInProgress.sibling; - newWorkInProgress.return = oldWorkInProgress.return; - newWorkInProgress.ref = oldWorkInProgress.ref; // Replace the child/sibling pointers above it. +function createScopeMethods(scope, instance) { + return { + getChildren: function() { + var currentFiber = instance.fiber; + var child = currentFiber.child; + var childrenScopes = []; - if (oldWorkInProgress === returnFiber.child) { - returnFiber.child = newWorkInProgress; - } else { - var prevSibling = returnFiber.child; + if (child !== null) { + collectNearestChildScopeMethods(child, scope, childrenScopes); + } - if (prevSibling === null) { - throw new Error("Expected parent to have a child."); + return childrenScopes.length === 0 ? null : childrenScopes; + }, + getChildrenFromRoot: function() { + var currentFiber = instance.fiber; + var node = currentFiber; + + while (node !== null) { + var parent = node.return; + + if (parent === null) { + break; + } + + node = parent; + + if (node.tag === ScopeComponent && node.type === scope) { + break; + } } - while (prevSibling.sibling !== oldWorkInProgress) { - prevSibling = prevSibling.sibling; + var childrenScopes = []; + collectNearestChildScopeMethods(node.child, scope, childrenScopes); + return childrenScopes.length === 0 ? null : childrenScopes; + }, + getParent: function() { + var node = instance.fiber.return; - if (prevSibling === null) { - throw new Error("Expected to find the previous sibling."); + while (node !== null) { + if (node.tag === ScopeComponent && node.type === scope) { + return node.stateNode.methods; } + + 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. + return null; + }, + getProps: function() { + var currentFiber = instance.fiber; + return currentFiber.memoizedProps; + }, + queryAllNodes: function(fn) { + var currentFiber = instance.fiber; + var child = currentFiber.child; + var scopedNodes = []; - var last = returnFiber.lastEffect; + if (child !== null) { + collectScopedNodesFromChildren(child, fn, scopedNodes); + } - if (last !== null) { - last.nextEffect = current; - returnFiber.lastEffect = current; - } else { - returnFiber.firstEffect = returnFiber.lastEffect = current; - } + return scopedNodes.length === 0 ? null : scopedNodes; + }, + queryFirstNode: function(fn) { + var currentFiber = instance.fiber; + var child = currentFiber.child; - current.nextEffect = null; - current.effectTag = Deletion; - newWorkInProgress.effectTag |= Placement; // Restart work from the new fiber. + if (child !== null) { + return collectFirstScopedNodeFromChildren(child, fn); + } - return newWorkInProgress; - } -} + return null; + }, + containsNode: function(node) { + var fiber = getInstanceFromNode$1(node); -function beginWork(current, workInProgress, renderExpirationTime) { - var updateExpirationTime = workInProgress.expirationTime; + while (fiber !== null) { + if ( + fiber.tag === ScopeComponent && + fiber.type === scope && + fiber.stateNode === instance + ) { + return true; + } - { - 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.expirationTime - ) - ); - } - } + fiber = fiber.return; + } - if (current !== null) { - var oldProps = current.memoizedProps; - var newProps = workInProgress.pendingProps; + return false; + } + }; +} - 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 (updateExpirationTime < renderExpirationTime) { - 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 markUpdate(workInProgress) { + // Tag the fiber with an update effect. This turns a Placement into + // a PlacementAndUpdate. + workInProgress.effectTag |= Update; +} - switch (workInProgress.tag) { - case HostRoot: - pushHostRootContext(workInProgress); - break; +function markRef$1(workInProgress) { + workInProgress.effectTag |= Ref; +} - case HostComponent: - pushHostContext(workInProgress); +var appendAllChildren; +var updateHostContainer; +var updateHostComponent$1; +var updateHostText$1; - if ( - workInProgress.mode & ConcurrentMode && - renderExpirationTime !== Never && - shouldDeprioritizeSubtree(workInProgress.type) - ) { - { - markSpawnedWork(Never); - } // Schedule this fiber to re-render at offscreen priority. Then bailout. +if (supportsMutation) { + // 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 (enableFundamentalAPI && node.tag === FundamentalComponent) { + appendInitialChild(parent, node.stateNode.instance); + } else if (node.tag === HostPortal) { + // If we have a portal child, then we don't want to traverse + // down its children. Instead, we'll get insertions from each child in + // the portal directly. + } else if (node.child !== null) { + node.child.return = node; + node = node.child; + continue; + } - workInProgress.expirationTime = workInProgress.childExpirationTime = Never; - return null; - } + if (node === workInProgress) { + return; + } - break; + while (node.sibling === null) { + if (node.return === null || node.return === workInProgress) { + return; + } - case ClassComponent: { - var Component = workInProgress.type; + node = node.return; + } - if (isContextProvider(Component)) { - pushContextProvider(workInProgress); - } + node.sibling.return = node.return; + node = node.sibling; + } + }; - break; - } + updateHostContainer = function(workInProgress) { + // Noop + }; + 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 (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. - case HostPortal: - pushHostContainer( - workInProgress, - workInProgress.stateNode.containerInfo - ); - break; + 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`. - case ContextProvider: { - var newValue = workInProgress.memoizedProps.value; - pushProvider(workInProgress, newValue); - break; - } + var updatePayload = prepareUpdate( + instance, + type, + oldProps, + newProps, + rootContainerInstance, + currentHostContext + ); // TODO: Type this specific to this type of component. - case Profiler: - { - // Profiler should only call onRender when one of its descendants actually rendered. - var hasChildWork = - workInProgress.childExpirationTime >= renderExpirationTime; + 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 (hasChildWork) { - workInProgress.effectTag |= 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 (updatePayload) { + markUpdate(workInProgress); + } + }; + 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); + } + }; +} else if (supportsPersistence) { + // 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 + branches: 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, type, props, node); + } - var stateNode = workInProgress.stateNode; - stateNode.effectDuration = 0; - stateNode.passiveEffectDuration = 0; - } + appendInitialChild(parent, instance); + } else if (node.tag === HostText) { + var _instance = node.stateNode; - break; + if (needsVisibilityToggle && isHidden) { + // This child is inside a timed out tree. Hide it. + var text = node.memoizedProps; + _instance = cloneHiddenTextInstance(_instance, text, node); + } - case SuspenseComponent: { - var state = workInProgress.memoizedState; + appendInitialChild(parent, _instance); + } else if (enableFundamentalAPI && node.tag === FundamentalComponent) { + var _instance2 = node.stateNode.instance; - 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 (needsVisibilityToggle && isHidden) { + // This child is inside a timed out tree. Hide it. + var _props = node.memoizedProps; + var _type = node.type; + _instance2 = cloneHiddenInstance(_instance2, _type, _props, node); + } + appendInitialChild(parent, _instance2); + } else if (node.tag === HostPortal) { + // If we have a portal child, then we don't want to traverse + // down its children. Instead, we'll get insertions from each child in + // the portal directly. + } else if (node.tag === SuspenseComponent) { + if ((node.effectTag & Update) !== NoEffect) { + // Need to toggle the visibility of the primary children. + var newIsHidden = node.memoizedState !== null; - var primaryChildFragment = workInProgress.child; - var primaryChildExpirationTime = - primaryChildFragment.childExpirationTime; + if (newIsHidden) { + var primaryChildParent = node.child; - if ( - primaryChildExpirationTime !== NoWork && - primaryChildExpirationTime >= renderExpirationTime - ) { - // The primary children have pending work. Use the normal path - // to attempt to render the primary children again. - return updateSuspenseComponent( - current, - workInProgress, - renderExpirationTime - ); - } else { - pushSuspenseContext( - workInProgress, - setDefaultShallowSuspenseContext(suspenseStackCursor.current) - ); // The primary children do not have pending work with sufficient - // priority. Bailout. + if (primaryChildParent !== null) { + if (primaryChildParent.child !== null) { + primaryChildParent.child.return = primaryChildParent; + appendAllChildren( + parent, + primaryChildParent, + true, + newIsHidden + ); + } - var child = bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderExpirationTime - ); + var fallbackChildParent = primaryChildParent.sibling; - 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; + if (fallbackChildParent !== null) { + fallbackChildParent.return = node; + node = fallbackChildParent; + continue; } } - } else { - pushSuspenseContext( - workInProgress, - setDefaultShallowSuspenseContext(suspenseStackCursor.current) - ); } - - 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 SuspenseListComponent: { - var didSuspendBefore = (current.effectTag & DidCapture) !== NoEffect; + node = node; - var _hasChildWork = - workInProgress.childExpirationTime >= renderExpirationTime; + if (node === workInProgress) { + return; + } - 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, - renderExpirationTime - ); - } // 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 (node.sibling === null) { + if (node.return === null || node.return === workInProgress) { + return; + } - workInProgress.effectTag |= 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. + node = node.return; + } - var renderState = workInProgress.memoizedState; + node.sibling.return = node.return; + node = node.sibling; + } + }; // An unfortunate fork of appendAllChildren because we have two different parent types. - 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; - } + 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; + while (node !== null) { + // eslint-disable-next-line no-labels + branches: 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, type, props, node); + } - pushSuspenseContext(workInProgress, suspenseStackCursor.current); + appendChildToContainerChildSet(containerChildSet, instance); + } else if (node.tag === HostText) { + var _instance3 = node.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; - } + if (needsVisibilityToggle && isHidden) { + // This child is inside a timed out tree. Hide it. + var text = node.memoizedProps; + _instance3 = cloneHiddenTextInstance(_instance3, text, node); } - } - return bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderExpirationTime - ); - } 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. + appendChildToContainerChildSet(containerChildSet, _instance3); + } else if (enableFundamentalAPI && node.tag === FundamentalComponent) { + var _instance4 = node.stateNode.instance; - workInProgress.expirationTime = NoWork; + if (needsVisibilityToggle && isHidden) { + // This child is inside a timed out tree. Hide it. + var _props2 = node.memoizedProps; + var _type2 = node.type; + _instance4 = cloneHiddenInstance(_instance4, _type2, _props2, node); + } + appendChildToContainerChildSet(containerChildSet, _instance4); + } else if (node.tag === HostPortal) { + // If we have a portal child, then we don't want to traverse + // down its children. Instead, we'll get insertions from each child in + // the portal directly. + } else if (node.tag === SuspenseComponent) { + if ((node.effectTag & Update) !== NoEffect) { + // Need to toggle the visibility of the primary children. + var newIsHidden = node.memoizedState !== null; - switch (workInProgress.tag) { - case IndeterminateComponent: { - return mountIndeterminateComponent( - current, - workInProgress, - workInProgress.type, - renderExpirationTime - ); - } + if (newIsHidden) { + var primaryChildParent = node.child; - case LazyComponent: { - var elementType = workInProgress.elementType; - return mountLazyComponent( - current, - workInProgress, - elementType, - updateExpirationTime, - renderExpirationTime - ); - } + if (primaryChildParent !== null) { + if (primaryChildParent.child !== null) { + primaryChildParent.child.return = primaryChildParent; + appendAllChildrenToContainer( + containerChildSet, + primaryChildParent, + true, + newIsHidden + ); + } - 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, - renderExpirationTime - ); - } + var fallbackChildParent = primaryChildParent.sibling; - case ClassComponent: { - var _Component2 = workInProgress.type; - var _unresolvedProps = workInProgress.pendingProps; + if (fallbackChildParent !== null) { + fallbackChildParent.return = node; + node = fallbackChildParent; + continue; + } + } + } + } + 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 _resolvedProps = - workInProgress.elementType === _Component2 - ? _unresolvedProps - : resolveDefaultProps(_Component2, _unresolvedProps); + node = node; - return updateClassComponent( - current, - workInProgress, - _Component2, - _resolvedProps, - renderExpirationTime - ); + if (node === workInProgress) { + return; + } + + while (node.sibling === null) { + if (node.return === null || node.return === workInProgress) { + return; + } + + node = node.return; + } + + node.sibling.return = node.return; + node = node.sibling; } + }; - case HostRoot: - return updateHostRoot(current, workInProgress, renderExpirationTime); + updateHostContainer = function(workInProgress) { + var portalOrRoot = workInProgress.stateNode; + var childrenUnchanged = workInProgress.firstEffect === null; - case HostComponent: - return updateHostComponent(current, workInProgress, renderExpirationTime); + if (childrenUnchanged) { + // No changes, just reuse the existing instance. + } else { + var container = portalOrRoot.containerInfo; + var newChildSet = createContainerChildSet(container); // If children might have changed, we have to add them all to the set. - case HostText: - return updateHostText(); + appendAllChildrenToContainer(newChildSet, workInProgress, false, false); + portalOrRoot.pendingChildren = newChildSet; // Schedule an update on the container to swap out the container. - case SuspenseComponent: - return updateSuspenseComponent( - current, - workInProgress, - renderExpirationTime - ); + markUpdate(workInProgress); + finalizeContainerChildren(container, newChildSet); + } + }; + 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. - case HostPortal: - return updatePortalComponent( - current, - workInProgress, - renderExpirationTime - ); + var childrenUnchanged = workInProgress.firstEffect === null; - case ForwardRef: { - var type = workInProgress.type; - var _unresolvedProps2 = workInProgress.pendingProps; + if (childrenUnchanged && oldProps === newProps) { + // No changes, just reuse the existing instance. + // Note that this might release a previous clone. + workInProgress.stateNode = currentInstance; + return; + } - var _resolvedProps2 = - workInProgress.elementType === type - ? _unresolvedProps2 - : resolveDefaultProps(type, _unresolvedProps2); + var recyclableInstance = workInProgress.stateNode; + var currentHostContext = getHostContext(); + var updatePayload = null; - return updateForwardRef( - current, - workInProgress, + if (oldProps !== newProps) { + updatePayload = prepareUpdate( + recyclableInstance, type, - _resolvedProps2, - renderExpirationTime + oldProps, + newProps, + rootContainerInstance, + currentHostContext ); } + if (childrenUnchanged && updatePayload === null) { + // No changes, just reuse the existing instance. + // Note that this might release a previous clone. + workInProgress.stateNode = currentInstance; + return; + } + var newInstance = cloneInstance( + currentInstance, + updatePayload, + type, + oldProps, + newProps, + workInProgress, + childrenUnchanged, + recyclableInstance + ); + if ( + finalizeInitialChildren( + newInstance, + type, + newProps, + rootContainerInstance, + currentHostContext + ) + ) { + markUpdate(workInProgress); + } - case Fragment: - return updateFragment(current, workInProgress, renderExpirationTime); + workInProgress.stateNode = newInstance; - case Mode: - return updateMode(current, workInProgress, renderExpirationTime); + 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); + } + }; + 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 Profiler: - return updateProfiler(current, workInProgress, renderExpirationTime); + markUpdate(workInProgress); + } + }; +} else { + // No host operations + updateHostContainer = function(workInProgress) { + // Noop + }; + updateHostComponent$1 = function( + current, + workInProgress, + type, + newProps, + rootContainerInstance + ) { + // Noop + }; + updateHostText$1 = function(current, workInProgress, oldText, newText) { + // Noop + }; +} - case ContextProvider: - return updateContextProvider( - current, - workInProgress, - renderExpirationTime - ); +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 (tailNode !== null) { + if (tailNode.alternate !== null) { + lastTailNode = tailNode; + } - case ContextConsumer: - return updateContextConsumer( - current, - workInProgress, - renderExpirationTime - ); + tailNode = tailNode.sibling; + } // Next we're simply going to delete all insertions after the + // last rendered item. - case MemoComponent: { - var _type2 = workInProgress.type; - var _unresolvedProps3 = workInProgress.pendingProps; // Resolve outer props first, then resolve inner props. + 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 _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3); + break; + } - { - if (workInProgress.type !== workInProgress.elementType) { - var outerPropTypes = _type2.propTypes; + 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 (outerPropTypes) { - checkPropTypes( - outerPropTypes, - _resolvedProps3, // Resolved for outer only - "prop", - getComponentName(_type2) - ); - } + _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; } - - _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3); - return updateMemoComponent( - current, - workInProgress, - _type2, - _resolvedProps3, - updateExpirationTime, - renderExpirationTime - ); + break; } + } +} - case SimpleMemoComponent: { - return updateSimpleMemoComponent( - current, - workInProgress, - workInProgress.type, - workInProgress.pendingProps, - updateExpirationTime, - renderExpirationTime - ); - } +function completeWork(current, workInProgress, renderExpirationTime) { + var newProps = workInProgress.pendingProps; - case IncompleteClassComponent: { - var _Component3 = workInProgress.type; - var _unresolvedProps4 = workInProgress.pendingProps; + switch (workInProgress.tag) { + case IndeterminateComponent: + break; - var _resolvedProps4 = - workInProgress.elementType === _Component3 - ? _unresolvedProps4 - : resolveDefaultProps(_Component3, _unresolvedProps4); + case LazyComponent: + break; - return mountIncompleteClassComponent( - current, - workInProgress, - _Component3, - _resolvedProps4, - renderExpirationTime - ); - } + case SimpleMemoComponent: + case FunctionComponent: + break; - case SuspenseListComponent: { - return updateSuspenseListComponent( - current, - workInProgress, - renderExpirationTime - ); - } - } + case ClassComponent: { + var Component = workInProgress.type; - { - throw Error( - "Unknown unit of work tag (" + - workInProgress.tag + - "). This error is likely caused by a bug in React. Please file an issue." - ); - } -} + if (isContextProvider(Component)) { + popContext(workInProgress); + } -function markUpdate(workInProgress) { - // Tag the fiber with an update effect. This turns a Placement into - // a PlacementAndUpdate. - workInProgress.effectTag |= Update; -} + break; + } -function markRef$1(workInProgress) { - workInProgress.effectTag |= Ref; -} + case HostRoot: { + popHostContainer(workInProgress); + popTopLevelContextObject(workInProgress); + var fiberRoot = workInProgress.stateNode; + if (fiberRoot.pendingContext) { + fiberRoot.context = fiberRoot.pendingContext; + fiberRoot.pendingContext = null; + } -var appendAllChildren; -var updateHostContainer; -var updateHostComponent$1; -var updateHostText$1; + 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); + + if (wasHydrated) { + // If we hydrated, then we'll need to schedule an update for + // the commit side-effects on the root. + markUpdate(workInProgress); + } + } -{ - // 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; + updateHostContainer(workInProgress); + break; + } - while (node !== null) { - // eslint-disable-next-line no-labels - if (node.tag === HostComponent) { - var instance = node.stateNode; + 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 (needsVisibilityToggle && isHidden) { - // This child is inside a timed out tree. Hide it. - var props = node.memoizedProps; - var type = node.type; - instance = cloneHiddenInstance(instance); + if (enableFlareAPI) { + var prevListeners = current.memoizedProps.listeners; + var nextListeners = newProps.listeners; + + if (prevListeners !== nextListeners) { + markUpdate(workInProgress); + } } - appendInitialChild(parent, instance); - } else if (node.tag === HostText) { - var _instance = node.stateNode; + 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 (needsVisibilityToggle && isHidden) { - // This child is inside a timed out tree. Hide it. - var text = node.memoizedProps; - _instance = cloneHiddenTextInstance(); + break; } - appendInitialChild(parent, _instance); - } else if (node.tag === HostPortal); - else if (node.tag === SuspenseComponent) { - if ((node.effectTag & Update) !== NoEffect) { - // Need to toggle the visibility of the primary children. - var newIsHidden = node.memoizedState !== null; + 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 we want to add then top->down or + // bottom->up. Top->down is faster in IE11. - if (newIsHidden) { - var primaryChildParent = node.child; + var _wasHydrated = popHydrationState(workInProgress); - if (primaryChildParent !== null) { - if (primaryChildParent.child !== null) { - primaryChildParent.child.return = primaryChildParent; - appendAllChildren( - parent, - primaryChildParent, - true, - newIsHidden - ); - } + if (_wasHydrated) { + // TODO: Move this and createInstance step into the beginPhase + // to consolidate. + if ( + prepareToHydrateHostInstance( + workInProgress, + rootContainerInstance, + currentHostContext + ) + ) { + // If changes to the hydrated node needs to be applied at the + // commit-phase we mark this as such. + markUpdate(workInProgress); + } - var fallbackChildParent = primaryChildParent.sibling; + if (enableFlareAPI) { + var listeners = newProps.listeners; - if (fallbackChildParent !== null) { - fallbackChildParent.return = node; - node = fallbackChildParent; - continue; - } + if (listeners != null) { + updateEventListeners( + listeners, + workInProgress, + rootContainerInstance + ); + } + } + } else { + var instance = createInstance( + type, + newProps, + rootContainerInstance, + currentHostContext, + workInProgress + ); + appendAllChildren(instance, workInProgress, false, false); // This needs to be set before we mount Flare event listeners + + workInProgress.stateNode = instance; + + if (enableFlareAPI) { + var _listeners = newProps.listeners; + + if (_listeners != null) { + updateEventListeners( + _listeners, + workInProgress, + rootContainerInstance + ); } + } // Certain renderers require commit-time effects for initial mount. + // (eg DOM renderer supports auto-focus for certain elements). + // Make sure such renderers get scheduled for later work. + + if ( + finalizeInitialChildren( + instance, + type, + newProps, + rootContainerInstance, + currentHostContext + ) + ) { + markUpdate(workInProgress); } } - if (node.child !== null) { - // Continue traversing like normal - node.child.return = node; - node = node.child; - continue; + if (workInProgress.ref !== null) { + // If there is a ref on a host node we need to schedule a callback + markRef$1(workInProgress); } - } 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; + break; + } - if (node === workInProgress) { - return; - } + case HostText: { + var newText = newProps; - while (node.sibling === null) { - if (node.return === null || node.return === workInProgress) { - return; + if (current && workInProgress.stateNode != null) { + var oldText = current.memoizedProps; // If we have an alternate, that means this is an update and we need + // to schedule a side-effect to do the updates. + + updateHostText$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. } - node = node.return; + var _rootContainerInstance = getRootHostContainer(); + + var _currentHostContext = getHostContext(); + + var _wasHydrated2 = popHydrationState(workInProgress); + + if (_wasHydrated2) { + if (prepareToHydrateHostTextInstance(workInProgress)) { + markUpdate(workInProgress); + } + } else { + workInProgress.stateNode = createTextInstance( + newText, + _rootContainerInstance, + _currentHostContext, + workInProgress + ); + } } - node.sibling.return = node.return; - node = node.sibling; + break; } - }; // 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 ForwardRef: + break; - while (node !== null) { - // eslint-disable-next-line no-labels - if (node.tag === HostComponent) { - var instance = node.stateNode; + case SuspenseComponent: { + popSuspenseContext(workInProgress); + var nextState = workInProgress.memoizedState; - 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 (enableSuspenseServerRenderer) { + if (nextState !== null && nextState.dehydrated !== null) { + if (current === null) { + var _wasHydrated3 = popHydrationState(workInProgress); - appendChildToContainerChildSet(containerChildSet, instance); - } else if (node.tag === HostText) { - var _instance3 = node.stateNode; + if (!_wasHydrated3) { + throw Error( + "A dehydrated suspense component was completed without a hydrated node. This is probably a bug in React." + ); + } - if (needsVisibilityToggle && isHidden) { - // This child is inside a timed out tree. Hide it. - var text = node.memoizedProps; - _instance3 = cloneHiddenTextInstance(); + prepareToHydrateHostSuspenseInstance(workInProgress); + + if (enableSchedulerTracing) { + markSpawnedWork(Never); + } + + return null; + } else { + // We should never have been in a hydration state if we didn't have a current. + // However, in some of those paths, we might have reentered a hydration state + // and then we might be inside a hydration state. In that case, we'll need to + // exit out of it. + resetHydrationState(); + + if ((workInProgress.effectTag & DidCapture) === NoEffect) { + // This boundary did not suspend so it's now hydrated and unsuspended. + workInProgress.memoizedState = null; + } // If nothing suspended, we need to schedule an effect to mark this boundary + // as having hydrated so events know that they're free be invoked. + // It's also a signal to replay events and the suspense callback. + // If something suspended, schedule an effect to attach retry listeners. + // So we might as well always mark this. + + workInProgress.effectTag |= Update; + return null; + } } + } - appendChildToContainerChildSet(containerChildSet, _instance3); - } else if (node.tag === HostPortal); - else if (node.tag === SuspenseComponent) { - if ((node.effectTag & Update) !== NoEffect) { - // Need to toggle the visibility of the primary children. - var newIsHidden = node.memoizedState !== null; + if ((workInProgress.effectTag & DidCapture) !== NoEffect) { + // Something suspended. Re-render with the fallback children. + workInProgress.expirationTime = renderExpirationTime; // Do not reset the effect list. - if (newIsHidden) { - var primaryChildParent = node.child; + return workInProgress; + } - if (primaryChildParent !== null) { - if (primaryChildParent.child !== null) { - primaryChildParent.child.return = primaryChildParent; - appendAllChildrenToContainer( - containerChildSet, - primaryChildParent, - true, - newIsHidden - ); - } + var nextDidTimeout = nextState !== null; + var prevDidTimeout = false; - var fallbackChildParent = primaryChildParent.sibling; + if (current === null) { + if (workInProgress.memoizedProps.fallback !== undefined) { + popHydrationState(workInProgress); + } + } else { + var prevState = current.memoizedState; + prevDidTimeout = prevState !== null; - if (fallbackChildParent !== null) { - fallbackChildParent.return = node; - node = fallbackChildParent; - continue; - } + if (!nextDidTimeout && prevState !== null) { + // We just switched from the fallback to the normal children. + // Delete the fallback. + // TODO: Would it be better to store the fallback fragment on + // the stateNode during the begin phase? + var currentFallbackChild = current.child.sibling; + + if (currentFallbackChild !== null) { + // Deletions go at the beginning of the return fiber's effect list + var first = workInProgress.firstEffect; + + if (first !== null) { + workInProgress.firstEffect = currentFallbackChild; + currentFallbackChild.nextEffect = first; + } else { + workInProgress.firstEffect = workInProgress.lastEffect = currentFallbackChild; + currentFallbackChild.nextEffect = null; } + currentFallbackChild.effectTag = Deletion; } } + } - if (node.child !== null) { - // Continue traversing like normal - node.child.return = node; - node = node.child; - continue; + 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(); + } } - } 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; + if (supportsPersistence) { + // 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 proimse. This flag is also used to hide the + // primary children. + workInProgress.effectTag |= Update; } - - node = node.return; + } + if (supportsMutation) { + // 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 proimse. 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 the + // is currently timed out, too. + workInProgress.effectTag |= Update; + } + } + if ( + enableSuspenseCallback && + workInProgress.updateQueue !== null && + workInProgress.memoizedProps.suspenseCallback != null + ) { + // Always notify the callback + workInProgress.effectTag |= Update; } - node.sibling.return = node.return; - node = node.sibling; + break; } - }; - - updateHostContainer = function(workInProgress) { - var portalOrRoot = workInProgress.stateNode; - var childrenUnchanged = workInProgress.firstEffect === null; - 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. + case Fragment: + break; - appendAllChildrenToContainer(newChildSet, workInProgress, false, false); - portalOrRoot.pendingChildren = newChildSet; // Schedule an update on the container to swap out the container. + case Mode: + break; - markUpdate(workInProgress); - finalizeContainerChildren(container, newChildSet); - } - }; + case Profiler: + break; - 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. + case HostPortal: + popHostContainer(workInProgress); + updateHostContainer(workInProgress); + break; + case ContextProvider: + // Pop provider fiber + popProvider(workInProgress); + break; - var childrenUnchanged = workInProgress.firstEffect === null; + case ContextConsumer: + 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 MemoComponent: + break; - var recyclableInstance = workInProgress.stateNode; - var currentHostContext = getHostContext(); - var updatePayload = null; + case IncompleteClassComponent: { + // Same as class component case. I put it down here so that the tags are + // sequential to ensure this switch is compiled to a jump table. + var _Component = workInProgress.type; - if (oldProps !== newProps) { - updatePayload = prepareUpdate( - recyclableInstance, - type, - oldProps, - newProps - ); - } + if (isContextProvider(_Component)) { + popContext(workInProgress); + } - if (childrenUnchanged && updatePayload === null) { - // No changes, just reuse the existing instance. - // Note that this might release a previous clone. - workInProgress.stateNode = currentInstance; - return; + break; } - var newInstance = cloneInstance( - currentInstance, - updatePayload, - type, - oldProps, - newProps, - workInProgress, - childrenUnchanged - ); - - workInProgress.stateNode = newInstance; + case SuspenseListComponent: { + popSuspenseContext(workInProgress); + var renderState = workInProgress.memoizedState; - 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); - } - }; + if (renderState === null) { + // We're running in the default, "independent" mode. We don't do anything + // in this mode. + 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. + var didSuspendAlready = + (workInProgress.effectTag & DidCapture) !== NoEffect; + var renderedTail = renderState.rendering; - markUpdate(workInProgress); - } else { - workInProgress.stateNode = current.stateNode; - } - }; -} + 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.effectTag & DidCapture) === NoEffect); -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 (!cannotBeSuspended) { + var row = workInProgress.child; - while (tailNode !== null) { - if (tailNode.alternate !== null) { - lastTailNode = tailNode; - } + while (row !== null) { + var suspended = findFirstSuspended(row); - tailNode = tailNode.sibling; - } // Next we're simply going to delete all insertions after the - // last rendered item. + if (suspended !== null) { + didSuspendAlready = true; + workInProgress.effectTag |= 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 (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 newThennables = suspended.updateQueue; - break; - } + if (newThennables !== null) { + workInProgress.updateQueue = newThennables; + workInProgress.effectTag |= 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. - 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 (renderState.lastEffect === null) { + workInProgress.firstEffect = null; + } - while (_tailNode !== null) { - if (_tailNode.alternate !== null) { - _lastTailNode = _tailNode; - } + workInProgress.lastEffect = renderState.lastEffect; // Reset the child fibers to their original state. - _tailNode = _tailNode.sibling; - } // Next we're simply going to delete all insertions after the - // last rendered item. + resetChildFibers(workInProgress, renderExpirationTime); // Set up the Suspense Context to force suspense and immediately + // rerender the children. - 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; + pushSuspenseContext( + workInProgress, + setShallowSuspenseContext( + suspenseStackCursor.current, + ForceSuspenseFallback + ) + ); + return workInProgress.child; + } + row = row.sibling; + } + } } else { - renderState.tail = null; - } + cutOffTailIfNeeded(renderState, false); + } // Next we're going to render the tail. } else { - // Detach the insertion after the last node that was already - // inserted. - _lastTailNode.sibling = null; - } - - break; - } - } -} - -function completeWork(current, workInProgress, renderExpirationTime) { - var newProps = workInProgress.pendingProps; + // Append the rendered row to the child list. + if (!didSuspendAlready) { + var _suspended = findFirstSuspended(renderedTail); - 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; + if (_suspended !== null) { + workInProgress.effectTag |= DidCapture; + didSuspendAlready = true; // Ensure we transfer the update queue to the parent so that it doesn't + // get lost if this row ends up dropped during a second pass. - case ClassComponent: { - var Component = workInProgress.type; + var _newThennables = _suspended.updateQueue; - if (isContextProvider(Component)) { - popContext(workInProgress); - } + if (_newThennables !== null) { + workInProgress.updateQueue = _newThennables; + workInProgress.effectTag |= Update; + } - return null; - } + cutOffTailIfNeeded(renderState, true); // This might have been modified. - case HostRoot: { - popHostContainer(workInProgress); - popTopLevelContextObject(workInProgress); - var fiberRoot = workInProgress.stateNode; + if ( + renderState.tail === null && + renderState.tailMode === "hidden" && + !renderedTail.alternate + ) { + // 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. - if (fiberRoot.pendingContext) { - fiberRoot.context = fiberRoot.pendingContext; - fiberRoot.pendingContext = null; - } + if (lastEffect !== null) { + lastEffect.nextEffect = null; + } // We're done. - 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(); + return null; + } + } else if ( + now() > renderState.tailExpiration && + renderExpirationTime > Never + ) { + // 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.effectTag |= 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. If we can show + // them, then they really have the same priority as this render. + // So we'll pick it back up the very next render pass once we've had + // an opportunity to yield for paint. - if (wasHydrated) { - // If we hydrated, then we'll need to schedule an update for - // the commit side-effects on the root. - markUpdate(workInProgress); + var nextPriority = renderExpirationTime - 1; + workInProgress.expirationTime = workInProgress.childExpirationTime = nextPriority; + if (enableSchedulerTracing) { + markSpawnedWork(nextPriority); + } + } + } + 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; } } - updateHostContainer(workInProgress); - return null; - } + if (renderState.tail !== null) { + // We still have tail rows to render. + if (renderState.tailExpiration === 0) { + // Heuristic for how long we're willing to spend rendering rows + // until we just give up and show what we have so far. + var TAIL_EXPIRATION_TIMEOUT_MS = 500; + renderState.tailExpiration = now() + TAIL_EXPIRATION_TIMEOUT_MS; + } // Pop a row. - case HostComponent: { - popHostContext(workInProgress); - var rootContainerInstance = getRootHostContainer(); - var type = workInProgress.type; + var next = renderState.tail; + renderState.rendering = next; + renderState.tail = next.sibling; + renderState.lastEffect = workInProgress.lastEffect; + 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. - if (current !== null && workInProgress.stateNode != null) { - updateHostComponent$1( - current, - workInProgress, - type, - newProps, - rootContainerInstance - ); + var suspenseContext = suspenseStackCursor.current; - if (current.ref !== workInProgress.ref) { - markRef$1(workInProgress); + if (didSuspendAlready) { + suspenseContext = setShallowSuspenseContext( + suspenseContext, + ForceSuspenseFallback + ); + } else { + suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); } - } 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 null; - } + pushSuspenseContext(workInProgress, suspenseContext); // Do a pass over the next row. - 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. + return next; + } - var _wasHydrated = popHydrationState(); + 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); + case FundamentalComponent: { + if (enableFundamentalAPI) { + var fundamentalImpl = workInProgress.type.impl; + var fundamentalInstance = workInProgress.stateNode; + + if (fundamentalInstance === null) { + var getInitialState = fundamentalImpl.getInitialState; + var fundamentalState; + + if (getInitialState !== undefined) { + fundamentalState = getInitialState(newProps); } - } else { - var instance = createInstance( - type, + + fundamentalInstance = workInProgress.stateNode = createFundamentalStateInstance( + workInProgress, newProps, - rootContainerInstance, - currentHostContext, - workInProgress + fundamentalImpl, + fundamentalState || {} ); - appendAllChildren(instance, workInProgress, false, false); // This needs to be set before we mount Flare event listeners - workInProgress.stateNode = instance; - } + var _instance5 = getFundamentalComponentInstance(fundamentalInstance); - if (workInProgress.ref !== null) { - // If there is a ref on a host node we need to schedule a callback - markRef$1(workInProgress); - } - } + fundamentalInstance.instance = _instance5; - return null; - } + if (fundamentalImpl.reconcileChildren === false) { + return null; + } - case HostText: { - var newText = newProps; + appendAllChildren(_instance5, workInProgress, false, false); + mountFundamentalComponent(fundamentalInstance); + } else { + // We fire update in commit phase + var prevProps = fundamentalInstance.props; + fundamentalInstance.prevProps = prevProps; + fundamentalInstance.props = newProps; + fundamentalInstance.currentFiber = workInProgress; - 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. + if (supportsPersistence) { + var _instance6 = cloneFundamentalInstance(fundamentalInstance); - 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. + fundamentalInstance.instance = _instance6; + appendAllChildren(_instance6, workInProgress, false, false); + } + + var shouldUpdate = shouldUpdateFundamentalComponent( + fundamentalInstance + ); + + if (shouldUpdate) { + markUpdate(workInProgress); + } } + } - var _rootContainerInstance = getRootHostContainer(); + break; + } - var _currentHostContext = getHostContext(); + case ScopeComponent: { + if (enableScopeAPI) { + if (current === null) { + var _type3 = workInProgress.type; + var scopeInstance = { + fiber: workInProgress, + methods: null + }; + workInProgress.stateNode = scopeInstance; + scopeInstance.methods = createScopeMethods(_type3, scopeInstance); - var _wasHydrated2 = popHydrationState(); + if (enableFlareAPI) { + var _listeners2 = newProps.listeners; - if (_wasHydrated2) { - if (prepareToHydrateHostTextInstance()) { + if (_listeners2 != null) { + var _rootContainerInstance2 = getRootHostContainer(); + + updateEventListeners( + _listeners2, + workInProgress, + _rootContainerInstance2 + ); + } + } + + if (workInProgress.ref !== null) { + markRef$1(workInProgress); markUpdate(workInProgress); } } else { - workInProgress.stateNode = createTextInstance( - newText, - _rootContainerInstance, - _currentHostContext, - workInProgress - ); + if (enableFlareAPI) { + var _prevListeners = current.memoizedProps.listeners; + var _nextListeners = newProps.listeners; + + if ( + _prevListeners !== _nextListeners || + workInProgress.ref !== null + ) { + markUpdate(workInProgress); + } + } else { + if (workInProgress.ref !== null) { + markUpdate(workInProgress); + } + } + + if (current.ref !== workInProgress.ref) { + markRef$1(workInProgress); + } } } - return null; + break; } - case SuspenseComponent: { - popSuspenseContext(workInProgress); - var nextState = workInProgress.memoizedState; + default: { + throw Error( + "Unknown unit of work tag (" + + workInProgress.tag + + "). This error is likely caused by a bug in React. Please file an issue." + ); + } + } - if ((workInProgress.effectTag & DidCapture) !== NoEffect) { - // Something suspended. Re-render with the fallback children. - workInProgress.expirationTime = renderExpirationTime; // Do not reset the effect list. + return null; +} + +function unwindWork(workInProgress, renderExpirationTime) { + switch (workInProgress.tag) { + case ClassComponent: { + var Component = workInProgress.type; + + if (isContextProvider(Component)) { + popContext(workInProgress); + } + + var effectTag = workInProgress.effectTag; + if (effectTag & ShouldCapture) { + workInProgress.effectTag = (effectTag & ~ShouldCapture) | DidCapture; return workInProgress; } - var nextDidTimeout = nextState !== null; - var prevDidTimeout = false; + return null; + } - if (current === null) { - if (workInProgress.memoizedProps.fallback !== undefined); - } else { - var prevState = current.memoizedState; - prevDidTimeout = prevState !== null; + case HostRoot: { + popHostContainer(workInProgress); + popTopLevelContextObject(workInProgress); + var _effectTag = workInProgress.effectTag; - if (!nextDidTimeout && prevState !== null) { - // We just switched from the fallback to the normal children. - // Delete the fallback. - // TODO: Would it be better to store the fallback fragment on - // the stateNode during the begin phase? - var currentFallbackChild = current.child.sibling; + if (!((_effectTag & DidCapture) === NoEffect)) { + throw Error( + "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." + ); + } - if (currentFallbackChild !== null) { - // Deletions go at the beginning of the return fiber's effect list - var first = workInProgress.firstEffect; + workInProgress.effectTag = (_effectTag & ~ShouldCapture) | DidCapture; + return workInProgress; + } - if (first !== null) { - workInProgress.firstEffect = currentFallbackChild; - currentFallbackChild.nextEffect = first; - } else { - workInProgress.firstEffect = workInProgress.lastEffect = currentFallbackChild; - currentFallbackChild.nextEffect = null; - } + case HostComponent: { + // TODO: popHydrationState + popHostContext(workInProgress); + return null; + } - currentFallbackChild.effectTag = Deletion; - } - } - } + case SuspenseComponent: { + popSuspenseContext(workInProgress); - 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 (enableSuspenseServerRenderer) { + var suspenseState = workInProgress.memoizedState; - 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 (suspenseState !== null && suspenseState.dehydrated !== null) { + if (!(workInProgress.alternate !== null)) { + throw Error( + "Threw in newly mounted dehydrated component. This is likely a bug in React. Please file an issue." + ); } + + resetHydrationState(); } } - { - // 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.effectTag |= Update; - } + var _effectTag2 = workInProgress.effectTag; + + if (_effectTag2 & ShouldCapture) { + workInProgress.effectTag = (_effectTag2 & ~ShouldCapture) | DidCapture; // Captured a suspense effect. Re-render the boundary. + + return 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); - updateHostContainer(workInProgress); return null; case ContextProvider: - // Pop provider fiber popProvider(workInProgress); return null; - case IncompleteClassComponent: { - // Same as class component case. I put it down here so that the tags are - // sequential to ensure this switch is compiled to a jump table. - var _Component = workInProgress.type; - - if (isContextProvider(_Component)) { - popContext(workInProgress); - } - + default: return null; - } + } +} - case SuspenseListComponent: { - popSuspenseContext(workInProgress); - var renderState = workInProgress.memoizedState; +function unwindInterruptedWork(interruptedWork) { + switch (interruptedWork.tag) { + case ClassComponent: { + var childContextTypes = interruptedWork.type.childContextTypes; - if (renderState === null) { - // We're running in the default, "independent" mode. - // We don't do anything in this mode. - return null; + if (childContextTypes !== null && childContextTypes !== undefined) { + popContext(interruptedWork); } - var didSuspendAlready = - (workInProgress.effectTag & DidCapture) !== NoEffect; - 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.effectTag & DidCapture) === NoEffect); - - if (!cannotBeSuspended) { - var row = workInProgress.child; + break; + } - while (row !== null) { - var suspended = findFirstSuspended(row); + case HostRoot: { + popHostContainer(interruptedWork); + popTopLevelContextObject(interruptedWork); + break; + } + case HostComponent: { + popHostContext(interruptedWork); + break; + } - if (suspended !== null) { - didSuspendAlready = true; - workInProgress.effectTag |= 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 HostPortal: + popHostContainer(interruptedWork); + break; - var newThennables = suspended.updateQueue; + case SuspenseComponent: + popSuspenseContext(interruptedWork); + break; - if (newThennables !== null) { - workInProgress.updateQueue = newThennables; - workInProgress.effectTag |= 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. + case SuspenseListComponent: + popSuspenseContext(interruptedWork); + break; - if (renderState.lastEffect === null) { - workInProgress.firstEffect = null; - } + case ContextProvider: + popProvider(interruptedWork); + break; - workInProgress.lastEffect = renderState.lastEffect; // Reset the child fibers to their original state. + default: + break; + } +} - resetChildFibers(workInProgress, renderExpirationTime); // Set up the Suspense Context to force suspense and immediately - // rerender the children. +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) + }; +} - pushSuspenseContext( - workInProgress, - setShallowSuspenseContext( - suspenseStackCursor.current, - ForceSuspenseFallback - ) - ); - return workInProgress.child; - } +// Module provided by RN: +if ( + !( + typeof ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog === + "function" + ) +) { + throw Error( + "Expected ReactFiberErrorDialog.showErrorDialog to be a function." + ); +} - row = row.sibling; - } - } - } else { - cutOffTailIfNeeded(renderState, false); - } // Next we're going to render the tail. - } else { - // Append the rendered row to the child list. - if (!didSuspendAlready) { - var _suspended = findFirstSuspended(renderedTail); +function showErrorDialog(capturedError) { + return ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog( + capturedError + ); +} - if (_suspended !== null) { - workInProgress.effectTag |= 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. +function logCapturedError(capturedError) { + var logError = showErrorDialog(capturedError); // Allow injected showErrorDialog() to prevent default console.error logging. + // This enables renderers like ReactNative to better manage redbox behavior. - var _newThennables = _suspended.updateQueue; + if (logError === false) { + return; + } - if (_newThennables !== null) { - workInProgress.updateQueue = _newThennables; - workInProgress.effectTag |= Update; - } + var error = capturedError.error; + { + var componentName = capturedError.componentName, + componentStack = capturedError.componentStack, + errorBoundaryName = capturedError.errorBoundaryName, + errorBoundaryFound = capturedError.errorBoundaryFound, + willRetry = capturedError.willRetry; // Browsers support silencing uncaught errors by calling + // `preventDefault()` in window `error` handler. + // We record this information as an expando on the error. - cutOffTailIfNeeded(renderState, true); // This might have been modified. + if (error != null && error._suppressLogging) { + if (errorBoundaryFound && willRetry) { + // 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 ( - renderState.tail === null && - renderState.tailMode === "hidden" && - !renderedTail.alternate - ) { - // 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. + console.error(error); // For a more detailed description of this block, see: + // https://github.com/facebook/react/pull/13384 + } - if (lastEffect !== null) { - lastEffect.nextEffect = null; - } // We're done. + var componentNameMessage = componentName + ? "The above error occurred in the <" + componentName + "> component:" + : "The above error occurred in one of your React components:"; + var errorBoundaryMessage; // errorBoundaryFound check is sufficient; errorBoundaryName check is to satisfy Flow. - return null; - } - } else if ( - // The time it took to render last row is greater than time until - // the expiration. - now() * 2 - renderState.renderingStartTime > - renderState.tailExpiration && - renderExpirationTime > Never - ) { - // 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.effectTag |= 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. If we can show - // them, then they really have the same priority as this render. - // So we'll pick it back up the very next render pass once we've had - // an opportunity to yield for paint. + if (errorBoundaryFound && errorBoundaryName) { + if (willRetry) { + errorBoundaryMessage = + "React will try to recreate this component tree from scratch " + + ("using the error boundary you provided, " + errorBoundaryName + "."); + } else { + errorBoundaryMessage = + "This error was initially handled by the error boundary " + + errorBoundaryName + + ".\n" + + "Recreating the tree from scratch failed so React will unmount the tree."; + } + } else { + errorBoundaryMessage = + "Consider adding an error boundary to your tree to customize error handling behavior.\n" + + "Visit https://fb.me/react-error-boundaries to learn more about error boundaries."; + } + var combinedMessage = + "" + + componentNameMessage + + 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. - var nextPriority = renderExpirationTime - 1; - workInProgress.expirationTime = workInProgress.childExpirationTime = nextPriority; + console.error(combinedMessage); + } +} - { - markSpawnedWork(nextPriority); - } - } - } +var didWarnAboutUndefinedSnapshotBeforeUpdate = null; +{ + didWarnAboutUndefinedSnapshotBeforeUpdate = new Set(); +} - 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 PossiblyWeakSet = typeof WeakSet === "function" ? WeakSet : Set; +function logError(boundary, errorInfo) { + var source = errorInfo.source; + var stack = errorInfo.stack; - if (previousSibling !== null) { - previousSibling.sibling = renderedTail; - } else { - workInProgress.child = renderedTail; - } + if (stack === null && source !== null) { + stack = getStackByFiberInDevAndProd(source); + } - renderState.last = renderedTail; - } - } + var capturedError = { + componentName: source !== null ? getComponentName(source.type) : null, + componentStack: stack !== null ? stack : "", + error: errorInfo.value, + errorBoundary: null, + errorBoundaryName: null, + errorBoundaryFound: false, + willRetry: false + }; - if (renderState.tail !== null) { - // We still have tail rows to render. - if (renderState.tailExpiration === 0) { - // Heuristic for how long we're willing to spend rendering rows - // until we just give up and show what we have so far. - var TAIL_EXPIRATION_TIMEOUT_MS = 500; - renderState.tailExpiration = now() + TAIL_EXPIRATION_TIMEOUT_MS; // TODO: This is meant to mimic the train model or JND but this - // is a per component value. It should really be since the start - // of the total render or last commit. Consider using something like - // globalMostRecentFallbackTime. That doesn't account for being - // suspended for part of the time or when it's a new render. - // It should probably use a global start time value instead. - } // Pop a row. + if (boundary !== null && boundary.tag === ClassComponent) { + capturedError.errorBoundary = boundary.stateNode; + capturedError.errorBoundaryName = getComponentName(boundary.type); + capturedError.errorBoundaryFound = true; + capturedError.willRetry = true; + } - 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. + try { + logCapturedError(capturedError); + } 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 suspenseContext = suspenseStackCursor.current; +var callComponentWillUnmountWithTimer = function(current$$1, instance) { + startPhaseTimer(current$$1, "componentWillUnmount"); + instance.props = current$$1.memoizedProps; + instance.state = current$$1.memoizedState; + instance.componentWillUnmount(); + stopPhaseTimer(); +}; // Capture errors so they don't interrupt unmounting. - if (didSuspendAlready) { - suspenseContext = setShallowSuspenseContext( - suspenseContext, - ForceSuspenseFallback - ); - } else { - suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); +function safelyCallComponentWillUnmount(current$$1, instance) { + { + invokeGuardedCallback( + null, + callComponentWillUnmountWithTimer, + null, + current$$1, + instance + ); + if (hasCaughtError()) { + var unmountError = clearCaughtError(); + captureCommitPhaseError(current$$1, unmountError); + } + } +} + +function safelyDetachRef(current$$1) { + var ref = current$$1.ref; + if (ref !== null) { + if (typeof ref === "function") { + { + invokeGuardedCallback(null, ref, null, null); + if (hasCaughtError()) { + var refError = clearCaughtError(); + captureCommitPhaseError(current$$1, refError); } - - pushSuspenseContext(workInProgress, suspenseContext); // Do a pass over the next row. - - return next; } - - return null; + } else { + ref.current = null; } } +} +function safelyCallDestroy(current$$1, destroy) { { - 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, destroy, null); + if (hasCaughtError()) { + var error = clearCaughtError(); + captureCommitPhaseError(current$$1, error); + } } } -function unwindWork(workInProgress, renderExpirationTime) { - switch (workInProgress.tag) { +function commitBeforeMutationLifeCycles(current$$1, finishedWork) { + switch (finishedWork.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + commitHookEffectList(UnmountSnapshot, NoEffect$1, finishedWork); + return; + } case ClassComponent: { - var Component = workInProgress.type; + if (finishedWork.effectTag & Snapshot) { + if (current$$1 !== null) { + var prevProps = current$$1.memoizedProps; + var prevState = current$$1.memoizedState; + startPhaseTimer(finishedWork, "getSnapshotBeforeUpdate"); + 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 (isContextProvider(Component)) { - popContext(workInProgress); - } + { + if ( + finishedWork.type === finishedWork.elementType && + !didWarnAboutReassigningProps + ) { + !(instance.props === finishedWork.memoizedProps) + ? warning$1( + false, + "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" + ) + : void 0; + !(instance.state === finishedWork.memoizedState) + ? warning$1( + false, + "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.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ) + : void 0; + } + } + var snapshot = instance.getSnapshotBeforeUpdate( + finishedWork.elementType === finishedWork.type + ? prevProps + : resolveDefaultProps(finishedWork.type, prevProps), + prevState + ); - var effectTag = workInProgress.effectTag; + { + var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate; - if (effectTag & ShouldCapture) { - workInProgress.effectTag = (effectTag & ~ShouldCapture) | DidCapture; - return workInProgress; + if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) { + didWarnSet.add(finishedWork.type); + warningWithoutStack$1( + false, + "%s.getSnapshotBeforeUpdate(): A snapshot value (or null) " + + "must be returned. You have returned undefined.", + getComponentName(finishedWork.type) + ); + } + } + instance.__reactInternalSnapshotBeforeUpdate = snapshot; + stopPhaseTimer(); + } } - return null; + return; } - case HostRoot: { - popHostContainer(workInProgress); - popTopLevelContextObject(workInProgress); - var _effectTag = workInProgress.effectTag; + case HostRoot: + case HostComponent: + case HostText: + case HostPortal: + case IncompleteClassComponent: + // Nothing to do for these component types + return; - if (!((_effectTag & DidCapture) === NoEffect)) { + default: { + { throw Error( - "The root failed to unmount after an error. This is likely 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." ); } - - workInProgress.effectTag = (_effectTag & ~ShouldCapture) | DidCapture; - return workInProgress; - } - - case HostComponent: { - // TODO: popHydrationState - popHostContext(workInProgress); - return null; } + } +} - case SuspenseComponent: { - popSuspenseContext(workInProgress); - - var _effectTag2 = workInProgress.effectTag; +function commitHookEffectList(unmountTag, mountTag, finishedWork) { + var updateQueue = finishedWork.updateQueue; + var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; - if (_effectTag2 & ShouldCapture) { - workInProgress.effectTag = (_effectTag2 & ~ShouldCapture) | DidCapture; // Captured a suspense effect. Re-render the boundary. + if (lastEffect !== null) { + var firstEffect = lastEffect.next; + var effect = firstEffect; - return workInProgress; + do { + if ((effect.tag & unmountTag) !== NoEffect$1) { + // Unmount + var destroy = effect.destroy; + effect.destroy = undefined; + if (destroy !== undefined) { + destroy(); + } } + if ((effect.tag & mountTag) !== NoEffect$1) { + // Mount + var create = effect.create; + effect.destroy = create(); - 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; + { + var _destroy = effect.destroy; - case ContextProvider: - popProvider(workInProgress); - return null; + if (_destroy !== undefined && typeof _destroy !== "function") { + var addendum = void 0; - default: - return null; + 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://fb.me/react-hooks-data-fetching"; + } else { + addendum = " You returned: " + _destroy; + } + warningWithoutStack$1( + false, + "An effect function must not return anything besides a function, " + + "which is used for clean-up.%s%s", + addendum, + getStackByFiberInDevAndProd(finishedWork) + ); + } + } + } + effect = effect.next; + } while (effect !== firstEffect); } } -function unwindInterruptedWork(interruptedWork) { - switch (interruptedWork.tag) { - case ClassComponent: { - var childContextTypes = interruptedWork.type.childContextTypes; - - if (childContextTypes !== null && childContextTypes !== undefined) { - popContext(interruptedWork); +function commitPassiveHookEffects(finishedWork) { + if ((finishedWork.effectTag & Passive) !== NoEffect) { + switch (finishedWork.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + commitHookEffectList(UnmountPassive, NoEffect$1, finishedWork); + commitHookEffectList(NoEffect$1, MountPassive, finishedWork); + break; } - - break; - } - - case HostRoot: { - popHostContainer(interruptedWork); - popTopLevelContextObject(interruptedWork); - break; + default: + break; } + } +} - case HostComponent: { - popHostContext(interruptedWork); +function commitLifeCycles( + finishedRoot, + current$$1, + finishedWork, + committedExpirationTime +) { + switch (finishedWork.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + commitHookEffectList(UnmountLayout, MountLayout, finishedWork); break; } - case HostPortal: - popHostContainer(interruptedWork); - break; - - case SuspenseComponent: - popSuspenseContext(interruptedWork); - break; - - case SuspenseListComponent: - popSuspenseContext(interruptedWork); - break; + case ClassComponent: { + var instance = finishedWork.stateNode; - case ContextProvider: - popProvider(interruptedWork); - break; - } -} + if (finishedWork.effectTag & Update) { + if (current$$1 === null) { + startPhaseTimer(finishedWork, "componentDidMount"); // 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 + ) { + !(instance.props === finishedWork.memoizedProps) + ? warning$1( + false, + "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" + ) + : void 0; + !(instance.state === finishedWork.memoizedState) + ? warning$1( + false, + "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.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ) + : void 0; + } + } + instance.componentDidMount(); + stopPhaseTimer(); + } else { + var prevProps = + finishedWork.elementType === finishedWork.type + ? current$$1.memoizedProps + : resolveDefaultProps( + finishedWork.type, + current$$1.memoizedProps + ); + var prevState = current$$1.memoizedState; + startPhaseTimer(finishedWork, "componentDidUpdate"); // 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. -// Module provided by RN: + { + if ( + finishedWork.type === finishedWork.elementType && + !didWarnAboutReassigningProps + ) { + !(instance.props === finishedWork.memoizedProps) + ? warning$1( + false, + "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" + ) + : void 0; + !(instance.state === finishedWork.memoizedState) + ? warning$1( + false, + "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.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ) + : void 0; + } + } + instance.componentDidUpdate( + prevProps, + prevState, + instance.__reactInternalSnapshotBeforeUpdate + ); + stopPhaseTimer(); + } + } -if ( - !( - typeof ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog === - "function" - ) -) { - throw Error( - "Expected ReactFiberErrorDialog.showErrorDialog to be a function." - ); -} + var updateQueue = finishedWork.updateQueue; -function showErrorDialog(capturedError) { - return ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog( - capturedError - ); -} + if (updateQueue !== null) { + { + if ( + finishedWork.type === finishedWork.elementType && + !didWarnAboutReassigningProps + ) { + !(instance.props === finishedWork.memoizedProps) + ? warning$1( + false, + "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" + ) + : void 0; + !(instance.state === finishedWork.memoizedState) + ? warning$1( + false, + "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.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ) + : void 0; + } + } // 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(capturedError) { - var logError = showErrorDialog(capturedError); // Allow injected showErrorDialog() to prevent default console.error logging. - // This enables renderers like ReactNative to better manage redbox behavior. + commitUpdateQueue( + finishedWork, + updateQueue, + instance, + committedExpirationTime + ); + } - if (logError === false) { - return; - } + return; + } - var error = capturedError.error; + case HostRoot: { + var _updateQueue = finishedWork.updateQueue; - { - var componentName = capturedError.componentName, - componentStack = capturedError.componentStack, - errorBoundaryName = capturedError.errorBoundaryName, - errorBoundaryFound = capturedError.errorBoundaryFound, - willRetry = capturedError.willRetry; // Browsers support silencing uncaught errors by calling - // `preventDefault()` in window `error` handler. - // We record this information as an expando on the error. + if (_updateQueue !== null) { + var _instance = null; - if (error != null && error._suppressLogging) { - if (errorBoundaryFound && willRetry) { - // 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 (finishedWork.child !== null) { + switch (finishedWork.child.tag) { + case HostComponent: + _instance = getPublicInstance(finishedWork.child.stateNode); + break; + case ClassComponent: + _instance = finishedWork.child.stateNode; + break; + } + } + commitUpdateQueue( + finishedWork, + _updateQueue, + _instance, + committedExpirationTime + ); + } - 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; } - var componentNameMessage = componentName - ? "The above error occurred in the <" + componentName + "> component:" - : "The above error occurred in one of your React components:"; - var errorBoundaryMessage; // errorBoundaryFound check is sufficient; errorBoundaryName check is to satisfy Flow. + 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 (errorBoundaryFound && errorBoundaryName) { - if (willRetry) { - errorBoundaryMessage = - "React will try to recreate this component tree from scratch " + - ("using the error boundary you provided, " + errorBoundaryName + "."); - } else { - errorBoundaryMessage = - "This error was initially handled by the error boundary " + - errorBoundaryName + - ".\n" + - "Recreating the tree from scratch failed so React will unmount the tree."; + if (current$$1 === null && finishedWork.effectTag & Update) { + var type = finishedWork.type; + var props = finishedWork.memoizedProps; + commitMount(_instance2, type, props, finishedWork); } - } else { - errorBoundaryMessage = - "Consider adding an error boundary to your tree to customize error handling behavior.\n" + - "Visit https://fb.me/react-error-boundaries to learn more about error boundaries."; - } - var combinedMessage = - "" + - componentNameMessage + - 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; + } + case HostText: { + // We have no life-cycles associated with text. + return; + } + case HostPortal: { + // We have no life-cycles associated with portals. + return; + } + case Profiler: { + if (enableProfilerTimer) { + var onRender = finishedWork.memoizedProps.onRender; - console["error"](combinedMessage); // Don't transform to our wrapper - } -} + if (typeof onRender === "function") { + if (enableSchedulerTracing) { + onRender( + finishedWork.memoizedProps.id, + current$$1 === null ? "mount" : "update", + finishedWork.actualDuration, + finishedWork.treeBaseDuration, + finishedWork.actualStartTime, + getCommitTime(), + finishedRoot.memoizedInteractions + ); + } else { + onRender( + finishedWork.memoizedProps.id, + current$$1 === null ? "mount" : "update", + finishedWork.actualDuration, + finishedWork.treeBaseDuration, + finishedWork.actualStartTime, + getCommitTime() + ); + } + } + } -var didWarnAboutUndefinedSnapshotBeforeUpdate = null; + return; + } -{ - didWarnAboutUndefinedSnapshotBeforeUpdate = new Set(); -} + case SuspenseComponent: { + commitSuspenseHydrationCallbacks(finishedRoot, finishedWork); + return; + } -var PossiblyWeakSet = typeof WeakSet === "function" ? WeakSet : Set; -function logError(boundary, errorInfo) { - var source = errorInfo.source; - var stack = errorInfo.stack; + case SuspenseListComponent: + case IncompleteClassComponent: + case FundamentalComponent: + case ScopeComponent: + return; - if (stack === null && source !== null) { - stack = getStackByFiberInDevAndProd(source); + 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." + ); + } + } } +} - var capturedError = { - componentName: source !== null ? getComponentName(source.type) : null, - componentStack: stack !== null ? stack : "", - error: errorInfo.value, - errorBoundary: null, - errorBoundaryName: null, - errorBoundaryFound: false, - willRetry: false - }; - - if (boundary !== null && boundary.tag === ClassComponent) { - capturedError.errorBoundary = boundary.stateNode; - capturedError.errorBoundaryName = getComponentName(boundary.type); - capturedError.errorBoundaryFound = true; - capturedError.willRetry = true; - } +function hideOrUnhideAllChildren(finishedWork, isHidden) { + if (supportsMutation) { + // 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; - try { - logCapturedError(capturedError); - } 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; - }); - } -} + while (true) { + if (node.tag === HostComponent) { + var instance = node.stateNode; -var callComponentWillUnmountWithTimer = function(current, instance) { - startPhaseTimer(current, "componentWillUnmount"); - instance.props = current.memoizedProps; - instance.state = current.memoizedState; + if (isHidden) { + hideInstance(instance); + } else { + unhideInstance(node.stateNode, node.memoizedProps); + } + } else if (node.tag === HostText) { + var _instance3 = node.stateNode; + if (isHidden) { + hideTextInstance(_instance3); + } else { + unhideTextInstance(_instance3, node.memoizedProps); + } + } else if ( + node.tag === SuspenseComponent && + node.memoizedState !== null && + node.memoizedState.dehydrated === null + ) { + // Found a nested Suspense component that timed out. Skip over the + // primary child fragment, which should remain hidden. + var fallbackChildFragment = node.child.sibling; + fallbackChildFragment.return = node; + node = fallbackChildFragment; + continue; + } else if (node.child !== null) { + node.child.return = node; + node = node.child; + continue; + } - { - instance.componentWillUnmount(); - } + if (node === finishedWork) { + return; + } - stopPhaseTimer(); -}; // Capture errors so they don't interrupt unmounting. + while (node.sibling === null) { + if (node.return === null || node.return === finishedWork) { + return; + } -function safelyCallComponentWillUnmount(current, instance) { - { - invokeGuardedCallback( - null, - callComponentWillUnmountWithTimer, - null, - current, - instance - ); + node = node.return; + } - if (hasCaughtError()) { - var unmountError = clearCaughtError(); - captureCommitPhaseError(current, unmountError); + 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 (enableScopeAPI && finishedWork.tag === ScopeComponent) { + instanceToUse = instance.methods; + } + if (typeof ref === "function") { + ref(instanceToUse); + } else { { - invokeGuardedCallback(null, ref, null, null); - - if (hasCaughtError()) { - var refError = clearCaughtError(); - captureCommitPhaseError(current, refError); + if (!ref.hasOwnProperty("current")) { + warningWithoutStack$1( + false, + "Unexpected ref object provided for %s. " + + "Use either a ref-setter function or React.createRef().%s", + getComponentName(finishedWork.type), + getStackByFiberInDevAndProd(finishedWork) + ); } } - } else { - ref.current = null; + + ref.current = instanceToUse; } } } -function safelyCallDestroy(current, destroy) { - { - invokeGuardedCallback(null, destroy, null); - - if (hasCaughtError()) { - var error = clearCaughtError(); - captureCommitPhaseError(current, error); +function commitDetachRef(current$$1) { + var currentRef = current$$1.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 commitBeforeMutationLifeCycles(current, finishedWork) { - switch (finishedWork.tag) { +function commitUnmount(finishedRoot, current$$1, renderPriorityLevel) { + onCommitUnmount(current$$1); + + switch (current$$1.tag) { case FunctionComponent: case ForwardRef: - case SimpleMemoComponent: - case Block: { - return; + case MemoComponent: + case SimpleMemoComponent: { + var updateQueue = current$$1.updateQueue; + + if (updateQueue !== null) { + var lastEffect = updateQueue.lastEffect; + + if (lastEffect !== null) { + var firstEffect = lastEffect.next; // When the owner fiber is deleted, the destroy function of a passive + // effect hook is called during the synchronous commit phase. This is + // a concession to implementation complexity. Calling it in the + // passive effect phase (like they usually are, when dependencies + // change during an update) would require either traversing the + // children of the deleted fiber again, or including unmount effects + // as part of the fiber effect list. + // + // Because this is during the sync commit phase, we need to change + // the priority. + // + // TODO: Reconsider this implementation trade off. + var priorityLevel = + renderPriorityLevel > NormalPriority + ? NormalPriority + : renderPriorityLevel; + runWithPriority$1(priorityLevel, function() { + var effect = firstEffect; + + do { + var destroy = effect.destroy; + + if (destroy !== undefined) { + safelyCallDestroy(current$$1, destroy); + } + + effect = effect.next; + } while (effect !== firstEffect); + }); + } + } + + break; } case ClassComponent: { - if (finishedWork.effectTag & Snapshot) { - if (current !== null) { - var prevProps = current.memoizedProps; - var prevState = current.memoizedState; - startPhaseTimer(finishedWork, "getSnapshotBeforeUpdate"); - 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. + safelyDetachRef(current$$1); + var instance = current$$1.stateNode; - { - 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 instance.componentWillUnmount === "function") { + safelyCallComponentWillUnmount(current$$1, instance); + } - 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" - ); - } - } - } + return; + } - var snapshot = instance.getSnapshotBeforeUpdate( - finishedWork.elementType === finishedWork.type - ? prevProps - : resolveDefaultProps(finishedWork.type, prevProps), - prevState - ); + case HostComponent: { + if (enableFlareAPI) { + var dependencies = current$$1.dependencies; - { - var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate; + if (dependencies !== null) { + var respondersMap = dependencies.responders; - if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) { - didWarnSet.add(finishedWork.type); + if (respondersMap !== null) { + var responderInstances = Array.from(respondersMap.values()); - error( - "%s.getSnapshotBeforeUpdate(): A snapshot value (or null) " + - "must be returned. You have returned undefined.", - getComponentName(finishedWork.type) - ); + for ( + var i = 0, length = responderInstances.length; + i < length; + i++ + ) { + var responderInstance = responderInstances[i]; + unmountResponderInstance(responderInstance); } + dependencies.responders = null; } - - instance.__reactInternalSnapshotBeforeUpdate = snapshot; - stopPhaseTimer(); } } + safelyDetachRef(current$$1); return; } - case HostRoot: - case HostComponent: - case HostText: - case HostPortal: - case IncompleteClassComponent: - // Nothing to do for these component types + case HostPortal: { + // TODO: this is recursive. + // We are also not using this parent because + // the portal will get pushed immediately. + if (supportsMutation) { + unmountHostComponents(finishedRoot, current$$1, renderPriorityLevel); + } else if (supportsPersistence) { + emptyPortalContainer(current$$1); + } + 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 FundamentalComponent: { + if (enableFundamentalAPI) { + var fundamentalInstance = current$$1.stateNode; -function commitHookEffectListUnmount(tag, finishedWork) { - var updateQueue = finishedWork.updateQueue; - var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; + if (fundamentalInstance !== null) { + unmountFundamentalComponent(fundamentalInstance); + current$$1.stateNode = null; + } + } - if (lastEffect !== null) { - var firstEffect = lastEffect.next; - var effect = firstEffect; + return; + } - do { - if ((effect.tag & tag) === tag) { - // Unmount - var destroy = effect.destroy; - effect.destroy = undefined; + case DehydratedFragment: { + if (enableSuspenseCallback) { + var hydrationCallbacks = finishedRoot.hydrationCallbacks; - if (destroy !== undefined) { - destroy(); + if (hydrationCallbacks !== null) { + var onDeleted = hydrationCallbacks.onDeleted; + + if (onDeleted) { + onDeleted(current$$1.stateNode); + } } } - effect = effect.next; - } while (effect !== firstEffect); + return; + } + + case ScopeComponent: { + if (enableScopeAPI) { + safelyDetachRef(current$$1); + } + } } } -function commitHookEffectListMount(tag, finishedWork) { - var updateQueue = finishedWork.updateQueue; - var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; +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 (lastEffect !== null) { - var firstEffect = lastEffect.next; - var effect = firstEffect; + while (true) { + commitUnmount(finishedRoot, node, renderPriorityLevel); // 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) { - // Mount - var create = effect.create; - effect.destroy = create(); + 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.tag !== HostPortal) + ) { + node.child.return = node; + node = node.child; + continue; + } - { - var destroy = effect.destroy; + if (node === root) { + return; + } - if (destroy !== undefined && typeof destroy !== "function") { - var addendum = void 0; + while (node.sibling === null) { + if (node.return === null || node.return === root) { + 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://fb.me/react-hooks-data-fetching"; - } else { - addendum = " You returned: " + destroy; - } + node = node.return; + } - error( - "An effect function must not return anything besides a function, " + - "which is used for clean-up.%s%s", - addendum, - getStackByFiberInDevAndProd(finishedWork) - ); - } - } - } + node.sibling.return = node.return; + node = node.sibling; + } +} + +function detachFiber(current$$1) { + var alternate = current$$1.alternate; // 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. + current$$1.return = null; + current$$1.child = null; + current$$1.memoizedState = null; + current$$1.updateQueue = null; + current$$1.dependencies = null; + current$$1.alternate = null; + current$$1.firstEffect = null; + current$$1.lastEffect = null; + current$$1.pendingProps = null; + current$$1.memoizedProps = null; + if (alternate !== null) { + detachFiber(alternate); + } +} + +function emptyPortalContainer(current$$1) { + if (!supportsPersistence) { + return; + } + + var portal = current$$1.stateNode; + var containerInfo = portal.containerInfo; + var emptyChildSet = createContainerChildSet(containerInfo); +} + +function commitContainer(finishedWork) { + if (!supportsPersistence) { + return; + } + + switch (finishedWork.tag) { + case ClassComponent: + case HostComponent: + case HostText: + case FundamentalComponent: { + return; + } + case HostRoot: + case HostPortal: { + var portalOrRoot = finishedWork.stateNode; + var containerInfo = portalOrRoot.containerInfo, + pendingChildren = portalOrRoot.pendingChildren; + return; + } - effect = effect.next; - } while (effect !== firstEffect); + 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." + ); + } + } } } -function commitPassiveHookEffects(finishedWork) { - if ((finishedWork.effectTag & Passive) !== NoEffect) { - switch (finishedWork.tag) { - case FunctionComponent: - case ForwardRef: - case SimpleMemoComponent: - case Block: { - // TODO (#17945) We should call all passive destroy functions (for all fibers) - // before calling any create functions. The current approach only serializes - // these for a single fiber. - { - commitHookEffectListUnmount(Passive$1 | HasEffect, finishedWork); - commitHookEffectListMount(Passive$1 | HasEffect, finishedWork); - } - - break; - } +function getHostParentFiber(fiber) { + var parent = fiber.return; + while (parent !== null) { + if (isHostParent(parent)) { + return parent; } + + 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." + ); } } -function commitLifeCycles( - finishedRoot, - current, - finishedWork, - committedExpirationTime -) { - switch (finishedWork.tag) { - case FunctionComponent: - case ForwardRef: - case SimpleMemoComponent: - case Block: { - // 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 isHostParent(fiber) { + return ( + fiber.tag === HostComponent || + fiber.tag === HostRoot || + fiber.tag === HostPortal + ); +} + +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; + + 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; } - return; + node = node.return; } - case ClassComponent: { - var instance = finishedWork.stateNode; + node.sibling.return = node.return; + node = node.sibling; - if (finishedWork.effectTag & Update) { - if (current === null) { - startPhaseTimer(finishedWork, "componentDidMount"); // 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 ( + 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.effectTag & 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 ( - 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 (!(node.effectTag & Placement)) { + // Found it! + return node.stateNode; + } + } +} - 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 commitPlacement(finishedWork) { + if (!supportsMutation) { + return; + } // Recursively insert all host nodes into the parent. - { - instance.componentDidMount(); - } + var parentFiber = getHostParentFiber(finishedWork); // Note: these two variables *must* always be updated together. - stopPhaseTimer(); - } else { - var prevProps = - finishedWork.elementType === finishedWork.type - ? current.memoizedProps - : resolveDefaultProps(finishedWork.type, current.memoizedProps); - var prevState = current.memoizedState; - startPhaseTimer(finishedWork, "componentDidUpdate"); // 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 parent; + var isContainer; + var parentStateNode = parentFiber.stateNode; - { - 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" - ); - } + 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: + if (enableFundamentalAPI) { + parent = parentStateNode.instance; + isContainer = false; + } - 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" - ); - } - } - } + // eslint-disable-next-line-no-fallthrough - { - instance.componentDidUpdate( - prevProps, - prevState, - instance.__reactInternalSnapshotBeforeUpdate - ); - } + default: { + throw Error( + "Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue." + ); + } + } - stopPhaseTimer(); - } - } + if (parentFiber.effectTag & ContentReset) { + // Reset the text content of the parent before doing any insertions + resetTextContent(parent); // Clear ContentReset from the effect tag - var updateQueue = finishedWork.updateQueue; + parentFiber.effectTag &= ~ContentReset; + } - 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" - ); - } + 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 (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. + var node = finishedWork; + + while (true) { + var isHost = node.tag === HostComponent || node.tag === HostText; + + if (isHost || (enableFundamentalAPI && node.tag === FundamentalComponent)) { + var stateNode = isHost ? node.stateNode : node.stateNode.instance; - commitUpdateQueue(finishedWork, updateQueue, instance); + if (before) { + if (isContainer) { + insertInContainerBefore(parent, stateNode, before); + } else { + insertBefore(parent, stateNode, before); + } + } else { + if (isContainer) { + appendChildToContainer(parent, stateNode); + } else { + appendChild(parent, stateNode); + } } + } else if (node.tag === HostPortal) { + // If the insertion itself is a portal, then we don't want to traverse + // down its children. Instead, we'll get insertions from each child in + // the portal directly. + } else if (node.child !== null) { + node.child.return = node; + node = node.child; + continue; + } + if (node === finishedWork) { return; } - case HostRoot: { - var _updateQueue = finishedWork.updateQueue; + while (node.sibling === null) { + if (node.return === null || node.return === finishedWork) { + return; + } - if (_updateQueue !== null) { - var _instance = null; + node = node.return; + } - if (finishedWork.child !== null) { - switch (finishedWork.child.tag) { - case HostComponent: - _instance = getPublicInstance(finishedWork.child.stateNode); - break; + node.sibling.return = node.return; + node = node.sibling; + } +} - case ClassComponent: - _instance = finishedWork.child.stateNode; - break; - } - } +function unmountHostComponents(finishedRoot, current$$1, 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$$1; // Each iteration, currentParent is populated with node's host parent if not + // currentParentIsValid. - commitUpdateQueue(finishedWork, _updateQueue, _instance); - } + 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.effectTag & Update) { - var type = finishedWork.type; - var props = finishedWork.memoizedProps; - commitMount(); + 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 parentStateNode = parent.stateNode; + + switch (parent.tag) { + case HostComponent: + currentParent = parentStateNode; + currentParentIsContainer = false; + break findParent; + case HostRoot: + currentParent = parentStateNode.containerInfo; + currentParentIsContainer = true; + break findParent; + case HostPortal: + currentParent = parentStateNode.containerInfo; + currentParentIsContainer = true; + break findParent; + case FundamentalComponent: + if (enableFundamentalAPI) { + currentParent = parentStateNode.instance; + currentParentIsContainer = false; + } + } + + parent = parent.return; } - return; + currentParentIsValid = true; } - case HostText: { - // We have no life-cycles associated with text. - return; - } + if (node.tag === HostComponent || node.tag === HostText) { + commitNestedUnmounts(finishedRoot, node, renderPriorityLevel); // After all the children have unmounted, it is now safe to remove the + // node from the tree. - case HostPortal: { - // We have no life-cycles associated with portals. - return; - } + if (currentParentIsContainer) { + removeChildFromContainer(currentParent, node.stateNode); + } else { + removeChild(currentParent, node.stateNode); + } // Don't visit children because we already visited them. + } else if (enableFundamentalAPI && node.tag === FundamentalComponent) { + var fundamentalNode = node.stateNode.instance; + commitNestedUnmounts(finishedRoot, node, renderPriorityLevel); // After all the children have unmounted, it is now safe to remove the + // node from the tree. + + if (currentParentIsContainer) { + removeChildFromContainer(currentParent, fundamentalNode); + } else { + removeChild(currentParent, fundamentalNode); + } + } else if ( + enableSuspenseServerRenderer && + node.tag === DehydratedFragment + ) { + if (enableSuspenseCallback) { + var hydrationCallbacks = finishedRoot.hydrationCallbacks; - case Profiler: { - { - var _finishedWork$memoize2 = finishedWork.memoizedProps, - onCommit = _finishedWork$memoize2.onCommit, - onRender = _finishedWork$memoize2.onRender; - var effectDuration = finishedWork.stateNode.effectDuration; - var commitTime = getCommitTime(); + if (hydrationCallbacks !== null) { + var onDeleted = hydrationCallbacks.onDeleted; - if (typeof onRender === "function") { - { - onRender( - finishedWork.memoizedProps.id, - current === null ? "mount" : "update", - finishedWork.actualDuration, - finishedWork.treeBaseDuration, - finishedWork.actualStartTime, - commitTime, - finishedRoot.memoizedInteractions - ); + if (onDeleted) { + onDeleted(node.stateNode); } } - } + } // Delete the dehydrated suspense boundary and all of its content. - return; - } + if (currentParentIsContainer) { + clearSuspenseBoundaryFromContainer(currentParent, node.stateNode); + } else { + clearSuspenseBoundary(currentParent, node.stateNode); + } + } 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 SuspenseComponent: { - return; - } + node.child.return = node; + node = node.child; + continue; + } + } else { + commitUnmount(finishedRoot, node, renderPriorityLevel); // Visit children because we may find more host components below. - case SuspenseListComponent: - case IncompleteClassComponent: - case FundamentalComponent: - case ScopeComponent: + if (node.child !== null) { + node.child.return = node; + node = node.child; + continue; + } + } + + if (node === current$$1) { 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." - ); + while (node.sibling === null) { + if (node.return === null || node.return === current$$1) { + 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; } } -function commitAttachRef(finishedWork) { - var ref = finishedWork.ref; +function commitDeletion(finishedRoot, current$$1, renderPriorityLevel) { + if (supportsMutation) { + // Recursively delete all host nodes from the parent. + // Detach refs and call componentWillUnmount() on the whole subtree. + unmountHostComponents(finishedRoot, current$$1, renderPriorityLevel); + } else { + // Detach refs and call componentWillUnmount() on the whole subtree. + commitNestedUnmounts(finishedRoot, current$$1, renderPriorityLevel); + } - if (ref !== null) { - var instance = finishedWork.stateNode; - var instanceToUse; + detachFiber(current$$1); +} +function commitWork(current$$1, finishedWork) { + if (!supportsMutation) { switch (finishedWork.tag) { - case HostComponent: - instanceToUse = getPublicInstance(instance); - break; + case FunctionComponent: + case ForwardRef: + case MemoComponent: + case SimpleMemoComponent: { + // Note: We currently never use MountMutation, but useLayout uses + // UnmountMutation. + commitHookEffectList(UnmountMutation, MountMutation, finishedWork); + return; + } - default: - instanceToUse = instance; - } // Moved outside to ensure DCE works with this flag + case Profiler: { + return; + } - 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().%s", - getComponentName(finishedWork.type), - getStackByFiberInDevAndProd(finishedWork) - ); - } + case SuspenseComponent: { + commitSuspenseComponent(finishedWork); + attachSuspenseRetryListeners(finishedWork); + return; + } + case SuspenseListComponent: { + attachSuspenseRetryListeners(finishedWork); + return; } - ref.current = instanceToUse; - } - } -} + case HostRoot: { + if (supportsHydration) { + var root = finishedWork.stateNode; -function commitDetachRef(current) { - var currentRef = current.ref; + if (root.hydrate) { + // We've just hydrated. No need to hydrate again. + root.hydrate = false; + commitHydratedContainer(root.containerInfo); + } + } - if (currentRef !== null) { - if (typeof currentRef === "function") { - currentRef(null); - } else { - currentRef.current = null; + break; + } } - } -} // 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); + commitContainer(finishedWork); + return; + } - switch (current.tag) { + switch (finishedWork.tag) { case FunctionComponent: case ForwardRef: case MemoComponent: - case SimpleMemoComponent: - case Block: { - var updateQueue = current.updateQueue; + case SimpleMemoComponent: { + // Note: We currently never use MountMutation, but useLayout uses + // UnmountMutation. + commitHookEffectList(UnmountMutation, MountMutation, finishedWork); + return; + } - if (updateQueue !== null) { - var lastEffect = updateQueue.lastEffect; + case ClassComponent: { + return; + } - if (lastEffect !== null) { - var firstEffect = lastEffect.next; + case HostComponent: { + var instance = finishedWork.stateNode; - { - // When the owner fiber is deleted, the destroy function of a passive - // effect hook is called during the synchronous commit phase. This is - // a concession to implementation complexity. Calling it in the - // passive effect phase (like they usually are, when dependencies - // change during an update) would require either traversing the - // children of the deleted fiber again, or including unmount effects - // as part of the fiber effect list. - // - // Because this is during the sync commit phase, we need to change - // the priority. - // - // TODO: Reconsider this implementation trade off. - var priorityLevel = - renderPriorityLevel > NormalPriority - ? NormalPriority - : renderPriorityLevel; - runWithPriority(priorityLevel, function() { - var effect = firstEffect; - - do { - var _effect3 = effect, - _destroy = _effect3.destroy, - _tag = _effect3.tag; - - if (_destroy !== undefined) { - { - safelyCallDestroy(current, _destroy); - } - } + 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. + + var oldProps = + current$$1 !== null ? current$$1.memoizedProps : newProps; + var type = finishedWork.type; // TODO: Type the updateQueue to be specific to host components. + + var updatePayload = finishedWork.updateQueue; + finishedWork.updateQueue = null; + + if (updatePayload !== null) { + commitUpdate( + instance, + updatePayload, + type, + oldProps, + newProps, + finishedWork + ); + } + + if (enableFlareAPI) { + var prevListeners = oldProps.listeners; + var nextListeners = newProps.listeners; - effect = effect.next; - } while (effect !== firstEffect); - }); + if (prevListeners !== nextListeners) { + updateEventListeners(nextListeners, finishedWork, null); } } } @@ -15839,199 +18935,164 @@ function commitUnmount(finishedRoot, current, renderPriorityLevel) { 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." + ); } - return; - } + 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. - case HostComponent: { - safelyDetachRef(current); + var oldText = current$$1 !== null ? current$$1.memoizedProps : newText; + commitTextUpdate(textInstance, oldText, newText); return; } - case HostPortal: { - // TODO: this is recursive. - // We are also not using this parent because - // the portal will get pushed immediately. - { - emptyPortalContainer(current); + case HostRoot: { + if (supportsHydration) { + var _root = finishedWork.stateNode; + + if (_root.hydrate) { + // We've just hydrated. No need to hydrate again. + _root.hydrate = false; + commitHydratedContainer(_root.containerInfo); + } } return; } - case FundamentalComponent: { + case Profiler: { return; } - case DehydratedFragment: { + case SuspenseComponent: { + commitSuspenseComponent(finishedWork); + attachSuspenseRetryListeners(finishedWork); return; } - - case ScopeComponent: { + case SuspenseListComponent: { + attachSuspenseRetryListeners(finishedWork); return; } - } -} - -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, renderPriorityLevel); // 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 IncompleteClassComponent: { return; } - while (node.sibling === null) { - if (node.return === null || node.return === root) { - return; + case FundamentalComponent: { + if (enableFundamentalAPI) { + var fundamentalInstance = finishedWork.stateNode; + updateFundamentalComponent(fundamentalInstance); } - node = node.return; + return; } - node.sibling.return = node.return; - node = node.sibling; - } -} + case ScopeComponent: { + if (enableScopeAPI) { + var scopeInstance = finishedWork.stateNode; + scopeInstance.fiber = finishedWork; -function detachFiber(current) { - var alternate = current.alternate; // 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. + if (enableFlareAPI) { + var _newProps = finishedWork.memoizedProps; - current.return = null; - current.child = null; - current.memoizedState = null; - current.updateQueue = null; - current.dependencies = null; - current.alternate = null; - current.firstEffect = null; - current.lastEffect = null; - current.pendingProps = null; - current.memoizedProps = null; - current.stateNode = null; + var _oldProps = + current$$1 !== null ? current$$1.memoizedProps : _newProps; - if (alternate !== null) { - detachFiber(alternate); - } -} + var _prevListeners = _oldProps.listeners; + var _nextListeners = _newProps.listeners; -function emptyPortalContainer(current) { - var portal = current.stateNode; - var containerInfo = portal.containerInfo; - var emptyChildSet = createContainerChildSet(containerInfo); -} + if (_prevListeners !== _nextListeners) { + updateEventListeners(_nextListeners, finishedWork, null); + } + } + } -function commitContainer(finishedWork) { - switch (finishedWork.tag) { - case ClassComponent: - case HostComponent: - case HostText: - case FundamentalComponent: { return; } - case HostRoot: - case HostPortal: { - var portalOrRoot = finishedWork.stateNode; - var containerInfo = portalOrRoot.containerInfo, - pendingChildren = portalOrRoot.pendingChildren; - return; + 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." + ); + } } } - - { - 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, renderPriorityLevel) { - { - // Detach refs and call componentWillUnmount() on the whole subtree. - commitNestedUnmounts(finishedRoot, current, renderPriorityLevel); - } +function commitSuspenseComponent(finishedWork) { + var newState = finishedWork.memoizedState; + var newDidTimeout; + var primaryChildParent = finishedWork; - detachFiber(current); -} + if (newState === null) { + newDidTimeout = false; + } else { + newDidTimeout = true; + primaryChildParent = finishedWork.child; + markCommitTimeOfFallback(); + } -function commitWork(current, finishedWork) { - { - switch (finishedWork.tag) { - case FunctionComponent: - case ForwardRef: - case MemoComponent: - case SimpleMemoComponent: - case Block: { - // 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); - } + if (supportsMutation && primaryChildParent !== null) { + hideOrUnhideAllChildren(primaryChildParent, newDidTimeout); + } - return; - } + if (enableSuspenseCallback && newState !== null) { + var suspenseCallback = finishedWork.memoizedProps.suspenseCallback; - case Profiler: { - return; - } + if (typeof suspenseCallback === "function") { + var thenables = finishedWork.updateQueue; - case SuspenseComponent: { - commitSuspenseComponent(finishedWork); - attachSuspenseRetryListeners(finishedWork); - return; + if (thenables !== null) { + suspenseCallback(new Set(thenables)); } - - case SuspenseListComponent: { - attachSuspenseRetryListeners(finishedWork); - return; + } else { + if (suspenseCallback !== undefined) { + warning$1(false, "Unexpected type for suspenseCallback."); } } + } +} - commitContainer(finishedWork); +function commitSuspenseHydrationCallbacks(finishedRoot, finishedWork) { + if (!supportsHydration) { return; } -} -function commitSuspenseComponent(finishedWork) { var newState = finishedWork.memoizedState; - var primaryChildParent = finishedWork; - if (newState === null); - else { - primaryChildParent = finishedWork.child; - markCommitTimeOfFallback(); + if (newState === null) { + var current$$1 = finishedWork.alternate; + + if (current$$1 !== null) { + var prevState = current$$1.memoizedState; + + if (prevState !== null) { + var suspenseInstance = prevState.dehydrated; + + if (suspenseInstance !== null) { + commitHydratedSuspenseInstance(suspenseInstance); + + if (enableSuspenseCallback) { + var hydrationCallbacks = finishedRoot.hydrationCallbacks; + + if (hydrationCallbacks !== null) { + var onHydrated = hydrationCallbacks.onHydrated; + + if (onHydrated) { + onHydrated(suspenseInstance); + } + } + } + } + } + } } } @@ -16054,7 +19115,7 @@ function attachSuspenseRetryListeners(finishedWork) { var retry = resolveRetryThenable.bind(null, finishedWork, thenable); if (!retryCache.has(thenable)) { - { + if (enableSchedulerTracing) { if (thenable.__reactDoNotTraceInteractions !== true) { retry = tracing.unstable_wrap(retry); } @@ -16067,6 +19128,14 @@ function attachSuspenseRetryListeners(finishedWork) { } } +function commitResetTextContent(current$$1) { + if (!supportsMutation) { + return; + } + + resetTextContent(current$$1.stateNode); +} + var PossiblyWeakMap = typeof WeakMap === "function" ? WeakMap : Map; function createRootErrorUpdate(fiber, errorInfo, expirationTime) { @@ -16084,7 +19153,6 @@ function createRootErrorUpdate(fiber, errorInfo, expirationTime) { onUncaughtError(error); logError(fiber, errorInfo); }; - return update; } @@ -16094,22 +19162,20 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { var getDerivedStateFromError = fiber.type.getDerivedStateFromError; if (typeof getDerivedStateFromError === "function") { - var error$1 = errorInfo.value; + var error = errorInfo.value; update.payload = function() { logError(fiber, errorInfo); - return getDerivedStateFromError(error$1); + return getDerivedStateFromError(error); }; } var inst = fiber.stateNode; - if (inst !== null && typeof inst.componentDidCatch === "function") { update.callback = function callback() { { markFailedErrorBoundaryForHotReloading(fiber); } - if (typeof getDerivedStateFromError !== "function") { // To preserve the preexisting retry behavior of error boundaries, // we keep track of which ones already failed during this batch. @@ -16121,24 +19187,24 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { logError(fiber, errorInfo); } - var error$1 = errorInfo.value; + var error = errorInfo.value; var stack = errorInfo.stack; - this.componentDidCatch(error$1, { + this.componentDidCatch(error, { 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 (fiber.expirationTime !== Sync) { - 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" - ); - } + !(fiber.expirationTime === Sync) + ? warningWithoutStack$1( + false, + "%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" + ) + : void 0; } } }; @@ -16147,7 +19213,6 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { markFailedErrorBoundaryForHotReloading(fiber); }; } - return update; } @@ -16164,13 +19229,11 @@ function attachPingListener(root, renderExpirationTime, thenable) { pingCache.set(thenable, threadIDs); } else { threadIDs = pingCache.get(thenable); - if (threadIDs === undefined) { threadIDs = new Set(); pingCache.set(thenable, threadIDs); } } - if (!threadIDs.has(renderExpirationTime)) { // Memoize using the thread ID to prevent redundant listeners. threadIDs.add(renderExpirationTime); @@ -16203,22 +19266,7 @@ function throwException( ) { // This is a thenable. var thenable = 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.expirationTime = currentSource.expirationTime; - } else { - sourceFiber.updateQueue = null; - sourceFiber.memoizedState = null; - } - } - + checkForWrongSuspensePriorityInDEV(sourceFiber); var hasInvisibleParentBoundary = hasSuspenseContext( suspenseStackCursor.current, InvisibleParentSuspenseContext @@ -16260,7 +19308,6 @@ function throwException( 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 @@ -16354,7 +19401,6 @@ function throwException( var _errorInfo = value; workInProgress.effectTag |= ShouldCapture; workInProgress.expirationTime = renderExpirationTime; - var _update = createRootErrorUpdate( workInProgress, _errorInfo, @@ -16370,7 +19416,6 @@ function throwException( var errorInfo = value; var ctor = workInProgress.type; var instance = workInProgress.stateNode; - if ( (workInProgress.effectTag & DidCapture) === NoEffect && (typeof ctor.getDerivedStateFromError === "function" || @@ -16392,6 +19437,9 @@ function throwException( } break; + + default: + break; } workInProgress = workInProgress.return; @@ -16399,15 +19447,18 @@ function throwException( } var ceil = Math.ceil; -var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, - ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, - IsSomeRendererActing = ReactSharedInternals.IsSomeRendererActing; +var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher; +var ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner; +var IsSomeRendererActing = ReactSharedInternals.IsSomeRendererActing; var NoContext = /* */ 0; var BatchedContext = /* */ 1; +var EventContext = + /* */ + 2; var DiscreteEventContext = /* */ 4; @@ -16433,7 +19484,7 @@ var workInProgressRoot = null; // The fiber we're working on var workInProgress = null; // The expiration time we're rendering -var renderExpirationTime$1 = NoWork; // Whether to root completed, errored, suspended, etc. +var renderExpirationTime = NoWork; // Whether to root completed, errored, suspended, etc. var workInProgressRootExitStatus = RootIncomplete; // A fatal error, if one is thrown @@ -16510,7 +19561,6 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { } var priorityLevel = getCurrentPriorityLevel(); - if ((mode & ConcurrentMode) === NoMode) { return priorityLevel === ImmediatePriority ? Sync : Batched; } @@ -16518,7 +19568,7 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { if ((executionContext & RenderContext) !== NoContext) { // Use whatever time we're already rendering // TODO: Should there be a way to opt out, like with `runWithPriority`? - return renderExpirationTime$1; + return renderExpirationTime; } var expirationTime; @@ -16535,12 +19585,10 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { case ImmediatePriority: expirationTime = Sync; break; - - case UserBlockingPriority: + case UserBlockingPriority$1: // TODO: Rename this to computeUserBlockingExpiration expirationTime = computeInteractiveExpiration(currentTime); break; - case NormalPriority: case LowPriority: // TODO: Handle LowPriority @@ -16561,11 +19609,7 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { // TODO: We shouldn't have to do this if the update is on a different root. // Refactor computeExpirationForFiber + scheduleUpdate so we have access to // the root when we check for this condition. - - if ( - workInProgressRoot !== null && - expirationTime === renderExpirationTime$1 - ) { + if (workInProgressRoot !== null && expirationTime === renderExpirationTime) { // This is a trick to move this update into a separate batch expirationTime -= 1; } @@ -16574,7 +19618,7 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { } function scheduleUpdateOnFiber(fiber, expirationTime) { checkForNestedUpdates(); - warnAboutRenderPhaseUpdatesInDEV(fiber); + warnAboutInvalidUpdatesOnClassComponentsInDEV(fiber); var root = markUpdateTimeFromFiberToRoot(fiber, expirationTime); if (root === null) { @@ -16621,7 +19665,7 @@ function scheduleUpdateOnFiber(fiber, expirationTime) { if ( (executionContext & DiscreteEventContext) !== NoContext && // Only updates at user-blocking priority or greater are considered // discrete, even inside a discrete event. - (priorityLevel === UserBlockingPriority || + (priorityLevel === UserBlockingPriority$1 || priorityLevel === ImmediatePriority) ) { // This is the result of a discrete event. Track the lowest priority @@ -16630,7 +19674,6 @@ function scheduleUpdateOnFiber(fiber, expirationTime) { rootsWithPendingDiscreteUpdates = new Map([[root, expirationTime]]); } else { var lastDiscreteTime = rootsWithPendingDiscreteUpdates.get(root); - if (lastDiscreteTime === undefined || lastDiscreteTime > expirationTime) { rootsWithPendingDiscreteUpdates.set(root, expirationTime); } @@ -16678,12 +19721,10 @@ function markUpdateTimeFromFiberToRoot(fiber, expirationTime) { ) { alternate.childExpirationTime = expirationTime; } - if (node.return === null && node.tag === HostRoot) { root = node.stateNode; break; } - node = node.return; } } @@ -16708,7 +19749,7 @@ function markUpdateTimeFromFiberToRoot(fiber, expirationTime) { // scheduled before the root started rendering. Need to track the next // pending expiration time (perhaps by backtracking the return path) and // then trigger a restart in the `renderDidSuspendDelayIfPossible` path. - markRootSuspendedAtTime(root, renderExpirationTime$1); + markRootSuspendedAtTime(root, renderExpirationTime); } } // Mark that the root has a pending update. @@ -16740,17 +19781,9 @@ function getNextRootExpirationTimeToWorkOn(root) { var lastPingedTime = root.lastPingedTime; var nextKnownPendingLevel = root.nextKnownPendingLevel; - var nextLevel = - lastPingedTime > nextKnownPendingLevel - ? lastPingedTime - : nextKnownPendingLevel; - - if (nextLevel <= Idle && firstPendingTime !== nextLevel) { - // Don't work on Idle/Never priority unless everything else is committed. - return NoWork; - } - - return nextLevel; + return lastPingedTime > nextKnownPendingLevel + ? lastPingedTime + : nextKnownPendingLevel; } // 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 // expiration time of the existing task is the same as the expiration time of @@ -16817,6 +19850,11 @@ function ensureRootIsScheduled(root) { if (expirationTime === Sync) { // Sync React callbacks are scheduled on a special internal queue callbackNode = scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root)); + } else if (disableSchedulerTimeoutBasedOnReactExpirationTime) { + callbackNode = scheduleCallback( + priorityLevel, + performConcurrentWorkOnRoot.bind(null, root) + ); } else { callbackNode = scheduleCallback( priorityLevel, @@ -16835,7 +19873,7 @@ function ensureRootIsScheduled(root) { function performConcurrentWorkOnRoot(root, didTimeout) { // 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 = NoWork; // Check if the render expired. + currentEventTime = NoWork; if (didTimeout) { // The render task took too long to complete. Mark the current time as @@ -16850,50 +19888,83 @@ function performConcurrentWorkOnRoot(root, didTimeout) { var expirationTime = getNextRootExpirationTimeToWorkOn(root); - if (expirationTime === NoWork) { - return null; - } + if (expirationTime !== NoWork) { + var originalCallbackNode = root.callbackNode; - var originalCallbackNode = root.callbackNode; + if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { + throw Error("Should not already be working."); + } - if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { - throw Error("Should not already be working."); - } + flushPassiveEffects(); // If the root or expiration time have changed, throw out the existing stack + // and prepare a fresh one. Otherwise we'll continue where we left off. - flushPassiveEffects(); - var exitStatus = renderRootConcurrent(root, expirationTime); + if ( + root !== workInProgressRoot || + expirationTime !== renderExpirationTime + ) { + prepareFreshStack(root, expirationTime); + startWorkOnPendingInteractions(root, expirationTime); + } // If we have a work-in-progress fiber, it means there's still work to do + // in this root. - if (exitStatus !== RootIncomplete) { - if (exitStatus === RootErrored) { - // If something threw an error, try rendering one more time. We'll - // render synchronously to block concurrent data mutations, and we'll - // render at Idle (or lower) so that all pending updates are included. - // If it still fails after the second attempt, we'll give up and commit - // the resulting tree. - expirationTime = expirationTime > Idle ? Idle : expirationTime; - exitStatus = renderRootSync(root, expirationTime); - } + if (workInProgress !== null) { + var prevExecutionContext = executionContext; + executionContext |= RenderContext; + var prevDispatcher = pushDispatcher(root); + var prevInteractions = pushInteractions(root); + startWorkLoopTimer(workInProgress); - if (exitStatus === RootFatalErrored) { - var fatalError = workInProgressRootFatalError; - prepareFreshStack(root, expirationTime); - markRootSuspendedAtTime(root, expirationTime); - ensureRootIsScheduled(root); - throw fatalError; - } // We now have a consistent tree. The next step is either to commit it, - // or, if something suspended, wait to commit it after a timeout. + do { + try { + workLoopConcurrent(); + break; + } catch (thrownValue) { + handleError(root, thrownValue); + } + } while (true); - var finishedWork = (root.finishedWork = root.current.alternate); - root.finishedExpirationTime = expirationTime; - finishConcurrentRender(root, finishedWork, exitStatus, expirationTime); - } + resetContextDependencies(); + executionContext = prevExecutionContext; + popDispatcher(prevDispatcher); - ensureRootIsScheduled(root); + if (enableSchedulerTracing) { + popInteractions(prevInteractions); + } + + if (workInProgressRootExitStatus === RootFatalErrored) { + var fatalError = workInProgressRootFatalError; + stopInterruptedWorkLoopTimer(); + prepareFreshStack(root, expirationTime); + markRootSuspendedAtTime(root, expirationTime); + ensureRootIsScheduled(root); + throw fatalError; + } + + if (workInProgress !== null) { + // There's still work left over. Exit without committing. + stopInterruptedWorkLoopTimer(); + } else { + // We now have a consistent tree. The next step is either to commit it, + // or, if something suspended, wait to commit it after a timeout. + stopFinishedWorkLoopTimer(); + var finishedWork = (root.finishedWork = root.current.alternate); + root.finishedExpirationTime = expirationTime; + finishConcurrentRender( + root, + finishedWork, + workInProgressRootExitStatus, + expirationTime + ); + } + + ensureRootIsScheduled(root); - if (root.callbackNode === originalCallbackNode) { - // The task node scheduled for this root is the same one that's - // currently executed. Need to return a continuation. - return performConcurrentWorkOnRoot.bind(null, root); + if (root.callbackNode === originalCallbackNode) { + // The task node scheduled for this root is the same one that's + // currently executed. Need to return a continuation. + return performConcurrentWorkOnRoot.bind(null, root); + } + } } return null; @@ -16905,6 +19976,9 @@ function finishConcurrentRender( exitStatus, expirationTime ) { + // Set this to null to indicate there's no in-progress render. + workInProgressRoot = null; + switch (exitStatus) { case RootIncomplete: case RootFatalErrored: { @@ -16917,9 +19991,19 @@ function finishConcurrentRender( // if I do. eslint-disable-next-line no-fallthrough case RootErrored: { - // We should have already attempted to retry this tree. If we reached - // this point, it errored again. Commit it. - commitRoot(root); + // If this was an async render, the error may have happened due to + // a mutation in a concurrent event. Try rendering one more time, + // synchronously, to see if the error goes away. If there are + // lower priority updates, let's include those, too, in case they + // fix the inconsistency. Render at Idle to include all updates. + // If it was Idle or Never or some not-yet-invented time, render + // at that time. + markRootExpiredAtTime( + root, + expirationTime > Idle ? Idle : expirationTime + ); // We assume that this second render pass will be synchronous + // and therefore not hit this path again. + break; } @@ -16929,7 +20013,9 @@ function finishConcurrentRender( if (expirationTime === lastSuspendedTime) { root.nextKnownPendingLevel = getRemainingExpirationTime(finishedWork); - } // We have an acceptable loading state. We need to figure out if we + } + + flushSuspensePriorityWarningInDEV(); // We have an acceptable loading state. We need to figure out if we // should immediately commit it or wait a bit. // If we have processed new updates during this render, we may now // have a new loading state ready. We want to ensure that we commit @@ -16940,7 +20026,7 @@ function finishConcurrentRender( if ( hasNotProcessedNewUpdates && // do not delay if we're inside an act() scope - !IsThisRendererActing.current + !(true && flushSuspenseFallbacksInTests && IsThisRendererActing.current) ) { // If we have not processed any new updates during this pass, then // this is either a retry of an existing fallback state or a @@ -17004,7 +20090,12 @@ function finishConcurrentRender( root.nextKnownPendingLevel = getRemainingExpirationTime(finishedWork); } - { + flushSuspensePriorityWarningInDEV(); + + if ( + // do not delay if we're inside an act() scope + !(true && flushSuspenseFallbacksInTests && IsThisRendererActing.current) + ) { // We're suspended in a state that should be avoided. We'll try to // avoid committing it for as long as the timeouts let us. if (workInProgressRootHasPendingPing) { @@ -17059,7 +20150,6 @@ function finishConcurrentRender( var timeUntilExpirationMs = expirationTimeToMs(expirationTime) - currentTimeMs; var timeElapsed = currentTimeMs - eventTimeMs; - if (timeElapsed < 0) { // We get this wrong some time since we estimate the time. timeElapsed = 0; @@ -17094,6 +20184,11 @@ function finishConcurrentRender( // The work completed. Ready to commit. if ( // do not delay if we're inside an act() scope + !( + true && + flushSuspenseFallbacksInTests && + IsThisRendererActing.current + ) && workInProgressRootLatestProcessedExpirationTime !== Sync && workInProgressRootCanSuspendUsingConfig !== null ) { @@ -17131,65 +20226,147 @@ function finishConcurrentRender( // through Scheduler function performSyncWorkOnRoot(root) { - if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { - throw Error("Should not already be working."); - } - - flushPassiveEffects(); + // Check if there's expired work on this root. Otherwise, render at Sync. var lastExpiredTime = root.lastExpiredTime; - var expirationTime; + var expirationTime = lastExpiredTime !== NoWork ? lastExpiredTime : Sync; + + if (root.finishedExpirationTime === expirationTime) { + // There's already a pending commit at this expiration time. + // TODO: This is poorly factored. This case only exists for the + // batch.commit() API. + commitRoot(root); + } else { + if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { + throw Error("Should not already be working."); + } + + flushPassiveEffects(); // If the root or expiration time have changed, throw out the existing stack + // and prepare a fresh one. Otherwise we'll continue where we left off. - if (lastExpiredTime !== NoWork) { - // There's expired work on this root. Check if we have a partial tree - // that we can reuse. if ( - root === workInProgressRoot && - renderExpirationTime$1 >= lastExpiredTime + root !== workInProgressRoot || + expirationTime !== renderExpirationTime ) { - // There's a partial tree with equal or greater than priority than the - // expired level. Finish rendering it before rendering the rest of the - // expired work. - expirationTime = renderExpirationTime$1; - } else { - // Start a fresh tree. - expirationTime = lastExpiredTime; + prepareFreshStack(root, expirationTime); + startWorkOnPendingInteractions(root, expirationTime); + } // If we have a work-in-progress fiber, it means there's still work to do + // in this root. + + if (workInProgress !== null) { + var prevExecutionContext = executionContext; + executionContext |= RenderContext; + var prevDispatcher = pushDispatcher(root); + var prevInteractions = pushInteractions(root); + startWorkLoopTimer(workInProgress); + + do { + try { + workLoopSync(); + break; + } catch (thrownValue) { + handleError(root, thrownValue); + } + } while (true); + + resetContextDependencies(); + executionContext = prevExecutionContext; + popDispatcher(prevDispatcher); + + if (enableSchedulerTracing) { + popInteractions(prevInteractions); + } + + if (workInProgressRootExitStatus === RootFatalErrored) { + var fatalError = workInProgressRootFatalError; + stopInterruptedWorkLoopTimer(); + prepareFreshStack(root, expirationTime); + markRootSuspendedAtTime(root, expirationTime); + ensureRootIsScheduled(root); + throw fatalError; + } + + if (workInProgress !== null) { + // This is a sync render, so we should have finished the whole tree. + { + throw Error( + "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." + ); + } + } else { + // We now have a consistent tree. Because this is a sync render, we + // will commit it even if something suspended. + stopFinishedWorkLoopTimer(); + root.finishedWork = root.current.alternate; + root.finishedExpirationTime = expirationTime; + finishSyncRender(root, workInProgressRootExitStatus, expirationTime); + } // Before exiting, make sure there's a callback scheduled for the next + // pending level. + + ensureRootIsScheduled(root); } - } else { - // There's no expired work. This must be a new, synchronous render. - expirationTime = Sync; } - var exitStatus = renderRootSync(root, expirationTime); + return null; +} + +function finishSyncRender(root, exitStatus, expirationTime) { + // Set this to null to indicate there's no in-progress render. + workInProgressRoot = null; - if (root.tag !== LegacyRoot && exitStatus === RootErrored) { - // If something threw an error, try rendering one more time. We'll - // render synchronously to block concurrent data mutations, and we'll - // render at Idle (or lower) so that all pending updates are included. - // If it still fails after the second attempt, we'll give up and commit - // the resulting tree. - expirationTime = expirationTime > Idle ? Idle : expirationTime; - exitStatus = renderRootSync(root, expirationTime); + { + if (exitStatus === RootSuspended || exitStatus === RootSuspendedWithDelay) { + flushSuspensePriorityWarningInDEV(); + } } - if (exitStatus === RootFatalErrored) { - var fatalError = workInProgressRootFatalError; - prepareFreshStack(root, expirationTime); - markRootSuspendedAtTime(root, expirationTime); - ensureRootIsScheduled(root); - throw fatalError; - } // We now have a consistent tree. Because this is a sync render, we - // will commit it even if something suspended. + commitRoot(root); +} - root.finishedWork = root.current.alternate; - root.finishedExpirationTime = expirationTime; - commitRoot(root); // Before exiting, make sure there's a callback scheduled for the next - // pending level. +function flushDiscreteUpdates() { + // TODO: Should be able to flush inside batchedUpdates, but not inside `act`. + // However, `act` uses `batchedUpdates`, so there's no way to distinguish + // those two cases. Need to fix this before exposing flushDiscreteUpdates + // as a public API. + if ( + (executionContext & (BatchedContext | RenderContext | CommitContext)) !== + NoContext + ) { + if (true && (executionContext & RenderContext) !== NoContext) { + warning$1( + false, + "unstable_flushDiscreteUpdates: Cannot flush updates when React is " + + "already rendering." + ); + } // We're already rendering, so we can't synchronously flush pending work. + // This is probably a nested event dispatch triggered by a lifecycle/effect, + // like `el.focus()`. Exit. - ensureRootIsScheduled(root); - return null; + return; + } + + flushPendingDiscreteUpdates(); // If the discrete updates scheduled passive effects, flush them now so that + // they fire before the next serial event. + + flushPassiveEffects(); } + function syncUpdates(fn, a, b, c) { - return runWithPriority(ImmediatePriority, fn.bind(null, a, b, c)); + return runWithPriority$1(ImmediatePriority, fn.bind(null, a, b, c)); +} + +function flushPendingDiscreteUpdates() { + if (rootsWithPendingDiscreteUpdates !== null) { + // For each root with pending discrete updates, schedule a callback to + // immediately flush them. + var roots = rootsWithPendingDiscreteUpdates; + rootsWithPendingDiscreteUpdates = null; + roots.forEach(function(expirationTime, root) { + markRootExpiredAtTime(root, expirationTime); + ensureRootIsScheduled(root); + }); // Now flush the immediate queue. + + flushSyncCallbackQueue(); + } } function batchedUpdates$1(fn, a) { @@ -17207,6 +20384,38 @@ function batchedUpdates$1(fn, a) { } } } +function batchedEventUpdates$1(fn, a) { + var prevExecutionContext = executionContext; + executionContext |= EventContext; + + try { + return fn(a); + } finally { + executionContext = prevExecutionContext; + + if (executionContext === NoContext) { + // Flush the immediate callbacks that were scheduled during this batch + flushSyncCallbackQueue(); + } + } +} +function discreteUpdates$1(fn, a, b, c) { + var prevExecutionContext = executionContext; + executionContext |= DiscreteEventContext; + + try { + // Should this + return runWithPriority$1(UserBlockingPriority$1, fn.bind(null, a, b, c)); + } finally { + executionContext = prevExecutionContext; + + if (executionContext === NoContext) { + // Flush the immediate callbacks that were scheduled during this batch + flushSyncCallbackQueue(); + } + } +} + function flushSync(fn, a) { if ((executionContext & (RenderContext | CommitContext)) !== NoContext) { { @@ -17220,7 +20429,7 @@ function flushSync(fn, a) { executionContext |= BatchedContext; try { - return runWithPriority(ImmediatePriority, fn.bind(null, a)); + return runWithPriority$1(ImmediatePriority, fn.bind(null, a)); } finally { executionContext = prevExecutionContext; // Flush the immediate callbacks that were scheduled during this batch. // Note that this will happen even if batchedUpdates is higher up @@ -17253,8 +20462,8 @@ function prepareFreshStack(root, expirationTime) { } workInProgressRoot = root; - workInProgress = createWorkInProgress(root.current, null); - renderExpirationTime$1 = expirationTime; + workInProgress = createWorkInProgress(root.current, null, expirationTime); + renderExpirationTime = expirationTime; workInProgressRootExitStatus = RootIncomplete; workInProgressRootFatalError = null; workInProgressRootLatestProcessedExpirationTime = Sync; @@ -17263,12 +20472,13 @@ function prepareFreshStack(root, expirationTime) { workInProgressRootNextUnprocessedUpdateTime = NoWork; workInProgressRootHasPendingPing = false; - { + if (enableSchedulerTracing) { spawnedWorkDuringRender = null; } { ReactStrictModeWarnings.discardPendingWarnings(); + componentsThatTriggeredHighPriSuspend = null; } } @@ -17277,7 +20487,7 @@ function handleError(root, thrownValue) { try { // Reset module-level state that was set during the render phase. resetContextDependencies(); - resetHooksAfterThrow(); + resetHooks(); resetCurrentFiber(); if (workInProgress === null || workInProgress.return === null) { @@ -17286,14 +20496,7 @@ function handleError(root, thrownValue) { // supposed to capture all errors that weren't caught by an error // boundary. workInProgressRootExitStatus = RootFatalErrored; - workInProgressRootFatalError = thrownValue; // Set `workInProgress` to null. This represents advancing to the next - // sibling, or the parent if there are no siblings. But since the root - // has no siblings nor a parent, we set it to null. Usually this is - // handled by `completeUnitOfWork` or `unwindWork`, but since we're - // interntionally not calling those, we need set it here. - // TODO: Consider calling `unwindWork` to pop the contexts. - - workInProgress = null; + workInProgressRootFatalError = thrownValue; return null; } @@ -17309,7 +20512,7 @@ function handleError(root, thrownValue) { workInProgress.return, workInProgress, thrownValue, - renderExpirationTime$1 + renderExpirationTime ); workInProgress = completeUnitOfWork(workInProgress); } catch (yetAnotherThrownValue) { @@ -17323,8 +20526,8 @@ function handleError(root, thrownValue) { } function pushDispatcher(root) { - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = ContextOnlyDispatcher; if (prevDispatcher === null) { // The React isomorphic package does not include a default dispatcher. @@ -17337,19 +20540,21 @@ function pushDispatcher(root) { } function popDispatcher(prevDispatcher) { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } function pushInteractions(root) { - { + if (enableSchedulerTracing) { var prevInteractions = tracing.__interactionsRef.current; tracing.__interactionsRef.current = root.memoizedInteractions; return prevInteractions; } + + return null; } function popInteractions(prevInteractions) { - { + if (enableSchedulerTracing) { tracing.__interactionsRef.current = prevInteractions; } } @@ -17402,7 +20607,7 @@ function renderDidSuspendDelayIfPossible() { // pending update. // TODO: This should immediately interrupt the current render, instead // of waiting until the next time we yield. - markRootSuspendedAtTime(workInProgressRoot, renderExpirationTime$1); + markRootSuspendedAtTime(workInProgressRoot, renderExpirationTime); markRootUpdatedAtTime( workInProgressRoot, workInProgressRootNextUnprocessedUpdateTime @@ -17437,117 +20642,18 @@ function inferTimeFromExpirationTimeWithSuspenseConfig( // approximate start time from the expiration time by subtracting the timeout // that was added to the event time. var earliestExpirationTimeMs = expirationTimeToMs(expirationTime); - return ( - earliestExpirationTimeMs - - (suspenseConfig.timeoutMs | 0 || LOW_PRIORITY_EXPIRATION) - ); -} - -function renderRootSync(root, expirationTime) { - var prevExecutionContext = executionContext; - executionContext |= RenderContext; - var prevDispatcher = pushDispatcher(); // If the root or expiration time have changed, throw out the existing stack - // and prepare a fresh one. Otherwise we'll continue where we left off. - - if ( - root !== workInProgressRoot || - expirationTime !== renderExpirationTime$1 - ) { - prepareFreshStack(root, expirationTime); - startWorkOnPendingInteractions(root, expirationTime); - } - - var prevInteractions = pushInteractions(root); - startWorkLoopTimer(workInProgress); - - do { - try { - workLoopSync(); - break; - } catch (thrownValue) { - handleError(root, thrownValue); - } - } while (true); - - resetContextDependencies(); - - { - popInteractions(prevInteractions); - } - - executionContext = prevExecutionContext; - popDispatcher(prevDispatcher); - - if (workInProgress !== null) { - // This is a sync render, so we should have finished the whole tree. - { - throw Error( - "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." - ); - } - } - - stopFinishedWorkLoopTimer(); // Set this to null to indicate there's no in-progress render. - - workInProgressRoot = null; - return workInProgressRootExitStatus; -} // The work loop is an extremely hot path. Tell Closure not to inline it. - -/** @noinline */ - -function workLoopSync() { - // Already timed out, so perform work without checking if we need to yield. - while (workInProgress !== null) { - workInProgress = performUnitOfWork(workInProgress); - } -} - -function renderRootConcurrent(root, expirationTime) { - var prevExecutionContext = executionContext; - executionContext |= RenderContext; - var prevDispatcher = pushDispatcher(); // If the root or expiration time have changed, throw out the existing stack - // and prepare a fresh one. Otherwise we'll continue where we left off. - - if ( - root !== workInProgressRoot || - expirationTime !== renderExpirationTime$1 - ) { - prepareFreshStack(root, expirationTime); - startWorkOnPendingInteractions(root, expirationTime); - } - - var prevInteractions = pushInteractions(root); - startWorkLoopTimer(workInProgress); - - do { - try { - workLoopConcurrent(); - break; - } catch (thrownValue) { - handleError(root, thrownValue); - } - } while (true); - - resetContextDependencies(); - - { - popInteractions(prevInteractions); - } - - popDispatcher(prevDispatcher); - executionContext = prevExecutionContext; // Check if the tree has completed. - - if (workInProgress !== null) { - // Still work remaining. - stopInterruptedWorkLoopTimer(); - return RootIncomplete; - } else { - // Completed the tree. - stopFinishedWorkLoopTimer(); // Set this to null to indicate there's no in-progress render. + return ( + earliestExpirationTimeMs - + (suspenseConfig.timeoutMs | 0 || LOW_PRIORITY_EXPIRATION) + ); +} // The work loop is an extremely hot path. Tell Closure not to inline it. - workInProgressRoot = null; // Return the final exit status. +/** @noinline */ - return workInProgressRootExitStatus; +function workLoopSync() { + // Already timed out, so perform work without checking if we need to yield. + while (workInProgress !== null) { + workInProgress = performUnitOfWork(workInProgress); } } /** @noinline */ @@ -17563,22 +20669,21 @@ function performUnitOfWork(unitOfWork) { // The current, flushed, state of this fiber is the alternate. Ideally // nothing should rely on this, but relying on it here means that we don't // need an additional field on the work in progress. - var current = unitOfWork.alternate; + var current$$1 = unitOfWork.alternate; startWorkTimer(unitOfWork); setCurrentFiber(unitOfWork); var next; - if ((unitOfWork.mode & ProfileMode) !== NoMode) { + if (enableProfilerTimer && (unitOfWork.mode & ProfileMode) !== NoMode) { startProfilerTimer(unitOfWork); - next = beginWork$1(current, unitOfWork, renderExpirationTime$1); + next = beginWork$$1(current$$1, unitOfWork, renderExpirationTime); stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true); } else { - next = beginWork$1(current, unitOfWork, renderExpirationTime$1); + next = beginWork$$1(current$$1, unitOfWork, renderExpirationTime); } resetCurrentFiber(); unitOfWork.memoizedProps = unitOfWork.pendingProps; - if (next === null) { // If this doesn't spawn new work, complete the current work. next = completeUnitOfWork(unitOfWork); @@ -17592,23 +20697,25 @@ function completeUnitOfWork(unitOfWork) { // Attempt to complete the current unit of work, then move to the next // sibling. If there are no more siblings, return to the parent fiber. workInProgress = unitOfWork; - do { // The current, flushed, state of this fiber is the alternate. Ideally // nothing should rely on this, but relying on it here means that we don't // need an additional field on the work in progress. - var current = workInProgress.alternate; + var current$$1 = workInProgress.alternate; var returnFiber = workInProgress.return; // Check if the work completed or if something threw. if ((workInProgress.effectTag & Incomplete) === NoEffect) { setCurrentFiber(workInProgress); var next = void 0; - if ((workInProgress.mode & ProfileMode) === NoMode) { - next = completeWork(current, workInProgress, renderExpirationTime$1); + if ( + !enableProfilerTimer || + (workInProgress.mode & ProfileMode) === NoMode + ) { + next = completeWork(current$$1, workInProgress, renderExpirationTime); } else { startProfilerTimer(workInProgress); - next = completeWork(current, workInProgress, renderExpirationTime$1); // Update render duration assuming we didn't error. + next = completeWork(current$$1, workInProgress, renderExpirationTime); // Update render duration assuming we didn't error. stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false); } @@ -17632,7 +20739,6 @@ function completeUnitOfWork(unitOfWork) { if (returnFiber.firstEffect === null) { returnFiber.firstEffect = workInProgress.firstEffect; } - if (workInProgress.lastEffect !== null) { if (returnFiber.lastEffect !== null) { returnFiber.lastEffect.nextEffect = workInProgress.firstEffect; @@ -17656,7 +20762,6 @@ function completeUnitOfWork(unitOfWork) { } else { returnFiber.firstEffect = workInProgress; } - returnFiber.lastEffect = workInProgress; } } @@ -17664,9 +20769,12 @@ function completeUnitOfWork(unitOfWork) { // This fiber did not complete because something threw. Pop values off // the stack without entering the complete phase. If this is a boundary, // capture values if possible. - var _next = unwindWork(workInProgress); // Because this fiber did not complete, don't reset its expiration time. + var _next = unwindWork(workInProgress, renderExpirationTime); // Because this fiber did not complete, don't reset its expiration time. - if ((workInProgress.mode & ProfileMode) !== NoMode) { + if ( + enableProfilerTimer && + (workInProgress.mode & ProfileMode) !== NoMode + ) { // Record the render duration for the fiber that errored. stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false); // Include the time spent working on failed children before continuing. @@ -17677,7 +20785,6 @@ function completeUnitOfWork(unitOfWork) { actualDuration += child.actualDuration; child = child.sibling; } - workInProgress.actualDuration = actualDuration; } @@ -17692,7 +20799,6 @@ function completeUnitOfWork(unitOfWork) { _next.effectTag &= HostEffectMask; return _next; } - stopWorkTimer(workInProgress); if (returnFiber !== null) { @@ -17729,7 +20835,7 @@ function getRemainingExpirationTime(fiber) { function resetChildExpirationTime(completedWork) { if ( - renderExpirationTime$1 !== Never && + renderExpirationTime !== Never && completedWork.childExpirationTime === Never ) { // The children of this component are hidden. Don't bubble their @@ -17739,7 +20845,7 @@ function resetChildExpirationTime(completedWork) { var newChildExpirationTime = NoWork; // Bubble up the earliest expiration time. - if ((completedWork.mode & ProfileMode) !== NoMode) { + if (enableProfilerTimer && (completedWork.mode & ProfileMode) !== NoMode) { // In profiling mode, resetChildExpirationTime is also used to reset // profiler durations. var actualDuration = completedWork.actualDuration; @@ -17802,7 +20908,7 @@ function resetChildExpirationTime(completedWork) { function commitRoot(root) { var renderPriorityLevel = getCurrentPriorityLevel(); - runWithPriority( + runWithPriority$1( ImmediatePriority, commitRootImpl.bind(null, root, renderPriorityLevel) ); @@ -17810,16 +20916,7 @@ function commitRoot(root) { } function commitRootImpl(root, renderPriorityLevel) { - do { - // `flushPassiveEffects` will call `flushSyncUpdateQueue` at the end, which - // means `flushPassiveEffects` will sometimes result in additional - // passive effects. So we need to keep flushing in a loop until there are - // no more pending effects. - // TODO: Might be better if `flushPassiveEffects` did not automatically - // flush synchronous work at the end, to avoid factoring hazards like this. - flushPassiveEffects(); - } while (rootWithPendingPassiveEffects !== null); - + flushPassiveEffects(); flushRenderPhaseStrictModeWarningsInDEV(); if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { @@ -17863,7 +20960,8 @@ function commitRootImpl(root, renderPriorityLevel) { // We can reset these now that they are finished. workInProgressRoot = null; workInProgress = null; - renderExpirationTime$1 = NoWork; + renderExpirationTime = NoWork; + } else { } // This indicates that the last root we worked on is not the same one that // we're committing now. This most commonly happens when a suspended root // times out. @@ -17918,10 +21016,9 @@ function commitRootImpl(root, renderPriorityLevel) { } } } while (nextEffect !== null); - stopCommitSnapshotEffectsTimer(); - { + if (enableProfilerTimer) { // Mark the current commit time to be shared by all Profilers in this // batch. This enables them to be grouped later. recordCommitTime(); @@ -17995,7 +21092,7 @@ function commitRootImpl(root, renderPriorityLevel) { requestPaint(); - { + if (enableSchedulerTracing) { popInteractions(prevInteractions); } @@ -18009,7 +21106,7 @@ function commitRootImpl(root, renderPriorityLevel) { startCommitSnapshotEffectsTimer(); stopCommitSnapshotEffectsTimer(); - { + if (enableProfilerTimer) { recordCommitTime(); } @@ -18034,7 +21131,6 @@ function commitRootImpl(root, renderPriorityLevel) { // 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; @@ -18045,11 +21141,10 @@ function commitRootImpl(root, renderPriorityLevel) { var remainingExpirationTime = root.firstPendingTime; if (remainingExpirationTime !== NoWork) { - { + if (enableSchedulerTracing) { if (spawnedWorkDuringRender !== null) { var expirationTimes = spawnedWorkDuringRender; spawnedWorkDuringRender = null; - for (var i = 0; i < expirationTimes.length; i++) { scheduleInteractions( root, @@ -18067,7 +21162,7 @@ function commitRootImpl(root, renderPriorityLevel) { legacyErrorBoundariesThatAlreadyFailed = null; } - { + if (enableSchedulerTracing) { if (!rootDidHavePassiveEffects) { // If there are no passive effects, then we can complete the pending interactions. // Otherwise, we'll wait until after the passive effects are flushed. @@ -18121,8 +21216,8 @@ function commitBeforeMutationEffects() { if ((effectTag & Snapshot) !== NoEffect) { setCurrentFiber(nextEffect); recordEffect(); - var current = nextEffect.alternate; - commitBeforeMutationLifeCycles(current, nextEffect); + var current$$1 = nextEffect.alternate; + commitBeforeMutationLifeCycles(current$$1, nextEffect); resetCurrentFiber(); } @@ -18148,11 +21243,15 @@ function commitMutationEffects(root, renderPriorityLevel) { setCurrentFiber(nextEffect); var effectTag = nextEffect.effectTag; + if (effectTag & ContentReset) { + commitResetTextContent(nextEffect); + } + if (effectTag & Ref) { - var current = nextEffect.alternate; + var current$$1 = nextEffect.alternate; - if (current !== null) { - commitDetachRef(current); + if (current$$1 !== null) { + commitDetachRef(current$$1); } } // The following switch statement is only concerned about placement, // updates, and deletions. To avoid needing to add a case for every possible @@ -18164,6 +21263,7 @@ function commitMutationEffects(root, renderPriorityLevel) { switch (primaryEffectTag) { 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. @@ -18173,6 +21273,8 @@ function commitMutationEffects(root, renderPriorityLevel) { } 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.effectTag &= ~Placement; // Update @@ -18221,8 +21323,8 @@ function commitLayoutEffects(root, committedExpirationTime) { if (effectTag & (Update | Callback)) { recordEffect(); - var current = nextEffect.alternate; - commitLifeCycles(root, current, nextEffect); + var current$$1 = nextEffect.alternate; + commitLifeCycles(root, current$$1, nextEffect, committedExpirationTime); } if (effectTag & Ref) { @@ -18242,7 +21344,7 @@ function flushPassiveEffects() { ? NormalPriority : pendingPassiveEffectsRenderPriority; pendingPassiveEffectsRenderPriority = NoPriority; - return runWithPriority(priorityLevel, flushPassiveEffectsImpl); + return runWithPriority$1(priorityLevel, flushPassiveEffectsImpl); } } @@ -18262,40 +21364,36 @@ function flushPassiveEffectsImpl() { var prevExecutionContext = executionContext; executionContext |= CommitContext; - var prevInteractions = pushInteractions(root); - - { - // 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 _effect2 = root.current.firstEffect; - - while (_effect2 !== null) { - { - setCurrentFiber(_effect2); - invokeGuardedCallback(null, commitPassiveHookEffects, null, _effect2); + var prevInteractions = pushInteractions(root); // 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. - if (hasCaughtError()) { - if (!(_effect2 !== null)) { - throw Error("Should be working on an effect."); - } + var effect = root.current.firstEffect; - var _error5 = clearCaughtError(); + while (effect !== null) { + { + setCurrentFiber(effect); + invokeGuardedCallback(null, commitPassiveHookEffects, null, effect); - captureCommitPhaseError(_effect2, _error5); + if (hasCaughtError()) { + if (!(effect !== null)) { + throw Error("Should be working on an effect."); } - resetCurrentFiber(); + var error = clearCaughtError(); + captureCommitPhaseError(effect, error); } - var nextNextEffect = _effect2.nextEffect; // Remove nextEffect pointer to assist GC - - _effect2.nextEffect = null; - _effect2 = nextNextEffect; + resetCurrentFiber(); } + + var nextNextEffect = effect.nextEffect; // Remove nextEffect pointer to assist GC + + effect.nextEffect = null; + effect = nextNextEffect; } - { + if (enableSchedulerTracing) { popInteractions(prevInteractions); finishPendingInteractions(root, expirationTime); } @@ -18329,7 +21427,6 @@ function prepareToThrowUncaughtError(error) { firstUncaughtError = error; } } - var onUncaughtError = prepareToThrowUncaughtError; function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { @@ -18353,7 +21450,6 @@ function captureCommitPhaseError(sourceFiber, error) { } var fiber = sourceFiber.return; - while (fiber !== null) { if (fiber.tag === HostRoot) { captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error); @@ -18361,7 +21457,6 @@ function captureCommitPhaseError(sourceFiber, error) { } else if (fiber.tag === ClassComponent) { var ctor = fiber.type; var instance = fiber.stateNode; - if ( typeof ctor.getDerivedStateFromError === "function" || (typeof instance.componentDidCatch === "function" && @@ -18397,7 +21492,7 @@ function pingSuspendedRoot(root, thenable, suspendedTime) { pingCache.delete(thenable); } - if (workInProgressRoot === root && renderExpirationTime$1 === suspendedTime) { + if (workInProgressRoot === root && renderExpirationTime === suspendedTime) { // Received a ping at the same priority level at which we're currently // rendering. We might want to restart this render. This should mirror // the logic of whether or not a root suspends once it completes. @@ -18417,7 +21512,7 @@ function pingSuspendedRoot(root, thenable, suspendedTime) { ) { // Restart from the root. Don't need to schedule a ping because // we're already working on this tree. - prepareFreshStack(root, renderExpirationTime$1); + prepareFreshStack(root, renderExpirationTime); } else { // Even though we can't restart right now, we might get an // opportunity later. So we mark this render as having a ping. @@ -18440,6 +21535,13 @@ function pingSuspendedRoot(root, thenable, suspendedTime) { } // Mark the time at which this ping was scheduled. root.lastPingedTime = suspendedTime; + + if (root.finishedExpirationTime === suspendedTime) { + // If there's a pending fallback waiting to commit, throw it away. + root.finishedExpirationTime = NoWork; + root.finishedWork = null; + } + ensureRootIsScheduled(root); schedulePendingInteractions(root, suspendedTime); } @@ -18467,12 +21569,45 @@ function retryTimedOutBoundary(boundaryFiber, retryTime) { schedulePendingInteractions(root, retryTime); } } + +function retryDehydratedSuspenseBoundary(boundaryFiber) { + var suspenseState = boundaryFiber.memoizedState; + var retryTime = NoWork; + + if (suspenseState !== null) { + retryTime = suspenseState.retryTime; + } + + retryTimedOutBoundary(boundaryFiber, retryTime); +} function resolveRetryThenable(boundaryFiber, thenable) { var retryTime = NoWork; // Default var retryCache; - { + if (enableSuspenseServerRenderer) { + switch (boundaryFiber.tag) { + case SuspenseComponent: + retryCache = boundaryFiber.stateNode; + var suspenseState = boundaryFiber.memoizedState; + + if (suspenseState !== null) { + retryTime = suspenseState.retryTime; + } + + break; + + case SuspenseListComponent: + retryCache = boundaryFiber.stateNode; + break; + + default: { + throw Error( + "Pinged unknown suspense boundary type. This is probably a bug in React." + ); + } + } + } else { retryCache = boundaryFiber.stateNode; } @@ -18492,21 +21627,20 @@ function resolveRetryThenable(boundaryFiber, thenable) { // the longer we can wait additionally. At some point we have to give up though. // We pick a train model where the next boundary commits at a consistent schedule. // These particular numbers are vague estimates. We expect to adjust them based on research. - function jnd(timeElapsed) { return timeElapsed < 120 ? 120 : timeElapsed < 480 - ? 480 - : timeElapsed < 1080 - ? 1080 - : timeElapsed < 1920 - ? 1920 - : timeElapsed < 3000 - ? 3000 - : timeElapsed < 4320 - ? 4320 - : ceil(timeElapsed / 1960) * 1960; + ? 480 + : timeElapsed < 1080 + ? 1080 + : timeElapsed < 1920 + ? 1920 + : timeElapsed < 3000 + ? 3000 + : timeElapsed < 4320 + ? 4320 + : ceil(timeElapsed / 1960) * 1960; } function computeMsUntilSuspenseLoadingDelay( @@ -18528,7 +21662,6 @@ function computeMsUntilSuspenseLoadingDelay( suspenseConfig ); var timeElapsed = currentTimeMs - eventTimeMs; - if (timeElapsed <= busyDelayMs) { // If we haven't yet waited longer than the initial delay, we don't // have to wait any additional time. @@ -18555,8 +21688,8 @@ function checkForNestedUpdates() { { if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) { nestedPassiveUpdateCount = 0; - - error( + warning$1( + false, "Maximum update depth exceeded. This can happen when a component " + "calls setState inside useEffect, but useEffect either doesn't " + "have a dependency array, or one of the dependencies changes on " + @@ -18570,7 +21703,7 @@ function flushRenderPhaseStrictModeWarningsInDEV() { { ReactStrictModeWarnings.flushLegacyContextWarning(); - { + if (warnAboutDeprecatedLifecycles) { ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings(); } } @@ -18591,8 +21724,9 @@ function stopInterruptedWorkLoopTimer() { function checkForInterruption(fiberThatReceivedUpdate, updateExpirationTime) { if ( + enableUserTimingAPI && workInProgressRoot !== null && - updateExpirationTime > renderExpirationTime$1 + updateExpirationTime > renderExpirationTime ) { interruptedBy = fiberThatReceivedUpdate; } @@ -18610,12 +21744,11 @@ function warnAboutUpdateOnUnmountedFiberInDEV(fiber) { tag !== FunctionComponent && tag !== ForwardRef && tag !== MemoComponent && - tag !== SimpleMemoComponent && - tag !== Block + tag !== SimpleMemoComponent ) { // Only warn for user-defined components, not internal ones like Suspense. return; - } + } // We show the whole stack but dedupe on the top component's name because // the problematic code almost always lies inside that component. var componentName = getComponentName(fiber.type) || "ReactComponent"; @@ -18624,13 +21757,12 @@ function warnAboutUpdateOnUnmountedFiberInDEV(fiber) { if (didWarnStateUpdateForUnmountedComponent.has(componentName)) { return; } - didWarnStateUpdateForUnmountedComponent.add(componentName); } else { didWarnStateUpdateForUnmountedComponent = new Set([componentName]); } - - error( + warningWithoutStack$1( + false, "Can't perform a React state update on an unmounted component. This " + "is a no-op, but it indicates a memory leak in your application. To " + "fix, cancel all subscriptions and asynchronous tasks in %s.%s", @@ -18642,12 +21774,12 @@ function warnAboutUpdateOnUnmountedFiberInDEV(fiber) { } } -var beginWork$1; +var beginWork$$1; -{ +if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) { var dummyFiber = null; - beginWork$1 = function(current, unitOfWork, expirationTime) { + beginWork$$1 = function(current$$1, unitOfWork, expirationTime) { // If a component throws an error, we replay it again in a synchronously // dispatched event, so that the debugger will treat it as an uncaught // error See ReactErrorUtils for more information. @@ -18657,9 +21789,8 @@ var beginWork$1; dummyFiber, unitOfWork ); - try { - return beginWork(current, unitOfWork, expirationTime); + return beginWork$1(current$$1, unitOfWork, expirationTime); } catch (originalError) { if ( originalError !== null && @@ -18672,7 +21803,7 @@ var beginWork$1; // corresponding changes there. resetContextDependencies(); - resetHooksAfterThrow(); // Don't reset current debug fiber, since we're about to work on the + resetHooks(); // Don't reset current debug fiber, since we're about to work on the // same fiber again. // Unwind the failed stack frame @@ -18680,16 +21811,16 @@ var beginWork$1; assignFiberPropertiesInDEV(unitOfWork, originalWorkInProgressCopy); - if (unitOfWork.mode & ProfileMode) { + if (enableProfilerTimer && unitOfWork.mode & ProfileMode) { // Reset the profiler timer. startProfilerTimer(unitOfWork); } // Run beginWork again. invokeGuardedCallback( null, - beginWork, + beginWork$1, null, - current, + current$$1, unitOfWork, expirationTime ); @@ -18705,37 +21836,38 @@ var beginWork$1; } } }; +} else { + beginWork$$1 = beginWork$1; } var didWarnAboutUpdateInRender = false; - -function warnAboutRenderPhaseUpdatesInDEV(fiber) { +var didWarnAboutUpdateInGetChildContext = false; +function warnAboutInvalidUpdatesOnClassComponentsInDEV(fiber) { { - if ((executionContext & RenderContext) !== NoContext) { - switch (fiber.tag) { - case FunctionComponent: - case ForwardRef: - case SimpleMemoComponent: { - error( - "Cannot update a component from inside the function body of a " + - "different component." + if (fiber.tag === ClassComponent) { + switch (phase) { + case "getChildContext": + if (didWarnAboutUpdateInGetChildContext) { + return; + } + warningWithoutStack$1( + false, + "setState(...): Cannot call setState() inside getChildContext()" ); - + didWarnAboutUpdateInGetChildContext = true; break; - } - - case ClassComponent: { - if (isRendering && !didWarnAboutUpdateInRender) { - error( - "Cannot update during an existing state transition (such as " + - "within `render`). Render methods should be a pure " + - "function of props and state." - ); - - didWarnAboutUpdateInRender = true; - break; + case "render": + if (didWarnAboutUpdateInRender) { + return; } - } + warningWithoutStack$1( + false, + "Cannot update during an existing state transition (such as " + + "within `render`). Render methods should be a pure function of " + + "props and state." + ); + didWarnAboutUpdateInRender = true; + break; } } } @@ -18744,6 +21876,89 @@ function warnAboutRenderPhaseUpdatesInDEV(fiber) { var IsThisRendererActing = { current: false }; +function warnIfNotScopedWithMatchingAct(fiber) { + { + if ( + warnsIfNotActing === true && + IsSomeRendererActing.current === true && + IsThisRendererActing.current !== true + ) { + warningWithoutStack$1( + false, + "It looks like you're using the wrong act() around your test interactions.\n" + + "Be sure to use the matching version of act() corresponding to your renderer:\n\n" + + "// for react-dom:\n" + + "import {act} from 'react-dom/test-utils';\n" + + "// ...\n" + + "act(() => ...);\n\n" + + "// for react-test-renderer:\n" + + "import TestRenderer from 'react-test-renderer';\n" + + "const {act} = TestRenderer;\n" + + "// ...\n" + + "act(() => ...);" + + "%s", + getStackByFiberInDevAndProd(fiber) + ); + } + } +} +function warnIfNotCurrentlyActingEffectsInDEV(fiber) { + { + if ( + warnsIfNotActing === true && + (fiber.mode & StrictMode) !== NoMode && + IsSomeRendererActing.current === false && + IsThisRendererActing.current === false + ) { + warningWithoutStack$1( + false, + "An update to %s ran an effect, but was not wrapped in act(...).\n\n" + + "When testing, code that causes React state updates should be " + + "wrapped into act(...):\n\n" + + "act(() => {\n" + + " /* fire events that update state */\n" + + "});\n" + + "/* assert on the output */\n\n" + + "This ensures that you're testing the behavior the user would see " + + "in the browser." + + " Learn more at https://fb.me/react-wrap-tests-with-act" + + "%s", + getComponentName(fiber.type), + getStackByFiberInDevAndProd(fiber) + ); + } + } +} + +function warnIfNotCurrentlyActingUpdatesInDEV(fiber) { + { + if ( + warnsIfNotActing === true && + executionContext === NoContext && + IsSomeRendererActing.current === false && + IsThisRendererActing.current === false + ) { + warningWithoutStack$1( + false, + "An update to %s inside a test was not wrapped in act(...).\n\n" + + "When testing, code that causes React state updates should be " + + "wrapped into act(...):\n\n" + + "act(() => {\n" + + " /* fire events that update state */\n" + + "});\n" + + "/* assert on the output */\n\n" + + "This ensures that you're testing the behavior the user would see " + + "in the browser." + + " Learn more at https://fb.me/react-wrap-tests-with-act" + + "%s", + getComponentName(fiber.type), + getStackByFiberInDevAndProd(fiber) + ); + } + } +} + +var warnIfNotCurrentlyActingUpdatesInDev = warnIfNotCurrentlyActingUpdatesInDEV; // In tests, we want to enforce a mocked scheduler. var didWarnAboutUnmockedScheduler = false; // TODO Before we release concurrent mode, revisit this and decide whether a mocked // scheduler is the actual recommendation. The alternative could be a testing build, @@ -18758,19 +21973,159 @@ function warnIfUnmockedScheduler(fiber) { ) { if (fiber.mode & BlockingMode || fiber.mode & ConcurrentMode) { didWarnAboutUnmockedScheduler = true; - - error( + warningWithoutStack$1( + false, 'In Concurrent or Sync modes, the "scheduler" module needs to be mocked ' + - "to guarantee consistent behaviour across tests and browsers. " + - "For example, with jest: \n" + // Break up requires to avoid accidentally parsing them as dependencies. - "jest.mock('scheduler', () => require" + - "('scheduler/unstable_mock'));\n\n" + + "to guarantee consistent behaviour across tests and browsers. " + + "For example, with jest: \n" + + "jest.mock('scheduler', () => require('scheduler/unstable_mock'));\n\n" + + "For more info, visit https://fb.me/react-mock-scheduler" + ); + } else if (warnAboutUnmockedScheduler === true) { + didWarnAboutUnmockedScheduler = true; + warningWithoutStack$1( + false, + 'Starting from React v17, the "scheduler" module will need to be mocked ' + + "to guarantee consistent behaviour across tests and browsers. " + + "For example, with jest: \n" + + "jest.mock('scheduler', () => require('scheduler/unstable_mock'));\n\n" + "For more info, visit https://fb.me/react-mock-scheduler" ); } } } } +var componentsThatTriggeredHighPriSuspend = null; +function checkForWrongSuspensePriorityInDEV(sourceFiber) { + { + var currentPriorityLevel = getCurrentPriorityLevel(); + if ( + (sourceFiber.mode & ConcurrentMode) !== NoEffect && + (currentPriorityLevel === UserBlockingPriority$1 || + currentPriorityLevel === ImmediatePriority) + ) { + var workInProgressNode = sourceFiber; + + while (workInProgressNode !== null) { + // Add the component that triggered the suspense + var current$$1 = workInProgressNode.alternate; + + if (current$$1 !== null) { + // TODO: warn component that triggers the high priority + // suspend is the HostRoot + switch (workInProgressNode.tag) { + case ClassComponent: + // Loop through the component's update queue and see whether the component + // has triggered any high priority updates + var updateQueue = current$$1.updateQueue; + + if (updateQueue !== null) { + var update = updateQueue.firstUpdate; + + while (update !== null) { + var priorityLevel = update.priority; + + if ( + priorityLevel === UserBlockingPriority$1 || + priorityLevel === ImmediatePriority + ) { + if (componentsThatTriggeredHighPriSuspend === null) { + componentsThatTriggeredHighPriSuspend = new Set([ + getComponentName(workInProgressNode.type) + ]); + } else { + componentsThatTriggeredHighPriSuspend.add( + getComponentName(workInProgressNode.type) + ); + } + + break; + } + + update = update.next; + } + } + + break; + + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: + if ( + workInProgressNode.memoizedState !== null && + workInProgressNode.memoizedState.baseUpdate !== null + ) { + var _update = workInProgressNode.memoizedState.baseUpdate; // Loop through the functional component's memoized state to see whether + // the component has triggered any high pri updates + + while (_update !== null) { + var priority = _update.priority; + + if ( + priority === UserBlockingPriority$1 || + priority === ImmediatePriority + ) { + if (componentsThatTriggeredHighPriSuspend === null) { + componentsThatTriggeredHighPriSuspend = new Set([ + getComponentName(workInProgressNode.type) + ]); + } else { + componentsThatTriggeredHighPriSuspend.add( + getComponentName(workInProgressNode.type) + ); + } + + break; + } + + if ( + _update.next === workInProgressNode.memoizedState.baseUpdate + ) { + break; + } + + _update = _update.next; + } + } + + break; + + default: + break; + } + } + workInProgressNode = workInProgressNode.return; + } + } + } +} + +function flushSuspensePriorityWarningInDEV() { + { + if (componentsThatTriggeredHighPriSuspend !== null) { + var componentNames = []; + componentsThatTriggeredHighPriSuspend.forEach(function(name) { + return componentNames.push(name); + }); + componentsThatTriggeredHighPriSuspend = null; + + if (componentNames.length > 0) { + warningWithoutStack$1( + false, + "%s triggered a user-blocking update that suspended." + + "\n\n" + + "The fix is to split the update into multiple parts: a user-blocking " + + "update to provide immediate feedback, and another update that " + + "triggers the bulk of the changes." + + "\n\n" + + "Refer to the documentation for useTransition to learn how " + + "to implement this pattern.", // TODO: Add link to React docs with more information, once it exists + componentNames.sort().join(", ") + ); + } + } + } +} function computeThreadID(root, expirationTime) { // Interaction threads are unique per root and expiration time. @@ -18778,6 +22133,9 @@ function computeThreadID(root, expirationTime) { } function markSpawnedWork(expirationTime) { + if (!enableSchedulerTracing) { + return; + } if (spawnedWorkDuringRender === null) { spawnedWorkDuringRender = [expirationTime]; } else { @@ -18786,10 +22144,13 @@ function markSpawnedWork(expirationTime) { } function scheduleInteractions(root, expirationTime, interactions) { + if (!enableSchedulerTracing) { + return; + } + if (interactions.size > 0) { var pendingInteractionMap = root.pendingInteractionMap; var pendingInteractions = pendingInteractionMap.get(expirationTime); - if (pendingInteractions != null) { interactions.forEach(function(interaction) { if (!pendingInteractions.has(interaction)) { @@ -18808,7 +22169,6 @@ function scheduleInteractions(root, expirationTime, interactions) { } var subscriber = tracing.__subscriberRef.current; - if (subscriber !== null) { var threadID = computeThreadID(root, expirationTime); subscriber.onWorkScheduled(interactions, threadID); @@ -18817,10 +22177,21 @@ function scheduleInteractions(root, expirationTime, interactions) { } function schedulePendingInteractions(root, expirationTime) { + // This is called when work is scheduled on a root. + // It associates the current interactions with the newly-scheduled expiration. + // They will be restored when that expiration is later committed. + if (!enableSchedulerTracing) { + return; + } + scheduleInteractions(root, expirationTime, tracing.__interactionsRef.current); } function startWorkOnPendingInteractions(root, expirationTime) { + // This is called when new work is started on a root. + if (!enableSchedulerTracing) { + return; + } // Determine which interactions this batch of work currently includes, So that // we can accurately attribute time spent working on it, And so that cascading // work triggered during the render phase will be associated with it. @@ -18861,6 +22232,10 @@ function startWorkOnPendingInteractions(root, expirationTime) { } function finishPendingInteractions(root, committedExpirationTime) { + if (!enableSchedulerTracing) { + return; + } + var earliestRemainingTimeAfterCommit = root.firstPendingTime; var subscriber; @@ -18909,7 +22284,6 @@ function finishPendingInteractions(root, committedExpirationTime) { } } -var onScheduleFiberRoot = null; var onCommitFiberRoot = null; var onCommitFiberUnmount = null; var hasLoggedError = false; @@ -18928,10 +22302,10 @@ function injectInternals(internals) { // https://github.com/facebook/react/issues/3877 return true; } - if (!hook.supportsFiber) { { - error( + warningWithoutStack$1( + false, "The installed version of React DevTools is too old and will not work " + "with the current version of React. Please update React DevTools. " + "https://fb.me/react-devtools" @@ -18944,23 +22318,6 @@ function injectInternals(internals) { try { var rendererID = hook.inject(internals); // We have successfully injected, so now it is safe to set up hooks. - if (true) { - // Only used by Fast Refresh - if (typeof hook.onScheduleFiberRoot === "function") { - onScheduleFiberRoot = function(root, children) { - try { - hook.onScheduleFiberRoot(rendererID, root, children); - } catch (err) { - if (true && !hasLoggedError) { - hasLoggedError = true; - - error("React instrumentation encountered an error: %s", err); - } - } - }; - } - } - onCommitFiberRoot = function(root, expirationTime) { try { var didError = (root.current.effectTag & DidCapture) === DidCapture; @@ -18976,43 +22333,43 @@ function injectInternals(internals) { hook.onCommitFiberRoot(rendererID, root, undefined, didError); } } catch (err) { - if (true) { - if (!hasLoggedError) { - hasLoggedError = true; - - error("React instrumentation encountered an error: %s", err); - } + if (true && !hasLoggedError) { + hasLoggedError = true; + warningWithoutStack$1( + false, + "React DevTools encountered an error: %s", + err + ); } } }; - onCommitFiberUnmount = function(fiber) { try { hook.onCommitFiberUnmount(rendererID, fiber); } catch (err) { - if (true) { - if (!hasLoggedError) { - hasLoggedError = true; - - error("React instrumentation encountered an error: %s", err); - } + if (true && !hasLoggedError) { + hasLoggedError = true; + warningWithoutStack$1( + false, + "React DevTools encountered an error: %s", + err + ); } } }; } catch (err) { // Catch all errors because it is unsafe to throw during initialization. { - error("React instrumentation encountered an error: %s.", err); + warningWithoutStack$1( + false, + "React DevTools encountered an error: %s.", + err + ); } } // DevTools exists return true; } -function onScheduleRoot(root, children) { - if (typeof onScheduleFiberRoot === "function") { - onScheduleFiberRoot(root, children); - } -} function onCommitRoot(root, expirationTime) { if (typeof onCommitFiberRoot === "function") { onCommitFiberRoot(root, expirationTime); @@ -19074,7 +22431,7 @@ function FiberNode(tag, pendingProps, key, mode) { this.childExpirationTime = NoWork; this.alternate = null; - { + if (enableProfilerTimer) { // Note: The following is done to avoid a v8 performance cliff. // // Initializing the fields below to smis and later updating them with @@ -19101,7 +22458,7 @@ function FiberNode(tag, pendingProps, key, mode) { } // This is normally DEV-only except www when it adds listeners. // TODO: remove the User Timing integration in favor of Root Events. - { + if (enableUserTimingAPI) { this._debugID = debugCounter++; this._debugIsCurrentlyTiming = false; } @@ -19129,7 +22486,6 @@ function FiberNode(tag, pendingProps, key, mode) { // is faster. // 5) It should be easy to port this to a C struct and keep a C implementation // compatible. - var createFiber = function(tag, pendingProps, key, mode) { // $FlowFixMe: the shapes are exact here but Flow doesn't like constructors return new FiberNode(tag, pendingProps, key, mode); @@ -19165,7 +22521,7 @@ function resolveLazyComponentTag(Component) { return IndeterminateComponent; } // This is used to create an alternate fiber to do work on. -function createWorkInProgress(current, pendingProps) { +function createWorkInProgress(current, pendingProps, expirationTime) { var workInProgress = current.alternate; if (workInProgress === null) { @@ -19186,10 +22542,7 @@ function createWorkInProgress(current, pendingProps) { { // DEV-only fields - { - workInProgress._debugID = current._debugID; - } - + workInProgress._debugID = current._debugID; workInProgress._debugSource = current._debugSource; workInProgress._debugOwner = current._debugOwner; workInProgress._debugHookTypes = current._debugHookTypes; @@ -19207,7 +22560,7 @@ function createWorkInProgress(current, pendingProps) { workInProgress.firstEffect = null; workInProgress.lastEffect = null; - { + if (enableProfilerTimer) { // We intentionally reset, rather than copy, actualDuration & actualStartTime. // This prevents time from endlessly accumulating in new commits. // This has the downside of resetting values for different priority renders, @@ -19239,14 +22592,13 @@ function createWorkInProgress(current, pendingProps) { workInProgress.index = current.index; workInProgress.ref = current.ref; - { + if (enableProfilerTimer) { workInProgress.selfBaseDuration = current.selfBaseDuration; workInProgress.treeBaseDuration = current.treeBaseDuration; } { workInProgress._debugNeedsRemount = current._debugNeedsRemount; - switch (workInProgress.tag) { case IndeterminateComponent: case FunctionComponent: @@ -19261,6 +22613,9 @@ function createWorkInProgress(current, pendingProps) { case ForwardRef: workInProgress.type = resolveForwardRefForHotReloading(current.type); break; + + default: + break; } } @@ -19293,7 +22648,7 @@ function resetWorkInProgress(workInProgress, renderExpirationTime) { workInProgress.updateQueue = null; workInProgress.dependencies = null; - { + if (enableProfilerTimer) { // Note: We don't reset the actualTime counts. It's useful to accumulate // actual time across multiple render passes. workInProgress.selfBaseDuration = 0; @@ -19319,7 +22674,7 @@ function resetWorkInProgress(workInProgress, renderExpirationTime) { responders: currentDependencies.responders }; - { + if (enableProfilerTimer) { // Note: We don't reset the actualTime counts. It's useful to accumulate // actual time across multiple render passes. workInProgress.selfBaseDuration = current.selfBaseDuration; @@ -19340,7 +22695,7 @@ function createHostRootFiber(tag) { mode = NoMode; } - if (isDevToolsPresent) { + if (enableProfilerTimer && isDevToolsPresent) { // Always collect profile timings when DevTools are present. // This enables DevTools to start capturing timing at any point– // Without some nodes in the tree having empty base times. @@ -19409,14 +22764,12 @@ function createFiberFromTypeAndProps( expirationTime, key ); - default: { if (typeof type === "object" && type !== null) { switch (type.$$typeof) { case REACT_PROVIDER_TYPE: fiberTag = ContextProvider; break getTag; - case REACT_CONTEXT_TYPE: // This is a consumer fiberTag = ContextConsumer; @@ -19439,10 +22792,29 @@ function createFiberFromTypeAndProps( fiberTag = LazyComponent; resolvedType = null; break getTag; + case REACT_FUNDAMENTAL_TYPE: + if (enableFundamentalAPI) { + return createFiberFromFundamental( + type, + pendingProps, + mode, + expirationTime, + key + ); + } - case REACT_BLOCK_TYPE: - fiberTag = Block; - break getTag; + break; + + case REACT_SCOPE_TYPE: + if (enableScopeAPI) { + return createFiberFromScope( + type, + pendingProps, + mode, + expirationTime, + key + ); + } } } @@ -19504,7 +22876,6 @@ function createFiberFromElement(element, mode, expirationTime) { mode, expirationTime ); - { fiber._debugSource = element._source; fiber._debugOwner = element._owner; @@ -19517,11 +22888,38 @@ function createFiberFromFragment(elements, mode, expirationTime, key) { fiber.expirationTime = expirationTime; return fiber; } +function createFiberFromFundamental( + fundamentalComponent, + pendingProps, + mode, + expirationTime, + key +) { + var fiber = createFiber(FundamentalComponent, pendingProps, key, mode); + fiber.elementType = fundamentalComponent; + fiber.type = fundamentalComponent; + fiber.expirationTime = expirationTime; + return fiber; +} + +function createFiberFromScope(scope, pendingProps, mode, expirationTime, key) { + var fiber = createFiber(ScopeComponent, pendingProps, key, mode); + fiber.type = scope; + fiber.elementType = scope; + fiber.expirationTime = expirationTime; + return fiber; +} function createFiberFromProfiler(pendingProps, mode, expirationTime, key) { { - if (typeof pendingProps.id !== "string") { - error('Profiler must specify an "id" as a prop'); + if ( + typeof pendingProps.id !== "string" || + typeof pendingProps.onRender !== "function" + ) { + warningWithoutStack$1( + false, + 'Profiler must specify an "id" string and "onRender" function as props' + ); } } @@ -19530,14 +22928,6 @@ function createFiberFromProfiler(pendingProps, mode, expirationTime, key) { fiber.elementType = REACT_PROFILER_TYPE; fiber.type = REACT_PROFILER_TYPE; fiber.expirationTime = expirationTime; - - { - fiber.stateNode = { - effectDuration: 0, - passiveEffectDuration: 0 - }; - } - return fiber; } @@ -19560,7 +22950,6 @@ function createFiberFromSuspenseList(pendingProps, mode, expirationTime, key) { // instead. fiber.type = REACT_SUSPENSE_LIST_TYPE; } - fiber.elementType = REACT_SUSPENSE_LIST_TYPE; fiber.expirationTime = expirationTime; return fiber; @@ -19570,6 +22959,18 @@ function createFiberFromText(content, mode, expirationTime) { fiber.expirationTime = expirationTime; return fiber; } +function createFiberFromHostInstanceForDeletion() { + var fiber = createFiber(HostComponent, null, null, NoMode); // TODO: These should not need a type. + + fiber.elementType = "DELETED"; + fiber.type = "DELETED"; + return fiber; +} +function createFiberFromDehydratedFragment(dehydratedNode) { + var fiber = createFiber(DehydratedFragment, null, null, NoMode); + fiber.stateNode = dehydratedNode; + return fiber; +} function createFiberFromPortal(portal, mode, expirationTime) { var pendingProps = portal.children !== null ? portal.children : []; var fiber = createFiber(HostPortal, pendingProps, portal.key, mode); @@ -19617,21 +23018,16 @@ function assignFiberPropertiesInDEV(target, source) { target.expirationTime = source.expirationTime; target.childExpirationTime = source.childExpirationTime; target.alternate = source.alternate; - - { + if (enableProfilerTimer) { target.actualDuration = source.actualDuration; target.actualStartTime = source.actualStartTime; target.selfBaseDuration = source.selfBaseDuration; target.treeBaseDuration = source.treeBaseDuration; } - - { - target._debugID = source._debugID; - target._debugIsCurrentlyTiming = source._debugIsCurrentlyTiming; - } - + target._debugID = source._debugID; target._debugSource = source._debugSource; target._debugOwner = source._debugOwner; + target._debugIsCurrentlyTiming = source._debugIsCurrentlyTiming; target._debugNeedsRemount = source._debugNeedsRemount; target._debugHookTypes = source._debugHookTypes; return target; @@ -19658,21 +23054,28 @@ function FiberRootNode(containerInfo, tag, hydrate) { this.lastPingedTime = NoWork; this.lastExpiredTime = NoWork; - { + if (enableSchedulerTracing) { this.interactionThreadID = tracing.unstable_getThreadID(); this.memoizedInteractions = new Set(); this.pendingInteractionMap = new Map(); } + + if (enableSuspenseCallback) { + this.hydrationCallbacks = null; + } } function createFiberRoot(containerInfo, tag, hydrate, hydrationCallbacks) { var root = new FiberRootNode(containerInfo, tag, hydrate); + + if (enableSuspenseCallback) { + root.hydrationCallbacks = hydrationCallbacks; + } // Cyclic construction. This cheats the type system right now because // stateNode is any. var uninitializedFiber = createHostRootFiber(tag); root.current = uninitializedFiber; uninitializedFiber.stateNode = root; - initializeUpdateQueue(uninitializedFiber); return root; } function isRootSuspendedAtTime(root, expirationTime) { @@ -19766,6 +23169,15 @@ function markRootExpiredAtTime(root, expirationTime) { } } +// This lets us hook into Fiber to debug what it's doing. +// See https://github.com/facebook/react/pull/8033. +// This is not part of the public API, not even for React DevTools. +// You may only inject a debugTool if you work on React Fiber itself. +var ReactFiberInstrumentation = { + debugTool: null +}; +var ReactFiberInstrumentation_1 = ReactFiberInstrumentation; + var didWarnAboutNestedUpdates; var didWarnAboutFindNodeInStrictMode; @@ -19784,7 +23196,6 @@ function getContextForSubtree(parentComponent) { if (fiber.tag === ClassComponent) { var Component = fiber.type; - if (isContextProvider(Component)) { return processChildContext(fiber, Component, parentContext); } @@ -19793,6 +23204,33 @@ function getContextForSubtree(parentComponent) { return parentContext; } +function findHostInstance(component) { + var fiber = get(component); + + if (fiber === undefined) { + if (typeof component.render === "function") { + { + throw Error("Unable to find node on an unmounted component."); + } + } else { + { + throw Error( + "Argument appears to not be a ReactComponent. Keys: " + + Object.keys(component) + ); + } + } + } + + var hostFiber = findCurrentHostFiber(fiber); + + if (hostFiber === null) { + return null; + } + + return hostFiber.stateNode; +} + function findHostInstanceWithWarning(component, methodName) { { var fiber = get(component); @@ -19825,7 +23263,8 @@ function findHostInstanceWithWarning(component, methodName) { didWarnAboutFindNodeInStrictMode[componentName] = true; if (fiber.mode & StrictMode) { - error( + warningWithoutStack$1( + false, "%s is deprecated in StrictMode. " + "%s was passed an instance of %s which is inside StrictMode. " + "Instead, add a ref directly to the element you want to reference. " + @@ -19837,7 +23276,8 @@ function findHostInstanceWithWarning(component, methodName) { getStackByFiberInDevAndProd(hostFiber) ); } else { - error( + warningWithoutStack$1( + false, "%s is deprecated in StrictMode. " + "%s was passed an instance of %s which renders StrictMode children. " + "Instead, add a ref directly to the element you want to reference. " + @@ -19854,32 +23294,43 @@ function findHostInstanceWithWarning(component, methodName) { return hostFiber.stateNode; } + + return findHostInstance(component); } function createContainer(containerInfo, tag, hydrate, hydrationCallbacks) { - return createFiberRoot(containerInfo, tag, hydrate); + return createFiberRoot(containerInfo, tag, hydrate, hydrationCallbacks); } function updateContainer(element, container, parentComponent, callback) { - { - onScheduleRoot(container, element); - } - - var current$1 = container.current; + var current$$1 = container.current; var currentTime = requestCurrentTimeForUpdate(); { // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests if ("undefined" !== typeof jest) { - warnIfUnmockedScheduler(current$1); + warnIfUnmockedScheduler(current$$1); + warnIfNotScopedWithMatchingAct(current$$1); } } - var suspenseConfig = requestCurrentSuspenseConfig(); var expirationTime = computeExpirationForFiber( currentTime, - current$1, + current$$1, suspenseConfig ); + + { + if (ReactFiberInstrumentation_1.debugTool) { + if (current$$1.alternate === null) { + ReactFiberInstrumentation_1.debugTool.onMountContainer(container); + } else if (element === null) { + ReactFiberInstrumentation_1.debugTool.onUnmountContainer(container); + } else { + ReactFiberInstrumentation_1.debugTool.onUpdateContainer(container); + } + } + } + var context = getContextForSubtree(parentComponent); if (container.context === null) { @@ -19889,10 +23340,10 @@ function updateContainer(element, container, parentComponent, callback) { } { - if (isRendering && current !== null && !didWarnAboutNestedUpdates) { + if (phase === "render" && current !== null && !didWarnAboutNestedUpdates) { didWarnAboutNestedUpdates = true; - - error( + warningWithoutStack$1( + false, "Render methods should be a pure function of props and state; " + "triggering nested component updates from render is not allowed. " + "If necessary, trigger nested updates in componentDidUpdate.\n\n" + @@ -19911,21 +23362,19 @@ function updateContainer(element, container, parentComponent, callback) { callback = callback === undefined ? null : callback; if (callback !== null) { - { - if (typeof callback !== "function") { - error( + !(typeof callback === "function") + ? warningWithoutStack$1( + false, "render(...): Expected the last optional `callback` argument to be a " + "function. Instead received: %s.", callback - ); - } - } - + ) + : void 0; update.callback = callback; } - enqueueUpdate(current$1, update); - scheduleWork(current$1, expirationTime); + enqueueUpdate(current$$1, update); + scheduleWork(current$$1, expirationTime); return expirationTime; } function getPublicRootInstance(container) { @@ -19939,145 +23388,693 @@ function getPublicRootInstance(container) { case HostComponent: return getPublicInstance(containerFiber.child.stateNode); - default: - return containerFiber.child.stateNode; + default: + return containerFiber.child.stateNode; + } +} + +var shouldSuspendImpl = function(fiber) { + return false; +}; + +function shouldSuspend(fiber) { + return shouldSuspendImpl(fiber); +} +var overrideHookState = null; +var overrideProps = null; +var scheduleUpdate = null; +var setSuspenseHandler = null; + +{ + var copyWithSetImpl = function(obj, path, idx, value) { + if (idx >= path.length) { + return value; + } + + var key = path[idx]; + var updated = Array.isArray(obj) ? obj.slice() : Object.assign({}, obj); // $FlowFixMe number or string is fine here + + updated[key] = copyWithSetImpl(obj[key], path, idx + 1, value); + return updated; + }; + + var copyWithSet = function(obj, path, value) { + return copyWithSetImpl(obj, path, 0, value); + }; // Support DevTools editable values for useState and useReducer. + + overrideHookState = function(fiber, id, path, value) { + // For now, the "id" of stateful hooks is just the stateful hook index. + // This may change in the future with e.g. nested hooks. + var currentHook = fiber.memoizedState; + while (currentHook !== null && id > 0) { + currentHook = currentHook.next; + id--; + } + + if (currentHook !== null) { + var newState = copyWithSet(currentHook.memoizedState, path, value); + currentHook.memoizedState = newState; + currentHook.baseState = newState; // We aren't actually adding an update to the queue, + // because there is no update we can add for useReducer hooks that won't trigger an error. + // (There's no appropriate action type for DevTools overrides.) + // As a result though, React will see the scheduled update as a noop and bailout. + // Shallow cloning props works as a workaround for now to bypass the bailout check. + + fiber.memoizedProps = Object.assign({}, fiber.memoizedProps); + scheduleWork(fiber, Sync); + } + }; // Support DevTools props for function components, forwardRef, memo, host components, etc. + + overrideProps = function(fiber, path, value) { + fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value); + + if (fiber.alternate) { + fiber.alternate.pendingProps = fiber.pendingProps; + } + + scheduleWork(fiber, Sync); + }; + + scheduleUpdate = function(fiber) { + scheduleWork(fiber, Sync); + }; + + setSuspenseHandler = function(newShouldSuspendImpl) { + shouldSuspendImpl = newShouldSuspendImpl; + }; +} + +function injectIntoDevTools(devToolsConfig) { + var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance; + var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher; + return injectInternals( + Object.assign({}, devToolsConfig, { + overrideHookState: overrideHookState, + overrideProps: overrideProps, + setSuspenseHandler: setSuspenseHandler, + scheduleUpdate: scheduleUpdate, + currentDispatcherRef: ReactCurrentDispatcher, + findHostInstanceByFiber: function(fiber) { + var hostFiber = findCurrentHostFiber(fiber); + + if (hostFiber === null) { + return null; + } + + return hostFiber.stateNode; + }, + findFiberByHostInstance: function(instance) { + if (!findFiberByHostInstance) { + // Might not be implemented by the renderer. + return null; + } + + return findFiberByHostInstance(instance); + }, + // React Refresh + findHostInstancesForRefresh: findHostInstancesForRefresh, + scheduleRefresh: scheduleRefresh, + scheduleRoot: scheduleRoot, + setRefreshHandler: setRefreshHandler, + // Enables DevTools to append owner stacks to error messages in DEV mode. + getCurrentFiber: function() { + return current; + } + }) + ); +} + +// This file intentionally does *not* have the Flow annotation. +// Don't add it. See `./inline-typed.js` for an explanation. + +function createPortal( + children, + containerInfo, // TODO: figure out the API for cross-renderer implementation. + implementation +) { + var key = + arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null; + return { + // This tag allow us to uniquely identify this as a React Portal + $$typeof: REACT_PORTAL_TYPE, + key: key == null ? null : "" + key, + children: children, + containerInfo: containerInfo, + implementation: implementation + }; +} + +// TODO: this is special because it gets imported during build. + +var ReactVersion = "16.11.0"; + +var NativeMethodsMixin = function(findNodeHandle, findHostInstance) { + /** + * `NativeMethodsMixin` provides methods to access the underlying native + * component directly. This can be useful in cases when you want to focus + * a view or measure its on-screen dimensions, for example. + * + * The methods described here are available on most of the default components + * provided by React Native. Note, however, that they are *not* available on + * composite components that aren't directly backed by a native view. This will + * generally include most components that you define in your own app. For more + * information, see [Direct + * Manipulation](docs/direct-manipulation.html). + * + * Note the Flow $Exact<> syntax is required to support mixins. + * React createClass mixins can only be used with exact types. + */ + var NativeMethodsMixin = { + /** + * Determines the location on screen, width, and height of the given view and + * returns the values via an async callback. If successful, the callback will + * be called with the following arguments: + * + * - x + * - y + * - width + * - height + * - pageX + * - pageY + * + * Note that these measurements are not available until after the rendering + * has been completed in native. If you need the measurements as soon as + * possible, consider using the [`onLayout` + * prop](docs/view.html#onlayout) instead. + */ + measure: function(callback) { + var maybeInstance; // Fiber errors if findNodeHandle is called for an umounted component. + // Tests using ReactTestRenderer will trigger this case indirectly. + // Mimicking stack behavior, we should silently ignore this case. + // TODO Fix ReactTestRenderer so we can remove this try/catch. + + try { + maybeInstance = findHostInstance(this); + } catch (error) {} // If there is no host component beneath this we should fail silently. + // This is not an error; it could mean a class component rendered null. + + if (maybeInstance == null) { + return; + } + + if (maybeInstance.canonical) { + // We can't call FabricUIManager here because it won't be loaded in paper + // at initialization time. See https://github.com/facebook/react/pull/15490 + // for more info. + nativeFabricUIManager.measure( + maybeInstance.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ); + } else { + ReactNativePrivateInterface.UIManager.measure( + findNodeHandle(this), + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ); + } + }, + + /** + * Determines the location of the given view in the window and returns the + * values via an async callback. If the React root view is embedded in + * another native view, this will give you the absolute coordinates. If + * successful, the callback will be called with the following + * arguments: + * + * - x + * - y + * - width + * - height + * + * Note that these measurements are not available until after the rendering + * has been completed in native. + */ + measureInWindow: function(callback) { + var maybeInstance; // Fiber errors if findNodeHandle is called for an umounted component. + // Tests using ReactTestRenderer will trigger this case indirectly. + // Mimicking stack behavior, we should silently ignore this case. + // TODO Fix ReactTestRenderer so we can remove this try/catch. + + try { + maybeInstance = findHostInstance(this); + } catch (error) {} // If there is no host component beneath this we should fail silently. + // This is not an error; it could mean a class component rendered null. + + if (maybeInstance == null) { + return; + } + + if (maybeInstance.canonical) { + // We can't call FabricUIManager here because it won't be loaded in paper + // at initialization time. See https://github.com/facebook/react/pull/15490 + // for more info. + nativeFabricUIManager.measureInWindow( + maybeInstance.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ); + } else { + ReactNativePrivateInterface.UIManager.measureInWindow( + findNodeHandle(this), + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ); + } + }, + + /** + * Like [`measure()`](#measure), but measures the view relative an ancestor, + * specified as `relativeToNativeNode`. This means that the returned x, y + * are relative to the origin x, y of the ancestor view. + * + * As always, to obtain a native node handle for a component, you can use + * `findNodeHandle(component)`. + */ + measureLayout: function( + relativeToNativeNode, + onSuccess, + onFail + ) /* currently unused */ + { + var maybeInstance; // Fiber errors if findNodeHandle is called for an umounted component. + // Tests using ReactTestRenderer will trigger this case indirectly. + // Mimicking stack behavior, we should silently ignore this case. + // TODO Fix ReactTestRenderer so we can remove this try/catch. + + try { + maybeInstance = findHostInstance(this); + } catch (error) {} // If there is no host component beneath this we should fail silently. + // This is not an error; it could mean a class component rendered null. + + if (maybeInstance == null) { + return; + } + + if (maybeInstance.canonical) { + warningWithoutStack$1( + false, + "Warning: measureLayout on components using NativeMethodsMixin " + + "or ReactNative.NativeComponent is not currently supported in Fabric. " + + "measureLayout must be called on a native ref. Consider using forwardRef." + ); + return; + } else { + var relativeNode; + + if (typeof relativeToNativeNode === "number") { + // Already a node handle + relativeNode = relativeToNativeNode; + } else if (relativeToNativeNode._nativeTag) { + relativeNode = relativeToNativeNode._nativeTag; + } + + if (relativeNode == null) { + warningWithoutStack$1( + false, + "Warning: ref.measureLayout must be called with a node handle or a ref to a native component." + ); + return; + } + + ReactNativePrivateInterface.UIManager.measureLayout( + findNodeHandle(this), + relativeNode, + mountSafeCallback_NOT_REALLY_SAFE(this, onFail), + mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) + ); + } + }, + + /** + * This function sends props straight to native. They will not participate in + * future diff process - this means that if you do not include them in the + * next render, they will remain active (see [Direct + * Manipulation](docs/direct-manipulation.html)). + */ + setNativeProps: function(nativeProps) { + // Class components don't have viewConfig -> validateAttributes. + // Nor does it make sense to set native props on a non-native component. + // Instead, find the nearest host component and set props on it. + // Use findNodeHandle() rather than findNodeHandle() because + // We want the instance/wrapper (not the native tag). + var maybeInstance; // Fiber errors if findNodeHandle is called for an umounted component. + // Tests using ReactTestRenderer will trigger this case indirectly. + // Mimicking stack behavior, we should silently ignore this case. + // TODO Fix ReactTestRenderer so we can remove this try/catch. + + try { + maybeInstance = findHostInstance(this); + } catch (error) {} // If there is no host component beneath this we should fail silently. + // This is not an error; it could mean a class component rendered null. + + if (maybeInstance == null) { + return; + } + + if (maybeInstance.canonical) { + warningWithoutStack$1( + false, + "Warning: setNativeProps is not currently supported in Fabric" + ); + return; + } + + var nativeTag = + maybeInstance._nativeTag || maybeInstance.canonical._nativeTag; + var viewConfig = + maybeInstance.viewConfig || maybeInstance.canonical.viewConfig; + + { + warnForStyleProps(nativeProps, viewConfig.validAttributes); + } + + var updatePayload = create(nativeProps, 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( + nativeTag, + viewConfig.uiViewClassName, + updatePayload + ); + } + }, + + /** + * Requests focus for the given input or view. The exact behavior triggered + * will depend on the platform and type of view. + */ + focus: function() { + ReactNativePrivateInterface.TextInputState.focusTextInput( + findNodeHandle(this) + ); + }, + + /** + * Removes focus from an input or view. This is the opposite of `focus()`. + */ + blur: function() { + ReactNativePrivateInterface.TextInputState.blurTextInput( + findNodeHandle(this) + ); + } + }; + + { + // hide this from Flow since we can't define these properties outside of + // true without actually implementing them (setting them to undefined + // isn't allowed by ReactClass) + var NativeMethodsMixin_DEV = NativeMethodsMixin; + + if ( + !( + !NativeMethodsMixin_DEV.componentWillMount && + !NativeMethodsMixin_DEV.componentWillReceiveProps && + !NativeMethodsMixin_DEV.UNSAFE_componentWillMount && + !NativeMethodsMixin_DEV.UNSAFE_componentWillReceiveProps + ) + ) { + throw Error("Do not override existing functions."); + } // TODO (bvaughn) Remove cWM and cWRP in a future version of React Native, + // Once these lifecycles have been remove from the reconciler. + + NativeMethodsMixin_DEV.componentWillMount = function() { + throwOnStylesProp(this, this.props); + }; + + NativeMethodsMixin_DEV.componentWillReceiveProps = function(newProps) { + throwOnStylesProp(this, newProps); + }; + + NativeMethodsMixin_DEV.UNSAFE_componentWillMount = function() { + throwOnStylesProp(this, this.props); + }; + + NativeMethodsMixin_DEV.UNSAFE_componentWillReceiveProps = function( + newProps + ) { + throwOnStylesProp(this, newProps); + }; // React may warn about cWM/cWRP/cWU methods being deprecated. + // Add a flag to suppress these warnings for this special case. + // TODO (bvaughn) Remove this flag once the above methods have been removed. + + NativeMethodsMixin_DEV.componentWillMount.__suppressDeprecationWarning = true; + NativeMethodsMixin_DEV.componentWillReceiveProps.__suppressDeprecationWarning = true; } -} -var shouldSuspendImpl = function(fiber) { - return false; + return NativeMethodsMixin; }; -function shouldSuspend(fiber) { - return shouldSuspendImpl(fiber); -} -var overrideHookState = null; -var overrideProps = null; -var scheduleUpdate = null; -var setSuspenseHandler = null; +var ReactNativeComponent$1 = function(findNodeHandle, findHostInstance) { + /** + * Superclass that provides methods to access the underlying native component. + * This can be useful when you want to focus a view or measure its dimensions. + * + * Methods implemented by this class are available on most default components + * provided by React Native. However, they are *not* available on composite + * components that are not directly backed by a native view. For more + * information, see [Direct Manipulation](docs/direct-manipulation.html). + * + * @abstract + */ + var ReactNativeComponent = + /*#__PURE__*/ + (function(_React$Component) { + _inheritsLoose(ReactNativeComponent, _React$Component); -{ - var copyWithSetImpl = function(obj, path, idx, value) { - if (idx >= path.length) { - return value; - } + function ReactNativeComponent() { + return _React$Component.apply(this, arguments) || this; + } - var key = path[idx]; - var updated = Array.isArray(obj) ? obj.slice() : Object.assign({}, obj); // $FlowFixMe number or string is fine here + var _proto = ReactNativeComponent.prototype; - updated[key] = copyWithSetImpl(obj[key], path, idx + 1, value); - return updated; - }; + /** + * Due to bugs in Flow's handling of React.createClass, some fields already + * declared in the base class need to be redeclared below. + */ - var copyWithSet = function(obj, path, value) { - return copyWithSetImpl(obj, path, 0, value); - }; // Support DevTools editable values for useState and useReducer. + /** + * Removes focus. This is the opposite of `focus()`. + */ + _proto.blur = function blur() { + ReactNativePrivateInterface.TextInputState.blurTextInput( + findNodeHandle(this) + ); + }; + /** + * Requests focus. The exact behavior depends on the platform and view. + */ - overrideHookState = function(fiber, id, path, value) { - // For now, the "id" of stateful hooks is just the stateful hook index. - // This may change in the future with e.g. nested hooks. - var currentHook = fiber.memoizedState; + _proto.focus = function focus() { + ReactNativePrivateInterface.TextInputState.focusTextInput( + findNodeHandle(this) + ); + }; + /** + * Measures the on-screen location and dimensions. If successful, the callback + * will be called asynchronously with the following arguments: + * + * - x + * - y + * - width + * - height + * - pageX + * - pageY + * + * These values are not available until after natives rendering completes. If + * you need the measurements as soon as possible, consider using the + * [`onLayout` prop](docs/view.html#onlayout) instead. + */ + + _proto.measure = function measure(callback) { + var maybeInstance; // Fiber errors if findNodeHandle is called for an umounted component. + // Tests using ReactTestRenderer will trigger this case indirectly. + // Mimicking stack behavior, we should silently ignore this case. + // TODO Fix ReactTestRenderer so we can remove this try/catch. - while (currentHook !== null && id > 0) { - currentHook = currentHook.next; - id--; - } + try { + maybeInstance = findHostInstance(this); + } catch (error) {} // If there is no host component beneath this we should fail silently. + // This is not an error; it could mean a class component rendered null. - if (currentHook !== null) { - var newState = copyWithSet(currentHook.memoizedState, path, value); - currentHook.memoizedState = newState; - currentHook.baseState = newState; // We aren't actually adding an update to the queue, - // because there is no update we can add for useReducer hooks that won't trigger an error. - // (There's no appropriate action type for DevTools overrides.) - // As a result though, React will see the scheduled update as a noop and bailout. - // Shallow cloning props works as a workaround for now to bypass the bailout check. + if (maybeInstance == null) { + return; + } - fiber.memoizedProps = Object.assign({}, fiber.memoizedProps); - scheduleWork(fiber, Sync); - } - }; // Support DevTools props for function components, forwardRef, memo, host components, etc. + if (maybeInstance.canonical) { + // We can't call FabricUIManager here because it won't be loaded in paper + // at initialization time. See https://github.com/facebook/react/pull/15490 + // for more info. + nativeFabricUIManager.measure( + maybeInstance.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ); + } else { + ReactNativePrivateInterface.UIManager.measure( + findNodeHandle(this), + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ); + } + }; + /** + * Measures the on-screen location and dimensions. Even if the React Native + * root view is embedded within another native view, this method will give you + * the absolute coordinates measured from the window. If successful, the + * callback will be called asynchronously with the following arguments: + * + * - x + * - y + * - width + * - height + * + * These values are not available until after natives rendering completes. + */ + + _proto.measureInWindow = function measureInWindow(callback) { + var maybeInstance; // Fiber errors if findNodeHandle is called for an umounted component. + // Tests using ReactTestRenderer will trigger this case indirectly. + // Mimicking stack behavior, we should silently ignore this case. + // TODO Fix ReactTestRenderer so we can remove this try/catch. - overrideProps = function(fiber, path, value) { - fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value); + try { + maybeInstance = findHostInstance(this); + } catch (error) {} // If there is no host component beneath this we should fail silently. + // This is not an error; it could mean a class component rendered null. - if (fiber.alternate) { - fiber.alternate.pendingProps = fiber.pendingProps; - } + if (maybeInstance == null) { + return; + } - scheduleWork(fiber, Sync); - }; + if (maybeInstance.canonical) { + // We can't call FabricUIManager here because it won't be loaded in paper + // at initialization time. See https://github.com/facebook/react/pull/15490 + // for more info. + nativeFabricUIManager.measureInWindow( + maybeInstance.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ); + } else { + ReactNativePrivateInterface.UIManager.measureInWindow( + findNodeHandle(this), + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ); + } + }; + /** + * Similar to [`measure()`](#measure), but the resulting location will be + * relative to the supplied ancestor's location. + * + * Obtain a native node handle with `ReactNative.findNodeHandle(component)`. + */ + + _proto.measureLayout = function measureLayout( + relativeToNativeNode, + onSuccess, + onFail + ) { + var maybeInstance; // Fiber errors if findNodeHandle is called for an umounted component. + // Tests using ReactTestRenderer will trigger this case indirectly. + // Mimicking stack behavior, we should silently ignore this case. + // TODO Fix ReactTestRenderer so we can remove this try/catch. - scheduleUpdate = function(fiber) { - scheduleWork(fiber, Sync); - }; + try { + maybeInstance = findHostInstance(this); + } catch (error) {} // If there is no host component beneath this we should fail silently. + // This is not an error; it could mean a class component rendered null. - setSuspenseHandler = function(newShouldSuspendImpl) { - shouldSuspendImpl = newShouldSuspendImpl; - }; -} + if (maybeInstance == null) { + return; + } -function injectIntoDevTools(devToolsConfig) { - var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance; - var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher; - return injectInternals({ - bundleType: devToolsConfig.bundleType, - version: devToolsConfig.version, - rendererPackageName: devToolsConfig.rendererPackageName, - rendererConfig: devToolsConfig.rendererConfig, - overrideHookState: overrideHookState, - overrideProps: overrideProps, - setSuspenseHandler: setSuspenseHandler, - scheduleUpdate: scheduleUpdate, - currentDispatcherRef: ReactCurrentDispatcher, - findHostInstanceByFiber: function(fiber) { - var hostFiber = findCurrentHostFiber(fiber); - - if (hostFiber === null) { - return null; - } + if (maybeInstance.canonical) { + warningWithoutStack$1( + false, + "Warning: measureLayout on components using NativeMethodsMixin " + + "or ReactNative.NativeComponent is not currently supported in Fabric. " + + "measureLayout must be called on a native ref. Consider using forwardRef." + ); + return; + } else { + var relativeNode; - return hostFiber.stateNode; - }, - findFiberByHostInstance: function(instance) { - if (!findFiberByHostInstance) { - // Might not be implemented by the renderer. - return null; - } + if (typeof relativeToNativeNode === "number") { + // Already a node handle + relativeNode = relativeToNativeNode; + } else if (relativeToNativeNode._nativeTag) { + relativeNode = relativeToNativeNode._nativeTag; + } - return findFiberByHostInstance(instance); - }, - // React Refresh - findHostInstancesForRefresh: findHostInstancesForRefresh, - scheduleRefresh: scheduleRefresh, - scheduleRoot: scheduleRoot, - setRefreshHandler: setRefreshHandler, - // Enables DevTools to append owner stacks to error messages in DEV mode. - getCurrentFiber: function() { - return current; - } - }); -} -var IsSomeRendererActing$1 = ReactSharedInternals.IsSomeRendererActing; + if (relativeNode == null) { + warningWithoutStack$1( + false, + "Warning: ref.measureLayout must be called with a node handle or a ref to a native component." + ); + return; + } -function createPortal( - children, - containerInfo, // TODO: figure out the API for cross-renderer implementation. - implementation -) { - var key = - arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null; - return { - // This tag allow us to uniquely identify this as a React Portal - $$typeof: REACT_PORTAL_TYPE, - key: key == null ? null : "" + key, - children: children, - containerInfo: containerInfo, - implementation: implementation - }; -} + ReactNativePrivateInterface.UIManager.measureLayout( + findNodeHandle(this), + relativeNode, + mountSafeCallback_NOT_REALLY_SAFE(this, onFail), + mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) + ); + } + }; + /** + * This function sends props straight to native. They will not participate in + * future diff process - this means that if you do not include them in the + * next render, they will remain active (see [Direct + * Manipulation](docs/direct-manipulation.html)). + */ + + _proto.setNativeProps = function setNativeProps(nativeProps) { + // Class components don't have viewConfig -> validateAttributes. + // Nor does it make sense to set native props on a non-native component. + // Instead, find the nearest host component and set props on it. + // Use findNodeHandle() rather than ReactNative.findNodeHandle() because + // We want the instance/wrapper (not the native tag). + var maybeInstance; // Fiber errors if findNodeHandle is called for an umounted component. + // Tests using ReactTestRenderer will trigger this case indirectly. + // Mimicking stack behavior, we should silently ignore this case. + // TODO Fix ReactTestRenderer so we can remove this try/catch. -// TODO: this is special because it gets imported during build. -var ReactVersion = "16.13.0"; + try { + maybeInstance = findHostInstance(this); + } catch (error) {} // If there is no host component beneath this we should fail silently. + // This is not an error; it could mean a class component rendered null. + + if (maybeInstance == null) { + return; + } + + if (maybeInstance.canonical) { + warningWithoutStack$1( + false, + "Warning: setNativeProps is not currently supported in Fabric" + ); + return; + } + + var nativeTag = + maybeInstance._nativeTag || maybeInstance.canonical._nativeTag; + var viewConfig = + maybeInstance.viewConfig || maybeInstance.canonical.viewConfig; + var updatePayload = create(nativeProps, 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( + nativeTag, + viewConfig.uiViewClassName, + updatePayload + ); + } + }; + + return ReactNativeComponent; + })(React.Component); // eslint-disable-next-line no-unused-expressions + + return ReactNativeComponent; +}; var instanceCache = new Map(); @@ -20085,14 +24082,13 @@ function getInstanceFromTag(tag) { return instanceCache.get(tag) || null; } -var emptyObject$1 = {}; +var emptyObject$3 = {}; { - Object.freeze(emptyObject$1); + Object.freeze(emptyObject$3); } var getInspectorDataForViewTag; -var getInspectorDataForViewAtPoint; { var traverseOwnerTreeUp = function(hierarchy, instance) { @@ -20116,7 +24112,6 @@ var getInspectorDataForViewAtPoint; return instance; } } - return hierarchy[0]; }; @@ -20124,10 +24119,10 @@ var getInspectorDataForViewAtPoint; var host = findCurrentHostFiber(fiber); if (host) { - return host.memoizedProps || emptyObject$1; + return host.memoizedProps || emptyObject$3; } - return emptyObject$1; + return emptyObject$3; }; var getHostNode = function(fiber, findNodeHandle) { @@ -20155,65 +24150,28 @@ var getInspectorDataForViewAtPoint; name: getComponentName(fiber.type), getInspectorData: function(findNodeHandle) { return { - props: getHostProps(fiber), - source: fiber._debugSource, measure: function(callback) { - // If this is Fabric, we'll find a ShadowNode and use that to measure. - var hostFiber = findCurrentHostFiber(fiber); - var shadowNode = - hostFiber != null && - hostFiber.stateNode !== null && - hostFiber.stateNode.node; - - if (shadowNode) { - nativeFabricUIManager.measure(shadowNode, callback); - } else { - return ReactNativePrivateInterface.UIManager.measure( - getHostNode(fiber, findNodeHandle), - callback - ); - } - } + return ReactNativePrivateInterface.UIManager.measure( + getHostNode(fiber, findNodeHandle), + callback + ); + }, + props: getHostProps(fiber), + source: fiber._debugSource }; } }; }); }; - var getInspectorDataForInstance = function(closestInstance) { - // Handle case where user clicks outside of ReactNative - if (!closestInstance) { - return { - hierarchy: [], - props: emptyObject$1, - selectedIndex: null, - source: null - }; - } - - var fiber = findCurrentFiberUsingSlowPath(closestInstance); - var fiberHierarchy = getOwnerHierarchy(fiber); - var instance = lastNonHostInstance(fiberHierarchy); - var hierarchy = createHierarchy(fiberHierarchy); - var props = getHostProps(instance); - var source = instance._debugSource; - var selectedIndex = fiberHierarchy.indexOf(instance); - return { - hierarchy: hierarchy, - props: props, - selectedIndex: selectedIndex, - source: source - }; - }; - getInspectorDataForViewTag = function(viewTag) { var closestInstance = getInstanceFromTag(viewTag); // Handle case where user clicks outside of ReactNative if (!closestInstance) { return { hierarchy: [], - props: emptyObject$1, - selectedIndex: null, + props: emptyObject$3, + selection: null, source: null }; } @@ -20224,122 +24182,36 @@ var getInspectorDataForViewAtPoint; var hierarchy = createHierarchy(fiberHierarchy); var props = getHostProps(instance); var source = instance._debugSource; - var selectedIndex = fiberHierarchy.indexOf(instance); + var selection = fiberHierarchy.indexOf(instance); return { hierarchy: hierarchy, props: props, - selectedIndex: selectedIndex, + selection: selection, source: source }; }; - - getInspectorDataForViewAtPoint = function( - findNodeHandle, - inspectedView, - locationX, - locationY, - callback - ) { - var closestInstance = null; - - if (inspectedView._internalInstanceHandle != null) { - // For Fabric we can look up the instance handle directly and measure it. - nativeFabricUIManager.findNodeAtPoint( - inspectedView._internalInstanceHandle.stateNode.node, - locationX, - locationY, - function(internalInstanceHandle) { - if (internalInstanceHandle == null) { - callback( - Object.assign( - { - pointerY: locationY, - frame: { - left: 0, - top: 0, - width: 0, - height: 0 - } - }, - getInspectorDataForInstance(closestInstance) - ) - ); - } - - closestInstance = - internalInstanceHandle.stateNode.canonical._internalInstanceHandle; - nativeFabricUIManager.measure( - internalInstanceHandle.stateNode.node, - function(x, y, width, height, pageX, pageY) { - callback( - Object.assign( - { - pointerY: locationY, - frame: { - left: pageX, - top: pageY, - width: width, - height: height - } - }, - getInspectorDataForInstance(closestInstance) - ) - ); - } - ); - } - ); - } else if (inspectedView._internalFiberInstanceHandleDEV != null) { - // For Paper we fall back to the old strategy using the React tag. - ReactNativePrivateInterface.UIManager.findSubviewIn( - findNodeHandle(inspectedView), - [locationX, locationY], - function(nativeViewTag, left, top, width, height) { - var inspectorData = getInspectorDataForInstance( - getInstanceFromTag(nativeViewTag) - ); - callback( - Object.assign({}, inspectorData, { - pointerY: locationY, - frame: { - left: left, - top: top, - width: width, - height: height - }, - touchedViewTag: nativeViewTag - }) - ); - } - ); - } else { - error( - "getInspectorDataForViewAtPoint expects to receieve a host component" - ); - - return; - } - }; } -var ReactCurrentOwner$3 = ReactSharedInternals.ReactCurrentOwner; +var _nativeFabricUIManage = nativeFabricUIManager; +var fabricDispatchCommand = _nativeFabricUIManage.dispatchCommand; +var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner; function findHostInstance_DEPRECATED(componentOrHandle) { { - var owner = ReactCurrentOwner$3.current; + var owner = ReactCurrentOwner.current; if (owner !== null && owner.stateNode !== null) { - if (!owner.stateNode._warnedAboutRefsInRender) { - error( - "%s is accessing findNodeHandle inside its render(). " + - "render() should be a pure function of props and state. It should " + - "never access something that requires stale data from the previous " + - "render, such as refs. Move this logic to componentDidMount and " + - "componentDidUpdate instead.", - getComponentName(owner.type) || "A component" - ); - } - + !owner.stateNode._warnedAboutRefsInRender + ? warningWithoutStack$1( + false, + "%s is accessing findNodeHandle inside its render(). " + + "render() should be a pure function of props and state. It should " + + "never access something that requires stale data from the previous " + + "render, such as refs. Move this logic to componentDidMount and " + + "componentDidUpdate instead.", + getComponentName(owner.type) || "A component" + ) + : void 0; owner.stateNode._warnedAboutRefsInRender = true; } } @@ -20379,20 +24251,20 @@ function findHostInstance_DEPRECATED(componentOrHandle) { function findNodeHandle(componentOrHandle) { { - var owner = ReactCurrentOwner$3.current; + var owner = ReactCurrentOwner.current; if (owner !== null && owner.stateNode !== null) { - if (!owner.stateNode._warnedAboutRefsInRender) { - error( - "%s is accessing findNodeHandle inside its render(). " + - "render() should be a pure function of props and state. It should " + - "never access something that requires stale data from the previous " + - "render, such as refs. Move this logic to componentDidMount and " + - "componentDidUpdate instead.", - getComponentName(owner.type) || "A component" - ); - } - + !owner.stateNode._warnedAboutRefsInRender + ? warningWithoutStack$1( + false, + "%s is accessing findNodeHandle inside its render(). " + + "render() should be a pure function of props and state. It should " + + "never access something that requires stale data from the previous " + + "render, such as refs. Move this logic to componentDidMount and " + + "componentDidUpdate instead.", + getComponentName(owner.type) || "A component" + ) + : void 0; owner.stateNode._warnedAboutRefsInRender = true; } } @@ -20432,95 +24304,94 @@ function findNodeHandle(componentOrHandle) { // Fabric return hostInstance.canonical._nativeTag; } - return hostInstance._nativeTag; } -function dispatchCommand(handle, command, args) { - if (handle._nativeTag == null) { - { - error( - "dispatchCommand was called with a ref that isn't a " + - "native component. Use React.forwardRef to get access to the underlying native component" - ); +setBatchingImplementation( + batchedUpdates$1, + discreteUpdates$1, + flushDiscreteUpdates, + batchedEventUpdates$1 +); +var roots = new Map(); +var ReactFabric = { + NativeComponent: ReactNativeComponent$1(findNodeHandle, findHostInstance), + // This is needed for implementation details of TouchableNativeFeedback + // Remove this once TouchableNativeFeedback doesn't use cloneElement + findHostInstance_DEPRECATED: findHostInstance_DEPRECATED, + findNodeHandle: findNodeHandle, + dispatchCommand: function(handle, command, args) { + var invalid = + handle._nativeTag == null || handle._internalInstanceHandle == null; + + if (invalid) { + !!invalid + ? warningWithoutStack$1( + false, + "dispatchCommand was called with a ref that isn't a " + + "native component. Use React.forwardRef to get access to the underlying native component" + ) + : void 0; + return; } - return; - } - - if (handle._internalInstanceHandle) { - nativeFabricUIManager.dispatchCommand( + fabricDispatchCommand( handle._internalInstanceHandle.stateNode.node, command, args ); - } else { - ReactNativePrivateInterface.UIManager.dispatchViewManagerCommand( - handle._nativeTag, - command, - args - ); - } -} - -function render(element, containerTag, callback) { - var root = roots.get(containerTag); - - 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); - roots.set(containerTag, root); - } - - updateContainer(element, root, null, callback); - return getPublicRootInstance(root); -} - -function unmountComponentAtNode(containerTag) { - this.stopSurface(containerTag); -} + }, + render: function(element, containerTag, callback) { + var root = roots.get(containerTag); -function stopSurface(containerTag) { - var root = roots.get(containerTag); + 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); + roots.set(containerTag, root); + } - if (root) { - // TODO: Is it safe to reset this now or should I wait since this unmount could be deferred? - updateContainer(null, root, null, function() { - roots.delete(containerTag); - }); + updateContainer(element, root, null, callback); + return getPublicRootInstance(root); + }, + unmountComponentAtNode: function(containerTag) { + var root = roots.get(containerTag); + if (root) { + // TODO: Is it safe to reset this now or should I wait since this unmount could be deferred? + updateContainer(null, root, null, function() { + roots.delete(containerTag); + }); + } + }, + createPortal: function(children, containerTag) { + var key = + arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; + return createPortal(children, containerTag, null, key); + }, + __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: { + // Used as a mixin in many createClass-based components + NativeMethodsMixin: NativeMethodsMixin(findNodeHandle, findHostInstance) } -} - -function createPortal$1(children, containerTag) { - var key = - arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; - return createPortal(children, containerTag, null, key); -} - -setBatchingImplementation(batchedUpdates$1); -var roots = new Map(); +}; injectIntoDevTools({ findFiberByHostInstance: getInstanceFromInstance, + getInspectorDataForViewTag: getInspectorDataForViewTag, bundleType: 1, version: ReactVersion, - rendererPackageName: "react-native-renderer", - rendererConfig: { - getInspectorDataForViewTag: getInspectorDataForViewTag, - getInspectorDataForViewAtPoint: getInspectorDataForViewAtPoint.bind( - null, - findNodeHandle - ) - } + rendererPackageName: "react-native-renderer" }); -exports.createPortal = createPortal$1; -exports.dispatchCommand = dispatchCommand; -exports.findHostInstance_DEPRECATED = findHostInstance_DEPRECATED; -exports.findNodeHandle = findNodeHandle; -exports.render = render; -exports.stopSurface = stopSurface; -exports.unmountComponentAtNode = unmountComponentAtNode; +var ReactFabric$2 = Object.freeze({ + default: ReactFabric +}); + +var ReactFabric$3 = (ReactFabric$2 && ReactFabric) || ReactFabric$2; + +// TODO: decide on the top-level export form. +// This is hacky but makes it work with both Rollup and Jest. +var fabric = ReactFabric$3.default || ReactFabric$3; + +module.exports = fabric; })(); } diff --git a/Libraries/Renderer/implementations/ReactFabric-prod.fb.js b/Libraries/Renderer/implementations/ReactFabric-prod.fb.js index 278eba5fa3c464..1977c28b91768a 100644 --- a/Libraries/Renderer/implementations/ReactFabric-prod.fb.js +++ b/Libraries/Renderer/implementations/ReactFabric-prod.fb.js @@ -5,7 +5,6 @@ * LICENSE file in the root directory of this source tree. * * @noflow - * @nolint * @preventMunge * @generated */ @@ -15,16 +14,85 @@ require("react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore"); var ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/ReactNativePrivateInterface"), React = require("react"), Scheduler = require("scheduler"); -function getParent(inst) { - do inst = inst.return; - while (inst && 5 !== inst.tag); - return inst ? inst : null; +var eventPluginOrder = null, + namesToPlugins = {}; +function recomputePluginOrdering() { + if (eventPluginOrder) + for (var pluginName in namesToPlugins) { + var pluginModule = namesToPlugins[pluginName], + pluginIndex = eventPluginOrder.indexOf(pluginName); + if (!(-1 < pluginIndex)) + throw Error( + "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + + pluginName + + "`." + ); + if (!plugins[pluginIndex]) { + if (!pluginModule.extractEvents) + throw Error( + "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + + pluginName + + "` does not." + ); + plugins[pluginIndex] = pluginModule; + pluginIndex = pluginModule.eventTypes; + for (var eventName in pluginIndex) { + var JSCompiler_inline_result = void 0; + var dispatchConfig = pluginIndex[eventName], + pluginModule$jscomp$0 = pluginModule, + eventName$jscomp$0 = eventName; + if (eventNameDispatchConfigs.hasOwnProperty(eventName$jscomp$0)) + throw Error( + "EventPluginHub: More than one plugin attempted to publish the same event name, `" + + eventName$jscomp$0 + + "`." + ); + eventNameDispatchConfigs[eventName$jscomp$0] = dispatchConfig; + var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; + if (phasedRegistrationNames) { + for (JSCompiler_inline_result in phasedRegistrationNames) + phasedRegistrationNames.hasOwnProperty( + JSCompiler_inline_result + ) && + publishRegistrationName( + phasedRegistrationNames[JSCompiler_inline_result], + pluginModule$jscomp$0, + eventName$jscomp$0 + ); + JSCompiler_inline_result = !0; + } else + dispatchConfig.registrationName + ? (publishRegistrationName( + dispatchConfig.registrationName, + pluginModule$jscomp$0, + eventName$jscomp$0 + ), + (JSCompiler_inline_result = !0)) + : (JSCompiler_inline_result = !1); + if (!JSCompiler_inline_result) + throw Error( + "EventPluginRegistry: Failed to publish event `" + + eventName + + "` for plugin `" + + pluginName + + "`." + ); + } + } + } } -function traverseTwoPhase(inst, fn, arg) { - for (var path = []; inst; ) path.push(inst), (inst = getParent(inst)); - for (inst = path.length; 0 < inst--; ) fn(path[inst], "captured", arg); - for (inst = 0; inst < path.length; inst++) fn(path[inst], "bubbled", arg); +function publishRegistrationName(registrationName, pluginModule) { + if (registrationNameModules[registrationName]) + throw Error( + "EventPluginHub: More than one plugin attempted to publish the same registration name, `" + + registrationName + + "`." + ); + registrationNameModules[registrationName] = pluginModule; } +var plugins = [], + eventNameDispatchConfigs = {}, + registrationNameModules = {}; function invokeGuardedCallbackImpl(name, func, context, a, b, c, d, e, f) { var funcArgs = Array.prototype.slice.call(arguments, 3); try { @@ -95,6 +163,74 @@ function executeDirectDispatch(event) { event._dispatchInstances = null; return dispatchListener; } +function accumulateInto(current, next) { + if (null == next) + throw Error( + "accumulateInto(...): Accumulated items must not be null or undefined." + ); + if (null == current) return next; + if (Array.isArray(current)) { + if (Array.isArray(next)) return current.push.apply(current, next), current; + current.push(next); + return current; + } + return Array.isArray(next) ? [current].concat(next) : [current, next]; +} +function forEachAccumulated(arr, cb, scope) { + Array.isArray(arr) ? arr.forEach(cb, scope) : arr && cb.call(scope, arr); +} +var eventQueue = null; +function executeDispatchesAndReleaseTopLevel(e) { + if (e) { + var dispatchListeners = e._dispatchListeners, + dispatchInstances = e._dispatchInstances; + if (Array.isArray(dispatchListeners)) + for ( + var i = 0; + i < dispatchListeners.length && !e.isPropagationStopped(); + i++ + ) + executeDispatch(e, dispatchListeners[i], dispatchInstances[i]); + else + dispatchListeners && + executeDispatch(e, dispatchListeners, dispatchInstances); + e._dispatchListeners = null; + e._dispatchInstances = null; + e.isPersistent() || e.constructor.release(e); + } +} +var injection = { + injectEventPluginOrder: function(injectedEventPluginOrder) { + if (eventPluginOrder) + throw Error( + "EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React." + ); + eventPluginOrder = Array.prototype.slice.call(injectedEventPluginOrder); + recomputePluginOrdering(); + }, + injectEventPluginsByName: function(injectedNamesToPlugins) { + var isOrderingDirty = !1, + pluginName; + for (pluginName in injectedNamesToPlugins) + if (injectedNamesToPlugins.hasOwnProperty(pluginName)) { + var pluginModule = injectedNamesToPlugins[pluginName]; + if ( + !namesToPlugins.hasOwnProperty(pluginName) || + namesToPlugins[pluginName] !== pluginModule + ) { + if (namesToPlugins[pluginName]) + throw Error( + "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + + pluginName + + "`." + ); + namesToPlugins[pluginName] = pluginModule; + isOrderingDirty = !0; + } + } + isOrderingDirty && recomputePluginOrdering(); + } +}; function getListener(inst, registrationName) { var listener = inst.stateNode; if (!listener) return null; @@ -112,7 +248,6 @@ function getListener(inst, registrationName) { case "onMouseMoveCapture": case "onMouseUp": case "onMouseUpCapture": - case "onMouseEnter": (props = !props.disabled) || ((inst = inst.type), (props = !( @@ -137,21 +272,15 @@ function getListener(inst, registrationName) { ); return listener; } -function accumulateInto(current, next) { - if (null == next) - throw Error( - "accumulateInto(...): Accumulated items must not be null or undefined." - ); - if (null == current) return next; - if (Array.isArray(current)) { - if (Array.isArray(next)) return current.push.apply(current, next), current; - current.push(next); - return current; - } - return Array.isArray(next) ? [current].concat(next) : [current, next]; +function getParent(inst) { + do inst = inst.return; + while (inst && 5 !== inst.tag); + return inst ? inst : null; } -function forEachAccumulated(arr, cb, scope) { - Array.isArray(arr) ? arr.forEach(cb, scope) : arr && cb.call(scope, arr); +function traverseTwoPhase(inst, fn, arg) { + for (var path = []; inst; ) path.push(inst), (inst = getParent(inst)); + for (inst = path.length; 0 < inst--; ) fn(path[inst], "captured", arg); + for (inst = 0; inst < path.length; inst++) fn(path[inst], "bubbled", arg); } function accumulateDirectionalDispatches(inst, phase, event) { if ( @@ -219,8 +348,8 @@ function SyntheticEvent( ((targetInst = dispatchConfig[propName]) ? (this[propName] = targetInst(nativeEvent)) : "target" === propName - ? (this.target = nativeEventTarget) - : (this[propName] = nativeEvent[propName])); + ? (this.target = nativeEventTarget) + : (this[propName] = nativeEvent[propName])); this.isDefaultPrevented = (null != nativeEvent.defaultPrevented ? nativeEvent.defaultPrevented : !1 === nativeEvent.returnValue) @@ -373,27 +502,53 @@ function recordTouchStart(touch) { } function recordTouchMove(touch) { var touchRecord = touchBank[getTouchIdentifier(touch)]; - touchRecord && - ((touchRecord.touchActive = !0), - (touchRecord.previousPageX = touchRecord.currentPageX), - (touchRecord.previousPageY = touchRecord.currentPageY), - (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), - (touchRecord.currentPageX = touch.pageX), - (touchRecord.currentPageY = touch.pageY), - (touchRecord.currentTimeStamp = timestampForTouch(touch)), - (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))); + touchRecord + ? ((touchRecord.touchActive = !0), + (touchRecord.previousPageX = touchRecord.currentPageX), + (touchRecord.previousPageY = touchRecord.currentPageY), + (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), + (touchRecord.currentPageX = touch.pageX), + (touchRecord.currentPageY = touch.pageY), + (touchRecord.currentTimeStamp = timestampForTouch(touch)), + (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))) + : console.warn( + "Cannot record touch move without a touch start.\nTouch Move: %s\n", + "Touch Bank: %s", + printTouch(touch), + printTouchBank() + ); } function recordTouchEnd(touch) { var touchRecord = touchBank[getTouchIdentifier(touch)]; - touchRecord && - ((touchRecord.touchActive = !1), - (touchRecord.previousPageX = touchRecord.currentPageX), - (touchRecord.previousPageY = touchRecord.currentPageY), - (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), - (touchRecord.currentPageX = touch.pageX), - (touchRecord.currentPageY = touch.pageY), - (touchRecord.currentTimeStamp = timestampForTouch(touch)), - (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))); + touchRecord + ? ((touchRecord.touchActive = !1), + (touchRecord.previousPageX = touchRecord.currentPageX), + (touchRecord.previousPageY = touchRecord.currentPageY), + (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), + (touchRecord.currentPageX = touch.pageX), + (touchRecord.currentPageY = touch.pageY), + (touchRecord.currentTimeStamp = timestampForTouch(touch)), + (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))) + : console.warn( + "Cannot record touch end without a touch start.\nTouch End: %s\n", + "Touch Bank: %s", + printTouch(touch), + printTouchBank() + ); +} +function printTouch(touch) { + return JSON.stringify({ + identifier: touch.identifier, + pageX: touch.pageX, + pageY: touch.pageY, + timestamp: timestampForTouch(touch) + }); +} +function printTouchBank() { + var printed = JSON.stringify(touchBank.slice(0, 20)); + 20 < touchBank.length && + (printed += " (original size: " + touchBank.length + ")"); + return printed; } var ResponderTouchHistoryStore = { recordTouchTrack: function(topLevelType, nativeEvent) { @@ -433,10 +588,10 @@ function accumulate(current, next) { return null == current ? next : Array.isArray(current) - ? current.concat(next) - : Array.isArray(next) - ? [current].concat(next) - : [current, next]; + ? current.concat(next) + : Array.isArray(next) + ? [current].concat(next) + : [current, next]; } var responderInst = null, trackedTouchCount = 0; @@ -526,7 +681,13 @@ var eventTypes = { "topTouchCancel" === topLevelType ) if (0 <= trackedTouchCount) --trackedTouchCount; - else return null; + else + return ( + console.warn( + "Ended a touch event which was not counted in `trackedTouchCount`." + ), + null + ); ResponderTouchHistoryStore.recordTouchTrack(topLevelType, nativeEvent); if ( targetInst && @@ -538,10 +699,10 @@ var eventTypes = { var shouldSetEventType = isStartish(topLevelType) ? eventTypes.startShouldSetResponder : isMoveish(topLevelType) - ? eventTypes.moveShouldSetResponder - : "topSelectionChange" === topLevelType - ? eventTypes.selectionChangeShouldSetResponder - : eventTypes.scrollShouldSetResponder; + ? eventTypes.moveShouldSetResponder + : "topSelectionChange" === topLevelType + ? eventTypes.selectionChangeShouldSetResponder + : eventTypes.scrollShouldSetResponder; if (responderInst) b: { var JSCompiler_temp = responderInst; @@ -695,10 +856,10 @@ var eventTypes = { (shouldSetEventType = shouldSetEventType ? eventTypes.responderStart : JSCompiler_temp - ? eventTypes.responderMove - : targetInst - ? eventTypes.responderEnd - : null) + ? eventTypes.responderMove + : targetInst + ? eventTypes.responderEnd + : null) ) (shouldSetEventType = ResponderSyntheticEvent.getPooled( shouldSetEventType, @@ -761,8 +922,8 @@ var eventTypes = { (topLevelType = shouldSetEventType ? eventTypes.responderTerminate : topLevelType - ? eventTypes.responderRelease - : null) + ? eventTypes.responderRelease + : null) ) (nativeEvent = ResponderSyntheticEvent.getPooled( topLevelType, @@ -786,160 +947,50 @@ var eventTypes = { } } }, - eventPluginOrder = null, - namesToPlugins = {}; -function recomputePluginOrdering() { - if (eventPluginOrder) - for (var pluginName in namesToPlugins) { - var pluginModule = namesToPlugins[pluginName], - pluginIndex = eventPluginOrder.indexOf(pluginName); - if (!(-1 < pluginIndex)) - throw Error( - "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + - pluginName + - "`." - ); - if (!plugins[pluginIndex]) { - if (!pluginModule.extractEvents) - throw Error( - "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + - pluginName + - "` does not." - ); - plugins[pluginIndex] = pluginModule; - pluginIndex = pluginModule.eventTypes; - for (var eventName in pluginIndex) { - var JSCompiler_inline_result = void 0; - var dispatchConfig = pluginIndex[eventName], - pluginModule$jscomp$0 = pluginModule, - eventName$jscomp$0 = eventName; - if (eventNameDispatchConfigs.hasOwnProperty(eventName$jscomp$0)) - throw Error( - "EventPluginRegistry: More than one plugin attempted to publish the same event name, `" + - eventName$jscomp$0 + - "`." - ); - eventNameDispatchConfigs[eventName$jscomp$0] = dispatchConfig; - var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; - if (phasedRegistrationNames) { - for (JSCompiler_inline_result in phasedRegistrationNames) - phasedRegistrationNames.hasOwnProperty( - JSCompiler_inline_result - ) && - publishRegistrationName( - phasedRegistrationNames[JSCompiler_inline_result], - pluginModule$jscomp$0, - eventName$jscomp$0 - ); - JSCompiler_inline_result = !0; - } else - dispatchConfig.registrationName - ? (publishRegistrationName( - dispatchConfig.registrationName, - pluginModule$jscomp$0, - eventName$jscomp$0 - ), - (JSCompiler_inline_result = !0)) - : (JSCompiler_inline_result = !1); - if (!JSCompiler_inline_result) - throw Error( - "EventPluginRegistry: Failed to publish event `" + - eventName + - "` for plugin `" + - pluginName + - "`." - ); - } - } - } -} -function publishRegistrationName(registrationName, pluginModule) { - if (registrationNameModules[registrationName]) - throw Error( - "EventPluginRegistry: More than one plugin attempted to publish the same registration name, `" + - registrationName + - "`." - ); - registrationNameModules[registrationName] = pluginModule; -} -var plugins = [], - eventNameDispatchConfigs = {}, - registrationNameModules = {}, customBubblingEventTypes = ReactNativePrivateInterface.ReactNativeViewConfigRegistry .customBubblingEventTypes, customDirectEventTypes = ReactNativePrivateInterface.ReactNativeViewConfigRegistry .customDirectEventTypes; -if (eventPluginOrder) - throw Error( - "EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React." - ); -eventPluginOrder = Array.prototype.slice.call([ +injection.injectEventPluginOrder([ "ResponderEventPlugin", "ReactNativeBridgeEventPlugin" ]); -recomputePluginOrdering(); -var injectedNamesToPlugins$jscomp$inline_92 = { - ResponderEventPlugin: ResponderEventPlugin, - ReactNativeBridgeEventPlugin: { - eventTypes: {}, - extractEvents: function( - topLevelType, +injection.injectEventPluginsByName({ + ResponderEventPlugin: ResponderEventPlugin, + ReactNativeBridgeEventPlugin: { + eventTypes: {}, + extractEvents: function( + topLevelType, + targetInst, + nativeEvent, + nativeEventTarget + ) { + if (null == targetInst) return null; + var bubbleDispatchConfig = customBubblingEventTypes[topLevelType], + directDispatchConfig = customDirectEventTypes[topLevelType]; + if (!bubbleDispatchConfig && !directDispatchConfig) + throw Error( + 'Unsupported top level event type "' + topLevelType + '" dispatched' + ); + topLevelType = SyntheticEvent.getPooled( + bubbleDispatchConfig || directDispatchConfig, targetInst, nativeEvent, nativeEventTarget - ) { - if (null == targetInst) return null; - var bubbleDispatchConfig = customBubblingEventTypes[topLevelType], - directDispatchConfig = customDirectEventTypes[topLevelType]; - if (!bubbleDispatchConfig && !directDispatchConfig) - throw Error( - 'Unsupported top level event type "' + topLevelType + '" dispatched' - ); - topLevelType = SyntheticEvent.getPooled( - bubbleDispatchConfig || directDispatchConfig, - targetInst, - nativeEvent, - nativeEventTarget - ); - if (bubbleDispatchConfig) - forEachAccumulated(topLevelType, accumulateTwoPhaseDispatchesSingle); - else if (directDispatchConfig) - forEachAccumulated(topLevelType, accumulateDirectDispatchesSingle); - else return null; - return topLevelType; - } - } - }, - isOrderingDirty$jscomp$inline_93 = !1, - pluginName$jscomp$inline_94; -for (pluginName$jscomp$inline_94 in injectedNamesToPlugins$jscomp$inline_92) - if ( - injectedNamesToPlugins$jscomp$inline_92.hasOwnProperty( - pluginName$jscomp$inline_94 - ) - ) { - var pluginModule$jscomp$inline_95 = - injectedNamesToPlugins$jscomp$inline_92[pluginName$jscomp$inline_94]; - if ( - !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_94) || - namesToPlugins[pluginName$jscomp$inline_94] !== - pluginModule$jscomp$inline_95 - ) { - if (namesToPlugins[pluginName$jscomp$inline_94]) - throw Error( - "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - pluginName$jscomp$inline_94 + - "`." - ); - namesToPlugins[ - pluginName$jscomp$inline_94 - ] = pluginModule$jscomp$inline_95; - isOrderingDirty$jscomp$inline_93 = !0; + ); + if (bubbleDispatchConfig) + forEachAccumulated(topLevelType, accumulateTwoPhaseDispatchesSingle); + else if (directDispatchConfig) + forEachAccumulated(topLevelType, accumulateDirectDispatchesSingle); + else return null; + return topLevelType; } } -isOrderingDirty$jscomp$inline_93 && recomputePluginOrdering(); +}); +var enableNativeTargetAsInstance = require("../shims/ReactFeatureFlags") + .enableNativeTargetAsInstance; function getInstanceFromInstance(instanceHandle) { return instanceHandle; } @@ -948,8 +999,14 @@ getFiberCurrentPropsFromNode = function(inst) { }; getInstanceFromNode = getInstanceFromInstance; getNodeFromInstance = function(inst) { - inst = inst.stateNode.canonical; - if (!inst._nativeTag) throw Error("All native instances should have a tag."); + if (enableNativeTargetAsInstance) { + inst = inst.stateNode.canonical; + if (!inst._nativeTag) + throw Error("All native instances should have a tag."); + return inst; + } + inst = inst.stateNode.canonical._nativeTag; + if (!inst) throw Error("All native instances should have a tag."); return inst; }; ResponderEventPlugin.injection.injectGlobalResponderHandler({ @@ -985,9 +1042,11 @@ var hasSymbol = "function" === typeof Symbol && Symbol.for, ? Symbol.for("react.suspense_list") : 60120, REACT_MEMO_TYPE = hasSymbol ? Symbol.for("react.memo") : 60115, - REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 60116, - REACT_BLOCK_TYPE = hasSymbol ? Symbol.for("react.block") : 60121, - MAYBE_ITERATOR_SYMBOL = "function" === typeof Symbol && Symbol.iterator; + REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 60116; +hasSymbol && Symbol.for("react.fundamental"); +hasSymbol && Symbol.for("react.responder"); +hasSymbol && Symbol.for("react.scope"); +var MAYBE_ITERATOR_SYMBOL = "function" === typeof Symbol && Symbol.iterator; function getIteratorFn(maybeIterable) { if (null === maybeIterable || "object" !== typeof maybeIterable) return null; maybeIterable = @@ -997,10 +1056,9 @@ function getIteratorFn(maybeIterable) { } function initializeLazyComponentType(lazyComponent) { if (-1 === lazyComponent._status) { - var ctor = lazyComponent._result; - ctor || (ctor = lazyComponent._ctor); - ctor = ctor(); lazyComponent._status = 0; + var ctor = lazyComponent._ctor; + ctor = ctor(); lazyComponent._result = ctor; ctor.then( function(moduleObject) { @@ -1037,9 +1095,9 @@ function getComponentName(type) { if ("object" === typeof type) switch (type.$$typeof) { case REACT_CONTEXT_TYPE: - return (type.displayName || "Context") + ".Consumer"; + return "Context.Consumer"; case REACT_PROVIDER_TYPE: - return (type._context.displayName || "Context") + ".Provider"; + return "Context.Provider"; case REACT_FORWARD_REF_TYPE: var innerType = type.render; innerType = innerType.displayName || innerType.name || ""; @@ -1049,8 +1107,6 @@ function getComponentName(type) { ); case REACT_MEMO_TYPE: return getComponentName(type.type); - case REACT_BLOCK_TYPE: - return getComponentName(type.render); case REACT_LAZY_TYPE: if ((type = 1 === type._status ? type._result : null)) return getComponentName(type); @@ -1240,8 +1296,8 @@ function diffNestedProperty( return nextProp ? addNestedProperty(updatePayload, nextProp, validAttributes) : prevProp - ? clearNestedProperty(updatePayload, prevProp, validAttributes) - : updatePayload; + ? clearNestedProperty(updatePayload, prevProp, validAttributes) + : updatePayload; if (!Array.isArray(prevProp) && !Array.isArray(nextProp)) return diffProperties(updatePayload, prevProp, nextProp, validAttributes); if (Array.isArray(prevProp) && Array.isArray(nextProp)) { @@ -1402,9 +1458,18 @@ function diffProperties(updatePayload, prevProps, nextProps, validAttributes) { ))))); return updatePayload; } +var restoreTarget = null, + restoreQueue = null; +function restoreStateOfTarget(target) { + if (getInstanceFromNode(target)) + throw Error( + "setRestoreImplementation() needs to be called to handle a target for controlled events. This error is likely caused by a bug in React. Please file an issue." + ); +} function batchedUpdatesImpl(fn, bookkeeping) { return fn(bookkeeping); } +function flushDiscreteUpdatesImpl() {} var isInsideEventHandler = !1; function batchedUpdates(fn, bookkeeping) { if (isInsideEventHandler) return fn(bookkeeping); @@ -1412,35 +1477,48 @@ function batchedUpdates(fn, bookkeeping) { try { return batchedUpdatesImpl(fn, bookkeeping); } finally { - isInsideEventHandler = !1; - } -} -var eventQueue = null; -function executeDispatchesAndReleaseTopLevel(e) { - if (e) { - var dispatchListeners = e._dispatchListeners, - dispatchInstances = e._dispatchInstances; - if (Array.isArray(dispatchListeners)) - for ( - var i = 0; - i < dispatchListeners.length && !e.isPropagationStopped(); - i++ + if ( + ((isInsideEventHandler = !1), + null !== restoreTarget || null !== restoreQueue) + ) + if ( + (flushDiscreteUpdatesImpl(), + restoreTarget && + ((bookkeeping = restoreTarget), + (fn = restoreQueue), + (restoreQueue = restoreTarget = null), + restoreStateOfTarget(bookkeeping), + fn)) ) - executeDispatch(e, dispatchListeners[i], dispatchInstances[i]); - else - dispatchListeners && - executeDispatch(e, dispatchListeners, dispatchInstances); - e._dispatchListeners = null; - e._dispatchInstances = null; - e.isPersistent() || e.constructor.release(e); + for (bookkeeping = 0; bookkeeping < fn.length; bookkeeping++) + restoreStateOfTarget(fn[bookkeeping]); } } +function _inheritsLoose(subClass, superClass) { + subClass.prototype = Object.create(superClass.prototype); + subClass.prototype.constructor = subClass; + subClass.__proto__ = superClass; +} +(function(_React$Component) { + function ReactNativeComponent() { + return _React$Component.apply(this, arguments) || this; + } + _inheritsLoose(ReactNativeComponent, _React$Component); + var _proto = ReactNativeComponent.prototype; + _proto.blur = function() {}; + _proto.focus = function() {}; + _proto.measure = function() {}; + _proto.measureInWindow = function() {}; + _proto.measureLayout = function() {}; + _proto.setNativeProps = function() {}; + return ReactNativeComponent; +})(React.Component); +new Map(); function dispatchEvent(target, topLevelType, nativeEvent) { var eventTarget = null; - if (null != target) { - var stateNode = target.stateNode; - null != stateNode && (eventTarget = stateNode.canonical); - } + enableNativeTargetAsInstance + ? null != target && (eventTarget = target.stateNode.canonical) + : (eventTarget = nativeEvent.target); batchedUpdates(function() { var events = eventTarget; for (var events$jscomp$0 = null, i = 0; i < plugins.length; i++) { @@ -1478,21 +1556,21 @@ function shim$1() { "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." ); } -var _nativeFabricUIManage = nativeFabricUIManager, - createNode = _nativeFabricUIManage.createNode, - cloneNode = _nativeFabricUIManage.cloneNode, - cloneNodeWithNewChildren = _nativeFabricUIManage.cloneNodeWithNewChildren, +var _nativeFabricUIManage$1 = nativeFabricUIManager, + createNode = _nativeFabricUIManage$1.createNode, + cloneNode = _nativeFabricUIManage$1.cloneNode, + cloneNodeWithNewChildren = _nativeFabricUIManage$1.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, + _nativeFabricUIManage$1.cloneNodeWithNewChildrenAndProps, + cloneNodeWithNewProps = _nativeFabricUIManage$1.cloneNodeWithNewProps, + createChildNodeSet = _nativeFabricUIManage$1.createChildSet, + appendChildNode = _nativeFabricUIManage$1.appendChild, + appendChildNodeToSet = _nativeFabricUIManage$1.appendChildToSet, + completeRoot = _nativeFabricUIManage$1.completeRoot, + registerEventHandler = _nativeFabricUIManage$1.registerEventHandler, + fabricMeasure = _nativeFabricUIManage$1.measure, + fabricMeasureInWindow = _nativeFabricUIManage$1.measureInWindow, + fabricMeasureLayout = _nativeFabricUIManage$1.measureLayout, getViewConfigForType = ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get, nextReactTag = 2; @@ -1511,10 +1589,10 @@ var ReactFabricHostComponent = (function() { } var _proto = ReactFabricHostComponent.prototype; _proto.blur = function() { - ReactNativePrivateInterface.TextInputState.blurTextInput(this); + ReactNativePrivateInterface.TextInputState.blurTextInput(this._nativeTag); }; _proto.focus = function() { - ReactNativePrivateInterface.TextInputState.focusTextInput(this); + ReactNativePrivateInterface.TextInputState.focusTextInput(this._nativeTag); }; _proto.measure = function(callback) { fabricMeasure( @@ -1576,6 +1654,44 @@ function cloneHiddenInstance(instance) { canonical: instance.canonical }; } +var BEFORE_SLASH_RE = /^(.*)[\\\/]/; +function getStackByFiberInDevAndProd(workInProgress) { + var info = ""; + do { + a: switch (workInProgress.tag) { + case 3: + case 4: + case 6: + case 7: + case 10: + case 9: + var JSCompiler_inline_result = ""; + break a; + default: + var owner = workInProgress._debugOwner, + source = workInProgress._debugSource, + name = getComponentName(workInProgress.type); + JSCompiler_inline_result = null; + owner && (JSCompiler_inline_result = getComponentName(owner.type)); + owner = name; + name = ""; + source + ? (name = + " (at " + + source.fileName.replace(BEFORE_SLASH_RE, "") + + ":" + + source.lineNumber + + ")") + : JSCompiler_inline_result && + (name = " (created by " + JSCompiler_inline_result + ")"); + JSCompiler_inline_result = "\n in " + (owner || "Unknown") + name; + } + info += JSCompiler_inline_result; + workInProgress = workInProgress.return; + } while (workInProgress); + return info; +} +new Set(); var valueStack = [], index = -1; function pop(cursor) { @@ -1613,17 +1729,21 @@ function isContextProvider(type) { type = type.childContextTypes; return null !== type && void 0 !== type; } -function popContext() { - pop(didPerformWorkStackCursor); - pop(contextStackCursor); +function popContext(fiber) { + pop(didPerformWorkStackCursor, fiber); + pop(contextStackCursor, fiber); +} +function popTopLevelContextObject(fiber) { + pop(didPerformWorkStackCursor, fiber); + pop(contextStackCursor, fiber); } 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); + push(contextStackCursor, context, fiber); + push(didPerformWorkStackCursor, didChange, fiber); } function processChildContext(fiber, type, parentContext) { var instance = fiber.stateNode; @@ -1641,13 +1761,17 @@ function processChildContext(fiber, type, parentContext) { return Object.assign({}, parentContext, {}, instance); } function pushContextProvider(workInProgress) { - workInProgress = - ((workInProgress = workInProgress.stateNode) && - workInProgress.__reactInternalMemoizedMergedChildContext) || + var instance = workInProgress.stateNode; + instance = + (instance && instance.__reactInternalMemoizedMergedChildContext) || emptyContextObject; previousContext = contextStackCursor.current; - push(contextStackCursor, workInProgress); - push(didPerformWorkStackCursor, didPerformWorkStackCursor.current); + push(contextStackCursor, instance, workInProgress); + push( + didPerformWorkStackCursor, + didPerformWorkStackCursor.current, + workInProgress + ); return !0; } function invalidateContextProvider(workInProgress, type, didChange) { @@ -1657,21 +1781,18 @@ function invalidateContextProvider(workInProgress, type, didChange) { "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); + ? ((type = processChildContext(workInProgress, type, previousContext)), + (instance.__reactInternalMemoizedMergedChildContext = type), + pop(didPerformWorkStackCursor, workInProgress), + pop(contextStackCursor, workInProgress), + push(contextStackCursor, type, workInProgress)) + : pop(didPerformWorkStackCursor, workInProgress); + push(didPerformWorkStackCursor, didChange, workInProgress); } 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 = @@ -1682,7 +1803,6 @@ var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, Scheduler_LowPriority = Scheduler.unstable_LowPriority, Scheduler_IdlePriority = Scheduler.unstable_IdlePriority, fakeCallbackNode = {}, - shouldYield = Scheduler.unstable_shouldYield, requestPaint = void 0 !== Scheduler_requestPaint ? Scheduler_requestPaint : function() {}, syncQueue = null, @@ -1727,7 +1847,7 @@ function reactPriorityToSchedulerPriority(reactPriorityLevel) { throw Error("Unknown priority level."); } } -function runWithPriority(reactPriorityLevel, fn) { +function runWithPriority$1(reactPriorityLevel, fn) { reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); return Scheduler_runWithPriority(reactPriorityLevel, fn); } @@ -1759,7 +1879,7 @@ function flushSyncCallbackQueueImpl() { var i = 0; try { var queue = syncQueue; - runWithPriority(99, function() { + runWithPriority$1(99, function() { for (; i < queue.length; i++) { var callback = queue[i]; do callback = callback(!0); @@ -1782,10 +1902,10 @@ function flushSyncCallbackQueueImpl() { function is(x, y) { return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y); } -var objectIs = "function" === typeof Object.is ? Object.is : is, +var is$1 = "function" === typeof Object.is ? Object.is : is, hasOwnProperty = Object.prototype.hasOwnProperty; function shallowEqual(objA, objB) { - if (objectIs(objA, objB)) return !0; + if (is$1(objA, objB)) return !0; if ( "object" !== typeof objA || null === objA || @@ -1799,48 +1919,11 @@ function shallowEqual(objA, objB) { for (keysB = 0; keysB < keysA.length; keysB++) if ( !hasOwnProperty.call(objB, keysA[keysB]) || - !objectIs(objA[keysA[keysB]], objB[keysA[keysB]]) + !is$1(objA[keysA[keysB]], objB[keysA[keysB]]) ) return !1; return !0; } -var BEFORE_SLASH_RE = /^(.*)[\\\/]/; -function getStackByFiberInDevAndProd(workInProgress) { - var info = ""; - do { - a: switch (workInProgress.tag) { - case 3: - case 4: - case 6: - case 7: - case 10: - case 9: - var JSCompiler_inline_result = ""; - break a; - default: - var owner = workInProgress._debugOwner, - source = workInProgress._debugSource, - name = getComponentName(workInProgress.type); - JSCompiler_inline_result = null; - owner && (JSCompiler_inline_result = getComponentName(owner.type)); - owner = name; - name = ""; - source - ? (name = - " (at " + - source.fileName.replace(BEFORE_SLASH_RE, "") + - ":" + - source.lineNumber + - ")") - : JSCompiler_inline_result && - (name = " (created by " + JSCompiler_inline_result + ")"); - JSCompiler_inline_result = "\n in " + (owner || "Unknown") + name; - } - info += JSCompiler_inline_result; - workInProgress = workInProgress.return; - } while (workInProgress); - return info; -} function resolveDefaultProps(Component, baseProps) { if (Component && Component.defaultProps) { baseProps = Object.assign({}, baseProps); @@ -1858,9 +1941,14 @@ var valueCursor = { current: null }, function resetContextDependencies() { lastContextWithAllBitsObserved = lastContextDependency = currentlyRenderingFiber = null; } +function pushProvider(providerFiber, nextValue) { + var context = providerFiber.type._context; + push(valueCursor, context._currentValue2, providerFiber); + context._currentValue2 = nextValue; +} function popProvider(providerFiber) { var currentValue = valueCursor.current; - pop(valueCursor); + pop(valueCursor, providerFiber); providerFiber.type._context._currentValue2 = currentValue; } function scheduleWorkOnParentPath(parent, renderExpirationTime) { @@ -1915,195 +2003,237 @@ function readContext(context, observedBits) { return context._currentValue2; } var hasForceUpdate = !1; -function initializeUpdateQueue(fiber) { - fiber.updateQueue = { - baseState: fiber.memoizedState, - baseQueue: null, - shared: { pending: null }, - effects: null +function createUpdateQueue(baseState) { + return { + baseState: baseState, + firstUpdate: null, + lastUpdate: null, + firstCapturedUpdate: null, + lastCapturedUpdate: null, + firstEffect: null, + lastEffect: null, + firstCapturedEffect: null, + lastCapturedEffect: null }; } -function cloneUpdateQueue(current, workInProgress) { - current = current.updateQueue; - workInProgress.updateQueue === current && - (workInProgress.updateQueue = { - baseState: current.baseState, - baseQueue: current.baseQueue, - shared: current.shared, - effects: current.effects - }); +function cloneUpdateQueue(currentQueue) { + return { + baseState: currentQueue.baseState, + firstUpdate: currentQueue.firstUpdate, + lastUpdate: currentQueue.lastUpdate, + firstCapturedUpdate: null, + lastCapturedUpdate: null, + firstEffect: null, + lastEffect: null, + firstCapturedEffect: null, + lastCapturedEffect: null + }; } function createUpdate(expirationTime, suspenseConfig) { - expirationTime = { + return { expirationTime: expirationTime, suspenseConfig: suspenseConfig, tag: 0, payload: null, callback: null, - next: null + next: null, + nextEffect: null }; - return (expirationTime.next = expirationTime); +} +function appendUpdateToQueue(queue, update) { + null === queue.lastUpdate + ? (queue.firstUpdate = queue.lastUpdate = update) + : ((queue.lastUpdate.next = update), (queue.lastUpdate = update)); } function enqueueUpdate(fiber, update) { - 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; - } + var alternate = fiber.alternate; + if (null === alternate) { + var queue1 = fiber.updateQueue; + var queue2 = null; + null === queue1 && + (queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState)); + } else + (queue1 = fiber.updateQueue), + (queue2 = alternate.updateQueue), + null === queue1 + ? null === queue2 + ? ((queue1 = fiber.updateQueue = createUpdateQueue( + fiber.memoizedState + )), + (queue2 = alternate.updateQueue = createUpdateQueue( + alternate.memoizedState + ))) + : (queue1 = fiber.updateQueue = cloneUpdateQueue(queue2)) + : null === queue2 && + (queue2 = alternate.updateQueue = cloneUpdateQueue(queue1)); + null === queue2 || queue1 === queue2 + ? appendUpdateToQueue(queue1, update) + : null === queue1.lastUpdate || null === queue2.lastUpdate + ? (appendUpdateToQueue(queue1, update), + appendUpdateToQueue(queue2, update)) + : (appendUpdateToQueue(queue1, update), (queue2.lastUpdate = update)); } function enqueueCapturedUpdate(workInProgress, update) { + var workInProgressQueue = workInProgress.updateQueue; + workInProgressQueue = + null === workInProgressQueue + ? (workInProgress.updateQueue = createUpdateQueue( + workInProgress.memoizedState + )) + : ensureWorkInProgressQueueIsAClone(workInProgress, workInProgressQueue); + null === workInProgressQueue.lastCapturedUpdate + ? (workInProgressQueue.firstCapturedUpdate = workInProgressQueue.lastCapturedUpdate = update) + : ((workInProgressQueue.lastCapturedUpdate.next = update), + (workInProgressQueue.lastCapturedUpdate = update)); +} +function ensureWorkInProgressQueueIsAClone(workInProgress, queue) { var current = workInProgress.alternate; - null !== current && cloneUpdateQueue(current, workInProgress); - workInProgress = workInProgress.updateQueue; - current = workInProgress.baseQueue; - null === current - ? ((workInProgress.baseQueue = update.next = update), - (update.next = update)) - : ((update.next = current.next), (current.next = update)); + null !== current && + queue === current.updateQueue && + (queue = workInProgress.updateQueue = cloneUpdateQueue(queue)); + return queue; +} +function getStateFromUpdate( + workInProgress, + queue, + update, + prevState, + nextProps, + instance +) { + switch (update.tag) { + case 1: + return ( + (workInProgress = update.payload), + "function" === typeof workInProgress + ? workInProgress.call(instance, prevState, nextProps) + : workInProgress + ); + case 3: + workInProgress.effectTag = (workInProgress.effectTag & -4097) | 64; + case 0: + workInProgress = update.payload; + nextProps = + "function" === typeof workInProgress + ? workInProgress.call(instance, prevState, nextProps) + : workInProgress; + if (null === nextProps || void 0 === nextProps) break; + return Object.assign({}, prevState, nextProps); + case 2: + hasForceUpdate = !0; + } + return prevState; } function processUpdateQueue( - workInProgress$jscomp$0, + workInProgress, + queue, props, instance, renderExpirationTime ) { - var queue = workInProgress$jscomp$0.updateQueue; hasForceUpdate = !1; - var baseQueue = queue.baseQueue, - pendingQueue = queue.shared.pending; - if (null !== pendingQueue) { - if (null !== baseQueue) { - var baseFirst = baseQueue.next; - baseQueue.next = pendingQueue.next; - pendingQueue.next = baseFirst; - } - baseQueue = pendingQueue; - queue.shared.pending = null; - baseFirst = workInProgress$jscomp$0.alternate; - null !== baseFirst && - ((baseFirst = baseFirst.updateQueue), - null !== baseFirst && (baseFirst.baseQueue = pendingQueue)); - } - if (null !== baseQueue) { - baseFirst = baseQueue.next; - var newState = queue.baseState, + queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue); + for ( + var newBaseState = queue.baseState, + newFirstUpdate = null, newExpirationTime = 0, - newBaseState = null, - newBaseQueueFirst = null, - newBaseQueueLast = null; - if (null !== baseFirst) { - var update = baseFirst; - do { - pendingQueue = update.expirationTime; - if (pendingQueue < renderExpirationTime) { - var clone = { - expirationTime: update.expirationTime, - suspenseConfig: update.suspenseConfig, - tag: update.tag, - payload: update.payload, - callback: update.callback, - next: null - }; - null === newBaseQueueLast - ? ((newBaseQueueFirst = newBaseQueueLast = clone), - (newBaseState = newState)) - : (newBaseQueueLast = newBaseQueueLast.next = clone); - pendingQueue > newExpirationTime && - (newExpirationTime = pendingQueue); - } else { - null !== newBaseQueueLast && - (newBaseQueueLast = newBaseQueueLast.next = { - expirationTime: 1073741823, - suspenseConfig: update.suspenseConfig, - tag: update.tag, - payload: update.payload, - callback: update.callback, - next: null - }); - markRenderEventTimeAndConfig(pendingQueue, update.suspenseConfig); - a: { - var workInProgress = workInProgress$jscomp$0, - update$jscomp$0 = update; - pendingQueue = props; - clone = instance; - switch (update$jscomp$0.tag) { - case 1: - workInProgress = update$jscomp$0.payload; - if ("function" === typeof workInProgress) { - newState = workInProgress.call(clone, newState, pendingQueue); - break a; - } - newState = workInProgress; - break a; - case 3: - workInProgress.effectTag = - (workInProgress.effectTag & -4097) | 64; - case 0: - workInProgress = update$jscomp$0.payload; - pendingQueue = - "function" === typeof workInProgress - ? workInProgress.call(clone, newState, pendingQueue) - : workInProgress; - if (null === pendingQueue || void 0 === pendingQueue) break a; - newState = Object.assign({}, newState, pendingQueue); - break a; - case 2: - hasForceUpdate = !0; - } - } - null !== update.callback && - ((workInProgress$jscomp$0.effectTag |= 32), - (pendingQueue = queue.effects), - null === pendingQueue - ? (queue.effects = [update]) - : pendingQueue.push(update)); - } - update = update.next; - if (null === update || update === baseFirst) - if (((pendingQueue = queue.shared.pending), null === pendingQueue)) - break; - else - (update = baseQueue.next = pendingQueue.next), - (pendingQueue.next = baseFirst), - (queue.baseQueue = baseQueue = pendingQueue), - (queue.shared.pending = null); - } while (1); - } - null === newBaseQueueLast - ? (newBaseState = newState) - : (newBaseQueueLast.next = newBaseQueueFirst); - queue.baseState = newBaseState; - queue.baseQueue = newBaseQueueLast; - markUnprocessedUpdateTime(newExpirationTime); - workInProgress$jscomp$0.expirationTime = newExpirationTime; - workInProgress$jscomp$0.memoizedState = newState; + update = queue.firstUpdate, + resultState = newBaseState; + null !== update; + + ) { + var updateExpirationTime = update.expirationTime; + updateExpirationTime < renderExpirationTime + ? (null === newFirstUpdate && + ((newFirstUpdate = update), (newBaseState = resultState)), + newExpirationTime < updateExpirationTime && + (newExpirationTime = updateExpirationTime)) + : (markRenderEventTimeAndConfig( + updateExpirationTime, + update.suspenseConfig + ), + (resultState = getStateFromUpdate( + workInProgress, + queue, + update, + resultState, + props, + instance + )), + null !== update.callback && + ((workInProgress.effectTag |= 32), + (update.nextEffect = null), + null === queue.lastEffect + ? (queue.firstEffect = queue.lastEffect = update) + : ((queue.lastEffect.nextEffect = update), + (queue.lastEffect = update)))); + update = update.next; + } + updateExpirationTime = null; + for (update = queue.firstCapturedUpdate; null !== update; ) { + var _updateExpirationTime = update.expirationTime; + _updateExpirationTime < renderExpirationTime + ? (null === updateExpirationTime && + ((updateExpirationTime = update), + null === newFirstUpdate && (newBaseState = resultState)), + newExpirationTime < _updateExpirationTime && + (newExpirationTime = _updateExpirationTime)) + : ((resultState = getStateFromUpdate( + workInProgress, + queue, + update, + resultState, + props, + instance + )), + null !== update.callback && + ((workInProgress.effectTag |= 32), + (update.nextEffect = null), + null === queue.lastCapturedEffect + ? (queue.firstCapturedEffect = queue.lastCapturedEffect = update) + : ((queue.lastCapturedEffect.nextEffect = update), + (queue.lastCapturedEffect = update)))); + update = update.next; } + null === newFirstUpdate && (queue.lastUpdate = null); + null === updateExpirationTime + ? (queue.lastCapturedUpdate = null) + : (workInProgress.effectTag |= 32); + null === newFirstUpdate && + null === updateExpirationTime && + (newBaseState = resultState); + queue.baseState = newBaseState; + queue.firstUpdate = newFirstUpdate; + queue.firstCapturedUpdate = updateExpirationTime; + markUnprocessedUpdateTime(newExpirationTime); + workInProgress.expirationTime = newExpirationTime; + workInProgress.memoizedState = resultState; } function commitUpdateQueue(finishedWork, finishedQueue, instance) { - finishedWork = finishedQueue.effects; - finishedQueue.effects = null; - if (null !== finishedWork) - for ( - finishedQueue = 0; - finishedQueue < finishedWork.length; - finishedQueue++ - ) { - var effect = finishedWork[finishedQueue], - callback = effect.callback; - if (null !== callback) { - effect.callback = null; - if ("function" !== typeof callback) - throw Error( - "Invalid argument passed as callback. Expected a function. Instead received: " + - callback - ); - callback.call(instance); - } + null !== finishedQueue.firstCapturedUpdate && + (null !== finishedQueue.lastUpdate && + ((finishedQueue.lastUpdate.next = finishedQueue.firstCapturedUpdate), + (finishedQueue.lastUpdate = finishedQueue.lastCapturedUpdate)), + (finishedQueue.firstCapturedUpdate = finishedQueue.lastCapturedUpdate = null)); + commitUpdateEffects(finishedQueue.firstEffect, instance); + finishedQueue.firstEffect = finishedQueue.lastEffect = null; + commitUpdateEffects(finishedQueue.firstCapturedEffect, instance); + finishedQueue.firstCapturedEffect = finishedQueue.lastCapturedEffect = null; +} +function commitUpdateEffects(effect, instance) { + for (; null !== effect; ) { + var callback = effect.callback; + if (null !== callback) { + effect.callback = null; + if ("function" !== typeof callback) + throw Error( + "Invalid argument passed as callback. Expected a function. Instead received: " + + callback + ); + callback.call(instance); } + effect = effect.nextEffect; + } } var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig, emptyRefsObject = new React.Component().refs; @@ -2120,8 +2250,10 @@ function applyDerivedStateFromProps( ? ctor : Object.assign({}, ctor, getDerivedStateFromProps); workInProgress.memoizedState = getDerivedStateFromProps; - 0 === workInProgress.expirationTime && - (workInProgress.updateQueue.baseState = getDerivedStateFromProps); + nextProps = workInProgress.updateQueue; + null !== nextProps && + 0 === workInProgress.expirationTime && + (nextProps.baseState = getDerivedStateFromProps); } var classComponentUpdater = { isMounted: function(component) { @@ -2140,7 +2272,7 @@ var classComponentUpdater = { null !== callback && (suspenseConfig.callback = callback); enqueueUpdate(inst, suspenseConfig); - scheduleWork(inst, currentTime); + scheduleUpdateOnFiber(inst, currentTime); }, enqueueReplaceState: function(inst, payload, callback) { inst = inst._reactInternalFiber; @@ -2154,7 +2286,7 @@ var classComponentUpdater = { null !== callback && (suspenseConfig.callback = callback); enqueueUpdate(inst, suspenseConfig); - scheduleWork(inst, currentTime); + scheduleUpdateOnFiber(inst, currentTime); }, enqueueForceUpdate: function(inst, callback) { inst = inst._reactInternalFiber; @@ -2167,7 +2299,7 @@ var classComponentUpdater = { null !== callback && (suspenseConfig.callback = callback); enqueueUpdate(inst, suspenseConfig); - scheduleWork(inst, currentTime); + scheduleUpdateOnFiber(inst, currentTime); } }; function checkShouldComponentUpdate( @@ -2183,8 +2315,8 @@ function checkShouldComponentUpdate( return "function" === typeof workInProgress.shouldComponentUpdate ? workInProgress.shouldComponentUpdate(newProps, newState, nextContext) : ctor.prototype && ctor.prototype.isPureReactComponent - ? !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState) - : !0; + ? !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState) + : !0; } function constructClassInstance(workInProgress, ctor, props) { var isLegacyContextConsumer = !1, @@ -2236,7 +2368,6 @@ function mountClassInstance( instance.props = newProps; instance.state = workInProgress.memoizedState; instance.refs = emptyRefsObject; - initializeUpdateQueue(workInProgress); var contextType = ctor.contextType; "object" === typeof contextType && null !== contextType ? (instance.context = readContext(contextType)) @@ -2244,8 +2375,16 @@ function mountClassInstance( ? previousContext : contextStackCursor.current), (instance.context = getMaskedContext(workInProgress, contextType))); - processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); - instance.state = workInProgress.memoizedState; + contextType = workInProgress.updateQueue; + null !== contextType && + (processUpdateQueue( + workInProgress, + contextType, + newProps, + instance, + renderExpirationTime + ), + (instance.state = workInProgress.memoizedState)); contextType = ctor.getDerivedStateFromProps; "function" === typeof contextType && (applyDerivedStateFromProps(workInProgress, ctor, contextType, newProps), @@ -2261,18 +2400,21 @@ function mountClassInstance( instance.UNSAFE_componentWillMount(), ctor !== instance.state && classComponentUpdater.enqueueReplaceState(instance, instance.state, null), - processUpdateQueue( - workInProgress, - newProps, - instance, - renderExpirationTime - ), - (instance.state = workInProgress.memoizedState)); + (contextType = workInProgress.updateQueue), + null !== contextType && + (processUpdateQueue( + workInProgress, + contextType, + newProps, + instance, + renderExpirationTime + ), + (instance.state = workInProgress.memoizedState))); "function" === typeof instance.componentDidMount && (workInProgress.effectTag |= 4); } var isArray = Array.isArray; -function coerceRef(returnFiber, current, element) { +function coerceRef(returnFiber, current$$1, element) { returnFiber = element.ref; if ( null !== returnFiber && @@ -2284,7 +2426,7 @@ function coerceRef(returnFiber, current, element) { if (element) { if (1 !== element.tag) throw Error( - "Function components cannot have string refs. We recommend using useRef() instead. Learn more about using refs safely here: https://fb.me/react-strict-mode-string-ref" + "Function components cannot have refs. Did you mean to use React.forwardRef()?" ); var inst = element.stateNode; } @@ -2296,19 +2438,19 @@ function coerceRef(returnFiber, current, element) { ); var stringRef = "" + returnFiber; if ( - null !== current && - null !== current.ref && - "function" === typeof current.ref && - current.ref._stringRef === stringRef + null !== current$$1 && + null !== current$$1.ref && + "function" === typeof current$$1.ref && + current$$1.ref._stringRef === stringRef ) - return current.ref; - current = function(value) { + return current$$1.ref; + current$$1 = function(value) { var refs = inst.refs; refs === emptyRefsObject && (refs = inst.refs = {}); null === value ? delete refs[stringRef] : (refs[stringRef] = value); }; - current._stringRef = stringRef; - return current; + current$$1._stringRef = stringRef; + return current$$1; } if ("string" !== typeof returnFiber) throw Error( @@ -2360,8 +2502,8 @@ function ChildReconciler(shouldTrackSideEffects) { (currentFirstChild = currentFirstChild.sibling); return returnFiber; } - function useFiber(fiber, pendingProps) { - fiber = createWorkInProgress(fiber, pendingProps); + function useFiber(fiber, pendingProps, expirationTime) { + fiber = createWorkInProgress(fiber, pendingProps, expirationTime); fiber.index = 0; fiber.sibling = null; return fiber; @@ -2386,26 +2528,31 @@ function ChildReconciler(shouldTrackSideEffects) { (newFiber.effectTag = 2); return newFiber; } - function updateTextNode(returnFiber, current, textContent, expirationTime) { - if (null === current || 6 !== current.tag) + function updateTextNode( + returnFiber, + current$$1, + textContent, + expirationTime + ) { + if (null === current$$1 || 6 !== current$$1.tag) return ( - (current = createFiberFromText( + (current$$1 = createFiberFromText( textContent, returnFiber.mode, expirationTime )), - (current.return = returnFiber), - current + (current$$1.return = returnFiber), + current$$1 ); - current = useFiber(current, textContent); - current.return = returnFiber; - return current; + current$$1 = useFiber(current$$1, textContent, expirationTime); + current$$1.return = returnFiber; + return current$$1; } - function updateElement(returnFiber, current, element, expirationTime) { - if (null !== current && current.elementType === element.type) + function updateElement(returnFiber, current$$1, element, expirationTime) { + if (null !== current$$1 && current$$1.elementType === element.type) return ( - (expirationTime = useFiber(current, element.props)), - (expirationTime.ref = coerceRef(returnFiber, current, element)), + (expirationTime = useFiber(current$$1, element.props, expirationTime)), + (expirationTime.ref = coerceRef(returnFiber, current$$1, element)), (expirationTime.return = returnFiber), expirationTime ); @@ -2417,45 +2564,51 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime ); - expirationTime.ref = coerceRef(returnFiber, current, element); + expirationTime.ref = coerceRef(returnFiber, current$$1, element); expirationTime.return = returnFiber; return expirationTime; } - function updatePortal(returnFiber, current, portal, expirationTime) { + function updatePortal(returnFiber, current$$1, portal, expirationTime) { if ( - null === current || - 4 !== current.tag || - current.stateNode.containerInfo !== portal.containerInfo || - current.stateNode.implementation !== portal.implementation + null === current$$1 || + 4 !== current$$1.tag || + current$$1.stateNode.containerInfo !== portal.containerInfo || + current$$1.stateNode.implementation !== portal.implementation ) return ( - (current = createFiberFromPortal( + (current$$1 = createFiberFromPortal( portal, returnFiber.mode, expirationTime )), - (current.return = returnFiber), - current + (current$$1.return = returnFiber), + current$$1 ); - current = useFiber(current, portal.children || []); - current.return = returnFiber; - return current; + current$$1 = useFiber(current$$1, portal.children || [], expirationTime); + current$$1.return = returnFiber; + return current$$1; } - function updateFragment(returnFiber, current, fragment, expirationTime, key) { - if (null === current || 7 !== current.tag) + function updateFragment( + returnFiber, + current$$1, + fragment, + expirationTime, + key + ) { + if (null === current$$1 || 7 !== current$$1.tag) return ( - (current = createFiberFromFragment( + (current$$1 = createFiberFromFragment( fragment, returnFiber.mode, expirationTime, key )), - (current.return = returnFiber), - current + (current$$1.return = returnFiber), + current$$1 ); - current = useFiber(current, fragment); - current.return = returnFiber; - return current; + current$$1 = useFiber(current$$1, fragment, expirationTime); + current$$1.return = returnFiber; + return current$$1; } function createChild(returnFiber, newChild, expirationTime) { if ("string" === typeof newChild || "number" === typeof newChild) @@ -2818,48 +2971,39 @@ function ChildReconciler(shouldTrackSideEffects) { 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; - } + if (isUnkeyedTopLevelFragment.key === isObject) + if ( + 7 === isUnkeyedTopLevelFragment.tag + ? newChild.type === REACT_FRAGMENT_TYPE + : isUnkeyedTopLevelFragment.elementType === newChild.type + ) { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment.sibling + ); + currentFirstChild = useFiber( + isUnkeyedTopLevelFragment, + newChild.type === REACT_FRAGMENT_TYPE + ? newChild.props.children + : newChild.props, + expirationTime + ); + currentFirstChild.ref = coerceRef( + returnFiber, + isUnkeyedTopLevelFragment, + newChild + ); + currentFirstChild.return = returnFiber; + returnFiber = currentFirstChild; + break a; + } else { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment + ); + break; } - deleteRemainingChildren(returnFiber, isUnkeyedTopLevelFragment); - break; - } else deleteChild(returnFiber, isUnkeyedTopLevelFragment); + else deleteChild(returnFiber, isUnkeyedTopLevelFragment); isUnkeyedTopLevelFragment = isUnkeyedTopLevelFragment.sibling; } newChild.type === REACT_FRAGMENT_TYPE @@ -2909,7 +3053,8 @@ function ChildReconciler(shouldTrackSideEffects) { ); currentFirstChild = useFiber( currentFirstChild, - newChild.children || [] + newChild.children || [], + expirationTime ); currentFirstChild.return = returnFiber; returnFiber = currentFirstChild; @@ -2936,7 +3081,11 @@ function ChildReconciler(shouldTrackSideEffects) { (newChild = "" + newChild), null !== currentFirstChild && 6 === currentFirstChild.tag ? (deleteRemainingChildren(returnFiber, currentFirstChild.sibling), - (currentFirstChild = useFiber(currentFirstChild, newChild)), + (currentFirstChild = useFiber( + currentFirstChild, + newChild, + expirationTime + )), (currentFirstChild.return = returnFiber), (returnFiber = currentFirstChild)) : (deleteRemainingChildren(returnFiber, currentFirstChild), @@ -2991,16 +3140,16 @@ function requiredContext(c) { return c; } function pushHostContainer(fiber, nextRootInstance) { - push(rootInstanceStackCursor, nextRootInstance); - push(contextFiberStackCursor, fiber); - push(contextStackCursor$1, NO_CONTEXT); - pop(contextStackCursor$1); - push(contextStackCursor$1, { isInAParentText: !1 }); + push(rootInstanceStackCursor, nextRootInstance, fiber); + push(contextFiberStackCursor, fiber, fiber); + push(contextStackCursor$1, NO_CONTEXT, fiber); + pop(contextStackCursor$1, fiber); + push(contextStackCursor$1, { isInAParentText: !1 }, fiber); } -function popHostContainer() { - pop(contextStackCursor$1); - pop(contextFiberStackCursor); - pop(rootInstanceStackCursor); +function popHostContainer(fiber) { + pop(contextStackCursor$1, fiber); + pop(contextFiberStackCursor, fiber); + pop(rootInstanceStackCursor, fiber); } function pushHostContext(fiber) { requiredContext(rootInstanceStackCursor.current); @@ -3017,19 +3166,23 @@ function pushHostContext(fiber) { ? { isInAParentText: nextContext } : context; context !== nextContext && - (push(contextFiberStackCursor, fiber), - push(contextStackCursor$1, nextContext)); + (push(contextFiberStackCursor, fiber, fiber), + push(contextStackCursor$1, nextContext, fiber)); } function popHostContext(fiber) { contextFiberStackCursor.current === fiber && - (pop(contextStackCursor$1), pop(contextFiberStackCursor)); + (pop(contextStackCursor$1, fiber), pop(contextFiberStackCursor, fiber)); } var suspenseStackCursor = { current: 0 }; function findFirstSuspended(row) { for (var node = row; null !== node; ) { if (13 === node.tag) { var state = node.memoizedState; - if (null !== state && (null === state.dehydrated || shim$1() || shim$1())) + if ( + null !== state && + ((state = state.dehydrated), + null === state || shim$1(state) || shim$1(state)) + ) return node; } else if (19 === node.tag && void 0 !== node.memoizedProps.revealOrder) { if (0 !== (node.effectTag & 64)) return node; @@ -3048,16 +3201,24 @@ function findFirstSuspended(row) { } return null; } -function createDeprecatedResponderListener(responder, props) { +function createResponderListener(responder, props) { return { responder: responder, props: props }; } -var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher, +var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig, - renderExpirationTime = 0, + renderExpirationTime$1 = 0, currentlyRenderingFiber$1 = null, currentHook = null, + nextCurrentHook = null, + firstWorkInProgressHook = null, workInProgressHook = null, - didScheduleRenderPhaseUpdate = !1; + nextWorkInProgressHook = null, + remainingExpirationTime = 0, + componentUpdateQueue = null, + sideEffectTag = 0, + didScheduleRenderPhaseUpdate = !1, + renderPhaseUpdates = null, + numberOfReRenders = 0; function throwInvalidHookError() { throw Error( "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem." @@ -3066,7 +3227,7 @@ function throwInvalidHookError() { function areHookInputsEqual(nextDeps, prevDeps) { if (null === prevDeps) return !1; for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) - if (!objectIs(nextDeps[i], prevDeps[i])) return !1; + if (!is$1(nextDeps[i], prevDeps[i])) return !1; return !0; } function renderWithHooks( @@ -3074,85 +3235,92 @@ function renderWithHooks( workInProgress, Component, props, - secondArg, + refOrContext, nextRenderExpirationTime ) { - renderExpirationTime = nextRenderExpirationTime; + renderExpirationTime$1 = nextRenderExpirationTime; currentlyRenderingFiber$1 = workInProgress; - workInProgress.memoizedState = null; - workInProgress.updateQueue = null; - workInProgress.expirationTime = 0; - ReactCurrentDispatcher.current = - null === current || null === current.memoizedState - ? HooksDispatcherOnMount - : HooksDispatcherOnUpdate; - current = Component(props, secondArg); - if (workInProgress.expirationTime === renderExpirationTime) { - nextRenderExpirationTime = 0; - do { - workInProgress.expirationTime = 0; - if (!(25 > nextRenderExpirationTime)) - throw Error( - "Too many re-renders. React limits the number of renders to prevent an infinite loop." - ); - nextRenderExpirationTime += 1; - workInProgressHook = currentHook = null; - workInProgress.updateQueue = null; - ReactCurrentDispatcher.current = HooksDispatcherOnRerender; - current = Component(props, secondArg); - } while (workInProgress.expirationTime === renderExpirationTime); + nextCurrentHook = null !== current ? current.memoizedState : null; + ReactCurrentDispatcher$1.current = + null === nextCurrentHook ? HooksDispatcherOnMount : HooksDispatcherOnUpdate; + workInProgress = Component(props, refOrContext); + if (didScheduleRenderPhaseUpdate) { + do + (didScheduleRenderPhaseUpdate = !1), + (numberOfReRenders += 1), + (nextCurrentHook = null !== current ? current.memoizedState : null), + (nextWorkInProgressHook = firstWorkInProgressHook), + (componentUpdateQueue = workInProgressHook = currentHook = null), + (ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdate), + (workInProgress = Component(props, refOrContext)); + while (didScheduleRenderPhaseUpdate); + renderPhaseUpdates = null; + numberOfReRenders = 0; } - ReactCurrentDispatcher.current = ContextOnlyDispatcher; - workInProgress = null !== currentHook && null !== currentHook.next; - renderExpirationTime = 0; - workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; - didScheduleRenderPhaseUpdate = !1; - if (workInProgress) + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; + current = currentlyRenderingFiber$1; + current.memoizedState = firstWorkInProgressHook; + current.expirationTime = remainingExpirationTime; + current.updateQueue = componentUpdateQueue; + current.effectTag |= sideEffectTag; + current = null !== currentHook && null !== currentHook.next; + renderExpirationTime$1 = 0; + nextWorkInProgressHook = workInProgressHook = firstWorkInProgressHook = nextCurrentHook = currentHook = currentlyRenderingFiber$1 = null; + remainingExpirationTime = 0; + componentUpdateQueue = null; + sideEffectTag = 0; + if (current) throw Error( "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." ); - return current; + return workInProgress; +} +function resetHooks() { + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; + renderExpirationTime$1 = 0; + nextWorkInProgressHook = workInProgressHook = firstWorkInProgressHook = nextCurrentHook = currentHook = currentlyRenderingFiber$1 = null; + remainingExpirationTime = 0; + componentUpdateQueue = null; + sideEffectTag = 0; + didScheduleRenderPhaseUpdate = !1; + renderPhaseUpdates = null; + numberOfReRenders = 0; } function mountWorkInProgressHook() { var hook = { memoizedState: null, baseState: null, - baseQueue: null, queue: null, + baseUpdate: null, next: null }; null === workInProgressHook - ? (currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook) + ? (firstWorkInProgressHook = workInProgressHook = hook) : (workInProgressHook = workInProgressHook.next = hook); return workInProgressHook; } function updateWorkInProgressHook() { - if (null === currentHook) { - var nextCurrentHook = currentlyRenderingFiber$1.alternate; - nextCurrentHook = - null !== nextCurrentHook ? nextCurrentHook.memoizedState : null; - } else nextCurrentHook = currentHook.next; - var nextWorkInProgressHook = - null === workInProgressHook - ? currentlyRenderingFiber$1.memoizedState - : workInProgressHook.next; if (null !== nextWorkInProgressHook) (workInProgressHook = nextWorkInProgressHook), - (currentHook = nextCurrentHook); + (nextWorkInProgressHook = workInProgressHook.next), + (currentHook = nextCurrentHook), + (nextCurrentHook = null !== currentHook ? currentHook.next : null); else { if (null === nextCurrentHook) throw Error("Rendered more hooks than during the previous render."); currentHook = nextCurrentHook; - nextCurrentHook = { + var newHook = { memoizedState: currentHook.memoizedState, baseState: currentHook.baseState, - baseQueue: currentHook.baseQueue, queue: currentHook.queue, + baseUpdate: currentHook.baseUpdate, next: null }; - null === workInProgressHook - ? (currentlyRenderingFiber$1.memoizedState = workInProgressHook = nextCurrentHook) - : (workInProgressHook = workInProgressHook.next = nextCurrentHook); + workInProgressHook = + null === workInProgressHook + ? (firstWorkInProgressHook = newHook) + : (workInProgressHook.next = newHook); + nextCurrentHook = currentHook.next; } return workInProgressHook; } @@ -3167,100 +3335,74 @@ function updateReducer(reducer) { "Should have a queue. This is likely a bug in React. Please file an issue." ); queue.lastRenderedReducer = reducer; - var current = currentHook, - baseQueue = current.baseQueue, - pendingQueue = queue.pending; - if (null !== pendingQueue) { - if (null !== baseQueue) { - var baseFirst = baseQueue.next; - baseQueue.next = pendingQueue.next; - pendingQueue.next = baseFirst; + if (0 < numberOfReRenders) { + var _dispatch = queue.dispatch; + if (null !== renderPhaseUpdates) { + var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue); + if (void 0 !== firstRenderPhaseUpdate) { + renderPhaseUpdates.delete(queue); + var newState = hook.memoizedState; + do + (newState = reducer(newState, firstRenderPhaseUpdate.action)), + (firstRenderPhaseUpdate = firstRenderPhaseUpdate.next); + while (null !== firstRenderPhaseUpdate); + is$1(newState, hook.memoizedState) || (didReceiveUpdate = !0); + hook.memoizedState = newState; + hook.baseUpdate === queue.last && (hook.baseState = newState); + queue.lastRenderedState = newState; + return [newState, _dispatch]; + } } - current.baseQueue = baseQueue = pendingQueue; - queue.pending = null; + return [hook.memoizedState, _dispatch]; } - if (null !== baseQueue) { - baseQueue = baseQueue.next; - current = current.baseState; - var newBaseQueueLast = (baseFirst = pendingQueue = null), - update = baseQueue; + _dispatch = queue.last; + var baseUpdate = hook.baseUpdate; + newState = hook.baseState; + null !== baseUpdate + ? (null !== _dispatch && (_dispatch.next = null), + (_dispatch = baseUpdate.next)) + : (_dispatch = null !== _dispatch ? _dispatch.next : null); + if (null !== _dispatch) { + var newBaseUpdate = (firstRenderPhaseUpdate = null), + _update = _dispatch, + didSkip = !1; do { - var updateExpirationTime = update.expirationTime; - if (updateExpirationTime < renderExpirationTime) { - var clone = { - expirationTime: update.expirationTime, - suspenseConfig: update.suspenseConfig, - action: update.action, - eagerReducer: update.eagerReducer, - eagerState: update.eagerState, - next: null - }; - null === newBaseQueueLast - ? ((baseFirst = newBaseQueueLast = clone), (pendingQueue = current)) - : (newBaseQueueLast = newBaseQueueLast.next = clone); - updateExpirationTime > currentlyRenderingFiber$1.expirationTime && - ((currentlyRenderingFiber$1.expirationTime = updateExpirationTime), - markUnprocessedUpdateTime(updateExpirationTime)); - } else - null !== newBaseQueueLast && - (newBaseQueueLast = newBaseQueueLast.next = { - expirationTime: 1073741823, - suspenseConfig: update.suspenseConfig, - action: update.action, - eagerReducer: update.eagerReducer, - eagerState: update.eagerState, - next: null - }), - markRenderEventTimeAndConfig( + var updateExpirationTime = _update.expirationTime; + updateExpirationTime < renderExpirationTime$1 + ? (didSkip || + ((didSkip = !0), + (newBaseUpdate = baseUpdate), + (firstRenderPhaseUpdate = newState)), + updateExpirationTime > remainingExpirationTime && + ((remainingExpirationTime = updateExpirationTime), + markUnprocessedUpdateTime(remainingExpirationTime))) + : (markRenderEventTimeAndConfig( updateExpirationTime, - update.suspenseConfig + _update.suspenseConfig ), - (current = - update.eagerReducer === reducer - ? update.eagerState - : reducer(current, update.action)); - update = update.next; - } while (null !== update && update !== baseQueue); - null === newBaseQueueLast - ? (pendingQueue = current) - : (newBaseQueueLast.next = baseFirst); - objectIs(current, hook.memoizedState) || (didReceiveUpdate = !0); - hook.memoizedState = current; - hook.baseState = pendingQueue; - hook.baseQueue = newBaseQueueLast; - queue.lastRenderedState = current; - } - return [hook.memoizedState, queue.dispatch]; -} -function rerenderReducer(reducer) { - var hook = updateWorkInProgressHook(), - queue = hook.queue; - if (null === queue) - throw Error( - "Should have a queue. This is likely a bug in React. Please file an issue." - ); - queue.lastRenderedReducer = reducer; - var dispatch = queue.dispatch, - lastRenderPhaseUpdate = queue.pending, - newState = hook.memoizedState; - if (null !== lastRenderPhaseUpdate) { - queue.pending = null; - var update = (lastRenderPhaseUpdate = lastRenderPhaseUpdate.next); - do (newState = reducer(newState, update.action)), (update = update.next); - while (update !== lastRenderPhaseUpdate); - objectIs(newState, hook.memoizedState) || (didReceiveUpdate = !0); + (newState = + _update.eagerReducer === reducer + ? _update.eagerState + : reducer(newState, _update.action))); + baseUpdate = _update; + _update = _update.next; + } while (null !== _update && _update !== _dispatch); + didSkip || + ((newBaseUpdate = baseUpdate), (firstRenderPhaseUpdate = newState)); + is$1(newState, hook.memoizedState) || (didReceiveUpdate = !0); hook.memoizedState = newState; - null === hook.baseQueue && (hook.baseState = newState); + hook.baseUpdate = newBaseUpdate; + hook.baseState = firstRenderPhaseUpdate; queue.lastRenderedState = newState; } - return [newState, dispatch]; + return [hook.memoizedState, queue.dispatch]; } function mountState(initialState) { var hook = mountWorkInProgressHook(); "function" === typeof initialState && (initialState = initialState()); hook.memoizedState = hook.baseState = initialState; initialState = hook.queue = { - pending: null, + last: null, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState @@ -3272,30 +3414,28 @@ function mountState(initialState) { ); return [hook.memoizedState, initialState]; } +function updateState(initialState) { + return updateReducer(basicStateReducer, initialState); +} function pushEffect(tag, create, destroy, deps) { tag = { tag: tag, create: create, destroy: destroy, deps: deps, next: null }; - create = currentlyRenderingFiber$1.updateQueue; - null === create - ? ((create = { lastEffect: null }), - (currentlyRenderingFiber$1.updateQueue = create), - (create.lastEffect = tag.next = tag)) - : ((destroy = create.lastEffect), - null === destroy - ? (create.lastEffect = tag.next = tag) - : ((deps = destroy.next), - (destroy.next = tag), - (tag.next = deps), - (create.lastEffect = tag))); + null === componentUpdateQueue + ? ((componentUpdateQueue = { lastEffect: null }), + (componentUpdateQueue.lastEffect = tag.next = tag)) + : ((create = componentUpdateQueue.lastEffect), + null === create + ? (componentUpdateQueue.lastEffect = tag.next = tag) + : ((destroy = create.next), + (create.next = tag), + (tag.next = destroy), + (componentUpdateQueue.lastEffect = tag))); return tag; } -function updateRef() { - return updateWorkInProgressHook().memoizedState; -} function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var hook = mountWorkInProgressHook(); - currentlyRenderingFiber$1.effectTag |= fiberEffectTag; + sideEffectTag |= fiberEffectTag; hook.memoizedState = pushEffect( - 1 | hookEffectTag, + hookEffectTag, create, void 0, void 0 === deps ? null : deps @@ -3309,21 +3449,18 @@ function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var prevEffect = currentHook.memoizedState; destroy = prevEffect.destroy; if (null !== deps && areHookInputsEqual(deps, prevEffect.deps)) { - pushEffect(hookEffectTag, create, destroy, deps); + pushEffect(0, create, destroy, deps); return; } } - currentlyRenderingFiber$1.effectTag |= fiberEffectTag; - hook.memoizedState = pushEffect(1 | hookEffectTag, create, destroy, deps); + sideEffectTag |= fiberEffectTag; + hook.memoizedState = pushEffect(hookEffectTag, create, destroy, deps); } function mountEffect(create, deps) { - return mountEffectImpl(516, 4, create, deps); + return mountEffectImpl(516, 192, create, deps); } function updateEffect(create, deps) { - return updateEffectImpl(516, 4, create, deps); -} -function updateLayoutEffect(create, deps) { - return updateEffectImpl(4, 2, create, deps); + return updateEffectImpl(516, 192, create, deps); } function imperativeHandleEffect(create, ref) { if ("function" === typeof ref) @@ -3343,15 +3480,6 @@ function imperativeHandleEffect(create, ref) { } ); } -function updateImperativeHandle(ref, create, deps) { - deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; - return updateEffectImpl( - 4, - 2, - imperativeHandleEffect.bind(null, create, ref), - deps - ); -} function mountDebugValue() {} function mountCallback(callback, deps) { mountWorkInProgressHook().memoizedState = [ @@ -3373,79 +3501,72 @@ function updateCallback(callback, deps) { hook.memoizedState = [callback, deps]; return callback; } -function updateMemo(nextCreate, deps) { - var hook = updateWorkInProgressHook(); - deps = void 0 === deps ? null : deps; - var prevState = hook.memoizedState; - if ( - null !== prevState && - null !== deps && - areHookInputsEqual(deps, prevState[1]) - ) - return prevState[0]; - nextCreate = nextCreate(); - hook.memoizedState = [nextCreate, deps]; - return nextCreate; -} -function startTransition(setPending, config, callback) { - var priorityLevel = getCurrentPriorityLevel(); - runWithPriority(98 > priorityLevel ? 98 : priorityLevel, function() { - setPending(!0); - }); - runWithPriority(97 < priorityLevel ? 97 : priorityLevel, function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = void 0 === config ? null : config; - try { - setPending(!1), callback(); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); -} function dispatchAction(fiber, queue, action) { - var currentTime = requestCurrentTimeForUpdate(), - suspenseConfig = ReactCurrentBatchConfig.suspense; - currentTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig); - suspenseConfig = { - expirationTime: currentTime, - suspenseConfig: suspenseConfig, - action: action, - eagerReducer: null, - eagerState: null, - next: null - }; - var pending = queue.pending; - null === pending - ? (suspenseConfig.next = suspenseConfig) - : ((suspenseConfig.next = pending.next), (pending.next = suspenseConfig)); - queue.pending = suspenseConfig; - pending = fiber.alternate; + if (!(25 > numberOfReRenders)) + throw Error( + "Too many re-renders. React limits the number of renders to prevent an infinite loop." + ); + var alternate = fiber.alternate; if ( fiber === currentlyRenderingFiber$1 || - (null !== pending && pending === currentlyRenderingFiber$1) + (null !== alternate && alternate === currentlyRenderingFiber$1) ) - (didScheduleRenderPhaseUpdate = !0), - (suspenseConfig.expirationTime = renderExpirationTime), - (currentlyRenderingFiber$1.expirationTime = renderExpirationTime); + if ( + ((didScheduleRenderPhaseUpdate = !0), + (fiber = { + expirationTime: renderExpirationTime$1, + suspenseConfig: null, + action: action, + eagerReducer: null, + eagerState: null, + next: null + }), + null === renderPhaseUpdates && (renderPhaseUpdates = new Map()), + (action = renderPhaseUpdates.get(queue)), + void 0 === action) + ) + renderPhaseUpdates.set(queue, fiber); + else { + for (queue = action; null !== queue.next; ) queue = queue.next; + queue.next = fiber; + } else { + var currentTime = requestCurrentTimeForUpdate(), + suspenseConfig = ReactCurrentBatchConfig.suspense; + currentTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig); + suspenseConfig = { + expirationTime: currentTime, + suspenseConfig: suspenseConfig, + action: action, + eagerReducer: null, + eagerState: null, + next: null + }; + var last = queue.last; + if (null === last) suspenseConfig.next = suspenseConfig; + else { + var first = last.next; + null !== first && (suspenseConfig.next = first); + last.next = suspenseConfig; + } + queue.last = suspenseConfig; if ( 0 === fiber.expirationTime && - (null === pending || 0 === pending.expirationTime) && - ((pending = queue.lastRenderedReducer), null !== pending) + (null === alternate || 0 === alternate.expirationTime) && + ((alternate = queue.lastRenderedReducer), null !== alternate) ) try { var currentState = queue.lastRenderedState, - eagerState = pending(currentState, action); - suspenseConfig.eagerReducer = pending; + eagerState = alternate(currentState, action); + suspenseConfig.eagerReducer = alternate; suspenseConfig.eagerState = eagerState; - if (objectIs(eagerState, currentState)) return; + if (is$1(eagerState, currentState)) return; } catch (error) { } finally { } - scheduleWork(fiber, currentTime); + scheduleUpdateOnFiber(fiber, currentTime); } } -function updateEventListener() {} var ContextOnlyDispatcher = { readContext: readContext, useCallback: throwInvalidHookError, @@ -3460,8 +3581,7 @@ var ContextOnlyDispatcher = { useDebugValue: throwInvalidHookError, useResponder: throwInvalidHookError, useDeferredValue: throwInvalidHookError, - useTransition: throwInvalidHookError, - useEvent: throwInvalidHookError + useTransition: throwInvalidHookError }, HooksDispatcherOnMount = { readContext: readContext, @@ -3472,13 +3592,13 @@ var ContextOnlyDispatcher = { deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; return mountEffectImpl( 4, - 2, + 36, imperativeHandleEffect.bind(null, create, ref), deps ); }, useLayoutEffect: function(create, deps) { - return mountEffectImpl(4, 2, create, deps); + return mountEffectImpl(4, 36, create, deps); }, useMemo: function(nextCreate, deps) { var hook = mountWorkInProgressHook(); @@ -3492,7 +3612,7 @@ var ContextOnlyDispatcher = { initialArg = void 0 !== init ? init(initialArg) : initialArg; hook.memoizedState = hook.baseState = initialArg; reducer = hook.queue = { - pending: null, + last: null, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialArg @@ -3511,21 +3631,23 @@ var ContextOnlyDispatcher = { }, useState: mountState, useDebugValue: mountDebugValue, - useResponder: createDeprecatedResponderListener, + useResponder: createResponderListener, useDeferredValue: function(value, config) { var _mountState = mountState(value), prevValue = _mountState[0], setValue = _mountState[1]; mountEffect( function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - void 0 === config ? null : config; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } + Scheduler.unstable_next(function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }); }, [value, config] ); @@ -3533,124 +3655,177 @@ var ContextOnlyDispatcher = { }, useTransition: function(config) { var _mountState2 = mountState(!1), - isPending = _mountState2[0]; - _mountState2 = _mountState2[1]; + isPending = _mountState2[0], + setPending = _mountState2[1]; return [ - mountCallback(startTransition.bind(null, _mountState2, config), [ - _mountState2, - config - ]), + mountCallback( + function(callback) { + setPending(!0); + Scheduler.unstable_next(function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setPending(!1), callback(); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }); + }, + [config, isPending] + ), isPending ]; - }, - useEvent: function() {} + } }, HooksDispatcherOnUpdate = { readContext: readContext, useCallback: updateCallback, useContext: readContext, useEffect: updateEffect, - useImperativeHandle: updateImperativeHandle, - useLayoutEffect: updateLayoutEffect, - useMemo: updateMemo, + useImperativeHandle: function(ref, create, deps) { + deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; + return updateEffectImpl( + 4, + 36, + imperativeHandleEffect.bind(null, create, ref), + deps + ); + }, + useLayoutEffect: function(create, deps) { + return updateEffectImpl(4, 36, create, deps); + }, + useMemo: function(nextCreate, deps) { + var hook = updateWorkInProgressHook(); + deps = void 0 === deps ? null : deps; + var prevState = hook.memoizedState; + if ( + null !== prevState && + null !== deps && + areHookInputsEqual(deps, prevState[1]) + ) + return prevState[0]; + nextCreate = nextCreate(); + hook.memoizedState = [nextCreate, deps]; + return nextCreate; + }, useReducer: updateReducer, - useRef: updateRef, - useState: function() { - return updateReducer(basicStateReducer); + useRef: function() { + return updateWorkInProgressHook().memoizedState; }, + useState: updateState, useDebugValue: mountDebugValue, - useResponder: createDeprecatedResponderListener, + useResponder: createResponderListener, useDeferredValue: function(value, config) { - var _updateState = updateReducer(basicStateReducer), + var _updateState = updateState(value), prevValue = _updateState[0], setValue = _updateState[1]; updateEffect( function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - void 0 === config ? null : config; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } + Scheduler.unstable_next(function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }); }, [value, config] ); return prevValue; }, useTransition: function(config) { - var _updateState2 = updateReducer(basicStateReducer), - isPending = _updateState2[0]; - _updateState2 = _updateState2[1]; + var _updateState2 = updateState(!1), + isPending = _updateState2[0], + setPending = _updateState2[1]; return [ - updateCallback(startTransition.bind(null, _updateState2, config), [ - _updateState2, - config - ]), + updateCallback( + function(callback) { + setPending(!0); + Scheduler.unstable_next(function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setPending(!1), callback(); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }); + }, + [config, isPending] + ), isPending ]; - }, - useEvent: updateEventListener + } }, - HooksDispatcherOnRerender = { - readContext: readContext, - useCallback: updateCallback, - useContext: readContext, - useEffect: updateEffect, - useImperativeHandle: updateImperativeHandle, - useLayoutEffect: updateLayoutEffect, - useMemo: updateMemo, - useReducer: rerenderReducer, - useRef: updateRef, - useState: function() { - return rerenderReducer(basicStateReducer); - }, - useDebugValue: mountDebugValue, - useResponder: createDeprecatedResponderListener, - useDeferredValue: function(value, config) { - var _rerenderState = rerenderReducer(basicStateReducer), - prevValue = _rerenderState[0], - setValue = _rerenderState[1]; - updateEffect( - function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - void 0 === config ? null : config; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }, - [value, config] + hydrationParentFiber = null, + nextHydratableInstance = null, + isHydrating = !1; +function tryHydrate(fiber, nextInstance) { + switch (fiber.tag) { + case 5: + return ( + (nextInstance = shim$1(nextInstance, fiber.type, fiber.pendingProps)), + null !== nextInstance ? ((fiber.stateNode = nextInstance), !0) : !1 ); - return prevValue; - }, - useTransition: function(config) { - var _rerenderState2 = rerenderReducer(basicStateReducer), - isPending = _rerenderState2[0]; - _rerenderState2 = _rerenderState2[1]; - return [ - updateCallback(startTransition.bind(null, _rerenderState2, config), [ - _rerenderState2, - config - ]), - isPending - ]; - }, - useEvent: updateEventListener - }, - ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner, + case 6: + return ( + (nextInstance = shim$1(nextInstance, fiber.pendingProps)), + null !== nextInstance ? ((fiber.stateNode = nextInstance), !0) : !1 + ); + case 13: + return !1; + default: + return !1; + } +} +function tryToClaimNextHydratableInstance(fiber$jscomp$0) { + if (isHydrating) { + var nextInstance = nextHydratableInstance; + if (nextInstance) { + var firstAttemptedInstance = nextInstance; + if (!tryHydrate(fiber$jscomp$0, nextInstance)) { + nextInstance = shim$1(firstAttemptedInstance); + if (!nextInstance || !tryHydrate(fiber$jscomp$0, nextInstance)) { + fiber$jscomp$0.effectTag = (fiber$jscomp$0.effectTag & -1025) | 2; + isHydrating = !1; + hydrationParentFiber = fiber$jscomp$0; + return; + } + var returnFiber = hydrationParentFiber, + fiber = createFiber(5, null, null, 0); + fiber.elementType = "DELETED"; + fiber.type = "DELETED"; + fiber.stateNode = firstAttemptedInstance; + fiber.return = returnFiber; + fiber.effectTag = 8; + null !== returnFiber.lastEffect + ? ((returnFiber.lastEffect.nextEffect = fiber), + (returnFiber.lastEffect = fiber)) + : (returnFiber.firstEffect = returnFiber.lastEffect = fiber); + } + hydrationParentFiber = fiber$jscomp$0; + nextHydratableInstance = shim$1(nextInstance); + } else + (fiber$jscomp$0.effectTag = (fiber$jscomp$0.effectTag & -1025) | 2), + (isHydrating = !1), + (hydrationParentFiber = fiber$jscomp$0); + } +} +var ReactCurrentOwner$3 = ReactSharedInternals.ReactCurrentOwner, didReceiveUpdate = !1; function reconcileChildren( - current, + current$$1, workInProgress, nextChildren, renderExpirationTime ) { workInProgress.child = - null === current + null === current$$1 ? mountChildFibers( workInProgress, null, @@ -3659,13 +3834,13 @@ function reconcileChildren( ) : reconcileChildFibers( workInProgress, - current.child, + current$$1.child, nextChildren, renderExpirationTime ); } function updateForwardRef( - current, + current$$1, workInProgress, Component, nextProps, @@ -3675,38 +3850,43 @@ function updateForwardRef( var ref = workInProgress.ref; prepareToReadContext(workInProgress, renderExpirationTime); nextProps = renderWithHooks( - current, + current$$1, workInProgress, Component, nextProps, ref, renderExpirationTime ); - if (null !== current && !didReceiveUpdate) + if (null !== current$$1 && !didReceiveUpdate) return ( - (workInProgress.updateQueue = current.updateQueue), + (workInProgress.updateQueue = current$$1.updateQueue), (workInProgress.effectTag &= -517), - current.expirationTime <= renderExpirationTime && - (current.expirationTime = 0), + current$$1.expirationTime <= renderExpirationTime && + (current$$1.expirationTime = 0), bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ) ); workInProgress.effectTag |= 1; - reconcileChildren(current, workInProgress, nextProps, renderExpirationTime); + reconcileChildren( + current$$1, + workInProgress, + nextProps, + renderExpirationTime + ); return workInProgress.child; } function updateMemoComponent( - current, + current$$1, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime ) { - if (null === current) { + if (null === current$$1) { var type = Component.type; if ( "function" === typeof type && @@ -3719,7 +3899,7 @@ function updateMemoComponent( (workInProgress.tag = 15), (workInProgress.type = type), updateSimpleMemoComponent( - current, + current$$1, workInProgress, type, nextProps, @@ -3727,7 +3907,7 @@ function updateMemoComponent( renderExpirationTime ) ); - current = createFiberFromTypeAndProps( + current$$1 = createFiberFromTypeAndProps( Component.type, null, nextProps, @@ -3735,66 +3915,65 @@ function updateMemoComponent( workInProgress.mode, renderExpirationTime ); - current.ref = workInProgress.ref; - current.return = workInProgress; - return (workInProgress.child = current); + current$$1.ref = workInProgress.ref; + current$$1.return = workInProgress; + return (workInProgress.child = current$$1); } - type = current.child; + type = current$$1.child; if ( updateExpirationTime < renderExpirationTime && ((updateExpirationTime = type.memoizedProps), (Component = Component.compare), (Component = null !== Component ? Component : shallowEqual), Component(updateExpirationTime, nextProps) && - current.ref === workInProgress.ref) + current$$1.ref === workInProgress.ref) ) return bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ); workInProgress.effectTag |= 1; - current = createWorkInProgress(type, nextProps); - current.ref = workInProgress.ref; - current.return = workInProgress; - return (workInProgress.child = current); + current$$1 = createWorkInProgress(type, nextProps, renderExpirationTime); + current$$1.ref = workInProgress.ref; + current$$1.return = workInProgress; + return (workInProgress.child = current$$1); } function updateSimpleMemoComponent( - current, + current$$1, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime ) { - return null !== current && - shallowEqual(current.memoizedProps, nextProps) && - current.ref === workInProgress.ref && + return null !== current$$1 && + shallowEqual(current$$1.memoizedProps, nextProps) && + current$$1.ref === workInProgress.ref && ((didReceiveUpdate = !1), updateExpirationTime < renderExpirationTime) - ? ((workInProgress.expirationTime = current.expirationTime), - bailoutOnAlreadyFinishedWork( - current, + ? bailoutOnAlreadyFinishedWork( + current$$1, workInProgress, renderExpirationTime - )) + ) : updateFunctionComponent( - current, + current$$1, workInProgress, Component, nextProps, renderExpirationTime ); } -function markRef(current, workInProgress) { +function markRef(current$$1, workInProgress) { var ref = workInProgress.ref; if ( - (null === current && null !== ref) || - (null !== current && current.ref !== ref) + (null === current$$1 && null !== ref) || + (null !== current$$1 && current$$1.ref !== ref) ) workInProgress.effectTag |= 128; } function updateFunctionComponent( - current, + current$$1, workInProgress, Component, nextProps, @@ -3806,31 +3985,36 @@ function updateFunctionComponent( context = getMaskedContext(workInProgress, context); prepareToReadContext(workInProgress, renderExpirationTime); Component = renderWithHooks( - current, + current$$1, workInProgress, Component, nextProps, context, renderExpirationTime ); - if (null !== current && !didReceiveUpdate) + if (null !== current$$1 && !didReceiveUpdate) return ( - (workInProgress.updateQueue = current.updateQueue), + (workInProgress.updateQueue = current$$1.updateQueue), (workInProgress.effectTag &= -517), - current.expirationTime <= renderExpirationTime && - (current.expirationTime = 0), + current$$1.expirationTime <= renderExpirationTime && + (current$$1.expirationTime = 0), bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ) ); workInProgress.effectTag |= 1; - reconcileChildren(current, workInProgress, Component, renderExpirationTime); + reconcileChildren( + current$$1, + workInProgress, + Component, + renderExpirationTime + ); return workInProgress.child; } function updateClassComponent( - current, + current$$1, workInProgress, Component, nextProps, @@ -3842,11 +4026,16 @@ function updateClassComponent( } else hasContext = !1; prepareToReadContext(workInProgress, renderExpirationTime); if (null === workInProgress.stateNode) - null !== current && - ((current.alternate = null), + null !== current$$1 && + ((current$$1.alternate = null), (workInProgress.alternate = null), (workInProgress.effectTag |= 2)), - constructClassInstance(workInProgress, Component, nextProps), + constructClassInstance( + workInProgress, + Component, + nextProps, + renderExpirationTime + ), mountClassInstance( workInProgress, Component, @@ -3854,7 +4043,7 @@ function updateClassComponent( renderExpirationTime ), (nextProps = !0); - else if (null === current) { + else if (null === current$$1) { var instance = workInProgress.stateNode, oldProps = workInProgress.memoizedProps; instance.props = oldProps; @@ -3882,14 +4071,17 @@ function updateClassComponent( )); hasForceUpdate = !1; var oldState = workInProgress.memoizedState; - instance.state = oldState; - processUpdateQueue( - workInProgress, - nextProps, - instance, - renderExpirationTime - ); - oldContext = workInProgress.memoizedState; + oldContext = instance.state = oldState; + var updateQueue = workInProgress.updateQueue; + null !== updateQueue && + (processUpdateQueue( + workInProgress, + updateQueue, + nextProps, + instance, + renderExpirationTime + ), + (oldContext = workInProgress.memoizedState)); oldProps !== nextProps || oldState !== oldContext || didPerformWorkStackCursor.current || @@ -3935,7 +4127,6 @@ function updateClassComponent( (nextProps = !1)); } else (instance = workInProgress.stateNode), - cloneUpdateQueue(current, workInProgress), (oldProps = workInProgress.memoizedProps), (instance.props = workInProgress.type === workInProgress.elementType @@ -3964,14 +4155,17 @@ function updateClassComponent( )), (hasForceUpdate = !1), (oldContext = workInProgress.memoizedState), - (instance.state = oldContext), - processUpdateQueue( - workInProgress, - nextProps, - instance, - renderExpirationTime - ), - (oldState = workInProgress.memoizedState), + (oldState = instance.state = oldContext), + (updateQueue = workInProgress.updateQueue), + null !== updateQueue && + (processUpdateQueue( + workInProgress, + updateQueue, + nextProps, + instance, + renderExpirationTime + ), + (oldState = workInProgress.memoizedState)), oldProps !== nextProps || oldContext !== oldState || didPerformWorkStackCursor.current || @@ -4015,12 +4209,12 @@ function updateClassComponent( "function" === typeof instance.getSnapshotBeforeUpdate && (workInProgress.effectTag |= 256)) : ("function" !== typeof instance.componentDidUpdate || - (oldProps === current.memoizedProps && - oldContext === current.memoizedState) || + (oldProps === current$$1.memoizedProps && + oldContext === current$$1.memoizedState) || (workInProgress.effectTag |= 4), "function" !== typeof instance.getSnapshotBeforeUpdate || - (oldProps === current.memoizedProps && - oldContext === current.memoizedState) || + (oldProps === current$$1.memoizedProps && + oldContext === current$$1.memoizedState) || (workInProgress.effectTag |= 256), (workInProgress.memoizedProps = nextProps), (workInProgress.memoizedState = oldState)), @@ -4029,16 +4223,16 @@ function updateClassComponent( (instance.context = contextType), (nextProps = getDerivedStateFromProps)) : ("function" !== typeof instance.componentDidUpdate || - (oldProps === current.memoizedProps && - oldContext === current.memoizedState) || + (oldProps === current$$1.memoizedProps && + oldContext === current$$1.memoizedState) || (workInProgress.effectTag |= 4), "function" !== typeof instance.getSnapshotBeforeUpdate || - (oldProps === current.memoizedProps && - oldContext === current.memoizedState) || + (oldProps === current$$1.memoizedProps && + oldContext === current$$1.memoizedState) || (workInProgress.effectTag |= 256), (nextProps = !1)); return finishClassComponent( - current, + current$$1, workInProgress, Component, nextProps, @@ -4047,35 +4241,35 @@ function updateClassComponent( ); } function finishClassComponent( - current, + current$$1, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime ) { - markRef(current, workInProgress); + markRef(current$$1, workInProgress); var didCaptureError = 0 !== (workInProgress.effectTag & 64); if (!shouldUpdate && !didCaptureError) return ( hasContext && invalidateContextProvider(workInProgress, Component, !1), bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ) ); shouldUpdate = workInProgress.stateNode; - ReactCurrentOwner$1.current = workInProgress; + ReactCurrentOwner$3.current = workInProgress; var nextChildren = didCaptureError && "function" !== typeof Component.getDerivedStateFromError ? null : shouldUpdate.render(); workInProgress.effectTag |= 1; - null !== current && didCaptureError + null !== current$$1 && didCaptureError ? ((workInProgress.child = reconcileChildFibers( workInProgress, - current.child, + current$$1.child, null, renderExpirationTime )), @@ -4086,7 +4280,7 @@ function finishClassComponent( renderExpirationTime ))) : reconcileChildren( - current, + current$$1, workInProgress, nextChildren, renderExpirationTime @@ -4109,7 +4303,7 @@ function pushHostRootContext(workInProgress) { } var SUSPENDED_MARKER = { dehydrated: null, retryTime: 0 }; function updateSuspenseComponent( - current, + current$$1, workInProgress, renderExpirationTime ) { @@ -4121,30 +4315,32 @@ function updateSuspenseComponent( (JSCompiler_temp = 0 !== (workInProgress.effectTag & 64)) || (JSCompiler_temp = 0 !== (suspenseContext & 2) && - (null === current || null !== current.memoizedState)); + (null === current$$1 || null !== current$$1.memoizedState)); JSCompiler_temp ? ((nextDidTimeout = !0), (workInProgress.effectTag &= -65)) - : (null !== current && null === current.memoizedState) || + : (null !== current$$1 && null === current$$1.memoizedState) || void 0 === nextProps.fallback || !0 === nextProps.unstable_avoidThisFallback || (suspenseContext |= 1); - push(suspenseStackCursor, suspenseContext & 1); - if (null === current) { + push(suspenseStackCursor, suspenseContext & 1, workInProgress); + if (null === current$$1) { + void 0 !== nextProps.fallback && + tryToClaimNextHydratableInstance(workInProgress); if (nextDidTimeout) { nextDidTimeout = nextProps.fallback; nextProps = createFiberFromFragment(null, mode, 0, null); nextProps.return = workInProgress; if (0 === (workInProgress.mode & 2)) for ( - current = + current$$1 = null !== workInProgress.memoizedState ? workInProgress.child.child : workInProgress.child, - nextProps.child = current; - null !== current; + nextProps.child = current$$1; + null !== current$$1; ) - (current.return = nextProps), (current = current.sibling); + (current$$1.return = nextProps), (current$$1 = current$$1.sibling); renderExpirationTime = createFiberFromFragment( nextDidTimeout, mode, @@ -4166,14 +4362,15 @@ function updateSuspenseComponent( renderExpirationTime )); } - if (null !== current.memoizedState) { - current = current.child; - mode = current.sibling; + if (null !== current$$1.memoizedState) { + current$$1 = current$$1.child; + mode = current$$1.sibling; if (nextDidTimeout) { nextProps = nextProps.fallback; renderExpirationTime = createWorkInProgress( - current, - current.pendingProps + current$$1, + current$$1.pendingProps, + 0 ); renderExpirationTime.return = workInProgress; if ( @@ -4182,7 +4379,7 @@ function updateSuspenseComponent( null !== workInProgress.memoizedState ? workInProgress.child.child : workInProgress.child), - nextDidTimeout !== current.child) + nextDidTimeout !== current$$1.child) ) for ( renderExpirationTime.child = nextDidTimeout; @@ -4191,7 +4388,7 @@ function updateSuspenseComponent( ) (nextDidTimeout.return = renderExpirationTime), (nextDidTimeout = nextDidTimeout.sibling); - mode = createWorkInProgress(mode, nextProps); + mode = createWorkInProgress(mode, nextProps, mode.expirationTime); mode.return = workInProgress; renderExpirationTime.sibling = mode; renderExpirationTime.childExpirationTime = 0; @@ -4201,31 +4398,31 @@ function updateSuspenseComponent( } renderExpirationTime = reconcileChildFibers( workInProgress, - current.child, + current$$1.child, nextProps.children, renderExpirationTime ); workInProgress.memoizedState = null; return (workInProgress.child = renderExpirationTime); } - current = current.child; + current$$1 = current$$1.child; if (nextDidTimeout) { nextDidTimeout = nextProps.fallback; nextProps = createFiberFromFragment(null, mode, 0, null); nextProps.return = workInProgress; - nextProps.child = current; - null !== current && (current.return = nextProps); + nextProps.child = current$$1; + null !== current$$1 && (current$$1.return = nextProps); if (0 === (workInProgress.mode & 2)) for ( - current = + current$$1 = null !== workInProgress.memoizedState ? workInProgress.child.child : workInProgress.child, - nextProps.child = current; - null !== current; + nextProps.child = current$$1; + null !== current$$1; ) - (current.return = nextProps), (current = current.sibling); + (current$$1.return = nextProps), (current$$1 = current$$1.sibling); renderExpirationTime = createFiberFromFragment( nextDidTimeout, mode, @@ -4243,7 +4440,7 @@ function updateSuspenseComponent( workInProgress.memoizedState = null; return (workInProgress.child = reconcileChildFibers( workInProgress, - current, + current$$1, nextProps.children, renderExpirationTime )); @@ -4270,7 +4467,6 @@ function initSuspenseListRenderState( ? (workInProgress.memoizedState = { isBackwards: isBackwards, rendering: null, - renderingStartTime: 0, last: lastContentRow, tail: tail, tailExpiration: 0, @@ -4279,7 +4475,6 @@ function initSuspenseListRenderState( }) : ((renderState.isBackwards = isBackwards), (renderState.rendering = null), - (renderState.renderingStartTime = 0), (renderState.last = lastContentRow), (renderState.tail = tail), (renderState.tailExpiration = 0), @@ -4287,7 +4482,7 @@ function initSuspenseListRenderState( (renderState.lastEffect = lastEffectBeforeRendering)); } function updateSuspenseListComponent( - current, + current$$1, workInProgress, renderExpirationTime ) { @@ -4295,7 +4490,7 @@ function updateSuspenseListComponent( revealOrder = nextProps.revealOrder, tailMode = nextProps.tail; reconcileChildren( - current, + current$$1, workInProgress, nextProps.children, renderExpirationTime @@ -4304,39 +4499,42 @@ function updateSuspenseListComponent( if (0 !== (nextProps & 2)) (nextProps = (nextProps & 1) | 2), (workInProgress.effectTag |= 64); else { - if (null !== current && 0 !== (current.effectTag & 64)) - a: for (current = workInProgress.child; null !== current; ) { - if (13 === current.tag) - null !== current.memoizedState && - scheduleWorkOnFiber(current, renderExpirationTime); - else if (19 === current.tag) - scheduleWorkOnFiber(current, renderExpirationTime); - else if (null !== current.child) { - current.child.return = current; - current = current.child; + if (null !== current$$1 && 0 !== (current$$1.effectTag & 64)) + a: for (current$$1 = workInProgress.child; null !== current$$1; ) { + if (13 === current$$1.tag) + null !== current$$1.memoizedState && + scheduleWorkOnFiber(current$$1, renderExpirationTime); + else if (19 === current$$1.tag) + scheduleWorkOnFiber(current$$1, renderExpirationTime); + else if (null !== current$$1.child) { + current$$1.child.return = current$$1; + current$$1 = current$$1.child; continue; } - if (current === workInProgress) break a; - for (; null === current.sibling; ) { - if (null === current.return || current.return === workInProgress) + if (current$$1 === workInProgress) break a; + for (; null === current$$1.sibling; ) { + if ( + null === current$$1.return || + current$$1.return === workInProgress + ) break a; - current = current.return; + current$$1 = current$$1.return; } - current.sibling.return = current.return; - current = current.sibling; + current$$1.sibling.return = current$$1.return; + current$$1 = current$$1.sibling; } nextProps &= 1; } - push(suspenseStackCursor, nextProps); + push(suspenseStackCursor, nextProps, workInProgress); if (0 === (workInProgress.mode & 2)) workInProgress.memoizedState = null; else switch (revealOrder) { case "forwards": renderExpirationTime = workInProgress.child; for (revealOrder = null; null !== renderExpirationTime; ) - (current = renderExpirationTime.alternate), - null !== current && - null === findFirstSuspended(current) && + (current$$1 = renderExpirationTime.alternate), + null !== current$$1 && + null === findFirstSuspended(current$$1) && (revealOrder = renderExpirationTime), (renderExpirationTime = renderExpirationTime.sibling); renderExpirationTime = revealOrder; @@ -4358,15 +4556,15 @@ function updateSuspenseListComponent( renderExpirationTime = null; revealOrder = workInProgress.child; for (workInProgress.child = null; null !== revealOrder; ) { - current = revealOrder.alternate; - if (null !== current && null === findFirstSuspended(current)) { + current$$1 = revealOrder.alternate; + if (null !== current$$1 && null === findFirstSuspended(current$$1)) { workInProgress.child = revealOrder; break; } - current = revealOrder.sibling; + current$$1 = revealOrder.sibling; revealOrder.sibling = renderExpirationTime; renderExpirationTime = revealOrder; - revealOrder = current; + revealOrder = current$$1; } initSuspenseListRenderState( workInProgress, @@ -4393,29 +4591,35 @@ function updateSuspenseListComponent( return workInProgress.child; } function bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ) { - null !== current && (workInProgress.dependencies = current.dependencies); + null !== current$$1 && + (workInProgress.dependencies = current$$1.dependencies); var updateExpirationTime = workInProgress.expirationTime; 0 !== updateExpirationTime && markUnprocessedUpdateTime(updateExpirationTime); if (workInProgress.childExpirationTime < renderExpirationTime) return null; - if (null !== current && workInProgress.child !== current.child) + if (null !== current$$1 && workInProgress.child !== current$$1.child) throw Error("Resuming work not yet implemented."); if (null !== workInProgress.child) { - current = workInProgress.child; - renderExpirationTime = createWorkInProgress(current, current.pendingProps); + current$$1 = workInProgress.child; + renderExpirationTime = createWorkInProgress( + current$$1, + current$$1.pendingProps, + current$$1.expirationTime + ); workInProgress.child = renderExpirationTime; for ( renderExpirationTime.return = workInProgress; - null !== current.sibling; + null !== current$$1.sibling; ) - (current = current.sibling), + (current$$1 = current$$1.sibling), (renderExpirationTime = renderExpirationTime.sibling = createWorkInProgress( - current, - current.pendingProps + current$$1, + current$$1.pendingProps, + current$$1.expirationTime )), (renderExpirationTime.return = workInProgress); renderExpirationTime.sibling = null; @@ -4437,7 +4641,12 @@ appendAllChildren = function( var instance = node.stateNode; needsVisibilityToggle && isHidden && - (instance = cloneHiddenInstance(instance)); + (instance = cloneHiddenInstance( + instance, + node.type, + node.memoizedProps, + node + )); appendChildNode(parent.node, instance.node); } else if (6 === node.tag) { instance = node.stateNode; @@ -4490,7 +4699,12 @@ function appendAllChildrenToContainer( var instance = node.stateNode; needsVisibilityToggle && isHidden && - (instance = cloneHiddenInstance(instance)); + (instance = cloneHiddenInstance( + instance, + node.type, + node.memoizedProps, + node + )); appendChildNodeToSet(containerChildSet, instance.node); } else if (6 === node.tag) { instance = node.stateNode; @@ -4576,8 +4790,8 @@ updateHostComponent$1 = function(current, workInProgress, type, newProps) { ? cloneNodeWithNewProps(recyclableInstance, newProps) : cloneNode(recyclableInstance) : null !== newProps - ? cloneNodeWithNewChildrenAndProps(recyclableInstance, newProps) - : cloneNodeWithNewChildren(recyclableInstance), + ? cloneNodeWithNewChildrenAndProps(recyclableInstance, newProps) + : cloneNodeWithNewChildren(recyclableInstance), canonical: type.canonical }), (workInProgress.stateNode = type), @@ -4587,17 +4801,16 @@ updateHostComponent$1 = function(current, workInProgress, type, newProps) { } }; updateHostText$1 = function(current, workInProgress, oldText, newText) { - oldText !== newText - ? ((current = requiredContext(rootInstanceStackCursor.current)), - (oldText = requiredContext(contextStackCursor$1.current)), - (workInProgress.stateNode = createTextInstance( - newText, - current, - oldText, - workInProgress - )), - (workInProgress.effectTag |= 4)) - : (workInProgress.stateNode = current.stateNode); + oldText !== newText && + ((current = requiredContext(rootInstanceStackCursor.current)), + (oldText = requiredContext(contextStackCursor$1.current)), + (workInProgress.stateNode = createTextInstance( + newText, + current, + oldText, + workInProgress + )), + (workInProgress.effectTag |= 4)); }; function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { switch (renderState.tailMode) { @@ -4623,317 +4836,18 @@ function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { : (_lastTailNode.sibling = null); } } -function completeWork(current, workInProgress, renderExpirationTime) { - var newProps = workInProgress.pendingProps; - switch (workInProgress.tag) { - case 2: - case 16: - case 15: - case 0: - case 11: - case 7: - case 8: - case 12: - case 9: - case 14: - return null; - case 1: - return isContextProvider(workInProgress.type) && popContext(), null; - case 3: - return ( - popHostContainer(), - pop(didPerformWorkStackCursor), - pop(contextStackCursor), - (current = workInProgress.stateNode), - current.pendingContext && - ((current.context = current.pendingContext), - (current.pendingContext = null)), - updateHostContainer(workInProgress), - null - ); - case 5: - popHostContext(workInProgress); - var rootContainerInstance = requiredContext( - rootInstanceStackCursor.current - ); - renderExpirationTime = workInProgress.type; - if (null !== current && null != workInProgress.stateNode) - updateHostComponent$1( - current, - workInProgress, - renderExpirationTime, - newProps, - rootContainerInstance - ), - current.ref !== workInProgress.ref && - (workInProgress.effectTag |= 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." - ); - return null; - } - requiredContext(contextStackCursor$1.current); - current = nextReactTag; - nextReactTag += 2; - renderExpirationTime = getViewConfigForType(renderExpirationTime); - var updatePayload = diffProperties( - null, - emptyObject, - newProps, - renderExpirationTime.validAttributes - ); - rootContainerInstance = createNode( - current, - renderExpirationTime.uiViewClassName, - rootContainerInstance, - updatePayload, - workInProgress - ); - current = new ReactFabricHostComponent( - current, - renderExpirationTime, - newProps, - workInProgress - ); - current = { node: rootContainerInstance, canonical: current }; - appendAllChildren(current, workInProgress, !1, !1); - workInProgress.stateNode = current; - null !== workInProgress.ref && (workInProgress.effectTag |= 128); - } - return null; - case 6: - if (current && null != workInProgress.stateNode) - updateHostText$1( - current, - workInProgress, - current.memoizedProps, - newProps - ); - else { - if ("string" !== typeof newProps && null === workInProgress.stateNode) - throw Error( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." - ); - current = requiredContext(rootInstanceStackCursor.current); - rootContainerInstance = requiredContext(contextStackCursor$1.current); - workInProgress.stateNode = createTextInstance( - newProps, - current, - rootContainerInstance, - workInProgress - ); - } - return null; - case 13: - pop(suspenseStackCursor); - newProps = workInProgress.memoizedState; - if (0 !== (workInProgress.effectTag & 64)) - return ( - (workInProgress.expirationTime = renderExpirationTime), workInProgress - ); - newProps = null !== newProps; - rootContainerInstance = !1; - null !== current && - ((renderExpirationTime = current.memoizedState), - (rootContainerInstance = null !== renderExpirationTime), - newProps || - null === renderExpirationTime || - ((renderExpirationTime = current.child.sibling), - null !== renderExpirationTime && - ((updatePayload = workInProgress.firstEffect), - null !== updatePayload - ? ((workInProgress.firstEffect = renderExpirationTime), - (renderExpirationTime.nextEffect = updatePayload)) - : ((workInProgress.firstEffect = workInProgress.lastEffect = renderExpirationTime), - (renderExpirationTime.nextEffect = null)), - (renderExpirationTime.effectTag = 8)))); - if (newProps && !rootContainerInstance && 0 !== (workInProgress.mode & 2)) - if ( - (null === current && - !0 !== workInProgress.memoizedProps.unstable_avoidThisFallback) || - 0 !== (suspenseStackCursor.current & 1) - ) - workInProgressRootExitStatus === RootIncomplete && - (workInProgressRootExitStatus = RootSuspended); - else { - if ( - workInProgressRootExitStatus === RootIncomplete || - workInProgressRootExitStatus === RootSuspended - ) - workInProgressRootExitStatus = RootSuspendedWithDelay; - 0 !== workInProgressRootNextUnprocessedUpdateTime && - null !== workInProgressRoot && - (markRootSuspendedAtTime( - workInProgressRoot, - renderExpirationTime$1 - ), - markRootUpdatedAtTime( - workInProgressRoot, - workInProgressRootNextUnprocessedUpdateTime - )); - } - newProps && (workInProgress.effectTag |= 4); - return null; - case 4: - return popHostContainer(), updateHostContainer(workInProgress), null; - case 10: - return popProvider(workInProgress), null; - case 17: - return isContextProvider(workInProgress.type) && popContext(), null; - case 19: - pop(suspenseStackCursor); - newProps = workInProgress.memoizedState; - if (null === newProps) return null; - rootContainerInstance = 0 !== (workInProgress.effectTag & 64); - updatePayload = newProps.rendering; - if (null === updatePayload) - if (rootContainerInstance) cutOffTailIfNeeded(newProps, !1); - else { - if ( - workInProgressRootExitStatus !== RootIncomplete || - (null !== current && 0 !== (current.effectTag & 64)) - ) - for (current = workInProgress.child; null !== current; ) { - updatePayload = findFirstSuspended(current); - if (null !== updatePayload) { - workInProgress.effectTag |= 64; - cutOffTailIfNeeded(newProps, !1); - current = updatePayload.updateQueue; - null !== current && - ((workInProgress.updateQueue = current), - (workInProgress.effectTag |= 4)); - null === newProps.lastEffect && - (workInProgress.firstEffect = null); - workInProgress.lastEffect = newProps.lastEffect; - current = renderExpirationTime; - for (newProps = workInProgress.child; null !== newProps; ) - (rootContainerInstance = newProps), - (renderExpirationTime = current), - (rootContainerInstance.effectTag &= 2), - (rootContainerInstance.nextEffect = null), - (rootContainerInstance.firstEffect = null), - (rootContainerInstance.lastEffect = null), - (updatePayload = rootContainerInstance.alternate), - null === updatePayload - ? ((rootContainerInstance.childExpirationTime = 0), - (rootContainerInstance.expirationTime = renderExpirationTime), - (rootContainerInstance.child = null), - (rootContainerInstance.memoizedProps = null), - (rootContainerInstance.memoizedState = null), - (rootContainerInstance.updateQueue = null), - (rootContainerInstance.dependencies = null)) - : ((rootContainerInstance.childExpirationTime = - updatePayload.childExpirationTime), - (rootContainerInstance.expirationTime = - updatePayload.expirationTime), - (rootContainerInstance.child = updatePayload.child), - (rootContainerInstance.memoizedProps = - updatePayload.memoizedProps), - (rootContainerInstance.memoizedState = - updatePayload.memoizedState), - (rootContainerInstance.updateQueue = - updatePayload.updateQueue), - (renderExpirationTime = updatePayload.dependencies), - (rootContainerInstance.dependencies = - null === renderExpirationTime - ? null - : { - expirationTime: - renderExpirationTime.expirationTime, - firstContext: renderExpirationTime.firstContext, - responders: renderExpirationTime.responders - })), - (newProps = newProps.sibling); - push( - suspenseStackCursor, - (suspenseStackCursor.current & 1) | 2 - ); - return workInProgress.child; - } - current = current.sibling; - } - } - else { - if (!rootContainerInstance) - if ( - ((current = findFirstSuspended(updatePayload)), null !== current) - ) { - if ( - ((workInProgress.effectTag |= 64), - (rootContainerInstance = !0), - (current = current.updateQueue), - null !== current && - ((workInProgress.updateQueue = current), - (workInProgress.effectTag |= 4)), - cutOffTailIfNeeded(newProps, !0), - null === newProps.tail && - "hidden" === newProps.tailMode && - !updatePayload.alternate) - ) - return ( - (workInProgress = workInProgress.lastEffect = - newProps.lastEffect), - null !== workInProgress && (workInProgress.nextEffect = null), - null - ); - } else - 2 * now() - newProps.renderingStartTime > newProps.tailExpiration && - 1 < renderExpirationTime && - ((workInProgress.effectTag |= 64), - (rootContainerInstance = !0), - cutOffTailIfNeeded(newProps, !1), - (workInProgress.expirationTime = workInProgress.childExpirationTime = - renderExpirationTime - 1)); - newProps.isBackwards - ? ((updatePayload.sibling = workInProgress.child), - (workInProgress.child = updatePayload)) - : ((current = newProps.last), - null !== current - ? (current.sibling = updatePayload) - : (workInProgress.child = updatePayload), - (newProps.last = updatePayload)); - } - return null !== newProps.tail - ? (0 === newProps.tailExpiration && - (newProps.tailExpiration = now() + 500), - (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; - } - 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) { switch (workInProgress.tag) { case 1: - isContextProvider(workInProgress.type) && popContext(); + isContextProvider(workInProgress.type) && popContext(workInProgress); var effectTag = workInProgress.effectTag; return effectTag & 4096 ? ((workInProgress.effectTag = (effectTag & -4097) | 64), workInProgress) : null; case 3: - popHostContainer(); - pop(didPerformWorkStackCursor); - pop(contextStackCursor); + popHostContainer(workInProgress); + popTopLevelContextObject(workInProgress); effectTag = workInProgress.effectTag; if (0 !== (effectTag & 64)) throw Error( @@ -4945,7 +4859,7 @@ function unwindWork(workInProgress) { return popHostContext(workInProgress), null; case 13: return ( - pop(suspenseStackCursor), + pop(suspenseStackCursor, workInProgress), (effectTag = workInProgress.effectTag), effectTag & 4096 ? ((workInProgress.effectTag = (effectTag & -4097) | 64), @@ -4953,9 +4867,9 @@ function unwindWork(workInProgress) { : null ); case 19: - return pop(suspenseStackCursor), null; + return pop(suspenseStackCursor, workInProgress), null; case 4: - return popHostContainer(), null; + return popHostContainer(workInProgress), null; case 10: return popProvider(workInProgress), null; default: @@ -5012,180 +4926,102 @@ function logError(boundary, errorInfo) { }); } } -function safelyCallComponentWillUnmount(current, instance) { +function safelyCallComponentWillUnmount(current$$1, instance) { try { - (instance.props = current.memoizedProps), - (instance.state = current.memoizedState), + (instance.props = current$$1.memoizedProps), + (instance.state = current$$1.memoizedState), instance.componentWillUnmount(); } catch (unmountError) { - captureCommitPhaseError(current, unmountError); + captureCommitPhaseError(current$$1, unmountError); } } -function safelyDetachRef(current) { - var ref = current.ref; +function safelyDetachRef(current$$1) { + var ref = current$$1.ref; if (null !== ref) if ("function" === typeof ref) try { ref(null); } catch (refError) { - captureCommitPhaseError(current, refError); + captureCommitPhaseError(current$$1, refError); } else ref.current = null; } -function commitBeforeMutationLifeCycles(current, finishedWork) { +function commitBeforeMutationLifeCycles(current$$1, finishedWork) { switch (finishedWork.tag) { case 0: case 11: case 15: - case 22: - return; + commitHookEffectList(2, 0, finishedWork); + break; case 1: - if (finishedWork.effectTag & 256 && null !== current) { - var prevProps = current.memoizedProps, - prevState = current.memoizedState; - current = finishedWork.stateNode; - finishedWork = current.getSnapshotBeforeUpdate( + if (finishedWork.effectTag & 256 && null !== current$$1) { + var prevProps = current$$1.memoizedProps, + prevState = current$$1.memoizedState; + current$$1 = finishedWork.stateNode; + finishedWork = current$$1.getSnapshotBeforeUpdate( finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState ); - current.__reactInternalSnapshotBeforeUpdate = finishedWork; + current$$1.__reactInternalSnapshotBeforeUpdate = finishedWork; } - return; + break; case 3: case 5: case 6: case 4: case 17: - return; + 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." + ); } - 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(tag, finishedWork) { +function commitHookEffectList(unmountTag, mountTag, finishedWork) { finishedWork = finishedWork.updateQueue; finishedWork = null !== finishedWork ? finishedWork.lastEffect : null; if (null !== finishedWork) { var effect = (finishedWork = finishedWork.next); do { - if ((effect.tag & tag) === tag) { + if (0 !== (effect.tag & unmountTag)) { var destroy = effect.destroy; effect.destroy = void 0; void 0 !== destroy && destroy(); } + 0 !== (effect.tag & mountTag) && + ((destroy = effect.create), (effect.destroy = destroy())); effect = effect.next; } while (effect !== finishedWork); } } -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 = effect.create; - effect.destroy = create(); - } - effect = effect.next; - } while (effect !== finishedWork); - } -} -function commitLifeCycles(finishedRoot, current, finishedWork) { - switch (finishedWork.tag) { - case 0: - case 11: - case 15: - case 22: - commitHookEffectListMount(3, finishedWork); - return; - case 1: - finishedRoot = finishedWork.stateNode; - if (finishedWork.effectTag & 4) - if (null === current) finishedRoot.componentDidMount(); - else { - var prevProps = - finishedWork.elementType === finishedWork.type - ? current.memoizedProps - : resolveDefaultProps(finishedWork.type, current.memoizedProps); - finishedRoot.componentDidUpdate( - prevProps, - 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); - } - return; - case 5: - if (null === current && finishedWork.effectTag & 4) - throw Error( - "The current renderer does not support mutation. This error is likely caused by a bug in React. Please file an issue." - ); - return; - case 6: - return; - case 4: - return; - case 12: - return; - case 13: - return; - case 19: - case 17: - case 20: - case 21: - 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 commitUnmount(finishedRoot, current$jscomp$0, renderPriorityLevel) { +function commitUnmount(finishedRoot, current$$1$jscomp$0, renderPriorityLevel) { "function" === typeof onCommitFiberUnmount && - onCommitFiberUnmount(current$jscomp$0); - switch (current$jscomp$0.tag) { + onCommitFiberUnmount(current$$1$jscomp$0); + switch (current$$1$jscomp$0.tag) { case 0: case 11: case 14: case 15: - case 22: - finishedRoot = current$jscomp$0.updateQueue; + finishedRoot = current$$1$jscomp$0.updateQueue; if ( null !== finishedRoot && ((finishedRoot = finishedRoot.lastEffect), null !== finishedRoot) ) { var firstEffect = finishedRoot.next; - runWithPriority( + runWithPriority$1( 97 < renderPriorityLevel ? 97 : renderPriorityLevel, function() { var effect = firstEffect; do { - var _destroy = effect.destroy; - if (void 0 !== _destroy) { - var current = current$jscomp$0; + var destroy = effect.destroy; + if (void 0 !== destroy) { + var current$$1 = current$$1$jscomp$0; try { - _destroy(); + destroy(); } catch (error) { - captureCommitPhaseError(current, error); + captureCommitPhaseError(current$$1, error); } } effect = effect.next; @@ -5195,41 +5031,42 @@ function commitUnmount(finishedRoot, current$jscomp$0, renderPriorityLevel) { } break; case 1: - safelyDetachRef(current$jscomp$0); - renderPriorityLevel = current$jscomp$0.stateNode; + safelyDetachRef(current$$1$jscomp$0); + renderPriorityLevel = current$$1$jscomp$0.stateNode; "function" === typeof renderPriorityLevel.componentWillUnmount && - safelyCallComponentWillUnmount(current$jscomp$0, renderPriorityLevel); + safelyCallComponentWillUnmount( + current$$1$jscomp$0, + renderPriorityLevel + ); break; case 5: - safelyDetachRef(current$jscomp$0); + safelyDetachRef(current$$1$jscomp$0); break; case 4: - createChildNodeSet(current$jscomp$0.stateNode.containerInfo); + createChildNodeSet(current$$1$jscomp$0.stateNode.containerInfo); } } -function detachFiber(current) { - var alternate = current.alternate; - current.return = null; - current.child = null; - current.memoizedState = null; - current.updateQueue = null; - current.dependencies = null; - current.alternate = null; - current.firstEffect = null; - current.lastEffect = null; - current.pendingProps = null; - current.memoizedProps = null; - current.stateNode = null; +function detachFiber(current$$1) { + var alternate = current$$1.alternate; + current$$1.return = null; + current$$1.child = null; + current$$1.memoizedState = null; + current$$1.updateQueue = null; + current$$1.dependencies = null; + current$$1.alternate = null; + current$$1.firstEffect = null; + current$$1.lastEffect = null; + current$$1.pendingProps = null; + current$$1.memoizedProps = null; null !== alternate && detachFiber(alternate); } -function commitWork(current, finishedWork) { +function commitWork(current$$1, finishedWork) { switch (finishedWork.tag) { case 0: case 11: case 14: case 15: - case 22: - commitHookEffectListUnmount(3, finishedWork); + commitHookEffectList(4, 8, finishedWork); return; case 12: return; @@ -5242,20 +5079,19 @@ function commitWork(current, finishedWork) { attachSuspenseRetryListeners(finishedWork); return; } - a: { - switch (finishedWork.tag) { - 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." - ); + a: switch (finishedWork.tag) { + case 1: + case 5: + case 6: + case 20: + break a; + case 3: + case 4: + break a; + 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." + ); } } function attachSuspenseRetryListeners(finishedWork) { @@ -5312,7 +5148,7 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { return expirationTime; } var ceil = Math.ceil, - ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, + ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, NoContext = 0, LegacyUnbatchedContext = 8, @@ -5327,7 +5163,7 @@ var ceil = Math.ceil, executionContext = NoContext, workInProgressRoot = null, workInProgress = null, - renderExpirationTime$1 = 0, + renderExpirationTime = 0, workInProgressRootExitStatus = RootIncomplete, workInProgressRootFatalError = null, workInProgressRootLatestProcessedExpirationTime = 1073741823, @@ -5352,8 +5188,8 @@ function requestCurrentTimeForUpdate() { return (executionContext & (RenderContext | CommitContext)) !== NoContext ? 1073741821 - ((now() / 10) | 0) : 0 !== currentEventTime - ? currentEventTime - : (currentEventTime = 1073741821 - ((now() / 10) | 0)); + ? currentEventTime + : (currentEventTime = 1073741821 - ((now() / 10) | 0)); } function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { fiber = fiber.mode; @@ -5361,7 +5197,7 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { var priorityLevel = getCurrentPriorityLevel(); if (0 === (fiber & 4)) return 99 === priorityLevel ? 1073741823 : 1073741822; if ((executionContext & RenderContext) !== NoContext) - return renderExpirationTime$1; + return renderExpirationTime; if (null !== suspenseConfig) currentTime = 1073741821 - @@ -5393,11 +5229,11 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { throw Error("Expected a valid priority level"); } null !== workInProgressRoot && - currentTime === renderExpirationTime$1 && + currentTime === renderExpirationTime && --currentTime; return currentTime; } -function scheduleWork(fiber, expirationTime) { +function scheduleUpdateOnFiber(fiber, expirationTime) { if (50 < nestedUpdateCount) throw ((nestedUpdateCount = 0), (rootWithNestedUpdates = null), @@ -5451,7 +5287,7 @@ function markUpdateTimeFromFiberToRoot(fiber, expirationTime) { (workInProgressRoot === root && (markUnprocessedUpdateTime(expirationTime), workInProgressRootExitStatus === RootSuspendedWithDelay && - markRootSuspendedAtTime(root, renderExpirationTime$1)), + markRootSuspendedAtTime(root, renderExpirationTime)), markRootUpdatedAtTime(root, expirationTime)); return root; } @@ -5460,10 +5296,9 @@ function getNextRootExpirationTimeToWorkOn(root) { if (0 !== lastExpiredTime) return lastExpiredTime; lastExpiredTime = root.firstPendingTime; if (!isRootSuspendedAtTime(root, lastExpiredTime)) return lastExpiredTime; - var lastPingedTime = root.lastPingedTime; + lastExpiredTime = root.lastPingedTime; root = root.nextKnownPendingLevel; - root = lastPingedTime > root ? lastPingedTime : root; - return 2 >= root && lastExpiredTime !== root ? 0 : root; + return lastExpiredTime > root ? lastExpiredTime : root; } function ensureRootIsScheduled(root) { if (0 !== root.lastExpiredTime) @@ -5485,18 +5320,18 @@ function ensureRootIsScheduled(root) { 1073741823 === expirationTime ? (priorityLevel = 99) : 1 === expirationTime || 2 === expirationTime - ? (priorityLevel = 95) - : ((priorityLevel = - 10 * (1073741821 - expirationTime) - - 10 * (1073741821 - priorityLevel)), - (priorityLevel = - 0 >= priorityLevel - ? 99 - : 250 >= priorityLevel - ? 98 - : 5250 >= priorityLevel - ? 97 - : 95)); + ? (priorityLevel = 95) + : ((priorityLevel = + 10 * (1073741821 - expirationTime) - + 10 * (1073741821 - priorityLevel)), + (priorityLevel = + 0 >= priorityLevel + ? 99 + : 250 >= priorityLevel + ? 98 + : 5250 >= priorityLevel + ? 97 + : 95)); if (null !== existingCallbackNode) { var existingCallbackPriority = root.callbackPriority; if ( @@ -5523,225 +5358,264 @@ function ensureRootIsScheduled(root) { } function performConcurrentWorkOnRoot(root, didTimeout) { currentEventTime = 0; - if (didTimeout) { - didTimeout = requestCurrentTimeForUpdate(); - var lastExpiredTime = root.lastExpiredTime; - if (0 === lastExpiredTime || lastExpiredTime > didTimeout) - root.lastExpiredTime = didTimeout; - ensureRootIsScheduled(root); - return null; - } - lastExpiredTime = getNextRootExpirationTimeToWorkOn(root); - if (0 === lastExpiredTime) return null; - didTimeout = root.callbackNode; - if ((executionContext & (RenderContext | CommitContext)) !== NoContext) - throw Error("Should not already be working."); - flushPassiveEffects(); - var expirationTime = lastExpiredTime; - var exitStatus = executionContext; - executionContext |= RenderContext; - var prevDispatcher = pushDispatcher(); - (root === workInProgressRoot && expirationTime === renderExpirationTime$1) || - prepareFreshStack(root, expirationTime); - do - try { - workLoopConcurrent(); - break; - } catch (thrownValue) { - handleError(root, thrownValue); - } - while (1); - resetContextDependencies(); - ReactCurrentDispatcher$1.current = prevDispatcher; - executionContext = exitStatus; - null !== workInProgress - ? (exitStatus = RootIncomplete) - : ((workInProgressRoot = null), - (exitStatus = workInProgressRootExitStatus)); - if (exitStatus !== RootIncomplete) { - exitStatus === RootErrored && - ((lastExpiredTime = 2 < lastExpiredTime ? 2 : lastExpiredTime), - (exitStatus = renderRootSync(root, lastExpiredTime))); - if (exitStatus === RootFatalErrored) - throw ((didTimeout = workInProgressRootFatalError), - prepareFreshStack(root, lastExpiredTime), - markRootSuspendedAtTime(root, lastExpiredTime), + if (didTimeout) + return ( + (didTimeout = requestCurrentTimeForUpdate()), + markRootExpiredAtTime(root, didTimeout), ensureRootIsScheduled(root), - didTimeout); - expirationTime = root.finishedWork = root.current.alternate; - root.finishedExpirationTime = lastExpiredTime; - switch (exitStatus) { - case RootIncomplete: - case RootFatalErrored: - throw Error("Root did not complete. This is a bug in React."); - case RootErrored: - commitRoot(root); - break; - case RootSuspended: - markRootSuspendedAtTime(root, lastExpiredTime); - exitStatus = root.lastSuspendedTime; - lastExpiredTime === exitStatus && - (root.nextKnownPendingLevel = getRemainingExpirationTime( - expirationTime - )); - if ( - 1073741823 === workInProgressRootLatestProcessedExpirationTime && - ((expirationTime = - globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now()), - 10 < expirationTime) - ) { - if ( - workInProgressRootHasPendingPing && - ((prevDispatcher = root.lastPingedTime), - 0 === prevDispatcher || prevDispatcher >= lastExpiredTime) - ) { - root.lastPingedTime = lastExpiredTime; - prepareFreshStack(root, lastExpiredTime); - break; - } - prevDispatcher = getNextRootExpirationTimeToWorkOn(root); - if (0 !== prevDispatcher && prevDispatcher !== lastExpiredTime) break; - if (0 !== exitStatus && exitStatus !== lastExpiredTime) { - root.lastPingedTime = exitStatus; - break; - } - root.timeoutHandle = scheduleTimeout( - commitRoot.bind(null, root), - expirationTime - ); - break; - } - commitRoot(root); - break; - case RootSuspendedWithDelay: - markRootSuspendedAtTime(root, lastExpiredTime); - exitStatus = root.lastSuspendedTime; - lastExpiredTime === exitStatus && - (root.nextKnownPendingLevel = getRemainingExpirationTime( - expirationTime - )); - if ( - workInProgressRootHasPendingPing && - ((expirationTime = root.lastPingedTime), - 0 === expirationTime || expirationTime >= lastExpiredTime) - ) { - root.lastPingedTime = lastExpiredTime; - prepareFreshStack(root, lastExpiredTime); - break; - } - expirationTime = getNextRootExpirationTimeToWorkOn(root); - if (0 !== expirationTime && expirationTime !== lastExpiredTime) break; - if (0 !== exitStatus && exitStatus !== lastExpiredTime) { - root.lastPingedTime = exitStatus; - break; - } - 1073741823 !== workInProgressRootLatestSuspenseTimeout - ? (expirationTime = - 10 * (1073741821 - workInProgressRootLatestSuspenseTimeout) - - now()) - : 1073741823 === workInProgressRootLatestProcessedExpirationTime - ? (expirationTime = 0) - : ((expirationTime = - 10 * - (1073741821 - workInProgressRootLatestProcessedExpirationTime) - - 5e3), - (exitStatus = now()), - (lastExpiredTime = - 10 * (1073741821 - lastExpiredTime) - exitStatus), - (expirationTime = exitStatus - expirationTime), - 0 > expirationTime && (expirationTime = 0), - (expirationTime = - (120 > expirationTime - ? 120 - : 480 > expirationTime - ? 480 - : 1080 > expirationTime - ? 1080 - : 1920 > expirationTime - ? 1920 - : 3e3 > expirationTime - ? 3e3 - : 4320 > expirationTime - ? 4320 - : 1960 * ceil(expirationTime / 1960)) - expirationTime), - lastExpiredTime < expirationTime && - (expirationTime = lastExpiredTime)); - if (10 < expirationTime) { - root.timeoutHandle = scheduleTimeout( - commitRoot.bind(null, root), - expirationTime - ); + null + ); + var expirationTime = getNextRootExpirationTimeToWorkOn(root); + if (0 !== expirationTime) { + didTimeout = root.callbackNode; + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) + throw Error("Should not already be working."); + flushPassiveEffects(); + (root === workInProgressRoot && expirationTime === renderExpirationTime) || + prepareFreshStack(root, expirationTime); + if (null !== workInProgress) { + var prevExecutionContext = executionContext; + executionContext |= RenderContext; + var prevDispatcher = pushDispatcher(root); + do + try { + workLoopConcurrent(); break; + } catch (thrownValue) { + handleError(root, thrownValue); } - commitRoot(root); - break; - case RootCompleted: - if ( - 1073741823 !== workInProgressRootLatestProcessedExpirationTime && - null !== workInProgressRootCanSuspendUsingConfig + while (1); + resetContextDependencies(); + executionContext = prevExecutionContext; + ReactCurrentDispatcher.current = prevDispatcher; + if (workInProgressRootExitStatus === RootFatalErrored) + throw ((didTimeout = workInProgressRootFatalError), + prepareFreshStack(root, expirationTime), + markRootSuspendedAtTime(root, expirationTime), + ensureRootIsScheduled(root), + didTimeout); + if (null === workInProgress) + switch ( + ((prevDispatcher = root.finishedWork = root.current.alternate), + (root.finishedExpirationTime = expirationTime), + (prevExecutionContext = workInProgressRootExitStatus), + (workInProgressRoot = null), + prevExecutionContext) ) { - prevDispatcher = workInProgressRootLatestProcessedExpirationTime; - var suspenseConfig = workInProgressRootCanSuspendUsingConfig; - expirationTime = suspenseConfig.busyMinDurationMs | 0; - 0 >= expirationTime - ? (expirationTime = 0) - : ((exitStatus = suspenseConfig.busyDelayMs | 0), - (prevDispatcher = - now() - - (10 * (1073741821 - prevDispatcher) - - (suspenseConfig.timeoutMs | 0 || 5e3))), - (expirationTime = - prevDispatcher <= exitStatus - ? 0 - : exitStatus + expirationTime - prevDispatcher)); - if (10 < expirationTime) { - markRootSuspendedAtTime(root, lastExpiredTime); - root.timeoutHandle = scheduleTimeout( - commitRoot.bind(null, root), - expirationTime + case RootIncomplete: + case RootFatalErrored: + throw Error("Root did not complete. This is a bug in React."); + case RootErrored: + markRootExpiredAtTime( + root, + 2 < expirationTime ? 2 : expirationTime ); break; - } + case RootSuspended: + markRootSuspendedAtTime(root, expirationTime); + prevExecutionContext = root.lastSuspendedTime; + expirationTime === prevExecutionContext && + (root.nextKnownPendingLevel = getRemainingExpirationTime( + prevDispatcher + )); + if ( + 1073741823 === workInProgressRootLatestProcessedExpirationTime && + ((prevDispatcher = + globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now()), + 10 < prevDispatcher) + ) { + if (workInProgressRootHasPendingPing) { + var lastPingedTime = root.lastPingedTime; + if (0 === lastPingedTime || lastPingedTime >= expirationTime) { + root.lastPingedTime = expirationTime; + prepareFreshStack(root, expirationTime); + break; + } + } + lastPingedTime = getNextRootExpirationTimeToWorkOn(root); + if (0 !== lastPingedTime && lastPingedTime !== expirationTime) + break; + if ( + 0 !== prevExecutionContext && + prevExecutionContext !== expirationTime + ) { + root.lastPingedTime = prevExecutionContext; + break; + } + root.timeoutHandle = scheduleTimeout( + commitRoot.bind(null, root), + prevDispatcher + ); + break; + } + commitRoot(root); + break; + case RootSuspendedWithDelay: + markRootSuspendedAtTime(root, expirationTime); + prevExecutionContext = root.lastSuspendedTime; + expirationTime === prevExecutionContext && + (root.nextKnownPendingLevel = getRemainingExpirationTime( + prevDispatcher + )); + if ( + workInProgressRootHasPendingPing && + ((prevDispatcher = root.lastPingedTime), + 0 === prevDispatcher || prevDispatcher >= expirationTime) + ) { + root.lastPingedTime = expirationTime; + prepareFreshStack(root, expirationTime); + break; + } + prevDispatcher = getNextRootExpirationTimeToWorkOn(root); + if (0 !== prevDispatcher && prevDispatcher !== expirationTime) + break; + if ( + 0 !== prevExecutionContext && + prevExecutionContext !== expirationTime + ) { + root.lastPingedTime = prevExecutionContext; + break; + } + 1073741823 !== workInProgressRootLatestSuspenseTimeout + ? (prevExecutionContext = + 10 * (1073741821 - workInProgressRootLatestSuspenseTimeout) - + now()) + : 1073741823 === workInProgressRootLatestProcessedExpirationTime + ? (prevExecutionContext = 0) + : ((prevExecutionContext = + 10 * + (1073741821 - + workInProgressRootLatestProcessedExpirationTime) - + 5e3), + (prevDispatcher = now()), + (expirationTime = + 10 * (1073741821 - expirationTime) - prevDispatcher), + (prevExecutionContext = + prevDispatcher - prevExecutionContext), + 0 > prevExecutionContext && (prevExecutionContext = 0), + (prevExecutionContext = + (120 > prevExecutionContext + ? 120 + : 480 > prevExecutionContext + ? 480 + : 1080 > prevExecutionContext + ? 1080 + : 1920 > prevExecutionContext + ? 1920 + : 3e3 > prevExecutionContext + ? 3e3 + : 4320 > prevExecutionContext + ? 4320 + : 1960 * ceil(prevExecutionContext / 1960)) - + prevExecutionContext), + expirationTime < prevExecutionContext && + (prevExecutionContext = expirationTime)); + if (10 < prevExecutionContext) { + root.timeoutHandle = scheduleTimeout( + commitRoot.bind(null, root), + prevExecutionContext + ); + break; + } + commitRoot(root); + break; + case RootCompleted: + if ( + 1073741823 !== workInProgressRootLatestProcessedExpirationTime && + null !== workInProgressRootCanSuspendUsingConfig + ) { + lastPingedTime = workInProgressRootLatestProcessedExpirationTime; + var suspenseConfig = workInProgressRootCanSuspendUsingConfig; + prevExecutionContext = suspenseConfig.busyMinDurationMs | 0; + 0 >= prevExecutionContext + ? (prevExecutionContext = 0) + : ((prevDispatcher = suspenseConfig.busyDelayMs | 0), + (lastPingedTime = + now() - + (10 * (1073741821 - lastPingedTime) - + (suspenseConfig.timeoutMs | 0 || 5e3))), + (prevExecutionContext = + lastPingedTime <= prevDispatcher + ? 0 + : prevDispatcher + + prevExecutionContext - + lastPingedTime)); + if (10 < prevExecutionContext) { + markRootSuspendedAtTime(root, expirationTime); + root.timeoutHandle = scheduleTimeout( + commitRoot.bind(null, root), + prevExecutionContext + ); + break; + } + } + commitRoot(root); + break; + default: + throw Error("Unknown root exit status."); } - commitRoot(root); - break; - default: - throw Error("Unknown root exit status."); + ensureRootIsScheduled(root); + if (root.callbackNode === didTimeout) + return performConcurrentWorkOnRoot.bind(null, root); } } - ensureRootIsScheduled(root); - return root.callbackNode === didTimeout - ? performConcurrentWorkOnRoot.bind(null, root) - : null; + return null; } function performSyncWorkOnRoot(root) { - if ((executionContext & (RenderContext | CommitContext)) !== NoContext) - throw Error("Should not already be working."); - flushPassiveEffects(); var lastExpiredTime = root.lastExpiredTime; - lastExpiredTime = - 0 !== lastExpiredTime - ? root === workInProgressRoot && renderExpirationTime$1 >= lastExpiredTime - ? renderExpirationTime$1 - : lastExpiredTime - : 1073741823; - var exitStatus = renderRootSync(root, lastExpiredTime); - 0 !== root.tag && - exitStatus === RootErrored && - ((lastExpiredTime = 2 < lastExpiredTime ? 2 : lastExpiredTime), - (exitStatus = renderRootSync(root, lastExpiredTime))); - if (exitStatus === RootFatalErrored) - throw ((exitStatus = workInProgressRootFatalError), - prepareFreshStack(root, lastExpiredTime), - markRootSuspendedAtTime(root, lastExpiredTime), - ensureRootIsScheduled(root), - exitStatus); - root.finishedWork = root.current.alternate; - root.finishedExpirationTime = lastExpiredTime; - commitRoot(root); - ensureRootIsScheduled(root); + lastExpiredTime = 0 !== lastExpiredTime ? lastExpiredTime : 1073741823; + if (root.finishedExpirationTime === lastExpiredTime) commitRoot(root); + else { + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) + throw Error("Should not already be working."); + flushPassiveEffects(); + (root === workInProgressRoot && lastExpiredTime === renderExpirationTime) || + prepareFreshStack(root, lastExpiredTime); + if (null !== workInProgress) { + var prevExecutionContext = executionContext; + executionContext |= RenderContext; + var prevDispatcher = pushDispatcher(root); + do + try { + workLoopSync(); + break; + } catch (thrownValue) { + handleError(root, thrownValue); + } + while (1); + resetContextDependencies(); + executionContext = prevExecutionContext; + ReactCurrentDispatcher.current = prevDispatcher; + if (workInProgressRootExitStatus === RootFatalErrored) + throw ((prevExecutionContext = workInProgressRootFatalError), + prepareFreshStack(root, lastExpiredTime), + markRootSuspendedAtTime(root, lastExpiredTime), + ensureRootIsScheduled(root), + prevExecutionContext); + if (null !== workInProgress) + throw Error( + "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." + ); + root.finishedWork = root.current.alternate; + root.finishedExpirationTime = lastExpiredTime; + workInProgressRoot = null; + commitRoot(root); + ensureRootIsScheduled(root); + } + } return null; } +function flushPendingDiscreteUpdates() { + if (null !== rootsWithPendingDiscreteUpdates) { + var roots = rootsWithPendingDiscreteUpdates; + rootsWithPendingDiscreteUpdates = null; + roots.forEach(function(expirationTime, root) { + markRootExpiredAtTime(root, expirationTime); + ensureRootIsScheduled(root); + }); + flushSyncCallbackQueue(); + } +} function prepareFreshStack(root, expirationTime) { root.finishedWork = null; root.finishedExpirationTime = 0; @@ -5753,27 +5627,26 @@ function prepareFreshStack(root, expirationTime) { var interruptedWork = timeoutHandle; switch (interruptedWork.tag) { case 1: - interruptedWork = interruptedWork.type.childContextTypes; - null !== interruptedWork && - void 0 !== interruptedWork && - popContext(); + var childContextTypes = interruptedWork.type.childContextTypes; + null !== childContextTypes && + void 0 !== childContextTypes && + popContext(interruptedWork); break; case 3: - popHostContainer(); - pop(didPerformWorkStackCursor); - pop(contextStackCursor); + popHostContainer(interruptedWork); + popTopLevelContextObject(interruptedWork); break; case 5: popHostContext(interruptedWork); break; case 4: - popHostContainer(); + popHostContainer(interruptedWork); break; case 13: - pop(suspenseStackCursor); + pop(suspenseStackCursor, interruptedWork); break; case 19: - pop(suspenseStackCursor); + pop(suspenseStackCursor, interruptedWork); break; case 10: popProvider(interruptedWork); @@ -5781,8 +5654,8 @@ function prepareFreshStack(root, expirationTime) { timeoutHandle = timeoutHandle.return; } workInProgressRoot = root; - workInProgress = createWorkInProgress(root.current, null); - renderExpirationTime$1 = expirationTime; + workInProgress = createWorkInProgress(root.current, null, expirationTime); + renderExpirationTime = expirationTime; workInProgressRootExitStatus = RootIncomplete; workInProgressRootFatalError = null; workInProgressRootLatestSuspenseTimeout = workInProgressRootLatestProcessedExpirationTime = 1073741823; @@ -5794,32 +5667,19 @@ function handleError(root$jscomp$0, thrownValue) { do { try { resetContextDependencies(); - ReactCurrentDispatcher.current = ContextOnlyDispatcher; - if (didScheduleRenderPhaseUpdate) - for ( - var hook = currentlyRenderingFiber$1.memoizedState; - null !== hook; - - ) { - var queue = hook.queue; - null !== queue && (queue.pending = null); - hook = hook.next; - } - renderExpirationTime = 0; - workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; - didScheduleRenderPhaseUpdate = !1; + resetHooks(); if (null === workInProgress || null === workInProgress.return) return ( (workInProgressRootExitStatus = RootFatalErrored), (workInProgressRootFatalError = thrownValue), - (workInProgress = null) + null ); a: { var root = root$jscomp$0, returnFiber = workInProgress.return, sourceFiber = workInProgress, value = thrownValue; - thrownValue = renderExpirationTime$1; + thrownValue = renderExpirationTime; sourceFiber.effectTag |= 2048; sourceFiber.firstEffect = sourceFiber.lastEffect = null; if ( @@ -5827,17 +5687,8 @@ function handleError(root$jscomp$0, thrownValue) { "object" === typeof value && "function" === typeof value.then ) { - var thenable = value; - if (0 === (sourceFiber.mode & 2)) { - var currentSource = sourceFiber.alternate; - currentSource - ? ((sourceFiber.updateQueue = currentSource.updateQueue), - (sourceFiber.memoizedState = currentSource.memoizedState), - (sourceFiber.expirationTime = currentSource.expirationTime)) - : ((sourceFiber.updateQueue = null), - (sourceFiber.memoizedState = null)); - } - var hasInvisibleParentBoundary = + var thenable = value, + hasInvisibleParentBoundary = 0 !== (suspenseStackCursor.current & 1), _workInProgress = returnFiber; do { @@ -5852,10 +5703,10 @@ function handleError(root$jscomp$0, thrownValue) { void 0 === props.fallback ? !1 : !0 !== props.unstable_avoidThisFallback - ? !0 - : hasInvisibleParentBoundary - ? !1 - : !0; + ? !0 + : hasInvisibleParentBoundary + ? !1 + : !0; } } if (JSCompiler_temp) { @@ -5962,8 +5813,8 @@ function handleError(root$jscomp$0, thrownValue) { } while (1); } function pushDispatcher() { - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = ContextOnlyDispatcher; return null === prevDispatcher ? ContextOnlyDispatcher : prevDispatcher; } function markRenderEventTimeAndConfig(expirationTime, suspenseConfig) { @@ -5980,43 +5831,19 @@ function markUnprocessedUpdateTime(expirationTime) { expirationTime > workInProgressRootNextUnprocessedUpdateTime && (workInProgressRootNextUnprocessedUpdateTime = expirationTime); } -function renderRootSync(root, expirationTime) { - var prevExecutionContext = executionContext; - executionContext |= RenderContext; - var prevDispatcher = pushDispatcher(); - (root === workInProgressRoot && expirationTime === renderExpirationTime$1) || - prepareFreshStack(root, expirationTime); - do - try { - workLoopSync(); - break; - } catch (thrownValue) { - handleError(root, thrownValue); - } - while (1); - resetContextDependencies(); - executionContext = prevExecutionContext; - ReactCurrentDispatcher$1.current = prevDispatcher; - if (null !== workInProgress) - throw Error( - "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." - ); - workInProgressRoot = null; - return workInProgressRootExitStatus; -} function workLoopSync() { for (; null !== workInProgress; ) workInProgress = performUnitOfWork(workInProgress); } function workLoopConcurrent() { - for (; null !== workInProgress && !shouldYield(); ) + for (; null !== workInProgress && !Scheduler_shouldYield(); ) workInProgress = performUnitOfWork(workInProgress); } function performUnitOfWork(unitOfWork) { - var next = beginWork$1( + var next = beginWork$$1( unitOfWork.alternate, unitOfWork, - renderExpirationTime$1 + renderExpirationTime ); unitOfWork.memoizedProps = unitOfWork.pendingProps; null === next && (next = completeUnitOfWork(unitOfWork)); @@ -6026,30 +5853,351 @@ function performUnitOfWork(unitOfWork) { function completeUnitOfWork(unitOfWork) { workInProgress = unitOfWork; do { - var current = workInProgress.alternate; + var current$$1 = workInProgress.alternate; unitOfWork = workInProgress.return; if (0 === (workInProgress.effectTag & 2048)) { - current = completeWork(current, workInProgress, renderExpirationTime$1); - if ( - 1 === renderExpirationTime$1 || - 1 !== workInProgress.childExpirationTime - ) { + a: { + var instance = current$$1; + current$$1 = workInProgress; + var renderExpirationTime$jscomp$0 = renderExpirationTime, + newProps = current$$1.pendingProps; + switch (current$$1.tag) { + case 2: + break; + case 16: + break; + case 15: + case 0: + break; + case 1: + isContextProvider(current$$1.type) && popContext(current$$1); + break; + case 3: + popHostContainer(current$$1); + popTopLevelContextObject(current$$1); + instance = current$$1.stateNode; + instance.pendingContext && + ((instance.context = instance.pendingContext), + (instance.pendingContext = null)); + updateHostContainer(current$$1); + break; + case 5: + popHostContext(current$$1); + var rootContainerInstance = requiredContext( + rootInstanceStackCursor.current + ), + type = current$$1.type; + if (null !== instance && null != current$$1.stateNode) + updateHostComponent$1( + instance, + current$$1, + type, + newProps, + rootContainerInstance + ), + instance.ref !== current$$1.ref && + (current$$1.effectTag |= 128); + else if (newProps) { + requiredContext(contextStackCursor$1.current); + instance = current$$1; + renderExpirationTime$jscomp$0 = nextReactTag; + nextReactTag += 2; + type = getViewConfigForType(type); + var updatePayload = diffProperties( + null, + emptyObject, + newProps, + type.validAttributes + ); + rootContainerInstance = createNode( + renderExpirationTime$jscomp$0, + type.uiViewClassName, + rootContainerInstance, + updatePayload, + instance + ); + instance = new ReactFabricHostComponent( + renderExpirationTime$jscomp$0, + type, + newProps, + instance + ); + instance = { + node: rootContainerInstance, + canonical: instance + }; + appendAllChildren(instance, current$$1, !1, !1); + current$$1.stateNode = instance; + null !== current$$1.ref && (current$$1.effectTag |= 128); + } else if (null === current$$1.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." + ); + break; + case 6: + if (instance && null != current$$1.stateNode) + updateHostText$1( + instance, + current$$1, + instance.memoizedProps, + newProps + ); + else { + if ("string" !== typeof newProps && null === current$$1.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." + ); + instance = requiredContext(rootInstanceStackCursor.current); + rootContainerInstance = requiredContext( + contextStackCursor$1.current + ); + current$$1.stateNode = createTextInstance( + newProps, + instance, + rootContainerInstance, + current$$1 + ); + } + break; + case 11: + break; + case 13: + pop(suspenseStackCursor, current$$1); + newProps = current$$1.memoizedState; + if (0 !== (current$$1.effectTag & 64)) { + current$$1.expirationTime = renderExpirationTime$jscomp$0; + break a; + } + newProps = null !== newProps; + rootContainerInstance = !1; + null !== instance && + ((renderExpirationTime$jscomp$0 = instance.memoizedState), + (rootContainerInstance = null !== renderExpirationTime$jscomp$0), + newProps || + null === renderExpirationTime$jscomp$0 || + ((renderExpirationTime$jscomp$0 = instance.child.sibling), + null !== renderExpirationTime$jscomp$0 && + ((type = current$$1.firstEffect), + null !== type + ? ((current$$1.firstEffect = renderExpirationTime$jscomp$0), + (renderExpirationTime$jscomp$0.nextEffect = type)) + : ((current$$1.firstEffect = current$$1.lastEffect = renderExpirationTime$jscomp$0), + (renderExpirationTime$jscomp$0.nextEffect = null)), + (renderExpirationTime$jscomp$0.effectTag = 8)))); + if ( + newProps && + !rootContainerInstance && + 0 !== (current$$1.mode & 2) + ) + if ( + (null === instance && + !0 !== current$$1.memoizedProps.unstable_avoidThisFallback) || + 0 !== (suspenseStackCursor.current & 1) + ) + workInProgressRootExitStatus === RootIncomplete && + (workInProgressRootExitStatus = RootSuspended); + else { + if ( + workInProgressRootExitStatus === RootIncomplete || + workInProgressRootExitStatus === RootSuspended + ) + workInProgressRootExitStatus = RootSuspendedWithDelay; + 0 !== workInProgressRootNextUnprocessedUpdateTime && + null !== workInProgressRoot && + (markRootSuspendedAtTime( + workInProgressRoot, + renderExpirationTime + ), + markRootUpdatedAtTime( + workInProgressRoot, + workInProgressRootNextUnprocessedUpdateTime + )); + } + newProps && (current$$1.effectTag |= 4); + break; + case 7: + break; + case 8: + break; + case 12: + break; + case 4: + popHostContainer(current$$1); + updateHostContainer(current$$1); + break; + case 10: + popProvider(current$$1); + break; + case 9: + break; + case 14: + break; + case 17: + isContextProvider(current$$1.type) && popContext(current$$1); + break; + case 19: + pop(suspenseStackCursor, current$$1); + newProps = current$$1.memoizedState; + if (null === newProps) break; + rootContainerInstance = 0 !== (current$$1.effectTag & 64); + type = newProps.rendering; + if (null === type) + if (rootContainerInstance) cutOffTailIfNeeded(newProps, !1); + else { + if ( + workInProgressRootExitStatus !== RootIncomplete || + (null !== instance && 0 !== (instance.effectTag & 64)) + ) + for (instance = current$$1.child; null !== instance; ) { + type = findFirstSuspended(instance); + if (null !== type) { + current$$1.effectTag |= 64; + cutOffTailIfNeeded(newProps, !1); + instance = type.updateQueue; + null !== instance && + ((current$$1.updateQueue = instance), + (current$$1.effectTag |= 4)); + null === newProps.lastEffect && + (current$$1.firstEffect = null); + current$$1.lastEffect = newProps.lastEffect; + instance = renderExpirationTime$jscomp$0; + for (newProps = current$$1.child; null !== newProps; ) + (rootContainerInstance = newProps), + (renderExpirationTime$jscomp$0 = instance), + (rootContainerInstance.effectTag &= 2), + (rootContainerInstance.nextEffect = null), + (rootContainerInstance.firstEffect = null), + (rootContainerInstance.lastEffect = null), + (type = rootContainerInstance.alternate), + null === type + ? ((rootContainerInstance.childExpirationTime = 0), + (rootContainerInstance.expirationTime = renderExpirationTime$jscomp$0), + (rootContainerInstance.child = null), + (rootContainerInstance.memoizedProps = null), + (rootContainerInstance.memoizedState = null), + (rootContainerInstance.updateQueue = null), + (rootContainerInstance.dependencies = null)) + : ((rootContainerInstance.childExpirationTime = + type.childExpirationTime), + (rootContainerInstance.expirationTime = + type.expirationTime), + (rootContainerInstance.child = type.child), + (rootContainerInstance.memoizedProps = + type.memoizedProps), + (rootContainerInstance.memoizedState = + type.memoizedState), + (rootContainerInstance.updateQueue = + type.updateQueue), + (renderExpirationTime$jscomp$0 = + type.dependencies), + (rootContainerInstance.dependencies = + null === renderExpirationTime$jscomp$0 + ? null + : { + expirationTime: + renderExpirationTime$jscomp$0.expirationTime, + firstContext: + renderExpirationTime$jscomp$0.firstContext, + responders: + renderExpirationTime$jscomp$0.responders + })), + (newProps = newProps.sibling); + push( + suspenseStackCursor, + (suspenseStackCursor.current & 1) | 2, + current$$1 + ); + current$$1 = current$$1.child; + break a; + } + instance = instance.sibling; + } + } + else { + if (!rootContainerInstance) + if ( + ((instance = findFirstSuspended(type)), null !== instance) + ) { + if ( + ((current$$1.effectTag |= 64), + (rootContainerInstance = !0), + (instance = instance.updateQueue), + null !== instance && + ((current$$1.updateQueue = instance), + (current$$1.effectTag |= 4)), + cutOffTailIfNeeded(newProps, !0), + null === newProps.tail && + "hidden" === newProps.tailMode && + !type.alternate) + ) { + current$$1 = current$$1.lastEffect = newProps.lastEffect; + null !== current$$1 && (current$$1.nextEffect = null); + break; + } + } else + now() > newProps.tailExpiration && + 1 < renderExpirationTime$jscomp$0 && + ((current$$1.effectTag |= 64), + (rootContainerInstance = !0), + cutOffTailIfNeeded(newProps, !1), + (current$$1.expirationTime = current$$1.childExpirationTime = + renderExpirationTime$jscomp$0 - 1)); + newProps.isBackwards + ? ((type.sibling = current$$1.child), (current$$1.child = type)) + : ((instance = newProps.last), + null !== instance + ? (instance.sibling = type) + : (current$$1.child = type), + (newProps.last = type)); + } + if (null !== newProps.tail) { + 0 === newProps.tailExpiration && + (newProps.tailExpiration = now() + 500); + instance = newProps.tail; + newProps.rendering = instance; + newProps.tail = instance.sibling; + newProps.lastEffect = current$$1.lastEffect; + instance.sibling = null; + newProps = suspenseStackCursor.current; + newProps = rootContainerInstance + ? (newProps & 1) | 2 + : newProps & 1; + push(suspenseStackCursor, newProps, current$$1); + current$$1 = instance; + break a; + } + break; + case 20: + break; + case 21: + break; + default: + throw Error( + "Unknown unit of work tag (" + + current$$1.tag + + "). This error is likely caused by a bug in React. Please file an issue." + ); + } + current$$1 = null; + } + instance = workInProgress; + if (1 === renderExpirationTime || 1 !== instance.childExpirationTime) { + newProps = 0; for ( - var newChildExpirationTime = 0, _child = workInProgress.child; - null !== _child; + rootContainerInstance = instance.child; + null !== rootContainerInstance; - ) { - var _childUpdateExpirationTime = _child.expirationTime, - _childChildExpirationTime = _child.childExpirationTime; - _childUpdateExpirationTime > newChildExpirationTime && - (newChildExpirationTime = _childUpdateExpirationTime); - _childChildExpirationTime > newChildExpirationTime && - (newChildExpirationTime = _childChildExpirationTime); - _child = _child.sibling; - } - workInProgress.childExpirationTime = newChildExpirationTime; + ) + (renderExpirationTime$jscomp$0 = + rootContainerInstance.expirationTime), + (type = rootContainerInstance.childExpirationTime), + renderExpirationTime$jscomp$0 > newProps && + (newProps = renderExpirationTime$jscomp$0), + type > newProps && (newProps = type), + (rootContainerInstance = rootContainerInstance.sibling); + instance.childExpirationTime = newProps; } - if (null !== current) return current; + if (null !== current$$1) return current$$1; null !== unitOfWork && 0 === (unitOfWork.effectTag & 2048) && (null === unitOfWork.firstEffect && @@ -6064,14 +6212,15 @@ function completeUnitOfWork(unitOfWork) { : (unitOfWork.firstEffect = workInProgress), (unitOfWork.lastEffect = workInProgress))); } else { - current = unwindWork(workInProgress); - if (null !== current) return (current.effectTag &= 2047), current; + current$$1 = unwindWork(workInProgress, renderExpirationTime); + if (null !== current$$1) + return (current$$1.effectTag &= 2047), current$$1; null !== unitOfWork && ((unitOfWork.firstEffect = unitOfWork.lastEffect = null), (unitOfWork.effectTag |= 2048)); } - current = workInProgress.sibling; - if (null !== current) return current; + current$$1 = workInProgress.sibling; + if (null !== current$$1) return current$$1; workInProgress = unitOfWork; } while (null !== workInProgress); workInProgressRootExitStatus === RootIncomplete && @@ -6085,12 +6234,11 @@ function getRemainingExpirationTime(fiber) { } function commitRoot(root) { var renderPriorityLevel = getCurrentPriorityLevel(); - runWithPriority(99, commitRootImpl.bind(null, root, renderPriorityLevel)); + runWithPriority$1(99, commitRootImpl.bind(null, root, renderPriorityLevel)); return null; } function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { - do flushPassiveEffects(); - while (null !== rootWithPendingPassiveEffects); + flushPassiveEffects(); if ((executionContext & (RenderContext | CommitContext)) !== NoContext) throw Error("Should not already be working."); var finishedWork = root$jscomp$1.finishedWork, @@ -6119,8 +6267,7 @@ function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { expirationTime <= root$jscomp$1.lastExpiredTime && (root$jscomp$1.lastExpiredTime = 0); root$jscomp$1 === workInProgressRoot && - ((workInProgress = workInProgressRoot = null), - (renderExpirationTime$1 = 0)); + ((workInProgress = workInProgressRoot = null), (renderExpirationTime = 0)); 1 < finishedWork.effectTag ? null !== finishedWork.lastEffect ? ((finishedWork.lastEffect.nextEffect = finishedWork), @@ -6152,9 +6299,9 @@ function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { ) { var effectTag = nextEffect.effectTag; if (effectTag & 128) { - var current = nextEffect.alternate; - if (null !== current) { - var currentRef = current.ref; + var current$$1 = nextEffect.alternate; + if (null !== current$$1) { + var currentRef = current$$1.ref; null !== currentRef && ("function" === typeof currentRef ? currentRef(null) @@ -6180,10 +6327,10 @@ function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { commitWork(nextEffect.alternate, nextEffect); break; case 8: - var current$jscomp$0 = nextEffect; + var current$$1$jscomp$0 = nextEffect; a: for ( var finishedRoot = root, - root$jscomp$0 = current$jscomp$0, + root$jscomp$0 = current$$1$jscomp$0, renderPriorityLevel$jscomp$0 = renderPriorityLevel, node = root$jscomp$0; ; @@ -6208,7 +6355,7 @@ function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { node.sibling.return = node.return; node = node.sibling; } - detachFiber(current$jscomp$0); + detachFiber(current$$1$jscomp$0); } nextEffect = nextEffect.nextEffect; } @@ -6222,25 +6369,101 @@ function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { nextEffect = remainingExpirationTimeBeforeCommit; do try { - for (effectTag = root$jscomp$1; null !== nextEffect; ) { + for (effectTag = expirationTime; null !== nextEffect; ) { var effectTag$jscomp$0 = nextEffect.effectTag; - effectTag$jscomp$0 & 36 && - commitLifeCycles(effectTag, nextEffect.alternate, nextEffect); + if (effectTag$jscomp$0 & 36) { + var current$$1$jscomp$1 = nextEffect.alternate; + current$$1 = nextEffect; + currentRef = effectTag; + switch (current$$1.tag) { + case 0: + case 11: + case 15: + commitHookEffectList(16, 32, current$$1); + break; + case 1: + var instance = current$$1.stateNode; + if (current$$1.effectTag & 4) + if (null === current$$1$jscomp$1) + instance.componentDidMount(); + else { + var prevProps = + current$$1.elementType === current$$1.type + ? current$$1$jscomp$1.memoizedProps + : resolveDefaultProps( + current$$1.type, + current$$1$jscomp$1.memoizedProps + ); + instance.componentDidUpdate( + prevProps, + current$$1$jscomp$1.memoizedState, + instance.__reactInternalSnapshotBeforeUpdate + ); + } + var updateQueue = current$$1.updateQueue; + null !== updateQueue && + commitUpdateQueue( + current$$1, + updateQueue, + instance, + currentRef + ); + break; + case 3: + var _updateQueue = current$$1.updateQueue; + if (null !== _updateQueue) { + root = null; + if (null !== current$$1.child) + switch (current$$1.child.tag) { + case 5: + root = current$$1.child.stateNode.canonical; + break; + case 1: + root = current$$1.child.stateNode; + } + commitUpdateQueue(current$$1, _updateQueue, root, currentRef); + } + break; + case 5: + if (null === current$$1$jscomp$1 && current$$1.effectTag & 4) + throw Error( + "The current renderer does not support mutation. This error is likely caused by a bug in React. Please file an issue." + ); + break; + case 6: + break; + case 4: + break; + case 12: + break; + case 13: + break; + case 19: + case 17: + case 20: + case 21: + 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 (effectTag$jscomp$0 & 128) { - current = void 0; + current$$1 = void 0; var ref = nextEffect.ref; if (null !== ref) { - var instance = nextEffect.stateNode; + var instance$jscomp$0 = nextEffect.stateNode; switch (nextEffect.tag) { case 5: - current = instance.canonical; + current$$1 = instance$jscomp$0.canonical; break; default: - current = instance; + current$$1 = instance$jscomp$0; } "function" === typeof ref - ? ref(current) - : (ref.current = current); + ? ref(current$$1) + : (ref.current = current$$1); } } nextEffect = nextEffect.nextEffect; @@ -6310,7 +6533,7 @@ function flushPassiveEffects() { ? 97 : pendingPassiveEffectsRenderPriority; pendingPassiveEffectsRenderPriority = 90; - return runWithPriority(priorityLevel, flushPassiveEffectsImpl); + return runWithPriority$1(priorityLevel, flushPassiveEffectsImpl); } } function flushPassiveEffectsImpl() { @@ -6329,9 +6552,8 @@ function flushPassiveEffectsImpl() { case 0: case 11: case 15: - case 22: - commitHookEffectListUnmount(5, finishedWork), - commitHookEffectListMount(5, finishedWork); + commitHookEffectList(128, 0, finishedWork), + commitHookEffectList(0, 64, finishedWork); } } catch (error) { if (null === root) throw Error("Should be working on an effect."); @@ -6382,17 +6604,20 @@ function captureCommitPhaseError(sourceFiber, error) { function pingSuspendedRoot(root, thenable, suspendedTime) { var pingCache = root.pingCache; null !== pingCache && pingCache.delete(thenable); - workInProgressRoot === root && renderExpirationTime$1 === suspendedTime + workInProgressRoot === root && renderExpirationTime === suspendedTime ? workInProgressRootExitStatus === RootSuspendedWithDelay || (workInProgressRootExitStatus === RootSuspended && 1073741823 === workInProgressRootLatestProcessedExpirationTime && now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) - ? prepareFreshStack(root, renderExpirationTime$1) + ? prepareFreshStack(root, renderExpirationTime) : (workInProgressRootHasPendingPing = !0) : isRootSuspendedAtTime(root, suspendedTime) && ((thenable = root.lastPingedTime), (0 !== thenable && thenable < suspendedTime) || - ((root.lastPingedTime = suspendedTime), ensureRootIsScheduled(root))); + ((root.lastPingedTime = suspendedTime), + root.finishedExpirationTime === suspendedTime && + ((root.finishedExpirationTime = 0), (root.finishedWork = null)), + ensureRootIsScheduled(root))); } function resolveRetryThenable(boundaryFiber, thenable) { var retryCache = boundaryFiber.stateNode; @@ -6404,12 +6629,12 @@ function resolveRetryThenable(boundaryFiber, thenable) { boundaryFiber = markUpdateTimeFromFiberToRoot(boundaryFiber, thenable); null !== boundaryFiber && ensureRootIsScheduled(boundaryFiber); } -var beginWork$1; -beginWork$1 = function(current, workInProgress, renderExpirationTime) { +var beginWork$$1; +beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { var updateExpirationTime = workInProgress.expirationTime; - if (null !== current) + if (null !== current$$1) if ( - current.memoizedProps !== workInProgress.pendingProps || + current$$1.memoizedProps !== workInProgress.pendingProps || didPerformWorkStackCursor.current ) didReceiveUpdate = !0; @@ -6434,10 +6659,7 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { ); break; case 10: - updateExpirationTime = workInProgress.memoizedProps.value; - var context = workInProgress.type._context; - push(valueCursor, context._currentValue2); - context._currentValue2 = updateExpirationTime; + pushProvider(workInProgress, workInProgress.memoizedProps.value); break; case 13: if (null !== workInProgress.memoizedState) { @@ -6447,40 +6669,52 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { updateExpirationTime >= renderExpirationTime ) return updateSuspenseComponent( - current, + current$$1, workInProgress, renderExpirationTime ); - push(suspenseStackCursor, suspenseStackCursor.current & 1); + push( + suspenseStackCursor, + suspenseStackCursor.current & 1, + workInProgress + ); workInProgress = bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ); return null !== workInProgress ? workInProgress.sibling : null; } - push(suspenseStackCursor, suspenseStackCursor.current & 1); + push( + suspenseStackCursor, + suspenseStackCursor.current & 1, + workInProgress + ); break; case 19: updateExpirationTime = workInProgress.childExpirationTime >= renderExpirationTime; - if (0 !== (current.effectTag & 64)) { + if (0 !== (current$$1.effectTag & 64)) { if (updateExpirationTime) return updateSuspenseListComponent( - current, + current$$1, workInProgress, renderExpirationTime ); workInProgress.effectTag |= 64; } - context = workInProgress.memoizedState; - null !== context && - ((context.rendering = null), (context.tail = null)); - push(suspenseStackCursor, suspenseStackCursor.current); + var renderState = workInProgress.memoizedState; + null !== renderState && + ((renderState.rendering = null), (renderState.tail = null)); + push( + suspenseStackCursor, + suspenseStackCursor.current, + workInProgress + ); if (!updateExpirationTime) return null; } return bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -6492,40 +6726,41 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { switch (workInProgress.tag) { case 2: updateExpirationTime = workInProgress.type; - null !== current && - ((current.alternate = null), + null !== current$$1 && + ((current$$1.alternate = null), (workInProgress.alternate = null), (workInProgress.effectTag |= 2)); - current = workInProgress.pendingProps; - context = getMaskedContext(workInProgress, contextStackCursor.current); + current$$1 = workInProgress.pendingProps; + renderState = getMaskedContext( + workInProgress, + contextStackCursor.current + ); prepareToReadContext(workInProgress, renderExpirationTime); - context = renderWithHooks( + renderState = renderWithHooks( null, workInProgress, updateExpirationTime, - current, - context, + current$$1, + renderState, renderExpirationTime ); workInProgress.effectTag |= 1; if ( - "object" === typeof context && - null !== context && - "function" === typeof context.render && - void 0 === context.$$typeof + "object" === typeof renderState && + null !== renderState && + "function" === typeof renderState.render && + void 0 === renderState.$$typeof ) { workInProgress.tag = 1; - workInProgress.memoizedState = null; - workInProgress.updateQueue = null; + resetHooks(); if (isContextProvider(updateExpirationTime)) { var hasContext = !0; pushContextProvider(workInProgress); } else hasContext = !1; workInProgress.memoizedState = - null !== context.state && void 0 !== context.state - ? context.state + null !== renderState.state && void 0 !== renderState.state + ? renderState.state : null; - initializeUpdateQueue(workInProgress); var getDerivedStateFromProps = updateExpirationTime.getDerivedStateFromProps; "function" === typeof getDerivedStateFromProps && @@ -6533,15 +6768,15 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { workInProgress, updateExpirationTime, getDerivedStateFromProps, - current + current$$1 ); - context.updater = classComponentUpdater; - workInProgress.stateNode = context; - context._reactInternalFiber = workInProgress; + renderState.updater = classComponentUpdater; + workInProgress.stateNode = renderState; + renderState._reactInternalFiber = workInProgress; mountClassInstance( workInProgress, updateExpirationTime, - current, + current$$1, renderExpirationTime ); workInProgress = finishClassComponent( @@ -6557,129 +6792,127 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { reconcileChildren( null, workInProgress, - context, + renderState, renderExpirationTime ), (workInProgress = workInProgress.child); return workInProgress; case 16: - a: { - context = workInProgress.elementType; - null !== current && - ((current.alternate = null), - (workInProgress.alternate = null), - (workInProgress.effectTag |= 2)); - current = workInProgress.pendingProps; - initializeLazyComponentType(context); - if (1 !== context._status) throw context._result; - context = context._result; - workInProgress.type = context; - hasContext = workInProgress.tag = resolveLazyComponentTag(context); - current = resolveDefaultProps(context, current); - switch (hasContext) { - case 0: - workInProgress = updateFunctionComponent( - null, - workInProgress, - context, - current, - renderExpirationTime - ); - break a; - case 1: - workInProgress = updateClassComponent( - null, - workInProgress, - context, - current, - renderExpirationTime - ); - break a; - case 11: - workInProgress = updateForwardRef( - null, - workInProgress, - context, - current, - renderExpirationTime - ); - break a; - case 14: - workInProgress = updateMemoComponent( - null, - workInProgress, - context, - resolveDefaultProps(context.type, current), - updateExpirationTime, - renderExpirationTime - ); - break a; - } - throw Error( - "Element type is invalid. Received a promise that resolves to: " + - context + - ". Lazy element type must resolve to a class or function." - ); + renderState = workInProgress.elementType; + null !== current$$1 && + ((current$$1.alternate = null), + (workInProgress.alternate = null), + (workInProgress.effectTag |= 2)); + current$$1 = workInProgress.pendingProps; + initializeLazyComponentType(renderState); + if (1 !== renderState._status) throw renderState._result; + renderState = renderState._result; + workInProgress.type = renderState; + hasContext = workInProgress.tag = resolveLazyComponentTag(renderState); + current$$1 = resolveDefaultProps(renderState, current$$1); + switch (hasContext) { + case 0: + workInProgress = updateFunctionComponent( + null, + workInProgress, + renderState, + current$$1, + renderExpirationTime + ); + break; + case 1: + workInProgress = updateClassComponent( + null, + workInProgress, + renderState, + current$$1, + renderExpirationTime + ); + break; + case 11: + workInProgress = updateForwardRef( + null, + workInProgress, + renderState, + current$$1, + renderExpirationTime + ); + break; + case 14: + workInProgress = updateMemoComponent( + null, + workInProgress, + renderState, + resolveDefaultProps(renderState.type, current$$1), + updateExpirationTime, + renderExpirationTime + ); + break; + default: + throw Error( + "Element type is invalid. Received a promise that resolves to: " + + renderState + + ". Lazy element type must resolve to a class or function." + ); } return workInProgress; case 0: return ( (updateExpirationTime = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (renderState = workInProgress.pendingProps), + (renderState = workInProgress.elementType === updateExpirationTime - ? context - : resolveDefaultProps(updateExpirationTime, context)), + ? renderState + : resolveDefaultProps(updateExpirationTime, renderState)), updateFunctionComponent( - current, + current$$1, workInProgress, updateExpirationTime, - context, + renderState, renderExpirationTime ) ); case 1: return ( (updateExpirationTime = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (renderState = workInProgress.pendingProps), + (renderState = workInProgress.elementType === updateExpirationTime - ? context - : resolveDefaultProps(updateExpirationTime, context)), + ? renderState + : resolveDefaultProps(updateExpirationTime, renderState)), updateClassComponent( - current, + current$$1, workInProgress, updateExpirationTime, - context, + renderState, renderExpirationTime ) ); case 3: pushHostRootContext(workInProgress); updateExpirationTime = workInProgress.updateQueue; - if (null === current || null === updateExpirationTime) + if (null === updateExpirationTime) 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." ); - updateExpirationTime = workInProgress.pendingProps; - context = workInProgress.memoizedState; - context = null !== context ? context.element : null; - cloneUpdateQueue(current, workInProgress); + renderState = workInProgress.memoizedState; + renderState = null !== renderState ? renderState.element : null; processUpdateQueue( workInProgress, updateExpirationTime, + workInProgress.pendingProps, null, renderExpirationTime ); updateExpirationTime = workInProgress.memoizedState.element; - updateExpirationTime === context + updateExpirationTime === renderState ? (workInProgress = bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime )) : (reconcileChildren( - current, + current$$1, workInProgress, updateExpirationTime, renderExpirationTime @@ -6689,10 +6922,11 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { case 5: return ( pushHostContext(workInProgress), + null === current$$1 && tryToClaimNextHydratableInstance(workInProgress), (updateExpirationTime = workInProgress.pendingProps.children), - markRef(current, workInProgress), + markRef(current$$1, workInProgress), reconcileChildren( - current, + current$$1, workInProgress, updateExpirationTime, renderExpirationTime @@ -6701,10 +6935,13 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { workInProgress ); case 6: - return null; + return ( + null === current$$1 && tryToClaimNextHydratableInstance(workInProgress), + null + ); case 13: return updateSuspenseComponent( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -6715,7 +6952,7 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { workInProgress.stateNode.containerInfo ), (updateExpirationTime = workInProgress.pendingProps), - null === current + null === current$$1 ? (workInProgress.child = reconcileChildFibers( workInProgress, null, @@ -6723,7 +6960,7 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { renderExpirationTime )) : reconcileChildren( - current, + current$$1, workInProgress, updateExpirationTime, renderExpirationTime @@ -6733,23 +6970,23 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { case 11: return ( (updateExpirationTime = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (renderState = workInProgress.pendingProps), + (renderState = workInProgress.elementType === updateExpirationTime - ? context - : resolveDefaultProps(updateExpirationTime, context)), + ? renderState + : resolveDefaultProps(updateExpirationTime, renderState)), updateForwardRef( - current, + current$$1, workInProgress, updateExpirationTime, - context, + renderState, renderExpirationTime ) ); case 7: return ( reconcileChildren( - current, + current$$1, workInProgress, workInProgress.pendingProps, renderExpirationTime @@ -6759,7 +6996,7 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { case 8: return ( reconcileChildren( - current, + current$$1, workInProgress, workInProgress.pendingProps.children, renderExpirationTime @@ -6769,7 +7006,7 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { case 12: return ( reconcileChildren( - current, + current$$1, workInProgress, workInProgress.pendingProps.children, renderExpirationTime @@ -6779,32 +7016,27 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { case 10: a: { updateExpirationTime = workInProgress.type._context; - context = workInProgress.pendingProps; + renderState = 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 updateExpirationTime._calculateChangedBits - ? updateExpirationTime._calculateChangedBits( - context$jscomp$0, - hasContext - ) - : 1073741823) | 0), - 0 === hasContext) - ) { + hasContext = renderState.value; + pushProvider(workInProgress, hasContext); + if (null !== getDerivedStateFromProps) { + var oldValue = getDerivedStateFromProps.value; + hasContext = is$1(oldValue, hasContext) + ? 0 + : ("function" === typeof updateExpirationTime._calculateChangedBits + ? updateExpirationTime._calculateChangedBits( + oldValue, + hasContext + ) + : 1073741823) | 0; + if (0 === hasContext) { if ( - getDerivedStateFromProps.children === context.children && + getDerivedStateFromProps.children === renderState.children && !didPerformWorkStackCursor.current ) { workInProgress = bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -6812,15 +7044,14 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { } } 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; @@ -6830,18 +7061,18 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { dependency.context === updateExpirationTime && 0 !== (dependency.observedBits & hasContext) ) { - 1 === context$jscomp$0.tag && + 1 === oldValue.tag && ((dependency = createUpdate(renderExpirationTime, null)), (dependency.tag = 2), - enqueueUpdate(context$jscomp$0, dependency)); - context$jscomp$0.expirationTime < renderExpirationTime && - (context$jscomp$0.expirationTime = renderExpirationTime); - dependency = context$jscomp$0.alternate; + enqueueUpdate(oldValue, dependency)); + oldValue.expirationTime < renderExpirationTime && + (oldValue.expirationTime = renderExpirationTime); + dependency = oldValue.alternate; null !== dependency && dependency.expirationTime < renderExpirationTime && (dependency.expirationTime = renderExpirationTime); scheduleWorkOnParentPath( - context$jscomp$0.return, + oldValue.return, renderExpirationTime ); list.expirationTime < renderExpirationTime && @@ -6852,16 +7083,16 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { } } 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; ) { @@ -6869,20 +7100,21 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { 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, + current$$1, workInProgress, - context.children, + renderState.children, renderExpirationTime ); workInProgress = workInProgress.child; @@ -6890,15 +7122,18 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { return workInProgress; case 9: return ( - (context = workInProgress.type), + (renderState = workInProgress.type), (hasContext = workInProgress.pendingProps), (updateExpirationTime = hasContext.children), prepareToReadContext(workInProgress, renderExpirationTime), - (context = readContext(context, hasContext.unstable_observedBits)), - (updateExpirationTime = updateExpirationTime(context)), + (renderState = readContext( + renderState, + hasContext.unstable_observedBits + )), + (updateExpirationTime = updateExpirationTime(renderState)), (workInProgress.effectTag |= 1), reconcileChildren( - current, + current$$1, workInProgress, updateExpirationTime, renderExpirationTime @@ -6907,16 +7142,16 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { ); case 14: return ( - (context = workInProgress.type), + (renderState = workInProgress.type), (hasContext = resolveDefaultProps( - context, + renderState, workInProgress.pendingProps )), - (hasContext = resolveDefaultProps(context.type, hasContext)), + (hasContext = resolveDefaultProps(renderState.type, hasContext)), updateMemoComponent( - current, + current$$1, workInProgress, - context, + renderState, hasContext, updateExpirationTime, renderExpirationTime @@ -6924,7 +7159,7 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { ); case 15: return updateSimpleMemoComponent( - current, + current$$1, workInProgress, workInProgress.type, workInProgress.pendingProps, @@ -6934,25 +7169,30 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { case 17: return ( (updateExpirationTime = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (renderState = workInProgress.pendingProps), + (renderState = workInProgress.elementType === updateExpirationTime - ? context - : resolveDefaultProps(updateExpirationTime, context)), - null !== current && - ((current.alternate = null), + ? renderState + : resolveDefaultProps(updateExpirationTime, renderState)), + null !== current$$1 && + ((current$$1.alternate = null), (workInProgress.alternate = null), (workInProgress.effectTag |= 2)), (workInProgress.tag = 1), isContextProvider(updateExpirationTime) - ? ((current = !0), pushContextProvider(workInProgress)) - : (current = !1), + ? ((current$$1 = !0), pushContextProvider(workInProgress)) + : (current$$1 = !1), prepareToReadContext(workInProgress, renderExpirationTime), - constructClassInstance(workInProgress, updateExpirationTime, context), + constructClassInstance( + workInProgress, + updateExpirationTime, + renderState, + renderExpirationTime + ), mountClassInstance( workInProgress, updateExpirationTime, - context, + renderState, renderExpirationTime ), finishClassComponent( @@ -6960,13 +7200,13 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { workInProgress, updateExpirationTime, !0, - current, + current$$1, renderExpirationTime ) ); case 19: return updateSuspenseListComponent( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -7017,6 +7257,9 @@ function FiberNode(tag, pendingProps, key, mode) { this.childExpirationTime = this.expirationTime = 0; this.alternate = null; } +function createFiber(tag, pendingProps, key, mode) { + return new FiberNode(tag, pendingProps, key, mode); +} function shouldConstruct(Component) { Component = Component.prototype; return !(!Component || !Component.isReactComponent); @@ -7034,7 +7277,7 @@ function resolveLazyComponentTag(Component) { function createWorkInProgress(current, pendingProps) { var workInProgress = current.alternate; null === workInProgress - ? ((workInProgress = new FiberNode( + ? ((workInProgress = createFiber( current.tag, pendingProps, current.key, @@ -7050,10 +7293,6 @@ function createWorkInProgress(current, pendingProps) { (workInProgress.nextEffect = null), (workInProgress.firstEffect = null), (workInProgress.lastEffect = null)); - if (null == current) - throw Error("current is " + current + " but it can't be"); - if (null == workInProgress) - throw Error("workInProgress is " + workInProgress + " but it can't be"); workInProgress.childExpirationTime = current.childExpirationTime; workInProgress.expirationTime = current.expirationTime; workInProgress.child = current.child; @@ -7105,7 +7344,7 @@ function createFiberFromTypeAndProps( break; case REACT_PROFILER_TYPE: return ( - (type = new FiberNode(12, pendingProps, key, mode | 8)), + (type = createFiber(12, pendingProps, key, mode | 8)), (type.elementType = REACT_PROFILER_TYPE), (type.type = REACT_PROFILER_TYPE), (type.expirationTime = expirationTime), @@ -7113,7 +7352,7 @@ function createFiberFromTypeAndProps( ); case REACT_SUSPENSE_TYPE: return ( - (type = new FiberNode(13, pendingProps, key, mode)), + (type = createFiber(13, pendingProps, key, mode)), (type.type = REACT_SUSPENSE_TYPE), (type.elementType = REACT_SUSPENSE_TYPE), (type.expirationTime = expirationTime), @@ -7121,7 +7360,7 @@ function createFiberFromTypeAndProps( ); case REACT_SUSPENSE_LIST_TYPE: return ( - (type = new FiberNode(19, pendingProps, key, mode)), + (type = createFiber(19, pendingProps, key, mode)), (type.elementType = REACT_SUSPENSE_LIST_TYPE), (type.expirationTime = expirationTime), type @@ -7145,9 +7384,6 @@ function createFiberFromTypeAndProps( fiberTag = 16; owner = null; break a; - case REACT_BLOCK_TYPE: - fiberTag = 22; - break a; } throw Error( "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + @@ -7155,24 +7391,24 @@ function createFiberFromTypeAndProps( "." ); } - key = new FiberNode(fiberTag, pendingProps, key, mode); + key = createFiber(fiberTag, pendingProps, key, mode); key.elementType = type; key.type = owner; key.expirationTime = expirationTime; return key; } function createFiberFromFragment(elements, mode, expirationTime, key) { - elements = new FiberNode(7, elements, key, mode); + elements = createFiber(7, elements, key, mode); elements.expirationTime = expirationTime; return elements; } function createFiberFromText(content, mode, expirationTime) { - content = new FiberNode(6, content, null, mode); + content = createFiber(6, content, null, mode); content.expirationTime = expirationTime; return content; } function createFiberFromPortal(portal, mode, expirationTime) { - mode = new FiberNode( + mode = createFiber( 4, null !== portal.children ? portal.children : [], portal.key, @@ -7231,6 +7467,11 @@ function markRootUpdatedAtTime(root, expirationTime) { expirationTime > root.nextKnownPendingLevel && (root.nextKnownPendingLevel = expirationTime)); } +function markRootExpiredAtTime(root, expirationTime) { + var lastExpiredTime = root.lastExpiredTime; + if (0 === lastExpiredTime || lastExpiredTime > expirationTime) + root.lastExpiredTime = expirationTime; +} function findHostInstance(component) { var fiber = component._reactInternalFiber; if (void 0 === fiber) { @@ -7245,10 +7486,14 @@ function findHostInstance(component) { return null === component ? null : component.stateNode; } function updateContainer(element, container, parentComponent, callback) { - var current = container.current, + var current$$1 = container.current, currentTime = requestCurrentTimeForUpdate(), suspenseConfig = ReactCurrentBatchConfig.suspense; - currentTime = computeExpirationForFiber(currentTime, current, suspenseConfig); + currentTime = computeExpirationForFiber( + currentTime, + current$$1, + suspenseConfig + ); a: if (parentComponent) { parentComponent = parentComponent._reactInternalFiber; b: { @@ -7299,8 +7544,8 @@ function updateContainer(element, container, parentComponent, callback) { container.payload = { element: element }; callback = void 0 === callback ? null : callback; null !== callback && (container.callback = callback); - enqueueUpdate(current, container); - scheduleWork(current, currentTime); + enqueueUpdate(current$$1, container); + scheduleUpdateOnFiber(current$$1, currentTime); return currentTime; } function createPortal(children, containerInfo, implementation) { @@ -7314,6 +7559,7 @@ function createPortal(children, containerInfo, implementation) { implementation: implementation }; } +var fabricDispatchCommand = nativeFabricUIManager.dispatchCommand; function findNodeHandle(componentOrHandle) { if (null == componentOrHandle) return null; if ("number" === typeof componentOrHandle) return componentOrHandle; @@ -7324,8 +7570,8 @@ function findNodeHandle(componentOrHandle) { return null == componentOrHandle ? componentOrHandle : componentOrHandle.canonical - ? componentOrHandle.canonical._nativeTag - : componentOrHandle._nativeTag; + ? componentOrHandle.canonical._nativeTag + : componentOrHandle._nativeTag; } batchedUpdatesImpl = function(fn, a) { var prevExecutionContext = executionContext; @@ -7337,114 +7583,289 @@ batchedUpdatesImpl = function(fn, a) { executionContext === NoContext && flushSyncCallbackQueue(); } }; -var roots = new Map(); -(function(devToolsConfig) { - var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance; - return injectInternals({ - bundleType: devToolsConfig.bundleType, - version: devToolsConfig.version, - rendererPackageName: devToolsConfig.rendererPackageName, - rendererConfig: devToolsConfig.rendererConfig, - overrideHookState: null, - overrideProps: null, - setSuspenseHandler: null, - scheduleUpdate: null, - currentDispatcherRef: ReactSharedInternals.ReactCurrentDispatcher, - findHostInstanceByFiber: function(fiber) { - fiber = findCurrentHostFiber(fiber); - return null === fiber ? null : fiber.stateNode; +flushDiscreteUpdatesImpl = function() { + (executionContext & (1 | RenderContext | CommitContext)) === NoContext && + (flushPendingDiscreteUpdates(), flushPassiveEffects()); +}; +var roots = new Map(), + ReactFabric = { + NativeComponent: (function(findNodeHandle, findHostInstance) { + return (function(_React$Component) { + function ReactNativeComponent() { + return _React$Component.apply(this, arguments) || this; + } + _inheritsLoose(ReactNativeComponent, _React$Component); + var _proto = ReactNativeComponent.prototype; + _proto.blur = function() { + ReactNativePrivateInterface.TextInputState.blurTextInput( + findNodeHandle(this) + ); + }; + _proto.focus = function() { + ReactNativePrivateInterface.TextInputState.focusTextInput( + findNodeHandle(this) + ); + }; + _proto.measure = function(callback) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + null != maybeInstance && + (maybeInstance.canonical + ? nativeFabricUIManager.measure( + maybeInstance.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ) + : ReactNativePrivateInterface.UIManager.measure( + findNodeHandle(this), + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + )); + }; + _proto.measureInWindow = function(callback) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + null != maybeInstance && + (maybeInstance.canonical + ? nativeFabricUIManager.measureInWindow( + maybeInstance.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ) + : ReactNativePrivateInterface.UIManager.measureInWindow( + findNodeHandle(this), + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + )); + }; + _proto.measureLayout = function( + relativeToNativeNode, + onSuccess, + onFail + ) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + if (null != maybeInstance && !maybeInstance.canonical) { + if ("number" === typeof relativeToNativeNode) + var relativeNode = relativeToNativeNode; + else + relativeToNativeNode._nativeTag && + (relativeNode = relativeToNativeNode._nativeTag); + null != relativeNode && + ReactNativePrivateInterface.UIManager.measureLayout( + findNodeHandle(this), + relativeNode, + mountSafeCallback_NOT_REALLY_SAFE(this, onFail), + mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) + ); + } + }; + _proto.setNativeProps = function(nativeProps) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + if (null != maybeInstance && !maybeInstance.canonical) { + var nativeTag = + maybeInstance._nativeTag || maybeInstance.canonical._nativeTag; + maybeInstance = + maybeInstance.viewConfig || maybeInstance.canonical.viewConfig; + nativeProps = diffProperties( + null, + emptyObject, + nativeProps, + maybeInstance.validAttributes + ); + null != nativeProps && + ReactNativePrivateInterface.UIManager.updateView( + nativeTag, + maybeInstance.uiViewClassName, + nativeProps + ); + } + }; + return ReactNativeComponent; + })(React.Component); + })(findNodeHandle, findHostInstance), + findHostInstance_DEPRECATED: function(componentOrHandle) { + if (null == componentOrHandle) return null; + if (componentOrHandle._nativeTag) return componentOrHandle; + if (componentOrHandle.canonical && componentOrHandle.canonical._nativeTag) + return componentOrHandle.canonical; + componentOrHandle = findHostInstance(componentOrHandle); + return null == componentOrHandle + ? componentOrHandle + : componentOrHandle.canonical + ? componentOrHandle.canonical + : componentOrHandle; }, - findFiberByHostInstance: function(instance) { - return findFiberByHostInstance ? findFiberByHostInstance(instance) : null; + findNodeHandle: findNodeHandle, + dispatchCommand: function(handle, command, args) { + null != handle._nativeTag && + null != handle._internalInstanceHandle && + fabricDispatchCommand( + handle._internalInstanceHandle.stateNode.node, + command, + args + ); }, - findHostInstancesForRefresh: null, - scheduleRefresh: null, - scheduleRoot: null, - setRefreshHandler: null, - getCurrentFiber: null - }); + 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; + roots.set(containerTag, root); + } + updateContainer(element, root, null, callback); + a: if (((element = root.current), element.child)) + switch (element.child.tag) { + case 5: + element = element.child.stateNode.canonical; + break a; + default: + element = element.child.stateNode; + } + else element = null; + return element; + }, + unmountComponentAtNode: function(containerTag) { + var root = roots.get(containerTag); + root && + updateContainer(null, root, null, function() { + roots.delete(containerTag); + }); + }, + createPortal: function(children, containerTag) { + return createPortal( + children, + containerTag, + null, + 2 < arguments.length && void 0 !== arguments[2] ? arguments[2] : null + ); + }, + __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: { + NativeMethodsMixin: (function(findNodeHandle, findHostInstance) { + return { + measure: function(callback) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + null != maybeInstance && + (maybeInstance.canonical + ? nativeFabricUIManager.measure( + maybeInstance.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ) + : ReactNativePrivateInterface.UIManager.measure( + findNodeHandle(this), + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + )); + }, + measureInWindow: function(callback) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + null != maybeInstance && + (maybeInstance.canonical + ? nativeFabricUIManager.measureInWindow( + maybeInstance.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ) + : ReactNativePrivateInterface.UIManager.measureInWindow( + findNodeHandle(this), + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + )); + }, + measureLayout: function(relativeToNativeNode, onSuccess, onFail) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + if (null != maybeInstance && !maybeInstance.canonical) { + if ("number" === typeof relativeToNativeNode) + var relativeNode = relativeToNativeNode; + else + relativeToNativeNode._nativeTag && + (relativeNode = relativeToNativeNode._nativeTag); + null != relativeNode && + ReactNativePrivateInterface.UIManager.measureLayout( + findNodeHandle(this), + relativeNode, + mountSafeCallback_NOT_REALLY_SAFE(this, onFail), + mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) + ); + } + }, + setNativeProps: function(nativeProps) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + if (null != maybeInstance && !maybeInstance.canonical) { + var nativeTag = + maybeInstance._nativeTag || maybeInstance.canonical._nativeTag; + maybeInstance = + maybeInstance.viewConfig || maybeInstance.canonical.viewConfig; + nativeProps = diffProperties( + null, + emptyObject, + nativeProps, + maybeInstance.validAttributes + ); + null != nativeProps && + ReactNativePrivateInterface.UIManager.updateView( + nativeTag, + maybeInstance.uiViewClassName, + nativeProps + ); + } + }, + focus: function() { + ReactNativePrivateInterface.TextInputState.focusTextInput( + findNodeHandle(this) + ); + }, + blur: function() { + ReactNativePrivateInterface.TextInputState.blurTextInput( + findNodeHandle(this) + ); + } + }; + })(findNodeHandle, findHostInstance) + } + }; +(function(devToolsConfig) { + var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance; + return injectInternals( + Object.assign({}, devToolsConfig, { + overrideHookState: null, + overrideProps: null, + setSuspenseHandler: null, + scheduleUpdate: null, + currentDispatcherRef: ReactSharedInternals.ReactCurrentDispatcher, + findHostInstanceByFiber: function(fiber) { + fiber = findCurrentHostFiber(fiber); + return null === fiber ? null : fiber.stateNode; + }, + findFiberByHostInstance: function(instance) { + return findFiberByHostInstance + ? findFiberByHostInstance(instance) + : null; + }, + findHostInstancesForRefresh: null, + scheduleRefresh: null, + scheduleRoot: null, + setRefreshHandler: null, + getCurrentFiber: null + }) + ); })({ findFiberByHostInstance: getInstanceFromInstance, + getInspectorDataForViewTag: function() { + throw Error("getInspectorDataForViewTag() is not available in production"); + }, bundleType: 0, - version: "16.13.0", - rendererPackageName: "react-native-renderer", - rendererConfig: { - getInspectorDataForViewTag: function() { - throw Error( - "getInspectorDataForViewTag() is not available in production" - ); - }, - getInspectorDataForViewAtPoint: function() { - throw Error( - "getInspectorDataForViewAtPoint() is not available in production." - ); - }.bind(null, findNodeHandle) - } + version: "16.11.0", + rendererPackageName: "react-native-renderer" }); -exports.createPortal = function(children, containerTag) { - return createPortal( - children, - containerTag, - null, - 2 < arguments.length && void 0 !== arguments[2] ? arguments[2] : null - ); -}; -exports.dispatchCommand = function(handle, command, args) { - null != handle._nativeTag && - (handle._internalInstanceHandle - ? nativeFabricUIManager.dispatchCommand( - handle._internalInstanceHandle.stateNode.node, - command, - args - ) - : ReactNativePrivateInterface.UIManager.dispatchViewManagerCommand( - handle._nativeTag, - command, - args - )); -}; -exports.findHostInstance_DEPRECATED = function(componentOrHandle) { - if (null == componentOrHandle) return null; - if (componentOrHandle._nativeTag) return componentOrHandle; - if (componentOrHandle.canonical && componentOrHandle.canonical._nativeTag) - return componentOrHandle.canonical; - componentOrHandle = findHostInstance(componentOrHandle); - return null == componentOrHandle - ? componentOrHandle - : componentOrHandle.canonical - ? componentOrHandle.canonical - : componentOrHandle; -}; -exports.findNodeHandle = findNodeHandle; -exports.render = function(element, containerTag, callback) { - var root = roots.get(containerTag); - if (!root) { - root = new FiberRootNode(containerTag, 0, !1); - var uninitializedFiber = new FiberNode(3, null, null, 0); - root.current = uninitializedFiber; - uninitializedFiber.stateNode = root; - initializeUpdateQueue(uninitializedFiber); - roots.set(containerTag, root); - } - updateContainer(element, root, null, callback); - a: if (((element = root.current), element.child)) - switch (element.child.tag) { - case 5: - element = element.child.stateNode.canonical; - break a; - default: - element = element.child.stateNode; - } - else element = null; - return element; -}; -exports.stopSurface = function(containerTag) { - var root = roots.get(containerTag); - root && - updateContainer(null, root, null, function() { - roots.delete(containerTag); - }); -}; -exports.unmountComponentAtNode = function(containerTag) { - this.stopSurface(containerTag); -}; +var ReactFabric$2 = { default: ReactFabric }, + ReactFabric$3 = (ReactFabric$2 && ReactFabric) || ReactFabric$2; +module.exports = ReactFabric$3.default || ReactFabric$3; diff --git a/Libraries/Renderer/implementations/ReactFabric-prod.js b/Libraries/Renderer/implementations/ReactFabric-prod.js index 7df0e13f1f7fe1..21270fe18669b9 100644 --- a/Libraries/Renderer/implementations/ReactFabric-prod.js +++ b/Libraries/Renderer/implementations/ReactFabric-prod.js @@ -5,7 +5,6 @@ * LICENSE file in the root directory of this source tree. * * @noflow - * @nolint * @providesModule ReactFabric-prod * @preventMunge * @generated @@ -16,16 +15,85 @@ require("react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore"); var ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/ReactNativePrivateInterface"), React = require("react"), Scheduler = require("scheduler"); -function getParent(inst) { - do inst = inst.return; - while (inst && 5 !== inst.tag); - return inst ? inst : null; +var eventPluginOrder = null, + namesToPlugins = {}; +function recomputePluginOrdering() { + if (eventPluginOrder) + for (var pluginName in namesToPlugins) { + var pluginModule = namesToPlugins[pluginName], + pluginIndex = eventPluginOrder.indexOf(pluginName); + if (!(-1 < pluginIndex)) + throw Error( + "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + + pluginName + + "`." + ); + if (!plugins[pluginIndex]) { + if (!pluginModule.extractEvents) + throw Error( + "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + + pluginName + + "` does not." + ); + plugins[pluginIndex] = pluginModule; + pluginIndex = pluginModule.eventTypes; + for (var eventName in pluginIndex) { + var JSCompiler_inline_result = void 0; + var dispatchConfig = pluginIndex[eventName], + pluginModule$jscomp$0 = pluginModule, + eventName$jscomp$0 = eventName; + if (eventNameDispatchConfigs.hasOwnProperty(eventName$jscomp$0)) + throw Error( + "EventPluginHub: More than one plugin attempted to publish the same event name, `" + + eventName$jscomp$0 + + "`." + ); + eventNameDispatchConfigs[eventName$jscomp$0] = dispatchConfig; + var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; + if (phasedRegistrationNames) { + for (JSCompiler_inline_result in phasedRegistrationNames) + phasedRegistrationNames.hasOwnProperty( + JSCompiler_inline_result + ) && + publishRegistrationName( + phasedRegistrationNames[JSCompiler_inline_result], + pluginModule$jscomp$0, + eventName$jscomp$0 + ); + JSCompiler_inline_result = !0; + } else + dispatchConfig.registrationName + ? (publishRegistrationName( + dispatchConfig.registrationName, + pluginModule$jscomp$0, + eventName$jscomp$0 + ), + (JSCompiler_inline_result = !0)) + : (JSCompiler_inline_result = !1); + if (!JSCompiler_inline_result) + throw Error( + "EventPluginRegistry: Failed to publish event `" + + eventName + + "` for plugin `" + + pluginName + + "`." + ); + } + } + } } -function traverseTwoPhase(inst, fn, arg) { - for (var path = []; inst; ) path.push(inst), (inst = getParent(inst)); - for (inst = path.length; 0 < inst--; ) fn(path[inst], "captured", arg); - for (inst = 0; inst < path.length; inst++) fn(path[inst], "bubbled", arg); +function publishRegistrationName(registrationName, pluginModule) { + if (registrationNameModules[registrationName]) + throw Error( + "EventPluginHub: More than one plugin attempted to publish the same registration name, `" + + registrationName + + "`." + ); + registrationNameModules[registrationName] = pluginModule; } +var plugins = [], + eventNameDispatchConfigs = {}, + registrationNameModules = {}; function invokeGuardedCallbackImpl(name, func, context, a, b, c, d, e, f) { var funcArgs = Array.prototype.slice.call(arguments, 3); try { @@ -96,6 +164,74 @@ function executeDirectDispatch(event) { event._dispatchInstances = null; return dispatchListener; } +function accumulateInto(current, next) { + if (null == next) + throw Error( + "accumulateInto(...): Accumulated items must not be null or undefined." + ); + if (null == current) return next; + if (Array.isArray(current)) { + if (Array.isArray(next)) return current.push.apply(current, next), current; + current.push(next); + return current; + } + return Array.isArray(next) ? [current].concat(next) : [current, next]; +} +function forEachAccumulated(arr, cb, scope) { + Array.isArray(arr) ? arr.forEach(cb, scope) : arr && cb.call(scope, arr); +} +var eventQueue = null; +function executeDispatchesAndReleaseTopLevel(e) { + if (e) { + var dispatchListeners = e._dispatchListeners, + dispatchInstances = e._dispatchInstances; + if (Array.isArray(dispatchListeners)) + for ( + var i = 0; + i < dispatchListeners.length && !e.isPropagationStopped(); + i++ + ) + executeDispatch(e, dispatchListeners[i], dispatchInstances[i]); + else + dispatchListeners && + executeDispatch(e, dispatchListeners, dispatchInstances); + e._dispatchListeners = null; + e._dispatchInstances = null; + e.isPersistent() || e.constructor.release(e); + } +} +var injection = { + injectEventPluginOrder: function(injectedEventPluginOrder) { + if (eventPluginOrder) + throw Error( + "EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React." + ); + eventPluginOrder = Array.prototype.slice.call(injectedEventPluginOrder); + recomputePluginOrdering(); + }, + injectEventPluginsByName: function(injectedNamesToPlugins) { + var isOrderingDirty = !1, + pluginName; + for (pluginName in injectedNamesToPlugins) + if (injectedNamesToPlugins.hasOwnProperty(pluginName)) { + var pluginModule = injectedNamesToPlugins[pluginName]; + if ( + !namesToPlugins.hasOwnProperty(pluginName) || + namesToPlugins[pluginName] !== pluginModule + ) { + if (namesToPlugins[pluginName]) + throw Error( + "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + + pluginName + + "`." + ); + namesToPlugins[pluginName] = pluginModule; + isOrderingDirty = !0; + } + } + isOrderingDirty && recomputePluginOrdering(); + } +}; function getListener(inst, registrationName) { var listener = inst.stateNode; if (!listener) return null; @@ -113,7 +249,6 @@ function getListener(inst, registrationName) { case "onMouseMoveCapture": case "onMouseUp": case "onMouseUpCapture": - case "onMouseEnter": (props = !props.disabled) || ((inst = inst.type), (props = !( @@ -138,21 +273,15 @@ function getListener(inst, registrationName) { ); return listener; } -function accumulateInto(current, next) { - if (null == next) - throw Error( - "accumulateInto(...): Accumulated items must not be null or undefined." - ); - if (null == current) return next; - if (Array.isArray(current)) { - if (Array.isArray(next)) return current.push.apply(current, next), current; - current.push(next); - return current; - } - return Array.isArray(next) ? [current].concat(next) : [current, next]; +function getParent(inst) { + do inst = inst.return; + while (inst && 5 !== inst.tag); + return inst ? inst : null; } -function forEachAccumulated(arr, cb, scope) { - Array.isArray(arr) ? arr.forEach(cb, scope) : arr && cb.call(scope, arr); +function traverseTwoPhase(inst, fn, arg) { + for (var path = []; inst; ) path.push(inst), (inst = getParent(inst)); + for (inst = path.length; 0 < inst--; ) fn(path[inst], "captured", arg); + for (inst = 0; inst < path.length; inst++) fn(path[inst], "bubbled", arg); } function accumulateDirectionalDispatches(inst, phase, event) { if ( @@ -220,8 +349,8 @@ function SyntheticEvent( ((targetInst = dispatchConfig[propName]) ? (this[propName] = targetInst(nativeEvent)) : "target" === propName - ? (this.target = nativeEventTarget) - : (this[propName] = nativeEvent[propName])); + ? (this.target = nativeEventTarget) + : (this[propName] = nativeEvent[propName])); this.isDefaultPrevented = (null != nativeEvent.defaultPrevented ? nativeEvent.defaultPrevented : !1 === nativeEvent.returnValue) @@ -374,27 +503,53 @@ function recordTouchStart(touch) { } function recordTouchMove(touch) { var touchRecord = touchBank[getTouchIdentifier(touch)]; - touchRecord && - ((touchRecord.touchActive = !0), - (touchRecord.previousPageX = touchRecord.currentPageX), - (touchRecord.previousPageY = touchRecord.currentPageY), - (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), - (touchRecord.currentPageX = touch.pageX), - (touchRecord.currentPageY = touch.pageY), - (touchRecord.currentTimeStamp = timestampForTouch(touch)), - (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))); + touchRecord + ? ((touchRecord.touchActive = !0), + (touchRecord.previousPageX = touchRecord.currentPageX), + (touchRecord.previousPageY = touchRecord.currentPageY), + (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), + (touchRecord.currentPageX = touch.pageX), + (touchRecord.currentPageY = touch.pageY), + (touchRecord.currentTimeStamp = timestampForTouch(touch)), + (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))) + : console.warn( + "Cannot record touch move without a touch start.\nTouch Move: %s\n", + "Touch Bank: %s", + printTouch(touch), + printTouchBank() + ); } function recordTouchEnd(touch) { var touchRecord = touchBank[getTouchIdentifier(touch)]; - touchRecord && - ((touchRecord.touchActive = !1), - (touchRecord.previousPageX = touchRecord.currentPageX), - (touchRecord.previousPageY = touchRecord.currentPageY), - (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), - (touchRecord.currentPageX = touch.pageX), - (touchRecord.currentPageY = touch.pageY), - (touchRecord.currentTimeStamp = timestampForTouch(touch)), - (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))); + touchRecord + ? ((touchRecord.touchActive = !1), + (touchRecord.previousPageX = touchRecord.currentPageX), + (touchRecord.previousPageY = touchRecord.currentPageY), + (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), + (touchRecord.currentPageX = touch.pageX), + (touchRecord.currentPageY = touch.pageY), + (touchRecord.currentTimeStamp = timestampForTouch(touch)), + (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))) + : console.warn( + "Cannot record touch end without a touch start.\nTouch End: %s\n", + "Touch Bank: %s", + printTouch(touch), + printTouchBank() + ); +} +function printTouch(touch) { + return JSON.stringify({ + identifier: touch.identifier, + pageX: touch.pageX, + pageY: touch.pageY, + timestamp: timestampForTouch(touch) + }); +} +function printTouchBank() { + var printed = JSON.stringify(touchBank.slice(0, 20)); + 20 < touchBank.length && + (printed += " (original size: " + touchBank.length + ")"); + return printed; } var ResponderTouchHistoryStore = { recordTouchTrack: function(topLevelType, nativeEvent) { @@ -434,10 +589,10 @@ function accumulate(current, next) { return null == current ? next : Array.isArray(current) - ? current.concat(next) - : Array.isArray(next) - ? [current].concat(next) - : [current, next]; + ? current.concat(next) + : Array.isArray(next) + ? [current].concat(next) + : [current, next]; } var responderInst = null, trackedTouchCount = 0; @@ -527,7 +682,13 @@ var eventTypes = { "topTouchCancel" === topLevelType ) if (0 <= trackedTouchCount) --trackedTouchCount; - else return null; + else + return ( + console.warn( + "Ended a touch event which was not counted in `trackedTouchCount`." + ), + null + ); ResponderTouchHistoryStore.recordTouchTrack(topLevelType, nativeEvent); if ( targetInst && @@ -539,10 +700,10 @@ var eventTypes = { var shouldSetEventType = isStartish(topLevelType) ? eventTypes.startShouldSetResponder : isMoveish(topLevelType) - ? eventTypes.moveShouldSetResponder - : "topSelectionChange" === topLevelType - ? eventTypes.selectionChangeShouldSetResponder - : eventTypes.scrollShouldSetResponder; + ? eventTypes.moveShouldSetResponder + : "topSelectionChange" === topLevelType + ? eventTypes.selectionChangeShouldSetResponder + : eventTypes.scrollShouldSetResponder; if (responderInst) b: { var JSCompiler_temp = responderInst; @@ -696,10 +857,10 @@ var eventTypes = { (shouldSetEventType = shouldSetEventType ? eventTypes.responderStart : JSCompiler_temp - ? eventTypes.responderMove - : targetInst - ? eventTypes.responderEnd - : null) + ? eventTypes.responderMove + : targetInst + ? eventTypes.responderEnd + : null) ) (shouldSetEventType = ResponderSyntheticEvent.getPooled( shouldSetEventType, @@ -762,8 +923,8 @@ var eventTypes = { (topLevelType = shouldSetEventType ? eventTypes.responderTerminate : topLevelType - ? eventTypes.responderRelease - : null) + ? eventTypes.responderRelease + : null) ) (nativeEvent = ResponderSyntheticEvent.getPooled( topLevelType, @@ -787,160 +948,48 @@ var eventTypes = { } } }, - eventPluginOrder = null, - namesToPlugins = {}; -function recomputePluginOrdering() { - if (eventPluginOrder) - for (var pluginName in namesToPlugins) { - var pluginModule = namesToPlugins[pluginName], - pluginIndex = eventPluginOrder.indexOf(pluginName); - if (!(-1 < pluginIndex)) - throw Error( - "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + - pluginName + - "`." - ); - if (!plugins[pluginIndex]) { - if (!pluginModule.extractEvents) - throw Error( - "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + - pluginName + - "` does not." - ); - plugins[pluginIndex] = pluginModule; - pluginIndex = pluginModule.eventTypes; - for (var eventName in pluginIndex) { - var JSCompiler_inline_result = void 0; - var dispatchConfig = pluginIndex[eventName], - pluginModule$jscomp$0 = pluginModule, - eventName$jscomp$0 = eventName; - if (eventNameDispatchConfigs.hasOwnProperty(eventName$jscomp$0)) - throw Error( - "EventPluginRegistry: More than one plugin attempted to publish the same event name, `" + - eventName$jscomp$0 + - "`." - ); - eventNameDispatchConfigs[eventName$jscomp$0] = dispatchConfig; - var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; - if (phasedRegistrationNames) { - for (JSCompiler_inline_result in phasedRegistrationNames) - phasedRegistrationNames.hasOwnProperty( - JSCompiler_inline_result - ) && - publishRegistrationName( - phasedRegistrationNames[JSCompiler_inline_result], - pluginModule$jscomp$0, - eventName$jscomp$0 - ); - JSCompiler_inline_result = !0; - } else - dispatchConfig.registrationName - ? (publishRegistrationName( - dispatchConfig.registrationName, - pluginModule$jscomp$0, - eventName$jscomp$0 - ), - (JSCompiler_inline_result = !0)) - : (JSCompiler_inline_result = !1); - if (!JSCompiler_inline_result) - throw Error( - "EventPluginRegistry: Failed to publish event `" + - eventName + - "` for plugin `" + - pluginName + - "`." - ); - } - } - } -} -function publishRegistrationName(registrationName, pluginModule) { - if (registrationNameModules[registrationName]) - throw Error( - "EventPluginRegistry: More than one plugin attempted to publish the same registration name, `" + - registrationName + - "`." - ); - registrationNameModules[registrationName] = pluginModule; -} -var plugins = [], - eventNameDispatchConfigs = {}, - registrationNameModules = {}, customBubblingEventTypes = ReactNativePrivateInterface.ReactNativeViewConfigRegistry .customBubblingEventTypes, customDirectEventTypes = ReactNativePrivateInterface.ReactNativeViewConfigRegistry .customDirectEventTypes; -if (eventPluginOrder) - throw Error( - "EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React." - ); -eventPluginOrder = Array.prototype.slice.call([ +injection.injectEventPluginOrder([ "ResponderEventPlugin", "ReactNativeBridgeEventPlugin" ]); -recomputePluginOrdering(); -var injectedNamesToPlugins$jscomp$inline_92 = { - ResponderEventPlugin: ResponderEventPlugin, - ReactNativeBridgeEventPlugin: { - eventTypes: {}, - extractEvents: function( - topLevelType, +injection.injectEventPluginsByName({ + ResponderEventPlugin: ResponderEventPlugin, + ReactNativeBridgeEventPlugin: { + eventTypes: {}, + extractEvents: function( + topLevelType, + targetInst, + nativeEvent, + nativeEventTarget + ) { + if (null == targetInst) return null; + var bubbleDispatchConfig = customBubblingEventTypes[topLevelType], + directDispatchConfig = customDirectEventTypes[topLevelType]; + if (!bubbleDispatchConfig && !directDispatchConfig) + throw Error( + 'Unsupported top level event type "' + topLevelType + '" dispatched' + ); + topLevelType = SyntheticEvent.getPooled( + bubbleDispatchConfig || directDispatchConfig, targetInst, nativeEvent, nativeEventTarget - ) { - if (null == targetInst) return null; - var bubbleDispatchConfig = customBubblingEventTypes[topLevelType], - directDispatchConfig = customDirectEventTypes[topLevelType]; - if (!bubbleDispatchConfig && !directDispatchConfig) - throw Error( - 'Unsupported top level event type "' + topLevelType + '" dispatched' - ); - topLevelType = SyntheticEvent.getPooled( - bubbleDispatchConfig || directDispatchConfig, - targetInst, - nativeEvent, - nativeEventTarget - ); - if (bubbleDispatchConfig) - forEachAccumulated(topLevelType, accumulateTwoPhaseDispatchesSingle); - else if (directDispatchConfig) - forEachAccumulated(topLevelType, accumulateDirectDispatchesSingle); - else return null; - return topLevelType; - } - } - }, - isOrderingDirty$jscomp$inline_93 = !1, - pluginName$jscomp$inline_94; -for (pluginName$jscomp$inline_94 in injectedNamesToPlugins$jscomp$inline_92) - if ( - injectedNamesToPlugins$jscomp$inline_92.hasOwnProperty( - pluginName$jscomp$inline_94 - ) - ) { - var pluginModule$jscomp$inline_95 = - injectedNamesToPlugins$jscomp$inline_92[pluginName$jscomp$inline_94]; - if ( - !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_94) || - namesToPlugins[pluginName$jscomp$inline_94] !== - pluginModule$jscomp$inline_95 - ) { - if (namesToPlugins[pluginName$jscomp$inline_94]) - throw Error( - "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - pluginName$jscomp$inline_94 + - "`." - ); - namesToPlugins[ - pluginName$jscomp$inline_94 - ] = pluginModule$jscomp$inline_95; - isOrderingDirty$jscomp$inline_93 = !0; + ); + if (bubbleDispatchConfig) + forEachAccumulated(topLevelType, accumulateTwoPhaseDispatchesSingle); + else if (directDispatchConfig) + forEachAccumulated(topLevelType, accumulateDirectDispatchesSingle); + else return null; + return topLevelType; } } -isOrderingDirty$jscomp$inline_93 && recomputePluginOrdering(); +}); function getInstanceFromInstance(instanceHandle) { return instanceHandle; } @@ -949,8 +998,8 @@ getFiberCurrentPropsFromNode = function(inst) { }; getInstanceFromNode = getInstanceFromInstance; getNodeFromInstance = function(inst) { - inst = inst.stateNode.canonical; - if (!inst._nativeTag) throw Error("All native instances should have a tag."); + inst = inst.stateNode.canonical._nativeTag; + if (!inst) throw Error("All native instances should have a tag."); return inst; }; ResponderEventPlugin.injection.injectGlobalResponderHandler({ @@ -986,9 +1035,11 @@ var hasSymbol = "function" === typeof Symbol && Symbol.for, ? Symbol.for("react.suspense_list") : 60120, REACT_MEMO_TYPE = hasSymbol ? Symbol.for("react.memo") : 60115, - REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 60116, - REACT_BLOCK_TYPE = hasSymbol ? Symbol.for("react.block") : 60121, - MAYBE_ITERATOR_SYMBOL = "function" === typeof Symbol && Symbol.iterator; + REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 60116; +hasSymbol && Symbol.for("react.fundamental"); +hasSymbol && Symbol.for("react.responder"); +hasSymbol && Symbol.for("react.scope"); +var MAYBE_ITERATOR_SYMBOL = "function" === typeof Symbol && Symbol.iterator; function getIteratorFn(maybeIterable) { if (null === maybeIterable || "object" !== typeof maybeIterable) return null; maybeIterable = @@ -998,10 +1049,9 @@ function getIteratorFn(maybeIterable) { } function initializeLazyComponentType(lazyComponent) { if (-1 === lazyComponent._status) { - var ctor = lazyComponent._result; - ctor || (ctor = lazyComponent._ctor); - ctor = ctor(); lazyComponent._status = 0; + var ctor = lazyComponent._ctor; + ctor = ctor(); lazyComponent._result = ctor; ctor.then( function(moduleObject) { @@ -1038,9 +1088,9 @@ function getComponentName(type) { if ("object" === typeof type) switch (type.$$typeof) { case REACT_CONTEXT_TYPE: - return (type.displayName || "Context") + ".Consumer"; + return "Context.Consumer"; case REACT_PROVIDER_TYPE: - return (type._context.displayName || "Context") + ".Provider"; + return "Context.Provider"; case REACT_FORWARD_REF_TYPE: var innerType = type.render; innerType = innerType.displayName || innerType.name || ""; @@ -1050,8 +1100,6 @@ function getComponentName(type) { ); case REACT_MEMO_TYPE: return getComponentName(type.type); - case REACT_BLOCK_TYPE: - return getComponentName(type.render); case REACT_LAZY_TYPE: if ((type = 1 === type._status ? type._result : null)) return getComponentName(type); @@ -1241,8 +1289,8 @@ function diffNestedProperty( return nextProp ? addNestedProperty(updatePayload, nextProp, validAttributes) : prevProp - ? clearNestedProperty(updatePayload, prevProp, validAttributes) - : updatePayload; + ? clearNestedProperty(updatePayload, prevProp, validAttributes) + : updatePayload; if (!Array.isArray(prevProp) && !Array.isArray(nextProp)) return diffProperties(updatePayload, prevProp, nextProp, validAttributes); if (Array.isArray(prevProp) && Array.isArray(nextProp)) { @@ -1403,9 +1451,18 @@ function diffProperties(updatePayload, prevProps, nextProps, validAttributes) { ))))); return updatePayload; } +var restoreTarget = null, + restoreQueue = null; +function restoreStateOfTarget(target) { + if (getInstanceFromNode(target)) + throw Error( + "setRestoreImplementation() needs to be called to handle a target for controlled events. This error is likely caused by a bug in React. Please file an issue." + ); +} function batchedUpdatesImpl(fn, bookkeeping) { return fn(bookkeeping); } +function flushDiscreteUpdatesImpl() {} var isInsideEventHandler = !1; function batchedUpdates(fn, bookkeeping) { if (isInsideEventHandler) return fn(bookkeeping); @@ -1413,35 +1470,46 @@ function batchedUpdates(fn, bookkeeping) { try { return batchedUpdatesImpl(fn, bookkeeping); } finally { - isInsideEventHandler = !1; - } -} -var eventQueue = null; -function executeDispatchesAndReleaseTopLevel(e) { - if (e) { - var dispatchListeners = e._dispatchListeners, - dispatchInstances = e._dispatchInstances; - if (Array.isArray(dispatchListeners)) - for ( - var i = 0; - i < dispatchListeners.length && !e.isPropagationStopped(); - i++ + if ( + ((isInsideEventHandler = !1), + null !== restoreTarget || null !== restoreQueue) + ) + if ( + (flushDiscreteUpdatesImpl(), + restoreTarget && + ((bookkeeping = restoreTarget), + (fn = restoreQueue), + (restoreQueue = restoreTarget = null), + restoreStateOfTarget(bookkeeping), + fn)) ) - executeDispatch(e, dispatchListeners[i], dispatchInstances[i]); - else - dispatchListeners && - executeDispatch(e, dispatchListeners, dispatchInstances); - e._dispatchListeners = null; - e._dispatchInstances = null; - e.isPersistent() || e.constructor.release(e); + for (bookkeeping = 0; bookkeeping < fn.length; bookkeeping++) + restoreStateOfTarget(fn[bookkeeping]); } } +function _inheritsLoose(subClass, superClass) { + subClass.prototype = Object.create(superClass.prototype); + subClass.prototype.constructor = subClass; + subClass.__proto__ = superClass; +} +(function(_React$Component) { + function ReactNativeComponent() { + return _React$Component.apply(this, arguments) || this; + } + _inheritsLoose(ReactNativeComponent, _React$Component); + var _proto = ReactNativeComponent.prototype; + _proto.blur = function() {}; + _proto.focus = function() {}; + _proto.measure = function() {}; + _proto.measureInWindow = function() {}; + _proto.measureLayout = function() {}; + _proto.setNativeProps = function() {}; + return ReactNativeComponent; +})(React.Component); +new Map(); function dispatchEvent(target, topLevelType, nativeEvent) { var eventTarget = null; - if (null != target) { - var stateNode = target.stateNode; - null != stateNode && (eventTarget = stateNode.canonical); - } + eventTarget = nativeEvent.target; batchedUpdates(function() { var events = eventTarget; for (var events$jscomp$0 = null, i = 0; i < plugins.length; i++) { @@ -1479,21 +1547,21 @@ function shim$1() { "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." ); } -var _nativeFabricUIManage = nativeFabricUIManager, - createNode = _nativeFabricUIManage.createNode, - cloneNode = _nativeFabricUIManage.cloneNode, - cloneNodeWithNewChildren = _nativeFabricUIManage.cloneNodeWithNewChildren, +var _nativeFabricUIManage$1 = nativeFabricUIManager, + createNode = _nativeFabricUIManage$1.createNode, + cloneNode = _nativeFabricUIManage$1.cloneNode, + cloneNodeWithNewChildren = _nativeFabricUIManage$1.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, + _nativeFabricUIManage$1.cloneNodeWithNewChildrenAndProps, + cloneNodeWithNewProps = _nativeFabricUIManage$1.cloneNodeWithNewProps, + createChildNodeSet = _nativeFabricUIManage$1.createChildSet, + appendChildNode = _nativeFabricUIManage$1.appendChild, + appendChildNodeToSet = _nativeFabricUIManage$1.appendChildToSet, + completeRoot = _nativeFabricUIManage$1.completeRoot, + registerEventHandler = _nativeFabricUIManage$1.registerEventHandler, + fabricMeasure = _nativeFabricUIManage$1.measure, + fabricMeasureInWindow = _nativeFabricUIManage$1.measureInWindow, + fabricMeasureLayout = _nativeFabricUIManage$1.measureLayout, getViewConfigForType = ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get, nextReactTag = 2; @@ -1512,10 +1580,10 @@ var ReactFabricHostComponent = (function() { } var _proto = ReactFabricHostComponent.prototype; _proto.blur = function() { - ReactNativePrivateInterface.TextInputState.blurTextInput(this); + ReactNativePrivateInterface.TextInputState.blurTextInput(this._nativeTag); }; _proto.focus = function() { - ReactNativePrivateInterface.TextInputState.focusTextInput(this); + ReactNativePrivateInterface.TextInputState.focusTextInput(this._nativeTag); }; _proto.measure = function(callback) { fabricMeasure( @@ -1577,6 +1645,44 @@ function cloneHiddenInstance(instance) { canonical: instance.canonical }; } +var BEFORE_SLASH_RE = /^(.*)[\\\/]/; +function getStackByFiberInDevAndProd(workInProgress) { + var info = ""; + do { + a: switch (workInProgress.tag) { + case 3: + case 4: + case 6: + case 7: + case 10: + case 9: + var JSCompiler_inline_result = ""; + break a; + default: + var owner = workInProgress._debugOwner, + source = workInProgress._debugSource, + name = getComponentName(workInProgress.type); + JSCompiler_inline_result = null; + owner && (JSCompiler_inline_result = getComponentName(owner.type)); + owner = name; + name = ""; + source + ? (name = + " (at " + + source.fileName.replace(BEFORE_SLASH_RE, "") + + ":" + + source.lineNumber + + ")") + : JSCompiler_inline_result && + (name = " (created by " + JSCompiler_inline_result + ")"); + JSCompiler_inline_result = "\n in " + (owner || "Unknown") + name; + } + info += JSCompiler_inline_result; + workInProgress = workInProgress.return; + } while (workInProgress); + return info; +} +new Set(); var valueStack = [], index = -1; function pop(cursor) { @@ -1614,17 +1720,21 @@ function isContextProvider(type) { type = type.childContextTypes; return null !== type && void 0 !== type; } -function popContext() { - pop(didPerformWorkStackCursor); - pop(contextStackCursor); +function popContext(fiber) { + pop(didPerformWorkStackCursor, fiber); + pop(contextStackCursor, fiber); +} +function popTopLevelContextObject(fiber) { + pop(didPerformWorkStackCursor, fiber); + pop(contextStackCursor, fiber); } 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); + push(contextStackCursor, context, fiber); + push(didPerformWorkStackCursor, didChange, fiber); } function processChildContext(fiber, type, parentContext) { var instance = fiber.stateNode; @@ -1642,13 +1752,17 @@ function processChildContext(fiber, type, parentContext) { return Object.assign({}, parentContext, {}, instance); } function pushContextProvider(workInProgress) { - workInProgress = - ((workInProgress = workInProgress.stateNode) && - workInProgress.__reactInternalMemoizedMergedChildContext) || + var instance = workInProgress.stateNode; + instance = + (instance && instance.__reactInternalMemoizedMergedChildContext) || emptyContextObject; previousContext = contextStackCursor.current; - push(contextStackCursor, workInProgress); - push(didPerformWorkStackCursor, didPerformWorkStackCursor.current); + push(contextStackCursor, instance, workInProgress); + push( + didPerformWorkStackCursor, + didPerformWorkStackCursor.current, + workInProgress + ); return !0; } function invalidateContextProvider(workInProgress, type, didChange) { @@ -1658,21 +1772,18 @@ function invalidateContextProvider(workInProgress, type, didChange) { "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); + ? ((type = processChildContext(workInProgress, type, previousContext)), + (instance.__reactInternalMemoizedMergedChildContext = type), + pop(didPerformWorkStackCursor, workInProgress), + pop(contextStackCursor, workInProgress), + push(contextStackCursor, type, workInProgress)) + : pop(didPerformWorkStackCursor, workInProgress); + push(didPerformWorkStackCursor, didChange, workInProgress); } 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 = @@ -1683,7 +1794,6 @@ var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, Scheduler_LowPriority = Scheduler.unstable_LowPriority, Scheduler_IdlePriority = Scheduler.unstable_IdlePriority, fakeCallbackNode = {}, - shouldYield = Scheduler.unstable_shouldYield, requestPaint = void 0 !== Scheduler_requestPaint ? Scheduler_requestPaint : function() {}, syncQueue = null, @@ -1728,7 +1838,7 @@ function reactPriorityToSchedulerPriority(reactPriorityLevel) { throw Error("Unknown priority level."); } } -function runWithPriority(reactPriorityLevel, fn) { +function runWithPriority$1(reactPriorityLevel, fn) { reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); return Scheduler_runWithPriority(reactPriorityLevel, fn); } @@ -1760,7 +1870,7 @@ function flushSyncCallbackQueueImpl() { var i = 0; try { var queue = syncQueue; - runWithPriority(99, function() { + runWithPriority$1(99, function() { for (; i < queue.length; i++) { var callback = queue[i]; do callback = callback(!0); @@ -1783,10 +1893,10 @@ function flushSyncCallbackQueueImpl() { function is(x, y) { return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y); } -var objectIs = "function" === typeof Object.is ? Object.is : is, +var is$1 = "function" === typeof Object.is ? Object.is : is, hasOwnProperty = Object.prototype.hasOwnProperty; function shallowEqual(objA, objB) { - if (objectIs(objA, objB)) return !0; + if (is$1(objA, objB)) return !0; if ( "object" !== typeof objA || null === objA || @@ -1800,48 +1910,11 @@ function shallowEqual(objA, objB) { for (keysB = 0; keysB < keysA.length; keysB++) if ( !hasOwnProperty.call(objB, keysA[keysB]) || - !objectIs(objA[keysA[keysB]], objB[keysA[keysB]]) + !is$1(objA[keysA[keysB]], objB[keysA[keysB]]) ) return !1; return !0; } -var BEFORE_SLASH_RE = /^(.*)[\\\/]/; -function getStackByFiberInDevAndProd(workInProgress) { - var info = ""; - do { - a: switch (workInProgress.tag) { - case 3: - case 4: - case 6: - case 7: - case 10: - case 9: - var JSCompiler_inline_result = ""; - break a; - default: - var owner = workInProgress._debugOwner, - source = workInProgress._debugSource, - name = getComponentName(workInProgress.type); - JSCompiler_inline_result = null; - owner && (JSCompiler_inline_result = getComponentName(owner.type)); - owner = name; - name = ""; - source - ? (name = - " (at " + - source.fileName.replace(BEFORE_SLASH_RE, "") + - ":" + - source.lineNumber + - ")") - : JSCompiler_inline_result && - (name = " (created by " + JSCompiler_inline_result + ")"); - JSCompiler_inline_result = "\n in " + (owner || "Unknown") + name; - } - info += JSCompiler_inline_result; - workInProgress = workInProgress.return; - } while (workInProgress); - return info; -} function resolveDefaultProps(Component, baseProps) { if (Component && Component.defaultProps) { baseProps = Object.assign({}, baseProps); @@ -1859,9 +1932,14 @@ var valueCursor = { current: null }, function resetContextDependencies() { lastContextWithAllBitsObserved = lastContextDependency = currentlyRenderingFiber = null; } +function pushProvider(providerFiber, nextValue) { + var context = providerFiber.type._context; + push(valueCursor, context._currentValue2, providerFiber); + context._currentValue2 = nextValue; +} function popProvider(providerFiber) { var currentValue = valueCursor.current; - pop(valueCursor); + pop(valueCursor, providerFiber); providerFiber.type._context._currentValue2 = currentValue; } function scheduleWorkOnParentPath(parent, renderExpirationTime) { @@ -1916,195 +1994,237 @@ function readContext(context, observedBits) { return context._currentValue2; } var hasForceUpdate = !1; -function initializeUpdateQueue(fiber) { - fiber.updateQueue = { - baseState: fiber.memoizedState, - baseQueue: null, - shared: { pending: null }, - effects: null +function createUpdateQueue(baseState) { + return { + baseState: baseState, + firstUpdate: null, + lastUpdate: null, + firstCapturedUpdate: null, + lastCapturedUpdate: null, + firstEffect: null, + lastEffect: null, + firstCapturedEffect: null, + lastCapturedEffect: null }; } -function cloneUpdateQueue(current, workInProgress) { - current = current.updateQueue; - workInProgress.updateQueue === current && - (workInProgress.updateQueue = { - baseState: current.baseState, - baseQueue: current.baseQueue, - shared: current.shared, - effects: current.effects - }); +function cloneUpdateQueue(currentQueue) { + return { + baseState: currentQueue.baseState, + firstUpdate: currentQueue.firstUpdate, + lastUpdate: currentQueue.lastUpdate, + firstCapturedUpdate: null, + lastCapturedUpdate: null, + firstEffect: null, + lastEffect: null, + firstCapturedEffect: null, + lastCapturedEffect: null + }; } function createUpdate(expirationTime, suspenseConfig) { - expirationTime = { + return { expirationTime: expirationTime, suspenseConfig: suspenseConfig, tag: 0, payload: null, callback: null, - next: null + next: null, + nextEffect: null }; - return (expirationTime.next = expirationTime); +} +function appendUpdateToQueue(queue, update) { + null === queue.lastUpdate + ? (queue.firstUpdate = queue.lastUpdate = update) + : ((queue.lastUpdate.next = update), (queue.lastUpdate = update)); } function enqueueUpdate(fiber, update) { - 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; - } + var alternate = fiber.alternate; + if (null === alternate) { + var queue1 = fiber.updateQueue; + var queue2 = null; + null === queue1 && + (queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState)); + } else + (queue1 = fiber.updateQueue), + (queue2 = alternate.updateQueue), + null === queue1 + ? null === queue2 + ? ((queue1 = fiber.updateQueue = createUpdateQueue( + fiber.memoizedState + )), + (queue2 = alternate.updateQueue = createUpdateQueue( + alternate.memoizedState + ))) + : (queue1 = fiber.updateQueue = cloneUpdateQueue(queue2)) + : null === queue2 && + (queue2 = alternate.updateQueue = cloneUpdateQueue(queue1)); + null === queue2 || queue1 === queue2 + ? appendUpdateToQueue(queue1, update) + : null === queue1.lastUpdate || null === queue2.lastUpdate + ? (appendUpdateToQueue(queue1, update), + appendUpdateToQueue(queue2, update)) + : (appendUpdateToQueue(queue1, update), (queue2.lastUpdate = update)); } function enqueueCapturedUpdate(workInProgress, update) { + var workInProgressQueue = workInProgress.updateQueue; + workInProgressQueue = + null === workInProgressQueue + ? (workInProgress.updateQueue = createUpdateQueue( + workInProgress.memoizedState + )) + : ensureWorkInProgressQueueIsAClone(workInProgress, workInProgressQueue); + null === workInProgressQueue.lastCapturedUpdate + ? (workInProgressQueue.firstCapturedUpdate = workInProgressQueue.lastCapturedUpdate = update) + : ((workInProgressQueue.lastCapturedUpdate.next = update), + (workInProgressQueue.lastCapturedUpdate = update)); +} +function ensureWorkInProgressQueueIsAClone(workInProgress, queue) { var current = workInProgress.alternate; - null !== current && cloneUpdateQueue(current, workInProgress); - workInProgress = workInProgress.updateQueue; - current = workInProgress.baseQueue; - null === current - ? ((workInProgress.baseQueue = update.next = update), - (update.next = update)) - : ((update.next = current.next), (current.next = update)); + null !== current && + queue === current.updateQueue && + (queue = workInProgress.updateQueue = cloneUpdateQueue(queue)); + return queue; +} +function getStateFromUpdate( + workInProgress, + queue, + update, + prevState, + nextProps, + instance +) { + switch (update.tag) { + case 1: + return ( + (workInProgress = update.payload), + "function" === typeof workInProgress + ? workInProgress.call(instance, prevState, nextProps) + : workInProgress + ); + case 3: + workInProgress.effectTag = (workInProgress.effectTag & -4097) | 64; + case 0: + workInProgress = update.payload; + nextProps = + "function" === typeof workInProgress + ? workInProgress.call(instance, prevState, nextProps) + : workInProgress; + if (null === nextProps || void 0 === nextProps) break; + return Object.assign({}, prevState, nextProps); + case 2: + hasForceUpdate = !0; + } + return prevState; } function processUpdateQueue( - workInProgress$jscomp$0, + workInProgress, + queue, props, instance, renderExpirationTime ) { - var queue = workInProgress$jscomp$0.updateQueue; hasForceUpdate = !1; - var baseQueue = queue.baseQueue, - pendingQueue = queue.shared.pending; - if (null !== pendingQueue) { - if (null !== baseQueue) { - var baseFirst = baseQueue.next; - baseQueue.next = pendingQueue.next; - pendingQueue.next = baseFirst; - } - baseQueue = pendingQueue; - queue.shared.pending = null; - baseFirst = workInProgress$jscomp$0.alternate; - null !== baseFirst && - ((baseFirst = baseFirst.updateQueue), - null !== baseFirst && (baseFirst.baseQueue = pendingQueue)); - } - if (null !== baseQueue) { - baseFirst = baseQueue.next; - var newState = queue.baseState, + queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue); + for ( + var newBaseState = queue.baseState, + newFirstUpdate = null, newExpirationTime = 0, - newBaseState = null, - newBaseQueueFirst = null, - newBaseQueueLast = null; - if (null !== baseFirst) { - var update = baseFirst; - do { - pendingQueue = update.expirationTime; - if (pendingQueue < renderExpirationTime) { - var clone = { - expirationTime: update.expirationTime, - suspenseConfig: update.suspenseConfig, - tag: update.tag, - payload: update.payload, - callback: update.callback, - next: null - }; - null === newBaseQueueLast - ? ((newBaseQueueFirst = newBaseQueueLast = clone), - (newBaseState = newState)) - : (newBaseQueueLast = newBaseQueueLast.next = clone); - pendingQueue > newExpirationTime && - (newExpirationTime = pendingQueue); - } else { - null !== newBaseQueueLast && - (newBaseQueueLast = newBaseQueueLast.next = { - expirationTime: 1073741823, - suspenseConfig: update.suspenseConfig, - tag: update.tag, - payload: update.payload, - callback: update.callback, - next: null - }); - markRenderEventTimeAndConfig(pendingQueue, update.suspenseConfig); - a: { - var workInProgress = workInProgress$jscomp$0, - update$jscomp$0 = update; - pendingQueue = props; - clone = instance; - switch (update$jscomp$0.tag) { - case 1: - workInProgress = update$jscomp$0.payload; - if ("function" === typeof workInProgress) { - newState = workInProgress.call(clone, newState, pendingQueue); - break a; - } - newState = workInProgress; - break a; - case 3: - workInProgress.effectTag = - (workInProgress.effectTag & -4097) | 64; - case 0: - workInProgress = update$jscomp$0.payload; - pendingQueue = - "function" === typeof workInProgress - ? workInProgress.call(clone, newState, pendingQueue) - : workInProgress; - if (null === pendingQueue || void 0 === pendingQueue) break a; - newState = Object.assign({}, newState, pendingQueue); - break a; - case 2: - hasForceUpdate = !0; - } - } - null !== update.callback && - ((workInProgress$jscomp$0.effectTag |= 32), - (pendingQueue = queue.effects), - null === pendingQueue - ? (queue.effects = [update]) - : pendingQueue.push(update)); - } - update = update.next; - if (null === update || update === baseFirst) - if (((pendingQueue = queue.shared.pending), null === pendingQueue)) - break; - else - (update = baseQueue.next = pendingQueue.next), - (pendingQueue.next = baseFirst), - (queue.baseQueue = baseQueue = pendingQueue), - (queue.shared.pending = null); - } while (1); - } - null === newBaseQueueLast - ? (newBaseState = newState) - : (newBaseQueueLast.next = newBaseQueueFirst); - queue.baseState = newBaseState; - queue.baseQueue = newBaseQueueLast; - markUnprocessedUpdateTime(newExpirationTime); - workInProgress$jscomp$0.expirationTime = newExpirationTime; - workInProgress$jscomp$0.memoizedState = newState; + update = queue.firstUpdate, + resultState = newBaseState; + null !== update; + + ) { + var updateExpirationTime = update.expirationTime; + updateExpirationTime < renderExpirationTime + ? (null === newFirstUpdate && + ((newFirstUpdate = update), (newBaseState = resultState)), + newExpirationTime < updateExpirationTime && + (newExpirationTime = updateExpirationTime)) + : (markRenderEventTimeAndConfig( + updateExpirationTime, + update.suspenseConfig + ), + (resultState = getStateFromUpdate( + workInProgress, + queue, + update, + resultState, + props, + instance + )), + null !== update.callback && + ((workInProgress.effectTag |= 32), + (update.nextEffect = null), + null === queue.lastEffect + ? (queue.firstEffect = queue.lastEffect = update) + : ((queue.lastEffect.nextEffect = update), + (queue.lastEffect = update)))); + update = update.next; + } + updateExpirationTime = null; + for (update = queue.firstCapturedUpdate; null !== update; ) { + var _updateExpirationTime = update.expirationTime; + _updateExpirationTime < renderExpirationTime + ? (null === updateExpirationTime && + ((updateExpirationTime = update), + null === newFirstUpdate && (newBaseState = resultState)), + newExpirationTime < _updateExpirationTime && + (newExpirationTime = _updateExpirationTime)) + : ((resultState = getStateFromUpdate( + workInProgress, + queue, + update, + resultState, + props, + instance + )), + null !== update.callback && + ((workInProgress.effectTag |= 32), + (update.nextEffect = null), + null === queue.lastCapturedEffect + ? (queue.firstCapturedEffect = queue.lastCapturedEffect = update) + : ((queue.lastCapturedEffect.nextEffect = update), + (queue.lastCapturedEffect = update)))); + update = update.next; } + null === newFirstUpdate && (queue.lastUpdate = null); + null === updateExpirationTime + ? (queue.lastCapturedUpdate = null) + : (workInProgress.effectTag |= 32); + null === newFirstUpdate && + null === updateExpirationTime && + (newBaseState = resultState); + queue.baseState = newBaseState; + queue.firstUpdate = newFirstUpdate; + queue.firstCapturedUpdate = updateExpirationTime; + markUnprocessedUpdateTime(newExpirationTime); + workInProgress.expirationTime = newExpirationTime; + workInProgress.memoizedState = resultState; } function commitUpdateQueue(finishedWork, finishedQueue, instance) { - finishedWork = finishedQueue.effects; - finishedQueue.effects = null; - if (null !== finishedWork) - for ( - finishedQueue = 0; - finishedQueue < finishedWork.length; - finishedQueue++ - ) { - var effect = finishedWork[finishedQueue], - callback = effect.callback; - if (null !== callback) { - effect.callback = null; - if ("function" !== typeof callback) - throw Error( - "Invalid argument passed as callback. Expected a function. Instead received: " + - callback - ); - callback.call(instance); - } + null !== finishedQueue.firstCapturedUpdate && + (null !== finishedQueue.lastUpdate && + ((finishedQueue.lastUpdate.next = finishedQueue.firstCapturedUpdate), + (finishedQueue.lastUpdate = finishedQueue.lastCapturedUpdate)), + (finishedQueue.firstCapturedUpdate = finishedQueue.lastCapturedUpdate = null)); + commitUpdateEffects(finishedQueue.firstEffect, instance); + finishedQueue.firstEffect = finishedQueue.lastEffect = null; + commitUpdateEffects(finishedQueue.firstCapturedEffect, instance); + finishedQueue.firstCapturedEffect = finishedQueue.lastCapturedEffect = null; +} +function commitUpdateEffects(effect, instance) { + for (; null !== effect; ) { + var callback = effect.callback; + if (null !== callback) { + effect.callback = null; + if ("function" !== typeof callback) + throw Error( + "Invalid argument passed as callback. Expected a function. Instead received: " + + callback + ); + callback.call(instance); } + effect = effect.nextEffect; + } } var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig, emptyRefsObject = new React.Component().refs; @@ -2121,8 +2241,10 @@ function applyDerivedStateFromProps( ? ctor : Object.assign({}, ctor, getDerivedStateFromProps); workInProgress.memoizedState = getDerivedStateFromProps; - 0 === workInProgress.expirationTime && - (workInProgress.updateQueue.baseState = getDerivedStateFromProps); + nextProps = workInProgress.updateQueue; + null !== nextProps && + 0 === workInProgress.expirationTime && + (nextProps.baseState = getDerivedStateFromProps); } var classComponentUpdater = { isMounted: function(component) { @@ -2141,7 +2263,7 @@ var classComponentUpdater = { null !== callback && (suspenseConfig.callback = callback); enqueueUpdate(inst, suspenseConfig); - scheduleWork(inst, currentTime); + scheduleUpdateOnFiber(inst, currentTime); }, enqueueReplaceState: function(inst, payload, callback) { inst = inst._reactInternalFiber; @@ -2155,7 +2277,7 @@ var classComponentUpdater = { null !== callback && (suspenseConfig.callback = callback); enqueueUpdate(inst, suspenseConfig); - scheduleWork(inst, currentTime); + scheduleUpdateOnFiber(inst, currentTime); }, enqueueForceUpdate: function(inst, callback) { inst = inst._reactInternalFiber; @@ -2168,7 +2290,7 @@ var classComponentUpdater = { null !== callback && (suspenseConfig.callback = callback); enqueueUpdate(inst, suspenseConfig); - scheduleWork(inst, currentTime); + scheduleUpdateOnFiber(inst, currentTime); } }; function checkShouldComponentUpdate( @@ -2184,8 +2306,8 @@ function checkShouldComponentUpdate( return "function" === typeof workInProgress.shouldComponentUpdate ? workInProgress.shouldComponentUpdate(newProps, newState, nextContext) : ctor.prototype && ctor.prototype.isPureReactComponent - ? !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState) - : !0; + ? !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState) + : !0; } function constructClassInstance(workInProgress, ctor, props) { var isLegacyContextConsumer = !1, @@ -2237,7 +2359,6 @@ function mountClassInstance( instance.props = newProps; instance.state = workInProgress.memoizedState; instance.refs = emptyRefsObject; - initializeUpdateQueue(workInProgress); var contextType = ctor.contextType; "object" === typeof contextType && null !== contextType ? (instance.context = readContext(contextType)) @@ -2245,8 +2366,16 @@ function mountClassInstance( ? previousContext : contextStackCursor.current), (instance.context = getMaskedContext(workInProgress, contextType))); - processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); - instance.state = workInProgress.memoizedState; + contextType = workInProgress.updateQueue; + null !== contextType && + (processUpdateQueue( + workInProgress, + contextType, + newProps, + instance, + renderExpirationTime + ), + (instance.state = workInProgress.memoizedState)); contextType = ctor.getDerivedStateFromProps; "function" === typeof contextType && (applyDerivedStateFromProps(workInProgress, ctor, contextType, newProps), @@ -2262,18 +2391,21 @@ function mountClassInstance( instance.UNSAFE_componentWillMount(), ctor !== instance.state && classComponentUpdater.enqueueReplaceState(instance, instance.state, null), - processUpdateQueue( - workInProgress, - newProps, - instance, - renderExpirationTime - ), - (instance.state = workInProgress.memoizedState)); + (contextType = workInProgress.updateQueue), + null !== contextType && + (processUpdateQueue( + workInProgress, + contextType, + newProps, + instance, + renderExpirationTime + ), + (instance.state = workInProgress.memoizedState))); "function" === typeof instance.componentDidMount && (workInProgress.effectTag |= 4); } var isArray = Array.isArray; -function coerceRef(returnFiber, current, element) { +function coerceRef(returnFiber, current$$1, element) { returnFiber = element.ref; if ( null !== returnFiber && @@ -2285,7 +2417,7 @@ function coerceRef(returnFiber, current, element) { if (element) { if (1 !== element.tag) throw Error( - "Function components cannot have string refs. We recommend using useRef() instead. Learn more about using refs safely here: https://fb.me/react-strict-mode-string-ref" + "Function components cannot have refs. Did you mean to use React.forwardRef()?" ); var inst = element.stateNode; } @@ -2297,19 +2429,19 @@ function coerceRef(returnFiber, current, element) { ); var stringRef = "" + returnFiber; if ( - null !== current && - null !== current.ref && - "function" === typeof current.ref && - current.ref._stringRef === stringRef + null !== current$$1 && + null !== current$$1.ref && + "function" === typeof current$$1.ref && + current$$1.ref._stringRef === stringRef ) - return current.ref; - current = function(value) { + return current$$1.ref; + current$$1 = function(value) { var refs = inst.refs; refs === emptyRefsObject && (refs = inst.refs = {}); null === value ? delete refs[stringRef] : (refs[stringRef] = value); }; - current._stringRef = stringRef; - return current; + current$$1._stringRef = stringRef; + return current$$1; } if ("string" !== typeof returnFiber) throw Error( @@ -2361,8 +2493,8 @@ function ChildReconciler(shouldTrackSideEffects) { (currentFirstChild = currentFirstChild.sibling); return returnFiber; } - function useFiber(fiber, pendingProps) { - fiber = createWorkInProgress(fiber, pendingProps); + function useFiber(fiber, pendingProps, expirationTime) { + fiber = createWorkInProgress(fiber, pendingProps, expirationTime); fiber.index = 0; fiber.sibling = null; return fiber; @@ -2387,26 +2519,31 @@ function ChildReconciler(shouldTrackSideEffects) { (newFiber.effectTag = 2); return newFiber; } - function updateTextNode(returnFiber, current, textContent, expirationTime) { - if (null === current || 6 !== current.tag) + function updateTextNode( + returnFiber, + current$$1, + textContent, + expirationTime + ) { + if (null === current$$1 || 6 !== current$$1.tag) return ( - (current = createFiberFromText( + (current$$1 = createFiberFromText( textContent, returnFiber.mode, expirationTime )), - (current.return = returnFiber), - current + (current$$1.return = returnFiber), + current$$1 ); - current = useFiber(current, textContent); - current.return = returnFiber; - return current; + current$$1 = useFiber(current$$1, textContent, expirationTime); + current$$1.return = returnFiber; + return current$$1; } - function updateElement(returnFiber, current, element, expirationTime) { - if (null !== current && current.elementType === element.type) + function updateElement(returnFiber, current$$1, element, expirationTime) { + if (null !== current$$1 && current$$1.elementType === element.type) return ( - (expirationTime = useFiber(current, element.props)), - (expirationTime.ref = coerceRef(returnFiber, current, element)), + (expirationTime = useFiber(current$$1, element.props, expirationTime)), + (expirationTime.ref = coerceRef(returnFiber, current$$1, element)), (expirationTime.return = returnFiber), expirationTime ); @@ -2418,45 +2555,51 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime ); - expirationTime.ref = coerceRef(returnFiber, current, element); + expirationTime.ref = coerceRef(returnFiber, current$$1, element); expirationTime.return = returnFiber; return expirationTime; } - function updatePortal(returnFiber, current, portal, expirationTime) { + function updatePortal(returnFiber, current$$1, portal, expirationTime) { if ( - null === current || - 4 !== current.tag || - current.stateNode.containerInfo !== portal.containerInfo || - current.stateNode.implementation !== portal.implementation + null === current$$1 || + 4 !== current$$1.tag || + current$$1.stateNode.containerInfo !== portal.containerInfo || + current$$1.stateNode.implementation !== portal.implementation ) return ( - (current = createFiberFromPortal( + (current$$1 = createFiberFromPortal( portal, returnFiber.mode, expirationTime )), - (current.return = returnFiber), - current + (current$$1.return = returnFiber), + current$$1 ); - current = useFiber(current, portal.children || []); - current.return = returnFiber; - return current; + current$$1 = useFiber(current$$1, portal.children || [], expirationTime); + current$$1.return = returnFiber; + return current$$1; } - function updateFragment(returnFiber, current, fragment, expirationTime, key) { - if (null === current || 7 !== current.tag) + function updateFragment( + returnFiber, + current$$1, + fragment, + expirationTime, + key + ) { + if (null === current$$1 || 7 !== current$$1.tag) return ( - (current = createFiberFromFragment( + (current$$1 = createFiberFromFragment( fragment, returnFiber.mode, expirationTime, key )), - (current.return = returnFiber), - current + (current$$1.return = returnFiber), + current$$1 ); - current = useFiber(current, fragment); - current.return = returnFiber; - return current; + current$$1 = useFiber(current$$1, fragment, expirationTime); + current$$1.return = returnFiber; + return current$$1; } function createChild(returnFiber, newChild, expirationTime) { if ("string" === typeof newChild || "number" === typeof newChild) @@ -2819,48 +2962,39 @@ function ChildReconciler(shouldTrackSideEffects) { 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; - } + if (isUnkeyedTopLevelFragment.key === isObject) + if ( + 7 === isUnkeyedTopLevelFragment.tag + ? newChild.type === REACT_FRAGMENT_TYPE + : isUnkeyedTopLevelFragment.elementType === newChild.type + ) { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment.sibling + ); + currentFirstChild = useFiber( + isUnkeyedTopLevelFragment, + newChild.type === REACT_FRAGMENT_TYPE + ? newChild.props.children + : newChild.props, + expirationTime + ); + currentFirstChild.ref = coerceRef( + returnFiber, + isUnkeyedTopLevelFragment, + newChild + ); + currentFirstChild.return = returnFiber; + returnFiber = currentFirstChild; + break a; + } else { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment + ); + break; } - deleteRemainingChildren(returnFiber, isUnkeyedTopLevelFragment); - break; - } else deleteChild(returnFiber, isUnkeyedTopLevelFragment); + else deleteChild(returnFiber, isUnkeyedTopLevelFragment); isUnkeyedTopLevelFragment = isUnkeyedTopLevelFragment.sibling; } newChild.type === REACT_FRAGMENT_TYPE @@ -2910,7 +3044,8 @@ function ChildReconciler(shouldTrackSideEffects) { ); currentFirstChild = useFiber( currentFirstChild, - newChild.children || [] + newChild.children || [], + expirationTime ); currentFirstChild.return = returnFiber; returnFiber = currentFirstChild; @@ -2937,7 +3072,11 @@ function ChildReconciler(shouldTrackSideEffects) { (newChild = "" + newChild), null !== currentFirstChild && 6 === currentFirstChild.tag ? (deleteRemainingChildren(returnFiber, currentFirstChild.sibling), - (currentFirstChild = useFiber(currentFirstChild, newChild)), + (currentFirstChild = useFiber( + currentFirstChild, + newChild, + expirationTime + )), (currentFirstChild.return = returnFiber), (returnFiber = currentFirstChild)) : (deleteRemainingChildren(returnFiber, currentFirstChild), @@ -2992,16 +3131,16 @@ function requiredContext(c) { return c; } function pushHostContainer(fiber, nextRootInstance) { - push(rootInstanceStackCursor, nextRootInstance); - push(contextFiberStackCursor, fiber); - push(contextStackCursor$1, NO_CONTEXT); - pop(contextStackCursor$1); - push(contextStackCursor$1, { isInAParentText: !1 }); + push(rootInstanceStackCursor, nextRootInstance, fiber); + push(contextFiberStackCursor, fiber, fiber); + push(contextStackCursor$1, NO_CONTEXT, fiber); + pop(contextStackCursor$1, fiber); + push(contextStackCursor$1, { isInAParentText: !1 }, fiber); } -function popHostContainer() { - pop(contextStackCursor$1); - pop(contextFiberStackCursor); - pop(rootInstanceStackCursor); +function popHostContainer(fiber) { + pop(contextStackCursor$1, fiber); + pop(contextFiberStackCursor, fiber); + pop(rootInstanceStackCursor, fiber); } function pushHostContext(fiber) { requiredContext(rootInstanceStackCursor.current); @@ -3018,19 +3157,23 @@ function pushHostContext(fiber) { ? { isInAParentText: nextContext } : context; context !== nextContext && - (push(contextFiberStackCursor, fiber), - push(contextStackCursor$1, nextContext)); + (push(contextFiberStackCursor, fiber, fiber), + push(contextStackCursor$1, nextContext, fiber)); } function popHostContext(fiber) { contextFiberStackCursor.current === fiber && - (pop(contextStackCursor$1), pop(contextFiberStackCursor)); + (pop(contextStackCursor$1, fiber), pop(contextFiberStackCursor, fiber)); } var suspenseStackCursor = { current: 0 }; function findFirstSuspended(row) { for (var node = row; null !== node; ) { if (13 === node.tag) { var state = node.memoizedState; - if (null !== state && (null === state.dehydrated || shim$1() || shim$1())) + if ( + null !== state && + ((state = state.dehydrated), + null === state || shim$1(state) || shim$1(state)) + ) return node; } else if (19 === node.tag && void 0 !== node.memoizedProps.revealOrder) { if (0 !== (node.effectTag & 64)) return node; @@ -3049,16 +3192,24 @@ function findFirstSuspended(row) { } return null; } -function createDeprecatedResponderListener(responder, props) { +function createResponderListener(responder, props) { return { responder: responder, props: props }; } -var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher, +var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig, - renderExpirationTime = 0, + renderExpirationTime$1 = 0, currentlyRenderingFiber$1 = null, currentHook = null, + nextCurrentHook = null, + firstWorkInProgressHook = null, workInProgressHook = null, - didScheduleRenderPhaseUpdate = !1; + nextWorkInProgressHook = null, + remainingExpirationTime = 0, + componentUpdateQueue = null, + sideEffectTag = 0, + didScheduleRenderPhaseUpdate = !1, + renderPhaseUpdates = null, + numberOfReRenders = 0; function throwInvalidHookError() { throw Error( "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem." @@ -3067,7 +3218,7 @@ function throwInvalidHookError() { function areHookInputsEqual(nextDeps, prevDeps) { if (null === prevDeps) return !1; for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) - if (!objectIs(nextDeps[i], prevDeps[i])) return !1; + if (!is$1(nextDeps[i], prevDeps[i])) return !1; return !0; } function renderWithHooks( @@ -3075,85 +3226,92 @@ function renderWithHooks( workInProgress, Component, props, - secondArg, + refOrContext, nextRenderExpirationTime ) { - renderExpirationTime = nextRenderExpirationTime; + renderExpirationTime$1 = nextRenderExpirationTime; currentlyRenderingFiber$1 = workInProgress; - workInProgress.memoizedState = null; - workInProgress.updateQueue = null; - workInProgress.expirationTime = 0; - ReactCurrentDispatcher.current = - null === current || null === current.memoizedState - ? HooksDispatcherOnMount - : HooksDispatcherOnUpdate; - current = Component(props, secondArg); - if (workInProgress.expirationTime === renderExpirationTime) { - nextRenderExpirationTime = 0; - do { - workInProgress.expirationTime = 0; - if (!(25 > nextRenderExpirationTime)) - throw Error( - "Too many re-renders. React limits the number of renders to prevent an infinite loop." - ); - nextRenderExpirationTime += 1; - workInProgressHook = currentHook = null; - workInProgress.updateQueue = null; - ReactCurrentDispatcher.current = HooksDispatcherOnRerender; - current = Component(props, secondArg); - } while (workInProgress.expirationTime === renderExpirationTime); + nextCurrentHook = null !== current ? current.memoizedState : null; + ReactCurrentDispatcher$1.current = + null === nextCurrentHook ? HooksDispatcherOnMount : HooksDispatcherOnUpdate; + workInProgress = Component(props, refOrContext); + if (didScheduleRenderPhaseUpdate) { + do + (didScheduleRenderPhaseUpdate = !1), + (numberOfReRenders += 1), + (nextCurrentHook = null !== current ? current.memoizedState : null), + (nextWorkInProgressHook = firstWorkInProgressHook), + (componentUpdateQueue = workInProgressHook = currentHook = null), + (ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdate), + (workInProgress = Component(props, refOrContext)); + while (didScheduleRenderPhaseUpdate); + renderPhaseUpdates = null; + numberOfReRenders = 0; } - ReactCurrentDispatcher.current = ContextOnlyDispatcher; - workInProgress = null !== currentHook && null !== currentHook.next; - renderExpirationTime = 0; - workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; - didScheduleRenderPhaseUpdate = !1; - if (workInProgress) + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; + current = currentlyRenderingFiber$1; + current.memoizedState = firstWorkInProgressHook; + current.expirationTime = remainingExpirationTime; + current.updateQueue = componentUpdateQueue; + current.effectTag |= sideEffectTag; + current = null !== currentHook && null !== currentHook.next; + renderExpirationTime$1 = 0; + nextWorkInProgressHook = workInProgressHook = firstWorkInProgressHook = nextCurrentHook = currentHook = currentlyRenderingFiber$1 = null; + remainingExpirationTime = 0; + componentUpdateQueue = null; + sideEffectTag = 0; + if (current) throw Error( "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." ); - return current; + return workInProgress; +} +function resetHooks() { + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; + renderExpirationTime$1 = 0; + nextWorkInProgressHook = workInProgressHook = firstWorkInProgressHook = nextCurrentHook = currentHook = currentlyRenderingFiber$1 = null; + remainingExpirationTime = 0; + componentUpdateQueue = null; + sideEffectTag = 0; + didScheduleRenderPhaseUpdate = !1; + renderPhaseUpdates = null; + numberOfReRenders = 0; } function mountWorkInProgressHook() { var hook = { memoizedState: null, baseState: null, - baseQueue: null, queue: null, + baseUpdate: null, next: null }; null === workInProgressHook - ? (currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook) + ? (firstWorkInProgressHook = workInProgressHook = hook) : (workInProgressHook = workInProgressHook.next = hook); return workInProgressHook; } function updateWorkInProgressHook() { - if (null === currentHook) { - var nextCurrentHook = currentlyRenderingFiber$1.alternate; - nextCurrentHook = - null !== nextCurrentHook ? nextCurrentHook.memoizedState : null; - } else nextCurrentHook = currentHook.next; - var nextWorkInProgressHook = - null === workInProgressHook - ? currentlyRenderingFiber$1.memoizedState - : workInProgressHook.next; if (null !== nextWorkInProgressHook) (workInProgressHook = nextWorkInProgressHook), - (currentHook = nextCurrentHook); + (nextWorkInProgressHook = workInProgressHook.next), + (currentHook = nextCurrentHook), + (nextCurrentHook = null !== currentHook ? currentHook.next : null); else { if (null === nextCurrentHook) throw Error("Rendered more hooks than during the previous render."); currentHook = nextCurrentHook; - nextCurrentHook = { + var newHook = { memoizedState: currentHook.memoizedState, baseState: currentHook.baseState, - baseQueue: currentHook.baseQueue, queue: currentHook.queue, + baseUpdate: currentHook.baseUpdate, next: null }; - null === workInProgressHook - ? (currentlyRenderingFiber$1.memoizedState = workInProgressHook = nextCurrentHook) - : (workInProgressHook = workInProgressHook.next = nextCurrentHook); + workInProgressHook = + null === workInProgressHook + ? (firstWorkInProgressHook = newHook) + : (workInProgressHook.next = newHook); + nextCurrentHook = currentHook.next; } return workInProgressHook; } @@ -3168,100 +3326,74 @@ function updateReducer(reducer) { "Should have a queue. This is likely a bug in React. Please file an issue." ); queue.lastRenderedReducer = reducer; - var current = currentHook, - baseQueue = current.baseQueue, - pendingQueue = queue.pending; - if (null !== pendingQueue) { - if (null !== baseQueue) { - var baseFirst = baseQueue.next; - baseQueue.next = pendingQueue.next; - pendingQueue.next = baseFirst; + if (0 < numberOfReRenders) { + var _dispatch = queue.dispatch; + if (null !== renderPhaseUpdates) { + var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue); + if (void 0 !== firstRenderPhaseUpdate) { + renderPhaseUpdates.delete(queue); + var newState = hook.memoizedState; + do + (newState = reducer(newState, firstRenderPhaseUpdate.action)), + (firstRenderPhaseUpdate = firstRenderPhaseUpdate.next); + while (null !== firstRenderPhaseUpdate); + is$1(newState, hook.memoizedState) || (didReceiveUpdate = !0); + hook.memoizedState = newState; + hook.baseUpdate === queue.last && (hook.baseState = newState); + queue.lastRenderedState = newState; + return [newState, _dispatch]; + } } - current.baseQueue = baseQueue = pendingQueue; - queue.pending = null; + return [hook.memoizedState, _dispatch]; } - if (null !== baseQueue) { - baseQueue = baseQueue.next; - current = current.baseState; - var newBaseQueueLast = (baseFirst = pendingQueue = null), - update = baseQueue; + _dispatch = queue.last; + var baseUpdate = hook.baseUpdate; + newState = hook.baseState; + null !== baseUpdate + ? (null !== _dispatch && (_dispatch.next = null), + (_dispatch = baseUpdate.next)) + : (_dispatch = null !== _dispatch ? _dispatch.next : null); + if (null !== _dispatch) { + var newBaseUpdate = (firstRenderPhaseUpdate = null), + _update = _dispatch, + didSkip = !1; do { - var updateExpirationTime = update.expirationTime; - if (updateExpirationTime < renderExpirationTime) { - var clone = { - expirationTime: update.expirationTime, - suspenseConfig: update.suspenseConfig, - action: update.action, - eagerReducer: update.eagerReducer, - eagerState: update.eagerState, - next: null - }; - null === newBaseQueueLast - ? ((baseFirst = newBaseQueueLast = clone), (pendingQueue = current)) - : (newBaseQueueLast = newBaseQueueLast.next = clone); - updateExpirationTime > currentlyRenderingFiber$1.expirationTime && - ((currentlyRenderingFiber$1.expirationTime = updateExpirationTime), - markUnprocessedUpdateTime(updateExpirationTime)); - } else - null !== newBaseQueueLast && - (newBaseQueueLast = newBaseQueueLast.next = { - expirationTime: 1073741823, - suspenseConfig: update.suspenseConfig, - action: update.action, - eagerReducer: update.eagerReducer, - eagerState: update.eagerState, - next: null - }), - markRenderEventTimeAndConfig( + var updateExpirationTime = _update.expirationTime; + updateExpirationTime < renderExpirationTime$1 + ? (didSkip || + ((didSkip = !0), + (newBaseUpdate = baseUpdate), + (firstRenderPhaseUpdate = newState)), + updateExpirationTime > remainingExpirationTime && + ((remainingExpirationTime = updateExpirationTime), + markUnprocessedUpdateTime(remainingExpirationTime))) + : (markRenderEventTimeAndConfig( updateExpirationTime, - update.suspenseConfig + _update.suspenseConfig ), - (current = - update.eagerReducer === reducer - ? update.eagerState - : reducer(current, update.action)); - update = update.next; - } while (null !== update && update !== baseQueue); - null === newBaseQueueLast - ? (pendingQueue = current) - : (newBaseQueueLast.next = baseFirst); - objectIs(current, hook.memoizedState) || (didReceiveUpdate = !0); - hook.memoizedState = current; - hook.baseState = pendingQueue; - hook.baseQueue = newBaseQueueLast; - queue.lastRenderedState = current; - } - return [hook.memoizedState, queue.dispatch]; -} -function rerenderReducer(reducer) { - var hook = updateWorkInProgressHook(), - queue = hook.queue; - if (null === queue) - throw Error( - "Should have a queue. This is likely a bug in React. Please file an issue." - ); - queue.lastRenderedReducer = reducer; - var dispatch = queue.dispatch, - lastRenderPhaseUpdate = queue.pending, - newState = hook.memoizedState; - if (null !== lastRenderPhaseUpdate) { - queue.pending = null; - var update = (lastRenderPhaseUpdate = lastRenderPhaseUpdate.next); - do (newState = reducer(newState, update.action)), (update = update.next); - while (update !== lastRenderPhaseUpdate); - objectIs(newState, hook.memoizedState) || (didReceiveUpdate = !0); + (newState = + _update.eagerReducer === reducer + ? _update.eagerState + : reducer(newState, _update.action))); + baseUpdate = _update; + _update = _update.next; + } while (null !== _update && _update !== _dispatch); + didSkip || + ((newBaseUpdate = baseUpdate), (firstRenderPhaseUpdate = newState)); + is$1(newState, hook.memoizedState) || (didReceiveUpdate = !0); hook.memoizedState = newState; - null === hook.baseQueue && (hook.baseState = newState); + hook.baseUpdate = newBaseUpdate; + hook.baseState = firstRenderPhaseUpdate; queue.lastRenderedState = newState; } - return [newState, dispatch]; + return [hook.memoizedState, queue.dispatch]; } function mountState(initialState) { var hook = mountWorkInProgressHook(); "function" === typeof initialState && (initialState = initialState()); hook.memoizedState = hook.baseState = initialState; initialState = hook.queue = { - pending: null, + last: null, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState @@ -3273,30 +3405,28 @@ function mountState(initialState) { ); return [hook.memoizedState, initialState]; } +function updateState(initialState) { + return updateReducer(basicStateReducer, initialState); +} function pushEffect(tag, create, destroy, deps) { tag = { tag: tag, create: create, destroy: destroy, deps: deps, next: null }; - create = currentlyRenderingFiber$1.updateQueue; - null === create - ? ((create = { lastEffect: null }), - (currentlyRenderingFiber$1.updateQueue = create), - (create.lastEffect = tag.next = tag)) - : ((destroy = create.lastEffect), - null === destroy - ? (create.lastEffect = tag.next = tag) - : ((deps = destroy.next), - (destroy.next = tag), - (tag.next = deps), - (create.lastEffect = tag))); + null === componentUpdateQueue + ? ((componentUpdateQueue = { lastEffect: null }), + (componentUpdateQueue.lastEffect = tag.next = tag)) + : ((create = componentUpdateQueue.lastEffect), + null === create + ? (componentUpdateQueue.lastEffect = tag.next = tag) + : ((destroy = create.next), + (create.next = tag), + (tag.next = destroy), + (componentUpdateQueue.lastEffect = tag))); return tag; } -function updateRef() { - return updateWorkInProgressHook().memoizedState; -} function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var hook = mountWorkInProgressHook(); - currentlyRenderingFiber$1.effectTag |= fiberEffectTag; + sideEffectTag |= fiberEffectTag; hook.memoizedState = pushEffect( - 1 | hookEffectTag, + hookEffectTag, create, void 0, void 0 === deps ? null : deps @@ -3310,21 +3440,18 @@ function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var prevEffect = currentHook.memoizedState; destroy = prevEffect.destroy; if (null !== deps && areHookInputsEqual(deps, prevEffect.deps)) { - pushEffect(hookEffectTag, create, destroy, deps); + pushEffect(0, create, destroy, deps); return; } } - currentlyRenderingFiber$1.effectTag |= fiberEffectTag; - hook.memoizedState = pushEffect(1 | hookEffectTag, create, destroy, deps); + sideEffectTag |= fiberEffectTag; + hook.memoizedState = pushEffect(hookEffectTag, create, destroy, deps); } function mountEffect(create, deps) { - return mountEffectImpl(516, 4, create, deps); + return mountEffectImpl(516, 192, create, deps); } function updateEffect(create, deps) { - return updateEffectImpl(516, 4, create, deps); -} -function updateLayoutEffect(create, deps) { - return updateEffectImpl(4, 2, create, deps); + return updateEffectImpl(516, 192, create, deps); } function imperativeHandleEffect(create, ref) { if ("function" === typeof ref) @@ -3344,15 +3471,6 @@ function imperativeHandleEffect(create, ref) { } ); } -function updateImperativeHandle(ref, create, deps) { - deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; - return updateEffectImpl( - 4, - 2, - imperativeHandleEffect.bind(null, create, ref), - deps - ); -} function mountDebugValue() {} function mountCallback(callback, deps) { mountWorkInProgressHook().memoizedState = [ @@ -3374,79 +3492,72 @@ function updateCallback(callback, deps) { hook.memoizedState = [callback, deps]; return callback; } -function updateMemo(nextCreate, deps) { - var hook = updateWorkInProgressHook(); - deps = void 0 === deps ? null : deps; - var prevState = hook.memoizedState; - if ( - null !== prevState && - null !== deps && - areHookInputsEqual(deps, prevState[1]) - ) - return prevState[0]; - nextCreate = nextCreate(); - hook.memoizedState = [nextCreate, deps]; - return nextCreate; -} -function startTransition(setPending, config, callback) { - var priorityLevel = getCurrentPriorityLevel(); - runWithPriority(98 > priorityLevel ? 98 : priorityLevel, function() { - setPending(!0); - }); - runWithPriority(97 < priorityLevel ? 97 : priorityLevel, function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = void 0 === config ? null : config; - try { - setPending(!1), callback(); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); -} function dispatchAction(fiber, queue, action) { - var currentTime = requestCurrentTimeForUpdate(), - suspenseConfig = ReactCurrentBatchConfig.suspense; - currentTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig); - suspenseConfig = { - expirationTime: currentTime, - suspenseConfig: suspenseConfig, - action: action, - eagerReducer: null, - eagerState: null, - next: null - }; - var pending = queue.pending; - null === pending - ? (suspenseConfig.next = suspenseConfig) - : ((suspenseConfig.next = pending.next), (pending.next = suspenseConfig)); - queue.pending = suspenseConfig; - pending = fiber.alternate; + if (!(25 > numberOfReRenders)) + throw Error( + "Too many re-renders. React limits the number of renders to prevent an infinite loop." + ); + var alternate = fiber.alternate; if ( fiber === currentlyRenderingFiber$1 || - (null !== pending && pending === currentlyRenderingFiber$1) + (null !== alternate && alternate === currentlyRenderingFiber$1) ) - (didScheduleRenderPhaseUpdate = !0), - (suspenseConfig.expirationTime = renderExpirationTime), - (currentlyRenderingFiber$1.expirationTime = renderExpirationTime); + if ( + ((didScheduleRenderPhaseUpdate = !0), + (fiber = { + expirationTime: renderExpirationTime$1, + suspenseConfig: null, + action: action, + eagerReducer: null, + eagerState: null, + next: null + }), + null === renderPhaseUpdates && (renderPhaseUpdates = new Map()), + (action = renderPhaseUpdates.get(queue)), + void 0 === action) + ) + renderPhaseUpdates.set(queue, fiber); + else { + for (queue = action; null !== queue.next; ) queue = queue.next; + queue.next = fiber; + } else { + var currentTime = requestCurrentTimeForUpdate(), + suspenseConfig = ReactCurrentBatchConfig.suspense; + currentTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig); + suspenseConfig = { + expirationTime: currentTime, + suspenseConfig: suspenseConfig, + action: action, + eagerReducer: null, + eagerState: null, + next: null + }; + var last = queue.last; + if (null === last) suspenseConfig.next = suspenseConfig; + else { + var first = last.next; + null !== first && (suspenseConfig.next = first); + last.next = suspenseConfig; + } + queue.last = suspenseConfig; if ( 0 === fiber.expirationTime && - (null === pending || 0 === pending.expirationTime) && - ((pending = queue.lastRenderedReducer), null !== pending) + (null === alternate || 0 === alternate.expirationTime) && + ((alternate = queue.lastRenderedReducer), null !== alternate) ) try { var currentState = queue.lastRenderedState, - eagerState = pending(currentState, action); - suspenseConfig.eagerReducer = pending; + eagerState = alternate(currentState, action); + suspenseConfig.eagerReducer = alternate; suspenseConfig.eagerState = eagerState; - if (objectIs(eagerState, currentState)) return; + if (is$1(eagerState, currentState)) return; } catch (error) { } finally { } - scheduleWork(fiber, currentTime); + scheduleUpdateOnFiber(fiber, currentTime); } } -function updateEventListener() {} var ContextOnlyDispatcher = { readContext: readContext, useCallback: throwInvalidHookError, @@ -3461,8 +3572,7 @@ var ContextOnlyDispatcher = { useDebugValue: throwInvalidHookError, useResponder: throwInvalidHookError, useDeferredValue: throwInvalidHookError, - useTransition: throwInvalidHookError, - useEvent: throwInvalidHookError + useTransition: throwInvalidHookError }, HooksDispatcherOnMount = { readContext: readContext, @@ -3473,13 +3583,13 @@ var ContextOnlyDispatcher = { deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; return mountEffectImpl( 4, - 2, + 36, imperativeHandleEffect.bind(null, create, ref), deps ); }, useLayoutEffect: function(create, deps) { - return mountEffectImpl(4, 2, create, deps); + return mountEffectImpl(4, 36, create, deps); }, useMemo: function(nextCreate, deps) { var hook = mountWorkInProgressHook(); @@ -3493,7 +3603,7 @@ var ContextOnlyDispatcher = { initialArg = void 0 !== init ? init(initialArg) : initialArg; hook.memoizedState = hook.baseState = initialArg; reducer = hook.queue = { - pending: null, + last: null, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialArg @@ -3512,21 +3622,23 @@ var ContextOnlyDispatcher = { }, useState: mountState, useDebugValue: mountDebugValue, - useResponder: createDeprecatedResponderListener, + useResponder: createResponderListener, useDeferredValue: function(value, config) { var _mountState = mountState(value), prevValue = _mountState[0], setValue = _mountState[1]; mountEffect( function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - void 0 === config ? null : config; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } + Scheduler.unstable_next(function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }); }, [value, config] ); @@ -3534,124 +3646,177 @@ var ContextOnlyDispatcher = { }, useTransition: function(config) { var _mountState2 = mountState(!1), - isPending = _mountState2[0]; - _mountState2 = _mountState2[1]; + isPending = _mountState2[0], + setPending = _mountState2[1]; return [ - mountCallback(startTransition.bind(null, _mountState2, config), [ - _mountState2, - config - ]), + mountCallback( + function(callback) { + setPending(!0); + Scheduler.unstable_next(function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setPending(!1), callback(); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }); + }, + [config, isPending] + ), isPending ]; - }, - useEvent: function() {} + } }, HooksDispatcherOnUpdate = { readContext: readContext, useCallback: updateCallback, useContext: readContext, useEffect: updateEffect, - useImperativeHandle: updateImperativeHandle, - useLayoutEffect: updateLayoutEffect, - useMemo: updateMemo, + useImperativeHandle: function(ref, create, deps) { + deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; + return updateEffectImpl( + 4, + 36, + imperativeHandleEffect.bind(null, create, ref), + deps + ); + }, + useLayoutEffect: function(create, deps) { + return updateEffectImpl(4, 36, create, deps); + }, + useMemo: function(nextCreate, deps) { + var hook = updateWorkInProgressHook(); + deps = void 0 === deps ? null : deps; + var prevState = hook.memoizedState; + if ( + null !== prevState && + null !== deps && + areHookInputsEqual(deps, prevState[1]) + ) + return prevState[0]; + nextCreate = nextCreate(); + hook.memoizedState = [nextCreate, deps]; + return nextCreate; + }, useReducer: updateReducer, - useRef: updateRef, - useState: function() { - return updateReducer(basicStateReducer); + useRef: function() { + return updateWorkInProgressHook().memoizedState; }, + useState: updateState, useDebugValue: mountDebugValue, - useResponder: createDeprecatedResponderListener, + useResponder: createResponderListener, useDeferredValue: function(value, config) { - var _updateState = updateReducer(basicStateReducer), + var _updateState = updateState(value), prevValue = _updateState[0], setValue = _updateState[1]; updateEffect( function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - void 0 === config ? null : config; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } + Scheduler.unstable_next(function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }); }, [value, config] ); return prevValue; }, useTransition: function(config) { - var _updateState2 = updateReducer(basicStateReducer), - isPending = _updateState2[0]; - _updateState2 = _updateState2[1]; + var _updateState2 = updateState(!1), + isPending = _updateState2[0], + setPending = _updateState2[1]; return [ - updateCallback(startTransition.bind(null, _updateState2, config), [ - _updateState2, - config - ]), + updateCallback( + function(callback) { + setPending(!0); + Scheduler.unstable_next(function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setPending(!1), callback(); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }); + }, + [config, isPending] + ), isPending ]; - }, - useEvent: updateEventListener + } }, - HooksDispatcherOnRerender = { - readContext: readContext, - useCallback: updateCallback, - useContext: readContext, - useEffect: updateEffect, - useImperativeHandle: updateImperativeHandle, - useLayoutEffect: updateLayoutEffect, - useMemo: updateMemo, - useReducer: rerenderReducer, - useRef: updateRef, - useState: function() { - return rerenderReducer(basicStateReducer); - }, - useDebugValue: mountDebugValue, - useResponder: createDeprecatedResponderListener, - useDeferredValue: function(value, config) { - var _rerenderState = rerenderReducer(basicStateReducer), - prevValue = _rerenderState[0], - setValue = _rerenderState[1]; - updateEffect( - function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - void 0 === config ? null : config; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }, - [value, config] + hydrationParentFiber = null, + nextHydratableInstance = null, + isHydrating = !1; +function tryHydrate(fiber, nextInstance) { + switch (fiber.tag) { + case 5: + return ( + (nextInstance = shim$1(nextInstance, fiber.type, fiber.pendingProps)), + null !== nextInstance ? ((fiber.stateNode = nextInstance), !0) : !1 ); - return prevValue; - }, - useTransition: function(config) { - var _rerenderState2 = rerenderReducer(basicStateReducer), - isPending = _rerenderState2[0]; - _rerenderState2 = _rerenderState2[1]; - return [ - updateCallback(startTransition.bind(null, _rerenderState2, config), [ - _rerenderState2, - config - ]), - isPending - ]; - }, - useEvent: updateEventListener - }, - ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner, + case 6: + return ( + (nextInstance = shim$1(nextInstance, fiber.pendingProps)), + null !== nextInstance ? ((fiber.stateNode = nextInstance), !0) : !1 + ); + case 13: + return !1; + default: + return !1; + } +} +function tryToClaimNextHydratableInstance(fiber$jscomp$0) { + if (isHydrating) { + var nextInstance = nextHydratableInstance; + if (nextInstance) { + var firstAttemptedInstance = nextInstance; + if (!tryHydrate(fiber$jscomp$0, nextInstance)) { + nextInstance = shim$1(firstAttemptedInstance); + if (!nextInstance || !tryHydrate(fiber$jscomp$0, nextInstance)) { + fiber$jscomp$0.effectTag = (fiber$jscomp$0.effectTag & -1025) | 2; + isHydrating = !1; + hydrationParentFiber = fiber$jscomp$0; + return; + } + var returnFiber = hydrationParentFiber, + fiber = createFiber(5, null, null, 0); + fiber.elementType = "DELETED"; + fiber.type = "DELETED"; + fiber.stateNode = firstAttemptedInstance; + fiber.return = returnFiber; + fiber.effectTag = 8; + null !== returnFiber.lastEffect + ? ((returnFiber.lastEffect.nextEffect = fiber), + (returnFiber.lastEffect = fiber)) + : (returnFiber.firstEffect = returnFiber.lastEffect = fiber); + } + hydrationParentFiber = fiber$jscomp$0; + nextHydratableInstance = shim$1(nextInstance); + } else + (fiber$jscomp$0.effectTag = (fiber$jscomp$0.effectTag & -1025) | 2), + (isHydrating = !1), + (hydrationParentFiber = fiber$jscomp$0); + } +} +var ReactCurrentOwner$3 = ReactSharedInternals.ReactCurrentOwner, didReceiveUpdate = !1; function reconcileChildren( - current, + current$$1, workInProgress, nextChildren, renderExpirationTime ) { workInProgress.child = - null === current + null === current$$1 ? mountChildFibers( workInProgress, null, @@ -3660,13 +3825,13 @@ function reconcileChildren( ) : reconcileChildFibers( workInProgress, - current.child, + current$$1.child, nextChildren, renderExpirationTime ); } function updateForwardRef( - current, + current$$1, workInProgress, Component, nextProps, @@ -3676,38 +3841,43 @@ function updateForwardRef( var ref = workInProgress.ref; prepareToReadContext(workInProgress, renderExpirationTime); nextProps = renderWithHooks( - current, + current$$1, workInProgress, Component, nextProps, ref, renderExpirationTime ); - if (null !== current && !didReceiveUpdate) + if (null !== current$$1 && !didReceiveUpdate) return ( - (workInProgress.updateQueue = current.updateQueue), + (workInProgress.updateQueue = current$$1.updateQueue), (workInProgress.effectTag &= -517), - current.expirationTime <= renderExpirationTime && - (current.expirationTime = 0), + current$$1.expirationTime <= renderExpirationTime && + (current$$1.expirationTime = 0), bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ) ); workInProgress.effectTag |= 1; - reconcileChildren(current, workInProgress, nextProps, renderExpirationTime); + reconcileChildren( + current$$1, + workInProgress, + nextProps, + renderExpirationTime + ); return workInProgress.child; } function updateMemoComponent( - current, + current$$1, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime ) { - if (null === current) { + if (null === current$$1) { var type = Component.type; if ( "function" === typeof type && @@ -3720,7 +3890,7 @@ function updateMemoComponent( (workInProgress.tag = 15), (workInProgress.type = type), updateSimpleMemoComponent( - current, + current$$1, workInProgress, type, nextProps, @@ -3728,7 +3898,7 @@ function updateMemoComponent( renderExpirationTime ) ); - current = createFiberFromTypeAndProps( + current$$1 = createFiberFromTypeAndProps( Component.type, null, nextProps, @@ -3736,66 +3906,65 @@ function updateMemoComponent( workInProgress.mode, renderExpirationTime ); - current.ref = workInProgress.ref; - current.return = workInProgress; - return (workInProgress.child = current); + current$$1.ref = workInProgress.ref; + current$$1.return = workInProgress; + return (workInProgress.child = current$$1); } - type = current.child; + type = current$$1.child; if ( updateExpirationTime < renderExpirationTime && ((updateExpirationTime = type.memoizedProps), (Component = Component.compare), (Component = null !== Component ? Component : shallowEqual), Component(updateExpirationTime, nextProps) && - current.ref === workInProgress.ref) + current$$1.ref === workInProgress.ref) ) return bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ); workInProgress.effectTag |= 1; - current = createWorkInProgress(type, nextProps); - current.ref = workInProgress.ref; - current.return = workInProgress; - return (workInProgress.child = current); + current$$1 = createWorkInProgress(type, nextProps, renderExpirationTime); + current$$1.ref = workInProgress.ref; + current$$1.return = workInProgress; + return (workInProgress.child = current$$1); } function updateSimpleMemoComponent( - current, + current$$1, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime ) { - return null !== current && - shallowEqual(current.memoizedProps, nextProps) && - current.ref === workInProgress.ref && + return null !== current$$1 && + shallowEqual(current$$1.memoizedProps, nextProps) && + current$$1.ref === workInProgress.ref && ((didReceiveUpdate = !1), updateExpirationTime < renderExpirationTime) - ? ((workInProgress.expirationTime = current.expirationTime), - bailoutOnAlreadyFinishedWork( - current, + ? bailoutOnAlreadyFinishedWork( + current$$1, workInProgress, renderExpirationTime - )) + ) : updateFunctionComponent( - current, + current$$1, workInProgress, Component, nextProps, renderExpirationTime ); } -function markRef(current, workInProgress) { +function markRef(current$$1, workInProgress) { var ref = workInProgress.ref; if ( - (null === current && null !== ref) || - (null !== current && current.ref !== ref) + (null === current$$1 && null !== ref) || + (null !== current$$1 && current$$1.ref !== ref) ) workInProgress.effectTag |= 128; } function updateFunctionComponent( - current, + current$$1, workInProgress, Component, nextProps, @@ -3807,31 +3976,36 @@ function updateFunctionComponent( context = getMaskedContext(workInProgress, context); prepareToReadContext(workInProgress, renderExpirationTime); Component = renderWithHooks( - current, + current$$1, workInProgress, Component, nextProps, context, renderExpirationTime ); - if (null !== current && !didReceiveUpdate) + if (null !== current$$1 && !didReceiveUpdate) return ( - (workInProgress.updateQueue = current.updateQueue), + (workInProgress.updateQueue = current$$1.updateQueue), (workInProgress.effectTag &= -517), - current.expirationTime <= renderExpirationTime && - (current.expirationTime = 0), + current$$1.expirationTime <= renderExpirationTime && + (current$$1.expirationTime = 0), bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ) ); workInProgress.effectTag |= 1; - reconcileChildren(current, workInProgress, Component, renderExpirationTime); + reconcileChildren( + current$$1, + workInProgress, + Component, + renderExpirationTime + ); return workInProgress.child; } function updateClassComponent( - current, + current$$1, workInProgress, Component, nextProps, @@ -3843,11 +4017,16 @@ function updateClassComponent( } else hasContext = !1; prepareToReadContext(workInProgress, renderExpirationTime); if (null === workInProgress.stateNode) - null !== current && - ((current.alternate = null), + null !== current$$1 && + ((current$$1.alternate = null), (workInProgress.alternate = null), (workInProgress.effectTag |= 2)), - constructClassInstance(workInProgress, Component, nextProps), + constructClassInstance( + workInProgress, + Component, + nextProps, + renderExpirationTime + ), mountClassInstance( workInProgress, Component, @@ -3855,7 +4034,7 @@ function updateClassComponent( renderExpirationTime ), (nextProps = !0); - else if (null === current) { + else if (null === current$$1) { var instance = workInProgress.stateNode, oldProps = workInProgress.memoizedProps; instance.props = oldProps; @@ -3883,14 +4062,17 @@ function updateClassComponent( )); hasForceUpdate = !1; var oldState = workInProgress.memoizedState; - instance.state = oldState; - processUpdateQueue( - workInProgress, - nextProps, - instance, - renderExpirationTime - ); - oldContext = workInProgress.memoizedState; + oldContext = instance.state = oldState; + var updateQueue = workInProgress.updateQueue; + null !== updateQueue && + (processUpdateQueue( + workInProgress, + updateQueue, + nextProps, + instance, + renderExpirationTime + ), + (oldContext = workInProgress.memoizedState)); oldProps !== nextProps || oldState !== oldContext || didPerformWorkStackCursor.current || @@ -3936,7 +4118,6 @@ function updateClassComponent( (nextProps = !1)); } else (instance = workInProgress.stateNode), - cloneUpdateQueue(current, workInProgress), (oldProps = workInProgress.memoizedProps), (instance.props = workInProgress.type === workInProgress.elementType @@ -3965,14 +4146,17 @@ function updateClassComponent( )), (hasForceUpdate = !1), (oldContext = workInProgress.memoizedState), - (instance.state = oldContext), - processUpdateQueue( - workInProgress, - nextProps, - instance, - renderExpirationTime - ), - (oldState = workInProgress.memoizedState), + (oldState = instance.state = oldContext), + (updateQueue = workInProgress.updateQueue), + null !== updateQueue && + (processUpdateQueue( + workInProgress, + updateQueue, + nextProps, + instance, + renderExpirationTime + ), + (oldState = workInProgress.memoizedState)), oldProps !== nextProps || oldContext !== oldState || didPerformWorkStackCursor.current || @@ -4016,12 +4200,12 @@ function updateClassComponent( "function" === typeof instance.getSnapshotBeforeUpdate && (workInProgress.effectTag |= 256)) : ("function" !== typeof instance.componentDidUpdate || - (oldProps === current.memoizedProps && - oldContext === current.memoizedState) || + (oldProps === current$$1.memoizedProps && + oldContext === current$$1.memoizedState) || (workInProgress.effectTag |= 4), "function" !== typeof instance.getSnapshotBeforeUpdate || - (oldProps === current.memoizedProps && - oldContext === current.memoizedState) || + (oldProps === current$$1.memoizedProps && + oldContext === current$$1.memoizedState) || (workInProgress.effectTag |= 256), (workInProgress.memoizedProps = nextProps), (workInProgress.memoizedState = oldState)), @@ -4030,16 +4214,16 @@ function updateClassComponent( (instance.context = contextType), (nextProps = getDerivedStateFromProps)) : ("function" !== typeof instance.componentDidUpdate || - (oldProps === current.memoizedProps && - oldContext === current.memoizedState) || + (oldProps === current$$1.memoizedProps && + oldContext === current$$1.memoizedState) || (workInProgress.effectTag |= 4), "function" !== typeof instance.getSnapshotBeforeUpdate || - (oldProps === current.memoizedProps && - oldContext === current.memoizedState) || + (oldProps === current$$1.memoizedProps && + oldContext === current$$1.memoizedState) || (workInProgress.effectTag |= 256), (nextProps = !1)); return finishClassComponent( - current, + current$$1, workInProgress, Component, nextProps, @@ -4048,35 +4232,35 @@ function updateClassComponent( ); } function finishClassComponent( - current, + current$$1, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime ) { - markRef(current, workInProgress); + markRef(current$$1, workInProgress); var didCaptureError = 0 !== (workInProgress.effectTag & 64); if (!shouldUpdate && !didCaptureError) return ( hasContext && invalidateContextProvider(workInProgress, Component, !1), bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ) ); shouldUpdate = workInProgress.stateNode; - ReactCurrentOwner$1.current = workInProgress; + ReactCurrentOwner$3.current = workInProgress; var nextChildren = didCaptureError && "function" !== typeof Component.getDerivedStateFromError ? null : shouldUpdate.render(); workInProgress.effectTag |= 1; - null !== current && didCaptureError + null !== current$$1 && didCaptureError ? ((workInProgress.child = reconcileChildFibers( workInProgress, - current.child, + current$$1.child, null, renderExpirationTime )), @@ -4087,7 +4271,7 @@ function finishClassComponent( renderExpirationTime ))) : reconcileChildren( - current, + current$$1, workInProgress, nextChildren, renderExpirationTime @@ -4110,7 +4294,7 @@ function pushHostRootContext(workInProgress) { } var SUSPENDED_MARKER = { dehydrated: null, retryTime: 0 }; function updateSuspenseComponent( - current, + current$$1, workInProgress, renderExpirationTime ) { @@ -4122,30 +4306,32 @@ function updateSuspenseComponent( (JSCompiler_temp = 0 !== (workInProgress.effectTag & 64)) || (JSCompiler_temp = 0 !== (suspenseContext & 2) && - (null === current || null !== current.memoizedState)); + (null === current$$1 || null !== current$$1.memoizedState)); JSCompiler_temp ? ((nextDidTimeout = !0), (workInProgress.effectTag &= -65)) - : (null !== current && null === current.memoizedState) || + : (null !== current$$1 && null === current$$1.memoizedState) || void 0 === nextProps.fallback || !0 === nextProps.unstable_avoidThisFallback || (suspenseContext |= 1); - push(suspenseStackCursor, suspenseContext & 1); - if (null === current) { + push(suspenseStackCursor, suspenseContext & 1, workInProgress); + if (null === current$$1) { + void 0 !== nextProps.fallback && + tryToClaimNextHydratableInstance(workInProgress); if (nextDidTimeout) { nextDidTimeout = nextProps.fallback; nextProps = createFiberFromFragment(null, mode, 0, null); nextProps.return = workInProgress; if (0 === (workInProgress.mode & 2)) for ( - current = + current$$1 = null !== workInProgress.memoizedState ? workInProgress.child.child : workInProgress.child, - nextProps.child = current; - null !== current; + nextProps.child = current$$1; + null !== current$$1; ) - (current.return = nextProps), (current = current.sibling); + (current$$1.return = nextProps), (current$$1 = current$$1.sibling); renderExpirationTime = createFiberFromFragment( nextDidTimeout, mode, @@ -4167,14 +4353,15 @@ function updateSuspenseComponent( renderExpirationTime )); } - if (null !== current.memoizedState) { - current = current.child; - mode = current.sibling; + if (null !== current$$1.memoizedState) { + current$$1 = current$$1.child; + mode = current$$1.sibling; if (nextDidTimeout) { nextProps = nextProps.fallback; renderExpirationTime = createWorkInProgress( - current, - current.pendingProps + current$$1, + current$$1.pendingProps, + 0 ); renderExpirationTime.return = workInProgress; if ( @@ -4183,7 +4370,7 @@ function updateSuspenseComponent( null !== workInProgress.memoizedState ? workInProgress.child.child : workInProgress.child), - nextDidTimeout !== current.child) + nextDidTimeout !== current$$1.child) ) for ( renderExpirationTime.child = nextDidTimeout; @@ -4192,7 +4379,7 @@ function updateSuspenseComponent( ) (nextDidTimeout.return = renderExpirationTime), (nextDidTimeout = nextDidTimeout.sibling); - mode = createWorkInProgress(mode, nextProps); + mode = createWorkInProgress(mode, nextProps, mode.expirationTime); mode.return = workInProgress; renderExpirationTime.sibling = mode; renderExpirationTime.childExpirationTime = 0; @@ -4202,31 +4389,31 @@ function updateSuspenseComponent( } renderExpirationTime = reconcileChildFibers( workInProgress, - current.child, + current$$1.child, nextProps.children, renderExpirationTime ); workInProgress.memoizedState = null; return (workInProgress.child = renderExpirationTime); } - current = current.child; + current$$1 = current$$1.child; if (nextDidTimeout) { nextDidTimeout = nextProps.fallback; nextProps = createFiberFromFragment(null, mode, 0, null); nextProps.return = workInProgress; - nextProps.child = current; - null !== current && (current.return = nextProps); + nextProps.child = current$$1; + null !== current$$1 && (current$$1.return = nextProps); if (0 === (workInProgress.mode & 2)) for ( - current = + current$$1 = null !== workInProgress.memoizedState ? workInProgress.child.child : workInProgress.child, - nextProps.child = current; - null !== current; + nextProps.child = current$$1; + null !== current$$1; ) - (current.return = nextProps), (current = current.sibling); + (current$$1.return = nextProps), (current$$1 = current$$1.sibling); renderExpirationTime = createFiberFromFragment( nextDidTimeout, mode, @@ -4244,7 +4431,7 @@ function updateSuspenseComponent( workInProgress.memoizedState = null; return (workInProgress.child = reconcileChildFibers( workInProgress, - current, + current$$1, nextProps.children, renderExpirationTime )); @@ -4271,7 +4458,6 @@ function initSuspenseListRenderState( ? (workInProgress.memoizedState = { isBackwards: isBackwards, rendering: null, - renderingStartTime: 0, last: lastContentRow, tail: tail, tailExpiration: 0, @@ -4280,7 +4466,6 @@ function initSuspenseListRenderState( }) : ((renderState.isBackwards = isBackwards), (renderState.rendering = null), - (renderState.renderingStartTime = 0), (renderState.last = lastContentRow), (renderState.tail = tail), (renderState.tailExpiration = 0), @@ -4288,7 +4473,7 @@ function initSuspenseListRenderState( (renderState.lastEffect = lastEffectBeforeRendering)); } function updateSuspenseListComponent( - current, + current$$1, workInProgress, renderExpirationTime ) { @@ -4296,7 +4481,7 @@ function updateSuspenseListComponent( revealOrder = nextProps.revealOrder, tailMode = nextProps.tail; reconcileChildren( - current, + current$$1, workInProgress, nextProps.children, renderExpirationTime @@ -4305,39 +4490,42 @@ function updateSuspenseListComponent( if (0 !== (nextProps & 2)) (nextProps = (nextProps & 1) | 2), (workInProgress.effectTag |= 64); else { - if (null !== current && 0 !== (current.effectTag & 64)) - a: for (current = workInProgress.child; null !== current; ) { - if (13 === current.tag) - null !== current.memoizedState && - scheduleWorkOnFiber(current, renderExpirationTime); - else if (19 === current.tag) - scheduleWorkOnFiber(current, renderExpirationTime); - else if (null !== current.child) { - current.child.return = current; - current = current.child; + if (null !== current$$1 && 0 !== (current$$1.effectTag & 64)) + a: for (current$$1 = workInProgress.child; null !== current$$1; ) { + if (13 === current$$1.tag) + null !== current$$1.memoizedState && + scheduleWorkOnFiber(current$$1, renderExpirationTime); + else if (19 === current$$1.tag) + scheduleWorkOnFiber(current$$1, renderExpirationTime); + else if (null !== current$$1.child) { + current$$1.child.return = current$$1; + current$$1 = current$$1.child; continue; } - if (current === workInProgress) break a; - for (; null === current.sibling; ) { - if (null === current.return || current.return === workInProgress) + if (current$$1 === workInProgress) break a; + for (; null === current$$1.sibling; ) { + if ( + null === current$$1.return || + current$$1.return === workInProgress + ) break a; - current = current.return; + current$$1 = current$$1.return; } - current.sibling.return = current.return; - current = current.sibling; + current$$1.sibling.return = current$$1.return; + current$$1 = current$$1.sibling; } nextProps &= 1; } - push(suspenseStackCursor, nextProps); + push(suspenseStackCursor, nextProps, workInProgress); if (0 === (workInProgress.mode & 2)) workInProgress.memoizedState = null; else switch (revealOrder) { case "forwards": renderExpirationTime = workInProgress.child; for (revealOrder = null; null !== renderExpirationTime; ) - (current = renderExpirationTime.alternate), - null !== current && - null === findFirstSuspended(current) && + (current$$1 = renderExpirationTime.alternate), + null !== current$$1 && + null === findFirstSuspended(current$$1) && (revealOrder = renderExpirationTime), (renderExpirationTime = renderExpirationTime.sibling); renderExpirationTime = revealOrder; @@ -4359,15 +4547,15 @@ function updateSuspenseListComponent( renderExpirationTime = null; revealOrder = workInProgress.child; for (workInProgress.child = null; null !== revealOrder; ) { - current = revealOrder.alternate; - if (null !== current && null === findFirstSuspended(current)) { + current$$1 = revealOrder.alternate; + if (null !== current$$1 && null === findFirstSuspended(current$$1)) { workInProgress.child = revealOrder; break; } - current = revealOrder.sibling; + current$$1 = revealOrder.sibling; revealOrder.sibling = renderExpirationTime; renderExpirationTime = revealOrder; - revealOrder = current; + revealOrder = current$$1; } initSuspenseListRenderState( workInProgress, @@ -4394,29 +4582,35 @@ function updateSuspenseListComponent( return workInProgress.child; } function bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ) { - null !== current && (workInProgress.dependencies = current.dependencies); + null !== current$$1 && + (workInProgress.dependencies = current$$1.dependencies); var updateExpirationTime = workInProgress.expirationTime; 0 !== updateExpirationTime && markUnprocessedUpdateTime(updateExpirationTime); if (workInProgress.childExpirationTime < renderExpirationTime) return null; - if (null !== current && workInProgress.child !== current.child) + if (null !== current$$1 && workInProgress.child !== current$$1.child) throw Error("Resuming work not yet implemented."); if (null !== workInProgress.child) { - current = workInProgress.child; - renderExpirationTime = createWorkInProgress(current, current.pendingProps); + current$$1 = workInProgress.child; + renderExpirationTime = createWorkInProgress( + current$$1, + current$$1.pendingProps, + current$$1.expirationTime + ); workInProgress.child = renderExpirationTime; for ( renderExpirationTime.return = workInProgress; - null !== current.sibling; + null !== current$$1.sibling; ) - (current = current.sibling), + (current$$1 = current$$1.sibling), (renderExpirationTime = renderExpirationTime.sibling = createWorkInProgress( - current, - current.pendingProps + current$$1, + current$$1.pendingProps, + current$$1.expirationTime )), (renderExpirationTime.return = workInProgress); renderExpirationTime.sibling = null; @@ -4438,7 +4632,12 @@ appendAllChildren = function( var instance = node.stateNode; needsVisibilityToggle && isHidden && - (instance = cloneHiddenInstance(instance)); + (instance = cloneHiddenInstance( + instance, + node.type, + node.memoizedProps, + node + )); appendChildNode(parent.node, instance.node); } else if (6 === node.tag) { instance = node.stateNode; @@ -4491,7 +4690,12 @@ function appendAllChildrenToContainer( var instance = node.stateNode; needsVisibilityToggle && isHidden && - (instance = cloneHiddenInstance(instance)); + (instance = cloneHiddenInstance( + instance, + node.type, + node.memoizedProps, + node + )); appendChildNodeToSet(containerChildSet, instance.node); } else if (6 === node.tag) { instance = node.stateNode; @@ -4577,8 +4781,8 @@ updateHostComponent$1 = function(current, workInProgress, type, newProps) { ? cloneNodeWithNewProps(recyclableInstance, newProps) : cloneNode(recyclableInstance) : null !== newProps - ? cloneNodeWithNewChildrenAndProps(recyclableInstance, newProps) - : cloneNodeWithNewChildren(recyclableInstance), + ? cloneNodeWithNewChildrenAndProps(recyclableInstance, newProps) + : cloneNodeWithNewChildren(recyclableInstance), canonical: type.canonical }), (workInProgress.stateNode = type), @@ -4588,17 +4792,16 @@ updateHostComponent$1 = function(current, workInProgress, type, newProps) { } }; updateHostText$1 = function(current, workInProgress, oldText, newText) { - oldText !== newText - ? ((current = requiredContext(rootInstanceStackCursor.current)), - (oldText = requiredContext(contextStackCursor$1.current)), - (workInProgress.stateNode = createTextInstance( - newText, - current, - oldText, - workInProgress - )), - (workInProgress.effectTag |= 4)) - : (workInProgress.stateNode = current.stateNode); + oldText !== newText && + ((current = requiredContext(rootInstanceStackCursor.current)), + (oldText = requiredContext(contextStackCursor$1.current)), + (workInProgress.stateNode = createTextInstance( + newText, + current, + oldText, + workInProgress + )), + (workInProgress.effectTag |= 4)); }; function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { switch (renderState.tailMode) { @@ -4624,317 +4827,18 @@ function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { : (_lastTailNode.sibling = null); } } -function completeWork(current, workInProgress, renderExpirationTime) { - var newProps = workInProgress.pendingProps; - switch (workInProgress.tag) { - case 2: - case 16: - case 15: - case 0: - case 11: - case 7: - case 8: - case 12: - case 9: - case 14: - return null; - case 1: - return isContextProvider(workInProgress.type) && popContext(), null; - case 3: - return ( - popHostContainer(), - pop(didPerformWorkStackCursor), - pop(contextStackCursor), - (current = workInProgress.stateNode), - current.pendingContext && - ((current.context = current.pendingContext), - (current.pendingContext = null)), - updateHostContainer(workInProgress), - null - ); - case 5: - popHostContext(workInProgress); - var rootContainerInstance = requiredContext( - rootInstanceStackCursor.current - ); - renderExpirationTime = workInProgress.type; - if (null !== current && null != workInProgress.stateNode) - updateHostComponent$1( - current, - workInProgress, - renderExpirationTime, - newProps, - rootContainerInstance - ), - current.ref !== workInProgress.ref && - (workInProgress.effectTag |= 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." - ); - return null; - } - requiredContext(contextStackCursor$1.current); - current = nextReactTag; - nextReactTag += 2; - renderExpirationTime = getViewConfigForType(renderExpirationTime); - var updatePayload = diffProperties( - null, - emptyObject, - newProps, - renderExpirationTime.validAttributes - ); - rootContainerInstance = createNode( - current, - renderExpirationTime.uiViewClassName, - rootContainerInstance, - updatePayload, - workInProgress - ); - current = new ReactFabricHostComponent( - current, - renderExpirationTime, - newProps, - workInProgress - ); - current = { node: rootContainerInstance, canonical: current }; - appendAllChildren(current, workInProgress, !1, !1); - workInProgress.stateNode = current; - null !== workInProgress.ref && (workInProgress.effectTag |= 128); - } - return null; - case 6: - if (current && null != workInProgress.stateNode) - updateHostText$1( - current, - workInProgress, - current.memoizedProps, - newProps - ); - else { - if ("string" !== typeof newProps && null === workInProgress.stateNode) - throw Error( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." - ); - current = requiredContext(rootInstanceStackCursor.current); - rootContainerInstance = requiredContext(contextStackCursor$1.current); - workInProgress.stateNode = createTextInstance( - newProps, - current, - rootContainerInstance, - workInProgress - ); - } - return null; - case 13: - pop(suspenseStackCursor); - newProps = workInProgress.memoizedState; - if (0 !== (workInProgress.effectTag & 64)) - return ( - (workInProgress.expirationTime = renderExpirationTime), workInProgress - ); - newProps = null !== newProps; - rootContainerInstance = !1; - null !== current && - ((renderExpirationTime = current.memoizedState), - (rootContainerInstance = null !== renderExpirationTime), - newProps || - null === renderExpirationTime || - ((renderExpirationTime = current.child.sibling), - null !== renderExpirationTime && - ((updatePayload = workInProgress.firstEffect), - null !== updatePayload - ? ((workInProgress.firstEffect = renderExpirationTime), - (renderExpirationTime.nextEffect = updatePayload)) - : ((workInProgress.firstEffect = workInProgress.lastEffect = renderExpirationTime), - (renderExpirationTime.nextEffect = null)), - (renderExpirationTime.effectTag = 8)))); - if (newProps && !rootContainerInstance && 0 !== (workInProgress.mode & 2)) - if ( - (null === current && - !0 !== workInProgress.memoizedProps.unstable_avoidThisFallback) || - 0 !== (suspenseStackCursor.current & 1) - ) - workInProgressRootExitStatus === RootIncomplete && - (workInProgressRootExitStatus = RootSuspended); - else { - if ( - workInProgressRootExitStatus === RootIncomplete || - workInProgressRootExitStatus === RootSuspended - ) - workInProgressRootExitStatus = RootSuspendedWithDelay; - 0 !== workInProgressRootNextUnprocessedUpdateTime && - null !== workInProgressRoot && - (markRootSuspendedAtTime( - workInProgressRoot, - renderExpirationTime$1 - ), - markRootUpdatedAtTime( - workInProgressRoot, - workInProgressRootNextUnprocessedUpdateTime - )); - } - newProps && (workInProgress.effectTag |= 4); - return null; - case 4: - return popHostContainer(), updateHostContainer(workInProgress), null; - case 10: - return popProvider(workInProgress), null; - case 17: - return isContextProvider(workInProgress.type) && popContext(), null; - case 19: - pop(suspenseStackCursor); - newProps = workInProgress.memoizedState; - if (null === newProps) return null; - rootContainerInstance = 0 !== (workInProgress.effectTag & 64); - updatePayload = newProps.rendering; - if (null === updatePayload) - if (rootContainerInstance) cutOffTailIfNeeded(newProps, !1); - else { - if ( - workInProgressRootExitStatus !== RootIncomplete || - (null !== current && 0 !== (current.effectTag & 64)) - ) - for (current = workInProgress.child; null !== current; ) { - updatePayload = findFirstSuspended(current); - if (null !== updatePayload) { - workInProgress.effectTag |= 64; - cutOffTailIfNeeded(newProps, !1); - current = updatePayload.updateQueue; - null !== current && - ((workInProgress.updateQueue = current), - (workInProgress.effectTag |= 4)); - null === newProps.lastEffect && - (workInProgress.firstEffect = null); - workInProgress.lastEffect = newProps.lastEffect; - current = renderExpirationTime; - for (newProps = workInProgress.child; null !== newProps; ) - (rootContainerInstance = newProps), - (renderExpirationTime = current), - (rootContainerInstance.effectTag &= 2), - (rootContainerInstance.nextEffect = null), - (rootContainerInstance.firstEffect = null), - (rootContainerInstance.lastEffect = null), - (updatePayload = rootContainerInstance.alternate), - null === updatePayload - ? ((rootContainerInstance.childExpirationTime = 0), - (rootContainerInstance.expirationTime = renderExpirationTime), - (rootContainerInstance.child = null), - (rootContainerInstance.memoizedProps = null), - (rootContainerInstance.memoizedState = null), - (rootContainerInstance.updateQueue = null), - (rootContainerInstance.dependencies = null)) - : ((rootContainerInstance.childExpirationTime = - updatePayload.childExpirationTime), - (rootContainerInstance.expirationTime = - updatePayload.expirationTime), - (rootContainerInstance.child = updatePayload.child), - (rootContainerInstance.memoizedProps = - updatePayload.memoizedProps), - (rootContainerInstance.memoizedState = - updatePayload.memoizedState), - (rootContainerInstance.updateQueue = - updatePayload.updateQueue), - (renderExpirationTime = updatePayload.dependencies), - (rootContainerInstance.dependencies = - null === renderExpirationTime - ? null - : { - expirationTime: - renderExpirationTime.expirationTime, - firstContext: renderExpirationTime.firstContext, - responders: renderExpirationTime.responders - })), - (newProps = newProps.sibling); - push( - suspenseStackCursor, - (suspenseStackCursor.current & 1) | 2 - ); - return workInProgress.child; - } - current = current.sibling; - } - } - else { - if (!rootContainerInstance) - if ( - ((current = findFirstSuspended(updatePayload)), null !== current) - ) { - if ( - ((workInProgress.effectTag |= 64), - (rootContainerInstance = !0), - (current = current.updateQueue), - null !== current && - ((workInProgress.updateQueue = current), - (workInProgress.effectTag |= 4)), - cutOffTailIfNeeded(newProps, !0), - null === newProps.tail && - "hidden" === newProps.tailMode && - !updatePayload.alternate) - ) - return ( - (workInProgress = workInProgress.lastEffect = - newProps.lastEffect), - null !== workInProgress && (workInProgress.nextEffect = null), - null - ); - } else - 2 * now() - newProps.renderingStartTime > newProps.tailExpiration && - 1 < renderExpirationTime && - ((workInProgress.effectTag |= 64), - (rootContainerInstance = !0), - cutOffTailIfNeeded(newProps, !1), - (workInProgress.expirationTime = workInProgress.childExpirationTime = - renderExpirationTime - 1)); - newProps.isBackwards - ? ((updatePayload.sibling = workInProgress.child), - (workInProgress.child = updatePayload)) - : ((current = newProps.last), - null !== current - ? (current.sibling = updatePayload) - : (workInProgress.child = updatePayload), - (newProps.last = updatePayload)); - } - return null !== newProps.tail - ? (0 === newProps.tailExpiration && - (newProps.tailExpiration = now() + 500), - (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; - } - 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) { switch (workInProgress.tag) { case 1: - isContextProvider(workInProgress.type) && popContext(); + isContextProvider(workInProgress.type) && popContext(workInProgress); var effectTag = workInProgress.effectTag; return effectTag & 4096 ? ((workInProgress.effectTag = (effectTag & -4097) | 64), workInProgress) : null; case 3: - popHostContainer(); - pop(didPerformWorkStackCursor); - pop(contextStackCursor); + popHostContainer(workInProgress); + popTopLevelContextObject(workInProgress); effectTag = workInProgress.effectTag; if (0 !== (effectTag & 64)) throw Error( @@ -4946,7 +4850,7 @@ function unwindWork(workInProgress) { return popHostContext(workInProgress), null; case 13: return ( - pop(suspenseStackCursor), + pop(suspenseStackCursor, workInProgress), (effectTag = workInProgress.effectTag), effectTag & 4096 ? ((workInProgress.effectTag = (effectTag & -4097) | 64), @@ -4954,9 +4858,9 @@ function unwindWork(workInProgress) { : null ); case 19: - return pop(suspenseStackCursor), null; + return pop(suspenseStackCursor, workInProgress), null; case 4: - return popHostContainer(), null; + return popHostContainer(workInProgress), null; case 10: return popProvider(workInProgress), null; default: @@ -5013,180 +4917,102 @@ function logError(boundary, errorInfo) { }); } } -function safelyCallComponentWillUnmount(current, instance) { +function safelyCallComponentWillUnmount(current$$1, instance) { try { - (instance.props = current.memoizedProps), - (instance.state = current.memoizedState), + (instance.props = current$$1.memoizedProps), + (instance.state = current$$1.memoizedState), instance.componentWillUnmount(); } catch (unmountError) { - captureCommitPhaseError(current, unmountError); + captureCommitPhaseError(current$$1, unmountError); } } -function safelyDetachRef(current) { - var ref = current.ref; +function safelyDetachRef(current$$1) { + var ref = current$$1.ref; if (null !== ref) if ("function" === typeof ref) try { ref(null); } catch (refError) { - captureCommitPhaseError(current, refError); + captureCommitPhaseError(current$$1, refError); } else ref.current = null; } -function commitBeforeMutationLifeCycles(current, finishedWork) { +function commitBeforeMutationLifeCycles(current$$1, finishedWork) { switch (finishedWork.tag) { case 0: case 11: case 15: - case 22: - return; + commitHookEffectList(2, 0, finishedWork); + break; case 1: - if (finishedWork.effectTag & 256 && null !== current) { - var prevProps = current.memoizedProps, - prevState = current.memoizedState; - current = finishedWork.stateNode; - finishedWork = current.getSnapshotBeforeUpdate( + if (finishedWork.effectTag & 256 && null !== current$$1) { + var prevProps = current$$1.memoizedProps, + prevState = current$$1.memoizedState; + current$$1 = finishedWork.stateNode; + finishedWork = current$$1.getSnapshotBeforeUpdate( finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState ); - current.__reactInternalSnapshotBeforeUpdate = finishedWork; + current$$1.__reactInternalSnapshotBeforeUpdate = finishedWork; } - return; + break; case 3: case 5: case 6: case 4: case 17: - return; + 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." + ); } - 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(tag, finishedWork) { +function commitHookEffectList(unmountTag, mountTag, finishedWork) { finishedWork = finishedWork.updateQueue; finishedWork = null !== finishedWork ? finishedWork.lastEffect : null; if (null !== finishedWork) { var effect = (finishedWork = finishedWork.next); do { - if ((effect.tag & tag) === tag) { + if (0 !== (effect.tag & unmountTag)) { var destroy = effect.destroy; effect.destroy = void 0; void 0 !== destroy && destroy(); } + 0 !== (effect.tag & mountTag) && + ((destroy = effect.create), (effect.destroy = destroy())); effect = effect.next; } while (effect !== finishedWork); } } -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 = effect.create; - effect.destroy = create(); - } - effect = effect.next; - } while (effect !== finishedWork); - } -} -function commitLifeCycles(finishedRoot, current, finishedWork) { - switch (finishedWork.tag) { - case 0: - case 11: - case 15: - case 22: - commitHookEffectListMount(3, finishedWork); - return; - case 1: - finishedRoot = finishedWork.stateNode; - if (finishedWork.effectTag & 4) - if (null === current) finishedRoot.componentDidMount(); - else { - var prevProps = - finishedWork.elementType === finishedWork.type - ? current.memoizedProps - : resolveDefaultProps(finishedWork.type, current.memoizedProps); - finishedRoot.componentDidUpdate( - prevProps, - 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); - } - return; - case 5: - if (null === current && finishedWork.effectTag & 4) - throw Error( - "The current renderer does not support mutation. This error is likely caused by a bug in React. Please file an issue." - ); - return; - case 6: - return; - case 4: - return; - case 12: - return; - case 13: - return; - case 19: - case 17: - case 20: - case 21: - 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 commitUnmount(finishedRoot, current$jscomp$0, renderPriorityLevel) { +function commitUnmount(finishedRoot, current$$1$jscomp$0, renderPriorityLevel) { "function" === typeof onCommitFiberUnmount && - onCommitFiberUnmount(current$jscomp$0); - switch (current$jscomp$0.tag) { + onCommitFiberUnmount(current$$1$jscomp$0); + switch (current$$1$jscomp$0.tag) { case 0: case 11: case 14: case 15: - case 22: - finishedRoot = current$jscomp$0.updateQueue; + finishedRoot = current$$1$jscomp$0.updateQueue; if ( null !== finishedRoot && ((finishedRoot = finishedRoot.lastEffect), null !== finishedRoot) ) { var firstEffect = finishedRoot.next; - runWithPriority( + runWithPriority$1( 97 < renderPriorityLevel ? 97 : renderPriorityLevel, function() { var effect = firstEffect; do { - var _destroy = effect.destroy; - if (void 0 !== _destroy) { - var current = current$jscomp$0; + var destroy = effect.destroy; + if (void 0 !== destroy) { + var current$$1 = current$$1$jscomp$0; try { - _destroy(); + destroy(); } catch (error) { - captureCommitPhaseError(current, error); + captureCommitPhaseError(current$$1, error); } } effect = effect.next; @@ -5196,41 +5022,42 @@ function commitUnmount(finishedRoot, current$jscomp$0, renderPriorityLevel) { } break; case 1: - safelyDetachRef(current$jscomp$0); - renderPriorityLevel = current$jscomp$0.stateNode; + safelyDetachRef(current$$1$jscomp$0); + renderPriorityLevel = current$$1$jscomp$0.stateNode; "function" === typeof renderPriorityLevel.componentWillUnmount && - safelyCallComponentWillUnmount(current$jscomp$0, renderPriorityLevel); + safelyCallComponentWillUnmount( + current$$1$jscomp$0, + renderPriorityLevel + ); break; case 5: - safelyDetachRef(current$jscomp$0); + safelyDetachRef(current$$1$jscomp$0); break; case 4: - createChildNodeSet(current$jscomp$0.stateNode.containerInfo); + createChildNodeSet(current$$1$jscomp$0.stateNode.containerInfo); } } -function detachFiber(current) { - var alternate = current.alternate; - current.return = null; - current.child = null; - current.memoizedState = null; - current.updateQueue = null; - current.dependencies = null; - current.alternate = null; - current.firstEffect = null; - current.lastEffect = null; - current.pendingProps = null; - current.memoizedProps = null; - current.stateNode = null; +function detachFiber(current$$1) { + var alternate = current$$1.alternate; + current$$1.return = null; + current$$1.child = null; + current$$1.memoizedState = null; + current$$1.updateQueue = null; + current$$1.dependencies = null; + current$$1.alternate = null; + current$$1.firstEffect = null; + current$$1.lastEffect = null; + current$$1.pendingProps = null; + current$$1.memoizedProps = null; null !== alternate && detachFiber(alternate); } -function commitWork(current, finishedWork) { +function commitWork(current$$1, finishedWork) { switch (finishedWork.tag) { case 0: case 11: case 14: case 15: - case 22: - commitHookEffectListUnmount(3, finishedWork); + commitHookEffectList(4, 8, finishedWork); return; case 12: return; @@ -5243,20 +5070,19 @@ function commitWork(current, finishedWork) { attachSuspenseRetryListeners(finishedWork); return; } - a: { - switch (finishedWork.tag) { - 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." - ); + a: switch (finishedWork.tag) { + case 1: + case 5: + case 6: + case 20: + break a; + case 3: + case 4: + break a; + 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." + ); } } function attachSuspenseRetryListeners(finishedWork) { @@ -5313,7 +5139,7 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { return expirationTime; } var ceil = Math.ceil, - ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, + ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, NoContext = 0, LegacyUnbatchedContext = 8, @@ -5328,7 +5154,7 @@ var ceil = Math.ceil, executionContext = NoContext, workInProgressRoot = null, workInProgress = null, - renderExpirationTime$1 = 0, + renderExpirationTime = 0, workInProgressRootExitStatus = RootIncomplete, workInProgressRootFatalError = null, workInProgressRootLatestProcessedExpirationTime = 1073741823, @@ -5353,8 +5179,8 @@ function requestCurrentTimeForUpdate() { return (executionContext & (RenderContext | CommitContext)) !== NoContext ? 1073741821 - ((now() / 10) | 0) : 0 !== currentEventTime - ? currentEventTime - : (currentEventTime = 1073741821 - ((now() / 10) | 0)); + ? currentEventTime + : (currentEventTime = 1073741821 - ((now() / 10) | 0)); } function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { fiber = fiber.mode; @@ -5362,7 +5188,7 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { var priorityLevel = getCurrentPriorityLevel(); if (0 === (fiber & 4)) return 99 === priorityLevel ? 1073741823 : 1073741822; if ((executionContext & RenderContext) !== NoContext) - return renderExpirationTime$1; + return renderExpirationTime; if (null !== suspenseConfig) currentTime = 1073741821 - @@ -5394,11 +5220,11 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { throw Error("Expected a valid priority level"); } null !== workInProgressRoot && - currentTime === renderExpirationTime$1 && + currentTime === renderExpirationTime && --currentTime; return currentTime; } -function scheduleWork(fiber, expirationTime) { +function scheduleUpdateOnFiber(fiber, expirationTime) { if (50 < nestedUpdateCount) throw ((nestedUpdateCount = 0), (rootWithNestedUpdates = null), @@ -5452,7 +5278,7 @@ function markUpdateTimeFromFiberToRoot(fiber, expirationTime) { (workInProgressRoot === root && (markUnprocessedUpdateTime(expirationTime), workInProgressRootExitStatus === RootSuspendedWithDelay && - markRootSuspendedAtTime(root, renderExpirationTime$1)), + markRootSuspendedAtTime(root, renderExpirationTime)), markRootUpdatedAtTime(root, expirationTime)); return root; } @@ -5461,10 +5287,9 @@ function getNextRootExpirationTimeToWorkOn(root) { if (0 !== lastExpiredTime) return lastExpiredTime; lastExpiredTime = root.firstPendingTime; if (!isRootSuspendedAtTime(root, lastExpiredTime)) return lastExpiredTime; - var lastPingedTime = root.lastPingedTime; + lastExpiredTime = root.lastPingedTime; root = root.nextKnownPendingLevel; - root = lastPingedTime > root ? lastPingedTime : root; - return 2 >= root && lastExpiredTime !== root ? 0 : root; + return lastExpiredTime > root ? lastExpiredTime : root; } function ensureRootIsScheduled(root) { if (0 !== root.lastExpiredTime) @@ -5486,18 +5311,18 @@ function ensureRootIsScheduled(root) { 1073741823 === expirationTime ? (priorityLevel = 99) : 1 === expirationTime || 2 === expirationTime - ? (priorityLevel = 95) - : ((priorityLevel = - 10 * (1073741821 - expirationTime) - - 10 * (1073741821 - priorityLevel)), - (priorityLevel = - 0 >= priorityLevel - ? 99 - : 250 >= priorityLevel - ? 98 - : 5250 >= priorityLevel - ? 97 - : 95)); + ? (priorityLevel = 95) + : ((priorityLevel = + 10 * (1073741821 - expirationTime) - + 10 * (1073741821 - priorityLevel)), + (priorityLevel = + 0 >= priorityLevel + ? 99 + : 250 >= priorityLevel + ? 98 + : 5250 >= priorityLevel + ? 97 + : 95)); if (null !== existingCallbackNode) { var existingCallbackPriority = root.callbackPriority; if ( @@ -5524,225 +5349,264 @@ function ensureRootIsScheduled(root) { } function performConcurrentWorkOnRoot(root, didTimeout) { currentEventTime = 0; - if (didTimeout) { - didTimeout = requestCurrentTimeForUpdate(); - var lastExpiredTime = root.lastExpiredTime; - if (0 === lastExpiredTime || lastExpiredTime > didTimeout) - root.lastExpiredTime = didTimeout; - ensureRootIsScheduled(root); - return null; - } - lastExpiredTime = getNextRootExpirationTimeToWorkOn(root); - if (0 === lastExpiredTime) return null; - didTimeout = root.callbackNode; - if ((executionContext & (RenderContext | CommitContext)) !== NoContext) - throw Error("Should not already be working."); - flushPassiveEffects(); - var expirationTime = lastExpiredTime; - var exitStatus = executionContext; - executionContext |= RenderContext; - var prevDispatcher = pushDispatcher(); - (root === workInProgressRoot && expirationTime === renderExpirationTime$1) || - prepareFreshStack(root, expirationTime); - do - try { - workLoopConcurrent(); - break; - } catch (thrownValue) { - handleError(root, thrownValue); - } - while (1); - resetContextDependencies(); - ReactCurrentDispatcher$1.current = prevDispatcher; - executionContext = exitStatus; - null !== workInProgress - ? (exitStatus = RootIncomplete) - : ((workInProgressRoot = null), - (exitStatus = workInProgressRootExitStatus)); - if (exitStatus !== RootIncomplete) { - exitStatus === RootErrored && - ((lastExpiredTime = 2 < lastExpiredTime ? 2 : lastExpiredTime), - (exitStatus = renderRootSync(root, lastExpiredTime))); - if (exitStatus === RootFatalErrored) - throw ((didTimeout = workInProgressRootFatalError), - prepareFreshStack(root, lastExpiredTime), - markRootSuspendedAtTime(root, lastExpiredTime), + if (didTimeout) + return ( + (didTimeout = requestCurrentTimeForUpdate()), + markRootExpiredAtTime(root, didTimeout), ensureRootIsScheduled(root), - didTimeout); - expirationTime = root.finishedWork = root.current.alternate; - root.finishedExpirationTime = lastExpiredTime; - switch (exitStatus) { - case RootIncomplete: - case RootFatalErrored: - throw Error("Root did not complete. This is a bug in React."); - case RootErrored: - commitRoot(root); - break; - case RootSuspended: - markRootSuspendedAtTime(root, lastExpiredTime); - exitStatus = root.lastSuspendedTime; - lastExpiredTime === exitStatus && - (root.nextKnownPendingLevel = getRemainingExpirationTime( - expirationTime - )); - if ( - 1073741823 === workInProgressRootLatestProcessedExpirationTime && - ((expirationTime = - globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now()), - 10 < expirationTime) - ) { - if ( - workInProgressRootHasPendingPing && - ((prevDispatcher = root.lastPingedTime), - 0 === prevDispatcher || prevDispatcher >= lastExpiredTime) - ) { - root.lastPingedTime = lastExpiredTime; - prepareFreshStack(root, lastExpiredTime); - break; - } - prevDispatcher = getNextRootExpirationTimeToWorkOn(root); - if (0 !== prevDispatcher && prevDispatcher !== lastExpiredTime) break; - if (0 !== exitStatus && exitStatus !== lastExpiredTime) { - root.lastPingedTime = exitStatus; - break; - } - root.timeoutHandle = scheduleTimeout( - commitRoot.bind(null, root), - expirationTime - ); - break; - } - commitRoot(root); - break; - case RootSuspendedWithDelay: - markRootSuspendedAtTime(root, lastExpiredTime); - exitStatus = root.lastSuspendedTime; - lastExpiredTime === exitStatus && - (root.nextKnownPendingLevel = getRemainingExpirationTime( - expirationTime - )); - if ( - workInProgressRootHasPendingPing && - ((expirationTime = root.lastPingedTime), - 0 === expirationTime || expirationTime >= lastExpiredTime) - ) { - root.lastPingedTime = lastExpiredTime; - prepareFreshStack(root, lastExpiredTime); - break; - } - expirationTime = getNextRootExpirationTimeToWorkOn(root); - if (0 !== expirationTime && expirationTime !== lastExpiredTime) break; - if (0 !== exitStatus && exitStatus !== lastExpiredTime) { - root.lastPingedTime = exitStatus; - break; - } - 1073741823 !== workInProgressRootLatestSuspenseTimeout - ? (expirationTime = - 10 * (1073741821 - workInProgressRootLatestSuspenseTimeout) - - now()) - : 1073741823 === workInProgressRootLatestProcessedExpirationTime - ? (expirationTime = 0) - : ((expirationTime = - 10 * - (1073741821 - workInProgressRootLatestProcessedExpirationTime) - - 5e3), - (exitStatus = now()), - (lastExpiredTime = - 10 * (1073741821 - lastExpiredTime) - exitStatus), - (expirationTime = exitStatus - expirationTime), - 0 > expirationTime && (expirationTime = 0), - (expirationTime = - (120 > expirationTime - ? 120 - : 480 > expirationTime - ? 480 - : 1080 > expirationTime - ? 1080 - : 1920 > expirationTime - ? 1920 - : 3e3 > expirationTime - ? 3e3 - : 4320 > expirationTime - ? 4320 - : 1960 * ceil(expirationTime / 1960)) - expirationTime), - lastExpiredTime < expirationTime && - (expirationTime = lastExpiredTime)); - if (10 < expirationTime) { - root.timeoutHandle = scheduleTimeout( - commitRoot.bind(null, root), - expirationTime - ); + null + ); + var expirationTime = getNextRootExpirationTimeToWorkOn(root); + if (0 !== expirationTime) { + didTimeout = root.callbackNode; + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) + throw Error("Should not already be working."); + flushPassiveEffects(); + (root === workInProgressRoot && expirationTime === renderExpirationTime) || + prepareFreshStack(root, expirationTime); + if (null !== workInProgress) { + var prevExecutionContext = executionContext; + executionContext |= RenderContext; + var prevDispatcher = pushDispatcher(root); + do + try { + workLoopConcurrent(); break; + } catch (thrownValue) { + handleError(root, thrownValue); } - commitRoot(root); - break; - case RootCompleted: - if ( - 1073741823 !== workInProgressRootLatestProcessedExpirationTime && - null !== workInProgressRootCanSuspendUsingConfig + while (1); + resetContextDependencies(); + executionContext = prevExecutionContext; + ReactCurrentDispatcher.current = prevDispatcher; + if (workInProgressRootExitStatus === RootFatalErrored) + throw ((didTimeout = workInProgressRootFatalError), + prepareFreshStack(root, expirationTime), + markRootSuspendedAtTime(root, expirationTime), + ensureRootIsScheduled(root), + didTimeout); + if (null === workInProgress) + switch ( + ((prevDispatcher = root.finishedWork = root.current.alternate), + (root.finishedExpirationTime = expirationTime), + (prevExecutionContext = workInProgressRootExitStatus), + (workInProgressRoot = null), + prevExecutionContext) ) { - prevDispatcher = workInProgressRootLatestProcessedExpirationTime; - var suspenseConfig = workInProgressRootCanSuspendUsingConfig; - expirationTime = suspenseConfig.busyMinDurationMs | 0; - 0 >= expirationTime - ? (expirationTime = 0) - : ((exitStatus = suspenseConfig.busyDelayMs | 0), - (prevDispatcher = - now() - - (10 * (1073741821 - prevDispatcher) - - (suspenseConfig.timeoutMs | 0 || 5e3))), - (expirationTime = - prevDispatcher <= exitStatus - ? 0 - : exitStatus + expirationTime - prevDispatcher)); - if (10 < expirationTime) { - markRootSuspendedAtTime(root, lastExpiredTime); - root.timeoutHandle = scheduleTimeout( - commitRoot.bind(null, root), - expirationTime + case RootIncomplete: + case RootFatalErrored: + throw Error("Root did not complete. This is a bug in React."); + case RootErrored: + markRootExpiredAtTime( + root, + 2 < expirationTime ? 2 : expirationTime ); break; - } + case RootSuspended: + markRootSuspendedAtTime(root, expirationTime); + prevExecutionContext = root.lastSuspendedTime; + expirationTime === prevExecutionContext && + (root.nextKnownPendingLevel = getRemainingExpirationTime( + prevDispatcher + )); + if ( + 1073741823 === workInProgressRootLatestProcessedExpirationTime && + ((prevDispatcher = + globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now()), + 10 < prevDispatcher) + ) { + if (workInProgressRootHasPendingPing) { + var lastPingedTime = root.lastPingedTime; + if (0 === lastPingedTime || lastPingedTime >= expirationTime) { + root.lastPingedTime = expirationTime; + prepareFreshStack(root, expirationTime); + break; + } + } + lastPingedTime = getNextRootExpirationTimeToWorkOn(root); + if (0 !== lastPingedTime && lastPingedTime !== expirationTime) + break; + if ( + 0 !== prevExecutionContext && + prevExecutionContext !== expirationTime + ) { + root.lastPingedTime = prevExecutionContext; + break; + } + root.timeoutHandle = scheduleTimeout( + commitRoot.bind(null, root), + prevDispatcher + ); + break; + } + commitRoot(root); + break; + case RootSuspendedWithDelay: + markRootSuspendedAtTime(root, expirationTime); + prevExecutionContext = root.lastSuspendedTime; + expirationTime === prevExecutionContext && + (root.nextKnownPendingLevel = getRemainingExpirationTime( + prevDispatcher + )); + if ( + workInProgressRootHasPendingPing && + ((prevDispatcher = root.lastPingedTime), + 0 === prevDispatcher || prevDispatcher >= expirationTime) + ) { + root.lastPingedTime = expirationTime; + prepareFreshStack(root, expirationTime); + break; + } + prevDispatcher = getNextRootExpirationTimeToWorkOn(root); + if (0 !== prevDispatcher && prevDispatcher !== expirationTime) + break; + if ( + 0 !== prevExecutionContext && + prevExecutionContext !== expirationTime + ) { + root.lastPingedTime = prevExecutionContext; + break; + } + 1073741823 !== workInProgressRootLatestSuspenseTimeout + ? (prevExecutionContext = + 10 * (1073741821 - workInProgressRootLatestSuspenseTimeout) - + now()) + : 1073741823 === workInProgressRootLatestProcessedExpirationTime + ? (prevExecutionContext = 0) + : ((prevExecutionContext = + 10 * + (1073741821 - + workInProgressRootLatestProcessedExpirationTime) - + 5e3), + (prevDispatcher = now()), + (expirationTime = + 10 * (1073741821 - expirationTime) - prevDispatcher), + (prevExecutionContext = + prevDispatcher - prevExecutionContext), + 0 > prevExecutionContext && (prevExecutionContext = 0), + (prevExecutionContext = + (120 > prevExecutionContext + ? 120 + : 480 > prevExecutionContext + ? 480 + : 1080 > prevExecutionContext + ? 1080 + : 1920 > prevExecutionContext + ? 1920 + : 3e3 > prevExecutionContext + ? 3e3 + : 4320 > prevExecutionContext + ? 4320 + : 1960 * ceil(prevExecutionContext / 1960)) - + prevExecutionContext), + expirationTime < prevExecutionContext && + (prevExecutionContext = expirationTime)); + if (10 < prevExecutionContext) { + root.timeoutHandle = scheduleTimeout( + commitRoot.bind(null, root), + prevExecutionContext + ); + break; + } + commitRoot(root); + break; + case RootCompleted: + if ( + 1073741823 !== workInProgressRootLatestProcessedExpirationTime && + null !== workInProgressRootCanSuspendUsingConfig + ) { + lastPingedTime = workInProgressRootLatestProcessedExpirationTime; + var suspenseConfig = workInProgressRootCanSuspendUsingConfig; + prevExecutionContext = suspenseConfig.busyMinDurationMs | 0; + 0 >= prevExecutionContext + ? (prevExecutionContext = 0) + : ((prevDispatcher = suspenseConfig.busyDelayMs | 0), + (lastPingedTime = + now() - + (10 * (1073741821 - lastPingedTime) - + (suspenseConfig.timeoutMs | 0 || 5e3))), + (prevExecutionContext = + lastPingedTime <= prevDispatcher + ? 0 + : prevDispatcher + + prevExecutionContext - + lastPingedTime)); + if (10 < prevExecutionContext) { + markRootSuspendedAtTime(root, expirationTime); + root.timeoutHandle = scheduleTimeout( + commitRoot.bind(null, root), + prevExecutionContext + ); + break; + } + } + commitRoot(root); + break; + default: + throw Error("Unknown root exit status."); } - commitRoot(root); - break; - default: - throw Error("Unknown root exit status."); + ensureRootIsScheduled(root); + if (root.callbackNode === didTimeout) + return performConcurrentWorkOnRoot.bind(null, root); } } - ensureRootIsScheduled(root); - return root.callbackNode === didTimeout - ? performConcurrentWorkOnRoot.bind(null, root) - : null; + return null; } function performSyncWorkOnRoot(root) { - if ((executionContext & (RenderContext | CommitContext)) !== NoContext) - throw Error("Should not already be working."); - flushPassiveEffects(); var lastExpiredTime = root.lastExpiredTime; - lastExpiredTime = - 0 !== lastExpiredTime - ? root === workInProgressRoot && renderExpirationTime$1 >= lastExpiredTime - ? renderExpirationTime$1 - : lastExpiredTime - : 1073741823; - var exitStatus = renderRootSync(root, lastExpiredTime); - 0 !== root.tag && - exitStatus === RootErrored && - ((lastExpiredTime = 2 < lastExpiredTime ? 2 : lastExpiredTime), - (exitStatus = renderRootSync(root, lastExpiredTime))); - if (exitStatus === RootFatalErrored) - throw ((exitStatus = workInProgressRootFatalError), - prepareFreshStack(root, lastExpiredTime), - markRootSuspendedAtTime(root, lastExpiredTime), - ensureRootIsScheduled(root), - exitStatus); - root.finishedWork = root.current.alternate; - root.finishedExpirationTime = lastExpiredTime; - commitRoot(root); - ensureRootIsScheduled(root); + lastExpiredTime = 0 !== lastExpiredTime ? lastExpiredTime : 1073741823; + if (root.finishedExpirationTime === lastExpiredTime) commitRoot(root); + else { + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) + throw Error("Should not already be working."); + flushPassiveEffects(); + (root === workInProgressRoot && lastExpiredTime === renderExpirationTime) || + prepareFreshStack(root, lastExpiredTime); + if (null !== workInProgress) { + var prevExecutionContext = executionContext; + executionContext |= RenderContext; + var prevDispatcher = pushDispatcher(root); + do + try { + workLoopSync(); + break; + } catch (thrownValue) { + handleError(root, thrownValue); + } + while (1); + resetContextDependencies(); + executionContext = prevExecutionContext; + ReactCurrentDispatcher.current = prevDispatcher; + if (workInProgressRootExitStatus === RootFatalErrored) + throw ((prevExecutionContext = workInProgressRootFatalError), + prepareFreshStack(root, lastExpiredTime), + markRootSuspendedAtTime(root, lastExpiredTime), + ensureRootIsScheduled(root), + prevExecutionContext); + if (null !== workInProgress) + throw Error( + "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." + ); + root.finishedWork = root.current.alternate; + root.finishedExpirationTime = lastExpiredTime; + workInProgressRoot = null; + commitRoot(root); + ensureRootIsScheduled(root); + } + } return null; } +function flushPendingDiscreteUpdates() { + if (null !== rootsWithPendingDiscreteUpdates) { + var roots = rootsWithPendingDiscreteUpdates; + rootsWithPendingDiscreteUpdates = null; + roots.forEach(function(expirationTime, root) { + markRootExpiredAtTime(root, expirationTime); + ensureRootIsScheduled(root); + }); + flushSyncCallbackQueue(); + } +} function prepareFreshStack(root, expirationTime) { root.finishedWork = null; root.finishedExpirationTime = 0; @@ -5754,27 +5618,26 @@ function prepareFreshStack(root, expirationTime) { var interruptedWork = timeoutHandle; switch (interruptedWork.tag) { case 1: - interruptedWork = interruptedWork.type.childContextTypes; - null !== interruptedWork && - void 0 !== interruptedWork && - popContext(); + var childContextTypes = interruptedWork.type.childContextTypes; + null !== childContextTypes && + void 0 !== childContextTypes && + popContext(interruptedWork); break; case 3: - popHostContainer(); - pop(didPerformWorkStackCursor); - pop(contextStackCursor); + popHostContainer(interruptedWork); + popTopLevelContextObject(interruptedWork); break; case 5: popHostContext(interruptedWork); break; case 4: - popHostContainer(); + popHostContainer(interruptedWork); break; case 13: - pop(suspenseStackCursor); + pop(suspenseStackCursor, interruptedWork); break; case 19: - pop(suspenseStackCursor); + pop(suspenseStackCursor, interruptedWork); break; case 10: popProvider(interruptedWork); @@ -5782,8 +5645,8 @@ function prepareFreshStack(root, expirationTime) { timeoutHandle = timeoutHandle.return; } workInProgressRoot = root; - workInProgress = createWorkInProgress(root.current, null); - renderExpirationTime$1 = expirationTime; + workInProgress = createWorkInProgress(root.current, null, expirationTime); + renderExpirationTime = expirationTime; workInProgressRootExitStatus = RootIncomplete; workInProgressRootFatalError = null; workInProgressRootLatestSuspenseTimeout = workInProgressRootLatestProcessedExpirationTime = 1073741823; @@ -5795,32 +5658,19 @@ function handleError(root$jscomp$0, thrownValue) { do { try { resetContextDependencies(); - ReactCurrentDispatcher.current = ContextOnlyDispatcher; - if (didScheduleRenderPhaseUpdate) - for ( - var hook = currentlyRenderingFiber$1.memoizedState; - null !== hook; - - ) { - var queue = hook.queue; - null !== queue && (queue.pending = null); - hook = hook.next; - } - renderExpirationTime = 0; - workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; - didScheduleRenderPhaseUpdate = !1; + resetHooks(); if (null === workInProgress || null === workInProgress.return) return ( (workInProgressRootExitStatus = RootFatalErrored), (workInProgressRootFatalError = thrownValue), - (workInProgress = null) + null ); a: { var root = root$jscomp$0, returnFiber = workInProgress.return, sourceFiber = workInProgress, value = thrownValue; - thrownValue = renderExpirationTime$1; + thrownValue = renderExpirationTime; sourceFiber.effectTag |= 2048; sourceFiber.firstEffect = sourceFiber.lastEffect = null; if ( @@ -5828,17 +5678,8 @@ function handleError(root$jscomp$0, thrownValue) { "object" === typeof value && "function" === typeof value.then ) { - var thenable = value; - if (0 === (sourceFiber.mode & 2)) { - var currentSource = sourceFiber.alternate; - currentSource - ? ((sourceFiber.updateQueue = currentSource.updateQueue), - (sourceFiber.memoizedState = currentSource.memoizedState), - (sourceFiber.expirationTime = currentSource.expirationTime)) - : ((sourceFiber.updateQueue = null), - (sourceFiber.memoizedState = null)); - } - var hasInvisibleParentBoundary = + var thenable = value, + hasInvisibleParentBoundary = 0 !== (suspenseStackCursor.current & 1), _workInProgress = returnFiber; do { @@ -5853,10 +5694,10 @@ function handleError(root$jscomp$0, thrownValue) { void 0 === props.fallback ? !1 : !0 !== props.unstable_avoidThisFallback - ? !0 - : hasInvisibleParentBoundary - ? !1 - : !0; + ? !0 + : hasInvisibleParentBoundary + ? !1 + : !0; } } if (JSCompiler_temp) { @@ -5963,8 +5804,8 @@ function handleError(root$jscomp$0, thrownValue) { } while (1); } function pushDispatcher() { - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = ContextOnlyDispatcher; return null === prevDispatcher ? ContextOnlyDispatcher : prevDispatcher; } function markRenderEventTimeAndConfig(expirationTime, suspenseConfig) { @@ -5981,43 +5822,19 @@ function markUnprocessedUpdateTime(expirationTime) { expirationTime > workInProgressRootNextUnprocessedUpdateTime && (workInProgressRootNextUnprocessedUpdateTime = expirationTime); } -function renderRootSync(root, expirationTime) { - var prevExecutionContext = executionContext; - executionContext |= RenderContext; - var prevDispatcher = pushDispatcher(); - (root === workInProgressRoot && expirationTime === renderExpirationTime$1) || - prepareFreshStack(root, expirationTime); - do - try { - workLoopSync(); - break; - } catch (thrownValue) { - handleError(root, thrownValue); - } - while (1); - resetContextDependencies(); - executionContext = prevExecutionContext; - ReactCurrentDispatcher$1.current = prevDispatcher; - if (null !== workInProgress) - throw Error( - "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." - ); - workInProgressRoot = null; - return workInProgressRootExitStatus; -} function workLoopSync() { for (; null !== workInProgress; ) workInProgress = performUnitOfWork(workInProgress); } function workLoopConcurrent() { - for (; null !== workInProgress && !shouldYield(); ) + for (; null !== workInProgress && !Scheduler_shouldYield(); ) workInProgress = performUnitOfWork(workInProgress); } function performUnitOfWork(unitOfWork) { - var next = beginWork$1( + var next = beginWork$$1( unitOfWork.alternate, unitOfWork, - renderExpirationTime$1 + renderExpirationTime ); unitOfWork.memoizedProps = unitOfWork.pendingProps; null === next && (next = completeUnitOfWork(unitOfWork)); @@ -6027,30 +5844,351 @@ function performUnitOfWork(unitOfWork) { function completeUnitOfWork(unitOfWork) { workInProgress = unitOfWork; do { - var current = workInProgress.alternate; + var current$$1 = workInProgress.alternate; unitOfWork = workInProgress.return; if (0 === (workInProgress.effectTag & 2048)) { - current = completeWork(current, workInProgress, renderExpirationTime$1); - if ( - 1 === renderExpirationTime$1 || - 1 !== workInProgress.childExpirationTime - ) { + a: { + var instance = current$$1; + current$$1 = workInProgress; + var renderExpirationTime$jscomp$0 = renderExpirationTime, + newProps = current$$1.pendingProps; + switch (current$$1.tag) { + case 2: + break; + case 16: + break; + case 15: + case 0: + break; + case 1: + isContextProvider(current$$1.type) && popContext(current$$1); + break; + case 3: + popHostContainer(current$$1); + popTopLevelContextObject(current$$1); + instance = current$$1.stateNode; + instance.pendingContext && + ((instance.context = instance.pendingContext), + (instance.pendingContext = null)); + updateHostContainer(current$$1); + break; + case 5: + popHostContext(current$$1); + var rootContainerInstance = requiredContext( + rootInstanceStackCursor.current + ), + type = current$$1.type; + if (null !== instance && null != current$$1.stateNode) + updateHostComponent$1( + instance, + current$$1, + type, + newProps, + rootContainerInstance + ), + instance.ref !== current$$1.ref && + (current$$1.effectTag |= 128); + else if (newProps) { + requiredContext(contextStackCursor$1.current); + instance = current$$1; + renderExpirationTime$jscomp$0 = nextReactTag; + nextReactTag += 2; + type = getViewConfigForType(type); + var updatePayload = diffProperties( + null, + emptyObject, + newProps, + type.validAttributes + ); + rootContainerInstance = createNode( + renderExpirationTime$jscomp$0, + type.uiViewClassName, + rootContainerInstance, + updatePayload, + instance + ); + instance = new ReactFabricHostComponent( + renderExpirationTime$jscomp$0, + type, + newProps, + instance + ); + instance = { + node: rootContainerInstance, + canonical: instance + }; + appendAllChildren(instance, current$$1, !1, !1); + current$$1.stateNode = instance; + null !== current$$1.ref && (current$$1.effectTag |= 128); + } else if (null === current$$1.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." + ); + break; + case 6: + if (instance && null != current$$1.stateNode) + updateHostText$1( + instance, + current$$1, + instance.memoizedProps, + newProps + ); + else { + if ("string" !== typeof newProps && null === current$$1.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." + ); + instance = requiredContext(rootInstanceStackCursor.current); + rootContainerInstance = requiredContext( + contextStackCursor$1.current + ); + current$$1.stateNode = createTextInstance( + newProps, + instance, + rootContainerInstance, + current$$1 + ); + } + break; + case 11: + break; + case 13: + pop(suspenseStackCursor, current$$1); + newProps = current$$1.memoizedState; + if (0 !== (current$$1.effectTag & 64)) { + current$$1.expirationTime = renderExpirationTime$jscomp$0; + break a; + } + newProps = null !== newProps; + rootContainerInstance = !1; + null !== instance && + ((renderExpirationTime$jscomp$0 = instance.memoizedState), + (rootContainerInstance = null !== renderExpirationTime$jscomp$0), + newProps || + null === renderExpirationTime$jscomp$0 || + ((renderExpirationTime$jscomp$0 = instance.child.sibling), + null !== renderExpirationTime$jscomp$0 && + ((type = current$$1.firstEffect), + null !== type + ? ((current$$1.firstEffect = renderExpirationTime$jscomp$0), + (renderExpirationTime$jscomp$0.nextEffect = type)) + : ((current$$1.firstEffect = current$$1.lastEffect = renderExpirationTime$jscomp$0), + (renderExpirationTime$jscomp$0.nextEffect = null)), + (renderExpirationTime$jscomp$0.effectTag = 8)))); + if ( + newProps && + !rootContainerInstance && + 0 !== (current$$1.mode & 2) + ) + if ( + (null === instance && + !0 !== current$$1.memoizedProps.unstable_avoidThisFallback) || + 0 !== (suspenseStackCursor.current & 1) + ) + workInProgressRootExitStatus === RootIncomplete && + (workInProgressRootExitStatus = RootSuspended); + else { + if ( + workInProgressRootExitStatus === RootIncomplete || + workInProgressRootExitStatus === RootSuspended + ) + workInProgressRootExitStatus = RootSuspendedWithDelay; + 0 !== workInProgressRootNextUnprocessedUpdateTime && + null !== workInProgressRoot && + (markRootSuspendedAtTime( + workInProgressRoot, + renderExpirationTime + ), + markRootUpdatedAtTime( + workInProgressRoot, + workInProgressRootNextUnprocessedUpdateTime + )); + } + newProps && (current$$1.effectTag |= 4); + break; + case 7: + break; + case 8: + break; + case 12: + break; + case 4: + popHostContainer(current$$1); + updateHostContainer(current$$1); + break; + case 10: + popProvider(current$$1); + break; + case 9: + break; + case 14: + break; + case 17: + isContextProvider(current$$1.type) && popContext(current$$1); + break; + case 19: + pop(suspenseStackCursor, current$$1); + newProps = current$$1.memoizedState; + if (null === newProps) break; + rootContainerInstance = 0 !== (current$$1.effectTag & 64); + type = newProps.rendering; + if (null === type) + if (rootContainerInstance) cutOffTailIfNeeded(newProps, !1); + else { + if ( + workInProgressRootExitStatus !== RootIncomplete || + (null !== instance && 0 !== (instance.effectTag & 64)) + ) + for (instance = current$$1.child; null !== instance; ) { + type = findFirstSuspended(instance); + if (null !== type) { + current$$1.effectTag |= 64; + cutOffTailIfNeeded(newProps, !1); + instance = type.updateQueue; + null !== instance && + ((current$$1.updateQueue = instance), + (current$$1.effectTag |= 4)); + null === newProps.lastEffect && + (current$$1.firstEffect = null); + current$$1.lastEffect = newProps.lastEffect; + instance = renderExpirationTime$jscomp$0; + for (newProps = current$$1.child; null !== newProps; ) + (rootContainerInstance = newProps), + (renderExpirationTime$jscomp$0 = instance), + (rootContainerInstance.effectTag &= 2), + (rootContainerInstance.nextEffect = null), + (rootContainerInstance.firstEffect = null), + (rootContainerInstance.lastEffect = null), + (type = rootContainerInstance.alternate), + null === type + ? ((rootContainerInstance.childExpirationTime = 0), + (rootContainerInstance.expirationTime = renderExpirationTime$jscomp$0), + (rootContainerInstance.child = null), + (rootContainerInstance.memoizedProps = null), + (rootContainerInstance.memoizedState = null), + (rootContainerInstance.updateQueue = null), + (rootContainerInstance.dependencies = null)) + : ((rootContainerInstance.childExpirationTime = + type.childExpirationTime), + (rootContainerInstance.expirationTime = + type.expirationTime), + (rootContainerInstance.child = type.child), + (rootContainerInstance.memoizedProps = + type.memoizedProps), + (rootContainerInstance.memoizedState = + type.memoizedState), + (rootContainerInstance.updateQueue = + type.updateQueue), + (renderExpirationTime$jscomp$0 = + type.dependencies), + (rootContainerInstance.dependencies = + null === renderExpirationTime$jscomp$0 + ? null + : { + expirationTime: + renderExpirationTime$jscomp$0.expirationTime, + firstContext: + renderExpirationTime$jscomp$0.firstContext, + responders: + renderExpirationTime$jscomp$0.responders + })), + (newProps = newProps.sibling); + push( + suspenseStackCursor, + (suspenseStackCursor.current & 1) | 2, + current$$1 + ); + current$$1 = current$$1.child; + break a; + } + instance = instance.sibling; + } + } + else { + if (!rootContainerInstance) + if ( + ((instance = findFirstSuspended(type)), null !== instance) + ) { + if ( + ((current$$1.effectTag |= 64), + (rootContainerInstance = !0), + (instance = instance.updateQueue), + null !== instance && + ((current$$1.updateQueue = instance), + (current$$1.effectTag |= 4)), + cutOffTailIfNeeded(newProps, !0), + null === newProps.tail && + "hidden" === newProps.tailMode && + !type.alternate) + ) { + current$$1 = current$$1.lastEffect = newProps.lastEffect; + null !== current$$1 && (current$$1.nextEffect = null); + break; + } + } else + now() > newProps.tailExpiration && + 1 < renderExpirationTime$jscomp$0 && + ((current$$1.effectTag |= 64), + (rootContainerInstance = !0), + cutOffTailIfNeeded(newProps, !1), + (current$$1.expirationTime = current$$1.childExpirationTime = + renderExpirationTime$jscomp$0 - 1)); + newProps.isBackwards + ? ((type.sibling = current$$1.child), (current$$1.child = type)) + : ((instance = newProps.last), + null !== instance + ? (instance.sibling = type) + : (current$$1.child = type), + (newProps.last = type)); + } + if (null !== newProps.tail) { + 0 === newProps.tailExpiration && + (newProps.tailExpiration = now() + 500); + instance = newProps.tail; + newProps.rendering = instance; + newProps.tail = instance.sibling; + newProps.lastEffect = current$$1.lastEffect; + instance.sibling = null; + newProps = suspenseStackCursor.current; + newProps = rootContainerInstance + ? (newProps & 1) | 2 + : newProps & 1; + push(suspenseStackCursor, newProps, current$$1); + current$$1 = instance; + break a; + } + break; + case 20: + break; + case 21: + break; + default: + throw Error( + "Unknown unit of work tag (" + + current$$1.tag + + "). This error is likely caused by a bug in React. Please file an issue." + ); + } + current$$1 = null; + } + instance = workInProgress; + if (1 === renderExpirationTime || 1 !== instance.childExpirationTime) { + newProps = 0; for ( - var newChildExpirationTime = 0, _child = workInProgress.child; - null !== _child; + rootContainerInstance = instance.child; + null !== rootContainerInstance; - ) { - var _childUpdateExpirationTime = _child.expirationTime, - _childChildExpirationTime = _child.childExpirationTime; - _childUpdateExpirationTime > newChildExpirationTime && - (newChildExpirationTime = _childUpdateExpirationTime); - _childChildExpirationTime > newChildExpirationTime && - (newChildExpirationTime = _childChildExpirationTime); - _child = _child.sibling; - } - workInProgress.childExpirationTime = newChildExpirationTime; + ) + (renderExpirationTime$jscomp$0 = + rootContainerInstance.expirationTime), + (type = rootContainerInstance.childExpirationTime), + renderExpirationTime$jscomp$0 > newProps && + (newProps = renderExpirationTime$jscomp$0), + type > newProps && (newProps = type), + (rootContainerInstance = rootContainerInstance.sibling); + instance.childExpirationTime = newProps; } - if (null !== current) return current; + if (null !== current$$1) return current$$1; null !== unitOfWork && 0 === (unitOfWork.effectTag & 2048) && (null === unitOfWork.firstEffect && @@ -6065,14 +6203,15 @@ function completeUnitOfWork(unitOfWork) { : (unitOfWork.firstEffect = workInProgress), (unitOfWork.lastEffect = workInProgress))); } else { - current = unwindWork(workInProgress); - if (null !== current) return (current.effectTag &= 2047), current; + current$$1 = unwindWork(workInProgress, renderExpirationTime); + if (null !== current$$1) + return (current$$1.effectTag &= 2047), current$$1; null !== unitOfWork && ((unitOfWork.firstEffect = unitOfWork.lastEffect = null), (unitOfWork.effectTag |= 2048)); } - current = workInProgress.sibling; - if (null !== current) return current; + current$$1 = workInProgress.sibling; + if (null !== current$$1) return current$$1; workInProgress = unitOfWork; } while (null !== workInProgress); workInProgressRootExitStatus === RootIncomplete && @@ -6086,12 +6225,11 @@ function getRemainingExpirationTime(fiber) { } function commitRoot(root) { var renderPriorityLevel = getCurrentPriorityLevel(); - runWithPriority(99, commitRootImpl.bind(null, root, renderPriorityLevel)); + runWithPriority$1(99, commitRootImpl.bind(null, root, renderPriorityLevel)); return null; } function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { - do flushPassiveEffects(); - while (null !== rootWithPendingPassiveEffects); + flushPassiveEffects(); if ((executionContext & (RenderContext | CommitContext)) !== NoContext) throw Error("Should not already be working."); var finishedWork = root$jscomp$1.finishedWork, @@ -6120,8 +6258,7 @@ function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { expirationTime <= root$jscomp$1.lastExpiredTime && (root$jscomp$1.lastExpiredTime = 0); root$jscomp$1 === workInProgressRoot && - ((workInProgress = workInProgressRoot = null), - (renderExpirationTime$1 = 0)); + ((workInProgress = workInProgressRoot = null), (renderExpirationTime = 0)); 1 < finishedWork.effectTag ? null !== finishedWork.lastEffect ? ((finishedWork.lastEffect.nextEffect = finishedWork), @@ -6153,9 +6290,9 @@ function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { ) { var effectTag = nextEffect.effectTag; if (effectTag & 128) { - var current = nextEffect.alternate; - if (null !== current) { - var currentRef = current.ref; + var current$$1 = nextEffect.alternate; + if (null !== current$$1) { + var currentRef = current$$1.ref; null !== currentRef && ("function" === typeof currentRef ? currentRef(null) @@ -6181,10 +6318,10 @@ function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { commitWork(nextEffect.alternate, nextEffect); break; case 8: - var current$jscomp$0 = nextEffect; + var current$$1$jscomp$0 = nextEffect; a: for ( var finishedRoot = root, - root$jscomp$0 = current$jscomp$0, + root$jscomp$0 = current$$1$jscomp$0, renderPriorityLevel$jscomp$0 = renderPriorityLevel, node = root$jscomp$0; ; @@ -6209,7 +6346,7 @@ function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { node.sibling.return = node.return; node = node.sibling; } - detachFiber(current$jscomp$0); + detachFiber(current$$1$jscomp$0); } nextEffect = nextEffect.nextEffect; } @@ -6223,25 +6360,101 @@ function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { nextEffect = remainingExpirationTimeBeforeCommit; do try { - for (effectTag = root$jscomp$1; null !== nextEffect; ) { + for (effectTag = expirationTime; null !== nextEffect; ) { var effectTag$jscomp$0 = nextEffect.effectTag; - effectTag$jscomp$0 & 36 && - commitLifeCycles(effectTag, nextEffect.alternate, nextEffect); + if (effectTag$jscomp$0 & 36) { + var current$$1$jscomp$1 = nextEffect.alternate; + current$$1 = nextEffect; + currentRef = effectTag; + switch (current$$1.tag) { + case 0: + case 11: + case 15: + commitHookEffectList(16, 32, current$$1); + break; + case 1: + var instance = current$$1.stateNode; + if (current$$1.effectTag & 4) + if (null === current$$1$jscomp$1) + instance.componentDidMount(); + else { + var prevProps = + current$$1.elementType === current$$1.type + ? current$$1$jscomp$1.memoizedProps + : resolveDefaultProps( + current$$1.type, + current$$1$jscomp$1.memoizedProps + ); + instance.componentDidUpdate( + prevProps, + current$$1$jscomp$1.memoizedState, + instance.__reactInternalSnapshotBeforeUpdate + ); + } + var updateQueue = current$$1.updateQueue; + null !== updateQueue && + commitUpdateQueue( + current$$1, + updateQueue, + instance, + currentRef + ); + break; + case 3: + var _updateQueue = current$$1.updateQueue; + if (null !== _updateQueue) { + root = null; + if (null !== current$$1.child) + switch (current$$1.child.tag) { + case 5: + root = current$$1.child.stateNode.canonical; + break; + case 1: + root = current$$1.child.stateNode; + } + commitUpdateQueue(current$$1, _updateQueue, root, currentRef); + } + break; + case 5: + if (null === current$$1$jscomp$1 && current$$1.effectTag & 4) + throw Error( + "The current renderer does not support mutation. This error is likely caused by a bug in React. Please file an issue." + ); + break; + case 6: + break; + case 4: + break; + case 12: + break; + case 13: + break; + case 19: + case 17: + case 20: + case 21: + 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 (effectTag$jscomp$0 & 128) { - current = void 0; + current$$1 = void 0; var ref = nextEffect.ref; if (null !== ref) { - var instance = nextEffect.stateNode; + var instance$jscomp$0 = nextEffect.stateNode; switch (nextEffect.tag) { case 5: - current = instance.canonical; + current$$1 = instance$jscomp$0.canonical; break; default: - current = instance; + current$$1 = instance$jscomp$0; } "function" === typeof ref - ? ref(current) - : (ref.current = current); + ? ref(current$$1) + : (ref.current = current$$1); } } nextEffect = nextEffect.nextEffect; @@ -6311,7 +6524,7 @@ function flushPassiveEffects() { ? 97 : pendingPassiveEffectsRenderPriority; pendingPassiveEffectsRenderPriority = 90; - return runWithPriority(priorityLevel, flushPassiveEffectsImpl); + return runWithPriority$1(priorityLevel, flushPassiveEffectsImpl); } } function flushPassiveEffectsImpl() { @@ -6330,9 +6543,8 @@ function flushPassiveEffectsImpl() { case 0: case 11: case 15: - case 22: - commitHookEffectListUnmount(5, finishedWork), - commitHookEffectListMount(5, finishedWork); + commitHookEffectList(128, 0, finishedWork), + commitHookEffectList(0, 64, finishedWork); } } catch (error) { if (null === root) throw Error("Should be working on an effect."); @@ -6383,17 +6595,20 @@ function captureCommitPhaseError(sourceFiber, error) { function pingSuspendedRoot(root, thenable, suspendedTime) { var pingCache = root.pingCache; null !== pingCache && pingCache.delete(thenable); - workInProgressRoot === root && renderExpirationTime$1 === suspendedTime + workInProgressRoot === root && renderExpirationTime === suspendedTime ? workInProgressRootExitStatus === RootSuspendedWithDelay || (workInProgressRootExitStatus === RootSuspended && 1073741823 === workInProgressRootLatestProcessedExpirationTime && now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) - ? prepareFreshStack(root, renderExpirationTime$1) + ? prepareFreshStack(root, renderExpirationTime) : (workInProgressRootHasPendingPing = !0) : isRootSuspendedAtTime(root, suspendedTime) && ((thenable = root.lastPingedTime), (0 !== thenable && thenable < suspendedTime) || - ((root.lastPingedTime = suspendedTime), ensureRootIsScheduled(root))); + ((root.lastPingedTime = suspendedTime), + root.finishedExpirationTime === suspendedTime && + ((root.finishedExpirationTime = 0), (root.finishedWork = null)), + ensureRootIsScheduled(root))); } function resolveRetryThenable(boundaryFiber, thenable) { var retryCache = boundaryFiber.stateNode; @@ -6405,12 +6620,12 @@ function resolveRetryThenable(boundaryFiber, thenable) { boundaryFiber = markUpdateTimeFromFiberToRoot(boundaryFiber, thenable); null !== boundaryFiber && ensureRootIsScheduled(boundaryFiber); } -var beginWork$1; -beginWork$1 = function(current, workInProgress, renderExpirationTime) { +var beginWork$$1; +beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { var updateExpirationTime = workInProgress.expirationTime; - if (null !== current) + if (null !== current$$1) if ( - current.memoizedProps !== workInProgress.pendingProps || + current$$1.memoizedProps !== workInProgress.pendingProps || didPerformWorkStackCursor.current ) didReceiveUpdate = !0; @@ -6435,10 +6650,7 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { ); break; case 10: - updateExpirationTime = workInProgress.memoizedProps.value; - var context = workInProgress.type._context; - push(valueCursor, context._currentValue2); - context._currentValue2 = updateExpirationTime; + pushProvider(workInProgress, workInProgress.memoizedProps.value); break; case 13: if (null !== workInProgress.memoizedState) { @@ -6448,40 +6660,52 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { updateExpirationTime >= renderExpirationTime ) return updateSuspenseComponent( - current, + current$$1, workInProgress, renderExpirationTime ); - push(suspenseStackCursor, suspenseStackCursor.current & 1); + push( + suspenseStackCursor, + suspenseStackCursor.current & 1, + workInProgress + ); workInProgress = bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ); return null !== workInProgress ? workInProgress.sibling : null; } - push(suspenseStackCursor, suspenseStackCursor.current & 1); + push( + suspenseStackCursor, + suspenseStackCursor.current & 1, + workInProgress + ); break; case 19: updateExpirationTime = workInProgress.childExpirationTime >= renderExpirationTime; - if (0 !== (current.effectTag & 64)) { + if (0 !== (current$$1.effectTag & 64)) { if (updateExpirationTime) return updateSuspenseListComponent( - current, + current$$1, workInProgress, renderExpirationTime ); workInProgress.effectTag |= 64; } - context = workInProgress.memoizedState; - null !== context && - ((context.rendering = null), (context.tail = null)); - push(suspenseStackCursor, suspenseStackCursor.current); + var renderState = workInProgress.memoizedState; + null !== renderState && + ((renderState.rendering = null), (renderState.tail = null)); + push( + suspenseStackCursor, + suspenseStackCursor.current, + workInProgress + ); if (!updateExpirationTime) return null; } return bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -6493,40 +6717,41 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { switch (workInProgress.tag) { case 2: updateExpirationTime = workInProgress.type; - null !== current && - ((current.alternate = null), + null !== current$$1 && + ((current$$1.alternate = null), (workInProgress.alternate = null), (workInProgress.effectTag |= 2)); - current = workInProgress.pendingProps; - context = getMaskedContext(workInProgress, contextStackCursor.current); + current$$1 = workInProgress.pendingProps; + renderState = getMaskedContext( + workInProgress, + contextStackCursor.current + ); prepareToReadContext(workInProgress, renderExpirationTime); - context = renderWithHooks( + renderState = renderWithHooks( null, workInProgress, updateExpirationTime, - current, - context, + current$$1, + renderState, renderExpirationTime ); workInProgress.effectTag |= 1; if ( - "object" === typeof context && - null !== context && - "function" === typeof context.render && - void 0 === context.$$typeof + "object" === typeof renderState && + null !== renderState && + "function" === typeof renderState.render && + void 0 === renderState.$$typeof ) { workInProgress.tag = 1; - workInProgress.memoizedState = null; - workInProgress.updateQueue = null; + resetHooks(); if (isContextProvider(updateExpirationTime)) { var hasContext = !0; pushContextProvider(workInProgress); } else hasContext = !1; workInProgress.memoizedState = - null !== context.state && void 0 !== context.state - ? context.state + null !== renderState.state && void 0 !== renderState.state + ? renderState.state : null; - initializeUpdateQueue(workInProgress); var getDerivedStateFromProps = updateExpirationTime.getDerivedStateFromProps; "function" === typeof getDerivedStateFromProps && @@ -6534,15 +6759,15 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { workInProgress, updateExpirationTime, getDerivedStateFromProps, - current + current$$1 ); - context.updater = classComponentUpdater; - workInProgress.stateNode = context; - context._reactInternalFiber = workInProgress; + renderState.updater = classComponentUpdater; + workInProgress.stateNode = renderState; + renderState._reactInternalFiber = workInProgress; mountClassInstance( workInProgress, updateExpirationTime, - current, + current$$1, renderExpirationTime ); workInProgress = finishClassComponent( @@ -6558,129 +6783,127 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { reconcileChildren( null, workInProgress, - context, + renderState, renderExpirationTime ), (workInProgress = workInProgress.child); return workInProgress; case 16: - a: { - context = workInProgress.elementType; - null !== current && - ((current.alternate = null), - (workInProgress.alternate = null), - (workInProgress.effectTag |= 2)); - current = workInProgress.pendingProps; - initializeLazyComponentType(context); - if (1 !== context._status) throw context._result; - context = context._result; - workInProgress.type = context; - hasContext = workInProgress.tag = resolveLazyComponentTag(context); - current = resolveDefaultProps(context, current); - switch (hasContext) { - case 0: - workInProgress = updateFunctionComponent( - null, - workInProgress, - context, - current, - renderExpirationTime - ); - break a; - case 1: - workInProgress = updateClassComponent( - null, - workInProgress, - context, - current, - renderExpirationTime - ); - break a; - case 11: - workInProgress = updateForwardRef( - null, - workInProgress, - context, - current, - renderExpirationTime - ); - break a; - case 14: - workInProgress = updateMemoComponent( - null, - workInProgress, - context, - resolveDefaultProps(context.type, current), - updateExpirationTime, - renderExpirationTime - ); - break a; - } - throw Error( - "Element type is invalid. Received a promise that resolves to: " + - context + - ". Lazy element type must resolve to a class or function." - ); + renderState = workInProgress.elementType; + null !== current$$1 && + ((current$$1.alternate = null), + (workInProgress.alternate = null), + (workInProgress.effectTag |= 2)); + current$$1 = workInProgress.pendingProps; + initializeLazyComponentType(renderState); + if (1 !== renderState._status) throw renderState._result; + renderState = renderState._result; + workInProgress.type = renderState; + hasContext = workInProgress.tag = resolveLazyComponentTag(renderState); + current$$1 = resolveDefaultProps(renderState, current$$1); + switch (hasContext) { + case 0: + workInProgress = updateFunctionComponent( + null, + workInProgress, + renderState, + current$$1, + renderExpirationTime + ); + break; + case 1: + workInProgress = updateClassComponent( + null, + workInProgress, + renderState, + current$$1, + renderExpirationTime + ); + break; + case 11: + workInProgress = updateForwardRef( + null, + workInProgress, + renderState, + current$$1, + renderExpirationTime + ); + break; + case 14: + workInProgress = updateMemoComponent( + null, + workInProgress, + renderState, + resolveDefaultProps(renderState.type, current$$1), + updateExpirationTime, + renderExpirationTime + ); + break; + default: + throw Error( + "Element type is invalid. Received a promise that resolves to: " + + renderState + + ". Lazy element type must resolve to a class or function." + ); } return workInProgress; case 0: return ( (updateExpirationTime = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (renderState = workInProgress.pendingProps), + (renderState = workInProgress.elementType === updateExpirationTime - ? context - : resolveDefaultProps(updateExpirationTime, context)), + ? renderState + : resolveDefaultProps(updateExpirationTime, renderState)), updateFunctionComponent( - current, + current$$1, workInProgress, updateExpirationTime, - context, + renderState, renderExpirationTime ) ); case 1: return ( (updateExpirationTime = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (renderState = workInProgress.pendingProps), + (renderState = workInProgress.elementType === updateExpirationTime - ? context - : resolveDefaultProps(updateExpirationTime, context)), + ? renderState + : resolveDefaultProps(updateExpirationTime, renderState)), updateClassComponent( - current, + current$$1, workInProgress, updateExpirationTime, - context, + renderState, renderExpirationTime ) ); case 3: pushHostRootContext(workInProgress); updateExpirationTime = workInProgress.updateQueue; - if (null === current || null === updateExpirationTime) + if (null === updateExpirationTime) 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." ); - updateExpirationTime = workInProgress.pendingProps; - context = workInProgress.memoizedState; - context = null !== context ? context.element : null; - cloneUpdateQueue(current, workInProgress); + renderState = workInProgress.memoizedState; + renderState = null !== renderState ? renderState.element : null; processUpdateQueue( workInProgress, updateExpirationTime, + workInProgress.pendingProps, null, renderExpirationTime ); updateExpirationTime = workInProgress.memoizedState.element; - updateExpirationTime === context + updateExpirationTime === renderState ? (workInProgress = bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime )) : (reconcileChildren( - current, + current$$1, workInProgress, updateExpirationTime, renderExpirationTime @@ -6690,10 +6913,11 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { case 5: return ( pushHostContext(workInProgress), + null === current$$1 && tryToClaimNextHydratableInstance(workInProgress), (updateExpirationTime = workInProgress.pendingProps.children), - markRef(current, workInProgress), + markRef(current$$1, workInProgress), reconcileChildren( - current, + current$$1, workInProgress, updateExpirationTime, renderExpirationTime @@ -6702,10 +6926,13 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { workInProgress ); case 6: - return null; + return ( + null === current$$1 && tryToClaimNextHydratableInstance(workInProgress), + null + ); case 13: return updateSuspenseComponent( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -6716,7 +6943,7 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { workInProgress.stateNode.containerInfo ), (updateExpirationTime = workInProgress.pendingProps), - null === current + null === current$$1 ? (workInProgress.child = reconcileChildFibers( workInProgress, null, @@ -6724,7 +6951,7 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { renderExpirationTime )) : reconcileChildren( - current, + current$$1, workInProgress, updateExpirationTime, renderExpirationTime @@ -6734,23 +6961,23 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { case 11: return ( (updateExpirationTime = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (renderState = workInProgress.pendingProps), + (renderState = workInProgress.elementType === updateExpirationTime - ? context - : resolveDefaultProps(updateExpirationTime, context)), + ? renderState + : resolveDefaultProps(updateExpirationTime, renderState)), updateForwardRef( - current, + current$$1, workInProgress, updateExpirationTime, - context, + renderState, renderExpirationTime ) ); case 7: return ( reconcileChildren( - current, + current$$1, workInProgress, workInProgress.pendingProps, renderExpirationTime @@ -6760,7 +6987,7 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { case 8: return ( reconcileChildren( - current, + current$$1, workInProgress, workInProgress.pendingProps.children, renderExpirationTime @@ -6770,7 +6997,7 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { case 12: return ( reconcileChildren( - current, + current$$1, workInProgress, workInProgress.pendingProps.children, renderExpirationTime @@ -6780,32 +7007,27 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { case 10: a: { updateExpirationTime = workInProgress.type._context; - context = workInProgress.pendingProps; + renderState = 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 updateExpirationTime._calculateChangedBits - ? updateExpirationTime._calculateChangedBits( - context$jscomp$0, - hasContext - ) - : 1073741823) | 0), - 0 === hasContext) - ) { + hasContext = renderState.value; + pushProvider(workInProgress, hasContext); + if (null !== getDerivedStateFromProps) { + var oldValue = getDerivedStateFromProps.value; + hasContext = is$1(oldValue, hasContext) + ? 0 + : ("function" === typeof updateExpirationTime._calculateChangedBits + ? updateExpirationTime._calculateChangedBits( + oldValue, + hasContext + ) + : 1073741823) | 0; + if (0 === hasContext) { if ( - getDerivedStateFromProps.children === context.children && + getDerivedStateFromProps.children === renderState.children && !didPerformWorkStackCursor.current ) { workInProgress = bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -6813,15 +7035,14 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { } } 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; @@ -6831,18 +7052,18 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { dependency.context === updateExpirationTime && 0 !== (dependency.observedBits & hasContext) ) { - 1 === context$jscomp$0.tag && + 1 === oldValue.tag && ((dependency = createUpdate(renderExpirationTime, null)), (dependency.tag = 2), - enqueueUpdate(context$jscomp$0, dependency)); - context$jscomp$0.expirationTime < renderExpirationTime && - (context$jscomp$0.expirationTime = renderExpirationTime); - dependency = context$jscomp$0.alternate; + enqueueUpdate(oldValue, dependency)); + oldValue.expirationTime < renderExpirationTime && + (oldValue.expirationTime = renderExpirationTime); + dependency = oldValue.alternate; null !== dependency && dependency.expirationTime < renderExpirationTime && (dependency.expirationTime = renderExpirationTime); scheduleWorkOnParentPath( - context$jscomp$0.return, + oldValue.return, renderExpirationTime ); list.expirationTime < renderExpirationTime && @@ -6853,16 +7074,16 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { } } 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; ) { @@ -6870,20 +7091,21 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { 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, + current$$1, workInProgress, - context.children, + renderState.children, renderExpirationTime ); workInProgress = workInProgress.child; @@ -6891,15 +7113,18 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { return workInProgress; case 9: return ( - (context = workInProgress.type), + (renderState = workInProgress.type), (hasContext = workInProgress.pendingProps), (updateExpirationTime = hasContext.children), prepareToReadContext(workInProgress, renderExpirationTime), - (context = readContext(context, hasContext.unstable_observedBits)), - (updateExpirationTime = updateExpirationTime(context)), + (renderState = readContext( + renderState, + hasContext.unstable_observedBits + )), + (updateExpirationTime = updateExpirationTime(renderState)), (workInProgress.effectTag |= 1), reconcileChildren( - current, + current$$1, workInProgress, updateExpirationTime, renderExpirationTime @@ -6908,16 +7133,16 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { ); case 14: return ( - (context = workInProgress.type), + (renderState = workInProgress.type), (hasContext = resolveDefaultProps( - context, + renderState, workInProgress.pendingProps )), - (hasContext = resolveDefaultProps(context.type, hasContext)), + (hasContext = resolveDefaultProps(renderState.type, hasContext)), updateMemoComponent( - current, + current$$1, workInProgress, - context, + renderState, hasContext, updateExpirationTime, renderExpirationTime @@ -6925,7 +7150,7 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { ); case 15: return updateSimpleMemoComponent( - current, + current$$1, workInProgress, workInProgress.type, workInProgress.pendingProps, @@ -6935,25 +7160,30 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { case 17: return ( (updateExpirationTime = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (renderState = workInProgress.pendingProps), + (renderState = workInProgress.elementType === updateExpirationTime - ? context - : resolveDefaultProps(updateExpirationTime, context)), - null !== current && - ((current.alternate = null), + ? renderState + : resolveDefaultProps(updateExpirationTime, renderState)), + null !== current$$1 && + ((current$$1.alternate = null), (workInProgress.alternate = null), (workInProgress.effectTag |= 2)), (workInProgress.tag = 1), isContextProvider(updateExpirationTime) - ? ((current = !0), pushContextProvider(workInProgress)) - : (current = !1), + ? ((current$$1 = !0), pushContextProvider(workInProgress)) + : (current$$1 = !1), prepareToReadContext(workInProgress, renderExpirationTime), - constructClassInstance(workInProgress, updateExpirationTime, context), + constructClassInstance( + workInProgress, + updateExpirationTime, + renderState, + renderExpirationTime + ), mountClassInstance( workInProgress, updateExpirationTime, - context, + renderState, renderExpirationTime ), finishClassComponent( @@ -6961,13 +7191,13 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { workInProgress, updateExpirationTime, !0, - current, + current$$1, renderExpirationTime ) ); case 19: return updateSuspenseListComponent( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -7018,6 +7248,9 @@ function FiberNode(tag, pendingProps, key, mode) { this.childExpirationTime = this.expirationTime = 0; this.alternate = null; } +function createFiber(tag, pendingProps, key, mode) { + return new FiberNode(tag, pendingProps, key, mode); +} function shouldConstruct(Component) { Component = Component.prototype; return !(!Component || !Component.isReactComponent); @@ -7035,7 +7268,7 @@ function resolveLazyComponentTag(Component) { function createWorkInProgress(current, pendingProps) { var workInProgress = current.alternate; null === workInProgress - ? ((workInProgress = new FiberNode( + ? ((workInProgress = createFiber( current.tag, pendingProps, current.key, @@ -7102,7 +7335,7 @@ function createFiberFromTypeAndProps( break; case REACT_PROFILER_TYPE: return ( - (type = new FiberNode(12, pendingProps, key, mode | 8)), + (type = createFiber(12, pendingProps, key, mode | 8)), (type.elementType = REACT_PROFILER_TYPE), (type.type = REACT_PROFILER_TYPE), (type.expirationTime = expirationTime), @@ -7110,7 +7343,7 @@ function createFiberFromTypeAndProps( ); case REACT_SUSPENSE_TYPE: return ( - (type = new FiberNode(13, pendingProps, key, mode)), + (type = createFiber(13, pendingProps, key, mode)), (type.type = REACT_SUSPENSE_TYPE), (type.elementType = REACT_SUSPENSE_TYPE), (type.expirationTime = expirationTime), @@ -7118,7 +7351,7 @@ function createFiberFromTypeAndProps( ); case REACT_SUSPENSE_LIST_TYPE: return ( - (type = new FiberNode(19, pendingProps, key, mode)), + (type = createFiber(19, pendingProps, key, mode)), (type.elementType = REACT_SUSPENSE_LIST_TYPE), (type.expirationTime = expirationTime), type @@ -7142,9 +7375,6 @@ function createFiberFromTypeAndProps( fiberTag = 16; owner = null; break a; - case REACT_BLOCK_TYPE: - fiberTag = 22; - break a; } throw Error( "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + @@ -7152,24 +7382,24 @@ function createFiberFromTypeAndProps( "." ); } - key = new FiberNode(fiberTag, pendingProps, key, mode); + key = createFiber(fiberTag, pendingProps, key, mode); key.elementType = type; key.type = owner; key.expirationTime = expirationTime; return key; } function createFiberFromFragment(elements, mode, expirationTime, key) { - elements = new FiberNode(7, elements, key, mode); + elements = createFiber(7, elements, key, mode); elements.expirationTime = expirationTime; return elements; } function createFiberFromText(content, mode, expirationTime) { - content = new FiberNode(6, content, null, mode); + content = createFiber(6, content, null, mode); content.expirationTime = expirationTime; return content; } function createFiberFromPortal(portal, mode, expirationTime) { - mode = new FiberNode( + mode = createFiber( 4, null !== portal.children ? portal.children : [], portal.key, @@ -7228,6 +7458,11 @@ function markRootUpdatedAtTime(root, expirationTime) { expirationTime > root.nextKnownPendingLevel && (root.nextKnownPendingLevel = expirationTime)); } +function markRootExpiredAtTime(root, expirationTime) { + var lastExpiredTime = root.lastExpiredTime; + if (0 === lastExpiredTime || lastExpiredTime > expirationTime) + root.lastExpiredTime = expirationTime; +} function findHostInstance(component) { var fiber = component._reactInternalFiber; if (void 0 === fiber) { @@ -7242,10 +7477,14 @@ function findHostInstance(component) { return null === component ? null : component.stateNode; } function updateContainer(element, container, parentComponent, callback) { - var current = container.current, + var current$$1 = container.current, currentTime = requestCurrentTimeForUpdate(), suspenseConfig = ReactCurrentBatchConfig.suspense; - currentTime = computeExpirationForFiber(currentTime, current, suspenseConfig); + currentTime = computeExpirationForFiber( + currentTime, + current$$1, + suspenseConfig + ); a: if (parentComponent) { parentComponent = parentComponent._reactInternalFiber; b: { @@ -7296,8 +7535,8 @@ function updateContainer(element, container, parentComponent, callback) { container.payload = { element: element }; callback = void 0 === callback ? null : callback; null !== callback && (container.callback = callback); - enqueueUpdate(current, container); - scheduleWork(current, currentTime); + enqueueUpdate(current$$1, container); + scheduleUpdateOnFiber(current$$1, currentTime); return currentTime; } function createPortal(children, containerInfo, implementation) { @@ -7311,6 +7550,7 @@ function createPortal(children, containerInfo, implementation) { implementation: implementation }; } +var fabricDispatchCommand = nativeFabricUIManager.dispatchCommand; function findNodeHandle(componentOrHandle) { if (null == componentOrHandle) return null; if ("number" === typeof componentOrHandle) return componentOrHandle; @@ -7321,8 +7561,8 @@ function findNodeHandle(componentOrHandle) { return null == componentOrHandle ? componentOrHandle : componentOrHandle.canonical - ? componentOrHandle.canonical._nativeTag - : componentOrHandle._nativeTag; + ? componentOrHandle.canonical._nativeTag + : componentOrHandle._nativeTag; } batchedUpdatesImpl = function(fn, a) { var prevExecutionContext = executionContext; @@ -7334,114 +7574,289 @@ batchedUpdatesImpl = function(fn, a) { executionContext === NoContext && flushSyncCallbackQueue(); } }; -var roots = new Map(); -(function(devToolsConfig) { - var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance; - return injectInternals({ - bundleType: devToolsConfig.bundleType, - version: devToolsConfig.version, - rendererPackageName: devToolsConfig.rendererPackageName, - rendererConfig: devToolsConfig.rendererConfig, - overrideHookState: null, - overrideProps: null, - setSuspenseHandler: null, - scheduleUpdate: null, - currentDispatcherRef: ReactSharedInternals.ReactCurrentDispatcher, - findHostInstanceByFiber: function(fiber) { - fiber = findCurrentHostFiber(fiber); - return null === fiber ? null : fiber.stateNode; +flushDiscreteUpdatesImpl = function() { + (executionContext & (1 | RenderContext | CommitContext)) === NoContext && + (flushPendingDiscreteUpdates(), flushPassiveEffects()); +}; +var roots = new Map(), + ReactFabric = { + NativeComponent: (function(findNodeHandle, findHostInstance) { + return (function(_React$Component) { + function ReactNativeComponent() { + return _React$Component.apply(this, arguments) || this; + } + _inheritsLoose(ReactNativeComponent, _React$Component); + var _proto = ReactNativeComponent.prototype; + _proto.blur = function() { + ReactNativePrivateInterface.TextInputState.blurTextInput( + findNodeHandle(this) + ); + }; + _proto.focus = function() { + ReactNativePrivateInterface.TextInputState.focusTextInput( + findNodeHandle(this) + ); + }; + _proto.measure = function(callback) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + null != maybeInstance && + (maybeInstance.canonical + ? nativeFabricUIManager.measure( + maybeInstance.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ) + : ReactNativePrivateInterface.UIManager.measure( + findNodeHandle(this), + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + )); + }; + _proto.measureInWindow = function(callback) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + null != maybeInstance && + (maybeInstance.canonical + ? nativeFabricUIManager.measureInWindow( + maybeInstance.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ) + : ReactNativePrivateInterface.UIManager.measureInWindow( + findNodeHandle(this), + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + )); + }; + _proto.measureLayout = function( + relativeToNativeNode, + onSuccess, + onFail + ) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + if (null != maybeInstance && !maybeInstance.canonical) { + if ("number" === typeof relativeToNativeNode) + var relativeNode = relativeToNativeNode; + else + relativeToNativeNode._nativeTag && + (relativeNode = relativeToNativeNode._nativeTag); + null != relativeNode && + ReactNativePrivateInterface.UIManager.measureLayout( + findNodeHandle(this), + relativeNode, + mountSafeCallback_NOT_REALLY_SAFE(this, onFail), + mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) + ); + } + }; + _proto.setNativeProps = function(nativeProps) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + if (null != maybeInstance && !maybeInstance.canonical) { + var nativeTag = + maybeInstance._nativeTag || maybeInstance.canonical._nativeTag; + maybeInstance = + maybeInstance.viewConfig || maybeInstance.canonical.viewConfig; + nativeProps = diffProperties( + null, + emptyObject, + nativeProps, + maybeInstance.validAttributes + ); + null != nativeProps && + ReactNativePrivateInterface.UIManager.updateView( + nativeTag, + maybeInstance.uiViewClassName, + nativeProps + ); + } + }; + return ReactNativeComponent; + })(React.Component); + })(findNodeHandle, findHostInstance), + findHostInstance_DEPRECATED: function(componentOrHandle) { + if (null == componentOrHandle) return null; + if (componentOrHandle._nativeTag) return componentOrHandle; + if (componentOrHandle.canonical && componentOrHandle.canonical._nativeTag) + return componentOrHandle.canonical; + componentOrHandle = findHostInstance(componentOrHandle); + return null == componentOrHandle + ? componentOrHandle + : componentOrHandle.canonical + ? componentOrHandle.canonical + : componentOrHandle; }, - findFiberByHostInstance: function(instance) { - return findFiberByHostInstance ? findFiberByHostInstance(instance) : null; + findNodeHandle: findNodeHandle, + dispatchCommand: function(handle, command, args) { + null != handle._nativeTag && + null != handle._internalInstanceHandle && + fabricDispatchCommand( + handle._internalInstanceHandle.stateNode.node, + command, + args + ); }, - findHostInstancesForRefresh: null, - scheduleRefresh: null, - scheduleRoot: null, - setRefreshHandler: null, - getCurrentFiber: null - }); + 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; + roots.set(containerTag, root); + } + updateContainer(element, root, null, callback); + a: if (((element = root.current), element.child)) + switch (element.child.tag) { + case 5: + element = element.child.stateNode.canonical; + break a; + default: + element = element.child.stateNode; + } + else element = null; + return element; + }, + unmountComponentAtNode: function(containerTag) { + var root = roots.get(containerTag); + root && + updateContainer(null, root, null, function() { + roots.delete(containerTag); + }); + }, + createPortal: function(children, containerTag) { + return createPortal( + children, + containerTag, + null, + 2 < arguments.length && void 0 !== arguments[2] ? arguments[2] : null + ); + }, + __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: { + NativeMethodsMixin: (function(findNodeHandle, findHostInstance) { + return { + measure: function(callback) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + null != maybeInstance && + (maybeInstance.canonical + ? nativeFabricUIManager.measure( + maybeInstance.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ) + : ReactNativePrivateInterface.UIManager.measure( + findNodeHandle(this), + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + )); + }, + measureInWindow: function(callback) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + null != maybeInstance && + (maybeInstance.canonical + ? nativeFabricUIManager.measureInWindow( + maybeInstance.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ) + : ReactNativePrivateInterface.UIManager.measureInWindow( + findNodeHandle(this), + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + )); + }, + measureLayout: function(relativeToNativeNode, onSuccess, onFail) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + if (null != maybeInstance && !maybeInstance.canonical) { + if ("number" === typeof relativeToNativeNode) + var relativeNode = relativeToNativeNode; + else + relativeToNativeNode._nativeTag && + (relativeNode = relativeToNativeNode._nativeTag); + null != relativeNode && + ReactNativePrivateInterface.UIManager.measureLayout( + findNodeHandle(this), + relativeNode, + mountSafeCallback_NOT_REALLY_SAFE(this, onFail), + mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) + ); + } + }, + setNativeProps: function(nativeProps) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + if (null != maybeInstance && !maybeInstance.canonical) { + var nativeTag = + maybeInstance._nativeTag || maybeInstance.canonical._nativeTag; + maybeInstance = + maybeInstance.viewConfig || maybeInstance.canonical.viewConfig; + nativeProps = diffProperties( + null, + emptyObject, + nativeProps, + maybeInstance.validAttributes + ); + null != nativeProps && + ReactNativePrivateInterface.UIManager.updateView( + nativeTag, + maybeInstance.uiViewClassName, + nativeProps + ); + } + }, + focus: function() { + ReactNativePrivateInterface.TextInputState.focusTextInput( + findNodeHandle(this) + ); + }, + blur: function() { + ReactNativePrivateInterface.TextInputState.blurTextInput( + findNodeHandle(this) + ); + } + }; + })(findNodeHandle, findHostInstance) + } + }; +(function(devToolsConfig) { + var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance; + return injectInternals( + Object.assign({}, devToolsConfig, { + overrideHookState: null, + overrideProps: null, + setSuspenseHandler: null, + scheduleUpdate: null, + currentDispatcherRef: ReactSharedInternals.ReactCurrentDispatcher, + findHostInstanceByFiber: function(fiber) { + fiber = findCurrentHostFiber(fiber); + return null === fiber ? null : fiber.stateNode; + }, + findFiberByHostInstance: function(instance) { + return findFiberByHostInstance + ? findFiberByHostInstance(instance) + : null; + }, + findHostInstancesForRefresh: null, + scheduleRefresh: null, + scheduleRoot: null, + setRefreshHandler: null, + getCurrentFiber: null + }) + ); })({ findFiberByHostInstance: getInstanceFromInstance, + getInspectorDataForViewTag: function() { + throw Error("getInspectorDataForViewTag() is not available in production"); + }, bundleType: 0, - version: "16.13.0", - rendererPackageName: "react-native-renderer", - rendererConfig: { - getInspectorDataForViewTag: function() { - throw Error( - "getInspectorDataForViewTag() is not available in production" - ); - }, - getInspectorDataForViewAtPoint: function() { - throw Error( - "getInspectorDataForViewAtPoint() is not available in production." - ); - }.bind(null, findNodeHandle) - } + version: "16.11.0", + rendererPackageName: "react-native-renderer" }); -exports.createPortal = function(children, containerTag) { - return createPortal( - children, - containerTag, - null, - 2 < arguments.length && void 0 !== arguments[2] ? arguments[2] : null - ); -}; -exports.dispatchCommand = function(handle, command, args) { - null != handle._nativeTag && - (handle._internalInstanceHandle - ? nativeFabricUIManager.dispatchCommand( - handle._internalInstanceHandle.stateNode.node, - command, - args - ) - : ReactNativePrivateInterface.UIManager.dispatchViewManagerCommand( - handle._nativeTag, - command, - args - )); -}; -exports.findHostInstance_DEPRECATED = function(componentOrHandle) { - if (null == componentOrHandle) return null; - if (componentOrHandle._nativeTag) return componentOrHandle; - if (componentOrHandle.canonical && componentOrHandle.canonical._nativeTag) - return componentOrHandle.canonical; - componentOrHandle = findHostInstance(componentOrHandle); - return null == componentOrHandle - ? componentOrHandle - : componentOrHandle.canonical - ? componentOrHandle.canonical - : componentOrHandle; -}; -exports.findNodeHandle = findNodeHandle; -exports.render = function(element, containerTag, callback) { - var root = roots.get(containerTag); - if (!root) { - root = new FiberRootNode(containerTag, 0, !1); - var uninitializedFiber = new FiberNode(3, null, null, 0); - root.current = uninitializedFiber; - uninitializedFiber.stateNode = root; - initializeUpdateQueue(uninitializedFiber); - roots.set(containerTag, root); - } - updateContainer(element, root, null, callback); - a: if (((element = root.current), element.child)) - switch (element.child.tag) { - case 5: - element = element.child.stateNode.canonical; - break a; - default: - element = element.child.stateNode; - } - else element = null; - return element; -}; -exports.stopSurface = function(containerTag) { - var root = roots.get(containerTag); - root && - updateContainer(null, root, null, function() { - roots.delete(containerTag); - }); -}; -exports.unmountComponentAtNode = function(containerTag) { - this.stopSurface(containerTag); -}; +var ReactFabric$2 = { default: ReactFabric }, + ReactFabric$3 = (ReactFabric$2 && ReactFabric) || ReactFabric$2; +module.exports = ReactFabric$3.default || ReactFabric$3; diff --git a/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js b/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js index be0ac55a7b83dc..90b9fe4a0821c5 100644 --- a/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js +++ b/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js @@ -5,7 +5,6 @@ * LICENSE file in the root directory of this source tree. * * @noflow - * @nolint * @preventMunge * @generated */ @@ -15,17 +14,86 @@ require("react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore"); var ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/ReactNativePrivateInterface"), React = require("react"), Scheduler = require("scheduler"), - tracing = require("scheduler/tracing"); -function getParent(inst) { - do inst = inst.return; - while (inst && 5 !== inst.tag); - return inst ? inst : null; + tracing = require("scheduler/tracing"), + eventPluginOrder = null, + namesToPlugins = {}; +function recomputePluginOrdering() { + if (eventPluginOrder) + for (var pluginName in namesToPlugins) { + var pluginModule = namesToPlugins[pluginName], + pluginIndex = eventPluginOrder.indexOf(pluginName); + if (!(-1 < pluginIndex)) + throw Error( + "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + + pluginName + + "`." + ); + if (!plugins[pluginIndex]) { + if (!pluginModule.extractEvents) + throw Error( + "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + + pluginName + + "` does not." + ); + plugins[pluginIndex] = pluginModule; + pluginIndex = pluginModule.eventTypes; + for (var eventName in pluginIndex) { + var JSCompiler_inline_result = void 0; + var dispatchConfig = pluginIndex[eventName], + pluginModule$jscomp$0 = pluginModule, + eventName$jscomp$0 = eventName; + if (eventNameDispatchConfigs.hasOwnProperty(eventName$jscomp$0)) + throw Error( + "EventPluginHub: More than one plugin attempted to publish the same event name, `" + + eventName$jscomp$0 + + "`." + ); + eventNameDispatchConfigs[eventName$jscomp$0] = dispatchConfig; + var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; + if (phasedRegistrationNames) { + for (JSCompiler_inline_result in phasedRegistrationNames) + phasedRegistrationNames.hasOwnProperty( + JSCompiler_inline_result + ) && + publishRegistrationName( + phasedRegistrationNames[JSCompiler_inline_result], + pluginModule$jscomp$0, + eventName$jscomp$0 + ); + JSCompiler_inline_result = !0; + } else + dispatchConfig.registrationName + ? (publishRegistrationName( + dispatchConfig.registrationName, + pluginModule$jscomp$0, + eventName$jscomp$0 + ), + (JSCompiler_inline_result = !0)) + : (JSCompiler_inline_result = !1); + if (!JSCompiler_inline_result) + throw Error( + "EventPluginRegistry: Failed to publish event `" + + eventName + + "` for plugin `" + + pluginName + + "`." + ); + } + } + } } -function traverseTwoPhase(inst, fn, arg) { - for (var path = []; inst; ) path.push(inst), (inst = getParent(inst)); - for (inst = path.length; 0 < inst--; ) fn(path[inst], "captured", arg); - for (inst = 0; inst < path.length; inst++) fn(path[inst], "bubbled", arg); +function publishRegistrationName(registrationName, pluginModule) { + if (registrationNameModules[registrationName]) + throw Error( + "EventPluginHub: More than one plugin attempted to publish the same registration name, `" + + registrationName + + "`." + ); + registrationNameModules[registrationName] = pluginModule; } +var plugins = [], + eventNameDispatchConfigs = {}, + registrationNameModules = {}; function invokeGuardedCallbackImpl(name, func, context, a, b, c, d, e, f) { var funcArgs = Array.prototype.slice.call(arguments, 3); try { @@ -96,6 +164,74 @@ function executeDirectDispatch(event) { event._dispatchInstances = null; return dispatchListener; } +function accumulateInto(current, next) { + if (null == next) + throw Error( + "accumulateInto(...): Accumulated items must not be null or undefined." + ); + if (null == current) return next; + if (Array.isArray(current)) { + if (Array.isArray(next)) return current.push.apply(current, next), current; + current.push(next); + return current; + } + return Array.isArray(next) ? [current].concat(next) : [current, next]; +} +function forEachAccumulated(arr, cb, scope) { + Array.isArray(arr) ? arr.forEach(cb, scope) : arr && cb.call(scope, arr); +} +var eventQueue = null; +function executeDispatchesAndReleaseTopLevel(e) { + if (e) { + var dispatchListeners = e._dispatchListeners, + dispatchInstances = e._dispatchInstances; + if (Array.isArray(dispatchListeners)) + for ( + var i = 0; + i < dispatchListeners.length && !e.isPropagationStopped(); + i++ + ) + executeDispatch(e, dispatchListeners[i], dispatchInstances[i]); + else + dispatchListeners && + executeDispatch(e, dispatchListeners, dispatchInstances); + e._dispatchListeners = null; + e._dispatchInstances = null; + e.isPersistent() || e.constructor.release(e); + } +} +var injection = { + injectEventPluginOrder: function(injectedEventPluginOrder) { + if (eventPluginOrder) + throw Error( + "EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React." + ); + eventPluginOrder = Array.prototype.slice.call(injectedEventPluginOrder); + recomputePluginOrdering(); + }, + injectEventPluginsByName: function(injectedNamesToPlugins) { + var isOrderingDirty = !1, + pluginName; + for (pluginName in injectedNamesToPlugins) + if (injectedNamesToPlugins.hasOwnProperty(pluginName)) { + var pluginModule = injectedNamesToPlugins[pluginName]; + if ( + !namesToPlugins.hasOwnProperty(pluginName) || + namesToPlugins[pluginName] !== pluginModule + ) { + if (namesToPlugins[pluginName]) + throw Error( + "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + + pluginName + + "`." + ); + namesToPlugins[pluginName] = pluginModule; + isOrderingDirty = !0; + } + } + isOrderingDirty && recomputePluginOrdering(); + } +}; function getListener(inst, registrationName) { var listener = inst.stateNode; if (!listener) return null; @@ -113,7 +249,6 @@ function getListener(inst, registrationName) { case "onMouseMoveCapture": case "onMouseUp": case "onMouseUpCapture": - case "onMouseEnter": (props = !props.disabled) || ((inst = inst.type), (props = !( @@ -138,21 +273,15 @@ function getListener(inst, registrationName) { ); return listener; } -function accumulateInto(current, next) { - if (null == next) - throw Error( - "accumulateInto(...): Accumulated items must not be null or undefined." - ); - if (null == current) return next; - if (Array.isArray(current)) { - if (Array.isArray(next)) return current.push.apply(current, next), current; - current.push(next); - return current; - } - return Array.isArray(next) ? [current].concat(next) : [current, next]; +function getParent(inst) { + do inst = inst.return; + while (inst && 5 !== inst.tag); + return inst ? inst : null; } -function forEachAccumulated(arr, cb, scope) { - Array.isArray(arr) ? arr.forEach(cb, scope) : arr && cb.call(scope, arr); +function traverseTwoPhase(inst, fn, arg) { + for (var path = []; inst; ) path.push(inst), (inst = getParent(inst)); + for (inst = path.length; 0 < inst--; ) fn(path[inst], "captured", arg); + for (inst = 0; inst < path.length; inst++) fn(path[inst], "bubbled", arg); } function accumulateDirectionalDispatches(inst, phase, event) { if ( @@ -220,8 +349,8 @@ function SyntheticEvent( ((targetInst = dispatchConfig[propName]) ? (this[propName] = targetInst(nativeEvent)) : "target" === propName - ? (this.target = nativeEventTarget) - : (this[propName] = nativeEvent[propName])); + ? (this.target = nativeEventTarget) + : (this[propName] = nativeEvent[propName])); this.isDefaultPrevented = (null != nativeEvent.defaultPrevented ? nativeEvent.defaultPrevented : !1 === nativeEvent.returnValue) @@ -374,27 +503,53 @@ function recordTouchStart(touch) { } function recordTouchMove(touch) { var touchRecord = touchBank[getTouchIdentifier(touch)]; - touchRecord && - ((touchRecord.touchActive = !0), - (touchRecord.previousPageX = touchRecord.currentPageX), - (touchRecord.previousPageY = touchRecord.currentPageY), - (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), - (touchRecord.currentPageX = touch.pageX), - (touchRecord.currentPageY = touch.pageY), - (touchRecord.currentTimeStamp = timestampForTouch(touch)), - (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))); + touchRecord + ? ((touchRecord.touchActive = !0), + (touchRecord.previousPageX = touchRecord.currentPageX), + (touchRecord.previousPageY = touchRecord.currentPageY), + (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), + (touchRecord.currentPageX = touch.pageX), + (touchRecord.currentPageY = touch.pageY), + (touchRecord.currentTimeStamp = timestampForTouch(touch)), + (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))) + : console.warn( + "Cannot record touch move without a touch start.\nTouch Move: %s\n", + "Touch Bank: %s", + printTouch(touch), + printTouchBank() + ); } function recordTouchEnd(touch) { var touchRecord = touchBank[getTouchIdentifier(touch)]; - touchRecord && - ((touchRecord.touchActive = !1), - (touchRecord.previousPageX = touchRecord.currentPageX), - (touchRecord.previousPageY = touchRecord.currentPageY), - (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), - (touchRecord.currentPageX = touch.pageX), - (touchRecord.currentPageY = touch.pageY), - (touchRecord.currentTimeStamp = timestampForTouch(touch)), - (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))); + touchRecord + ? ((touchRecord.touchActive = !1), + (touchRecord.previousPageX = touchRecord.currentPageX), + (touchRecord.previousPageY = touchRecord.currentPageY), + (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), + (touchRecord.currentPageX = touch.pageX), + (touchRecord.currentPageY = touch.pageY), + (touchRecord.currentTimeStamp = timestampForTouch(touch)), + (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))) + : console.warn( + "Cannot record touch end without a touch start.\nTouch End: %s\n", + "Touch Bank: %s", + printTouch(touch), + printTouchBank() + ); +} +function printTouch(touch) { + return JSON.stringify({ + identifier: touch.identifier, + pageX: touch.pageX, + pageY: touch.pageY, + timestamp: timestampForTouch(touch) + }); +} +function printTouchBank() { + var printed = JSON.stringify(touchBank.slice(0, 20)); + 20 < touchBank.length && + (printed += " (original size: " + touchBank.length + ")"); + return printed; } var ResponderTouchHistoryStore = { recordTouchTrack: function(topLevelType, nativeEvent) { @@ -434,10 +589,10 @@ function accumulate(current, next) { return null == current ? next : Array.isArray(current) - ? current.concat(next) - : Array.isArray(next) - ? [current].concat(next) - : [current, next]; + ? current.concat(next) + : Array.isArray(next) + ? [current].concat(next) + : [current, next]; } var responderInst = null, trackedTouchCount = 0; @@ -527,7 +682,13 @@ var eventTypes = { "topTouchCancel" === topLevelType ) if (0 <= trackedTouchCount) --trackedTouchCount; - else return null; + else + return ( + console.warn( + "Ended a touch event which was not counted in `trackedTouchCount`." + ), + null + ); ResponderTouchHistoryStore.recordTouchTrack(topLevelType, nativeEvent); if ( targetInst && @@ -539,10 +700,10 @@ var eventTypes = { var shouldSetEventType = isStartish(topLevelType) ? eventTypes.startShouldSetResponder : isMoveish(topLevelType) - ? eventTypes.moveShouldSetResponder - : "topSelectionChange" === topLevelType - ? eventTypes.selectionChangeShouldSetResponder - : eventTypes.scrollShouldSetResponder; + ? eventTypes.moveShouldSetResponder + : "topSelectionChange" === topLevelType + ? eventTypes.selectionChangeShouldSetResponder + : eventTypes.scrollShouldSetResponder; if (responderInst) b: { var JSCompiler_temp = responderInst; @@ -696,10 +857,10 @@ var eventTypes = { (shouldSetEventType = shouldSetEventType ? eventTypes.responderStart : JSCompiler_temp - ? eventTypes.responderMove - : targetInst - ? eventTypes.responderEnd - : null) + ? eventTypes.responderMove + : targetInst + ? eventTypes.responderEnd + : null) ) (shouldSetEventType = ResponderSyntheticEvent.getPooled( shouldSetEventType, @@ -762,8 +923,8 @@ var eventTypes = { (topLevelType = shouldSetEventType ? eventTypes.responderTerminate : topLevelType - ? eventTypes.responderRelease - : null) + ? eventTypes.responderRelease + : null) ) (nativeEvent = ResponderSyntheticEvent.getPooled( topLevelType, @@ -787,160 +948,50 @@ var eventTypes = { } } }, - eventPluginOrder = null, - namesToPlugins = {}; -function recomputePluginOrdering() { - if (eventPluginOrder) - for (var pluginName in namesToPlugins) { - var pluginModule = namesToPlugins[pluginName], - pluginIndex = eventPluginOrder.indexOf(pluginName); - if (!(-1 < pluginIndex)) - throw Error( - "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + - pluginName + - "`." - ); - if (!plugins[pluginIndex]) { - if (!pluginModule.extractEvents) - throw Error( - "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + - pluginName + - "` does not." - ); - plugins[pluginIndex] = pluginModule; - pluginIndex = pluginModule.eventTypes; - for (var eventName in pluginIndex) { - var JSCompiler_inline_result = void 0; - var dispatchConfig = pluginIndex[eventName], - pluginModule$jscomp$0 = pluginModule, - eventName$jscomp$0 = eventName; - if (eventNameDispatchConfigs.hasOwnProperty(eventName$jscomp$0)) - throw Error( - "EventPluginRegistry: More than one plugin attempted to publish the same event name, `" + - eventName$jscomp$0 + - "`." - ); - eventNameDispatchConfigs[eventName$jscomp$0] = dispatchConfig; - var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; - if (phasedRegistrationNames) { - for (JSCompiler_inline_result in phasedRegistrationNames) - phasedRegistrationNames.hasOwnProperty( - JSCompiler_inline_result - ) && - publishRegistrationName( - phasedRegistrationNames[JSCompiler_inline_result], - pluginModule$jscomp$0, - eventName$jscomp$0 - ); - JSCompiler_inline_result = !0; - } else - dispatchConfig.registrationName - ? (publishRegistrationName( - dispatchConfig.registrationName, - pluginModule$jscomp$0, - eventName$jscomp$0 - ), - (JSCompiler_inline_result = !0)) - : (JSCompiler_inline_result = !1); - if (!JSCompiler_inline_result) - throw Error( - "EventPluginRegistry: Failed to publish event `" + - eventName + - "` for plugin `" + - pluginName + - "`." - ); - } - } - } -} -function publishRegistrationName(registrationName, pluginModule) { - if (registrationNameModules[registrationName]) - throw Error( - "EventPluginRegistry: More than one plugin attempted to publish the same registration name, `" + - registrationName + - "`." - ); - registrationNameModules[registrationName] = pluginModule; -} -var plugins = [], - eventNameDispatchConfigs = {}, - registrationNameModules = {}, customBubblingEventTypes = ReactNativePrivateInterface.ReactNativeViewConfigRegistry .customBubblingEventTypes, customDirectEventTypes = ReactNativePrivateInterface.ReactNativeViewConfigRegistry .customDirectEventTypes; -if (eventPluginOrder) - throw Error( - "EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React." - ); -eventPluginOrder = Array.prototype.slice.call([ +injection.injectEventPluginOrder([ "ResponderEventPlugin", "ReactNativeBridgeEventPlugin" ]); -recomputePluginOrdering(); -var injectedNamesToPlugins$jscomp$inline_92 = { - ResponderEventPlugin: ResponderEventPlugin, - ReactNativeBridgeEventPlugin: { - eventTypes: {}, - extractEvents: function( - topLevelType, - targetInst, - nativeEvent, - nativeEventTarget - ) { - if (null == targetInst) return null; - var bubbleDispatchConfig = customBubblingEventTypes[topLevelType], - directDispatchConfig = customDirectEventTypes[topLevelType]; - if (!bubbleDispatchConfig && !directDispatchConfig) - throw Error( - 'Unsupported top level event type "' + topLevelType + '" dispatched' - ); - topLevelType = SyntheticEvent.getPooled( - bubbleDispatchConfig || directDispatchConfig, - targetInst, - nativeEvent, - nativeEventTarget - ); - if (bubbleDispatchConfig) - forEachAccumulated(topLevelType, accumulateTwoPhaseDispatchesSingle); - else if (directDispatchConfig) - forEachAccumulated(topLevelType, accumulateDirectDispatchesSingle); - else return null; - return topLevelType; - } - } - }, - isOrderingDirty$jscomp$inline_93 = !1, - pluginName$jscomp$inline_94; -for (pluginName$jscomp$inline_94 in injectedNamesToPlugins$jscomp$inline_92) - if ( - injectedNamesToPlugins$jscomp$inline_92.hasOwnProperty( - pluginName$jscomp$inline_94 - ) - ) { - var pluginModule$jscomp$inline_95 = - injectedNamesToPlugins$jscomp$inline_92[pluginName$jscomp$inline_94]; - if ( - !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_94) || - namesToPlugins[pluginName$jscomp$inline_94] !== - pluginModule$jscomp$inline_95 +injection.injectEventPluginsByName({ + ResponderEventPlugin: ResponderEventPlugin, + ReactNativeBridgeEventPlugin: { + eventTypes: {}, + extractEvents: function( + topLevelType, + targetInst, + nativeEvent, + nativeEventTarget ) { - if (namesToPlugins[pluginName$jscomp$inline_94]) + if (null == targetInst) return null; + var bubbleDispatchConfig = customBubblingEventTypes[topLevelType], + directDispatchConfig = customDirectEventTypes[topLevelType]; + if (!bubbleDispatchConfig && !directDispatchConfig) throw Error( - "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - pluginName$jscomp$inline_94 + - "`." + 'Unsupported top level event type "' + topLevelType + '" dispatched' ); - namesToPlugins[ - pluginName$jscomp$inline_94 - ] = pluginModule$jscomp$inline_95; - isOrderingDirty$jscomp$inline_93 = !0; + topLevelType = SyntheticEvent.getPooled( + bubbleDispatchConfig || directDispatchConfig, + targetInst, + nativeEvent, + nativeEventTarget + ); + if (bubbleDispatchConfig) + forEachAccumulated(topLevelType, accumulateTwoPhaseDispatchesSingle); + else if (directDispatchConfig) + forEachAccumulated(topLevelType, accumulateDirectDispatchesSingle); + else return null; + return topLevelType; } } -isOrderingDirty$jscomp$inline_93 && recomputePluginOrdering(); +}); +var enableNativeTargetAsInstance = require("../shims/ReactFeatureFlags") + .enableNativeTargetAsInstance; function getInstanceFromInstance(instanceHandle) { return instanceHandle; } @@ -949,8 +1000,14 @@ getFiberCurrentPropsFromNode = function(inst) { }; getInstanceFromNode = getInstanceFromInstance; getNodeFromInstance = function(inst) { - inst = inst.stateNode.canonical; - if (!inst._nativeTag) throw Error("All native instances should have a tag."); + if (enableNativeTargetAsInstance) { + inst = inst.stateNode.canonical; + if (!inst._nativeTag) + throw Error("All native instances should have a tag."); + return inst; + } + inst = inst.stateNode.canonical._nativeTag; + if (!inst) throw Error("All native instances should have a tag."); return inst; }; ResponderEventPlugin.injection.injectGlobalResponderHandler({ @@ -986,9 +1043,11 @@ var hasSymbol = "function" === typeof Symbol && Symbol.for, ? Symbol.for("react.suspense_list") : 60120, REACT_MEMO_TYPE = hasSymbol ? Symbol.for("react.memo") : 60115, - REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 60116, - REACT_BLOCK_TYPE = hasSymbol ? Symbol.for("react.block") : 60121, - MAYBE_ITERATOR_SYMBOL = "function" === typeof Symbol && Symbol.iterator; + REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 60116; +hasSymbol && Symbol.for("react.fundamental"); +hasSymbol && Symbol.for("react.responder"); +hasSymbol && Symbol.for("react.scope"); +var MAYBE_ITERATOR_SYMBOL = "function" === typeof Symbol && Symbol.iterator; function getIteratorFn(maybeIterable) { if (null === maybeIterable || "object" !== typeof maybeIterable) return null; maybeIterable = @@ -998,10 +1057,9 @@ function getIteratorFn(maybeIterable) { } function initializeLazyComponentType(lazyComponent) { if (-1 === lazyComponent._status) { - var ctor = lazyComponent._result; - ctor || (ctor = lazyComponent._ctor); - ctor = ctor(); lazyComponent._status = 0; + var ctor = lazyComponent._ctor; + ctor = ctor(); lazyComponent._result = ctor; ctor.then( function(moduleObject) { @@ -1038,9 +1096,9 @@ function getComponentName(type) { if ("object" === typeof type) switch (type.$$typeof) { case REACT_CONTEXT_TYPE: - return (type.displayName || "Context") + ".Consumer"; + return "Context.Consumer"; case REACT_PROVIDER_TYPE: - return (type._context.displayName || "Context") + ".Provider"; + return "Context.Provider"; case REACT_FORWARD_REF_TYPE: var innerType = type.render; innerType = innerType.displayName || innerType.name || ""; @@ -1050,8 +1108,6 @@ function getComponentName(type) { ); case REACT_MEMO_TYPE: return getComponentName(type.type); - case REACT_BLOCK_TYPE: - return getComponentName(type.render); case REACT_LAZY_TYPE: if ((type = 1 === type._status ? type._result : null)) return getComponentName(type); @@ -1241,8 +1297,8 @@ function diffNestedProperty( return nextProp ? addNestedProperty(updatePayload, nextProp, validAttributes) : prevProp - ? clearNestedProperty(updatePayload, prevProp, validAttributes) - : updatePayload; + ? clearNestedProperty(updatePayload, prevProp, validAttributes) + : updatePayload; if (!Array.isArray(prevProp) && !Array.isArray(nextProp)) return diffProperties(updatePayload, prevProp, nextProp, validAttributes); if (Array.isArray(prevProp) && Array.isArray(nextProp)) { @@ -1403,9 +1459,18 @@ function diffProperties(updatePayload, prevProps, nextProps, validAttributes) { ))))); return updatePayload; } +var restoreTarget = null, + restoreQueue = null; +function restoreStateOfTarget(target) { + if (getInstanceFromNode(target)) + throw Error( + "setRestoreImplementation() needs to be called to handle a target for controlled events. This error is likely caused by a bug in React. Please file an issue." + ); +} function batchedUpdatesImpl(fn, bookkeeping) { return fn(bookkeeping); } +function flushDiscreteUpdatesImpl() {} var isInsideEventHandler = !1; function batchedUpdates(fn, bookkeeping) { if (isInsideEventHandler) return fn(bookkeeping); @@ -1413,35 +1478,48 @@ function batchedUpdates(fn, bookkeeping) { try { return batchedUpdatesImpl(fn, bookkeeping); } finally { - isInsideEventHandler = !1; - } -} -var eventQueue = null; -function executeDispatchesAndReleaseTopLevel(e) { - if (e) { - var dispatchListeners = e._dispatchListeners, - dispatchInstances = e._dispatchInstances; - if (Array.isArray(dispatchListeners)) - for ( - var i = 0; - i < dispatchListeners.length && !e.isPropagationStopped(); - i++ + if ( + ((isInsideEventHandler = !1), + null !== restoreTarget || null !== restoreQueue) + ) + if ( + (flushDiscreteUpdatesImpl(), + restoreTarget && + ((bookkeeping = restoreTarget), + (fn = restoreQueue), + (restoreQueue = restoreTarget = null), + restoreStateOfTarget(bookkeeping), + fn)) ) - executeDispatch(e, dispatchListeners[i], dispatchInstances[i]); - else - dispatchListeners && - executeDispatch(e, dispatchListeners, dispatchInstances); - e._dispatchListeners = null; - e._dispatchInstances = null; - e.isPersistent() || e.constructor.release(e); + for (bookkeeping = 0; bookkeeping < fn.length; bookkeeping++) + restoreStateOfTarget(fn[bookkeeping]); } } +function _inheritsLoose(subClass, superClass) { + subClass.prototype = Object.create(superClass.prototype); + subClass.prototype.constructor = subClass; + subClass.__proto__ = superClass; +} +(function(_React$Component) { + function ReactNativeComponent() { + return _React$Component.apply(this, arguments) || this; + } + _inheritsLoose(ReactNativeComponent, _React$Component); + var _proto = ReactNativeComponent.prototype; + _proto.blur = function() {}; + _proto.focus = function() {}; + _proto.measure = function() {}; + _proto.measureInWindow = function() {}; + _proto.measureLayout = function() {}; + _proto.setNativeProps = function() {}; + return ReactNativeComponent; +})(React.Component); +new Map(); function dispatchEvent(target, topLevelType, nativeEvent) { var eventTarget = null; - if (null != target) { - var stateNode = target.stateNode; - null != stateNode && (eventTarget = stateNode.canonical); - } + enableNativeTargetAsInstance + ? null != target && (eventTarget = target.stateNode.canonical) + : (eventTarget = nativeEvent.target); batchedUpdates(function() { var events = eventTarget; for (var events$jscomp$0 = null, i = 0; i < plugins.length; i++) { @@ -1479,21 +1557,21 @@ function shim$1() { "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." ); } -var _nativeFabricUIManage = nativeFabricUIManager, - createNode = _nativeFabricUIManage.createNode, - cloneNode = _nativeFabricUIManage.cloneNode, - cloneNodeWithNewChildren = _nativeFabricUIManage.cloneNodeWithNewChildren, +var _nativeFabricUIManage$1 = nativeFabricUIManager, + createNode = _nativeFabricUIManage$1.createNode, + cloneNode = _nativeFabricUIManage$1.cloneNode, + cloneNodeWithNewChildren = _nativeFabricUIManage$1.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, + _nativeFabricUIManage$1.cloneNodeWithNewChildrenAndProps, + cloneNodeWithNewProps = _nativeFabricUIManage$1.cloneNodeWithNewProps, + createChildNodeSet = _nativeFabricUIManage$1.createChildSet, + appendChildNode = _nativeFabricUIManage$1.appendChild, + appendChildNodeToSet = _nativeFabricUIManage$1.appendChildToSet, + completeRoot = _nativeFabricUIManage$1.completeRoot, + registerEventHandler = _nativeFabricUIManage$1.registerEventHandler, + fabricMeasure = _nativeFabricUIManage$1.measure, + fabricMeasureInWindow = _nativeFabricUIManage$1.measureInWindow, + fabricMeasureLayout = _nativeFabricUIManage$1.measureLayout, getViewConfigForType = ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get, nextReactTag = 2; @@ -1512,10 +1590,10 @@ var ReactFabricHostComponent = (function() { } var _proto = ReactFabricHostComponent.prototype; _proto.blur = function() { - ReactNativePrivateInterface.TextInputState.blurTextInput(this); + ReactNativePrivateInterface.TextInputState.blurTextInput(this._nativeTag); }; _proto.focus = function() { - ReactNativePrivateInterface.TextInputState.focusTextInput(this); + ReactNativePrivateInterface.TextInputState.focusTextInput(this._nativeTag); }; _proto.measure = function(callback) { fabricMeasure( @@ -1577,6 +1655,44 @@ function cloneHiddenInstance(instance) { canonical: instance.canonical }; } +var BEFORE_SLASH_RE = /^(.*)[\\\/]/; +function getStackByFiberInDevAndProd(workInProgress) { + var info = ""; + do { + a: switch (workInProgress.tag) { + case 3: + case 4: + case 6: + case 7: + case 10: + case 9: + var JSCompiler_inline_result = ""; + break a; + default: + var owner = workInProgress._debugOwner, + source = workInProgress._debugSource, + name = getComponentName(workInProgress.type); + JSCompiler_inline_result = null; + owner && (JSCompiler_inline_result = getComponentName(owner.type)); + owner = name; + name = ""; + source + ? (name = + " (at " + + source.fileName.replace(BEFORE_SLASH_RE, "") + + ":" + + source.lineNumber + + ")") + : JSCompiler_inline_result && + (name = " (created by " + JSCompiler_inline_result + ")"); + JSCompiler_inline_result = "\n in " + (owner || "Unknown") + name; + } + info += JSCompiler_inline_result; + workInProgress = workInProgress.return; + } while (workInProgress); + return info; +} +new Set(); var valueStack = [], index = -1; function pop(cursor) { @@ -1614,17 +1730,21 @@ function isContextProvider(type) { type = type.childContextTypes; return null !== type && void 0 !== type; } -function popContext() { - pop(didPerformWorkStackCursor); - pop(contextStackCursor); +function popContext(fiber) { + pop(didPerformWorkStackCursor, fiber); + pop(contextStackCursor, fiber); +} +function popTopLevelContextObject(fiber) { + pop(didPerformWorkStackCursor, fiber); + pop(contextStackCursor, fiber); } 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); + push(contextStackCursor, context, fiber); + push(didPerformWorkStackCursor, didChange, fiber); } function processChildContext(fiber, type, parentContext) { var instance = fiber.stateNode; @@ -1642,13 +1762,17 @@ function processChildContext(fiber, type, parentContext) { return Object.assign({}, parentContext, {}, instance); } function pushContextProvider(workInProgress) { - workInProgress = - ((workInProgress = workInProgress.stateNode) && - workInProgress.__reactInternalMemoizedMergedChildContext) || + var instance = workInProgress.stateNode; + instance = + (instance && instance.__reactInternalMemoizedMergedChildContext) || emptyContextObject; previousContext = contextStackCursor.current; - push(contextStackCursor, workInProgress); - push(didPerformWorkStackCursor, didPerformWorkStackCursor.current); + push(contextStackCursor, instance, workInProgress); + push( + didPerformWorkStackCursor, + didPerformWorkStackCursor.current, + workInProgress + ); return !0; } function invalidateContextProvider(workInProgress, type, didChange) { @@ -1658,17 +1782,13 @@ function invalidateContextProvider(workInProgress, type, didChange) { "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); + ? ((type = processChildContext(workInProgress, type, previousContext)), + (instance.__reactInternalMemoizedMergedChildContext = type), + pop(didPerformWorkStackCursor, workInProgress), + pop(contextStackCursor, workInProgress), + push(contextStackCursor, type, workInProgress)) + : pop(didPerformWorkStackCursor, workInProgress); + push(didPerformWorkStackCursor, didChange, workInProgress); } var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback, @@ -1735,7 +1855,7 @@ function reactPriorityToSchedulerPriority(reactPriorityLevel) { throw Error("Unknown priority level."); } } -function runWithPriority(reactPriorityLevel, fn) { +function runWithPriority$1(reactPriorityLevel, fn) { reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); return Scheduler_runWithPriority(reactPriorityLevel, fn); } @@ -1767,7 +1887,7 @@ function flushSyncCallbackQueueImpl() { var i = 0; try { var queue = syncQueue; - runWithPriority(99, function() { + runWithPriority$1(99, function() { for (; i < queue.length; i++) { var callback = queue[i]; do callback = callback(!0); @@ -1795,18 +1915,18 @@ function inferPriorityFromExpirationTime(currentTime, expirationTime) { return 0 >= currentTime ? 99 : 250 >= currentTime - ? 98 - : 5250 >= currentTime - ? 97 - : 95; + ? 98 + : 5250 >= currentTime + ? 97 + : 95; } function is(x, y) { return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y); } -var objectIs = "function" === typeof Object.is ? Object.is : is, +var is$1 = "function" === typeof Object.is ? Object.is : is, hasOwnProperty = Object.prototype.hasOwnProperty; function shallowEqual(objA, objB) { - if (objectIs(objA, objB)) return !0; + if (is$1(objA, objB)) return !0; if ( "object" !== typeof objA || null === objA || @@ -1820,48 +1940,11 @@ function shallowEqual(objA, objB) { for (keysB = 0; keysB < keysA.length; keysB++) if ( !hasOwnProperty.call(objB, keysA[keysB]) || - !objectIs(objA[keysA[keysB]], objB[keysA[keysB]]) + !is$1(objA[keysA[keysB]], objB[keysA[keysB]]) ) return !1; return !0; } -var BEFORE_SLASH_RE = /^(.*)[\\\/]/; -function getStackByFiberInDevAndProd(workInProgress) { - var info = ""; - do { - a: switch (workInProgress.tag) { - case 3: - case 4: - case 6: - case 7: - case 10: - case 9: - var JSCompiler_inline_result = ""; - break a; - default: - var owner = workInProgress._debugOwner, - source = workInProgress._debugSource, - name = getComponentName(workInProgress.type); - JSCompiler_inline_result = null; - owner && (JSCompiler_inline_result = getComponentName(owner.type)); - owner = name; - name = ""; - source - ? (name = - " (at " + - source.fileName.replace(BEFORE_SLASH_RE, "") + - ":" + - source.lineNumber + - ")") - : JSCompiler_inline_result && - (name = " (created by " + JSCompiler_inline_result + ")"); - JSCompiler_inline_result = "\n in " + (owner || "Unknown") + name; - } - info += JSCompiler_inline_result; - workInProgress = workInProgress.return; - } while (workInProgress); - return info; -} function resolveDefaultProps(Component, baseProps) { if (Component && Component.defaultProps) { baseProps = Object.assign({}, baseProps); @@ -1879,9 +1962,14 @@ var valueCursor = { current: null }, function resetContextDependencies() { lastContextWithAllBitsObserved = lastContextDependency = currentlyRenderingFiber = null; } +function pushProvider(providerFiber, nextValue) { + var context = providerFiber.type._context; + push(valueCursor, context._currentValue2, providerFiber); + context._currentValue2 = nextValue; +} function popProvider(providerFiber) { var currentValue = valueCursor.current; - pop(valueCursor); + pop(valueCursor, providerFiber); providerFiber.type._context._currentValue2 = currentValue; } function scheduleWorkOnParentPath(parent, renderExpirationTime) { @@ -1936,195 +2024,237 @@ function readContext(context, observedBits) { return context._currentValue2; } var hasForceUpdate = !1; -function initializeUpdateQueue(fiber) { - fiber.updateQueue = { - baseState: fiber.memoizedState, - baseQueue: null, - shared: { pending: null }, - effects: null +function createUpdateQueue(baseState) { + return { + baseState: baseState, + firstUpdate: null, + lastUpdate: null, + firstCapturedUpdate: null, + lastCapturedUpdate: null, + firstEffect: null, + lastEffect: null, + firstCapturedEffect: null, + lastCapturedEffect: null }; } -function cloneUpdateQueue(current, workInProgress) { - current = current.updateQueue; - workInProgress.updateQueue === current && - (workInProgress.updateQueue = { - baseState: current.baseState, - baseQueue: current.baseQueue, - shared: current.shared, - effects: current.effects - }); +function cloneUpdateQueue(currentQueue) { + return { + baseState: currentQueue.baseState, + firstUpdate: currentQueue.firstUpdate, + lastUpdate: currentQueue.lastUpdate, + firstCapturedUpdate: null, + lastCapturedUpdate: null, + firstEffect: null, + lastEffect: null, + firstCapturedEffect: null, + lastCapturedEffect: null + }; } function createUpdate(expirationTime, suspenseConfig) { - expirationTime = { + return { expirationTime: expirationTime, suspenseConfig: suspenseConfig, tag: 0, payload: null, callback: null, - next: null + next: null, + nextEffect: null }; - return (expirationTime.next = expirationTime); +} +function appendUpdateToQueue(queue, update) { + null === queue.lastUpdate + ? (queue.firstUpdate = queue.lastUpdate = update) + : ((queue.lastUpdate.next = update), (queue.lastUpdate = update)); } function enqueueUpdate(fiber, update) { - 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; - } + var alternate = fiber.alternate; + if (null === alternate) { + var queue1 = fiber.updateQueue; + var queue2 = null; + null === queue1 && + (queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState)); + } else + (queue1 = fiber.updateQueue), + (queue2 = alternate.updateQueue), + null === queue1 + ? null === queue2 + ? ((queue1 = fiber.updateQueue = createUpdateQueue( + fiber.memoizedState + )), + (queue2 = alternate.updateQueue = createUpdateQueue( + alternate.memoizedState + ))) + : (queue1 = fiber.updateQueue = cloneUpdateQueue(queue2)) + : null === queue2 && + (queue2 = alternate.updateQueue = cloneUpdateQueue(queue1)); + null === queue2 || queue1 === queue2 + ? appendUpdateToQueue(queue1, update) + : null === queue1.lastUpdate || null === queue2.lastUpdate + ? (appendUpdateToQueue(queue1, update), + appendUpdateToQueue(queue2, update)) + : (appendUpdateToQueue(queue1, update), (queue2.lastUpdate = update)); } function enqueueCapturedUpdate(workInProgress, update) { + var workInProgressQueue = workInProgress.updateQueue; + workInProgressQueue = + null === workInProgressQueue + ? (workInProgress.updateQueue = createUpdateQueue( + workInProgress.memoizedState + )) + : ensureWorkInProgressQueueIsAClone(workInProgress, workInProgressQueue); + null === workInProgressQueue.lastCapturedUpdate + ? (workInProgressQueue.firstCapturedUpdate = workInProgressQueue.lastCapturedUpdate = update) + : ((workInProgressQueue.lastCapturedUpdate.next = update), + (workInProgressQueue.lastCapturedUpdate = update)); +} +function ensureWorkInProgressQueueIsAClone(workInProgress, queue) { var current = workInProgress.alternate; - null !== current && cloneUpdateQueue(current, workInProgress); - workInProgress = workInProgress.updateQueue; - current = workInProgress.baseQueue; - null === current - ? ((workInProgress.baseQueue = update.next = update), - (update.next = update)) - : ((update.next = current.next), (current.next = update)); + null !== current && + queue === current.updateQueue && + (queue = workInProgress.updateQueue = cloneUpdateQueue(queue)); + return queue; +} +function getStateFromUpdate( + workInProgress, + queue, + update, + prevState, + nextProps, + instance +) { + switch (update.tag) { + case 1: + return ( + (workInProgress = update.payload), + "function" === typeof workInProgress + ? workInProgress.call(instance, prevState, nextProps) + : workInProgress + ); + case 3: + workInProgress.effectTag = (workInProgress.effectTag & -4097) | 64; + case 0: + workInProgress = update.payload; + nextProps = + "function" === typeof workInProgress + ? workInProgress.call(instance, prevState, nextProps) + : workInProgress; + if (null === nextProps || void 0 === nextProps) break; + return Object.assign({}, prevState, nextProps); + case 2: + hasForceUpdate = !0; + } + return prevState; } function processUpdateQueue( - workInProgress$jscomp$0, + workInProgress, + queue, props, instance, renderExpirationTime ) { - var queue = workInProgress$jscomp$0.updateQueue; hasForceUpdate = !1; - var baseQueue = queue.baseQueue, - pendingQueue = queue.shared.pending; - if (null !== pendingQueue) { - if (null !== baseQueue) { - var baseFirst = baseQueue.next; - baseQueue.next = pendingQueue.next; - pendingQueue.next = baseFirst; - } - baseQueue = pendingQueue; - queue.shared.pending = null; - baseFirst = workInProgress$jscomp$0.alternate; - null !== baseFirst && - ((baseFirst = baseFirst.updateQueue), - null !== baseFirst && (baseFirst.baseQueue = pendingQueue)); - } - if (null !== baseQueue) { - baseFirst = baseQueue.next; - var newState = queue.baseState, + queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue); + for ( + var newBaseState = queue.baseState, + newFirstUpdate = null, newExpirationTime = 0, - newBaseState = null, - newBaseQueueFirst = null, - newBaseQueueLast = null; - if (null !== baseFirst) { - var update = baseFirst; - do { - pendingQueue = update.expirationTime; - if (pendingQueue < renderExpirationTime) { - var clone = { - expirationTime: update.expirationTime, - suspenseConfig: update.suspenseConfig, - tag: update.tag, - payload: update.payload, - callback: update.callback, - next: null - }; - null === newBaseQueueLast - ? ((newBaseQueueFirst = newBaseQueueLast = clone), - (newBaseState = newState)) - : (newBaseQueueLast = newBaseQueueLast.next = clone); - pendingQueue > newExpirationTime && - (newExpirationTime = pendingQueue); - } else { - null !== newBaseQueueLast && - (newBaseQueueLast = newBaseQueueLast.next = { - expirationTime: 1073741823, - suspenseConfig: update.suspenseConfig, - tag: update.tag, - payload: update.payload, - callback: update.callback, - next: null - }); - markRenderEventTimeAndConfig(pendingQueue, update.suspenseConfig); - a: { - var workInProgress = workInProgress$jscomp$0, - update$jscomp$0 = update; - pendingQueue = props; - clone = instance; - switch (update$jscomp$0.tag) { - case 1: - workInProgress = update$jscomp$0.payload; - if ("function" === typeof workInProgress) { - newState = workInProgress.call(clone, newState, pendingQueue); - break a; - } - newState = workInProgress; - break a; - case 3: - workInProgress.effectTag = - (workInProgress.effectTag & -4097) | 64; - case 0: - workInProgress = update$jscomp$0.payload; - pendingQueue = - "function" === typeof workInProgress - ? workInProgress.call(clone, newState, pendingQueue) - : workInProgress; - if (null === pendingQueue || void 0 === pendingQueue) break a; - newState = Object.assign({}, newState, pendingQueue); - break a; - case 2: - hasForceUpdate = !0; - } - } - null !== update.callback && - ((workInProgress$jscomp$0.effectTag |= 32), - (pendingQueue = queue.effects), - null === pendingQueue - ? (queue.effects = [update]) - : pendingQueue.push(update)); - } - update = update.next; - if (null === update || update === baseFirst) - if (((pendingQueue = queue.shared.pending), null === pendingQueue)) - break; - else - (update = baseQueue.next = pendingQueue.next), - (pendingQueue.next = baseFirst), - (queue.baseQueue = baseQueue = pendingQueue), - (queue.shared.pending = null); - } while (1); - } - null === newBaseQueueLast - ? (newBaseState = newState) - : (newBaseQueueLast.next = newBaseQueueFirst); - queue.baseState = newBaseState; - queue.baseQueue = newBaseQueueLast; - markUnprocessedUpdateTime(newExpirationTime); - workInProgress$jscomp$0.expirationTime = newExpirationTime; - workInProgress$jscomp$0.memoizedState = newState; + update = queue.firstUpdate, + resultState = newBaseState; + null !== update; + + ) { + var updateExpirationTime = update.expirationTime; + updateExpirationTime < renderExpirationTime + ? (null === newFirstUpdate && + ((newFirstUpdate = update), (newBaseState = resultState)), + newExpirationTime < updateExpirationTime && + (newExpirationTime = updateExpirationTime)) + : (markRenderEventTimeAndConfig( + updateExpirationTime, + update.suspenseConfig + ), + (resultState = getStateFromUpdate( + workInProgress, + queue, + update, + resultState, + props, + instance + )), + null !== update.callback && + ((workInProgress.effectTag |= 32), + (update.nextEffect = null), + null === queue.lastEffect + ? (queue.firstEffect = queue.lastEffect = update) + : ((queue.lastEffect.nextEffect = update), + (queue.lastEffect = update)))); + update = update.next; } + updateExpirationTime = null; + for (update = queue.firstCapturedUpdate; null !== update; ) { + var _updateExpirationTime = update.expirationTime; + _updateExpirationTime < renderExpirationTime + ? (null === updateExpirationTime && + ((updateExpirationTime = update), + null === newFirstUpdate && (newBaseState = resultState)), + newExpirationTime < _updateExpirationTime && + (newExpirationTime = _updateExpirationTime)) + : ((resultState = getStateFromUpdate( + workInProgress, + queue, + update, + resultState, + props, + instance + )), + null !== update.callback && + ((workInProgress.effectTag |= 32), + (update.nextEffect = null), + null === queue.lastCapturedEffect + ? (queue.firstCapturedEffect = queue.lastCapturedEffect = update) + : ((queue.lastCapturedEffect.nextEffect = update), + (queue.lastCapturedEffect = update)))); + update = update.next; + } + null === newFirstUpdate && (queue.lastUpdate = null); + null === updateExpirationTime + ? (queue.lastCapturedUpdate = null) + : (workInProgress.effectTag |= 32); + null === newFirstUpdate && + null === updateExpirationTime && + (newBaseState = resultState); + queue.baseState = newBaseState; + queue.firstUpdate = newFirstUpdate; + queue.firstCapturedUpdate = updateExpirationTime; + markUnprocessedUpdateTime(newExpirationTime); + workInProgress.expirationTime = newExpirationTime; + workInProgress.memoizedState = resultState; } function commitUpdateQueue(finishedWork, finishedQueue, instance) { - finishedWork = finishedQueue.effects; - finishedQueue.effects = null; - if (null !== finishedWork) - for ( - finishedQueue = 0; - finishedQueue < finishedWork.length; - finishedQueue++ - ) { - var effect = finishedWork[finishedQueue], - callback = effect.callback; - if (null !== callback) { - effect.callback = null; - if ("function" !== typeof callback) - throw Error( - "Invalid argument passed as callback. Expected a function. Instead received: " + - callback - ); - callback.call(instance); - } + null !== finishedQueue.firstCapturedUpdate && + (null !== finishedQueue.lastUpdate && + ((finishedQueue.lastUpdate.next = finishedQueue.firstCapturedUpdate), + (finishedQueue.lastUpdate = finishedQueue.lastCapturedUpdate)), + (finishedQueue.firstCapturedUpdate = finishedQueue.lastCapturedUpdate = null)); + commitUpdateEffects(finishedQueue.firstEffect, instance); + finishedQueue.firstEffect = finishedQueue.lastEffect = null; + commitUpdateEffects(finishedQueue.firstCapturedEffect, instance); + finishedQueue.firstCapturedEffect = finishedQueue.lastCapturedEffect = null; +} +function commitUpdateEffects(effect, instance) { + for (; null !== effect; ) { + var callback = effect.callback; + if (null !== callback) { + effect.callback = null; + if ("function" !== typeof callback) + throw Error( + "Invalid argument passed as callback. Expected a function. Instead received: " + + callback + ); + callback.call(instance); } + effect = effect.nextEffect; + } } var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig, emptyRefsObject = new React.Component().refs; @@ -2141,8 +2271,10 @@ function applyDerivedStateFromProps( ? ctor : Object.assign({}, ctor, getDerivedStateFromProps); workInProgress.memoizedState = getDerivedStateFromProps; - 0 === workInProgress.expirationTime && - (workInProgress.updateQueue.baseState = getDerivedStateFromProps); + nextProps = workInProgress.updateQueue; + null !== nextProps && + 0 === workInProgress.expirationTime && + (nextProps.baseState = getDerivedStateFromProps); } var classComponentUpdater = { isMounted: function(component) { @@ -2161,7 +2293,7 @@ var classComponentUpdater = { null !== callback && (suspenseConfig.callback = callback); enqueueUpdate(inst, suspenseConfig); - scheduleWork(inst, currentTime); + scheduleUpdateOnFiber(inst, currentTime); }, enqueueReplaceState: function(inst, payload, callback) { inst = inst._reactInternalFiber; @@ -2175,7 +2307,7 @@ var classComponentUpdater = { null !== callback && (suspenseConfig.callback = callback); enqueueUpdate(inst, suspenseConfig); - scheduleWork(inst, currentTime); + scheduleUpdateOnFiber(inst, currentTime); }, enqueueForceUpdate: function(inst, callback) { inst = inst._reactInternalFiber; @@ -2188,7 +2320,7 @@ var classComponentUpdater = { null !== callback && (suspenseConfig.callback = callback); enqueueUpdate(inst, suspenseConfig); - scheduleWork(inst, currentTime); + scheduleUpdateOnFiber(inst, currentTime); } }; function checkShouldComponentUpdate( @@ -2204,8 +2336,8 @@ function checkShouldComponentUpdate( return "function" === typeof workInProgress.shouldComponentUpdate ? workInProgress.shouldComponentUpdate(newProps, newState, nextContext) : ctor.prototype && ctor.prototype.isPureReactComponent - ? !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState) - : !0; + ? !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState) + : !0; } function constructClassInstance(workInProgress, ctor, props) { var isLegacyContextConsumer = !1, @@ -2257,7 +2389,6 @@ function mountClassInstance( instance.props = newProps; instance.state = workInProgress.memoizedState; instance.refs = emptyRefsObject; - initializeUpdateQueue(workInProgress); var contextType = ctor.contextType; "object" === typeof contextType && null !== contextType ? (instance.context = readContext(contextType)) @@ -2265,8 +2396,16 @@ function mountClassInstance( ? previousContext : contextStackCursor.current), (instance.context = getMaskedContext(workInProgress, contextType))); - processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); - instance.state = workInProgress.memoizedState; + contextType = workInProgress.updateQueue; + null !== contextType && + (processUpdateQueue( + workInProgress, + contextType, + newProps, + instance, + renderExpirationTime + ), + (instance.state = workInProgress.memoizedState)); contextType = ctor.getDerivedStateFromProps; "function" === typeof contextType && (applyDerivedStateFromProps(workInProgress, ctor, contextType, newProps), @@ -2282,18 +2421,21 @@ function mountClassInstance( instance.UNSAFE_componentWillMount(), ctor !== instance.state && classComponentUpdater.enqueueReplaceState(instance, instance.state, null), - processUpdateQueue( - workInProgress, - newProps, - instance, - renderExpirationTime - ), - (instance.state = workInProgress.memoizedState)); + (contextType = workInProgress.updateQueue), + null !== contextType && + (processUpdateQueue( + workInProgress, + contextType, + newProps, + instance, + renderExpirationTime + ), + (instance.state = workInProgress.memoizedState))); "function" === typeof instance.componentDidMount && (workInProgress.effectTag |= 4); } var isArray = Array.isArray; -function coerceRef(returnFiber, current, element) { +function coerceRef(returnFiber, current$$1, element) { returnFiber = element.ref; if ( null !== returnFiber && @@ -2305,7 +2447,7 @@ function coerceRef(returnFiber, current, element) { if (element) { if (1 !== element.tag) throw Error( - "Function components cannot have string refs. We recommend using useRef() instead. Learn more about using refs safely here: https://fb.me/react-strict-mode-string-ref" + "Function components cannot have refs. Did you mean to use React.forwardRef()?" ); var inst = element.stateNode; } @@ -2317,19 +2459,19 @@ function coerceRef(returnFiber, current, element) { ); var stringRef = "" + returnFiber; if ( - null !== current && - null !== current.ref && - "function" === typeof current.ref && - current.ref._stringRef === stringRef + null !== current$$1 && + null !== current$$1.ref && + "function" === typeof current$$1.ref && + current$$1.ref._stringRef === stringRef ) - return current.ref; - current = function(value) { + return current$$1.ref; + current$$1 = function(value) { var refs = inst.refs; refs === emptyRefsObject && (refs = inst.refs = {}); null === value ? delete refs[stringRef] : (refs[stringRef] = value); }; - current._stringRef = stringRef; - return current; + current$$1._stringRef = stringRef; + return current$$1; } if ("string" !== typeof returnFiber) throw Error( @@ -2381,8 +2523,8 @@ function ChildReconciler(shouldTrackSideEffects) { (currentFirstChild = currentFirstChild.sibling); return returnFiber; } - function useFiber(fiber, pendingProps) { - fiber = createWorkInProgress(fiber, pendingProps); + function useFiber(fiber, pendingProps, expirationTime) { + fiber = createWorkInProgress(fiber, pendingProps, expirationTime); fiber.index = 0; fiber.sibling = null; return fiber; @@ -2407,26 +2549,31 @@ function ChildReconciler(shouldTrackSideEffects) { (newFiber.effectTag = 2); return newFiber; } - function updateTextNode(returnFiber, current, textContent, expirationTime) { - if (null === current || 6 !== current.tag) + function updateTextNode( + returnFiber, + current$$1, + textContent, + expirationTime + ) { + if (null === current$$1 || 6 !== current$$1.tag) return ( - (current = createFiberFromText( + (current$$1 = createFiberFromText( textContent, returnFiber.mode, expirationTime )), - (current.return = returnFiber), - current + (current$$1.return = returnFiber), + current$$1 ); - current = useFiber(current, textContent); - current.return = returnFiber; - return current; + current$$1 = useFiber(current$$1, textContent, expirationTime); + current$$1.return = returnFiber; + return current$$1; } - function updateElement(returnFiber, current, element, expirationTime) { - if (null !== current && current.elementType === element.type) + function updateElement(returnFiber, current$$1, element, expirationTime) { + if (null !== current$$1 && current$$1.elementType === element.type) return ( - (expirationTime = useFiber(current, element.props)), - (expirationTime.ref = coerceRef(returnFiber, current, element)), + (expirationTime = useFiber(current$$1, element.props, expirationTime)), + (expirationTime.ref = coerceRef(returnFiber, current$$1, element)), (expirationTime.return = returnFiber), expirationTime ); @@ -2438,45 +2585,51 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime ); - expirationTime.ref = coerceRef(returnFiber, current, element); + expirationTime.ref = coerceRef(returnFiber, current$$1, element); expirationTime.return = returnFiber; return expirationTime; } - function updatePortal(returnFiber, current, portal, expirationTime) { + function updatePortal(returnFiber, current$$1, portal, expirationTime) { if ( - null === current || - 4 !== current.tag || - current.stateNode.containerInfo !== portal.containerInfo || - current.stateNode.implementation !== portal.implementation + null === current$$1 || + 4 !== current$$1.tag || + current$$1.stateNode.containerInfo !== portal.containerInfo || + current$$1.stateNode.implementation !== portal.implementation ) return ( - (current = createFiberFromPortal( + (current$$1 = createFiberFromPortal( portal, returnFiber.mode, expirationTime )), - (current.return = returnFiber), - current + (current$$1.return = returnFiber), + current$$1 ); - current = useFiber(current, portal.children || []); - current.return = returnFiber; - return current; + current$$1 = useFiber(current$$1, portal.children || [], expirationTime); + current$$1.return = returnFiber; + return current$$1; } - function updateFragment(returnFiber, current, fragment, expirationTime, key) { - if (null === current || 7 !== current.tag) + function updateFragment( + returnFiber, + current$$1, + fragment, + expirationTime, + key + ) { + if (null === current$$1 || 7 !== current$$1.tag) return ( - (current = createFiberFromFragment( + (current$$1 = createFiberFromFragment( fragment, returnFiber.mode, expirationTime, key )), - (current.return = returnFiber), - current + (current$$1.return = returnFiber), + current$$1 ); - current = useFiber(current, fragment); - current.return = returnFiber; - return current; + current$$1 = useFiber(current$$1, fragment, expirationTime); + current$$1.return = returnFiber; + return current$$1; } function createChild(returnFiber, newChild, expirationTime) { if ("string" === typeof newChild || "number" === typeof newChild) @@ -2839,48 +2992,39 @@ function ChildReconciler(shouldTrackSideEffects) { 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; - } + if (isUnkeyedTopLevelFragment.key === isObject) + if ( + 7 === isUnkeyedTopLevelFragment.tag + ? newChild.type === REACT_FRAGMENT_TYPE + : isUnkeyedTopLevelFragment.elementType === newChild.type + ) { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment.sibling + ); + currentFirstChild = useFiber( + isUnkeyedTopLevelFragment, + newChild.type === REACT_FRAGMENT_TYPE + ? newChild.props.children + : newChild.props, + expirationTime + ); + currentFirstChild.ref = coerceRef( + returnFiber, + isUnkeyedTopLevelFragment, + newChild + ); + currentFirstChild.return = returnFiber; + returnFiber = currentFirstChild; + break a; + } else { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment + ); + break; } - deleteRemainingChildren(returnFiber, isUnkeyedTopLevelFragment); - break; - } else deleteChild(returnFiber, isUnkeyedTopLevelFragment); + else deleteChild(returnFiber, isUnkeyedTopLevelFragment); isUnkeyedTopLevelFragment = isUnkeyedTopLevelFragment.sibling; } newChild.type === REACT_FRAGMENT_TYPE @@ -2930,7 +3074,8 @@ function ChildReconciler(shouldTrackSideEffects) { ); currentFirstChild = useFiber( currentFirstChild, - newChild.children || [] + newChild.children || [], + expirationTime ); currentFirstChild.return = returnFiber; returnFiber = currentFirstChild; @@ -2957,7 +3102,11 @@ function ChildReconciler(shouldTrackSideEffects) { (newChild = "" + newChild), null !== currentFirstChild && 6 === currentFirstChild.tag ? (deleteRemainingChildren(returnFiber, currentFirstChild.sibling), - (currentFirstChild = useFiber(currentFirstChild, newChild)), + (currentFirstChild = useFiber( + currentFirstChild, + newChild, + expirationTime + )), (currentFirstChild.return = returnFiber), (returnFiber = currentFirstChild)) : (deleteRemainingChildren(returnFiber, currentFirstChild), @@ -3012,16 +3161,16 @@ function requiredContext(c) { return c; } function pushHostContainer(fiber, nextRootInstance) { - push(rootInstanceStackCursor, nextRootInstance); - push(contextFiberStackCursor, fiber); - push(contextStackCursor$1, NO_CONTEXT); - pop(contextStackCursor$1); - push(contextStackCursor$1, { isInAParentText: !1 }); + push(rootInstanceStackCursor, nextRootInstance, fiber); + push(contextFiberStackCursor, fiber, fiber); + push(contextStackCursor$1, NO_CONTEXT, fiber); + pop(contextStackCursor$1, fiber); + push(contextStackCursor$1, { isInAParentText: !1 }, fiber); } -function popHostContainer() { - pop(contextStackCursor$1); - pop(contextFiberStackCursor); - pop(rootInstanceStackCursor); +function popHostContainer(fiber) { + pop(contextStackCursor$1, fiber); + pop(contextFiberStackCursor, fiber); + pop(rootInstanceStackCursor, fiber); } function pushHostContext(fiber) { requiredContext(rootInstanceStackCursor.current); @@ -3038,19 +3187,23 @@ function pushHostContext(fiber) { ? { isInAParentText: nextContext } : context; context !== nextContext && - (push(contextFiberStackCursor, fiber), - push(contextStackCursor$1, nextContext)); + (push(contextFiberStackCursor, fiber, fiber), + push(contextStackCursor$1, nextContext, fiber)); } function popHostContext(fiber) { contextFiberStackCursor.current === fiber && - (pop(contextStackCursor$1), pop(contextFiberStackCursor)); + (pop(contextStackCursor$1, fiber), pop(contextFiberStackCursor, fiber)); } var suspenseStackCursor = { current: 0 }; function findFirstSuspended(row) { for (var node = row; null !== node; ) { if (13 === node.tag) { var state = node.memoizedState; - if (null !== state && (null === state.dehydrated || shim$1() || shim$1())) + if ( + null !== state && + ((state = state.dehydrated), + null === state || shim$1(state) || shim$1(state)) + ) return node; } else if (19 === node.tag && void 0 !== node.memoizedProps.revealOrder) { if (0 !== (node.effectTag & 64)) return node; @@ -3069,16 +3222,24 @@ function findFirstSuspended(row) { } return null; } -function createDeprecatedResponderListener(responder, props) { +function createResponderListener(responder, props) { return { responder: responder, props: props }; } -var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher, +var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig, - renderExpirationTime = 0, + renderExpirationTime$1 = 0, currentlyRenderingFiber$1 = null, currentHook = null, + nextCurrentHook = null, + firstWorkInProgressHook = null, workInProgressHook = null, - didScheduleRenderPhaseUpdate = !1; + nextWorkInProgressHook = null, + remainingExpirationTime = 0, + componentUpdateQueue = null, + sideEffectTag = 0, + didScheduleRenderPhaseUpdate = !1, + renderPhaseUpdates = null, + numberOfReRenders = 0; function throwInvalidHookError() { throw Error( "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem." @@ -3087,7 +3248,7 @@ function throwInvalidHookError() { function areHookInputsEqual(nextDeps, prevDeps) { if (null === prevDeps) return !1; for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) - if (!objectIs(nextDeps[i], prevDeps[i])) return !1; + if (!is$1(nextDeps[i], prevDeps[i])) return !1; return !0; } function renderWithHooks( @@ -3095,85 +3256,92 @@ function renderWithHooks( workInProgress, Component, props, - secondArg, + refOrContext, nextRenderExpirationTime ) { - renderExpirationTime = nextRenderExpirationTime; + renderExpirationTime$1 = nextRenderExpirationTime; currentlyRenderingFiber$1 = workInProgress; - workInProgress.memoizedState = null; - workInProgress.updateQueue = null; - workInProgress.expirationTime = 0; - ReactCurrentDispatcher.current = - null === current || null === current.memoizedState - ? HooksDispatcherOnMount - : HooksDispatcherOnUpdate; - current = Component(props, secondArg); - if (workInProgress.expirationTime === renderExpirationTime) { - nextRenderExpirationTime = 0; - do { - workInProgress.expirationTime = 0; - if (!(25 > nextRenderExpirationTime)) - throw Error( - "Too many re-renders. React limits the number of renders to prevent an infinite loop." - ); - nextRenderExpirationTime += 1; - workInProgressHook = currentHook = null; - workInProgress.updateQueue = null; - ReactCurrentDispatcher.current = HooksDispatcherOnRerender; - current = Component(props, secondArg); - } while (workInProgress.expirationTime === renderExpirationTime); + nextCurrentHook = null !== current ? current.memoizedState : null; + ReactCurrentDispatcher$1.current = + null === nextCurrentHook ? HooksDispatcherOnMount : HooksDispatcherOnUpdate; + workInProgress = Component(props, refOrContext); + if (didScheduleRenderPhaseUpdate) { + do + (didScheduleRenderPhaseUpdate = !1), + (numberOfReRenders += 1), + (nextCurrentHook = null !== current ? current.memoizedState : null), + (nextWorkInProgressHook = firstWorkInProgressHook), + (componentUpdateQueue = workInProgressHook = currentHook = null), + (ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdate), + (workInProgress = Component(props, refOrContext)); + while (didScheduleRenderPhaseUpdate); + renderPhaseUpdates = null; + numberOfReRenders = 0; } - ReactCurrentDispatcher.current = ContextOnlyDispatcher; - workInProgress = null !== currentHook && null !== currentHook.next; - renderExpirationTime = 0; - workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; - didScheduleRenderPhaseUpdate = !1; - if (workInProgress) + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; + current = currentlyRenderingFiber$1; + current.memoizedState = firstWorkInProgressHook; + current.expirationTime = remainingExpirationTime; + current.updateQueue = componentUpdateQueue; + current.effectTag |= sideEffectTag; + current = null !== currentHook && null !== currentHook.next; + renderExpirationTime$1 = 0; + nextWorkInProgressHook = workInProgressHook = firstWorkInProgressHook = nextCurrentHook = currentHook = currentlyRenderingFiber$1 = null; + remainingExpirationTime = 0; + componentUpdateQueue = null; + sideEffectTag = 0; + if (current) throw Error( "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." ); - return current; + return workInProgress; +} +function resetHooks() { + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; + renderExpirationTime$1 = 0; + nextWorkInProgressHook = workInProgressHook = firstWorkInProgressHook = nextCurrentHook = currentHook = currentlyRenderingFiber$1 = null; + remainingExpirationTime = 0; + componentUpdateQueue = null; + sideEffectTag = 0; + didScheduleRenderPhaseUpdate = !1; + renderPhaseUpdates = null; + numberOfReRenders = 0; } function mountWorkInProgressHook() { var hook = { memoizedState: null, baseState: null, - baseQueue: null, queue: null, + baseUpdate: null, next: null }; null === workInProgressHook - ? (currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook) + ? (firstWorkInProgressHook = workInProgressHook = hook) : (workInProgressHook = workInProgressHook.next = hook); return workInProgressHook; } function updateWorkInProgressHook() { - if (null === currentHook) { - var nextCurrentHook = currentlyRenderingFiber$1.alternate; - nextCurrentHook = - null !== nextCurrentHook ? nextCurrentHook.memoizedState : null; - } else nextCurrentHook = currentHook.next; - var nextWorkInProgressHook = - null === workInProgressHook - ? currentlyRenderingFiber$1.memoizedState - : workInProgressHook.next; if (null !== nextWorkInProgressHook) (workInProgressHook = nextWorkInProgressHook), - (currentHook = nextCurrentHook); + (nextWorkInProgressHook = workInProgressHook.next), + (currentHook = nextCurrentHook), + (nextCurrentHook = null !== currentHook ? currentHook.next : null); else { if (null === nextCurrentHook) throw Error("Rendered more hooks than during the previous render."); currentHook = nextCurrentHook; - nextCurrentHook = { + var newHook = { memoizedState: currentHook.memoizedState, baseState: currentHook.baseState, - baseQueue: currentHook.baseQueue, queue: currentHook.queue, + baseUpdate: currentHook.baseUpdate, next: null }; - null === workInProgressHook - ? (currentlyRenderingFiber$1.memoizedState = workInProgressHook = nextCurrentHook) - : (workInProgressHook = workInProgressHook.next = nextCurrentHook); + workInProgressHook = + null === workInProgressHook + ? (firstWorkInProgressHook = newHook) + : (workInProgressHook.next = newHook); + nextCurrentHook = currentHook.next; } return workInProgressHook; } @@ -3188,100 +3356,74 @@ function updateReducer(reducer) { "Should have a queue. This is likely a bug in React. Please file an issue." ); queue.lastRenderedReducer = reducer; - var current = currentHook, - baseQueue = current.baseQueue, - pendingQueue = queue.pending; - if (null !== pendingQueue) { - if (null !== baseQueue) { - var baseFirst = baseQueue.next; - baseQueue.next = pendingQueue.next; - pendingQueue.next = baseFirst; + if (0 < numberOfReRenders) { + var _dispatch = queue.dispatch; + if (null !== renderPhaseUpdates) { + var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue); + if (void 0 !== firstRenderPhaseUpdate) { + renderPhaseUpdates.delete(queue); + var newState = hook.memoizedState; + do + (newState = reducer(newState, firstRenderPhaseUpdate.action)), + (firstRenderPhaseUpdate = firstRenderPhaseUpdate.next); + while (null !== firstRenderPhaseUpdate); + is$1(newState, hook.memoizedState) || (didReceiveUpdate = !0); + hook.memoizedState = newState; + hook.baseUpdate === queue.last && (hook.baseState = newState); + queue.lastRenderedState = newState; + return [newState, _dispatch]; + } } - current.baseQueue = baseQueue = pendingQueue; - queue.pending = null; + return [hook.memoizedState, _dispatch]; } - if (null !== baseQueue) { - baseQueue = baseQueue.next; - current = current.baseState; - var newBaseQueueLast = (baseFirst = pendingQueue = null), - update = baseQueue; + _dispatch = queue.last; + var baseUpdate = hook.baseUpdate; + newState = hook.baseState; + null !== baseUpdate + ? (null !== _dispatch && (_dispatch.next = null), + (_dispatch = baseUpdate.next)) + : (_dispatch = null !== _dispatch ? _dispatch.next : null); + if (null !== _dispatch) { + var newBaseUpdate = (firstRenderPhaseUpdate = null), + _update = _dispatch, + didSkip = !1; do { - var updateExpirationTime = update.expirationTime; - if (updateExpirationTime < renderExpirationTime) { - var clone = { - expirationTime: update.expirationTime, - suspenseConfig: update.suspenseConfig, - action: update.action, - eagerReducer: update.eagerReducer, - eagerState: update.eagerState, - next: null - }; - null === newBaseQueueLast - ? ((baseFirst = newBaseQueueLast = clone), (pendingQueue = current)) - : (newBaseQueueLast = newBaseQueueLast.next = clone); - updateExpirationTime > currentlyRenderingFiber$1.expirationTime && - ((currentlyRenderingFiber$1.expirationTime = updateExpirationTime), - markUnprocessedUpdateTime(updateExpirationTime)); - } else - null !== newBaseQueueLast && - (newBaseQueueLast = newBaseQueueLast.next = { - expirationTime: 1073741823, - suspenseConfig: update.suspenseConfig, - action: update.action, - eagerReducer: update.eagerReducer, - eagerState: update.eagerState, - next: null - }), - markRenderEventTimeAndConfig( + var updateExpirationTime = _update.expirationTime; + updateExpirationTime < renderExpirationTime$1 + ? (didSkip || + ((didSkip = !0), + (newBaseUpdate = baseUpdate), + (firstRenderPhaseUpdate = newState)), + updateExpirationTime > remainingExpirationTime && + ((remainingExpirationTime = updateExpirationTime), + markUnprocessedUpdateTime(remainingExpirationTime))) + : (markRenderEventTimeAndConfig( updateExpirationTime, - update.suspenseConfig + _update.suspenseConfig ), - (current = - update.eagerReducer === reducer - ? update.eagerState - : reducer(current, update.action)); - update = update.next; - } while (null !== update && update !== baseQueue); - null === newBaseQueueLast - ? (pendingQueue = current) - : (newBaseQueueLast.next = baseFirst); - objectIs(current, hook.memoizedState) || (didReceiveUpdate = !0); - hook.memoizedState = current; - hook.baseState = pendingQueue; - hook.baseQueue = newBaseQueueLast; - queue.lastRenderedState = current; - } - return [hook.memoizedState, queue.dispatch]; -} -function rerenderReducer(reducer) { - var hook = updateWorkInProgressHook(), - queue = hook.queue; - if (null === queue) - throw Error( - "Should have a queue. This is likely a bug in React. Please file an issue." - ); - queue.lastRenderedReducer = reducer; - var dispatch = queue.dispatch, - lastRenderPhaseUpdate = queue.pending, - newState = hook.memoizedState; - if (null !== lastRenderPhaseUpdate) { - queue.pending = null; - var update = (lastRenderPhaseUpdate = lastRenderPhaseUpdate.next); - do (newState = reducer(newState, update.action)), (update = update.next); - while (update !== lastRenderPhaseUpdate); - objectIs(newState, hook.memoizedState) || (didReceiveUpdate = !0); + (newState = + _update.eagerReducer === reducer + ? _update.eagerState + : reducer(newState, _update.action))); + baseUpdate = _update; + _update = _update.next; + } while (null !== _update && _update !== _dispatch); + didSkip || + ((newBaseUpdate = baseUpdate), (firstRenderPhaseUpdate = newState)); + is$1(newState, hook.memoizedState) || (didReceiveUpdate = !0); hook.memoizedState = newState; - null === hook.baseQueue && (hook.baseState = newState); + hook.baseUpdate = newBaseUpdate; + hook.baseState = firstRenderPhaseUpdate; queue.lastRenderedState = newState; } - return [newState, dispatch]; + return [hook.memoizedState, queue.dispatch]; } function mountState(initialState) { var hook = mountWorkInProgressHook(); "function" === typeof initialState && (initialState = initialState()); hook.memoizedState = hook.baseState = initialState; initialState = hook.queue = { - pending: null, + last: null, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState @@ -3293,30 +3435,28 @@ function mountState(initialState) { ); return [hook.memoizedState, initialState]; } +function updateState(initialState) { + return updateReducer(basicStateReducer, initialState); +} function pushEffect(tag, create, destroy, deps) { tag = { tag: tag, create: create, destroy: destroy, deps: deps, next: null }; - create = currentlyRenderingFiber$1.updateQueue; - null === create - ? ((create = { lastEffect: null }), - (currentlyRenderingFiber$1.updateQueue = create), - (create.lastEffect = tag.next = tag)) - : ((destroy = create.lastEffect), - null === destroy - ? (create.lastEffect = tag.next = tag) - : ((deps = destroy.next), - (destroy.next = tag), - (tag.next = deps), - (create.lastEffect = tag))); + null === componentUpdateQueue + ? ((componentUpdateQueue = { lastEffect: null }), + (componentUpdateQueue.lastEffect = tag.next = tag)) + : ((create = componentUpdateQueue.lastEffect), + null === create + ? (componentUpdateQueue.lastEffect = tag.next = tag) + : ((destroy = create.next), + (create.next = tag), + (tag.next = destroy), + (componentUpdateQueue.lastEffect = tag))); return tag; } -function updateRef() { - return updateWorkInProgressHook().memoizedState; -} function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var hook = mountWorkInProgressHook(); - currentlyRenderingFiber$1.effectTag |= fiberEffectTag; + sideEffectTag |= fiberEffectTag; hook.memoizedState = pushEffect( - 1 | hookEffectTag, + hookEffectTag, create, void 0, void 0 === deps ? null : deps @@ -3330,21 +3470,18 @@ function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var prevEffect = currentHook.memoizedState; destroy = prevEffect.destroy; if (null !== deps && areHookInputsEqual(deps, prevEffect.deps)) { - pushEffect(hookEffectTag, create, destroy, deps); + pushEffect(0, create, destroy, deps); return; } } - currentlyRenderingFiber$1.effectTag |= fiberEffectTag; - hook.memoizedState = pushEffect(1 | hookEffectTag, create, destroy, deps); + sideEffectTag |= fiberEffectTag; + hook.memoizedState = pushEffect(hookEffectTag, create, destroy, deps); } function mountEffect(create, deps) { - return mountEffectImpl(516, 4, create, deps); + return mountEffectImpl(516, 192, create, deps); } function updateEffect(create, deps) { - return updateEffectImpl(516, 4, create, deps); -} -function updateLayoutEffect(create, deps) { - return updateEffectImpl(4, 2, create, deps); + return updateEffectImpl(516, 192, create, deps); } function imperativeHandleEffect(create, ref) { if ("function" === typeof ref) @@ -3364,15 +3501,6 @@ function imperativeHandleEffect(create, ref) { } ); } -function updateImperativeHandle(ref, create, deps) { - deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; - return updateEffectImpl( - 4, - 2, - imperativeHandleEffect.bind(null, create, ref), - deps - ); -} function mountDebugValue() {} function mountCallback(callback, deps) { mountWorkInProgressHook().memoizedState = [ @@ -3394,79 +3522,72 @@ function updateCallback(callback, deps) { hook.memoizedState = [callback, deps]; return callback; } -function updateMemo(nextCreate, deps) { - var hook = updateWorkInProgressHook(); - deps = void 0 === deps ? null : deps; - var prevState = hook.memoizedState; - if ( - null !== prevState && - null !== deps && - areHookInputsEqual(deps, prevState[1]) - ) - return prevState[0]; - nextCreate = nextCreate(); - hook.memoizedState = [nextCreate, deps]; - return nextCreate; -} -function startTransition(setPending, config, callback) { - var priorityLevel = getCurrentPriorityLevel(); - runWithPriority(98 > priorityLevel ? 98 : priorityLevel, function() { - setPending(!0); - }); - runWithPriority(97 < priorityLevel ? 97 : priorityLevel, function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = void 0 === config ? null : config; - try { - setPending(!1), callback(); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); -} function dispatchAction(fiber, queue, action) { - var currentTime = requestCurrentTimeForUpdate(), - suspenseConfig = ReactCurrentBatchConfig.suspense; - currentTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig); - suspenseConfig = { - expirationTime: currentTime, - suspenseConfig: suspenseConfig, - action: action, - eagerReducer: null, - eagerState: null, - next: null - }; - var pending = queue.pending; - null === pending - ? (suspenseConfig.next = suspenseConfig) - : ((suspenseConfig.next = pending.next), (pending.next = suspenseConfig)); - queue.pending = suspenseConfig; - pending = fiber.alternate; + if (!(25 > numberOfReRenders)) + throw Error( + "Too many re-renders. React limits the number of renders to prevent an infinite loop." + ); + var alternate = fiber.alternate; if ( fiber === currentlyRenderingFiber$1 || - (null !== pending && pending === currentlyRenderingFiber$1) + (null !== alternate && alternate === currentlyRenderingFiber$1) ) - (didScheduleRenderPhaseUpdate = !0), - (suspenseConfig.expirationTime = renderExpirationTime), - (currentlyRenderingFiber$1.expirationTime = renderExpirationTime); + if ( + ((didScheduleRenderPhaseUpdate = !0), + (fiber = { + expirationTime: renderExpirationTime$1, + suspenseConfig: null, + action: action, + eagerReducer: null, + eagerState: null, + next: null + }), + null === renderPhaseUpdates && (renderPhaseUpdates = new Map()), + (action = renderPhaseUpdates.get(queue)), + void 0 === action) + ) + renderPhaseUpdates.set(queue, fiber); + else { + for (queue = action; null !== queue.next; ) queue = queue.next; + queue.next = fiber; + } else { + var currentTime = requestCurrentTimeForUpdate(), + suspenseConfig = ReactCurrentBatchConfig.suspense; + currentTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig); + suspenseConfig = { + expirationTime: currentTime, + suspenseConfig: suspenseConfig, + action: action, + eagerReducer: null, + eagerState: null, + next: null + }; + var last = queue.last; + if (null === last) suspenseConfig.next = suspenseConfig; + else { + var first = last.next; + null !== first && (suspenseConfig.next = first); + last.next = suspenseConfig; + } + queue.last = suspenseConfig; if ( 0 === fiber.expirationTime && - (null === pending || 0 === pending.expirationTime) && - ((pending = queue.lastRenderedReducer), null !== pending) + (null === alternate || 0 === alternate.expirationTime) && + ((alternate = queue.lastRenderedReducer), null !== alternate) ) try { var currentState = queue.lastRenderedState, - eagerState = pending(currentState, action); - suspenseConfig.eagerReducer = pending; + eagerState = alternate(currentState, action); + suspenseConfig.eagerReducer = alternate; suspenseConfig.eagerState = eagerState; - if (objectIs(eagerState, currentState)) return; + if (is$1(eagerState, currentState)) return; } catch (error) { } finally { } - scheduleWork(fiber, currentTime); + scheduleUpdateOnFiber(fiber, currentTime); } } -function updateEventListener() {} var ContextOnlyDispatcher = { readContext: readContext, useCallback: throwInvalidHookError, @@ -3481,8 +3602,7 @@ var ContextOnlyDispatcher = { useDebugValue: throwInvalidHookError, useResponder: throwInvalidHookError, useDeferredValue: throwInvalidHookError, - useTransition: throwInvalidHookError, - useEvent: throwInvalidHookError + useTransition: throwInvalidHookError }, HooksDispatcherOnMount = { readContext: readContext, @@ -3493,13 +3613,13 @@ var ContextOnlyDispatcher = { deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; return mountEffectImpl( 4, - 2, + 36, imperativeHandleEffect.bind(null, create, ref), deps ); }, useLayoutEffect: function(create, deps) { - return mountEffectImpl(4, 2, create, deps); + return mountEffectImpl(4, 36, create, deps); }, useMemo: function(nextCreate, deps) { var hook = mountWorkInProgressHook(); @@ -3513,7 +3633,7 @@ var ContextOnlyDispatcher = { initialArg = void 0 !== init ? init(initialArg) : initialArg; hook.memoizedState = hook.baseState = initialArg; reducer = hook.queue = { - pending: null, + last: null, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialArg @@ -3532,21 +3652,23 @@ var ContextOnlyDispatcher = { }, useState: mountState, useDebugValue: mountDebugValue, - useResponder: createDeprecatedResponderListener, + useResponder: createResponderListener, useDeferredValue: function(value, config) { var _mountState = mountState(value), prevValue = _mountState[0], setValue = _mountState[1]; mountEffect( function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - void 0 === config ? null : config; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } + Scheduler.unstable_next(function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }); }, [value, config] ); @@ -3554,113 +3676,112 @@ var ContextOnlyDispatcher = { }, useTransition: function(config) { var _mountState2 = mountState(!1), - isPending = _mountState2[0]; - _mountState2 = _mountState2[1]; + isPending = _mountState2[0], + setPending = _mountState2[1]; return [ - mountCallback(startTransition.bind(null, _mountState2, config), [ - _mountState2, - config - ]), + mountCallback( + function(callback) { + setPending(!0); + Scheduler.unstable_next(function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setPending(!1), callback(); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }); + }, + [config, isPending] + ), isPending ]; - }, - useEvent: function() {} + } }, HooksDispatcherOnUpdate = { readContext: readContext, useCallback: updateCallback, useContext: readContext, useEffect: updateEffect, - useImperativeHandle: updateImperativeHandle, - useLayoutEffect: updateLayoutEffect, - useMemo: updateMemo, - useReducer: updateReducer, - useRef: updateRef, - useState: function() { - return updateReducer(basicStateReducer); - }, - useDebugValue: mountDebugValue, - useResponder: createDeprecatedResponderListener, - useDeferredValue: function(value, config) { - var _updateState = updateReducer(basicStateReducer), - prevValue = _updateState[0], - setValue = _updateState[1]; - updateEffect( - function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - void 0 === config ? null : config; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }, - [value, config] + useImperativeHandle: function(ref, create, deps) { + deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; + return updateEffectImpl( + 4, + 36, + imperativeHandleEffect.bind(null, create, ref), + deps ); - return prevValue; }, - useTransition: function(config) { - var _updateState2 = updateReducer(basicStateReducer), - isPending = _updateState2[0]; - _updateState2 = _updateState2[1]; - return [ - updateCallback(startTransition.bind(null, _updateState2, config), [ - _updateState2, - config - ]), - isPending - ]; + useLayoutEffect: function(create, deps) { + return updateEffectImpl(4, 36, create, deps); }, - useEvent: updateEventListener - }, - HooksDispatcherOnRerender = { - readContext: readContext, - useCallback: updateCallback, - useContext: readContext, - useEffect: updateEffect, - useImperativeHandle: updateImperativeHandle, - useLayoutEffect: updateLayoutEffect, - useMemo: updateMemo, - useReducer: rerenderReducer, - useRef: updateRef, - useState: function() { - return rerenderReducer(basicStateReducer); + useMemo: function(nextCreate, deps) { + var hook = updateWorkInProgressHook(); + deps = void 0 === deps ? null : deps; + var prevState = hook.memoizedState; + if ( + null !== prevState && + null !== deps && + areHookInputsEqual(deps, prevState[1]) + ) + return prevState[0]; + nextCreate = nextCreate(); + hook.memoizedState = [nextCreate, deps]; + return nextCreate; + }, + useReducer: updateReducer, + useRef: function() { + return updateWorkInProgressHook().memoizedState; }, + useState: updateState, useDebugValue: mountDebugValue, - useResponder: createDeprecatedResponderListener, + useResponder: createResponderListener, useDeferredValue: function(value, config) { - var _rerenderState = rerenderReducer(basicStateReducer), - prevValue = _rerenderState[0], - setValue = _rerenderState[1]; + var _updateState = updateState(value), + prevValue = _updateState[0], + setValue = _updateState[1]; updateEffect( function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - void 0 === config ? null : config; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } + Scheduler.unstable_next(function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }); }, [value, config] ); return prevValue; }, useTransition: function(config) { - var _rerenderState2 = rerenderReducer(basicStateReducer), - isPending = _rerenderState2[0]; - _rerenderState2 = _rerenderState2[1]; + var _updateState2 = updateState(!1), + isPending = _updateState2[0], + setPending = _updateState2[1]; return [ - updateCallback(startTransition.bind(null, _rerenderState2, config), [ - _rerenderState2, - config - ]), + updateCallback( + function(callback) { + setPending(!0); + Scheduler.unstable_next(function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setPending(!1), callback(); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }); + }, + [config, isPending] + ), isPending ]; - }, - useEvent: updateEventListener + } }, now$1 = Scheduler.unstable_now, commitTime = 0, @@ -3673,16 +3794,70 @@ function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) { profilerStartTime = -1; } } -var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner, +var hydrationParentFiber = null, + nextHydratableInstance = null, + isHydrating = !1; +function tryHydrate(fiber, nextInstance) { + switch (fiber.tag) { + case 5: + return ( + (nextInstance = shim$1(nextInstance, fiber.type, fiber.pendingProps)), + null !== nextInstance ? ((fiber.stateNode = nextInstance), !0) : !1 + ); + case 6: + return ( + (nextInstance = shim$1(nextInstance, fiber.pendingProps)), + null !== nextInstance ? ((fiber.stateNode = nextInstance), !0) : !1 + ); + case 13: + return !1; + default: + return !1; + } +} +function tryToClaimNextHydratableInstance(fiber$jscomp$0) { + if (isHydrating) { + var nextInstance = nextHydratableInstance; + if (nextInstance) { + var firstAttemptedInstance = nextInstance; + if (!tryHydrate(fiber$jscomp$0, nextInstance)) { + nextInstance = shim$1(firstAttemptedInstance); + if (!nextInstance || !tryHydrate(fiber$jscomp$0, nextInstance)) { + fiber$jscomp$0.effectTag = (fiber$jscomp$0.effectTag & -1025) | 2; + isHydrating = !1; + hydrationParentFiber = fiber$jscomp$0; + return; + } + var returnFiber = hydrationParentFiber, + fiber = createFiber(5, null, null, 0); + fiber.elementType = "DELETED"; + fiber.type = "DELETED"; + fiber.stateNode = firstAttemptedInstance; + fiber.return = returnFiber; + fiber.effectTag = 8; + null !== returnFiber.lastEffect + ? ((returnFiber.lastEffect.nextEffect = fiber), + (returnFiber.lastEffect = fiber)) + : (returnFiber.firstEffect = returnFiber.lastEffect = fiber); + } + hydrationParentFiber = fiber$jscomp$0; + nextHydratableInstance = shim$1(nextInstance); + } else + (fiber$jscomp$0.effectTag = (fiber$jscomp$0.effectTag & -1025) | 2), + (isHydrating = !1), + (hydrationParentFiber = fiber$jscomp$0); + } +} +var ReactCurrentOwner$3 = ReactSharedInternals.ReactCurrentOwner, didReceiveUpdate = !1; function reconcileChildren( - current, + current$$1, workInProgress, nextChildren, renderExpirationTime ) { workInProgress.child = - null === current + null === current$$1 ? mountChildFibers( workInProgress, null, @@ -3691,13 +3866,13 @@ function reconcileChildren( ) : reconcileChildFibers( workInProgress, - current.child, + current$$1.child, nextChildren, renderExpirationTime ); } function updateForwardRef( - current, + current$$1, workInProgress, Component, nextProps, @@ -3707,38 +3882,43 @@ function updateForwardRef( var ref = workInProgress.ref; prepareToReadContext(workInProgress, renderExpirationTime); nextProps = renderWithHooks( - current, + current$$1, workInProgress, Component, nextProps, ref, renderExpirationTime ); - if (null !== current && !didReceiveUpdate) + if (null !== current$$1 && !didReceiveUpdate) return ( - (workInProgress.updateQueue = current.updateQueue), + (workInProgress.updateQueue = current$$1.updateQueue), (workInProgress.effectTag &= -517), - current.expirationTime <= renderExpirationTime && - (current.expirationTime = 0), + current$$1.expirationTime <= renderExpirationTime && + (current$$1.expirationTime = 0), bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ) ); workInProgress.effectTag |= 1; - reconcileChildren(current, workInProgress, nextProps, renderExpirationTime); + reconcileChildren( + current$$1, + workInProgress, + nextProps, + renderExpirationTime + ); return workInProgress.child; } function updateMemoComponent( - current, + current$$1, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime ) { - if (null === current) { + if (null === current$$1) { var type = Component.type; if ( "function" === typeof type && @@ -3751,7 +3931,7 @@ function updateMemoComponent( (workInProgress.tag = 15), (workInProgress.type = type), updateSimpleMemoComponent( - current, + current$$1, workInProgress, type, nextProps, @@ -3759,7 +3939,7 @@ function updateMemoComponent( renderExpirationTime ) ); - current = createFiberFromTypeAndProps( + current$$1 = createFiberFromTypeAndProps( Component.type, null, nextProps, @@ -3767,66 +3947,65 @@ function updateMemoComponent( workInProgress.mode, renderExpirationTime ); - current.ref = workInProgress.ref; - current.return = workInProgress; - return (workInProgress.child = current); + current$$1.ref = workInProgress.ref; + current$$1.return = workInProgress; + return (workInProgress.child = current$$1); } - type = current.child; + type = current$$1.child; if ( updateExpirationTime < renderExpirationTime && ((updateExpirationTime = type.memoizedProps), (Component = Component.compare), (Component = null !== Component ? Component : shallowEqual), Component(updateExpirationTime, nextProps) && - current.ref === workInProgress.ref) + current$$1.ref === workInProgress.ref) ) return bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ); workInProgress.effectTag |= 1; - current = createWorkInProgress(type, nextProps); - current.ref = workInProgress.ref; - current.return = workInProgress; - return (workInProgress.child = current); + current$$1 = createWorkInProgress(type, nextProps, renderExpirationTime); + current$$1.ref = workInProgress.ref; + current$$1.return = workInProgress; + return (workInProgress.child = current$$1); } function updateSimpleMemoComponent( - current, + current$$1, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime ) { - return null !== current && - shallowEqual(current.memoizedProps, nextProps) && - current.ref === workInProgress.ref && + return null !== current$$1 && + shallowEqual(current$$1.memoizedProps, nextProps) && + current$$1.ref === workInProgress.ref && ((didReceiveUpdate = !1), updateExpirationTime < renderExpirationTime) - ? ((workInProgress.expirationTime = current.expirationTime), - bailoutOnAlreadyFinishedWork( - current, + ? bailoutOnAlreadyFinishedWork( + current$$1, workInProgress, renderExpirationTime - )) + ) : updateFunctionComponent( - current, + current$$1, workInProgress, Component, nextProps, renderExpirationTime ); } -function markRef(current, workInProgress) { +function markRef(current$$1, workInProgress) { var ref = workInProgress.ref; if ( - (null === current && null !== ref) || - (null !== current && current.ref !== ref) + (null === current$$1 && null !== ref) || + (null !== current$$1 && current$$1.ref !== ref) ) workInProgress.effectTag |= 128; } function updateFunctionComponent( - current, + current$$1, workInProgress, Component, nextProps, @@ -3838,31 +4017,36 @@ function updateFunctionComponent( context = getMaskedContext(workInProgress, context); prepareToReadContext(workInProgress, renderExpirationTime); Component = renderWithHooks( - current, + current$$1, workInProgress, Component, nextProps, context, renderExpirationTime ); - if (null !== current && !didReceiveUpdate) + if (null !== current$$1 && !didReceiveUpdate) return ( - (workInProgress.updateQueue = current.updateQueue), + (workInProgress.updateQueue = current$$1.updateQueue), (workInProgress.effectTag &= -517), - current.expirationTime <= renderExpirationTime && - (current.expirationTime = 0), + current$$1.expirationTime <= renderExpirationTime && + (current$$1.expirationTime = 0), bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ) ); workInProgress.effectTag |= 1; - reconcileChildren(current, workInProgress, Component, renderExpirationTime); + reconcileChildren( + current$$1, + workInProgress, + Component, + renderExpirationTime + ); return workInProgress.child; } function updateClassComponent( - current, + current$$1, workInProgress, Component, nextProps, @@ -3874,11 +4058,16 @@ function updateClassComponent( } else hasContext = !1; prepareToReadContext(workInProgress, renderExpirationTime); if (null === workInProgress.stateNode) - null !== current && - ((current.alternate = null), + null !== current$$1 && + ((current$$1.alternate = null), (workInProgress.alternate = null), (workInProgress.effectTag |= 2)), - constructClassInstance(workInProgress, Component, nextProps), + constructClassInstance( + workInProgress, + Component, + nextProps, + renderExpirationTime + ), mountClassInstance( workInProgress, Component, @@ -3886,7 +4075,7 @@ function updateClassComponent( renderExpirationTime ), (nextProps = !0); - else if (null === current) { + else if (null === current$$1) { var instance = workInProgress.stateNode, oldProps = workInProgress.memoizedProps; instance.props = oldProps; @@ -3914,14 +4103,17 @@ function updateClassComponent( )); hasForceUpdate = !1; var oldState = workInProgress.memoizedState; - instance.state = oldState; - processUpdateQueue( - workInProgress, - nextProps, - instance, - renderExpirationTime - ); - oldContext = workInProgress.memoizedState; + oldContext = instance.state = oldState; + var updateQueue = workInProgress.updateQueue; + null !== updateQueue && + (processUpdateQueue( + workInProgress, + updateQueue, + nextProps, + instance, + renderExpirationTime + ), + (oldContext = workInProgress.memoizedState)); oldProps !== nextProps || oldState !== oldContext || didPerformWorkStackCursor.current || @@ -3967,7 +4159,6 @@ function updateClassComponent( (nextProps = !1)); } else (instance = workInProgress.stateNode), - cloneUpdateQueue(current, workInProgress), (oldProps = workInProgress.memoizedProps), (instance.props = workInProgress.type === workInProgress.elementType @@ -3996,14 +4187,17 @@ function updateClassComponent( )), (hasForceUpdate = !1), (oldContext = workInProgress.memoizedState), - (instance.state = oldContext), - processUpdateQueue( - workInProgress, - nextProps, - instance, - renderExpirationTime - ), - (oldState = workInProgress.memoizedState), + (oldState = instance.state = oldContext), + (updateQueue = workInProgress.updateQueue), + null !== updateQueue && + (processUpdateQueue( + workInProgress, + updateQueue, + nextProps, + instance, + renderExpirationTime + ), + (oldState = workInProgress.memoizedState)), oldProps !== nextProps || oldContext !== oldState || didPerformWorkStackCursor.current || @@ -4047,12 +4241,12 @@ function updateClassComponent( "function" === typeof instance.getSnapshotBeforeUpdate && (workInProgress.effectTag |= 256)) : ("function" !== typeof instance.componentDidUpdate || - (oldProps === current.memoizedProps && - oldContext === current.memoizedState) || + (oldProps === current$$1.memoizedProps && + oldContext === current$$1.memoizedState) || (workInProgress.effectTag |= 4), "function" !== typeof instance.getSnapshotBeforeUpdate || - (oldProps === current.memoizedProps && - oldContext === current.memoizedState) || + (oldProps === current$$1.memoizedProps && + oldContext === current$$1.memoizedState) || (workInProgress.effectTag |= 256), (workInProgress.memoizedProps = nextProps), (workInProgress.memoizedState = oldState)), @@ -4061,16 +4255,16 @@ function updateClassComponent( (instance.context = contextType), (nextProps = getDerivedStateFromProps)) : ("function" !== typeof instance.componentDidUpdate || - (oldProps === current.memoizedProps && - oldContext === current.memoizedState) || + (oldProps === current$$1.memoizedProps && + oldContext === current$$1.memoizedState) || (workInProgress.effectTag |= 4), "function" !== typeof instance.getSnapshotBeforeUpdate || - (oldProps === current.memoizedProps && - oldContext === current.memoizedState) || + (oldProps === current$$1.memoizedProps && + oldContext === current$$1.memoizedState) || (workInProgress.effectTag |= 256), (nextProps = !1)); return finishClassComponent( - current, + current$$1, workInProgress, Component, nextProps, @@ -4079,26 +4273,26 @@ function updateClassComponent( ); } function finishClassComponent( - current, + current$$1, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime ) { - markRef(current, workInProgress); + markRef(current$$1, workInProgress); var didCaptureError = 0 !== (workInProgress.effectTag & 64); if (!shouldUpdate && !didCaptureError) return ( hasContext && invalidateContextProvider(workInProgress, Component, !1), bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ) ); shouldUpdate = workInProgress.stateNode; - ReactCurrentOwner$1.current = workInProgress; + ReactCurrentOwner$3.current = workInProgress; if ( didCaptureError && "function" !== typeof Component.getDerivedStateFromError @@ -4107,11 +4301,11 @@ function finishClassComponent( profilerStartTime = -1; } else nextChildren = shouldUpdate.render(); workInProgress.effectTag |= 1; - null !== current && didCaptureError + null !== current$$1 && didCaptureError ? ((didCaptureError = nextChildren), (workInProgress.child = reconcileChildFibers( workInProgress, - current.child, + current$$1.child, null, renderExpirationTime )), @@ -4122,7 +4316,7 @@ function finishClassComponent( renderExpirationTime ))) : reconcileChildren( - current, + current$$1, workInProgress, nextChildren, renderExpirationTime @@ -4145,7 +4339,7 @@ function pushHostRootContext(workInProgress) { } var SUSPENDED_MARKER = { dehydrated: null, retryTime: 0 }; function updateSuspenseComponent( - current, + current$$1, workInProgress, renderExpirationTime ) { @@ -4157,30 +4351,32 @@ function updateSuspenseComponent( (JSCompiler_temp = 0 !== (workInProgress.effectTag & 64)) || (JSCompiler_temp = 0 !== (suspenseContext & 2) && - (null === current || null !== current.memoizedState)); + (null === current$$1 || null !== current$$1.memoizedState)); JSCompiler_temp ? ((nextDidTimeout = !0), (workInProgress.effectTag &= -65)) - : (null !== current && null === current.memoizedState) || + : (null !== current$$1 && null === current$$1.memoizedState) || void 0 === nextProps.fallback || !0 === nextProps.unstable_avoidThisFallback || (suspenseContext |= 1); - push(suspenseStackCursor, suspenseContext & 1); - if (null === current) { + push(suspenseStackCursor, suspenseContext & 1, workInProgress); + if (null === current$$1) { + void 0 !== nextProps.fallback && + tryToClaimNextHydratableInstance(workInProgress); if (nextDidTimeout) { nextDidTimeout = nextProps.fallback; nextProps = createFiberFromFragment(null, mode, 0, null); nextProps.return = workInProgress; if (0 === (workInProgress.mode & 2)) for ( - current = + current$$1 = null !== workInProgress.memoizedState ? workInProgress.child.child : workInProgress.child, - nextProps.child = current; - null !== current; + nextProps.child = current$$1; + null !== current$$1; ) - (current.return = nextProps), (current = current.sibling); + (current$$1.return = nextProps), (current$$1 = current$$1.sibling); renderExpirationTime = createFiberFromFragment( nextDidTimeout, mode, @@ -4202,14 +4398,15 @@ function updateSuspenseComponent( renderExpirationTime )); } - if (null !== current.memoizedState) { - current = current.child; - mode = current.sibling; + if (null !== current$$1.memoizedState) { + current$$1 = current$$1.child; + mode = current$$1.sibling; if (nextDidTimeout) { nextProps = nextProps.fallback; renderExpirationTime = createWorkInProgress( - current, - current.pendingProps + current$$1, + current$$1.pendingProps, + 0 ); renderExpirationTime.return = workInProgress; if ( @@ -4218,7 +4415,7 @@ function updateSuspenseComponent( null !== workInProgress.memoizedState ? workInProgress.child.child : workInProgress.child), - nextDidTimeout !== current.child) + nextDidTimeout !== current$$1.child) ) for ( renderExpirationTime.child = nextDidTimeout; @@ -4229,12 +4426,12 @@ function updateSuspenseComponent( (nextDidTimeout = nextDidTimeout.sibling); if (workInProgress.mode & 8) { nextDidTimeout = 0; - for (current = renderExpirationTime.child; null !== current; ) - (nextDidTimeout += current.treeBaseDuration), - (current = current.sibling); + for (current$$1 = renderExpirationTime.child; null !== current$$1; ) + (nextDidTimeout += current$$1.treeBaseDuration), + (current$$1 = current$$1.sibling); renderExpirationTime.treeBaseDuration = nextDidTimeout; } - mode = createWorkInProgress(mode, nextProps); + mode = createWorkInProgress(mode, nextProps, mode.expirationTime); mode.return = workInProgress; renderExpirationTime.sibling = mode; renderExpirationTime.childExpirationTime = 0; @@ -4244,37 +4441,37 @@ function updateSuspenseComponent( } renderExpirationTime = reconcileChildFibers( workInProgress, - current.child, + current$$1.child, nextProps.children, renderExpirationTime ); workInProgress.memoizedState = null; return (workInProgress.child = renderExpirationTime); } - current = current.child; + current$$1 = current$$1.child; if (nextDidTimeout) { nextDidTimeout = nextProps.fallback; nextProps = createFiberFromFragment(null, mode, 0, null); nextProps.return = workInProgress; - nextProps.child = current; - null !== current && (current.return = nextProps); + nextProps.child = current$$1; + null !== current$$1 && (current$$1.return = nextProps); if (0 === (workInProgress.mode & 2)) for ( - current = + current$$1 = null !== workInProgress.memoizedState ? workInProgress.child.child : workInProgress.child, - nextProps.child = current; - null !== current; + nextProps.child = current$$1; + null !== current$$1; ) - (current.return = nextProps), (current = current.sibling); + (current$$1.return = nextProps), (current$$1 = current$$1.sibling); if (workInProgress.mode & 8) { - current = 0; + current$$1 = 0; for (suspenseContext = nextProps.child; null !== suspenseContext; ) - (current += suspenseContext.treeBaseDuration), + (current$$1 += suspenseContext.treeBaseDuration), (suspenseContext = suspenseContext.sibling); - nextProps.treeBaseDuration = current; + nextProps.treeBaseDuration = current$$1; } renderExpirationTime = createFiberFromFragment( nextDidTimeout, @@ -4293,7 +4490,7 @@ function updateSuspenseComponent( workInProgress.memoizedState = null; return (workInProgress.child = reconcileChildFibers( workInProgress, - current, + current$$1, nextProps.children, renderExpirationTime )); @@ -4320,7 +4517,6 @@ function initSuspenseListRenderState( ? (workInProgress.memoizedState = { isBackwards: isBackwards, rendering: null, - renderingStartTime: 0, last: lastContentRow, tail: tail, tailExpiration: 0, @@ -4329,7 +4525,6 @@ function initSuspenseListRenderState( }) : ((renderState.isBackwards = isBackwards), (renderState.rendering = null), - (renderState.renderingStartTime = 0), (renderState.last = lastContentRow), (renderState.tail = tail), (renderState.tailExpiration = 0), @@ -4337,7 +4532,7 @@ function initSuspenseListRenderState( (renderState.lastEffect = lastEffectBeforeRendering)); } function updateSuspenseListComponent( - current, + current$$1, workInProgress, renderExpirationTime ) { @@ -4345,7 +4540,7 @@ function updateSuspenseListComponent( revealOrder = nextProps.revealOrder, tailMode = nextProps.tail; reconcileChildren( - current, + current$$1, workInProgress, nextProps.children, renderExpirationTime @@ -4354,39 +4549,42 @@ function updateSuspenseListComponent( if (0 !== (nextProps & 2)) (nextProps = (nextProps & 1) | 2), (workInProgress.effectTag |= 64); else { - if (null !== current && 0 !== (current.effectTag & 64)) - a: for (current = workInProgress.child; null !== current; ) { - if (13 === current.tag) - null !== current.memoizedState && - scheduleWorkOnFiber(current, renderExpirationTime); - else if (19 === current.tag) - scheduleWorkOnFiber(current, renderExpirationTime); - else if (null !== current.child) { - current.child.return = current; - current = current.child; + if (null !== current$$1 && 0 !== (current$$1.effectTag & 64)) + a: for (current$$1 = workInProgress.child; null !== current$$1; ) { + if (13 === current$$1.tag) + null !== current$$1.memoizedState && + scheduleWorkOnFiber(current$$1, renderExpirationTime); + else if (19 === current$$1.tag) + scheduleWorkOnFiber(current$$1, renderExpirationTime); + else if (null !== current$$1.child) { + current$$1.child.return = current$$1; + current$$1 = current$$1.child; continue; } - if (current === workInProgress) break a; - for (; null === current.sibling; ) { - if (null === current.return || current.return === workInProgress) + if (current$$1 === workInProgress) break a; + for (; null === current$$1.sibling; ) { + if ( + null === current$$1.return || + current$$1.return === workInProgress + ) break a; - current = current.return; + current$$1 = current$$1.return; } - current.sibling.return = current.return; - current = current.sibling; + current$$1.sibling.return = current$$1.return; + current$$1 = current$$1.sibling; } nextProps &= 1; } - push(suspenseStackCursor, nextProps); + push(suspenseStackCursor, nextProps, workInProgress); if (0 === (workInProgress.mode & 2)) workInProgress.memoizedState = null; else switch (revealOrder) { case "forwards": renderExpirationTime = workInProgress.child; for (revealOrder = null; null !== renderExpirationTime; ) - (current = renderExpirationTime.alternate), - null !== current && - null === findFirstSuspended(current) && + (current$$1 = renderExpirationTime.alternate), + null !== current$$1 && + null === findFirstSuspended(current$$1) && (revealOrder = renderExpirationTime), (renderExpirationTime = renderExpirationTime.sibling); renderExpirationTime = revealOrder; @@ -4408,15 +4606,15 @@ function updateSuspenseListComponent( renderExpirationTime = null; revealOrder = workInProgress.child; for (workInProgress.child = null; null !== revealOrder; ) { - current = revealOrder.alternate; - if (null !== current && null === findFirstSuspended(current)) { + current$$1 = revealOrder.alternate; + if (null !== current$$1 && null === findFirstSuspended(current$$1)) { workInProgress.child = revealOrder; break; } - current = revealOrder.sibling; + current$$1 = revealOrder.sibling; revealOrder.sibling = renderExpirationTime; renderExpirationTime = revealOrder; - revealOrder = current; + revealOrder = current$$1; } initSuspenseListRenderState( workInProgress, @@ -4443,30 +4641,36 @@ function updateSuspenseListComponent( return workInProgress.child; } function bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ) { - null !== current && (workInProgress.dependencies = current.dependencies); + null !== current$$1 && + (workInProgress.dependencies = current$$1.dependencies); profilerStartTime = -1; var updateExpirationTime = workInProgress.expirationTime; 0 !== updateExpirationTime && markUnprocessedUpdateTime(updateExpirationTime); if (workInProgress.childExpirationTime < renderExpirationTime) return null; - if (null !== current && workInProgress.child !== current.child) + if (null !== current$$1 && workInProgress.child !== current$$1.child) throw Error("Resuming work not yet implemented."); if (null !== workInProgress.child) { - current = workInProgress.child; - renderExpirationTime = createWorkInProgress(current, current.pendingProps); + current$$1 = workInProgress.child; + renderExpirationTime = createWorkInProgress( + current$$1, + current$$1.pendingProps, + current$$1.expirationTime + ); workInProgress.child = renderExpirationTime; for ( renderExpirationTime.return = workInProgress; - null !== current.sibling; + null !== current$$1.sibling; ) - (current = current.sibling), + (current$$1 = current$$1.sibling), (renderExpirationTime = renderExpirationTime.sibling = createWorkInProgress( - current, - current.pendingProps + current$$1, + current$$1.pendingProps, + current$$1.expirationTime )), (renderExpirationTime.return = workInProgress); renderExpirationTime.sibling = null; @@ -4488,7 +4692,12 @@ appendAllChildren = function( var instance = node.stateNode; needsVisibilityToggle && isHidden && - (instance = cloneHiddenInstance(instance)); + (instance = cloneHiddenInstance( + instance, + node.type, + node.memoizedProps, + node + )); appendChildNode(parent.node, instance.node); } else if (6 === node.tag) { instance = node.stateNode; @@ -4541,7 +4750,12 @@ function appendAllChildrenToContainer( var instance = node.stateNode; needsVisibilityToggle && isHidden && - (instance = cloneHiddenInstance(instance)); + (instance = cloneHiddenInstance( + instance, + node.type, + node.memoizedProps, + node + )); appendChildNodeToSet(containerChildSet, instance.node); } else if (6 === node.tag) { instance = node.stateNode; @@ -4627,8 +4841,8 @@ updateHostComponent$1 = function(current, workInProgress, type, newProps) { ? cloneNodeWithNewProps(recyclableInstance, newProps) : cloneNode(recyclableInstance) : null !== newProps - ? cloneNodeWithNewChildrenAndProps(recyclableInstance, newProps) - : cloneNodeWithNewChildren(recyclableInstance), + ? cloneNodeWithNewChildrenAndProps(recyclableInstance, newProps) + : cloneNodeWithNewChildren(recyclableInstance), canonical: type.canonical }), (workInProgress.stateNode = type), @@ -4638,17 +4852,16 @@ updateHostComponent$1 = function(current, workInProgress, type, newProps) { } }; updateHostText$1 = function(current, workInProgress, oldText, newText) { - oldText !== newText - ? ((current = requiredContext(rootInstanceStackCursor.current)), - (oldText = requiredContext(contextStackCursor$1.current)), - (workInProgress.stateNode = createTextInstance( - newText, - current, - oldText, - workInProgress - )), - (workInProgress.effectTag |= 4)) - : (workInProgress.stateNode = current.stateNode); + oldText !== newText && + ((current = requiredContext(rootInstanceStackCursor.current)), + (oldText = requiredContext(contextStackCursor$1.current)), + (workInProgress.stateNode = createTextInstance( + newText, + current, + oldText, + workInProgress + )), + (workInProgress.effectTag |= 4)); }; function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { switch (renderState.tailMode) { @@ -4674,78 +4887,67 @@ function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { : (_lastTailNode.sibling = null); } } -function completeWork(current, workInProgress, renderExpirationTime) { +function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { var newProps = workInProgress.pendingProps; switch (workInProgress.tag) { case 2: + break; case 16: + break; case 15: case 0: - case 11: - case 7: - case 8: - case 12: - case 9: - case 14: - return null; + break; case 1: - return isContextProvider(workInProgress.type) && popContext(), null; + isContextProvider(workInProgress.type) && popContext(workInProgress); + break; case 3: - return ( - popHostContainer(), - pop(didPerformWorkStackCursor), - pop(contextStackCursor), - (current = workInProgress.stateNode), - current.pendingContext && - ((current.context = current.pendingContext), - (current.pendingContext = null)), - updateHostContainer(workInProgress), - null - ); + popHostContainer(workInProgress); + popTopLevelContextObject(workInProgress); + current = workInProgress.stateNode; + current.pendingContext && + ((current.context = current.pendingContext), + (current.pendingContext = null)); + updateHostContainer(workInProgress); + break; case 5: popHostContext(workInProgress); var rootContainerInstance = requiredContext( rootInstanceStackCursor.current ); - renderExpirationTime = workInProgress.type; + renderExpirationTime$jscomp$0 = workInProgress.type; if (null !== current && null != workInProgress.stateNode) updateHostComponent$1( current, workInProgress, - renderExpirationTime, + renderExpirationTime$jscomp$0, newProps, rootContainerInstance ), current.ref !== workInProgress.ref && (workInProgress.effectTag |= 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." - ); - return null; - } + else if (newProps) { requiredContext(contextStackCursor$1.current); current = nextReactTag; nextReactTag += 2; - renderExpirationTime = getViewConfigForType(renderExpirationTime); + renderExpirationTime$jscomp$0 = getViewConfigForType( + renderExpirationTime$jscomp$0 + ); var updatePayload = diffProperties( null, emptyObject, newProps, - renderExpirationTime.validAttributes + renderExpirationTime$jscomp$0.validAttributes ); rootContainerInstance = createNode( current, - renderExpirationTime.uiViewClassName, + renderExpirationTime$jscomp$0.uiViewClassName, rootContainerInstance, updatePayload, workInProgress ); current = new ReactFabricHostComponent( current, - renderExpirationTime, + renderExpirationTime$jscomp$0, newProps, workInProgress ); @@ -4753,8 +4955,11 @@ function completeWork(current, workInProgress, renderExpirationTime) { appendAllChildren(current, workInProgress, !1, !1); workInProgress.stateNode = current; null !== workInProgress.ref && (workInProgress.effectTag |= 128); - } - return null; + } else 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." + ); + break; case 6: if (current && null != workInProgress.stateNode) updateHostText$1( @@ -4777,30 +4982,33 @@ function completeWork(current, workInProgress, renderExpirationTime) { workInProgress ); } - return null; + break; + case 11: + break; case 13: - pop(suspenseStackCursor); + pop(suspenseStackCursor, workInProgress); newProps = workInProgress.memoizedState; if (0 !== (workInProgress.effectTag & 64)) return ( - (workInProgress.expirationTime = renderExpirationTime), workInProgress + (workInProgress.expirationTime = renderExpirationTime$jscomp$0), + workInProgress ); newProps = null !== newProps; rootContainerInstance = !1; null !== current && - ((renderExpirationTime = current.memoizedState), - (rootContainerInstance = null !== renderExpirationTime), + ((renderExpirationTime$jscomp$0 = current.memoizedState), + (rootContainerInstance = null !== renderExpirationTime$jscomp$0), newProps || - null === renderExpirationTime || - ((renderExpirationTime = current.child.sibling), - null !== renderExpirationTime && + null === renderExpirationTime$jscomp$0 || + ((renderExpirationTime$jscomp$0 = current.child.sibling), + null !== renderExpirationTime$jscomp$0 && ((updatePayload = workInProgress.firstEffect), null !== updatePayload - ? ((workInProgress.firstEffect = renderExpirationTime), - (renderExpirationTime.nextEffect = updatePayload)) - : ((workInProgress.firstEffect = workInProgress.lastEffect = renderExpirationTime), - (renderExpirationTime.nextEffect = null)), - (renderExpirationTime.effectTag = 8)))); + ? ((workInProgress.firstEffect = renderExpirationTime$jscomp$0), + (renderExpirationTime$jscomp$0.nextEffect = updatePayload)) + : ((workInProgress.firstEffect = workInProgress.lastEffect = renderExpirationTime$jscomp$0), + (renderExpirationTime$jscomp$0.nextEffect = null)), + (renderExpirationTime$jscomp$0.effectTag = 8)))); if (newProps && !rootContainerInstance && 0 !== (workInProgress.mode & 2)) if ( (null === current && @@ -4817,27 +5025,38 @@ function completeWork(current, workInProgress, renderExpirationTime) { workInProgressRootExitStatus = RootSuspendedWithDelay; 0 !== workInProgressRootNextUnprocessedUpdateTime && null !== workInProgressRoot && - (markRootSuspendedAtTime( - workInProgressRoot, - renderExpirationTime$1 - ), + (markRootSuspendedAtTime(workInProgressRoot, renderExpirationTime), markRootUpdatedAtTime( workInProgressRoot, workInProgressRootNextUnprocessedUpdateTime )); } newProps && (workInProgress.effectTag |= 4); - return null; + break; + case 7: + break; + case 8: + break; + case 12: + break; case 4: - return popHostContainer(), updateHostContainer(workInProgress), null; + popHostContainer(workInProgress); + updateHostContainer(workInProgress); + break; case 10: - return popProvider(workInProgress), null; + popProvider(workInProgress); + break; + case 9: + break; + case 14: + break; case 17: - return isContextProvider(workInProgress.type) && popContext(), null; + isContextProvider(workInProgress.type) && popContext(workInProgress); + break; case 19: - pop(suspenseStackCursor); + pop(suspenseStackCursor, workInProgress); newProps = workInProgress.memoizedState; - if (null === newProps) return null; + if (null === newProps) break; rootContainerInstance = 0 !== (workInProgress.effectTag & 64); updatePayload = newProps.rendering; if (null === updatePayload) @@ -4859,7 +5078,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { null === newProps.lastEffect && (workInProgress.firstEffect = null); workInProgress.lastEffect = newProps.lastEffect; - current = renderExpirationTime; + current = renderExpirationTime$jscomp$0; for (newProps = workInProgress.child; null !== newProps; ) (rootContainerInstance = newProps), (updatePayload = current), @@ -4867,8 +5086,9 @@ function completeWork(current, workInProgress, renderExpirationTime) { (rootContainerInstance.nextEffect = null), (rootContainerInstance.firstEffect = null), (rootContainerInstance.lastEffect = null), - (renderExpirationTime = rootContainerInstance.alternate), - null === renderExpirationTime + (renderExpirationTime$jscomp$0 = + rootContainerInstance.alternate), + null === renderExpirationTime$jscomp$0 ? ((rootContainerInstance.childExpirationTime = 0), (rootContainerInstance.expirationTime = updatePayload), (rootContainerInstance.child = null), @@ -4879,18 +5099,19 @@ function completeWork(current, workInProgress, renderExpirationTime) { (rootContainerInstance.selfBaseDuration = 0), (rootContainerInstance.treeBaseDuration = 0)) : ((rootContainerInstance.childExpirationTime = - renderExpirationTime.childExpirationTime), + renderExpirationTime$jscomp$0.childExpirationTime), (rootContainerInstance.expirationTime = - renderExpirationTime.expirationTime), + renderExpirationTime$jscomp$0.expirationTime), (rootContainerInstance.child = - renderExpirationTime.child), + renderExpirationTime$jscomp$0.child), (rootContainerInstance.memoizedProps = - renderExpirationTime.memoizedProps), + renderExpirationTime$jscomp$0.memoizedProps), (rootContainerInstance.memoizedState = - renderExpirationTime.memoizedState), + renderExpirationTime$jscomp$0.memoizedState), (rootContainerInstance.updateQueue = - renderExpirationTime.updateQueue), - (updatePayload = renderExpirationTime.dependencies), + renderExpirationTime$jscomp$0.updateQueue), + (updatePayload = + renderExpirationTime$jscomp$0.dependencies), (rootContainerInstance.dependencies = null === updatePayload ? null @@ -4900,13 +5121,14 @@ function completeWork(current, workInProgress, renderExpirationTime) { responders: updatePayload.responders }), (rootContainerInstance.selfBaseDuration = - renderExpirationTime.selfBaseDuration), + renderExpirationTime$jscomp$0.selfBaseDuration), (rootContainerInstance.treeBaseDuration = - renderExpirationTime.treeBaseDuration)), + renderExpirationTime$jscomp$0.treeBaseDuration)), (newProps = newProps.sibling); push( suspenseStackCursor, - (suspenseStackCursor.current & 1) | 2 + (suspenseStackCursor.current & 1) | 2, + workInProgress ); return workInProgress.child; } @@ -4929,20 +5151,18 @@ function completeWork(current, workInProgress, renderExpirationTime) { null === newProps.tail && "hidden" === newProps.tailMode && !updatePayload.alternate) - ) - return ( - (workInProgress = workInProgress.lastEffect = - newProps.lastEffect), - null !== workInProgress && (workInProgress.nextEffect = null), - null - ); + ) { + workInProgress = workInProgress.lastEffect = newProps.lastEffect; + null !== workInProgress && (workInProgress.nextEffect = null); + break; + } } else - 2 * now() - newProps.renderingStartTime > newProps.tailExpiration && - 1 < renderExpirationTime && + now() > newProps.tailExpiration && + 1 < renderExpirationTime$jscomp$0 && ((workInProgress.effectTag |= 64), (rootContainerInstance = !0), cutOffTailIfNeeded(newProps, !1), - (current = renderExpirationTime - 1), + (current = renderExpirationTime$jscomp$0 - 1), (workInProgress.expirationTime = workInProgress.childExpirationTime = current), null === spawnedWorkDuringRender ? (spawnedWorkDuringRender = [current]) @@ -4956,44 +5176,49 @@ function completeWork(current, workInProgress, renderExpirationTime) { : (workInProgress.child = updatePayload), (newProps.last = updatePayload)); } - return null !== newProps.tail - ? (0 === newProps.tailExpiration && + if (null !== newProps.tail) + return ( + 0 === newProps.tailExpiration && (newProps.tailExpiration = now() + 500), (current = newProps.tail), (newProps.rendering = current), (newProps.tail = current.sibling), (newProps.lastEffect = workInProgress.lastEffect), - (newProps.renderingStartTime = now()), (current.sibling = null), - (workInProgress = suspenseStackCursor.current), + (newProps = suspenseStackCursor.current), push( suspenseStackCursor, - rootContainerInstance - ? (workInProgress & 1) | 2 - : workInProgress & 1 + rootContainerInstance ? (newProps & 1) | 2 : newProps & 1, + workInProgress ), - current) - : null; + current + ); + break; + case 20: + break; + case 21: + break; + default: + throw Error( + "Unknown unit of work tag (" + + workInProgress.tag + + "). This error is likely caused by a bug in React. Please file an issue." + ); } - throw Error( - "Unknown unit of work tag (" + - workInProgress.tag + - "). This error is likely caused by a bug in React. Please file an issue." - ); + return null; } function unwindWork(workInProgress) { switch (workInProgress.tag) { case 1: - isContextProvider(workInProgress.type) && popContext(); + isContextProvider(workInProgress.type) && popContext(workInProgress); var effectTag = workInProgress.effectTag; return effectTag & 4096 ? ((workInProgress.effectTag = (effectTag & -4097) | 64), workInProgress) : null; case 3: - popHostContainer(); - pop(didPerformWorkStackCursor); - pop(contextStackCursor); + popHostContainer(workInProgress); + popTopLevelContextObject(workInProgress); effectTag = workInProgress.effectTag; if (0 !== (effectTag & 64)) throw Error( @@ -5005,7 +5230,7 @@ function unwindWork(workInProgress) { return popHostContext(workInProgress), null; case 13: return ( - pop(suspenseStackCursor), + pop(suspenseStackCursor, workInProgress), (effectTag = workInProgress.effectTag), effectTag & 4096 ? ((workInProgress.effectTag = (effectTag & -4097) | 64), @@ -5013,9 +5238,9 @@ function unwindWork(workInProgress) { : null ); case 19: - return pop(suspenseStackCursor), null; + return pop(suspenseStackCursor, workInProgress), null; case 4: - return popHostContainer(), null; + return popHostContainer(workInProgress), null; case 10: return popProvider(workInProgress), null; default: @@ -5072,192 +5297,102 @@ function logError(boundary, errorInfo) { }); } } -function safelyCallComponentWillUnmount(current, instance) { +function safelyCallComponentWillUnmount(current$$1, instance) { try { - (instance.props = current.memoizedProps), - (instance.state = current.memoizedState), + (instance.props = current$$1.memoizedProps), + (instance.state = current$$1.memoizedState), instance.componentWillUnmount(); } catch (unmountError) { - captureCommitPhaseError(current, unmountError); + captureCommitPhaseError(current$$1, unmountError); } } -function safelyDetachRef(current) { - var ref = current.ref; +function safelyDetachRef(current$$1) { + var ref = current$$1.ref; if (null !== ref) if ("function" === typeof ref) try { ref(null); } catch (refError) { - captureCommitPhaseError(current, refError); + captureCommitPhaseError(current$$1, refError); } else ref.current = null; } -function commitBeforeMutationLifeCycles(current, finishedWork) { +function commitBeforeMutationLifeCycles(current$$1, finishedWork) { switch (finishedWork.tag) { case 0: case 11: case 15: - case 22: - return; + commitHookEffectList(2, 0, finishedWork); + break; case 1: - if (finishedWork.effectTag & 256 && null !== current) { - var prevProps = current.memoizedProps, - prevState = current.memoizedState; - current = finishedWork.stateNode; - finishedWork = current.getSnapshotBeforeUpdate( + if (finishedWork.effectTag & 256 && null !== current$$1) { + var prevProps = current$$1.memoizedProps, + prevState = current$$1.memoizedState; + current$$1 = finishedWork.stateNode; + finishedWork = current$$1.getSnapshotBeforeUpdate( finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState ); - current.__reactInternalSnapshotBeforeUpdate = finishedWork; + current$$1.__reactInternalSnapshotBeforeUpdate = finishedWork; } - return; + break; case 3: case 5: case 6: case 4: case 17: - return; + 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." + ); } - 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(tag, finishedWork) { +function commitHookEffectList(unmountTag, mountTag, finishedWork) { finishedWork = finishedWork.updateQueue; finishedWork = null !== finishedWork ? finishedWork.lastEffect : null; if (null !== finishedWork) { var effect = (finishedWork = finishedWork.next); do { - if ((effect.tag & tag) === tag) { + if (0 !== (effect.tag & unmountTag)) { var destroy = effect.destroy; effect.destroy = void 0; void 0 !== destroy && destroy(); } + 0 !== (effect.tag & mountTag) && + ((destroy = effect.create), (effect.destroy = destroy())); effect = effect.next; } while (effect !== finishedWork); } } -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 = effect.create; - effect.destroy = create(); - } - effect = effect.next; - } while (effect !== finishedWork); - } -} -function commitLifeCycles(finishedRoot, current, finishedWork) { - switch (finishedWork.tag) { - case 0: - case 11: - case 15: - case 22: - commitHookEffectListMount(3, finishedWork); - return; - case 1: - finishedRoot = finishedWork.stateNode; - if (finishedWork.effectTag & 4) - if (null === current) finishedRoot.componentDidMount(); - else { - var prevProps = - finishedWork.elementType === finishedWork.type - ? current.memoizedProps - : resolveDefaultProps(finishedWork.type, current.memoizedProps); - finishedRoot.componentDidUpdate( - prevProps, - 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); - } - return; - case 5: - if (null === current && finishedWork.effectTag & 4) - throw Error( - "The current renderer does not support mutation. This error is likely caused by a bug in React. Please file an issue." - ); - return; - case 6: - return; - case 4: - return; - case 12: - prevProps = finishedWork.memoizedProps.onRender; - var commitTime$jscomp$0 = commitTime; - "function" === typeof prevProps && - prevProps( - finishedWork.memoizedProps.id, - null === current ? "mount" : "update", - finishedWork.actualDuration, - finishedWork.treeBaseDuration, - finishedWork.actualStartTime, - commitTime$jscomp$0, - finishedRoot.memoizedInteractions - ); - return; - case 13: - return; - case 19: - case 17: - case 20: - case 21: - 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 commitUnmount(finishedRoot, current$jscomp$0, renderPriorityLevel) { +function commitUnmount(finishedRoot, current$$1$jscomp$0, renderPriorityLevel) { "function" === typeof onCommitFiberUnmount && - onCommitFiberUnmount(current$jscomp$0); - switch (current$jscomp$0.tag) { + onCommitFiberUnmount(current$$1$jscomp$0); + switch (current$$1$jscomp$0.tag) { case 0: case 11: case 14: case 15: - case 22: - finishedRoot = current$jscomp$0.updateQueue; + finishedRoot = current$$1$jscomp$0.updateQueue; if ( null !== finishedRoot && ((finishedRoot = finishedRoot.lastEffect), null !== finishedRoot) ) { var firstEffect = finishedRoot.next; - runWithPriority( + runWithPriority$1( 97 < renderPriorityLevel ? 97 : renderPriorityLevel, function() { var effect = firstEffect; do { - var _destroy = effect.destroy; - if (void 0 !== _destroy) { - var current = current$jscomp$0; + var destroy = effect.destroy; + if (void 0 !== destroy) { + var current$$1 = current$$1$jscomp$0; try { - _destroy(); + destroy(); } catch (error) { - captureCommitPhaseError(current, error); + captureCommitPhaseError(current$$1, error); } } effect = effect.next; @@ -5267,41 +5402,42 @@ function commitUnmount(finishedRoot, current$jscomp$0, renderPriorityLevel) { } break; case 1: - safelyDetachRef(current$jscomp$0); - renderPriorityLevel = current$jscomp$0.stateNode; + safelyDetachRef(current$$1$jscomp$0); + renderPriorityLevel = current$$1$jscomp$0.stateNode; "function" === typeof renderPriorityLevel.componentWillUnmount && - safelyCallComponentWillUnmount(current$jscomp$0, renderPriorityLevel); + safelyCallComponentWillUnmount( + current$$1$jscomp$0, + renderPriorityLevel + ); break; case 5: - safelyDetachRef(current$jscomp$0); + safelyDetachRef(current$$1$jscomp$0); break; case 4: - createChildNodeSet(current$jscomp$0.stateNode.containerInfo); + createChildNodeSet(current$$1$jscomp$0.stateNode.containerInfo); } } -function detachFiber(current) { - var alternate = current.alternate; - current.return = null; - current.child = null; - current.memoizedState = null; - current.updateQueue = null; - current.dependencies = null; - current.alternate = null; - current.firstEffect = null; - current.lastEffect = null; - current.pendingProps = null; - current.memoizedProps = null; - current.stateNode = null; +function detachFiber(current$$1) { + var alternate = current$$1.alternate; + current$$1.return = null; + current$$1.child = null; + current$$1.memoizedState = null; + current$$1.updateQueue = null; + current$$1.dependencies = null; + current$$1.alternate = null; + current$$1.firstEffect = null; + current$$1.lastEffect = null; + current$$1.pendingProps = null; + current$$1.memoizedProps = null; null !== alternate && detachFiber(alternate); } -function commitWork(current, finishedWork) { +function commitWork(current$$1, finishedWork) { switch (finishedWork.tag) { case 0: case 11: case 14: case 15: - case 22: - commitHookEffectListUnmount(3, finishedWork); + commitHookEffectList(4, 8, finishedWork); return; case 12: return; @@ -5314,20 +5450,19 @@ function commitWork(current, finishedWork) { attachSuspenseRetryListeners(finishedWork); return; } - a: { - switch (finishedWork.tag) { - 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." - ); + a: switch (finishedWork.tag) { + case 1: + case 5: + case 6: + case 20: + break a; + case 3: + case 4: + break a; + 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." + ); } } function attachSuspenseRetryListeners(finishedWork) { @@ -5387,7 +5522,7 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { return expirationTime; } var ceil = Math.ceil, - ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, + ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, NoContext = 0, LegacyUnbatchedContext = 8, @@ -5402,7 +5537,7 @@ var ceil = Math.ceil, executionContext = NoContext, workInProgressRoot = null, workInProgress = null, - renderExpirationTime$1 = 0, + renderExpirationTime = 0, workInProgressRootExitStatus = RootIncomplete, workInProgressRootFatalError = null, workInProgressRootLatestProcessedExpirationTime = 1073741823, @@ -5429,8 +5564,8 @@ function requestCurrentTimeForUpdate() { return (executionContext & (RenderContext | CommitContext)) !== NoContext ? 1073741821 - ((now() / 10) | 0) : 0 !== currentEventTime - ? currentEventTime - : (currentEventTime = 1073741821 - ((now() / 10) | 0)); + ? currentEventTime + : (currentEventTime = 1073741821 - ((now() / 10) | 0)); } function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { fiber = fiber.mode; @@ -5438,7 +5573,7 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { var priorityLevel = getCurrentPriorityLevel(); if (0 === (fiber & 4)) return 99 === priorityLevel ? 1073741823 : 1073741822; if ((executionContext & RenderContext) !== NoContext) - return renderExpirationTime$1; + return renderExpirationTime; if (null !== suspenseConfig) currentTime = 1073741821 - @@ -5470,11 +5605,11 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { throw Error("Expected a valid priority level"); } null !== workInProgressRoot && - currentTime === renderExpirationTime$1 && + currentTime === renderExpirationTime && --currentTime; return currentTime; } -function scheduleWork(fiber, expirationTime) { +function scheduleUpdateOnFiber(fiber, expirationTime) { if (50 < nestedUpdateCount) throw ((nestedUpdateCount = 0), (rootWithNestedUpdates = null), @@ -5531,7 +5666,7 @@ function markUpdateTimeFromFiberToRoot(fiber, expirationTime) { (workInProgressRoot === root && (markUnprocessedUpdateTime(expirationTime), workInProgressRootExitStatus === RootSuspendedWithDelay && - markRootSuspendedAtTime(root, renderExpirationTime$1)), + markRootSuspendedAtTime(root, renderExpirationTime)), markRootUpdatedAtTime(root, expirationTime)); return root; } @@ -5540,10 +5675,9 @@ function getNextRootExpirationTimeToWorkOn(root) { if (0 !== lastExpiredTime) return lastExpiredTime; lastExpiredTime = root.firstPendingTime; if (!isRootSuspendedAtTime(root, lastExpiredTime)) return lastExpiredTime; - var lastPingedTime = root.lastPingedTime; + lastExpiredTime = root.lastPingedTime; root = root.nextKnownPendingLevel; - root = lastPingedTime > root ? lastPingedTime : root; - return 2 >= root && lastExpiredTime !== root ? 0 : root; + return lastExpiredTime > root ? lastExpiredTime : root; } function ensureRootIsScheduled(root) { if (0 !== root.lastExpiredTime) @@ -5592,233 +5726,271 @@ function ensureRootIsScheduled(root) { } function performConcurrentWorkOnRoot(root, didTimeout) { currentEventTime = 0; - if (didTimeout) { - didTimeout = requestCurrentTimeForUpdate(); - var lastExpiredTime = root.lastExpiredTime; - if (0 === lastExpiredTime || lastExpiredTime > didTimeout) - root.lastExpiredTime = didTimeout; - ensureRootIsScheduled(root); - return null; - } - lastExpiredTime = getNextRootExpirationTimeToWorkOn(root); - if (0 === lastExpiredTime) return null; - didTimeout = root.callbackNode; - if ((executionContext & (RenderContext | CommitContext)) !== NoContext) - throw Error("Should not already be working."); - flushPassiveEffects(); - var expirationTime = lastExpiredTime, - prevExecutionContext = executionContext; - executionContext |= RenderContext; - var exitStatus = pushDispatcher(); - if (root !== workInProgressRoot || expirationTime !== renderExpirationTime$1) - prepareFreshStack(root, expirationTime), - startWorkOnPendingInteractions(root, expirationTime); - expirationTime = pushInteractions(root); - do - try { - workLoopConcurrent(); - break; - } catch (thrownValue) { - handleError(root, thrownValue); - } - while (1); - resetContextDependencies(); - tracing.__interactionsRef.current = expirationTime; - ReactCurrentDispatcher$1.current = exitStatus; - executionContext = prevExecutionContext; - null !== workInProgress - ? (exitStatus = RootIncomplete) - : ((workInProgressRoot = null), - (exitStatus = workInProgressRootExitStatus)); - if (exitStatus !== RootIncomplete) { - exitStatus === RootErrored && - ((lastExpiredTime = 2 < lastExpiredTime ? 2 : lastExpiredTime), - (exitStatus = renderRootSync(root, lastExpiredTime))); - if (exitStatus === RootFatalErrored) - throw ((didTimeout = workInProgressRootFatalError), - prepareFreshStack(root, lastExpiredTime), - markRootSuspendedAtTime(root, lastExpiredTime), + if (didTimeout) + return ( + (didTimeout = requestCurrentTimeForUpdate()), + markRootExpiredAtTime(root, didTimeout), ensureRootIsScheduled(root), - didTimeout); - prevExecutionContext = root.finishedWork = root.current.alternate; - root.finishedExpirationTime = lastExpiredTime; - switch (exitStatus) { - case RootIncomplete: - case RootFatalErrored: - throw Error("Root did not complete. This is a bug in React."); - case RootErrored: - commitRoot(root); - break; - case RootSuspended: - markRootSuspendedAtTime(root, lastExpiredTime); - exitStatus = root.lastSuspendedTime; - lastExpiredTime === exitStatus && - (root.nextKnownPendingLevel = getRemainingExpirationTime( - prevExecutionContext - )); - if ( - 1073741823 === workInProgressRootLatestProcessedExpirationTime && - ((prevExecutionContext = - globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now()), - 10 < prevExecutionContext) - ) { - if ( - workInProgressRootHasPendingPing && - ((expirationTime = root.lastPingedTime), - 0 === expirationTime || expirationTime >= lastExpiredTime) - ) { - root.lastPingedTime = lastExpiredTime; - prepareFreshStack(root, lastExpiredTime); - break; - } - expirationTime = getNextRootExpirationTimeToWorkOn(root); - if (0 !== expirationTime && expirationTime !== lastExpiredTime) break; - if (0 !== exitStatus && exitStatus !== lastExpiredTime) { - root.lastPingedTime = exitStatus; - break; - } - root.timeoutHandle = scheduleTimeout( - commitRoot.bind(null, root), - prevExecutionContext - ); - break; - } - commitRoot(root); - break; - case RootSuspendedWithDelay: - markRootSuspendedAtTime(root, lastExpiredTime); - exitStatus = root.lastSuspendedTime; - lastExpiredTime === exitStatus && - (root.nextKnownPendingLevel = getRemainingExpirationTime( - prevExecutionContext - )); - if ( - workInProgressRootHasPendingPing && - ((prevExecutionContext = root.lastPingedTime), - 0 === prevExecutionContext || prevExecutionContext >= lastExpiredTime) - ) { - root.lastPingedTime = lastExpiredTime; - prepareFreshStack(root, lastExpiredTime); - break; - } - prevExecutionContext = getNextRootExpirationTimeToWorkOn(root); - if ( - 0 !== prevExecutionContext && - prevExecutionContext !== lastExpiredTime - ) - break; - if (0 !== exitStatus && exitStatus !== lastExpiredTime) { - root.lastPingedTime = exitStatus; - break; - } - 1073741823 !== workInProgressRootLatestSuspenseTimeout - ? (prevExecutionContext = - 10 * (1073741821 - workInProgressRootLatestSuspenseTimeout) - - now()) - : 1073741823 === workInProgressRootLatestProcessedExpirationTime - ? (prevExecutionContext = 0) - : ((prevExecutionContext = - 10 * - (1073741821 - workInProgressRootLatestProcessedExpirationTime) - - 5e3), - (exitStatus = now()), - (lastExpiredTime = - 10 * (1073741821 - lastExpiredTime) - exitStatus), - (prevExecutionContext = exitStatus - prevExecutionContext), - 0 > prevExecutionContext && (prevExecutionContext = 0), - (prevExecutionContext = - (120 > prevExecutionContext - ? 120 - : 480 > prevExecutionContext - ? 480 - : 1080 > prevExecutionContext - ? 1080 - : 1920 > prevExecutionContext - ? 1920 - : 3e3 > prevExecutionContext - ? 3e3 - : 4320 > prevExecutionContext - ? 4320 - : 1960 * ceil(prevExecutionContext / 1960)) - - prevExecutionContext), - lastExpiredTime < prevExecutionContext && - (prevExecutionContext = lastExpiredTime)); - if (10 < prevExecutionContext) { - root.timeoutHandle = scheduleTimeout( - commitRoot.bind(null, root), - prevExecutionContext - ); + null + ); + var expirationTime = getNextRootExpirationTimeToWorkOn(root); + if (0 !== expirationTime) { + didTimeout = root.callbackNode; + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) + throw Error("Should not already be working."); + flushPassiveEffects(); + if (root !== workInProgressRoot || expirationTime !== renderExpirationTime) + prepareFreshStack(root, expirationTime), + startWorkOnPendingInteractions(root, expirationTime); + if (null !== workInProgress) { + var prevExecutionContext = executionContext; + executionContext |= RenderContext; + var prevDispatcher = pushDispatcher(root), + prevInteractions = pushInteractions(root); + do + try { + workLoopConcurrent(); break; + } catch (thrownValue) { + handleError(root, thrownValue); } - commitRoot(root); - break; - case RootCompleted: - if ( - 1073741823 !== workInProgressRootLatestProcessedExpirationTime && - null !== workInProgressRootCanSuspendUsingConfig + while (1); + resetContextDependencies(); + executionContext = prevExecutionContext; + ReactCurrentDispatcher.current = prevDispatcher; + tracing.__interactionsRef.current = prevInteractions; + if (workInProgressRootExitStatus === RootFatalErrored) + throw ((didTimeout = workInProgressRootFatalError), + prepareFreshStack(root, expirationTime), + markRootSuspendedAtTime(root, expirationTime), + ensureRootIsScheduled(root), + didTimeout); + if (null === workInProgress) + switch ( + ((prevDispatcher = root.finishedWork = root.current.alternate), + (root.finishedExpirationTime = expirationTime), + (prevExecutionContext = workInProgressRootExitStatus), + (workInProgressRoot = null), + prevExecutionContext) ) { - expirationTime = workInProgressRootLatestProcessedExpirationTime; - var suspenseConfig = workInProgressRootCanSuspendUsingConfig; - prevExecutionContext = suspenseConfig.busyMinDurationMs | 0; - 0 >= prevExecutionContext - ? (prevExecutionContext = 0) - : ((exitStatus = suspenseConfig.busyDelayMs | 0), - (expirationTime = - now() - - (10 * (1073741821 - expirationTime) - - (suspenseConfig.timeoutMs | 0 || 5e3))), - (prevExecutionContext = - expirationTime <= exitStatus - ? 0 - : exitStatus + prevExecutionContext - expirationTime)); - if (10 < prevExecutionContext) { - markRootSuspendedAtTime(root, lastExpiredTime); - root.timeoutHandle = scheduleTimeout( - commitRoot.bind(null, root), - prevExecutionContext + case RootIncomplete: + case RootFatalErrored: + throw Error("Root did not complete. This is a bug in React."); + case RootErrored: + markRootExpiredAtTime( + root, + 2 < expirationTime ? 2 : expirationTime ); break; - } + case RootSuspended: + markRootSuspendedAtTime(root, expirationTime); + prevExecutionContext = root.lastSuspendedTime; + expirationTime === prevExecutionContext && + (root.nextKnownPendingLevel = getRemainingExpirationTime( + prevDispatcher + )); + if ( + 1073741823 === workInProgressRootLatestProcessedExpirationTime && + ((prevDispatcher = + globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now()), + 10 < prevDispatcher) + ) { + if ( + workInProgressRootHasPendingPing && + ((prevInteractions = root.lastPingedTime), + 0 === prevInteractions || prevInteractions >= expirationTime) + ) { + root.lastPingedTime = expirationTime; + prepareFreshStack(root, expirationTime); + break; + } + prevInteractions = getNextRootExpirationTimeToWorkOn(root); + if (0 !== prevInteractions && prevInteractions !== expirationTime) + break; + if ( + 0 !== prevExecutionContext && + prevExecutionContext !== expirationTime + ) { + root.lastPingedTime = prevExecutionContext; + break; + } + root.timeoutHandle = scheduleTimeout( + commitRoot.bind(null, root), + prevDispatcher + ); + break; + } + commitRoot(root); + break; + case RootSuspendedWithDelay: + markRootSuspendedAtTime(root, expirationTime); + prevExecutionContext = root.lastSuspendedTime; + expirationTime === prevExecutionContext && + (root.nextKnownPendingLevel = getRemainingExpirationTime( + prevDispatcher + )); + if ( + workInProgressRootHasPendingPing && + ((prevDispatcher = root.lastPingedTime), + 0 === prevDispatcher || prevDispatcher >= expirationTime) + ) { + root.lastPingedTime = expirationTime; + prepareFreshStack(root, expirationTime); + break; + } + prevDispatcher = getNextRootExpirationTimeToWorkOn(root); + if (0 !== prevDispatcher && prevDispatcher !== expirationTime) + break; + if ( + 0 !== prevExecutionContext && + prevExecutionContext !== expirationTime + ) { + root.lastPingedTime = prevExecutionContext; + break; + } + 1073741823 !== workInProgressRootLatestSuspenseTimeout + ? (prevExecutionContext = + 10 * (1073741821 - workInProgressRootLatestSuspenseTimeout) - + now()) + : 1073741823 === workInProgressRootLatestProcessedExpirationTime + ? (prevExecutionContext = 0) + : ((prevExecutionContext = + 10 * + (1073741821 - + workInProgressRootLatestProcessedExpirationTime) - + 5e3), + (prevDispatcher = now()), + (expirationTime = + 10 * (1073741821 - expirationTime) - prevDispatcher), + (prevExecutionContext = + prevDispatcher - prevExecutionContext), + 0 > prevExecutionContext && (prevExecutionContext = 0), + (prevExecutionContext = + (120 > prevExecutionContext + ? 120 + : 480 > prevExecutionContext + ? 480 + : 1080 > prevExecutionContext + ? 1080 + : 1920 > prevExecutionContext + ? 1920 + : 3e3 > prevExecutionContext + ? 3e3 + : 4320 > prevExecutionContext + ? 4320 + : 1960 * ceil(prevExecutionContext / 1960)) - + prevExecutionContext), + expirationTime < prevExecutionContext && + (prevExecutionContext = expirationTime)); + if (10 < prevExecutionContext) { + root.timeoutHandle = scheduleTimeout( + commitRoot.bind(null, root), + prevExecutionContext + ); + break; + } + commitRoot(root); + break; + case RootCompleted: + if ( + 1073741823 !== workInProgressRootLatestProcessedExpirationTime && + null !== workInProgressRootCanSuspendUsingConfig + ) { + prevInteractions = workInProgressRootLatestProcessedExpirationTime; + var suspenseConfig = workInProgressRootCanSuspendUsingConfig; + prevExecutionContext = suspenseConfig.busyMinDurationMs | 0; + 0 >= prevExecutionContext + ? (prevExecutionContext = 0) + : ((prevDispatcher = suspenseConfig.busyDelayMs | 0), + (prevInteractions = + now() - + (10 * (1073741821 - prevInteractions) - + (suspenseConfig.timeoutMs | 0 || 5e3))), + (prevExecutionContext = + prevInteractions <= prevDispatcher + ? 0 + : prevDispatcher + + prevExecutionContext - + prevInteractions)); + if (10 < prevExecutionContext) { + markRootSuspendedAtTime(root, expirationTime); + root.timeoutHandle = scheduleTimeout( + commitRoot.bind(null, root), + prevExecutionContext + ); + break; + } + } + commitRoot(root); + break; + default: + throw Error("Unknown root exit status."); } - commitRoot(root); - break; - default: - throw Error("Unknown root exit status."); + ensureRootIsScheduled(root); + if (root.callbackNode === didTimeout) + return performConcurrentWorkOnRoot.bind(null, root); + } + } + return null; +} +function performSyncWorkOnRoot(root) { + var lastExpiredTime = root.lastExpiredTime; + lastExpiredTime = 0 !== lastExpiredTime ? lastExpiredTime : 1073741823; + if (root.finishedExpirationTime === lastExpiredTime) commitRoot(root); + else { + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) + throw Error("Should not already be working."); + flushPassiveEffects(); + if (root !== workInProgressRoot || lastExpiredTime !== renderExpirationTime) + prepareFreshStack(root, lastExpiredTime), + startWorkOnPendingInteractions(root, lastExpiredTime); + if (null !== workInProgress) { + var prevExecutionContext = executionContext; + executionContext |= RenderContext; + var prevDispatcher = pushDispatcher(root), + prevInteractions = pushInteractions(root); + do + try { + workLoopSync(); + break; + } catch (thrownValue) { + handleError(root, thrownValue); + } + while (1); + resetContextDependencies(); + executionContext = prevExecutionContext; + ReactCurrentDispatcher.current = prevDispatcher; + tracing.__interactionsRef.current = prevInteractions; + if (workInProgressRootExitStatus === RootFatalErrored) + throw ((prevExecutionContext = workInProgressRootFatalError), + prepareFreshStack(root, lastExpiredTime), + markRootSuspendedAtTime(root, lastExpiredTime), + ensureRootIsScheduled(root), + prevExecutionContext); + if (null !== workInProgress) + throw Error( + "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." + ); + root.finishedWork = root.current.alternate; + root.finishedExpirationTime = lastExpiredTime; + workInProgressRoot = null; + commitRoot(root); + ensureRootIsScheduled(root); } } - ensureRootIsScheduled(root); - return root.callbackNode === didTimeout - ? performConcurrentWorkOnRoot.bind(null, root) - : null; -} -function performSyncWorkOnRoot(root) { - if ((executionContext & (RenderContext | CommitContext)) !== NoContext) - throw Error("Should not already be working."); - flushPassiveEffects(); - var lastExpiredTime = root.lastExpiredTime; - lastExpiredTime = - 0 !== lastExpiredTime - ? root === workInProgressRoot && renderExpirationTime$1 >= lastExpiredTime - ? renderExpirationTime$1 - : lastExpiredTime - : 1073741823; - var exitStatus = renderRootSync(root, lastExpiredTime); - 0 !== root.tag && - exitStatus === RootErrored && - ((lastExpiredTime = 2 < lastExpiredTime ? 2 : lastExpiredTime), - (exitStatus = renderRootSync(root, lastExpiredTime))); - if (exitStatus === RootFatalErrored) - throw ((exitStatus = workInProgressRootFatalError), - prepareFreshStack(root, lastExpiredTime), - markRootSuspendedAtTime(root, lastExpiredTime), - ensureRootIsScheduled(root), - exitStatus); - root.finishedWork = root.current.alternate; - root.finishedExpirationTime = lastExpiredTime; - commitRoot(root); - ensureRootIsScheduled(root); return null; } +function flushPendingDiscreteUpdates() { + if (null !== rootsWithPendingDiscreteUpdates) { + var roots = rootsWithPendingDiscreteUpdates; + rootsWithPendingDiscreteUpdates = null; + roots.forEach(function(expirationTime, root) { + markRootExpiredAtTime(root, expirationTime); + ensureRootIsScheduled(root); + }); + flushSyncCallbackQueue(); + } +} function prepareFreshStack(root, expirationTime) { root.finishedWork = null; root.finishedExpirationTime = 0; @@ -5830,27 +6002,26 @@ function prepareFreshStack(root, expirationTime) { var interruptedWork = timeoutHandle; switch (interruptedWork.tag) { case 1: - interruptedWork = interruptedWork.type.childContextTypes; - null !== interruptedWork && - void 0 !== interruptedWork && - popContext(); + var childContextTypes = interruptedWork.type.childContextTypes; + null !== childContextTypes && + void 0 !== childContextTypes && + popContext(interruptedWork); break; case 3: - popHostContainer(); - pop(didPerformWorkStackCursor); - pop(contextStackCursor); + popHostContainer(interruptedWork); + popTopLevelContextObject(interruptedWork); break; case 5: popHostContext(interruptedWork); break; case 4: - popHostContainer(); + popHostContainer(interruptedWork); break; case 13: - pop(suspenseStackCursor); + pop(suspenseStackCursor, interruptedWork); break; case 19: - pop(suspenseStackCursor); + pop(suspenseStackCursor, interruptedWork); break; case 10: popProvider(interruptedWork); @@ -5858,8 +6029,8 @@ function prepareFreshStack(root, expirationTime) { timeoutHandle = timeoutHandle.return; } workInProgressRoot = root; - workInProgress = createWorkInProgress(root.current, null); - renderExpirationTime$1 = expirationTime; + workInProgress = createWorkInProgress(root.current, null, expirationTime); + renderExpirationTime = expirationTime; workInProgressRootExitStatus = RootIncomplete; workInProgressRootFatalError = null; workInProgressRootLatestSuspenseTimeout = workInProgressRootLatestProcessedExpirationTime = 1073741823; @@ -5872,25 +6043,12 @@ function handleError(root$jscomp$0, thrownValue) { do { try { resetContextDependencies(); - ReactCurrentDispatcher.current = ContextOnlyDispatcher; - if (didScheduleRenderPhaseUpdate) - for ( - var hook = currentlyRenderingFiber$1.memoizedState; - null !== hook; - - ) { - var queue = hook.queue; - null !== queue && (queue.pending = null); - hook = hook.next; - } - renderExpirationTime = 0; - workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; - didScheduleRenderPhaseUpdate = !1; + resetHooks(); if (null === workInProgress || null === workInProgress.return) return ( (workInProgressRootExitStatus = RootFatalErrored), (workInProgressRootFatalError = thrownValue), - (workInProgress = null) + null ); workInProgress.mode & 8 && stopProfilerTimerIfRunningAndRecordDelta(workInProgress, !0); @@ -5899,7 +6057,7 @@ function handleError(root$jscomp$0, thrownValue) { returnFiber = workInProgress.return, sourceFiber = workInProgress, value = thrownValue; - thrownValue = renderExpirationTime$1; + thrownValue = renderExpirationTime; sourceFiber.effectTag |= 2048; sourceFiber.firstEffect = sourceFiber.lastEffect = null; if ( @@ -5907,17 +6065,8 @@ function handleError(root$jscomp$0, thrownValue) { "object" === typeof value && "function" === typeof value.then ) { - var thenable = value; - if (0 === (sourceFiber.mode & 2)) { - var currentSource = sourceFiber.alternate; - currentSource - ? ((sourceFiber.updateQueue = currentSource.updateQueue), - (sourceFiber.memoizedState = currentSource.memoizedState), - (sourceFiber.expirationTime = currentSource.expirationTime)) - : ((sourceFiber.updateQueue = null), - (sourceFiber.memoizedState = null)); - } - var hasInvisibleParentBoundary = + var thenable = value, + hasInvisibleParentBoundary = 0 !== (suspenseStackCursor.current & 1), _workInProgress = returnFiber; do { @@ -5932,10 +6081,10 @@ function handleError(root$jscomp$0, thrownValue) { void 0 === props.fallback ? !1 : !0 !== props.unstable_avoidThisFallback - ? !0 - : hasInvisibleParentBoundary - ? !1 - : !0; + ? !0 + : hasInvisibleParentBoundary + ? !1 + : !0; } } if (JSCompiler_temp) { @@ -6042,8 +6191,8 @@ function handleError(root$jscomp$0, thrownValue) { } while (1); } function pushDispatcher() { - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = ContextOnlyDispatcher; return null === prevDispatcher ? ContextOnlyDispatcher : prevDispatcher; } function pushInteractions(root) { @@ -6065,33 +6214,6 @@ function markUnprocessedUpdateTime(expirationTime) { expirationTime > workInProgressRootNextUnprocessedUpdateTime && (workInProgressRootNextUnprocessedUpdateTime = expirationTime); } -function renderRootSync(root, expirationTime) { - var prevExecutionContext = executionContext; - executionContext |= RenderContext; - var prevDispatcher = pushDispatcher(); - if (root !== workInProgressRoot || expirationTime !== renderExpirationTime$1) - prepareFreshStack(root, expirationTime), - startWorkOnPendingInteractions(root, expirationTime); - expirationTime = pushInteractions(root); - do - try { - workLoopSync(); - break; - } catch (thrownValue) { - handleError(root, thrownValue); - } - while (1); - resetContextDependencies(); - tracing.__interactionsRef.current = expirationTime; - executionContext = prevExecutionContext; - ReactCurrentDispatcher$1.current = prevDispatcher; - if (null !== workInProgress) - throw Error( - "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." - ); - workInProgressRoot = null; - return workInProgressRootExitStatus; -} function workLoopSync() { for (; null !== workInProgress; ) workInProgress = performUnitOfWork(workInProgress); @@ -6101,35 +6223,43 @@ function workLoopConcurrent() { workInProgress = performUnitOfWork(workInProgress); } function performUnitOfWork(unitOfWork) { - var current = unitOfWork.alternate; + var current$$1 = unitOfWork.alternate; 0 !== (unitOfWork.mode & 8) ? ((profilerStartTime = now$1()), 0 > unitOfWork.actualStartTime && (unitOfWork.actualStartTime = now$1()), - (current = beginWork$1(current, unitOfWork, renderExpirationTime$1)), + (current$$1 = beginWork$$1(current$$1, unitOfWork, renderExpirationTime)), stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, !0)) - : (current = beginWork$1(current, unitOfWork, renderExpirationTime$1)); + : (current$$1 = beginWork$$1(current$$1, unitOfWork, renderExpirationTime)); unitOfWork.memoizedProps = unitOfWork.pendingProps; - null === current && (current = completeUnitOfWork(unitOfWork)); + null === current$$1 && (current$$1 = completeUnitOfWork(unitOfWork)); ReactCurrentOwner$2.current = null; - return current; + return current$$1; } function completeUnitOfWork(unitOfWork) { workInProgress = unitOfWork; do { - var current = workInProgress.alternate; + var current$$1 = workInProgress.alternate; unitOfWork = workInProgress.return; if (0 === (workInProgress.effectTag & 2048)) { if (0 === (workInProgress.mode & 8)) - current = completeWork(current, workInProgress, renderExpirationTime$1); + current$$1 = completeWork( + current$$1, + workInProgress, + renderExpirationTime + ); else { var fiber = workInProgress; profilerStartTime = now$1(); 0 > fiber.actualStartTime && (fiber.actualStartTime = now$1()); - current = completeWork(current, workInProgress, renderExpirationTime$1); + current$$1 = completeWork( + current$$1, + workInProgress, + renderExpirationTime + ); stopProfilerTimerIfRunningAndRecordDelta(workInProgress, !1); } fiber = workInProgress; - if (1 === renderExpirationTime$1 || 1 !== fiber.childExpirationTime) { + if (1 === renderExpirationTime || 1 !== fiber.childExpirationTime) { var newChildExpirationTime = 0; if (0 !== (fiber.mode & 8)) { for ( @@ -6167,7 +6297,7 @@ function completeUnitOfWork(unitOfWork) { (actualDuration = actualDuration.sibling); fiber.childExpirationTime = newChildExpirationTime; } - if (null !== current) return current; + if (null !== current$$1) return current$$1; null !== unitOfWork && 0 === (unitOfWork.effectTag & 2048) && (null === unitOfWork.firstEffect && @@ -6182,7 +6312,7 @@ function completeUnitOfWork(unitOfWork) { : (unitOfWork.firstEffect = workInProgress), (unitOfWork.lastEffect = workInProgress))); } else { - current = unwindWork(workInProgress); + current$$1 = unwindWork(workInProgress, renderExpirationTime); if (0 !== (workInProgress.mode & 8)) { stopProfilerTimerIfRunningAndRecordDelta(workInProgress, !1); fiber = workInProgress.actualDuration; @@ -6195,13 +6325,14 @@ function completeUnitOfWork(unitOfWork) { (newChildExpirationTime = newChildExpirationTime.sibling); workInProgress.actualDuration = fiber; } - if (null !== current) return (current.effectTag &= 2047), current; + if (null !== current$$1) + return (current$$1.effectTag &= 2047), current$$1; null !== unitOfWork && ((unitOfWork.firstEffect = unitOfWork.lastEffect = null), (unitOfWork.effectTag |= 2048)); } - current = workInProgress.sibling; - if (null !== current) return current; + current$$1 = workInProgress.sibling; + if (null !== current$$1) return current$$1; workInProgress = unitOfWork; } while (null !== workInProgress); workInProgressRootExitStatus === RootIncomplete && @@ -6215,12 +6346,11 @@ function getRemainingExpirationTime(fiber) { } function commitRoot(root) { var renderPriorityLevel = getCurrentPriorityLevel(); - runWithPriority(99, commitRootImpl.bind(null, root, renderPriorityLevel)); + runWithPriority$1(99, commitRootImpl.bind(null, root, renderPriorityLevel)); return null; } function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { - do flushPassiveEffects(); - while (null !== rootWithPendingPassiveEffects); + flushPassiveEffects(); if ((executionContext & (RenderContext | CommitContext)) !== NoContext) throw Error("Should not already be working."); var finishedWork = root$jscomp$1.finishedWork, @@ -6249,8 +6379,7 @@ function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { expirationTime <= root$jscomp$1.lastExpiredTime && (root$jscomp$1.lastExpiredTime = 0); root$jscomp$1 === workInProgressRoot && - ((workInProgress = workInProgressRoot = null), - (renderExpirationTime$1 = 0)); + ((workInProgress = workInProgressRoot = null), (renderExpirationTime = 0)); 1 < finishedWork.effectTag ? null !== finishedWork.lastEffect ? ((finishedWork.lastEffect.nextEffect = finishedWork), @@ -6284,9 +6413,9 @@ function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { ) { var effectTag = nextEffect.effectTag; if (effectTag & 128) { - var current = nextEffect.alternate; - if (null !== current) { - var currentRef = current.ref; + var current$$1 = nextEffect.alternate; + if (null !== current$$1) { + var currentRef = current$$1.ref; null !== currentRef && ("function" === typeof currentRef ? currentRef(null) @@ -6312,10 +6441,10 @@ function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { commitWork(nextEffect.alternate, nextEffect); break; case 8: - var current$jscomp$0 = nextEffect; + var current$$1$jscomp$0 = nextEffect; a: for ( var finishedRoot = root, - root$jscomp$0 = current$jscomp$0, + root$jscomp$0 = current$$1$jscomp$0, renderPriorityLevel$jscomp$0 = renderPriorityLevel, node = root$jscomp$0; ; @@ -6340,7 +6469,7 @@ function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { node.sibling.return = node.return; node = node.sibling; } - detachFiber(current$jscomp$0); + detachFiber(current$$1$jscomp$0); } nextEffect = nextEffect.nextEffect; } @@ -6354,25 +6483,118 @@ function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { nextEffect = remainingExpirationTimeBeforeCommit; do try { - for (effectTag = root$jscomp$1; null !== nextEffect; ) { + for ( + effectTag = root$jscomp$1, current$$1 = expirationTime; + null !== nextEffect; + + ) { var effectTag$jscomp$0 = nextEffect.effectTag; - effectTag$jscomp$0 & 36 && - commitLifeCycles(effectTag, nextEffect.alternate, nextEffect); + if (effectTag$jscomp$0 & 36) { + renderPriorityLevel = effectTag; + var current$$1$jscomp$1 = nextEffect.alternate; + currentRef = nextEffect; + root = current$$1; + switch (currentRef.tag) { + case 0: + case 11: + case 15: + commitHookEffectList(16, 32, currentRef); + break; + case 1: + var instance = currentRef.stateNode; + if (currentRef.effectTag & 4) + if (null === current$$1$jscomp$1) + instance.componentDidMount(); + else { + var prevProps = + currentRef.elementType === currentRef.type + ? current$$1$jscomp$1.memoizedProps + : resolveDefaultProps( + currentRef.type, + current$$1$jscomp$1.memoizedProps + ); + instance.componentDidUpdate( + prevProps, + current$$1$jscomp$1.memoizedState, + instance.__reactInternalSnapshotBeforeUpdate + ); + } + var updateQueue = currentRef.updateQueue; + null !== updateQueue && + commitUpdateQueue(currentRef, updateQueue, instance, root); + break; + case 3: + var _updateQueue = currentRef.updateQueue; + if (null !== _updateQueue) { + renderPriorityLevel = null; + if (null !== currentRef.child) + switch (currentRef.child.tag) { + case 5: + renderPriorityLevel = + currentRef.child.stateNode.canonical; + break; + case 1: + renderPriorityLevel = currentRef.child.stateNode; + } + commitUpdateQueue( + currentRef, + _updateQueue, + renderPriorityLevel, + root + ); + } + break; + case 5: + if (null === current$$1$jscomp$1 && currentRef.effectTag & 4) + throw Error( + "The current renderer does not support mutation. This error is likely caused by a bug in React. Please file an issue." + ); + break; + case 6: + break; + case 4: + break; + case 12: + var onRender = currentRef.memoizedProps.onRender; + "function" === typeof onRender && + onRender( + currentRef.memoizedProps.id, + null === current$$1$jscomp$1 ? "mount" : "update", + currentRef.actualDuration, + currentRef.treeBaseDuration, + currentRef.actualStartTime, + commitTime, + renderPriorityLevel.memoizedInteractions + ); + break; + case 13: + break; + case 19: + case 17: + case 20: + case 21: + 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 (effectTag$jscomp$0 & 128) { - current = void 0; + currentRef = void 0; var ref = nextEffect.ref; if (null !== ref) { - var instance = nextEffect.stateNode; + var instance$jscomp$0 = nextEffect.stateNode; switch (nextEffect.tag) { case 5: - current = instance.canonical; + currentRef = instance$jscomp$0.canonical; break; default: - current = instance; + currentRef = instance$jscomp$0; } "function" === typeof ref - ? ref(current) - : (ref.current = current); + ? ref(currentRef) + : (ref.current = currentRef); } } nextEffect = nextEffect.nextEffect; @@ -6408,13 +6630,13 @@ function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { for ( remainingExpirationTimeBeforeCommit = spawnedWorkDuringRender, spawnedWorkDuringRender = null, - ref = 0; - ref < remainingExpirationTimeBeforeCommit.length; - ref++ + current$$1$jscomp$1 = 0; + current$$1$jscomp$1 < remainingExpirationTimeBeforeCommit.length; + current$$1$jscomp$1++ ) scheduleInteractions( root$jscomp$1, - remainingExpirationTimeBeforeCommit[ref], + remainingExpirationTimeBeforeCommit[current$$1$jscomp$1], root$jscomp$1.memoizedInteractions ); schedulePendingInteractions(root$jscomp$1, renderPriorityLevel$jscomp$1); @@ -6460,7 +6682,7 @@ function flushPassiveEffects() { ? 97 : pendingPassiveEffectsRenderPriority; pendingPassiveEffectsRenderPriority = 90; - return runWithPriority(priorityLevel, flushPassiveEffectsImpl); + return runWithPriority$1(priorityLevel, flushPassiveEffectsImpl); } } function flushPassiveEffectsImpl() { @@ -6475,28 +6697,27 @@ function flushPassiveEffectsImpl() { executionContext |= CommitContext; for ( var prevInteractions = pushInteractions(root), - _effect2 = root.current.firstEffect; - null !== _effect2; + effect = root.current.firstEffect; + null !== effect; ) { try { - var finishedWork = _effect2; + var finishedWork = effect; if (0 !== (finishedWork.effectTag & 512)) switch (finishedWork.tag) { case 0: case 11: case 15: - case 22: - commitHookEffectListUnmount(5, finishedWork), - commitHookEffectListMount(5, finishedWork); + commitHookEffectList(128, 0, finishedWork), + commitHookEffectList(0, 64, finishedWork); } } catch (error) { - if (null === _effect2) throw Error("Should be working on an effect."); - captureCommitPhaseError(_effect2, error); + if (null === effect) throw Error("Should be working on an effect."); + captureCommitPhaseError(effect, error); } - finishedWork = _effect2.nextEffect; - _effect2.nextEffect = null; - _effect2 = finishedWork; + finishedWork = effect.nextEffect; + effect.nextEffect = null; + effect = finishedWork; } tracing.__interactionsRef.current = prevInteractions; finishPendingInteractions(root, expirationTime); @@ -6545,17 +6766,19 @@ function captureCommitPhaseError(sourceFiber, error) { function pingSuspendedRoot(root, thenable, suspendedTime) { var pingCache = root.pingCache; null !== pingCache && pingCache.delete(thenable); - workInProgressRoot === root && renderExpirationTime$1 === suspendedTime + workInProgressRoot === root && renderExpirationTime === suspendedTime ? workInProgressRootExitStatus === RootSuspendedWithDelay || (workInProgressRootExitStatus === RootSuspended && 1073741823 === workInProgressRootLatestProcessedExpirationTime && now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) - ? prepareFreshStack(root, renderExpirationTime$1) + ? prepareFreshStack(root, renderExpirationTime) : (workInProgressRootHasPendingPing = !0) : isRootSuspendedAtTime(root, suspendedTime) && ((thenable = root.lastPingedTime), (0 !== thenable && thenable < suspendedTime) || ((root.lastPingedTime = suspendedTime), + root.finishedExpirationTime === suspendedTime && + ((root.finishedExpirationTime = 0), (root.finishedWork = null)), ensureRootIsScheduled(root), schedulePendingInteractions(root, suspendedTime))); } @@ -6571,12 +6794,12 @@ function resolveRetryThenable(boundaryFiber, thenable) { (ensureRootIsScheduled(boundaryFiber), schedulePendingInteractions(boundaryFiber, thenable)); } -var beginWork$1; -beginWork$1 = function(current, workInProgress, renderExpirationTime) { +var beginWork$$1; +beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { var updateExpirationTime = workInProgress.expirationTime; - if (null !== current) + if (null !== current$$1) if ( - current.memoizedProps !== workInProgress.pendingProps || + current$$1.memoizedProps !== workInProgress.pendingProps || didPerformWorkStackCursor.current ) didReceiveUpdate = !0; @@ -6601,17 +6824,11 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { ); break; case 10: - updateExpirationTime = workInProgress.memoizedProps.value; - var context = workInProgress.type._context; - push(valueCursor, context._currentValue2); - context._currentValue2 = updateExpirationTime; + pushProvider(workInProgress, workInProgress.memoizedProps.value); break; case 12: workInProgress.childExpirationTime >= renderExpirationTime && (workInProgress.effectTag |= 4); - updateExpirationTime = workInProgress.stateNode; - updateExpirationTime.effectDuration = 0; - updateExpirationTime.passiveEffectDuration = 0; break; case 13: if (null !== workInProgress.memoizedState) { @@ -6621,40 +6838,52 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { updateExpirationTime >= renderExpirationTime ) return updateSuspenseComponent( - current, + current$$1, workInProgress, renderExpirationTime ); - push(suspenseStackCursor, suspenseStackCursor.current & 1); + push( + suspenseStackCursor, + suspenseStackCursor.current & 1, + workInProgress + ); workInProgress = bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ); return null !== workInProgress ? workInProgress.sibling : null; } - push(suspenseStackCursor, suspenseStackCursor.current & 1); + push( + suspenseStackCursor, + suspenseStackCursor.current & 1, + workInProgress + ); break; case 19: updateExpirationTime = workInProgress.childExpirationTime >= renderExpirationTime; - if (0 !== (current.effectTag & 64)) { + if (0 !== (current$$1.effectTag & 64)) { if (updateExpirationTime) return updateSuspenseListComponent( - current, + current$$1, workInProgress, renderExpirationTime ); workInProgress.effectTag |= 64; } - context = workInProgress.memoizedState; - null !== context && - ((context.rendering = null), (context.tail = null)); - push(suspenseStackCursor, suspenseStackCursor.current); + var renderState = workInProgress.memoizedState; + null !== renderState && + ((renderState.rendering = null), (renderState.tail = null)); + push( + suspenseStackCursor, + suspenseStackCursor.current, + workInProgress + ); if (!updateExpirationTime) return null; } return bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -6666,40 +6895,41 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { switch (workInProgress.tag) { case 2: updateExpirationTime = workInProgress.type; - null !== current && - ((current.alternate = null), + null !== current$$1 && + ((current$$1.alternate = null), (workInProgress.alternate = null), (workInProgress.effectTag |= 2)); - current = workInProgress.pendingProps; - context = getMaskedContext(workInProgress, contextStackCursor.current); + current$$1 = workInProgress.pendingProps; + renderState = getMaskedContext( + workInProgress, + contextStackCursor.current + ); prepareToReadContext(workInProgress, renderExpirationTime); - context = renderWithHooks( + renderState = renderWithHooks( null, workInProgress, updateExpirationTime, - current, - context, + current$$1, + renderState, renderExpirationTime ); workInProgress.effectTag |= 1; if ( - "object" === typeof context && - null !== context && - "function" === typeof context.render && - void 0 === context.$$typeof + "object" === typeof renderState && + null !== renderState && + "function" === typeof renderState.render && + void 0 === renderState.$$typeof ) { workInProgress.tag = 1; - workInProgress.memoizedState = null; - workInProgress.updateQueue = null; + resetHooks(); if (isContextProvider(updateExpirationTime)) { var hasContext = !0; pushContextProvider(workInProgress); } else hasContext = !1; workInProgress.memoizedState = - null !== context.state && void 0 !== context.state - ? context.state + null !== renderState.state && void 0 !== renderState.state + ? renderState.state : null; - initializeUpdateQueue(workInProgress); var getDerivedStateFromProps = updateExpirationTime.getDerivedStateFromProps; "function" === typeof getDerivedStateFromProps && @@ -6707,15 +6937,15 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { workInProgress, updateExpirationTime, getDerivedStateFromProps, - current + current$$1 ); - context.updater = classComponentUpdater; - workInProgress.stateNode = context; - context._reactInternalFiber = workInProgress; + renderState.updater = classComponentUpdater; + workInProgress.stateNode = renderState; + renderState._reactInternalFiber = workInProgress; mountClassInstance( workInProgress, updateExpirationTime, - current, + current$$1, renderExpirationTime ); workInProgress = finishClassComponent( @@ -6731,129 +6961,127 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { reconcileChildren( null, workInProgress, - context, + renderState, renderExpirationTime ), (workInProgress = workInProgress.child); return workInProgress; case 16: - a: { - context = workInProgress.elementType; - null !== current && - ((current.alternate = null), - (workInProgress.alternate = null), - (workInProgress.effectTag |= 2)); - current = workInProgress.pendingProps; - initializeLazyComponentType(context); - if (1 !== context._status) throw context._result; - context = context._result; - workInProgress.type = context; - hasContext = workInProgress.tag = resolveLazyComponentTag(context); - current = resolveDefaultProps(context, current); - switch (hasContext) { - case 0: - workInProgress = updateFunctionComponent( - null, - workInProgress, - context, - current, - renderExpirationTime - ); - break a; - case 1: - workInProgress = updateClassComponent( - null, - workInProgress, - context, - current, - renderExpirationTime - ); - break a; - case 11: - workInProgress = updateForwardRef( - null, - workInProgress, - context, - current, - renderExpirationTime - ); - break a; - case 14: - workInProgress = updateMemoComponent( - null, - workInProgress, - context, - resolveDefaultProps(context.type, current), - updateExpirationTime, - renderExpirationTime - ); - break a; - } - throw Error( - "Element type is invalid. Received a promise that resolves to: " + - context + - ". Lazy element type must resolve to a class or function." - ); + renderState = workInProgress.elementType; + null !== current$$1 && + ((current$$1.alternate = null), + (workInProgress.alternate = null), + (workInProgress.effectTag |= 2)); + current$$1 = workInProgress.pendingProps; + initializeLazyComponentType(renderState); + if (1 !== renderState._status) throw renderState._result; + renderState = renderState._result; + workInProgress.type = renderState; + hasContext = workInProgress.tag = resolveLazyComponentTag(renderState); + current$$1 = resolveDefaultProps(renderState, current$$1); + switch (hasContext) { + case 0: + workInProgress = updateFunctionComponent( + null, + workInProgress, + renderState, + current$$1, + renderExpirationTime + ); + break; + case 1: + workInProgress = updateClassComponent( + null, + workInProgress, + renderState, + current$$1, + renderExpirationTime + ); + break; + case 11: + workInProgress = updateForwardRef( + null, + workInProgress, + renderState, + current$$1, + renderExpirationTime + ); + break; + case 14: + workInProgress = updateMemoComponent( + null, + workInProgress, + renderState, + resolveDefaultProps(renderState.type, current$$1), + updateExpirationTime, + renderExpirationTime + ); + break; + default: + throw Error( + "Element type is invalid. Received a promise that resolves to: " + + renderState + + ". Lazy element type must resolve to a class or function." + ); } return workInProgress; case 0: return ( (updateExpirationTime = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (renderState = workInProgress.pendingProps), + (renderState = workInProgress.elementType === updateExpirationTime - ? context - : resolveDefaultProps(updateExpirationTime, context)), + ? renderState + : resolveDefaultProps(updateExpirationTime, renderState)), updateFunctionComponent( - current, + current$$1, workInProgress, updateExpirationTime, - context, + renderState, renderExpirationTime ) ); case 1: return ( (updateExpirationTime = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (renderState = workInProgress.pendingProps), + (renderState = workInProgress.elementType === updateExpirationTime - ? context - : resolveDefaultProps(updateExpirationTime, context)), + ? renderState + : resolveDefaultProps(updateExpirationTime, renderState)), updateClassComponent( - current, + current$$1, workInProgress, updateExpirationTime, - context, + renderState, renderExpirationTime ) ); case 3: pushHostRootContext(workInProgress); updateExpirationTime = workInProgress.updateQueue; - if (null === current || null === updateExpirationTime) + if (null === updateExpirationTime) 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." ); - updateExpirationTime = workInProgress.pendingProps; - context = workInProgress.memoizedState; - context = null !== context ? context.element : null; - cloneUpdateQueue(current, workInProgress); + renderState = workInProgress.memoizedState; + renderState = null !== renderState ? renderState.element : null; processUpdateQueue( workInProgress, updateExpirationTime, + workInProgress.pendingProps, null, renderExpirationTime ); updateExpirationTime = workInProgress.memoizedState.element; - updateExpirationTime === context + updateExpirationTime === renderState ? (workInProgress = bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime )) : (reconcileChildren( - current, + current$$1, workInProgress, updateExpirationTime, renderExpirationTime @@ -6863,10 +7091,11 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { case 5: return ( pushHostContext(workInProgress), + null === current$$1 && tryToClaimNextHydratableInstance(workInProgress), (updateExpirationTime = workInProgress.pendingProps.children), - markRef(current, workInProgress), + markRef(current$$1, workInProgress), reconcileChildren( - current, + current$$1, workInProgress, updateExpirationTime, renderExpirationTime @@ -6875,10 +7104,13 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { workInProgress ); case 6: - return null; + return ( + null === current$$1 && tryToClaimNextHydratableInstance(workInProgress), + null + ); case 13: return updateSuspenseComponent( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -6889,7 +7121,7 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { workInProgress.stateNode.containerInfo ), (updateExpirationTime = workInProgress.pendingProps), - null === current + null === current$$1 ? (workInProgress.child = reconcileChildFibers( workInProgress, null, @@ -6897,7 +7129,7 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { renderExpirationTime )) : reconcileChildren( - current, + current$$1, workInProgress, updateExpirationTime, renderExpirationTime @@ -6907,23 +7139,23 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { case 11: return ( (updateExpirationTime = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (renderState = workInProgress.pendingProps), + (renderState = workInProgress.elementType === updateExpirationTime - ? context - : resolveDefaultProps(updateExpirationTime, context)), + ? renderState + : resolveDefaultProps(updateExpirationTime, renderState)), updateForwardRef( - current, + current$$1, workInProgress, updateExpirationTime, - context, + renderState, renderExpirationTime ) ); case 7: return ( reconcileChildren( - current, + current$$1, workInProgress, workInProgress.pendingProps, renderExpirationTime @@ -6933,7 +7165,7 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { case 8: return ( reconcileChildren( - current, + current$$1, workInProgress, workInProgress.pendingProps.children, renderExpirationTime @@ -6943,11 +7175,8 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { case 12: return ( (workInProgress.effectTag |= 4), - (updateExpirationTime = workInProgress.stateNode), - (updateExpirationTime.effectDuration = 0), - (updateExpirationTime.passiveEffectDuration = 0), reconcileChildren( - current, + current$$1, workInProgress, workInProgress.pendingProps.children, renderExpirationTime @@ -6957,32 +7186,27 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { case 10: a: { updateExpirationTime = workInProgress.type._context; - context = workInProgress.pendingProps; + renderState = 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 updateExpirationTime._calculateChangedBits - ? updateExpirationTime._calculateChangedBits( - context$jscomp$0, - hasContext - ) - : 1073741823) | 0), - 0 === hasContext) - ) { + hasContext = renderState.value; + pushProvider(workInProgress, hasContext); + if (null !== getDerivedStateFromProps) { + var oldValue = getDerivedStateFromProps.value; + hasContext = is$1(oldValue, hasContext) + ? 0 + : ("function" === typeof updateExpirationTime._calculateChangedBits + ? updateExpirationTime._calculateChangedBits( + oldValue, + hasContext + ) + : 1073741823) | 0; + if (0 === hasContext) { if ( - getDerivedStateFromProps.children === context.children && + getDerivedStateFromProps.children === renderState.children && !didPerformWorkStackCursor.current ) { workInProgress = bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -6990,15 +7214,14 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { } } 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; @@ -7008,18 +7231,18 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { dependency.context === updateExpirationTime && 0 !== (dependency.observedBits & hasContext) ) { - 1 === context$jscomp$0.tag && + 1 === oldValue.tag && ((dependency = createUpdate(renderExpirationTime, null)), (dependency.tag = 2), - enqueueUpdate(context$jscomp$0, dependency)); - context$jscomp$0.expirationTime < renderExpirationTime && - (context$jscomp$0.expirationTime = renderExpirationTime); - dependency = context$jscomp$0.alternate; + enqueueUpdate(oldValue, dependency)); + oldValue.expirationTime < renderExpirationTime && + (oldValue.expirationTime = renderExpirationTime); + dependency = oldValue.alternate; null !== dependency && dependency.expirationTime < renderExpirationTime && (dependency.expirationTime = renderExpirationTime); scheduleWorkOnParentPath( - context$jscomp$0.return, + oldValue.return, renderExpirationTime ); list.expirationTime < renderExpirationTime && @@ -7030,16 +7253,16 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { } } 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; ) { @@ -7047,20 +7270,21 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { 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, + current$$1, workInProgress, - context.children, + renderState.children, renderExpirationTime ); workInProgress = workInProgress.child; @@ -7068,15 +7292,18 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { return workInProgress; case 9: return ( - (context = workInProgress.type), + (renderState = workInProgress.type), (hasContext = workInProgress.pendingProps), (updateExpirationTime = hasContext.children), prepareToReadContext(workInProgress, renderExpirationTime), - (context = readContext(context, hasContext.unstable_observedBits)), - (updateExpirationTime = updateExpirationTime(context)), + (renderState = readContext( + renderState, + hasContext.unstable_observedBits + )), + (updateExpirationTime = updateExpirationTime(renderState)), (workInProgress.effectTag |= 1), reconcileChildren( - current, + current$$1, workInProgress, updateExpirationTime, renderExpirationTime @@ -7085,16 +7312,16 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { ); case 14: return ( - (context = workInProgress.type), + (renderState = workInProgress.type), (hasContext = resolveDefaultProps( - context, + renderState, workInProgress.pendingProps )), - (hasContext = resolveDefaultProps(context.type, hasContext)), + (hasContext = resolveDefaultProps(renderState.type, hasContext)), updateMemoComponent( - current, + current$$1, workInProgress, - context, + renderState, hasContext, updateExpirationTime, renderExpirationTime @@ -7102,7 +7329,7 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { ); case 15: return updateSimpleMemoComponent( - current, + current$$1, workInProgress, workInProgress.type, workInProgress.pendingProps, @@ -7112,25 +7339,30 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { case 17: return ( (updateExpirationTime = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (renderState = workInProgress.pendingProps), + (renderState = workInProgress.elementType === updateExpirationTime - ? context - : resolveDefaultProps(updateExpirationTime, context)), - null !== current && - ((current.alternate = null), + ? renderState + : resolveDefaultProps(updateExpirationTime, renderState)), + null !== current$$1 && + ((current$$1.alternate = null), (workInProgress.alternate = null), (workInProgress.effectTag |= 2)), (workInProgress.tag = 1), isContextProvider(updateExpirationTime) - ? ((current = !0), pushContextProvider(workInProgress)) - : (current = !1), + ? ((current$$1 = !0), pushContextProvider(workInProgress)) + : (current$$1 = !1), prepareToReadContext(workInProgress, renderExpirationTime), - constructClassInstance(workInProgress, updateExpirationTime, context), + constructClassInstance( + workInProgress, + updateExpirationTime, + renderState, + renderExpirationTime + ), mountClassInstance( workInProgress, updateExpirationTime, - context, + renderState, renderExpirationTime ), finishClassComponent( @@ -7138,13 +7370,13 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { workInProgress, updateExpirationTime, !0, - current, + current$$1, renderExpirationTime ) ); case 19: return updateSuspenseListComponent( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -7285,6 +7517,9 @@ function FiberNode(tag, pendingProps, key, mode) { this.actualStartTime = -1; this.treeBaseDuration = this.selfBaseDuration = 0; } +function createFiber(tag, pendingProps, key, mode) { + return new FiberNode(tag, pendingProps, key, mode); +} function shouldConstruct(Component) { Component = Component.prototype; return !(!Component || !Component.isReactComponent); @@ -7302,7 +7537,7 @@ function resolveLazyComponentTag(Component) { function createWorkInProgress(current, pendingProps) { var workInProgress = current.alternate; null === workInProgress - ? ((workInProgress = new FiberNode( + ? ((workInProgress = createFiber( current.tag, pendingProps, current.key, @@ -7320,10 +7555,6 @@ function createWorkInProgress(current, pendingProps) { (workInProgress.lastEffect = null), (workInProgress.actualDuration = 0), (workInProgress.actualStartTime = -1)); - if (null == current) - throw Error("current is " + current + " but it can't be"); - if (null == workInProgress) - throw Error("workInProgress is " + workInProgress + " but it can't be"); workInProgress.childExpirationTime = current.childExpirationTime; workInProgress.expirationTime = current.expirationTime; workInProgress.child = current.child; @@ -7377,16 +7608,15 @@ function createFiberFromTypeAndProps( break; case REACT_PROFILER_TYPE: return ( - (type = new FiberNode(12, pendingProps, key, mode | 8)), + (type = createFiber(12, pendingProps, key, mode | 8)), (type.elementType = REACT_PROFILER_TYPE), (type.type = REACT_PROFILER_TYPE), (type.expirationTime = expirationTime), - (type.stateNode = { effectDuration: 0, passiveEffectDuration: 0 }), type ); case REACT_SUSPENSE_TYPE: return ( - (type = new FiberNode(13, pendingProps, key, mode)), + (type = createFiber(13, pendingProps, key, mode)), (type.type = REACT_SUSPENSE_TYPE), (type.elementType = REACT_SUSPENSE_TYPE), (type.expirationTime = expirationTime), @@ -7394,7 +7624,7 @@ function createFiberFromTypeAndProps( ); case REACT_SUSPENSE_LIST_TYPE: return ( - (type = new FiberNode(19, pendingProps, key, mode)), + (type = createFiber(19, pendingProps, key, mode)), (type.elementType = REACT_SUSPENSE_LIST_TYPE), (type.expirationTime = expirationTime), type @@ -7418,9 +7648,6 @@ function createFiberFromTypeAndProps( fiberTag = 16; owner = null; break a; - case REACT_BLOCK_TYPE: - fiberTag = 22; - break a; } throw Error( "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + @@ -7428,24 +7655,24 @@ function createFiberFromTypeAndProps( "." ); } - key = new FiberNode(fiberTag, pendingProps, key, mode); + key = createFiber(fiberTag, pendingProps, key, mode); key.elementType = type; key.type = owner; key.expirationTime = expirationTime; return key; } function createFiberFromFragment(elements, mode, expirationTime, key) { - elements = new FiberNode(7, elements, key, mode); + elements = createFiber(7, elements, key, mode); elements.expirationTime = expirationTime; return elements; } function createFiberFromText(content, mode, expirationTime) { - content = new FiberNode(6, content, null, mode); + content = createFiber(6, content, null, mode); content.expirationTime = expirationTime; return content; } function createFiberFromPortal(portal, mode, expirationTime) { - mode = new FiberNode( + mode = createFiber( 4, null !== portal.children ? portal.children : [], portal.key, @@ -7507,6 +7734,11 @@ function markRootUpdatedAtTime(root, expirationTime) { expirationTime > root.nextKnownPendingLevel && (root.nextKnownPendingLevel = expirationTime)); } +function markRootExpiredAtTime(root, expirationTime) { + var lastExpiredTime = root.lastExpiredTime; + if (0 === lastExpiredTime || lastExpiredTime > expirationTime) + root.lastExpiredTime = expirationTime; +} function findHostInstance(component) { var fiber = component._reactInternalFiber; if (void 0 === fiber) { @@ -7521,10 +7753,14 @@ function findHostInstance(component) { return null === component ? null : component.stateNode; } function updateContainer(element, container, parentComponent, callback) { - var current = container.current, + var current$$1 = container.current, currentTime = requestCurrentTimeForUpdate(), suspenseConfig = ReactCurrentBatchConfig.suspense; - currentTime = computeExpirationForFiber(currentTime, current, suspenseConfig); + currentTime = computeExpirationForFiber( + currentTime, + current$$1, + suspenseConfig + ); a: if (parentComponent) { parentComponent = parentComponent._reactInternalFiber; b: { @@ -7575,8 +7811,8 @@ function updateContainer(element, container, parentComponent, callback) { container.payload = { element: element }; callback = void 0 === callback ? null : callback; null !== callback && (container.callback = callback); - enqueueUpdate(current, container); - scheduleWork(current, currentTime); + enqueueUpdate(current$$1, container); + scheduleUpdateOnFiber(current$$1, currentTime); return currentTime; } function createPortal(children, containerInfo, implementation) { @@ -7590,6 +7826,7 @@ function createPortal(children, containerInfo, implementation) { implementation: implementation }; } +var fabricDispatchCommand = nativeFabricUIManager.dispatchCommand; function findNodeHandle(componentOrHandle) { if (null == componentOrHandle) return null; if ("number" === typeof componentOrHandle) return componentOrHandle; @@ -7600,8 +7837,8 @@ function findNodeHandle(componentOrHandle) { return null == componentOrHandle ? componentOrHandle : componentOrHandle.canonical - ? componentOrHandle.canonical._nativeTag - : componentOrHandle._nativeTag; + ? componentOrHandle.canonical._nativeTag + : componentOrHandle._nativeTag; } batchedUpdatesImpl = function(fn, a) { var prevExecutionContext = executionContext; @@ -7613,116 +7850,291 @@ batchedUpdatesImpl = function(fn, a) { executionContext === NoContext && flushSyncCallbackQueue(); } }; -var roots = new Map(); -(function(devToolsConfig) { - var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance; - return injectInternals({ - bundleType: devToolsConfig.bundleType, - version: devToolsConfig.version, - rendererPackageName: devToolsConfig.rendererPackageName, - rendererConfig: devToolsConfig.rendererConfig, - overrideHookState: null, - overrideProps: null, - setSuspenseHandler: null, - scheduleUpdate: null, - currentDispatcherRef: ReactSharedInternals.ReactCurrentDispatcher, - findHostInstanceByFiber: function(fiber) { - fiber = findCurrentHostFiber(fiber); - return null === fiber ? null : fiber.stateNode; +flushDiscreteUpdatesImpl = function() { + (executionContext & (1 | RenderContext | CommitContext)) === NoContext && + (flushPendingDiscreteUpdates(), flushPassiveEffects()); +}; +var roots = new Map(), + ReactFabric = { + NativeComponent: (function(findNodeHandle, findHostInstance) { + return (function(_React$Component) { + function ReactNativeComponent() { + return _React$Component.apply(this, arguments) || this; + } + _inheritsLoose(ReactNativeComponent, _React$Component); + var _proto = ReactNativeComponent.prototype; + _proto.blur = function() { + ReactNativePrivateInterface.TextInputState.blurTextInput( + findNodeHandle(this) + ); + }; + _proto.focus = function() { + ReactNativePrivateInterface.TextInputState.focusTextInput( + findNodeHandle(this) + ); + }; + _proto.measure = function(callback) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + null != maybeInstance && + (maybeInstance.canonical + ? nativeFabricUIManager.measure( + maybeInstance.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ) + : ReactNativePrivateInterface.UIManager.measure( + findNodeHandle(this), + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + )); + }; + _proto.measureInWindow = function(callback) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + null != maybeInstance && + (maybeInstance.canonical + ? nativeFabricUIManager.measureInWindow( + maybeInstance.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ) + : ReactNativePrivateInterface.UIManager.measureInWindow( + findNodeHandle(this), + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + )); + }; + _proto.measureLayout = function( + relativeToNativeNode, + onSuccess, + onFail + ) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + if (null != maybeInstance && !maybeInstance.canonical) { + if ("number" === typeof relativeToNativeNode) + var relativeNode = relativeToNativeNode; + else + relativeToNativeNode._nativeTag && + (relativeNode = relativeToNativeNode._nativeTag); + null != relativeNode && + ReactNativePrivateInterface.UIManager.measureLayout( + findNodeHandle(this), + relativeNode, + mountSafeCallback_NOT_REALLY_SAFE(this, onFail), + mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) + ); + } + }; + _proto.setNativeProps = function(nativeProps) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + if (null != maybeInstance && !maybeInstance.canonical) { + var nativeTag = + maybeInstance._nativeTag || maybeInstance.canonical._nativeTag; + maybeInstance = + maybeInstance.viewConfig || maybeInstance.canonical.viewConfig; + nativeProps = diffProperties( + null, + emptyObject, + nativeProps, + maybeInstance.validAttributes + ); + null != nativeProps && + ReactNativePrivateInterface.UIManager.updateView( + nativeTag, + maybeInstance.uiViewClassName, + nativeProps + ); + } + }; + return ReactNativeComponent; + })(React.Component); + })(findNodeHandle, findHostInstance), + findHostInstance_DEPRECATED: function(componentOrHandle) { + if (null == componentOrHandle) return null; + if (componentOrHandle._nativeTag) return componentOrHandle; + if (componentOrHandle.canonical && componentOrHandle.canonical._nativeTag) + return componentOrHandle.canonical; + componentOrHandle = findHostInstance(componentOrHandle); + return null == componentOrHandle + ? componentOrHandle + : componentOrHandle.canonical + ? componentOrHandle.canonical + : componentOrHandle; }, - findFiberByHostInstance: function(instance) { - return findFiberByHostInstance ? findFiberByHostInstance(instance) : null; + findNodeHandle: findNodeHandle, + dispatchCommand: function(handle, command, args) { + null != handle._nativeTag && + null != handle._internalInstanceHandle && + fabricDispatchCommand( + handle._internalInstanceHandle.stateNode.node, + command, + args + ); }, - findHostInstancesForRefresh: null, - scheduleRefresh: null, - scheduleRoot: null, - setRefreshHandler: null, - getCurrentFiber: null - }); + render: function(element, containerTag, callback) { + var root = roots.get(containerTag); + if (!root) { + root = new FiberRootNode(containerTag, 0, !1); + var uninitializedFiber = 0; + isDevToolsPresent && (uninitializedFiber |= 8); + uninitializedFiber = createFiber(3, null, null, uninitializedFiber); + root.current = uninitializedFiber; + uninitializedFiber.stateNode = root; + roots.set(containerTag, root); + } + updateContainer(element, root, null, callback); + a: if (((element = root.current), element.child)) + switch (element.child.tag) { + case 5: + element = element.child.stateNode.canonical; + break a; + default: + element = element.child.stateNode; + } + else element = null; + return element; + }, + unmountComponentAtNode: function(containerTag) { + var root = roots.get(containerTag); + root && + updateContainer(null, root, null, function() { + roots.delete(containerTag); + }); + }, + createPortal: function(children, containerTag) { + return createPortal( + children, + containerTag, + null, + 2 < arguments.length && void 0 !== arguments[2] ? arguments[2] : null + ); + }, + __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: { + NativeMethodsMixin: (function(findNodeHandle, findHostInstance) { + return { + measure: function(callback) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + null != maybeInstance && + (maybeInstance.canonical + ? nativeFabricUIManager.measure( + maybeInstance.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ) + : ReactNativePrivateInterface.UIManager.measure( + findNodeHandle(this), + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + )); + }, + measureInWindow: function(callback) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + null != maybeInstance && + (maybeInstance.canonical + ? nativeFabricUIManager.measureInWindow( + maybeInstance.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ) + : ReactNativePrivateInterface.UIManager.measureInWindow( + findNodeHandle(this), + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + )); + }, + measureLayout: function(relativeToNativeNode, onSuccess, onFail) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + if (null != maybeInstance && !maybeInstance.canonical) { + if ("number" === typeof relativeToNativeNode) + var relativeNode = relativeToNativeNode; + else + relativeToNativeNode._nativeTag && + (relativeNode = relativeToNativeNode._nativeTag); + null != relativeNode && + ReactNativePrivateInterface.UIManager.measureLayout( + findNodeHandle(this), + relativeNode, + mountSafeCallback_NOT_REALLY_SAFE(this, onFail), + mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) + ); + } + }, + setNativeProps: function(nativeProps) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + if (null != maybeInstance && !maybeInstance.canonical) { + var nativeTag = + maybeInstance._nativeTag || maybeInstance.canonical._nativeTag; + maybeInstance = + maybeInstance.viewConfig || maybeInstance.canonical.viewConfig; + nativeProps = diffProperties( + null, + emptyObject, + nativeProps, + maybeInstance.validAttributes + ); + null != nativeProps && + ReactNativePrivateInterface.UIManager.updateView( + nativeTag, + maybeInstance.uiViewClassName, + nativeProps + ); + } + }, + focus: function() { + ReactNativePrivateInterface.TextInputState.focusTextInput( + findNodeHandle(this) + ); + }, + blur: function() { + ReactNativePrivateInterface.TextInputState.blurTextInput( + findNodeHandle(this) + ); + } + }; + })(findNodeHandle, findHostInstance) + } + }; +(function(devToolsConfig) { + var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance; + return injectInternals( + Object.assign({}, devToolsConfig, { + overrideHookState: null, + overrideProps: null, + setSuspenseHandler: null, + scheduleUpdate: null, + currentDispatcherRef: ReactSharedInternals.ReactCurrentDispatcher, + findHostInstanceByFiber: function(fiber) { + fiber = findCurrentHostFiber(fiber); + return null === fiber ? null : fiber.stateNode; + }, + findFiberByHostInstance: function(instance) { + return findFiberByHostInstance + ? findFiberByHostInstance(instance) + : null; + }, + findHostInstancesForRefresh: null, + scheduleRefresh: null, + scheduleRoot: null, + setRefreshHandler: null, + getCurrentFiber: null + }) + ); })({ findFiberByHostInstance: getInstanceFromInstance, + getInspectorDataForViewTag: function() { + throw Error("getInspectorDataForViewTag() is not available in production"); + }, bundleType: 0, - version: "16.13.0", - rendererPackageName: "react-native-renderer", - rendererConfig: { - getInspectorDataForViewTag: function() { - throw Error( - "getInspectorDataForViewTag() is not available in production" - ); - }, - getInspectorDataForViewAtPoint: function() { - throw Error( - "getInspectorDataForViewAtPoint() is not available in production." - ); - }.bind(null, findNodeHandle) - } + version: "16.11.0", + rendererPackageName: "react-native-renderer" }); -exports.createPortal = function(children, containerTag) { - return createPortal( - children, - containerTag, - null, - 2 < arguments.length && void 0 !== arguments[2] ? arguments[2] : null - ); -}; -exports.dispatchCommand = function(handle, command, args) { - null != handle._nativeTag && - (handle._internalInstanceHandle - ? nativeFabricUIManager.dispatchCommand( - handle._internalInstanceHandle.stateNode.node, - command, - args - ) - : ReactNativePrivateInterface.UIManager.dispatchViewManagerCommand( - handle._nativeTag, - command, - args - )); -}; -exports.findHostInstance_DEPRECATED = function(componentOrHandle) { - if (null == componentOrHandle) return null; - if (componentOrHandle._nativeTag) return componentOrHandle; - if (componentOrHandle.canonical && componentOrHandle.canonical._nativeTag) - return componentOrHandle.canonical; - componentOrHandle = findHostInstance(componentOrHandle); - return null == componentOrHandle - ? componentOrHandle - : componentOrHandle.canonical - ? componentOrHandle.canonical - : componentOrHandle; -}; -exports.findNodeHandle = findNodeHandle; -exports.render = function(element, containerTag, callback) { - var root = roots.get(containerTag); - if (!root) { - root = new FiberRootNode(containerTag, 0, !1); - var uninitializedFiber = 0; - isDevToolsPresent && (uninitializedFiber |= 8); - uninitializedFiber = new FiberNode(3, null, null, uninitializedFiber); - root.current = uninitializedFiber; - uninitializedFiber.stateNode = root; - initializeUpdateQueue(uninitializedFiber); - roots.set(containerTag, root); - } - updateContainer(element, root, null, callback); - a: if (((element = root.current), element.child)) - switch (element.child.tag) { - case 5: - element = element.child.stateNode.canonical; - break a; - default: - element = element.child.stateNode; - } - else element = null; - return element; -}; -exports.stopSurface = function(containerTag) { - var root = roots.get(containerTag); - root && - updateContainer(null, root, null, function() { - roots.delete(containerTag); - }); -}; -exports.unmountComponentAtNode = function(containerTag) { - this.stopSurface(containerTag); -}; +var ReactFabric$2 = { default: ReactFabric }, + ReactFabric$3 = (ReactFabric$2 && ReactFabric) || ReactFabric$2; +module.exports = ReactFabric$3.default || ReactFabric$3; diff --git a/Libraries/Renderer/implementations/ReactFabric-profiling.js b/Libraries/Renderer/implementations/ReactFabric-profiling.js index cc076b1040285b..d36acbd2303fcf 100644 --- a/Libraries/Renderer/implementations/ReactFabric-profiling.js +++ b/Libraries/Renderer/implementations/ReactFabric-profiling.js @@ -5,7 +5,6 @@ * LICENSE file in the root directory of this source tree. * * @noflow - * @nolint * @providesModule ReactFabric-profiling * @preventMunge * @generated @@ -16,17 +15,86 @@ require("react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore"); var ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/ReactNativePrivateInterface"), React = require("react"), Scheduler = require("scheduler"), - tracing = require("scheduler/tracing"); -function getParent(inst) { - do inst = inst.return; - while (inst && 5 !== inst.tag); - return inst ? inst : null; + tracing = require("scheduler/tracing"), + eventPluginOrder = null, + namesToPlugins = {}; +function recomputePluginOrdering() { + if (eventPluginOrder) + for (var pluginName in namesToPlugins) { + var pluginModule = namesToPlugins[pluginName], + pluginIndex = eventPluginOrder.indexOf(pluginName); + if (!(-1 < pluginIndex)) + throw Error( + "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + + pluginName + + "`." + ); + if (!plugins[pluginIndex]) { + if (!pluginModule.extractEvents) + throw Error( + "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + + pluginName + + "` does not." + ); + plugins[pluginIndex] = pluginModule; + pluginIndex = pluginModule.eventTypes; + for (var eventName in pluginIndex) { + var JSCompiler_inline_result = void 0; + var dispatchConfig = pluginIndex[eventName], + pluginModule$jscomp$0 = pluginModule, + eventName$jscomp$0 = eventName; + if (eventNameDispatchConfigs.hasOwnProperty(eventName$jscomp$0)) + throw Error( + "EventPluginHub: More than one plugin attempted to publish the same event name, `" + + eventName$jscomp$0 + + "`." + ); + eventNameDispatchConfigs[eventName$jscomp$0] = dispatchConfig; + var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; + if (phasedRegistrationNames) { + for (JSCompiler_inline_result in phasedRegistrationNames) + phasedRegistrationNames.hasOwnProperty( + JSCompiler_inline_result + ) && + publishRegistrationName( + phasedRegistrationNames[JSCompiler_inline_result], + pluginModule$jscomp$0, + eventName$jscomp$0 + ); + JSCompiler_inline_result = !0; + } else + dispatchConfig.registrationName + ? (publishRegistrationName( + dispatchConfig.registrationName, + pluginModule$jscomp$0, + eventName$jscomp$0 + ), + (JSCompiler_inline_result = !0)) + : (JSCompiler_inline_result = !1); + if (!JSCompiler_inline_result) + throw Error( + "EventPluginRegistry: Failed to publish event `" + + eventName + + "` for plugin `" + + pluginName + + "`." + ); + } + } + } } -function traverseTwoPhase(inst, fn, arg) { - for (var path = []; inst; ) path.push(inst), (inst = getParent(inst)); - for (inst = path.length; 0 < inst--; ) fn(path[inst], "captured", arg); - for (inst = 0; inst < path.length; inst++) fn(path[inst], "bubbled", arg); +function publishRegistrationName(registrationName, pluginModule) { + if (registrationNameModules[registrationName]) + throw Error( + "EventPluginHub: More than one plugin attempted to publish the same registration name, `" + + registrationName + + "`." + ); + registrationNameModules[registrationName] = pluginModule; } +var plugins = [], + eventNameDispatchConfigs = {}, + registrationNameModules = {}; function invokeGuardedCallbackImpl(name, func, context, a, b, c, d, e, f) { var funcArgs = Array.prototype.slice.call(arguments, 3); try { @@ -97,6 +165,74 @@ function executeDirectDispatch(event) { event._dispatchInstances = null; return dispatchListener; } +function accumulateInto(current, next) { + if (null == next) + throw Error( + "accumulateInto(...): Accumulated items must not be null or undefined." + ); + if (null == current) return next; + if (Array.isArray(current)) { + if (Array.isArray(next)) return current.push.apply(current, next), current; + current.push(next); + return current; + } + return Array.isArray(next) ? [current].concat(next) : [current, next]; +} +function forEachAccumulated(arr, cb, scope) { + Array.isArray(arr) ? arr.forEach(cb, scope) : arr && cb.call(scope, arr); +} +var eventQueue = null; +function executeDispatchesAndReleaseTopLevel(e) { + if (e) { + var dispatchListeners = e._dispatchListeners, + dispatchInstances = e._dispatchInstances; + if (Array.isArray(dispatchListeners)) + for ( + var i = 0; + i < dispatchListeners.length && !e.isPropagationStopped(); + i++ + ) + executeDispatch(e, dispatchListeners[i], dispatchInstances[i]); + else + dispatchListeners && + executeDispatch(e, dispatchListeners, dispatchInstances); + e._dispatchListeners = null; + e._dispatchInstances = null; + e.isPersistent() || e.constructor.release(e); + } +} +var injection = { + injectEventPluginOrder: function(injectedEventPluginOrder) { + if (eventPluginOrder) + throw Error( + "EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React." + ); + eventPluginOrder = Array.prototype.slice.call(injectedEventPluginOrder); + recomputePluginOrdering(); + }, + injectEventPluginsByName: function(injectedNamesToPlugins) { + var isOrderingDirty = !1, + pluginName; + for (pluginName in injectedNamesToPlugins) + if (injectedNamesToPlugins.hasOwnProperty(pluginName)) { + var pluginModule = injectedNamesToPlugins[pluginName]; + if ( + !namesToPlugins.hasOwnProperty(pluginName) || + namesToPlugins[pluginName] !== pluginModule + ) { + if (namesToPlugins[pluginName]) + throw Error( + "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + + pluginName + + "`." + ); + namesToPlugins[pluginName] = pluginModule; + isOrderingDirty = !0; + } + } + isOrderingDirty && recomputePluginOrdering(); + } +}; function getListener(inst, registrationName) { var listener = inst.stateNode; if (!listener) return null; @@ -114,7 +250,6 @@ function getListener(inst, registrationName) { case "onMouseMoveCapture": case "onMouseUp": case "onMouseUpCapture": - case "onMouseEnter": (props = !props.disabled) || ((inst = inst.type), (props = !( @@ -139,21 +274,15 @@ function getListener(inst, registrationName) { ); return listener; } -function accumulateInto(current, next) { - if (null == next) - throw Error( - "accumulateInto(...): Accumulated items must not be null or undefined." - ); - if (null == current) return next; - if (Array.isArray(current)) { - if (Array.isArray(next)) return current.push.apply(current, next), current; - current.push(next); - return current; - } - return Array.isArray(next) ? [current].concat(next) : [current, next]; +function getParent(inst) { + do inst = inst.return; + while (inst && 5 !== inst.tag); + return inst ? inst : null; } -function forEachAccumulated(arr, cb, scope) { - Array.isArray(arr) ? arr.forEach(cb, scope) : arr && cb.call(scope, arr); +function traverseTwoPhase(inst, fn, arg) { + for (var path = []; inst; ) path.push(inst), (inst = getParent(inst)); + for (inst = path.length; 0 < inst--; ) fn(path[inst], "captured", arg); + for (inst = 0; inst < path.length; inst++) fn(path[inst], "bubbled", arg); } function accumulateDirectionalDispatches(inst, phase, event) { if ( @@ -221,8 +350,8 @@ function SyntheticEvent( ((targetInst = dispatchConfig[propName]) ? (this[propName] = targetInst(nativeEvent)) : "target" === propName - ? (this.target = nativeEventTarget) - : (this[propName] = nativeEvent[propName])); + ? (this.target = nativeEventTarget) + : (this[propName] = nativeEvent[propName])); this.isDefaultPrevented = (null != nativeEvent.defaultPrevented ? nativeEvent.defaultPrevented : !1 === nativeEvent.returnValue) @@ -375,27 +504,53 @@ function recordTouchStart(touch) { } function recordTouchMove(touch) { var touchRecord = touchBank[getTouchIdentifier(touch)]; - touchRecord && - ((touchRecord.touchActive = !0), - (touchRecord.previousPageX = touchRecord.currentPageX), - (touchRecord.previousPageY = touchRecord.currentPageY), - (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), - (touchRecord.currentPageX = touch.pageX), - (touchRecord.currentPageY = touch.pageY), - (touchRecord.currentTimeStamp = timestampForTouch(touch)), - (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))); + touchRecord + ? ((touchRecord.touchActive = !0), + (touchRecord.previousPageX = touchRecord.currentPageX), + (touchRecord.previousPageY = touchRecord.currentPageY), + (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), + (touchRecord.currentPageX = touch.pageX), + (touchRecord.currentPageY = touch.pageY), + (touchRecord.currentTimeStamp = timestampForTouch(touch)), + (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))) + : console.warn( + "Cannot record touch move without a touch start.\nTouch Move: %s\n", + "Touch Bank: %s", + printTouch(touch), + printTouchBank() + ); } function recordTouchEnd(touch) { var touchRecord = touchBank[getTouchIdentifier(touch)]; - touchRecord && - ((touchRecord.touchActive = !1), - (touchRecord.previousPageX = touchRecord.currentPageX), - (touchRecord.previousPageY = touchRecord.currentPageY), - (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), - (touchRecord.currentPageX = touch.pageX), - (touchRecord.currentPageY = touch.pageY), - (touchRecord.currentTimeStamp = timestampForTouch(touch)), - (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))); + touchRecord + ? ((touchRecord.touchActive = !1), + (touchRecord.previousPageX = touchRecord.currentPageX), + (touchRecord.previousPageY = touchRecord.currentPageY), + (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), + (touchRecord.currentPageX = touch.pageX), + (touchRecord.currentPageY = touch.pageY), + (touchRecord.currentTimeStamp = timestampForTouch(touch)), + (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))) + : console.warn( + "Cannot record touch end without a touch start.\nTouch End: %s\n", + "Touch Bank: %s", + printTouch(touch), + printTouchBank() + ); +} +function printTouch(touch) { + return JSON.stringify({ + identifier: touch.identifier, + pageX: touch.pageX, + pageY: touch.pageY, + timestamp: timestampForTouch(touch) + }); +} +function printTouchBank() { + var printed = JSON.stringify(touchBank.slice(0, 20)); + 20 < touchBank.length && + (printed += " (original size: " + touchBank.length + ")"); + return printed; } var ResponderTouchHistoryStore = { recordTouchTrack: function(topLevelType, nativeEvent) { @@ -435,10 +590,10 @@ function accumulate(current, next) { return null == current ? next : Array.isArray(current) - ? current.concat(next) - : Array.isArray(next) - ? [current].concat(next) - : [current, next]; + ? current.concat(next) + : Array.isArray(next) + ? [current].concat(next) + : [current, next]; } var responderInst = null, trackedTouchCount = 0; @@ -528,7 +683,13 @@ var eventTypes = { "topTouchCancel" === topLevelType ) if (0 <= trackedTouchCount) --trackedTouchCount; - else return null; + else + return ( + console.warn( + "Ended a touch event which was not counted in `trackedTouchCount`." + ), + null + ); ResponderTouchHistoryStore.recordTouchTrack(topLevelType, nativeEvent); if ( targetInst && @@ -540,10 +701,10 @@ var eventTypes = { var shouldSetEventType = isStartish(topLevelType) ? eventTypes.startShouldSetResponder : isMoveish(topLevelType) - ? eventTypes.moveShouldSetResponder - : "topSelectionChange" === topLevelType - ? eventTypes.selectionChangeShouldSetResponder - : eventTypes.scrollShouldSetResponder; + ? eventTypes.moveShouldSetResponder + : "topSelectionChange" === topLevelType + ? eventTypes.selectionChangeShouldSetResponder + : eventTypes.scrollShouldSetResponder; if (responderInst) b: { var JSCompiler_temp = responderInst; @@ -697,10 +858,10 @@ var eventTypes = { (shouldSetEventType = shouldSetEventType ? eventTypes.responderStart : JSCompiler_temp - ? eventTypes.responderMove - : targetInst - ? eventTypes.responderEnd - : null) + ? eventTypes.responderMove + : targetInst + ? eventTypes.responderEnd + : null) ) (shouldSetEventType = ResponderSyntheticEvent.getPooled( shouldSetEventType, @@ -763,8 +924,8 @@ var eventTypes = { (topLevelType = shouldSetEventType ? eventTypes.responderTerminate : topLevelType - ? eventTypes.responderRelease - : null) + ? eventTypes.responderRelease + : null) ) (nativeEvent = ResponderSyntheticEvent.getPooled( topLevelType, @@ -788,160 +949,48 @@ var eventTypes = { } } }, - eventPluginOrder = null, - namesToPlugins = {}; -function recomputePluginOrdering() { - if (eventPluginOrder) - for (var pluginName in namesToPlugins) { - var pluginModule = namesToPlugins[pluginName], - pluginIndex = eventPluginOrder.indexOf(pluginName); - if (!(-1 < pluginIndex)) - throw Error( - "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + - pluginName + - "`." - ); - if (!plugins[pluginIndex]) { - if (!pluginModule.extractEvents) - throw Error( - "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + - pluginName + - "` does not." - ); - plugins[pluginIndex] = pluginModule; - pluginIndex = pluginModule.eventTypes; - for (var eventName in pluginIndex) { - var JSCompiler_inline_result = void 0; - var dispatchConfig = pluginIndex[eventName], - pluginModule$jscomp$0 = pluginModule, - eventName$jscomp$0 = eventName; - if (eventNameDispatchConfigs.hasOwnProperty(eventName$jscomp$0)) - throw Error( - "EventPluginRegistry: More than one plugin attempted to publish the same event name, `" + - eventName$jscomp$0 + - "`." - ); - eventNameDispatchConfigs[eventName$jscomp$0] = dispatchConfig; - var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; - if (phasedRegistrationNames) { - for (JSCompiler_inline_result in phasedRegistrationNames) - phasedRegistrationNames.hasOwnProperty( - JSCompiler_inline_result - ) && - publishRegistrationName( - phasedRegistrationNames[JSCompiler_inline_result], - pluginModule$jscomp$0, - eventName$jscomp$0 - ); - JSCompiler_inline_result = !0; - } else - dispatchConfig.registrationName - ? (publishRegistrationName( - dispatchConfig.registrationName, - pluginModule$jscomp$0, - eventName$jscomp$0 - ), - (JSCompiler_inline_result = !0)) - : (JSCompiler_inline_result = !1); - if (!JSCompiler_inline_result) - throw Error( - "EventPluginRegistry: Failed to publish event `" + - eventName + - "` for plugin `" + - pluginName + - "`." - ); - } - } - } -} -function publishRegistrationName(registrationName, pluginModule) { - if (registrationNameModules[registrationName]) - throw Error( - "EventPluginRegistry: More than one plugin attempted to publish the same registration name, `" + - registrationName + - "`." - ); - registrationNameModules[registrationName] = pluginModule; -} -var plugins = [], - eventNameDispatchConfigs = {}, - registrationNameModules = {}, customBubblingEventTypes = ReactNativePrivateInterface.ReactNativeViewConfigRegistry .customBubblingEventTypes, customDirectEventTypes = ReactNativePrivateInterface.ReactNativeViewConfigRegistry .customDirectEventTypes; -if (eventPluginOrder) - throw Error( - "EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React." - ); -eventPluginOrder = Array.prototype.slice.call([ +injection.injectEventPluginOrder([ "ResponderEventPlugin", "ReactNativeBridgeEventPlugin" ]); -recomputePluginOrdering(); -var injectedNamesToPlugins$jscomp$inline_92 = { - ResponderEventPlugin: ResponderEventPlugin, - ReactNativeBridgeEventPlugin: { - eventTypes: {}, - extractEvents: function( - topLevelType, - targetInst, - nativeEvent, - nativeEventTarget - ) { - if (null == targetInst) return null; - var bubbleDispatchConfig = customBubblingEventTypes[topLevelType], - directDispatchConfig = customDirectEventTypes[topLevelType]; - if (!bubbleDispatchConfig && !directDispatchConfig) - throw Error( - 'Unsupported top level event type "' + topLevelType + '" dispatched' - ); - topLevelType = SyntheticEvent.getPooled( - bubbleDispatchConfig || directDispatchConfig, - targetInst, - nativeEvent, - nativeEventTarget - ); - if (bubbleDispatchConfig) - forEachAccumulated(topLevelType, accumulateTwoPhaseDispatchesSingle); - else if (directDispatchConfig) - forEachAccumulated(topLevelType, accumulateDirectDispatchesSingle); - else return null; - return topLevelType; - } - } - }, - isOrderingDirty$jscomp$inline_93 = !1, - pluginName$jscomp$inline_94; -for (pluginName$jscomp$inline_94 in injectedNamesToPlugins$jscomp$inline_92) - if ( - injectedNamesToPlugins$jscomp$inline_92.hasOwnProperty( - pluginName$jscomp$inline_94 - ) - ) { - var pluginModule$jscomp$inline_95 = - injectedNamesToPlugins$jscomp$inline_92[pluginName$jscomp$inline_94]; - if ( - !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_94) || - namesToPlugins[pluginName$jscomp$inline_94] !== - pluginModule$jscomp$inline_95 +injection.injectEventPluginsByName({ + ResponderEventPlugin: ResponderEventPlugin, + ReactNativeBridgeEventPlugin: { + eventTypes: {}, + extractEvents: function( + topLevelType, + targetInst, + nativeEvent, + nativeEventTarget ) { - if (namesToPlugins[pluginName$jscomp$inline_94]) + if (null == targetInst) return null; + var bubbleDispatchConfig = customBubblingEventTypes[topLevelType], + directDispatchConfig = customDirectEventTypes[topLevelType]; + if (!bubbleDispatchConfig && !directDispatchConfig) throw Error( - "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - pluginName$jscomp$inline_94 + - "`." + 'Unsupported top level event type "' + topLevelType + '" dispatched' ); - namesToPlugins[ - pluginName$jscomp$inline_94 - ] = pluginModule$jscomp$inline_95; - isOrderingDirty$jscomp$inline_93 = !0; + topLevelType = SyntheticEvent.getPooled( + bubbleDispatchConfig || directDispatchConfig, + targetInst, + nativeEvent, + nativeEventTarget + ); + if (bubbleDispatchConfig) + forEachAccumulated(topLevelType, accumulateTwoPhaseDispatchesSingle); + else if (directDispatchConfig) + forEachAccumulated(topLevelType, accumulateDirectDispatchesSingle); + else return null; + return topLevelType; } } -isOrderingDirty$jscomp$inline_93 && recomputePluginOrdering(); +}); function getInstanceFromInstance(instanceHandle) { return instanceHandle; } @@ -950,8 +999,8 @@ getFiberCurrentPropsFromNode = function(inst) { }; getInstanceFromNode = getInstanceFromInstance; getNodeFromInstance = function(inst) { - inst = inst.stateNode.canonical; - if (!inst._nativeTag) throw Error("All native instances should have a tag."); + inst = inst.stateNode.canonical._nativeTag; + if (!inst) throw Error("All native instances should have a tag."); return inst; }; ResponderEventPlugin.injection.injectGlobalResponderHandler({ @@ -987,9 +1036,11 @@ var hasSymbol = "function" === typeof Symbol && Symbol.for, ? Symbol.for("react.suspense_list") : 60120, REACT_MEMO_TYPE = hasSymbol ? Symbol.for("react.memo") : 60115, - REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 60116, - REACT_BLOCK_TYPE = hasSymbol ? Symbol.for("react.block") : 60121, - MAYBE_ITERATOR_SYMBOL = "function" === typeof Symbol && Symbol.iterator; + REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 60116; +hasSymbol && Symbol.for("react.fundamental"); +hasSymbol && Symbol.for("react.responder"); +hasSymbol && Symbol.for("react.scope"); +var MAYBE_ITERATOR_SYMBOL = "function" === typeof Symbol && Symbol.iterator; function getIteratorFn(maybeIterable) { if (null === maybeIterable || "object" !== typeof maybeIterable) return null; maybeIterable = @@ -999,10 +1050,9 @@ function getIteratorFn(maybeIterable) { } function initializeLazyComponentType(lazyComponent) { if (-1 === lazyComponent._status) { - var ctor = lazyComponent._result; - ctor || (ctor = lazyComponent._ctor); - ctor = ctor(); lazyComponent._status = 0; + var ctor = lazyComponent._ctor; + ctor = ctor(); lazyComponent._result = ctor; ctor.then( function(moduleObject) { @@ -1039,9 +1089,9 @@ function getComponentName(type) { if ("object" === typeof type) switch (type.$$typeof) { case REACT_CONTEXT_TYPE: - return (type.displayName || "Context") + ".Consumer"; + return "Context.Consumer"; case REACT_PROVIDER_TYPE: - return (type._context.displayName || "Context") + ".Provider"; + return "Context.Provider"; case REACT_FORWARD_REF_TYPE: var innerType = type.render; innerType = innerType.displayName || innerType.name || ""; @@ -1051,8 +1101,6 @@ function getComponentName(type) { ); case REACT_MEMO_TYPE: return getComponentName(type.type); - case REACT_BLOCK_TYPE: - return getComponentName(type.render); case REACT_LAZY_TYPE: if ((type = 1 === type._status ? type._result : null)) return getComponentName(type); @@ -1242,8 +1290,8 @@ function diffNestedProperty( return nextProp ? addNestedProperty(updatePayload, nextProp, validAttributes) : prevProp - ? clearNestedProperty(updatePayload, prevProp, validAttributes) - : updatePayload; + ? clearNestedProperty(updatePayload, prevProp, validAttributes) + : updatePayload; if (!Array.isArray(prevProp) && !Array.isArray(nextProp)) return diffProperties(updatePayload, prevProp, nextProp, validAttributes); if (Array.isArray(prevProp) && Array.isArray(nextProp)) { @@ -1404,9 +1452,18 @@ function diffProperties(updatePayload, prevProps, nextProps, validAttributes) { ))))); return updatePayload; } +var restoreTarget = null, + restoreQueue = null; +function restoreStateOfTarget(target) { + if (getInstanceFromNode(target)) + throw Error( + "setRestoreImplementation() needs to be called to handle a target for controlled events. This error is likely caused by a bug in React. Please file an issue." + ); +} function batchedUpdatesImpl(fn, bookkeeping) { return fn(bookkeeping); } +function flushDiscreteUpdatesImpl() {} var isInsideEventHandler = !1; function batchedUpdates(fn, bookkeeping) { if (isInsideEventHandler) return fn(bookkeeping); @@ -1414,35 +1471,46 @@ function batchedUpdates(fn, bookkeeping) { try { return batchedUpdatesImpl(fn, bookkeeping); } finally { - isInsideEventHandler = !1; - } -} -var eventQueue = null; -function executeDispatchesAndReleaseTopLevel(e) { - if (e) { - var dispatchListeners = e._dispatchListeners, - dispatchInstances = e._dispatchInstances; - if (Array.isArray(dispatchListeners)) - for ( - var i = 0; - i < dispatchListeners.length && !e.isPropagationStopped(); - i++ + if ( + ((isInsideEventHandler = !1), + null !== restoreTarget || null !== restoreQueue) + ) + if ( + (flushDiscreteUpdatesImpl(), + restoreTarget && + ((bookkeeping = restoreTarget), + (fn = restoreQueue), + (restoreQueue = restoreTarget = null), + restoreStateOfTarget(bookkeeping), + fn)) ) - executeDispatch(e, dispatchListeners[i], dispatchInstances[i]); - else - dispatchListeners && - executeDispatch(e, dispatchListeners, dispatchInstances); - e._dispatchListeners = null; - e._dispatchInstances = null; - e.isPersistent() || e.constructor.release(e); + for (bookkeeping = 0; bookkeeping < fn.length; bookkeeping++) + restoreStateOfTarget(fn[bookkeeping]); } } +function _inheritsLoose(subClass, superClass) { + subClass.prototype = Object.create(superClass.prototype); + subClass.prototype.constructor = subClass; + subClass.__proto__ = superClass; +} +(function(_React$Component) { + function ReactNativeComponent() { + return _React$Component.apply(this, arguments) || this; + } + _inheritsLoose(ReactNativeComponent, _React$Component); + var _proto = ReactNativeComponent.prototype; + _proto.blur = function() {}; + _proto.focus = function() {}; + _proto.measure = function() {}; + _proto.measureInWindow = function() {}; + _proto.measureLayout = function() {}; + _proto.setNativeProps = function() {}; + return ReactNativeComponent; +})(React.Component); +new Map(); function dispatchEvent(target, topLevelType, nativeEvent) { var eventTarget = null; - if (null != target) { - var stateNode = target.stateNode; - null != stateNode && (eventTarget = stateNode.canonical); - } + eventTarget = nativeEvent.target; batchedUpdates(function() { var events = eventTarget; for (var events$jscomp$0 = null, i = 0; i < plugins.length; i++) { @@ -1480,21 +1548,21 @@ function shim$1() { "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." ); } -var _nativeFabricUIManage = nativeFabricUIManager, - createNode = _nativeFabricUIManage.createNode, - cloneNode = _nativeFabricUIManage.cloneNode, - cloneNodeWithNewChildren = _nativeFabricUIManage.cloneNodeWithNewChildren, +var _nativeFabricUIManage$1 = nativeFabricUIManager, + createNode = _nativeFabricUIManage$1.createNode, + cloneNode = _nativeFabricUIManage$1.cloneNode, + cloneNodeWithNewChildren = _nativeFabricUIManage$1.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, + _nativeFabricUIManage$1.cloneNodeWithNewChildrenAndProps, + cloneNodeWithNewProps = _nativeFabricUIManage$1.cloneNodeWithNewProps, + createChildNodeSet = _nativeFabricUIManage$1.createChildSet, + appendChildNode = _nativeFabricUIManage$1.appendChild, + appendChildNodeToSet = _nativeFabricUIManage$1.appendChildToSet, + completeRoot = _nativeFabricUIManage$1.completeRoot, + registerEventHandler = _nativeFabricUIManage$1.registerEventHandler, + fabricMeasure = _nativeFabricUIManage$1.measure, + fabricMeasureInWindow = _nativeFabricUIManage$1.measureInWindow, + fabricMeasureLayout = _nativeFabricUIManage$1.measureLayout, getViewConfigForType = ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get, nextReactTag = 2; @@ -1513,10 +1581,10 @@ var ReactFabricHostComponent = (function() { } var _proto = ReactFabricHostComponent.prototype; _proto.blur = function() { - ReactNativePrivateInterface.TextInputState.blurTextInput(this); + ReactNativePrivateInterface.TextInputState.blurTextInput(this._nativeTag); }; _proto.focus = function() { - ReactNativePrivateInterface.TextInputState.focusTextInput(this); + ReactNativePrivateInterface.TextInputState.focusTextInput(this._nativeTag); }; _proto.measure = function(callback) { fabricMeasure( @@ -1578,6 +1646,44 @@ function cloneHiddenInstance(instance) { canonical: instance.canonical }; } +var BEFORE_SLASH_RE = /^(.*)[\\\/]/; +function getStackByFiberInDevAndProd(workInProgress) { + var info = ""; + do { + a: switch (workInProgress.tag) { + case 3: + case 4: + case 6: + case 7: + case 10: + case 9: + var JSCompiler_inline_result = ""; + break a; + default: + var owner = workInProgress._debugOwner, + source = workInProgress._debugSource, + name = getComponentName(workInProgress.type); + JSCompiler_inline_result = null; + owner && (JSCompiler_inline_result = getComponentName(owner.type)); + owner = name; + name = ""; + source + ? (name = + " (at " + + source.fileName.replace(BEFORE_SLASH_RE, "") + + ":" + + source.lineNumber + + ")") + : JSCompiler_inline_result && + (name = " (created by " + JSCompiler_inline_result + ")"); + JSCompiler_inline_result = "\n in " + (owner || "Unknown") + name; + } + info += JSCompiler_inline_result; + workInProgress = workInProgress.return; + } while (workInProgress); + return info; +} +new Set(); var valueStack = [], index = -1; function pop(cursor) { @@ -1615,17 +1721,21 @@ function isContextProvider(type) { type = type.childContextTypes; return null !== type && void 0 !== type; } -function popContext() { - pop(didPerformWorkStackCursor); - pop(contextStackCursor); +function popContext(fiber) { + pop(didPerformWorkStackCursor, fiber); + pop(contextStackCursor, fiber); +} +function popTopLevelContextObject(fiber) { + pop(didPerformWorkStackCursor, fiber); + pop(contextStackCursor, fiber); } 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); + push(contextStackCursor, context, fiber); + push(didPerformWorkStackCursor, didChange, fiber); } function processChildContext(fiber, type, parentContext) { var instance = fiber.stateNode; @@ -1643,13 +1753,17 @@ function processChildContext(fiber, type, parentContext) { return Object.assign({}, parentContext, {}, instance); } function pushContextProvider(workInProgress) { - workInProgress = - ((workInProgress = workInProgress.stateNode) && - workInProgress.__reactInternalMemoizedMergedChildContext) || + var instance = workInProgress.stateNode; + instance = + (instance && instance.__reactInternalMemoizedMergedChildContext) || emptyContextObject; previousContext = contextStackCursor.current; - push(contextStackCursor, workInProgress); - push(didPerformWorkStackCursor, didPerformWorkStackCursor.current); + push(contextStackCursor, instance, workInProgress); + push( + didPerformWorkStackCursor, + didPerformWorkStackCursor.current, + workInProgress + ); return !0; } function invalidateContextProvider(workInProgress, type, didChange) { @@ -1659,17 +1773,13 @@ function invalidateContextProvider(workInProgress, type, didChange) { "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); + ? ((type = processChildContext(workInProgress, type, previousContext)), + (instance.__reactInternalMemoizedMergedChildContext = type), + pop(didPerformWorkStackCursor, workInProgress), + pop(contextStackCursor, workInProgress), + push(contextStackCursor, type, workInProgress)) + : pop(didPerformWorkStackCursor, workInProgress); + push(didPerformWorkStackCursor, didChange, workInProgress); } var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback, @@ -1736,7 +1846,7 @@ function reactPriorityToSchedulerPriority(reactPriorityLevel) { throw Error("Unknown priority level."); } } -function runWithPriority(reactPriorityLevel, fn) { +function runWithPriority$1(reactPriorityLevel, fn) { reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); return Scheduler_runWithPriority(reactPriorityLevel, fn); } @@ -1768,7 +1878,7 @@ function flushSyncCallbackQueueImpl() { var i = 0; try { var queue = syncQueue; - runWithPriority(99, function() { + runWithPriority$1(99, function() { for (; i < queue.length; i++) { var callback = queue[i]; do callback = callback(!0); @@ -1796,18 +1906,18 @@ function inferPriorityFromExpirationTime(currentTime, expirationTime) { return 0 >= currentTime ? 99 : 250 >= currentTime - ? 98 - : 5250 >= currentTime - ? 97 - : 95; + ? 98 + : 5250 >= currentTime + ? 97 + : 95; } function is(x, y) { return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y); } -var objectIs = "function" === typeof Object.is ? Object.is : is, +var is$1 = "function" === typeof Object.is ? Object.is : is, hasOwnProperty = Object.prototype.hasOwnProperty; function shallowEqual(objA, objB) { - if (objectIs(objA, objB)) return !0; + if (is$1(objA, objB)) return !0; if ( "object" !== typeof objA || null === objA || @@ -1821,48 +1931,11 @@ function shallowEqual(objA, objB) { for (keysB = 0; keysB < keysA.length; keysB++) if ( !hasOwnProperty.call(objB, keysA[keysB]) || - !objectIs(objA[keysA[keysB]], objB[keysA[keysB]]) + !is$1(objA[keysA[keysB]], objB[keysA[keysB]]) ) return !1; return !0; } -var BEFORE_SLASH_RE = /^(.*)[\\\/]/; -function getStackByFiberInDevAndProd(workInProgress) { - var info = ""; - do { - a: switch (workInProgress.tag) { - case 3: - case 4: - case 6: - case 7: - case 10: - case 9: - var JSCompiler_inline_result = ""; - break a; - default: - var owner = workInProgress._debugOwner, - source = workInProgress._debugSource, - name = getComponentName(workInProgress.type); - JSCompiler_inline_result = null; - owner && (JSCompiler_inline_result = getComponentName(owner.type)); - owner = name; - name = ""; - source - ? (name = - " (at " + - source.fileName.replace(BEFORE_SLASH_RE, "") + - ":" + - source.lineNumber + - ")") - : JSCompiler_inline_result && - (name = " (created by " + JSCompiler_inline_result + ")"); - JSCompiler_inline_result = "\n in " + (owner || "Unknown") + name; - } - info += JSCompiler_inline_result; - workInProgress = workInProgress.return; - } while (workInProgress); - return info; -} function resolveDefaultProps(Component, baseProps) { if (Component && Component.defaultProps) { baseProps = Object.assign({}, baseProps); @@ -1880,9 +1953,14 @@ var valueCursor = { current: null }, function resetContextDependencies() { lastContextWithAllBitsObserved = lastContextDependency = currentlyRenderingFiber = null; } +function pushProvider(providerFiber, nextValue) { + var context = providerFiber.type._context; + push(valueCursor, context._currentValue2, providerFiber); + context._currentValue2 = nextValue; +} function popProvider(providerFiber) { var currentValue = valueCursor.current; - pop(valueCursor); + pop(valueCursor, providerFiber); providerFiber.type._context._currentValue2 = currentValue; } function scheduleWorkOnParentPath(parent, renderExpirationTime) { @@ -1937,195 +2015,237 @@ function readContext(context, observedBits) { return context._currentValue2; } var hasForceUpdate = !1; -function initializeUpdateQueue(fiber) { - fiber.updateQueue = { - baseState: fiber.memoizedState, - baseQueue: null, - shared: { pending: null }, - effects: null +function createUpdateQueue(baseState) { + return { + baseState: baseState, + firstUpdate: null, + lastUpdate: null, + firstCapturedUpdate: null, + lastCapturedUpdate: null, + firstEffect: null, + lastEffect: null, + firstCapturedEffect: null, + lastCapturedEffect: null }; } -function cloneUpdateQueue(current, workInProgress) { - current = current.updateQueue; - workInProgress.updateQueue === current && - (workInProgress.updateQueue = { - baseState: current.baseState, - baseQueue: current.baseQueue, - shared: current.shared, - effects: current.effects - }); +function cloneUpdateQueue(currentQueue) { + return { + baseState: currentQueue.baseState, + firstUpdate: currentQueue.firstUpdate, + lastUpdate: currentQueue.lastUpdate, + firstCapturedUpdate: null, + lastCapturedUpdate: null, + firstEffect: null, + lastEffect: null, + firstCapturedEffect: null, + lastCapturedEffect: null + }; } function createUpdate(expirationTime, suspenseConfig) { - expirationTime = { + return { expirationTime: expirationTime, suspenseConfig: suspenseConfig, tag: 0, payload: null, callback: null, - next: null + next: null, + nextEffect: null }; - return (expirationTime.next = expirationTime); +} +function appendUpdateToQueue(queue, update) { + null === queue.lastUpdate + ? (queue.firstUpdate = queue.lastUpdate = update) + : ((queue.lastUpdate.next = update), (queue.lastUpdate = update)); } function enqueueUpdate(fiber, update) { - 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; - } + var alternate = fiber.alternate; + if (null === alternate) { + var queue1 = fiber.updateQueue; + var queue2 = null; + null === queue1 && + (queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState)); + } else + (queue1 = fiber.updateQueue), + (queue2 = alternate.updateQueue), + null === queue1 + ? null === queue2 + ? ((queue1 = fiber.updateQueue = createUpdateQueue( + fiber.memoizedState + )), + (queue2 = alternate.updateQueue = createUpdateQueue( + alternate.memoizedState + ))) + : (queue1 = fiber.updateQueue = cloneUpdateQueue(queue2)) + : null === queue2 && + (queue2 = alternate.updateQueue = cloneUpdateQueue(queue1)); + null === queue2 || queue1 === queue2 + ? appendUpdateToQueue(queue1, update) + : null === queue1.lastUpdate || null === queue2.lastUpdate + ? (appendUpdateToQueue(queue1, update), + appendUpdateToQueue(queue2, update)) + : (appendUpdateToQueue(queue1, update), (queue2.lastUpdate = update)); } function enqueueCapturedUpdate(workInProgress, update) { + var workInProgressQueue = workInProgress.updateQueue; + workInProgressQueue = + null === workInProgressQueue + ? (workInProgress.updateQueue = createUpdateQueue( + workInProgress.memoizedState + )) + : ensureWorkInProgressQueueIsAClone(workInProgress, workInProgressQueue); + null === workInProgressQueue.lastCapturedUpdate + ? (workInProgressQueue.firstCapturedUpdate = workInProgressQueue.lastCapturedUpdate = update) + : ((workInProgressQueue.lastCapturedUpdate.next = update), + (workInProgressQueue.lastCapturedUpdate = update)); +} +function ensureWorkInProgressQueueIsAClone(workInProgress, queue) { var current = workInProgress.alternate; - null !== current && cloneUpdateQueue(current, workInProgress); - workInProgress = workInProgress.updateQueue; - current = workInProgress.baseQueue; - null === current - ? ((workInProgress.baseQueue = update.next = update), - (update.next = update)) - : ((update.next = current.next), (current.next = update)); + null !== current && + queue === current.updateQueue && + (queue = workInProgress.updateQueue = cloneUpdateQueue(queue)); + return queue; +} +function getStateFromUpdate( + workInProgress, + queue, + update, + prevState, + nextProps, + instance +) { + switch (update.tag) { + case 1: + return ( + (workInProgress = update.payload), + "function" === typeof workInProgress + ? workInProgress.call(instance, prevState, nextProps) + : workInProgress + ); + case 3: + workInProgress.effectTag = (workInProgress.effectTag & -4097) | 64; + case 0: + workInProgress = update.payload; + nextProps = + "function" === typeof workInProgress + ? workInProgress.call(instance, prevState, nextProps) + : workInProgress; + if (null === nextProps || void 0 === nextProps) break; + return Object.assign({}, prevState, nextProps); + case 2: + hasForceUpdate = !0; + } + return prevState; } function processUpdateQueue( - workInProgress$jscomp$0, + workInProgress, + queue, props, instance, renderExpirationTime ) { - var queue = workInProgress$jscomp$0.updateQueue; hasForceUpdate = !1; - var baseQueue = queue.baseQueue, - pendingQueue = queue.shared.pending; - if (null !== pendingQueue) { - if (null !== baseQueue) { - var baseFirst = baseQueue.next; - baseQueue.next = pendingQueue.next; - pendingQueue.next = baseFirst; - } - baseQueue = pendingQueue; - queue.shared.pending = null; - baseFirst = workInProgress$jscomp$0.alternate; - null !== baseFirst && - ((baseFirst = baseFirst.updateQueue), - null !== baseFirst && (baseFirst.baseQueue = pendingQueue)); - } - if (null !== baseQueue) { - baseFirst = baseQueue.next; - var newState = queue.baseState, + queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue); + for ( + var newBaseState = queue.baseState, + newFirstUpdate = null, newExpirationTime = 0, - newBaseState = null, - newBaseQueueFirst = null, - newBaseQueueLast = null; - if (null !== baseFirst) { - var update = baseFirst; - do { - pendingQueue = update.expirationTime; - if (pendingQueue < renderExpirationTime) { - var clone = { - expirationTime: update.expirationTime, - suspenseConfig: update.suspenseConfig, - tag: update.tag, - payload: update.payload, - callback: update.callback, - next: null - }; - null === newBaseQueueLast - ? ((newBaseQueueFirst = newBaseQueueLast = clone), - (newBaseState = newState)) - : (newBaseQueueLast = newBaseQueueLast.next = clone); - pendingQueue > newExpirationTime && - (newExpirationTime = pendingQueue); - } else { - null !== newBaseQueueLast && - (newBaseQueueLast = newBaseQueueLast.next = { - expirationTime: 1073741823, - suspenseConfig: update.suspenseConfig, - tag: update.tag, - payload: update.payload, - callback: update.callback, - next: null - }); - markRenderEventTimeAndConfig(pendingQueue, update.suspenseConfig); - a: { - var workInProgress = workInProgress$jscomp$0, - update$jscomp$0 = update; - pendingQueue = props; - clone = instance; - switch (update$jscomp$0.tag) { - case 1: - workInProgress = update$jscomp$0.payload; - if ("function" === typeof workInProgress) { - newState = workInProgress.call(clone, newState, pendingQueue); - break a; - } - newState = workInProgress; - break a; - case 3: - workInProgress.effectTag = - (workInProgress.effectTag & -4097) | 64; - case 0: - workInProgress = update$jscomp$0.payload; - pendingQueue = - "function" === typeof workInProgress - ? workInProgress.call(clone, newState, pendingQueue) - : workInProgress; - if (null === pendingQueue || void 0 === pendingQueue) break a; - newState = Object.assign({}, newState, pendingQueue); - break a; - case 2: - hasForceUpdate = !0; - } - } - null !== update.callback && - ((workInProgress$jscomp$0.effectTag |= 32), - (pendingQueue = queue.effects), - null === pendingQueue - ? (queue.effects = [update]) - : pendingQueue.push(update)); - } - update = update.next; - if (null === update || update === baseFirst) - if (((pendingQueue = queue.shared.pending), null === pendingQueue)) - break; - else - (update = baseQueue.next = pendingQueue.next), - (pendingQueue.next = baseFirst), - (queue.baseQueue = baseQueue = pendingQueue), - (queue.shared.pending = null); - } while (1); - } - null === newBaseQueueLast - ? (newBaseState = newState) - : (newBaseQueueLast.next = newBaseQueueFirst); - queue.baseState = newBaseState; - queue.baseQueue = newBaseQueueLast; - markUnprocessedUpdateTime(newExpirationTime); - workInProgress$jscomp$0.expirationTime = newExpirationTime; - workInProgress$jscomp$0.memoizedState = newState; + update = queue.firstUpdate, + resultState = newBaseState; + null !== update; + + ) { + var updateExpirationTime = update.expirationTime; + updateExpirationTime < renderExpirationTime + ? (null === newFirstUpdate && + ((newFirstUpdate = update), (newBaseState = resultState)), + newExpirationTime < updateExpirationTime && + (newExpirationTime = updateExpirationTime)) + : (markRenderEventTimeAndConfig( + updateExpirationTime, + update.suspenseConfig + ), + (resultState = getStateFromUpdate( + workInProgress, + queue, + update, + resultState, + props, + instance + )), + null !== update.callback && + ((workInProgress.effectTag |= 32), + (update.nextEffect = null), + null === queue.lastEffect + ? (queue.firstEffect = queue.lastEffect = update) + : ((queue.lastEffect.nextEffect = update), + (queue.lastEffect = update)))); + update = update.next; } + updateExpirationTime = null; + for (update = queue.firstCapturedUpdate; null !== update; ) { + var _updateExpirationTime = update.expirationTime; + _updateExpirationTime < renderExpirationTime + ? (null === updateExpirationTime && + ((updateExpirationTime = update), + null === newFirstUpdate && (newBaseState = resultState)), + newExpirationTime < _updateExpirationTime && + (newExpirationTime = _updateExpirationTime)) + : ((resultState = getStateFromUpdate( + workInProgress, + queue, + update, + resultState, + props, + instance + )), + null !== update.callback && + ((workInProgress.effectTag |= 32), + (update.nextEffect = null), + null === queue.lastCapturedEffect + ? (queue.firstCapturedEffect = queue.lastCapturedEffect = update) + : ((queue.lastCapturedEffect.nextEffect = update), + (queue.lastCapturedEffect = update)))); + update = update.next; + } + null === newFirstUpdate && (queue.lastUpdate = null); + null === updateExpirationTime + ? (queue.lastCapturedUpdate = null) + : (workInProgress.effectTag |= 32); + null === newFirstUpdate && + null === updateExpirationTime && + (newBaseState = resultState); + queue.baseState = newBaseState; + queue.firstUpdate = newFirstUpdate; + queue.firstCapturedUpdate = updateExpirationTime; + markUnprocessedUpdateTime(newExpirationTime); + workInProgress.expirationTime = newExpirationTime; + workInProgress.memoizedState = resultState; } function commitUpdateQueue(finishedWork, finishedQueue, instance) { - finishedWork = finishedQueue.effects; - finishedQueue.effects = null; - if (null !== finishedWork) - for ( - finishedQueue = 0; - finishedQueue < finishedWork.length; - finishedQueue++ - ) { - var effect = finishedWork[finishedQueue], - callback = effect.callback; - if (null !== callback) { - effect.callback = null; - if ("function" !== typeof callback) - throw Error( - "Invalid argument passed as callback. Expected a function. Instead received: " + - callback - ); - callback.call(instance); - } + null !== finishedQueue.firstCapturedUpdate && + (null !== finishedQueue.lastUpdate && + ((finishedQueue.lastUpdate.next = finishedQueue.firstCapturedUpdate), + (finishedQueue.lastUpdate = finishedQueue.lastCapturedUpdate)), + (finishedQueue.firstCapturedUpdate = finishedQueue.lastCapturedUpdate = null)); + commitUpdateEffects(finishedQueue.firstEffect, instance); + finishedQueue.firstEffect = finishedQueue.lastEffect = null; + commitUpdateEffects(finishedQueue.firstCapturedEffect, instance); + finishedQueue.firstCapturedEffect = finishedQueue.lastCapturedEffect = null; +} +function commitUpdateEffects(effect, instance) { + for (; null !== effect; ) { + var callback = effect.callback; + if (null !== callback) { + effect.callback = null; + if ("function" !== typeof callback) + throw Error( + "Invalid argument passed as callback. Expected a function. Instead received: " + + callback + ); + callback.call(instance); } + effect = effect.nextEffect; + } } var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig, emptyRefsObject = new React.Component().refs; @@ -2142,8 +2262,10 @@ function applyDerivedStateFromProps( ? ctor : Object.assign({}, ctor, getDerivedStateFromProps); workInProgress.memoizedState = getDerivedStateFromProps; - 0 === workInProgress.expirationTime && - (workInProgress.updateQueue.baseState = getDerivedStateFromProps); + nextProps = workInProgress.updateQueue; + null !== nextProps && + 0 === workInProgress.expirationTime && + (nextProps.baseState = getDerivedStateFromProps); } var classComponentUpdater = { isMounted: function(component) { @@ -2162,7 +2284,7 @@ var classComponentUpdater = { null !== callback && (suspenseConfig.callback = callback); enqueueUpdate(inst, suspenseConfig); - scheduleWork(inst, currentTime); + scheduleUpdateOnFiber(inst, currentTime); }, enqueueReplaceState: function(inst, payload, callback) { inst = inst._reactInternalFiber; @@ -2176,7 +2298,7 @@ var classComponentUpdater = { null !== callback && (suspenseConfig.callback = callback); enqueueUpdate(inst, suspenseConfig); - scheduleWork(inst, currentTime); + scheduleUpdateOnFiber(inst, currentTime); }, enqueueForceUpdate: function(inst, callback) { inst = inst._reactInternalFiber; @@ -2189,7 +2311,7 @@ var classComponentUpdater = { null !== callback && (suspenseConfig.callback = callback); enqueueUpdate(inst, suspenseConfig); - scheduleWork(inst, currentTime); + scheduleUpdateOnFiber(inst, currentTime); } }; function checkShouldComponentUpdate( @@ -2205,8 +2327,8 @@ function checkShouldComponentUpdate( return "function" === typeof workInProgress.shouldComponentUpdate ? workInProgress.shouldComponentUpdate(newProps, newState, nextContext) : ctor.prototype && ctor.prototype.isPureReactComponent - ? !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState) - : !0; + ? !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState) + : !0; } function constructClassInstance(workInProgress, ctor, props) { var isLegacyContextConsumer = !1, @@ -2258,7 +2380,6 @@ function mountClassInstance( instance.props = newProps; instance.state = workInProgress.memoizedState; instance.refs = emptyRefsObject; - initializeUpdateQueue(workInProgress); var contextType = ctor.contextType; "object" === typeof contextType && null !== contextType ? (instance.context = readContext(contextType)) @@ -2266,8 +2387,16 @@ function mountClassInstance( ? previousContext : contextStackCursor.current), (instance.context = getMaskedContext(workInProgress, contextType))); - processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); - instance.state = workInProgress.memoizedState; + contextType = workInProgress.updateQueue; + null !== contextType && + (processUpdateQueue( + workInProgress, + contextType, + newProps, + instance, + renderExpirationTime + ), + (instance.state = workInProgress.memoizedState)); contextType = ctor.getDerivedStateFromProps; "function" === typeof contextType && (applyDerivedStateFromProps(workInProgress, ctor, contextType, newProps), @@ -2283,18 +2412,21 @@ function mountClassInstance( instance.UNSAFE_componentWillMount(), ctor !== instance.state && classComponentUpdater.enqueueReplaceState(instance, instance.state, null), - processUpdateQueue( - workInProgress, - newProps, - instance, - renderExpirationTime - ), - (instance.state = workInProgress.memoizedState)); + (contextType = workInProgress.updateQueue), + null !== contextType && + (processUpdateQueue( + workInProgress, + contextType, + newProps, + instance, + renderExpirationTime + ), + (instance.state = workInProgress.memoizedState))); "function" === typeof instance.componentDidMount && (workInProgress.effectTag |= 4); } var isArray = Array.isArray; -function coerceRef(returnFiber, current, element) { +function coerceRef(returnFiber, current$$1, element) { returnFiber = element.ref; if ( null !== returnFiber && @@ -2306,7 +2438,7 @@ function coerceRef(returnFiber, current, element) { if (element) { if (1 !== element.tag) throw Error( - "Function components cannot have string refs. We recommend using useRef() instead. Learn more about using refs safely here: https://fb.me/react-strict-mode-string-ref" + "Function components cannot have refs. Did you mean to use React.forwardRef()?" ); var inst = element.stateNode; } @@ -2318,19 +2450,19 @@ function coerceRef(returnFiber, current, element) { ); var stringRef = "" + returnFiber; if ( - null !== current && - null !== current.ref && - "function" === typeof current.ref && - current.ref._stringRef === stringRef + null !== current$$1 && + null !== current$$1.ref && + "function" === typeof current$$1.ref && + current$$1.ref._stringRef === stringRef ) - return current.ref; - current = function(value) { + return current$$1.ref; + current$$1 = function(value) { var refs = inst.refs; refs === emptyRefsObject && (refs = inst.refs = {}); null === value ? delete refs[stringRef] : (refs[stringRef] = value); }; - current._stringRef = stringRef; - return current; + current$$1._stringRef = stringRef; + return current$$1; } if ("string" !== typeof returnFiber) throw Error( @@ -2382,8 +2514,8 @@ function ChildReconciler(shouldTrackSideEffects) { (currentFirstChild = currentFirstChild.sibling); return returnFiber; } - function useFiber(fiber, pendingProps) { - fiber = createWorkInProgress(fiber, pendingProps); + function useFiber(fiber, pendingProps, expirationTime) { + fiber = createWorkInProgress(fiber, pendingProps, expirationTime); fiber.index = 0; fiber.sibling = null; return fiber; @@ -2408,26 +2540,31 @@ function ChildReconciler(shouldTrackSideEffects) { (newFiber.effectTag = 2); return newFiber; } - function updateTextNode(returnFiber, current, textContent, expirationTime) { - if (null === current || 6 !== current.tag) + function updateTextNode( + returnFiber, + current$$1, + textContent, + expirationTime + ) { + if (null === current$$1 || 6 !== current$$1.tag) return ( - (current = createFiberFromText( + (current$$1 = createFiberFromText( textContent, returnFiber.mode, expirationTime )), - (current.return = returnFiber), - current + (current$$1.return = returnFiber), + current$$1 ); - current = useFiber(current, textContent); - current.return = returnFiber; - return current; + current$$1 = useFiber(current$$1, textContent, expirationTime); + current$$1.return = returnFiber; + return current$$1; } - function updateElement(returnFiber, current, element, expirationTime) { - if (null !== current && current.elementType === element.type) + function updateElement(returnFiber, current$$1, element, expirationTime) { + if (null !== current$$1 && current$$1.elementType === element.type) return ( - (expirationTime = useFiber(current, element.props)), - (expirationTime.ref = coerceRef(returnFiber, current, element)), + (expirationTime = useFiber(current$$1, element.props, expirationTime)), + (expirationTime.ref = coerceRef(returnFiber, current$$1, element)), (expirationTime.return = returnFiber), expirationTime ); @@ -2439,45 +2576,51 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime ); - expirationTime.ref = coerceRef(returnFiber, current, element); + expirationTime.ref = coerceRef(returnFiber, current$$1, element); expirationTime.return = returnFiber; return expirationTime; } - function updatePortal(returnFiber, current, portal, expirationTime) { + function updatePortal(returnFiber, current$$1, portal, expirationTime) { if ( - null === current || - 4 !== current.tag || - current.stateNode.containerInfo !== portal.containerInfo || - current.stateNode.implementation !== portal.implementation + null === current$$1 || + 4 !== current$$1.tag || + current$$1.stateNode.containerInfo !== portal.containerInfo || + current$$1.stateNode.implementation !== portal.implementation ) return ( - (current = createFiberFromPortal( + (current$$1 = createFiberFromPortal( portal, returnFiber.mode, expirationTime )), - (current.return = returnFiber), - current + (current$$1.return = returnFiber), + current$$1 ); - current = useFiber(current, portal.children || []); - current.return = returnFiber; - return current; + current$$1 = useFiber(current$$1, portal.children || [], expirationTime); + current$$1.return = returnFiber; + return current$$1; } - function updateFragment(returnFiber, current, fragment, expirationTime, key) { - if (null === current || 7 !== current.tag) + function updateFragment( + returnFiber, + current$$1, + fragment, + expirationTime, + key + ) { + if (null === current$$1 || 7 !== current$$1.tag) return ( - (current = createFiberFromFragment( + (current$$1 = createFiberFromFragment( fragment, returnFiber.mode, expirationTime, key )), - (current.return = returnFiber), - current + (current$$1.return = returnFiber), + current$$1 ); - current = useFiber(current, fragment); - current.return = returnFiber; - return current; + current$$1 = useFiber(current$$1, fragment, expirationTime); + current$$1.return = returnFiber; + return current$$1; } function createChild(returnFiber, newChild, expirationTime) { if ("string" === typeof newChild || "number" === typeof newChild) @@ -2840,48 +2983,39 @@ function ChildReconciler(shouldTrackSideEffects) { 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; - } + if (isUnkeyedTopLevelFragment.key === isObject) + if ( + 7 === isUnkeyedTopLevelFragment.tag + ? newChild.type === REACT_FRAGMENT_TYPE + : isUnkeyedTopLevelFragment.elementType === newChild.type + ) { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment.sibling + ); + currentFirstChild = useFiber( + isUnkeyedTopLevelFragment, + newChild.type === REACT_FRAGMENT_TYPE + ? newChild.props.children + : newChild.props, + expirationTime + ); + currentFirstChild.ref = coerceRef( + returnFiber, + isUnkeyedTopLevelFragment, + newChild + ); + currentFirstChild.return = returnFiber; + returnFiber = currentFirstChild; + break a; + } else { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment + ); + break; } - deleteRemainingChildren(returnFiber, isUnkeyedTopLevelFragment); - break; - } else deleteChild(returnFiber, isUnkeyedTopLevelFragment); + else deleteChild(returnFiber, isUnkeyedTopLevelFragment); isUnkeyedTopLevelFragment = isUnkeyedTopLevelFragment.sibling; } newChild.type === REACT_FRAGMENT_TYPE @@ -2931,7 +3065,8 @@ function ChildReconciler(shouldTrackSideEffects) { ); currentFirstChild = useFiber( currentFirstChild, - newChild.children || [] + newChild.children || [], + expirationTime ); currentFirstChild.return = returnFiber; returnFiber = currentFirstChild; @@ -2958,7 +3093,11 @@ function ChildReconciler(shouldTrackSideEffects) { (newChild = "" + newChild), null !== currentFirstChild && 6 === currentFirstChild.tag ? (deleteRemainingChildren(returnFiber, currentFirstChild.sibling), - (currentFirstChild = useFiber(currentFirstChild, newChild)), + (currentFirstChild = useFiber( + currentFirstChild, + newChild, + expirationTime + )), (currentFirstChild.return = returnFiber), (returnFiber = currentFirstChild)) : (deleteRemainingChildren(returnFiber, currentFirstChild), @@ -3013,16 +3152,16 @@ function requiredContext(c) { return c; } function pushHostContainer(fiber, nextRootInstance) { - push(rootInstanceStackCursor, nextRootInstance); - push(contextFiberStackCursor, fiber); - push(contextStackCursor$1, NO_CONTEXT); - pop(contextStackCursor$1); - push(contextStackCursor$1, { isInAParentText: !1 }); + push(rootInstanceStackCursor, nextRootInstance, fiber); + push(contextFiberStackCursor, fiber, fiber); + push(contextStackCursor$1, NO_CONTEXT, fiber); + pop(contextStackCursor$1, fiber); + push(contextStackCursor$1, { isInAParentText: !1 }, fiber); } -function popHostContainer() { - pop(contextStackCursor$1); - pop(contextFiberStackCursor); - pop(rootInstanceStackCursor); +function popHostContainer(fiber) { + pop(contextStackCursor$1, fiber); + pop(contextFiberStackCursor, fiber); + pop(rootInstanceStackCursor, fiber); } function pushHostContext(fiber) { requiredContext(rootInstanceStackCursor.current); @@ -3039,19 +3178,23 @@ function pushHostContext(fiber) { ? { isInAParentText: nextContext } : context; context !== nextContext && - (push(contextFiberStackCursor, fiber), - push(contextStackCursor$1, nextContext)); + (push(contextFiberStackCursor, fiber, fiber), + push(contextStackCursor$1, nextContext, fiber)); } function popHostContext(fiber) { contextFiberStackCursor.current === fiber && - (pop(contextStackCursor$1), pop(contextFiberStackCursor)); + (pop(contextStackCursor$1, fiber), pop(contextFiberStackCursor, fiber)); } var suspenseStackCursor = { current: 0 }; function findFirstSuspended(row) { for (var node = row; null !== node; ) { if (13 === node.tag) { var state = node.memoizedState; - if (null !== state && (null === state.dehydrated || shim$1() || shim$1())) + if ( + null !== state && + ((state = state.dehydrated), + null === state || shim$1(state) || shim$1(state)) + ) return node; } else if (19 === node.tag && void 0 !== node.memoizedProps.revealOrder) { if (0 !== (node.effectTag & 64)) return node; @@ -3070,16 +3213,24 @@ function findFirstSuspended(row) { } return null; } -function createDeprecatedResponderListener(responder, props) { +function createResponderListener(responder, props) { return { responder: responder, props: props }; } -var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher, +var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig, - renderExpirationTime = 0, + renderExpirationTime$1 = 0, currentlyRenderingFiber$1 = null, currentHook = null, + nextCurrentHook = null, + firstWorkInProgressHook = null, workInProgressHook = null, - didScheduleRenderPhaseUpdate = !1; + nextWorkInProgressHook = null, + remainingExpirationTime = 0, + componentUpdateQueue = null, + sideEffectTag = 0, + didScheduleRenderPhaseUpdate = !1, + renderPhaseUpdates = null, + numberOfReRenders = 0; function throwInvalidHookError() { throw Error( "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem." @@ -3088,7 +3239,7 @@ function throwInvalidHookError() { function areHookInputsEqual(nextDeps, prevDeps) { if (null === prevDeps) return !1; for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) - if (!objectIs(nextDeps[i], prevDeps[i])) return !1; + if (!is$1(nextDeps[i], prevDeps[i])) return !1; return !0; } function renderWithHooks( @@ -3096,85 +3247,92 @@ function renderWithHooks( workInProgress, Component, props, - secondArg, + refOrContext, nextRenderExpirationTime ) { - renderExpirationTime = nextRenderExpirationTime; + renderExpirationTime$1 = nextRenderExpirationTime; currentlyRenderingFiber$1 = workInProgress; - workInProgress.memoizedState = null; - workInProgress.updateQueue = null; - workInProgress.expirationTime = 0; - ReactCurrentDispatcher.current = - null === current || null === current.memoizedState - ? HooksDispatcherOnMount - : HooksDispatcherOnUpdate; - current = Component(props, secondArg); - if (workInProgress.expirationTime === renderExpirationTime) { - nextRenderExpirationTime = 0; - do { - workInProgress.expirationTime = 0; - if (!(25 > nextRenderExpirationTime)) - throw Error( - "Too many re-renders. React limits the number of renders to prevent an infinite loop." - ); - nextRenderExpirationTime += 1; - workInProgressHook = currentHook = null; - workInProgress.updateQueue = null; - ReactCurrentDispatcher.current = HooksDispatcherOnRerender; - current = Component(props, secondArg); - } while (workInProgress.expirationTime === renderExpirationTime); + nextCurrentHook = null !== current ? current.memoizedState : null; + ReactCurrentDispatcher$1.current = + null === nextCurrentHook ? HooksDispatcherOnMount : HooksDispatcherOnUpdate; + workInProgress = Component(props, refOrContext); + if (didScheduleRenderPhaseUpdate) { + do + (didScheduleRenderPhaseUpdate = !1), + (numberOfReRenders += 1), + (nextCurrentHook = null !== current ? current.memoizedState : null), + (nextWorkInProgressHook = firstWorkInProgressHook), + (componentUpdateQueue = workInProgressHook = currentHook = null), + (ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdate), + (workInProgress = Component(props, refOrContext)); + while (didScheduleRenderPhaseUpdate); + renderPhaseUpdates = null; + numberOfReRenders = 0; } - ReactCurrentDispatcher.current = ContextOnlyDispatcher; - workInProgress = null !== currentHook && null !== currentHook.next; - renderExpirationTime = 0; - workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; - didScheduleRenderPhaseUpdate = !1; - if (workInProgress) + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; + current = currentlyRenderingFiber$1; + current.memoizedState = firstWorkInProgressHook; + current.expirationTime = remainingExpirationTime; + current.updateQueue = componentUpdateQueue; + current.effectTag |= sideEffectTag; + current = null !== currentHook && null !== currentHook.next; + renderExpirationTime$1 = 0; + nextWorkInProgressHook = workInProgressHook = firstWorkInProgressHook = nextCurrentHook = currentHook = currentlyRenderingFiber$1 = null; + remainingExpirationTime = 0; + componentUpdateQueue = null; + sideEffectTag = 0; + if (current) throw Error( "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." ); - return current; + return workInProgress; +} +function resetHooks() { + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; + renderExpirationTime$1 = 0; + nextWorkInProgressHook = workInProgressHook = firstWorkInProgressHook = nextCurrentHook = currentHook = currentlyRenderingFiber$1 = null; + remainingExpirationTime = 0; + componentUpdateQueue = null; + sideEffectTag = 0; + didScheduleRenderPhaseUpdate = !1; + renderPhaseUpdates = null; + numberOfReRenders = 0; } function mountWorkInProgressHook() { var hook = { memoizedState: null, baseState: null, - baseQueue: null, queue: null, + baseUpdate: null, next: null }; null === workInProgressHook - ? (currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook) + ? (firstWorkInProgressHook = workInProgressHook = hook) : (workInProgressHook = workInProgressHook.next = hook); return workInProgressHook; } function updateWorkInProgressHook() { - if (null === currentHook) { - var nextCurrentHook = currentlyRenderingFiber$1.alternate; - nextCurrentHook = - null !== nextCurrentHook ? nextCurrentHook.memoizedState : null; - } else nextCurrentHook = currentHook.next; - var nextWorkInProgressHook = - null === workInProgressHook - ? currentlyRenderingFiber$1.memoizedState - : workInProgressHook.next; if (null !== nextWorkInProgressHook) (workInProgressHook = nextWorkInProgressHook), - (currentHook = nextCurrentHook); + (nextWorkInProgressHook = workInProgressHook.next), + (currentHook = nextCurrentHook), + (nextCurrentHook = null !== currentHook ? currentHook.next : null); else { if (null === nextCurrentHook) throw Error("Rendered more hooks than during the previous render."); currentHook = nextCurrentHook; - nextCurrentHook = { + var newHook = { memoizedState: currentHook.memoizedState, baseState: currentHook.baseState, - baseQueue: currentHook.baseQueue, queue: currentHook.queue, + baseUpdate: currentHook.baseUpdate, next: null }; - null === workInProgressHook - ? (currentlyRenderingFiber$1.memoizedState = workInProgressHook = nextCurrentHook) - : (workInProgressHook = workInProgressHook.next = nextCurrentHook); + workInProgressHook = + null === workInProgressHook + ? (firstWorkInProgressHook = newHook) + : (workInProgressHook.next = newHook); + nextCurrentHook = currentHook.next; } return workInProgressHook; } @@ -3189,100 +3347,74 @@ function updateReducer(reducer) { "Should have a queue. This is likely a bug in React. Please file an issue." ); queue.lastRenderedReducer = reducer; - var current = currentHook, - baseQueue = current.baseQueue, - pendingQueue = queue.pending; - if (null !== pendingQueue) { - if (null !== baseQueue) { - var baseFirst = baseQueue.next; - baseQueue.next = pendingQueue.next; - pendingQueue.next = baseFirst; + if (0 < numberOfReRenders) { + var _dispatch = queue.dispatch; + if (null !== renderPhaseUpdates) { + var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue); + if (void 0 !== firstRenderPhaseUpdate) { + renderPhaseUpdates.delete(queue); + var newState = hook.memoizedState; + do + (newState = reducer(newState, firstRenderPhaseUpdate.action)), + (firstRenderPhaseUpdate = firstRenderPhaseUpdate.next); + while (null !== firstRenderPhaseUpdate); + is$1(newState, hook.memoizedState) || (didReceiveUpdate = !0); + hook.memoizedState = newState; + hook.baseUpdate === queue.last && (hook.baseState = newState); + queue.lastRenderedState = newState; + return [newState, _dispatch]; + } } - current.baseQueue = baseQueue = pendingQueue; - queue.pending = null; + return [hook.memoizedState, _dispatch]; } - if (null !== baseQueue) { - baseQueue = baseQueue.next; - current = current.baseState; - var newBaseQueueLast = (baseFirst = pendingQueue = null), - update = baseQueue; + _dispatch = queue.last; + var baseUpdate = hook.baseUpdate; + newState = hook.baseState; + null !== baseUpdate + ? (null !== _dispatch && (_dispatch.next = null), + (_dispatch = baseUpdate.next)) + : (_dispatch = null !== _dispatch ? _dispatch.next : null); + if (null !== _dispatch) { + var newBaseUpdate = (firstRenderPhaseUpdate = null), + _update = _dispatch, + didSkip = !1; do { - var updateExpirationTime = update.expirationTime; - if (updateExpirationTime < renderExpirationTime) { - var clone = { - expirationTime: update.expirationTime, - suspenseConfig: update.suspenseConfig, - action: update.action, - eagerReducer: update.eagerReducer, - eagerState: update.eagerState, - next: null - }; - null === newBaseQueueLast - ? ((baseFirst = newBaseQueueLast = clone), (pendingQueue = current)) - : (newBaseQueueLast = newBaseQueueLast.next = clone); - updateExpirationTime > currentlyRenderingFiber$1.expirationTime && - ((currentlyRenderingFiber$1.expirationTime = updateExpirationTime), - markUnprocessedUpdateTime(updateExpirationTime)); - } else - null !== newBaseQueueLast && - (newBaseQueueLast = newBaseQueueLast.next = { - expirationTime: 1073741823, - suspenseConfig: update.suspenseConfig, - action: update.action, - eagerReducer: update.eagerReducer, - eagerState: update.eagerState, - next: null - }), - markRenderEventTimeAndConfig( + var updateExpirationTime = _update.expirationTime; + updateExpirationTime < renderExpirationTime$1 + ? (didSkip || + ((didSkip = !0), + (newBaseUpdate = baseUpdate), + (firstRenderPhaseUpdate = newState)), + updateExpirationTime > remainingExpirationTime && + ((remainingExpirationTime = updateExpirationTime), + markUnprocessedUpdateTime(remainingExpirationTime))) + : (markRenderEventTimeAndConfig( updateExpirationTime, - update.suspenseConfig + _update.suspenseConfig ), - (current = - update.eagerReducer === reducer - ? update.eagerState - : reducer(current, update.action)); - update = update.next; - } while (null !== update && update !== baseQueue); - null === newBaseQueueLast - ? (pendingQueue = current) - : (newBaseQueueLast.next = baseFirst); - objectIs(current, hook.memoizedState) || (didReceiveUpdate = !0); - hook.memoizedState = current; - hook.baseState = pendingQueue; - hook.baseQueue = newBaseQueueLast; - queue.lastRenderedState = current; - } - return [hook.memoizedState, queue.dispatch]; -} -function rerenderReducer(reducer) { - var hook = updateWorkInProgressHook(), - queue = hook.queue; - if (null === queue) - throw Error( - "Should have a queue. This is likely a bug in React. Please file an issue." - ); - queue.lastRenderedReducer = reducer; - var dispatch = queue.dispatch, - lastRenderPhaseUpdate = queue.pending, - newState = hook.memoizedState; - if (null !== lastRenderPhaseUpdate) { - queue.pending = null; - var update = (lastRenderPhaseUpdate = lastRenderPhaseUpdate.next); - do (newState = reducer(newState, update.action)), (update = update.next); - while (update !== lastRenderPhaseUpdate); - objectIs(newState, hook.memoizedState) || (didReceiveUpdate = !0); + (newState = + _update.eagerReducer === reducer + ? _update.eagerState + : reducer(newState, _update.action))); + baseUpdate = _update; + _update = _update.next; + } while (null !== _update && _update !== _dispatch); + didSkip || + ((newBaseUpdate = baseUpdate), (firstRenderPhaseUpdate = newState)); + is$1(newState, hook.memoizedState) || (didReceiveUpdate = !0); hook.memoizedState = newState; - null === hook.baseQueue && (hook.baseState = newState); + hook.baseUpdate = newBaseUpdate; + hook.baseState = firstRenderPhaseUpdate; queue.lastRenderedState = newState; } - return [newState, dispatch]; + return [hook.memoizedState, queue.dispatch]; } function mountState(initialState) { var hook = mountWorkInProgressHook(); "function" === typeof initialState && (initialState = initialState()); hook.memoizedState = hook.baseState = initialState; initialState = hook.queue = { - pending: null, + last: null, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState @@ -3294,30 +3426,28 @@ function mountState(initialState) { ); return [hook.memoizedState, initialState]; } +function updateState(initialState) { + return updateReducer(basicStateReducer, initialState); +} function pushEffect(tag, create, destroy, deps) { tag = { tag: tag, create: create, destroy: destroy, deps: deps, next: null }; - create = currentlyRenderingFiber$1.updateQueue; - null === create - ? ((create = { lastEffect: null }), - (currentlyRenderingFiber$1.updateQueue = create), - (create.lastEffect = tag.next = tag)) - : ((destroy = create.lastEffect), - null === destroy - ? (create.lastEffect = tag.next = tag) - : ((deps = destroy.next), - (destroy.next = tag), - (tag.next = deps), - (create.lastEffect = tag))); + null === componentUpdateQueue + ? ((componentUpdateQueue = { lastEffect: null }), + (componentUpdateQueue.lastEffect = tag.next = tag)) + : ((create = componentUpdateQueue.lastEffect), + null === create + ? (componentUpdateQueue.lastEffect = tag.next = tag) + : ((destroy = create.next), + (create.next = tag), + (tag.next = destroy), + (componentUpdateQueue.lastEffect = tag))); return tag; } -function updateRef() { - return updateWorkInProgressHook().memoizedState; -} function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var hook = mountWorkInProgressHook(); - currentlyRenderingFiber$1.effectTag |= fiberEffectTag; + sideEffectTag |= fiberEffectTag; hook.memoizedState = pushEffect( - 1 | hookEffectTag, + hookEffectTag, create, void 0, void 0 === deps ? null : deps @@ -3331,21 +3461,18 @@ function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var prevEffect = currentHook.memoizedState; destroy = prevEffect.destroy; if (null !== deps && areHookInputsEqual(deps, prevEffect.deps)) { - pushEffect(hookEffectTag, create, destroy, deps); + pushEffect(0, create, destroy, deps); return; } } - currentlyRenderingFiber$1.effectTag |= fiberEffectTag; - hook.memoizedState = pushEffect(1 | hookEffectTag, create, destroy, deps); + sideEffectTag |= fiberEffectTag; + hook.memoizedState = pushEffect(hookEffectTag, create, destroy, deps); } function mountEffect(create, deps) { - return mountEffectImpl(516, 4, create, deps); + return mountEffectImpl(516, 192, create, deps); } function updateEffect(create, deps) { - return updateEffectImpl(516, 4, create, deps); -} -function updateLayoutEffect(create, deps) { - return updateEffectImpl(4, 2, create, deps); + return updateEffectImpl(516, 192, create, deps); } function imperativeHandleEffect(create, ref) { if ("function" === typeof ref) @@ -3365,15 +3492,6 @@ function imperativeHandleEffect(create, ref) { } ); } -function updateImperativeHandle(ref, create, deps) { - deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; - return updateEffectImpl( - 4, - 2, - imperativeHandleEffect.bind(null, create, ref), - deps - ); -} function mountDebugValue() {} function mountCallback(callback, deps) { mountWorkInProgressHook().memoizedState = [ @@ -3395,79 +3513,72 @@ function updateCallback(callback, deps) { hook.memoizedState = [callback, deps]; return callback; } -function updateMemo(nextCreate, deps) { - var hook = updateWorkInProgressHook(); - deps = void 0 === deps ? null : deps; - var prevState = hook.memoizedState; - if ( - null !== prevState && - null !== deps && - areHookInputsEqual(deps, prevState[1]) - ) - return prevState[0]; - nextCreate = nextCreate(); - hook.memoizedState = [nextCreate, deps]; - return nextCreate; -} -function startTransition(setPending, config, callback) { - var priorityLevel = getCurrentPriorityLevel(); - runWithPriority(98 > priorityLevel ? 98 : priorityLevel, function() { - setPending(!0); - }); - runWithPriority(97 < priorityLevel ? 97 : priorityLevel, function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = void 0 === config ? null : config; - try { - setPending(!1), callback(); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); -} function dispatchAction(fiber, queue, action) { - var currentTime = requestCurrentTimeForUpdate(), - suspenseConfig = ReactCurrentBatchConfig.suspense; - currentTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig); - suspenseConfig = { - expirationTime: currentTime, - suspenseConfig: suspenseConfig, - action: action, - eagerReducer: null, - eagerState: null, - next: null - }; - var pending = queue.pending; - null === pending - ? (suspenseConfig.next = suspenseConfig) - : ((suspenseConfig.next = pending.next), (pending.next = suspenseConfig)); - queue.pending = suspenseConfig; - pending = fiber.alternate; + if (!(25 > numberOfReRenders)) + throw Error( + "Too many re-renders. React limits the number of renders to prevent an infinite loop." + ); + var alternate = fiber.alternate; if ( fiber === currentlyRenderingFiber$1 || - (null !== pending && pending === currentlyRenderingFiber$1) + (null !== alternate && alternate === currentlyRenderingFiber$1) ) - (didScheduleRenderPhaseUpdate = !0), - (suspenseConfig.expirationTime = renderExpirationTime), - (currentlyRenderingFiber$1.expirationTime = renderExpirationTime); + if ( + ((didScheduleRenderPhaseUpdate = !0), + (fiber = { + expirationTime: renderExpirationTime$1, + suspenseConfig: null, + action: action, + eagerReducer: null, + eagerState: null, + next: null + }), + null === renderPhaseUpdates && (renderPhaseUpdates = new Map()), + (action = renderPhaseUpdates.get(queue)), + void 0 === action) + ) + renderPhaseUpdates.set(queue, fiber); + else { + for (queue = action; null !== queue.next; ) queue = queue.next; + queue.next = fiber; + } else { + var currentTime = requestCurrentTimeForUpdate(), + suspenseConfig = ReactCurrentBatchConfig.suspense; + currentTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig); + suspenseConfig = { + expirationTime: currentTime, + suspenseConfig: suspenseConfig, + action: action, + eagerReducer: null, + eagerState: null, + next: null + }; + var last = queue.last; + if (null === last) suspenseConfig.next = suspenseConfig; + else { + var first = last.next; + null !== first && (suspenseConfig.next = first); + last.next = suspenseConfig; + } + queue.last = suspenseConfig; if ( 0 === fiber.expirationTime && - (null === pending || 0 === pending.expirationTime) && - ((pending = queue.lastRenderedReducer), null !== pending) + (null === alternate || 0 === alternate.expirationTime) && + ((alternate = queue.lastRenderedReducer), null !== alternate) ) try { var currentState = queue.lastRenderedState, - eagerState = pending(currentState, action); - suspenseConfig.eagerReducer = pending; + eagerState = alternate(currentState, action); + suspenseConfig.eagerReducer = alternate; suspenseConfig.eagerState = eagerState; - if (objectIs(eagerState, currentState)) return; + if (is$1(eagerState, currentState)) return; } catch (error) { } finally { } - scheduleWork(fiber, currentTime); + scheduleUpdateOnFiber(fiber, currentTime); } } -function updateEventListener() {} var ContextOnlyDispatcher = { readContext: readContext, useCallback: throwInvalidHookError, @@ -3482,8 +3593,7 @@ var ContextOnlyDispatcher = { useDebugValue: throwInvalidHookError, useResponder: throwInvalidHookError, useDeferredValue: throwInvalidHookError, - useTransition: throwInvalidHookError, - useEvent: throwInvalidHookError + useTransition: throwInvalidHookError }, HooksDispatcherOnMount = { readContext: readContext, @@ -3494,13 +3604,13 @@ var ContextOnlyDispatcher = { deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; return mountEffectImpl( 4, - 2, + 36, imperativeHandleEffect.bind(null, create, ref), deps ); }, useLayoutEffect: function(create, deps) { - return mountEffectImpl(4, 2, create, deps); + return mountEffectImpl(4, 36, create, deps); }, useMemo: function(nextCreate, deps) { var hook = mountWorkInProgressHook(); @@ -3514,7 +3624,7 @@ var ContextOnlyDispatcher = { initialArg = void 0 !== init ? init(initialArg) : initialArg; hook.memoizedState = hook.baseState = initialArg; reducer = hook.queue = { - pending: null, + last: null, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialArg @@ -3533,21 +3643,23 @@ var ContextOnlyDispatcher = { }, useState: mountState, useDebugValue: mountDebugValue, - useResponder: createDeprecatedResponderListener, + useResponder: createResponderListener, useDeferredValue: function(value, config) { var _mountState = mountState(value), prevValue = _mountState[0], setValue = _mountState[1]; mountEffect( function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - void 0 === config ? null : config; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } + Scheduler.unstable_next(function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }); }, [value, config] ); @@ -3555,113 +3667,112 @@ var ContextOnlyDispatcher = { }, useTransition: function(config) { var _mountState2 = mountState(!1), - isPending = _mountState2[0]; - _mountState2 = _mountState2[1]; + isPending = _mountState2[0], + setPending = _mountState2[1]; return [ - mountCallback(startTransition.bind(null, _mountState2, config), [ - _mountState2, - config - ]), + mountCallback( + function(callback) { + setPending(!0); + Scheduler.unstable_next(function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setPending(!1), callback(); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }); + }, + [config, isPending] + ), isPending ]; - }, - useEvent: function() {} + } }, HooksDispatcherOnUpdate = { readContext: readContext, useCallback: updateCallback, useContext: readContext, useEffect: updateEffect, - useImperativeHandle: updateImperativeHandle, - useLayoutEffect: updateLayoutEffect, - useMemo: updateMemo, - useReducer: updateReducer, - useRef: updateRef, - useState: function() { - return updateReducer(basicStateReducer); - }, - useDebugValue: mountDebugValue, - useResponder: createDeprecatedResponderListener, - useDeferredValue: function(value, config) { - var _updateState = updateReducer(basicStateReducer), - prevValue = _updateState[0], - setValue = _updateState[1]; - updateEffect( - function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - void 0 === config ? null : config; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }, - [value, config] + useImperativeHandle: function(ref, create, deps) { + deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; + return updateEffectImpl( + 4, + 36, + imperativeHandleEffect.bind(null, create, ref), + deps ); - return prevValue; }, - useTransition: function(config) { - var _updateState2 = updateReducer(basicStateReducer), - isPending = _updateState2[0]; - _updateState2 = _updateState2[1]; - return [ - updateCallback(startTransition.bind(null, _updateState2, config), [ - _updateState2, - config - ]), - isPending - ]; + useLayoutEffect: function(create, deps) { + return updateEffectImpl(4, 36, create, deps); }, - useEvent: updateEventListener - }, - HooksDispatcherOnRerender = { - readContext: readContext, - useCallback: updateCallback, - useContext: readContext, - useEffect: updateEffect, - useImperativeHandle: updateImperativeHandle, - useLayoutEffect: updateLayoutEffect, - useMemo: updateMemo, - useReducer: rerenderReducer, - useRef: updateRef, - useState: function() { - return rerenderReducer(basicStateReducer); + useMemo: function(nextCreate, deps) { + var hook = updateWorkInProgressHook(); + deps = void 0 === deps ? null : deps; + var prevState = hook.memoizedState; + if ( + null !== prevState && + null !== deps && + areHookInputsEqual(deps, prevState[1]) + ) + return prevState[0]; + nextCreate = nextCreate(); + hook.memoizedState = [nextCreate, deps]; + return nextCreate; + }, + useReducer: updateReducer, + useRef: function() { + return updateWorkInProgressHook().memoizedState; }, + useState: updateState, useDebugValue: mountDebugValue, - useResponder: createDeprecatedResponderListener, + useResponder: createResponderListener, useDeferredValue: function(value, config) { - var _rerenderState = rerenderReducer(basicStateReducer), - prevValue = _rerenderState[0], - setValue = _rerenderState[1]; + var _updateState = updateState(value), + prevValue = _updateState[0], + setValue = _updateState[1]; updateEffect( function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - void 0 === config ? null : config; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } + Scheduler.unstable_next(function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }); }, [value, config] ); return prevValue; }, useTransition: function(config) { - var _rerenderState2 = rerenderReducer(basicStateReducer), - isPending = _rerenderState2[0]; - _rerenderState2 = _rerenderState2[1]; + var _updateState2 = updateState(!1), + isPending = _updateState2[0], + setPending = _updateState2[1]; return [ - updateCallback(startTransition.bind(null, _rerenderState2, config), [ - _rerenderState2, - config - ]), + updateCallback( + function(callback) { + setPending(!0); + Scheduler.unstable_next(function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setPending(!1), callback(); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }); + }, + [config, isPending] + ), isPending ]; - }, - useEvent: updateEventListener + } }, now$1 = Scheduler.unstable_now, commitTime = 0, @@ -3674,16 +3785,70 @@ function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) { profilerStartTime = -1; } } -var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner, +var hydrationParentFiber = null, + nextHydratableInstance = null, + isHydrating = !1; +function tryHydrate(fiber, nextInstance) { + switch (fiber.tag) { + case 5: + return ( + (nextInstance = shim$1(nextInstance, fiber.type, fiber.pendingProps)), + null !== nextInstance ? ((fiber.stateNode = nextInstance), !0) : !1 + ); + case 6: + return ( + (nextInstance = shim$1(nextInstance, fiber.pendingProps)), + null !== nextInstance ? ((fiber.stateNode = nextInstance), !0) : !1 + ); + case 13: + return !1; + default: + return !1; + } +} +function tryToClaimNextHydratableInstance(fiber$jscomp$0) { + if (isHydrating) { + var nextInstance = nextHydratableInstance; + if (nextInstance) { + var firstAttemptedInstance = nextInstance; + if (!tryHydrate(fiber$jscomp$0, nextInstance)) { + nextInstance = shim$1(firstAttemptedInstance); + if (!nextInstance || !tryHydrate(fiber$jscomp$0, nextInstance)) { + fiber$jscomp$0.effectTag = (fiber$jscomp$0.effectTag & -1025) | 2; + isHydrating = !1; + hydrationParentFiber = fiber$jscomp$0; + return; + } + var returnFiber = hydrationParentFiber, + fiber = createFiber(5, null, null, 0); + fiber.elementType = "DELETED"; + fiber.type = "DELETED"; + fiber.stateNode = firstAttemptedInstance; + fiber.return = returnFiber; + fiber.effectTag = 8; + null !== returnFiber.lastEffect + ? ((returnFiber.lastEffect.nextEffect = fiber), + (returnFiber.lastEffect = fiber)) + : (returnFiber.firstEffect = returnFiber.lastEffect = fiber); + } + hydrationParentFiber = fiber$jscomp$0; + nextHydratableInstance = shim$1(nextInstance); + } else + (fiber$jscomp$0.effectTag = (fiber$jscomp$0.effectTag & -1025) | 2), + (isHydrating = !1), + (hydrationParentFiber = fiber$jscomp$0); + } +} +var ReactCurrentOwner$3 = ReactSharedInternals.ReactCurrentOwner, didReceiveUpdate = !1; function reconcileChildren( - current, + current$$1, workInProgress, nextChildren, renderExpirationTime ) { workInProgress.child = - null === current + null === current$$1 ? mountChildFibers( workInProgress, null, @@ -3692,13 +3857,13 @@ function reconcileChildren( ) : reconcileChildFibers( workInProgress, - current.child, + current$$1.child, nextChildren, renderExpirationTime ); } function updateForwardRef( - current, + current$$1, workInProgress, Component, nextProps, @@ -3708,38 +3873,43 @@ function updateForwardRef( var ref = workInProgress.ref; prepareToReadContext(workInProgress, renderExpirationTime); nextProps = renderWithHooks( - current, + current$$1, workInProgress, Component, nextProps, ref, renderExpirationTime ); - if (null !== current && !didReceiveUpdate) + if (null !== current$$1 && !didReceiveUpdate) return ( - (workInProgress.updateQueue = current.updateQueue), + (workInProgress.updateQueue = current$$1.updateQueue), (workInProgress.effectTag &= -517), - current.expirationTime <= renderExpirationTime && - (current.expirationTime = 0), + current$$1.expirationTime <= renderExpirationTime && + (current$$1.expirationTime = 0), bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ) ); workInProgress.effectTag |= 1; - reconcileChildren(current, workInProgress, nextProps, renderExpirationTime); + reconcileChildren( + current$$1, + workInProgress, + nextProps, + renderExpirationTime + ); return workInProgress.child; } function updateMemoComponent( - current, + current$$1, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime ) { - if (null === current) { + if (null === current$$1) { var type = Component.type; if ( "function" === typeof type && @@ -3752,7 +3922,7 @@ function updateMemoComponent( (workInProgress.tag = 15), (workInProgress.type = type), updateSimpleMemoComponent( - current, + current$$1, workInProgress, type, nextProps, @@ -3760,7 +3930,7 @@ function updateMemoComponent( renderExpirationTime ) ); - current = createFiberFromTypeAndProps( + current$$1 = createFiberFromTypeAndProps( Component.type, null, nextProps, @@ -3768,66 +3938,65 @@ function updateMemoComponent( workInProgress.mode, renderExpirationTime ); - current.ref = workInProgress.ref; - current.return = workInProgress; - return (workInProgress.child = current); + current$$1.ref = workInProgress.ref; + current$$1.return = workInProgress; + return (workInProgress.child = current$$1); } - type = current.child; + type = current$$1.child; if ( updateExpirationTime < renderExpirationTime && ((updateExpirationTime = type.memoizedProps), (Component = Component.compare), (Component = null !== Component ? Component : shallowEqual), Component(updateExpirationTime, nextProps) && - current.ref === workInProgress.ref) + current$$1.ref === workInProgress.ref) ) return bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ); workInProgress.effectTag |= 1; - current = createWorkInProgress(type, nextProps); - current.ref = workInProgress.ref; - current.return = workInProgress; - return (workInProgress.child = current); + current$$1 = createWorkInProgress(type, nextProps, renderExpirationTime); + current$$1.ref = workInProgress.ref; + current$$1.return = workInProgress; + return (workInProgress.child = current$$1); } function updateSimpleMemoComponent( - current, + current$$1, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime ) { - return null !== current && - shallowEqual(current.memoizedProps, nextProps) && - current.ref === workInProgress.ref && + return null !== current$$1 && + shallowEqual(current$$1.memoizedProps, nextProps) && + current$$1.ref === workInProgress.ref && ((didReceiveUpdate = !1), updateExpirationTime < renderExpirationTime) - ? ((workInProgress.expirationTime = current.expirationTime), - bailoutOnAlreadyFinishedWork( - current, + ? bailoutOnAlreadyFinishedWork( + current$$1, workInProgress, renderExpirationTime - )) + ) : updateFunctionComponent( - current, + current$$1, workInProgress, Component, nextProps, renderExpirationTime ); } -function markRef(current, workInProgress) { +function markRef(current$$1, workInProgress) { var ref = workInProgress.ref; if ( - (null === current && null !== ref) || - (null !== current && current.ref !== ref) + (null === current$$1 && null !== ref) || + (null !== current$$1 && current$$1.ref !== ref) ) workInProgress.effectTag |= 128; } function updateFunctionComponent( - current, + current$$1, workInProgress, Component, nextProps, @@ -3839,31 +4008,36 @@ function updateFunctionComponent( context = getMaskedContext(workInProgress, context); prepareToReadContext(workInProgress, renderExpirationTime); Component = renderWithHooks( - current, + current$$1, workInProgress, Component, nextProps, context, renderExpirationTime ); - if (null !== current && !didReceiveUpdate) + if (null !== current$$1 && !didReceiveUpdate) return ( - (workInProgress.updateQueue = current.updateQueue), + (workInProgress.updateQueue = current$$1.updateQueue), (workInProgress.effectTag &= -517), - current.expirationTime <= renderExpirationTime && - (current.expirationTime = 0), + current$$1.expirationTime <= renderExpirationTime && + (current$$1.expirationTime = 0), bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ) ); workInProgress.effectTag |= 1; - reconcileChildren(current, workInProgress, Component, renderExpirationTime); + reconcileChildren( + current$$1, + workInProgress, + Component, + renderExpirationTime + ); return workInProgress.child; } function updateClassComponent( - current, + current$$1, workInProgress, Component, nextProps, @@ -3875,11 +4049,16 @@ function updateClassComponent( } else hasContext = !1; prepareToReadContext(workInProgress, renderExpirationTime); if (null === workInProgress.stateNode) - null !== current && - ((current.alternate = null), + null !== current$$1 && + ((current$$1.alternate = null), (workInProgress.alternate = null), (workInProgress.effectTag |= 2)), - constructClassInstance(workInProgress, Component, nextProps), + constructClassInstance( + workInProgress, + Component, + nextProps, + renderExpirationTime + ), mountClassInstance( workInProgress, Component, @@ -3887,7 +4066,7 @@ function updateClassComponent( renderExpirationTime ), (nextProps = !0); - else if (null === current) { + else if (null === current$$1) { var instance = workInProgress.stateNode, oldProps = workInProgress.memoizedProps; instance.props = oldProps; @@ -3915,14 +4094,17 @@ function updateClassComponent( )); hasForceUpdate = !1; var oldState = workInProgress.memoizedState; - instance.state = oldState; - processUpdateQueue( - workInProgress, - nextProps, - instance, - renderExpirationTime - ); - oldContext = workInProgress.memoizedState; + oldContext = instance.state = oldState; + var updateQueue = workInProgress.updateQueue; + null !== updateQueue && + (processUpdateQueue( + workInProgress, + updateQueue, + nextProps, + instance, + renderExpirationTime + ), + (oldContext = workInProgress.memoizedState)); oldProps !== nextProps || oldState !== oldContext || didPerformWorkStackCursor.current || @@ -3968,7 +4150,6 @@ function updateClassComponent( (nextProps = !1)); } else (instance = workInProgress.stateNode), - cloneUpdateQueue(current, workInProgress), (oldProps = workInProgress.memoizedProps), (instance.props = workInProgress.type === workInProgress.elementType @@ -3997,14 +4178,17 @@ function updateClassComponent( )), (hasForceUpdate = !1), (oldContext = workInProgress.memoizedState), - (instance.state = oldContext), - processUpdateQueue( - workInProgress, - nextProps, - instance, - renderExpirationTime - ), - (oldState = workInProgress.memoizedState), + (oldState = instance.state = oldContext), + (updateQueue = workInProgress.updateQueue), + null !== updateQueue && + (processUpdateQueue( + workInProgress, + updateQueue, + nextProps, + instance, + renderExpirationTime + ), + (oldState = workInProgress.memoizedState)), oldProps !== nextProps || oldContext !== oldState || didPerformWorkStackCursor.current || @@ -4048,12 +4232,12 @@ function updateClassComponent( "function" === typeof instance.getSnapshotBeforeUpdate && (workInProgress.effectTag |= 256)) : ("function" !== typeof instance.componentDidUpdate || - (oldProps === current.memoizedProps && - oldContext === current.memoizedState) || + (oldProps === current$$1.memoizedProps && + oldContext === current$$1.memoizedState) || (workInProgress.effectTag |= 4), "function" !== typeof instance.getSnapshotBeforeUpdate || - (oldProps === current.memoizedProps && - oldContext === current.memoizedState) || + (oldProps === current$$1.memoizedProps && + oldContext === current$$1.memoizedState) || (workInProgress.effectTag |= 256), (workInProgress.memoizedProps = nextProps), (workInProgress.memoizedState = oldState)), @@ -4062,16 +4246,16 @@ function updateClassComponent( (instance.context = contextType), (nextProps = getDerivedStateFromProps)) : ("function" !== typeof instance.componentDidUpdate || - (oldProps === current.memoizedProps && - oldContext === current.memoizedState) || + (oldProps === current$$1.memoizedProps && + oldContext === current$$1.memoizedState) || (workInProgress.effectTag |= 4), "function" !== typeof instance.getSnapshotBeforeUpdate || - (oldProps === current.memoizedProps && - oldContext === current.memoizedState) || + (oldProps === current$$1.memoizedProps && + oldContext === current$$1.memoizedState) || (workInProgress.effectTag |= 256), (nextProps = !1)); return finishClassComponent( - current, + current$$1, workInProgress, Component, nextProps, @@ -4080,26 +4264,26 @@ function updateClassComponent( ); } function finishClassComponent( - current, + current$$1, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime ) { - markRef(current, workInProgress); + markRef(current$$1, workInProgress); var didCaptureError = 0 !== (workInProgress.effectTag & 64); if (!shouldUpdate && !didCaptureError) return ( hasContext && invalidateContextProvider(workInProgress, Component, !1), bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ) ); shouldUpdate = workInProgress.stateNode; - ReactCurrentOwner$1.current = workInProgress; + ReactCurrentOwner$3.current = workInProgress; if ( didCaptureError && "function" !== typeof Component.getDerivedStateFromError @@ -4108,11 +4292,11 @@ function finishClassComponent( profilerStartTime = -1; } else nextChildren = shouldUpdate.render(); workInProgress.effectTag |= 1; - null !== current && didCaptureError + null !== current$$1 && didCaptureError ? ((didCaptureError = nextChildren), (workInProgress.child = reconcileChildFibers( workInProgress, - current.child, + current$$1.child, null, renderExpirationTime )), @@ -4123,7 +4307,7 @@ function finishClassComponent( renderExpirationTime ))) : reconcileChildren( - current, + current$$1, workInProgress, nextChildren, renderExpirationTime @@ -4146,7 +4330,7 @@ function pushHostRootContext(workInProgress) { } var SUSPENDED_MARKER = { dehydrated: null, retryTime: 0 }; function updateSuspenseComponent( - current, + current$$1, workInProgress, renderExpirationTime ) { @@ -4158,30 +4342,32 @@ function updateSuspenseComponent( (JSCompiler_temp = 0 !== (workInProgress.effectTag & 64)) || (JSCompiler_temp = 0 !== (suspenseContext & 2) && - (null === current || null !== current.memoizedState)); + (null === current$$1 || null !== current$$1.memoizedState)); JSCompiler_temp ? ((nextDidTimeout = !0), (workInProgress.effectTag &= -65)) - : (null !== current && null === current.memoizedState) || + : (null !== current$$1 && null === current$$1.memoizedState) || void 0 === nextProps.fallback || !0 === nextProps.unstable_avoidThisFallback || (suspenseContext |= 1); - push(suspenseStackCursor, suspenseContext & 1); - if (null === current) { + push(suspenseStackCursor, suspenseContext & 1, workInProgress); + if (null === current$$1) { + void 0 !== nextProps.fallback && + tryToClaimNextHydratableInstance(workInProgress); if (nextDidTimeout) { nextDidTimeout = nextProps.fallback; nextProps = createFiberFromFragment(null, mode, 0, null); nextProps.return = workInProgress; if (0 === (workInProgress.mode & 2)) for ( - current = + current$$1 = null !== workInProgress.memoizedState ? workInProgress.child.child : workInProgress.child, - nextProps.child = current; - null !== current; + nextProps.child = current$$1; + null !== current$$1; ) - (current.return = nextProps), (current = current.sibling); + (current$$1.return = nextProps), (current$$1 = current$$1.sibling); renderExpirationTime = createFiberFromFragment( nextDidTimeout, mode, @@ -4203,14 +4389,15 @@ function updateSuspenseComponent( renderExpirationTime )); } - if (null !== current.memoizedState) { - current = current.child; - mode = current.sibling; + if (null !== current$$1.memoizedState) { + current$$1 = current$$1.child; + mode = current$$1.sibling; if (nextDidTimeout) { nextProps = nextProps.fallback; renderExpirationTime = createWorkInProgress( - current, - current.pendingProps + current$$1, + current$$1.pendingProps, + 0 ); renderExpirationTime.return = workInProgress; if ( @@ -4219,7 +4406,7 @@ function updateSuspenseComponent( null !== workInProgress.memoizedState ? workInProgress.child.child : workInProgress.child), - nextDidTimeout !== current.child) + nextDidTimeout !== current$$1.child) ) for ( renderExpirationTime.child = nextDidTimeout; @@ -4230,12 +4417,12 @@ function updateSuspenseComponent( (nextDidTimeout = nextDidTimeout.sibling); if (workInProgress.mode & 8) { nextDidTimeout = 0; - for (current = renderExpirationTime.child; null !== current; ) - (nextDidTimeout += current.treeBaseDuration), - (current = current.sibling); + for (current$$1 = renderExpirationTime.child; null !== current$$1; ) + (nextDidTimeout += current$$1.treeBaseDuration), + (current$$1 = current$$1.sibling); renderExpirationTime.treeBaseDuration = nextDidTimeout; } - mode = createWorkInProgress(mode, nextProps); + mode = createWorkInProgress(mode, nextProps, mode.expirationTime); mode.return = workInProgress; renderExpirationTime.sibling = mode; renderExpirationTime.childExpirationTime = 0; @@ -4245,37 +4432,37 @@ function updateSuspenseComponent( } renderExpirationTime = reconcileChildFibers( workInProgress, - current.child, + current$$1.child, nextProps.children, renderExpirationTime ); workInProgress.memoizedState = null; return (workInProgress.child = renderExpirationTime); } - current = current.child; + current$$1 = current$$1.child; if (nextDidTimeout) { nextDidTimeout = nextProps.fallback; nextProps = createFiberFromFragment(null, mode, 0, null); nextProps.return = workInProgress; - nextProps.child = current; - null !== current && (current.return = nextProps); + nextProps.child = current$$1; + null !== current$$1 && (current$$1.return = nextProps); if (0 === (workInProgress.mode & 2)) for ( - current = + current$$1 = null !== workInProgress.memoizedState ? workInProgress.child.child : workInProgress.child, - nextProps.child = current; - null !== current; + nextProps.child = current$$1; + null !== current$$1; ) - (current.return = nextProps), (current = current.sibling); + (current$$1.return = nextProps), (current$$1 = current$$1.sibling); if (workInProgress.mode & 8) { - current = 0; + current$$1 = 0; for (suspenseContext = nextProps.child; null !== suspenseContext; ) - (current += suspenseContext.treeBaseDuration), + (current$$1 += suspenseContext.treeBaseDuration), (suspenseContext = suspenseContext.sibling); - nextProps.treeBaseDuration = current; + nextProps.treeBaseDuration = current$$1; } renderExpirationTime = createFiberFromFragment( nextDidTimeout, @@ -4294,7 +4481,7 @@ function updateSuspenseComponent( workInProgress.memoizedState = null; return (workInProgress.child = reconcileChildFibers( workInProgress, - current, + current$$1, nextProps.children, renderExpirationTime )); @@ -4321,7 +4508,6 @@ function initSuspenseListRenderState( ? (workInProgress.memoizedState = { isBackwards: isBackwards, rendering: null, - renderingStartTime: 0, last: lastContentRow, tail: tail, tailExpiration: 0, @@ -4330,7 +4516,6 @@ function initSuspenseListRenderState( }) : ((renderState.isBackwards = isBackwards), (renderState.rendering = null), - (renderState.renderingStartTime = 0), (renderState.last = lastContentRow), (renderState.tail = tail), (renderState.tailExpiration = 0), @@ -4338,7 +4523,7 @@ function initSuspenseListRenderState( (renderState.lastEffect = lastEffectBeforeRendering)); } function updateSuspenseListComponent( - current, + current$$1, workInProgress, renderExpirationTime ) { @@ -4346,7 +4531,7 @@ function updateSuspenseListComponent( revealOrder = nextProps.revealOrder, tailMode = nextProps.tail; reconcileChildren( - current, + current$$1, workInProgress, nextProps.children, renderExpirationTime @@ -4355,39 +4540,42 @@ function updateSuspenseListComponent( if (0 !== (nextProps & 2)) (nextProps = (nextProps & 1) | 2), (workInProgress.effectTag |= 64); else { - if (null !== current && 0 !== (current.effectTag & 64)) - a: for (current = workInProgress.child; null !== current; ) { - if (13 === current.tag) - null !== current.memoizedState && - scheduleWorkOnFiber(current, renderExpirationTime); - else if (19 === current.tag) - scheduleWorkOnFiber(current, renderExpirationTime); - else if (null !== current.child) { - current.child.return = current; - current = current.child; + if (null !== current$$1 && 0 !== (current$$1.effectTag & 64)) + a: for (current$$1 = workInProgress.child; null !== current$$1; ) { + if (13 === current$$1.tag) + null !== current$$1.memoizedState && + scheduleWorkOnFiber(current$$1, renderExpirationTime); + else if (19 === current$$1.tag) + scheduleWorkOnFiber(current$$1, renderExpirationTime); + else if (null !== current$$1.child) { + current$$1.child.return = current$$1; + current$$1 = current$$1.child; continue; } - if (current === workInProgress) break a; - for (; null === current.sibling; ) { - if (null === current.return || current.return === workInProgress) + if (current$$1 === workInProgress) break a; + for (; null === current$$1.sibling; ) { + if ( + null === current$$1.return || + current$$1.return === workInProgress + ) break a; - current = current.return; + current$$1 = current$$1.return; } - current.sibling.return = current.return; - current = current.sibling; + current$$1.sibling.return = current$$1.return; + current$$1 = current$$1.sibling; } nextProps &= 1; } - push(suspenseStackCursor, nextProps); + push(suspenseStackCursor, nextProps, workInProgress); if (0 === (workInProgress.mode & 2)) workInProgress.memoizedState = null; else switch (revealOrder) { case "forwards": renderExpirationTime = workInProgress.child; for (revealOrder = null; null !== renderExpirationTime; ) - (current = renderExpirationTime.alternate), - null !== current && - null === findFirstSuspended(current) && + (current$$1 = renderExpirationTime.alternate), + null !== current$$1 && + null === findFirstSuspended(current$$1) && (revealOrder = renderExpirationTime), (renderExpirationTime = renderExpirationTime.sibling); renderExpirationTime = revealOrder; @@ -4409,15 +4597,15 @@ function updateSuspenseListComponent( renderExpirationTime = null; revealOrder = workInProgress.child; for (workInProgress.child = null; null !== revealOrder; ) { - current = revealOrder.alternate; - if (null !== current && null === findFirstSuspended(current)) { + current$$1 = revealOrder.alternate; + if (null !== current$$1 && null === findFirstSuspended(current$$1)) { workInProgress.child = revealOrder; break; } - current = revealOrder.sibling; + current$$1 = revealOrder.sibling; revealOrder.sibling = renderExpirationTime; renderExpirationTime = revealOrder; - revealOrder = current; + revealOrder = current$$1; } initSuspenseListRenderState( workInProgress, @@ -4444,30 +4632,36 @@ function updateSuspenseListComponent( return workInProgress.child; } function bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ) { - null !== current && (workInProgress.dependencies = current.dependencies); + null !== current$$1 && + (workInProgress.dependencies = current$$1.dependencies); profilerStartTime = -1; var updateExpirationTime = workInProgress.expirationTime; 0 !== updateExpirationTime && markUnprocessedUpdateTime(updateExpirationTime); if (workInProgress.childExpirationTime < renderExpirationTime) return null; - if (null !== current && workInProgress.child !== current.child) + if (null !== current$$1 && workInProgress.child !== current$$1.child) throw Error("Resuming work not yet implemented."); if (null !== workInProgress.child) { - current = workInProgress.child; - renderExpirationTime = createWorkInProgress(current, current.pendingProps); + current$$1 = workInProgress.child; + renderExpirationTime = createWorkInProgress( + current$$1, + current$$1.pendingProps, + current$$1.expirationTime + ); workInProgress.child = renderExpirationTime; for ( renderExpirationTime.return = workInProgress; - null !== current.sibling; + null !== current$$1.sibling; ) - (current = current.sibling), + (current$$1 = current$$1.sibling), (renderExpirationTime = renderExpirationTime.sibling = createWorkInProgress( - current, - current.pendingProps + current$$1, + current$$1.pendingProps, + current$$1.expirationTime )), (renderExpirationTime.return = workInProgress); renderExpirationTime.sibling = null; @@ -4489,7 +4683,12 @@ appendAllChildren = function( var instance = node.stateNode; needsVisibilityToggle && isHidden && - (instance = cloneHiddenInstance(instance)); + (instance = cloneHiddenInstance( + instance, + node.type, + node.memoizedProps, + node + )); appendChildNode(parent.node, instance.node); } else if (6 === node.tag) { instance = node.stateNode; @@ -4542,7 +4741,12 @@ function appendAllChildrenToContainer( var instance = node.stateNode; needsVisibilityToggle && isHidden && - (instance = cloneHiddenInstance(instance)); + (instance = cloneHiddenInstance( + instance, + node.type, + node.memoizedProps, + node + )); appendChildNodeToSet(containerChildSet, instance.node); } else if (6 === node.tag) { instance = node.stateNode; @@ -4628,8 +4832,8 @@ updateHostComponent$1 = function(current, workInProgress, type, newProps) { ? cloneNodeWithNewProps(recyclableInstance, newProps) : cloneNode(recyclableInstance) : null !== newProps - ? cloneNodeWithNewChildrenAndProps(recyclableInstance, newProps) - : cloneNodeWithNewChildren(recyclableInstance), + ? cloneNodeWithNewChildrenAndProps(recyclableInstance, newProps) + : cloneNodeWithNewChildren(recyclableInstance), canonical: type.canonical }), (workInProgress.stateNode = type), @@ -4639,17 +4843,16 @@ updateHostComponent$1 = function(current, workInProgress, type, newProps) { } }; updateHostText$1 = function(current, workInProgress, oldText, newText) { - oldText !== newText - ? ((current = requiredContext(rootInstanceStackCursor.current)), - (oldText = requiredContext(contextStackCursor$1.current)), - (workInProgress.stateNode = createTextInstance( - newText, - current, - oldText, - workInProgress - )), - (workInProgress.effectTag |= 4)) - : (workInProgress.stateNode = current.stateNode); + oldText !== newText && + ((current = requiredContext(rootInstanceStackCursor.current)), + (oldText = requiredContext(contextStackCursor$1.current)), + (workInProgress.stateNode = createTextInstance( + newText, + current, + oldText, + workInProgress + )), + (workInProgress.effectTag |= 4)); }; function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { switch (renderState.tailMode) { @@ -4675,78 +4878,67 @@ function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { : (_lastTailNode.sibling = null); } } -function completeWork(current, workInProgress, renderExpirationTime) { +function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { var newProps = workInProgress.pendingProps; switch (workInProgress.tag) { case 2: + break; case 16: + break; case 15: case 0: - case 11: - case 7: - case 8: - case 12: - case 9: - case 14: - return null; + break; case 1: - return isContextProvider(workInProgress.type) && popContext(), null; + isContextProvider(workInProgress.type) && popContext(workInProgress); + break; case 3: - return ( - popHostContainer(), - pop(didPerformWorkStackCursor), - pop(contextStackCursor), - (current = workInProgress.stateNode), - current.pendingContext && - ((current.context = current.pendingContext), - (current.pendingContext = null)), - updateHostContainer(workInProgress), - null - ); + popHostContainer(workInProgress); + popTopLevelContextObject(workInProgress); + current = workInProgress.stateNode; + current.pendingContext && + ((current.context = current.pendingContext), + (current.pendingContext = null)); + updateHostContainer(workInProgress); + break; case 5: popHostContext(workInProgress); var rootContainerInstance = requiredContext( rootInstanceStackCursor.current ); - renderExpirationTime = workInProgress.type; + renderExpirationTime$jscomp$0 = workInProgress.type; if (null !== current && null != workInProgress.stateNode) updateHostComponent$1( current, workInProgress, - renderExpirationTime, + renderExpirationTime$jscomp$0, newProps, rootContainerInstance ), current.ref !== workInProgress.ref && (workInProgress.effectTag |= 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." - ); - return null; - } + else if (newProps) { requiredContext(contextStackCursor$1.current); current = nextReactTag; nextReactTag += 2; - renderExpirationTime = getViewConfigForType(renderExpirationTime); + renderExpirationTime$jscomp$0 = getViewConfigForType( + renderExpirationTime$jscomp$0 + ); var updatePayload = diffProperties( null, emptyObject, newProps, - renderExpirationTime.validAttributes + renderExpirationTime$jscomp$0.validAttributes ); rootContainerInstance = createNode( current, - renderExpirationTime.uiViewClassName, + renderExpirationTime$jscomp$0.uiViewClassName, rootContainerInstance, updatePayload, workInProgress ); current = new ReactFabricHostComponent( current, - renderExpirationTime, + renderExpirationTime$jscomp$0, newProps, workInProgress ); @@ -4754,8 +4946,11 @@ function completeWork(current, workInProgress, renderExpirationTime) { appendAllChildren(current, workInProgress, !1, !1); workInProgress.stateNode = current; null !== workInProgress.ref && (workInProgress.effectTag |= 128); - } - return null; + } else 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." + ); + break; case 6: if (current && null != workInProgress.stateNode) updateHostText$1( @@ -4778,30 +4973,33 @@ function completeWork(current, workInProgress, renderExpirationTime) { workInProgress ); } - return null; + break; + case 11: + break; case 13: - pop(suspenseStackCursor); + pop(suspenseStackCursor, workInProgress); newProps = workInProgress.memoizedState; if (0 !== (workInProgress.effectTag & 64)) return ( - (workInProgress.expirationTime = renderExpirationTime), workInProgress + (workInProgress.expirationTime = renderExpirationTime$jscomp$0), + workInProgress ); newProps = null !== newProps; rootContainerInstance = !1; null !== current && - ((renderExpirationTime = current.memoizedState), - (rootContainerInstance = null !== renderExpirationTime), + ((renderExpirationTime$jscomp$0 = current.memoizedState), + (rootContainerInstance = null !== renderExpirationTime$jscomp$0), newProps || - null === renderExpirationTime || - ((renderExpirationTime = current.child.sibling), - null !== renderExpirationTime && + null === renderExpirationTime$jscomp$0 || + ((renderExpirationTime$jscomp$0 = current.child.sibling), + null !== renderExpirationTime$jscomp$0 && ((updatePayload = workInProgress.firstEffect), null !== updatePayload - ? ((workInProgress.firstEffect = renderExpirationTime), - (renderExpirationTime.nextEffect = updatePayload)) - : ((workInProgress.firstEffect = workInProgress.lastEffect = renderExpirationTime), - (renderExpirationTime.nextEffect = null)), - (renderExpirationTime.effectTag = 8)))); + ? ((workInProgress.firstEffect = renderExpirationTime$jscomp$0), + (renderExpirationTime$jscomp$0.nextEffect = updatePayload)) + : ((workInProgress.firstEffect = workInProgress.lastEffect = renderExpirationTime$jscomp$0), + (renderExpirationTime$jscomp$0.nextEffect = null)), + (renderExpirationTime$jscomp$0.effectTag = 8)))); if (newProps && !rootContainerInstance && 0 !== (workInProgress.mode & 2)) if ( (null === current && @@ -4818,27 +5016,38 @@ function completeWork(current, workInProgress, renderExpirationTime) { workInProgressRootExitStatus = RootSuspendedWithDelay; 0 !== workInProgressRootNextUnprocessedUpdateTime && null !== workInProgressRoot && - (markRootSuspendedAtTime( - workInProgressRoot, - renderExpirationTime$1 - ), + (markRootSuspendedAtTime(workInProgressRoot, renderExpirationTime), markRootUpdatedAtTime( workInProgressRoot, workInProgressRootNextUnprocessedUpdateTime )); } newProps && (workInProgress.effectTag |= 4); - return null; + break; + case 7: + break; + case 8: + break; + case 12: + break; case 4: - return popHostContainer(), updateHostContainer(workInProgress), null; + popHostContainer(workInProgress); + updateHostContainer(workInProgress); + break; case 10: - return popProvider(workInProgress), null; + popProvider(workInProgress); + break; + case 9: + break; + case 14: + break; case 17: - return isContextProvider(workInProgress.type) && popContext(), null; + isContextProvider(workInProgress.type) && popContext(workInProgress); + break; case 19: - pop(suspenseStackCursor); + pop(suspenseStackCursor, workInProgress); newProps = workInProgress.memoizedState; - if (null === newProps) return null; + if (null === newProps) break; rootContainerInstance = 0 !== (workInProgress.effectTag & 64); updatePayload = newProps.rendering; if (null === updatePayload) @@ -4860,7 +5069,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { null === newProps.lastEffect && (workInProgress.firstEffect = null); workInProgress.lastEffect = newProps.lastEffect; - current = renderExpirationTime; + current = renderExpirationTime$jscomp$0; for (newProps = workInProgress.child; null !== newProps; ) (rootContainerInstance = newProps), (updatePayload = current), @@ -4868,8 +5077,9 @@ function completeWork(current, workInProgress, renderExpirationTime) { (rootContainerInstance.nextEffect = null), (rootContainerInstance.firstEffect = null), (rootContainerInstance.lastEffect = null), - (renderExpirationTime = rootContainerInstance.alternate), - null === renderExpirationTime + (renderExpirationTime$jscomp$0 = + rootContainerInstance.alternate), + null === renderExpirationTime$jscomp$0 ? ((rootContainerInstance.childExpirationTime = 0), (rootContainerInstance.expirationTime = updatePayload), (rootContainerInstance.child = null), @@ -4880,18 +5090,19 @@ function completeWork(current, workInProgress, renderExpirationTime) { (rootContainerInstance.selfBaseDuration = 0), (rootContainerInstance.treeBaseDuration = 0)) : ((rootContainerInstance.childExpirationTime = - renderExpirationTime.childExpirationTime), + renderExpirationTime$jscomp$0.childExpirationTime), (rootContainerInstance.expirationTime = - renderExpirationTime.expirationTime), + renderExpirationTime$jscomp$0.expirationTime), (rootContainerInstance.child = - renderExpirationTime.child), + renderExpirationTime$jscomp$0.child), (rootContainerInstance.memoizedProps = - renderExpirationTime.memoizedProps), + renderExpirationTime$jscomp$0.memoizedProps), (rootContainerInstance.memoizedState = - renderExpirationTime.memoizedState), + renderExpirationTime$jscomp$0.memoizedState), (rootContainerInstance.updateQueue = - renderExpirationTime.updateQueue), - (updatePayload = renderExpirationTime.dependencies), + renderExpirationTime$jscomp$0.updateQueue), + (updatePayload = + renderExpirationTime$jscomp$0.dependencies), (rootContainerInstance.dependencies = null === updatePayload ? null @@ -4901,13 +5112,14 @@ function completeWork(current, workInProgress, renderExpirationTime) { responders: updatePayload.responders }), (rootContainerInstance.selfBaseDuration = - renderExpirationTime.selfBaseDuration), + renderExpirationTime$jscomp$0.selfBaseDuration), (rootContainerInstance.treeBaseDuration = - renderExpirationTime.treeBaseDuration)), + renderExpirationTime$jscomp$0.treeBaseDuration)), (newProps = newProps.sibling); push( suspenseStackCursor, - (suspenseStackCursor.current & 1) | 2 + (suspenseStackCursor.current & 1) | 2, + workInProgress ); return workInProgress.child; } @@ -4930,20 +5142,18 @@ function completeWork(current, workInProgress, renderExpirationTime) { null === newProps.tail && "hidden" === newProps.tailMode && !updatePayload.alternate) - ) - return ( - (workInProgress = workInProgress.lastEffect = - newProps.lastEffect), - null !== workInProgress && (workInProgress.nextEffect = null), - null - ); + ) { + workInProgress = workInProgress.lastEffect = newProps.lastEffect; + null !== workInProgress && (workInProgress.nextEffect = null); + break; + } } else - 2 * now() - newProps.renderingStartTime > newProps.tailExpiration && - 1 < renderExpirationTime && + now() > newProps.tailExpiration && + 1 < renderExpirationTime$jscomp$0 && ((workInProgress.effectTag |= 64), (rootContainerInstance = !0), cutOffTailIfNeeded(newProps, !1), - (current = renderExpirationTime - 1), + (current = renderExpirationTime$jscomp$0 - 1), (workInProgress.expirationTime = workInProgress.childExpirationTime = current), null === spawnedWorkDuringRender ? (spawnedWorkDuringRender = [current]) @@ -4957,44 +5167,49 @@ function completeWork(current, workInProgress, renderExpirationTime) { : (workInProgress.child = updatePayload), (newProps.last = updatePayload)); } - return null !== newProps.tail - ? (0 === newProps.tailExpiration && + if (null !== newProps.tail) + return ( + 0 === newProps.tailExpiration && (newProps.tailExpiration = now() + 500), (current = newProps.tail), (newProps.rendering = current), (newProps.tail = current.sibling), (newProps.lastEffect = workInProgress.lastEffect), - (newProps.renderingStartTime = now()), (current.sibling = null), - (workInProgress = suspenseStackCursor.current), + (newProps = suspenseStackCursor.current), push( suspenseStackCursor, - rootContainerInstance - ? (workInProgress & 1) | 2 - : workInProgress & 1 + rootContainerInstance ? (newProps & 1) | 2 : newProps & 1, + workInProgress ), - current) - : null; + current + ); + break; + case 20: + break; + case 21: + break; + default: + throw Error( + "Unknown unit of work tag (" + + workInProgress.tag + + "). This error is likely caused by a bug in React. Please file an issue." + ); } - throw Error( - "Unknown unit of work tag (" + - workInProgress.tag + - "). This error is likely caused by a bug in React. Please file an issue." - ); + return null; } function unwindWork(workInProgress) { switch (workInProgress.tag) { case 1: - isContextProvider(workInProgress.type) && popContext(); + isContextProvider(workInProgress.type) && popContext(workInProgress); var effectTag = workInProgress.effectTag; return effectTag & 4096 ? ((workInProgress.effectTag = (effectTag & -4097) | 64), workInProgress) : null; case 3: - popHostContainer(); - pop(didPerformWorkStackCursor); - pop(contextStackCursor); + popHostContainer(workInProgress); + popTopLevelContextObject(workInProgress); effectTag = workInProgress.effectTag; if (0 !== (effectTag & 64)) throw Error( @@ -5006,7 +5221,7 @@ function unwindWork(workInProgress) { return popHostContext(workInProgress), null; case 13: return ( - pop(suspenseStackCursor), + pop(suspenseStackCursor, workInProgress), (effectTag = workInProgress.effectTag), effectTag & 4096 ? ((workInProgress.effectTag = (effectTag & -4097) | 64), @@ -5014,9 +5229,9 @@ function unwindWork(workInProgress) { : null ); case 19: - return pop(suspenseStackCursor), null; + return pop(suspenseStackCursor, workInProgress), null; case 4: - return popHostContainer(), null; + return popHostContainer(workInProgress), null; case 10: return popProvider(workInProgress), null; default: @@ -5073,192 +5288,102 @@ function logError(boundary, errorInfo) { }); } } -function safelyCallComponentWillUnmount(current, instance) { +function safelyCallComponentWillUnmount(current$$1, instance) { try { - (instance.props = current.memoizedProps), - (instance.state = current.memoizedState), + (instance.props = current$$1.memoizedProps), + (instance.state = current$$1.memoizedState), instance.componentWillUnmount(); } catch (unmountError) { - captureCommitPhaseError(current, unmountError); + captureCommitPhaseError(current$$1, unmountError); } } -function safelyDetachRef(current) { - var ref = current.ref; +function safelyDetachRef(current$$1) { + var ref = current$$1.ref; if (null !== ref) if ("function" === typeof ref) try { ref(null); } catch (refError) { - captureCommitPhaseError(current, refError); + captureCommitPhaseError(current$$1, refError); } else ref.current = null; } -function commitBeforeMutationLifeCycles(current, finishedWork) { +function commitBeforeMutationLifeCycles(current$$1, finishedWork) { switch (finishedWork.tag) { case 0: case 11: case 15: - case 22: - return; + commitHookEffectList(2, 0, finishedWork); + break; case 1: - if (finishedWork.effectTag & 256 && null !== current) { - var prevProps = current.memoizedProps, - prevState = current.memoizedState; - current = finishedWork.stateNode; - finishedWork = current.getSnapshotBeforeUpdate( + if (finishedWork.effectTag & 256 && null !== current$$1) { + var prevProps = current$$1.memoizedProps, + prevState = current$$1.memoizedState; + current$$1 = finishedWork.stateNode; + finishedWork = current$$1.getSnapshotBeforeUpdate( finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState ); - current.__reactInternalSnapshotBeforeUpdate = finishedWork; + current$$1.__reactInternalSnapshotBeforeUpdate = finishedWork; } - return; + break; case 3: case 5: case 6: case 4: case 17: - return; + 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." + ); } - 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(tag, finishedWork) { +function commitHookEffectList(unmountTag, mountTag, finishedWork) { finishedWork = finishedWork.updateQueue; finishedWork = null !== finishedWork ? finishedWork.lastEffect : null; if (null !== finishedWork) { var effect = (finishedWork = finishedWork.next); do { - if ((effect.tag & tag) === tag) { + if (0 !== (effect.tag & unmountTag)) { var destroy = effect.destroy; effect.destroy = void 0; void 0 !== destroy && destroy(); } + 0 !== (effect.tag & mountTag) && + ((destroy = effect.create), (effect.destroy = destroy())); effect = effect.next; } while (effect !== finishedWork); } } -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 = effect.create; - effect.destroy = create(); - } - effect = effect.next; - } while (effect !== finishedWork); - } -} -function commitLifeCycles(finishedRoot, current, finishedWork) { - switch (finishedWork.tag) { - case 0: - case 11: - case 15: - case 22: - commitHookEffectListMount(3, finishedWork); - return; - case 1: - finishedRoot = finishedWork.stateNode; - if (finishedWork.effectTag & 4) - if (null === current) finishedRoot.componentDidMount(); - else { - var prevProps = - finishedWork.elementType === finishedWork.type - ? current.memoizedProps - : resolveDefaultProps(finishedWork.type, current.memoizedProps); - finishedRoot.componentDidUpdate( - prevProps, - 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); - } - return; - case 5: - if (null === current && finishedWork.effectTag & 4) - throw Error( - "The current renderer does not support mutation. This error is likely caused by a bug in React. Please file an issue." - ); - return; - case 6: - return; - case 4: - return; - case 12: - prevProps = finishedWork.memoizedProps.onRender; - var commitTime$jscomp$0 = commitTime; - "function" === typeof prevProps && - prevProps( - finishedWork.memoizedProps.id, - null === current ? "mount" : "update", - finishedWork.actualDuration, - finishedWork.treeBaseDuration, - finishedWork.actualStartTime, - commitTime$jscomp$0, - finishedRoot.memoizedInteractions - ); - return; - case 13: - return; - case 19: - case 17: - case 20: - case 21: - 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 commitUnmount(finishedRoot, current$jscomp$0, renderPriorityLevel) { +function commitUnmount(finishedRoot, current$$1$jscomp$0, renderPriorityLevel) { "function" === typeof onCommitFiberUnmount && - onCommitFiberUnmount(current$jscomp$0); - switch (current$jscomp$0.tag) { + onCommitFiberUnmount(current$$1$jscomp$0); + switch (current$$1$jscomp$0.tag) { case 0: case 11: case 14: case 15: - case 22: - finishedRoot = current$jscomp$0.updateQueue; + finishedRoot = current$$1$jscomp$0.updateQueue; if ( null !== finishedRoot && ((finishedRoot = finishedRoot.lastEffect), null !== finishedRoot) ) { var firstEffect = finishedRoot.next; - runWithPriority( + runWithPriority$1( 97 < renderPriorityLevel ? 97 : renderPriorityLevel, function() { var effect = firstEffect; do { - var _destroy = effect.destroy; - if (void 0 !== _destroy) { - var current = current$jscomp$0; + var destroy = effect.destroy; + if (void 0 !== destroy) { + var current$$1 = current$$1$jscomp$0; try { - _destroy(); + destroy(); } catch (error) { - captureCommitPhaseError(current, error); + captureCommitPhaseError(current$$1, error); } } effect = effect.next; @@ -5268,41 +5393,42 @@ function commitUnmount(finishedRoot, current$jscomp$0, renderPriorityLevel) { } break; case 1: - safelyDetachRef(current$jscomp$0); - renderPriorityLevel = current$jscomp$0.stateNode; + safelyDetachRef(current$$1$jscomp$0); + renderPriorityLevel = current$$1$jscomp$0.stateNode; "function" === typeof renderPriorityLevel.componentWillUnmount && - safelyCallComponentWillUnmount(current$jscomp$0, renderPriorityLevel); + safelyCallComponentWillUnmount( + current$$1$jscomp$0, + renderPriorityLevel + ); break; case 5: - safelyDetachRef(current$jscomp$0); + safelyDetachRef(current$$1$jscomp$0); break; case 4: - createChildNodeSet(current$jscomp$0.stateNode.containerInfo); + createChildNodeSet(current$$1$jscomp$0.stateNode.containerInfo); } } -function detachFiber(current) { - var alternate = current.alternate; - current.return = null; - current.child = null; - current.memoizedState = null; - current.updateQueue = null; - current.dependencies = null; - current.alternate = null; - current.firstEffect = null; - current.lastEffect = null; - current.pendingProps = null; - current.memoizedProps = null; - current.stateNode = null; +function detachFiber(current$$1) { + var alternate = current$$1.alternate; + current$$1.return = null; + current$$1.child = null; + current$$1.memoizedState = null; + current$$1.updateQueue = null; + current$$1.dependencies = null; + current$$1.alternate = null; + current$$1.firstEffect = null; + current$$1.lastEffect = null; + current$$1.pendingProps = null; + current$$1.memoizedProps = null; null !== alternate && detachFiber(alternate); } -function commitWork(current, finishedWork) { +function commitWork(current$$1, finishedWork) { switch (finishedWork.tag) { case 0: case 11: case 14: case 15: - case 22: - commitHookEffectListUnmount(3, finishedWork); + commitHookEffectList(4, 8, finishedWork); return; case 12: return; @@ -5315,20 +5441,19 @@ function commitWork(current, finishedWork) { attachSuspenseRetryListeners(finishedWork); return; } - a: { - switch (finishedWork.tag) { - 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." - ); + a: switch (finishedWork.tag) { + case 1: + case 5: + case 6: + case 20: + break a; + case 3: + case 4: + break a; + 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." + ); } } function attachSuspenseRetryListeners(finishedWork) { @@ -5388,7 +5513,7 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { return expirationTime; } var ceil = Math.ceil, - ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, + ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, NoContext = 0, LegacyUnbatchedContext = 8, @@ -5403,7 +5528,7 @@ var ceil = Math.ceil, executionContext = NoContext, workInProgressRoot = null, workInProgress = null, - renderExpirationTime$1 = 0, + renderExpirationTime = 0, workInProgressRootExitStatus = RootIncomplete, workInProgressRootFatalError = null, workInProgressRootLatestProcessedExpirationTime = 1073741823, @@ -5430,8 +5555,8 @@ function requestCurrentTimeForUpdate() { return (executionContext & (RenderContext | CommitContext)) !== NoContext ? 1073741821 - ((now() / 10) | 0) : 0 !== currentEventTime - ? currentEventTime - : (currentEventTime = 1073741821 - ((now() / 10) | 0)); + ? currentEventTime + : (currentEventTime = 1073741821 - ((now() / 10) | 0)); } function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { fiber = fiber.mode; @@ -5439,7 +5564,7 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { var priorityLevel = getCurrentPriorityLevel(); if (0 === (fiber & 4)) return 99 === priorityLevel ? 1073741823 : 1073741822; if ((executionContext & RenderContext) !== NoContext) - return renderExpirationTime$1; + return renderExpirationTime; if (null !== suspenseConfig) currentTime = 1073741821 - @@ -5471,11 +5596,11 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { throw Error("Expected a valid priority level"); } null !== workInProgressRoot && - currentTime === renderExpirationTime$1 && + currentTime === renderExpirationTime && --currentTime; return currentTime; } -function scheduleWork(fiber, expirationTime) { +function scheduleUpdateOnFiber(fiber, expirationTime) { if (50 < nestedUpdateCount) throw ((nestedUpdateCount = 0), (rootWithNestedUpdates = null), @@ -5532,7 +5657,7 @@ function markUpdateTimeFromFiberToRoot(fiber, expirationTime) { (workInProgressRoot === root && (markUnprocessedUpdateTime(expirationTime), workInProgressRootExitStatus === RootSuspendedWithDelay && - markRootSuspendedAtTime(root, renderExpirationTime$1)), + markRootSuspendedAtTime(root, renderExpirationTime)), markRootUpdatedAtTime(root, expirationTime)); return root; } @@ -5541,10 +5666,9 @@ function getNextRootExpirationTimeToWorkOn(root) { if (0 !== lastExpiredTime) return lastExpiredTime; lastExpiredTime = root.firstPendingTime; if (!isRootSuspendedAtTime(root, lastExpiredTime)) return lastExpiredTime; - var lastPingedTime = root.lastPingedTime; + lastExpiredTime = root.lastPingedTime; root = root.nextKnownPendingLevel; - root = lastPingedTime > root ? lastPingedTime : root; - return 2 >= root && lastExpiredTime !== root ? 0 : root; + return lastExpiredTime > root ? lastExpiredTime : root; } function ensureRootIsScheduled(root) { if (0 !== root.lastExpiredTime) @@ -5593,233 +5717,271 @@ function ensureRootIsScheduled(root) { } function performConcurrentWorkOnRoot(root, didTimeout) { currentEventTime = 0; - if (didTimeout) { - didTimeout = requestCurrentTimeForUpdate(); - var lastExpiredTime = root.lastExpiredTime; - if (0 === lastExpiredTime || lastExpiredTime > didTimeout) - root.lastExpiredTime = didTimeout; - ensureRootIsScheduled(root); - return null; - } - lastExpiredTime = getNextRootExpirationTimeToWorkOn(root); - if (0 === lastExpiredTime) return null; - didTimeout = root.callbackNode; - if ((executionContext & (RenderContext | CommitContext)) !== NoContext) - throw Error("Should not already be working."); - flushPassiveEffects(); - var expirationTime = lastExpiredTime, - prevExecutionContext = executionContext; - executionContext |= RenderContext; - var exitStatus = pushDispatcher(); - if (root !== workInProgressRoot || expirationTime !== renderExpirationTime$1) - prepareFreshStack(root, expirationTime), - startWorkOnPendingInteractions(root, expirationTime); - expirationTime = pushInteractions(root); - do - try { - workLoopConcurrent(); - break; - } catch (thrownValue) { - handleError(root, thrownValue); - } - while (1); - resetContextDependencies(); - tracing.__interactionsRef.current = expirationTime; - ReactCurrentDispatcher$1.current = exitStatus; - executionContext = prevExecutionContext; - null !== workInProgress - ? (exitStatus = RootIncomplete) - : ((workInProgressRoot = null), - (exitStatus = workInProgressRootExitStatus)); - if (exitStatus !== RootIncomplete) { - exitStatus === RootErrored && - ((lastExpiredTime = 2 < lastExpiredTime ? 2 : lastExpiredTime), - (exitStatus = renderRootSync(root, lastExpiredTime))); - if (exitStatus === RootFatalErrored) - throw ((didTimeout = workInProgressRootFatalError), - prepareFreshStack(root, lastExpiredTime), - markRootSuspendedAtTime(root, lastExpiredTime), + if (didTimeout) + return ( + (didTimeout = requestCurrentTimeForUpdate()), + markRootExpiredAtTime(root, didTimeout), ensureRootIsScheduled(root), - didTimeout); - prevExecutionContext = root.finishedWork = root.current.alternate; - root.finishedExpirationTime = lastExpiredTime; - switch (exitStatus) { - case RootIncomplete: - case RootFatalErrored: - throw Error("Root did not complete. This is a bug in React."); - case RootErrored: - commitRoot(root); - break; - case RootSuspended: - markRootSuspendedAtTime(root, lastExpiredTime); - exitStatus = root.lastSuspendedTime; - lastExpiredTime === exitStatus && - (root.nextKnownPendingLevel = getRemainingExpirationTime( - prevExecutionContext - )); - if ( - 1073741823 === workInProgressRootLatestProcessedExpirationTime && - ((prevExecutionContext = - globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now()), - 10 < prevExecutionContext) - ) { - if ( - workInProgressRootHasPendingPing && - ((expirationTime = root.lastPingedTime), - 0 === expirationTime || expirationTime >= lastExpiredTime) - ) { - root.lastPingedTime = lastExpiredTime; - prepareFreshStack(root, lastExpiredTime); - break; - } - expirationTime = getNextRootExpirationTimeToWorkOn(root); - if (0 !== expirationTime && expirationTime !== lastExpiredTime) break; - if (0 !== exitStatus && exitStatus !== lastExpiredTime) { - root.lastPingedTime = exitStatus; - break; - } - root.timeoutHandle = scheduleTimeout( - commitRoot.bind(null, root), - prevExecutionContext - ); - break; - } - commitRoot(root); - break; - case RootSuspendedWithDelay: - markRootSuspendedAtTime(root, lastExpiredTime); - exitStatus = root.lastSuspendedTime; - lastExpiredTime === exitStatus && - (root.nextKnownPendingLevel = getRemainingExpirationTime( - prevExecutionContext - )); - if ( - workInProgressRootHasPendingPing && - ((prevExecutionContext = root.lastPingedTime), - 0 === prevExecutionContext || prevExecutionContext >= lastExpiredTime) - ) { - root.lastPingedTime = lastExpiredTime; - prepareFreshStack(root, lastExpiredTime); - break; - } - prevExecutionContext = getNextRootExpirationTimeToWorkOn(root); - if ( - 0 !== prevExecutionContext && - prevExecutionContext !== lastExpiredTime - ) - break; - if (0 !== exitStatus && exitStatus !== lastExpiredTime) { - root.lastPingedTime = exitStatus; - break; - } - 1073741823 !== workInProgressRootLatestSuspenseTimeout - ? (prevExecutionContext = - 10 * (1073741821 - workInProgressRootLatestSuspenseTimeout) - - now()) - : 1073741823 === workInProgressRootLatestProcessedExpirationTime - ? (prevExecutionContext = 0) - : ((prevExecutionContext = - 10 * - (1073741821 - workInProgressRootLatestProcessedExpirationTime) - - 5e3), - (exitStatus = now()), - (lastExpiredTime = - 10 * (1073741821 - lastExpiredTime) - exitStatus), - (prevExecutionContext = exitStatus - prevExecutionContext), - 0 > prevExecutionContext && (prevExecutionContext = 0), - (prevExecutionContext = - (120 > prevExecutionContext - ? 120 - : 480 > prevExecutionContext - ? 480 - : 1080 > prevExecutionContext - ? 1080 - : 1920 > prevExecutionContext - ? 1920 - : 3e3 > prevExecutionContext - ? 3e3 - : 4320 > prevExecutionContext - ? 4320 - : 1960 * ceil(prevExecutionContext / 1960)) - - prevExecutionContext), - lastExpiredTime < prevExecutionContext && - (prevExecutionContext = lastExpiredTime)); - if (10 < prevExecutionContext) { - root.timeoutHandle = scheduleTimeout( - commitRoot.bind(null, root), - prevExecutionContext - ); + null + ); + var expirationTime = getNextRootExpirationTimeToWorkOn(root); + if (0 !== expirationTime) { + didTimeout = root.callbackNode; + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) + throw Error("Should not already be working."); + flushPassiveEffects(); + if (root !== workInProgressRoot || expirationTime !== renderExpirationTime) + prepareFreshStack(root, expirationTime), + startWorkOnPendingInteractions(root, expirationTime); + if (null !== workInProgress) { + var prevExecutionContext = executionContext; + executionContext |= RenderContext; + var prevDispatcher = pushDispatcher(root), + prevInteractions = pushInteractions(root); + do + try { + workLoopConcurrent(); break; + } catch (thrownValue) { + handleError(root, thrownValue); } - commitRoot(root); - break; - case RootCompleted: - if ( - 1073741823 !== workInProgressRootLatestProcessedExpirationTime && - null !== workInProgressRootCanSuspendUsingConfig + while (1); + resetContextDependencies(); + executionContext = prevExecutionContext; + ReactCurrentDispatcher.current = prevDispatcher; + tracing.__interactionsRef.current = prevInteractions; + if (workInProgressRootExitStatus === RootFatalErrored) + throw ((didTimeout = workInProgressRootFatalError), + prepareFreshStack(root, expirationTime), + markRootSuspendedAtTime(root, expirationTime), + ensureRootIsScheduled(root), + didTimeout); + if (null === workInProgress) + switch ( + ((prevDispatcher = root.finishedWork = root.current.alternate), + (root.finishedExpirationTime = expirationTime), + (prevExecutionContext = workInProgressRootExitStatus), + (workInProgressRoot = null), + prevExecutionContext) ) { - expirationTime = workInProgressRootLatestProcessedExpirationTime; - var suspenseConfig = workInProgressRootCanSuspendUsingConfig; - prevExecutionContext = suspenseConfig.busyMinDurationMs | 0; - 0 >= prevExecutionContext - ? (prevExecutionContext = 0) - : ((exitStatus = suspenseConfig.busyDelayMs | 0), - (expirationTime = - now() - - (10 * (1073741821 - expirationTime) - - (suspenseConfig.timeoutMs | 0 || 5e3))), - (prevExecutionContext = - expirationTime <= exitStatus - ? 0 - : exitStatus + prevExecutionContext - expirationTime)); - if (10 < prevExecutionContext) { - markRootSuspendedAtTime(root, lastExpiredTime); - root.timeoutHandle = scheduleTimeout( - commitRoot.bind(null, root), - prevExecutionContext + case RootIncomplete: + case RootFatalErrored: + throw Error("Root did not complete. This is a bug in React."); + case RootErrored: + markRootExpiredAtTime( + root, + 2 < expirationTime ? 2 : expirationTime ); break; - } + case RootSuspended: + markRootSuspendedAtTime(root, expirationTime); + prevExecutionContext = root.lastSuspendedTime; + expirationTime === prevExecutionContext && + (root.nextKnownPendingLevel = getRemainingExpirationTime( + prevDispatcher + )); + if ( + 1073741823 === workInProgressRootLatestProcessedExpirationTime && + ((prevDispatcher = + globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now()), + 10 < prevDispatcher) + ) { + if ( + workInProgressRootHasPendingPing && + ((prevInteractions = root.lastPingedTime), + 0 === prevInteractions || prevInteractions >= expirationTime) + ) { + root.lastPingedTime = expirationTime; + prepareFreshStack(root, expirationTime); + break; + } + prevInteractions = getNextRootExpirationTimeToWorkOn(root); + if (0 !== prevInteractions && prevInteractions !== expirationTime) + break; + if ( + 0 !== prevExecutionContext && + prevExecutionContext !== expirationTime + ) { + root.lastPingedTime = prevExecutionContext; + break; + } + root.timeoutHandle = scheduleTimeout( + commitRoot.bind(null, root), + prevDispatcher + ); + break; + } + commitRoot(root); + break; + case RootSuspendedWithDelay: + markRootSuspendedAtTime(root, expirationTime); + prevExecutionContext = root.lastSuspendedTime; + expirationTime === prevExecutionContext && + (root.nextKnownPendingLevel = getRemainingExpirationTime( + prevDispatcher + )); + if ( + workInProgressRootHasPendingPing && + ((prevDispatcher = root.lastPingedTime), + 0 === prevDispatcher || prevDispatcher >= expirationTime) + ) { + root.lastPingedTime = expirationTime; + prepareFreshStack(root, expirationTime); + break; + } + prevDispatcher = getNextRootExpirationTimeToWorkOn(root); + if (0 !== prevDispatcher && prevDispatcher !== expirationTime) + break; + if ( + 0 !== prevExecutionContext && + prevExecutionContext !== expirationTime + ) { + root.lastPingedTime = prevExecutionContext; + break; + } + 1073741823 !== workInProgressRootLatestSuspenseTimeout + ? (prevExecutionContext = + 10 * (1073741821 - workInProgressRootLatestSuspenseTimeout) - + now()) + : 1073741823 === workInProgressRootLatestProcessedExpirationTime + ? (prevExecutionContext = 0) + : ((prevExecutionContext = + 10 * + (1073741821 - + workInProgressRootLatestProcessedExpirationTime) - + 5e3), + (prevDispatcher = now()), + (expirationTime = + 10 * (1073741821 - expirationTime) - prevDispatcher), + (prevExecutionContext = + prevDispatcher - prevExecutionContext), + 0 > prevExecutionContext && (prevExecutionContext = 0), + (prevExecutionContext = + (120 > prevExecutionContext + ? 120 + : 480 > prevExecutionContext + ? 480 + : 1080 > prevExecutionContext + ? 1080 + : 1920 > prevExecutionContext + ? 1920 + : 3e3 > prevExecutionContext + ? 3e3 + : 4320 > prevExecutionContext + ? 4320 + : 1960 * ceil(prevExecutionContext / 1960)) - + prevExecutionContext), + expirationTime < prevExecutionContext && + (prevExecutionContext = expirationTime)); + if (10 < prevExecutionContext) { + root.timeoutHandle = scheduleTimeout( + commitRoot.bind(null, root), + prevExecutionContext + ); + break; + } + commitRoot(root); + break; + case RootCompleted: + if ( + 1073741823 !== workInProgressRootLatestProcessedExpirationTime && + null !== workInProgressRootCanSuspendUsingConfig + ) { + prevInteractions = workInProgressRootLatestProcessedExpirationTime; + var suspenseConfig = workInProgressRootCanSuspendUsingConfig; + prevExecutionContext = suspenseConfig.busyMinDurationMs | 0; + 0 >= prevExecutionContext + ? (prevExecutionContext = 0) + : ((prevDispatcher = suspenseConfig.busyDelayMs | 0), + (prevInteractions = + now() - + (10 * (1073741821 - prevInteractions) - + (suspenseConfig.timeoutMs | 0 || 5e3))), + (prevExecutionContext = + prevInteractions <= prevDispatcher + ? 0 + : prevDispatcher + + prevExecutionContext - + prevInteractions)); + if (10 < prevExecutionContext) { + markRootSuspendedAtTime(root, expirationTime); + root.timeoutHandle = scheduleTimeout( + commitRoot.bind(null, root), + prevExecutionContext + ); + break; + } + } + commitRoot(root); + break; + default: + throw Error("Unknown root exit status."); } - commitRoot(root); - break; - default: - throw Error("Unknown root exit status."); + ensureRootIsScheduled(root); + if (root.callbackNode === didTimeout) + return performConcurrentWorkOnRoot.bind(null, root); + } + } + return null; +} +function performSyncWorkOnRoot(root) { + var lastExpiredTime = root.lastExpiredTime; + lastExpiredTime = 0 !== lastExpiredTime ? lastExpiredTime : 1073741823; + if (root.finishedExpirationTime === lastExpiredTime) commitRoot(root); + else { + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) + throw Error("Should not already be working."); + flushPassiveEffects(); + if (root !== workInProgressRoot || lastExpiredTime !== renderExpirationTime) + prepareFreshStack(root, lastExpiredTime), + startWorkOnPendingInteractions(root, lastExpiredTime); + if (null !== workInProgress) { + var prevExecutionContext = executionContext; + executionContext |= RenderContext; + var prevDispatcher = pushDispatcher(root), + prevInteractions = pushInteractions(root); + do + try { + workLoopSync(); + break; + } catch (thrownValue) { + handleError(root, thrownValue); + } + while (1); + resetContextDependencies(); + executionContext = prevExecutionContext; + ReactCurrentDispatcher.current = prevDispatcher; + tracing.__interactionsRef.current = prevInteractions; + if (workInProgressRootExitStatus === RootFatalErrored) + throw ((prevExecutionContext = workInProgressRootFatalError), + prepareFreshStack(root, lastExpiredTime), + markRootSuspendedAtTime(root, lastExpiredTime), + ensureRootIsScheduled(root), + prevExecutionContext); + if (null !== workInProgress) + throw Error( + "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." + ); + root.finishedWork = root.current.alternate; + root.finishedExpirationTime = lastExpiredTime; + workInProgressRoot = null; + commitRoot(root); + ensureRootIsScheduled(root); } } - ensureRootIsScheduled(root); - return root.callbackNode === didTimeout - ? performConcurrentWorkOnRoot.bind(null, root) - : null; -} -function performSyncWorkOnRoot(root) { - if ((executionContext & (RenderContext | CommitContext)) !== NoContext) - throw Error("Should not already be working."); - flushPassiveEffects(); - var lastExpiredTime = root.lastExpiredTime; - lastExpiredTime = - 0 !== lastExpiredTime - ? root === workInProgressRoot && renderExpirationTime$1 >= lastExpiredTime - ? renderExpirationTime$1 - : lastExpiredTime - : 1073741823; - var exitStatus = renderRootSync(root, lastExpiredTime); - 0 !== root.tag && - exitStatus === RootErrored && - ((lastExpiredTime = 2 < lastExpiredTime ? 2 : lastExpiredTime), - (exitStatus = renderRootSync(root, lastExpiredTime))); - if (exitStatus === RootFatalErrored) - throw ((exitStatus = workInProgressRootFatalError), - prepareFreshStack(root, lastExpiredTime), - markRootSuspendedAtTime(root, lastExpiredTime), - ensureRootIsScheduled(root), - exitStatus); - root.finishedWork = root.current.alternate; - root.finishedExpirationTime = lastExpiredTime; - commitRoot(root); - ensureRootIsScheduled(root); return null; } +function flushPendingDiscreteUpdates() { + if (null !== rootsWithPendingDiscreteUpdates) { + var roots = rootsWithPendingDiscreteUpdates; + rootsWithPendingDiscreteUpdates = null; + roots.forEach(function(expirationTime, root) { + markRootExpiredAtTime(root, expirationTime); + ensureRootIsScheduled(root); + }); + flushSyncCallbackQueue(); + } +} function prepareFreshStack(root, expirationTime) { root.finishedWork = null; root.finishedExpirationTime = 0; @@ -5831,27 +5993,26 @@ function prepareFreshStack(root, expirationTime) { var interruptedWork = timeoutHandle; switch (interruptedWork.tag) { case 1: - interruptedWork = interruptedWork.type.childContextTypes; - null !== interruptedWork && - void 0 !== interruptedWork && - popContext(); + var childContextTypes = interruptedWork.type.childContextTypes; + null !== childContextTypes && + void 0 !== childContextTypes && + popContext(interruptedWork); break; case 3: - popHostContainer(); - pop(didPerformWorkStackCursor); - pop(contextStackCursor); + popHostContainer(interruptedWork); + popTopLevelContextObject(interruptedWork); break; case 5: popHostContext(interruptedWork); break; case 4: - popHostContainer(); + popHostContainer(interruptedWork); break; case 13: - pop(suspenseStackCursor); + pop(suspenseStackCursor, interruptedWork); break; case 19: - pop(suspenseStackCursor); + pop(suspenseStackCursor, interruptedWork); break; case 10: popProvider(interruptedWork); @@ -5859,8 +6020,8 @@ function prepareFreshStack(root, expirationTime) { timeoutHandle = timeoutHandle.return; } workInProgressRoot = root; - workInProgress = createWorkInProgress(root.current, null); - renderExpirationTime$1 = expirationTime; + workInProgress = createWorkInProgress(root.current, null, expirationTime); + renderExpirationTime = expirationTime; workInProgressRootExitStatus = RootIncomplete; workInProgressRootFatalError = null; workInProgressRootLatestSuspenseTimeout = workInProgressRootLatestProcessedExpirationTime = 1073741823; @@ -5873,25 +6034,12 @@ function handleError(root$jscomp$0, thrownValue) { do { try { resetContextDependencies(); - ReactCurrentDispatcher.current = ContextOnlyDispatcher; - if (didScheduleRenderPhaseUpdate) - for ( - var hook = currentlyRenderingFiber$1.memoizedState; - null !== hook; - - ) { - var queue = hook.queue; - null !== queue && (queue.pending = null); - hook = hook.next; - } - renderExpirationTime = 0; - workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; - didScheduleRenderPhaseUpdate = !1; + resetHooks(); if (null === workInProgress || null === workInProgress.return) return ( (workInProgressRootExitStatus = RootFatalErrored), (workInProgressRootFatalError = thrownValue), - (workInProgress = null) + null ); workInProgress.mode & 8 && stopProfilerTimerIfRunningAndRecordDelta(workInProgress, !0); @@ -5900,7 +6048,7 @@ function handleError(root$jscomp$0, thrownValue) { returnFiber = workInProgress.return, sourceFiber = workInProgress, value = thrownValue; - thrownValue = renderExpirationTime$1; + thrownValue = renderExpirationTime; sourceFiber.effectTag |= 2048; sourceFiber.firstEffect = sourceFiber.lastEffect = null; if ( @@ -5908,17 +6056,8 @@ function handleError(root$jscomp$0, thrownValue) { "object" === typeof value && "function" === typeof value.then ) { - var thenable = value; - if (0 === (sourceFiber.mode & 2)) { - var currentSource = sourceFiber.alternate; - currentSource - ? ((sourceFiber.updateQueue = currentSource.updateQueue), - (sourceFiber.memoizedState = currentSource.memoizedState), - (sourceFiber.expirationTime = currentSource.expirationTime)) - : ((sourceFiber.updateQueue = null), - (sourceFiber.memoizedState = null)); - } - var hasInvisibleParentBoundary = + var thenable = value, + hasInvisibleParentBoundary = 0 !== (suspenseStackCursor.current & 1), _workInProgress = returnFiber; do { @@ -5933,10 +6072,10 @@ function handleError(root$jscomp$0, thrownValue) { void 0 === props.fallback ? !1 : !0 !== props.unstable_avoidThisFallback - ? !0 - : hasInvisibleParentBoundary - ? !1 - : !0; + ? !0 + : hasInvisibleParentBoundary + ? !1 + : !0; } } if (JSCompiler_temp) { @@ -6043,8 +6182,8 @@ function handleError(root$jscomp$0, thrownValue) { } while (1); } function pushDispatcher() { - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = ContextOnlyDispatcher; return null === prevDispatcher ? ContextOnlyDispatcher : prevDispatcher; } function pushInteractions(root) { @@ -6066,33 +6205,6 @@ function markUnprocessedUpdateTime(expirationTime) { expirationTime > workInProgressRootNextUnprocessedUpdateTime && (workInProgressRootNextUnprocessedUpdateTime = expirationTime); } -function renderRootSync(root, expirationTime) { - var prevExecutionContext = executionContext; - executionContext |= RenderContext; - var prevDispatcher = pushDispatcher(); - if (root !== workInProgressRoot || expirationTime !== renderExpirationTime$1) - prepareFreshStack(root, expirationTime), - startWorkOnPendingInteractions(root, expirationTime); - expirationTime = pushInteractions(root); - do - try { - workLoopSync(); - break; - } catch (thrownValue) { - handleError(root, thrownValue); - } - while (1); - resetContextDependencies(); - tracing.__interactionsRef.current = expirationTime; - executionContext = prevExecutionContext; - ReactCurrentDispatcher$1.current = prevDispatcher; - if (null !== workInProgress) - throw Error( - "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." - ); - workInProgressRoot = null; - return workInProgressRootExitStatus; -} function workLoopSync() { for (; null !== workInProgress; ) workInProgress = performUnitOfWork(workInProgress); @@ -6102,35 +6214,43 @@ function workLoopConcurrent() { workInProgress = performUnitOfWork(workInProgress); } function performUnitOfWork(unitOfWork) { - var current = unitOfWork.alternate; + var current$$1 = unitOfWork.alternate; 0 !== (unitOfWork.mode & 8) ? ((profilerStartTime = now$1()), 0 > unitOfWork.actualStartTime && (unitOfWork.actualStartTime = now$1()), - (current = beginWork$1(current, unitOfWork, renderExpirationTime$1)), + (current$$1 = beginWork$$1(current$$1, unitOfWork, renderExpirationTime)), stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, !0)) - : (current = beginWork$1(current, unitOfWork, renderExpirationTime$1)); + : (current$$1 = beginWork$$1(current$$1, unitOfWork, renderExpirationTime)); unitOfWork.memoizedProps = unitOfWork.pendingProps; - null === current && (current = completeUnitOfWork(unitOfWork)); + null === current$$1 && (current$$1 = completeUnitOfWork(unitOfWork)); ReactCurrentOwner$2.current = null; - return current; + return current$$1; } function completeUnitOfWork(unitOfWork) { workInProgress = unitOfWork; do { - var current = workInProgress.alternate; + var current$$1 = workInProgress.alternate; unitOfWork = workInProgress.return; if (0 === (workInProgress.effectTag & 2048)) { if (0 === (workInProgress.mode & 8)) - current = completeWork(current, workInProgress, renderExpirationTime$1); + current$$1 = completeWork( + current$$1, + workInProgress, + renderExpirationTime + ); else { var fiber = workInProgress; profilerStartTime = now$1(); 0 > fiber.actualStartTime && (fiber.actualStartTime = now$1()); - current = completeWork(current, workInProgress, renderExpirationTime$1); + current$$1 = completeWork( + current$$1, + workInProgress, + renderExpirationTime + ); stopProfilerTimerIfRunningAndRecordDelta(workInProgress, !1); } fiber = workInProgress; - if (1 === renderExpirationTime$1 || 1 !== fiber.childExpirationTime) { + if (1 === renderExpirationTime || 1 !== fiber.childExpirationTime) { var newChildExpirationTime = 0; if (0 !== (fiber.mode & 8)) { for ( @@ -6168,7 +6288,7 @@ function completeUnitOfWork(unitOfWork) { (actualDuration = actualDuration.sibling); fiber.childExpirationTime = newChildExpirationTime; } - if (null !== current) return current; + if (null !== current$$1) return current$$1; null !== unitOfWork && 0 === (unitOfWork.effectTag & 2048) && (null === unitOfWork.firstEffect && @@ -6183,7 +6303,7 @@ function completeUnitOfWork(unitOfWork) { : (unitOfWork.firstEffect = workInProgress), (unitOfWork.lastEffect = workInProgress))); } else { - current = unwindWork(workInProgress); + current$$1 = unwindWork(workInProgress, renderExpirationTime); if (0 !== (workInProgress.mode & 8)) { stopProfilerTimerIfRunningAndRecordDelta(workInProgress, !1); fiber = workInProgress.actualDuration; @@ -6196,13 +6316,14 @@ function completeUnitOfWork(unitOfWork) { (newChildExpirationTime = newChildExpirationTime.sibling); workInProgress.actualDuration = fiber; } - if (null !== current) return (current.effectTag &= 2047), current; + if (null !== current$$1) + return (current$$1.effectTag &= 2047), current$$1; null !== unitOfWork && ((unitOfWork.firstEffect = unitOfWork.lastEffect = null), (unitOfWork.effectTag |= 2048)); } - current = workInProgress.sibling; - if (null !== current) return current; + current$$1 = workInProgress.sibling; + if (null !== current$$1) return current$$1; workInProgress = unitOfWork; } while (null !== workInProgress); workInProgressRootExitStatus === RootIncomplete && @@ -6216,12 +6337,11 @@ function getRemainingExpirationTime(fiber) { } function commitRoot(root) { var renderPriorityLevel = getCurrentPriorityLevel(); - runWithPriority(99, commitRootImpl.bind(null, root, renderPriorityLevel)); + runWithPriority$1(99, commitRootImpl.bind(null, root, renderPriorityLevel)); return null; } function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { - do flushPassiveEffects(); - while (null !== rootWithPendingPassiveEffects); + flushPassiveEffects(); if ((executionContext & (RenderContext | CommitContext)) !== NoContext) throw Error("Should not already be working."); var finishedWork = root$jscomp$1.finishedWork, @@ -6250,8 +6370,7 @@ function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { expirationTime <= root$jscomp$1.lastExpiredTime && (root$jscomp$1.lastExpiredTime = 0); root$jscomp$1 === workInProgressRoot && - ((workInProgress = workInProgressRoot = null), - (renderExpirationTime$1 = 0)); + ((workInProgress = workInProgressRoot = null), (renderExpirationTime = 0)); 1 < finishedWork.effectTag ? null !== finishedWork.lastEffect ? ((finishedWork.lastEffect.nextEffect = finishedWork), @@ -6285,9 +6404,9 @@ function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { ) { var effectTag = nextEffect.effectTag; if (effectTag & 128) { - var current = nextEffect.alternate; - if (null !== current) { - var currentRef = current.ref; + var current$$1 = nextEffect.alternate; + if (null !== current$$1) { + var currentRef = current$$1.ref; null !== currentRef && ("function" === typeof currentRef ? currentRef(null) @@ -6313,10 +6432,10 @@ function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { commitWork(nextEffect.alternate, nextEffect); break; case 8: - var current$jscomp$0 = nextEffect; + var current$$1$jscomp$0 = nextEffect; a: for ( var finishedRoot = root, - root$jscomp$0 = current$jscomp$0, + root$jscomp$0 = current$$1$jscomp$0, renderPriorityLevel$jscomp$0 = renderPriorityLevel, node = root$jscomp$0; ; @@ -6341,7 +6460,7 @@ function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { node.sibling.return = node.return; node = node.sibling; } - detachFiber(current$jscomp$0); + detachFiber(current$$1$jscomp$0); } nextEffect = nextEffect.nextEffect; } @@ -6355,25 +6474,118 @@ function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { nextEffect = remainingExpirationTimeBeforeCommit; do try { - for (effectTag = root$jscomp$1; null !== nextEffect; ) { + for ( + effectTag = root$jscomp$1, current$$1 = expirationTime; + null !== nextEffect; + + ) { var effectTag$jscomp$0 = nextEffect.effectTag; - effectTag$jscomp$0 & 36 && - commitLifeCycles(effectTag, nextEffect.alternate, nextEffect); + if (effectTag$jscomp$0 & 36) { + renderPriorityLevel = effectTag; + var current$$1$jscomp$1 = nextEffect.alternate; + currentRef = nextEffect; + root = current$$1; + switch (currentRef.tag) { + case 0: + case 11: + case 15: + commitHookEffectList(16, 32, currentRef); + break; + case 1: + var instance = currentRef.stateNode; + if (currentRef.effectTag & 4) + if (null === current$$1$jscomp$1) + instance.componentDidMount(); + else { + var prevProps = + currentRef.elementType === currentRef.type + ? current$$1$jscomp$1.memoizedProps + : resolveDefaultProps( + currentRef.type, + current$$1$jscomp$1.memoizedProps + ); + instance.componentDidUpdate( + prevProps, + current$$1$jscomp$1.memoizedState, + instance.__reactInternalSnapshotBeforeUpdate + ); + } + var updateQueue = currentRef.updateQueue; + null !== updateQueue && + commitUpdateQueue(currentRef, updateQueue, instance, root); + break; + case 3: + var _updateQueue = currentRef.updateQueue; + if (null !== _updateQueue) { + renderPriorityLevel = null; + if (null !== currentRef.child) + switch (currentRef.child.tag) { + case 5: + renderPriorityLevel = + currentRef.child.stateNode.canonical; + break; + case 1: + renderPriorityLevel = currentRef.child.stateNode; + } + commitUpdateQueue( + currentRef, + _updateQueue, + renderPriorityLevel, + root + ); + } + break; + case 5: + if (null === current$$1$jscomp$1 && currentRef.effectTag & 4) + throw Error( + "The current renderer does not support mutation. This error is likely caused by a bug in React. Please file an issue." + ); + break; + case 6: + break; + case 4: + break; + case 12: + var onRender = currentRef.memoizedProps.onRender; + "function" === typeof onRender && + onRender( + currentRef.memoizedProps.id, + null === current$$1$jscomp$1 ? "mount" : "update", + currentRef.actualDuration, + currentRef.treeBaseDuration, + currentRef.actualStartTime, + commitTime, + renderPriorityLevel.memoizedInteractions + ); + break; + case 13: + break; + case 19: + case 17: + case 20: + case 21: + 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 (effectTag$jscomp$0 & 128) { - current = void 0; + currentRef = void 0; var ref = nextEffect.ref; if (null !== ref) { - var instance = nextEffect.stateNode; + var instance$jscomp$0 = nextEffect.stateNode; switch (nextEffect.tag) { case 5: - current = instance.canonical; + currentRef = instance$jscomp$0.canonical; break; default: - current = instance; + currentRef = instance$jscomp$0; } "function" === typeof ref - ? ref(current) - : (ref.current = current); + ? ref(currentRef) + : (ref.current = currentRef); } } nextEffect = nextEffect.nextEffect; @@ -6409,13 +6621,13 @@ function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { for ( remainingExpirationTimeBeforeCommit = spawnedWorkDuringRender, spawnedWorkDuringRender = null, - ref = 0; - ref < remainingExpirationTimeBeforeCommit.length; - ref++ + current$$1$jscomp$1 = 0; + current$$1$jscomp$1 < remainingExpirationTimeBeforeCommit.length; + current$$1$jscomp$1++ ) scheduleInteractions( root$jscomp$1, - remainingExpirationTimeBeforeCommit[ref], + remainingExpirationTimeBeforeCommit[current$$1$jscomp$1], root$jscomp$1.memoizedInteractions ); schedulePendingInteractions(root$jscomp$1, renderPriorityLevel$jscomp$1); @@ -6461,7 +6673,7 @@ function flushPassiveEffects() { ? 97 : pendingPassiveEffectsRenderPriority; pendingPassiveEffectsRenderPriority = 90; - return runWithPriority(priorityLevel, flushPassiveEffectsImpl); + return runWithPriority$1(priorityLevel, flushPassiveEffectsImpl); } } function flushPassiveEffectsImpl() { @@ -6476,28 +6688,27 @@ function flushPassiveEffectsImpl() { executionContext |= CommitContext; for ( var prevInteractions = pushInteractions(root), - _effect2 = root.current.firstEffect; - null !== _effect2; + effect = root.current.firstEffect; + null !== effect; ) { try { - var finishedWork = _effect2; + var finishedWork = effect; if (0 !== (finishedWork.effectTag & 512)) switch (finishedWork.tag) { case 0: case 11: case 15: - case 22: - commitHookEffectListUnmount(5, finishedWork), - commitHookEffectListMount(5, finishedWork); + commitHookEffectList(128, 0, finishedWork), + commitHookEffectList(0, 64, finishedWork); } } catch (error) { - if (null === _effect2) throw Error("Should be working on an effect."); - captureCommitPhaseError(_effect2, error); + if (null === effect) throw Error("Should be working on an effect."); + captureCommitPhaseError(effect, error); } - finishedWork = _effect2.nextEffect; - _effect2.nextEffect = null; - _effect2 = finishedWork; + finishedWork = effect.nextEffect; + effect.nextEffect = null; + effect = finishedWork; } tracing.__interactionsRef.current = prevInteractions; finishPendingInteractions(root, expirationTime); @@ -6546,17 +6757,19 @@ function captureCommitPhaseError(sourceFiber, error) { function pingSuspendedRoot(root, thenable, suspendedTime) { var pingCache = root.pingCache; null !== pingCache && pingCache.delete(thenable); - workInProgressRoot === root && renderExpirationTime$1 === suspendedTime + workInProgressRoot === root && renderExpirationTime === suspendedTime ? workInProgressRootExitStatus === RootSuspendedWithDelay || (workInProgressRootExitStatus === RootSuspended && 1073741823 === workInProgressRootLatestProcessedExpirationTime && now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) - ? prepareFreshStack(root, renderExpirationTime$1) + ? prepareFreshStack(root, renderExpirationTime) : (workInProgressRootHasPendingPing = !0) : isRootSuspendedAtTime(root, suspendedTime) && ((thenable = root.lastPingedTime), (0 !== thenable && thenable < suspendedTime) || ((root.lastPingedTime = suspendedTime), + root.finishedExpirationTime === suspendedTime && + ((root.finishedExpirationTime = 0), (root.finishedWork = null)), ensureRootIsScheduled(root), schedulePendingInteractions(root, suspendedTime))); } @@ -6572,12 +6785,12 @@ function resolveRetryThenable(boundaryFiber, thenable) { (ensureRootIsScheduled(boundaryFiber), schedulePendingInteractions(boundaryFiber, thenable)); } -var beginWork$1; -beginWork$1 = function(current, workInProgress, renderExpirationTime) { +var beginWork$$1; +beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { var updateExpirationTime = workInProgress.expirationTime; - if (null !== current) + if (null !== current$$1) if ( - current.memoizedProps !== workInProgress.pendingProps || + current$$1.memoizedProps !== workInProgress.pendingProps || didPerformWorkStackCursor.current ) didReceiveUpdate = !0; @@ -6602,17 +6815,11 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { ); break; case 10: - updateExpirationTime = workInProgress.memoizedProps.value; - var context = workInProgress.type._context; - push(valueCursor, context._currentValue2); - context._currentValue2 = updateExpirationTime; + pushProvider(workInProgress, workInProgress.memoizedProps.value); break; case 12: workInProgress.childExpirationTime >= renderExpirationTime && (workInProgress.effectTag |= 4); - updateExpirationTime = workInProgress.stateNode; - updateExpirationTime.effectDuration = 0; - updateExpirationTime.passiveEffectDuration = 0; break; case 13: if (null !== workInProgress.memoizedState) { @@ -6622,40 +6829,52 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { updateExpirationTime >= renderExpirationTime ) return updateSuspenseComponent( - current, + current$$1, workInProgress, renderExpirationTime ); - push(suspenseStackCursor, suspenseStackCursor.current & 1); + push( + suspenseStackCursor, + suspenseStackCursor.current & 1, + workInProgress + ); workInProgress = bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ); return null !== workInProgress ? workInProgress.sibling : null; } - push(suspenseStackCursor, suspenseStackCursor.current & 1); + push( + suspenseStackCursor, + suspenseStackCursor.current & 1, + workInProgress + ); break; case 19: updateExpirationTime = workInProgress.childExpirationTime >= renderExpirationTime; - if (0 !== (current.effectTag & 64)) { + if (0 !== (current$$1.effectTag & 64)) { if (updateExpirationTime) return updateSuspenseListComponent( - current, + current$$1, workInProgress, renderExpirationTime ); workInProgress.effectTag |= 64; } - context = workInProgress.memoizedState; - null !== context && - ((context.rendering = null), (context.tail = null)); - push(suspenseStackCursor, suspenseStackCursor.current); + var renderState = workInProgress.memoizedState; + null !== renderState && + ((renderState.rendering = null), (renderState.tail = null)); + push( + suspenseStackCursor, + suspenseStackCursor.current, + workInProgress + ); if (!updateExpirationTime) return null; } return bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -6667,40 +6886,41 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { switch (workInProgress.tag) { case 2: updateExpirationTime = workInProgress.type; - null !== current && - ((current.alternate = null), + null !== current$$1 && + ((current$$1.alternate = null), (workInProgress.alternate = null), (workInProgress.effectTag |= 2)); - current = workInProgress.pendingProps; - context = getMaskedContext(workInProgress, contextStackCursor.current); + current$$1 = workInProgress.pendingProps; + renderState = getMaskedContext( + workInProgress, + contextStackCursor.current + ); prepareToReadContext(workInProgress, renderExpirationTime); - context = renderWithHooks( + renderState = renderWithHooks( null, workInProgress, updateExpirationTime, - current, - context, + current$$1, + renderState, renderExpirationTime ); workInProgress.effectTag |= 1; if ( - "object" === typeof context && - null !== context && - "function" === typeof context.render && - void 0 === context.$$typeof + "object" === typeof renderState && + null !== renderState && + "function" === typeof renderState.render && + void 0 === renderState.$$typeof ) { workInProgress.tag = 1; - workInProgress.memoizedState = null; - workInProgress.updateQueue = null; + resetHooks(); if (isContextProvider(updateExpirationTime)) { var hasContext = !0; pushContextProvider(workInProgress); } else hasContext = !1; workInProgress.memoizedState = - null !== context.state && void 0 !== context.state - ? context.state + null !== renderState.state && void 0 !== renderState.state + ? renderState.state : null; - initializeUpdateQueue(workInProgress); var getDerivedStateFromProps = updateExpirationTime.getDerivedStateFromProps; "function" === typeof getDerivedStateFromProps && @@ -6708,15 +6928,15 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { workInProgress, updateExpirationTime, getDerivedStateFromProps, - current + current$$1 ); - context.updater = classComponentUpdater; - workInProgress.stateNode = context; - context._reactInternalFiber = workInProgress; + renderState.updater = classComponentUpdater; + workInProgress.stateNode = renderState; + renderState._reactInternalFiber = workInProgress; mountClassInstance( workInProgress, updateExpirationTime, - current, + current$$1, renderExpirationTime ); workInProgress = finishClassComponent( @@ -6732,129 +6952,127 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { reconcileChildren( null, workInProgress, - context, + renderState, renderExpirationTime ), (workInProgress = workInProgress.child); return workInProgress; case 16: - a: { - context = workInProgress.elementType; - null !== current && - ((current.alternate = null), - (workInProgress.alternate = null), - (workInProgress.effectTag |= 2)); - current = workInProgress.pendingProps; - initializeLazyComponentType(context); - if (1 !== context._status) throw context._result; - context = context._result; - workInProgress.type = context; - hasContext = workInProgress.tag = resolveLazyComponentTag(context); - current = resolveDefaultProps(context, current); - switch (hasContext) { - case 0: - workInProgress = updateFunctionComponent( - null, - workInProgress, - context, - current, - renderExpirationTime - ); - break a; - case 1: - workInProgress = updateClassComponent( - null, - workInProgress, - context, - current, - renderExpirationTime - ); - break a; - case 11: - workInProgress = updateForwardRef( - null, - workInProgress, - context, - current, - renderExpirationTime - ); - break a; - case 14: - workInProgress = updateMemoComponent( - null, - workInProgress, - context, - resolveDefaultProps(context.type, current), - updateExpirationTime, - renderExpirationTime - ); - break a; - } - throw Error( - "Element type is invalid. Received a promise that resolves to: " + - context + - ". Lazy element type must resolve to a class or function." - ); + renderState = workInProgress.elementType; + null !== current$$1 && + ((current$$1.alternate = null), + (workInProgress.alternate = null), + (workInProgress.effectTag |= 2)); + current$$1 = workInProgress.pendingProps; + initializeLazyComponentType(renderState); + if (1 !== renderState._status) throw renderState._result; + renderState = renderState._result; + workInProgress.type = renderState; + hasContext = workInProgress.tag = resolveLazyComponentTag(renderState); + current$$1 = resolveDefaultProps(renderState, current$$1); + switch (hasContext) { + case 0: + workInProgress = updateFunctionComponent( + null, + workInProgress, + renderState, + current$$1, + renderExpirationTime + ); + break; + case 1: + workInProgress = updateClassComponent( + null, + workInProgress, + renderState, + current$$1, + renderExpirationTime + ); + break; + case 11: + workInProgress = updateForwardRef( + null, + workInProgress, + renderState, + current$$1, + renderExpirationTime + ); + break; + case 14: + workInProgress = updateMemoComponent( + null, + workInProgress, + renderState, + resolveDefaultProps(renderState.type, current$$1), + updateExpirationTime, + renderExpirationTime + ); + break; + default: + throw Error( + "Element type is invalid. Received a promise that resolves to: " + + renderState + + ". Lazy element type must resolve to a class or function." + ); } return workInProgress; case 0: return ( (updateExpirationTime = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (renderState = workInProgress.pendingProps), + (renderState = workInProgress.elementType === updateExpirationTime - ? context - : resolveDefaultProps(updateExpirationTime, context)), + ? renderState + : resolveDefaultProps(updateExpirationTime, renderState)), updateFunctionComponent( - current, + current$$1, workInProgress, updateExpirationTime, - context, + renderState, renderExpirationTime ) ); case 1: return ( (updateExpirationTime = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (renderState = workInProgress.pendingProps), + (renderState = workInProgress.elementType === updateExpirationTime - ? context - : resolveDefaultProps(updateExpirationTime, context)), + ? renderState + : resolveDefaultProps(updateExpirationTime, renderState)), updateClassComponent( - current, + current$$1, workInProgress, updateExpirationTime, - context, + renderState, renderExpirationTime ) ); case 3: pushHostRootContext(workInProgress); updateExpirationTime = workInProgress.updateQueue; - if (null === current || null === updateExpirationTime) + if (null === updateExpirationTime) 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." ); - updateExpirationTime = workInProgress.pendingProps; - context = workInProgress.memoizedState; - context = null !== context ? context.element : null; - cloneUpdateQueue(current, workInProgress); + renderState = workInProgress.memoizedState; + renderState = null !== renderState ? renderState.element : null; processUpdateQueue( workInProgress, updateExpirationTime, + workInProgress.pendingProps, null, renderExpirationTime ); updateExpirationTime = workInProgress.memoizedState.element; - updateExpirationTime === context + updateExpirationTime === renderState ? (workInProgress = bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime )) : (reconcileChildren( - current, + current$$1, workInProgress, updateExpirationTime, renderExpirationTime @@ -6864,10 +7082,11 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { case 5: return ( pushHostContext(workInProgress), + null === current$$1 && tryToClaimNextHydratableInstance(workInProgress), (updateExpirationTime = workInProgress.pendingProps.children), - markRef(current, workInProgress), + markRef(current$$1, workInProgress), reconcileChildren( - current, + current$$1, workInProgress, updateExpirationTime, renderExpirationTime @@ -6876,10 +7095,13 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { workInProgress ); case 6: - return null; + return ( + null === current$$1 && tryToClaimNextHydratableInstance(workInProgress), + null + ); case 13: return updateSuspenseComponent( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -6890,7 +7112,7 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { workInProgress.stateNode.containerInfo ), (updateExpirationTime = workInProgress.pendingProps), - null === current + null === current$$1 ? (workInProgress.child = reconcileChildFibers( workInProgress, null, @@ -6898,7 +7120,7 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { renderExpirationTime )) : reconcileChildren( - current, + current$$1, workInProgress, updateExpirationTime, renderExpirationTime @@ -6908,23 +7130,23 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { case 11: return ( (updateExpirationTime = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (renderState = workInProgress.pendingProps), + (renderState = workInProgress.elementType === updateExpirationTime - ? context - : resolveDefaultProps(updateExpirationTime, context)), + ? renderState + : resolveDefaultProps(updateExpirationTime, renderState)), updateForwardRef( - current, + current$$1, workInProgress, updateExpirationTime, - context, + renderState, renderExpirationTime ) ); case 7: return ( reconcileChildren( - current, + current$$1, workInProgress, workInProgress.pendingProps, renderExpirationTime @@ -6934,7 +7156,7 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { case 8: return ( reconcileChildren( - current, + current$$1, workInProgress, workInProgress.pendingProps.children, renderExpirationTime @@ -6944,11 +7166,8 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { case 12: return ( (workInProgress.effectTag |= 4), - (updateExpirationTime = workInProgress.stateNode), - (updateExpirationTime.effectDuration = 0), - (updateExpirationTime.passiveEffectDuration = 0), reconcileChildren( - current, + current$$1, workInProgress, workInProgress.pendingProps.children, renderExpirationTime @@ -6958,32 +7177,27 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { case 10: a: { updateExpirationTime = workInProgress.type._context; - context = workInProgress.pendingProps; + renderState = 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 updateExpirationTime._calculateChangedBits - ? updateExpirationTime._calculateChangedBits( - context$jscomp$0, - hasContext - ) - : 1073741823) | 0), - 0 === hasContext) - ) { + hasContext = renderState.value; + pushProvider(workInProgress, hasContext); + if (null !== getDerivedStateFromProps) { + var oldValue = getDerivedStateFromProps.value; + hasContext = is$1(oldValue, hasContext) + ? 0 + : ("function" === typeof updateExpirationTime._calculateChangedBits + ? updateExpirationTime._calculateChangedBits( + oldValue, + hasContext + ) + : 1073741823) | 0; + if (0 === hasContext) { if ( - getDerivedStateFromProps.children === context.children && + getDerivedStateFromProps.children === renderState.children && !didPerformWorkStackCursor.current ) { workInProgress = bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -6991,15 +7205,14 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { } } 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; @@ -7009,18 +7222,18 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { dependency.context === updateExpirationTime && 0 !== (dependency.observedBits & hasContext) ) { - 1 === context$jscomp$0.tag && + 1 === oldValue.tag && ((dependency = createUpdate(renderExpirationTime, null)), (dependency.tag = 2), - enqueueUpdate(context$jscomp$0, dependency)); - context$jscomp$0.expirationTime < renderExpirationTime && - (context$jscomp$0.expirationTime = renderExpirationTime); - dependency = context$jscomp$0.alternate; + enqueueUpdate(oldValue, dependency)); + oldValue.expirationTime < renderExpirationTime && + (oldValue.expirationTime = renderExpirationTime); + dependency = oldValue.alternate; null !== dependency && dependency.expirationTime < renderExpirationTime && (dependency.expirationTime = renderExpirationTime); scheduleWorkOnParentPath( - context$jscomp$0.return, + oldValue.return, renderExpirationTime ); list.expirationTime < renderExpirationTime && @@ -7031,16 +7244,16 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { } } 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; ) { @@ -7048,20 +7261,21 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { 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, + current$$1, workInProgress, - context.children, + renderState.children, renderExpirationTime ); workInProgress = workInProgress.child; @@ -7069,15 +7283,18 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { return workInProgress; case 9: return ( - (context = workInProgress.type), + (renderState = workInProgress.type), (hasContext = workInProgress.pendingProps), (updateExpirationTime = hasContext.children), prepareToReadContext(workInProgress, renderExpirationTime), - (context = readContext(context, hasContext.unstable_observedBits)), - (updateExpirationTime = updateExpirationTime(context)), + (renderState = readContext( + renderState, + hasContext.unstable_observedBits + )), + (updateExpirationTime = updateExpirationTime(renderState)), (workInProgress.effectTag |= 1), reconcileChildren( - current, + current$$1, workInProgress, updateExpirationTime, renderExpirationTime @@ -7086,16 +7303,16 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { ); case 14: return ( - (context = workInProgress.type), + (renderState = workInProgress.type), (hasContext = resolveDefaultProps( - context, + renderState, workInProgress.pendingProps )), - (hasContext = resolveDefaultProps(context.type, hasContext)), + (hasContext = resolveDefaultProps(renderState.type, hasContext)), updateMemoComponent( - current, + current$$1, workInProgress, - context, + renderState, hasContext, updateExpirationTime, renderExpirationTime @@ -7103,7 +7320,7 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { ); case 15: return updateSimpleMemoComponent( - current, + current$$1, workInProgress, workInProgress.type, workInProgress.pendingProps, @@ -7113,25 +7330,30 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { case 17: return ( (updateExpirationTime = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (renderState = workInProgress.pendingProps), + (renderState = workInProgress.elementType === updateExpirationTime - ? context - : resolveDefaultProps(updateExpirationTime, context)), - null !== current && - ((current.alternate = null), + ? renderState + : resolveDefaultProps(updateExpirationTime, renderState)), + null !== current$$1 && + ((current$$1.alternate = null), (workInProgress.alternate = null), (workInProgress.effectTag |= 2)), (workInProgress.tag = 1), isContextProvider(updateExpirationTime) - ? ((current = !0), pushContextProvider(workInProgress)) - : (current = !1), + ? ((current$$1 = !0), pushContextProvider(workInProgress)) + : (current$$1 = !1), prepareToReadContext(workInProgress, renderExpirationTime), - constructClassInstance(workInProgress, updateExpirationTime, context), + constructClassInstance( + workInProgress, + updateExpirationTime, + renderState, + renderExpirationTime + ), mountClassInstance( workInProgress, updateExpirationTime, - context, + renderState, renderExpirationTime ), finishClassComponent( @@ -7139,13 +7361,13 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { workInProgress, updateExpirationTime, !0, - current, + current$$1, renderExpirationTime ) ); case 19: return updateSuspenseListComponent( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -7286,6 +7508,9 @@ function FiberNode(tag, pendingProps, key, mode) { this.actualStartTime = -1; this.treeBaseDuration = this.selfBaseDuration = 0; } +function createFiber(tag, pendingProps, key, mode) { + return new FiberNode(tag, pendingProps, key, mode); +} function shouldConstruct(Component) { Component = Component.prototype; return !(!Component || !Component.isReactComponent); @@ -7303,7 +7528,7 @@ function resolveLazyComponentTag(Component) { function createWorkInProgress(current, pendingProps) { var workInProgress = current.alternate; null === workInProgress - ? ((workInProgress = new FiberNode( + ? ((workInProgress = createFiber( current.tag, pendingProps, current.key, @@ -7374,16 +7599,15 @@ function createFiberFromTypeAndProps( break; case REACT_PROFILER_TYPE: return ( - (type = new FiberNode(12, pendingProps, key, mode | 8)), + (type = createFiber(12, pendingProps, key, mode | 8)), (type.elementType = REACT_PROFILER_TYPE), (type.type = REACT_PROFILER_TYPE), (type.expirationTime = expirationTime), - (type.stateNode = { effectDuration: 0, passiveEffectDuration: 0 }), type ); case REACT_SUSPENSE_TYPE: return ( - (type = new FiberNode(13, pendingProps, key, mode)), + (type = createFiber(13, pendingProps, key, mode)), (type.type = REACT_SUSPENSE_TYPE), (type.elementType = REACT_SUSPENSE_TYPE), (type.expirationTime = expirationTime), @@ -7391,7 +7615,7 @@ function createFiberFromTypeAndProps( ); case REACT_SUSPENSE_LIST_TYPE: return ( - (type = new FiberNode(19, pendingProps, key, mode)), + (type = createFiber(19, pendingProps, key, mode)), (type.elementType = REACT_SUSPENSE_LIST_TYPE), (type.expirationTime = expirationTime), type @@ -7415,9 +7639,6 @@ function createFiberFromTypeAndProps( fiberTag = 16; owner = null; break a; - case REACT_BLOCK_TYPE: - fiberTag = 22; - break a; } throw Error( "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + @@ -7425,24 +7646,24 @@ function createFiberFromTypeAndProps( "." ); } - key = new FiberNode(fiberTag, pendingProps, key, mode); + key = createFiber(fiberTag, pendingProps, key, mode); key.elementType = type; key.type = owner; key.expirationTime = expirationTime; return key; } function createFiberFromFragment(elements, mode, expirationTime, key) { - elements = new FiberNode(7, elements, key, mode); + elements = createFiber(7, elements, key, mode); elements.expirationTime = expirationTime; return elements; } function createFiberFromText(content, mode, expirationTime) { - content = new FiberNode(6, content, null, mode); + content = createFiber(6, content, null, mode); content.expirationTime = expirationTime; return content; } function createFiberFromPortal(portal, mode, expirationTime) { - mode = new FiberNode( + mode = createFiber( 4, null !== portal.children ? portal.children : [], portal.key, @@ -7504,6 +7725,11 @@ function markRootUpdatedAtTime(root, expirationTime) { expirationTime > root.nextKnownPendingLevel && (root.nextKnownPendingLevel = expirationTime)); } +function markRootExpiredAtTime(root, expirationTime) { + var lastExpiredTime = root.lastExpiredTime; + if (0 === lastExpiredTime || lastExpiredTime > expirationTime) + root.lastExpiredTime = expirationTime; +} function findHostInstance(component) { var fiber = component._reactInternalFiber; if (void 0 === fiber) { @@ -7518,10 +7744,14 @@ function findHostInstance(component) { return null === component ? null : component.stateNode; } function updateContainer(element, container, parentComponent, callback) { - var current = container.current, + var current$$1 = container.current, currentTime = requestCurrentTimeForUpdate(), suspenseConfig = ReactCurrentBatchConfig.suspense; - currentTime = computeExpirationForFiber(currentTime, current, suspenseConfig); + currentTime = computeExpirationForFiber( + currentTime, + current$$1, + suspenseConfig + ); a: if (parentComponent) { parentComponent = parentComponent._reactInternalFiber; b: { @@ -7572,8 +7802,8 @@ function updateContainer(element, container, parentComponent, callback) { container.payload = { element: element }; callback = void 0 === callback ? null : callback; null !== callback && (container.callback = callback); - enqueueUpdate(current, container); - scheduleWork(current, currentTime); + enqueueUpdate(current$$1, container); + scheduleUpdateOnFiber(current$$1, currentTime); return currentTime; } function createPortal(children, containerInfo, implementation) { @@ -7587,6 +7817,7 @@ function createPortal(children, containerInfo, implementation) { implementation: implementation }; } +var fabricDispatchCommand = nativeFabricUIManager.dispatchCommand; function findNodeHandle(componentOrHandle) { if (null == componentOrHandle) return null; if ("number" === typeof componentOrHandle) return componentOrHandle; @@ -7597,8 +7828,8 @@ function findNodeHandle(componentOrHandle) { return null == componentOrHandle ? componentOrHandle : componentOrHandle.canonical - ? componentOrHandle.canonical._nativeTag - : componentOrHandle._nativeTag; + ? componentOrHandle.canonical._nativeTag + : componentOrHandle._nativeTag; } batchedUpdatesImpl = function(fn, a) { var prevExecutionContext = executionContext; @@ -7610,116 +7841,291 @@ batchedUpdatesImpl = function(fn, a) { executionContext === NoContext && flushSyncCallbackQueue(); } }; -var roots = new Map(); -(function(devToolsConfig) { - var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance; - return injectInternals({ - bundleType: devToolsConfig.bundleType, - version: devToolsConfig.version, - rendererPackageName: devToolsConfig.rendererPackageName, - rendererConfig: devToolsConfig.rendererConfig, - overrideHookState: null, - overrideProps: null, - setSuspenseHandler: null, - scheduleUpdate: null, - currentDispatcherRef: ReactSharedInternals.ReactCurrentDispatcher, - findHostInstanceByFiber: function(fiber) { - fiber = findCurrentHostFiber(fiber); - return null === fiber ? null : fiber.stateNode; +flushDiscreteUpdatesImpl = function() { + (executionContext & (1 | RenderContext | CommitContext)) === NoContext && + (flushPendingDiscreteUpdates(), flushPassiveEffects()); +}; +var roots = new Map(), + ReactFabric = { + NativeComponent: (function(findNodeHandle, findHostInstance) { + return (function(_React$Component) { + function ReactNativeComponent() { + return _React$Component.apply(this, arguments) || this; + } + _inheritsLoose(ReactNativeComponent, _React$Component); + var _proto = ReactNativeComponent.prototype; + _proto.blur = function() { + ReactNativePrivateInterface.TextInputState.blurTextInput( + findNodeHandle(this) + ); + }; + _proto.focus = function() { + ReactNativePrivateInterface.TextInputState.focusTextInput( + findNodeHandle(this) + ); + }; + _proto.measure = function(callback) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + null != maybeInstance && + (maybeInstance.canonical + ? nativeFabricUIManager.measure( + maybeInstance.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ) + : ReactNativePrivateInterface.UIManager.measure( + findNodeHandle(this), + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + )); + }; + _proto.measureInWindow = function(callback) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + null != maybeInstance && + (maybeInstance.canonical + ? nativeFabricUIManager.measureInWindow( + maybeInstance.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ) + : ReactNativePrivateInterface.UIManager.measureInWindow( + findNodeHandle(this), + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + )); + }; + _proto.measureLayout = function( + relativeToNativeNode, + onSuccess, + onFail + ) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + if (null != maybeInstance && !maybeInstance.canonical) { + if ("number" === typeof relativeToNativeNode) + var relativeNode = relativeToNativeNode; + else + relativeToNativeNode._nativeTag && + (relativeNode = relativeToNativeNode._nativeTag); + null != relativeNode && + ReactNativePrivateInterface.UIManager.measureLayout( + findNodeHandle(this), + relativeNode, + mountSafeCallback_NOT_REALLY_SAFE(this, onFail), + mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) + ); + } + }; + _proto.setNativeProps = function(nativeProps) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + if (null != maybeInstance && !maybeInstance.canonical) { + var nativeTag = + maybeInstance._nativeTag || maybeInstance.canonical._nativeTag; + maybeInstance = + maybeInstance.viewConfig || maybeInstance.canonical.viewConfig; + nativeProps = diffProperties( + null, + emptyObject, + nativeProps, + maybeInstance.validAttributes + ); + null != nativeProps && + ReactNativePrivateInterface.UIManager.updateView( + nativeTag, + maybeInstance.uiViewClassName, + nativeProps + ); + } + }; + return ReactNativeComponent; + })(React.Component); + })(findNodeHandle, findHostInstance), + findHostInstance_DEPRECATED: function(componentOrHandle) { + if (null == componentOrHandle) return null; + if (componentOrHandle._nativeTag) return componentOrHandle; + if (componentOrHandle.canonical && componentOrHandle.canonical._nativeTag) + return componentOrHandle.canonical; + componentOrHandle = findHostInstance(componentOrHandle); + return null == componentOrHandle + ? componentOrHandle + : componentOrHandle.canonical + ? componentOrHandle.canonical + : componentOrHandle; }, - findFiberByHostInstance: function(instance) { - return findFiberByHostInstance ? findFiberByHostInstance(instance) : null; + findNodeHandle: findNodeHandle, + dispatchCommand: function(handle, command, args) { + null != handle._nativeTag && + null != handle._internalInstanceHandle && + fabricDispatchCommand( + handle._internalInstanceHandle.stateNode.node, + command, + args + ); }, - findHostInstancesForRefresh: null, - scheduleRefresh: null, - scheduleRoot: null, - setRefreshHandler: null, - getCurrentFiber: null - }); + render: function(element, containerTag, callback) { + var root = roots.get(containerTag); + if (!root) { + root = new FiberRootNode(containerTag, 0, !1); + var uninitializedFiber = 0; + isDevToolsPresent && (uninitializedFiber |= 8); + uninitializedFiber = createFiber(3, null, null, uninitializedFiber); + root.current = uninitializedFiber; + uninitializedFiber.stateNode = root; + roots.set(containerTag, root); + } + updateContainer(element, root, null, callback); + a: if (((element = root.current), element.child)) + switch (element.child.tag) { + case 5: + element = element.child.stateNode.canonical; + break a; + default: + element = element.child.stateNode; + } + else element = null; + return element; + }, + unmountComponentAtNode: function(containerTag) { + var root = roots.get(containerTag); + root && + updateContainer(null, root, null, function() { + roots.delete(containerTag); + }); + }, + createPortal: function(children, containerTag) { + return createPortal( + children, + containerTag, + null, + 2 < arguments.length && void 0 !== arguments[2] ? arguments[2] : null + ); + }, + __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: { + NativeMethodsMixin: (function(findNodeHandle, findHostInstance) { + return { + measure: function(callback) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + null != maybeInstance && + (maybeInstance.canonical + ? nativeFabricUIManager.measure( + maybeInstance.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ) + : ReactNativePrivateInterface.UIManager.measure( + findNodeHandle(this), + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + )); + }, + measureInWindow: function(callback) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + null != maybeInstance && + (maybeInstance.canonical + ? nativeFabricUIManager.measureInWindow( + maybeInstance.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ) + : ReactNativePrivateInterface.UIManager.measureInWindow( + findNodeHandle(this), + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + )); + }, + measureLayout: function(relativeToNativeNode, onSuccess, onFail) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + if (null != maybeInstance && !maybeInstance.canonical) { + if ("number" === typeof relativeToNativeNode) + var relativeNode = relativeToNativeNode; + else + relativeToNativeNode._nativeTag && + (relativeNode = relativeToNativeNode._nativeTag); + null != relativeNode && + ReactNativePrivateInterface.UIManager.measureLayout( + findNodeHandle(this), + relativeNode, + mountSafeCallback_NOT_REALLY_SAFE(this, onFail), + mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) + ); + } + }, + setNativeProps: function(nativeProps) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + if (null != maybeInstance && !maybeInstance.canonical) { + var nativeTag = + maybeInstance._nativeTag || maybeInstance.canonical._nativeTag; + maybeInstance = + maybeInstance.viewConfig || maybeInstance.canonical.viewConfig; + nativeProps = diffProperties( + null, + emptyObject, + nativeProps, + maybeInstance.validAttributes + ); + null != nativeProps && + ReactNativePrivateInterface.UIManager.updateView( + nativeTag, + maybeInstance.uiViewClassName, + nativeProps + ); + } + }, + focus: function() { + ReactNativePrivateInterface.TextInputState.focusTextInput( + findNodeHandle(this) + ); + }, + blur: function() { + ReactNativePrivateInterface.TextInputState.blurTextInput( + findNodeHandle(this) + ); + } + }; + })(findNodeHandle, findHostInstance) + } + }; +(function(devToolsConfig) { + var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance; + return injectInternals( + Object.assign({}, devToolsConfig, { + overrideHookState: null, + overrideProps: null, + setSuspenseHandler: null, + scheduleUpdate: null, + currentDispatcherRef: ReactSharedInternals.ReactCurrentDispatcher, + findHostInstanceByFiber: function(fiber) { + fiber = findCurrentHostFiber(fiber); + return null === fiber ? null : fiber.stateNode; + }, + findFiberByHostInstance: function(instance) { + return findFiberByHostInstance + ? findFiberByHostInstance(instance) + : null; + }, + findHostInstancesForRefresh: null, + scheduleRefresh: null, + scheduleRoot: null, + setRefreshHandler: null, + getCurrentFiber: null + }) + ); })({ findFiberByHostInstance: getInstanceFromInstance, + getInspectorDataForViewTag: function() { + throw Error("getInspectorDataForViewTag() is not available in production"); + }, bundleType: 0, - version: "16.13.0", - rendererPackageName: "react-native-renderer", - rendererConfig: { - getInspectorDataForViewTag: function() { - throw Error( - "getInspectorDataForViewTag() is not available in production" - ); - }, - getInspectorDataForViewAtPoint: function() { - throw Error( - "getInspectorDataForViewAtPoint() is not available in production." - ); - }.bind(null, findNodeHandle) - } + version: "16.11.0", + rendererPackageName: "react-native-renderer" }); -exports.createPortal = function(children, containerTag) { - return createPortal( - children, - containerTag, - null, - 2 < arguments.length && void 0 !== arguments[2] ? arguments[2] : null - ); -}; -exports.dispatchCommand = function(handle, command, args) { - null != handle._nativeTag && - (handle._internalInstanceHandle - ? nativeFabricUIManager.dispatchCommand( - handle._internalInstanceHandle.stateNode.node, - command, - args - ) - : ReactNativePrivateInterface.UIManager.dispatchViewManagerCommand( - handle._nativeTag, - command, - args - )); -}; -exports.findHostInstance_DEPRECATED = function(componentOrHandle) { - if (null == componentOrHandle) return null; - if (componentOrHandle._nativeTag) return componentOrHandle; - if (componentOrHandle.canonical && componentOrHandle.canonical._nativeTag) - return componentOrHandle.canonical; - componentOrHandle = findHostInstance(componentOrHandle); - return null == componentOrHandle - ? componentOrHandle - : componentOrHandle.canonical - ? componentOrHandle.canonical - : componentOrHandle; -}; -exports.findNodeHandle = findNodeHandle; -exports.render = function(element, containerTag, callback) { - var root = roots.get(containerTag); - if (!root) { - root = new FiberRootNode(containerTag, 0, !1); - var uninitializedFiber = 0; - isDevToolsPresent && (uninitializedFiber |= 8); - uninitializedFiber = new FiberNode(3, null, null, uninitializedFiber); - root.current = uninitializedFiber; - uninitializedFiber.stateNode = root; - initializeUpdateQueue(uninitializedFiber); - roots.set(containerTag, root); - } - updateContainer(element, root, null, callback); - a: if (((element = root.current), element.child)) - switch (element.child.tag) { - case 5: - element = element.child.stateNode.canonical; - break a; - default: - element = element.child.stateNode; - } - else element = null; - return element; -}; -exports.stopSurface = function(containerTag) { - var root = roots.get(containerTag); - root && - updateContainer(null, root, null, function() { - roots.delete(containerTag); - }); -}; -exports.unmountComponentAtNode = function(containerTag) { - this.stopSurface(containerTag); -}; +var ReactFabric$2 = { default: ReactFabric }, + ReactFabric$3 = (ReactFabric$2 && ReactFabric) || ReactFabric$2; +module.exports = ReactFabric$3.default || ReactFabric$3; diff --git a/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js b/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js index 8ef9be346094b2..b1ae206b2534e5 100644 --- a/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js +++ b/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js @@ -5,7 +5,6 @@ * LICENSE file in the root directory of this source tree. * * @noflow - * @nolint * @preventMunge * @generated */ @@ -16,234 +15,256 @@ if (__DEV__) { (function() { "use strict"; -var React = require("react"); require("react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore"); var ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/ReactNativePrivateInterface"); +var React = require("react"); +var checkPropTypes = require("prop-types/checkPropTypes"); var Scheduler = require("scheduler"); var tracing = require("scheduler/tracing"); -var ReactSharedInternals = - React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; // Prevent newer renderers from RTE when used with older react package versions. -// Current owner and dispatcher used to share the same ref, -// but PR #14548 split them out to better support the react-debug-tools package. +/** + * Use invariant() to assert state which your program assumes to be true. + * + * Provide sprintf-style format (only %s is supported) and arguments + * to provide information about what broke and what you were + * expecting. + * + * The invariant message will be stripped in production, but the invariant + * will remain to ensure logic does not differ in production. + */ -if (!ReactSharedInternals.hasOwnProperty("ReactCurrentDispatcher")) { - ReactSharedInternals.ReactCurrentDispatcher = { - current: null - }; -} +/** + * Injectable ordering of event plugins. + */ +var eventPluginOrder = null; +/** + * Injectable mapping from names to event plugin modules. + */ -if (!ReactSharedInternals.hasOwnProperty("ReactCurrentBatchConfig")) { - ReactSharedInternals.ReactCurrentBatchConfig = { - suspense: null - }; -} +var namesToPlugins = {}; +/** + * Recomputes the plugin list using the injected plugins and plugin ordering. + * + * @private + */ -// by calls to these methods by a Babel plugin. -// -// In PROD (or in packages without access to React internals), -// they are left as they are instead. +function recomputePluginOrdering() { + if (!eventPluginOrder) { + // Wait until an `eventPluginOrder` is injected. + return; + } -function warn(format) { - { - for ( - var _len = arguments.length, - args = new Array(_len > 1 ? _len - 1 : 0), - _key = 1; - _key < _len; - _key++ - ) { - args[_key - 1] = arguments[_key]; - } + for (var pluginName in namesToPlugins) { + var pluginModule = namesToPlugins[pluginName]; + var pluginIndex = eventPluginOrder.indexOf(pluginName); - printWarning("warn", format, args); - } -} -function error(format) { - { - for ( - var _len2 = arguments.length, - args = new Array(_len2 > 1 ? _len2 - 1 : 0), - _key2 = 1; - _key2 < _len2; - _key2++ - ) { - args[_key2 - 1] = arguments[_key2]; + if (!(pluginIndex > -1)) { + throw Error( + "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + + pluginName + + "`." + ); } - printWarning("error", format, args); - } -} + if (plugins[pluginIndex]) { + continue; + } -function printWarning(level, format, args) { - // When changing this logic, you might want to also - // update consoleWithStackDev.www.js as well. - { - var hasExistingStack = - args.length > 0 && - typeof args[args.length - 1] === "string" && - args[args.length - 1].indexOf("\n in") === 0; + if (!pluginModule.extractEvents) { + throw Error( + "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + + pluginName + + "` does not." + ); + } - if (!hasExistingStack) { - var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; - var stack = ReactDebugCurrentFrame.getStackAddendum(); + plugins[pluginIndex] = pluginModule; + var publishedEvents = pluginModule.eventTypes; - if (stack !== "") { - format += "%s"; - args = args.concat([stack]); + for (var eventName in publishedEvents) { + if ( + !publishEventForPlugin( + publishedEvents[eventName], + pluginModule, + eventName + ) + ) { + throw Error( + "EventPluginRegistry: Failed to publish event `" + + eventName + + "` for plugin `" + + pluginName + + "`." + ); } } - - var argsWithFormat = args.map(function(item) { - return "" + item; - }); // Careful: RN currently depends on this prefix - - argsWithFormat.unshift("Warning: " + format); // We intentionally don't use spread (or .apply) directly because it - // breaks IE9: https://github.com/facebook/react/issues/13610 - // eslint-disable-next-line react-internal/no-production-logging - - Function.prototype.apply.call(console[level], console, argsWithFormat); - - try { - // --- Welcome to debugging React --- - // This error was thrown as a convenience so that you can use this stack - // to find the callsite that caused this warning to fire. - var argIndex = 0; - var message = - "Warning: " + - format.replace(/%s/g, function() { - return args[argIndex++]; - }); - throw new Error(message); - } catch (x) {} } } +/** + * Publishes an event so that it can be dispatched by the supplied plugin. + * + * @param {object} dispatchConfig Dispatch configuration for the event. + * @param {object} PluginModule Plugin publishing the event. + * @return {boolean} True if the event was successfully published. + * @private + */ -var FunctionComponent = 0; -var ClassComponent = 1; -var IndeterminateComponent = 2; // Before we know whether it is function or class - -var HostRoot = 3; // Root of a host tree. Could be nested inside another node. - -var HostPortal = 4; // A subtree. Could be an entry point to a different renderer. +function publishEventForPlugin(dispatchConfig, pluginModule, eventName) { + if (!!eventNameDispatchConfigs.hasOwnProperty(eventName)) { + throw Error( + "EventPluginHub: More than one plugin attempted to publish the same event name, `" + + eventName + + "`." + ); + } -var HostComponent = 5; -var HostText = 6; -var Fragment = 7; -var Mode = 8; -var ContextConsumer = 9; -var ContextProvider = 10; -var ForwardRef = 11; -var Profiler = 12; -var SuspenseComponent = 13; -var MemoComponent = 14; -var SimpleMemoComponent = 15; -var LazyComponent = 16; -var IncompleteClassComponent = 17; -var DehydratedFragment = 18; -var SuspenseListComponent = 19; -var FundamentalComponent = 20; -var ScopeComponent = 21; -var Block = 22; + eventNameDispatchConfigs[eventName] = dispatchConfig; + var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; -function getParent(inst) { - do { - inst = inst.return; // TODO: If this is a HostRoot we might want to bail out. - // That is depending on if we want nested subtrees (layers) to bubble - // events to their parent. We could also go through parentNode on the - // host node but that wouldn't work for React Native and doesn't let us - // do the portal feature. - } while (inst && inst.tag !== HostComponent); + if (phasedRegistrationNames) { + for (var phaseName in phasedRegistrationNames) { + if (phasedRegistrationNames.hasOwnProperty(phaseName)) { + var phasedRegistrationName = phasedRegistrationNames[phaseName]; + publishRegistrationName( + phasedRegistrationName, + pluginModule, + eventName + ); + } + } - if (inst) { - return inst; + return true; + } else if (dispatchConfig.registrationName) { + publishRegistrationName( + dispatchConfig.registrationName, + pluginModule, + eventName + ); + return true; } - return null; + return false; } /** - * Return the lowest common ancestor of A and B, or null if they are in - * different trees. + * Publishes a registration name that is used to identify dispatched events. + * + * @param {string} registrationName Registration name to add. + * @param {object} PluginModule Plugin publishing the event. + * @private */ -function getLowestCommonAncestor(instA, instB) { - var depthA = 0; - - for (var tempA = instA; tempA; tempA = getParent(tempA)) { - depthA++; +function publishRegistrationName(registrationName, pluginModule, eventName) { + if (!!registrationNameModules[registrationName]) { + throw Error( + "EventPluginHub: More than one plugin attempted to publish the same registration name, `" + + registrationName + + "`." + ); } - var depthB = 0; - - for (var tempB = instB; tempB; tempB = getParent(tempB)) { - depthB++; - } // If A is deeper, crawl up. - - while (depthA - depthB > 0) { - instA = getParent(instA); - depthA--; - } // If B is deeper, crawl up. - - while (depthB - depthA > 0) { - instB = getParent(instB); - depthB--; - } // Walk in lockstep until we find a match. - - var depth = depthA; - - while (depth--) { - if (instA === instB || instA === instB.alternate) { - return instA; - } + registrationNameModules[registrationName] = pluginModule; + registrationNameDependencies[registrationName] = + pluginModule.eventTypes[eventName].dependencies; - instA = getParent(instA); - instB = getParent(instB); + { + var lowerCasedName = registrationName.toLowerCase(); } - - return null; } /** - * Return if A is an ancestor of B. + * Registers plugins so that they can extract and dispatch events. + * + * @see {EventPluginHub} */ -function isAncestor(instA, instB) { - while (instB) { - if (instA === instB || instA === instB.alternate) { - return true; - } - - instB = getParent(instB); - } +/** + * Ordered list of injected plugins. + */ - return false; -} +var plugins = []; /** - * Return the parent instance of the passed-in instance. + * Mapping from event name to dispatch config */ -function getParentInstance(inst) { - return getParent(inst); -} +var eventNameDispatchConfigs = {}; /** - * Simulates the traversal of a two-phase, capture/bubble event dispatch. + * Mapping from registration name to plugin module */ -function traverseTwoPhase(inst, fn, arg) { - var path = []; +var registrationNameModules = {}; +/** + * Mapping from registration name to event name + */ - while (inst) { - path.push(inst); - inst = getParent(inst); - } +var registrationNameDependencies = {}; +/** + * Mapping from lowercase registration names to the properly cased version, + * used to warn in the case of missing event handlers. Available + * only in true. + * @type {Object} + */ - var i; +// Trust the developer to only use possibleRegistrationNames in true - for (i = path.length; i-- > 0; ) { - fn(path[i], "captured", arg); +/** + * Injects an ordering of plugins (by plugin name). This allows the ordering + * to be decoupled from injection of the actual plugins so that ordering is + * always deterministic regardless of packaging, on-the-fly injection, etc. + * + * @param {array} InjectedEventPluginOrder + * @internal + * @see {EventPluginHub.injection.injectEventPluginOrder} + */ + +function injectEventPluginOrder(injectedEventPluginOrder) { + if (!!eventPluginOrder) { + throw Error( + "EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React." + ); + } // Clone the ordering so it cannot be dynamically mutated. + + eventPluginOrder = Array.prototype.slice.call(injectedEventPluginOrder); + recomputePluginOrdering(); +} +/** + * Injects plugins to be used by `EventPluginHub`. The plugin names must be + * in the ordering injected by `injectEventPluginOrder`. + * + * Plugins can be injected as part of page initialization or on-the-fly. + * + * @param {object} injectedNamesToPlugins Map from names to plugin modules. + * @internal + * @see {EventPluginHub.injection.injectEventPluginsByName} + */ + +function injectEventPluginsByName(injectedNamesToPlugins) { + var isOrderingDirty = false; + + for (var pluginName in injectedNamesToPlugins) { + if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) { + continue; + } + + var pluginModule = injectedNamesToPlugins[pluginName]; + + if ( + !namesToPlugins.hasOwnProperty(pluginName) || + namesToPlugins[pluginName] !== pluginModule + ) { + if (!!namesToPlugins[pluginName]) { + throw Error( + "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + + pluginName + + "`." + ); + } + + namesToPlugins[pluginName] = pluginModule; + isOrderingDirty = true; + } } - for (i = 0; i < path.length; i++) { - fn(path[i], "bubbled", arg); + if (isOrderingDirty) { + recomputePluginOrdering(); } } @@ -538,6 +559,71 @@ function clearCaughtError() { } } +/** + * Similar to invariant but only logs a warning if the condition is not met. + * This can be used to log issues in development environments in critical + * paths. Removing the logging code for production environments will keep the + * same logic and follow the same code paths. + */ +var warningWithoutStack = function() {}; + +{ + warningWithoutStack = function(condition, format) { + for ( + var _len = arguments.length, + args = new Array(_len > 2 ? _len - 2 : 0), + _key = 2; + _key < _len; + _key++ + ) { + args[_key - 2] = arguments[_key]; + } + + if (format === undefined) { + throw new Error( + "`warningWithoutStack(condition, format, ...args)` requires a warning " + + "message argument" + ); + } + + if (args.length > 8) { + // Check before the condition to catch violations early. + throw new Error( + "warningWithoutStack() currently supports at most 8 arguments." + ); + } + + if (condition) { + return; + } + + if (typeof console !== "undefined") { + var argsWithFormat = args.map(function(item) { + return "" + item; + }); + argsWithFormat.unshift("Warning: " + format); // We intentionally don't use spread (or .apply) directly because it + // breaks IE9: https://github.com/facebook/react/issues/13610 + + Function.prototype.apply.call(console.error, console, argsWithFormat); + } + + try { + // --- Welcome to debugging React --- + // This error was thrown as a convenience so that you can use this stack + // to find the callsite that caused this warning to fire. + var argIndex = 0; + var message = + "Warning: " + + format.replace(/%s/g, function() { + return args[argIndex++]; + }); + throw new Error(message); + } catch (x) {} + }; +} + +var warningWithoutStack$1 = warningWithoutStack; + var getFiberCurrentPropsFromNode = null; var getInstanceFromNode = null; var getNodeFromInstance = null; @@ -551,12 +637,13 @@ function setComponentTree( getNodeFromInstance = getNodeFromInstanceImpl; { - if (!getNodeFromInstance || !getInstanceFromNode) { - error( - "EventPluginUtils.setComponentTree(...): Injected " + - "module is missing getNodeFromInstance or getInstanceFromNode." - ); - } + !(getNodeFromInstance && getInstanceFromNode) + ? warningWithoutStack$1( + false, + "EventPluginUtils.setComponentTree(...): Injected " + + "module is missing getNodeFromInstance or getInstanceFromNode." + ) + : void 0; } } var validateEventDispatches; @@ -569,18 +656,17 @@ var validateEventDispatches; var listenersLen = listenersIsArr ? dispatchListeners.length : dispatchListeners - ? 1 - : 0; + ? 1 + : 0; var instancesIsArr = Array.isArray(dispatchInstances); var instancesLen = instancesIsArr ? dispatchInstances.length : dispatchInstances - ? 1 - : 0; - - if (instancesIsArr !== listenersIsArr || instancesLen !== listenersLen) { - error("EventPluginUtils: Invalid `event`."); - } + ? 1 + : 0; + !(instancesIsArr === listenersIsArr && instancesLen === listenersLen) + ? warningWithoutStack$1(false, "EventPluginUtils: Invalid `event`.") + : void 0; }; } /** @@ -707,77 +793,6 @@ function hasDispatches(event) { return !!event._dispatchListeners; } -function isInteractive(tag) { - return ( - tag === "button" || - tag === "input" || - tag === "select" || - tag === "textarea" - ); -} - -function shouldPreventMouseEvent(name, type, props) { - switch (name) { - case "onClick": - case "onClickCapture": - case "onDoubleClick": - case "onDoubleClickCapture": - case "onMouseDown": - case "onMouseDownCapture": - case "onMouseMove": - case "onMouseMoveCapture": - case "onMouseUp": - case "onMouseUpCapture": - case "onMouseEnter": - return !!(props.disabled && isInteractive(type)); - - default: - return false; - } -} -/** - * @param {object} inst The instance, which is the source of events. - * @param {string} registrationName Name of listener (e.g. `onClick`). - * @return {?function} The stored callback. - */ - -function getListener(inst, registrationName) { - var listener; // TODO: shouldPreventMouseEvent is DOM-specific and definitely should not - // live here; needs to be moved to a better place soon - - var stateNode = inst.stateNode; - - if (!stateNode) { - // Work in progress (ex: onload events in incremental mode). - return null; - } - - var props = getFiberCurrentPropsFromNode(stateNode); - - if (!props) { - // Work in progress. - return null; - } - - listener = props[registrationName]; - - if (shouldPreventMouseEvent(registrationName, inst.type, props)) { - return null; - } - - if (!(!listener || typeof listener === "function")) { - throw Error( - "Expected `" + - registrationName + - "` listener to be a function, instead got a value of `" + - typeof listener + - "` type." - ); - } - - return listener; -} - /** * Accumulates items that must not be null or undefined into the first one. This * is used to conserve memory by avoiding array allocations, and thus sacrifices @@ -839,1526 +854,1651 @@ function forEachAccumulated(arr, cb, scope) { } /** - * Some event types have a notion of different registration names for different - * "phases" of propagation. This finds listeners by a given phase. - */ -function listenerAtPhase(inst, event, propagationPhase) { - var registrationName = - event.dispatchConfig.phasedRegistrationNames[propagationPhase]; - return getListener(inst, registrationName); -} -/** - * A small set of propagation patterns, each of which will accept a small amount - * of information, and generate a set of "dispatch ready event objects" - which - * are sets of events that have already been annotated with a set of dispatched - * listener functions/ids. The API is designed this way to discourage these - * propagation strategies from actually executing the dispatches, since we - * always want to collect the entire set of dispatches before executing even a - * single one. + * Internal queue of events that have accumulated their dispatches and are + * waiting to have their dispatches executed. */ +var eventQueue = null; /** - * Tags a `SyntheticEvent` with dispatched listeners. Creating this function - * here, allows us to not have to bind or create functions for each event. - * Mutating the event's members allows us to not have to create a wrapping - * "dispatch" object that pairs the event with the listener. + * Dispatches an event and releases it back into the pool, unless persistent. + * + * @param {?object} event Synthetic event to be dispatched. + * @private */ -function accumulateDirectionalDispatches(inst, phase, event) { - { - if (!inst) { - error("Dispatching inst must not be null"); +var executeDispatchesAndRelease = function(event) { + if (event) { + executeDispatchesInOrder(event); + + if (!event.isPersistent()) { + event.constructor.release(event); } } +}; - var listener = listenerAtPhase(inst, event, phase); +var executeDispatchesAndReleaseTopLevel = function(e) { + return executeDispatchesAndRelease(e); +}; - if (listener) { - event._dispatchListeners = accumulateInto( - event._dispatchListeners, - listener - ); - event._dispatchInstances = accumulateInto(event._dispatchInstances, inst); - } -} -/** - * Collect dispatches (must be entirely collected before dispatching - see unit - * tests). Lazily allocate the array to conserve memory. We must loop through - * each event and perform the traversal for each one. We cannot perform a - * single traversal for the entire collection of events because each event may - * have a different target. - */ +function runEventsInBatch(events) { + if (events !== null) { + eventQueue = accumulateInto(eventQueue, events); + } // Set `eventQueue` to null before processing it so that we can tell if more + // events get enqueued while processing. -function accumulateTwoPhaseDispatchesSingle(event) { - if (event && event.dispatchConfig.phasedRegistrationNames) { - traverseTwoPhase(event._targetInst, accumulateDirectionalDispatches, event); + var processingEventQueue = eventQueue; + eventQueue = null; + + if (!processingEventQueue) { + return; } -} -/** - * Same as `accumulateTwoPhaseDispatchesSingle`, but skips over the targetID. - */ -function accumulateTwoPhaseDispatchesSingleSkipTarget(event) { - if (event && event.dispatchConfig.phasedRegistrationNames) { - var targetInst = event._targetInst; - var parentInst = targetInst ? getParentInstance(targetInst) : null; - traverseTwoPhase(parentInst, accumulateDirectionalDispatches, event); - } + forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseTopLevel); + + if (!!eventQueue) { + throw Error( + "processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented." + ); + } // This would be a good time to rethrow if any of the event handlers threw. + + rethrowCaughtError(); } -/** - * Accumulates without regard to direction, does not look for phased - * registration names. Same as `accumulateDirectDispatchesSingle` but without - * requiring that the `dispatchMarker` be the same as the dispatched ID. - */ -function accumulateDispatches(inst, ignoredDirection, event) { - if (inst && event && event.dispatchConfig.registrationName) { - var registrationName = event.dispatchConfig.registrationName; - var listener = getListener(inst, registrationName); +function isInteractive(tag) { + return ( + tag === "button" || + tag === "input" || + tag === "select" || + tag === "textarea" + ); +} - if (listener) { - event._dispatchListeners = accumulateInto( - event._dispatchListeners, - listener - ); - event._dispatchInstances = accumulateInto(event._dispatchInstances, inst); - } +function shouldPreventMouseEvent(name, type, props) { + switch (name) { + case "onClick": + case "onClickCapture": + case "onDoubleClick": + case "onDoubleClickCapture": + case "onMouseDown": + case "onMouseDownCapture": + case "onMouseMove": + case "onMouseMoveCapture": + case "onMouseUp": + case "onMouseUpCapture": + return !!(props.disabled && isInteractive(type)); + + default: + return false; } } /** - * Accumulates dispatches on an `SyntheticEvent`, but only for the - * `dispatchMarker`. - * @param {SyntheticEvent} event + * This is a unified interface for event plugins to be installed and configured. + * + * Event plugins can implement the following properties: + * + * `extractEvents` {function(string, DOMEventTarget, string, object): *} + * Required. When a top-level event is fired, this method is expected to + * extract synthetic events that will in turn be queued and dispatched. + * + * `eventTypes` {object} + * Optional, plugins that fire events must publish a mapping of registration + * names that are used to register listeners. Values of this mapping must + * be objects that contain `registrationName` or `phasedRegistrationNames`. + * + * `executeDispatch` {function(object, function, string)} + * Optional, allows plugins to override how an event gets dispatched. By + * default, the listener is simply invoked. + * + * Each plugin that is injected into `EventsPluginHub` is immediately operable. + * + * @public */ -function accumulateDirectDispatchesSingle(event) { - if (event && event.dispatchConfig.registrationName) { - accumulateDispatches(event._targetInst, null, event); - } -} +/** + * Methods for injecting dependencies. + */ -function accumulateTwoPhaseDispatches(events) { - forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle); -} -function accumulateTwoPhaseDispatchesSkipTarget(events) { - forEachAccumulated(events, accumulateTwoPhaseDispatchesSingleSkipTarget); -} -function accumulateDirectDispatches(events) { - forEachAccumulated(events, accumulateDirectDispatchesSingle); -} +var injection = { + /** + * @param {array} InjectedEventPluginOrder + * @public + */ + injectEventPluginOrder: injectEventPluginOrder, -var EVENT_POOL_SIZE = 10; + /** + * @param {object} injectedNamesToPlugins Map from names to plugin modules. + */ + injectEventPluginsByName: injectEventPluginsByName +}; /** - * @interface Event - * @see http://www.w3.org/TR/DOM-Level-3-Events/ + * @param {object} inst The instance, which is the source of events. + * @param {string} registrationName Name of listener (e.g. `onClick`). + * @return {?function} The stored callback. */ -var EventInterface = { - type: null, - target: null, - // currentTarget is set when dispatching; no use in copying it here - currentTarget: function() { +function getListener(inst, registrationName) { + var listener; // TODO: shouldPreventMouseEvent is DOM-specific and definitely should not + // live here; needs to be moved to a better place soon + + var stateNode = inst.stateNode; + + if (!stateNode) { + // Work in progress (ex: onload events in incremental mode). return null; - }, - eventPhase: null, - bubbles: null, - cancelable: null, - timeStamp: function(event) { - return event.timeStamp || Date.now(); - }, - defaultPrevented: null, - isTrusted: null -}; + } -function functionThatReturnsTrue() { - return true; -} + var props = getFiberCurrentPropsFromNode(stateNode); -function functionThatReturnsFalse() { - return false; + if (!props) { + // Work in progress. + return null; + } + + listener = props[registrationName]; + + if (shouldPreventMouseEvent(registrationName, inst.type, props)) { + return null; + } + + if (!(!listener || typeof listener === "function")) { + throw Error( + "Expected `" + + registrationName + + "` listener to be a function, instead got a value of `" + + typeof listener + + "` type." + ); + } + + return listener; } /** - * Synthetic events are dispatched by event plugins, typically in response to a - * top-level event delegation handler. - * - * These systems should generally use pooling to reduce the frequency of garbage - * collection. The system should check `isPersistent` to determine whether the - * event should be released into the pool after being dispatched. Users that - * need a persisted event should invoke `persist`. - * - * Synthetic events (and subclasses) implement the DOM Level 3 Events API by - * normalizing browser quirks. Subclasses do not necessarily have to implement a - * DOM interface; custom application-specific events can also subclass this. + * Allows registered plugins an opportunity to extract events from top-level + * native browser events. * - * @param {object} dispatchConfig Configuration used to dispatch this event. - * @param {*} targetInst Marker identifying the event target. - * @param {object} nativeEvent Native browser event. - * @param {DOMEventTarget} nativeEventTarget Target node. + * @return {*} An accumulation of synthetic events. + * @internal */ -function SyntheticEvent( - dispatchConfig, +function extractPluginEvents( + topLevelType, targetInst, nativeEvent, - nativeEventTarget + nativeEventTarget, + eventSystemFlags ) { - { - // these have a getter/setter for warnings - delete this.nativeEvent; - delete this.preventDefault; - delete this.stopPropagation; - delete this.isDefaultPrevented; - delete this.isPropagationStopped; - } - - this.dispatchConfig = dispatchConfig; - this._targetInst = targetInst; - this.nativeEvent = nativeEvent; - var Interface = this.constructor.Interface; - - for (var propName in Interface) { - if (!Interface.hasOwnProperty(propName)) { - continue; - } + var events = null; - { - delete this[propName]; // this has a getter/setter for warnings - } + for (var i = 0; i < plugins.length; i++) { + // Not every plugin in the ordering may be loaded at runtime. + var possiblePlugin = plugins[i]; - var normalize = Interface[propName]; + if (possiblePlugin) { + var extractedEvents = possiblePlugin.extractEvents( + topLevelType, + targetInst, + nativeEvent, + nativeEventTarget, + eventSystemFlags + ); - if (normalize) { - this[propName] = normalize(nativeEvent); - } else { - if (propName === "target") { - this.target = nativeEventTarget; - } else { - this[propName] = nativeEvent[propName]; + if (extractedEvents) { + events = accumulateInto(events, extractedEvents); } } } - var defaultPrevented = - nativeEvent.defaultPrevented != null - ? nativeEvent.defaultPrevented - : nativeEvent.returnValue === false; - - if (defaultPrevented) { - this.isDefaultPrevented = functionThatReturnsTrue; - } else { - this.isDefaultPrevented = functionThatReturnsFalse; - } + return events; +} - this.isPropagationStopped = functionThatReturnsFalse; - return this; +function runExtractedPluginEventsInBatch( + topLevelType, + targetInst, + nativeEvent, + nativeEventTarget, + eventSystemFlags +) { + var events = extractPluginEvents( + topLevelType, + targetInst, + nativeEvent, + nativeEventTarget, + eventSystemFlags + ); + runEventsInBatch(events); } -Object.assign(SyntheticEvent.prototype, { - preventDefault: function() { - this.defaultPrevented = true; - var event = this.nativeEvent; +var FunctionComponent = 0; +var ClassComponent = 1; +var IndeterminateComponent = 2; // Before we know whether it is function or class - if (!event) { - return; - } +var HostRoot = 3; // Root of a host tree. Could be nested inside another node. - if (event.preventDefault) { - event.preventDefault(); - } else if (typeof event.returnValue !== "unknown") { - event.returnValue = false; - } +var HostPortal = 4; // A subtree. Could be an entry point to a different renderer. - this.isDefaultPrevented = functionThatReturnsTrue; - }, - stopPropagation: function() { - var event = this.nativeEvent; +var HostComponent = 5; +var HostText = 6; +var Fragment = 7; +var Mode = 8; +var ContextConsumer = 9; +var ContextProvider = 10; +var ForwardRef = 11; +var Profiler = 12; +var SuspenseComponent = 13; +var MemoComponent = 14; +var SimpleMemoComponent = 15; +var LazyComponent = 16; +var IncompleteClassComponent = 17; +var DehydratedFragment = 18; +var SuspenseListComponent = 19; +var FundamentalComponent = 20; +var ScopeComponent = 21; - if (!event) { - return; - } +function getParent(inst) { + do { + inst = inst.return; // TODO: If this is a HostRoot we might want to bail out. + // That is depending on if we want nested subtrees (layers) to bubble + // events to their parent. We could also go through parentNode on the + // host node but that wouldn't work for React Native and doesn't let us + // do the portal feature. + } while (inst && inst.tag !== HostComponent); - if (event.stopPropagation) { - event.stopPropagation(); - } else if (typeof event.cancelBubble !== "unknown") { - // The ChangeEventPlugin registers a "propertychange" event for - // IE. This event does not support bubbling or cancelling, and - // any references to cancelBubble throw "Member not found". A - // typeof check of "unknown" circumvents this issue (and is also - // IE specific). - event.cancelBubble = true; - } + if (inst) { + return inst; + } - this.isPropagationStopped = functionThatReturnsTrue; - }, + return null; +} +/** + * Return the lowest common ancestor of A and B, or null if they are in + * different trees. + */ - /** - * We release all dispatched `SyntheticEvent`s after each event loop, adding - * them back into the pool. This allows a way to hold onto a reference that - * won't be added back into the pool. - */ - persist: function() { - this.isPersistent = functionThatReturnsTrue; - }, +function getLowestCommonAncestor(instA, instB) { + var depthA = 0; - /** - * Checks if this event should be released back into the pool. - * - * @return {boolean} True if this should not be released, false otherwise. - */ - isPersistent: functionThatReturnsFalse, + for (var tempA = instA; tempA; tempA = getParent(tempA)) { + depthA++; + } - /** - * `PooledClass` looks for `destructor` on each instance it releases. - */ - destructor: function() { - var Interface = this.constructor.Interface; + var depthB = 0; - for (var propName in Interface) { - { - Object.defineProperty( - this, - propName, - getPooledWarningPropertyDefinition(propName, Interface[propName]) - ); - } - } + for (var tempB = instB; tempB; tempB = getParent(tempB)) { + depthB++; + } // If A is deeper, crawl up. - this.dispatchConfig = null; - this._targetInst = null; - this.nativeEvent = null; - this.isDefaultPrevented = functionThatReturnsFalse; - this.isPropagationStopped = functionThatReturnsFalse; - this._dispatchListeners = null; - this._dispatchInstances = null; + while (depthA - depthB > 0) { + instA = getParent(instA); + depthA--; + } // If B is deeper, crawl up. - { - Object.defineProperty( - this, - "nativeEvent", - getPooledWarningPropertyDefinition("nativeEvent", null) - ); - Object.defineProperty( - this, - "isDefaultPrevented", - getPooledWarningPropertyDefinition( - "isDefaultPrevented", - functionThatReturnsFalse - ) - ); - Object.defineProperty( - this, - "isPropagationStopped", - getPooledWarningPropertyDefinition( - "isPropagationStopped", - functionThatReturnsFalse - ) - ); - Object.defineProperty( - this, - "preventDefault", - getPooledWarningPropertyDefinition("preventDefault", function() {}) - ); - Object.defineProperty( - this, - "stopPropagation", - getPooledWarningPropertyDefinition("stopPropagation", function() {}) - ); + while (depthB - depthA > 0) { + instB = getParent(instB); + depthB--; + } // Walk in lockstep until we find a match. + + var depth = depthA; + + while (depth--) { + if (instA === instB || instA === instB.alternate) { + return instA; } + + instA = getParent(instA); + instB = getParent(instB); } -}); -SyntheticEvent.Interface = EventInterface; + + return null; +} /** - * Helper to reduce boilerplate when creating subclasses. + * Return if A is an ancestor of B. */ -SyntheticEvent.extend = function(Interface) { - var Super = this; - - var E = function() {}; - - E.prototype = Super.prototype; - var prototype = new E(); +function isAncestor(instA, instB) { + while (instB) { + if (instA === instB || instA === instB.alternate) { + return true; + } - function Class() { - return Super.apply(this, arguments); + instB = getParent(instB); } - Object.assign(prototype, Class.prototype); - Class.prototype = prototype; - Class.prototype.constructor = Class; - Class.Interface = Object.assign({}, Super.Interface, Interface); - Class.extend = Super.extend; - addEventPoolingTo(Class); - return Class; -}; + return false; +} +/** + * Return the parent instance of the passed-in instance. + */ -addEventPoolingTo(SyntheticEvent); +function getParentInstance(inst) { + return getParent(inst); +} /** - * Helper to nullify syntheticEvent instance properties when destructing - * - * @param {String} propName - * @param {?object} getVal - * @return {object} defineProperty object + * Simulates the traversal of a two-phase, capture/bubble event dispatch. */ -function getPooledWarningPropertyDefinition(propName, getVal) { - var isFunction = typeof getVal === "function"; - return { - configurable: true, - set: set, - get: get - }; +function traverseTwoPhase(inst, fn, arg) { + var path = []; - function set(val) { - var action = isFunction ? "setting the method" : "setting the property"; - warn(action, "This is effectively a no-op"); - return val; + while (inst) { + path.push(inst); + inst = getParent(inst); } - function get() { - var action = isFunction ? "accessing the method" : "accessing the property"; - var result = isFunction - ? "This is a no-op function" - : "This is set to null"; - warn(action, result); - return getVal; - } + var i; - function warn(action, result) { - { - error( - "This synthetic event is reused for performance reasons. If you're seeing this, " + - "you're %s `%s` on a released/nullified synthetic event. %s. " + - "If you must keep the original synthetic event around, use event.persist(). " + - "See https://fb.me/react-event-pooling for more information.", - action, - propName, - result - ); - } + for (i = path.length; i-- > 0; ) { + fn(path[i], "captured", arg); } -} -function getPooledEvent(dispatchConfig, targetInst, nativeEvent, nativeInst) { - var EventConstructor = this; - - if (EventConstructor.eventPool.length) { - var instance = EventConstructor.eventPool.pop(); - EventConstructor.call( - instance, - dispatchConfig, - targetInst, - nativeEvent, - nativeInst - ); - return instance; + for (i = 0; i < path.length; i++) { + fn(path[i], "bubbled", arg); } - - return new EventConstructor( - dispatchConfig, - targetInst, - nativeEvent, - nativeInst - ); } +/** + * Traverses the ID hierarchy and invokes the supplied `cb` on any IDs that + * should would receive a `mouseEnter` or `mouseLeave` event. + * + * Does not invoke the callback on the nearest common ancestor because nothing + * "entered" or "left" that element. + */ -function releasePooledEvent(event) { - var EventConstructor = this; - - if (!(event instanceof EventConstructor)) { - throw Error( - "Trying to release an event instance into a pool of a different type." - ); - } - - event.destructor(); - - if (EventConstructor.eventPool.length < EVENT_POOL_SIZE) { - EventConstructor.eventPool.push(event); - } -} - -function addEventPoolingTo(EventConstructor) { - EventConstructor.eventPool = []; - EventConstructor.getPooled = getPooledEvent; - EventConstructor.release = releasePooledEvent; +/** + * Some event types have a notion of different registration names for different + * "phases" of propagation. This finds listeners by a given phase. + */ +function listenerAtPhase(inst, event, propagationPhase) { + var registrationName = + event.dispatchConfig.phasedRegistrationNames[propagationPhase]; + return getListener(inst, registrationName); } +/** + * A small set of propagation patterns, each of which will accept a small amount + * of information, and generate a set of "dispatch ready event objects" - which + * are sets of events that have already been annotated with a set of dispatched + * listener functions/ids. The API is designed this way to discourage these + * propagation strategies from actually executing the dispatches, since we + * always want to collect the entire set of dispatches before executing even a + * single one. + */ /** - * `touchHistory` isn't actually on the native event, but putting it in the - * interface will ensure that it is cleaned up when pooled/destroyed. The - * `ResponderEventPlugin` will populate it appropriately. + * Tags a `SyntheticEvent` with dispatched listeners. Creating this function + * here, allows us to not have to bind or create functions for each event. + * Mutating the event's members allows us to not have to create a wrapping + * "dispatch" object that pairs the event with the listener. */ -var ResponderSyntheticEvent = SyntheticEvent.extend({ - touchHistory: function(nativeEvent) { - return null; // Actually doesn't even look at the native event. +function accumulateDirectionalDispatches(inst, phase, event) { + { + !inst + ? warningWithoutStack$1(false, "Dispatching inst must not be null") + : void 0; } -}); -var TOP_TOUCH_START = "topTouchStart"; -var TOP_TOUCH_MOVE = "topTouchMove"; -var TOP_TOUCH_END = "topTouchEnd"; -var TOP_TOUCH_CANCEL = "topTouchCancel"; -var TOP_SCROLL = "topScroll"; -var TOP_SELECTION_CHANGE = "topSelectionChange"; -function isStartish(topLevelType) { - return topLevelType === TOP_TOUCH_START; -} -function isMoveish(topLevelType) { - return topLevelType === TOP_TOUCH_MOVE; -} -function isEndish(topLevelType) { - return topLevelType === TOP_TOUCH_END || topLevelType === TOP_TOUCH_CANCEL; -} -var startDependencies = [TOP_TOUCH_START]; -var moveDependencies = [TOP_TOUCH_MOVE]; -var endDependencies = [TOP_TOUCH_CANCEL, TOP_TOUCH_END]; + var listener = listenerAtPhase(inst, event, phase); + if (listener) { + event._dispatchListeners = accumulateInto( + event._dispatchListeners, + listener + ); + event._dispatchInstances = accumulateInto(event._dispatchInstances, inst); + } +} /** - * Tracks the position and time of each active touch by `touch.identifier`. We - * should typically only see IDs in the range of 1-20 because IDs get recycled - * when touches end and start again. + * Collect dispatches (must be entirely collected before dispatching - see unit + * tests). Lazily allocate the array to conserve memory. We must loop through + * each event and perform the traversal for each one. We cannot perform a + * single traversal for the entire collection of events because each event may + * have a different target. */ -var MAX_TOUCH_BANK = 20; -var touchBank = []; -var touchHistory = { - touchBank: touchBank, - numberActiveTouches: 0, - // If there is only one active touch, we remember its location. This prevents - // us having to loop through all of the touches all the time in the most - // common case. - indexOfSingleActiveTouch: -1, - mostRecentTimeStamp: 0 -}; - -function timestampForTouch(touch) { - // The legacy internal implementation provides "timeStamp", which has been - // renamed to "timestamp". Let both work for now while we iron it out - // TODO (evv): rename timeStamp to timestamp in internal code - return touch.timeStamp || touch.timestamp; +function accumulateTwoPhaseDispatchesSingle(event) { + if (event && event.dispatchConfig.phasedRegistrationNames) { + traverseTwoPhase(event._targetInst, accumulateDirectionalDispatches, event); + } } /** - * TODO: Instead of making gestures recompute filtered velocity, we could - * include a built in velocity computation that can be reused globally. + * Same as `accumulateTwoPhaseDispatchesSingle`, but skips over the targetID. */ -function createTouchRecord(touch) { - return { - touchActive: true, - startPageX: touch.pageX, - startPageY: touch.pageY, - startTimeStamp: timestampForTouch(touch), - currentPageX: touch.pageX, - currentPageY: touch.pageY, - currentTimeStamp: timestampForTouch(touch), - previousPageX: touch.pageX, - previousPageY: touch.pageY, - previousTimeStamp: timestampForTouch(touch) - }; -} - -function resetTouchRecord(touchRecord, touch) { - touchRecord.touchActive = true; - touchRecord.startPageX = touch.pageX; - touchRecord.startPageY = touch.pageY; - touchRecord.startTimeStamp = timestampForTouch(touch); - touchRecord.currentPageX = touch.pageX; - touchRecord.currentPageY = touch.pageY; - touchRecord.currentTimeStamp = timestampForTouch(touch); - touchRecord.previousPageX = touch.pageX; - touchRecord.previousPageY = touch.pageY; - touchRecord.previousTimeStamp = timestampForTouch(touch); +function accumulateTwoPhaseDispatchesSingleSkipTarget(event) { + if (event && event.dispatchConfig.phasedRegistrationNames) { + var targetInst = event._targetInst; + var parentInst = targetInst ? getParentInstance(targetInst) : null; + traverseTwoPhase(parentInst, accumulateDirectionalDispatches, event); + } } +/** + * Accumulates without regard to direction, does not look for phased + * registration names. Same as `accumulateDirectDispatchesSingle` but without + * requiring that the `dispatchMarker` be the same as the dispatched ID. + */ -function getTouchIdentifier(_ref) { - var identifier = _ref.identifier; - - if (!(identifier != null)) { - throw Error("Touch object is missing identifier."); - } +function accumulateDispatches(inst, ignoredDirection, event) { + if (inst && event && event.dispatchConfig.registrationName) { + var registrationName = event.dispatchConfig.registrationName; + var listener = getListener(inst, registrationName); - { - if (identifier > MAX_TOUCH_BANK) { - error( - "Touch identifier %s is greater than maximum supported %s which causes " + - "performance issues backfilling array locations for all of the indices.", - identifier, - MAX_TOUCH_BANK + if (listener) { + event._dispatchListeners = accumulateInto( + event._dispatchListeners, + listener ); + event._dispatchInstances = accumulateInto(event._dispatchInstances, inst); } } - - return identifier; } +/** + * Accumulates dispatches on an `SyntheticEvent`, but only for the + * `dispatchMarker`. + * @param {SyntheticEvent} event + */ -function recordTouchStart(touch) { - var identifier = getTouchIdentifier(touch); - var touchRecord = touchBank[identifier]; - - if (touchRecord) { - resetTouchRecord(touchRecord, touch); - } else { - touchBank[identifier] = createTouchRecord(touch); +function accumulateDirectDispatchesSingle(event) { + if (event && event.dispatchConfig.registrationName) { + accumulateDispatches(event._targetInst, null, event); } - - touchHistory.mostRecentTimeStamp = timestampForTouch(touch); } -function recordTouchMove(touch) { - var touchRecord = touchBank[getTouchIdentifier(touch)]; - - if (touchRecord) { - touchRecord.touchActive = true; - touchRecord.previousPageX = touchRecord.currentPageX; - touchRecord.previousPageY = touchRecord.currentPageY; - touchRecord.previousTimeStamp = touchRecord.currentTimeStamp; - touchRecord.currentPageX = touch.pageX; - touchRecord.currentPageY = touch.pageY; - touchRecord.currentTimeStamp = timestampForTouch(touch); - touchHistory.mostRecentTimeStamp = timestampForTouch(touch); - } else { - { - warn( - "Cannot record touch move without a touch start.\n" + - "Touch Move: %s\n" + - "Touch Bank: %s", - printTouch(touch), - printTouchBank() - ); - } - } +function accumulateTwoPhaseDispatches(events) { + forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle); } - -function recordTouchEnd(touch) { - var touchRecord = touchBank[getTouchIdentifier(touch)]; - - if (touchRecord) { - touchRecord.touchActive = false; - touchRecord.previousPageX = touchRecord.currentPageX; - touchRecord.previousPageY = touchRecord.currentPageY; - touchRecord.previousTimeStamp = touchRecord.currentTimeStamp; - touchRecord.currentPageX = touch.pageX; - touchRecord.currentPageY = touch.pageY; - touchRecord.currentTimeStamp = timestampForTouch(touch); - touchHistory.mostRecentTimeStamp = timestampForTouch(touch); - } else { - { - warn( - "Cannot record touch end without a touch start.\n" + - "Touch End: %s\n" + - "Touch Bank: %s", - printTouch(touch), - printTouchBank() - ); - } - } +function accumulateTwoPhaseDispatchesSkipTarget(events) { + forEachAccumulated(events, accumulateTwoPhaseDispatchesSingleSkipTarget); } -function printTouch(touch) { - return JSON.stringify({ - identifier: touch.identifier, - pageX: touch.pageX, - pageY: touch.pageY, - timestamp: timestampForTouch(touch) - }); +function accumulateDirectDispatches(events) { + forEachAccumulated(events, accumulateDirectDispatchesSingle); } -function printTouchBank() { - var printed = JSON.stringify(touchBank.slice(0, MAX_TOUCH_BANK)); +/* eslint valid-typeof: 0 */ +var EVENT_POOL_SIZE = 10; +/** + * @interface Event + * @see http://www.w3.org/TR/DOM-Level-3-Events/ + */ - if (touchBank.length > MAX_TOUCH_BANK) { - printed += " (original size: " + touchBank.length + ")"; - } +var EventInterface = { + type: null, + target: null, + // currentTarget is set when dispatching; no use in copying it here + currentTarget: function() { + return null; + }, + eventPhase: null, + bubbles: null, + cancelable: null, + timeStamp: function(event) { + return event.timeStamp || Date.now(); + }, + defaultPrevented: null, + isTrusted: null +}; - return printed; +function functionThatReturnsTrue() { + return true; } -var ResponderTouchHistoryStore = { - recordTouchTrack: function(topLevelType, nativeEvent) { - if (isMoveish(topLevelType)) { - nativeEvent.changedTouches.forEach(recordTouchMove); - } else if (isStartish(topLevelType)) { - nativeEvent.changedTouches.forEach(recordTouchStart); - touchHistory.numberActiveTouches = nativeEvent.touches.length; - - if (touchHistory.numberActiveTouches === 1) { - touchHistory.indexOfSingleActiveTouch = - nativeEvent.touches[0].identifier; - } - } else if (isEndish(topLevelType)) { - nativeEvent.changedTouches.forEach(recordTouchEnd); - touchHistory.numberActiveTouches = nativeEvent.touches.length; - - if (touchHistory.numberActiveTouches === 1) { - for (var i = 0; i < touchBank.length; i++) { - var touchTrackToCheck = touchBank[i]; - - if (touchTrackToCheck != null && touchTrackToCheck.touchActive) { - touchHistory.indexOfSingleActiveTouch = i; - break; - } - } - - { - var activeRecord = touchBank[touchHistory.indexOfSingleActiveTouch]; - - if (activeRecord == null || !activeRecord.touchActive) { - error("Cannot find single active touch."); - } - } - } - } - }, - touchHistory: touchHistory -}; - +function functionThatReturnsFalse() { + return false; +} /** - * Accumulates items that must not be null or undefined. + * Synthetic events are dispatched by event plugins, typically in response to a + * top-level event delegation handler. * - * This is used to conserve memory by avoiding array allocations. + * These systems should generally use pooling to reduce the frequency of garbage + * collection. The system should check `isPersistent` to determine whether the + * event should be released into the pool after being dispatched. Users that + * need a persisted event should invoke `persist`. * - * @return {*|array<*>} An accumulation of items. + * Synthetic events (and subclasses) implement the DOM Level 3 Events API by + * normalizing browser quirks. Subclasses do not necessarily have to implement a + * DOM interface; custom application-specific events can also subclass this. + * + * @param {object} dispatchConfig Configuration used to dispatch this event. + * @param {*} targetInst Marker identifying the event target. + * @param {object} nativeEvent Native browser event. + * @param {DOMEventTarget} nativeEventTarget Target node. */ -function accumulate(current, next) { - if (!(next != null)) { - throw Error( - "accumulate(...): Accumulated items must not be null or undefined." - ); +function SyntheticEvent( + dispatchConfig, + targetInst, + nativeEvent, + nativeEventTarget +) { + { + // these have a getter/setter for warnings + delete this.nativeEvent; + delete this.preventDefault; + delete this.stopPropagation; + delete this.isDefaultPrevented; + delete this.isPropagationStopped; } - if (current == null) { - return next; - } // Both are not empty. Warning: Never call x.concat(y) when you are not - // certain that x is an Array (x could be a string with concat method). + this.dispatchConfig = dispatchConfig; + this._targetInst = targetInst; + this.nativeEvent = nativeEvent; + var Interface = this.constructor.Interface; - if (Array.isArray(current)) { - return current.concat(next); + for (var propName in Interface) { + if (!Interface.hasOwnProperty(propName)) { + continue; + } + + { + delete this[propName]; // this has a getter/setter for warnings + } + + var normalize = Interface[propName]; + + if (normalize) { + this[propName] = normalize(nativeEvent); + } else { + if (propName === "target") { + this.target = nativeEventTarget; + } else { + this[propName] = nativeEvent[propName]; + } + } } - if (Array.isArray(next)) { - return [current].concat(next); + var defaultPrevented = + nativeEvent.defaultPrevented != null + ? nativeEvent.defaultPrevented + : nativeEvent.returnValue === false; + + if (defaultPrevented) { + this.isDefaultPrevented = functionThatReturnsTrue; + } else { + this.isDefaultPrevented = functionThatReturnsFalse; } - return [current, next]; + this.isPropagationStopped = functionThatReturnsFalse; + return this; } -/** - * Instance of element that should respond to touch/move types of interactions, - * as indicated explicitly by relevant callbacks. - */ +Object.assign(SyntheticEvent.prototype, { + preventDefault: function() { + this.defaultPrevented = true; + var event = this.nativeEvent; -var responderInst = null; -/** - * Count of current touches. A textInput should become responder iff the - * selection changes while there is a touch on the screen. - */ + if (!event) { + return; + } -var trackedTouchCount = 0; + if (event.preventDefault) { + event.preventDefault(); + } else if (typeof event.returnValue !== "unknown") { + event.returnValue = false; + } -var changeResponder = function(nextResponderInst, blockHostResponder) { - var oldResponderInst = responderInst; - responderInst = nextResponderInst; + this.isDefaultPrevented = functionThatReturnsTrue; + }, + stopPropagation: function() { + var event = this.nativeEvent; - if (ResponderEventPlugin.GlobalResponderHandler !== null) { - ResponderEventPlugin.GlobalResponderHandler.onChange( - oldResponderInst, - nextResponderInst, - blockHostResponder - ); - } -}; + if (!event) { + return; + } -var eventTypes = { - /** - * On a `touchStart`/`mouseDown`, is it desired that this element become the - * responder? - */ - startShouldSetResponder: { - phasedRegistrationNames: { - bubbled: "onStartShouldSetResponder", - captured: "onStartShouldSetResponderCapture" - }, - dependencies: startDependencies + if (event.stopPropagation) { + event.stopPropagation(); + } else if (typeof event.cancelBubble !== "unknown") { + // The ChangeEventPlugin registers a "propertychange" event for + // IE. This event does not support bubbling or cancelling, and + // any references to cancelBubble throw "Member not found". A + // typeof check of "unknown" circumvents this issue (and is also + // IE specific). + event.cancelBubble = true; + } + + this.isPropagationStopped = functionThatReturnsTrue; }, /** - * On a `scroll`, is it desired that this element become the responder? This - * is usually not needed, but should be used to retroactively infer that a - * `touchStart` had occurred during momentum scroll. During a momentum scroll, - * a touch start will be immediately followed by a scroll event if the view is - * currently scrolling. - * - * TODO: This shouldn't bubble. + * We release all dispatched `SyntheticEvent`s after each event loop, adding + * them back into the pool. This allows a way to hold onto a reference that + * won't be added back into the pool. */ - scrollShouldSetResponder: { - phasedRegistrationNames: { - bubbled: "onScrollShouldSetResponder", - captured: "onScrollShouldSetResponderCapture" - }, - dependencies: [TOP_SCROLL] + persist: function() { + this.isPersistent = functionThatReturnsTrue; }, /** - * On text selection change, should this element become the responder? This - * is needed for text inputs or other views with native selection, so the - * JS view can claim the responder. + * Checks if this event should be released back into the pool. * - * TODO: This shouldn't bubble. + * @return {boolean} True if this should not be released, false otherwise. */ - selectionChangeShouldSetResponder: { - phasedRegistrationNames: { - bubbled: "onSelectionChangeShouldSetResponder", - captured: "onSelectionChangeShouldSetResponderCapture" - }, - dependencies: [TOP_SELECTION_CHANGE] - }, + isPersistent: functionThatReturnsFalse, /** - * On a `touchMove`/`mouseMove`, is it desired that this element become the - * responder? + * `PooledClass` looks for `destructor` on each instance it releases. */ - moveShouldSetResponder: { - phasedRegistrationNames: { - bubbled: "onMoveShouldSetResponder", - captured: "onMoveShouldSetResponderCapture" - }, - dependencies: moveDependencies - }, + destructor: function() { + var Interface = this.constructor.Interface; - /** - * Direct responder events dispatched directly to responder. Do not bubble. - */ - responderStart: { - registrationName: "onResponderStart", - dependencies: startDependencies - }, - responderMove: { - registrationName: "onResponderMove", - dependencies: moveDependencies - }, - responderEnd: { - registrationName: "onResponderEnd", - dependencies: endDependencies - }, - responderRelease: { - registrationName: "onResponderRelease", - dependencies: endDependencies - }, - responderTerminationRequest: { - registrationName: "onResponderTerminationRequest", - dependencies: [] - }, - responderGrant: { - registrationName: "onResponderGrant", - dependencies: [] - }, - responderReject: { - registrationName: "onResponderReject", - dependencies: [] - }, - responderTerminate: { - registrationName: "onResponderTerminate", - dependencies: [] + for (var propName in Interface) { + { + Object.defineProperty( + this, + propName, + getPooledWarningPropertyDefinition(propName, Interface[propName]) + ); + } + } + + this.dispatchConfig = null; + this._targetInst = null; + this.nativeEvent = null; + this.isDefaultPrevented = functionThatReturnsFalse; + this.isPropagationStopped = functionThatReturnsFalse; + this._dispatchListeners = null; + this._dispatchInstances = null; + + { + Object.defineProperty( + this, + "nativeEvent", + getPooledWarningPropertyDefinition("nativeEvent", null) + ); + Object.defineProperty( + this, + "isDefaultPrevented", + getPooledWarningPropertyDefinition( + "isDefaultPrevented", + functionThatReturnsFalse + ) + ); + Object.defineProperty( + this, + "isPropagationStopped", + getPooledWarningPropertyDefinition( + "isPropagationStopped", + functionThatReturnsFalse + ) + ); + Object.defineProperty( + this, + "preventDefault", + getPooledWarningPropertyDefinition("preventDefault", function() {}) + ); + Object.defineProperty( + this, + "stopPropagation", + getPooledWarningPropertyDefinition("stopPropagation", function() {}) + ); + } + } +}); +SyntheticEvent.Interface = EventInterface; +/** + * Helper to reduce boilerplate when creating subclasses. + */ + +SyntheticEvent.extend = function(Interface) { + var Super = this; + + var E = function() {}; + + E.prototype = Super.prototype; + var prototype = new E(); + + function Class() { + return Super.apply(this, arguments); } + + Object.assign(prototype, Class.prototype); + Class.prototype = prototype; + Class.prototype.constructor = Class; + Class.Interface = Object.assign({}, Super.Interface, Interface); + Class.extend = Super.extend; + addEventPoolingTo(Class); + return Class; }; + +addEventPoolingTo(SyntheticEvent); /** + * Helper to nullify syntheticEvent instance properties when destructing * - * Responder System: - * ---------------- - * - * - A global, solitary "interaction lock" on a view. - * - If a node becomes the responder, it should convey visual feedback - * immediately to indicate so, either by highlighting or moving accordingly. - * - To be the responder means, that touches are exclusively important to that - * responder view, and no other view. - * - While touches are still occurring, the responder lock can be transferred to - * a new view, but only to increasingly "higher" views (meaning ancestors of - * the current responder). - * - * Responder being granted: - * ------------------------ - * - * - Touch starts, moves, and scrolls can cause an ID to become the responder. - * - We capture/bubble `startShouldSetResponder`/`moveShouldSetResponder` to - * the "appropriate place". - * - If nothing is currently the responder, the "appropriate place" is the - * initiating event's `targetID`. - * - If something *is* already the responder, the "appropriate place" is the - * first common ancestor of the event target and the current `responderInst`. - * - Some negotiation happens: See the timing diagram below. - * - Scrolled views automatically become responder. The reasoning is that a - * platform scroll view that isn't built on top of the responder system has - * began scrolling, and the active responder must now be notified that the - * interaction is no longer locked to it - the system has taken over. - * - * - Responder being released: - * As soon as no more touches that *started* inside of descendants of the - * *current* responderInst, an `onResponderRelease` event is dispatched to the - * current responder, and the responder lock is released. - * - * TODO: - * - on "end", a callback hook for `onResponderEndShouldRemainResponder` that - * determines if the responder lock should remain. - * - If a view shouldn't "remain" the responder, any active touches should by - * default be considered "dead" and do not influence future negotiations or - * bubble paths. It should be as if those touches do not exist. - * -- For multitouch: Usually a translate-z will choose to "remain" responder - * after one out of many touches ended. For translate-y, usually the view - * doesn't wish to "remain" responder after one of many touches end. - * - Consider building this on top of a `stopPropagation` model similar to - * `W3C` events. - * - Ensure that `onResponderTerminate` is called on touch cancels, whether or - * not `onResponderTerminationRequest` returns `true` or `false`. - * + * @param {String} propName + * @param {?object} getVal + * @return {object} defineProperty object */ -/* Negotiation Performed - +-----------------------+ - / \ -Process low level events to + Current Responder + wantsResponderID -determine who to perform negot-| (if any exists at all) | -iation/transition | Otherwise just pass through| --------------------------------+----------------------------+------------------+ -Bubble to find first ID | | -to return true:wantsResponderID| | - | | - +-------------+ | | - | onTouchStart| | | - +------+------+ none | | - | return| | -+-----------v-------------+true| +------------------------+ | -|onStartShouldSetResponder|----->|onResponderStart (cur) |<-----------+ -+-----------+-------------+ | +------------------------+ | | - | | | +--------+-------+ - | returned true for| false:REJECT +-------->|onResponderReject - | wantsResponderID | | | +----------------+ - | (now attempt | +------------------+-----+ | - | handoff) | | onResponder | | - +------------------->| TerminationRequest| | - | +------------------+-----+ | - | | | +----------------+ - | true:GRANT +-------->|onResponderGrant| - | | +--------+-------+ - | +------------------------+ | | - | | onResponderTerminate |<-----------+ - | +------------------+-----+ | - | | | +----------------+ - | +-------->|onResponderStart| - | | +----------------+ -Bubble to find first ID | | -to return true:wantsResponderID| | - | | - +-------------+ | | - | onTouchMove | | | - +------+------+ none | | - | return| | -+-----------v-------------+true| +------------------------+ | -|onMoveShouldSetResponder |----->|onResponderMove (cur) |<-----------+ -+-----------+-------------+ | +------------------------+ | | - | | | +--------+-------+ - | returned true for| false:REJECT +-------->|onResponderRejec| - | wantsResponderID | | | +----------------+ - | (now attempt | +------------------+-----+ | - | handoff) | | onResponder | | - +------------------->| TerminationRequest| | - | +------------------+-----+ | - | | | +----------------+ - | true:GRANT +-------->|onResponderGrant| - | | +--------+-------+ - | +------------------------+ | | - | | onResponderTerminate |<-----------+ - | +------------------+-----+ | - | | | +----------------+ - | +-------->|onResponderMove | - | | +----------------+ - | | - | | - Some active touch started| | - inside current responder | +------------------------+ | - +------------------------->| onResponderEnd | | - | | +------------------------+ | - +---+---------+ | | - | onTouchEnd | | | - +---+---------+ | | - | | +------------------------+ | - +------------------------->| onResponderEnd | | - No active touches started| +-----------+------------+ | - inside current responder | | | - | v | - | +------------------------+ | - | | onResponderRelease | | - | +------------------------+ | - | | - + + */ +function getPooledWarningPropertyDefinition(propName, getVal) { + var isFunction = typeof getVal === "function"; + return { + configurable: true, + set: set, + get: get + }; + + function set(val) { + var action = isFunction ? "setting the method" : "setting the property"; + warn(action, "This is effectively a no-op"); + return val; + } + + function get() { + var action = isFunction ? "accessing the method" : "accessing the property"; + var result = isFunction + ? "This is a no-op function" + : "This is set to null"; + warn(action, result); + return getVal; + } + + function warn(action, result) { + var warningCondition = false; + !warningCondition + ? warningWithoutStack$1( + false, + "This synthetic event is reused for performance reasons. If you're seeing this, " + + "you're %s `%s` on a released/nullified synthetic event. %s. " + + "If you must keep the original synthetic event around, use event.persist(). " + + "See https://fb.me/react-event-pooling for more information.", + action, + propName, + result + ) + : void 0; + } +} + +function getPooledEvent(dispatchConfig, targetInst, nativeEvent, nativeInst) { + var EventConstructor = this; + + if (EventConstructor.eventPool.length) { + var instance = EventConstructor.eventPool.pop(); + EventConstructor.call( + instance, + dispatchConfig, + targetInst, + nativeEvent, + nativeInst + ); + return instance; + } + + return new EventConstructor( + dispatchConfig, + targetInst, + nativeEvent, + nativeInst + ); +} + +function releasePooledEvent(event) { + var EventConstructor = this; + + if (!(event instanceof EventConstructor)) { + throw Error( + "Trying to release an event instance into a pool of a different type." + ); + } + + event.destructor(); + + if (EventConstructor.eventPool.length < EVENT_POOL_SIZE) { + EventConstructor.eventPool.push(event); + } +} + +function addEventPoolingTo(EventConstructor) { + EventConstructor.eventPool = []; + EventConstructor.getPooled = getPooledEvent; + EventConstructor.release = releasePooledEvent; +} + +/** + * `touchHistory` isn't actually on the native event, but putting it in the + * interface will ensure that it is cleaned up when pooled/destroyed. The + * `ResponderEventPlugin` will populate it appropriately. + */ + +var ResponderSyntheticEvent = SyntheticEvent.extend({ + touchHistory: function(nativeEvent) { + return null; // Actually doesn't even look at the native event. + } +}); + +var TOP_TOUCH_START = "topTouchStart"; +var TOP_TOUCH_MOVE = "topTouchMove"; +var TOP_TOUCH_END = "topTouchEnd"; +var TOP_TOUCH_CANCEL = "topTouchCancel"; +var TOP_SCROLL = "topScroll"; +var TOP_SELECTION_CHANGE = "topSelectionChange"; +function isStartish(topLevelType) { + return topLevelType === TOP_TOUCH_START; +} +function isMoveish(topLevelType) { + return topLevelType === TOP_TOUCH_MOVE; +} +function isEndish(topLevelType) { + return topLevelType === TOP_TOUCH_END || topLevelType === TOP_TOUCH_CANCEL; +} +var startDependencies = [TOP_TOUCH_START]; +var moveDependencies = [TOP_TOUCH_MOVE]; +var endDependencies = [TOP_TOUCH_CANCEL, TOP_TOUCH_END]; /** - * A note about event ordering in the `EventPluginRegistry`. - * - * Suppose plugins are injected in the following order: - * - * `[R, S, C]` - * - * To help illustrate the example, assume `S` is `SimpleEventPlugin` (for - * `onClick` etc) and `R` is `ResponderEventPlugin`. - * - * "Deferred-Dispatched Events": - * - * - The current event plugin system will traverse the list of injected plugins, - * in order, and extract events by collecting the plugin's return value of - * `extractEvents()`. - * - These events that are returned from `extractEvents` are "deferred - * dispatched events". - * - When returned from `extractEvents`, deferred-dispatched events contain an - * "accumulation" of deferred dispatches. - * - These deferred dispatches are accumulated/collected before they are - * returned, but processed at a later time by the `EventPluginRegistry` (hence the - * name deferred). - * - * In the process of returning their deferred-dispatched events, event plugins - * themselves can dispatch events on-demand without returning them from - * `extractEvents`. Plugins might want to do this, so that they can use event - * dispatching as a tool that helps them decide which events should be extracted - * in the first place. - * - * "On-Demand-Dispatched Events": - * - * - On-demand-dispatched events are not returned from `extractEvents`. - * - On-demand-dispatched events are dispatched during the process of returning - * the deferred-dispatched events. - * - They should not have side effects. - * - They should be avoided, and/or eventually be replaced with another - * abstraction that allows event plugins to perform multiple "rounds" of event - * extraction. - * - * Therefore, the sequence of event dispatches becomes: - * - * - `R`s on-demand events (if any) (dispatched by `R` on-demand) - * - `S`s on-demand events (if any) (dispatched by `S` on-demand) - * - `C`s on-demand events (if any) (dispatched by `C` on-demand) - * - `R`s extracted events (if any) (dispatched by `EventPluginRegistry`) - * - `S`s extracted events (if any) (dispatched by `EventPluginRegistry`) - * - `C`s extracted events (if any) (dispatched by `EventPluginRegistry`) - * - * In the case of `ResponderEventPlugin`: If the `startShouldSetResponder` - * on-demand dispatch returns `true` (and some other details are satisfied) the - * `onResponderGrant` deferred dispatched event is returned from - * `extractEvents`. The sequence of dispatch executions in this case - * will appear as follows: - * - * - `startShouldSetResponder` (`ResponderEventPlugin` dispatches on-demand) - * - `touchStartCapture` (`EventPluginRegistry` dispatches as usual) - * - `touchStart` (`EventPluginRegistry` dispatches as usual) - * - `responderGrant/Reject` (`EventPluginRegistry` dispatches as usual) + * Tracks the position and time of each active touch by `touch.identifier`. We + * should typically only see IDs in the range of 1-20 because IDs get recycled + * when touches end and start again. */ -function setResponderAndExtractTransfer( - topLevelType, - targetInst, - nativeEvent, - nativeEventTarget -) { - var shouldSetEventType = isStartish(topLevelType) - ? eventTypes.startShouldSetResponder - : isMoveish(topLevelType) - ? eventTypes.moveShouldSetResponder - : topLevelType === TOP_SELECTION_CHANGE - ? eventTypes.selectionChangeShouldSetResponder - : eventTypes.scrollShouldSetResponder; // TODO: stop one short of the current responder. +var MAX_TOUCH_BANK = 20; +var touchBank = []; +var touchHistory = { + touchBank: touchBank, + numberActiveTouches: 0, + // If there is only one active touch, we remember its location. This prevents + // us having to loop through all of the touches all the time in the most + // common case. + indexOfSingleActiveTouch: -1, + mostRecentTimeStamp: 0 +}; - var bubbleShouldSetFrom = !responderInst - ? targetInst - : getLowestCommonAncestor(responderInst, targetInst); // When capturing/bubbling the "shouldSet" event, we want to skip the target - // (deepest ID) if it happens to be the current responder. The reasoning: - // It's strange to get an `onMoveShouldSetResponder` when you're *already* - // the responder. +function timestampForTouch(touch) { + // The legacy internal implementation provides "timeStamp", which has been + // renamed to "timestamp". Let both work for now while we iron it out + // TODO (evv): rename timeStamp to timestamp in internal code + return touch.timeStamp || touch.timestamp; +} +/** + * TODO: Instead of making gestures recompute filtered velocity, we could + * include a built in velocity computation that can be reused globally. + */ - var skipOverBubbleShouldSetFrom = bubbleShouldSetFrom === responderInst; - var shouldSetEvent = ResponderSyntheticEvent.getPooled( - shouldSetEventType, - bubbleShouldSetFrom, - nativeEvent, - nativeEventTarget - ); - shouldSetEvent.touchHistory = ResponderTouchHistoryStore.touchHistory; +function createTouchRecord(touch) { + return { + touchActive: true, + startPageX: touch.pageX, + startPageY: touch.pageY, + startTimeStamp: timestampForTouch(touch), + currentPageX: touch.pageX, + currentPageY: touch.pageY, + currentTimeStamp: timestampForTouch(touch), + previousPageX: touch.pageX, + previousPageY: touch.pageY, + previousTimeStamp: timestampForTouch(touch) + }; +} - if (skipOverBubbleShouldSetFrom) { - accumulateTwoPhaseDispatchesSkipTarget(shouldSetEvent); - } else { - accumulateTwoPhaseDispatches(shouldSetEvent); +function resetTouchRecord(touchRecord, touch) { + touchRecord.touchActive = true; + touchRecord.startPageX = touch.pageX; + touchRecord.startPageY = touch.pageY; + touchRecord.startTimeStamp = timestampForTouch(touch); + touchRecord.currentPageX = touch.pageX; + touchRecord.currentPageY = touch.pageY; + touchRecord.currentTimeStamp = timestampForTouch(touch); + touchRecord.previousPageX = touch.pageX; + touchRecord.previousPageY = touch.pageY; + touchRecord.previousTimeStamp = timestampForTouch(touch); +} + +function getTouchIdentifier(_ref) { + var identifier = _ref.identifier; + + if (!(identifier != null)) { + throw Error("Touch object is missing identifier."); } - var wantsResponderInst = executeDispatchesInOrderStopAtTrue(shouldSetEvent); + { + !(identifier <= MAX_TOUCH_BANK) + ? warningWithoutStack$1( + false, + "Touch identifier %s is greater than maximum supported %s which causes " + + "performance issues backfilling array locations for all of the indices.", + identifier, + MAX_TOUCH_BANK + ) + : void 0; + } - if (!shouldSetEvent.isPersistent()) { - shouldSetEvent.constructor.release(shouldSetEvent); + return identifier; +} + +function recordTouchStart(touch) { + var identifier = getTouchIdentifier(touch); + var touchRecord = touchBank[identifier]; + + if (touchRecord) { + resetTouchRecord(touchRecord, touch); + } else { + touchBank[identifier] = createTouchRecord(touch); } - if (!wantsResponderInst || wantsResponderInst === responderInst) { - return null; + touchHistory.mostRecentTimeStamp = timestampForTouch(touch); +} + +function recordTouchMove(touch) { + var touchRecord = touchBank[getTouchIdentifier(touch)]; + + if (touchRecord) { + touchRecord.touchActive = true; + touchRecord.previousPageX = touchRecord.currentPageX; + touchRecord.previousPageY = touchRecord.currentPageY; + touchRecord.previousTimeStamp = touchRecord.currentTimeStamp; + touchRecord.currentPageX = touch.pageX; + touchRecord.currentPageY = touch.pageY; + touchRecord.currentTimeStamp = timestampForTouch(touch); + touchHistory.mostRecentTimeStamp = timestampForTouch(touch); + } else { + console.warn( + "Cannot record touch move without a touch start.\n" + "Touch Move: %s\n", + "Touch Bank: %s", + printTouch(touch), + printTouchBank() + ); } +} - var extracted; - var grantEvent = ResponderSyntheticEvent.getPooled( - eventTypes.responderGrant, - wantsResponderInst, - nativeEvent, - nativeEventTarget - ); - grantEvent.touchHistory = ResponderTouchHistoryStore.touchHistory; - accumulateDirectDispatches(grantEvent); - var blockHostResponder = executeDirectDispatch(grantEvent) === true; +function recordTouchEnd(touch) { + var touchRecord = touchBank[getTouchIdentifier(touch)]; - if (responderInst) { - var terminationRequestEvent = ResponderSyntheticEvent.getPooled( - eventTypes.responderTerminationRequest, - responderInst, - nativeEvent, - nativeEventTarget + if (touchRecord) { + touchRecord.touchActive = false; + touchRecord.previousPageX = touchRecord.currentPageX; + touchRecord.previousPageY = touchRecord.currentPageY; + touchRecord.previousTimeStamp = touchRecord.currentTimeStamp; + touchRecord.currentPageX = touch.pageX; + touchRecord.currentPageY = touch.pageY; + touchRecord.currentTimeStamp = timestampForTouch(touch); + touchHistory.mostRecentTimeStamp = timestampForTouch(touch); + } else { + console.warn( + "Cannot record touch end without a touch start.\n" + "Touch End: %s\n", + "Touch Bank: %s", + printTouch(touch), + printTouchBank() ); - terminationRequestEvent.touchHistory = - ResponderTouchHistoryStore.touchHistory; - accumulateDirectDispatches(terminationRequestEvent); - var shouldSwitch = - !hasDispatches(terminationRequestEvent) || - executeDirectDispatch(terminationRequestEvent); + } +} - if (!terminationRequestEvent.isPersistent()) { - terminationRequestEvent.constructor.release(terminationRequestEvent); - } +function printTouch(touch) { + return JSON.stringify({ + identifier: touch.identifier, + pageX: touch.pageX, + pageY: touch.pageY, + timestamp: timestampForTouch(touch) + }); +} + +function printTouchBank() { + var printed = JSON.stringify(touchBank.slice(0, MAX_TOUCH_BANK)); + + if (touchBank.length > MAX_TOUCH_BANK) { + printed += " (original size: " + touchBank.length + ")"; + } + + return printed; +} + +var ResponderTouchHistoryStore = { + recordTouchTrack: function(topLevelType, nativeEvent) { + if (isMoveish(topLevelType)) { + nativeEvent.changedTouches.forEach(recordTouchMove); + } else if (isStartish(topLevelType)) { + nativeEvent.changedTouches.forEach(recordTouchStart); + touchHistory.numberActiveTouches = nativeEvent.touches.length; + + if (touchHistory.numberActiveTouches === 1) { + touchHistory.indexOfSingleActiveTouch = + nativeEvent.touches[0].identifier; + } + } else if (isEndish(topLevelType)) { + nativeEvent.changedTouches.forEach(recordTouchEnd); + touchHistory.numberActiveTouches = nativeEvent.touches.length; + + if (touchHistory.numberActiveTouches === 1) { + for (var i = 0; i < touchBank.length; i++) { + var touchTrackToCheck = touchBank[i]; + + if (touchTrackToCheck != null && touchTrackToCheck.touchActive) { + touchHistory.indexOfSingleActiveTouch = i; + break; + } + } - if (shouldSwitch) { - var terminateEvent = ResponderSyntheticEvent.getPooled( - eventTypes.responderTerminate, - responderInst, - nativeEvent, - nativeEventTarget - ); - terminateEvent.touchHistory = ResponderTouchHistoryStore.touchHistory; - accumulateDirectDispatches(terminateEvent); - extracted = accumulate(extracted, [grantEvent, terminateEvent]); - changeResponder(wantsResponderInst, blockHostResponder); - } else { - var rejectEvent = ResponderSyntheticEvent.getPooled( - eventTypes.responderReject, - wantsResponderInst, - nativeEvent, - nativeEventTarget - ); - rejectEvent.touchHistory = ResponderTouchHistoryStore.touchHistory; - accumulateDirectDispatches(rejectEvent); - extracted = accumulate(extracted, rejectEvent); + { + var activeRecord = touchBank[touchHistory.indexOfSingleActiveTouch]; + !(activeRecord != null && activeRecord.touchActive) + ? warningWithoutStack$1(false, "Cannot find single active touch.") + : void 0; + } + } } - } else { - extracted = accumulate(extracted, grantEvent); - changeResponder(wantsResponderInst, blockHostResponder); - } + }, + touchHistory: touchHistory +}; - return extracted; -} /** - * A transfer is a negotiation between a currently set responder and the next - * element to claim responder status. Any start event could trigger a transfer - * of responderInst. Any move event could trigger a transfer. + * Accumulates items that must not be null or undefined. * - * @param {string} topLevelType Record from `BrowserEventConstants`. - * @return {boolean} True if a transfer of responder could possibly occur. - */ - -function canTriggerTransfer(topLevelType, topLevelInst, nativeEvent) { - return ( - topLevelInst && // responderIgnoreScroll: We are trying to migrate away from specifically - // tracking native scroll events here and responderIgnoreScroll indicates we - // will send topTouchCancel to handle canceling touch events instead - ((topLevelType === TOP_SCROLL && !nativeEvent.responderIgnoreScroll) || - (trackedTouchCount > 0 && topLevelType === TOP_SELECTION_CHANGE) || - isStartish(topLevelType) || - isMoveish(topLevelType)) - ); -} -/** - * Returns whether or not this touch end event makes it such that there are no - * longer any touches that started inside of the current `responderInst`. + * This is used to conserve memory by avoiding array allocations. * - * @param {NativeEvent} nativeEvent Native touch end event. - * @return {boolean} Whether or not this touch end event ends the responder. + * @return {*|array<*>} An accumulation of items. */ -function noResponderTouches(nativeEvent) { - var touches = nativeEvent.touches; - - if (!touches || touches.length === 0) { - return true; +function accumulate(current, next) { + if (!(next != null)) { + throw Error( + "accumulate(...): Accumulated items must not be null or undefined." + ); } - for (var i = 0; i < touches.length; i++) { - var activeTouch = touches[i]; - var target = activeTouch.target; + if (current == null) { + return next; + } // Both are not empty. Warning: Never call x.concat(y) when you are not + // certain that x is an Array (x could be a string with concat method). - if (target !== null && target !== undefined && target !== 0) { - // Is the original touch location inside of the current responder? - var targetInst = getInstanceFromNode(target); + if (Array.isArray(current)) { + return current.concat(next); + } - if (isAncestor(responderInst, targetInst)) { - return false; - } - } + if (Array.isArray(next)) { + return [current].concat(next); } - return true; + return [current, next]; } -var ResponderEventPlugin = { - /* For unit testing only */ - _getResponder: function() { - return responderInst; - }, - eventTypes: eventTypes, +/** + * Instance of element that should respond to touch/move types of interactions, + * as indicated explicitly by relevant callbacks. + */ - /** - * We must be resilient to `targetInst` being `null` on `touchMove` or - * `touchEnd`. On certain platforms, this means that a native scroll has - * assumed control and the original touch targets are destroyed. - */ - extractEvents: function( - topLevelType, - targetInst, - nativeEvent, - nativeEventTarget, - eventSystemFlags - ) { - if (isStartish(topLevelType)) { - trackedTouchCount += 1; - } else if (isEndish(topLevelType)) { - if (trackedTouchCount >= 0) { - trackedTouchCount -= 1; - } else { - { - warn( - "Ended a touch event which was not counted in `trackedTouchCount`." - ); - } +var responderInst = null; +/** + * Count of current touches. A textInput should become responder iff the + * selection changes while there is a touch on the screen. + */ - return null; - } - } +var trackedTouchCount = 0; - ResponderTouchHistoryStore.recordTouchTrack(topLevelType, nativeEvent); - var extracted = canTriggerTransfer(topLevelType, targetInst, nativeEvent) - ? setResponderAndExtractTransfer( - topLevelType, - targetInst, - nativeEvent, - nativeEventTarget - ) - : null; // Responder may or may not have transferred on a new touch start/move. - // Regardless, whoever is the responder after any potential transfer, we - // direct all touch start/move/ends to them in the form of - // `onResponderMove/Start/End`. These will be called for *every* additional - // finger that move/start/end, dispatched directly to whoever is the - // current responder at that moment, until the responder is "released". - // - // These multiple individual change touch events are are always bookended - // by `onResponderGrant`, and one of - // (`onResponderRelease/onResponderTerminate`). +var changeResponder = function(nextResponderInst, blockHostResponder) { + var oldResponderInst = responderInst; + responderInst = nextResponderInst; - var isResponderTouchStart = responderInst && isStartish(topLevelType); - var isResponderTouchMove = responderInst && isMoveish(topLevelType); - var isResponderTouchEnd = responderInst && isEndish(topLevelType); - var incrementalTouch = isResponderTouchStart - ? eventTypes.responderStart - : isResponderTouchMove - ? eventTypes.responderMove - : isResponderTouchEnd - ? eventTypes.responderEnd - : null; + if (ResponderEventPlugin.GlobalResponderHandler !== null) { + ResponderEventPlugin.GlobalResponderHandler.onChange( + oldResponderInst, + nextResponderInst, + blockHostResponder + ); + } +}; - if (incrementalTouch) { - var gesture = ResponderSyntheticEvent.getPooled( - incrementalTouch, - responderInst, - nativeEvent, - nativeEventTarget - ); - gesture.touchHistory = ResponderTouchHistoryStore.touchHistory; - accumulateDirectDispatches(gesture); - extracted = accumulate(extracted, gesture); - } +var eventTypes = { + /** + * On a `touchStart`/`mouseDown`, is it desired that this element become the + * responder? + */ + startShouldSetResponder: { + phasedRegistrationNames: { + bubbled: "onStartShouldSetResponder", + captured: "onStartShouldSetResponderCapture" + }, + dependencies: startDependencies + }, - var isResponderTerminate = - responderInst && topLevelType === TOP_TOUCH_CANCEL; - var isResponderRelease = - responderInst && - !isResponderTerminate && - isEndish(topLevelType) && - noResponderTouches(nativeEvent); - var finalTouch = isResponderTerminate - ? eventTypes.responderTerminate - : isResponderRelease - ? eventTypes.responderRelease - : null; + /** + * On a `scroll`, is it desired that this element become the responder? This + * is usually not needed, but should be used to retroactively infer that a + * `touchStart` had occurred during momentum scroll. During a momentum scroll, + * a touch start will be immediately followed by a scroll event if the view is + * currently scrolling. + * + * TODO: This shouldn't bubble. + */ + scrollShouldSetResponder: { + phasedRegistrationNames: { + bubbled: "onScrollShouldSetResponder", + captured: "onScrollShouldSetResponderCapture" + }, + dependencies: [TOP_SCROLL] + }, - if (finalTouch) { - var finalEvent = ResponderSyntheticEvent.getPooled( - finalTouch, - responderInst, - nativeEvent, - nativeEventTarget - ); - finalEvent.touchHistory = ResponderTouchHistoryStore.touchHistory; - accumulateDirectDispatches(finalEvent); - extracted = accumulate(extracted, finalEvent); - changeResponder(null); - } + /** + * On text selection change, should this element become the responder? This + * is needed for text inputs or other views with native selection, so the + * JS view can claim the responder. + * + * TODO: This shouldn't bubble. + */ + selectionChangeShouldSetResponder: { + phasedRegistrationNames: { + bubbled: "onSelectionChangeShouldSetResponder", + captured: "onSelectionChangeShouldSetResponderCapture" + }, + dependencies: [TOP_SELECTION_CHANGE] + }, + + /** + * On a `touchMove`/`mouseMove`, is it desired that this element become the + * responder? + */ + moveShouldSetResponder: { + phasedRegistrationNames: { + bubbled: "onMoveShouldSetResponder", + captured: "onMoveShouldSetResponderCapture" + }, + dependencies: moveDependencies + }, - return extracted; + /** + * Direct responder events dispatched directly to responder. Do not bubble. + */ + responderStart: { + registrationName: "onResponderStart", + dependencies: startDependencies }, - GlobalResponderHandler: null, - injection: { - /** - * @param {{onChange: (ReactID, ReactID) => void} GlobalResponderHandler - * Object that handles any change in responder. Use this to inject - * integration with an existing touch handling system etc. - */ - injectGlobalResponderHandler: function(GlobalResponderHandler) { - ResponderEventPlugin.GlobalResponderHandler = GlobalResponderHandler; - } + responderMove: { + registrationName: "onResponderMove", + dependencies: moveDependencies + }, + responderEnd: { + registrationName: "onResponderEnd", + dependencies: endDependencies + }, + responderRelease: { + registrationName: "onResponderRelease", + dependencies: endDependencies + }, + responderTerminationRequest: { + registrationName: "onResponderTerminationRequest", + dependencies: [] + }, + responderGrant: { + registrationName: "onResponderGrant", + dependencies: [] + }, + responderReject: { + registrationName: "onResponderReject", + dependencies: [] + }, + responderTerminate: { + registrationName: "onResponderTerminate", + dependencies: [] } }; - -/** - * Injectable ordering of event plugins. - */ -var eventPluginOrder = null; /** - * Injectable mapping from names to event plugin modules. + * + * Responder System: + * ---------------- + * + * - A global, solitary "interaction lock" on a view. + * - If a node becomes the responder, it should convey visual feedback + * immediately to indicate so, either by highlighting or moving accordingly. + * - To be the responder means, that touches are exclusively important to that + * responder view, and no other view. + * - While touches are still occurring, the responder lock can be transferred to + * a new view, but only to increasingly "higher" views (meaning ancestors of + * the current responder). + * + * Responder being granted: + * ------------------------ + * + * - Touch starts, moves, and scrolls can cause an ID to become the responder. + * - We capture/bubble `startShouldSetResponder`/`moveShouldSetResponder` to + * the "appropriate place". + * - If nothing is currently the responder, the "appropriate place" is the + * initiating event's `targetID`. + * - If something *is* already the responder, the "appropriate place" is the + * first common ancestor of the event target and the current `responderInst`. + * - Some negotiation happens: See the timing diagram below. + * - Scrolled views automatically become responder. The reasoning is that a + * platform scroll view that isn't built on top of the responder system has + * began scrolling, and the active responder must now be notified that the + * interaction is no longer locked to it - the system has taken over. + * + * - Responder being released: + * As soon as no more touches that *started* inside of descendants of the + * *current* responderInst, an `onResponderRelease` event is dispatched to the + * current responder, and the responder lock is released. + * + * TODO: + * - on "end", a callback hook for `onResponderEndShouldRemainResponder` that + * determines if the responder lock should remain. + * - If a view shouldn't "remain" the responder, any active touches should by + * default be considered "dead" and do not influence future negotiations or + * bubble paths. It should be as if those touches do not exist. + * -- For multitouch: Usually a translate-z will choose to "remain" responder + * after one out of many touches ended. For translate-y, usually the view + * doesn't wish to "remain" responder after one of many touches end. + * - Consider building this on top of a `stopPropagation` model similar to + * `W3C` events. + * - Ensure that `onResponderTerminate` is called on touch cancels, whether or + * not `onResponderTerminationRequest` returns `true` or `false`. + * */ -var namesToPlugins = {}; +/* Negotiation Performed + +-----------------------+ + / \ +Process low level events to + Current Responder + wantsResponderID +determine who to perform negot-| (if any exists at all) | +iation/transition | Otherwise just pass through| +-------------------------------+----------------------------+------------------+ +Bubble to find first ID | | +to return true:wantsResponderID| | + | | + +-------------+ | | + | onTouchStart| | | + +------+------+ none | | + | return| | ++-----------v-------------+true| +------------------------+ | +|onStartShouldSetResponder|----->|onResponderStart (cur) |<-----------+ ++-----------+-------------+ | +------------------------+ | | + | | | +--------+-------+ + | returned true for| false:REJECT +-------->|onResponderReject + | wantsResponderID | | | +----------------+ + | (now attempt | +------------------+-----+ | + | handoff) | | onResponder | | + +------------------->| TerminationRequest| | + | +------------------+-----+ | + | | | +----------------+ + | true:GRANT +-------->|onResponderGrant| + | | +--------+-------+ + | +------------------------+ | | + | | onResponderTerminate |<-----------+ + | +------------------+-----+ | + | | | +----------------+ + | +-------->|onResponderStart| + | | +----------------+ +Bubble to find first ID | | +to return true:wantsResponderID| | + | | + +-------------+ | | + | onTouchMove | | | + +------+------+ none | | + | return| | ++-----------v-------------+true| +------------------------+ | +|onMoveShouldSetResponder |----->|onResponderMove (cur) |<-----------+ ++-----------+-------------+ | +------------------------+ | | + | | | +--------+-------+ + | returned true for| false:REJECT +-------->|onResponderRejec| + | wantsResponderID | | | +----------------+ + | (now attempt | +------------------+-----+ | + | handoff) | | onResponder | | + +------------------->| TerminationRequest| | + | +------------------+-----+ | + | | | +----------------+ + | true:GRANT +-------->|onResponderGrant| + | | +--------+-------+ + | +------------------------+ | | + | | onResponderTerminate |<-----------+ + | +------------------+-----+ | + | | | +----------------+ + | +-------->|onResponderMove | + | | +----------------+ + | | + | | + Some active touch started| | + inside current responder | +------------------------+ | + +------------------------->| onResponderEnd | | + | | +------------------------+ | + +---+---------+ | | + | onTouchEnd | | | + +---+---------+ | | + | | +------------------------+ | + +------------------------->| onResponderEnd | | + No active touches started| +-----------+------------+ | + inside current responder | | | + | v | + | +------------------------+ | + | | onResponderRelease | | + | +------------------------+ | + | | + + + */ + /** - * Recomputes the plugin list using the injected plugins and plugin ordering. + * A note about event ordering in the `EventPluginHub`. * - * @private + * Suppose plugins are injected in the following order: + * + * `[R, S, C]` + * + * To help illustrate the example, assume `S` is `SimpleEventPlugin` (for + * `onClick` etc) and `R` is `ResponderEventPlugin`. + * + * "Deferred-Dispatched Events": + * + * - The current event plugin system will traverse the list of injected plugins, + * in order, and extract events by collecting the plugin's return value of + * `extractEvents()`. + * - These events that are returned from `extractEvents` are "deferred + * dispatched events". + * - When returned from `extractEvents`, deferred-dispatched events contain an + * "accumulation" of deferred dispatches. + * - These deferred dispatches are accumulated/collected before they are + * returned, but processed at a later time by the `EventPluginHub` (hence the + * name deferred). + * + * In the process of returning their deferred-dispatched events, event plugins + * themselves can dispatch events on-demand without returning them from + * `extractEvents`. Plugins might want to do this, so that they can use event + * dispatching as a tool that helps them decide which events should be extracted + * in the first place. + * + * "On-Demand-Dispatched Events": + * + * - On-demand-dispatched events are not returned from `extractEvents`. + * - On-demand-dispatched events are dispatched during the process of returning + * the deferred-dispatched events. + * - They should not have side effects. + * - They should be avoided, and/or eventually be replaced with another + * abstraction that allows event plugins to perform multiple "rounds" of event + * extraction. + * + * Therefore, the sequence of event dispatches becomes: + * + * - `R`s on-demand events (if any) (dispatched by `R` on-demand) + * - `S`s on-demand events (if any) (dispatched by `S` on-demand) + * - `C`s on-demand events (if any) (dispatched by `C` on-demand) + * - `R`s extracted events (if any) (dispatched by `EventPluginHub`) + * - `S`s extracted events (if any) (dispatched by `EventPluginHub`) + * - `C`s extracted events (if any) (dispatched by `EventPluginHub`) + * + * In the case of `ResponderEventPlugin`: If the `startShouldSetResponder` + * on-demand dispatch returns `true` (and some other details are satisfied) the + * `onResponderGrant` deferred dispatched event is returned from + * `extractEvents`. The sequence of dispatch executions in this case + * will appear as follows: + * + * - `startShouldSetResponder` (`ResponderEventPlugin` dispatches on-demand) + * - `touchStartCapture` (`EventPluginHub` dispatches as usual) + * - `touchStart` (`EventPluginHub` dispatches as usual) + * - `responderGrant/Reject` (`EventPluginHub` dispatches as usual) */ -function recomputePluginOrdering() { - if (!eventPluginOrder) { - // Wait until an `eventPluginOrder` is injected. - return; - } - - for (var pluginName in namesToPlugins) { - var pluginModule = namesToPlugins[pluginName]; - var pluginIndex = eventPluginOrder.indexOf(pluginName); +function setResponderAndExtractTransfer( + topLevelType, + targetInst, + nativeEvent, + nativeEventTarget +) { + var shouldSetEventType = isStartish(topLevelType) + ? eventTypes.startShouldSetResponder + : isMoveish(topLevelType) + ? eventTypes.moveShouldSetResponder + : topLevelType === TOP_SELECTION_CHANGE + ? eventTypes.selectionChangeShouldSetResponder + : eventTypes.scrollShouldSetResponder; // TODO: stop one short of the current responder. - if (!(pluginIndex > -1)) { - throw Error( - "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + - pluginName + - "`." - ); - } + var bubbleShouldSetFrom = !responderInst + ? targetInst + : getLowestCommonAncestor(responderInst, targetInst); // When capturing/bubbling the "shouldSet" event, we want to skip the target + // (deepest ID) if it happens to be the current responder. The reasoning: + // It's strange to get an `onMoveShouldSetResponder` when you're *already* + // the responder. - if (plugins[pluginIndex]) { - continue; - } + var skipOverBubbleShouldSetFrom = bubbleShouldSetFrom === responderInst; + var shouldSetEvent = ResponderSyntheticEvent.getPooled( + shouldSetEventType, + bubbleShouldSetFrom, + nativeEvent, + nativeEventTarget + ); + shouldSetEvent.touchHistory = ResponderTouchHistoryStore.touchHistory; - if (!pluginModule.extractEvents) { - throw Error( - "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + - pluginName + - "` does not." - ); - } + if (skipOverBubbleShouldSetFrom) { + accumulateTwoPhaseDispatchesSkipTarget(shouldSetEvent); + } else { + accumulateTwoPhaseDispatches(shouldSetEvent); + } - plugins[pluginIndex] = pluginModule; - var publishedEvents = pluginModule.eventTypes; + var wantsResponderInst = executeDispatchesInOrderStopAtTrue(shouldSetEvent); - for (var eventName in publishedEvents) { - if ( - !publishEventForPlugin( - publishedEvents[eventName], - pluginModule, - eventName - ) - ) { - throw Error( - "EventPluginRegistry: Failed to publish event `" + - eventName + - "` for plugin `" + - pluginName + - "`." - ); - } - } + if (!shouldSetEvent.isPersistent()) { + shouldSetEvent.constructor.release(shouldSetEvent); } -} -/** - * Publishes an event so that it can be dispatched by the supplied plugin. - * - * @param {object} dispatchConfig Dispatch configuration for the event. - * @param {object} PluginModule Plugin publishing the event. - * @return {boolean} True if the event was successfully published. - * @private - */ -function publishEventForPlugin(dispatchConfig, pluginModule, eventName) { - if (!!eventNameDispatchConfigs.hasOwnProperty(eventName)) { - throw Error( - "EventPluginRegistry: More than one plugin attempted to publish the same event name, `" + - eventName + - "`." - ); + if (!wantsResponderInst || wantsResponderInst === responderInst) { + return null; } - eventNameDispatchConfigs[eventName] = dispatchConfig; - var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; + var extracted; + var grantEvent = ResponderSyntheticEvent.getPooled( + eventTypes.responderGrant, + wantsResponderInst, + nativeEvent, + nativeEventTarget + ); + grantEvent.touchHistory = ResponderTouchHistoryStore.touchHistory; + accumulateDirectDispatches(grantEvent); + var blockHostResponder = executeDirectDispatch(grantEvent) === true; - if (phasedRegistrationNames) { - for (var phaseName in phasedRegistrationNames) { - if (phasedRegistrationNames.hasOwnProperty(phaseName)) { - var phasedRegistrationName = phasedRegistrationNames[phaseName]; - publishRegistrationName( - phasedRegistrationName, - pluginModule, - eventName - ); - } + if (responderInst) { + var terminationRequestEvent = ResponderSyntheticEvent.getPooled( + eventTypes.responderTerminationRequest, + responderInst, + nativeEvent, + nativeEventTarget + ); + terminationRequestEvent.touchHistory = + ResponderTouchHistoryStore.touchHistory; + accumulateDirectDispatches(terminationRequestEvent); + var shouldSwitch = + !hasDispatches(terminationRequestEvent) || + executeDirectDispatch(terminationRequestEvent); + + if (!terminationRequestEvent.isPersistent()) { + terminationRequestEvent.constructor.release(terminationRequestEvent); } - return true; - } else if (dispatchConfig.registrationName) { - publishRegistrationName( - dispatchConfig.registrationName, - pluginModule, - eventName - ); - return true; + if (shouldSwitch) { + var terminateEvent = ResponderSyntheticEvent.getPooled( + eventTypes.responderTerminate, + responderInst, + nativeEvent, + nativeEventTarget + ); + terminateEvent.touchHistory = ResponderTouchHistoryStore.touchHistory; + accumulateDirectDispatches(terminateEvent); + extracted = accumulate(extracted, [grantEvent, terminateEvent]); + changeResponder(wantsResponderInst, blockHostResponder); + } else { + var rejectEvent = ResponderSyntheticEvent.getPooled( + eventTypes.responderReject, + wantsResponderInst, + nativeEvent, + nativeEventTarget + ); + rejectEvent.touchHistory = ResponderTouchHistoryStore.touchHistory; + accumulateDirectDispatches(rejectEvent); + extracted = accumulate(extracted, rejectEvent); + } + } else { + extracted = accumulate(extracted, grantEvent); + changeResponder(wantsResponderInst, blockHostResponder); } - return false; + return extracted; } /** - * Publishes a registration name that is used to identify dispatched events. + * A transfer is a negotiation between a currently set responder and the next + * element to claim responder status. Any start event could trigger a transfer + * of responderInst. Any move event could trigger a transfer. * - * @param {string} registrationName Registration name to add. - * @param {object} PluginModule Plugin publishing the event. - * @private + * @param {string} topLevelType Record from `BrowserEventConstants`. + * @return {boolean} True if a transfer of responder could possibly occur. */ -function publishRegistrationName(registrationName, pluginModule, eventName) { - if (!!registrationNameModules[registrationName]) { - throw Error( - "EventPluginRegistry: More than one plugin attempted to publish the same registration name, `" + - registrationName + - "`." - ); - } - - registrationNameModules[registrationName] = pluginModule; - registrationNameDependencies[registrationName] = - pluginModule.eventTypes[eventName].dependencies; - - { - var lowerCasedName = registrationName.toLowerCase(); - } +function canTriggerTransfer(topLevelType, topLevelInst, nativeEvent) { + return ( + topLevelInst && // responderIgnoreScroll: We are trying to migrate away from specifically + // tracking native scroll events here and responderIgnoreScroll indicates we + // will send topTouchCancel to handle canceling touch events instead + ((topLevelType === TOP_SCROLL && !nativeEvent.responderIgnoreScroll) || + (trackedTouchCount > 0 && topLevelType === TOP_SELECTION_CHANGE) || + isStartish(topLevelType) || + isMoveish(topLevelType)) + ); } /** - * Registers plugins so that they can extract and dispatch events. + * Returns whether or not this touch end event makes it such that there are no + * longer any touches that started inside of the current `responderInst`. + * + * @param {NativeEvent} nativeEvent Native touch end event. + * @return {boolean} Whether or not this touch end event ends the responder. */ -/** - * Ordered list of injected plugins. - */ +function noResponderTouches(nativeEvent) { + var touches = nativeEvent.touches; -var plugins = []; -/** - * Mapping from event name to dispatch config - */ + if (!touches || touches.length === 0) { + return true; + } -var eventNameDispatchConfigs = {}; -/** - * Mapping from registration name to plugin module - */ + for (var i = 0; i < touches.length; i++) { + var activeTouch = touches[i]; + var target = activeTouch.target; -var registrationNameModules = {}; -/** - * Mapping from registration name to event name - */ + if (target !== null && target !== undefined && target !== 0) { + // Is the original touch location inside of the current responder? + var targetInst = getInstanceFromNode(target); -var registrationNameDependencies = {}; + if (isAncestor(responderInst, targetInst)) { + return false; + } + } + } -/** - * Injects an ordering of plugins (by plugin name). This allows the ordering - * to be decoupled from injection of the actual plugins so that ordering is - * always deterministic regardless of packaging, on-the-fly injection, etc. - * - * @param {array} InjectedEventPluginOrder - * @internal - */ + return true; +} -function injectEventPluginOrder(injectedEventPluginOrder) { - if (!!eventPluginOrder) { - throw Error( - "EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React." - ); - } // Clone the ordering so it cannot be dynamically mutated. +var ResponderEventPlugin = { + /* For unit testing only */ + _getResponder: function() { + return responderInst; + }, + eventTypes: eventTypes, + + /** + * We must be resilient to `targetInst` being `null` on `touchMove` or + * `touchEnd`. On certain platforms, this means that a native scroll has + * assumed control and the original touch targets are destroyed. + */ + extractEvents: function( + topLevelType, + targetInst, + nativeEvent, + nativeEventTarget, + eventSystemFlags + ) { + if (isStartish(topLevelType)) { + trackedTouchCount += 1; + } else if (isEndish(topLevelType)) { + if (trackedTouchCount >= 0) { + trackedTouchCount -= 1; + } else { + console.warn( + "Ended a touch event which was not counted in `trackedTouchCount`." + ); + return null; + } + } - eventPluginOrder = Array.prototype.slice.call(injectedEventPluginOrder); - recomputePluginOrdering(); -} -/** - * Injects plugins to be used by plugin event system. The plugin names must be - * in the ordering injected by `injectEventPluginOrder`. - * - * Plugins can be injected as part of page initialization or on-the-fly. - * - * @param {object} injectedNamesToPlugins Map from names to plugin modules. - * @internal - */ + ResponderTouchHistoryStore.recordTouchTrack(topLevelType, nativeEvent); + var extracted = canTriggerTransfer(topLevelType, targetInst, nativeEvent) + ? setResponderAndExtractTransfer( + topLevelType, + targetInst, + nativeEvent, + nativeEventTarget + ) + : null; // Responder may or may not have transferred on a new touch start/move. + // Regardless, whoever is the responder after any potential transfer, we + // direct all touch start/move/ends to them in the form of + // `onResponderMove/Start/End`. These will be called for *every* additional + // finger that move/start/end, dispatched directly to whoever is the + // current responder at that moment, until the responder is "released". + // + // These multiple individual change touch events are are always bookended + // by `onResponderGrant`, and one of + // (`onResponderRelease/onResponderTerminate`). -function injectEventPluginsByName(injectedNamesToPlugins) { - var isOrderingDirty = false; + var isResponderTouchStart = responderInst && isStartish(topLevelType); + var isResponderTouchMove = responderInst && isMoveish(topLevelType); + var isResponderTouchEnd = responderInst && isEndish(topLevelType); + var incrementalTouch = isResponderTouchStart + ? eventTypes.responderStart + : isResponderTouchMove + ? eventTypes.responderMove + : isResponderTouchEnd + ? eventTypes.responderEnd + : null; - for (var pluginName in injectedNamesToPlugins) { - if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) { - continue; + if (incrementalTouch) { + var gesture = ResponderSyntheticEvent.getPooled( + incrementalTouch, + responderInst, + nativeEvent, + nativeEventTarget + ); + gesture.touchHistory = ResponderTouchHistoryStore.touchHistory; + accumulateDirectDispatches(gesture); + extracted = accumulate(extracted, gesture); } - var pluginModule = injectedNamesToPlugins[pluginName]; - - if ( - !namesToPlugins.hasOwnProperty(pluginName) || - namesToPlugins[pluginName] !== pluginModule - ) { - if (!!namesToPlugins[pluginName]) { - throw Error( - "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - pluginName + - "`." - ); - } + var isResponderTerminate = + responderInst && topLevelType === TOP_TOUCH_CANCEL; + var isResponderRelease = + responderInst && + !isResponderTerminate && + isEndish(topLevelType) && + noResponderTouches(nativeEvent); + var finalTouch = isResponderTerminate + ? eventTypes.responderTerminate + : isResponderRelease + ? eventTypes.responderRelease + : null; - namesToPlugins[pluginName] = pluginModule; - isOrderingDirty = true; + if (finalTouch) { + var finalEvent = ResponderSyntheticEvent.getPooled( + finalTouch, + responderInst, + nativeEvent, + nativeEventTarget + ); + finalEvent.touchHistory = ResponderTouchHistoryStore.touchHistory; + accumulateDirectDispatches(finalEvent); + extracted = accumulate(extracted, finalEvent); + changeResponder(null); } - } - if (isOrderingDirty) { - recomputePluginOrdering(); + return extracted; + }, + GlobalResponderHandler: null, + injection: { + /** + * @param {{onChange: (ReactID, ReactID) => void} GlobalResponderHandler + * Object that handles any change in responder. Use this to inject + * integration with an existing touch handling system etc. + */ + injectGlobalResponderHandler: function(GlobalResponderHandler) { + ResponderEventPlugin.GlobalResponderHandler = GlobalResponderHandler; + } } -} +}; var customBubblingEventTypes = - ReactNativePrivateInterface.ReactNativeViewConfigRegistry - .customBubblingEventTypes, - customDirectEventTypes = - ReactNativePrivateInterface.ReactNativeViewConfigRegistry - .customDirectEventTypes; + ReactNativePrivateInterface.ReactNativeViewConfigRegistry + .customBubblingEventTypes; +var customDirectEventTypes = + ReactNativePrivateInterface.ReactNativeViewConfigRegistry + .customDirectEventTypes; var ReactNativeBridgeEventPlugin = { eventTypes: {}, + + /** + * @see {EventPluginHub.extractEvents} + */ extractEvents: function( topLevelType, targetInst, @@ -2410,21 +2550,50 @@ var ReactNativeEventPluginOrder = [ * ensures it exists in the dependency graph and can be `require`d. * TODO: require this in packager, not in React #10932517 */ +// Module provided by RN: /** * Inject module for resolving DOM hierarchy and plugin ordering. */ -injectEventPluginOrder(ReactNativeEventPluginOrder); +injection.injectEventPluginOrder(ReactNativeEventPluginOrder); /** * Some important event plugins included by default (without having to require * them). */ -injectEventPluginsByName({ +injection.injectEventPluginsByName({ ResponderEventPlugin: ResponderEventPlugin, ReactNativeBridgeEventPlugin: ReactNativeBridgeEventPlugin }); +// Uncomment to re-export dynamic flags from the fbsource version. +var _require = require("../shims/ReactFeatureFlags"); +var enableNativeTargetAsInstance = _require.enableNativeTargetAsInstance; // The rest of the flags are static for better dead code elimination. + +var enableUserTimingAPI = true; +var enableProfilerTimer = true; +var enableSchedulerTracing = true; +var enableSuspenseServerRenderer = false; + +var debugRenderPhaseSideEffectsForStrictMode = true; + +var replayFailedUnitOfWorkWithInvokeGuardedCallback = true; +var warnAboutDeprecatedLifecycles = true; +var enableFlareAPI = false; +var enableFundamentalAPI = false; +var enableScopeAPI = false; + +var warnAboutUnmockedScheduler = true; +var flushSuspenseFallbacksInTests = true; +var enableSuspenseCallback = false; +var warnAboutDefaultPropsOnFunctionComponents = false; +var warnAboutStringRefs = false; +var disableLegacyContext = false; +var disableSchedulerTimeoutBasedOnReactExpirationTime = false; +// Only used in www builds. + +// Flow magic to verify the exports of this file match the original version. + var instanceCache = new Map(); var instanceProps = new Map(); function precacheFiberNode(hostInst, tag) { @@ -2440,20 +2609,35 @@ function getInstanceFromTag(tag) { } function getTagFromInstance(inst) { - var nativeInstance = inst.stateNode; - var tag = nativeInstance._nativeTag; + if (enableNativeTargetAsInstance) { + var nativeInstance = inst.stateNode; + var tag = nativeInstance._nativeTag; - if (tag === undefined) { - nativeInstance = nativeInstance.canonical; - tag = nativeInstance._nativeTag; - } + if (tag === undefined) { + nativeInstance = nativeInstance.canonical; + tag = nativeInstance._nativeTag; + } - if (!tag) { - throw Error("All native instances should have a tag."); - } + if (!tag) { + throw Error("All native instances should have a tag."); + } + + return nativeInstance; + } else { + var _tag = inst.stateNode._nativeTag; + + if (_tag === undefined) { + _tag = inst.stateNode.canonical._nativeTag; + } + + if (!_tag) { + throw Error("All native instances should have a tag."); + } - return nativeInstance; + return _tag; + } } + function getFiberCurrentPropsFromNode$1(stateNode) { return instanceProps.get(stateNode._nativeTag) || null; } @@ -2463,9 +2647,50 @@ function updateFiberProps(tag, props) { var PLUGIN_EVENT_SYSTEM = 1; -var enableProfilerTimer = true; -var enableFundamentalAPI = false; -var warnAboutStringRefs = false; +var restoreImpl = null; +var restoreTarget = null; +var restoreQueue = null; + +function restoreStateOfTarget(target) { + // We perform this translation at the end of the event loop so that we + // always receive the correct fiber here + var internalInstance = getInstanceFromNode(target); + + if (!internalInstance) { + // Unmounted + return; + } + + if (!(typeof restoreImpl === "function")) { + throw Error( + "setRestoreImplementation() needs to be called to handle a target for controlled events. This error is likely caused by a bug in React. Please file an issue." + ); + } + + var props = getFiberCurrentPropsFromNode(internalInstance.stateNode); + restoreImpl(internalInstance.stateNode, internalInstance.type, props); +} + +function needsStateRestore() { + return restoreTarget !== null || restoreQueue !== null; +} +function restoreStateIfNeeded() { + if (!restoreTarget) { + return; + } + + var target = restoreTarget; + var queuedTargets = restoreQueue; + restoreTarget = null; + restoreQueue = null; + restoreStateOfTarget(target); + + if (queuedTargets) { + for (var i = 0; i < queuedTargets.length; i++) { + restoreStateOfTarget(queuedTargets[i]); + } + } +} // the renderer. Such as when we're dispatching events or if third party // libraries need to call batchedUpdates. Eventually, this API will go away when @@ -2476,7 +2701,25 @@ var warnAboutStringRefs = false; var batchedUpdatesImpl = function(fn, bookkeeping) { return fn(bookkeeping); }; + +var flushDiscreteUpdatesImpl = function() {}; + var isInsideEventHandler = false; +function finishEventHandler() { + // Here we wait until all updates have propagated, which is important + // when using controlled components within layers: + // https://github.com/facebook/react/issues/1698 + // Then we restore state of any controlled component. + var controlledComponentsHavePendingUpdates = needsStateRestore(); + + if (controlledComponentsHavePendingUpdates) { + // If a controlled event was fired, we may need to restore the state of + // the DOM node back to the controlled value. This is necessary when React + // bails out of the update without touching the DOM. + flushDiscreteUpdatesImpl(); + restoreStateIfNeeded(); + } +} function batchedUpdates(fn, bookkeeping) { if (isInsideEventHandler) { @@ -2491,8 +2734,11 @@ function batchedUpdates(fn, bookkeeping) { return batchedUpdatesImpl(fn, bookkeeping); } finally { isInsideEventHandler = false; + finishEventHandler(); } } +// This is for the React Flare event system + function setBatchingImplementation( _batchedUpdatesImpl, _discreteUpdatesImpl, @@ -2500,57 +2746,7 @@ function setBatchingImplementation( _batchedEventUpdatesImpl ) { batchedUpdatesImpl = _batchedUpdatesImpl; -} - -/** - * Internal queue of events that have accumulated their dispatches and are - * waiting to have their dispatches executed. - */ - -var eventQueue = null; -/** - * Dispatches an event and releases it back into the pool, unless persistent. - * - * @param {?object} event Synthetic event to be dispatched. - * @private - */ - -var executeDispatchesAndRelease = function(event) { - if (event) { - executeDispatchesInOrder(event); - - if (!event.isPersistent()) { - event.constructor.release(event); - } - } -}; - -var executeDispatchesAndReleaseTopLevel = function(e) { - return executeDispatchesAndRelease(e); -}; - -function runEventsInBatch(events) { - if (events !== null) { - eventQueue = accumulateInto(eventQueue, events); - } // Set `eventQueue` to null before processing it so that we can tell if more - // events get enqueued while processing. - - var processingEventQueue = eventQueue; - eventQueue = null; - - if (!processingEventQueue) { - return; - } - - forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseTopLevel); - - if (!!eventQueue) { - throw Error( - "processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented." - ); - } // This would be a good time to rethrow if any of the event handlers threw. - - rethrowCaughtError(); + flushDiscreteUpdatesImpl = _flushDiscreteUpdatesImpl; } /** @@ -2630,75 +2826,24 @@ function _receiveRootNodeIDEvent(rootNodeID, topLevelType, nativeEventParam) { var inst = getInstanceFromTag(rootNodeID); var target = null; - if (inst != null) { - target = inst.stateNode; - } - - batchedUpdates(function() { - runExtractedPluginEventsInBatch( - topLevelType, - inst, - nativeEvent, - target, - PLUGIN_EVENT_SYSTEM - ); - }); // React Native doesn't use ReactControlledComponent but if it did, here's - // where it would do it. -} -/** - * Allows registered plugins an opportunity to extract events from top-level - * native browser events. - * - * @return {*} An accumulation of synthetic events. - * @internal - */ - -function extractPluginEvents( - topLevelType, - targetInst, - nativeEvent, - nativeEventTarget, - eventSystemFlags -) { - var events = null; - - for (var i = 0; i < plugins.length; i++) { - // Not every plugin in the ordering may be loaded at runtime. - var possiblePlugin = plugins[i]; - - if (possiblePlugin) { - var extractedEvents = possiblePlugin.extractEvents( - topLevelType, - targetInst, - nativeEvent, - nativeEventTarget, - eventSystemFlags - ); - - if (extractedEvents) { - events = accumulateInto(events, extractedEvents); - } + if (enableNativeTargetAsInstance) { + if (inst != null) { + target = inst.stateNode; } + } else { + target = nativeEvent.target; } - return events; -} - -function runExtractedPluginEventsInBatch( - topLevelType, - targetInst, - nativeEvent, - nativeEventTarget, - eventSystemFlags -) { - var events = extractPluginEvents( - topLevelType, - targetInst, - nativeEvent, - nativeEventTarget, - eventSystemFlags - ); - runEventsInBatch(events); + batchedUpdates(function() { + runExtractedPluginEventsInBatch( + topLevelType, + inst, + nativeEvent, + target, + PLUGIN_EVENT_SYSTEM + ); + }); // React Native doesn't use ReactControlledComponent but if it did, here's + // where it would do it. } /** * Publicly exposed method on module for native objc to invoke when a top @@ -2756,7 +2901,10 @@ function receiveTouches(eventTopLevelType, touches, changedIndices) { if (target !== null && target !== undefined) { if (target < 1) { { - error("A view is reporting that a touch occurred on tag zero."); + warningWithoutStack$1( + false, + "A view is reporting that a touch occurred on tag zero." + ); } } else { rootNodeID = target; @@ -2808,13 +2956,38 @@ ResponderEventPlugin.injection.injectGlobalResponderHandler( * Note that this module is currently shared and assumed to be stateless. * If this becomes an actual Map, that will break. */ + +/** + * This API should be called `delete` but we'd have to make sure to always + * transform these to strings for IE support. When this transform is fully + * supported we can rename it. + */ + function get(key) { return key._reactInternalFiber; } + function set(key, value) { key._reactInternalFiber = value; } +var ReactSharedInternals = + React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; // Prevent newer renderers from RTE when used with older react package versions. +// Current owner and dispatcher used to share the same ref, +// but PR #14548 split them out to better support the react-debug-tools package. + +if (!ReactSharedInternals.hasOwnProperty("ReactCurrentDispatcher")) { + ReactSharedInternals.ReactCurrentDispatcher = { + current: null + }; +} + +if (!ReactSharedInternals.hasOwnProperty("ReactCurrentBatchConfig")) { + ReactSharedInternals.ReactCurrentBatchConfig = { + suspense: null + }; +} + // The Symbol used to tag the ReactElement-like types. If there is no native Symbol // nor polyfill, then a plain number is used for performance. var hasSymbol = typeof Symbol === "function" && Symbol.for; @@ -2827,6 +3000,8 @@ var REACT_STRICT_MODE_TYPE = hasSymbol var REACT_PROFILER_TYPE = hasSymbol ? Symbol.for("react.profiler") : 0xead2; var REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for("react.provider") : 0xeacd; var REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for("react.context") : 0xeace; // TODO: We don't use AsyncMode or ConcurrentMode anymore. They were temporary +// (unstable) APIs that have been removed. Can we remove the symbols? + var REACT_CONCURRENT_MODE_TYPE = hasSymbol ? Symbol.for("react.concurrent_mode") : 0xeacf; @@ -2839,7 +3014,11 @@ var REACT_SUSPENSE_LIST_TYPE = hasSymbol : 0xead8; var REACT_MEMO_TYPE = hasSymbol ? Symbol.for("react.memo") : 0xead3; var REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 0xead4; -var REACT_BLOCK_TYPE = hasSymbol ? Symbol.for("react.block") : 0xead9; +var REACT_FUNDAMENTAL_TYPE = hasSymbol + ? Symbol.for("react.fundamental") + : 0xead5; +var REACT_RESPONDER_TYPE = hasSymbol ? Symbol.for("react.responder") : 0xead6; +var REACT_SCOPE_TYPE = hasSymbol ? Symbol.for("react.scope") : 0xead7; var MAYBE_ITERATOR_SYMBOL = typeof Symbol === "function" && Symbol.iterator; var FAUX_ITERATOR_SYMBOL = "@@iterator"; function getIteratorFn(maybeIterable) { @@ -2858,29 +3037,56 @@ function getIteratorFn(maybeIterable) { return null; } -// TODO: Move this to "react" once we can import from externals. +/** + * Similar to invariant but only logs a warning if the condition is not met. + * This can be used to log issues in development environments in critical + * paths. Removing the logging code for production environments will keep the + * same logic and follow the same code paths. + */ + +var warning = warningWithoutStack$1; + +{ + warning = function(condition, format) { + if (condition) { + return; + } + + var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; + var stack = ReactDebugCurrentFrame.getStackAddendum(); // eslint-disable-next-line react-internal/warning-and-invariant-args + + for ( + var _len = arguments.length, + args = new Array(_len > 2 ? _len - 2 : 0), + _key = 2; + _key < _len; + _key++ + ) { + args[_key - 2] = arguments[_key]; + } + + warningWithoutStack$1.apply( + void 0, + [false, format + "%s"].concat(args, [stack]) + ); + }; +} + +var warning$1 = warning; + var Uninitialized = -1; var Pending = 0; var Resolved = 1; var Rejected = 2; - function refineResolvedLazyComponent(lazyComponent) { return lazyComponent._status === Resolved ? lazyComponent._result : null; } function initializeLazyComponentType(lazyComponent) { if (lazyComponent._status === Uninitialized) { - var ctor = lazyComponent._result; - - if (!ctor) { - // TODO: Remove this later. THis only exists in case you use an older "react" package. - ctor = lazyComponent._ctor; - } - - var thenable = ctor(); // Transition to the next state. - - var pending = lazyComponent; - pending._status = Pending; - pending._result = thenable; + lazyComponent._status = Pending; + var ctor = lazyComponent._ctor; + var thenable = ctor(); + lazyComponent._result = thenable; thenable.then( function(moduleObject) { if (lazyComponent._status === Pending) { @@ -2888,27 +3094,24 @@ function initializeLazyComponentType(lazyComponent) { { if (defaultExport === undefined) { - error( + warning$1( + false, "lazy: Expected the result of a dynamic import() call. " + - "Instead received: %s\n\nYour code should look like: \n " + // Break up imports to avoid accidentally parsing them as dependencies. - "const MyComponent = lazy(() => imp" + - "ort('./MyComponent'))", + "Instead received: %s\n\nYour code should look like: \n " + + "const MyComponent = lazy(() => import('./MyComponent'))", moduleObject ); } - } // Transition to the next state. + } - var resolved = lazyComponent; - resolved._status = Resolved; - resolved._result = defaultExport; + lazyComponent._status = Resolved; + lazyComponent._result = defaultExport; } }, function(error) { if (lazyComponent._status === Pending) { - // Transition to the next state. - var rejected = lazyComponent; - rejected._status = Rejected; - rejected._result = error; + lazyComponent._status = Rejected; + lazyComponent._result = error; } } ); @@ -2923,10 +3126,6 @@ function getWrappedName(outerType, innerType, wrapperName) { ); } -function getContextName(type) { - return type.displayName || "Context"; -} - function getComponentName(type) { if (type == null) { // Host root, text node or just invalid type. @@ -2935,7 +3134,8 @@ function getComponentName(type) { { if (typeof type.tag === "number") { - error( + warningWithoutStack$1( + false, "Received an unexpected object in getComponentName(). " + "This is likely a bug in React. Please file an issue." ); @@ -2973,12 +3173,10 @@ function getComponentName(type) { if (typeof type === "object") { switch (type.$$typeof) { case REACT_CONTEXT_TYPE: - var context = type; - return getContextName(context) + ".Consumer"; + return "Context.Consumer"; case REACT_PROVIDER_TYPE: - var provider = type; - return getContextName(provider._context) + ".Provider"; + return "Context.Provider"; case REACT_FORWARD_REF_TYPE: return getWrappedName(type, type.render, "ForwardRef"); @@ -2986,9 +3184,6 @@ function getComponentName(type) { case REACT_MEMO_TYPE: return getComponentName(type.type); - case REACT_BLOCK_TYPE: - return getComponentName(type.render); - case REACT_LAZY_TYPE: { var thenable = type; var resolvedThenable = refineResolvedLazyComponent(thenable); @@ -3064,7 +3259,7 @@ var ShouldCapture = /* */ 4096; -var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner; +var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner; function getNearestMountedFiber(fiber) { var node = fiber; var nearestMounted = fiber; @@ -3101,28 +3296,28 @@ function getNearestMountedFiber(fiber) { return null; } + function isFiberMounted(fiber) { return getNearestMountedFiber(fiber) === fiber; } function isMounted(component) { { - var owner = ReactCurrentOwner.current; + var owner = ReactCurrentOwner$1.current; if (owner !== null && owner.tag === ClassComponent) { var ownerFiber = owner; var instance = ownerFiber.stateNode; - - if (!instance._warnedAboutRefsInRender) { - error( - "%s is accessing isMounted inside its render() function. " + - "render() should be a pure function of props and state. It should " + - "never access something that requires stale data from the previous " + - "render, such as refs. Move this logic to componentDidMount and " + - "componentDidUpdate instead.", - getComponentName(ownerFiber.type) || "A component" - ); - } - + !instance._warnedAboutRefsInRender + ? warningWithoutStack$1( + false, + "%s is accessing isMounted inside its render() function. " + + "render() should be a pure function of props and state. It should " + + "never access something that requires stale data from the previous " + + "render, such as refs. Move this logic to componentDidMount and " + + "componentDidUpdate instead.", + getComponentName(ownerFiber.type) || "A component" + ) + : void 0; instance._warnedAboutRefsInRender = true; } } @@ -3825,49 +4020,71 @@ function mountSafeCallback_NOT_REALLY_SAFE(context, callback) { return callback.apply(context, arguments); }; } +function throwOnStylesProp(component, props) { + if (props.styles !== undefined) { + var owner = component._owner || null; + var name = component.constructor.displayName; + var msg = + "`styles` is not a supported property of `" + + name + + "`, did " + + "you mean `style` (singular)?"; + + if (owner && owner.constructor && owner.constructor.displayName) { + msg += + "\n\nCheck the `" + + owner.constructor.displayName + + "` parent " + + " component."; + } + + throw new Error(msg); + } +} function warnForStyleProps(props, validAttributes) { - { - for (var key in validAttributes.style) { - if (!(validAttributes[key] || props[key] === undefined)) { - error( - "You are setting the style `{ %s" + - ": ... }` as a prop. You " + - "should nest it in a style object. " + - "E.g. `{ style: { %s" + - ": ... } }`", - key, - key - ); - } + for (var key in validAttributes.style) { + if (!(validAttributes[key] || props[key] === undefined)) { + console.error( + "You are setting the style `{ " + + key + + ": ... }` as a prop. You " + + "should nest it in a style object. " + + "E.g. `{ style: { " + + key + + ": ... } }`" + ); } } } +// Modules provided by RN: +/** + * This component defines the same methods as NativeMethodsMixin but without the + * findNodeHandle wrapper. This wrapper is unnecessary for HostComponent views + * and would also result in a circular require.js dependency (since + * ReactNativeFiber depends on this component and NativeMethodsMixin depends on + * ReactNativeFiber). + */ + var ReactNativeFiberHostComponent = /*#__PURE__*/ (function() { - function ReactNativeFiberHostComponent( - tag, - viewConfig, - internalInstanceHandleDEV - ) { + function ReactNativeFiberHostComponent(tag, viewConfig) { this._nativeTag = tag; this._children = []; this.viewConfig = viewConfig; - - { - this._internalFiberInstanceHandleDEV = internalInstanceHandleDEV; - } } var _proto = ReactNativeFiberHostComponent.prototype; _proto.blur = function blur() { - ReactNativePrivateInterface.TextInputState.blurTextInput(this); + ReactNativePrivateInterface.TextInputState.blurTextInput(this._nativeTag); }; _proto.focus = function focus() { - ReactNativePrivateInterface.TextInputState.focusTextInput(this); + ReactNativePrivateInterface.TextInputState.focusTextInput( + this._nativeTag + ); }; _proto.measure = function measure(callback) { @@ -3895,21 +4112,15 @@ var ReactNativeFiberHostComponent = if (typeof relativeToNativeNode === "number") { // Already a node handle relativeNode = relativeToNativeNode; - } else { - var nativeNode = relativeToNativeNode; - - if (nativeNode._nativeTag) { - relativeNode = nativeNode._nativeTag; - } + } else if (relativeToNativeNode._nativeTag) { + relativeNode = relativeToNativeNode._nativeTag; } if (relativeNode == null) { - { - error( - "Warning: ref.measureLayout must be called with a node handle or a ref to a native component." - ); - } - + warningWithoutStack$1( + false, + "Warning: ref.measureLayout must be called with a node handle or a ref to a native component." + ); return; } @@ -3945,15 +4156,60 @@ var ReactNativeFiberHostComponent = // can re-export everything from this module. function shim() { + { + throw Error( + "The current renderer does not support persistence. This error is likely caused by a bug in React. Please file an issue." + ); + } +} // Persistence (when unsupported) + +var supportsPersistence = false; +var cloneInstance = shim; +var cloneFundamentalInstance = shim; +var createContainerChildSet = shim; +var appendChildToContainerChildSet = shim; +var finalizeContainerChildren = shim; +var replaceContainerChildren = shim; +var cloneHiddenInstance = shim; +var cloneHiddenTextInstance = shim; + +// can re-export everything from this module. + +function shim$1() { { throw Error( "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." ); } } // Hydration (when unsupported) -var isSuspenseInstancePending = shim; -var isSuspenseInstanceFallback = shim; -var hydrateTextInstance = shim; + +var supportsHydration = false; +var canHydrateInstance = shim$1; +var canHydrateTextInstance = shim$1; +var canHydrateSuspenseInstance = shim$1; +var isSuspenseInstancePending = shim$1; +var isSuspenseInstanceFallback = shim$1; +var registerSuspenseInstanceRetry = shim$1; +var getNextHydratableSibling = shim$1; +var getFirstHydratableChild = shim$1; +var hydrateInstance = shim$1; +var hydrateTextInstance = shim$1; +var hydrateSuspenseInstance = shim$1; +var getNextHydratableInstanceAfterSuspenseInstance = shim$1; +var commitHydratedContainer = shim$1; +var commitHydratedSuspenseInstance = shim$1; +var clearSuspenseBoundary = shim$1; +var clearSuspenseBoundaryFromContainer = shim$1; +var didNotMatchHydratedContainerTextInstance = shim$1; +var didNotMatchHydratedTextInstance = shim$1; +var didNotHydrateContainerInstance = shim$1; +var didNotHydrateInstance = shim$1; +var didNotFindHydratableContainerInstance = shim$1; +var didNotFindHydratableContainerTextInstance = shim$1; +var didNotFindHydratableContainerSuspenseInstance = shim$1; +var didNotFindHydratableInstance = shim$1; +var didNotFindHydratableTextInstance = shim$1; +var didNotFindHydratableSuspenseInstance = shim$1; var getViewConfigForType = ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get; @@ -3988,6 +4244,7 @@ function recursivelyUncacheFiberNode(node) { node._children.forEach(recursivelyUncacheFiberNode); } } + function appendInitialChild(parentInstance, child) { parentInstance._children.push(child); } @@ -4018,11 +4275,7 @@ function createInstance( rootContainerInstance, // rootTag updatePayload // props ); - var component = new ReactNativeFiberHostComponent( - tag, - viewConfig, - internalInstanceHandle - ); + var component = new ReactNativeFiberHostComponent(tag, viewConfig); 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. @@ -4117,6 +4370,8 @@ function prepareUpdate( function resetAfterCommit(containerInfo) { // Noop } +var isPrimaryRenderer = true; +var warnsIfNotActing = true; var scheduleTimeout = setTimeout; var cancelTimeout = clearTimeout; var noTimeout = -1; @@ -4132,6 +4387,10 @@ function shouldSetTextContent(type, props) { // More context @ github.com/facebook/react/pull/8560#discussion_r92111303 return false; } // ------------------- +// Mutation +// ------------------- + +var supportsMutation = true; function appendChild(parentInstance, child) { var childTag = typeof child === "number" ? child : child._nativeTag; var children = parentInstance._children; @@ -4176,6 +4435,7 @@ function commitTextUpdate(textInstance, oldText, newText) { } // props ); } + function commitUpdate( instance, updatePayloadTODO, @@ -4305,81 +4565,156 @@ function unhideInstance(instance, props) { updatePayload ); } -function unhideTextInstance(textInstance, text) { - throw new Error("Not yet implemented."); +function unhideTextInstance(textInstance, text) { + throw new Error("Not yet implemented."); +} +function mountResponderInstance( + responder, + responderInstance, + props, + state, + instance +) { + throw new Error("Not yet implemented."); +} +function unmountResponderInstance(responderInstance) { + throw new Error("Not yet implemented."); +} +function getFundamentalComponentInstance(fundamentalInstance) { + throw new Error("Not yet implemented."); +} +function mountFundamentalComponent(fundamentalInstance) { + throw new Error("Not yet implemented."); +} +function shouldUpdateFundamentalComponent(fundamentalInstance) { + throw new Error("Not yet implemented."); +} +function updateFundamentalComponent(fundamentalInstance) { + throw new Error("Not yet implemented."); +} +function unmountFundamentalComponent(fundamentalInstance) { + throw new Error("Not yet implemented."); +} +function getInstanceFromNode$1(node) { + throw new Error("Not yet implemented."); +} + +var BEFORE_SLASH_RE = /^(.*)[\\\/]/; +var describeComponentFrame = function(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]; + + if (pathBeforeSlash) { + var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, ""); + fileName = folderName + "/" + fileName; + } + } + } + } + + sourceInfo = " (at " + fileName + ":" + source.lineNumber + ")"; + } else if (ownerName) { + sourceInfo = " (created by " + ownerName + ")"; + } + + return "\n in " + (name || "Unknown") + sourceInfo; +}; + +var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; + +function describeFiber(fiber) { + switch (fiber.tag) { + case HostRoot: + case HostPortal: + case HostText: + case Fragment: + case ContextProvider: + case ContextConsumer: + return ""; + + default: + var owner = fiber._debugOwner; + var source = fiber._debugSource; + var name = getComponentName(fiber.type); + var ownerName = null; + + if (owner) { + ownerName = getComponentName(owner.type); + } + + return describeComponentFrame(name, source, ownerName); + } +} + +function getStackByFiberInDevAndProd(workInProgress) { + var info = ""; + var node = workInProgress; + + do { + info += describeFiber(node); + node = node.return; + } while (node); + + return info; +} +var current = null; +var phase = null; +function getCurrentFiberOwnerNameInDevOrNull() { + { + if (current === null) { + return null; + } + + var owner = current._debugOwner; + + if (owner !== null && typeof owner !== "undefined") { + return getComponentName(owner.type); + } + } + + return null; +} +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. + + return getStackByFiberInDevAndProd(current); + } + + return ""; +} +function resetCurrentFiber() { + { + ReactDebugCurrentFrame.getCurrentStack = null; + current = null; + phase = null; + } +} +function setCurrentFiber(fiber) { + { + ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackInDev; + current = fiber; + phase = null; + } } - -var loggedTypeFailures = {}; -function checkPropTypes(typeSpecs, values, location, componentName) { +function setCurrentPhase(lifeCyclePhase) { { - // $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)) { - 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 ( - 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; - - error("Failed %s type: %s", location, error$1.message); - } - } - } + phase = lifeCyclePhase; } } @@ -4559,12 +4894,12 @@ var resumeTimers = function() { }; function recordEffect() { - { + if (enableUserTimingAPI) { effectCountInCurrentCommit++; } } function recordScheduleUpdate() { - { + if (enableUserTimingAPI) { if (isCommitting) { hasScheduledUpdateInCurrentCommit = true; } @@ -4578,8 +4913,9 @@ function recordScheduleUpdate() { } } } + function startWorkTimer(fiber) { - { + if (enableUserTimingAPI) { if (!supportsUserTiming || shouldIgnoreFiber(fiber)) { return; } // If we pause, this is the fiber to unwind from. @@ -4594,7 +4930,7 @@ function startWorkTimer(fiber) { } } function cancelWorkTimer(fiber) { - { + if (enableUserTimingAPI) { if (!supportsUserTiming || shouldIgnoreFiber(fiber)) { return; } // Remember we shouldn't complete measurement for this fiber. @@ -4605,7 +4941,7 @@ function cancelWorkTimer(fiber) { } } function stopWorkTimer(fiber) { - { + if (enableUserTimingAPI) { if (!supportsUserTiming || shouldIgnoreFiber(fiber)) { return; } // If we pause, its parent is the fiber to unwind from. @@ -4621,7 +4957,7 @@ function stopWorkTimer(fiber) { } } function stopFailedWorkTimer(fiber) { - { + if (enableUserTimingAPI) { if (!supportsUserTiming || shouldIgnoreFiber(fiber)) { return; } // If we pause, its parent is the fiber to unwind from. @@ -4641,7 +4977,7 @@ function stopFailedWorkTimer(fiber) { } } function startPhaseTimer(fiber, phase) { - { + if (enableUserTimingAPI) { if (!supportsUserTiming) { return; } @@ -4657,7 +4993,7 @@ function startPhaseTimer(fiber, phase) { } } function stopPhaseTimer() { - { + if (enableUserTimingAPI) { if (!supportsUserTiming) { return; } @@ -4674,7 +5010,7 @@ function stopPhaseTimer() { } } function startWorkLoopTimer(nextUnitOfWork) { - { + if (enableUserTimingAPI) { currentFiber = nextUnitOfWork; if (!supportsUserTiming) { @@ -4690,7 +5026,7 @@ function startWorkLoopTimer(nextUnitOfWork) { } } function stopWorkLoopTimer(interruptedBy, didCompleteRoot) { - { + if (enableUserTimingAPI) { if (!supportsUserTiming) { return; } @@ -4719,7 +5055,7 @@ function stopWorkLoopTimer(interruptedBy, didCompleteRoot) { } } function startCommitTimer() { - { + if (enableUserTimingAPI) { if (!supportsUserTiming) { return; } @@ -4731,7 +5067,7 @@ function startCommitTimer() { } } function stopCommitTimer() { - { + if (enableUserTimingAPI) { if (!supportsUserTiming) { return; } @@ -4752,7 +5088,7 @@ function stopCommitTimer() { } } function startCommitSnapshotEffectsTimer() { - { + if (enableUserTimingAPI) { if (!supportsUserTiming) { return; } @@ -4762,7 +5098,7 @@ function startCommitSnapshotEffectsTimer() { } } function stopCommitSnapshotEffectsTimer() { - { + if (enableUserTimingAPI) { if (!supportsUserTiming) { return; } @@ -4777,7 +5113,7 @@ function stopCommitSnapshotEffectsTimer() { } } function startCommitHostEffectsTimer() { - { + if (enableUserTimingAPI) { if (!supportsUserTiming) { return; } @@ -4787,7 +5123,7 @@ function startCommitHostEffectsTimer() { } } function stopCommitHostEffectsTimer() { - { + if (enableUserTimingAPI) { if (!supportsUserTiming) { return; } @@ -4802,7 +5138,7 @@ function stopCommitHostEffectsTimer() { } } function startCommitLifeCyclesTimer() { - { + if (enableUserTimingAPI) { if (!supportsUserTiming) { return; } @@ -4812,7 +5148,7 @@ function startCommitLifeCyclesTimer() { } } function stopCommitLifeCyclesTimer() { - { + if (enableUserTimingAPI) { if (!supportsUserTiming) { return; } @@ -4845,7 +5181,7 @@ function createCursor(defaultValue) { function pop(cursor, fiber) { if (index < 0) { { - error("Unexpected pop."); + warningWithoutStack$1(false, "Unexpected pop."); } return; @@ -4853,7 +5189,7 @@ function pop(cursor, fiber) { { if (fiber !== fiberStack[index]) { - error("Unexpected Fiber popped."); + warningWithoutStack$1(false, "Unexpected Fiber popped."); } } @@ -4903,7 +5239,9 @@ function getUnmaskedContext( Component, didPushOwnContextIfProvider ) { - { + if (disableLegacyContext) { + return emptyContextObject; + } else { 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 @@ -4917,7 +5255,9 @@ function getUnmaskedContext( } function cacheContext(workInProgress, unmaskedContext, maskedContext) { - { + if (disableLegacyContext) { + return; + } else { var instance = workInProgress.stateNode; instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext; instance.__reactInternalMemoizedMaskedChildContext = maskedContext; @@ -4925,7 +5265,9 @@ function cacheContext(workInProgress, unmaskedContext, maskedContext) { } function getMaskedContext(workInProgress, unmaskedContext) { - { + if (disableLegacyContext) { + return emptyContextObject; + } else { var type = workInProgress.type; var contextTypes = type.contextTypes; @@ -4952,7 +5294,13 @@ function getMaskedContext(workInProgress, unmaskedContext) { { var name = getComponentName(type) || "Unknown"; - checkPropTypes(contextTypes, context, "context", name); + checkPropTypes( + contextTypes, + context, + "context", + name, + getCurrentFiberStackInDev + ); } // 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. @@ -4965,34 +5313,44 @@ function getMaskedContext(workInProgress, unmaskedContext) { } function hasContextChanged() { - { + if (disableLegacyContext) { + return false; + } else { return didPerformWorkStackCursor.current; } } function isContextProvider(type) { - { + if (disableLegacyContext) { + return false; + } else { var childContextTypes = type.childContextTypes; return childContextTypes !== null && childContextTypes !== undefined; } } function popContext(fiber) { - { + if (disableLegacyContext) { + return; + } else { pop(didPerformWorkStackCursor, fiber); pop(contextStackCursor, fiber); } } function popTopLevelContextObject(fiber) { - { + if (disableLegacyContext) { + return; + } else { pop(didPerformWorkStackCursor, fiber); pop(contextStackCursor, fiber); } } function pushTopLevelContextObject(fiber, context, didChange) { - { + if (disableLegacyContext) { + return; + } else { 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." @@ -5005,7 +5363,9 @@ function pushTopLevelContextObject(fiber, context, didChange) { } function processChildContext(fiber, type, parentContext) { - { + if (disableLegacyContext) { + return parentContext; + } else { 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. @@ -5016,8 +5376,8 @@ function processChildContext(fiber, type, parentContext) { if (!warnedAboutMissingGetChildContext[componentName]) { warnedAboutMissingGetChildContext[componentName] = true; - - error( + warningWithoutStack$1( + false, "%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.", @@ -5031,10 +5391,19 @@ function processChildContext(fiber, type, parentContext) { } var childContext; + + { + setCurrentPhase("getChildContext"); + } + startPhaseTimer(fiber, "getChildContext"); childContext = instance.getChildContext(); stopPhaseTimer(); + { + setCurrentPhase(null); + } + for (var contextKey in childContext) { if (!(contextKey in childContextTypes)) { throw Error( @@ -5048,7 +5417,17 @@ function processChildContext(fiber, type, parentContext) { { var name = getComponentName(type) || "Unknown"; - checkPropTypes(childContextTypes, childContext, "child context", name); + checkPropTypes( + childContextTypes, + childContext, + "child context", + name, // In practice, there is one case in which we won't get a stack. It's when + // somebody calls unstable_renderSubtreeIntoContainer() and we process + // context from the parent component instance. The stack will be missing + // because it's outside of the reconciliation, and so the pointer has not + // been set. This is rare and doesn't matter. We'll also remove that API. + getCurrentFiberStackInDev + ); } return Object.assign({}, parentContext, {}, childContext); @@ -5056,7 +5435,9 @@ function processChildContext(fiber, type, parentContext) { } function pushContextProvider(workInProgress) { - { + if (disableLegacyContext) { + return false; + } else { 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. @@ -5078,7 +5459,9 @@ function pushContextProvider(workInProgress) { } function invalidateContextProvider(workInProgress, type, didChange) { - { + if (disableLegacyContext) { + return; + } else { var instance = workInProgress.stateNode; if (!instance) { @@ -5112,7 +5495,9 @@ function invalidateContextProvider(workInProgress, type, didChange) { } function findCurrentUnmaskedContext(fiber) { - { + if (disableLegacyContext) { + return emptyContextObject; + } else { // Currently this is only used with renderSubtreeIntoContainer; not sure if it // makes sense elsewhere if (!(isFiberMounted(fiber) && fiber.tag === ClassComponent)) { @@ -5155,21 +5540,22 @@ var BlockingRoot = 1; var ConcurrentRoot = 2; // 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; - -{ +// CommonJS interop named imports. +var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority; +var Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback; +var Scheduler_cancelCallback = Scheduler.unstable_cancelCallback; +var Scheduler_shouldYield = Scheduler.unstable_shouldYield; +var Scheduler_requestPaint = Scheduler.unstable_requestPaint; +var Scheduler_now = Scheduler.unstable_now; +var Scheduler_getCurrentPriorityLevel = + Scheduler.unstable_getCurrentPriorityLevel; +var Scheduler_ImmediatePriority = Scheduler.unstable_ImmediatePriority; +var Scheduler_UserBlockingPriority = Scheduler.unstable_UserBlockingPriority; +var Scheduler_NormalPriority = Scheduler.unstable_NormalPriority; +var Scheduler_LowPriority = Scheduler.unstable_LowPriority; +var Scheduler_IdlePriority = Scheduler.unstable_IdlePriority; + +if (enableSchedulerTracing) { // Provide explicit error message when production+profiling bundle of e.g. // react-dom is used with production (non-profiling) bundle of // scheduler/tracing @@ -5363,14 +5749,14 @@ var NoWork = 0; // TODO: Think of a better name for Never. The key difference wi var Never = 1; // Idle is slightly higher priority than Never. It must completely finish in // order to be consistent. -var Idle = 2; // Continuous Hydration is slightly higher than Idle and is used to increase +var Idle = 2; // Continuous Hydration is a moving priority. It is slightly higher than Idle var Sync = MAX_SIGNED_31_BIT_INT; var Batched = Sync - 1; var UNIT_SIZE = 10; var MAGIC_NUMBER_OFFSET = Batched - 1; // 1 unit of expiration time represents 10ms. function msToExpirationTime(ms) { - // Always subtract from the offset so that we don't clash with the magic number for NoWork. + // Always add an offset so that we don't clash with the magic number for NoWork. return MAGIC_NUMBER_OFFSET - ((ms / UNIT_SIZE) | 0); } function expirationTimeToMs(expirationTime) { @@ -5429,6 +5815,7 @@ function computeInteractiveExpiration(currentTime) { HIGH_PRIORITY_BATCH_SIZE ); } + function inferPriorityFromExpirationTime(currentTime, expirationTime) { if (expirationTime === Sync) { return ImmediatePriority; @@ -5467,7 +5854,7 @@ function is(x, y) { ); } -var objectIs = typeof Object.is === "function" ? Object.is : is; +var is$1 = typeof Object.is === "function" ? Object.is : is; var hasOwnProperty = Object.prototype.hasOwnProperty; /** @@ -5477,7 +5864,7 @@ var hasOwnProperty = Object.prototype.hasOwnProperty; */ function shallowEqual(objA, objB) { - if (objectIs(objA, objB)) { + if (is$1(objA, objB)) { return true; } @@ -5500,7 +5887,7 @@ function shallowEqual(objA, objB) { for (var i = 0; i < keysA.length; i++) { if ( !hasOwnProperty.call(objB, keysA[i]) || - !objectIs(objA[keysA[i]], objB[keysA[i]]) + !is$1(objA[keysA[i]], objB[keysA[i]]) ) { return false; } @@ -5509,122 +5896,77 @@ function shallowEqual(objA, objB) { return true; } -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]; +/** + * Forked from fbjs/warning: + * https://github.com/facebook/fbjs/blob/e66ba20ad5be433eb54423f2b097d829324d9de6/packages/fbjs/src/__forks__/warning.js + * + * Only change is we use console.warn instead of console.error, + * and do nothing when 'console' is not supported. + * This really simplifies the code. + * --- + * Similar to invariant but only logs a warning if the condition is not met. + * This can be used to log issues in development environments in critical + * paths. Removing the logging code for production environments will keep the + * same logic and follow the same code paths. + */ +var lowPriorityWarningWithoutStack = function() {}; - if (pathBeforeSlash) { - var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, ""); - fileName = folderName + "/" + fileName; - } - } - } +{ + var printWarning = function(format) { + for ( + var _len = arguments.length, + args = new Array(_len > 1 ? _len - 1 : 0), + _key = 1; + _key < _len; + _key++ + ) { + args[_key - 1] = arguments[_key]; } - sourceInfo = " (at " + fileName + ":" + source.lineNumber + ")"; - } else if (ownerName) { - sourceInfo = " (created by " + ownerName + ")"; - } - - return "\n in " + (name || "Unknown") + sourceInfo; -} - -var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; - -function describeFiber(fiber) { - switch (fiber.tag) { - case HostRoot: - case HostPortal: - case HostText: - case Fragment: - case ContextProvider: - case ContextConsumer: - return ""; - - default: - var owner = fiber._debugOwner; - var source = fiber._debugSource; - var name = getComponentName(fiber.type); - var ownerName = null; - - if (owner) { - ownerName = getComponentName(owner.type); - } - - return describeComponentFrame(name, source, ownerName); - } -} + var argIndex = 0; + var message = + "Warning: " + + format.replace(/%s/g, function() { + return args[argIndex++]; + }); -function getStackByFiberInDevAndProd(workInProgress) { - var info = ""; - var node = workInProgress; + if (typeof console !== "undefined") { + console.warn(message); + } - do { - info += describeFiber(node); - node = node.return; - } while (node); + try { + // --- Welcome to debugging React --- + // This error was thrown as a convenience so that you can use this stack + // to find the callsite that caused this warning to fire. + throw new Error(message); + } catch (x) {} + }; - return info; -} -var current = null; -var isRendering = false; -function getCurrentFiberOwnerNameInDevOrNull() { - { - if (current === null) { - return null; + lowPriorityWarningWithoutStack = function(condition, format) { + if (format === undefined) { + throw new Error( + "`lowPriorityWarningWithoutStack(condition, format, ...args)` requires a warning " + + "message argument" + ); } - var owner = current._debugOwner; + if (!condition) { + for ( + var _len2 = arguments.length, + args = new Array(_len2 > 2 ? _len2 - 2 : 0), + _key2 = 2; + _key2 < _len2; + _key2++ + ) { + args[_key2 - 2] = arguments[_key2]; + } - if (owner !== null && typeof owner !== "undefined") { - return getComponentName(owner.type); + printWarning.apply(void 0, [format].concat(args)); } - } - - return null; + }; } -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. - return getStackByFiberInDevAndProd(current); - } -} -function resetCurrentFiber() { - { - ReactDebugCurrentFrame.getCurrentStack = null; - current = null; - isRendering = false; - } -} -function setCurrentFiber(fiber) { - { - ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackInDev; - current = fiber; - isRendering = false; - } -} -function setIsRendering(rendering) { - { - isRendering = rendering; - } -} +var lowPriorityWarningWithoutStack$1 = lowPriorityWarningWithoutStack; var ReactStrictModeWarnings = { recordUnsafeLifecycleWarnings: function(fiber, instance) {}, @@ -5796,8 +6138,8 @@ var ReactStrictModeWarnings = { if (UNSAFE_componentWillMountUniqueNames.size > 0) { var sortedNames = setToSortedString(UNSAFE_componentWillMountUniqueNames); - - error( + warningWithoutStack$1( + false, "Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. " + "See https://fb.me/react-unsafe-component-lifecycles for details.\n\n" + "* Move code with side effects to componentDidMount, and set initial state in the constructor.\n" + @@ -5811,7 +6153,8 @@ var ReactStrictModeWarnings = { UNSAFE_componentWillReceivePropsUniqueNames ); - error( + warningWithoutStack$1( + false, "Using UNSAFE_componentWillReceiveProps in strict mode is not recommended " + "and may indicate bugs in your code. " + "See https://fb.me/react-unsafe-component-lifecycles for details.\n\n" + @@ -5829,7 +6172,8 @@ var ReactStrictModeWarnings = { UNSAFE_componentWillUpdateUniqueNames ); - error( + warningWithoutStack$1( + false, "Using UNSAFE_componentWillUpdate in strict mode is not recommended " + "and may indicate bugs in your code. " + "See https://fb.me/react-unsafe-component-lifecycles for details.\n\n" + @@ -5842,7 +6186,8 @@ var ReactStrictModeWarnings = { if (componentWillMountUniqueNames.size > 0) { var _sortedNames3 = setToSortedString(componentWillMountUniqueNames); - warn( + lowPriorityWarningWithoutStack$1( + false, "componentWillMount has been renamed, and is not recommended for use. " + "See https://fb.me/react-unsafe-component-lifecycles for details.\n\n" + "* Move code with side effects to componentDidMount, and set initial state in the constructor.\n" + @@ -5860,7 +6205,8 @@ var ReactStrictModeWarnings = { componentWillReceivePropsUniqueNames ); - warn( + lowPriorityWarningWithoutStack$1( + false, "componentWillReceiveProps has been renamed, and is not recommended for use. " + "See https://fb.me/react-unsafe-component-lifecycles for details.\n\n" + "* Move data fetching code or side effects to componentDidUpdate.\n" + @@ -5879,7 +6225,8 @@ var ReactStrictModeWarnings = { if (componentWillUpdateUniqueNames.size > 0) { var _sortedNames5 = setToSortedString(componentWillUpdateUniqueNames); - warn( + lowPriorityWarningWithoutStack$1( + false, "componentWillUpdate has been renamed, and is not recommended for use. " + "See https://fb.me/react-unsafe-component-lifecycles for details.\n\n" + "* Move data fetching code or side effects to componentDidUpdate.\n" + @@ -5904,11 +6251,11 @@ var ReactStrictModeWarnings = { var strictRoot = findStrictRoot(fiber); if (strictRoot === null) { - error( + warningWithoutStack$1( + false, "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." ); - return; } // Dedup strategy: Warn once per component. @@ -5934,20 +6281,15 @@ var ReactStrictModeWarnings = { ReactStrictModeWarnings.flushLegacyContextWarning = function() { pendingLegacyContextWarning.forEach(function(fiberArray, strictRoot) { - if (fiberArray.length === 0) { - return; - } - - 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); - var firstComponentStack = getStackByFiberInDevAndProd(firstFiber); - - error( + var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot); + warningWithoutStack$1( + false, "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." + @@ -5955,7 +6297,7 @@ var ReactStrictModeWarnings = { "\n\nLearn more about this warning here: https://fb.me/react-legacy-context" + "%s", sortedNames, - firstComponentStack + strictRootComponentStack ); }); }; @@ -6198,6 +6540,9 @@ function scheduleFibersWithFamiliesRecursively( case ForwardRef: candidateType = type.render; break; + + default: + break; } if (resolveFamily === null) { @@ -6297,6 +6642,9 @@ function findHostInstancesForMatchingFibersRecursively( case ForwardRef: candidateType = type.render; break; + + default: + break; } var didMatch = false; @@ -6469,24 +6817,42 @@ function exitDisallowedContextReadInDEV() { function pushProvider(providerFiber, nextValue) { var context = providerFiber.type._context; - { + if (isPrimaryRenderer) { push(valueCursor, context._currentValue, providerFiber); context._currentValue = nextValue; { - if ( - context._currentRenderer !== undefined && - context._currentRenderer !== null && - context._currentRenderer !== rendererSigil - ) { - error( - "Detected multiple renderers concurrently rendering the " + - "same context provider. This is currently unsupported." - ); - } - + !( + context._currentRenderer === undefined || + context._currentRenderer === null || + context._currentRenderer === rendererSigil + ) + ? warningWithoutStack$1( + false, + "Detected multiple renderers concurrently rendering the " + + "same context provider. This is currently unsupported." + ) + : void 0; context._currentRenderer = rendererSigil; } + } else { + push(valueCursor, context._currentValue2, providerFiber); + context._currentValue2 = nextValue; + + { + !( + context._currentRenderer2 === undefined || + context._currentRenderer2 === null || + context._currentRenderer2 === rendererSigil + ) + ? warningWithoutStack$1( + false, + "Detected multiple renderers concurrently rendering the " + + "same context provider. This is currently unsupported." + ) + : void 0; + context._currentRenderer2 = rendererSigil; + } } } function popProvider(providerFiber) { @@ -6494,12 +6860,14 @@ function popProvider(providerFiber) { pop(valueCursor, providerFiber); var context = providerFiber.type._context; - { + if (isPrimaryRenderer) { context._currentValue = currentValue; + } else { + context._currentValue2 = currentValue; } } function calculateChangedBits(context, newValue, oldValue) { - if (objectIs(oldValue, newValue)) { + if (is$1(oldValue, newValue)) { // No change return 0; } else { @@ -6509,13 +6877,14 @@ function calculateChangedBits(context, newValue, oldValue) { : MAX_SIGNED_31_BIT_INT; { - if ((changedBits & MAX_SIGNED_31_BIT_INT) !== changedBits) { - error( - "calculateChangedBits: Expected the return value to be a " + - "31-bit integer. Instead received: %s", - changedBits - ); - } + !((changedBits & MAX_SIGNED_31_BIT_INT) === changedBits) + ? warning$1( + false, + "calculateChangedBits: Expected the return value to be a " + + "31-bit integer. Instead received: %s", + changedBits + ) + : void 0; } return changedBits | 0; @@ -6620,6 +6989,39 @@ function propagateContextChange( } else if (fiber.tag === ContextProvider) { // Don't scan deeper if this is a matching provider nextFiber = fiber.type === workInProgress.type ? null : fiber.child; + } else if ( + enableSuspenseServerRenderer && + fiber.tag === DehydratedFragment + ) { + // If a dehydrated suspense bounudary is in this subtree, we don't know + // if it will have any context consumers in it. The best we can do is + // mark it as having updates. + var parentSuspense = fiber.return; + + if (!(parentSuspense !== null)) { + throw Error( + "We just came from a parent so we must have had a parent. This is a bug in React." + ); + } + + if (parentSuspense.expirationTime < renderExpirationTime) { + parentSuspense.expirationTime = renderExpirationTime; + } + + var _alternate = parentSuspense.alternate; + + if ( + _alternate !== null && + _alternate.expirationTime < renderExpirationTime + ) { + _alternate.expirationTime = renderExpirationTime; + } // This is intentionally passing this fiber as the parent + // because we want to schedule this fiber as having work + // on its children. We'll use the childExpirationTime on + // this fiber to indicate that a context has changed. + + scheduleWorkOnParentPath(parentSuspense, renderExpirationTime); + nextFiber = fiber.sibling; } else { // Traverse down. nextFiber = fiber.child; @@ -6678,19 +7080,22 @@ 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()." - ); - } + !!isDisallowedContextReadInDEV + ? warning$1( + false, + "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()." + ) + : void 0; } - if (lastContextWithAllBitsObserved === context); - else if (observedBits === false || observedBits === 0); - else { + if (lastContextWithAllBitsObserved === context) { + // Nothing to do. We already observe everything in this context. + } else if (observedBits === false || observedBits === 0) { + // Do not observe any updates. + } else { var resolvedObservedBits; // Avoid deopting on observable arguments or heterogeneous types. if ( @@ -6729,9 +7134,85 @@ function readContext(context, observedBits) { } } - return context._currentValue; + return isPrimaryRenderer ? context._currentValue : context._currentValue2; } +// UpdateQueue is a linked list of prioritized updates. +// +// Like fibers, update queues come in pairs: a current queue, which represents +// the visible state of the screen, and a work-in-progress queue, which can be +// mutated and processed asynchronously before it is committed — a form of +// double buffering. If a work-in-progress render is discarded before finishing, +// we create a new work-in-progress by cloning the current queue. +// +// Both queues share a persistent, singly-linked list structure. To schedule an +// update, we append it to the end of both queues. Each queue maintains a +// pointer to first update in the persistent list that hasn't been processed. +// The work-in-progress pointer always has a position equal to or greater than +// the current queue, since we always work on that one. The current queue's +// pointer is only updated during the commit phase, when we swap in the +// work-in-progress. +// +// For example: +// +// Current pointer: A - B - C - D - E - F +// Work-in-progress pointer: D - E - F +// ^ +// The work-in-progress queue has +// processed more updates than current. +// +// The reason we append to both queues is because otherwise we might drop +// updates without ever processing them. For example, if we only add updates to +// the work-in-progress queue, some updates could be lost whenever a work-in +// -progress render restarts by cloning from current. Similarly, if we only add +// updates to the current queue, the updates will be lost whenever an already +// in-progress queue commits and swaps with the current queue. However, by +// adding to both queues, we guarantee that the update will be part of the next +// work-in-progress. (And because the work-in-progress queue becomes the +// current queue once it commits, there's no danger of applying the same +// update twice.) +// +// Prioritization +// -------------- +// +// Updates are not sorted by priority, but by insertion; new updates are always +// appended to the end of the list. +// +// The priority is still important, though. When processing the update queue +// during the render phase, only the updates with sufficient priority are +// included in the result. If we skip an update because it has insufficient +// priority, it remains in the queue to be processed later, during a lower +// priority render. Crucially, all updates subsequent to a skipped update also +// remain in the queue *regardless of their priority*. That means high priority +// updates are sometimes processed twice, at two separate priorities. We also +// keep track of a base state, that represents the state before the first +// update in the queue is applied. +// +// For example: +// +// Given a base state of '', and the following queue of updates +// +// A1 - B2 - C1 - D2 +// +// where the number indicates the priority, and the update is applied to the +// previous state by appending a letter, React will process these updates as +// two separate renders, one per distinct priority level: +// +// First render, at priority 1: +// Base state: '' +// Updates: [A1, C1] +// Result state: 'AC' +// +// Second render, at priority 2: +// Base state: 'A' <- The base state does not include C1, +// because B2 was skipped. +// Updates: [B2, C1, D2] <- C1 was rebased on top of B2 +// Result state: 'ABCD' +// +// Because we process updates in insertion order, and rebase high priority +// updates when preceding updates are skipped, the final result is deterministic +// regardless of priority. Intermediate state may vary according to system +// resources, but the final state is always the same. var UpdateState = 0; var ReplaceState = 1; var ForceUpdate = 2; @@ -6748,32 +7229,38 @@ var currentlyProcessingQueue; currentlyProcessingQueue = null; } -function initializeUpdateQueue(fiber) { +function createUpdateQueue(baseState) { var queue = { - baseState: fiber.memoizedState, - baseQueue: null, - shared: { - pending: null - }, - effects: null + baseState: baseState, + firstUpdate: null, + lastUpdate: null, + firstCapturedUpdate: null, + lastCapturedUpdate: null, + firstEffect: null, + lastEffect: null, + firstCapturedEffect: null, + lastCapturedEffect: 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; - - if (queue === currentQueue) { - var clone = { - baseState: currentQueue.baseState, - baseQueue: currentQueue.baseQueue, - shared: currentQueue.shared, - effects: currentQueue.effects - }; - workInProgress.updateQueue = clone; - } + return queue; +} + +function cloneUpdateQueue(currentQueue) { + var queue = { + baseState: currentQueue.baseState, + firstUpdate: currentQueue.firstUpdate, + lastUpdate: currentQueue.lastUpdate, + // TODO: With resuming, if we bail out and resuse the child tree, we should + // keep these effects. + firstCapturedUpdate: null, + lastCapturedUpdate: null, + firstEffect: null, + lastEffect: null, + firstCapturedEffect: null, + lastCapturedEffect: null + }; + return queue; } + function createUpdate(expirationTime, suspenseConfig) { var update = { expirationTime: expirationTime, @@ -6781,9 +7268,9 @@ function createUpdate(expirationTime, suspenseConfig) { tag: UpdateState, payload: null, callback: null, - next: null + next: null, + nextEffect: null }; - update.next = update; { update.priority = getCurrentPriorityLevel(); @@ -6791,62 +7278,136 @@ function createUpdate(expirationTime, suspenseConfig) { return update; } -function enqueueUpdate(fiber, update) { - var updateQueue = fiber.updateQueue; - if (updateQueue === null) { - // Only occurs if the fiber has been unmounted. - return; +function appendUpdateToQueue(queue, update) { + // Append the update to the end of the list. + if (queue.lastUpdate === null) { + // Queue is empty + queue.firstUpdate = queue.lastUpdate = update; + } else { + queue.lastUpdate.next = update; + queue.lastUpdate = update; } +} - var sharedQueue = updateQueue.shared; - var pending = sharedQueue.pending; +function enqueueUpdate(fiber, update) { + // Update queues are created lazily. + var alternate = fiber.alternate; + var queue1; + var queue2; - if (pending === null) { - // This is the first update. Create a circular list. - update.next = update; + if (alternate === null) { + // There's only one fiber. + queue1 = fiber.updateQueue; + queue2 = null; + + if (queue1 === null) { + queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState); + } } else { - update.next = pending.next; - pending.next = update; + // There are two owners. + queue1 = fiber.updateQueue; + queue2 = alternate.updateQueue; + + if (queue1 === null) { + if (queue2 === null) { + // Neither fiber has an update queue. Create new ones. + queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState); + queue2 = alternate.updateQueue = createUpdateQueue( + alternate.memoizedState + ); + } else { + // Only one fiber has an update queue. Clone to create a new one. + queue1 = fiber.updateQueue = cloneUpdateQueue(queue2); + } + } else { + if (queue2 === null) { + // Only one fiber has an update queue. Clone to create a new one. + queue2 = alternate.updateQueue = cloneUpdateQueue(queue1); + } else { + // Both owners have an update queue. + } + } } - sharedQueue.pending = update; + if (queue2 === null || queue1 === queue2) { + // There's only a single queue. + appendUpdateToQueue(queue1, update); + } else { + // There are two queues. We need to append the update to both queues, + // while accounting for the persistent structure of the list — we don't + // want the same update to be added multiple times. + if (queue1.lastUpdate === null || queue2.lastUpdate === null) { + // One of the queues is not empty. We must add the update to both queues. + appendUpdateToQueue(queue1, update); + appendUpdateToQueue(queue2, update); + } else { + // Both queues are non-empty. The last update is the same in both lists, + // because of structural sharing. So, only append to one of the lists. + appendUpdateToQueue(queue1, update); // But we still need to update the `lastUpdate` pointer of queue2. + + queue2.lastUpdate = update; + } + } { if ( - currentlyProcessingQueue === sharedQueue && + fiber.tag === ClassComponent && + (currentlyProcessingQueue === queue1 || + (queue2 !== null && currentlyProcessingQueue === queue2)) && !didWarnUpdateInsideUpdate ) { - error( + warningWithoutStack$1( + false, "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, update) { - var current = workInProgress.alternate; + // Captured updates go into a separate list, and only on the work-in- + // progress queue. + var workInProgressQueue = workInProgress.updateQueue; - if (current !== null) { - // Ensure the work-in-progress queue is a clone - cloneUpdateQueue(current, workInProgress); - } // Captured updates go only on the work-in-progress queue. + if (workInProgressQueue === null) { + workInProgressQueue = workInProgress.updateQueue = createUpdateQueue( + workInProgress.memoizedState + ); + } else { + // TODO: I put this here rather than createWorkInProgress so that we don't + // clone the queue unnecessarily. There's probably a better way to + // structure this. + workInProgressQueue = ensureWorkInProgressQueueIsAClone( + workInProgress, + workInProgressQueue + ); + } // Append the update to the end of the list. - var queue = workInProgress.updateQueue; // Append the update to the end of the list. + if (workInProgressQueue.lastCapturedUpdate === null) { + // This is the first render phase update + workInProgressQueue.firstCapturedUpdate = workInProgressQueue.lastCapturedUpdate = update; + } else { + workInProgressQueue.lastCapturedUpdate.next = update; + workInProgressQueue.lastCapturedUpdate = update; + } +} - var last = queue.baseQueue; +function ensureWorkInProgressQueueIsAClone(workInProgress, queue) { + var current = workInProgress.alternate; - if (last === null) { - queue.baseQueue = update.next = update; - update.next = update; - } else { - update.next = last.next; - last.next = update; + if (current !== null) { + // If the work-in-progress queue is equal to the current queue, + // we need to clone it first. + if (queue === current.updateQueue) { + queue = workInProgress.updateQueue = cloneUpdateQueue(queue); + } } + + return queue; } function getStateFromUpdate( @@ -6866,7 +7427,10 @@ function getStateFromUpdate( { enterDisallowedContextReadInDEV(); - if (workInProgress.mode & StrictMode) { + if ( + debugRenderPhaseSideEffectsForStrictMode && + workInProgress.mode & StrictMode + ) { payload.call(instance, prevState, nextProps); } } @@ -6898,7 +7462,10 @@ function getStateFromUpdate( { enterDisallowedContextReadInDEV(); - if (workInProgress.mode & StrictMode) { + if ( + debugRenderPhaseSideEffectsForStrictMode && + workInProgress.mode & StrictMode + ) { _payload.call(instance, prevState, nextProps); } } @@ -6932,171 +7499,163 @@ function getStateFromUpdate( function processUpdateQueue( workInProgress, + queue, props, instance, renderExpirationTime ) { - // This is always non-null on a ClassComponent or HostRoot - var queue = workInProgress.updateQueue; hasForceUpdate = false; + queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue); { - currentlyProcessingQueue = queue.shared; - } // The last rebase update that is NOT part of the base state. - - var baseQueue = queue.baseQueue; // The last pending update that hasn't been processed yet. + currentlyProcessingQueue = queue; + } // These values may change as we process the queue. - var pendingQueue = queue.shared.pending; + var newBaseState = queue.baseState; + var newFirstUpdate = null; + var newExpirationTime = NoWork; // Iterate through the list of updates to compute the result. - if (pendingQueue !== null) { - // We have new updates that haven't been processed yet. - // We'll add them to the base queue. - if (baseQueue !== null) { - // Merge the pending queue and the base queue. - var baseFirst = baseQueue.next; - var pendingFirst = pendingQueue.next; - baseQueue.next = pendingFirst; - pendingQueue.next = baseFirst; - } + var update = queue.firstUpdate; + var resultState = newBaseState; - baseQueue = pendingQueue; - queue.shared.pending = null; // TODO: Pass `current` as argument + while (update !== null) { + var updateExpirationTime = update.expirationTime; - var current = workInProgress.alternate; + if (updateExpirationTime < renderExpirationTime) { + // This update does not have sufficient priority. Skip it. + if (newFirstUpdate === null) { + // This is the first skipped update. It will be the first update in + // the new list. + newFirstUpdate = update; // Since this is the first update that was skipped, the current result + // is the new base state. - if (current !== null) { - var currentQueue = current.updateQueue; + newBaseState = resultState; + } // Since this update will remain in the list, update the remaining + // expiration time. - if (currentQueue !== null) { - currentQueue.baseQueue = pendingQueue; + if (newExpirationTime < updateExpirationTime) { + newExpirationTime = updateExpirationTime; } - } - } // These values may change as we process the queue. + } else { + // This update does have sufficient priority. + // Mark the event time of this update as relevant to this render pass. + // TODO: This should ideally use the true event time of this update rather than + // its priority which is a derived and not reverseable value. + // TODO: We should skip this update if it was already committed but currently + // we have no way of detecting the difference between a committed and suspended + // update here. + markRenderEventTimeAndConfig(updateExpirationTime, update.suspenseConfig); // Process it and compute a new result. + + resultState = getStateFromUpdate( + workInProgress, + queue, + update, + resultState, + props, + instance + ); + var callback = update.callback; - if (baseQueue !== null) { - var first = baseQueue.next; // Iterate through the list of updates to compute the result. + if (callback !== null) { + workInProgress.effectTag |= Callback; // Set this to null, in case it was mutated during an aborted render. - var newState = queue.baseState; - var newExpirationTime = NoWork; - var newBaseState = null; - var newBaseQueueFirst = null; - var newBaseQueueLast = null; + update.nextEffect = null; - if (first !== null) { - var update = first; + if (queue.lastEffect === null) { + queue.firstEffect = queue.lastEffect = update; + } else { + queue.lastEffect.nextEffect = update; + queue.lastEffect = update; + } + } + } // Continue to the next update. - do { - var updateExpirationTime = update.expirationTime; - - if (updateExpirationTime < renderExpirationTime) { - // 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 = { - expirationTime: update.expirationTime, - suspenseConfig: update.suspenseConfig, - tag: update.tag, - payload: update.payload, - callback: update.callback, - next: null - }; + update = update.next; + } // Separately, iterate though the list of captured updates. - if (newBaseQueueLast === null) { - newBaseQueueFirst = newBaseQueueLast = clone; - newBaseState = newState; - } else { - newBaseQueueLast = newBaseQueueLast.next = clone; - } // Update the remaining priority in the queue. + var newFirstCapturedUpdate = null; + update = queue.firstCapturedUpdate; - if (updateExpirationTime > newExpirationTime) { - newExpirationTime = updateExpirationTime; - } - } else { - // This update does have sufficient priority. - if (newBaseQueueLast !== null) { - var _clone = { - expirationTime: Sync, - // This update is going to be committed so we never want uncommit it. - suspenseConfig: update.suspenseConfig, - tag: update.tag, - payload: update.payload, - callback: update.callback, - next: null - }; - newBaseQueueLast = newBaseQueueLast.next = _clone; - } // Mark the event time of this update as relevant to this render pass. - // TODO: This should ideally use the true event time of this update rather than - // its priority which is a derived and not reverseable value. - // TODO: We should skip this update if it was already committed but currently - // we have no way of detecting the difference between a committed and suspended - // update here. - - markRenderEventTimeAndConfig( - updateExpirationTime, - update.suspenseConfig - ); // Process this update. - - newState = getStateFromUpdate( - workInProgress, - queue, - update, - newState, - props, - instance - ); - var callback = update.callback; + while (update !== null) { + var _updateExpirationTime = update.expirationTime; - if (callback !== null) { - workInProgress.effectTag |= Callback; - var effects = queue.effects; + if (_updateExpirationTime < renderExpirationTime) { + // This update does not have sufficient priority. Skip it. + if (newFirstCapturedUpdate === null) { + // This is the first skipped captured update. It will be the first + // update in the new list. + newFirstCapturedUpdate = update; // If this is the first update that was skipped, the current result is + // the new base state. - if (effects === null) { - queue.effects = [update]; - } else { - effects.push(update); - } - } + if (newFirstUpdate === null) { + newBaseState = resultState; } + } // Since this update will remain in the list, update the remaining + // expiration time. - update = update.next; + if (newExpirationTime < _updateExpirationTime) { + newExpirationTime = _updateExpirationTime; + } + } else { + // This update does have sufficient priority. Process it and compute + // a new result. + resultState = getStateFromUpdate( + workInProgress, + queue, + update, + resultState, + props, + instance + ); + var _callback = update.callback; - if (update === null || update === first) { - pendingQueue = queue.shared.pending; + if (_callback !== null) { + workInProgress.effectTag |= Callback; // Set this to null, in case it was mutated during an aborted render. - 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. - update = baseQueue.next = pendingQueue.next; - pendingQueue.next = first; - queue.baseQueue = baseQueue = pendingQueue; - queue.shared.pending = null; - } + update.nextEffect = null; + + if (queue.lastCapturedEffect === null) { + queue.firstCapturedEffect = queue.lastCapturedEffect = update; + } else { + queue.lastCapturedEffect.nextEffect = update; + queue.lastCapturedEffect = update; } - } while (true); + } } - if (newBaseQueueLast === null) { - newBaseState = newState; - } else { - newBaseQueueLast.next = newBaseQueueFirst; - } + update = update.next; + } - queue.baseState = newBaseState; - queue.baseQueue = newBaseQueueLast; // 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. + if (newFirstUpdate === null) { + queue.lastUpdate = null; + } - markUnprocessedUpdateTime(newExpirationTime); - workInProgress.expirationTime = newExpirationTime; - workInProgress.memoizedState = newState; + if (newFirstCapturedUpdate === null) { + queue.lastCapturedUpdate = null; + } else { + workInProgress.effectTag |= Callback; + } + + if (newFirstUpdate === null && newFirstCapturedUpdate === null) { + // We processed every update, without skipping. That means the new base + // state is the same as the result state. + newBaseState = resultState; } + queue.baseState = newBaseState; + queue.firstUpdate = newFirstUpdate; + queue.firstCapturedUpdate = newFirstCapturedUpdate; // 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. + + markUnprocessedUpdateTime(newExpirationTime); + workInProgress.expirationTime = newExpirationTime; + workInProgress.memoizedState = resultState; + { currentlyProcessingQueue = null; } @@ -7119,21 +7678,42 @@ function resetHasForceUpdateBeforeProcessing() { function checkHasForceUpdateAfterProcessing() { return hasForceUpdate; } -function commitUpdateQueue(finishedWork, finishedQueue, instance) { - // Commit the effects - var effects = finishedQueue.effects; - finishedQueue.effects = null; +function commitUpdateQueue( + finishedWork, + finishedQueue, + instance, + renderExpirationTime +) { + // If the finished render included captured updates, and there are still + // lower priority updates left over, we need to keep the captured updates + // in the queue so that they are rebased and not dropped once we process the + // queue again at the lower priority. + if (finishedQueue.firstCapturedUpdate !== null) { + // Join the captured update list to the end of the normal list. + if (finishedQueue.lastUpdate !== null) { + finishedQueue.lastUpdate.next = finishedQueue.firstCapturedUpdate; + finishedQueue.lastUpdate = finishedQueue.lastCapturedUpdate; + } // Clear the list of captured updates. - if (effects !== null) { - for (var i = 0; i < effects.length; i++) { - var effect = effects[i]; - var callback = effect.callback; + finishedQueue.firstCapturedUpdate = finishedQueue.lastCapturedUpdate = null; + } // Commit the effects - if (callback !== null) { - effect.callback = null; - callCallback(callback, instance); - } + commitUpdateEffects(finishedQueue.firstEffect, instance); + finishedQueue.firstEffect = finishedQueue.lastEffect = null; + commitUpdateEffects(finishedQueue.firstCapturedEffect, instance); + finishedQueue.firstCapturedEffect = finishedQueue.lastCapturedEffect = null; +} + +function commitUpdateEffects(effect, instance) { + while (effect !== null) { + var callback = effect.callback; + + if (callback !== null) { + effect.callback = null; + callCallback(callback, instance); } + + effect = effect.nextEffect; } } @@ -7143,7 +7723,7 @@ function requestCurrentSuspenseConfig() { } var fakeInternalInstance = {}; -var isArray = Array.isArray; // React.Component uses a shared frozen object by default. +var isArray$1 = Array.isArray; // React.Component uses a shared frozen object by default. // We'll use it to determine whether we need to initialize legacy refs. var emptyRefsObject = new React.Component().refs; @@ -7178,8 +7758,8 @@ var didWarnAboutInvalidateContextType; if (!didWarnOnInvalidCallback.has(key)) { didWarnOnInvalidCallback.add(key); - - error( + warningWithoutStack$1( + false, "%s(...): Expected the last optional `callback` argument to be a " + "function. Instead received: %s.", callerName, @@ -7194,8 +7774,8 @@ var didWarnAboutInvalidateContextType; if (!didWarnAboutUndefinedDerivedState.has(componentName)) { didWarnAboutUndefinedDerivedState.add(componentName); - - error( + warningWithoutStack$1( + false, "%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. " + "You have returned undefined.", componentName @@ -7230,7 +7810,10 @@ function applyDerivedStateFromProps( var prevState = workInProgress.memoizedState; { - if (workInProgress.mode & StrictMode) { + if ( + debugRenderPhaseSideEffectsForStrictMode && + workInProgress.mode & StrictMode + ) { // Invoke the function an extra time to help detect side-effects. getDerivedStateFromProps(nextProps, prevState); } @@ -7249,9 +7832,9 @@ function applyDerivedStateFromProps( workInProgress.memoizedState = memoizedState; // Once the update queue is empty, persist the derived state onto the // base state. - if (workInProgress.expirationTime === NoWork) { - // Queue is always non-null for classes - var updateQueue = workInProgress.updateQueue; + var updateQueue = workInProgress.updateQueue; + + if (updateQueue !== null && workInProgress.expirationTime === NoWork) { updateQueue.baseState = memoizedState; } } @@ -7341,13 +7924,6 @@ function checkShouldComponentUpdate( var instance = workInProgress.stateNode; if (typeof instance.shouldComponentUpdate === "function") { - { - if (workInProgress.mode & StrictMode) { - // Invoke the function an extra time to help detect side-effects. - instance.shouldComponentUpdate(newProps, newState, nextContext); - } - } - startPhaseTimer(workInProgress, "shouldComponentUpdate"); var shouldUpdate = instance.shouldComponentUpdate( newProps, @@ -7357,13 +7933,14 @@ function checkShouldComponentUpdate( stopPhaseTimer(); { - if (shouldUpdate === undefined) { - error( - "%s.shouldComponentUpdate(): Returned undefined instead of a " + - "boolean value. Make sure to return true or false.", - getComponentName(ctor) || "Component" - ); - } + !(shouldUpdate !== undefined) + ? warningWithoutStack$1( + false, + "%s.shouldComponentUpdate(): Returned undefined instead of a " + + "boolean value. Make sure to return true or false.", + getComponentName(ctor) || "Component" + ) + : void 0; } return shouldUpdate; @@ -7387,13 +7964,15 @@ function checkClassInstance(workInProgress, ctor, newProps) { if (!renderPresent) { if (ctor.prototype && typeof ctor.prototype.render === "function") { - error( + warningWithoutStack$1( + false, "%s(...): No `render` method found on the returned component " + "instance: did you accidentally return an object from the constructor?", name ); } else { - error( + warningWithoutStack$1( + false, "%s(...): No `render` method found on the returned component " + "instance: you may have forgotten to define `render`.", name @@ -7401,55 +7980,78 @@ function checkClassInstance(workInProgress, ctor, newProps) { } } - 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 - ); - } + var noGetInitialStateOnES6 = + !instance.getInitialState || + instance.getInitialState.isReactClassApproved || + instance.state; + !noGetInitialStateOnES6 + ? warningWithoutStack$1( + false, + "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 + ) + : void 0; + var noGetDefaultPropsOnES6 = + !instance.getDefaultProps || + instance.getDefaultProps.isReactClassApproved; + !noGetDefaultPropsOnES6 + ? warningWithoutStack$1( + false, + "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 + ) + : void 0; + var noInstancePropTypes = !instance.propTypes; + !noInstancePropTypes + ? warningWithoutStack$1( + false, + "propTypes was defined as an instance property on %s. Use a static " + + "property to define propTypes instead.", + name + ) + : void 0; + var noInstanceContextType = !instance.contextType; + !noInstanceContextType + ? warningWithoutStack$1( + false, + "contextType was defined as an instance property on %s. Use a static " + + "property to define contextType instead.", + name + ) + : void 0; + + if (disableLegacyContext) { + if (ctor.childContextTypes) { + warningWithoutStack$1( + false, + "%s uses the legacy childContextTypes API which is no longer supported. " + + "Use React.createContext() instead.", + name + ); + } - { - if (instance.contextTypes) { - error( - "contextTypes was defined as an instance property on %s. Use a static " + - "property to define contextTypes instead.", + if (ctor.contextTypes) { + warningWithoutStack$1( + false, + "%s uses the legacy contextTypes API which is no longer supported. " + + "Use React.createContext() with static contextType instead.", name ); } + } else { + var noInstanceContextTypes = !instance.contextTypes; + !noInstanceContextTypes + ? warningWithoutStack$1( + false, + "contextTypes was defined as an instance property on %s. Use a static " + + "property to define contextTypes instead.", + name + ) + : void 0; if ( ctor.contextType && @@ -7457,8 +8059,8 @@ function checkClassInstance(workInProgress, ctor, newProps) { !didWarnAboutContextTypeAndContextTypes.has(ctor) ) { didWarnAboutContextTypeAndContextTypes.add(ctor); - - error( + warningWithoutStack$1( + false, "%s declares both contextTypes and contextType static properties. " + "The legacy contextTypes property will be ignored.", name @@ -7466,22 +8068,26 @@ function checkClassInstance(workInProgress, ctor, newProps) { } } - if (typeof instance.componentShouldUpdate === "function") { - error( - "%s has a method called " + - "componentShouldUpdate(). Did you mean shouldComponentUpdate()? " + - "The name is phrased as a question because the function is " + - "expected to return a value.", - name - ); - } + var noComponentShouldUpdate = + typeof instance.componentShouldUpdate !== "function"; + !noComponentShouldUpdate + ? warningWithoutStack$1( + false, + "%s has a method called " + + "componentShouldUpdate(). Did you mean shouldComponentUpdate()? " + + "The name is phrased as a question because the function is " + + "expected to return a value.", + name + ) + : void 0; if ( ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== "undefined" ) { - error( + warningWithoutStack$1( + false, "%s has a method called shouldComponentUpdate(). " + "shouldComponentUpdate should not be used when extending React.PureComponent. " + "Please extend React.Component if shouldComponentUpdate is used.", @@ -7489,61 +8095,70 @@ function checkClassInstance(workInProgress, ctor, newProps) { ); } - if (typeof instance.componentDidUnmount === "function") { - error( - "%s has a method called " + - "componentDidUnmount(). But there is no such lifecycle method. " + - "Did you mean componentWillUnmount()?", - name - ); - } - - if (typeof instance.componentDidReceiveProps === "function") { - error( - "%s has a method called " + - "componentDidReceiveProps(). But there is no such lifecycle method. " + - "If you meant to update the state in response to changing props, " + - "use componentWillReceiveProps(). If you meant to fetch data or " + - "run side-effects or mutations after React has updated the UI, use componentDidUpdate().", - name - ); - } - - if (typeof instance.componentWillRecieveProps === "function") { - error( - "%s has a method called " + - "componentWillRecieveProps(). Did you mean componentWillReceiveProps()?", - name - ); - } - - if (typeof instance.UNSAFE_componentWillRecieveProps === "function") { - error( - "%s has a method called " + - "UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?", - name - ); - } - + var noComponentDidUnmount = + typeof instance.componentDidUnmount !== "function"; + !noComponentDidUnmount + ? warningWithoutStack$1( + false, + "%s has a method called " + + "componentDidUnmount(). But there is no such lifecycle method. " + + "Did you mean componentWillUnmount()?", + name + ) + : void 0; + var noComponentDidReceiveProps = + typeof instance.componentDidReceiveProps !== "function"; + !noComponentDidReceiveProps + ? warningWithoutStack$1( + false, + "%s has a method called " + + "componentDidReceiveProps(). But there is no such lifecycle method. " + + "If you meant to update the state in response to changing props, " + + "use componentWillReceiveProps(). If you meant to fetch data or " + + "run side-effects or mutations after React has updated the UI, use componentDidUpdate().", + name + ) + : void 0; + var noComponentWillRecieveProps = + typeof instance.componentWillRecieveProps !== "function"; + !noComponentWillRecieveProps + ? warningWithoutStack$1( + false, + "%s has a method called " + + "componentWillRecieveProps(). Did you mean componentWillReceiveProps()?", + name + ) + : void 0; + var noUnsafeComponentWillRecieveProps = + typeof instance.UNSAFE_componentWillRecieveProps !== "function"; + !noUnsafeComponentWillRecieveProps + ? warningWithoutStack$1( + false, + "%s has a method called " + + "UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?", + name + ) + : void 0; var hasMutatedProps = instance.props !== newProps; - - if (instance.props !== undefined && hasMutatedProps) { - error( - "%s(...): When calling super() in `%s`, make sure to pass " + - "up the same props that your component's constructor was passed.", - name, - name - ); - } - - if (instance.defaultProps) { - error( - "Setting defaultProps as an instance property on %s is not supported and will be ignored." + - " Instead, define defaultProps as a static property on %s.", - name, - name - ); - } + !(instance.props === undefined || !hasMutatedProps) + ? warningWithoutStack$1( + false, + "%s(...): When calling super() in `%s`, make sure to pass " + + "up the same props that your component's constructor was passed.", + name, + name + ) + : void 0; + var noInstanceDefaultProps = !instance.defaultProps; + !noInstanceDefaultProps + ? warningWithoutStack$1( + false, + "Setting defaultProps as an instance property on %s is not supported and will be ignored." + + " Instead, define defaultProps as a static property on %s.", + name, + name + ) + : void 0; if ( typeof instance.getSnapshotBeforeUpdate === "function" && @@ -7551,53 +8166,63 @@ function checkClassInstance(workInProgress, ctor, newProps) { !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor) ) { didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor); - - error( + warningWithoutStack$1( + false, "%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). " + "This component defines getSnapshotBeforeUpdate() only.", getComponentName(ctor) ); } - if (typeof instance.getDerivedStateFromProps === "function") { - error( - "%s: getDerivedStateFromProps() is defined as an instance method " + - "and will be ignored. Instead, declare it as a static method.", - name - ); - } - - if (typeof instance.getDerivedStateFromError === "function") { - error( - "%s: getDerivedStateFromError() is defined as an instance method " + - "and will be ignored. Instead, declare it as a static method.", - name - ); - } + var noInstanceGetDerivedStateFromProps = + typeof instance.getDerivedStateFromProps !== "function"; + !noInstanceGetDerivedStateFromProps + ? warningWithoutStack$1( + false, + "%s: getDerivedStateFromProps() is defined as an instance method " + + "and will be ignored. Instead, declare it as a static method.", + name + ) + : void 0; + var noInstanceGetDerivedStateFromCatch = + typeof instance.getDerivedStateFromError !== "function"; + !noInstanceGetDerivedStateFromCatch + ? warningWithoutStack$1( + false, + "%s: getDerivedStateFromError() is defined as an instance method " + + "and will be ignored. Instead, declare it as a static method.", + name + ) + : void 0; + var noStaticGetSnapshotBeforeUpdate = + typeof ctor.getSnapshotBeforeUpdate !== "function"; + !noStaticGetSnapshotBeforeUpdate + ? warningWithoutStack$1( + false, + "%s: getSnapshotBeforeUpdate() is defined as a static method " + + "and will be ignored. Instead, declare it as an instance method.", + name + ) + : void 0; + var _state = instance.state; - if (typeof ctor.getSnapshotBeforeUpdate === "function") { - error( - "%s: getSnapshotBeforeUpdate() is defined as a static method " + - "and will be ignored. Instead, declare it as an instance method.", + if (_state && (typeof _state !== "object" || isArray$1(_state))) { + warningWithoutStack$1( + false, + "%s.state: must be set to an object or null", name ); } - var _state = instance.state; - - if (_state && (typeof _state !== "object" || isArray(_state))) { - error("%s.state: must be set to an object or null", name); - } - - if ( - typeof instance.getChildContext === "function" && - typeof ctor.childContextTypes !== "object" - ) { - error( - "%s.getChildContext(): childContextTypes must be defined in order to " + - "use getChildContext().", - name - ); + if (typeof instance.getChildContext === "function") { + !(typeof ctor.childContextTypes === "object") + ? warningWithoutStack$1( + false, + "%s.getChildContext(): childContextTypes must be defined in order to " + + "use getChildContext().", + name + ) + : void 0; } } } @@ -7613,7 +8238,12 @@ function adoptClassInstance(workInProgress, instance) { } } -function constructClassInstance(workInProgress, ctor, props) { +function constructClassInstance( + workInProgress, + ctor, + props, + renderExpirationTime +) { var isLegacyContextConsumer = false; var unmaskedContext = emptyContextObject; var context = emptyContextObject; @@ -7651,7 +8281,8 @@ function constructClassInstance(workInProgress, ctor, props) { "}."; } - error( + warningWithoutStack$1( + false, "%s defines an invalid contextType. " + "contextType should point to the Context object returned by React.createContext().%s", getComponentName(ctor) || "Component", @@ -7663,7 +8294,7 @@ function constructClassInstance(workInProgress, ctor, props) { if (typeof contextType === "object" && contextType !== null) { context = readContext(contextType); - } else { + } else if (!disableLegacyContext) { unmaskedContext = getUnmaskedContext(workInProgress, ctor, true); var contextTypes = ctor.contextTypes; isLegacyContextConsumer = @@ -7674,7 +8305,10 @@ function constructClassInstance(workInProgress, ctor, props) { } // Instantiate twice to help detect side-effects. { - if (workInProgress.mode & StrictMode) { + if ( + debugRenderPhaseSideEffectsForStrictMode && + workInProgress.mode & StrictMode + ) { new ctor(props, context); // eslint-disable-line no-new } } @@ -7692,8 +8326,8 @@ function constructClassInstance(workInProgress, ctor, props) { if (!didWarnAboutUninitializedState.has(componentName)) { didWarnAboutUninitializedState.add(componentName); - - error( + warningWithoutStack$1( + false, "`%s` uses `getDerivedStateFromProps` but its initial state is " + "%s. This is not recommended. Instead, define the initial state by " + "assigning an object to `this.state` in the constructor of `%s`. " + @@ -7758,8 +8392,8 @@ function constructClassInstance(workInProgress, ctor, props) { if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName)) { didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName); - - error( + warningWithoutStack$1( + false, "Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n" + "%s uses %s but also contains the following legacy lifecycles:%s%s%s\n\n" + "The above lifecycles should be removed. Learn more about this warning here:\n" + @@ -7801,7 +8435,8 @@ function callComponentWillMount(workInProgress, instance) { if (oldState !== instance.state) { { - error( + warningWithoutStack$1( + false, "%s.componentWillMount(): Assigning directly to this.state is " + "deprecated (except inside a component's " + "constructor). Use setState instead.", @@ -7838,8 +8473,8 @@ function callComponentWillReceiveProps( if (!didWarnAboutStateAssignmentForComponent.has(componentName)) { didWarnAboutStateAssignmentForComponent.add(componentName); - - error( + warningWithoutStack$1( + false, "%s.componentWillReceiveProps(): Assigning directly to " + "this.state is deprecated (except inside a component's " + "constructor). Use setState instead.", @@ -7866,11 +8501,12 @@ function mountClassInstance( instance.props = newProps; instance.state = workInProgress.memoizedState; instance.refs = emptyRefsObject; - initializeUpdateQueue(workInProgress); var contextType = ctor.contextType; if (typeof contextType === "object" && contextType !== null) { instance.context = readContext(contextType); + } else if (disableLegacyContext) { + instance.context = emptyContextObject; } else { var unmaskedContext = getUnmaskedContext(workInProgress, ctor, true); instance.context = getMaskedContext(workInProgress, unmaskedContext); @@ -7882,8 +8518,8 @@ function mountClassInstance( if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) { didWarnAboutDirectlyAssigningPropsToState.add(componentName); - - error( + warningWithoutStack$1( + false, "%s: It is not recommended to assign props directly to state " + "because updates to props won't be reflected in state. " + "In most cases, it is better to use props directly.", @@ -7899,7 +8535,7 @@ function mountClassInstance( ); } - { + if (warnAboutDeprecatedLifecycles) { ReactStrictModeWarnings.recordUnsafeLifecycleWarnings( workInProgress, instance @@ -7907,8 +8543,19 @@ function mountClassInstance( } } - processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); - instance.state = workInProgress.memoizedState; + var updateQueue = workInProgress.updateQueue; + + if (updateQueue !== null) { + processUpdateQueue( + workInProgress, + updateQueue, + newProps, + instance, + renderExpirationTime + ); + instance.state = workInProgress.memoizedState; + } + var getDerivedStateFromProps = ctor.getDerivedStateFromProps; if (typeof getDerivedStateFromProps === "function") { @@ -7931,13 +8578,18 @@ function mountClassInstance( callComponentWillMount(workInProgress, instance); // If we had additional state updates during this life-cycle, let's // process them now. - processUpdateQueue( - workInProgress, - newProps, - instance, - renderExpirationTime - ); - instance.state = workInProgress.memoizedState; + updateQueue = workInProgress.updateQueue; + + if (updateQueue !== null) { + processUpdateQueue( + workInProgress, + updateQueue, + newProps, + instance, + renderExpirationTime + ); + instance.state = workInProgress.memoizedState; + } } if (typeof instance.componentDidMount === "function") { @@ -7960,7 +8612,7 @@ function resumeMountClassInstance( if (typeof contextType === "object" && contextType !== null) { nextContext = readContext(contextType); - } else { + } else if (!disableLegacyContext) { var nextLegacyUnmaskedContext = getUnmaskedContext( workInProgress, ctor, @@ -7996,8 +8648,18 @@ function resumeMountClassInstance( resetHasForceUpdateBeforeProcessing(); var oldState = workInProgress.memoizedState; var newState = (instance.state = oldState); - processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); - newState = workInProgress.memoizedState; + var updateQueue = workInProgress.updateQueue; + + if (updateQueue !== null) { + processUpdateQueue( + workInProgress, + updateQueue, + newProps, + instance, + renderExpirationTime + ); + newState = workInProgress.memoizedState; + } if ( oldProps === newProps && @@ -8087,7 +8749,6 @@ function updateClassInstance( renderExpirationTime ) { var instance = workInProgress.stateNode; - cloneUpdateQueue(current, workInProgress); var oldProps = workInProgress.memoizedProps; instance.props = workInProgress.type === workInProgress.elementType @@ -8099,7 +8760,7 @@ function updateClassInstance( if (typeof contextType === "object" && contextType !== null) { nextContext = readContext(contextType); - } else { + } else if (!disableLegacyContext) { var nextUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true); nextContext = getMaskedContext(workInProgress, nextUnmaskedContext); } @@ -8131,8 +8792,18 @@ function updateClassInstance( resetHasForceUpdateBeforeProcessing(); var oldState = workInProgress.memoizedState; var newState = (instance.state = oldState); - processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); - newState = workInProgress.memoizedState; + var updateQueue = workInProgress.updateQueue; + + if (updateQueue !== null) { + processUpdateQueue( + workInProgress, + updateQueue, + newProps, + instance, + renderExpirationTime + ); + newState = workInProgress.memoizedState; + } if ( oldProps === newProps && @@ -8294,8 +8965,8 @@ var warnForMissingKey = function(child) {}; } ownerHasKeyUseWarning[currentComponentErrorInfo] = true; - - error( + warning$1( + false, "Each child in a list should have a unique " + '"key" prop. See https://fb.me/react-warning-keys for ' + "more information." @@ -8303,9 +8974,9 @@ var warnForMissingKey = function(child) {}; }; } -var isArray$1 = Array.isArray; +var isArray = Array.isArray; -function coerceRef(returnFiber, current, element) { +function coerceRef(returnFiber, current$$1, element) { var mixedRef = element.ref; if ( @@ -8316,21 +8987,25 @@ 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 - // because these cannot be automatically converted to an arrow function - // using a codemod. Therefore, we don't have to warn about string refs again. - !( - element._owner && - element._self && - element._owner.stateNode !== element._self - ) - ) { + if (returnFiber.mode & StrictMode || warnAboutStringRefs) { var componentName = getComponentName(returnFiber.type) || "Component"; if (!didWarnAboutStringRefs[componentName]) { - { - error( + if (warnAboutStringRefs) { + warningWithoutStack$1( + false, + 'Component "%s" contains the string ref "%s". Support for string refs ' + + "will be removed in a future major release. We recommend using " + + "useRef() or createRef() instead. " + + "Learn more about using refs safely here: " + + "https://fb.me/react-strict-mode-string-ref%s", + componentName, + mixedRef, + getStackByFiberInDevAndProd(returnFiber) + ); + } else { + warningWithoutStack$1( + false, 'A string ref, "%s", has been found within a strict mode tree. ' + "String refs are a source of potential bugs and should be avoided. " + "We recommend using useRef() or createRef() instead. " + @@ -8355,7 +9030,7 @@ function coerceRef(returnFiber, current, element) { if (!(ownerFiber.tag === ClassComponent)) { throw Error( - "Function components cannot have string refs. We recommend using useRef() instead. Learn more about using refs safely here: https://fb.me/react-strict-mode-string-ref" + "Function components cannot have refs. Did you mean to use React.forwardRef()?" ); } @@ -8373,12 +9048,12 @@ function coerceRef(returnFiber, current, element) { var stringRef = "" + mixedRef; // Check if previous string ref matches new string ref if ( - current !== null && - current.ref !== null && - typeof current.ref === "function" && - current.ref._stringRef === stringRef + current$$1 !== null && + current$$1.ref !== null && + typeof current$$1.ref === "function" && + current$$1.ref._stringRef === stringRef ) { - return current.ref; + return current$$1.ref; } var ref = function(value) { @@ -8443,25 +9118,23 @@ function throwOnInvalidObjectType(returnFiber, newChild) { } function warnOnFunctionType() { - { - var currentComponentErrorInfo = - "Functions are not valid as a React child. This may happen if " + - "you return a Component instead of from render. " + - "Or maybe you meant to call this function rather than return it." + - getCurrentFiberStackInDev(); - - if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) { - return; - } + var currentComponentErrorInfo = + "Functions are not valid as a React child. This may happen if " + + "you return a Component instead of from render. " + + "Or maybe you meant to call this function rather than return it." + + getCurrentFiberStackInDev(); - ownerHasFunctionTypeWarning[currentComponentErrorInfo] = true; - - error( - "Functions are not valid as a React child. This may happen if " + - "you return a Component instead of from render. " + - "Or maybe you meant to call this function rather than return it." - ); + if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) { + return; } + + ownerHasFunctionTypeWarning[currentComponentErrorInfo] = true; + warning$1( + false, + "Functions are not valid as a React child. This may happen if " + + "you return a Component instead of from render. " + + "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 @@ -8528,10 +9201,10 @@ function ChildReconciler(shouldTrackSideEffects) { return existingChildren; } - function useFiber(fiber, pendingProps) { + function useFiber(fiber, pendingProps, expirationTime) { // We currently set sibling to null and index to 0 here because it is easy // to forget to do before returning it. E.g. for the single child case. - var clone = createWorkInProgress(fiber, pendingProps); + var clone = createWorkInProgress(fiber, pendingProps, expirationTime); clone.index = 0; clone.sibling = null; return clone; @@ -8545,10 +9218,10 @@ function ChildReconciler(shouldTrackSideEffects) { return lastPlacedIndex; } - var current = newFiber.alternate; + var current$$1 = newFiber.alternate; - if (current !== null) { - var oldIndex = current.index; + if (current$$1 !== null) { + var oldIndex = current$$1.index; if (oldIndex < lastPlacedIndex) { // This is a move. @@ -8575,8 +9248,13 @@ function ChildReconciler(shouldTrackSideEffects) { return newFiber; } - function updateTextNode(returnFiber, current, textContent, expirationTime) { - if (current === null || current.tag !== HostText) { + function updateTextNode( + returnFiber, + current$$1, + textContent, + expirationTime + ) { + if (current$$1 === null || current$$1.tag !== HostText) { // Insert var created = createFiberFromText( textContent, @@ -8587,48 +9265,48 @@ function ChildReconciler(shouldTrackSideEffects) { return created; } else { // Update - var existing = useFiber(current, textContent); + var existing = useFiber(current$$1, textContent, expirationTime); existing.return = returnFiber; return existing; } } - function updateElement(returnFiber, current, element, expirationTime) { - if (current !== null) { - if ( - 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); - existing.ref = coerceRef(returnFiber, current, element); - existing.return = returnFiber; - - { - existing._debugSource = element._source; - existing._debugOwner = element._owner; - } + function updateElement(returnFiber, current$$1, element, expirationTime) { + if ( + current$$1 !== null && + (current$$1.elementType === element.type || // Keep this check inline so it only runs on the false path: + isCompatibleFamilyForHotReloading(current$$1, element)) + ) { + // Move based on index + var existing = useFiber(current$$1, element.props, expirationTime); + existing.ref = coerceRef(returnFiber, current$$1, element); + existing.return = returnFiber; - return existing; + { + existing._debugSource = element._source; + existing._debugOwner = element._owner; } - } // Insert - var created = createFiberFromElement( - element, - returnFiber.mode, - expirationTime - ); - created.ref = coerceRef(returnFiber, current, element); - created.return = returnFiber; - return created; + return existing; + } else { + // Insert + var created = createFiberFromElement( + element, + returnFiber.mode, + expirationTime + ); + created.ref = coerceRef(returnFiber, current$$1, element); + created.return = returnFiber; + return created; + } } - function updatePortal(returnFiber, current, portal, expirationTime) { + function updatePortal(returnFiber, current$$1, portal, expirationTime) { if ( - current === null || - current.tag !== HostPortal || - current.stateNode.containerInfo !== portal.containerInfo || - current.stateNode.implementation !== portal.implementation + current$$1 === null || + current$$1.tag !== HostPortal || + current$$1.stateNode.containerInfo !== portal.containerInfo || + current$$1.stateNode.implementation !== portal.implementation ) { // Insert var created = createFiberFromPortal( @@ -8640,14 +9318,24 @@ function ChildReconciler(shouldTrackSideEffects) { return created; } else { // Update - var existing = useFiber(current, portal.children || []); + var existing = useFiber( + current$$1, + portal.children || [], + expirationTime + ); existing.return = returnFiber; return existing; } } - function updateFragment(returnFiber, current, fragment, expirationTime, key) { - if (current === null || current.tag !== Fragment) { + function updateFragment( + returnFiber, + current$$1, + fragment, + expirationTime, + key + ) { + if (current$$1 === null || current$$1.tag !== Fragment) { // Insert var created = createFiberFromFragment( fragment, @@ -8659,7 +9347,7 @@ function ChildReconciler(shouldTrackSideEffects) { return created; } else { // Update - var existing = useFiber(current, fragment); + var existing = useFiber(current$$1, fragment, expirationTime); existing.return = returnFiber; return existing; } @@ -8705,7 +9393,7 @@ function ChildReconciler(shouldTrackSideEffects) { } } - if (isArray$1(newChild) || getIteratorFn(newChild)) { + if (isArray(newChild) || getIteratorFn(newChild)) { var _created3 = createFiberFromFragment( newChild, returnFiber.mode, @@ -8788,7 +9476,7 @@ function ChildReconciler(shouldTrackSideEffects) { } } - if (isArray$1(newChild) || getIteratorFn(newChild)) { + if (isArray(newChild) || getIteratorFn(newChild)) { if (key !== null) { return null; } @@ -8874,7 +9562,7 @@ function ChildReconciler(shouldTrackSideEffects) { } } - if (isArray$1(newChild) || getIteratorFn(newChild)) { + if (isArray(newChild) || getIteratorFn(newChild)) { var _matchedFiber3 = existingChildren.get(newIdx) || null; return updateFragment( @@ -8928,7 +9616,8 @@ function ChildReconciler(shouldTrackSideEffects) { break; } - error( + warning$1( + false, "Encountered two children with the same key, `%s`. " + "Keys should be unique so that components maintain their identity " + "across updates. Non-unique keys may cause children to be " + @@ -8936,7 +9625,9 @@ function ChildReconciler(shouldTrackSideEffects) { "could change in a future version.", key ); + break; + default: break; } } @@ -9139,28 +9830,28 @@ function ChildReconciler(shouldTrackSideEffects) { typeof Symbol === "function" && // $FlowFixMe Flow doesn't know about toStringTag newChildrenIterable[Symbol.toStringTag] === "Generator" ) { - if (!didWarnAboutGenerators) { - error( - "Using Generators as children is unsupported and will likely yield " + - "unexpected results because enumerating a generator mutates it. " + - "You may convert it to an array with `Array.from()` or the " + - "`[...spread]` operator before rendering. Keep in mind " + - "you might need to polyfill these features for older browsers." - ); - } - + !didWarnAboutGenerators + ? warning$1( + false, + "Using Generators as children is unsupported and will likely yield " + + "unexpected results because enumerating a generator mutates it. " + + "You may convert it to an array with `Array.from()` or the " + + "`[...spread]` operator before rendering. Keep in mind " + + "you might need to polyfill these features for older browsers." + ) + : void 0; didWarnAboutGenerators = true; } // Warn about using Maps as children if (newChildrenIterable.entries === iteratorFn) { - if (!didWarnAboutMaps) { - error( - "Using Maps as children is unsupported and will likely yield " + - "unexpected results. Convert it to a sequence/iterable of keyed " + - "ReactElements instead." - ); - } - + !didWarnAboutMaps + ? warning$1( + false, + "Using Maps as children is unsupported and will likely yield " + + "unexpected results. Convert it to a sequence/iterable of keyed " + + "ReactElements instead." + ) + : void 0; didWarnAboutMaps = true; } // First, validate keys. // We'll get a different iterator later for the main pass. @@ -9339,7 +10030,7 @@ function ChildReconciler(shouldTrackSideEffects) { // We already have an existing node so let's just update it and delete // the rest. deleteRemainingChildren(returnFiber, currentFirstChild.sibling); - var existing = useFiber(currentFirstChild, textContent); + var existing = useFiber(currentFirstChild, textContent, expirationTime); existing.return = returnFiber; return existing; } // The existing first child is not a text node so we need to create one @@ -9368,55 +10059,33 @@ 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; - - { - existing._debugSource = element._source; - existing._debugOwner = element._owner; - } - - return existing; - } - - break; - } - - case Block: - - // We intentionally fallthrough here if enableBlocksAPI is not on. - // eslint-disable-next-lined no-fallthrough - - default: { - if ( - child.elementType === element.type || // Keep this check inline so it only runs on the false path: + if ( + child.tag === Fragment + ? element.type === REACT_FRAGMENT_TYPE + : child.elementType === element.type || // Keep this check inline so it only runs on the false path: isCompatibleFamilyForHotReloading(child, element) - ) { - deleteRemainingChildren(returnFiber, child.sibling); - - var _existing3 = useFiber(child, element.props); - - _existing3.ref = coerceRef(returnFiber, child, element); - _existing3.return = returnFiber; - - { - _existing3._debugSource = element._source; - _existing3._debugOwner = element._owner; - } - - return _existing3; - } + ) { + deleteRemainingChildren(returnFiber, child.sibling); + var existing = useFiber( + child, + element.type === REACT_FRAGMENT_TYPE + ? element.props.children + : element.props, + expirationTime + ); + existing.ref = coerceRef(returnFiber, child, element); + existing.return = returnFiber; - break; + { + existing._debugSource = element._source; + existing._debugOwner = element._owner; } - } // Didn't match. - deleteRemainingChildren(returnFiber, child); - break; + return existing; + } else { + deleteRemainingChildren(returnFiber, child); + break; + } } else { deleteChild(returnFiber, child); } @@ -9465,7 +10134,7 @@ function ChildReconciler(shouldTrackSideEffects) { child.stateNode.implementation === portal.implementation ) { deleteRemainingChildren(returnFiber, child.sibling); - var existing = useFiber(child, portal.children || []); + var existing = useFiber(child, portal.children || [], expirationTime); existing.return = returnFiber; return existing; } else { @@ -9550,7 +10219,7 @@ function ChildReconciler(shouldTrackSideEffects) { ); } - if (isArray$1(newChild)) { + if (isArray(newChild)) { return reconcileChildrenArray( returnFiber, currentFirstChild, @@ -9618,8 +10287,8 @@ function ChildReconciler(shouldTrackSideEffects) { var reconcileChildFibers = ChildReconciler(true); var mountChildFibers = ChildReconciler(false); -function cloneChildFibers(current, workInProgress) { - if (!(current === null || workInProgress.child === current.child)) { +function cloneChildFibers(current$$1, workInProgress) { + if (!(current$$1 === null || workInProgress.child === current$$1.child)) { throw Error("Resuming work not yet implemented."); } @@ -9628,7 +10297,11 @@ function cloneChildFibers(current, workInProgress) { } var currentChild = workInProgress.child; - var newChild = createWorkInProgress(currentChild, currentChild.pendingProps); + var newChild = createWorkInProgress( + currentChild, + currentChild.pendingProps, + currentChild.expirationTime + ); workInProgress.child = newChild; newChild.return = workInProgress; @@ -9636,7 +10309,8 @@ function cloneChildFibers(current, workInProgress) { currentChild = currentChild.sibling; newChild = newChild.sibling = createWorkInProgress( currentChild, - currentChild.pendingProps + currentChild.pendingProps, + currentChild.expirationTime ); newChild.return = workInProgress; } @@ -9686,7 +10360,7 @@ function pushHostContainer(fiber, nextRootInstance) { // So we push an empty value first. This lets us safely unwind on errors. push(contextStackCursor$1, NO_CONTEXT, fiber); - var nextRootContext = getRootHostContext(); // Now that we know this function doesn't throw, replace it. + var nextRootContext = getRootHostContext(nextRootInstance); // Now that we know this function doesn't throw, replace it. pop(contextStackCursor$1, fiber); push(contextStackCursor$1, nextRootContext, fiber); @@ -9706,7 +10380,7 @@ function getHostContext() { function pushHostContext(fiber) { var rootInstance = requiredContext(rootInstanceStackCursor.current); var context = requiredContext(contextStackCursor$1.current); - var nextContext = getChildHostContext(context, fiber.type); // Don't push this Fiber's context unless it's unique. + var nextContext = getChildHostContext(context, fiber.type, rootInstance); // Don't push this Fiber's context unless it's unique. if (context === nextContext) { return; @@ -9777,80 +10451,264 @@ function shouldCaptureSuspense(workInProgress, hasInvisibleParent) { return true; } - return false; + return false; + } + + var props = workInProgress.memoizedProps; // In order to capture, the Suspense component must have a fallback prop. + + if (props.fallback === undefined) { + return false; + } // Regular boundaries always capture. + + if (props.unstable_avoidThisFallback !== true) { + return true; + } // If it's a boundary we should avoid, then we prefer to bubble up to the + // parent boundary if it is currently invisible. + + if (hasInvisibleParent) { + return false; + } // If the parent is not able to handle it, we must handle it. + + return true; +} +function findFirstSuspended(row) { + var node = row; + + while (node !== null) { + if (node.tag === SuspenseComponent) { + var state = node.memoizedState; + + if (state !== null) { + var dehydrated = state.dehydrated; + + if ( + dehydrated === null || + isSuspenseInstancePending(dehydrated) || + isSuspenseInstanceFallback(dehydrated) + ) { + return node; + } + } + } else if ( + node.tag === SuspenseListComponent && // revealOrder undefined can't be trusted because it don't + // keep track of whether it suspended or not. + node.memoizedProps.revealOrder !== undefined + ) { + var didSuspend = (node.effectTag & DidCapture) !== NoEffect; + + if (didSuspend) { + return node; + } + } else if (node.child !== null) { + node.child.return = node; + node = node.child; + continue; + } + + if (node === row) { + return null; + } + + while (node.sibling === null) { + if (node.return === null || node.return === row) { + return null; + } + + node = node.return; + } + + node.sibling.return = node.return; + node = node.sibling; + } + + return null; +} + +var emptyObject$1 = {}; +var isArray$2 = Array.isArray; +function createResponderInstance( + responder, + responderProps, + responderState, + fiber +) { + return { + fiber: fiber, + props: responderProps, + responder: responder, + rootEventTypes: null, + state: responderState + }; +} + +function mountEventResponder( + responder, + responderProps, + fiber, + respondersMap, + rootContainerInstance +) { + var responderState = emptyObject$1; + var getInitialState = responder.getInitialState; + + if (getInitialState !== null) { + responderState = getInitialState(responderProps); + } + + var responderInstance = createResponderInstance( + responder, + responderProps, + responderState, + fiber + ); + + if (!rootContainerInstance) { + var node = fiber; + + while (node !== null) { + var tag = node.tag; + + if (tag === HostComponent) { + rootContainerInstance = node.stateNode; + break; + } else if (tag === HostRoot) { + rootContainerInstance = node.stateNode.containerInfo; + break; + } + + node = node.return; + } + } + + mountResponderInstance( + responder, + responderInstance, + responderProps, + responderState, + rootContainerInstance + ); + respondersMap.set(responder, responderInstance); +} + +function updateEventListener( + listener, + fiber, + visistedResponders, + respondersMap, + rootContainerInstance +) { + var responder; + var props; + + if (listener) { + responder = listener.responder; + props = listener.props; + } + + if (!(responder && responder.$$typeof === REACT_RESPONDER_TYPE)) { + throw Error( + "An invalid value was used as an event listener. Expect one or many event listeners created via React.unstable_useResponder()." + ); } - var props = workInProgress.memoizedProps; // In order to capture, the Suspense component must have a fallback prop. + var listenerProps = props; - if (props.fallback === undefined) { - return false; - } // Regular boundaries always capture. + if (visistedResponders.has(responder)) { + // show warning + { + warning$1( + false, + 'Duplicate event responder "%s" found in event listeners. ' + + "Event listeners passed to elements cannot use the same event responder more than once.", + responder.displayName + ); + } - if (props.unstable_avoidThisFallback !== true) { - return true; - } // If it's a boundary we should avoid, then we prefer to bubble up to the - // parent boundary if it is currently invisible. + return; + } - if (hasInvisibleParent) { - return false; - } // If the parent is not able to handle it, we must handle it. + visistedResponders.add(responder); + var responderInstance = respondersMap.get(responder); - return true; + if (responderInstance === undefined) { + // Mount (happens in either complete or commit phase) + mountEventResponder( + responder, + listenerProps, + fiber, + respondersMap, + rootContainerInstance + ); + } else { + // Update (happens during commit phase only) + responderInstance.props = listenerProps; + responderInstance.fiber = fiber; + } } -function findFirstSuspended(row) { - var node = row; - while (node !== null) { - if (node.tag === SuspenseComponent) { - var state = node.memoizedState; +function updateEventListeners(listeners, fiber, rootContainerInstance) { + var visistedResponders = new Set(); + var dependencies = fiber.dependencies; - if (state !== null) { - var dehydrated = state.dehydrated; + if (listeners != null) { + if (dependencies === null) { + dependencies = fiber.dependencies = { + expirationTime: NoWork, + firstContext: null, + responders: new Map() + }; + } - if ( - dehydrated === null || - isSuspenseInstancePending() || - isSuspenseInstanceFallback() - ) { - return node; - } - } - } else if ( - node.tag === SuspenseListComponent && // revealOrder undefined can't be trusted because it don't - // keep track of whether it suspended or not. - node.memoizedProps.revealOrder !== undefined - ) { - var didSuspend = (node.effectTag & DidCapture) !== NoEffect; + var respondersMap = dependencies.responders; - if (didSuspend) { - return node; - } - } else if (node.child !== null) { - node.child.return = node; - node = node.child; - continue; + if (respondersMap === null) { + respondersMap = new Map(); } - if (node === row) { - return null; + if (isArray$2(listeners)) { + for (var i = 0, length = listeners.length; i < length; i++) { + var listener = listeners[i]; + updateEventListener( + listener, + fiber, + visistedResponders, + respondersMap, + rootContainerInstance + ); + } + } else { + updateEventListener( + listeners, + fiber, + visistedResponders, + respondersMap, + rootContainerInstance + ); } + } - while (node.sibling === null) { - if (node.return === null || node.return === row) { - return null; - } + if (dependencies !== null) { + var _respondersMap = dependencies.responders; - node = node.return; - } + if (_respondersMap !== null) { + // Unmount + var mountedResponders = Array.from(_respondersMap.keys()); - node.sibling.return = node.return; - node = node.sibling; - } + for (var _i = 0, _length = mountedResponders.length; _i < _length; _i++) { + var mountedResponder = mountedResponders[_i]; - return null; -} + if (!visistedResponders.has(mountedResponder)) { + var responderInstance = _respondersMap.get(mountedResponder); -function createDeprecatedResponderListener(responder, props) { + unmountResponderInstance(responderInstance); + + _respondersMap.delete(mountedResponder); + } + } + } + } +} +function createResponderListener(responder, props) { var eventResponderListener = { responder: responder, props: props @@ -9863,19 +10721,33 @@ function createDeprecatedResponderListener(responder, props) { return eventResponderListener; } -var HasEffect = - /* */ - 1; // Represents the phase in which the effect (not the clean-up) fires. - -var Layout = - /* */ +var NoEffect$1 = + /* */ + 0; +var UnmountSnapshot = + /* */ 2; -var Passive$1 = - /* */ +var UnmountMutation = + /* */ 4; +var MountMutation = + /* */ + 8; +var UnmountLayout = + /* */ + 16; +var MountLayout = + /* */ + 32; +var MountPassive = + /* */ + 64; +var UnmountPassive = + /* */ + 128; -var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher, - ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig; +var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher; +var ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig; var didWarnAboutMismatchedHooksForComponent; { @@ -9883,7 +10755,7 @@ var didWarnAboutMismatchedHooksForComponent; } // These are set right before calling the component. -var renderExpirationTime = NoWork; // The work-in-progress fiber. I've named it differently to distinguish it from +var renderExpirationTime$1 = NoWork; // The work-in-progress fiber. I've named it differently to distinguish it from // the work-in-progress hook. var currentlyRenderingFiber$1 = null; // Hooks are stored as a linked list on the fiber's memoizedState field. The @@ -9892,12 +10764,26 @@ var currentlyRenderingFiber$1 = null; // Hooks are stored as a linked list on th // work-in-progress fiber. var currentHook = null; -var workInProgressHook = null; // Whether an update was scheduled at any point during the render phase. This -// does not get reset if we do another render pass; only when we're completely -// finished evaluating this component. This is an optimization so we know -// whether we need to clear render phase updates after a throw. - -var didScheduleRenderPhaseUpdate = false; +var nextCurrentHook = null; +var firstWorkInProgressHook = null; +var workInProgressHook = null; +var nextWorkInProgressHook = null; +var remainingExpirationTime = NoWork; +var componentUpdateQueue = null; +var sideEffectTag = 0; // Updates scheduled during render will trigger an immediate re-render at the +// end of the current pass. We can't store these updates on the normal queue, +// because if the work is aborted, they should be discarded. Because this is +// a relatively rare case, we also don't want to add an additional field to +// either the hook or queue object types. So we store them in a lazily create +// map of queue -> render-phase updates, which are discarded once the component +// completes without re-rendering. +// Whether an update was scheduled during the currently executing render pass. + +var didScheduleRenderPhaseUpdate = false; // Lazily created map of render-phase updates + +var renderPhaseUpdates = null; // Counter to prevent infinite loops. + +var numberOfReRenders = 0; var RE_RENDER_LIMIT = 25; // In DEV, this is the name of the currently executing primitive hook var currentHookNameInDev = null; // In DEV, this list ensures that hooks are called in the same order between renders. @@ -9942,7 +10828,8 @@ function checkDepsAreArrayDev(deps) { if (deps !== undefined && deps !== null && !Array.isArray(deps)) { // Verify deps, but only on mount to avoid extra checks. // It's unlikely their type would change as usually you define them inline. - error( + warning$1( + false, "%s received a final argument that is not an array (instead, received `%s`). When " + "specified, the final argument must be an array.", currentHookNameInDev, @@ -9978,7 +10865,8 @@ function warnOnHookMismatchInDev(currentHookName) { table += row; } - error( + warning$1( + false, "React has detected a change in the order of Hooks called by %s. " + "This will lead to bugs and errors if not fixed. " + "For more information, read the Rules of Hooks: https://fb.me/rules-of-hooks\n\n" + @@ -10012,7 +10900,8 @@ function areHookInputsEqual(nextDeps, prevDeps) { if (prevDeps === null) { { - error( + warning$1( + false, "%s received a final argument during this render, but not during " + "the previous render. Even though the final argument is optional, " + "its type cannot change between renders.", @@ -10027,7 +10916,8 @@ function areHookInputsEqual(nextDeps, prevDeps) { // Don't bother comparing lengths in prod because these arrays should be // passed inline. if (nextDeps.length !== prevDeps.length) { - error( + warning$1( + false, "The final argument passed to %s changed size between renders. The " + "order and size of this array must remain constant.\n\n" + "Previous: %s\n" + @@ -10040,7 +10930,7 @@ function areHookInputsEqual(nextDeps, prevDeps) { } for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) { - if (objectIs(nextDeps[i], prevDeps[i])) { + if (is$1(nextDeps[i], prevDeps[i])) { continue; } @@ -10055,11 +10945,12 @@ function renderWithHooks( workInProgress, Component, props, - secondArg, + refOrContext, nextRenderExpirationTime ) { - renderExpirationTime = nextRenderExpirationTime; + renderExpirationTime$1 = nextRenderExpirationTime; currentlyRenderingFiber$1 = workInProgress; + nextCurrentHook = current !== null ? current.memoizedState : null; { hookTypesDev = current !== null ? current._debugHookTypes : null; @@ -10067,52 +10958,42 @@ function renderWithHooks( ignorePreviousDependencies = current !== null && current.type !== workInProgress.type; - } - - workInProgress.memoizedState = null; - workInProgress.updateQueue = null; - workInProgress.expirationTime = NoWork; // The following should have already been reset + } // The following should have already been reset // currentHook = null; // workInProgressHook = null; + // remainingExpirationTime = NoWork; + // componentUpdateQueue = null; // didScheduleRenderPhaseUpdate = false; + // renderPhaseUpdates = null; + // numberOfReRenders = 0; + // sideEffectTag = 0; // TODO Warn if no hooks are used at all during mount, then some are used during update. - // Currently we will identify the update render as a mount because memoizedState === null. + // Currently we will identify the update render as a mount because nextCurrentHook === null. // This is tricky because it's valid for certain types of components (e.g. React.lazy) - // Using memoizedState to differentiate between mount/update only works if at least one stateful hook is used. + // Using nextCurrentHook to differentiate between mount/update only works if at least one stateful hook is used. // Non-stateful hooks (e.g. context) don't get added to memoizedState, - // so memoizedState would be null during updates and mounts. + // so nextCurrentHook would be null during updates and mounts. { - if (current !== null && current.memoizedState !== null) { - ReactCurrentDispatcher.current = HooksDispatcherOnUpdateInDEV; + if (nextCurrentHook !== null) { + ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV; } else if (hookTypesDev !== null) { // This dispatcher handles an edge case where a component is updating, // but no stateful hooks have been used. // We want to match the production code behavior (which will use HooksDispatcherOnMount), // but with the extra DEV validation to ensure hooks ordering hasn't changed. // This dispatcher does that. - ReactCurrentDispatcher.current = HooksDispatcherOnMountWithHookTypesInDEV; + ReactCurrentDispatcher$1.current = HooksDispatcherOnMountWithHookTypesInDEV; } else { - ReactCurrentDispatcher.current = HooksDispatcherOnMountInDEV; + ReactCurrentDispatcher$1.current = HooksDispatcherOnMountInDEV; } } - var children = Component(props, secondArg); // Check if there was a render phase update - - if (workInProgress.expirationTime === renderExpirationTime) { - // Keep rendering in a loop for as long as render phase updates continue to - // be scheduled. Use a counter to prevent infinite loops. - var numberOfReRenders = 0; + var children = Component(props, refOrContext); + if (didScheduleRenderPhaseUpdate) { do { - workInProgress.expirationTime = NoWork; - - if (!(numberOfReRenders < RE_RENDER_LIMIT)) { - throw Error( - "Too many re-renders. React limits the number of renders to prevent an infinite loop." - ); - } - + didScheduleRenderPhaseUpdate = false; numberOfReRenders += 1; { @@ -10121,33 +11002,46 @@ function renderWithHooks( ignorePreviousDependencies = false; } // Start over from the beginning of the list + nextCurrentHook = current !== null ? current.memoizedState : null; + nextWorkInProgressHook = firstWorkInProgressHook; currentHook = null; workInProgressHook = null; - workInProgress.updateQueue = null; + componentUpdateQueue = null; { // Also validate hook order for cascading updates. hookTypesUpdateIndexDev = -1; } - ReactCurrentDispatcher.current = HooksDispatcherOnRerenderInDEV; - children = Component(props, secondArg); - } while (workInProgress.expirationTime === renderExpirationTime); + ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV; + children = Component(props, refOrContext); + } while (didScheduleRenderPhaseUpdate); + + renderPhaseUpdates = null; + numberOfReRenders = 0; } // We can assume the previous dispatcher is always this one, since we set it // at the beginning of the render phase and there's no re-entrancy. - ReactCurrentDispatcher.current = ContextOnlyDispatcher; + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; + var renderedWork = currentlyRenderingFiber$1; + renderedWork.memoizedState = firstWorkInProgressHook; + renderedWork.expirationTime = remainingExpirationTime; + renderedWork.updateQueue = componentUpdateQueue; + renderedWork.effectTag |= sideEffectTag; { - workInProgress._debugHookTypes = hookTypesDev; + renderedWork._debugHookTypes = hookTypesDev; } // This check uses currentHook so that it works the same in DEV and prod bundles. // hookTypesDev could catch more cases (e.g. context) but only in DEV bundles. var didRenderTooFewHooks = currentHook !== null && currentHook.next !== null; - renderExpirationTime = NoWork; + renderExpirationTime$1 = NoWork; currentlyRenderingFiber$1 = null; currentHook = null; + nextCurrentHook = null; + firstWorkInProgressHook = null; workInProgressHook = null; + nextWorkInProgressHook = null; { currentHookNameInDev = null; @@ -10155,7 +11049,12 @@ function renderWithHooks( hookTypesUpdateIndexDev = -1; } - didScheduleRenderPhaseUpdate = false; + remainingExpirationTime = NoWork; + componentUpdateQueue = null; + sideEffectTag = 0; // These were reset above + // didScheduleRenderPhaseUpdate = false; + // renderPhaseUpdates = null; + // numberOfReRenders = 0; if (!!didRenderTooFewHooks) { throw Error( @@ -10173,37 +11072,20 @@ function bailoutHooks(current, workInProgress, expirationTime) { current.expirationTime = NoWork; } } -function resetHooksAfterThrow() { +function resetHooks() { // We can assume the previous dispatcher is always this one, since we set it // at the beginning of the render phase and there's no re-entrancy. - ReactCurrentDispatcher.current = ContextOnlyDispatcher; - - if (didScheduleRenderPhaseUpdate) { - // There were render phase updates. These are only valid for this render - // phase, which we are now aborting. Remove the updates from the queues so - // they do not persist to the next render. Do not remove updates from hooks - // that weren't processed. - // - // Only reset the updates from the queue if it has a clone. If it does - // not have a clone, that means it wasn't processed, and the updates were - // scheduled before we entered the render phase. - var hook = currentlyRenderingFiber$1.memoizedState; - - while (hook !== null) { - var queue = hook.queue; - - if (queue !== null) { - queue.pending = null; - } - - hook = hook.next; - } - } + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; // This is used to reset the state of this module when a component throws. + // It's also called inside mountIndeterminateComponent if we determine the + // component is a module-style component. - renderExpirationTime = NoWork; + renderExpirationTime$1 = NoWork; currentlyRenderingFiber$1 = null; currentHook = null; + nextCurrentHook = null; + firstWorkInProgressHook = null; workInProgressHook = null; + nextWorkInProgressHook = null; { hookTypesDev = null; @@ -10211,21 +11093,26 @@ function resetHooksAfterThrow() { currentHookNameInDev = null; } + remainingExpirationTime = NoWork; + componentUpdateQueue = null; + sideEffectTag = 0; didScheduleRenderPhaseUpdate = false; + renderPhaseUpdates = null; + numberOfReRenders = 0; } function mountWorkInProgressHook() { var hook = { memoizedState: null, baseState: null, - baseQueue: null, queue: null, + baseUpdate: null, next: null }; if (workInProgressHook === null) { // This is the first hook in the list - currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook; + firstWorkInProgressHook = workInProgressHook = hook; } else { // Append to the end of the list workInProgressHook = workInProgressHook.next = hook; @@ -10240,33 +11127,12 @@ function updateWorkInProgressHook() { // clone, or a work-in-progress hook from a previous render pass that we can // use as a base. When we reach the end of the base list, we must switch to // the dispatcher used for mounts. - var nextCurrentHook; - - if (currentHook === null) { - var current = currentlyRenderingFiber$1.alternate; - - if (current !== null) { - nextCurrentHook = current.memoizedState; - } else { - nextCurrentHook = null; - } - } else { - nextCurrentHook = currentHook.next; - } - - var nextWorkInProgressHook; - - if (workInProgressHook === null) { - nextWorkInProgressHook = currentlyRenderingFiber$1.memoizedState; - } else { - nextWorkInProgressHook = workInProgressHook.next; - } - if (nextWorkInProgressHook !== null) { // There's already a work-in-progress. Reuse it. workInProgressHook = nextWorkInProgressHook; nextWorkInProgressHook = workInProgressHook.next; currentHook = nextCurrentHook; + nextCurrentHook = currentHook !== null ? currentHook.next : null; } else { // Clone from the current hook. if (!(nextCurrentHook !== null)) { @@ -10277,18 +11143,20 @@ function updateWorkInProgressHook() { var newHook = { memoizedState: currentHook.memoizedState, baseState: currentHook.baseState, - baseQueue: currentHook.baseQueue, queue: currentHook.queue, + baseUpdate: currentHook.baseUpdate, next: null }; if (workInProgressHook === null) { // This is the first hook in the list. - currentlyRenderingFiber$1.memoizedState = workInProgressHook = newHook; + workInProgressHook = firstWorkInProgressHook = newHook; } else { // Append to the end of the list. workInProgressHook = workInProgressHook.next = newHook; } + + nextCurrentHook = currentHook.next; } return workInProgressHook; @@ -10301,7 +11169,6 @@ function createFunctionComponentUpdateQueue() { } function basicStateReducer(state, action) { - // $FlowFixMe: Flow doesn't like mixed types return typeof action === "function" ? action(state) : action; } @@ -10317,13 +11184,13 @@ function mountReducer(reducer, initialArg, init) { hook.memoizedState = hook.baseState = initialState; var queue = (hook.queue = { - pending: null, + last: null, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialState }); var dispatch = (queue.dispatch = dispatchAction.bind( - null, + null, // Flow doesn't know this is non-null, but we do. currentlyRenderingFiber$1, queue )); @@ -10341,191 +11208,160 @@ function updateReducer(reducer, initialArg, init) { } queue.lastRenderedReducer = reducer; - var current = currentHook; // The last rebase update that is NOT part of the base state. - var baseQueue = current.baseQueue; // The last pending update that hasn't been processed yet. + if (numberOfReRenders > 0) { + // This is a re-render. Apply the new render phase updates to the previous + // work-in-progress hook. + var _dispatch = queue.dispatch; + + if (renderPhaseUpdates !== null) { + // Render phase updates are stored in a map of queue -> linked list + var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue); + + if (firstRenderPhaseUpdate !== undefined) { + renderPhaseUpdates.delete(queue); + var newState = hook.memoizedState; + var update = firstRenderPhaseUpdate; + + do { + // Process this render phase update. We don't have to check the + // priority because it will always be the same as the current + // render's. + var action = update.action; + newState = reducer(newState, action); + update = update.next; + } while (update !== null); // Mark that the fiber performed work, but only if the new state is + // different from the current state. + + if (!is$1(newState, hook.memoizedState)) { + markWorkInProgressReceivedUpdate(); + } + + hook.memoizedState = newState; // Don't persist the state accumulated from the render phase updates to + // the base state unless the queue is empty. + // TODO: Not sure if this is the desired semantics, but it's what we + // do for gDSFP. I can't remember why. + + if (hook.baseUpdate === queue.last) { + hook.baseState = newState; + } + + queue.lastRenderedState = newState; + return [newState, _dispatch]; + } + } + + return [hook.memoizedState, _dispatch]; + } // The last update in the entire queue + + var last = queue.last; // The last update that is part of the base state. - var pendingQueue = queue.pending; + var baseUpdate = hook.baseUpdate; + var baseState = hook.baseState; // Find the first unprocessed update. - if (pendingQueue !== null) { - // We have new updates that haven't been processed yet. - // We'll add them to the base queue. - if (baseQueue !== null) { - // Merge the pending queue and the base queue. - var baseFirst = baseQueue.next; - var pendingFirst = pendingQueue.next; - baseQueue.next = pendingFirst; - pendingQueue.next = baseFirst; + var first; + + if (baseUpdate !== null) { + if (last !== null) { + // For the first update, the queue is a circular linked list where + // `queue.last.next = queue.first`. Once the first update commits, and + // the `baseUpdate` is no longer empty, we can unravel the list. + last.next = null; } - current.baseQueue = baseQueue = pendingQueue; - queue.pending = null; + first = baseUpdate.next; + } else { + first = last !== null ? last.next : null; } - if (baseQueue !== null) { - // We have a queue to process. - var first = baseQueue.next; - var newState = current.baseState; + if (first !== null) { + var _newState = baseState; var newBaseState = null; - var newBaseQueueFirst = null; - var newBaseQueueLast = null; - var update = first; + var newBaseUpdate = null; + var prevUpdate = baseUpdate; + var _update = first; + var didSkip = false; do { - var updateExpirationTime = update.expirationTime; + var updateExpirationTime = _update.expirationTime; - if (updateExpirationTime < renderExpirationTime) { + if (updateExpirationTime < renderExpirationTime$1) { // 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 = { - expirationTime: update.expirationTime, - suspenseConfig: update.suspenseConfig, - action: update.action, - eagerReducer: update.eagerReducer, - eagerState: update.eagerState, - next: null - }; - - if (newBaseQueueLast === null) { - newBaseQueueFirst = newBaseQueueLast = clone; - newBaseState = newState; - } else { - newBaseQueueLast = newBaseQueueLast.next = clone; + if (!didSkip) { + didSkip = true; + newBaseUpdate = prevUpdate; + newBaseState = _newState; } // Update the remaining priority in the queue. - if (updateExpirationTime > currentlyRenderingFiber$1.expirationTime) { - currentlyRenderingFiber$1.expirationTime = updateExpirationTime; - markUnprocessedUpdateTime(updateExpirationTime); + if (updateExpirationTime > remainingExpirationTime) { + remainingExpirationTime = updateExpirationTime; + markUnprocessedUpdateTime(remainingExpirationTime); } } else { // This update does have sufficient priority. - if (newBaseQueueLast !== null) { - var _clone = { - expirationTime: Sync, - // This update is going to be committed so we never want uncommit it. - suspenseConfig: update.suspenseConfig, - action: update.action, - eagerReducer: update.eagerReducer, - eagerState: update.eagerState, - next: null - }; - newBaseQueueLast = newBaseQueueLast.next = _clone; - } // Mark the event time of this update as relevant to this render pass. + // Mark the event time of this update as relevant to this render pass. // TODO: This should ideally use the true event time of this update rather than // its priority which is a derived and not reverseable value. // TODO: We should skip this update if it was already committed but currently // we have no way of detecting the difference between a committed and suspended // update here. - markRenderEventTimeAndConfig( updateExpirationTime, - update.suspenseConfig + _update.suspenseConfig ); // Process this update. - if (update.eagerReducer === reducer) { + if (_update.eagerReducer === reducer) { // If this update was processed eagerly, and its reducer matches the // current reducer, we can use the eagerly computed state. - newState = update.eagerState; + _newState = _update.eagerState; } else { - var action = update.action; - newState = reducer(newState, action); + var _action = _update.action; + _newState = reducer(_newState, _action); } } - update = update.next; - } while (update !== null && update !== first); + prevUpdate = _update; + _update = _update.next; + } while (_update !== null && _update !== first); - if (newBaseQueueLast === null) { - newBaseState = newState; - } else { - newBaseQueueLast.next = newBaseQueueFirst; + if (!didSkip) { + newBaseUpdate = prevUpdate; + newBaseState = _newState; } // Mark that the fiber performed work, but only if the new state is // different from the current state. - if (!objectIs(newState, hook.memoizedState)) { + if (!is$1(_newState, hook.memoizedState)) { markWorkInProgressReceivedUpdate(); } - hook.memoizedState = newState; + hook.memoizedState = _newState; + hook.baseUpdate = newBaseUpdate; hook.baseState = newBaseState; - hook.baseQueue = newBaseQueueLast; - queue.lastRenderedState = newState; + queue.lastRenderedState = _newState; } var dispatch = queue.dispatch; return [hook.memoizedState, dispatch]; } -function rerenderReducer(reducer, initialArg, init) { - var hook = updateWorkInProgressHook(); - var queue = hook.queue; - - if (!(queue !== null)) { - throw Error( - "Should have a queue. This is likely a bug in React. Please file an issue." - ); - } - - queue.lastRenderedReducer = reducer; // This is a re-render. Apply the new render phase updates to the previous - // work-in-progress hook. - - var dispatch = queue.dispatch; - var lastRenderPhaseUpdate = queue.pending; - var newState = hook.memoizedState; - - if (lastRenderPhaseUpdate !== null) { - // The queue doesn't persist past this render pass. - queue.pending = null; - var firstRenderPhaseUpdate = lastRenderPhaseUpdate.next; - var update = firstRenderPhaseUpdate; - - do { - // Process this render phase update. We don't have to check the - // priority because it will always be the same as the current - // render's. - var action = update.action; - newState = reducer(newState, action); - update = update.next; - } while (update !== firstRenderPhaseUpdate); // Mark that the fiber performed work, but only if the new state is - // different from the current state. - - if (!objectIs(newState, hook.memoizedState)) { - markWorkInProgressReceivedUpdate(); - } - - hook.memoizedState = newState; // Don't persist the state accumulated from the render phase updates to - // the base state unless the queue is empty. - // TODO: Not sure if this is the desired semantics, but it's what we - // do for gDSFP. I can't remember why. - - if (hook.baseQueue === null) { - hook.baseState = newState; - } - - queue.lastRenderedState = newState; - } - - return [newState, dispatch]; -} - function mountState(initialState) { var hook = mountWorkInProgressHook(); if (typeof initialState === "function") { - // $FlowFixMe: Flow doesn't like mixed types initialState = initialState(); } hook.memoizedState = hook.baseState = initialState; var queue = (hook.queue = { - pending: null, + last: null, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState }); var dispatch = (queue.dispatch = dispatchAction.bind( - null, + null, // Flow doesn't know this is non-null, but we do. currentlyRenderingFiber$1, queue )); @@ -10533,11 +11369,7 @@ function mountState(initialState) { } function updateState(initialState) { - return updateReducer(basicStateReducer); -} - -function rerenderState(initialState) { - return rerenderReducer(basicStateReducer); + return updateReducer(basicStateReducer, initialState); } function pushEffect(tag, create, destroy, deps) { @@ -10549,11 +11381,9 @@ function pushEffect(tag, create, destroy, deps) { // Circular next: null }; - var componentUpdateQueue = currentlyRenderingFiber$1.updateQueue; if (componentUpdateQueue === null) { componentUpdateQueue = createFunctionComponentUpdateQueue(); - currentlyRenderingFiber$1.updateQueue = componentUpdateQueue; componentUpdateQueue.lastEffect = effect.next = effect; } else { var lastEffect = componentUpdateQueue.lastEffect; @@ -10593,13 +11423,8 @@ function updateRef(initialValue) { function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var hook = mountWorkInProgressHook(); var nextDeps = deps === undefined ? null : deps; - currentlyRenderingFiber$1.effectTag |= fiberEffectTag; - hook.memoizedState = pushEffect( - HasEffect | hookEffectTag, - create, - undefined, - nextDeps - ); + sideEffectTag |= fiberEffectTag; + hook.memoizedState = pushEffect(hookEffectTag, create, undefined, nextDeps); } function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { @@ -10615,19 +11440,14 @@ function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var prevDeps = prevEffect.deps; if (areHookInputsEqual(nextDeps, prevDeps)) { - pushEffect(hookEffectTag, create, destroy, nextDeps); + pushEffect(NoEffect$1, create, destroy, nextDeps); return; } } } - currentlyRenderingFiber$1.effectTag |= fiberEffectTag; - hook.memoizedState = pushEffect( - HasEffect | hookEffectTag, - create, - destroy, - nextDeps - ); + sideEffectTag |= fiberEffectTag; + hook.memoizedState = pushEffect(hookEffectTag, create, destroy, nextDeps); } function mountEffect(create, deps) { @@ -10638,7 +11458,12 @@ function mountEffect(create, deps) { } } - return mountEffectImpl(Update | Passive, Passive$1, create, deps); + return mountEffectImpl( + Update | Passive, + UnmountPassive | MountPassive, + create, + deps + ); } function updateEffect(create, deps) { @@ -10649,15 +11474,20 @@ function updateEffect(create, deps) { } } - return updateEffectImpl(Update | Passive, Passive$1, create, deps); + return updateEffectImpl( + Update | Passive, + UnmountPassive | MountPassive, + create, + deps + ); } function mountLayoutEffect(create, deps) { - return mountEffectImpl(Update, Layout, create, deps); + return mountEffectImpl(Update, UnmountMutation | MountLayout, create, deps); } function updateLayoutEffect(create, deps) { - return updateEffectImpl(Update, Layout, create, deps); + return updateEffectImpl(Update, UnmountMutation | MountLayout, create, deps); } function imperativeHandleEffect(create, ref) { @@ -10674,13 +11504,14 @@ function imperativeHandleEffect(create, ref) { var refObject = ref; { - if (!refObject.hasOwnProperty("current")) { - error( - "Expected useImperativeHandle() first argument to either be a " + - "ref callback or React.createRef() object. Instead received: %s.", - "an object with keys {" + Object.keys(refObject).join(", ") + "}" - ); - } + !refObject.hasOwnProperty("current") + ? warning$1( + false, + "Expected useImperativeHandle() first argument to either be a " + + "ref callback or React.createRef() object. Instead received: %s.", + "an object with keys {" + Object.keys(refObject).join(", ") + "}" + ) + : void 0; } var _inst2 = create(); @@ -10694,20 +11525,21 @@ function imperativeHandleEffect(create, ref) { function mountImperativeHandle(ref, create, deps) { { - if (typeof create !== "function") { - error( - "Expected useImperativeHandle() second argument to be a function " + - "that creates a handle. Instead received: %s.", - create !== null ? typeof create : "null" - ); - } + !(typeof create === "function") + ? warning$1( + false, + "Expected useImperativeHandle() second argument to be a function " + + "that creates a handle. Instead received: %s.", + create !== null ? typeof create : "null" + ) + : void 0; } // TODO: If deps are provided, should we skip comparing the ref itself? var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null; return mountEffectImpl( Update, - Layout, + UnmountMutation | MountLayout, imperativeHandleEffect.bind(null, create, ref), effectDeps ); @@ -10715,20 +11547,21 @@ function mountImperativeHandle(ref, create, deps) { function updateImperativeHandle(ref, create, deps) { { - if (typeof create !== "function") { - error( - "Expected useImperativeHandle() second argument to be a function " + - "that creates a handle. Instead received: %s.", - create !== null ? typeof create : "null" - ); - } + !(typeof create === "function") + ? warning$1( + false, + "Expected useImperativeHandle() second argument to be a function " + + "that creates a handle. Instead received: %s.", + create !== null ? typeof create : "null" + ) + : void 0; } // TODO: If deps are provided, should we skip comparing the ref itself? var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null; return updateEffectImpl( Update, - Layout, + UnmountMutation | MountLayout, imperativeHandleEffect.bind(null, create, ref), effectDeps ); @@ -10804,14 +11637,17 @@ function mountDeferredValue(value, config) { mountEffect( function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config; + Scheduler.unstable_next(function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + config === undefined ? null : config; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }); }, [value, config] ); @@ -10819,149 +11655,99 @@ function mountDeferredValue(value, config) { } function updateDeferredValue(value, config) { - var _updateState = updateState(), + var _updateState = updateState(value), prevValue = _updateState[0], setValue = _updateState[1]; updateEffect( function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config; - - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }, - [value, config] - ); - return prevValue; -} - -function rerenderDeferredValue(value, config) { - var _rerenderState = rerenderState(), - prevValue = _rerenderState[0], - setValue = _rerenderState[1]; - - updateEffect( - function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config; + Scheduler.unstable_next(function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + config === undefined ? null : config; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }); }, [value, config] ); return prevValue; } -function startTransition(setPending, config, callback) { - var priorityLevel = getCurrentPriorityLevel(); - runWithPriority( - priorityLevel < UserBlockingPriority ? UserBlockingPriority : priorityLevel, - function() { - setPending(true); - } - ); - runWithPriority( - priorityLevel > NormalPriority ? NormalPriority : priorityLevel, - function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config; - - try { - setPending(false); - callback(); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - } - ); -} - function mountTransition(config) { var _mountState2 = mountState(false), isPending = _mountState2[0], setPending = _mountState2[1]; - var start = mountCallback(startTransition.bind(null, setPending, config), [ - setPending, - config - ]); - return [start, isPending]; + var startTransition = mountCallback( + function(callback) { + setPending(true); + Scheduler.unstable_next(function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + config === undefined ? null : config; + + try { + setPending(false); + callback(); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }); + }, + [config, isPending] + ); + return [startTransition, isPending]; } function updateTransition(config) { - var _updateState2 = updateState(), + var _updateState2 = updateState(false), isPending = _updateState2[0], setPending = _updateState2[1]; - var start = updateCallback(startTransition.bind(null, setPending, config), [ - setPending, - config - ]); - return [start, isPending]; -} - -function rerenderTransition(config) { - var _rerenderState2 = rerenderState(), - isPending = _rerenderState2[0], - setPending = _rerenderState2[1]; + var startTransition = updateCallback( + function(callback) { + setPending(true); + Scheduler.unstable_next(function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + config === undefined ? null : config; - var start = updateCallback(startTransition.bind(null, setPending, config), [ - setPending, - config - ]); - return [start, isPending]; + try { + setPending(false); + callback(); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }); + }, + [config, isPending] + ); + return [startTransition, isPending]; } function dispatchAction(fiber, queue, action) { - { - if (typeof arguments[3] === "function") { - error( - "State updates from the useState() and useReducer() Hooks don't support the " + - "second callback argument. To execute a side effect after " + - "rendering, declare it in the component body with useEffect()." - ); - } + if (!(numberOfReRenders < RE_RENDER_LIMIT)) { + throw Error( + "Too many re-renders. React limits the number of renders to prevent an infinite loop." + ); } - var currentTime = requestCurrentTimeForUpdate(); - var suspenseConfig = requestCurrentSuspenseConfig(); - var expirationTime = computeExpirationForFiber( - currentTime, - fiber, - suspenseConfig - ); - var update = { - expirationTime: expirationTime, - suspenseConfig: suspenseConfig, - action: action, - eagerReducer: null, - eagerState: null, - next: null - }; - { - update.priority = getCurrentPriorityLevel(); - } // 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; + !(typeof arguments[3] !== "function") + ? warning$1( + false, + "State updates from the useState() and useReducer() Hooks don't support the " + + "second callback argument. To execute a side effect after " + + "rendering, declare it in the component body with useEffect()." + ) + : void 0; } - queue.pending = update; var alternate = fiber.alternate; if ( @@ -10972,9 +11758,76 @@ 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. didScheduleRenderPhaseUpdate = true; - update.expirationTime = renderExpirationTime; - currentlyRenderingFiber$1.expirationTime = renderExpirationTime; + var update = { + expirationTime: renderExpirationTime$1, + suspenseConfig: null, + action: action, + eagerReducer: null, + eagerState: null, + next: null + }; + + { + update.priority = getCurrentPriorityLevel(); + } + + if (renderPhaseUpdates === null) { + renderPhaseUpdates = new Map(); + } + + var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue); + + if (firstRenderPhaseUpdate === undefined) { + renderPhaseUpdates.set(queue, update); + } else { + // Append the update to the end of the list. + var lastRenderPhaseUpdate = firstRenderPhaseUpdate; + + while (lastRenderPhaseUpdate.next !== null) { + lastRenderPhaseUpdate = lastRenderPhaseUpdate.next; + } + + lastRenderPhaseUpdate.next = update; + } } else { + var currentTime = requestCurrentTimeForUpdate(); + var suspenseConfig = requestCurrentSuspenseConfig(); + var expirationTime = computeExpirationForFiber( + currentTime, + fiber, + suspenseConfig + ); + var _update2 = { + expirationTime: expirationTime, + suspenseConfig: suspenseConfig, + action: action, + eagerReducer: null, + eagerState: null, + next: null + }; + + { + _update2.priority = getCurrentPriorityLevel(); + } // Append the update to the end of the list. + + var last = queue.last; + + if (last === null) { + // This is the first update. Create a circular list. + _update2.next = _update2; + } else { + var first = last.next; + + if (first !== null) { + // Still circular. + _update2.next = first; + } + + last.next = _update2; + } + + queue.last = _update2; + if ( fiber.expirationTime === NoWork && (alternate === null || alternate.expirationTime === NoWork) @@ -10988,8 +11841,8 @@ function dispatchAction(fiber, queue, action) { var prevDispatcher; { - prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; } try { @@ -10999,10 +11852,10 @@ function dispatchAction(fiber, queue, action) { // time we enter the render phase, then the eager state can be used // without calling the reducer again. - update.eagerReducer = lastRenderedReducer; - update.eagerState = eagerState; + _update2.eagerReducer = lastRenderedReducer; + _update2.eagerState = eagerState; - if (objectIs(eagerState, currentState)) { + if (is$1(eagerState, currentState)) { // Fast path. We can bail out without scheduling React to re-render. // It's still possible that we'll need to rebase this update later, // if the component re-renders for a different reason and by that @@ -11013,7 +11866,7 @@ function dispatchAction(fiber, queue, action) { // Suppress the error. It will throw again in the render phase. } finally { { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } } } @@ -11031,14 +11884,6 @@ function dispatchAction(fiber, queue, action) { } } -function mountEventListener(event) { - return undefined; -} - -function updateEventListener(event) { - return undefined; -} - var ContextOnlyDispatcher = { readContext: readContext, useCallback: throwInvalidHookError, @@ -11053,20 +11898,18 @@ var ContextOnlyDispatcher = { useDebugValue: throwInvalidHookError, useResponder: throwInvalidHookError, useDeferredValue: throwInvalidHookError, - useTransition: throwInvalidHookError, - useEvent: throwInvalidHookError + useTransition: throwInvalidHookError }; var HooksDispatcherOnMountInDEV = null; var HooksDispatcherOnMountWithHookTypesInDEV = null; var HooksDispatcherOnUpdateInDEV = null; -var HooksDispatcherOnRerenderInDEV = null; var InvalidNestedHooksDispatcherOnMountInDEV = null; var InvalidNestedHooksDispatcherOnUpdateInDEV = null; -var InvalidNestedHooksDispatcherOnRerenderInDEV = null; { var warnInvalidContextAccess = function() { - error( + warning$1( + false, "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 " + @@ -11075,7 +11918,8 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; }; var warnInvalidHookAccess = function() { - error( + warning$1( + false, "Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks. " + "You can only call Hooks at the top level of your React function. " + "For more information, see " + @@ -11120,25 +11964,25 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; currentHookNameInDev = "useMemo"; mountHookTypesDev(); checkDepsAreArrayDev(deps); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; try { return mountMemo(create, deps); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useReducer: function(reducer, initialArg, init) { currentHookNameInDev = "useReducer"; mountHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; try { return mountReducer(reducer, initialArg, init); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useRef: function(initialValue) { @@ -11149,24 +11993,24 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; useState: function(initialState) { currentHookNameInDev = "useState"; mountHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; try { return mountState(initialState); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useDebugValue: function(value, formatterFn) { currentHookNameInDev = "useDebugValue"; mountHookTypesDev(); - return mountDebugValue(); + return mountDebugValue(value, formatterFn); }, useResponder: function(responder, props) { currentHookNameInDev = "useResponder"; mountHookTypesDev(); - return createDeprecatedResponderListener(responder, props); + return createResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; @@ -11177,11 +12021,6 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; currentHookNameInDev = "useTransition"; mountHookTypesDev(); return mountTransition(config); - }, - useEvent: function(event) { - currentHookNameInDev = "useEvent"; - mountHookTypesDev(); - return mountEventListener(); } }; HooksDispatcherOnMountWithHookTypesInDEV = { @@ -11216,25 +12055,25 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; useMemo: function(create, deps) { currentHookNameInDev = "useMemo"; updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; try { return mountMemo(create, deps); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useReducer: function(reducer, initialArg, init) { currentHookNameInDev = "useReducer"; updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; try { return mountReducer(reducer, initialArg, init); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useRef: function(initialValue) { @@ -11245,24 +12084,24 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; useState: function(initialState) { currentHookNameInDev = "useState"; updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; try { return mountState(initialState); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useDebugValue: function(value, formatterFn) { currentHookNameInDev = "useDebugValue"; updateHookTypesDev(); - return mountDebugValue(); + return mountDebugValue(value, formatterFn); }, useResponder: function(responder, props) { currentHookNameInDev = "useResponder"; updateHookTypesDev(); - return createDeprecatedResponderListener(responder, props); + return createResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; @@ -11273,11 +12112,6 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; currentHookNameInDev = "useTransition"; updateHookTypesDev(); return mountTransition(config); - }, - useEvent: function(event) { - currentHookNameInDev = "useEvent"; - updateHookTypesDev(); - return mountEventListener(); } }; HooksDispatcherOnUpdateInDEV = { @@ -11312,53 +12146,53 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; useMemo: function(create, deps) { currentHookNameInDev = "useMemo"; updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; try { return updateMemo(create, deps); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useReducer: function(reducer, initialArg, init) { currentHookNameInDev = "useReducer"; updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; try { return updateReducer(reducer, initialArg, init); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useRef: function(initialValue) { currentHookNameInDev = "useRef"; updateHookTypesDev(); - return updateRef(); + return updateRef(initialValue); }, useState: function(initialState) { currentHookNameInDev = "useState"; updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; try { return updateState(initialState); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useDebugValue: function(value, formatterFn) { currentHookNameInDev = "useDebugValue"; updateHookTypesDev(); - return updateDebugValue(); + return updateDebugValue(value, formatterFn); }, useResponder: function(responder, props) { currentHookNameInDev = "useResponder"; updateHookTypesDev(); - return createDeprecatedResponderListener(responder, props); + return createResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; @@ -11369,107 +12203,6 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; currentHookNameInDev = "useTransition"; updateHookTypesDev(); return updateTransition(config); - }, - useEvent: function(event) { - currentHookNameInDev = "useEvent"; - updateHookTypesDev(); - return updateEventListener(); - } - }; - HooksDispatcherOnRerenderInDEV = { - readContext: function(context, observedBits) { - return readContext(context, observedBits); - }, - useCallback: function(callback, deps) { - currentHookNameInDev = "useCallback"; - updateHookTypesDev(); - return updateCallback(callback, deps); - }, - useContext: function(context, observedBits) { - currentHookNameInDev = "useContext"; - updateHookTypesDev(); - return readContext(context, observedBits); - }, - useEffect: function(create, deps) { - currentHookNameInDev = "useEffect"; - updateHookTypesDev(); - return updateEffect(create, deps); - }, - useImperativeHandle: function(ref, create, deps) { - currentHookNameInDev = "useImperativeHandle"; - updateHookTypesDev(); - return updateImperativeHandle(ref, create, deps); - }, - useLayoutEffect: function(create, deps) { - currentHookNameInDev = "useLayoutEffect"; - updateHookTypesDev(); - return updateLayoutEffect(create, deps); - }, - useMemo: function(create, deps) { - currentHookNameInDev = "useMemo"; - updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnRerenderInDEV; - - try { - return updateMemo(create, deps); - } finally { - ReactCurrentDispatcher.current = prevDispatcher; - } - }, - useReducer: function(reducer, initialArg, init) { - currentHookNameInDev = "useReducer"; - updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnRerenderInDEV; - - try { - return rerenderReducer(reducer, initialArg, init); - } finally { - ReactCurrentDispatcher.current = prevDispatcher; - } - }, - useRef: function(initialValue) { - currentHookNameInDev = "useRef"; - updateHookTypesDev(); - return updateRef(); - }, - useState: function(initialState) { - currentHookNameInDev = "useState"; - updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnRerenderInDEV; - - try { - return rerenderState(initialState); - } finally { - ReactCurrentDispatcher.current = prevDispatcher; - } - }, - useDebugValue: function(value, formatterFn) { - currentHookNameInDev = "useDebugValue"; - updateHookTypesDev(); - return updateDebugValue(); - }, - useResponder: function(responder, props) { - currentHookNameInDev = "useResponder"; - updateHookTypesDev(); - return createDeprecatedResponderListener(responder, props); - }, - useDeferredValue: function(value, config) { - currentHookNameInDev = "useDeferredValue"; - updateHookTypesDev(); - return rerenderDeferredValue(value, config); - }, - useTransition: function(config) { - currentHookNameInDev = "useTransition"; - updateHookTypesDev(); - return rerenderTransition(config); - }, - useEvent: function(event) { - currentHookNameInDev = "useEvent"; - updateHookTypesDev(); - return updateEventListener(); } }; InvalidNestedHooksDispatcherOnMountInDEV = { @@ -11511,190 +12244,73 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; currentHookNameInDev = "useMemo"; warnInvalidHookAccess(); mountHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; try { return mountMemo(create, deps); } finally { - ReactCurrentDispatcher.current = prevDispatcher; - } - }, - useReducer: function(reducer, initialArg, init) { - currentHookNameInDev = "useReducer"; - warnInvalidHookAccess(); - mountHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; - - try { - return mountReducer(reducer, initialArg, init); - } finally { - ReactCurrentDispatcher.current = prevDispatcher; - } - }, - useRef: function(initialValue) { - currentHookNameInDev = "useRef"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountRef(initialValue); - }, - useState: function(initialState) { - currentHookNameInDev = "useState"; - warnInvalidHookAccess(); - mountHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; - - try { - return mountState(initialState); - } finally { - ReactCurrentDispatcher.current = prevDispatcher; - } - }, - useDebugValue: function(value, formatterFn) { - currentHookNameInDev = "useDebugValue"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountDebugValue(); - }, - useResponder: function(responder, props) { - currentHookNameInDev = "useResponder"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return createDeprecatedResponderListener(responder, props); - }, - useDeferredValue: function(value, config) { - currentHookNameInDev = "useDeferredValue"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountDeferredValue(value, config); - }, - useTransition: function(config) { - currentHookNameInDev = "useTransition"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountTransition(config); - }, - useEvent: function(event) { - currentHookNameInDev = "useEvent"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountEventListener(); - } - }; - InvalidNestedHooksDispatcherOnUpdateInDEV = { - 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.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; - - try { - return updateMemo(create, deps); - } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useReducer: function(reducer, initialArg, init) { currentHookNameInDev = "useReducer"; warnInvalidHookAccess(); - updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + mountHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; try { - return updateReducer(reducer, initialArg, init); + return mountReducer(reducer, initialArg, init); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useRef: function(initialValue) { currentHookNameInDev = "useRef"; warnInvalidHookAccess(); - updateHookTypesDev(); - return updateRef(); + mountHookTypesDev(); + return mountRef(initialValue); }, useState: function(initialState) { currentHookNameInDev = "useState"; warnInvalidHookAccess(); - updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + mountHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; try { - return updateState(initialState); + return mountState(initialState); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useDebugValue: function(value, formatterFn) { currentHookNameInDev = "useDebugValue"; warnInvalidHookAccess(); - updateHookTypesDev(); - return updateDebugValue(); + mountHookTypesDev(); + return mountDebugValue(value, formatterFn); }, useResponder: function(responder, props) { currentHookNameInDev = "useResponder"; warnInvalidHookAccess(); - updateHookTypesDev(); - return createDeprecatedResponderListener(responder, props); + mountHookTypesDev(); + return createResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; warnInvalidHookAccess(); - updateHookTypesDev(); - return updateDeferredValue(value, config); + mountHookTypesDev(); + return mountDeferredValue(value, config); }, useTransition: function(config) { currentHookNameInDev = "useTransition"; warnInvalidHookAccess(); - updateHookTypesDev(); - return updateTransition(config); - }, - useEvent: function(event) { - currentHookNameInDev = "useEvent"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateEventListener(); + mountHookTypesDev(); + return mountTransition(config); } }; - InvalidNestedHooksDispatcherOnRerenderInDEV = { + InvalidNestedHooksDispatcherOnUpdateInDEV = { readContext: function(context, observedBits) { warnInvalidContextAccess(); return readContext(context, observedBits); @@ -11733,80 +12349,76 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; currentHookNameInDev = "useMemo"; warnInvalidHookAccess(); updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; try { return updateMemo(create, deps); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useReducer: function(reducer, initialArg, init) { currentHookNameInDev = "useReducer"; warnInvalidHookAccess(); updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; try { - return rerenderReducer(reducer, initialArg, init); + return updateReducer(reducer, initialArg, init); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useRef: function(initialValue) { currentHookNameInDev = "useRef"; warnInvalidHookAccess(); updateHookTypesDev(); - return updateRef(); + return updateRef(initialValue); }, useState: function(initialState) { currentHookNameInDev = "useState"; warnInvalidHookAccess(); updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; try { - return rerenderState(initialState); + return updateState(initialState); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useDebugValue: function(value, formatterFn) { currentHookNameInDev = "useDebugValue"; warnInvalidHookAccess(); updateHookTypesDev(); - return updateDebugValue(); + return updateDebugValue(value, formatterFn); }, useResponder: function(responder, props) { currentHookNameInDev = "useResponder"; warnInvalidHookAccess(); updateHookTypesDev(); - return createDeprecatedResponderListener(responder, props); + return createResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; warnInvalidHookAccess(); updateHookTypesDev(); - return rerenderDeferredValue(value, config); + return updateDeferredValue(value, config); }, useTransition: function(config) { currentHookNameInDev = "useTransition"; warnInvalidHookAccess(); updateHookTypesDev(); - return rerenderTransition(config); - }, - useEvent: function(event) { - currentHookNameInDev = "useEvent"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateEventListener(); + return updateTransition(config); } }; } +// CommonJS interop named imports. + var now$1 = Scheduler.unstable_now; var commitTime = 0; var profilerStartTime = -1; @@ -11816,10 +12428,18 @@ function getCommitTime() { } function recordCommitTime() { + if (!enableProfilerTimer) { + return; + } + commitTime = now$1(); } function startProfilerTimer(fiber) { + if (!enableProfilerTimer) { + return; + } + profilerStartTime = now$1(); if (fiber.actualStartTime < 0) { @@ -11828,10 +12448,18 @@ function startProfilerTimer(fiber) { } function stopProfilerTimerIfRunning(fiber) { + if (!enableProfilerTimer) { + return; + } + profilerStartTime = -1; } function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) { + if (!enableProfilerTimer) { + return; + } + if (profilerStartTime >= 0) { var elapsedTime = now$1() - profilerStartTime; fiber.actualDuration += elapsedTime; @@ -11844,10 +12472,258 @@ function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) { } } -function enterHydrationState(fiber) { +// This may have been an insertion or a hydration. + +var hydrationParentFiber = null; +var nextHydratableInstance = null; +var isHydrating = false; + +function warnIfHydrating() { { + !!isHydrating + ? warning$1( + false, + "We should not be hydrating here. This is a bug in React. Please file a bug." + ) + : void 0; + } +} + +function enterHydrationState(fiber) { + if (!supportsHydration) { + return false; + } + + var parentInstance = fiber.stateNode.containerInfo; + nextHydratableInstance = getFirstHydratableChild(parentInstance); + hydrationParentFiber = fiber; + isHydrating = true; + return true; +} + +function reenterHydrationStateFromDehydratedSuspenseInstance( + fiber, + suspenseInstance +) { + if (!supportsHydration) { return false; } + + nextHydratableInstance = getNextHydratableSibling(suspenseInstance); + popToNextHostParent(fiber); + isHydrating = true; + return true; +} + +function deleteHydratableInstance(returnFiber, instance) { + { + switch (returnFiber.tag) { + case HostRoot: + didNotHydrateContainerInstance( + returnFiber.stateNode.containerInfo, + instance + ); + break; + + case HostComponent: + didNotHydrateInstance( + returnFiber.type, + returnFiber.memoizedProps, + returnFiber.stateNode, + instance + ); + break; + } + } + + var childToDelete = createFiberFromHostInstanceForDeletion(); + childToDelete.stateNode = instance; + childToDelete.return = returnFiber; + childToDelete.effectTag = Deletion; // This might seem like it belongs on progressedFirstDeletion. However, + // these children are not part of the reconciliation list of children. + // Even if we abort and rereconcile the children, that will try to hydrate + // again and the nodes are still in the host tree so these will be + // recreated. + + if (returnFiber.lastEffect !== null) { + returnFiber.lastEffect.nextEffect = childToDelete; + returnFiber.lastEffect = childToDelete; + } else { + returnFiber.firstEffect = returnFiber.lastEffect = childToDelete; + } +} + +function insertNonHydratedInstance(returnFiber, fiber) { + fiber.effectTag = (fiber.effectTag & ~Hydrating) | Placement; + + { + switch (returnFiber.tag) { + case HostRoot: { + var parentContainer = returnFiber.stateNode.containerInfo; + + switch (fiber.tag) { + case HostComponent: + var type = fiber.type; + var props = fiber.pendingProps; + didNotFindHydratableContainerInstance(parentContainer, type, props); + break; + + case HostText: + var text = fiber.pendingProps; + didNotFindHydratableContainerTextInstance(parentContainer, text); + break; + + case SuspenseComponent: + didNotFindHydratableContainerSuspenseInstance(parentContainer); + break; + } + + break; + } + + case HostComponent: { + var parentType = returnFiber.type; + var parentProps = returnFiber.memoizedProps; + var parentInstance = returnFiber.stateNode; + + switch (fiber.tag) { + case HostComponent: + var _type = fiber.type; + var _props = fiber.pendingProps; + didNotFindHydratableInstance( + parentType, + parentProps, + parentInstance, + _type, + _props + ); + break; + + case HostText: + var _text = fiber.pendingProps; + didNotFindHydratableTextInstance( + parentType, + parentProps, + parentInstance, + _text + ); + break; + + case SuspenseComponent: + didNotFindHydratableSuspenseInstance( + parentType, + parentProps, + parentInstance + ); + break; + } + + break; + } + + default: + return; + } + } +} + +function tryHydrate(fiber, nextInstance) { + switch (fiber.tag) { + case HostComponent: { + var type = fiber.type; + var props = fiber.pendingProps; + var instance = canHydrateInstance(nextInstance, type, props); + + if (instance !== null) { + fiber.stateNode = instance; + return true; + } + + return false; + } + + case HostText: { + var text = fiber.pendingProps; + var textInstance = canHydrateTextInstance(nextInstance, text); + + if (textInstance !== null) { + fiber.stateNode = textInstance; + return true; + } + + return false; + } + + case SuspenseComponent: { + if (enableSuspenseServerRenderer) { + var suspenseInstance = canHydrateSuspenseInstance(nextInstance); + + if (suspenseInstance !== null) { + var suspenseState = { + dehydrated: suspenseInstance, + retryTime: Never + }; + fiber.memoizedState = suspenseState; // Store the dehydrated fragment as a child fiber. + // This simplifies the code for getHostSibling and deleting nodes, + // since it doesn't have to consider all Suspense boundaries and + // check if they're dehydrated ones or not. + + var dehydratedFragment = createFiberFromDehydratedFragment( + suspenseInstance + ); + dehydratedFragment.return = fiber; + fiber.child = dehydratedFragment; + return true; + } + } + + return false; + } + + default: + return false; + } +} + +function tryToClaimNextHydratableInstance(fiber) { + if (!isHydrating) { + return; + } + + var nextInstance = nextHydratableInstance; + + if (!nextInstance) { + // Nothing to hydrate. Make it an insertion. + insertNonHydratedInstance(hydrationParentFiber, fiber); + isHydrating = false; + hydrationParentFiber = fiber; + return; + } + + var firstAttemptedInstance = nextInstance; + + if (!tryHydrate(fiber, nextInstance)) { + // If we can't hydrate this instance let's try the next one. + // We use this as a heuristic. It's based on intuition and not data so it + // might be flawed or unnecessary. + nextInstance = getNextHydratableSibling(firstAttemptedInstance); + + if (!nextInstance || !tryHydrate(fiber, nextInstance)) { + // Nothing to hydrate. Make it an insertion. + insertNonHydratedInstance(hydrationParentFiber, fiber); + isHydrating = false; + hydrationParentFiber = fiber; + return; + } // We matched the next one, we'll now assume that the first one was + // superfluous and we'll delete it. Since we can't eagerly delete it + // we'll have to schedule a deletion. To do that, this node needs a dummy + // fiber associated with it. + + deleteHydratableInstance(hydrationParentFiber, firstAttemptedInstance); + } + + hydrationParentFiber = fiber; + nextHydratableInstance = getFirstHydratableChild(nextInstance); } function prepareToHydrateHostInstance( @@ -11855,33 +12731,209 @@ function prepareToHydrateHostInstance( rootContainerInstance, hostContext ) { - { + if (!supportsHydration) { { throw Error( "Expected prepareToHydrateHostInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." ); } } + + var instance = fiber.stateNode; + var updatePayload = hydrateInstance( + instance, + fiber.type, + fiber.memoizedProps, + rootContainerInstance, + hostContext, + fiber + ); // TODO: Type this specific to this type of component. + + fiber.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. + + if (updatePayload !== null) { + return true; + } + + return false; } function prepareToHydrateHostTextInstance(fiber) { - { + if (!supportsHydration) { { throw Error( "Expected prepareToHydrateHostTextInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." ); } } - var shouldUpdate = hydrateTextInstance(); + + var textInstance = fiber.stateNode; + var textContent = fiber.memoizedProps; + var shouldUpdate = hydrateTextInstance(textInstance, textContent, fiber); + + { + if (shouldUpdate) { + // We assume that prepareToHydrateHostTextInstance is called in a context where the + // hydration parent is the parent host component of this host text. + var returnFiber = hydrationParentFiber; + + if (returnFiber !== null) { + switch (returnFiber.tag) { + case HostRoot: { + var parentContainer = returnFiber.stateNode.containerInfo; + didNotMatchHydratedContainerTextInstance( + parentContainer, + textInstance, + textContent + ); + break; + } + + case HostComponent: { + var parentType = returnFiber.type; + var parentProps = returnFiber.memoizedProps; + var parentInstance = returnFiber.stateNode; + didNotMatchHydratedTextInstance( + parentType, + parentProps, + parentInstance, + textInstance, + textContent + ); + break; + } + } + } + } + } + + return shouldUpdate; +} + +function prepareToHydrateHostSuspenseInstance(fiber) { + if (!supportsHydration) { + { + throw Error( + "Expected prepareToHydrateHostSuspenseInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." + ); + } + } + + var suspenseState = fiber.memoizedState; + var suspenseInstance = + suspenseState !== null ? suspenseState.dehydrated : null; + + if (!suspenseInstance) { + throw Error( + "Expected to have a hydrated suspense instance. This error is likely caused by a bug in React. Please file an issue." + ); + } + + hydrateSuspenseInstance(suspenseInstance, fiber); +} + +function skipPastDehydratedSuspenseInstance(fiber) { + if (!supportsHydration) { + { + throw Error( + "Expected skipPastDehydratedSuspenseInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." + ); + } + } + + var suspenseState = fiber.memoizedState; + var suspenseInstance = + suspenseState !== null ? suspenseState.dehydrated : null; + + if (!suspenseInstance) { + throw Error( + "Expected to have a hydrated suspense instance. This error is likely caused by a bug in React. Please file an issue." + ); + } + + return getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance); +} + +function popToNextHostParent(fiber) { + var parent = fiber.return; + + while ( + parent !== null && + parent.tag !== HostComponent && + parent.tag !== HostRoot && + parent.tag !== SuspenseComponent + ) { + parent = parent.return; + } + + hydrationParentFiber = parent; } function popHydrationState(fiber) { - { + if (!supportsHydration) { + return false; + } + + if (fiber !== hydrationParentFiber) { + // We're deeper than the current hydration context, inside an inserted + // tree. + return false; + } + + if (!isHydrating) { + // If we're not currently hydrating but we're in a hydration context, then + // we were an insertion and now need to pop up reenter hydration of our + // siblings. + popToNextHostParent(fiber); + isHydrating = true; return false; } + + var type = fiber.type; // If we have any remaining hydratable nodes, we need to delete them now. + // We only do this deeper than head and body since they tend to have random + // other nodes in them. We also ignore components with pure text content in + // side of them. + // TODO: Better heuristic. + + if ( + fiber.tag !== HostComponent || + (type !== "head" && + type !== "body" && + !shouldSetTextContent(type, fiber.memoizedProps)) + ) { + var nextInstance = nextHydratableInstance; + + while (nextInstance) { + deleteHydratableInstance(fiber, nextInstance); + nextInstance = getNextHydratableSibling(nextInstance); + } + } + + popToNextHostParent(fiber); + + if (fiber.tag === SuspenseComponent) { + nextHydratableInstance = skipPastDehydratedSuspenseInstance(fiber); + } else { + nextHydratableInstance = hydrationParentFiber + ? getNextHydratableSibling(fiber.stateNode) + : null; + } + + return true; } -var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner; +function resetHydrationState() { + if (!supportsHydration) { + return; + } + + hydrationParentFiber = null; + nextHydratableInstance = null; + isHydrating = false; +} + +var ReactCurrentOwner$3 = ReactSharedInternals.ReactCurrentOwner; var didReceiveUpdate = false; var didWarnAboutBadClass; var didWarnAboutModulePatternComponent; @@ -11889,8 +12941,10 @@ var didWarnAboutContextTypeOnFunctionComponent; var didWarnAboutGetDerivedStateOnFunctionComponent; var didWarnAboutFunctionRefs; var didWarnAboutReassigningProps; +var didWarnAboutMaxDuration; var didWarnAboutRevealOrder; var didWarnAboutTailOptions; +var didWarnAboutDefaultPropsOnFunctionComponent; { didWarnAboutBadClass = {}; @@ -11899,17 +12953,19 @@ var didWarnAboutTailOptions; didWarnAboutGetDerivedStateOnFunctionComponent = {}; didWarnAboutFunctionRefs = {}; didWarnAboutReassigningProps = false; + didWarnAboutMaxDuration = false; didWarnAboutRevealOrder = {}; didWarnAboutTailOptions = {}; + didWarnAboutDefaultPropsOnFunctionComponent = {}; } function reconcileChildren( - current, + current$$1, workInProgress, nextChildren, renderExpirationTime ) { - if (current === null) { + if (current$$1 === 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 @@ -11928,7 +12984,7 @@ function reconcileChildren( // let's throw it out. workInProgress.child = reconcileChildFibers( workInProgress, - current.child, + current$$1.child, nextChildren, renderExpirationTime ); @@ -11936,7 +12992,7 @@ function reconcileChildren( } function forceUnmountCurrentAndReconcile( - current, + current$$1, workInProgress, nextChildren, renderExpirationTime @@ -11951,13 +13007,13 @@ function forceUnmountCurrentAndReconcile( // passing null. workInProgress.child = reconcileChildFibers( workInProgress, - current.child, + current$$1.child, null, renderExpirationTime ); // 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. + // the effect of remounting all children regardless of whether their their + // identity matches. workInProgress.child = reconcileChildFibers( workInProgress, @@ -11968,7 +13024,7 @@ function forceUnmountCurrentAndReconcile( } function updateForwardRef( - current, + current$$1, workInProgress, Component, nextProps, @@ -11988,7 +13044,8 @@ function updateForwardRef( innerPropTypes, nextProps, // Resolved props "prop", - getComponentName(Component) + getComponentName(Component), + getCurrentFiberStackInDev ); } } @@ -12001,10 +13058,10 @@ function updateForwardRef( prepareToReadContext(workInProgress, renderExpirationTime); { - ReactCurrentOwner$1.current = workInProgress; - setIsRendering(true); + ReactCurrentOwner$3.current = workInProgress; + setCurrentPhase("render"); nextChildren = renderWithHooks( - current, + current$$1, workInProgress, render, nextProps, @@ -12012,11 +13069,14 @@ function updateForwardRef( renderExpirationTime ); - if (workInProgress.mode & StrictMode) { + if ( + debugRenderPhaseSideEffectsForStrictMode && + workInProgress.mode & StrictMode + ) { // Only double-render components with Hooks if (workInProgress.memoizedState !== null) { nextChildren = renderWithHooks( - current, + current$$1, workInProgress, render, nextProps, @@ -12026,13 +13086,13 @@ function updateForwardRef( } } - setIsRendering(false); + setCurrentPhase(null); } - if (current !== null && !didReceiveUpdate) { - bailoutHooks(current, workInProgress, renderExpirationTime); + if (current$$1 !== null && !didReceiveUpdate) { + bailoutHooks(current$$1, workInProgress, renderExpirationTime); return bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -12040,7 +13100,7 @@ function updateForwardRef( workInProgress.effectTag |= PerformedWork; reconcileChildren( - current, + current$$1, workInProgress, nextChildren, renderExpirationTime @@ -12049,14 +13109,14 @@ function updateForwardRef( } function updateMemoComponent( - current, + current$$1, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime ) { - if (current === null) { + if (current$$1 === null) { var type = Component.type; if ( @@ -12080,7 +13140,7 @@ function updateMemoComponent( } return updateSimpleMemoComponent( - current, + current$$1, workInProgress, resolvedType, nextProps, @@ -12099,7 +13159,8 @@ function updateMemoComponent( innerPropTypes, nextProps, // Resolved props "prop", - getComponentName(type) + getComponentName(type), + getCurrentFiberStackInDev ); } } @@ -12129,12 +13190,13 @@ function updateMemoComponent( _innerPropTypes, nextProps, // Resolved props "prop", - getComponentName(_type) + getComponentName(_type), + getCurrentFiberStackInDev ); } } - var currentChild = current.child; // This is always exactly one child + var currentChild = current$$1.child; // This is always exactly one child if (updateExpirationTime < renderExpirationTime) { // This will be the props with resolved defaultProps, @@ -12144,9 +13206,12 @@ function updateMemoComponent( var compare = Component.compare; compare = compare !== null ? compare : shallowEqual; - if (compare(prevProps, nextProps) && current.ref === workInProgress.ref) { + if ( + compare(prevProps, nextProps) && + current$$1.ref === workInProgress.ref + ) { return bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -12154,7 +13219,11 @@ function updateMemoComponent( } // React DevTools reads this flag. workInProgress.effectTag |= PerformedWork; - var newChild = createWorkInProgress(currentChild, nextProps); + var newChild = createWorkInProgress( + currentChild, + nextProps, + renderExpirationTime + ); newChild.ref = workInProgress.ref; newChild.return = workInProgress; workInProgress.child = newChild; @@ -12162,7 +13231,7 @@ function updateMemoComponent( } function updateSimpleMemoComponent( - current, + current$$1, workInProgress, Component, nextProps, @@ -12192,39 +13261,26 @@ function updateSimpleMemoComponent( outerPropTypes, nextProps, // Resolved (SimpleMemoComponent has no defaultProps) "prop", - getComponentName(outerMemoType) + getComponentName(outerMemoType), + getCurrentFiberStackInDev ); } // Inner propTypes will be validated in the function component path. } } - if (current !== null) { - var prevProps = current.memoizedProps; + if (current$$1 !== null) { + var prevProps = current$$1.memoizedProps; if ( shallowEqual(prevProps, nextProps) && - current.ref === workInProgress.ref && // Prevent bailout if the implementation changed due to hot reload. - workInProgress.type === current.type + current$$1.ref === workInProgress.ref && // Prevent bailout if the implementation changed due to hot reload: + workInProgress.type === current$$1.type ) { didReceiveUpdate = false; if (updateExpirationTime < renderExpirationTime) { - // The pending update priority was cleared at the beginning of - // beginWork. We're about to bail out, but there might be additional - // updates at a lower priority. 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.expirationTime = current.expirationTime; return bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -12233,7 +13289,7 @@ function updateSimpleMemoComponent( } return updateFunctionComponent( - current, + current$$1, workInProgress, Component, nextProps, @@ -12241,10 +13297,10 @@ function updateSimpleMemoComponent( ); } -function updateFragment(current, workInProgress, renderExpirationTime) { +function updateFragment(current$$1, workInProgress, renderExpirationTime) { var nextChildren = workInProgress.pendingProps; reconcileChildren( - current, + current$$1, workInProgress, nextChildren, renderExpirationTime @@ -12252,10 +13308,10 @@ function updateFragment(current, workInProgress, renderExpirationTime) { return workInProgress.child; } -function updateMode(current, workInProgress, renderExpirationTime) { +function updateMode(current$$1, workInProgress, renderExpirationTime) { var nextChildren = workInProgress.pendingProps.children; reconcileChildren( - current, + current$$1, workInProgress, nextChildren, renderExpirationTime @@ -12263,20 +13319,15 @@ function updateMode(current, workInProgress, renderExpirationTime) { return workInProgress.child; } -function updateProfiler(current, workInProgress, renderExpirationTime) { - { - workInProgress.effectTag |= 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; +function updateProfiler(current$$1, workInProgress, renderExpirationTime) { + if (enableProfilerTimer) { + workInProgress.effectTag |= Update; } var nextProps = workInProgress.pendingProps; var nextChildren = nextProps.children; reconcileChildren( - current, + current$$1, workInProgress, nextChildren, renderExpirationTime @@ -12284,12 +13335,12 @@ function updateProfiler(current, workInProgress, renderExpirationTime) { return workInProgress.child; } -function markRef(current, workInProgress) { +function markRef(current$$1, workInProgress) { var ref = workInProgress.ref; if ( - (current === null && ref !== null) || - (current !== null && current.ref !== ref) + (current$$1 === null && ref !== null) || + (current$$1 !== null && current$$1.ref !== ref) ) { // Schedule a Ref effect workInProgress.effectTag |= Ref; @@ -12297,7 +13348,7 @@ function markRef(current, workInProgress) { } function updateFunctionComponent( - current, + current$$1, workInProgress, Component, nextProps, @@ -12314,7 +13365,8 @@ function updateFunctionComponent( innerPropTypes, nextProps, // Resolved props "prop", - getComponentName(Component) + getComponentName(Component), + getCurrentFiberStackInDev ); } } @@ -12322,7 +13374,7 @@ function updateFunctionComponent( var context; - { + if (!disableLegacyContext) { var unmaskedContext = getUnmaskedContext(workInProgress, Component, true); context = getMaskedContext(workInProgress, unmaskedContext); } @@ -12331,10 +13383,10 @@ function updateFunctionComponent( prepareToReadContext(workInProgress, renderExpirationTime); { - ReactCurrentOwner$1.current = workInProgress; - setIsRendering(true); + ReactCurrentOwner$3.current = workInProgress; + setCurrentPhase("render"); nextChildren = renderWithHooks( - current, + current$$1, workInProgress, Component, nextProps, @@ -12342,11 +13394,14 @@ function updateFunctionComponent( renderExpirationTime ); - if (workInProgress.mode & StrictMode) { + if ( + debugRenderPhaseSideEffectsForStrictMode && + workInProgress.mode & StrictMode + ) { // Only double-render components with Hooks if (workInProgress.memoizedState !== null) { nextChildren = renderWithHooks( - current, + current$$1, workInProgress, Component, nextProps, @@ -12356,13 +13411,13 @@ function updateFunctionComponent( } } - setIsRendering(false); + setCurrentPhase(null); } - if (current !== null && !didReceiveUpdate) { - bailoutHooks(current, workInProgress, renderExpirationTime); + if (current$$1 !== null && !didReceiveUpdate) { + bailoutHooks(current$$1, workInProgress, renderExpirationTime); return bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -12370,7 +13425,7 @@ function updateFunctionComponent( workInProgress.effectTag |= PerformedWork; reconcileChildren( - current, + current$$1, workInProgress, nextChildren, renderExpirationTime @@ -12379,7 +13434,7 @@ function updateFunctionComponent( } function updateClassComponent( - current, + current$$1, workInProgress, Component, nextProps, @@ -12396,7 +13451,8 @@ function updateClassComponent( innerPropTypes, nextProps, // Resolved props "prop", - getComponentName(Component) + getComponentName(Component), + getCurrentFiberStackInDev ); } } @@ -12418,18 +13474,23 @@ function updateClassComponent( 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 + if (current$$1 !== null) { + // An class component without an instance only mounts if it suspended + // inside a non- concurrent tree, in an inconsistent state. We want to + // tree it like a new mount, even though an empty version of it already // committed. Disconnect the alternate pointers. - current.alternate = null; + current$$1.alternate = null; workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect workInProgress.effectTag |= Placement; } // In the initial pass we might need to construct the instance. - constructClassInstance(workInProgress, Component, nextProps); + constructClassInstance( + workInProgress, + Component, + nextProps, + renderExpirationTime + ); mountClassInstance( workInProgress, Component, @@ -12437,7 +13498,7 @@ function updateClassComponent( renderExpirationTime ); shouldUpdate = true; - } else if (current === null) { + } else if (current$$1 === null) { // In a resume, we'll already have an instance we can reuse. shouldUpdate = resumeMountClassInstance( workInProgress, @@ -12447,7 +13508,7 @@ function updateClassComponent( ); } else { shouldUpdate = updateClassInstance( - current, + current$$1, workInProgress, Component, nextProps, @@ -12456,7 +13517,7 @@ function updateClassComponent( } var nextUnitOfWork = finishClassComponent( - current, + current$$1, workInProgress, Component, shouldUpdate, @@ -12468,14 +13529,14 @@ function updateClassComponent( var inst = workInProgress.stateNode; if (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 + ? warning$1( + false, + "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" + ) + : void 0; didWarnAboutReassigningProps = true; } } @@ -12484,7 +13545,7 @@ function updateClassComponent( } function finishClassComponent( - current, + current$$1, workInProgress, Component, shouldUpdate, @@ -12492,7 +13553,7 @@ function finishClassComponent( renderExpirationTime ) { // Refs should update even if shouldComponentUpdate returns false - markRef(current, workInProgress); + markRef(current$$1, workInProgress); var didCaptureError = (workInProgress.effectTag & DidCapture) !== NoEffect; if (!shouldUpdate && !didCaptureError) { @@ -12502,7 +13563,7 @@ function finishClassComponent( } return bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -12510,52 +13571,55 @@ function finishClassComponent( var instance = workInProgress.stateNode; // Rerender - ReactCurrentOwner$1.current = workInProgress; + ReactCurrentOwner$3.current = workInProgress; var nextChildren; if ( didCaptureError && typeof Component.getDerivedStateFromError !== "function" ) { - // If we captured an error, but getDerivedStateFromError is not defined, + // If we captured an error, but getDerivedStateFrom catch 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(); + if (enableProfilerTimer) { + stopProfilerTimerIfRunning(workInProgress); } } else { { - setIsRendering(true); + setCurrentPhase("render"); nextChildren = instance.render(); - if (workInProgress.mode & StrictMode) { + if ( + debugRenderPhaseSideEffectsForStrictMode && + workInProgress.mode & StrictMode + ) { instance.render(); } - setIsRendering(false); + setCurrentPhase(null); } } // React DevTools reads this flag. workInProgress.effectTag |= PerformedWork; - if (current !== null && didCaptureError) { + if (current$$1 !== 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, + current$$1, workInProgress, nextChildren, renderExpirationTime ); } else { reconcileChildren( - current, + current$$1, workInProgress, nextChildren, renderExpirationTime @@ -12589,11 +13653,11 @@ function pushHostRootContext(workInProgress) { pushHostContainer(workInProgress, root.containerInfo); } -function updateHostRoot(current, workInProgress, renderExpirationTime) { +function updateHostRoot(current$$1, workInProgress, renderExpirationTime) { pushHostRootContext(workInProgress); var updateQueue = workInProgress.updateQueue; - if (!(current !== null && updateQueue !== null)) { + if (!(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." ); @@ -12602,16 +13666,24 @@ function updateHostRoot(current, workInProgress, renderExpirationTime) { var nextProps = workInProgress.pendingProps; var prevState = workInProgress.memoizedState; var prevChildren = prevState !== null ? prevState.element : null; - cloneUpdateQueue(current, workInProgress); - processUpdateQueue(workInProgress, nextProps, null, renderExpirationTime); + processUpdateQueue( + workInProgress, + updateQueue, + nextProps, + null, + renderExpirationTime + ); var nextState = workInProgress.memoizedState; // Caution: React DevTools currently depends on this property // being called "element". var nextChildren = nextState.element; if (nextChildren === prevChildren) { + // If the state is the same as before, that's a bailout because we had + // no work that expires at this time. + resetHydrationState(); return bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -12619,7 +13691,7 @@ function updateHostRoot(current, workInProgress, renderExpirationTime) { var root = workInProgress.stateNode; - if (root.hydrate && enterHydrationState()) { + if (root.hydrate && enterHydrationState(workInProgress)) { // If we don't have any current children this might be the first pass. // We always try to hydrate. If this isn't a hydration pass there won't // be any children to hydrate which is effectively the same thing as @@ -12647,38 +13719,50 @@ function updateHostRoot(current, workInProgress, renderExpirationTime) { // Otherwise reset hydration state in case we aborted and resumed another // root. reconcileChildren( - current, + current$$1, workInProgress, nextChildren, renderExpirationTime ); + resetHydrationState(); } return workInProgress.child; } -function updateHostComponent(current, workInProgress, renderExpirationTime) { +function updateHostComponent(current$$1, workInProgress, renderExpirationTime) { pushHostContext(workInProgress); + if (current$$1 === null) { + tryToClaimNextHydratableInstance(workInProgress); + } + var type = workInProgress.type; var nextProps = workInProgress.pendingProps; - var prevProps = current !== null ? current.memoizedProps : null; + var prevProps = current$$1 !== null ? current$$1.memoizedProps : null; var nextChildren = nextProps.children; + var isDirectTextChild = shouldSetTextContent(type, nextProps); - if (prevProps !== null && shouldSetTextContent()) { + if (isDirectTextChild) { + // We special case a direct text child of a host node. This is a common + // case. We won't handle it as a reified child. We will instead handle + // this in the host environment that also have access to this prop. That + // avoids allocating another HostText fiber and traversing it. + nextChildren = null; + } else if (prevProps !== null && shouldSetTextContent(type, prevProps)) { // 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.effectTag |= ContentReset; } - markRef(current, workInProgress); // Check the host config to see if the children are offscreen/hidden. + markRef(current$$1, workInProgress); // Check the host config to see if the children are offscreen/hidden. if ( workInProgress.mode & ConcurrentMode && renderExpirationTime !== Never && - shouldDeprioritizeSubtree() + shouldDeprioritizeSubtree(type, nextProps) ) { - { + if (enableSchedulerTracing) { markSpawnedWork(Never); } // Schedule this fiber to re-render at offscreen priority. Then bailout. @@ -12687,7 +13771,7 @@ function updateHostComponent(current, workInProgress, renderExpirationTime) { } reconcileChildren( - current, + current$$1, workInProgress, nextChildren, renderExpirationTime @@ -12695,7 +13779,10 @@ function updateHostComponent(current, workInProgress, renderExpirationTime) { return workInProgress.child; } -function updateHostText(current, workInProgress) { +function updateHostText(current$$1, workInProgress) { + if (current$$1 === null) { + tryToClaimNextHydratableInstance(workInProgress); + } // Nothing to do here. This is terminal. We'll do the completion step // immediately after. return null; @@ -12709,7 +13796,7 @@ function mountLazyComponent( renderExpirationTime ) { if (_current !== null) { - // A lazy component only mounts if it suspended inside a non- + // An 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. @@ -12747,7 +13834,7 @@ function mountLazyComponent( resolvedProps, renderExpirationTime ); - return child; + break; } case ClassComponent: { @@ -12764,7 +13851,7 @@ function mountLazyComponent( resolvedProps, renderExpirationTime ); - return child; + break; } case ForwardRef: { @@ -12781,7 +13868,7 @@ function mountLazyComponent( resolvedProps, renderExpirationTime ); - return child; + break; } case MemoComponent: { @@ -12794,7 +13881,8 @@ function mountLazyComponent( outerPropTypes, resolvedProps, // Resolved for outer only "prop", - getComponentName(Component) + getComponentName(Component), + getCurrentFiberStackInDev ); } } @@ -12808,32 +13896,36 @@ function mountLazyComponent( updateExpirationTime, renderExpirationTime ); - return child; + break; } - } - var hint = ""; + default: { + 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. + { + 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 - ); + { + throw Error( + "Element type is invalid. Received a promise that resolves to: " + + Component + + ". Lazy element type must resolve to a class or function." + + hint + ); + } + } } + + return child; } function mountIncompleteClassComponent( @@ -12869,7 +13961,12 @@ function mountIncompleteClassComponent( } prepareToReadContext(workInProgress, renderExpirationTime); - constructClassInstance(workInProgress, Component, nextProps); + constructClassInstance( + workInProgress, + Component, + nextProps, + renderExpirationTime + ); mountClassInstance( workInProgress, Component, @@ -12906,7 +14003,7 @@ function mountIndeterminateComponent( var props = workInProgress.pendingProps; var context; - { + if (!disableLegacyContext) { var unmaskedContext = getUnmaskedContext(workInProgress, Component, false); context = getMaskedContext(workInProgress, unmaskedContext); } @@ -12922,13 +14019,13 @@ function mountIndeterminateComponent( var componentName = getComponentName(Component) || "Unknown"; if (!didWarnAboutBadClass[componentName]) { - error( + warningWithoutStack$1( + false, "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; } } @@ -12937,7 +14034,7 @@ function mountIndeterminateComponent( ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null); } - ReactCurrentOwner$1.current = workInProgress; + ReactCurrentOwner$3.current = workInProgress; value = renderWithHooks( null, workInProgress, @@ -12960,7 +14057,8 @@ function mountIndeterminateComponent( var _componentName = getComponentName(Component) || "Unknown"; if (!didWarnAboutModulePatternComponent[_componentName]) { - error( + warningWithoutStack$1( + false, "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. " + @@ -12970,15 +14068,13 @@ function mountIndeterminateComponent( _componentName, _componentName ); - didWarnAboutModulePatternComponent[_componentName] = 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. + resetHooks(); // 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. @@ -12993,7 +14089,6 @@ function mountIndeterminateComponent( workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null; - initializeUpdateQueue(workInProgress); var getDerivedStateFromProps = Component.getDerivedStateFromProps; if (typeof getDerivedStateFromProps === "function") { @@ -13020,7 +14115,19 @@ function mountIndeterminateComponent( workInProgress.tag = FunctionComponent; { - if (workInProgress.mode & StrictMode) { + if (disableLegacyContext && Component.contextTypes) { + warningWithoutStack$1( + false, + "%s uses the legacy contextTypes API which is no longer supported. " + + "Use React.createContext() with React.useContext() instead.", + getComponentName(Component) || "Unknown" + ); + } + + if ( + debugRenderPhaseSideEffectsForStrictMode && + workInProgress.mode & StrictMode + ) { // Only double-render components with Hooks if (workInProgress.memoizedState !== null) { value = renderWithHooks( @@ -13046,70 +14153,86 @@ function mountIndeterminateComponent( } function validateFunctionComponentInDev(workInProgress, Component) { - { - if (Component) { - if (Component.childContextTypes) { - error( + if (Component) { + !!Component.childContextTypes + ? warningWithoutStack$1( + false, "%s(...): childContextTypes cannot be defined on a function component.", Component.displayName || Component.name || "Component" - ); - } - } - - if (workInProgress.ref !== null) { - var info = ""; - var ownerName = getCurrentFiberOwnerNameInDevOrNull(); + ) + : void 0; + } - if (ownerName) { - info += "\n\nCheck the render method of `" + ownerName + "`."; - } + if (workInProgress.ref !== null) { + var info = ""; + var ownerName = getCurrentFiberOwnerNameInDevOrNull(); - var warningKey = ownerName || workInProgress._debugID || ""; - var debugSource = workInProgress._debugSource; + if (ownerName) { + info += "\n\nCheck the render method of `" + ownerName + "`."; + } - if (debugSource) { - warningKey = debugSource.fileName + ":" + debugSource.lineNumber; - } + var warningKey = ownerName || workInProgress._debugID || ""; + var debugSource = workInProgress._debugSource; - if (!didWarnAboutFunctionRefs[warningKey]) { - didWarnAboutFunctionRefs[warningKey] = true; + if (debugSource) { + warningKey = debugSource.fileName + ":" + debugSource.lineNumber; + } - error( - "Function components cannot be given refs. " + - "Attempts to access this ref will fail. " + - "Did you mean to use React.forwardRef()?%s", - info - ); - } + if (!didWarnAboutFunctionRefs[warningKey]) { + didWarnAboutFunctionRefs[warningKey] = true; + warning$1( + false, + "Function components cannot be given refs. " + + "Attempts to access this ref will fail. " + + "Did you mean to use React.forwardRef()?%s", + info + ); } + } - if (typeof Component.getDerivedStateFromProps === "function") { - var _componentName2 = getComponentName(Component) || "Unknown"; + if ( + warnAboutDefaultPropsOnFunctionComponents && + Component.defaultProps !== undefined + ) { + var componentName = getComponentName(Component) || "Unknown"; + + if (!didWarnAboutDefaultPropsOnFunctionComponent[componentName]) { + warningWithoutStack$1( + false, + "%s: Support for defaultProps will be removed from function components " + + "in a future major release. Use JavaScript default parameters instead.", + componentName + ); + didWarnAboutDefaultPropsOnFunctionComponent[componentName] = true; + } + } - if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2]) { - error( - "%s: Function components do not support getDerivedStateFromProps.", - _componentName2 - ); + if (typeof Component.getDerivedStateFromProps === "function") { + var _componentName2 = getComponentName(Component) || "Unknown"; - didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2] = true; - } + if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2]) { + warningWithoutStack$1( + false, + "%s: Function components do not support getDerivedStateFromProps.", + _componentName2 + ); + didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2] = true; } + } - if ( - typeof Component.contextType === "object" && - Component.contextType !== null - ) { - var _componentName3 = getComponentName(Component) || "Unknown"; - - if (!didWarnAboutContextTypeOnFunctionComponent[_componentName3]) { - error( - "%s: Function components do not support contextType.", - _componentName3 - ); + if ( + typeof Component.contextType === "object" && + Component.contextType !== null + ) { + var _componentName3 = getComponentName(Component) || "Unknown"; - didWarnAboutContextTypeOnFunctionComponent[_componentName3] = true; - } + if (!didWarnAboutContextTypeOnFunctionComponent[_componentName3]) { + warningWithoutStack$1( + false, + "%s: Function components do not support contextType.", + _componentName3 + ); + didWarnAboutContextTypeOnFunctionComponent[_componentName3] = true; } } } @@ -13119,17 +14242,17 @@ var SUSPENDED_MARKER = { retryTime: NoWork }; -function shouldRemainOnFallback(suspenseContext, current, workInProgress) { +function shouldRemainOnFallback(suspenseContext, current$$1, workInProgress) { // If the context is telling us that we should show a fallback, and we're not // already showing content, then we should show the fallback instead. return ( hasSuspenseContext(suspenseContext, ForceSuspenseFallback) && - (current === null || current.memoizedState !== null) + (current$$1 === null || current$$1.memoizedState !== null) ); } function updateSuspenseComponent( - current, + current$$1, workInProgress, renderExpirationTime ) { @@ -13146,14 +14269,17 @@ function updateSuspenseComponent( var nextDidTimeout = false; var didSuspend = (workInProgress.effectTag & DidCapture) !== NoEffect; - if (didSuspend || shouldRemainOnFallback(suspenseContext, current)) { + if ( + didSuspend || + shouldRemainOnFallback(suspenseContext, current$$1, workInProgress) + ) { // Something in this boundary's subtree already suspended. Switch to // rendering the fallback children. nextDidTimeout = true; workInProgress.effectTag &= ~DidCapture; } else { // Attempting the main content - if (current === null || current.memoizedState !== null) { + if (current$$1 === null || current$$1.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. @@ -13172,7 +14298,20 @@ function updateSuspenseComponent( } suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); - pushSuspenseContext(workInProgress, suspenseContext); // This next part is a bit confusing. If the children timeout, we switch to + pushSuspenseContext(workInProgress, suspenseContext); + + { + if ("maxDuration" in nextProps) { + if (!didWarnAboutMaxDuration) { + didWarnAboutMaxDuration = true; + warning$1( + false, + "maxDuration has been removed from React. " + + "Remove the maxDuration prop." + ); + } + } + } // This next part is a bit confusing. If the children timeout, we switch to // showing the fallback children in place of the "primary" children. // However, we don't want to delete the primary children because then their // state will be lost (both the React state and the host state, e.g. @@ -13194,10 +14333,28 @@ function updateSuspenseComponent( // custom reconciliation logic to preserve the state of the primary // children. It's essentially a very basic form of re-parenting. - if (current === null) { + if (current$$1 === null) { // If we're currently hydrating, try to hydrate this boundary. // But only if this has a fallback. - if (nextProps.fallback !== undefined); // This is the initial mount. This branch is pretty simple because there's + if (nextProps.fallback !== undefined) { + tryToClaimNextHydratableInstance(workInProgress); // This could've been a dehydrated suspense component. + + if (enableSuspenseServerRenderer) { + var suspenseState = workInProgress.memoizedState; + + if (suspenseState !== null) { + var dehydrated = suspenseState.dehydrated; + + if (dehydrated !== null) { + return mountDehydratedSuspenseComponent( + workInProgress, + dehydrated, + renderExpirationTime + ); + } + } + } + } // This is the initial mount. This branch is pretty simple because there's // no previous state that needs to be preserved. if (nextDidTimeout) { @@ -13255,12 +14412,107 @@ function updateSuspenseComponent( } else { // This is an update. This branch is more complicated because we need to // ensure the state of the primary children is preserved. - var prevState = current.memoizedState; + var prevState = current$$1.memoizedState; if (prevState !== null) { + if (enableSuspenseServerRenderer) { + var _dehydrated = prevState.dehydrated; + + if (_dehydrated !== null) { + if (!didSuspend) { + return updateDehydratedSuspenseComponent( + current$$1, + workInProgress, + _dehydrated, + prevState, + renderExpirationTime + ); + } else if (workInProgress.memoizedState !== null) { + // Something suspended and we should still be in dehydrated mode. + // Leave the existing child in place. + workInProgress.child = current$$1.child; // The dehydrated completion pass expects this flag to be there + // but the normal suspense pass doesn't. + + workInProgress.effectTag |= DidCapture; + return null; + } else { + // Suspended but we should no longer be in dehydrated mode. + // Therefore we now have to render the fallback. Wrap the children + // in a fragment fiber to keep them separate from the fallback + // children. + var _nextFallbackChildren = nextProps.fallback; + + var _primaryChildFragment = createFiberFromFragment( + // It shouldn't matter what the pending props are because we aren't + // going to render this fragment. + null, + mode, + NoWork, + null + ); + + _primaryChildFragment.return = workInProgress; // This is always null since we never want the previous child + // that we're not going to hydrate. + + _primaryChildFragment.child = null; + + if ((workInProgress.mode & BlockingMode) === NoMode) { + // Outside of blocking mode, we commit the effects from the + // partially completed, timed-out tree, too. + var _progressedChild = (_primaryChildFragment.child = + workInProgress.child); + + while (_progressedChild !== null) { + _progressedChild.return = _primaryChildFragment; + _progressedChild = _progressedChild.sibling; + } + } else { + // We will have dropped the effect list which contains the deletion. + // We need to reconcile to delete the current child. + reconcileChildFibers( + workInProgress, + current$$1.child, + null, + renderExpirationTime + ); + } // Because primaryChildFragment is a new fiber that we're inserting as the + // parent of a new tree, we need to set its treeBaseDuration. + + if (enableProfilerTimer && workInProgress.mode & ProfileMode) { + // treeBaseDuration is the sum of all the child tree base durations. + var treeBaseDuration = 0; + var hiddenChild = _primaryChildFragment.child; + + while (hiddenChild !== null) { + treeBaseDuration += hiddenChild.treeBaseDuration; + hiddenChild = hiddenChild.sibling; + } + + _primaryChildFragment.treeBaseDuration = treeBaseDuration; + } // Create a fragment from the fallback children, too. + + var _fallbackChildFragment = createFiberFromFragment( + _nextFallbackChildren, + mode, + renderExpirationTime, + null + ); + + _fallbackChildFragment.return = workInProgress; + _primaryChildFragment.sibling = _fallbackChildFragment; + _fallbackChildFragment.effectTag |= Placement; + _primaryChildFragment.childExpirationTime = NoWork; + workInProgress.memoizedState = SUSPENDED_MARKER; + workInProgress.child = _primaryChildFragment; // Skip the primary children, and continue working on the + // fallback children. + + return _fallbackChildFragment; + } + } + } // The current tree already timed out. That means each child set is // wrapped in a fragment fiber. - var currentPrimaryChildFragment = current.child; + var currentPrimaryChildFragment = current$$1.child; var currentFallbackChildFragment = currentPrimaryChildFragment.sibling; if (nextDidTimeout) { @@ -13270,7 +14522,8 @@ function updateSuspenseComponent( var _primaryChildFragment2 = createWorkInProgress( currentPrimaryChildFragment, - currentPrimaryChildFragment.pendingProps + currentPrimaryChildFragment.pendingProps, + NoWork ); _primaryChildFragment2.return = workInProgress; @@ -13297,7 +14550,7 @@ function updateSuspenseComponent( } // Because primaryChildFragment is a new fiber that we're inserting as the // parent of a new tree, we need to set its treeBaseDuration. - if (workInProgress.mode & ProfileMode) { + if (enableProfilerTimer && workInProgress.mode & ProfileMode) { // treeBaseDuration is the sum of all the child tree base durations. var _treeBaseDuration = 0; var _hiddenChild = _primaryChildFragment2.child; @@ -13313,7 +14566,8 @@ function updateSuspenseComponent( var _fallbackChildFragment2 = createWorkInProgress( currentFallbackChildFragment, - _nextFallbackChildren2 + _nextFallbackChildren2, + currentFallbackChildFragment.expirationTime ); _fallbackChildFragment2.return = workInProgress; @@ -13347,7 +14601,7 @@ function updateSuspenseComponent( } else { // The current tree has not already timed out. That means the primary // children are not wrapped in a fragment fiber. - var _currentPrimaryChild = current.child; + var _currentPrimaryChild = current$$1.child; if (nextDidTimeout) { // Timed out. Wrap the children in a fragment fiber to keep them @@ -13393,7 +14647,7 @@ function updateSuspenseComponent( } // Because primaryChildFragment is a new fiber that we're inserting as the // parent of a new tree, we need to set its treeBaseDuration. - if (workInProgress.mode & ProfileMode) { + if (enableProfilerTimer && workInProgress.mode & ProfileMode) { // treeBaseDuration is the sum of all the child tree base durations. var _treeBaseDuration2 = 0; var _hiddenChild2 = _primaryChildFragment3.child; @@ -13423,7 +14677,7 @@ function updateSuspenseComponent( workInProgress.child = _primaryChildFragment3; return _fallbackChildFragment3; } else { - // Still haven't timed out. Continue rendering the children, like we + // Still haven't timed out. Continue rendering the children, like we // normally do. workInProgress.memoizedState = null; var _nextPrimaryChildren2 = nextProps.children; @@ -13438,6 +14692,197 @@ function updateSuspenseComponent( } } +function retrySuspenseComponentWithoutHydrating( + current$$1, + workInProgress, + renderExpirationTime +) { + // We're now not suspended nor dehydrated. + workInProgress.memoizedState = null; // Retry with the full children. + + var nextProps = workInProgress.pendingProps; + var nextChildren = nextProps.children; // This will ensure that the children get Placement effects and + // that the old child gets a Deletion effect. + // We could also call forceUnmountCurrentAndReconcile. + + reconcileChildren( + current$$1, + workInProgress, + nextChildren, + renderExpirationTime + ); + return workInProgress.child; +} + +function mountDehydratedSuspenseComponent( + workInProgress, + suspenseInstance, + renderExpirationTime +) { + // During the first pass, we'll bail out and not drill into the children. + // Instead, we'll leave the content in place and try to hydrate it later. + if ((workInProgress.mode & BlockingMode) === NoMode) { + { + warning$1( + false, + "Cannot hydrate Suspense in legacy mode. Switch from " + + "ReactDOM.hydrate(element, container) to " + + "ReactDOM.createBlockingRoot(container, { hydrate: true })" + + ".render(element) or remove the Suspense components from " + + "the server rendered components." + ); + } + + workInProgress.expirationTime = Sync; + } else if (isSuspenseInstanceFallback(suspenseInstance)) { + // This is a client-only boundary. Since we won't get any content from the server + // for this, we need to schedule that at a higher priority based on when it would + // have timed out. In theory we could render it in this pass but it would have the + // wrong priority associated with it and will prevent hydration of parent path. + // Instead, we'll leave work left on it to render it in a separate commit. + // TODO This time should be the time at which the server rendered response that is + // a parent to this boundary was displayed. However, since we currently don't have + // a protocol to transfer that time, we'll just estimate it by using the current + // time. This will mean that Suspense timeouts are slightly shifted to later than + // they should be. + var serverDisplayTime = requestCurrentTimeForUpdate(); // Schedule a normal pri update to render this content. + + var newExpirationTime = computeAsyncExpiration(serverDisplayTime); + + if (enableSchedulerTracing) { + markSpawnedWork(newExpirationTime); + } + + workInProgress.expirationTime = newExpirationTime; + } else { + // We'll continue hydrating the rest at offscreen priority since we'll already + // be showing the right content coming from the server, it is no rush. + workInProgress.expirationTime = Never; + + if (enableSchedulerTracing) { + markSpawnedWork(Never); + } + } + + return null; +} + +function updateDehydratedSuspenseComponent( + current$$1, + workInProgress, + suspenseInstance, + suspenseState, + renderExpirationTime +) { + // We should never be hydrating at this point because it is the first pass, + // but after we've already committed once. + warnIfHydrating(); + + if ((workInProgress.mode & BlockingMode) === NoMode) { + return retrySuspenseComponentWithoutHydrating( + current$$1, + workInProgress, + renderExpirationTime + ); + } + + if (isSuspenseInstanceFallback(suspenseInstance)) { + // This boundary is in a permanent fallback state. In this case, we'll never + // get an update and we'll never be able to hydrate the final content. Let's just try the + // client side render instead. + return retrySuspenseComponentWithoutHydrating( + current$$1, + workInProgress, + renderExpirationTime + ); + } // We use childExpirationTime to indicate that a child might depend on context, so if + // any context has changed, we need to treat is as if the input might have changed. + + var hasContextChanged$$1 = + current$$1.childExpirationTime >= renderExpirationTime; + + if (didReceiveUpdate || hasContextChanged$$1) { + // This boundary has changed since the first render. This means that we are now unable to + // hydrate it. We might still be able to hydrate it using an earlier expiration time, if + // we are rendering at lower expiration than sync. + if (renderExpirationTime < Sync) { + if (suspenseState.retryTime <= renderExpirationTime) { + // This render is even higher pri than we've seen before, let's try again + // at even higher pri. + var attemptHydrationAtExpirationTime = renderExpirationTime + 1; + suspenseState.retryTime = attemptHydrationAtExpirationTime; + scheduleWork(current$$1, attemptHydrationAtExpirationTime); // TODO: Early abort this render. + } else { + // We have already tried to ping at a higher priority than we're rendering with + // so if we got here, we must have failed to hydrate at those levels. We must + // now give up. Instead, we're going to delete the whole subtree and instead inject + // a new real Suspense boundary to take its place, which may render content + // or fallback. This might suspend for a while and if it does we might still have + // an opportunity to hydrate before this pass commits. + } + } // If we have scheduled higher pri work above, this will probably just abort the render + // since we now have higher priority work, but in case it doesn't, we need to prepare to + // render something, if we time out. Even if that requires us to delete everything and + // skip hydration. + // Delay having to do this as long as the suspense timeout allows us. + + renderDidSuspendDelayIfPossible(); + return retrySuspenseComponentWithoutHydrating( + current$$1, + workInProgress, + renderExpirationTime + ); + } else if (isSuspenseInstancePending(suspenseInstance)) { + // This component is still pending more data from the server, so we can't hydrate its + // content. We treat it as if this component suspended itself. It might seem as if + // we could just try to render it client-side instead. However, this will perform a + // lot of unnecessary work and is unlikely to complete since it often will suspend + // on missing data anyway. Additionally, the server might be able to render more + // than we can on the client yet. In that case we'd end up with more fallback states + // on the client than if we just leave it alone. If the server times out or errors + // these should update this boundary to the permanent Fallback state instead. + // Mark it as having captured (i.e. suspended). + workInProgress.effectTag |= DidCapture; // Leave the child in place. I.e. the dehydrated fragment. + + workInProgress.child = current$$1.child; // Register a callback to retry this boundary once the server has sent the result. + + registerSuspenseInstanceRetry( + suspenseInstance, + retryDehydratedSuspenseBoundary.bind(null, current$$1) + ); + return null; + } else { + // This is the first attempt. + reenterHydrationStateFromDehydratedSuspenseInstance( + workInProgress, + suspenseInstance + ); + var nextProps = workInProgress.pendingProps; + var nextChildren = nextProps.children; + var child = mountChildFibers( + workInProgress, + null, + nextChildren, + renderExpirationTime + ); + 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.effectTag |= Hydrating; + node = node.sibling; + } + + workInProgress.child = child; + return workInProgress.child; + } +} + function scheduleWorkOnFiber(fiber, renderExpirationTime) { if (fiber.expirationTime < renderExpirationTime) { fiber.expirationTime = renderExpirationTime; @@ -13539,39 +14984,40 @@ function validateRevealOrder(revealOrder) { case "together": case "forwards": case "backwards": { - error( + warning$1( + false, '"%s" is not a valid value for revealOrder on . ' + 'Use lowercase "%s" instead.', revealOrder, revealOrder.toLowerCase() ); - break; } case "forward": case "backward": { - error( + warning$1( + false, '"%s" is not a valid value for revealOrder on . ' + 'React uses the -s suffix in the spelling. Use "%ss" instead.', revealOrder, revealOrder.toLowerCase() ); - break; } default: - error( + warning$1( + false, '"%s" is not a supported revealOrder on . ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder ); - break; } } else { - error( + warning$1( + false, "%s is not a supported value for revealOrder on . " + 'Did you mean "together", "forwards" or "backwards"?', revealOrder @@ -13586,16 +15032,16 @@ function validateTailOptions(tailMode, revealOrder) { if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) { if (tailMode !== "collapsed" && tailMode !== "hidden") { didWarnAboutTailOptions[tailMode] = true; - - error( + warning$1( + false, '"%s" is not a supported value for tail on . ' + 'Did you mean "collapsed" or "hidden"?', tailMode ); } else if (revealOrder !== "forwards" && revealOrder !== "backwards") { didWarnAboutTailOptions[tailMode] = true; - - error( + warning$1( + false, ' is only valid if revealOrder is ' + '"forwards" or "backwards". ' + 'Did you mean to specify revealOrder="forwards"?', @@ -13613,8 +15059,8 @@ function validateSuspenseListNestedChild(childSlot, index) { if (isArray || isIterable) { var type = isArray ? "array" : "iterable"; - - error( + warning$1( + false, "A nested %s was passed to row #%s in . Wrap it in " + "an additional SuspenseList to configure its revealOrder: " + " ... " + @@ -13624,7 +15070,6 @@ function validateSuspenseListNestedChild(childSlot, index) { index, type ); - return false; } } @@ -13665,7 +15110,8 @@ function validateSuspenseListChildren(children, revealOrder) { } } } else { - error( + warning$1( + false, '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?", @@ -13691,7 +15137,6 @@ function initSuspenseListRenderState( workInProgress.memoizedState = { isBackwards: isBackwards, rendering: null, - renderingStartTime: 0, last: lastContentRow, tail: tail, tailExpiration: 0, @@ -13702,7 +15147,6 @@ function initSuspenseListRenderState( // 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.tailExpiration = 0; @@ -13718,7 +15162,7 @@ function initSuspenseListRenderState( // That happens in the completeWork phase without going back to beginWork. function updateSuspenseListComponent( - current, + current$$1, workInProgress, renderExpirationTime ) { @@ -13729,7 +15173,12 @@ function updateSuspenseListComponent( validateRevealOrder(revealOrder); validateTailOptions(tailMode, revealOrder); validateSuspenseListChildren(newChildren, revealOrder); - reconcileChildren(current, workInProgress, newChildren, renderExpirationTime); + reconcileChildren( + current$$1, + workInProgress, + newChildren, + renderExpirationTime + ); var suspenseContext = suspenseStackCursor.current; var shouldForceFallback = hasSuspenseContext( suspenseContext, @@ -13744,7 +15193,7 @@ function updateSuspenseListComponent( workInProgress.effectTag |= DidCapture; } else { var didSuspendBefore = - current !== null && (current.effectTag & DidCapture) !== NoEffect; + current$$1 !== null && (current$$1.effectTag & DidCapture) !== NoEffect; if (didSuspendBefore) { // If we previously forced a fallback, we need to schedule work @@ -13853,11 +15302,15 @@ function updateSuspenseListComponent( return workInProgress.child; } -function updatePortalComponent(current, workInProgress, renderExpirationTime) { +function updatePortalComponent( + current$$1, + workInProgress, + renderExpirationTime +) { pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); var nextChildren = workInProgress.pendingProps; - if (current === null) { + if (current$$1 === 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 @@ -13871,7 +15324,7 @@ function updatePortalComponent(current, workInProgress, renderExpirationTime) { ); } else { reconcileChildren( - current, + current$$1, workInProgress, nextChildren, renderExpirationTime @@ -13881,7 +15334,11 @@ function updatePortalComponent(current, workInProgress, renderExpirationTime) { return workInProgress.child; } -function updateContextProvider(current, workInProgress, renderExpirationTime) { +function updateContextProvider( + current$$1, + workInProgress, + renderExpirationTime +) { var providerType = workInProgress.type; var context = providerType._context; var newProps = workInProgress.pendingProps; @@ -13892,7 +15349,13 @@ function updateContextProvider(current, workInProgress, renderExpirationTime) { var providerPropTypes = workInProgress.type.propTypes; if (providerPropTypes) { - checkPropTypes(providerPropTypes, newProps, "prop", "Context.Provider"); + checkPropTypes( + providerPropTypes, + newProps, + "prop", + "Context.Provider", + getCurrentFiberStackInDev + ); } } @@ -13906,7 +15369,7 @@ function updateContextProvider(current, workInProgress, renderExpirationTime) { // No change. Bailout early if children are the same. if (oldProps.children === newProps.children && !hasContextChanged()) { return bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -13924,13 +15387,22 @@ function updateContextProvider(current, workInProgress, renderExpirationTime) { } var newChildren = newProps.children; - reconcileChildren(current, workInProgress, newChildren, renderExpirationTime); + reconcileChildren( + current$$1, + workInProgress, + newChildren, + renderExpirationTime + ); return workInProgress.child; } var hasWarnedAboutUsingContextAsConsumer = false; -function updateContextConsumer(current, workInProgress, renderExpirationTime) { +function updateContextConsumer( + current$$1, + workInProgress, + renderExpirationTime +) { 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 @@ -13947,8 +15419,8 @@ function updateContextConsumer(current, workInProgress, renderExpirationTime) { if (context !== context.Consumer) { if (!hasWarnedAboutUsingContextAsConsumer) { hasWarnedAboutUsingContextAsConsumer = true; - - error( + warning$1( + false, "Rendering directly is not supported and will be removed in " + "a future major release. Did you mean to render instead?" ); @@ -13963,14 +15435,15 @@ function updateContextConsumer(current, workInProgress, renderExpirationTime) { 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." - ); - } + !(typeof render === "function") + ? warningWithoutStack$1( + false, + "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." + ) + : void 0; } prepareToReadContext(workInProgress, renderExpirationTime); @@ -13978,14 +15451,57 @@ function updateContextConsumer(current, workInProgress, renderExpirationTime) { var newChildren; { - ReactCurrentOwner$1.current = workInProgress; - setIsRendering(true); + ReactCurrentOwner$3.current = workInProgress; + setCurrentPhase("render"); newChildren = render(newValue); - setIsRendering(false); + setCurrentPhase(null); } // React DevTools reads this flag. workInProgress.effectTag |= PerformedWork; - reconcileChildren(current, workInProgress, newChildren, renderExpirationTime); + reconcileChildren( + current$$1, + workInProgress, + newChildren, + renderExpirationTime + ); + return workInProgress.child; +} + +function updateFundamentalComponent$1( + current$$1, + workInProgress, + renderExpirationTime +) { + var fundamentalImpl = workInProgress.type.impl; + + if (fundamentalImpl.reconcileChildren === false) { + return null; + } + + var nextProps = workInProgress.pendingProps; + var nextChildren = nextProps.children; + reconcileChildren( + current$$1, + workInProgress, + nextChildren, + renderExpirationTime + ); + return workInProgress.child; +} + +function updateScopeComponent( + current$$1, + workInProgress, + renderExpirationTime +) { + var nextProps = workInProgress.pendingProps; + var nextChildren = nextProps.children; + reconcileChildren( + current$$1, + workInProgress, + nextChildren, + renderExpirationTime + ); return workInProgress.child; } @@ -13994,20 +15510,20 @@ function markWorkInProgressReceivedUpdate() { } function bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ) { cancelWorkTimer(workInProgress); - if (current !== null) { + if (current$$1 !== null) { // Reuse previous dependencies - workInProgress.dependencies = current.dependencies; + workInProgress.dependencies = current$$1.dependencies; } - { + if (enableProfilerTimer) { // Don't update "base" render times for bailouts. - stopProfilerTimerIfRunning(); + stopProfilerTimerIfRunning(workInProgress); } var updateExpirationTime = workInProgress.expirationTime; @@ -14026,12 +15542,12 @@ function bailoutOnAlreadyFinishedWork( } else { // This fiber doesn't have work, but its subtree does. Clone the child // fibers and continue. - cloneChildFibers(current, workInProgress); + cloneChildFibers(current$$1, workInProgress); return workInProgress.child; } } -function remountFiber(current, oldWorkInProgress, newWorkInProgress) { +function remountFiber(current$$1, oldWorkInProgress, newWorkInProgress) { { var returnFiber = oldWorkInProgress.return; @@ -14040,7 +15556,7 @@ function remountFiber(current, oldWorkInProgress, newWorkInProgress) { } // Disconnect from the old current. // It will get deleted. - current.alternate = null; + current$$1.alternate = null; oldWorkInProgress.alternate = null; // Connect to the new tree. newWorkInProgress.index = oldWorkInProgress.index; @@ -14072,28 +15588,28 @@ function remountFiber(current, oldWorkInProgress, newWorkInProgress) { var last = returnFiber.lastEffect; if (last !== null) { - last.nextEffect = current; - returnFiber.lastEffect = current; + last.nextEffect = current$$1; + returnFiber.lastEffect = current$$1; } else { - returnFiber.firstEffect = returnFiber.lastEffect = current; + returnFiber.firstEffect = returnFiber.lastEffect = current$$1; } - current.nextEffect = null; - current.effectTag = Deletion; + current$$1.nextEffect = null; + current$$1.effectTag = Deletion; newWorkInProgress.effectTag |= Placement; // Restart work from the new fiber. return newWorkInProgress; } } -function beginWork(current, workInProgress, renderExpirationTime) { +function beginWork$1(current$$1, workInProgress, renderExpirationTime) { var updateExpirationTime = workInProgress.expirationTime; { - if (workInProgress._debugNeedsRemount && current !== null) { + if (workInProgress._debugNeedsRemount && current$$1 !== null) { // This will restart the begin phase with a new fiber. return remountFiber( - current, + current$$1, workInProgress, createFiberFromTypeAndProps( workInProgress.type, @@ -14107,14 +15623,14 @@ function beginWork(current, workInProgress, renderExpirationTime) { } } - if (current !== null) { - var oldProps = current.memoizedProps; + if (current$$1 !== null) { + var oldProps = current$$1.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 + workInProgress.type !== current$$1.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). @@ -14127,6 +15643,7 @@ function beginWork(current, workInProgress, renderExpirationTime) { switch (workInProgress.tag) { case HostRoot: pushHostRootContext(workInProgress); + resetHydrationState(); break; case HostComponent: @@ -14135,9 +15652,9 @@ function beginWork(current, workInProgress, renderExpirationTime) { if ( workInProgress.mode & ConcurrentMode && renderExpirationTime !== Never && - shouldDeprioritizeSubtree(workInProgress.type) + shouldDeprioritizeSubtree(workInProgress.type, newProps) ) { - { + if (enableSchedulerTracing) { markSpawnedWork(Never); } // Schedule this fiber to re-render at offscreen priority. Then bailout. @@ -14171,19 +15688,14 @@ function beginWork(current, workInProgress, renderExpirationTime) { } case Profiler: - { + if (enableProfilerTimer) { // Profiler should only call onRender when one of its descendants actually rendered. var hasChildWork = workInProgress.childExpirationTime >= renderExpirationTime; if (hasChildWork) { workInProgress.effectTag |= 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; @@ -14192,6 +15704,19 @@ function beginWork(current, workInProgress, renderExpirationTime) { var state = workInProgress.memoizedState; if (state !== null) { + if (enableSuspenseServerRenderer) { + if (state.dehydrated !== null) { + pushSuspenseContext( + workInProgress, + setDefaultShallowSuspenseContext(suspenseStackCursor.current) + ); // We know that this component will suspend again because if it has + // been unsuspended it has committed as a resolved Suspense component. + // If it needs to be retried, it should have work scheduled on it. + + workInProgress.effectTag |= DidCapture; + break; + } + } // If this boundary is currently timed out, we need to decide // 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. @@ -14207,7 +15732,7 @@ function beginWork(current, workInProgress, renderExpirationTime) { // The primary children have pending work. Use the normal path // to attempt to render the primary children again. return updateSuspenseComponent( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -14219,7 +15744,7 @@ function beginWork(current, workInProgress, renderExpirationTime) { // priority. Bailout. var child = bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -14243,7 +15768,8 @@ function beginWork(current, workInProgress, renderExpirationTime) { } case SuspenseListComponent: { - var didSuspendBefore = (current.effectTag & DidCapture) !== NoEffect; + var didSuspendBefore = + (current$$1.effectTag & DidCapture) !== NoEffect; var _hasChildWork = workInProgress.childExpirationTime >= renderExpirationTime; @@ -14256,7 +15782,7 @@ function beginWork(current, workInProgress, renderExpirationTime) { // tree which will affect the tail. So we need to use the normal // path to compute the correct tail. return updateSuspenseListComponent( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -14292,7 +15818,7 @@ function beginWork(current, workInProgress, renderExpirationTime) { } return bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -14305,18 +15831,14 @@ function beginWork(current, workInProgress, renderExpirationTime) { } } 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. + } // Before entering the begin phase, clear the expiration time. workInProgress.expirationTime = NoWork; switch (workInProgress.tag) { case IndeterminateComponent: { return mountIndeterminateComponent( - current, + current$$1, workInProgress, workInProgress.type, renderExpirationTime @@ -14326,7 +15848,7 @@ function beginWork(current, workInProgress, renderExpirationTime) { case LazyComponent: { var elementType = workInProgress.elementType; return mountLazyComponent( - current, + current$$1, workInProgress, elementType, updateExpirationTime, @@ -14342,7 +15864,7 @@ function beginWork(current, workInProgress, renderExpirationTime) { ? unresolvedProps : resolveDefaultProps(_Component, unresolvedProps); return updateFunctionComponent( - current, + current$$1, workInProgress, _Component, resolvedProps, @@ -14360,7 +15882,7 @@ function beginWork(current, workInProgress, renderExpirationTime) { : resolveDefaultProps(_Component2, _unresolvedProps); return updateClassComponent( - current, + current$$1, workInProgress, _Component2, _resolvedProps, @@ -14369,24 +15891,28 @@ function beginWork(current, workInProgress, renderExpirationTime) { } case HostRoot: - return updateHostRoot(current, workInProgress, renderExpirationTime); + return updateHostRoot(current$$1, workInProgress, renderExpirationTime); case HostComponent: - return updateHostComponent(current, workInProgress, renderExpirationTime); + return updateHostComponent( + current$$1, + workInProgress, + renderExpirationTime + ); case HostText: - return updateHostText(); + return updateHostText(current$$1, workInProgress); case SuspenseComponent: return updateSuspenseComponent( - current, + current$$1, workInProgress, renderExpirationTime ); case HostPortal: return updatePortalComponent( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -14401,7 +15927,7 @@ function beginWork(current, workInProgress, renderExpirationTime) { : resolveDefaultProps(type, _unresolvedProps2); return updateForwardRef( - current, + current$$1, workInProgress, type, _resolvedProps2, @@ -14410,24 +15936,24 @@ function beginWork(current, workInProgress, renderExpirationTime) { } case Fragment: - return updateFragment(current, workInProgress, renderExpirationTime); + return updateFragment(current$$1, workInProgress, renderExpirationTime); case Mode: - return updateMode(current, workInProgress, renderExpirationTime); + return updateMode(current$$1, workInProgress, renderExpirationTime); case Profiler: - return updateProfiler(current, workInProgress, renderExpirationTime); + return updateProfiler(current$$1, workInProgress, renderExpirationTime); case ContextProvider: return updateContextProvider( - current, + current$$1, workInProgress, renderExpirationTime ); case ContextConsumer: return updateContextConsumer( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -14447,7 +15973,8 @@ function beginWork(current, workInProgress, renderExpirationTime) { outerPropTypes, _resolvedProps3, // Resolved for outer only "prop", - getComponentName(_type2) + getComponentName(_type2), + getCurrentFiberStackInDev ); } } @@ -14455,7 +15982,7 @@ function beginWork(current, workInProgress, renderExpirationTime) { _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3); return updateMemoComponent( - current, + current$$1, workInProgress, _type2, _resolvedProps3, @@ -14464,51 +15991,307 @@ function beginWork(current, workInProgress, renderExpirationTime) { ); } - case SimpleMemoComponent: { - return updateSimpleMemoComponent( - current, - workInProgress, - workInProgress.type, - workInProgress.pendingProps, - updateExpirationTime, - renderExpirationTime - ); - } + case SimpleMemoComponent: { + return updateSimpleMemoComponent( + current$$1, + workInProgress, + workInProgress.type, + workInProgress.pendingProps, + updateExpirationTime, + renderExpirationTime + ); + } + + case IncompleteClassComponent: { + var _Component3 = workInProgress.type; + var _unresolvedProps4 = workInProgress.pendingProps; + + var _resolvedProps4 = + workInProgress.elementType === _Component3 + ? _unresolvedProps4 + : resolveDefaultProps(_Component3, _unresolvedProps4); + + return mountIncompleteClassComponent( + current$$1, + workInProgress, + _Component3, + _resolvedProps4, + renderExpirationTime + ); + } + + case SuspenseListComponent: { + return updateSuspenseListComponent( + current$$1, + workInProgress, + renderExpirationTime + ); + } + + case FundamentalComponent: { + if (enableFundamentalAPI) { + return updateFundamentalComponent$1( + current$$1, + workInProgress, + renderExpirationTime + ); + } + + break; + } + + case ScopeComponent: { + if (enableScopeAPI) { + return updateScopeComponent( + current$$1, + workInProgress, + renderExpirationTime + ); + } + + 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 createFundamentalStateInstance(currentFiber, props, impl, state) { + return { + currentFiber: currentFiber, + impl: impl, + instance: null, + prevProps: null, + props: props, + state: state + }; +} + +function isFiberSuspenseAndTimedOut(fiber) { + return fiber.tag === SuspenseComponent && fiber.memoizedState !== null; +} + +function getSuspenseFallbackChild(fiber) { + return fiber.child.sibling.child; +} + +var emptyObject$2 = {}; + +function collectScopedNodes(node, fn, scopedNodes) { + if (enableScopeAPI) { + if (node.tag === HostComponent) { + var _type = node.type, + memoizedProps = node.memoizedProps, + stateNode = node.stateNode; + + var _instance = getPublicInstance(stateNode); + + if ( + _instance !== null && + fn(_type, memoizedProps || emptyObject$2, _instance) === true + ) { + scopedNodes.push(_instance); + } + } + + var child = node.child; + + if (isFiberSuspenseAndTimedOut(node)) { + child = getSuspenseFallbackChild(node); + } + + if (child !== null) { + collectScopedNodesFromChildren(child, fn, scopedNodes); + } + } +} + +function collectFirstScopedNode(node, fn) { + if (enableScopeAPI) { + if (node.tag === HostComponent) { + var _type2 = node.type, + memoizedProps = node.memoizedProps, + stateNode = node.stateNode; + + var _instance2 = getPublicInstance(stateNode); + + if ( + _instance2 !== null && + fn(_type2, memoizedProps, _instance2) === true + ) { + return _instance2; + } + } + + var child = node.child; + + if (isFiberSuspenseAndTimedOut(node)) { + child = getSuspenseFallbackChild(node); + } + + if (child !== null) { + return collectFirstScopedNodeFromChildren(child, fn); + } + } + + return null; +} + +function collectScopedNodesFromChildren(startingChild, fn, scopedNodes) { + var child = startingChild; + + while (child !== null) { + collectScopedNodes(child, fn, scopedNodes); + child = child.sibling; + } +} + +function collectFirstScopedNodeFromChildren(startingChild, fn) { + var child = startingChild; + + while (child !== null) { + var scopedNode = collectFirstScopedNode(child, fn); + + if (scopedNode !== null) { + return scopedNode; + } + + child = child.sibling; + } + + return null; +} + +function collectNearestScopeMethods(node, scope, childrenScopes) { + if (isValidScopeNode(node, scope)) { + childrenScopes.push(node.stateNode.methods); + } else { + var child = node.child; + + if (isFiberSuspenseAndTimedOut(node)) { + child = getSuspenseFallbackChild(node); + } + + if (child !== null) { + collectNearestChildScopeMethods(child, scope, childrenScopes); + } + } +} + +function collectNearestChildScopeMethods(startingChild, scope, childrenScopes) { + var child = startingChild; + + while (child !== null) { + collectNearestScopeMethods(child, scope, childrenScopes); + child = child.sibling; + } +} + +function isValidScopeNode(node, scope) { + return ( + node.tag === ScopeComponent && + node.type === scope && + node.stateNode !== null + ); +} + +function createScopeMethods(scope, instance) { + return { + getChildren: function() { + var currentFiber = instance.fiber; + var child = currentFiber.child; + var childrenScopes = []; + + if (child !== null) { + collectNearestChildScopeMethods(child, scope, childrenScopes); + } + + return childrenScopes.length === 0 ? null : childrenScopes; + }, + getChildrenFromRoot: function() { + var currentFiber = instance.fiber; + var node = currentFiber; + + while (node !== null) { + var parent = node.return; + + if (parent === null) { + break; + } + + node = parent; + + if (node.tag === ScopeComponent && node.type === scope) { + break; + } + } + + var childrenScopes = []; + collectNearestChildScopeMethods(node.child, scope, childrenScopes); + return childrenScopes.length === 0 ? null : childrenScopes; + }, + getParent: function() { + var node = instance.fiber.return; + + while (node !== null) { + if (node.tag === ScopeComponent && node.type === scope) { + return node.stateNode.methods; + } + + node = node.return; + } + + return null; + }, + getProps: function() { + var currentFiber = instance.fiber; + return currentFiber.memoizedProps; + }, + queryAllNodes: function(fn) { + var currentFiber = instance.fiber; + var child = currentFiber.child; + var scopedNodes = []; + + if (child !== null) { + collectScopedNodesFromChildren(child, fn, scopedNodes); + } + + return scopedNodes.length === 0 ? null : scopedNodes; + }, + queryFirstNode: function(fn) { + var currentFiber = instance.fiber; + var child = currentFiber.child; + + if (child !== null) { + return collectFirstScopedNodeFromChildren(child, fn); + } - case IncompleteClassComponent: { - var _Component3 = workInProgress.type; - var _unresolvedProps4 = workInProgress.pendingProps; + return null; + }, + containsNode: function(node) { + var fiber = getInstanceFromNode$1(node); - var _resolvedProps4 = - workInProgress.elementType === _Component3 - ? _unresolvedProps4 - : resolveDefaultProps(_Component3, _unresolvedProps4); + while (fiber !== null) { + if ( + fiber.tag === ScopeComponent && + fiber.type === scope && + fiber.stateNode === instance + ) { + return true; + } - return mountIncompleteClassComponent( - current, - workInProgress, - _Component3, - _resolvedProps4, - renderExpirationTime - ); - } + fiber = fiber.return; + } - case SuspenseListComponent: { - return updateSuspenseListComponent( - current, - workInProgress, - renderExpirationTime - ); + return false; } - } - - { - throw Error( - "Unknown unit of work tag (" + - workInProgress.tag + - "). This error is likely caused by a bug in React. Please file an issue." - ); - } + }; } function markUpdate(workInProgress) { @@ -14526,7 +16309,7 @@ var updateHostContainer; var updateHostComponent$1; var updateHostText$1; -{ +if (supportsMutation) { // Mutation mode appendAllChildren = function( parent, @@ -14541,8 +16324,13 @@ var updateHostText$1; while (node !== null) { if (node.tag === HostComponent || node.tag === HostText) { appendInitialChild(parent, node.stateNode); - } else if (node.tag === HostPortal); - else if (node.child !== null) { + } else if (enableFundamentalAPI && node.tag === FundamentalComponent) { + appendInitialChild(parent, node.stateNode.instance); + } else if (node.tag === HostPortal) { + // If we have a portal child, then we don't want to traverse + // down its children. Instead, we'll get insertions from each child in + // the portal directly. + } else if (node.child !== null) { node.child.return = node; node = node.child; continue; @@ -14594,7 +16382,14 @@ var updateHostText$1; // component is hitting the resume path. Figure out why. Possibly // related to `hidden`. - var updatePayload = prepareUpdate(); // TODO: Type this specific to this type of component. + var updatePayload = prepareUpdate( + instance, + type, + oldProps, + newProps, + rootContainerInstance, + currentHostContext + ); // TODO: Type this specific to this type of component. 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. @@ -14610,6 +16405,357 @@ var updateHostText$1; markUpdate(workInProgress); } }; +} else if (supportsPersistence) { + // 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 + branches: 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, type, props, node); + } + + 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(_instance, text, node); + } + + appendInitialChild(parent, _instance); + } else if (enableFundamentalAPI && node.tag === FundamentalComponent) { + var _instance2 = node.stateNode.instance; + + if (needsVisibilityToggle && isHidden) { + // This child is inside a timed out tree. Hide it. + var _props = node.memoizedProps; + var _type = node.type; + _instance2 = cloneHiddenInstance(_instance2, _type, _props, node); + } + + appendInitialChild(parent, _instance2); + } else if (node.tag === HostPortal) { + // If we have a portal child, then we don't want to traverse + // down its children. Instead, we'll get insertions from each child in + // the portal directly. + } else if (node.tag === SuspenseComponent) { + if ((node.effectTag & Update) !== NoEffect) { + // 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; + + if (fallbackChildParent !== null) { + fallbackChildParent.return = node; + node = fallbackChildParent; + continue; + } + } + } + } + + 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; + } + + while (node.sibling === null) { + if (node.return === null || node.return === workInProgress) { + return; + } + + node = node.return; + } + + 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; + + while (node !== null) { + // eslint-disable-next-line no-labels + branches: 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, type, props, node); + } + + 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(_instance3, text, node); + } + + appendChildToContainerChildSet(containerChildSet, _instance3); + } else if (enableFundamentalAPI && node.tag === FundamentalComponent) { + var _instance4 = node.stateNode.instance; + + if (needsVisibilityToggle && isHidden) { + // This child is inside a timed out tree. Hide it. + var _props2 = node.memoizedProps; + var _type2 = node.type; + _instance4 = cloneHiddenInstance(_instance4, _type2, _props2, node); + } + + appendChildToContainerChildSet(containerChildSet, _instance4); + } else if (node.tag === HostPortal) { + // If we have a portal child, then we don't want to traverse + // down its children. Instead, we'll get insertions from each child in + // the portal directly. + } else if (node.tag === SuspenseComponent) { + if ((node.effectTag & Update) !== NoEffect) { + // 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; + appendAllChildrenToContainer( + containerChildSet, + primaryChildParent, + true, + newIsHidden + ); + } + + var fallbackChildParent = primaryChildParent.sibling; + + if (fallbackChildParent !== null) { + fallbackChildParent.return = node; + node = fallbackChildParent; + continue; + } + } + } + } + + 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; + } + + while (node.sibling === null) { + if (node.return === null || node.return === workInProgress) { + return; + } + + node = node.return; + } + + node.sibling.return = node.return; + node = node.sibling; + } + }; + + updateHostContainer = function(workInProgress) { + var portalOrRoot = workInProgress.stateNode; + var childrenUnchanged = workInProgress.firstEffect === null; + + if (childrenUnchanged) { + // No changes, just reuse the existing instance. + } 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); + } + }; + + 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 childrenUnchanged = workInProgress.firstEffect === null; + + if (childrenUnchanged && oldProps === newProps) { + // No changes, just reuse the existing instance. + // Note that this might release a previous clone. + workInProgress.stateNode = currentInstance; + return; + } + + var recyclableInstance = workInProgress.stateNode; + var currentHostContext = getHostContext(); + var updatePayload = null; + + if (oldProps !== newProps) { + updatePayload = prepareUpdate( + recyclableInstance, + type, + oldProps, + newProps, + rootContainerInstance, + currentHostContext + ); + } + + if (childrenUnchanged && updatePayload === null) { + // No changes, just reuse the existing instance. + // Note that this might release a previous clone. + workInProgress.stateNode = currentInstance; + return; + } + + var newInstance = cloneInstance( + currentInstance, + updatePayload, + type, + oldProps, + newProps, + workInProgress, + childrenUnchanged, + recyclableInstance + ); + + if ( + finalizeInitialChildren( + newInstance, + type, + newProps, + rootContainerInstance, + currentHostContext + ) + ) { + markUpdate(workInProgress); + } + + workInProgress.stateNode = newInstance; + + if (childrenUnchanged) { + // If there are no other effects in this tree, we need to flag this node as having one. + // Even though we're not going to use it for anything. + // Otherwise parents won't know that there are new children to propagate upwards. + markUpdate(workInProgress); + } else { + // If children might have changed, we have to add them all to the set. + appendAllChildren(newInstance, workInProgress, false, false); + } + }; + + 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. + + markUpdate(workInProgress); + } + }; +} else { + // No host operations + updateHostContainer = function(workInProgress) { + // Noop + }; + + updateHostComponent$1 = function( + current, + workInProgress, + type, + newProps, + rootContainerInstance + ) { + // Noop + }; + + updateHostText$1 = function(current, workInProgress, oldText, newText) { + // Noop + }; } function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { @@ -14687,16 +16833,14 @@ function completeWork(current, workInProgress, renderExpirationTime) { switch (workInProgress.tag) { case IndeterminateComponent: + break; + case LazyComponent: + break; + case SimpleMemoComponent: case FunctionComponent: - case ForwardRef: - case Fragment: - case Mode: - case Profiler: - case ContextConsumer: - case MemoComponent: - return null; + break; case ClassComponent: { var Component = workInProgress.type; @@ -14705,7 +16849,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { popContext(workInProgress); } - return null; + break; } case HostRoot: { @@ -14721,7 +16865,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { 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(); + var wasHydrated = popHydrationState(workInProgress); if (wasHydrated) { // If we hydrated, then we'll need to schedule an update for @@ -14731,7 +16875,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { } updateHostContainer(workInProgress); - return null; + break; } case HostComponent: { @@ -14748,6 +16892,15 @@ function completeWork(current, workInProgress, renderExpirationTime) { rootContainerInstance ); + if (enableFlareAPI) { + var prevListeners = current.memoizedProps.listeners; + var nextListeners = newProps.listeners; + + if (prevListeners !== nextListeners) { + markUpdate(workInProgress); + } + } + if (current.ref !== workInProgress.ref) { markRef$1(workInProgress); } @@ -14759,24 +16912,42 @@ function completeWork(current, workInProgress, renderExpirationTime) { ); } // This can happen when we abort work. - 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 + // or completeWork depending on we want to add then top->down or // bottom->up. Top->down is faster in IE11. - var _wasHydrated = popHydrationState(); + var _wasHydrated = popHydrationState(workInProgress); 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 + if ( + prepareToHydrateHostInstance( + workInProgress, + rootContainerInstance, + currentHostContext + ) + ) { + // If changes to the hydrated node needs to be applied at the // commit-phase we mark this as such. markUpdate(workInProgress); } + + if (enableFlareAPI) { + var listeners = newProps.listeners; + + if (listeners != null) { + updateEventListeners( + listeners, + workInProgress, + rootContainerInstance + ); + } + } } else { var instance = createInstance( type, @@ -14788,10 +16959,30 @@ function completeWork(current, workInProgress, renderExpirationTime) { appendAllChildren(instance, workInProgress, false, false); // This needs to be set before we mount Flare event listeners workInProgress.stateNode = instance; + + if (enableFlareAPI) { + var _listeners = newProps.listeners; + + if (_listeners != null) { + updateEventListeners( + _listeners, + workInProgress, + rootContainerInstance + ); + } + } // Certain renderers require commit-time effects for initial mount. // (eg DOM renderer supports auto-focus for certain elements). // Make sure such renderers get scheduled for later work. - if (finalizeInitialChildren(instance)) { + if ( + finalizeInitialChildren( + instance, + type, + newProps, + rootContainerInstance, + currentHostContext + ) + ) { markUpdate(workInProgress); } } @@ -14802,7 +16993,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { } } - return null; + break; } case HostText: { @@ -14826,10 +17017,10 @@ function completeWork(current, workInProgress, renderExpirationTime) { var _currentHostContext = getHostContext(); - var _wasHydrated2 = popHydrationState(); + var _wasHydrated2 = popHydrationState(workInProgress); if (_wasHydrated2) { - if (prepareToHydrateHostTextInstance()) { + if (prepareToHydrateHostTextInstance(workInProgress)) { markUpdate(workInProgress); } } else { @@ -14842,13 +17033,56 @@ function completeWork(current, workInProgress, renderExpirationTime) { } } - return null; + break; } + case ForwardRef: + break; + case SuspenseComponent: { popSuspenseContext(workInProgress); var nextState = workInProgress.memoizedState; + if (enableSuspenseServerRenderer) { + if (nextState !== null && nextState.dehydrated !== null) { + if (current === null) { + var _wasHydrated3 = popHydrationState(workInProgress); + + if (!_wasHydrated3) { + throw Error( + "A dehydrated suspense component was completed without a hydrated node. This is probably a bug in React." + ); + } + + prepareToHydrateHostSuspenseInstance(workInProgress); + + if (enableSchedulerTracing) { + markSpawnedWork(Never); + } + + return null; + } else { + // We should never have been in a hydration state if we didn't have a current. + // However, in some of those paths, we might have reentered a hydration state + // and then we might be inside a hydration state. In that case, we'll need to + // exit out of it. + resetHydrationState(); + + if ((workInProgress.effectTag & DidCapture) === NoEffect) { + // This boundary did not suspend so it's now hydrated and unsuspended. + workInProgress.memoizedState = null; + } // If nothing suspended, we need to schedule an effect to mark this boundary + // as having hydrated so events know that they're free be invoked. + // It's also a signal to replay events and the suspense callback. + // If something suspended, schedule an effect to attach retry listeners. + // So we might as well always mark this. + + workInProgress.effectTag |= Update; + return null; + } + } + } + if ((workInProgress.effectTag & DidCapture) !== NoEffect) { // Something suspended. Re-render with the fallback children. workInProgress.expirationTime = renderExpirationTime; // Do not reset the effect list. @@ -14860,7 +17094,9 @@ function completeWork(current, workInProgress, renderExpirationTime) { var prevDidTimeout = false; if (current === null) { - if (workInProgress.memoizedProps.fallback !== undefined); + if (workInProgress.memoizedProps.fallback !== undefined) { + popHydrationState(workInProgress); + } } else { var prevState = current.memoizedState; prevDidTimeout = prevState !== null; @@ -14925,30 +17161,64 @@ function completeWork(current, workInProgress, renderExpirationTime) { } } - { + if (supportsPersistence) { + // 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 proimse. This flag is also used to hide the + // primary children. + workInProgress.effectTag |= Update; + } + } + + if (supportsMutation) { // 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 + // retry listener to the proimse. 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 + // *unhide* children that were previously hidden, so check if the // is currently timed out, too. workInProgress.effectTag |= Update; } } - return null; + if ( + enableSuspenseCallback && + workInProgress.updateQueue !== null && + workInProgress.memoizedProps.suspenseCallback != null + ) { + // Always notify the callback + workInProgress.effectTag |= Update; + } + + break; } + case Fragment: + break; + + case Mode: + break; + + case Profiler: + break; + case HostPortal: popHostContainer(workInProgress); updateHostContainer(workInProgress); - return null; + break; case ContextProvider: // Pop provider fiber popProvider(workInProgress); - return null; + break; + + case ContextConsumer: + break; + + case MemoComponent: + break; case IncompleteClassComponent: { // Same as class component case. I put it down here so that the tags are @@ -14959,7 +17229,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { popContext(workInProgress); } - return null; + break; } case SuspenseListComponent: { @@ -14967,9 +17237,9 @@ function completeWork(current, workInProgress, renderExpirationTime) { 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; + // We're running in the default, "independent" mode. We don't do anything + // in this mode. + break; } var didSuspendAlready = @@ -15085,10 +17355,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { return null; } } else if ( - // The time it took to render last row is greater than time until - // the expiration. - now() * 2 - renderState.renderingStartTime > - renderState.tailExpiration && + now() > renderState.tailExpiration && renderExpirationTime > Never ) { // We have now passed our CPU deadline and we'll just give up further @@ -15105,7 +17372,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { var nextPriority = renderExpirationTime - 1; workInProgress.expirationTime = workInProgress.childExpirationTime = nextPriority; - { + if (enableSchedulerTracing) { markSpawnedWork(nextPriority); } } @@ -15138,19 +17405,13 @@ function completeWork(current, workInProgress, renderExpirationTime) { // Heuristic for how long we're willing to spend rendering rows // until we just give up and show what we have so far. var TAIL_EXPIRATION_TIMEOUT_MS = 500; - renderState.tailExpiration = now() + TAIL_EXPIRATION_TIMEOUT_MS; // TODO: This is meant to mimic the train model or JND but this - // is a per component value. It should really be since the start - // of the total render or last commit. Consider using something like - // globalMostRecentFallbackTime. That doesn't account for being - // suspended for part of the time or when it's a new render. - // It should probably use a global start time value instead. + renderState.tailExpiration = now() + TAIL_EXPIRATION_TIMEOUT_MS; } // 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. @@ -15171,17 +17432,131 @@ function completeWork(current, workInProgress, renderExpirationTime) { return next; } - 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." - ); + case FundamentalComponent: { + if (enableFundamentalAPI) { + var fundamentalImpl = workInProgress.type.impl; + var fundamentalInstance = workInProgress.stateNode; + + if (fundamentalInstance === null) { + var getInitialState = fundamentalImpl.getInitialState; + var fundamentalState; + + if (getInitialState !== undefined) { + fundamentalState = getInitialState(newProps); + } + + fundamentalInstance = workInProgress.stateNode = createFundamentalStateInstance( + workInProgress, + newProps, + fundamentalImpl, + fundamentalState || {} + ); + + var _instance5 = getFundamentalComponentInstance(fundamentalInstance); + + fundamentalInstance.instance = _instance5; + + if (fundamentalImpl.reconcileChildren === false) { + return null; + } + + appendAllChildren(_instance5, workInProgress, false, false); + mountFundamentalComponent(fundamentalInstance); + } else { + // We fire update in commit phase + var prevProps = fundamentalInstance.props; + fundamentalInstance.prevProps = prevProps; + fundamentalInstance.props = newProps; + fundamentalInstance.currentFiber = workInProgress; + + if (supportsPersistence) { + var _instance6 = cloneFundamentalInstance(fundamentalInstance); + + fundamentalInstance.instance = _instance6; + appendAllChildren(_instance6, workInProgress, false, false); + } + + var shouldUpdate = shouldUpdateFundamentalComponent( + fundamentalInstance + ); + + if (shouldUpdate) { + markUpdate(workInProgress); + } + } + } + + break; + } + + case ScopeComponent: { + if (enableScopeAPI) { + if (current === null) { + var _type3 = workInProgress.type; + var scopeInstance = { + fiber: workInProgress, + methods: null + }; + workInProgress.stateNode = scopeInstance; + scopeInstance.methods = createScopeMethods(_type3, scopeInstance); + + if (enableFlareAPI) { + var _listeners2 = newProps.listeners; + + if (_listeners2 != null) { + var _rootContainerInstance2 = getRootHostContainer(); + + updateEventListeners( + _listeners2, + workInProgress, + _rootContainerInstance2 + ); + } + } + + if (workInProgress.ref !== null) { + markRef$1(workInProgress); + markUpdate(workInProgress); + } + } else { + if (enableFlareAPI) { + var _prevListeners = current.memoizedProps.listeners; + var _nextListeners = newProps.listeners; + + if ( + _prevListeners !== _nextListeners || + workInProgress.ref !== null + ) { + markUpdate(workInProgress); + } + } else { + if (workInProgress.ref !== null) { + markUpdate(workInProgress); + } + } + + if (current.ref !== workInProgress.ref) { + markRef$1(workInProgress); + } + } + } + + break; + } + + default: { + throw Error( + "Unknown unit of work tag (" + + workInProgress.tag + + "). This error is likely caused by a bug in React. Please file an issue." + ); + } } + + return null; } function unwindWork(workInProgress, renderExpirationTime) { @@ -15227,6 +17602,20 @@ function unwindWork(workInProgress, renderExpirationTime) { case SuspenseComponent: { popSuspenseContext(workInProgress); + if (enableSuspenseServerRenderer) { + var suspenseState = workInProgress.memoizedState; + + if (suspenseState !== null && suspenseState.dehydrated !== null) { + if (!(workInProgress.alternate !== null)) { + throw Error( + "Threw in newly mounted dehydrated component. This is likely a bug in React. Please file an issue." + ); + } + + resetHydrationState(); + } + } + var _effectTag2 = workInProgress.effectTag; if (_effectTag2 & ShouldCapture) { @@ -15296,6 +17685,9 @@ function unwindInterruptedWork(interruptedWork) { case ContextProvider: popProvider(interruptedWork); break; + + default: + break; } } @@ -15310,7 +17702,6 @@ function createCapturedValue(value, source) { } // Module provided by RN: - if ( !( typeof ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog === @@ -15358,8 +17749,7 @@ function logCapturedError(capturedError) { // However, the browser would have silenced the original error // so we'll print it first, and then print the stack addendum. - console["error"](error); // Don't transform to our wrapper - // For a more detailed description of this block, see: + console.error(error); // For a more detailed description of this block, see: // https://github.com/facebook/react/pull/13384 } @@ -15396,7 +17786,7 @@ function logCapturedError(capturedError) { // 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 + console.error(combinedMessage); } } @@ -15445,37 +17835,33 @@ function logError(boundary, errorInfo) { } } -var callComponentWillUnmountWithTimer = function(current, instance) { - startPhaseTimer(current, "componentWillUnmount"); - instance.props = current.memoizedProps; - instance.state = current.memoizedState; - - { - instance.componentWillUnmount(); - } - +var callComponentWillUnmountWithTimer = function(current$$1, instance) { + startPhaseTimer(current$$1, "componentWillUnmount"); + instance.props = current$$1.memoizedProps; + instance.state = current$$1.memoizedState; + instance.componentWillUnmount(); stopPhaseTimer(); }; // Capture errors so they don't interrupt unmounting. -function safelyCallComponentWillUnmount(current, instance) { +function safelyCallComponentWillUnmount(current$$1, instance) { { invokeGuardedCallback( null, callComponentWillUnmountWithTimer, null, - current, + current$$1, instance ); if (hasCaughtError()) { var unmountError = clearCaughtError(); - captureCommitPhaseError(current, unmountError); + captureCommitPhaseError(current$$1, unmountError); } } } -function safelyDetachRef(current) { - var ref = current.ref; +function safelyDetachRef(current$$1) { + var ref = current$$1.ref; if (ref !== null) { if (typeof ref === "function") { @@ -15484,7 +17870,7 @@ function safelyDetachRef(current) { if (hasCaughtError()) { var refError = clearCaughtError(); - captureCommitPhaseError(current, refError); + captureCommitPhaseError(current$$1, refError); } } } else { @@ -15493,31 +17879,31 @@ function safelyDetachRef(current) { } } -function safelyCallDestroy(current, destroy) { +function safelyCallDestroy(current$$1, destroy) { { invokeGuardedCallback(null, destroy, null); if (hasCaughtError()) { var error = clearCaughtError(); - captureCommitPhaseError(current, error); + captureCommitPhaseError(current$$1, error); } } } -function commitBeforeMutationLifeCycles(current, finishedWork) { +function commitBeforeMutationLifeCycles(current$$1, finishedWork) { switch (finishedWork.tag) { case FunctionComponent: case ForwardRef: - case SimpleMemoComponent: - case Block: { + case SimpleMemoComponent: { + commitHookEffectList(UnmountSnapshot, NoEffect$1, finishedWork); return; } case ClassComponent: { if (finishedWork.effectTag & Snapshot) { - if (current !== null) { - var prevProps = current.memoizedProps; - var prevState = current.memoizedState; + if (current$$1 !== null) { + var prevProps = current$$1.memoizedProps; + var prevState = current$$1.memoizedState; startPhaseTimer(finishedWork, "getSnapshotBeforeUpdate"); var instance = finishedWork.stateNode; // We could update instance props and state here, // but instead we rely on them being set during last render. @@ -15528,27 +17914,28 @@ function commitBeforeMutationLifeCycles(current, finishedWork) { 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 (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" - ); - } + !(instance.props === finishedWork.memoizedProps) + ? warning$1( + false, + "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" + ) + : void 0; + !(instance.state === finishedWork.memoizedState) + ? warning$1( + false, + "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.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ) + : void 0; } } @@ -15564,8 +17951,8 @@ function commitBeforeMutationLifeCycles(current, finishedWork) { if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) { didWarnSet.add(finishedWork.type); - - error( + warningWithoutStack$1( + false, "%s.getSnapshotBeforeUpdate(): A snapshot value (or null) " + "must be returned. You have returned undefined.", getComponentName(finishedWork.type) @@ -15588,16 +17975,18 @@ function commitBeforeMutationLifeCycles(current, finishedWork) { 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." - ); + 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." + ); + } + } } } -function commitHookEffectListUnmount(tag, finishedWork) { +function commitHookEffectList(unmountTag, mountTag, finishedWork) { var updateQueue = finishedWork.updateQueue; var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; @@ -15606,7 +17995,7 @@ function commitHookEffectListUnmount(tag, finishedWork) { var effect = firstEffect; do { - if ((effect.tag & tag) === tag) { + if ((effect.tag & unmountTag) !== NoEffect$1) { // Unmount var destroy = effect.destroy; effect.destroy = undefined; @@ -15616,36 +18005,22 @@ function commitHookEffectListUnmount(tag, finishedWork) { } } - effect = effect.next; - } while (effect !== firstEffect); - } -} - -function commitHookEffectListMount(tag, finishedWork) { - var updateQueue = finishedWork.updateQueue; - var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; - - if (lastEffect !== null) { - var firstEffect = lastEffect.next; - var effect = firstEffect; - - do { - if ((effect.tag & tag) === tag) { + if ((effect.tag & mountTag) !== NoEffect$1) { // Mount var create = effect.create; effect.destroy = create(); { - var destroy = effect.destroy; + var _destroy = effect.destroy; - if (destroy !== undefined && typeof destroy !== "function") { + if (_destroy !== undefined && typeof _destroy !== "function") { var addendum = void 0; - if (destroy === null) { + 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") { + } 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 " + @@ -15660,10 +18035,11 @@ function commitHookEffectListMount(tag, finishedWork) { "}, [someId]); // Or [] if effect doesn't need props or state\n\n" + "Learn more about data fetching with Hooks: https://fb.me/react-hooks-data-fetching"; } else { - addendum = " You returned: " + destroy; + addendum = " You returned: " + _destroy; } - error( + warningWithoutStack$1( + false, "An effect function must not return anything besides a function, " + "which is used for clean-up.%s%s", addendum, @@ -15683,93 +18059,82 @@ function commitPassiveHookEffects(finishedWork) { switch (finishedWork.tag) { case FunctionComponent: case ForwardRef: - case SimpleMemoComponent: - case Block: { - // TODO (#17945) We should call all passive destroy functions (for all fibers) - // before calling any create functions. The current approach only serializes - // these for a single fiber. - { - commitHookEffectListUnmount(Passive$1 | HasEffect, finishedWork); - commitHookEffectListMount(Passive$1 | HasEffect, finishedWork); - } - + case SimpleMemoComponent: { + commitHookEffectList(UnmountPassive, NoEffect$1, finishedWork); + commitHookEffectList(NoEffect$1, MountPassive, finishedWork); break; } + + default: + break; } } } function commitLifeCycles( finishedRoot, - current, + current$$1, finishedWork, committedExpirationTime ) { switch (finishedWork.tag) { case FunctionComponent: case ForwardRef: - case SimpleMemoComponent: - case Block: { - // 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); - } - - return; + case SimpleMemoComponent: { + commitHookEffectList(UnmountLayout, MountLayout, finishedWork); + break; } - case ClassComponent: { - var instance = finishedWork.stateNode; - - if (finishedWork.effectTag & Update) { - if (current === null) { - startPhaseTimer(finishedWork, "componentDidMount"); // 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" - ); - } - } - } + case ClassComponent: { + var instance = finishedWork.stateNode; + + if (finishedWork.effectTag & Update) { + if (current$$1 === null) { + startPhaseTimer(finishedWork, "componentDidMount"); // 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. { - instance.componentDidMount(); + if ( + finishedWork.type === finishedWork.elementType && + !didWarnAboutReassigningProps + ) { + !(instance.props === finishedWork.memoizedProps) + ? warning$1( + false, + "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" + ) + : void 0; + !(instance.state === finishedWork.memoizedState) + ? warning$1( + false, + "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.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ) + : void 0; + } } + instance.componentDidMount(); stopPhaseTimer(); } else { var prevProps = finishedWork.elementType === finishedWork.type - ? current.memoizedProps - : resolveDefaultProps(finishedWork.type, current.memoizedProps); - var prevState = current.memoizedState; + ? current$$1.memoizedProps + : resolveDefaultProps( + finishedWork.type, + current$$1.memoizedProps + ); + var prevState = current$$1.memoizedState; startPhaseTimer(finishedWork, "componentDidUpdate"); // 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. @@ -15779,38 +18144,36 @@ function commitLifeCycles( 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.props === finishedWork.memoizedProps) + ? warning$1( + false, + "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" + ) + : void 0; + !(instance.state === finishedWork.memoizedState) + ? warning$1( + false, + "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.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ) + : void 0; } } - { - instance.componentDidUpdate( - prevProps, - prevState, - instance.__reactInternalSnapshotBeforeUpdate - ); - } - + instance.componentDidUpdate( + prevProps, + prevState, + instance.__reactInternalSnapshotBeforeUpdate + ); stopPhaseTimer(); } } @@ -15823,33 +18186,39 @@ function commitLifeCycles( 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" - ); - } + !(instance.props === finishedWork.memoizedProps) + ? warning$1( + false, + "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" + ) + : void 0; + !(instance.state === finishedWork.memoizedState) + ? warning$1( + false, + "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.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ) + : void 0; } } // 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); + commitUpdateQueue( + finishedWork, + updateQueue, + instance, + committedExpirationTime + ); } return; @@ -15873,7 +18242,12 @@ function commitLifeCycles( } } - commitUpdateQueue(finishedWork, _updateQueue, _instance); + commitUpdateQueue( + finishedWork, + _updateQueue, + _instance, + committedExpirationTime + ); } return; @@ -15885,7 +18259,7 @@ function commitLifeCycles( // These effects should only be committed when components are first mounted, // aka when there is no current/alternate. - if (current === null && finishedWork.effectTag & Update) { + if (current$$1 === null && finishedWork.effectTag & Update) { var type = finishedWork.type; var props = finishedWork.memoizedProps; } @@ -15904,24 +18278,29 @@ function commitLifeCycles( } case Profiler: { - { - var _finishedWork$memoize2 = finishedWork.memoizedProps, - onCommit = _finishedWork$memoize2.onCommit, - onRender = _finishedWork$memoize2.onRender; - var effectDuration = finishedWork.stateNode.effectDuration; - var commitTime = getCommitTime(); + if (enableProfilerTimer) { + var onRender = finishedWork.memoizedProps.onRender; if (typeof onRender === "function") { - { + if (enableSchedulerTracing) { onRender( finishedWork.memoizedProps.id, - current === null ? "mount" : "update", + current$$1 === null ? "mount" : "update", finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, - commitTime, + getCommitTime(), finishedRoot.memoizedInteractions ); + } else { + onRender( + finishedWork.memoizedProps.id, + current$$1 === null ? "mount" : "update", + finishedWork.actualDuration, + finishedWork.treeBaseDuration, + finishedWork.actualStartTime, + getCommitTime() + ); } } } @@ -15930,6 +18309,7 @@ function commitLifeCycles( } case SuspenseComponent: { + commitSuspenseHydrationCallbacks(finishedRoot, finishedWork); return; } @@ -15938,17 +18318,19 @@ function commitLifeCycles( case FundamentalComponent: case ScopeComponent: 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." - ); + 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." + ); + } + } } } function hideOrUnhideAllChildren(finishedWork, isHidden) { - { + if (supportsMutation) { // 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; @@ -15966,7 +18348,7 @@ function hideOrUnhideAllChildren(finishedWork, isHidden) { var _instance3 = node.stateNode; if (isHidden) { - hideTextInstance(); + hideTextInstance(_instance3); } else { unhideTextInstance(_instance3, node.memoizedProps); } @@ -16021,12 +18403,17 @@ function commitAttachRef(finishedWork) { instanceToUse = instance; } // Moved outside to ensure DCE works with this flag + if (enableScopeAPI && finishedWork.tag === ScopeComponent) { + instanceToUse = instance.methods; + } + if (typeof ref === "function") { ref(instanceToUse); } else { { if (!ref.hasOwnProperty("current")) { - error( + warningWithoutStack$1( + false, "Unexpected ref object provided for %s. " + "Use either a ref-setter function or React.createRef().%s", getComponentName(finishedWork.type), @@ -16040,8 +18427,8 @@ function commitAttachRef(finishedWork) { } } -function commitDetachRef(current) { - var currentRef = current.ref; +function commitDetachRef(current$$1) { + var currentRef = current$$1.ref; if (currentRef !== null) { if (typeof currentRef === "function") { @@ -16054,77 +18441,92 @@ function commitDetachRef(current) { // deletion, so don't let them throw. Host-originating errors should // interrupt deletion, so it's okay -function commitUnmount(finishedRoot, current, renderPriorityLevel) { - onCommitUnmount(current); +function commitUnmount(finishedRoot, current$$1, renderPriorityLevel) { + onCommitUnmount(current$$1); - switch (current.tag) { + switch (current$$1.tag) { case FunctionComponent: case ForwardRef: case MemoComponent: - case SimpleMemoComponent: - case Block: { - var updateQueue = current.updateQueue; + case SimpleMemoComponent: { + var updateQueue = current$$1.updateQueue; if (updateQueue !== null) { var lastEffect = updateQueue.lastEffect; if (lastEffect !== null) { - var firstEffect = lastEffect.next; - - { - // When the owner fiber is deleted, the destroy function of a passive - // effect hook is called during the synchronous commit phase. This is - // a concession to implementation complexity. Calling it in the - // passive effect phase (like they usually are, when dependencies - // change during an update) would require either traversing the - // children of the deleted fiber again, or including unmount effects - // as part of the fiber effect list. - // - // Because this is during the sync commit phase, we need to change - // the priority. - // - // TODO: Reconsider this implementation trade off. - var priorityLevel = - renderPriorityLevel > NormalPriority - ? NormalPriority - : renderPriorityLevel; - runWithPriority(priorityLevel, function() { - var effect = firstEffect; - - do { - var _effect3 = effect, - _destroy = _effect3.destroy, - _tag = _effect3.tag; - - if (_destroy !== undefined) { - { - safelyCallDestroy(current, _destroy); - } - } + var firstEffect = lastEffect.next; // When the owner fiber is deleted, the destroy function of a passive + // effect hook is called during the synchronous commit phase. This is + // a concession to implementation complexity. Calling it in the + // passive effect phase (like they usually are, when dependencies + // change during an update) would require either traversing the + // children of the deleted fiber again, or including unmount effects + // as part of the fiber effect list. + // + // Because this is during the sync commit phase, we need to change + // the priority. + // + // TODO: Reconsider this implementation trade off. + + var priorityLevel = + renderPriorityLevel > NormalPriority + ? NormalPriority + : renderPriorityLevel; + runWithPriority(priorityLevel, function() { + var effect = firstEffect; + + do { + var destroy = effect.destroy; + + if (destroy !== undefined) { + safelyCallDestroy(current$$1, destroy); + } - effect = effect.next; - } while (effect !== firstEffect); - }); - } + effect = effect.next; + } while (effect !== firstEffect); + }); } } - return; + break; } case ClassComponent: { - safelyDetachRef(current); - var instance = current.stateNode; + safelyDetachRef(current$$1); + var instance = current$$1.stateNode; if (typeof instance.componentWillUnmount === "function") { - safelyCallComponentWillUnmount(current, instance); + safelyCallComponentWillUnmount(current$$1, instance); } return; } case HostComponent: { - safelyDetachRef(current); + if (enableFlareAPI) { + var dependencies = current$$1.dependencies; + + if (dependencies !== null) { + var respondersMap = dependencies.responders; + + if (respondersMap !== null) { + var responderInstances = Array.from(respondersMap.values()); + + for ( + var i = 0, length = responderInstances.length; + i < length; + i++ + ) { + var responderInstance = responderInstances[i]; + unmountResponderInstance(responderInstance); + } + + dependencies.responders = null; + } + } + } + + safelyDetachRef(current$$1); return; } @@ -16132,23 +18534,48 @@ function commitUnmount(finishedRoot, current, renderPriorityLevel) { // TODO: this is recursive. // We are also not using this parent because // the portal will get pushed immediately. - { - unmountHostComponents(finishedRoot, current, renderPriorityLevel); + if (supportsMutation) { + unmountHostComponents(finishedRoot, current$$1, renderPriorityLevel); + } else if (supportsPersistence) { + emptyPortalContainer(current$$1); } return; } case FundamentalComponent: { + if (enableFundamentalAPI) { + var fundamentalInstance = current$$1.stateNode; + + if (fundamentalInstance !== null) { + unmountFundamentalComponent(fundamentalInstance); + current$$1.stateNode = null; + } + } + return; } case DehydratedFragment: { + if (enableSuspenseCallback) { + var hydrationCallbacks = finishedRoot.hydrationCallbacks; + + if (hydrationCallbacks !== null) { + var onDeleted = hydrationCallbacks.onDeleted; + + if (onDeleted) { + onDeleted(current$$1.stateNode); + } + } + } + return; } case ScopeComponent: { - return; + if (enableScopeAPI) { + safelyDetachRef(current$$1); + } } } } @@ -16168,7 +18595,7 @@ function commitNestedUnmounts(finishedRoot, root, renderPriorityLevel) { 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 + (!supportsMutation || node.tag !== HostPortal) ) { node.child.return = node; node = node.child; @@ -16192,30 +18619,72 @@ function commitNestedUnmounts(finishedRoot, root, renderPriorityLevel) { } } -function detachFiber(current) { - var alternate = current.alternate; // Cut off the return pointers to disconnect it from the tree. Ideally, we +function detachFiber(current$$1) { + var alternate = current$$1.alternate; // 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. - current.return = null; - current.child = null; - current.memoizedState = null; - current.updateQueue = null; - current.dependencies = null; - current.alternate = null; - current.firstEffect = null; - current.lastEffect = null; - current.pendingProps = null; - current.memoizedProps = null; - current.stateNode = null; + current$$1.return = null; + current$$1.child = null; + current$$1.memoizedState = null; + current$$1.updateQueue = null; + current$$1.dependencies = null; + current$$1.alternate = null; + current$$1.firstEffect = null; + current$$1.lastEffect = null; + current$$1.pendingProps = null; + current$$1.memoizedProps = null; if (alternate !== null) { detachFiber(alternate); } } +function emptyPortalContainer(current$$1) { + if (!supportsPersistence) { + return; + } + + var portal = current$$1.stateNode; + var containerInfo = portal.containerInfo; + var emptyChildSet = createContainerChildSet(containerInfo); + replaceContainerChildren(containerInfo, emptyChildSet); +} + +function commitContainer(finishedWork) { + if (!supportsPersistence) { + return; + } + + switch (finishedWork.tag) { + case ClassComponent: + case HostComponent: + case HostText: + case FundamentalComponent: { + return; + } + + case HostRoot: + case HostPortal: { + var portalOrRoot = finishedWork.stateNode; + var containerInfo = portalOrRoot.containerInfo, + pendingChildren = portalOrRoot.pendingChildren; + replaceContainerChildren(containerInfo, pendingChildren); + return; + } + + 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." + ); + } + } + } +} + function getHostParentFiber(fiber) { var parent = fiber.return; @@ -16293,6 +18762,10 @@ function getHostSibling(fiber) { } function commitPlacement(finishedWork) { + if (!supportsMutation) { + return; + } // Recursively insert all host nodes into the parent. + var parentFiber = getHostParentFiber(finishedWork); // Note: these two variables *must* always be updated together. var parent; @@ -16316,6 +18789,10 @@ function commitPlacement(finishedWork) { break; case FundamentalComponent: + if (enableFundamentalAPI) { + parent = parentStateNode.instance; + isContainer = false; + } // eslint-disable-next-line-no-fallthrough @@ -16327,79 +18804,65 @@ function commitPlacement(finishedWork) { } if (parentFiber.effectTag & ContentReset) { + // Reset the text content of the parent before doing any insertions parentFiber.effectTag &= ~ContentReset; } 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 (isContainer) { - insertOrAppendPlacementNodeIntoContainer(finishedWork, before, parent); - } else { - insertOrAppendPlacementNode(finishedWork, before, parent); - } -} - -function insertOrAppendPlacementNodeIntoContainer(node, before, parent) { - var tag = node.tag; - var isHost = tag === HostComponent || tag === HostText; - - if (isHost || enableFundamentalAPI) { - var stateNode = isHost ? node.stateNode : node.stateNode.instance; + var node = finishedWork; - if (before) { - insertInContainerBefore(parent); - } else { - appendChildToContainer(parent, stateNode); - } - } else if (tag === HostPortal); - else { - var child = node.child; + while (true) { + var isHost = node.tag === HostComponent || node.tag === HostText; - if (child !== null) { - insertOrAppendPlacementNodeIntoContainer(child, before, parent); - var sibling = child.sibling; + if (isHost || (enableFundamentalAPI && node.tag === FundamentalComponent)) { + var stateNode = isHost ? node.stateNode : node.stateNode.instance; - while (sibling !== null) { - insertOrAppendPlacementNodeIntoContainer(sibling, before, parent); - sibling = sibling.sibling; + if (before) { + if (isContainer) { + insertInContainerBefore(parent, stateNode, before); + } else { + insertBefore(parent, stateNode, before); + } + } else { + if (isContainer) { + appendChildToContainer(parent, stateNode); + } else { + appendChild(parent, stateNode); + } } + } else if (node.tag === HostPortal) { + // If the insertion itself is a portal, then we don't want to traverse + // down its children. Instead, we'll get insertions from each child in + // the portal directly. + } else if (node.child !== null) { + node.child.return = node; + node = node.child; + continue; } - } -} - -function insertOrAppendPlacementNode(node, before, parent) { - var tag = node.tag; - var isHost = tag === HostComponent || tag === HostText; - if (isHost || enableFundamentalAPI) { - var stateNode = isHost ? node.stateNode : node.stateNode.instance; - - if (before) { - insertBefore(parent, stateNode, before); - } else { - appendChild(parent, stateNode); + if (node === finishedWork) { + return; } - } 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; + while (node.sibling === null) { + if (node.return === null || node.return === finishedWork) { + return; } + + node = node.return; } + + node.sibling.return = node.return; + node = node.sibling; } } -function unmountHostComponents(finishedRoot, current, renderPriorityLevel) { +function unmountHostComponents(finishedRoot, current$$1, 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 + var node = current$$1; // 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. @@ -16435,6 +18898,12 @@ function unmountHostComponents(finishedRoot, current, renderPriorityLevel) { currentParent = parentStateNode.containerInfo; currentParentIsContainer = true; break findParent; + + case FundamentalComponent: + if (enableFundamentalAPI) { + currentParent = parentStateNode.instance; + currentParentIsContainer = false; + } } parent = parent.return; @@ -16452,6 +18921,37 @@ function unmountHostComponents(finishedRoot, current, renderPriorityLevel) { } else { removeChild(currentParent, node.stateNode); } // Don't visit children because we already visited them. + } else if (enableFundamentalAPI && node.tag === FundamentalComponent) { + var fundamentalNode = node.stateNode.instance; + commitNestedUnmounts(finishedRoot, node, renderPriorityLevel); // After all the children have unmounted, it is now safe to remove the + // node from the tree. + + if (currentParentIsContainer) { + removeChildFromContainer(currentParent, fundamentalNode); + } else { + removeChild(currentParent, fundamentalNode); + } + } else if ( + enableSuspenseServerRenderer && + node.tag === DehydratedFragment + ) { + if (enableSuspenseCallback) { + var hydrationCallbacks = finishedRoot.hydrationCallbacks; + + if (hydrationCallbacks !== null) { + var onDeleted = hydrationCallbacks.onDeleted; + + if (onDeleted) { + onDeleted(node.stateNode); + } + } + } // Delete the dehydrated suspense boundary and all of its content. + + if (currentParentIsContainer) { + clearSuspenseBoundaryFromContainer(currentParent, node.stateNode); + } else { + clearSuspenseBoundary(currentParent, node.stateNode); + } } else if (node.tag === HostPortal) { if (node.child !== null) { // When we go into a portal, it becomes the parent to remove from. @@ -16473,12 +18973,12 @@ function unmountHostComponents(finishedRoot, current, renderPriorityLevel) { } } - if (node === current) { + if (node === current$$1) { return; } while (node.sibling === null) { - if (node.return === null || node.return === current) { + if (node.return === null || node.return === current$$1) { return; } @@ -16496,32 +18996,74 @@ function unmountHostComponents(finishedRoot, current, renderPriorityLevel) { } } -function commitDeletion(finishedRoot, current, renderPriorityLevel) { - { +function commitDeletion(finishedRoot, current$$1, renderPriorityLevel) { + if (supportsMutation) { // Recursively delete all host nodes from the parent. // Detach refs and call componentWillUnmount() on the whole subtree. - unmountHostComponents(finishedRoot, current, renderPriorityLevel); + unmountHostComponents(finishedRoot, current$$1, renderPriorityLevel); + } else { + // Detach refs and call componentWillUnmount() on the whole subtree. + commitNestedUnmounts(finishedRoot, current$$1, renderPriorityLevel); } - detachFiber(current); + detachFiber(current$$1); } -function commitWork(current, finishedWork) { +function commitWork(current$$1, finishedWork) { + if (!supportsMutation) { + switch (finishedWork.tag) { + case FunctionComponent: + case ForwardRef: + case MemoComponent: + case SimpleMemoComponent: { + // Note: We currently never use MountMutation, but useLayout uses + // UnmountMutation. + commitHookEffectList(UnmountMutation, MountMutation, finishedWork); + return; + } + + case Profiler: { + return; + } + + case SuspenseComponent: { + commitSuspenseComponent(finishedWork); + attachSuspenseRetryListeners(finishedWork); + return; + } + + case SuspenseListComponent: { + attachSuspenseRetryListeners(finishedWork); + return; + } + + case HostRoot: { + if (supportsHydration) { + var root = finishedWork.stateNode; + + if (root.hydrate) { + // We've just hydrated. No need to hydrate again. + root.hydrate = false; + commitHydratedContainer(root.containerInfo); + } + } + + break; + } + } + + commitContainer(finishedWork); + return; + } + switch (finishedWork.tag) { case FunctionComponent: case ForwardRef: case MemoComponent: - case SimpleMemoComponent: - case Block: { - // 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); - } - + case SimpleMemoComponent: { + // Note: We currently never use MountMutation, but useLayout uses + // UnmountMutation. + commitHookEffectList(UnmountMutation, MountMutation, finishedWork); return; } @@ -16538,14 +19080,31 @@ function commitWork(current, finishedWork) { // as the newProps. The updatePayload will contain the real change in // this case. - var oldProps = current !== null ? current.memoizedProps : newProps; + var oldProps = + current$$1 !== null ? current$$1.memoizedProps : newProps; var type = finishedWork.type; // TODO: Type the updateQueue to be specific to host components. var updatePayload = finishedWork.updateQueue; finishedWork.updateQueue = null; if (updatePayload !== null) { - commitUpdate(instance, updatePayload, type, oldProps, newProps); + commitUpdate( + instance, + updatePayload, + type, + oldProps, + newProps, + finishedWork + ); + } + + if (enableFlareAPI) { + var prevListeners = oldProps.listeners; + var nextListeners = newProps.listeners; + + if (prevListeners !== nextListeners) { + updateEventListeners(nextListeners, finishedWork, null); + } } } @@ -16564,12 +19123,22 @@ function commitWork(current, finishedWork) { // as the newProps. The updatePayload will contain the real change in // this case. - var oldText = current !== null ? current.memoizedProps : newText; + var oldText = current$$1 !== null ? current$$1.memoizedProps : newText; commitTextUpdate(textInstance, oldText, newText); return; } case HostRoot: { + if (supportsHydration) { + var _root = finishedWork.stateNode; + + if (_root.hydrate) { + // We've just hydrated. No need to hydrate again. + _root.hydrate = false; + commitHydratedContainer(_root.containerInfo); + } + } + return; } @@ -16583,20 +19152,54 @@ function commitWork(current, finishedWork) { return; } - case SuspenseListComponent: { - attachSuspenseRetryListeners(finishedWork); + case SuspenseListComponent: { + attachSuspenseRetryListeners(finishedWork); + return; + } + + case IncompleteClassComponent: { + return; + } + + case FundamentalComponent: { + if (enableFundamentalAPI) { + var fundamentalInstance = finishedWork.stateNode; + updateFundamentalComponent(fundamentalInstance); + } + return; } - case IncompleteClassComponent: { + case ScopeComponent: { + if (enableScopeAPI) { + var scopeInstance = finishedWork.stateNode; + scopeInstance.fiber = finishedWork; + + if (enableFlareAPI) { + var _newProps = finishedWork.memoizedProps; + + var _oldProps = + current$$1 !== null ? current$$1.memoizedProps : _newProps; + + var _prevListeners = _oldProps.listeners; + var _nextListeners = _newProps.listeners; + + if (_prevListeners !== _nextListeners) { + updateEventListeners(_nextListeners, finishedWork, null); + } + } + } + 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." - ); + 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." + ); + } + } } } @@ -16613,9 +19216,61 @@ function commitSuspenseComponent(finishedWork) { markCommitTimeOfFallback(); } - if (primaryChildParent !== null) { + if (supportsMutation && primaryChildParent !== null) { hideOrUnhideAllChildren(primaryChildParent, newDidTimeout); } + + if (enableSuspenseCallback && newState !== null) { + var suspenseCallback = finishedWork.memoizedProps.suspenseCallback; + + if (typeof suspenseCallback === "function") { + var thenables = finishedWork.updateQueue; + + if (thenables !== null) { + suspenseCallback(new Set(thenables)); + } + } else { + if (suspenseCallback !== undefined) { + warning$1(false, "Unexpected type for suspenseCallback."); + } + } + } +} + +function commitSuspenseHydrationCallbacks(finishedRoot, finishedWork) { + if (!supportsHydration) { + return; + } + + var newState = finishedWork.memoizedState; + + if (newState === null) { + var current$$1 = finishedWork.alternate; + + if (current$$1 !== null) { + var prevState = current$$1.memoizedState; + + if (prevState !== null) { + var suspenseInstance = prevState.dehydrated; + + if (suspenseInstance !== null) { + commitHydratedSuspenseInstance(suspenseInstance); + + if (enableSuspenseCallback) { + var hydrationCallbacks = finishedRoot.hydrationCallbacks; + + if (hydrationCallbacks !== null) { + var onHydrated = hydrationCallbacks.onHydrated; + + if (onHydrated) { + onHydrated(suspenseInstance); + } + } + } + } + } + } + } } function attachSuspenseRetryListeners(finishedWork) { @@ -16637,7 +19292,7 @@ function attachSuspenseRetryListeners(finishedWork) { var retry = resolveRetryThenable.bind(null, finishedWork, thenable); if (!retryCache.has(thenable)) { - { + if (enableSchedulerTracing) { if (thenable.__reactDoNotTraceInteractions !== true) { retry = tracing.unstable_wrap(retry); } @@ -16650,8 +19305,12 @@ function attachSuspenseRetryListeners(finishedWork) { } } -function commitResetTextContent(current) { - resetTextContent(current.stateNode); +function commitResetTextContent(current$$1) { + if (!supportsMutation) { + return; + } + + resetTextContent(current$$1.stateNode); } var PossiblyWeakMap = typeof WeakMap === "function" ? WeakMap : Map; @@ -16681,11 +19340,11 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { var getDerivedStateFromError = fiber.type.getDerivedStateFromError; if (typeof getDerivedStateFromError === "function") { - var error$1 = errorInfo.value; + var error = errorInfo.value; update.payload = function() { logError(fiber, errorInfo); - return getDerivedStateFromError(error$1); + return getDerivedStateFromError(error); }; } @@ -16708,9 +19367,9 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { logError(fiber, errorInfo); } - var error$1 = errorInfo.value; + var error = errorInfo.value; var stack = errorInfo.stack; - this.componentDidCatch(error$1, { + this.componentDidCatch(error, { componentStack: stack !== null ? stack : "" }); @@ -16719,13 +19378,14 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { // 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 (fiber.expirationTime !== Sync) { - 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" - ); - } + !(fiber.expirationTime === Sync) + ? warningWithoutStack$1( + false, + "%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" + ) + : void 0; } } }; @@ -16790,22 +19450,7 @@ function throwException( ) { // This is a thenable. var thenable = 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.expirationTime = currentSource.expirationTime; - } else { - sourceFiber.updateQueue = null; - sourceFiber.memoizedState = null; - } - } - + checkForWrongSuspensePriorityInDEV(sourceFiber); var hasInvisibleParentBoundary = hasSuspenseContext( suspenseStackCursor.current, InvisibleParentSuspenseContext @@ -16979,6 +19624,9 @@ function throwException( } break; + + default: + break; } workInProgress = workInProgress.return; @@ -16986,15 +19634,18 @@ function throwException( } var ceil = Math.ceil; -var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, - ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, - IsSomeRendererActing = ReactSharedInternals.IsSomeRendererActing; +var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher; +var ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner; +var IsSomeRendererActing = ReactSharedInternals.IsSomeRendererActing; var NoContext = /* */ 0; var BatchedContext = /* */ 1; +var EventContext = + /* */ + 2; var DiscreteEventContext = /* */ 4; @@ -17020,7 +19671,7 @@ var workInProgressRoot = null; // The fiber we're working on var workInProgress = null; // The expiration time we're rendering -var renderExpirationTime$1 = NoWork; // Whether to root completed, errored, suspended, etc. +var renderExpirationTime = NoWork; // Whether to root completed, errored, suspended, etc. var workInProgressRootExitStatus = RootIncomplete; // A fatal error, if one is thrown @@ -17105,7 +19756,7 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { if ((executionContext & RenderContext) !== NoContext) { // Use whatever time we're already rendering // TODO: Should there be a way to opt out, like with `runWithPriority`? - return renderExpirationTime$1; + return renderExpirationTime; } var expirationTime; @@ -17149,10 +19800,7 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { // Refactor computeExpirationForFiber + scheduleUpdate so we have access to // the root when we check for this condition. - if ( - workInProgressRoot !== null && - expirationTime === renderExpirationTime$1 - ) { + if (workInProgressRoot !== null && expirationTime === renderExpirationTime) { // This is a trick to move this update into a separate batch expirationTime -= 1; } @@ -17161,7 +19809,7 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { } function scheduleUpdateOnFiber(fiber, expirationTime) { checkForNestedUpdates(); - warnAboutRenderPhaseUpdatesInDEV(fiber); + warnAboutInvalidUpdatesOnClassComponentsInDEV(fiber); var root = markUpdateTimeFromFiberToRoot(fiber, expirationTime); if (root === null) { @@ -17295,7 +19943,7 @@ function markUpdateTimeFromFiberToRoot(fiber, expirationTime) { // scheduled before the root started rendering. Need to track the next // pending expiration time (perhaps by backtracking the return path) and // then trigger a restart in the `renderDidSuspendDelayIfPossible` path. - markRootSuspendedAtTime(root, renderExpirationTime$1); + markRootSuspendedAtTime(root, renderExpirationTime); } } // Mark that the root has a pending update. @@ -17327,17 +19975,9 @@ function getNextRootExpirationTimeToWorkOn(root) { var lastPingedTime = root.lastPingedTime; var nextKnownPendingLevel = root.nextKnownPendingLevel; - var nextLevel = - lastPingedTime > nextKnownPendingLevel - ? lastPingedTime - : nextKnownPendingLevel; - - if (nextLevel <= Idle && firstPendingTime !== nextLevel) { - // Don't work on Idle/Never priority unless everything else is committed. - return NoWork; - } - - return nextLevel; + return lastPingedTime > nextKnownPendingLevel + ? lastPingedTime + : nextKnownPendingLevel; } // 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 // expiration time of the existing task is the same as the expiration time of @@ -17404,6 +20044,11 @@ function ensureRootIsScheduled(root) { if (expirationTime === Sync) { // Sync React callbacks are scheduled on a special internal queue callbackNode = scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root)); + } else if (disableSchedulerTimeoutBasedOnReactExpirationTime) { + callbackNode = scheduleCallback( + priorityLevel, + performConcurrentWorkOnRoot.bind(null, root) + ); } else { callbackNode = scheduleCallback( priorityLevel, @@ -17422,7 +20067,7 @@ function ensureRootIsScheduled(root) { function performConcurrentWorkOnRoot(root, didTimeout) { // 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 = NoWork; // Check if the render expired. + currentEventTime = NoWork; if (didTimeout) { // The render task took too long to complete. Mark the current time as @@ -17437,50 +20082,83 @@ function performConcurrentWorkOnRoot(root, didTimeout) { var expirationTime = getNextRootExpirationTimeToWorkOn(root); - if (expirationTime === NoWork) { - return null; - } + if (expirationTime !== NoWork) { + var originalCallbackNode = root.callbackNode; - var originalCallbackNode = root.callbackNode; + if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { + throw Error("Should not already be working."); + } - if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { - throw Error("Should not already be working."); - } + flushPassiveEffects(); // If the root or expiration time have changed, throw out the existing stack + // and prepare a fresh one. Otherwise we'll continue where we left off. - flushPassiveEffects(); - var exitStatus = renderRootConcurrent(root, expirationTime); + if ( + root !== workInProgressRoot || + expirationTime !== renderExpirationTime + ) { + prepareFreshStack(root, expirationTime); + startWorkOnPendingInteractions(root, expirationTime); + } // If we have a work-in-progress fiber, it means there's still work to do + // in this root. - if (exitStatus !== RootIncomplete) { - if (exitStatus === RootErrored) { - // If something threw an error, try rendering one more time. We'll - // render synchronously to block concurrent data mutations, and we'll - // render at Idle (or lower) so that all pending updates are included. - // If it still fails after the second attempt, we'll give up and commit - // the resulting tree. - expirationTime = expirationTime > Idle ? Idle : expirationTime; - exitStatus = renderRootSync(root, expirationTime); - } + if (workInProgress !== null) { + var prevExecutionContext = executionContext; + executionContext |= RenderContext; + var prevDispatcher = pushDispatcher(root); + var prevInteractions = pushInteractions(root); + startWorkLoopTimer(workInProgress); - if (exitStatus === RootFatalErrored) { - var fatalError = workInProgressRootFatalError; - prepareFreshStack(root, expirationTime); - markRootSuspendedAtTime(root, expirationTime); - ensureRootIsScheduled(root); - throw fatalError; - } // We now have a consistent tree. The next step is either to commit it, - // or, if something suspended, wait to commit it after a timeout. + do { + try { + workLoopConcurrent(); + break; + } catch (thrownValue) { + handleError(root, thrownValue); + } + } while (true); - var finishedWork = (root.finishedWork = root.current.alternate); - root.finishedExpirationTime = expirationTime; - finishConcurrentRender(root, finishedWork, exitStatus, expirationTime); - } + resetContextDependencies(); + executionContext = prevExecutionContext; + popDispatcher(prevDispatcher); - ensureRootIsScheduled(root); + if (enableSchedulerTracing) { + popInteractions(prevInteractions); + } + + if (workInProgressRootExitStatus === RootFatalErrored) { + var fatalError = workInProgressRootFatalError; + stopInterruptedWorkLoopTimer(); + prepareFreshStack(root, expirationTime); + markRootSuspendedAtTime(root, expirationTime); + ensureRootIsScheduled(root); + throw fatalError; + } + + if (workInProgress !== null) { + // There's still work left over. Exit without committing. + stopInterruptedWorkLoopTimer(); + } else { + // We now have a consistent tree. The next step is either to commit it, + // or, if something suspended, wait to commit it after a timeout. + stopFinishedWorkLoopTimer(); + var finishedWork = (root.finishedWork = root.current.alternate); + root.finishedExpirationTime = expirationTime; + finishConcurrentRender( + root, + finishedWork, + workInProgressRootExitStatus, + expirationTime + ); + } + + ensureRootIsScheduled(root); - if (root.callbackNode === originalCallbackNode) { - // The task node scheduled for this root is the same one that's - // currently executed. Need to return a continuation. - return performConcurrentWorkOnRoot.bind(null, root); + if (root.callbackNode === originalCallbackNode) { + // The task node scheduled for this root is the same one that's + // currently executed. Need to return a continuation. + return performConcurrentWorkOnRoot.bind(null, root); + } + } } return null; @@ -17492,6 +20170,9 @@ function finishConcurrentRender( exitStatus, expirationTime ) { + // Set this to null to indicate there's no in-progress render. + workInProgressRoot = null; + switch (exitStatus) { case RootIncomplete: case RootFatalErrored: { @@ -17504,9 +20185,19 @@ function finishConcurrentRender( // if I do. eslint-disable-next-line no-fallthrough case RootErrored: { - // We should have already attempted to retry this tree. If we reached - // this point, it errored again. Commit it. - commitRoot(root); + // If this was an async render, the error may have happened due to + // a mutation in a concurrent event. Try rendering one more time, + // synchronously, to see if the error goes away. If there are + // lower priority updates, let's include those, too, in case they + // fix the inconsistency. Render at Idle to include all updates. + // If it was Idle or Never or some not-yet-invented time, render + // at that time. + markRootExpiredAtTime( + root, + expirationTime > Idle ? Idle : expirationTime + ); // We assume that this second render pass will be synchronous + // and therefore not hit this path again. + break; } @@ -17516,7 +20207,9 @@ function finishConcurrentRender( if (expirationTime === lastSuspendedTime) { root.nextKnownPendingLevel = getRemainingExpirationTime(finishedWork); - } // We have an acceptable loading state. We need to figure out if we + } + + flushSuspensePriorityWarningInDEV(); // We have an acceptable loading state. We need to figure out if we // should immediately commit it or wait a bit. // If we have processed new updates during this render, we may now // have a new loading state ready. We want to ensure that we commit @@ -17527,7 +20220,7 @@ function finishConcurrentRender( if ( hasNotProcessedNewUpdates && // do not delay if we're inside an act() scope - !IsThisRendererActing.current + !(true && flushSuspenseFallbacksInTests && IsThisRendererActing.current) ) { // If we have not processed any new updates during this pass, then // this is either a retry of an existing fallback state or a @@ -17591,7 +20284,12 @@ function finishConcurrentRender( root.nextKnownPendingLevel = getRemainingExpirationTime(finishedWork); } - { + flushSuspensePriorityWarningInDEV(); + + if ( + // do not delay if we're inside an act() scope + !(true && flushSuspenseFallbacksInTests && IsThisRendererActing.current) + ) { // We're suspended in a state that should be avoided. We'll try to // avoid committing it for as long as the timeouts let us. if (workInProgressRootHasPendingPing) { @@ -17681,6 +20379,11 @@ function finishConcurrentRender( // The work completed. Ready to commit. if ( // do not delay if we're inside an act() scope + !( + true && + flushSuspenseFallbacksInTests && + IsThisRendererActing.current + ) && workInProgressRootLatestProcessedExpirationTime !== Sync && workInProgressRootCanSuspendUsingConfig !== null ) { @@ -17718,67 +20421,149 @@ function finishConcurrentRender( // through Scheduler function performSyncWorkOnRoot(root) { - if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { - throw Error("Should not already be working."); - } - - flushPassiveEffects(); + // Check if there's expired work on this root. Otherwise, render at Sync. var lastExpiredTime = root.lastExpiredTime; - var expirationTime; + var expirationTime = lastExpiredTime !== NoWork ? lastExpiredTime : Sync; + + if (root.finishedExpirationTime === expirationTime) { + // There's already a pending commit at this expiration time. + // TODO: This is poorly factored. This case only exists for the + // batch.commit() API. + commitRoot(root); + } else { + if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { + throw Error("Should not already be working."); + } + + flushPassiveEffects(); // If the root or expiration time have changed, throw out the existing stack + // and prepare a fresh one. Otherwise we'll continue where we left off. - if (lastExpiredTime !== NoWork) { - // There's expired work on this root. Check if we have a partial tree - // that we can reuse. if ( - root === workInProgressRoot && - renderExpirationTime$1 >= lastExpiredTime + root !== workInProgressRoot || + expirationTime !== renderExpirationTime ) { - // There's a partial tree with equal or greater than priority than the - // expired level. Finish rendering it before rendering the rest of the - // expired work. - expirationTime = renderExpirationTime$1; - } else { - // Start a fresh tree. - expirationTime = lastExpiredTime; + prepareFreshStack(root, expirationTime); + startWorkOnPendingInteractions(root, expirationTime); + } // If we have a work-in-progress fiber, it means there's still work to do + // in this root. + + if (workInProgress !== null) { + var prevExecutionContext = executionContext; + executionContext |= RenderContext; + var prevDispatcher = pushDispatcher(root); + var prevInteractions = pushInteractions(root); + startWorkLoopTimer(workInProgress); + + do { + try { + workLoopSync(); + break; + } catch (thrownValue) { + handleError(root, thrownValue); + } + } while (true); + + resetContextDependencies(); + executionContext = prevExecutionContext; + popDispatcher(prevDispatcher); + + if (enableSchedulerTracing) { + popInteractions(prevInteractions); + } + + if (workInProgressRootExitStatus === RootFatalErrored) { + var fatalError = workInProgressRootFatalError; + stopInterruptedWorkLoopTimer(); + prepareFreshStack(root, expirationTime); + markRootSuspendedAtTime(root, expirationTime); + ensureRootIsScheduled(root); + throw fatalError; + } + + if (workInProgress !== null) { + // This is a sync render, so we should have finished the whole tree. + { + throw Error( + "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." + ); + } + } else { + // We now have a consistent tree. Because this is a sync render, we + // will commit it even if something suspended. + stopFinishedWorkLoopTimer(); + root.finishedWork = root.current.alternate; + root.finishedExpirationTime = expirationTime; + finishSyncRender(root, workInProgressRootExitStatus, expirationTime); + } // Before exiting, make sure there's a callback scheduled for the next + // pending level. + + ensureRootIsScheduled(root); } - } else { - // There's no expired work. This must be a new, synchronous render. - expirationTime = Sync; } - var exitStatus = renderRootSync(root, expirationTime); + return null; +} + +function finishSyncRender(root, exitStatus, expirationTime) { + // Set this to null to indicate there's no in-progress render. + workInProgressRoot = null; - if (root.tag !== LegacyRoot && exitStatus === RootErrored) { - // If something threw an error, try rendering one more time. We'll - // render synchronously to block concurrent data mutations, and we'll - // render at Idle (or lower) so that all pending updates are included. - // If it still fails after the second attempt, we'll give up and commit - // the resulting tree. - expirationTime = expirationTime > Idle ? Idle : expirationTime; - exitStatus = renderRootSync(root, expirationTime); + { + if (exitStatus === RootSuspended || exitStatus === RootSuspendedWithDelay) { + flushSuspensePriorityWarningInDEV(); + } } - if (exitStatus === RootFatalErrored) { - var fatalError = workInProgressRootFatalError; - prepareFreshStack(root, expirationTime); - markRootSuspendedAtTime(root, expirationTime); - ensureRootIsScheduled(root); - throw fatalError; - } // We now have a consistent tree. Because this is a sync render, we - // will commit it even if something suspended. + commitRoot(root); +} - root.finishedWork = root.current.alternate; - root.finishedExpirationTime = expirationTime; - commitRoot(root); // Before exiting, make sure there's a callback scheduled for the next - // pending level. +function flushDiscreteUpdates() { + // TODO: Should be able to flush inside batchedUpdates, but not inside `act`. + // However, `act` uses `batchedUpdates`, so there's no way to distinguish + // those two cases. Need to fix this before exposing flushDiscreteUpdates + // as a public API. + if ( + (executionContext & (BatchedContext | RenderContext | CommitContext)) !== + NoContext + ) { + if (true && (executionContext & RenderContext) !== NoContext) { + warning$1( + false, + "unstable_flushDiscreteUpdates: Cannot flush updates when React is " + + "already rendering." + ); + } // We're already rendering, so we can't synchronously flush pending work. + // This is probably a nested event dispatch triggered by a lifecycle/effect, + // like `el.focus()`. Exit. - ensureRootIsScheduled(root); - return null; + return; + } + + flushPendingDiscreteUpdates(); // If the discrete updates scheduled passive effects, flush them now so that + // they fire before the next serial event. + + flushPassiveEffects(); } + function syncUpdates(fn, a, b, c) { return runWithPriority(ImmediatePriority, fn.bind(null, a, b, c)); } +function flushPendingDiscreteUpdates() { + if (rootsWithPendingDiscreteUpdates !== null) { + // For each root with pending discrete updates, schedule a callback to + // immediately flush them. + var roots = rootsWithPendingDiscreteUpdates; + rootsWithPendingDiscreteUpdates = null; + roots.forEach(function(expirationTime, root) { + markRootExpiredAtTime(root, expirationTime); + ensureRootIsScheduled(root); + }); // Now flush the immediate queue. + + flushSyncCallbackQueue(); + } +} + function batchedUpdates$1(fn, a) { var prevExecutionContext = executionContext; executionContext |= BatchedContext; @@ -17794,6 +20579,38 @@ function batchedUpdates$1(fn, a) { } } } +function batchedEventUpdates$1(fn, a) { + var prevExecutionContext = executionContext; + executionContext |= EventContext; + + try { + return fn(a); + } finally { + executionContext = prevExecutionContext; + + if (executionContext === NoContext) { + // Flush the immediate callbacks that were scheduled during this batch + flushSyncCallbackQueue(); + } + } +} +function discreteUpdates$1(fn, a, b, c) { + var prevExecutionContext = executionContext; + executionContext |= DiscreteEventContext; + + try { + // Should this + return runWithPriority(UserBlockingPriority, fn.bind(null, a, b, c)); + } finally { + executionContext = prevExecutionContext; + + if (executionContext === NoContext) { + // Flush the immediate callbacks that were scheduled during this batch + flushSyncCallbackQueue(); + } + } +} + function flushSync(fn, a) { if ((executionContext & (RenderContext | CommitContext)) !== NoContext) { { @@ -17840,8 +20657,8 @@ function prepareFreshStack(root, expirationTime) { } workInProgressRoot = root; - workInProgress = createWorkInProgress(root.current, null); - renderExpirationTime$1 = expirationTime; + workInProgress = createWorkInProgress(root.current, null, expirationTime); + renderExpirationTime = expirationTime; workInProgressRootExitStatus = RootIncomplete; workInProgressRootFatalError = null; workInProgressRootLatestProcessedExpirationTime = Sync; @@ -17850,12 +20667,13 @@ function prepareFreshStack(root, expirationTime) { workInProgressRootNextUnprocessedUpdateTime = NoWork; workInProgressRootHasPendingPing = false; - { + if (enableSchedulerTracing) { spawnedWorkDuringRender = null; } { ReactStrictModeWarnings.discardPendingWarnings(); + componentsThatTriggeredHighPriSuspend = null; } } @@ -17864,7 +20682,7 @@ function handleError(root, thrownValue) { try { // Reset module-level state that was set during the render phase. resetContextDependencies(); - resetHooksAfterThrow(); + resetHooks(); resetCurrentFiber(); if (workInProgress === null || workInProgress.return === null) { @@ -17873,14 +20691,7 @@ function handleError(root, thrownValue) { // supposed to capture all errors that weren't caught by an error // boundary. workInProgressRootExitStatus = RootFatalErrored; - workInProgressRootFatalError = thrownValue; // Set `workInProgress` to null. This represents advancing to the next - // sibling, or the parent if there are no siblings. But since the root - // has no siblings nor a parent, we set it to null. Usually this is - // handled by `completeUnitOfWork` or `unwindWork`, but since we're - // interntionally not calling those, we need set it here. - // TODO: Consider calling `unwindWork` to pop the contexts. - - workInProgress = null; + workInProgressRootFatalError = thrownValue; return null; } @@ -17896,7 +20707,7 @@ function handleError(root, thrownValue) { workInProgress.return, workInProgress, thrownValue, - renderExpirationTime$1 + renderExpirationTime ); workInProgress = completeUnitOfWork(workInProgress); } catch (yetAnotherThrownValue) { @@ -17910,8 +20721,8 @@ function handleError(root, thrownValue) { } function pushDispatcher(root) { - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = ContextOnlyDispatcher; if (prevDispatcher === null) { // The React isomorphic package does not include a default dispatcher. @@ -17924,19 +20735,21 @@ function pushDispatcher(root) { } function popDispatcher(prevDispatcher) { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } function pushInteractions(root) { - { + if (enableSchedulerTracing) { var prevInteractions = tracing.__interactionsRef.current; tracing.__interactionsRef.current = root.memoizedInteractions; return prevInteractions; } + + return null; } function popInteractions(prevInteractions) { - { + if (enableSchedulerTracing) { tracing.__interactionsRef.current = prevInteractions; } } @@ -17989,7 +20802,7 @@ function renderDidSuspendDelayIfPossible() { // pending update. // TODO: This should immediately interrupt the current render, instead // of waiting until the next time we yield. - markRootSuspendedAtTime(workInProgressRoot, renderExpirationTime$1); + markRootSuspendedAtTime(workInProgressRoot, renderExpirationTime); markRootUpdatedAtTime( workInProgressRoot, workInProgressRootNextUnprocessedUpdateTime @@ -18024,60 +20837,10 @@ function inferTimeFromExpirationTimeWithSuspenseConfig( // approximate start time from the expiration time by subtracting the timeout // that was added to the event time. var earliestExpirationTimeMs = expirationTimeToMs(expirationTime); - return ( - earliestExpirationTimeMs - - (suspenseConfig.timeoutMs | 0 || LOW_PRIORITY_EXPIRATION) - ); -} - -function renderRootSync(root, expirationTime) { - var prevExecutionContext = executionContext; - executionContext |= RenderContext; - var prevDispatcher = pushDispatcher(); // If the root or expiration time have changed, throw out the existing stack - // and prepare a fresh one. Otherwise we'll continue where we left off. - - if ( - root !== workInProgressRoot || - expirationTime !== renderExpirationTime$1 - ) { - prepareFreshStack(root, expirationTime); - startWorkOnPendingInteractions(root, expirationTime); - } - - var prevInteractions = pushInteractions(root); - startWorkLoopTimer(workInProgress); - - do { - try { - workLoopSync(); - break; - } catch (thrownValue) { - handleError(root, thrownValue); - } - } while (true); - - resetContextDependencies(); - - { - popInteractions(prevInteractions); - } - - executionContext = prevExecutionContext; - popDispatcher(prevDispatcher); - - if (workInProgress !== null) { - // This is a sync render, so we should have finished the whole tree. - { - throw Error( - "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." - ); - } - } - - stopFinishedWorkLoopTimer(); // Set this to null to indicate there's no in-progress render. - - workInProgressRoot = null; - return workInProgressRootExitStatus; + return ( + earliestExpirationTimeMs - + (suspenseConfig.timeoutMs | 0 || LOW_PRIORITY_EXPIRATION) + ); } // The work loop is an extremely hot path. Tell Closure not to inline it. /** @noinline */ @@ -18088,55 +20851,6 @@ function workLoopSync() { workInProgress = performUnitOfWork(workInProgress); } } - -function renderRootConcurrent(root, expirationTime) { - var prevExecutionContext = executionContext; - executionContext |= RenderContext; - var prevDispatcher = pushDispatcher(); // If the root or expiration time have changed, throw out the existing stack - // and prepare a fresh one. Otherwise we'll continue where we left off. - - if ( - root !== workInProgressRoot || - expirationTime !== renderExpirationTime$1 - ) { - prepareFreshStack(root, expirationTime); - startWorkOnPendingInteractions(root, expirationTime); - } - - var prevInteractions = pushInteractions(root); - startWorkLoopTimer(workInProgress); - - do { - try { - workLoopConcurrent(); - break; - } catch (thrownValue) { - handleError(root, thrownValue); - } - } while (true); - - resetContextDependencies(); - - { - popInteractions(prevInteractions); - } - - popDispatcher(prevDispatcher); - executionContext = prevExecutionContext; // Check if the tree has completed. - - if (workInProgress !== null) { - // Still work remaining. - stopInterruptedWorkLoopTimer(); - return RootIncomplete; - } else { - // Completed the tree. - stopFinishedWorkLoopTimer(); // Set this to null to indicate there's no in-progress render. - - workInProgressRoot = null; // Return the final exit status. - - return workInProgressRootExitStatus; - } -} /** @noinline */ function workLoopConcurrent() { @@ -18150,17 +20864,17 @@ function performUnitOfWork(unitOfWork) { // The current, flushed, state of this fiber is the alternate. Ideally // nothing should rely on this, but relying on it here means that we don't // need an additional field on the work in progress. - var current = unitOfWork.alternate; + var current$$1 = unitOfWork.alternate; startWorkTimer(unitOfWork); setCurrentFiber(unitOfWork); var next; - if ((unitOfWork.mode & ProfileMode) !== NoMode) { + if (enableProfilerTimer && (unitOfWork.mode & ProfileMode) !== NoMode) { startProfilerTimer(unitOfWork); - next = beginWork$1(current, unitOfWork, renderExpirationTime$1); + next = beginWork$$1(current$$1, unitOfWork, renderExpirationTime); stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true); } else { - next = beginWork$1(current, unitOfWork, renderExpirationTime$1); + next = beginWork$$1(current$$1, unitOfWork, renderExpirationTime); } resetCurrentFiber(); @@ -18184,18 +20898,21 @@ function completeUnitOfWork(unitOfWork) { // The current, flushed, state of this fiber is the alternate. Ideally // nothing should rely on this, but relying on it here means that we don't // need an additional field on the work in progress. - var current = workInProgress.alternate; + var current$$1 = workInProgress.alternate; var returnFiber = workInProgress.return; // Check if the work completed or if something threw. if ((workInProgress.effectTag & Incomplete) === NoEffect) { setCurrentFiber(workInProgress); var next = void 0; - if ((workInProgress.mode & ProfileMode) === NoMode) { - next = completeWork(current, workInProgress, renderExpirationTime$1); + if ( + !enableProfilerTimer || + (workInProgress.mode & ProfileMode) === NoMode + ) { + next = completeWork(current$$1, workInProgress, renderExpirationTime); } else { startProfilerTimer(workInProgress); - next = completeWork(current, workInProgress, renderExpirationTime$1); // Update render duration assuming we didn't error. + next = completeWork(current$$1, workInProgress, renderExpirationTime); // Update render duration assuming we didn't error. stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false); } @@ -18251,9 +20968,12 @@ function completeUnitOfWork(unitOfWork) { // This fiber did not complete because something threw. Pop values off // the stack without entering the complete phase. If this is a boundary, // capture values if possible. - var _next = unwindWork(workInProgress); // Because this fiber did not complete, don't reset its expiration time. + var _next = unwindWork(workInProgress, renderExpirationTime); // Because this fiber did not complete, don't reset its expiration time. - if ((workInProgress.mode & ProfileMode) !== NoMode) { + if ( + enableProfilerTimer && + (workInProgress.mode & ProfileMode) !== NoMode + ) { // Record the render duration for the fiber that errored. stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false); // Include the time spent working on failed children before continuing. @@ -18316,7 +21036,7 @@ function getRemainingExpirationTime(fiber) { function resetChildExpirationTime(completedWork) { if ( - renderExpirationTime$1 !== Never && + renderExpirationTime !== Never && completedWork.childExpirationTime === Never ) { // The children of this component are hidden. Don't bubble their @@ -18326,7 +21046,7 @@ function resetChildExpirationTime(completedWork) { var newChildExpirationTime = NoWork; // Bubble up the earliest expiration time. - if ((completedWork.mode & ProfileMode) !== NoMode) { + if (enableProfilerTimer && (completedWork.mode & ProfileMode) !== NoMode) { // In profiling mode, resetChildExpirationTime is also used to reset // profiler durations. var actualDuration = completedWork.actualDuration; @@ -18397,16 +21117,7 @@ function commitRoot(root) { } function commitRootImpl(root, renderPriorityLevel) { - do { - // `flushPassiveEffects` will call `flushSyncUpdateQueue` at the end, which - // means `flushPassiveEffects` will sometimes result in additional - // passive effects. So we need to keep flushing in a loop until there are - // no more pending effects. - // TODO: Might be better if `flushPassiveEffects` did not automatically - // flush synchronous work at the end, to avoid factoring hazards like this. - flushPassiveEffects(); - } while (rootWithPendingPassiveEffects !== null); - + flushPassiveEffects(); flushRenderPhaseStrictModeWarningsInDEV(); if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { @@ -18450,7 +21161,8 @@ function commitRootImpl(root, renderPriorityLevel) { // We can reset these now that they are finished. workInProgressRoot = null; workInProgress = null; - renderExpirationTime$1 = NoWork; + renderExpirationTime = NoWork; + } else { } // This indicates that the last root we worked on is not the same one that // we're committing now. This most commonly happens when a suspended root // times out. @@ -18508,7 +21220,7 @@ function commitRootImpl(root, renderPriorityLevel) { stopCommitSnapshotEffectsTimer(); - { + if (enableProfilerTimer) { // Mark the current commit time to be shared by all Profilers in this // batch. This enables them to be grouped later. recordCommitTime(); @@ -18582,7 +21294,7 @@ function commitRootImpl(root, renderPriorityLevel) { requestPaint(); - { + if (enableSchedulerTracing) { popInteractions(prevInteractions); } @@ -18596,7 +21308,7 @@ function commitRootImpl(root, renderPriorityLevel) { startCommitSnapshotEffectsTimer(); stopCommitSnapshotEffectsTimer(); - { + if (enableProfilerTimer) { recordCommitTime(); } @@ -18632,7 +21344,7 @@ function commitRootImpl(root, renderPriorityLevel) { var remainingExpirationTime = root.firstPendingTime; if (remainingExpirationTime !== NoWork) { - { + if (enableSchedulerTracing) { if (spawnedWorkDuringRender !== null) { var expirationTimes = spawnedWorkDuringRender; spawnedWorkDuringRender = null; @@ -18654,7 +21366,7 @@ function commitRootImpl(root, renderPriorityLevel) { legacyErrorBoundariesThatAlreadyFailed = null; } - { + if (enableSchedulerTracing) { if (!rootDidHavePassiveEffects) { // If there are no passive effects, then we can complete the pending interactions. // Otherwise, we'll wait until after the passive effects are flushed. @@ -18708,8 +21420,8 @@ function commitBeforeMutationEffects() { if ((effectTag & Snapshot) !== NoEffect) { setCurrentFiber(nextEffect); recordEffect(); - var current = nextEffect.alternate; - commitBeforeMutationLifeCycles(current, nextEffect); + var current$$1 = nextEffect.alternate; + commitBeforeMutationLifeCycles(current$$1, nextEffect); resetCurrentFiber(); } @@ -18740,10 +21452,10 @@ function commitMutationEffects(root, renderPriorityLevel) { } if (effectTag & Ref) { - var current = nextEffect.alternate; + var current$$1 = nextEffect.alternate; - if (current !== null) { - commitDetachRef(current); + if (current$$1 !== null) { + commitDetachRef(current$$1); } } // The following switch statement is only concerned about placement, // updates, and deletions. To avoid needing to add a case for every possible @@ -18815,8 +21527,8 @@ function commitLayoutEffects(root, committedExpirationTime) { if (effectTag & (Update | Callback)) { recordEffect(); - var current = nextEffect.alternate; - commitLifeCycles(root, current, nextEffect); + var current$$1 = nextEffect.alternate; + commitLifeCycles(root, current$$1, nextEffect, committedExpirationTime); } if (effectTag & Ref) { @@ -18856,40 +21568,36 @@ function flushPassiveEffectsImpl() { var prevExecutionContext = executionContext; executionContext |= CommitContext; - var prevInteractions = pushInteractions(root); - - { - // 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 _effect2 = root.current.firstEffect; - - while (_effect2 !== null) { - { - setCurrentFiber(_effect2); - invokeGuardedCallback(null, commitPassiveHookEffects, null, _effect2); + var prevInteractions = pushInteractions(root); // 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. - if (hasCaughtError()) { - if (!(_effect2 !== null)) { - throw Error("Should be working on an effect."); - } + var effect = root.current.firstEffect; - var _error5 = clearCaughtError(); + while (effect !== null) { + { + setCurrentFiber(effect); + invokeGuardedCallback(null, commitPassiveHookEffects, null, effect); - captureCommitPhaseError(_effect2, _error5); + if (hasCaughtError()) { + if (!(effect !== null)) { + throw Error("Should be working on an effect."); } - resetCurrentFiber(); + var error = clearCaughtError(); + captureCommitPhaseError(effect, error); } - var nextNextEffect = _effect2.nextEffect; // Remove nextEffect pointer to assist GC - - _effect2.nextEffect = null; - _effect2 = nextNextEffect; + resetCurrentFiber(); } + + var nextNextEffect = effect.nextEffect; // Remove nextEffect pointer to assist GC + + effect.nextEffect = null; + effect = nextNextEffect; } - { + if (enableSchedulerTracing) { popInteractions(prevInteractions); finishPendingInteractions(root, expirationTime); } @@ -18991,7 +21699,7 @@ function pingSuspendedRoot(root, thenable, suspendedTime) { pingCache.delete(thenable); } - if (workInProgressRoot === root && renderExpirationTime$1 === suspendedTime) { + if (workInProgressRoot === root && renderExpirationTime === suspendedTime) { // Received a ping at the same priority level at which we're currently // rendering. We might want to restart this render. This should mirror // the logic of whether or not a root suspends once it completes. @@ -19011,7 +21719,7 @@ function pingSuspendedRoot(root, thenable, suspendedTime) { ) { // Restart from the root. Don't need to schedule a ping because // we're already working on this tree. - prepareFreshStack(root, renderExpirationTime$1); + prepareFreshStack(root, renderExpirationTime); } else { // Even though we can't restart right now, we might get an // opportunity later. So we mark this render as having a ping. @@ -19034,6 +21742,13 @@ function pingSuspendedRoot(root, thenable, suspendedTime) { } // Mark the time at which this ping was scheduled. root.lastPingedTime = suspendedTime; + + if (root.finishedExpirationTime === suspendedTime) { + // If there's a pending fallback waiting to commit, throw it away. + root.finishedExpirationTime = NoWork; + root.finishedWork = null; + } + ensureRootIsScheduled(root); schedulePendingInteractions(root, suspendedTime); } @@ -19061,12 +21776,45 @@ function retryTimedOutBoundary(boundaryFiber, retryTime) { schedulePendingInteractions(root, retryTime); } } + +function retryDehydratedSuspenseBoundary(boundaryFiber) { + var suspenseState = boundaryFiber.memoizedState; + var retryTime = NoWork; + + if (suspenseState !== null) { + retryTime = suspenseState.retryTime; + } + + retryTimedOutBoundary(boundaryFiber, retryTime); +} function resolveRetryThenable(boundaryFiber, thenable) { var retryTime = NoWork; // Default var retryCache; - { + if (enableSuspenseServerRenderer) { + switch (boundaryFiber.tag) { + case SuspenseComponent: + retryCache = boundaryFiber.stateNode; + var suspenseState = boundaryFiber.memoizedState; + + if (suspenseState !== null) { + retryTime = suspenseState.retryTime; + } + + break; + + case SuspenseListComponent: + retryCache = boundaryFiber.stateNode; + break; + + default: { + throw Error( + "Pinged unknown suspense boundary type. This is probably a bug in React." + ); + } + } + } else { retryCache = boundaryFiber.stateNode; } @@ -19091,16 +21839,16 @@ function jnd(timeElapsed) { return timeElapsed < 120 ? 120 : timeElapsed < 480 - ? 480 - : timeElapsed < 1080 - ? 1080 - : timeElapsed < 1920 - ? 1920 - : timeElapsed < 3000 - ? 3000 - : timeElapsed < 4320 - ? 4320 - : ceil(timeElapsed / 1960) * 1960; + ? 480 + : timeElapsed < 1080 + ? 1080 + : timeElapsed < 1920 + ? 1920 + : timeElapsed < 3000 + ? 3000 + : timeElapsed < 4320 + ? 4320 + : ceil(timeElapsed / 1960) * 1960; } function computeMsUntilSuspenseLoadingDelay( @@ -19149,8 +21897,8 @@ function checkForNestedUpdates() { { if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) { nestedPassiveUpdateCount = 0; - - error( + warning$1( + false, "Maximum update depth exceeded. This can happen when a component " + "calls setState inside useEffect, but useEffect either doesn't " + "have a dependency array, or one of the dependencies changes on " + @@ -19164,7 +21912,7 @@ function flushRenderPhaseStrictModeWarningsInDEV() { { ReactStrictModeWarnings.flushLegacyContextWarning(); - { + if (warnAboutDeprecatedLifecycles) { ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings(); } } @@ -19185,8 +21933,9 @@ function stopInterruptedWorkLoopTimer() { function checkForInterruption(fiberThatReceivedUpdate, updateExpirationTime) { if ( + enableUserTimingAPI && workInProgressRoot !== null && - updateExpirationTime > renderExpirationTime$1 + updateExpirationTime > renderExpirationTime ) { interruptedBy = fiberThatReceivedUpdate; } @@ -19204,12 +21953,11 @@ function warnAboutUpdateOnUnmountedFiberInDEV(fiber) { tag !== FunctionComponent && tag !== ForwardRef && tag !== MemoComponent && - tag !== SimpleMemoComponent && - tag !== Block + tag !== SimpleMemoComponent ) { // Only warn for user-defined components, not internal ones like Suspense. return; - } + } // We show the whole stack but dedupe on the top component's name because // the problematic code almost always lies inside that component. var componentName = getComponentName(fiber.type) || "ReactComponent"; @@ -19224,7 +21972,8 @@ function warnAboutUpdateOnUnmountedFiberInDEV(fiber) { didWarnStateUpdateForUnmountedComponent = new Set([componentName]); } - error( + warningWithoutStack$1( + false, "Can't perform a React state update on an unmounted component. This " + "is a no-op, but it indicates a memory leak in your application. To " + "fix, cancel all subscriptions and asynchronous tasks in %s.%s", @@ -19236,12 +21985,12 @@ function warnAboutUpdateOnUnmountedFiberInDEV(fiber) { } } -var beginWork$1; +var beginWork$$1; -{ +if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) { var dummyFiber = null; - beginWork$1 = function(current, unitOfWork, expirationTime) { + beginWork$$1 = function(current$$1, unitOfWork, expirationTime) { // If a component throws an error, we replay it again in a synchronously // dispatched event, so that the debugger will treat it as an uncaught // error See ReactErrorUtils for more information. @@ -19253,7 +22002,7 @@ var beginWork$1; ); try { - return beginWork(current, unitOfWork, expirationTime); + return beginWork$1(current$$1, unitOfWork, expirationTime); } catch (originalError) { if ( originalError !== null && @@ -19266,7 +22015,7 @@ var beginWork$1; // corresponding changes there. resetContextDependencies(); - resetHooksAfterThrow(); // Don't reset current debug fiber, since we're about to work on the + resetHooks(); // Don't reset current debug fiber, since we're about to work on the // same fiber again. // Unwind the failed stack frame @@ -19274,16 +22023,16 @@ var beginWork$1; assignFiberPropertiesInDEV(unitOfWork, originalWorkInProgressCopy); - if (unitOfWork.mode & ProfileMode) { + if (enableProfilerTimer && unitOfWork.mode & ProfileMode) { // Reset the profiler timer. startProfilerTimer(unitOfWork); } // Run beginWork again. invokeGuardedCallback( null, - beginWork, + beginWork$1, null, - current, + current$$1, unitOfWork, expirationTime ); @@ -19299,37 +22048,42 @@ var beginWork$1; } } }; +} else { + beginWork$$1 = beginWork$1; } var didWarnAboutUpdateInRender = false; +var didWarnAboutUpdateInGetChildContext = false; -function warnAboutRenderPhaseUpdatesInDEV(fiber) { +function warnAboutInvalidUpdatesOnClassComponentsInDEV(fiber) { { - if ((executionContext & RenderContext) !== NoContext) { - switch (fiber.tag) { - case FunctionComponent: - case ForwardRef: - case SimpleMemoComponent: { - error( - "Cannot update a component from inside the function body of a " + - "different component." - ); + if (fiber.tag === ClassComponent) { + switch (phase) { + case "getChildContext": + if (didWarnAboutUpdateInGetChildContext) { + return; + } + warningWithoutStack$1( + false, + "setState(...): Cannot call setState() inside getChildContext()" + ); + didWarnAboutUpdateInGetChildContext = true; break; - } - - case ClassComponent: { - if (isRendering && !didWarnAboutUpdateInRender) { - error( - "Cannot update during an existing state transition (such as " + - "within `render`). Render methods should be a pure " + - "function of props and state." - ); - didWarnAboutUpdateInRender = true; - break; + case "render": + if (didWarnAboutUpdateInRender) { + return; } - } + + warningWithoutStack$1( + false, + "Cannot update during an existing state transition (such as " + + "within `render`). Render methods should be a pure function of " + + "props and state." + ); + didWarnAboutUpdateInRender = true; + break; } } } @@ -19341,20 +22095,20 @@ var IsThisRendererActing = { function warnIfNotScopedWithMatchingAct(fiber) { { if ( + warnsIfNotActing === true && IsSomeRendererActing.current === true && IsThisRendererActing.current !== true ) { - error( + warningWithoutStack$1( + false, "It looks like you're using the wrong act() around your test interactions.\n" + - "Be sure to use the matching version of act() corresponding to your renderer:\n\n" + - "// for react-dom:\n" + // Break up imports to avoid accidentally parsing them as dependencies. - "import {act} fr" + - "om 'react-dom/test-utils';\n" + - "// ...\n" + - "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" + + "Be sure to use the matching version of act() corresponding to your renderer:\n\n" + + "// for react-dom:\n" + + "import {act} from 'react-dom/test-utils';\n" + + "// ...\n" + + "act(() => ...);\n\n" + + "// for react-test-renderer:\n" + + "import TestRenderer from 'react-test-renderer';\n" + "const {act} = TestRenderer;\n" + "// ...\n" + "act(() => ...);" + @@ -19367,11 +22121,13 @@ function warnIfNotScopedWithMatchingAct(fiber) { function warnIfNotCurrentlyActingEffectsInDEV(fiber) { { if ( + warnsIfNotActing === true && (fiber.mode & StrictMode) !== NoMode && IsSomeRendererActing.current === false && IsThisRendererActing.current === false ) { - error( + warningWithoutStack$1( + false, "An update to %s ran an effect, but was not wrapped in act(...).\n\n" + "When testing, code that causes React state updates should be " + "wrapped into act(...):\n\n" + @@ -19393,11 +22149,13 @@ function warnIfNotCurrentlyActingEffectsInDEV(fiber) { function warnIfNotCurrentlyActingUpdatesInDEV(fiber) { { if ( + warnsIfNotActing === true && executionContext === NoContext && IsSomeRendererActing.current === false && IsThisRendererActing.current === false ) { - error( + warningWithoutStack$1( + false, "An update to %s inside a test was not wrapped in act(...).\n\n" + "When testing, code that causes React state updates should be " + "wrapped into act(...):\n\n" + @@ -19431,30 +22189,161 @@ function warnIfUnmockedScheduler(fiber) { ) { if (fiber.mode & BlockingMode || fiber.mode & ConcurrentMode) { didWarnAboutUnmockedScheduler = true; - - error( + warningWithoutStack$1( + false, 'In Concurrent or Sync modes, the "scheduler" module needs to be mocked ' + - "to guarantee consistent behaviour across tests and browsers. " + - "For example, with jest: \n" + // Break up requires to avoid accidentally parsing them as dependencies. - "jest.mock('scheduler', () => require" + - "('scheduler/unstable_mock'));\n\n" + + "to guarantee consistent behaviour across tests and browsers. " + + "For example, with jest: \n" + + "jest.mock('scheduler', () => require('scheduler/unstable_mock'));\n\n" + "For more info, visit https://fb.me/react-mock-scheduler" ); - } else { + } else if (warnAboutUnmockedScheduler === true) { didWarnAboutUnmockedScheduler = true; - - error( + warningWithoutStack$1( + false, 'Starting from React v17, the "scheduler" module will need to be mocked ' + - "to guarantee consistent behaviour across tests and browsers. " + - "For example, with jest: \n" + // Break up requires to avoid accidentally parsing them as dependencies. - "jest.mock('scheduler', () => require" + - "('scheduler/unstable_mock'));\n\n" + + "to guarantee consistent behaviour across tests and browsers. " + + "For example, with jest: \n" + + "jest.mock('scheduler', () => require('scheduler/unstable_mock'));\n\n" + "For more info, visit https://fb.me/react-mock-scheduler" ); } } } } +var componentsThatTriggeredHighPriSuspend = null; +function checkForWrongSuspensePriorityInDEV(sourceFiber) { + { + var currentPriorityLevel = getCurrentPriorityLevel(); + + if ( + (sourceFiber.mode & ConcurrentMode) !== NoEffect && + (currentPriorityLevel === UserBlockingPriority || + currentPriorityLevel === ImmediatePriority) + ) { + var workInProgressNode = sourceFiber; + + while (workInProgressNode !== null) { + // Add the component that triggered the suspense + var current$$1 = workInProgressNode.alternate; + + if (current$$1 !== null) { + // TODO: warn component that triggers the high priority + // suspend is the HostRoot + switch (workInProgressNode.tag) { + case ClassComponent: + // Loop through the component's update queue and see whether the component + // has triggered any high priority updates + var updateQueue = current$$1.updateQueue; + + if (updateQueue !== null) { + var update = updateQueue.firstUpdate; + + while (update !== null) { + var priorityLevel = update.priority; + + if ( + priorityLevel === UserBlockingPriority || + priorityLevel === ImmediatePriority + ) { + if (componentsThatTriggeredHighPriSuspend === null) { + componentsThatTriggeredHighPriSuspend = new Set([ + getComponentName(workInProgressNode.type) + ]); + } else { + componentsThatTriggeredHighPriSuspend.add( + getComponentName(workInProgressNode.type) + ); + } + + break; + } + + update = update.next; + } + } + + break; + + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: + if ( + workInProgressNode.memoizedState !== null && + workInProgressNode.memoizedState.baseUpdate !== null + ) { + var _update = workInProgressNode.memoizedState.baseUpdate; // Loop through the functional component's memoized state to see whether + // the component has triggered any high pri updates + + while (_update !== null) { + var priority = _update.priority; + + if ( + priority === UserBlockingPriority || + priority === ImmediatePriority + ) { + if (componentsThatTriggeredHighPriSuspend === null) { + componentsThatTriggeredHighPriSuspend = new Set([ + getComponentName(workInProgressNode.type) + ]); + } else { + componentsThatTriggeredHighPriSuspend.add( + getComponentName(workInProgressNode.type) + ); + } + + break; + } + + if ( + _update.next === workInProgressNode.memoizedState.baseUpdate + ) { + break; + } + + _update = _update.next; + } + } + + break; + + default: + break; + } + } + + workInProgressNode = workInProgressNode.return; + } + } + } +} + +function flushSuspensePriorityWarningInDEV() { + { + if (componentsThatTriggeredHighPriSuspend !== null) { + var componentNames = []; + componentsThatTriggeredHighPriSuspend.forEach(function(name) { + return componentNames.push(name); + }); + componentsThatTriggeredHighPriSuspend = null; + + if (componentNames.length > 0) { + warningWithoutStack$1( + false, + "%s triggered a user-blocking update that suspended." + + "\n\n" + + "The fix is to split the update into multiple parts: a user-blocking " + + "update to provide immediate feedback, and another update that " + + "triggers the bulk of the changes." + + "\n\n" + + "Refer to the documentation for useTransition to learn how " + + "to implement this pattern.", // TODO: Add link to React docs with more information, once it exists + componentNames.sort().join(", ") + ); + } + } + } +} function computeThreadID(root, expirationTime) { // Interaction threads are unique per root and expiration time. @@ -19462,6 +22351,10 @@ function computeThreadID(root, expirationTime) { } function markSpawnedWork(expirationTime) { + if (!enableSchedulerTracing) { + return; + } + if (spawnedWorkDuringRender === null) { spawnedWorkDuringRender = [expirationTime]; } else { @@ -19470,6 +22363,10 @@ function markSpawnedWork(expirationTime) { } function scheduleInteractions(root, expirationTime, interactions) { + if (!enableSchedulerTracing) { + return; + } + if (interactions.size > 0) { var pendingInteractionMap = root.pendingInteractionMap; var pendingInteractions = pendingInteractionMap.get(expirationTime); @@ -19501,10 +22398,21 @@ function scheduleInteractions(root, expirationTime, interactions) { } function schedulePendingInteractions(root, expirationTime) { + // This is called when work is scheduled on a root. + // It associates the current interactions with the newly-scheduled expiration. + // They will be restored when that expiration is later committed. + if (!enableSchedulerTracing) { + return; + } + scheduleInteractions(root, expirationTime, tracing.__interactionsRef.current); } function startWorkOnPendingInteractions(root, expirationTime) { + // This is called when new work is started on a root. + if (!enableSchedulerTracing) { + return; + } // Determine which interactions this batch of work currently includes, So that // we can accurately attribute time spent working on it, And so that cascading // work triggered during the render phase will be associated with it. @@ -19545,6 +22453,10 @@ function startWorkOnPendingInteractions(root, expirationTime) { } function finishPendingInteractions(root, committedExpirationTime) { + if (!enableSchedulerTracing) { + return; + } + var earliestRemainingTimeAfterCommit = root.firstPendingTime; var subscriber; @@ -19593,7 +22505,6 @@ function finishPendingInteractions(root, committedExpirationTime) { } } -var onScheduleFiberRoot = null; var onCommitFiberRoot = null; var onCommitFiberUnmount = null; var hasLoggedError = false; @@ -19615,7 +22526,8 @@ function injectInternals(internals) { if (!hook.supportsFiber) { { - error( + warningWithoutStack$1( + false, "The installed version of React DevTools is too old and will not work " + "with the current version of React. Please update React DevTools. " + "https://fb.me/react-devtools" @@ -19628,23 +22540,6 @@ function injectInternals(internals) { try { var rendererID = hook.inject(internals); // We have successfully injected, so now it is safe to set up hooks. - if (true) { - // Only used by Fast Refresh - if (typeof hook.onScheduleFiberRoot === "function") { - onScheduleFiberRoot = function(root, children) { - try { - hook.onScheduleFiberRoot(rendererID, root, children); - } catch (err) { - if (true && !hasLoggedError) { - hasLoggedError = true; - - error("React instrumentation encountered an error: %s", err); - } - } - }; - } - } - onCommitFiberRoot = function(root, expirationTime) { try { var didError = (root.current.effectTag & DidCapture) === DidCapture; @@ -19660,12 +22555,13 @@ function injectInternals(internals) { hook.onCommitFiberRoot(rendererID, root, undefined, didError); } } catch (err) { - if (true) { - if (!hasLoggedError) { - hasLoggedError = true; - - error("React instrumentation encountered an error: %s", err); - } + if (true && !hasLoggedError) { + hasLoggedError = true; + warningWithoutStack$1( + false, + "React DevTools encountered an error: %s", + err + ); } } }; @@ -19674,29 +22570,29 @@ function injectInternals(internals) { try { hook.onCommitFiberUnmount(rendererID, fiber); } catch (err) { - if (true) { - if (!hasLoggedError) { - hasLoggedError = true; - - error("React instrumentation encountered an error: %s", err); - } + if (true && !hasLoggedError) { + hasLoggedError = true; + warningWithoutStack$1( + false, + "React DevTools encountered an error: %s", + err + ); } } }; } catch (err) { // Catch all errors because it is unsafe to throw during initialization. { - error("React instrumentation encountered an error: %s.", err); + warningWithoutStack$1( + false, + "React DevTools encountered an error: %s.", + err + ); } } // DevTools exists return true; } -function onScheduleRoot(root, children) { - if (typeof onScheduleFiberRoot === "function") { - onScheduleFiberRoot(root, children); - } -} function onCommitRoot(root, expirationTime) { if (typeof onCommitFiberRoot === "function") { onCommitFiberRoot(root, expirationTime); @@ -19758,7 +22654,7 @@ function FiberNode(tag, pendingProps, key, mode) { this.childExpirationTime = NoWork; this.alternate = null; - { + if (enableProfilerTimer) { // Note: The following is done to avoid a v8 performance cliff. // // Initializing the fields below to smis and later updating them with @@ -19785,7 +22681,7 @@ function FiberNode(tag, pendingProps, key, mode) { } // This is normally DEV-only except www when it adds listeners. // TODO: remove the User Timing integration in favor of Root Events. - { + if (enableUserTimingAPI) { this._debugID = debugCounter++; this._debugIsCurrentlyTiming = false; } @@ -19849,7 +22745,7 @@ function resolveLazyComponentTag(Component) { return IndeterminateComponent; } // This is used to create an alternate fiber to do work on. -function createWorkInProgress(current, pendingProps) { +function createWorkInProgress(current, pendingProps, expirationTime) { var workInProgress = current.alternate; if (workInProgress === null) { @@ -19870,10 +22766,7 @@ function createWorkInProgress(current, pendingProps) { { // DEV-only fields - { - workInProgress._debugID = current._debugID; - } - + workInProgress._debugID = current._debugID; workInProgress._debugSource = current._debugSource; workInProgress._debugOwner = current._debugOwner; workInProgress._debugHookTypes = current._debugHookTypes; @@ -19891,7 +22784,7 @@ function createWorkInProgress(current, pendingProps) { workInProgress.firstEffect = null; workInProgress.lastEffect = null; - { + if (enableProfilerTimer) { // We intentionally reset, rather than copy, actualDuration & actualStartTime. // This prevents time from endlessly accumulating in new commits. // This has the downside of resetting values for different priority renders, @@ -19901,19 +22794,6 @@ function createWorkInProgress(current, pendingProps) { } } - { - // Trying to debug a mysterious internal-only production failure. - // See D20130868 and t62461245. - // This is only on for RN FB builds. - if (current == null) { - throw Error("current is " + current + " but it can't be"); - } - - if (workInProgress == null) { - throw Error("workInProgress is " + workInProgress + " but it can't be"); - } - } - workInProgress.childExpirationTime = current.childExpirationTime; workInProgress.expirationTime = current.expirationTime; workInProgress.child = current.child; @@ -19936,7 +22816,7 @@ function createWorkInProgress(current, pendingProps) { workInProgress.index = current.index; workInProgress.ref = current.ref; - { + if (enableProfilerTimer) { workInProgress.selfBaseDuration = current.selfBaseDuration; workInProgress.treeBaseDuration = current.treeBaseDuration; } @@ -19958,6 +22838,9 @@ function createWorkInProgress(current, pendingProps) { case ForwardRef: workInProgress.type = resolveForwardRefForHotReloading(current.type); break; + + default: + break; } } @@ -19990,7 +22873,7 @@ function resetWorkInProgress(workInProgress, renderExpirationTime) { workInProgress.updateQueue = null; workInProgress.dependencies = null; - { + if (enableProfilerTimer) { // Note: We don't reset the actualTime counts. It's useful to accumulate // actual time across multiple render passes. workInProgress.selfBaseDuration = 0; @@ -20016,7 +22899,7 @@ function resetWorkInProgress(workInProgress, renderExpirationTime) { responders: currentDependencies.responders }; - { + if (enableProfilerTimer) { // Note: We don't reset the actualTime counts. It's useful to accumulate // actual time across multiple render passes. workInProgress.selfBaseDuration = current.selfBaseDuration; @@ -20037,7 +22920,7 @@ function createHostRootFiber(tag) { mode = NoMode; } - if (isDevToolsPresent) { + if (enableProfilerTimer && isDevToolsPresent) { // Always collect profile timings when DevTools are present. // This enables DevTools to start capturing timing at any point– // Without some nodes in the tree having empty base times. @@ -20137,9 +23020,29 @@ function createFiberFromTypeAndProps( resolvedType = null; break getTag; - case REACT_BLOCK_TYPE: - fiberTag = Block; - break getTag; + case REACT_FUNDAMENTAL_TYPE: + if (enableFundamentalAPI) { + return createFiberFromFundamental( + type, + pendingProps, + mode, + expirationTime, + key + ); + } + + break; + + case REACT_SCOPE_TYPE: + if (enableScopeAPI) { + return createFiberFromScope( + type, + pendingProps, + mode, + expirationTime, + key + ); + } } } @@ -20214,11 +23117,38 @@ function createFiberFromFragment(elements, mode, expirationTime, key) { fiber.expirationTime = expirationTime; return fiber; } +function createFiberFromFundamental( + fundamentalComponent, + pendingProps, + mode, + expirationTime, + key +) { + var fiber = createFiber(FundamentalComponent, pendingProps, key, mode); + fiber.elementType = fundamentalComponent; + fiber.type = fundamentalComponent; + fiber.expirationTime = expirationTime; + return fiber; +} + +function createFiberFromScope(scope, pendingProps, mode, expirationTime, key) { + var fiber = createFiber(ScopeComponent, pendingProps, key, mode); + fiber.type = scope; + fiber.elementType = scope; + fiber.expirationTime = expirationTime; + return fiber; +} function createFiberFromProfiler(pendingProps, mode, expirationTime, key) { { - if (typeof pendingProps.id !== "string") { - error('Profiler must specify an "id" as a prop'); + if ( + typeof pendingProps.id !== "string" || + typeof pendingProps.onRender !== "function" + ) { + warningWithoutStack$1( + false, + 'Profiler must specify an "id" string and "onRender" function as props' + ); } } @@ -20227,14 +23157,6 @@ function createFiberFromProfiler(pendingProps, mode, expirationTime, key) { fiber.elementType = REACT_PROFILER_TYPE; fiber.type = REACT_PROFILER_TYPE; fiber.expirationTime = expirationTime; - - { - fiber.stateNode = { - effectDuration: 0, - passiveEffectDuration: 0 - }; - } - return fiber; } @@ -20267,6 +23189,18 @@ function createFiberFromText(content, mode, expirationTime) { fiber.expirationTime = expirationTime; return fiber; } +function createFiberFromHostInstanceForDeletion() { + var fiber = createFiber(HostComponent, null, null, NoMode); // TODO: These should not need a type. + + fiber.elementType = "DELETED"; + fiber.type = "DELETED"; + return fiber; +} +function createFiberFromDehydratedFragment(dehydratedNode) { + var fiber = createFiber(DehydratedFragment, null, null, NoMode); + fiber.stateNode = dehydratedNode; + return fiber; +} function createFiberFromPortal(portal, mode, expirationTime) { var pendingProps = portal.children !== null ? portal.children : []; var fiber = createFiber(HostPortal, pendingProps, portal.key, mode); @@ -20315,20 +23249,17 @@ function assignFiberPropertiesInDEV(target, source) { target.childExpirationTime = source.childExpirationTime; target.alternate = source.alternate; - { + if (enableProfilerTimer) { target.actualDuration = source.actualDuration; target.actualStartTime = source.actualStartTime; target.selfBaseDuration = source.selfBaseDuration; target.treeBaseDuration = source.treeBaseDuration; } - { - target._debugID = source._debugID; - target._debugIsCurrentlyTiming = source._debugIsCurrentlyTiming; - } - + target._debugID = source._debugID; target._debugSource = source._debugSource; target._debugOwner = source._debugOwner; + target._debugIsCurrentlyTiming = source._debugIsCurrentlyTiming; target._debugNeedsRemount = source._debugNeedsRemount; target._debugHookTypes = source._debugHookTypes; return target; @@ -20355,21 +23286,28 @@ function FiberRootNode(containerInfo, tag, hydrate) { this.lastPingedTime = NoWork; this.lastExpiredTime = NoWork; - { + if (enableSchedulerTracing) { this.interactionThreadID = tracing.unstable_getThreadID(); this.memoizedInteractions = new Set(); this.pendingInteractionMap = new Map(); } + + if (enableSuspenseCallback) { + this.hydrationCallbacks = null; + } } function createFiberRoot(containerInfo, tag, hydrate, hydrationCallbacks) { var root = new FiberRootNode(containerInfo, tag, hydrate); + + if (enableSuspenseCallback) { + root.hydrationCallbacks = hydrationCallbacks; + } // Cyclic construction. This cheats the type system right now because // stateNode is any. var uninitializedFiber = createHostRootFiber(tag); root.current = uninitializedFiber; uninitializedFiber.stateNode = root; - initializeUpdateQueue(uninitializedFiber); return root; } function isRootSuspendedAtTime(root, expirationTime) { @@ -20463,6 +23401,15 @@ function markRootExpiredAtTime(root, expirationTime) { } } +// This lets us hook into Fiber to debug what it's doing. +// See https://github.com/facebook/react/pull/8033. +// This is not part of the public API, not even for React DevTools. +// You may only inject a debugTool if you work on React Fiber itself. +var ReactFiberInstrumentation = { + debugTool: null +}; +var ReactFiberInstrumentation_1 = ReactFiberInstrumentation; + var didWarnAboutNestedUpdates; var didWarnAboutFindNodeInStrictMode; @@ -20479,15 +23426,42 @@ function getContextForSubtree(parentComponent) { var fiber = get(parentComponent); var parentContext = findCurrentUnmaskedContext(fiber); - if (fiber.tag === ClassComponent) { - var Component = fiber.type; + if (fiber.tag === ClassComponent) { + var Component = fiber.type; + + if (isContextProvider(Component)) { + return processChildContext(fiber, Component, parentContext); + } + } + + return parentContext; +} + +function findHostInstance(component) { + var fiber = get(component); + + if (fiber === undefined) { + if (typeof component.render === "function") { + { + throw Error("Unable to find node on an unmounted component."); + } + } else { + { + throw Error( + "Argument appears to not be a ReactComponent. Keys: " + + Object.keys(component) + ); + } + } + } + + var hostFiber = findCurrentHostFiber(fiber); - if (isContextProvider(Component)) { - return processChildContext(fiber, Component, parentContext); - } + if (hostFiber === null) { + return null; } - return parentContext; + return hostFiber.stateNode; } function findHostInstanceWithWarning(component, methodName) { @@ -20522,7 +23496,8 @@ function findHostInstanceWithWarning(component, methodName) { didWarnAboutFindNodeInStrictMode[componentName] = true; if (fiber.mode & StrictMode) { - error( + warningWithoutStack$1( + false, "%s is deprecated in StrictMode. " + "%s was passed an instance of %s which is inside StrictMode. " + "Instead, add a ref directly to the element you want to reference. " + @@ -20534,7 +23509,8 @@ function findHostInstanceWithWarning(component, methodName) { getStackByFiberInDevAndProd(hostFiber) ); } else { - error( + warningWithoutStack$1( + false, "%s is deprecated in StrictMode. " + "%s was passed an instance of %s which renders StrictMode children. " + "Instead, add a ref directly to the element you want to reference. " + @@ -20551,33 +23527,44 @@ function findHostInstanceWithWarning(component, methodName) { return hostFiber.stateNode; } + + return findHostInstance(component); } function createContainer(containerInfo, tag, hydrate, hydrationCallbacks) { - return createFiberRoot(containerInfo, tag, hydrate); + return createFiberRoot(containerInfo, tag, hydrate, hydrationCallbacks); } function updateContainer(element, container, parentComponent, callback) { - { - onScheduleRoot(container, element); - } - - var current$1 = container.current; + var current$$1 = container.current; var currentTime = requestCurrentTimeForUpdate(); { // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests if ("undefined" !== typeof jest) { - warnIfUnmockedScheduler(current$1); - warnIfNotScopedWithMatchingAct(current$1); + warnIfUnmockedScheduler(current$$1); + warnIfNotScopedWithMatchingAct(current$$1); } } var suspenseConfig = requestCurrentSuspenseConfig(); var expirationTime = computeExpirationForFiber( currentTime, - current$1, + current$$1, suspenseConfig ); + + { + if (ReactFiberInstrumentation_1.debugTool) { + if (current$$1.alternate === null) { + ReactFiberInstrumentation_1.debugTool.onMountContainer(container); + } else if (element === null) { + ReactFiberInstrumentation_1.debugTool.onUnmountContainer(container); + } else { + ReactFiberInstrumentation_1.debugTool.onUpdateContainer(container); + } + } + } + var context = getContextForSubtree(parentComponent); if (container.context === null) { @@ -20587,10 +23574,10 @@ function updateContainer(element, container, parentComponent, callback) { } { - if (isRendering && current !== null && !didWarnAboutNestedUpdates) { + if (phase === "render" && current !== null && !didWarnAboutNestedUpdates) { didWarnAboutNestedUpdates = true; - - error( + warningWithoutStack$1( + false, "Render methods should be a pure function of props and state; " + "triggering nested component updates from render is not allowed. " + "If necessary, trigger nested updates in componentDidUpdate.\n\n" + @@ -20609,21 +23596,19 @@ function updateContainer(element, container, parentComponent, callback) { callback = callback === undefined ? null : callback; if (callback !== null) { - { - if (typeof callback !== "function") { - error( + !(typeof callback === "function") + ? warningWithoutStack$1( + false, "render(...): Expected the last optional `callback` argument to be a " + "function. Instead received: %s.", callback - ); - } - } - + ) + : void 0; update.callback = callback; } - enqueueUpdate(current$1, update); - scheduleWork(current$1, expirationTime); + enqueueUpdate(current$$1, update); + scheduleWork(current$$1, expirationTime); return expirationTime; } function getPublicRootInstance(container) { @@ -20646,145 +23631,699 @@ var shouldSuspendImpl = function(fiber) { return false; }; -function shouldSuspend(fiber) { - return shouldSuspendImpl(fiber); -} -var overrideHookState = null; -var overrideProps = null; -var scheduleUpdate = null; -var setSuspenseHandler = null; +function shouldSuspend(fiber) { + return shouldSuspendImpl(fiber); +} +var overrideHookState = null; +var overrideProps = null; +var scheduleUpdate = null; +var setSuspenseHandler = null; + +{ + var copyWithSetImpl = function(obj, path, idx, value) { + if (idx >= path.length) { + return value; + } + + var key = path[idx]; + var updated = Array.isArray(obj) ? obj.slice() : Object.assign({}, obj); // $FlowFixMe number or string is fine here + + updated[key] = copyWithSetImpl(obj[key], path, idx + 1, value); + return updated; + }; + + var copyWithSet = function(obj, path, value) { + return copyWithSetImpl(obj, path, 0, value); + }; // Support DevTools editable values for useState and useReducer. + + overrideHookState = function(fiber, id, path, value) { + // For now, the "id" of stateful hooks is just the stateful hook index. + // This may change in the future with e.g. nested hooks. + var currentHook = fiber.memoizedState; + + while (currentHook !== null && id > 0) { + currentHook = currentHook.next; + id--; + } + + if (currentHook !== null) { + var newState = copyWithSet(currentHook.memoizedState, path, value); + currentHook.memoizedState = newState; + currentHook.baseState = newState; // We aren't actually adding an update to the queue, + // because there is no update we can add for useReducer hooks that won't trigger an error. + // (There's no appropriate action type for DevTools overrides.) + // As a result though, React will see the scheduled update as a noop and bailout. + // Shallow cloning props works as a workaround for now to bypass the bailout check. + + fiber.memoizedProps = Object.assign({}, fiber.memoizedProps); + scheduleWork(fiber, Sync); + } + }; // Support DevTools props for function components, forwardRef, memo, host components, etc. + + overrideProps = function(fiber, path, value) { + fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value); + + if (fiber.alternate) { + fiber.alternate.pendingProps = fiber.pendingProps; + } + + scheduleWork(fiber, Sync); + }; + + scheduleUpdate = function(fiber) { + scheduleWork(fiber, Sync); + }; + + setSuspenseHandler = function(newShouldSuspendImpl) { + shouldSuspendImpl = newShouldSuspendImpl; + }; +} + +function injectIntoDevTools(devToolsConfig) { + var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance; + var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher; + return injectInternals( + Object.assign({}, devToolsConfig, { + overrideHookState: overrideHookState, + overrideProps: overrideProps, + setSuspenseHandler: setSuspenseHandler, + scheduleUpdate: scheduleUpdate, + currentDispatcherRef: ReactCurrentDispatcher, + findHostInstanceByFiber: function(fiber) { + var hostFiber = findCurrentHostFiber(fiber); + + if (hostFiber === null) { + return null; + } + + return hostFiber.stateNode; + }, + findFiberByHostInstance: function(instance) { + if (!findFiberByHostInstance) { + // Might not be implemented by the renderer. + return null; + } + + return findFiberByHostInstance(instance); + }, + // React Refresh + findHostInstancesForRefresh: findHostInstancesForRefresh, + scheduleRefresh: scheduleRefresh, + scheduleRoot: scheduleRoot, + setRefreshHandler: setRefreshHandler, + // Enables DevTools to append owner stacks to error messages in DEV mode. + getCurrentFiber: function() { + return current; + } + }) + ); +} + +// This file intentionally does *not* have the Flow annotation. +// Don't add it. See `./inline-typed.js` for an explanation. + +function createPortal( + children, + containerInfo, // TODO: figure out the API for cross-renderer implementation. + implementation +) { + var key = + arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null; + return { + // This tag allow us to uniquely identify this as a React Portal + $$typeof: REACT_PORTAL_TYPE, + key: key == null ? null : "" + key, + children: children, + containerInfo: containerInfo, + implementation: implementation + }; +} + +// TODO: this is special because it gets imported during build. + +var ReactVersion = "16.11.0"; + +var NativeMethodsMixin = function(findNodeHandle, findHostInstance) { + /** + * `NativeMethodsMixin` provides methods to access the underlying native + * component directly. This can be useful in cases when you want to focus + * a view or measure its on-screen dimensions, for example. + * + * The methods described here are available on most of the default components + * provided by React Native. Note, however, that they are *not* available on + * composite components that aren't directly backed by a native view. This will + * generally include most components that you define in your own app. For more + * information, see [Direct + * Manipulation](docs/direct-manipulation.html). + * + * Note the Flow $Exact<> syntax is required to support mixins. + * React createClass mixins can only be used with exact types. + */ + var NativeMethodsMixin = { + /** + * Determines the location on screen, width, and height of the given view and + * returns the values via an async callback. If successful, the callback will + * be called with the following arguments: + * + * - x + * - y + * - width + * - height + * - pageX + * - pageY + * + * Note that these measurements are not available until after the rendering + * has been completed in native. If you need the measurements as soon as + * possible, consider using the [`onLayout` + * prop](docs/view.html#onlayout) instead. + */ + measure: function(callback) { + var maybeInstance; // Fiber errors if findNodeHandle is called for an umounted component. + // Tests using ReactTestRenderer will trigger this case indirectly. + // Mimicking stack behavior, we should silently ignore this case. + // TODO Fix ReactTestRenderer so we can remove this try/catch. + + try { + maybeInstance = findHostInstance(this); + } catch (error) {} // If there is no host component beneath this we should fail silently. + // This is not an error; it could mean a class component rendered null. + + if (maybeInstance == null) { + return; + } + + if (maybeInstance.canonical) { + // We can't call FabricUIManager here because it won't be loaded in paper + // at initialization time. See https://github.com/facebook/react/pull/15490 + // for more info. + nativeFabricUIManager.measure( + maybeInstance.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ); + } else { + ReactNativePrivateInterface.UIManager.measure( + findNodeHandle(this), + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ); + } + }, + + /** + * Determines the location of the given view in the window and returns the + * values via an async callback. If the React root view is embedded in + * another native view, this will give you the absolute coordinates. If + * successful, the callback will be called with the following + * arguments: + * + * - x + * - y + * - width + * - height + * + * Note that these measurements are not available until after the rendering + * has been completed in native. + */ + measureInWindow: function(callback) { + var maybeInstance; // Fiber errors if findNodeHandle is called for an umounted component. + // Tests using ReactTestRenderer will trigger this case indirectly. + // Mimicking stack behavior, we should silently ignore this case. + // TODO Fix ReactTestRenderer so we can remove this try/catch. + + try { + maybeInstance = findHostInstance(this); + } catch (error) {} // If there is no host component beneath this we should fail silently. + // This is not an error; it could mean a class component rendered null. + + if (maybeInstance == null) { + return; + } + + if (maybeInstance.canonical) { + // We can't call FabricUIManager here because it won't be loaded in paper + // at initialization time. See https://github.com/facebook/react/pull/15490 + // for more info. + nativeFabricUIManager.measureInWindow( + maybeInstance.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ); + } else { + ReactNativePrivateInterface.UIManager.measureInWindow( + findNodeHandle(this), + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ); + } + }, + + /** + * Like [`measure()`](#measure), but measures the view relative an ancestor, + * specified as `relativeToNativeNode`. This means that the returned x, y + * are relative to the origin x, y of the ancestor view. + * + * As always, to obtain a native node handle for a component, you can use + * `findNodeHandle(component)`. + */ + measureLayout: function( + relativeToNativeNode, + onSuccess, + onFail + ) /* currently unused */ + { + var maybeInstance; // Fiber errors if findNodeHandle is called for an umounted component. + // Tests using ReactTestRenderer will trigger this case indirectly. + // Mimicking stack behavior, we should silently ignore this case. + // TODO Fix ReactTestRenderer so we can remove this try/catch. + + try { + maybeInstance = findHostInstance(this); + } catch (error) {} // If there is no host component beneath this we should fail silently. + // This is not an error; it could mean a class component rendered null. + + if (maybeInstance == null) { + return; + } + + if (maybeInstance.canonical) { + warningWithoutStack$1( + false, + "Warning: measureLayout on components using NativeMethodsMixin " + + "or ReactNative.NativeComponent is not currently supported in Fabric. " + + "measureLayout must be called on a native ref. Consider using forwardRef." + ); + return; + } else { + var relativeNode; + + if (typeof relativeToNativeNode === "number") { + // Already a node handle + relativeNode = relativeToNativeNode; + } else if (relativeToNativeNode._nativeTag) { + relativeNode = relativeToNativeNode._nativeTag; + } + + if (relativeNode == null) { + warningWithoutStack$1( + false, + "Warning: ref.measureLayout must be called with a node handle or a ref to a native component." + ); + return; + } + + ReactNativePrivateInterface.UIManager.measureLayout( + findNodeHandle(this), + relativeNode, + mountSafeCallback_NOT_REALLY_SAFE(this, onFail), + mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) + ); + } + }, + + /** + * This function sends props straight to native. They will not participate in + * future diff process - this means that if you do not include them in the + * next render, they will remain active (see [Direct + * Manipulation](docs/direct-manipulation.html)). + */ + setNativeProps: function(nativeProps) { + // Class components don't have viewConfig -> validateAttributes. + // Nor does it make sense to set native props on a non-native component. + // Instead, find the nearest host component and set props on it. + // Use findNodeHandle() rather than findNodeHandle() because + // We want the instance/wrapper (not the native tag). + var maybeInstance; // Fiber errors if findNodeHandle is called for an umounted component. + // Tests using ReactTestRenderer will trigger this case indirectly. + // Mimicking stack behavior, we should silently ignore this case. + // TODO Fix ReactTestRenderer so we can remove this try/catch. + + try { + maybeInstance = findHostInstance(this); + } catch (error) {} // If there is no host component beneath this we should fail silently. + // This is not an error; it could mean a class component rendered null. + + if (maybeInstance == null) { + return; + } + + if (maybeInstance.canonical) { + warningWithoutStack$1( + false, + "Warning: setNativeProps is not currently supported in Fabric" + ); + return; + } + + var nativeTag = + maybeInstance._nativeTag || maybeInstance.canonical._nativeTag; + var viewConfig = + maybeInstance.viewConfig || maybeInstance.canonical.viewConfig; + + { + warnForStyleProps(nativeProps, viewConfig.validAttributes); + } + + var updatePayload = create(nativeProps, 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( + nativeTag, + viewConfig.uiViewClassName, + updatePayload + ); + } + }, + + /** + * Requests focus for the given input or view. The exact behavior triggered + * will depend on the platform and type of view. + */ + focus: function() { + ReactNativePrivateInterface.TextInputState.focusTextInput( + findNodeHandle(this) + ); + }, + + /** + * Removes focus from an input or view. This is the opposite of `focus()`. + */ + blur: function() { + ReactNativePrivateInterface.TextInputState.blurTextInput( + findNodeHandle(this) + ); + } + }; + + { + // hide this from Flow since we can't define these properties outside of + // true without actually implementing them (setting them to undefined + // isn't allowed by ReactClass) + var NativeMethodsMixin_DEV = NativeMethodsMixin; + + if ( + !( + !NativeMethodsMixin_DEV.componentWillMount && + !NativeMethodsMixin_DEV.componentWillReceiveProps && + !NativeMethodsMixin_DEV.UNSAFE_componentWillMount && + !NativeMethodsMixin_DEV.UNSAFE_componentWillReceiveProps + ) + ) { + throw Error("Do not override existing functions."); + } // TODO (bvaughn) Remove cWM and cWRP in a future version of React Native, + // Once these lifecycles have been remove from the reconciler. + + NativeMethodsMixin_DEV.componentWillMount = function() { + throwOnStylesProp(this, this.props); + }; + + NativeMethodsMixin_DEV.componentWillReceiveProps = function(newProps) { + throwOnStylesProp(this, newProps); + }; + + NativeMethodsMixin_DEV.UNSAFE_componentWillMount = function() { + throwOnStylesProp(this, this.props); + }; + + NativeMethodsMixin_DEV.UNSAFE_componentWillReceiveProps = function( + newProps + ) { + throwOnStylesProp(this, newProps); + }; // React may warn about cWM/cWRP/cWU methods being deprecated. + // Add a flag to suppress these warnings for this special case. + // TODO (bvaughn) Remove this flag once the above methods have been removed. + + NativeMethodsMixin_DEV.componentWillMount.__suppressDeprecationWarning = true; + NativeMethodsMixin_DEV.componentWillReceiveProps.__suppressDeprecationWarning = true; + } + + return NativeMethodsMixin; +}; + +function _inheritsLoose(subClass, superClass) { + subClass.prototype = Object.create(superClass.prototype); + subClass.prototype.constructor = subClass; + subClass.__proto__ = superClass; +} + +var ReactNativeComponent = function(findNodeHandle, findHostInstance) { + /** + * Superclass that provides methods to access the underlying native component. + * This can be useful when you want to focus a view or measure its dimensions. + * + * Methods implemented by this class are available on most default components + * provided by React Native. However, they are *not* available on composite + * components that are not directly backed by a native view. For more + * information, see [Direct Manipulation](docs/direct-manipulation.html). + * + * @abstract + */ + var ReactNativeComponent = + /*#__PURE__*/ + (function(_React$Component) { + _inheritsLoose(ReactNativeComponent, _React$Component); + + function ReactNativeComponent() { + return _React$Component.apply(this, arguments) || this; + } + + var _proto = ReactNativeComponent.prototype; + + /** + * Due to bugs in Flow's handling of React.createClass, some fields already + * declared in the base class need to be redeclared below. + */ + + /** + * Removes focus. This is the opposite of `focus()`. + */ + _proto.blur = function blur() { + ReactNativePrivateInterface.TextInputState.blurTextInput( + findNodeHandle(this) + ); + }; + /** + * Requests focus. The exact behavior depends on the platform and view. + */ -{ - var copyWithSetImpl = function(obj, path, idx, value) { - if (idx >= path.length) { - return value; - } + _proto.focus = function focus() { + ReactNativePrivateInterface.TextInputState.focusTextInput( + findNodeHandle(this) + ); + }; + /** + * Measures the on-screen location and dimensions. If successful, the callback + * will be called asynchronously with the following arguments: + * + * - x + * - y + * - width + * - height + * - pageX + * - pageY + * + * These values are not available until after natives rendering completes. If + * you need the measurements as soon as possible, consider using the + * [`onLayout` prop](docs/view.html#onlayout) instead. + */ + + _proto.measure = function measure(callback) { + var maybeInstance; // Fiber errors if findNodeHandle is called for an umounted component. + // Tests using ReactTestRenderer will trigger this case indirectly. + // Mimicking stack behavior, we should silently ignore this case. + // TODO Fix ReactTestRenderer so we can remove this try/catch. - var key = path[idx]; - var updated = Array.isArray(obj) ? obj.slice() : Object.assign({}, obj); // $FlowFixMe number or string is fine here + try { + maybeInstance = findHostInstance(this); + } catch (error) {} // If there is no host component beneath this we should fail silently. + // This is not an error; it could mean a class component rendered null. - updated[key] = copyWithSetImpl(obj[key], path, idx + 1, value); - return updated; - }; + if (maybeInstance == null) { + return; + } - var copyWithSet = function(obj, path, value) { - return copyWithSetImpl(obj, path, 0, value); - }; // Support DevTools editable values for useState and useReducer. + if (maybeInstance.canonical) { + // We can't call FabricUIManager here because it won't be loaded in paper + // at initialization time. See https://github.com/facebook/react/pull/15490 + // for more info. + nativeFabricUIManager.measure( + maybeInstance.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ); + } else { + ReactNativePrivateInterface.UIManager.measure( + findNodeHandle(this), + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ); + } + }; + /** + * Measures the on-screen location and dimensions. Even if the React Native + * root view is embedded within another native view, this method will give you + * the absolute coordinates measured from the window. If successful, the + * callback will be called asynchronously with the following arguments: + * + * - x + * - y + * - width + * - height + * + * These values are not available until after natives rendering completes. + */ + + _proto.measureInWindow = function measureInWindow(callback) { + var maybeInstance; // Fiber errors if findNodeHandle is called for an umounted component. + // Tests using ReactTestRenderer will trigger this case indirectly. + // Mimicking stack behavior, we should silently ignore this case. + // TODO Fix ReactTestRenderer so we can remove this try/catch. - overrideHookState = function(fiber, id, path, value) { - // For now, the "id" of stateful hooks is just the stateful hook index. - // This may change in the future with e.g. nested hooks. - var currentHook = fiber.memoizedState; + try { + maybeInstance = findHostInstance(this); + } catch (error) {} // If there is no host component beneath this we should fail silently. + // This is not an error; it could mean a class component rendered null. - while (currentHook !== null && id > 0) { - currentHook = currentHook.next; - id--; - } + if (maybeInstance == null) { + return; + } - if (currentHook !== null) { - var newState = copyWithSet(currentHook.memoizedState, path, value); - currentHook.memoizedState = newState; - currentHook.baseState = newState; // We aren't actually adding an update to the queue, - // because there is no update we can add for useReducer hooks that won't trigger an error. - // (There's no appropriate action type for DevTools overrides.) - // As a result though, React will see the scheduled update as a noop and bailout. - // Shallow cloning props works as a workaround for now to bypass the bailout check. + if (maybeInstance.canonical) { + // We can't call FabricUIManager here because it won't be loaded in paper + // at initialization time. See https://github.com/facebook/react/pull/15490 + // for more info. + nativeFabricUIManager.measureInWindow( + maybeInstance.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ); + } else { + ReactNativePrivateInterface.UIManager.measureInWindow( + findNodeHandle(this), + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ); + } + }; + /** + * Similar to [`measure()`](#measure), but the resulting location will be + * relative to the supplied ancestor's location. + * + * Obtain a native node handle with `ReactNative.findNodeHandle(component)`. + */ + + _proto.measureLayout = function measureLayout( + relativeToNativeNode, + onSuccess, + onFail + ) { + var maybeInstance; // Fiber errors if findNodeHandle is called for an umounted component. + // Tests using ReactTestRenderer will trigger this case indirectly. + // Mimicking stack behavior, we should silently ignore this case. + // TODO Fix ReactTestRenderer so we can remove this try/catch. - fiber.memoizedProps = Object.assign({}, fiber.memoizedProps); - scheduleWork(fiber, Sync); - } - }; // Support DevTools props for function components, forwardRef, memo, host components, etc. + try { + maybeInstance = findHostInstance(this); + } catch (error) {} // If there is no host component beneath this we should fail silently. + // This is not an error; it could mean a class component rendered null. - overrideProps = function(fiber, path, value) { - fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value); + if (maybeInstance == null) { + return; + } - if (fiber.alternate) { - fiber.alternate.pendingProps = fiber.pendingProps; - } + if (maybeInstance.canonical) { + warningWithoutStack$1( + false, + "Warning: measureLayout on components using NativeMethodsMixin " + + "or ReactNative.NativeComponent is not currently supported in Fabric. " + + "measureLayout must be called on a native ref. Consider using forwardRef." + ); + return; + } else { + var relativeNode; - scheduleWork(fiber, Sync); - }; + if (typeof relativeToNativeNode === "number") { + // Already a node handle + relativeNode = relativeToNativeNode; + } else if (relativeToNativeNode._nativeTag) { + relativeNode = relativeToNativeNode._nativeTag; + } - scheduleUpdate = function(fiber) { - scheduleWork(fiber, Sync); - }; + if (relativeNode == null) { + warningWithoutStack$1( + false, + "Warning: ref.measureLayout must be called with a node handle or a ref to a native component." + ); + return; + } - setSuspenseHandler = function(newShouldSuspendImpl) { - shouldSuspendImpl = newShouldSuspendImpl; - }; -} + ReactNativePrivateInterface.UIManager.measureLayout( + findNodeHandle(this), + relativeNode, + mountSafeCallback_NOT_REALLY_SAFE(this, onFail), + mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) + ); + } + }; + /** + * This function sends props straight to native. They will not participate in + * future diff process - this means that if you do not include them in the + * next render, they will remain active (see [Direct + * Manipulation](docs/direct-manipulation.html)). + */ + + _proto.setNativeProps = function setNativeProps(nativeProps) { + // Class components don't have viewConfig -> validateAttributes. + // Nor does it make sense to set native props on a non-native component. + // Instead, find the nearest host component and set props on it. + // Use findNodeHandle() rather than ReactNative.findNodeHandle() because + // We want the instance/wrapper (not the native tag). + var maybeInstance; // Fiber errors if findNodeHandle is called for an umounted component. + // Tests using ReactTestRenderer will trigger this case indirectly. + // Mimicking stack behavior, we should silently ignore this case. + // TODO Fix ReactTestRenderer so we can remove this try/catch. -function injectIntoDevTools(devToolsConfig) { - var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance; - var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher; - return injectInternals({ - bundleType: devToolsConfig.bundleType, - version: devToolsConfig.version, - rendererPackageName: devToolsConfig.rendererPackageName, - rendererConfig: devToolsConfig.rendererConfig, - overrideHookState: overrideHookState, - overrideProps: overrideProps, - setSuspenseHandler: setSuspenseHandler, - scheduleUpdate: scheduleUpdate, - currentDispatcherRef: ReactCurrentDispatcher, - findHostInstanceByFiber: function(fiber) { - var hostFiber = findCurrentHostFiber(fiber); - - if (hostFiber === null) { - return null; - } + try { + maybeInstance = findHostInstance(this); + } catch (error) {} // If there is no host component beneath this we should fail silently. + // This is not an error; it could mean a class component rendered null. - return hostFiber.stateNode; - }, - findFiberByHostInstance: function(instance) { - if (!findFiberByHostInstance) { - // Might not be implemented by the renderer. - return null; - } + if (maybeInstance == null) { + return; + } - return findFiberByHostInstance(instance); - }, - // React Refresh - findHostInstancesForRefresh: findHostInstancesForRefresh, - scheduleRefresh: scheduleRefresh, - scheduleRoot: scheduleRoot, - setRefreshHandler: setRefreshHandler, - // Enables DevTools to append owner stacks to error messages in DEV mode. - getCurrentFiber: function() { - return current; - } - }); -} -var IsSomeRendererActing$1 = ReactSharedInternals.IsSomeRendererActing; + if (maybeInstance.canonical) { + warningWithoutStack$1( + false, + "Warning: setNativeProps is not currently supported in Fabric" + ); + return; + } -function createPortal( - children, - containerInfo, // TODO: figure out the API for cross-renderer implementation. - implementation -) { - var key = - arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null; - return { - // This tag allow us to uniquely identify this as a React Portal - $$typeof: REACT_PORTAL_TYPE, - key: key == null ? null : "" + key, - children: children, - containerInfo: containerInfo, - implementation: implementation - }; -} + var nativeTag = + maybeInstance._nativeTag || maybeInstance.canonical._nativeTag; + var viewConfig = + maybeInstance.viewConfig || maybeInstance.canonical.viewConfig; + var updatePayload = create(nativeProps, 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( + nativeTag, + viewConfig.uiViewClassName, + updatePayload + ); + } + }; -// TODO: this is special because it gets imported during build. -var ReactVersion = "16.13.0"; + return ReactNativeComponent; + })(React.Component); // eslint-disable-next-line no-unused-expressions -var emptyObject$1 = {}; + return ReactNativeComponent; +}; + +var emptyObject$3 = {}; { - Object.freeze(emptyObject$1); + Object.freeze(emptyObject$3); } var getInspectorDataForViewTag; -var getInspectorDataForViewAtPoint; { var traverseOwnerTreeUp = function(hierarchy, instance) { @@ -20816,10 +24355,10 @@ var getInspectorDataForViewAtPoint; var host = findCurrentHostFiber(fiber); if (host) { - return host.memoizedProps || emptyObject$1; + return host.memoizedProps || emptyObject$3; } - return emptyObject$1; + return emptyObject$3; }; var getHostNode = function(fiber, findNodeHandle) { @@ -20847,65 +24386,28 @@ var getInspectorDataForViewAtPoint; name: getComponentName(fiber.type), getInspectorData: function(findNodeHandle) { return { - props: getHostProps(fiber), - source: fiber._debugSource, measure: function(callback) { - // If this is Fabric, we'll find a ShadowNode and use that to measure. - var hostFiber = findCurrentHostFiber(fiber); - var shadowNode = - hostFiber != null && - hostFiber.stateNode !== null && - hostFiber.stateNode.node; - - if (shadowNode) { - nativeFabricUIManager.measure(shadowNode, callback); - } else { - return ReactNativePrivateInterface.UIManager.measure( - getHostNode(fiber, findNodeHandle), - callback - ); - } - } + return ReactNativePrivateInterface.UIManager.measure( + getHostNode(fiber, findNodeHandle), + callback + ); + }, + props: getHostProps(fiber), + source: fiber._debugSource }; } }; }); }; - var getInspectorDataForInstance = function(closestInstance) { - // Handle case where user clicks outside of ReactNative - if (!closestInstance) { - return { - hierarchy: [], - props: emptyObject$1, - selectedIndex: null, - source: null - }; - } - - var fiber = findCurrentFiberUsingSlowPath(closestInstance); - var fiberHierarchy = getOwnerHierarchy(fiber); - var instance = lastNonHostInstance(fiberHierarchy); - var hierarchy = createHierarchy(fiberHierarchy); - var props = getHostProps(instance); - var source = instance._debugSource; - var selectedIndex = fiberHierarchy.indexOf(instance); - return { - hierarchy: hierarchy, - props: props, - selectedIndex: selectedIndex, - source: source - }; - }; - getInspectorDataForViewTag = function(viewTag) { var closestInstance = getInstanceFromTag(viewTag); // Handle case where user clicks outside of ReactNative if (!closestInstance) { return { hierarchy: [], - props: emptyObject$1, - selectedIndex: null, + props: emptyObject$3, + selection: null, source: null }; } @@ -20916,122 +24418,34 @@ var getInspectorDataForViewAtPoint; var hierarchy = createHierarchy(fiberHierarchy); var props = getHostProps(instance); var source = instance._debugSource; - var selectedIndex = fiberHierarchy.indexOf(instance); + var selection = fiberHierarchy.indexOf(instance); return { hierarchy: hierarchy, props: props, - selectedIndex: selectedIndex, + selection: selection, source: source }; }; - - getInspectorDataForViewAtPoint = function( - findNodeHandle, - inspectedView, - locationX, - locationY, - callback - ) { - var closestInstance = null; - - if (inspectedView._internalInstanceHandle != null) { - // For Fabric we can look up the instance handle directly and measure it. - nativeFabricUIManager.findNodeAtPoint( - inspectedView._internalInstanceHandle.stateNode.node, - locationX, - locationY, - function(internalInstanceHandle) { - if (internalInstanceHandle == null) { - callback( - Object.assign( - { - pointerY: locationY, - frame: { - left: 0, - top: 0, - width: 0, - height: 0 - } - }, - getInspectorDataForInstance(closestInstance) - ) - ); - } - - closestInstance = - internalInstanceHandle.stateNode.canonical._internalInstanceHandle; - nativeFabricUIManager.measure( - internalInstanceHandle.stateNode.node, - function(x, y, width, height, pageX, pageY) { - callback( - Object.assign( - { - pointerY: locationY, - frame: { - left: pageX, - top: pageY, - width: width, - height: height - } - }, - getInspectorDataForInstance(closestInstance) - ) - ); - } - ); - } - ); - } else if (inspectedView._internalFiberInstanceHandleDEV != null) { - // For Paper we fall back to the old strategy using the React tag. - ReactNativePrivateInterface.UIManager.findSubviewIn( - findNodeHandle(inspectedView), - [locationX, locationY], - function(nativeViewTag, left, top, width, height) { - var inspectorData = getInspectorDataForInstance( - getInstanceFromTag(nativeViewTag) - ); - callback( - Object.assign({}, inspectorData, { - pointerY: locationY, - frame: { - left: left, - top: top, - width: width, - height: height - }, - touchedViewTag: nativeViewTag - }) - ); - } - ); - } else { - error( - "getInspectorDataForViewAtPoint expects to receieve a host component" - ); - - return; - } - }; } -var ReactCurrentOwner$3 = ReactSharedInternals.ReactCurrentOwner; +var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner; function findHostInstance_DEPRECATED(componentOrHandle) { { - var owner = ReactCurrentOwner$3.current; + var owner = ReactCurrentOwner.current; if (owner !== null && owner.stateNode !== null) { - if (!owner.stateNode._warnedAboutRefsInRender) { - error( - "%s is accessing findNodeHandle inside its render(). " + - "render() should be a pure function of props and state. It should " + - "never access something that requires stale data from the previous " + - "render, such as refs. Move this logic to componentDidMount and " + - "componentDidUpdate instead.", - getComponentName(owner.type) || "A component" - ); - } - + !owner.stateNode._warnedAboutRefsInRender + ? warningWithoutStack$1( + false, + "%s is accessing findNodeHandle inside its render(). " + + "render() should be a pure function of props and state. It should " + + "never access something that requires stale data from the previous " + + "render, such as refs. Move this logic to componentDidMount and " + + "componentDidUpdate instead.", + getComponentName(owner.type) || "A component" + ) + : void 0; owner.stateNode._warnedAboutRefsInRender = true; } } @@ -21071,20 +24485,20 @@ function findHostInstance_DEPRECATED(componentOrHandle) { function findNodeHandle(componentOrHandle) { { - var owner = ReactCurrentOwner$3.current; + var owner = ReactCurrentOwner.current; if (owner !== null && owner.stateNode !== null) { - if (!owner.stateNode._warnedAboutRefsInRender) { - error( - "%s is accessing findNodeHandle inside its render(). " + - "render() should be a pure function of props and state. It should " + - "never access something that requires stale data from the previous " + - "render, such as refs. Move this logic to componentDidMount and " + - "componentDidUpdate instead.", - getComponentName(owner.type) || "A component" - ); - } - + !owner.stateNode._warnedAboutRefsInRender + ? warningWithoutStack$1( + false, + "%s is accessing findNodeHandle inside its render(). " + + "render() should be a pure function of props and state. It should " + + "never access something that requires stale data from the previous " + + "render, such as refs. Move this logic to componentDidMount and " + + "componentDidUpdate instead.", + getComponentName(owner.type) || "A component" + ) + : void 0; owner.stateNode._warnedAboutRefsInRender = true; } } @@ -21127,109 +24541,110 @@ function findNodeHandle(componentOrHandle) { return hostInstance._nativeTag; } -function dispatchCommand(handle, command, args) { - if (handle._nativeTag == null) { - { - error( - "dispatchCommand was called with a ref that isn't a " + - "native component. Use React.forwardRef to get access to the underlying native component" - ); - } +setBatchingImplementation( + batchedUpdates$1, + discreteUpdates$1, + flushDiscreteUpdates, + batchedEventUpdates$1 +); - return; +function computeComponentStackForErrorReporting(reactTag) { + var fiber = getInstanceFromTag(reactTag); + + if (!fiber) { + return ""; } - if (handle._internalInstanceHandle) { - nativeFabricUIManager.dispatchCommand( - handle._internalInstanceHandle.stateNode.node, - command, - args - ); - } else { + return getStackByFiberInDevAndProd(fiber); +} + +var roots = new Map(); +var ReactNativeRenderer = { + NativeComponent: ReactNativeComponent(findNodeHandle, findHostInstance), + // This is needed for implementation details of TouchableNativeFeedback + // Remove this once TouchableNativeFeedback doesn't use cloneElement + findHostInstance_DEPRECATED: findHostInstance_DEPRECATED, + findNodeHandle: findNodeHandle, + dispatchCommand: function(handle, command, args) { + if (handle._nativeTag == null) { + !(handle._nativeTag != null) + ? warningWithoutStack$1( + false, + "dispatchCommand was called with a ref that isn't a " + + "native component. Use React.forwardRef to get access to the underlying native component" + ) + : void 0; + return; + } + ReactNativePrivateInterface.UIManager.dispatchViewManagerCommand( handle._nativeTag, command, args ); - } -} - -function render(element, containerTag, callback) { - var root = roots.get(containerTag); - - 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); - roots.set(containerTag, root); - } - - updateContainer(element, root, null, callback); - return getPublicRootInstance(root); -} - -function unmountComponentAtNode(containerTag) { - var root = roots.get(containerTag); - - if (root) { - // TODO: Is it safe to reset this now or should I wait since this unmount could be deferred? - updateContainer(null, root, null, function() { - roots.delete(containerTag); - }); - } -} - -function unmountComponentAtNodeAndRemoveContainer(containerTag) { - unmountComponentAtNode(containerTag); // Call back into native to remove all of the subviews from this container - - ReactNativePrivateInterface.UIManager.removeRootView(containerTag); -} + }, + render: function(element, containerTag, callback) { + var root = roots.get(containerTag); -function createPortal$1(children, containerTag) { - var key = - arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; - return createPortal(children, containerTag, null, key); -} + 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); + roots.set(containerTag, root); + } -setBatchingImplementation(batchedUpdates$1); + updateContainer(element, root, null, callback); + return getPublicRootInstance(root); + }, + unmountComponentAtNode: function(containerTag) { + var root = roots.get(containerTag); -function computeComponentStackForErrorReporting(reactTag) { - var fiber = getInstanceFromTag(reactTag); + if (root) { + // TODO: Is it safe to reset this now or should I wait since this unmount could be deferred? + updateContainer(null, root, null, function() { + roots.delete(containerTag); + }); + } + }, + unmountComponentAtNodeAndRemoveContainer: function(containerTag) { + ReactNativeRenderer.unmountComponentAtNode(containerTag); // Call back into native to remove all of the subviews from this container - if (!fiber) { - return ""; + ReactNativePrivateInterface.UIManager.removeRootView(containerTag); + }, + createPortal: function(children, containerTag) { + var key = + arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; + return createPortal(children, containerTag, null, key); + }, + unstable_batchedUpdates: batchedUpdates, + __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: { + // Used as a mixin in many createClass-based components + NativeMethodsMixin: NativeMethodsMixin(findNodeHandle, findHostInstance), + computeComponentStackForErrorReporting: computeComponentStackForErrorReporting } - - return getStackByFiberInDevAndProd(fiber); -} - -var roots = new Map(); -var Internals = { - computeComponentStackForErrorReporting: computeComponentStackForErrorReporting }; injectIntoDevTools({ findFiberByHostInstance: getInstanceFromTag, + getInspectorDataForViewTag: getInspectorDataForViewTag, bundleType: 1, version: ReactVersion, - rendererPackageName: "react-native-renderer", - rendererConfig: { - getInspectorDataForViewTag: getInspectorDataForViewTag, - getInspectorDataForViewAtPoint: getInspectorDataForViewAtPoint.bind( - null, - findNodeHandle - ) - } + rendererPackageName: "react-native-renderer" +}); + +var ReactNativeRenderer$2 = Object.freeze({ + default: ReactNativeRenderer }); -exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = Internals; -exports.createPortal = createPortal$1; -exports.dispatchCommand = dispatchCommand; -exports.findHostInstance_DEPRECATED = findHostInstance_DEPRECATED; -exports.findNodeHandle = findNodeHandle; -exports.render = render; -exports.unmountComponentAtNode = unmountComponentAtNode; -exports.unmountComponentAtNodeAndRemoveContainer = unmountComponentAtNodeAndRemoveContainer; -exports.unstable_batchedUpdates = batchedUpdates; +var ReactNativeRenderer$3 = + (ReactNativeRenderer$2 && ReactNativeRenderer) || ReactNativeRenderer$2; + +// TODO: decide on the top-level export form. +// This is hacky but makes it work with both Rollup and Jest. + +var reactNativeRenderer = + ReactNativeRenderer$3.default || ReactNativeRenderer$3; + +module.exports = reactNativeRenderer; })(); } diff --git a/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js b/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js index d837754c50d25c..4aa16ac835491d 100644 --- a/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js +++ b/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js @@ -5,7 +5,6 @@ * LICENSE file in the root directory of this source tree. * * @noflow - * @nolint * @providesModule ReactNativeRenderer-dev * @preventMunge * @generated @@ -17,234 +16,256 @@ if (__DEV__) { (function() { "use strict"; -var React = require("react"); require("react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore"); var ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/ReactNativePrivateInterface"); +var React = require("react"); +var checkPropTypes = require("prop-types/checkPropTypes"); var Scheduler = require("scheduler"); var tracing = require("scheduler/tracing"); -var ReactSharedInternals = - React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; // Prevent newer renderers from RTE when used with older react package versions. -// Current owner and dispatcher used to share the same ref, -// but PR #14548 split them out to better support the react-debug-tools package. +/** + * Use invariant() to assert state which your program assumes to be true. + * + * Provide sprintf-style format (only %s is supported) and arguments + * to provide information about what broke and what you were + * expecting. + * + * The invariant message will be stripped in production, but the invariant + * will remain to ensure logic does not differ in production. + */ -if (!ReactSharedInternals.hasOwnProperty("ReactCurrentDispatcher")) { - ReactSharedInternals.ReactCurrentDispatcher = { - current: null - }; -} +/** + * Injectable ordering of event plugins. + */ +var eventPluginOrder = null; +/** + * Injectable mapping from names to event plugin modules. + */ -if (!ReactSharedInternals.hasOwnProperty("ReactCurrentBatchConfig")) { - ReactSharedInternals.ReactCurrentBatchConfig = { - suspense: null - }; -} +var namesToPlugins = {}; +/** + * Recomputes the plugin list using the injected plugins and plugin ordering. + * + * @private + */ -// by calls to these methods by a Babel plugin. -// -// In PROD (or in packages without access to React internals), -// they are left as they are instead. +function recomputePluginOrdering() { + if (!eventPluginOrder) { + // Wait until an `eventPluginOrder` is injected. + return; + } -function warn(format) { - { - for ( - var _len = arguments.length, - args = new Array(_len > 1 ? _len - 1 : 0), - _key = 1; - _key < _len; - _key++ - ) { - args[_key - 1] = arguments[_key]; - } + for (var pluginName in namesToPlugins) { + var pluginModule = namesToPlugins[pluginName]; + var pluginIndex = eventPluginOrder.indexOf(pluginName); - printWarning("warn", format, args); - } -} -function error(format) { - { - for ( - var _len2 = arguments.length, - args = new Array(_len2 > 1 ? _len2 - 1 : 0), - _key2 = 1; - _key2 < _len2; - _key2++ - ) { - args[_key2 - 1] = arguments[_key2]; + if (!(pluginIndex > -1)) { + throw Error( + "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + + pluginName + + "`." + ); } - printWarning("error", format, args); - } -} + if (plugins[pluginIndex]) { + continue; + } -function printWarning(level, format, args) { - // When changing this logic, you might want to also - // update consoleWithStackDev.www.js as well. - { - var hasExistingStack = - args.length > 0 && - typeof args[args.length - 1] === "string" && - args[args.length - 1].indexOf("\n in") === 0; + if (!pluginModule.extractEvents) { + throw Error( + "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + + pluginName + + "` does not." + ); + } - if (!hasExistingStack) { - var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; - var stack = ReactDebugCurrentFrame.getStackAddendum(); + plugins[pluginIndex] = pluginModule; + var publishedEvents = pluginModule.eventTypes; - if (stack !== "") { - format += "%s"; - args = args.concat([stack]); + for (var eventName in publishedEvents) { + if ( + !publishEventForPlugin( + publishedEvents[eventName], + pluginModule, + eventName + ) + ) { + throw Error( + "EventPluginRegistry: Failed to publish event `" + + eventName + + "` for plugin `" + + pluginName + + "`." + ); } } - - var argsWithFormat = args.map(function(item) { - return "" + item; - }); // Careful: RN currently depends on this prefix - - argsWithFormat.unshift("Warning: " + format); // We intentionally don't use spread (or .apply) directly because it - // breaks IE9: https://github.com/facebook/react/issues/13610 - // eslint-disable-next-line react-internal/no-production-logging - - Function.prototype.apply.call(console[level], console, argsWithFormat); - - try { - // --- Welcome to debugging React --- - // This error was thrown as a convenience so that you can use this stack - // to find the callsite that caused this warning to fire. - var argIndex = 0; - var message = - "Warning: " + - format.replace(/%s/g, function() { - return args[argIndex++]; - }); - throw new Error(message); - } catch (x) {} } } +/** + * Publishes an event so that it can be dispatched by the supplied plugin. + * + * @param {object} dispatchConfig Dispatch configuration for the event. + * @param {object} PluginModule Plugin publishing the event. + * @return {boolean} True if the event was successfully published. + * @private + */ -var FunctionComponent = 0; -var ClassComponent = 1; -var IndeterminateComponent = 2; // Before we know whether it is function or class - -var HostRoot = 3; // Root of a host tree. Could be nested inside another node. - -var HostPortal = 4; // A subtree. Could be an entry point to a different renderer. +function publishEventForPlugin(dispatchConfig, pluginModule, eventName) { + if (!!eventNameDispatchConfigs.hasOwnProperty(eventName)) { + throw Error( + "EventPluginHub: More than one plugin attempted to publish the same event name, `" + + eventName + + "`." + ); + } -var HostComponent = 5; -var HostText = 6; -var Fragment = 7; -var Mode = 8; -var ContextConsumer = 9; -var ContextProvider = 10; -var ForwardRef = 11; -var Profiler = 12; -var SuspenseComponent = 13; -var MemoComponent = 14; -var SimpleMemoComponent = 15; -var LazyComponent = 16; -var IncompleteClassComponent = 17; -var DehydratedFragment = 18; -var SuspenseListComponent = 19; -var FundamentalComponent = 20; -var ScopeComponent = 21; -var Block = 22; + eventNameDispatchConfigs[eventName] = dispatchConfig; + var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; -function getParent(inst) { - do { - inst = inst.return; // TODO: If this is a HostRoot we might want to bail out. - // That is depending on if we want nested subtrees (layers) to bubble - // events to their parent. We could also go through parentNode on the - // host node but that wouldn't work for React Native and doesn't let us - // do the portal feature. - } while (inst && inst.tag !== HostComponent); + if (phasedRegistrationNames) { + for (var phaseName in phasedRegistrationNames) { + if (phasedRegistrationNames.hasOwnProperty(phaseName)) { + var phasedRegistrationName = phasedRegistrationNames[phaseName]; + publishRegistrationName( + phasedRegistrationName, + pluginModule, + eventName + ); + } + } - if (inst) { - return inst; + return true; + } else if (dispatchConfig.registrationName) { + publishRegistrationName( + dispatchConfig.registrationName, + pluginModule, + eventName + ); + return true; } - return null; + return false; } /** - * Return the lowest common ancestor of A and B, or null if they are in - * different trees. + * Publishes a registration name that is used to identify dispatched events. + * + * @param {string} registrationName Registration name to add. + * @param {object} PluginModule Plugin publishing the event. + * @private */ -function getLowestCommonAncestor(instA, instB) { - var depthA = 0; - - for (var tempA = instA; tempA; tempA = getParent(tempA)) { - depthA++; +function publishRegistrationName(registrationName, pluginModule, eventName) { + if (!!registrationNameModules[registrationName]) { + throw Error( + "EventPluginHub: More than one plugin attempted to publish the same registration name, `" + + registrationName + + "`." + ); } - var depthB = 0; - - for (var tempB = instB; tempB; tempB = getParent(tempB)) { - depthB++; - } // If A is deeper, crawl up. - - while (depthA - depthB > 0) { - instA = getParent(instA); - depthA--; - } // If B is deeper, crawl up. - - while (depthB - depthA > 0) { - instB = getParent(instB); - depthB--; - } // Walk in lockstep until we find a match. - - var depth = depthA; - - while (depth--) { - if (instA === instB || instA === instB.alternate) { - return instA; - } + registrationNameModules[registrationName] = pluginModule; + registrationNameDependencies[registrationName] = + pluginModule.eventTypes[eventName].dependencies; - instA = getParent(instA); - instB = getParent(instB); + { + var lowerCasedName = registrationName.toLowerCase(); } - - return null; } /** - * Return if A is an ancestor of B. + * Registers plugins so that they can extract and dispatch events. + * + * @see {EventPluginHub} */ -function isAncestor(instA, instB) { - while (instB) { - if (instA === instB || instA === instB.alternate) { - return true; - } - - instB = getParent(instB); - } +/** + * Ordered list of injected plugins. + */ - return false; -} +var plugins = []; /** - * Return the parent instance of the passed-in instance. + * Mapping from event name to dispatch config */ -function getParentInstance(inst) { - return getParent(inst); -} +var eventNameDispatchConfigs = {}; /** - * Simulates the traversal of a two-phase, capture/bubble event dispatch. + * Mapping from registration name to plugin module */ -function traverseTwoPhase(inst, fn, arg) { - var path = []; +var registrationNameModules = {}; +/** + * Mapping from registration name to event name + */ - while (inst) { - path.push(inst); - inst = getParent(inst); - } +var registrationNameDependencies = {}; +/** + * Mapping from lowercase registration names to the properly cased version, + * used to warn in the case of missing event handlers. Available + * only in true. + * @type {Object} + */ - var i; +// Trust the developer to only use possibleRegistrationNames in true - for (i = path.length; i-- > 0; ) { - fn(path[i], "captured", arg); +/** + * Injects an ordering of plugins (by plugin name). This allows the ordering + * to be decoupled from injection of the actual plugins so that ordering is + * always deterministic regardless of packaging, on-the-fly injection, etc. + * + * @param {array} InjectedEventPluginOrder + * @internal + * @see {EventPluginHub.injection.injectEventPluginOrder} + */ + +function injectEventPluginOrder(injectedEventPluginOrder) { + if (!!eventPluginOrder) { + throw Error( + "EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React." + ); + } // Clone the ordering so it cannot be dynamically mutated. + + eventPluginOrder = Array.prototype.slice.call(injectedEventPluginOrder); + recomputePluginOrdering(); +} +/** + * Injects plugins to be used by `EventPluginHub`. The plugin names must be + * in the ordering injected by `injectEventPluginOrder`. + * + * Plugins can be injected as part of page initialization or on-the-fly. + * + * @param {object} injectedNamesToPlugins Map from names to plugin modules. + * @internal + * @see {EventPluginHub.injection.injectEventPluginsByName} + */ + +function injectEventPluginsByName(injectedNamesToPlugins) { + var isOrderingDirty = false; + + for (var pluginName in injectedNamesToPlugins) { + if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) { + continue; + } + + var pluginModule = injectedNamesToPlugins[pluginName]; + + if ( + !namesToPlugins.hasOwnProperty(pluginName) || + namesToPlugins[pluginName] !== pluginModule + ) { + if (!!namesToPlugins[pluginName]) { + throw Error( + "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + + pluginName + + "`." + ); + } + + namesToPlugins[pluginName] = pluginModule; + isOrderingDirty = true; + } } - for (i = 0; i < path.length; i++) { - fn(path[i], "bubbled", arg); + if (isOrderingDirty) { + recomputePluginOrdering(); } } @@ -539,6 +560,71 @@ function clearCaughtError() { } } +/** + * Similar to invariant but only logs a warning if the condition is not met. + * This can be used to log issues in development environments in critical + * paths. Removing the logging code for production environments will keep the + * same logic and follow the same code paths. + */ +var warningWithoutStack = function() {}; + +{ + warningWithoutStack = function(condition, format) { + for ( + var _len = arguments.length, + args = new Array(_len > 2 ? _len - 2 : 0), + _key = 2; + _key < _len; + _key++ + ) { + args[_key - 2] = arguments[_key]; + } + + if (format === undefined) { + throw new Error( + "`warningWithoutStack(condition, format, ...args)` requires a warning " + + "message argument" + ); + } + + if (args.length > 8) { + // Check before the condition to catch violations early. + throw new Error( + "warningWithoutStack() currently supports at most 8 arguments." + ); + } + + if (condition) { + return; + } + + if (typeof console !== "undefined") { + var argsWithFormat = args.map(function(item) { + return "" + item; + }); + argsWithFormat.unshift("Warning: " + format); // We intentionally don't use spread (or .apply) directly because it + // breaks IE9: https://github.com/facebook/react/issues/13610 + + Function.prototype.apply.call(console.error, console, argsWithFormat); + } + + try { + // --- Welcome to debugging React --- + // This error was thrown as a convenience so that you can use this stack + // to find the callsite that caused this warning to fire. + var argIndex = 0; + var message = + "Warning: " + + format.replace(/%s/g, function() { + return args[argIndex++]; + }); + throw new Error(message); + } catch (x) {} + }; +} + +var warningWithoutStack$1 = warningWithoutStack; + var getFiberCurrentPropsFromNode = null; var getInstanceFromNode = null; var getNodeFromInstance = null; @@ -552,12 +638,13 @@ function setComponentTree( getNodeFromInstance = getNodeFromInstanceImpl; { - if (!getNodeFromInstance || !getInstanceFromNode) { - error( - "EventPluginUtils.setComponentTree(...): Injected " + - "module is missing getNodeFromInstance or getInstanceFromNode." - ); - } + !(getNodeFromInstance && getInstanceFromNode) + ? warningWithoutStack$1( + false, + "EventPluginUtils.setComponentTree(...): Injected " + + "module is missing getNodeFromInstance or getInstanceFromNode." + ) + : void 0; } } var validateEventDispatches; @@ -570,18 +657,17 @@ var validateEventDispatches; var listenersLen = listenersIsArr ? dispatchListeners.length : dispatchListeners - ? 1 - : 0; + ? 1 + : 0; var instancesIsArr = Array.isArray(dispatchInstances); var instancesLen = instancesIsArr ? dispatchInstances.length : dispatchInstances - ? 1 - : 0; - - if (instancesIsArr !== listenersIsArr || instancesLen !== listenersLen) { - error("EventPluginUtils: Invalid `event`."); - } + ? 1 + : 0; + !(instancesIsArr === listenersIsArr && instancesLen === listenersLen) + ? warningWithoutStack$1(false, "EventPluginUtils: Invalid `event`.") + : void 0; }; } /** @@ -708,77 +794,6 @@ function hasDispatches(event) { return !!event._dispatchListeners; } -function isInteractive(tag) { - return ( - tag === "button" || - tag === "input" || - tag === "select" || - tag === "textarea" - ); -} - -function shouldPreventMouseEvent(name, type, props) { - switch (name) { - case "onClick": - case "onClickCapture": - case "onDoubleClick": - case "onDoubleClickCapture": - case "onMouseDown": - case "onMouseDownCapture": - case "onMouseMove": - case "onMouseMoveCapture": - case "onMouseUp": - case "onMouseUpCapture": - case "onMouseEnter": - return !!(props.disabled && isInteractive(type)); - - default: - return false; - } -} -/** - * @param {object} inst The instance, which is the source of events. - * @param {string} registrationName Name of listener (e.g. `onClick`). - * @return {?function} The stored callback. - */ - -function getListener(inst, registrationName) { - var listener; // TODO: shouldPreventMouseEvent is DOM-specific and definitely should not - // live here; needs to be moved to a better place soon - - var stateNode = inst.stateNode; - - if (!stateNode) { - // Work in progress (ex: onload events in incremental mode). - return null; - } - - var props = getFiberCurrentPropsFromNode(stateNode); - - if (!props) { - // Work in progress. - return null; - } - - listener = props[registrationName]; - - if (shouldPreventMouseEvent(registrationName, inst.type, props)) { - return null; - } - - if (!(!listener || typeof listener === "function")) { - throw Error( - "Expected `" + - registrationName + - "` listener to be a function, instead got a value of `" + - typeof listener + - "` type." - ); - } - - return listener; -} - /** * Accumulates items that must not be null or undefined into the first one. This * is used to conserve memory by avoiding array allocations, and thus sacrifices @@ -840,1526 +855,1651 @@ function forEachAccumulated(arr, cb, scope) { } /** - * Some event types have a notion of different registration names for different - * "phases" of propagation. This finds listeners by a given phase. - */ -function listenerAtPhase(inst, event, propagationPhase) { - var registrationName = - event.dispatchConfig.phasedRegistrationNames[propagationPhase]; - return getListener(inst, registrationName); -} -/** - * A small set of propagation patterns, each of which will accept a small amount - * of information, and generate a set of "dispatch ready event objects" - which - * are sets of events that have already been annotated with a set of dispatched - * listener functions/ids. The API is designed this way to discourage these - * propagation strategies from actually executing the dispatches, since we - * always want to collect the entire set of dispatches before executing even a - * single one. + * Internal queue of events that have accumulated their dispatches and are + * waiting to have their dispatches executed. */ +var eventQueue = null; /** - * Tags a `SyntheticEvent` with dispatched listeners. Creating this function - * here, allows us to not have to bind or create functions for each event. - * Mutating the event's members allows us to not have to create a wrapping - * "dispatch" object that pairs the event with the listener. + * Dispatches an event and releases it back into the pool, unless persistent. + * + * @param {?object} event Synthetic event to be dispatched. + * @private */ -function accumulateDirectionalDispatches(inst, phase, event) { - { - if (!inst) { - error("Dispatching inst must not be null"); +var executeDispatchesAndRelease = function(event) { + if (event) { + executeDispatchesInOrder(event); + + if (!event.isPersistent()) { + event.constructor.release(event); } } +}; - var listener = listenerAtPhase(inst, event, phase); +var executeDispatchesAndReleaseTopLevel = function(e) { + return executeDispatchesAndRelease(e); +}; - if (listener) { - event._dispatchListeners = accumulateInto( - event._dispatchListeners, - listener - ); - event._dispatchInstances = accumulateInto(event._dispatchInstances, inst); - } -} -/** - * Collect dispatches (must be entirely collected before dispatching - see unit - * tests). Lazily allocate the array to conserve memory. We must loop through - * each event and perform the traversal for each one. We cannot perform a - * single traversal for the entire collection of events because each event may - * have a different target. - */ +function runEventsInBatch(events) { + if (events !== null) { + eventQueue = accumulateInto(eventQueue, events); + } // Set `eventQueue` to null before processing it so that we can tell if more + // events get enqueued while processing. -function accumulateTwoPhaseDispatchesSingle(event) { - if (event && event.dispatchConfig.phasedRegistrationNames) { - traverseTwoPhase(event._targetInst, accumulateDirectionalDispatches, event); + var processingEventQueue = eventQueue; + eventQueue = null; + + if (!processingEventQueue) { + return; } -} -/** - * Same as `accumulateTwoPhaseDispatchesSingle`, but skips over the targetID. - */ -function accumulateTwoPhaseDispatchesSingleSkipTarget(event) { - if (event && event.dispatchConfig.phasedRegistrationNames) { - var targetInst = event._targetInst; - var parentInst = targetInst ? getParentInstance(targetInst) : null; - traverseTwoPhase(parentInst, accumulateDirectionalDispatches, event); - } + forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseTopLevel); + + if (!!eventQueue) { + throw Error( + "processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented." + ); + } // This would be a good time to rethrow if any of the event handlers threw. + + rethrowCaughtError(); } -/** - * Accumulates without regard to direction, does not look for phased - * registration names. Same as `accumulateDirectDispatchesSingle` but without - * requiring that the `dispatchMarker` be the same as the dispatched ID. - */ -function accumulateDispatches(inst, ignoredDirection, event) { - if (inst && event && event.dispatchConfig.registrationName) { - var registrationName = event.dispatchConfig.registrationName; - var listener = getListener(inst, registrationName); +function isInteractive(tag) { + return ( + tag === "button" || + tag === "input" || + tag === "select" || + tag === "textarea" + ); +} - if (listener) { - event._dispatchListeners = accumulateInto( - event._dispatchListeners, - listener - ); - event._dispatchInstances = accumulateInto(event._dispatchInstances, inst); - } +function shouldPreventMouseEvent(name, type, props) { + switch (name) { + case "onClick": + case "onClickCapture": + case "onDoubleClick": + case "onDoubleClickCapture": + case "onMouseDown": + case "onMouseDownCapture": + case "onMouseMove": + case "onMouseMoveCapture": + case "onMouseUp": + case "onMouseUpCapture": + return !!(props.disabled && isInteractive(type)); + + default: + return false; } } /** - * Accumulates dispatches on an `SyntheticEvent`, but only for the - * `dispatchMarker`. - * @param {SyntheticEvent} event + * This is a unified interface for event plugins to be installed and configured. + * + * Event plugins can implement the following properties: + * + * `extractEvents` {function(string, DOMEventTarget, string, object): *} + * Required. When a top-level event is fired, this method is expected to + * extract synthetic events that will in turn be queued and dispatched. + * + * `eventTypes` {object} + * Optional, plugins that fire events must publish a mapping of registration + * names that are used to register listeners. Values of this mapping must + * be objects that contain `registrationName` or `phasedRegistrationNames`. + * + * `executeDispatch` {function(object, function, string)} + * Optional, allows plugins to override how an event gets dispatched. By + * default, the listener is simply invoked. + * + * Each plugin that is injected into `EventsPluginHub` is immediately operable. + * + * @public */ -function accumulateDirectDispatchesSingle(event) { - if (event && event.dispatchConfig.registrationName) { - accumulateDispatches(event._targetInst, null, event); - } -} +/** + * Methods for injecting dependencies. + */ -function accumulateTwoPhaseDispatches(events) { - forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle); -} -function accumulateTwoPhaseDispatchesSkipTarget(events) { - forEachAccumulated(events, accumulateTwoPhaseDispatchesSingleSkipTarget); -} -function accumulateDirectDispatches(events) { - forEachAccumulated(events, accumulateDirectDispatchesSingle); -} +var injection = { + /** + * @param {array} InjectedEventPluginOrder + * @public + */ + injectEventPluginOrder: injectEventPluginOrder, -var EVENT_POOL_SIZE = 10; + /** + * @param {object} injectedNamesToPlugins Map from names to plugin modules. + */ + injectEventPluginsByName: injectEventPluginsByName +}; /** - * @interface Event - * @see http://www.w3.org/TR/DOM-Level-3-Events/ + * @param {object} inst The instance, which is the source of events. + * @param {string} registrationName Name of listener (e.g. `onClick`). + * @return {?function} The stored callback. */ -var EventInterface = { - type: null, - target: null, - // currentTarget is set when dispatching; no use in copying it here - currentTarget: function() { +function getListener(inst, registrationName) { + var listener; // TODO: shouldPreventMouseEvent is DOM-specific and definitely should not + // live here; needs to be moved to a better place soon + + var stateNode = inst.stateNode; + + if (!stateNode) { + // Work in progress (ex: onload events in incremental mode). return null; - }, - eventPhase: null, - bubbles: null, - cancelable: null, - timeStamp: function(event) { - return event.timeStamp || Date.now(); - }, - defaultPrevented: null, - isTrusted: null -}; + } -function functionThatReturnsTrue() { - return true; -} + var props = getFiberCurrentPropsFromNode(stateNode); -function functionThatReturnsFalse() { - return false; + if (!props) { + // Work in progress. + return null; + } + + listener = props[registrationName]; + + if (shouldPreventMouseEvent(registrationName, inst.type, props)) { + return null; + } + + if (!(!listener || typeof listener === "function")) { + throw Error( + "Expected `" + + registrationName + + "` listener to be a function, instead got a value of `" + + typeof listener + + "` type." + ); + } + + return listener; } /** - * Synthetic events are dispatched by event plugins, typically in response to a - * top-level event delegation handler. - * - * These systems should generally use pooling to reduce the frequency of garbage - * collection. The system should check `isPersistent` to determine whether the - * event should be released into the pool after being dispatched. Users that - * need a persisted event should invoke `persist`. - * - * Synthetic events (and subclasses) implement the DOM Level 3 Events API by - * normalizing browser quirks. Subclasses do not necessarily have to implement a - * DOM interface; custom application-specific events can also subclass this. + * Allows registered plugins an opportunity to extract events from top-level + * native browser events. * - * @param {object} dispatchConfig Configuration used to dispatch this event. - * @param {*} targetInst Marker identifying the event target. - * @param {object} nativeEvent Native browser event. - * @param {DOMEventTarget} nativeEventTarget Target node. + * @return {*} An accumulation of synthetic events. + * @internal */ -function SyntheticEvent( - dispatchConfig, +function extractPluginEvents( + topLevelType, targetInst, nativeEvent, - nativeEventTarget + nativeEventTarget, + eventSystemFlags ) { - { - // these have a getter/setter for warnings - delete this.nativeEvent; - delete this.preventDefault; - delete this.stopPropagation; - delete this.isDefaultPrevented; - delete this.isPropagationStopped; - } - - this.dispatchConfig = dispatchConfig; - this._targetInst = targetInst; - this.nativeEvent = nativeEvent; - var Interface = this.constructor.Interface; - - for (var propName in Interface) { - if (!Interface.hasOwnProperty(propName)) { - continue; - } + var events = null; - { - delete this[propName]; // this has a getter/setter for warnings - } + for (var i = 0; i < plugins.length; i++) { + // Not every plugin in the ordering may be loaded at runtime. + var possiblePlugin = plugins[i]; - var normalize = Interface[propName]; + if (possiblePlugin) { + var extractedEvents = possiblePlugin.extractEvents( + topLevelType, + targetInst, + nativeEvent, + nativeEventTarget, + eventSystemFlags + ); - if (normalize) { - this[propName] = normalize(nativeEvent); - } else { - if (propName === "target") { - this.target = nativeEventTarget; - } else { - this[propName] = nativeEvent[propName]; + if (extractedEvents) { + events = accumulateInto(events, extractedEvents); } } } - var defaultPrevented = - nativeEvent.defaultPrevented != null - ? nativeEvent.defaultPrevented - : nativeEvent.returnValue === false; - - if (defaultPrevented) { - this.isDefaultPrevented = functionThatReturnsTrue; - } else { - this.isDefaultPrevented = functionThatReturnsFalse; - } + return events; +} - this.isPropagationStopped = functionThatReturnsFalse; - return this; +function runExtractedPluginEventsInBatch( + topLevelType, + targetInst, + nativeEvent, + nativeEventTarget, + eventSystemFlags +) { + var events = extractPluginEvents( + topLevelType, + targetInst, + nativeEvent, + nativeEventTarget, + eventSystemFlags + ); + runEventsInBatch(events); } -Object.assign(SyntheticEvent.prototype, { - preventDefault: function() { - this.defaultPrevented = true; - var event = this.nativeEvent; +var FunctionComponent = 0; +var ClassComponent = 1; +var IndeterminateComponent = 2; // Before we know whether it is function or class - if (!event) { - return; - } +var HostRoot = 3; // Root of a host tree. Could be nested inside another node. - if (event.preventDefault) { - event.preventDefault(); - } else if (typeof event.returnValue !== "unknown") { - event.returnValue = false; - } +var HostPortal = 4; // A subtree. Could be an entry point to a different renderer. - this.isDefaultPrevented = functionThatReturnsTrue; - }, - stopPropagation: function() { - var event = this.nativeEvent; +var HostComponent = 5; +var HostText = 6; +var Fragment = 7; +var Mode = 8; +var ContextConsumer = 9; +var ContextProvider = 10; +var ForwardRef = 11; +var Profiler = 12; +var SuspenseComponent = 13; +var MemoComponent = 14; +var SimpleMemoComponent = 15; +var LazyComponent = 16; +var IncompleteClassComponent = 17; +var DehydratedFragment = 18; +var SuspenseListComponent = 19; +var FundamentalComponent = 20; +var ScopeComponent = 21; - if (!event) { - return; - } +function getParent(inst) { + do { + inst = inst.return; // TODO: If this is a HostRoot we might want to bail out. + // That is depending on if we want nested subtrees (layers) to bubble + // events to their parent. We could also go through parentNode on the + // host node but that wouldn't work for React Native and doesn't let us + // do the portal feature. + } while (inst && inst.tag !== HostComponent); - if (event.stopPropagation) { - event.stopPropagation(); - } else if (typeof event.cancelBubble !== "unknown") { - // The ChangeEventPlugin registers a "propertychange" event for - // IE. This event does not support bubbling or cancelling, and - // any references to cancelBubble throw "Member not found". A - // typeof check of "unknown" circumvents this issue (and is also - // IE specific). - event.cancelBubble = true; - } + if (inst) { + return inst; + } - this.isPropagationStopped = functionThatReturnsTrue; - }, + return null; +} +/** + * Return the lowest common ancestor of A and B, or null if they are in + * different trees. + */ - /** - * We release all dispatched `SyntheticEvent`s after each event loop, adding - * them back into the pool. This allows a way to hold onto a reference that - * won't be added back into the pool. - */ - persist: function() { - this.isPersistent = functionThatReturnsTrue; - }, +function getLowestCommonAncestor(instA, instB) { + var depthA = 0; - /** - * Checks if this event should be released back into the pool. - * - * @return {boolean} True if this should not be released, false otherwise. - */ - isPersistent: functionThatReturnsFalse, + for (var tempA = instA; tempA; tempA = getParent(tempA)) { + depthA++; + } - /** - * `PooledClass` looks for `destructor` on each instance it releases. - */ - destructor: function() { - var Interface = this.constructor.Interface; + var depthB = 0; - for (var propName in Interface) { - { - Object.defineProperty( - this, - propName, - getPooledWarningPropertyDefinition(propName, Interface[propName]) - ); - } - } + for (var tempB = instB; tempB; tempB = getParent(tempB)) { + depthB++; + } // If A is deeper, crawl up. - this.dispatchConfig = null; - this._targetInst = null; - this.nativeEvent = null; - this.isDefaultPrevented = functionThatReturnsFalse; - this.isPropagationStopped = functionThatReturnsFalse; - this._dispatchListeners = null; - this._dispatchInstances = null; + while (depthA - depthB > 0) { + instA = getParent(instA); + depthA--; + } // If B is deeper, crawl up. - { - Object.defineProperty( - this, - "nativeEvent", - getPooledWarningPropertyDefinition("nativeEvent", null) - ); - Object.defineProperty( - this, - "isDefaultPrevented", - getPooledWarningPropertyDefinition( - "isDefaultPrevented", - functionThatReturnsFalse - ) - ); - Object.defineProperty( - this, - "isPropagationStopped", - getPooledWarningPropertyDefinition( - "isPropagationStopped", - functionThatReturnsFalse - ) - ); - Object.defineProperty( - this, - "preventDefault", - getPooledWarningPropertyDefinition("preventDefault", function() {}) - ); - Object.defineProperty( - this, - "stopPropagation", - getPooledWarningPropertyDefinition("stopPropagation", function() {}) - ); + while (depthB - depthA > 0) { + instB = getParent(instB); + depthB--; + } // Walk in lockstep until we find a match. + + var depth = depthA; + + while (depth--) { + if (instA === instB || instA === instB.alternate) { + return instA; } + + instA = getParent(instA); + instB = getParent(instB); } -}); -SyntheticEvent.Interface = EventInterface; + + return null; +} /** - * Helper to reduce boilerplate when creating subclasses. + * Return if A is an ancestor of B. */ -SyntheticEvent.extend = function(Interface) { - var Super = this; - - var E = function() {}; - - E.prototype = Super.prototype; - var prototype = new E(); +function isAncestor(instA, instB) { + while (instB) { + if (instA === instB || instA === instB.alternate) { + return true; + } - function Class() { - return Super.apply(this, arguments); + instB = getParent(instB); } - Object.assign(prototype, Class.prototype); - Class.prototype = prototype; - Class.prototype.constructor = Class; - Class.Interface = Object.assign({}, Super.Interface, Interface); - Class.extend = Super.extend; - addEventPoolingTo(Class); - return Class; -}; + return false; +} +/** + * Return the parent instance of the passed-in instance. + */ -addEventPoolingTo(SyntheticEvent); +function getParentInstance(inst) { + return getParent(inst); +} /** - * Helper to nullify syntheticEvent instance properties when destructing - * - * @param {String} propName - * @param {?object} getVal - * @return {object} defineProperty object + * Simulates the traversal of a two-phase, capture/bubble event dispatch. */ -function getPooledWarningPropertyDefinition(propName, getVal) { - var isFunction = typeof getVal === "function"; - return { - configurable: true, - set: set, - get: get - }; +function traverseTwoPhase(inst, fn, arg) { + var path = []; - function set(val) { - var action = isFunction ? "setting the method" : "setting the property"; - warn(action, "This is effectively a no-op"); - return val; + while (inst) { + path.push(inst); + inst = getParent(inst); } - function get() { - var action = isFunction ? "accessing the method" : "accessing the property"; - var result = isFunction - ? "This is a no-op function" - : "This is set to null"; - warn(action, result); - return getVal; - } + var i; - function warn(action, result) { - { - error( - "This synthetic event is reused for performance reasons. If you're seeing this, " + - "you're %s `%s` on a released/nullified synthetic event. %s. " + - "If you must keep the original synthetic event around, use event.persist(). " + - "See https://fb.me/react-event-pooling for more information.", - action, - propName, - result - ); - } + for (i = path.length; i-- > 0; ) { + fn(path[i], "captured", arg); } -} -function getPooledEvent(dispatchConfig, targetInst, nativeEvent, nativeInst) { - var EventConstructor = this; - - if (EventConstructor.eventPool.length) { - var instance = EventConstructor.eventPool.pop(); - EventConstructor.call( - instance, - dispatchConfig, - targetInst, - nativeEvent, - nativeInst - ); - return instance; + for (i = 0; i < path.length; i++) { + fn(path[i], "bubbled", arg); } - - return new EventConstructor( - dispatchConfig, - targetInst, - nativeEvent, - nativeInst - ); } +/** + * Traverses the ID hierarchy and invokes the supplied `cb` on any IDs that + * should would receive a `mouseEnter` or `mouseLeave` event. + * + * Does not invoke the callback on the nearest common ancestor because nothing + * "entered" or "left" that element. + */ -function releasePooledEvent(event) { - var EventConstructor = this; - - if (!(event instanceof EventConstructor)) { - throw Error( - "Trying to release an event instance into a pool of a different type." - ); - } - - event.destructor(); - - if (EventConstructor.eventPool.length < EVENT_POOL_SIZE) { - EventConstructor.eventPool.push(event); - } -} - -function addEventPoolingTo(EventConstructor) { - EventConstructor.eventPool = []; - EventConstructor.getPooled = getPooledEvent; - EventConstructor.release = releasePooledEvent; +/** + * Some event types have a notion of different registration names for different + * "phases" of propagation. This finds listeners by a given phase. + */ +function listenerAtPhase(inst, event, propagationPhase) { + var registrationName = + event.dispatchConfig.phasedRegistrationNames[propagationPhase]; + return getListener(inst, registrationName); } +/** + * A small set of propagation patterns, each of which will accept a small amount + * of information, and generate a set of "dispatch ready event objects" - which + * are sets of events that have already been annotated with a set of dispatched + * listener functions/ids. The API is designed this way to discourage these + * propagation strategies from actually executing the dispatches, since we + * always want to collect the entire set of dispatches before executing even a + * single one. + */ /** - * `touchHistory` isn't actually on the native event, but putting it in the - * interface will ensure that it is cleaned up when pooled/destroyed. The - * `ResponderEventPlugin` will populate it appropriately. + * Tags a `SyntheticEvent` with dispatched listeners. Creating this function + * here, allows us to not have to bind or create functions for each event. + * Mutating the event's members allows us to not have to create a wrapping + * "dispatch" object that pairs the event with the listener. */ -var ResponderSyntheticEvent = SyntheticEvent.extend({ - touchHistory: function(nativeEvent) { - return null; // Actually doesn't even look at the native event. +function accumulateDirectionalDispatches(inst, phase, event) { + { + !inst + ? warningWithoutStack$1(false, "Dispatching inst must not be null") + : void 0; } -}); -var TOP_TOUCH_START = "topTouchStart"; -var TOP_TOUCH_MOVE = "topTouchMove"; -var TOP_TOUCH_END = "topTouchEnd"; -var TOP_TOUCH_CANCEL = "topTouchCancel"; -var TOP_SCROLL = "topScroll"; -var TOP_SELECTION_CHANGE = "topSelectionChange"; -function isStartish(topLevelType) { - return topLevelType === TOP_TOUCH_START; -} -function isMoveish(topLevelType) { - return topLevelType === TOP_TOUCH_MOVE; -} -function isEndish(topLevelType) { - return topLevelType === TOP_TOUCH_END || topLevelType === TOP_TOUCH_CANCEL; -} -var startDependencies = [TOP_TOUCH_START]; -var moveDependencies = [TOP_TOUCH_MOVE]; -var endDependencies = [TOP_TOUCH_CANCEL, TOP_TOUCH_END]; + var listener = listenerAtPhase(inst, event, phase); + if (listener) { + event._dispatchListeners = accumulateInto( + event._dispatchListeners, + listener + ); + event._dispatchInstances = accumulateInto(event._dispatchInstances, inst); + } +} /** - * Tracks the position and time of each active touch by `touch.identifier`. We - * should typically only see IDs in the range of 1-20 because IDs get recycled - * when touches end and start again. + * Collect dispatches (must be entirely collected before dispatching - see unit + * tests). Lazily allocate the array to conserve memory. We must loop through + * each event and perform the traversal for each one. We cannot perform a + * single traversal for the entire collection of events because each event may + * have a different target. */ -var MAX_TOUCH_BANK = 20; -var touchBank = []; -var touchHistory = { - touchBank: touchBank, - numberActiveTouches: 0, - // If there is only one active touch, we remember its location. This prevents - // us having to loop through all of the touches all the time in the most - // common case. - indexOfSingleActiveTouch: -1, - mostRecentTimeStamp: 0 -}; - -function timestampForTouch(touch) { - // The legacy internal implementation provides "timeStamp", which has been - // renamed to "timestamp". Let both work for now while we iron it out - // TODO (evv): rename timeStamp to timestamp in internal code - return touch.timeStamp || touch.timestamp; +function accumulateTwoPhaseDispatchesSingle(event) { + if (event && event.dispatchConfig.phasedRegistrationNames) { + traverseTwoPhase(event._targetInst, accumulateDirectionalDispatches, event); + } } /** - * TODO: Instead of making gestures recompute filtered velocity, we could - * include a built in velocity computation that can be reused globally. + * Same as `accumulateTwoPhaseDispatchesSingle`, but skips over the targetID. */ -function createTouchRecord(touch) { - return { - touchActive: true, - startPageX: touch.pageX, - startPageY: touch.pageY, - startTimeStamp: timestampForTouch(touch), - currentPageX: touch.pageX, - currentPageY: touch.pageY, - currentTimeStamp: timestampForTouch(touch), - previousPageX: touch.pageX, - previousPageY: touch.pageY, - previousTimeStamp: timestampForTouch(touch) - }; -} - -function resetTouchRecord(touchRecord, touch) { - touchRecord.touchActive = true; - touchRecord.startPageX = touch.pageX; - touchRecord.startPageY = touch.pageY; - touchRecord.startTimeStamp = timestampForTouch(touch); - touchRecord.currentPageX = touch.pageX; - touchRecord.currentPageY = touch.pageY; - touchRecord.currentTimeStamp = timestampForTouch(touch); - touchRecord.previousPageX = touch.pageX; - touchRecord.previousPageY = touch.pageY; - touchRecord.previousTimeStamp = timestampForTouch(touch); +function accumulateTwoPhaseDispatchesSingleSkipTarget(event) { + if (event && event.dispatchConfig.phasedRegistrationNames) { + var targetInst = event._targetInst; + var parentInst = targetInst ? getParentInstance(targetInst) : null; + traverseTwoPhase(parentInst, accumulateDirectionalDispatches, event); + } } +/** + * Accumulates without regard to direction, does not look for phased + * registration names. Same as `accumulateDirectDispatchesSingle` but without + * requiring that the `dispatchMarker` be the same as the dispatched ID. + */ -function getTouchIdentifier(_ref) { - var identifier = _ref.identifier; - - if (!(identifier != null)) { - throw Error("Touch object is missing identifier."); - } +function accumulateDispatches(inst, ignoredDirection, event) { + if (inst && event && event.dispatchConfig.registrationName) { + var registrationName = event.dispatchConfig.registrationName; + var listener = getListener(inst, registrationName); - { - if (identifier > MAX_TOUCH_BANK) { - error( - "Touch identifier %s is greater than maximum supported %s which causes " + - "performance issues backfilling array locations for all of the indices.", - identifier, - MAX_TOUCH_BANK + if (listener) { + event._dispatchListeners = accumulateInto( + event._dispatchListeners, + listener ); + event._dispatchInstances = accumulateInto(event._dispatchInstances, inst); } } - - return identifier; } +/** + * Accumulates dispatches on an `SyntheticEvent`, but only for the + * `dispatchMarker`. + * @param {SyntheticEvent} event + */ -function recordTouchStart(touch) { - var identifier = getTouchIdentifier(touch); - var touchRecord = touchBank[identifier]; - - if (touchRecord) { - resetTouchRecord(touchRecord, touch); - } else { - touchBank[identifier] = createTouchRecord(touch); +function accumulateDirectDispatchesSingle(event) { + if (event && event.dispatchConfig.registrationName) { + accumulateDispatches(event._targetInst, null, event); } - - touchHistory.mostRecentTimeStamp = timestampForTouch(touch); } -function recordTouchMove(touch) { - var touchRecord = touchBank[getTouchIdentifier(touch)]; - - if (touchRecord) { - touchRecord.touchActive = true; - touchRecord.previousPageX = touchRecord.currentPageX; - touchRecord.previousPageY = touchRecord.currentPageY; - touchRecord.previousTimeStamp = touchRecord.currentTimeStamp; - touchRecord.currentPageX = touch.pageX; - touchRecord.currentPageY = touch.pageY; - touchRecord.currentTimeStamp = timestampForTouch(touch); - touchHistory.mostRecentTimeStamp = timestampForTouch(touch); - } else { - { - warn( - "Cannot record touch move without a touch start.\n" + - "Touch Move: %s\n" + - "Touch Bank: %s", - printTouch(touch), - printTouchBank() - ); - } - } +function accumulateTwoPhaseDispatches(events) { + forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle); } - -function recordTouchEnd(touch) { - var touchRecord = touchBank[getTouchIdentifier(touch)]; - - if (touchRecord) { - touchRecord.touchActive = false; - touchRecord.previousPageX = touchRecord.currentPageX; - touchRecord.previousPageY = touchRecord.currentPageY; - touchRecord.previousTimeStamp = touchRecord.currentTimeStamp; - touchRecord.currentPageX = touch.pageX; - touchRecord.currentPageY = touch.pageY; - touchRecord.currentTimeStamp = timestampForTouch(touch); - touchHistory.mostRecentTimeStamp = timestampForTouch(touch); - } else { - { - warn( - "Cannot record touch end without a touch start.\n" + - "Touch End: %s\n" + - "Touch Bank: %s", - printTouch(touch), - printTouchBank() - ); - } - } +function accumulateTwoPhaseDispatchesSkipTarget(events) { + forEachAccumulated(events, accumulateTwoPhaseDispatchesSingleSkipTarget); } -function printTouch(touch) { - return JSON.stringify({ - identifier: touch.identifier, - pageX: touch.pageX, - pageY: touch.pageY, - timestamp: timestampForTouch(touch) - }); +function accumulateDirectDispatches(events) { + forEachAccumulated(events, accumulateDirectDispatchesSingle); } -function printTouchBank() { - var printed = JSON.stringify(touchBank.slice(0, MAX_TOUCH_BANK)); +/* eslint valid-typeof: 0 */ +var EVENT_POOL_SIZE = 10; +/** + * @interface Event + * @see http://www.w3.org/TR/DOM-Level-3-Events/ + */ - if (touchBank.length > MAX_TOUCH_BANK) { - printed += " (original size: " + touchBank.length + ")"; - } +var EventInterface = { + type: null, + target: null, + // currentTarget is set when dispatching; no use in copying it here + currentTarget: function() { + return null; + }, + eventPhase: null, + bubbles: null, + cancelable: null, + timeStamp: function(event) { + return event.timeStamp || Date.now(); + }, + defaultPrevented: null, + isTrusted: null +}; - return printed; +function functionThatReturnsTrue() { + return true; } -var ResponderTouchHistoryStore = { - recordTouchTrack: function(topLevelType, nativeEvent) { - if (isMoveish(topLevelType)) { - nativeEvent.changedTouches.forEach(recordTouchMove); - } else if (isStartish(topLevelType)) { - nativeEvent.changedTouches.forEach(recordTouchStart); - touchHistory.numberActiveTouches = nativeEvent.touches.length; - - if (touchHistory.numberActiveTouches === 1) { - touchHistory.indexOfSingleActiveTouch = - nativeEvent.touches[0].identifier; - } - } else if (isEndish(topLevelType)) { - nativeEvent.changedTouches.forEach(recordTouchEnd); - touchHistory.numberActiveTouches = nativeEvent.touches.length; - - if (touchHistory.numberActiveTouches === 1) { - for (var i = 0; i < touchBank.length; i++) { - var touchTrackToCheck = touchBank[i]; - - if (touchTrackToCheck != null && touchTrackToCheck.touchActive) { - touchHistory.indexOfSingleActiveTouch = i; - break; - } - } - - { - var activeRecord = touchBank[touchHistory.indexOfSingleActiveTouch]; - - if (activeRecord == null || !activeRecord.touchActive) { - error("Cannot find single active touch."); - } - } - } - } - }, - touchHistory: touchHistory -}; - +function functionThatReturnsFalse() { + return false; +} /** - * Accumulates items that must not be null or undefined. + * Synthetic events are dispatched by event plugins, typically in response to a + * top-level event delegation handler. * - * This is used to conserve memory by avoiding array allocations. + * These systems should generally use pooling to reduce the frequency of garbage + * collection. The system should check `isPersistent` to determine whether the + * event should be released into the pool after being dispatched. Users that + * need a persisted event should invoke `persist`. * - * @return {*|array<*>} An accumulation of items. + * Synthetic events (and subclasses) implement the DOM Level 3 Events API by + * normalizing browser quirks. Subclasses do not necessarily have to implement a + * DOM interface; custom application-specific events can also subclass this. + * + * @param {object} dispatchConfig Configuration used to dispatch this event. + * @param {*} targetInst Marker identifying the event target. + * @param {object} nativeEvent Native browser event. + * @param {DOMEventTarget} nativeEventTarget Target node. */ -function accumulate(current, next) { - if (!(next != null)) { - throw Error( - "accumulate(...): Accumulated items must not be null or undefined." - ); +function SyntheticEvent( + dispatchConfig, + targetInst, + nativeEvent, + nativeEventTarget +) { + { + // these have a getter/setter for warnings + delete this.nativeEvent; + delete this.preventDefault; + delete this.stopPropagation; + delete this.isDefaultPrevented; + delete this.isPropagationStopped; } - if (current == null) { - return next; - } // Both are not empty. Warning: Never call x.concat(y) when you are not - // certain that x is an Array (x could be a string with concat method). + this.dispatchConfig = dispatchConfig; + this._targetInst = targetInst; + this.nativeEvent = nativeEvent; + var Interface = this.constructor.Interface; - if (Array.isArray(current)) { - return current.concat(next); + for (var propName in Interface) { + if (!Interface.hasOwnProperty(propName)) { + continue; + } + + { + delete this[propName]; // this has a getter/setter for warnings + } + + var normalize = Interface[propName]; + + if (normalize) { + this[propName] = normalize(nativeEvent); + } else { + if (propName === "target") { + this.target = nativeEventTarget; + } else { + this[propName] = nativeEvent[propName]; + } + } } - if (Array.isArray(next)) { - return [current].concat(next); + var defaultPrevented = + nativeEvent.defaultPrevented != null + ? nativeEvent.defaultPrevented + : nativeEvent.returnValue === false; + + if (defaultPrevented) { + this.isDefaultPrevented = functionThatReturnsTrue; + } else { + this.isDefaultPrevented = functionThatReturnsFalse; } - return [current, next]; + this.isPropagationStopped = functionThatReturnsFalse; + return this; } -/** - * Instance of element that should respond to touch/move types of interactions, - * as indicated explicitly by relevant callbacks. - */ +Object.assign(SyntheticEvent.prototype, { + preventDefault: function() { + this.defaultPrevented = true; + var event = this.nativeEvent; -var responderInst = null; -/** - * Count of current touches. A textInput should become responder iff the - * selection changes while there is a touch on the screen. - */ + if (!event) { + return; + } -var trackedTouchCount = 0; + if (event.preventDefault) { + event.preventDefault(); + } else if (typeof event.returnValue !== "unknown") { + event.returnValue = false; + } -var changeResponder = function(nextResponderInst, blockHostResponder) { - var oldResponderInst = responderInst; - responderInst = nextResponderInst; + this.isDefaultPrevented = functionThatReturnsTrue; + }, + stopPropagation: function() { + var event = this.nativeEvent; - if (ResponderEventPlugin.GlobalResponderHandler !== null) { - ResponderEventPlugin.GlobalResponderHandler.onChange( - oldResponderInst, - nextResponderInst, - blockHostResponder - ); - } -}; + if (!event) { + return; + } -var eventTypes = { - /** - * On a `touchStart`/`mouseDown`, is it desired that this element become the - * responder? - */ - startShouldSetResponder: { - phasedRegistrationNames: { - bubbled: "onStartShouldSetResponder", - captured: "onStartShouldSetResponderCapture" - }, - dependencies: startDependencies + if (event.stopPropagation) { + event.stopPropagation(); + } else if (typeof event.cancelBubble !== "unknown") { + // The ChangeEventPlugin registers a "propertychange" event for + // IE. This event does not support bubbling or cancelling, and + // any references to cancelBubble throw "Member not found". A + // typeof check of "unknown" circumvents this issue (and is also + // IE specific). + event.cancelBubble = true; + } + + this.isPropagationStopped = functionThatReturnsTrue; }, /** - * On a `scroll`, is it desired that this element become the responder? This - * is usually not needed, but should be used to retroactively infer that a - * `touchStart` had occurred during momentum scroll. During a momentum scroll, - * a touch start will be immediately followed by a scroll event if the view is - * currently scrolling. - * - * TODO: This shouldn't bubble. + * We release all dispatched `SyntheticEvent`s after each event loop, adding + * them back into the pool. This allows a way to hold onto a reference that + * won't be added back into the pool. */ - scrollShouldSetResponder: { - phasedRegistrationNames: { - bubbled: "onScrollShouldSetResponder", - captured: "onScrollShouldSetResponderCapture" - }, - dependencies: [TOP_SCROLL] + persist: function() { + this.isPersistent = functionThatReturnsTrue; }, /** - * On text selection change, should this element become the responder? This - * is needed for text inputs or other views with native selection, so the - * JS view can claim the responder. + * Checks if this event should be released back into the pool. * - * TODO: This shouldn't bubble. + * @return {boolean} True if this should not be released, false otherwise. */ - selectionChangeShouldSetResponder: { - phasedRegistrationNames: { - bubbled: "onSelectionChangeShouldSetResponder", - captured: "onSelectionChangeShouldSetResponderCapture" - }, - dependencies: [TOP_SELECTION_CHANGE] - }, + isPersistent: functionThatReturnsFalse, /** - * On a `touchMove`/`mouseMove`, is it desired that this element become the - * responder? + * `PooledClass` looks for `destructor` on each instance it releases. */ - moveShouldSetResponder: { - phasedRegistrationNames: { - bubbled: "onMoveShouldSetResponder", - captured: "onMoveShouldSetResponderCapture" - }, - dependencies: moveDependencies - }, + destructor: function() { + var Interface = this.constructor.Interface; - /** - * Direct responder events dispatched directly to responder. Do not bubble. - */ - responderStart: { - registrationName: "onResponderStart", - dependencies: startDependencies - }, - responderMove: { - registrationName: "onResponderMove", - dependencies: moveDependencies - }, - responderEnd: { - registrationName: "onResponderEnd", - dependencies: endDependencies - }, - responderRelease: { - registrationName: "onResponderRelease", - dependencies: endDependencies - }, - responderTerminationRequest: { - registrationName: "onResponderTerminationRequest", - dependencies: [] - }, - responderGrant: { - registrationName: "onResponderGrant", - dependencies: [] - }, - responderReject: { - registrationName: "onResponderReject", - dependencies: [] - }, - responderTerminate: { - registrationName: "onResponderTerminate", - dependencies: [] + for (var propName in Interface) { + { + Object.defineProperty( + this, + propName, + getPooledWarningPropertyDefinition(propName, Interface[propName]) + ); + } + } + + this.dispatchConfig = null; + this._targetInst = null; + this.nativeEvent = null; + this.isDefaultPrevented = functionThatReturnsFalse; + this.isPropagationStopped = functionThatReturnsFalse; + this._dispatchListeners = null; + this._dispatchInstances = null; + + { + Object.defineProperty( + this, + "nativeEvent", + getPooledWarningPropertyDefinition("nativeEvent", null) + ); + Object.defineProperty( + this, + "isDefaultPrevented", + getPooledWarningPropertyDefinition( + "isDefaultPrevented", + functionThatReturnsFalse + ) + ); + Object.defineProperty( + this, + "isPropagationStopped", + getPooledWarningPropertyDefinition( + "isPropagationStopped", + functionThatReturnsFalse + ) + ); + Object.defineProperty( + this, + "preventDefault", + getPooledWarningPropertyDefinition("preventDefault", function() {}) + ); + Object.defineProperty( + this, + "stopPropagation", + getPooledWarningPropertyDefinition("stopPropagation", function() {}) + ); + } } -}; +}); +SyntheticEvent.Interface = EventInterface; /** - * - * Responder System: - * ---------------- - * - * - A global, solitary "interaction lock" on a view. - * - If a node becomes the responder, it should convey visual feedback - * immediately to indicate so, either by highlighting or moving accordingly. - * - To be the responder means, that touches are exclusively important to that - * responder view, and no other view. - * - While touches are still occurring, the responder lock can be transferred to - * a new view, but only to increasingly "higher" views (meaning ancestors of - * the current responder). - * - * Responder being granted: - * ------------------------ - * - * - Touch starts, moves, and scrolls can cause an ID to become the responder. - * - We capture/bubble `startShouldSetResponder`/`moveShouldSetResponder` to - * the "appropriate place". - * - If nothing is currently the responder, the "appropriate place" is the - * initiating event's `targetID`. - * - If something *is* already the responder, the "appropriate place" is the - * first common ancestor of the event target and the current `responderInst`. - * - Some negotiation happens: See the timing diagram below. - * - Scrolled views automatically become responder. The reasoning is that a - * platform scroll view that isn't built on top of the responder system has - * began scrolling, and the active responder must now be notified that the - * interaction is no longer locked to it - the system has taken over. - * - * - Responder being released: - * As soon as no more touches that *started* inside of descendants of the - * *current* responderInst, an `onResponderRelease` event is dispatched to the - * current responder, and the responder lock is released. - * - * TODO: - * - on "end", a callback hook for `onResponderEndShouldRemainResponder` that - * determines if the responder lock should remain. - * - If a view shouldn't "remain" the responder, any active touches should by - * default be considered "dead" and do not influence future negotiations or - * bubble paths. It should be as if those touches do not exist. - * -- For multitouch: Usually a translate-z will choose to "remain" responder - * after one out of many touches ended. For translate-y, usually the view - * doesn't wish to "remain" responder after one of many touches end. - * - Consider building this on top of a `stopPropagation` model similar to - * `W3C` events. - * - Ensure that `onResponderTerminate` is called on touch cancels, whether or - * not `onResponderTerminationRequest` returns `true` or `false`. - * + * Helper to reduce boilerplate when creating subclasses. */ -/* Negotiation Performed - +-----------------------+ - / \ -Process low level events to + Current Responder + wantsResponderID -determine who to perform negot-| (if any exists at all) | -iation/transition | Otherwise just pass through| --------------------------------+----------------------------+------------------+ -Bubble to find first ID | | -to return true:wantsResponderID| | - | | - +-------------+ | | - | onTouchStart| | | - +------+------+ none | | - | return| | -+-----------v-------------+true| +------------------------+ | -|onStartShouldSetResponder|----->|onResponderStart (cur) |<-----------+ -+-----------+-------------+ | +------------------------+ | | - | | | +--------+-------+ - | returned true for| false:REJECT +-------->|onResponderReject - | wantsResponderID | | | +----------------+ - | (now attempt | +------------------+-----+ | - | handoff) | | onResponder | | - +------------------->| TerminationRequest| | - | +------------------+-----+ | - | | | +----------------+ - | true:GRANT +-------->|onResponderGrant| - | | +--------+-------+ - | +------------------------+ | | - | | onResponderTerminate |<-----------+ - | +------------------+-----+ | - | | | +----------------+ - | +-------->|onResponderStart| - | | +----------------+ -Bubble to find first ID | | -to return true:wantsResponderID| | - | | - +-------------+ | | - | onTouchMove | | | - +------+------+ none | | - | return| | -+-----------v-------------+true| +------------------------+ | -|onMoveShouldSetResponder |----->|onResponderMove (cur) |<-----------+ -+-----------+-------------+ | +------------------------+ | | - | | | +--------+-------+ - | returned true for| false:REJECT +-------->|onResponderRejec| - | wantsResponderID | | | +----------------+ - | (now attempt | +------------------+-----+ | - | handoff) | | onResponder | | - +------------------->| TerminationRequest| | - | +------------------+-----+ | - | | | +----------------+ - | true:GRANT +-------->|onResponderGrant| - | | +--------+-------+ - | +------------------------+ | | - | | onResponderTerminate |<-----------+ - | +------------------+-----+ | - | | | +----------------+ - | +-------->|onResponderMove | - | | +----------------+ - | | - | | - Some active touch started| | - inside current responder | +------------------------+ | - +------------------------->| onResponderEnd | | - | | +------------------------+ | - +---+---------+ | | - | onTouchEnd | | | - +---+---------+ | | - | | +------------------------+ | - +------------------------->| onResponderEnd | | - No active touches started| +-----------+------------+ | - inside current responder | | | - | v | - | +------------------------+ | - | | onResponderRelease | | - | +------------------------+ | - | | - + + */ +SyntheticEvent.extend = function(Interface) { + var Super = this; + + var E = function() {}; + + E.prototype = Super.prototype; + var prototype = new E(); + + function Class() { + return Super.apply(this, arguments); + } + + Object.assign(prototype, Class.prototype); + Class.prototype = prototype; + Class.prototype.constructor = Class; + Class.Interface = Object.assign({}, Super.Interface, Interface); + Class.extend = Super.extend; + addEventPoolingTo(Class); + return Class; +}; +addEventPoolingTo(SyntheticEvent); /** - * A note about event ordering in the `EventPluginRegistry`. - * - * Suppose plugins are injected in the following order: - * - * `[R, S, C]` - * - * To help illustrate the example, assume `S` is `SimpleEventPlugin` (for - * `onClick` etc) and `R` is `ResponderEventPlugin`. - * - * "Deferred-Dispatched Events": - * - * - The current event plugin system will traverse the list of injected plugins, - * in order, and extract events by collecting the plugin's return value of - * `extractEvents()`. - * - These events that are returned from `extractEvents` are "deferred - * dispatched events". - * - When returned from `extractEvents`, deferred-dispatched events contain an - * "accumulation" of deferred dispatches. - * - These deferred dispatches are accumulated/collected before they are - * returned, but processed at a later time by the `EventPluginRegistry` (hence the - * name deferred). - * - * In the process of returning their deferred-dispatched events, event plugins - * themselves can dispatch events on-demand without returning them from - * `extractEvents`. Plugins might want to do this, so that they can use event - * dispatching as a tool that helps them decide which events should be extracted - * in the first place. - * - * "On-Demand-Dispatched Events": - * - * - On-demand-dispatched events are not returned from `extractEvents`. - * - On-demand-dispatched events are dispatched during the process of returning - * the deferred-dispatched events. - * - They should not have side effects. - * - They should be avoided, and/or eventually be replaced with another - * abstraction that allows event plugins to perform multiple "rounds" of event - * extraction. - * - * Therefore, the sequence of event dispatches becomes: - * - * - `R`s on-demand events (if any) (dispatched by `R` on-demand) - * - `S`s on-demand events (if any) (dispatched by `S` on-demand) - * - `C`s on-demand events (if any) (dispatched by `C` on-demand) - * - `R`s extracted events (if any) (dispatched by `EventPluginRegistry`) - * - `S`s extracted events (if any) (dispatched by `EventPluginRegistry`) - * - `C`s extracted events (if any) (dispatched by `EventPluginRegistry`) - * - * In the case of `ResponderEventPlugin`: If the `startShouldSetResponder` - * on-demand dispatch returns `true` (and some other details are satisfied) the - * `onResponderGrant` deferred dispatched event is returned from - * `extractEvents`. The sequence of dispatch executions in this case - * will appear as follows: + * Helper to nullify syntheticEvent instance properties when destructing * - * - `startShouldSetResponder` (`ResponderEventPlugin` dispatches on-demand) - * - `touchStartCapture` (`EventPluginRegistry` dispatches as usual) - * - `touchStart` (`EventPluginRegistry` dispatches as usual) - * - `responderGrant/Reject` (`EventPluginRegistry` dispatches as usual) + * @param {String} propName + * @param {?object} getVal + * @return {object} defineProperty object */ -function setResponderAndExtractTransfer( - topLevelType, - targetInst, - nativeEvent, - nativeEventTarget -) { - var shouldSetEventType = isStartish(topLevelType) - ? eventTypes.startShouldSetResponder - : isMoveish(topLevelType) - ? eventTypes.moveShouldSetResponder - : topLevelType === TOP_SELECTION_CHANGE - ? eventTypes.selectionChangeShouldSetResponder - : eventTypes.scrollShouldSetResponder; // TODO: stop one short of the current responder. +function getPooledWarningPropertyDefinition(propName, getVal) { + var isFunction = typeof getVal === "function"; + return { + configurable: true, + set: set, + get: get + }; - var bubbleShouldSetFrom = !responderInst - ? targetInst - : getLowestCommonAncestor(responderInst, targetInst); // When capturing/bubbling the "shouldSet" event, we want to skip the target - // (deepest ID) if it happens to be the current responder. The reasoning: - // It's strange to get an `onMoveShouldSetResponder` when you're *already* - // the responder. + function set(val) { + var action = isFunction ? "setting the method" : "setting the property"; + warn(action, "This is effectively a no-op"); + return val; + } - var skipOverBubbleShouldSetFrom = bubbleShouldSetFrom === responderInst; - var shouldSetEvent = ResponderSyntheticEvent.getPooled( - shouldSetEventType, - bubbleShouldSetFrom, + function get() { + var action = isFunction ? "accessing the method" : "accessing the property"; + var result = isFunction + ? "This is a no-op function" + : "This is set to null"; + warn(action, result); + return getVal; + } + + function warn(action, result) { + var warningCondition = false; + !warningCondition + ? warningWithoutStack$1( + false, + "This synthetic event is reused for performance reasons. If you're seeing this, " + + "you're %s `%s` on a released/nullified synthetic event. %s. " + + "If you must keep the original synthetic event around, use event.persist(). " + + "See https://fb.me/react-event-pooling for more information.", + action, + propName, + result + ) + : void 0; + } +} + +function getPooledEvent(dispatchConfig, targetInst, nativeEvent, nativeInst) { + var EventConstructor = this; + + if (EventConstructor.eventPool.length) { + var instance = EventConstructor.eventPool.pop(); + EventConstructor.call( + instance, + dispatchConfig, + targetInst, + nativeEvent, + nativeInst + ); + return instance; + } + + return new EventConstructor( + dispatchConfig, + targetInst, nativeEvent, - nativeEventTarget + nativeInst ); - shouldSetEvent.touchHistory = ResponderTouchHistoryStore.touchHistory; +} + +function releasePooledEvent(event) { + var EventConstructor = this; + + if (!(event instanceof EventConstructor)) { + throw Error( + "Trying to release an event instance into a pool of a different type." + ); + } + + event.destructor(); + + if (EventConstructor.eventPool.length < EVENT_POOL_SIZE) { + EventConstructor.eventPool.push(event); + } +} + +function addEventPoolingTo(EventConstructor) { + EventConstructor.eventPool = []; + EventConstructor.getPooled = getPooledEvent; + EventConstructor.release = releasePooledEvent; +} + +/** + * `touchHistory` isn't actually on the native event, but putting it in the + * interface will ensure that it is cleaned up when pooled/destroyed. The + * `ResponderEventPlugin` will populate it appropriately. + */ + +var ResponderSyntheticEvent = SyntheticEvent.extend({ + touchHistory: function(nativeEvent) { + return null; // Actually doesn't even look at the native event. + } +}); + +var TOP_TOUCH_START = "topTouchStart"; +var TOP_TOUCH_MOVE = "topTouchMove"; +var TOP_TOUCH_END = "topTouchEnd"; +var TOP_TOUCH_CANCEL = "topTouchCancel"; +var TOP_SCROLL = "topScroll"; +var TOP_SELECTION_CHANGE = "topSelectionChange"; +function isStartish(topLevelType) { + return topLevelType === TOP_TOUCH_START; +} +function isMoveish(topLevelType) { + return topLevelType === TOP_TOUCH_MOVE; +} +function isEndish(topLevelType) { + return topLevelType === TOP_TOUCH_END || topLevelType === TOP_TOUCH_CANCEL; +} +var startDependencies = [TOP_TOUCH_START]; +var moveDependencies = [TOP_TOUCH_MOVE]; +var endDependencies = [TOP_TOUCH_CANCEL, TOP_TOUCH_END]; + +/** + * Tracks the position and time of each active touch by `touch.identifier`. We + * should typically only see IDs in the range of 1-20 because IDs get recycled + * when touches end and start again. + */ + +var MAX_TOUCH_BANK = 20; +var touchBank = []; +var touchHistory = { + touchBank: touchBank, + numberActiveTouches: 0, + // If there is only one active touch, we remember its location. This prevents + // us having to loop through all of the touches all the time in the most + // common case. + indexOfSingleActiveTouch: -1, + mostRecentTimeStamp: 0 +}; + +function timestampForTouch(touch) { + // The legacy internal implementation provides "timeStamp", which has been + // renamed to "timestamp". Let both work for now while we iron it out + // TODO (evv): rename timeStamp to timestamp in internal code + return touch.timeStamp || touch.timestamp; +} +/** + * TODO: Instead of making gestures recompute filtered velocity, we could + * include a built in velocity computation that can be reused globally. + */ + +function createTouchRecord(touch) { + return { + touchActive: true, + startPageX: touch.pageX, + startPageY: touch.pageY, + startTimeStamp: timestampForTouch(touch), + currentPageX: touch.pageX, + currentPageY: touch.pageY, + currentTimeStamp: timestampForTouch(touch), + previousPageX: touch.pageX, + previousPageY: touch.pageY, + previousTimeStamp: timestampForTouch(touch) + }; +} + +function resetTouchRecord(touchRecord, touch) { + touchRecord.touchActive = true; + touchRecord.startPageX = touch.pageX; + touchRecord.startPageY = touch.pageY; + touchRecord.startTimeStamp = timestampForTouch(touch); + touchRecord.currentPageX = touch.pageX; + touchRecord.currentPageY = touch.pageY; + touchRecord.currentTimeStamp = timestampForTouch(touch); + touchRecord.previousPageX = touch.pageX; + touchRecord.previousPageY = touch.pageY; + touchRecord.previousTimeStamp = timestampForTouch(touch); +} + +function getTouchIdentifier(_ref) { + var identifier = _ref.identifier; + + if (!(identifier != null)) { + throw Error("Touch object is missing identifier."); + } + + { + !(identifier <= MAX_TOUCH_BANK) + ? warningWithoutStack$1( + false, + "Touch identifier %s is greater than maximum supported %s which causes " + + "performance issues backfilling array locations for all of the indices.", + identifier, + MAX_TOUCH_BANK + ) + : void 0; + } + + return identifier; +} - if (skipOverBubbleShouldSetFrom) { - accumulateTwoPhaseDispatchesSkipTarget(shouldSetEvent); +function recordTouchStart(touch) { + var identifier = getTouchIdentifier(touch); + var touchRecord = touchBank[identifier]; + + if (touchRecord) { + resetTouchRecord(touchRecord, touch); } else { - accumulateTwoPhaseDispatches(shouldSetEvent); + touchBank[identifier] = createTouchRecord(touch); } - var wantsResponderInst = executeDispatchesInOrderStopAtTrue(shouldSetEvent); + touchHistory.mostRecentTimeStamp = timestampForTouch(touch); +} - if (!shouldSetEvent.isPersistent()) { - shouldSetEvent.constructor.release(shouldSetEvent); - } +function recordTouchMove(touch) { + var touchRecord = touchBank[getTouchIdentifier(touch)]; - if (!wantsResponderInst || wantsResponderInst === responderInst) { - return null; + if (touchRecord) { + touchRecord.touchActive = true; + touchRecord.previousPageX = touchRecord.currentPageX; + touchRecord.previousPageY = touchRecord.currentPageY; + touchRecord.previousTimeStamp = touchRecord.currentTimeStamp; + touchRecord.currentPageX = touch.pageX; + touchRecord.currentPageY = touch.pageY; + touchRecord.currentTimeStamp = timestampForTouch(touch); + touchHistory.mostRecentTimeStamp = timestampForTouch(touch); + } else { + console.warn( + "Cannot record touch move without a touch start.\n" + "Touch Move: %s\n", + "Touch Bank: %s", + printTouch(touch), + printTouchBank() + ); } +} - var extracted; - var grantEvent = ResponderSyntheticEvent.getPooled( - eventTypes.responderGrant, - wantsResponderInst, - nativeEvent, - nativeEventTarget - ); - grantEvent.touchHistory = ResponderTouchHistoryStore.touchHistory; - accumulateDirectDispatches(grantEvent); - var blockHostResponder = executeDirectDispatch(grantEvent) === true; +function recordTouchEnd(touch) { + var touchRecord = touchBank[getTouchIdentifier(touch)]; - if (responderInst) { - var terminationRequestEvent = ResponderSyntheticEvent.getPooled( - eventTypes.responderTerminationRequest, - responderInst, - nativeEvent, - nativeEventTarget + if (touchRecord) { + touchRecord.touchActive = false; + touchRecord.previousPageX = touchRecord.currentPageX; + touchRecord.previousPageY = touchRecord.currentPageY; + touchRecord.previousTimeStamp = touchRecord.currentTimeStamp; + touchRecord.currentPageX = touch.pageX; + touchRecord.currentPageY = touch.pageY; + touchRecord.currentTimeStamp = timestampForTouch(touch); + touchHistory.mostRecentTimeStamp = timestampForTouch(touch); + } else { + console.warn( + "Cannot record touch end without a touch start.\n" + "Touch End: %s\n", + "Touch Bank: %s", + printTouch(touch), + printTouchBank() ); - terminationRequestEvent.touchHistory = - ResponderTouchHistoryStore.touchHistory; - accumulateDirectDispatches(terminationRequestEvent); - var shouldSwitch = - !hasDispatches(terminationRequestEvent) || - executeDirectDispatch(terminationRequestEvent); + } +} - if (!terminationRequestEvent.isPersistent()) { - terminationRequestEvent.constructor.release(terminationRequestEvent); - } +function printTouch(touch) { + return JSON.stringify({ + identifier: touch.identifier, + pageX: touch.pageX, + pageY: touch.pageY, + timestamp: timestampForTouch(touch) + }); +} - if (shouldSwitch) { - var terminateEvent = ResponderSyntheticEvent.getPooled( - eventTypes.responderTerminate, - responderInst, - nativeEvent, - nativeEventTarget - ); - terminateEvent.touchHistory = ResponderTouchHistoryStore.touchHistory; - accumulateDirectDispatches(terminateEvent); - extracted = accumulate(extracted, [grantEvent, terminateEvent]); - changeResponder(wantsResponderInst, blockHostResponder); - } else { - var rejectEvent = ResponderSyntheticEvent.getPooled( - eventTypes.responderReject, - wantsResponderInst, - nativeEvent, - nativeEventTarget - ); - rejectEvent.touchHistory = ResponderTouchHistoryStore.touchHistory; - accumulateDirectDispatches(rejectEvent); - extracted = accumulate(extracted, rejectEvent); - } - } else { - extracted = accumulate(extracted, grantEvent); - changeResponder(wantsResponderInst, blockHostResponder); +function printTouchBank() { + var printed = JSON.stringify(touchBank.slice(0, MAX_TOUCH_BANK)); + + if (touchBank.length > MAX_TOUCH_BANK) { + printed += " (original size: " + touchBank.length + ")"; } - return extracted; + return printed; } + +var ResponderTouchHistoryStore = { + recordTouchTrack: function(topLevelType, nativeEvent) { + if (isMoveish(topLevelType)) { + nativeEvent.changedTouches.forEach(recordTouchMove); + } else if (isStartish(topLevelType)) { + nativeEvent.changedTouches.forEach(recordTouchStart); + touchHistory.numberActiveTouches = nativeEvent.touches.length; + + if (touchHistory.numberActiveTouches === 1) { + touchHistory.indexOfSingleActiveTouch = + nativeEvent.touches[0].identifier; + } + } else if (isEndish(topLevelType)) { + nativeEvent.changedTouches.forEach(recordTouchEnd); + touchHistory.numberActiveTouches = nativeEvent.touches.length; + + if (touchHistory.numberActiveTouches === 1) { + for (var i = 0; i < touchBank.length; i++) { + var touchTrackToCheck = touchBank[i]; + + if (touchTrackToCheck != null && touchTrackToCheck.touchActive) { + touchHistory.indexOfSingleActiveTouch = i; + break; + } + } + + { + var activeRecord = touchBank[touchHistory.indexOfSingleActiveTouch]; + !(activeRecord != null && activeRecord.touchActive) + ? warningWithoutStack$1(false, "Cannot find single active touch.") + : void 0; + } + } + } + }, + touchHistory: touchHistory +}; + /** - * A transfer is a negotiation between a currently set responder and the next - * element to claim responder status. Any start event could trigger a transfer - * of responderInst. Any move event could trigger a transfer. + * Accumulates items that must not be null or undefined. * - * @param {string} topLevelType Record from `BrowserEventConstants`. - * @return {boolean} True if a transfer of responder could possibly occur. + * This is used to conserve memory by avoiding array allocations. + * + * @return {*|array<*>} An accumulation of items. */ -function canTriggerTransfer(topLevelType, topLevelInst, nativeEvent) { - return ( - topLevelInst && // responderIgnoreScroll: We are trying to migrate away from specifically - // tracking native scroll events here and responderIgnoreScroll indicates we - // will send topTouchCancel to handle canceling touch events instead - ((topLevelType === TOP_SCROLL && !nativeEvent.responderIgnoreScroll) || - (trackedTouchCount > 0 && topLevelType === TOP_SELECTION_CHANGE) || - isStartish(topLevelType) || - isMoveish(topLevelType)) - ); +function accumulate(current, next) { + if (!(next != null)) { + throw Error( + "accumulate(...): Accumulated items must not be null or undefined." + ); + } + + if (current == null) { + return next; + } // Both are not empty. Warning: Never call x.concat(y) when you are not + // certain that x is an Array (x could be a string with concat method). + + if (Array.isArray(current)) { + return current.concat(next); + } + + if (Array.isArray(next)) { + return [current].concat(next); + } + + return [current, next]; } + /** - * Returns whether or not this touch end event makes it such that there are no - * longer any touches that started inside of the current `responderInst`. - * - * @param {NativeEvent} nativeEvent Native touch end event. - * @return {boolean} Whether or not this touch end event ends the responder. + * Instance of element that should respond to touch/move types of interactions, + * as indicated explicitly by relevant callbacks. */ -function noResponderTouches(nativeEvent) { - var touches = nativeEvent.touches; - - if (!touches || touches.length === 0) { - return true; - } +var responderInst = null; +/** + * Count of current touches. A textInput should become responder iff the + * selection changes while there is a touch on the screen. + */ - for (var i = 0; i < touches.length; i++) { - var activeTouch = touches[i]; - var target = activeTouch.target; +var trackedTouchCount = 0; - if (target !== null && target !== undefined && target !== 0) { - // Is the original touch location inside of the current responder? - var targetInst = getInstanceFromNode(target); +var changeResponder = function(nextResponderInst, blockHostResponder) { + var oldResponderInst = responderInst; + responderInst = nextResponderInst; - if (isAncestor(responderInst, targetInst)) { - return false; - } - } + if (ResponderEventPlugin.GlobalResponderHandler !== null) { + ResponderEventPlugin.GlobalResponderHandler.onChange( + oldResponderInst, + nextResponderInst, + blockHostResponder + ); } +}; - return true; -} +var eventTypes = { + /** + * On a `touchStart`/`mouseDown`, is it desired that this element become the + * responder? + */ + startShouldSetResponder: { + phasedRegistrationNames: { + bubbled: "onStartShouldSetResponder", + captured: "onStartShouldSetResponderCapture" + }, + dependencies: startDependencies + }, -var ResponderEventPlugin = { - /* For unit testing only */ - _getResponder: function() { - return responderInst; + /** + * On a `scroll`, is it desired that this element become the responder? This + * is usually not needed, but should be used to retroactively infer that a + * `touchStart` had occurred during momentum scroll. During a momentum scroll, + * a touch start will be immediately followed by a scroll event if the view is + * currently scrolling. + * + * TODO: This shouldn't bubble. + */ + scrollShouldSetResponder: { + phasedRegistrationNames: { + bubbled: "onScrollShouldSetResponder", + captured: "onScrollShouldSetResponderCapture" + }, + dependencies: [TOP_SCROLL] }, - eventTypes: eventTypes, /** - * We must be resilient to `targetInst` being `null` on `touchMove` or - * `touchEnd`. On certain platforms, this means that a native scroll has - * assumed control and the original touch targets are destroyed. + * On text selection change, should this element become the responder? This + * is needed for text inputs or other views with native selection, so the + * JS view can claim the responder. + * + * TODO: This shouldn't bubble. */ - extractEvents: function( - topLevelType, - targetInst, - nativeEvent, - nativeEventTarget, - eventSystemFlags - ) { - if (isStartish(topLevelType)) { - trackedTouchCount += 1; - } else if (isEndish(topLevelType)) { - if (trackedTouchCount >= 0) { - trackedTouchCount -= 1; - } else { - { - warn( - "Ended a touch event which was not counted in `trackedTouchCount`." - ); - } - - return null; - } - } - - ResponderTouchHistoryStore.recordTouchTrack(topLevelType, nativeEvent); - var extracted = canTriggerTransfer(topLevelType, targetInst, nativeEvent) - ? setResponderAndExtractTransfer( - topLevelType, - targetInst, - nativeEvent, - nativeEventTarget - ) - : null; // Responder may or may not have transferred on a new touch start/move. - // Regardless, whoever is the responder after any potential transfer, we - // direct all touch start/move/ends to them in the form of - // `onResponderMove/Start/End`. These will be called for *every* additional - // finger that move/start/end, dispatched directly to whoever is the - // current responder at that moment, until the responder is "released". - // - // These multiple individual change touch events are are always bookended - // by `onResponderGrant`, and one of - // (`onResponderRelease/onResponderTerminate`). - - var isResponderTouchStart = responderInst && isStartish(topLevelType); - var isResponderTouchMove = responderInst && isMoveish(topLevelType); - var isResponderTouchEnd = responderInst && isEndish(topLevelType); - var incrementalTouch = isResponderTouchStart - ? eventTypes.responderStart - : isResponderTouchMove - ? eventTypes.responderMove - : isResponderTouchEnd - ? eventTypes.responderEnd - : null; - - if (incrementalTouch) { - var gesture = ResponderSyntheticEvent.getPooled( - incrementalTouch, - responderInst, - nativeEvent, - nativeEventTarget - ); - gesture.touchHistory = ResponderTouchHistoryStore.touchHistory; - accumulateDirectDispatches(gesture); - extracted = accumulate(extracted, gesture); - } - - var isResponderTerminate = - responderInst && topLevelType === TOP_TOUCH_CANCEL; - var isResponderRelease = - responderInst && - !isResponderTerminate && - isEndish(topLevelType) && - noResponderTouches(nativeEvent); - var finalTouch = isResponderTerminate - ? eventTypes.responderTerminate - : isResponderRelease - ? eventTypes.responderRelease - : null; + selectionChangeShouldSetResponder: { + phasedRegistrationNames: { + bubbled: "onSelectionChangeShouldSetResponder", + captured: "onSelectionChangeShouldSetResponderCapture" + }, + dependencies: [TOP_SELECTION_CHANGE] + }, - if (finalTouch) { - var finalEvent = ResponderSyntheticEvent.getPooled( - finalTouch, - responderInst, - nativeEvent, - nativeEventTarget - ); - finalEvent.touchHistory = ResponderTouchHistoryStore.touchHistory; - accumulateDirectDispatches(finalEvent); - extracted = accumulate(extracted, finalEvent); - changeResponder(null); - } + /** + * On a `touchMove`/`mouseMove`, is it desired that this element become the + * responder? + */ + moveShouldSetResponder: { + phasedRegistrationNames: { + bubbled: "onMoveShouldSetResponder", + captured: "onMoveShouldSetResponderCapture" + }, + dependencies: moveDependencies + }, - return extracted; + /** + * Direct responder events dispatched directly to responder. Do not bubble. + */ + responderStart: { + registrationName: "onResponderStart", + dependencies: startDependencies }, - GlobalResponderHandler: null, - injection: { - /** - * @param {{onChange: (ReactID, ReactID) => void} GlobalResponderHandler - * Object that handles any change in responder. Use this to inject - * integration with an existing touch handling system etc. - */ - injectGlobalResponderHandler: function(GlobalResponderHandler) { - ResponderEventPlugin.GlobalResponderHandler = GlobalResponderHandler; - } + responderMove: { + registrationName: "onResponderMove", + dependencies: moveDependencies + }, + responderEnd: { + registrationName: "onResponderEnd", + dependencies: endDependencies + }, + responderRelease: { + registrationName: "onResponderRelease", + dependencies: endDependencies + }, + responderTerminationRequest: { + registrationName: "onResponderTerminationRequest", + dependencies: [] + }, + responderGrant: { + registrationName: "onResponderGrant", + dependencies: [] + }, + responderReject: { + registrationName: "onResponderReject", + dependencies: [] + }, + responderTerminate: { + registrationName: "onResponderTerminate", + dependencies: [] } }; - -/** - * Injectable ordering of event plugins. - */ -var eventPluginOrder = null; /** - * Injectable mapping from names to event plugin modules. + * + * Responder System: + * ---------------- + * + * - A global, solitary "interaction lock" on a view. + * - If a node becomes the responder, it should convey visual feedback + * immediately to indicate so, either by highlighting or moving accordingly. + * - To be the responder means, that touches are exclusively important to that + * responder view, and no other view. + * - While touches are still occurring, the responder lock can be transferred to + * a new view, but only to increasingly "higher" views (meaning ancestors of + * the current responder). + * + * Responder being granted: + * ------------------------ + * + * - Touch starts, moves, and scrolls can cause an ID to become the responder. + * - We capture/bubble `startShouldSetResponder`/`moveShouldSetResponder` to + * the "appropriate place". + * - If nothing is currently the responder, the "appropriate place" is the + * initiating event's `targetID`. + * - If something *is* already the responder, the "appropriate place" is the + * first common ancestor of the event target and the current `responderInst`. + * - Some negotiation happens: See the timing diagram below. + * - Scrolled views automatically become responder. The reasoning is that a + * platform scroll view that isn't built on top of the responder system has + * began scrolling, and the active responder must now be notified that the + * interaction is no longer locked to it - the system has taken over. + * + * - Responder being released: + * As soon as no more touches that *started* inside of descendants of the + * *current* responderInst, an `onResponderRelease` event is dispatched to the + * current responder, and the responder lock is released. + * + * TODO: + * - on "end", a callback hook for `onResponderEndShouldRemainResponder` that + * determines if the responder lock should remain. + * - If a view shouldn't "remain" the responder, any active touches should by + * default be considered "dead" and do not influence future negotiations or + * bubble paths. It should be as if those touches do not exist. + * -- For multitouch: Usually a translate-z will choose to "remain" responder + * after one out of many touches ended. For translate-y, usually the view + * doesn't wish to "remain" responder after one of many touches end. + * - Consider building this on top of a `stopPropagation` model similar to + * `W3C` events. + * - Ensure that `onResponderTerminate` is called on touch cancels, whether or + * not `onResponderTerminationRequest` returns `true` or `false`. + * */ -var namesToPlugins = {}; +/* Negotiation Performed + +-----------------------+ + / \ +Process low level events to + Current Responder + wantsResponderID +determine who to perform negot-| (if any exists at all) | +iation/transition | Otherwise just pass through| +-------------------------------+----------------------------+------------------+ +Bubble to find first ID | | +to return true:wantsResponderID| | + | | + +-------------+ | | + | onTouchStart| | | + +------+------+ none | | + | return| | ++-----------v-------------+true| +------------------------+ | +|onStartShouldSetResponder|----->|onResponderStart (cur) |<-----------+ ++-----------+-------------+ | +------------------------+ | | + | | | +--------+-------+ + | returned true for| false:REJECT +-------->|onResponderReject + | wantsResponderID | | | +----------------+ + | (now attempt | +------------------+-----+ | + | handoff) | | onResponder | | + +------------------->| TerminationRequest| | + | +------------------+-----+ | + | | | +----------------+ + | true:GRANT +-------->|onResponderGrant| + | | +--------+-------+ + | +------------------------+ | | + | | onResponderTerminate |<-----------+ + | +------------------+-----+ | + | | | +----------------+ + | +-------->|onResponderStart| + | | +----------------+ +Bubble to find first ID | | +to return true:wantsResponderID| | + | | + +-------------+ | | + | onTouchMove | | | + +------+------+ none | | + | return| | ++-----------v-------------+true| +------------------------+ | +|onMoveShouldSetResponder |----->|onResponderMove (cur) |<-----------+ ++-----------+-------------+ | +------------------------+ | | + | | | +--------+-------+ + | returned true for| false:REJECT +-------->|onResponderRejec| + | wantsResponderID | | | +----------------+ + | (now attempt | +------------------+-----+ | + | handoff) | | onResponder | | + +------------------->| TerminationRequest| | + | +------------------+-----+ | + | | | +----------------+ + | true:GRANT +-------->|onResponderGrant| + | | +--------+-------+ + | +------------------------+ | | + | | onResponderTerminate |<-----------+ + | +------------------+-----+ | + | | | +----------------+ + | +-------->|onResponderMove | + | | +----------------+ + | | + | | + Some active touch started| | + inside current responder | +------------------------+ | + +------------------------->| onResponderEnd | | + | | +------------------------+ | + +---+---------+ | | + | onTouchEnd | | | + +---+---------+ | | + | | +------------------------+ | + +------------------------->| onResponderEnd | | + No active touches started| +-----------+------------+ | + inside current responder | | | + | v | + | +------------------------+ | + | | onResponderRelease | | + | +------------------------+ | + | | + + + */ + /** - * Recomputes the plugin list using the injected plugins and plugin ordering. + * A note about event ordering in the `EventPluginHub`. * - * @private + * Suppose plugins are injected in the following order: + * + * `[R, S, C]` + * + * To help illustrate the example, assume `S` is `SimpleEventPlugin` (for + * `onClick` etc) and `R` is `ResponderEventPlugin`. + * + * "Deferred-Dispatched Events": + * + * - The current event plugin system will traverse the list of injected plugins, + * in order, and extract events by collecting the plugin's return value of + * `extractEvents()`. + * - These events that are returned from `extractEvents` are "deferred + * dispatched events". + * - When returned from `extractEvents`, deferred-dispatched events contain an + * "accumulation" of deferred dispatches. + * - These deferred dispatches are accumulated/collected before they are + * returned, but processed at a later time by the `EventPluginHub` (hence the + * name deferred). + * + * In the process of returning their deferred-dispatched events, event plugins + * themselves can dispatch events on-demand without returning them from + * `extractEvents`. Plugins might want to do this, so that they can use event + * dispatching as a tool that helps them decide which events should be extracted + * in the first place. + * + * "On-Demand-Dispatched Events": + * + * - On-demand-dispatched events are not returned from `extractEvents`. + * - On-demand-dispatched events are dispatched during the process of returning + * the deferred-dispatched events. + * - They should not have side effects. + * - They should be avoided, and/or eventually be replaced with another + * abstraction that allows event plugins to perform multiple "rounds" of event + * extraction. + * + * Therefore, the sequence of event dispatches becomes: + * + * - `R`s on-demand events (if any) (dispatched by `R` on-demand) + * - `S`s on-demand events (if any) (dispatched by `S` on-demand) + * - `C`s on-demand events (if any) (dispatched by `C` on-demand) + * - `R`s extracted events (if any) (dispatched by `EventPluginHub`) + * - `S`s extracted events (if any) (dispatched by `EventPluginHub`) + * - `C`s extracted events (if any) (dispatched by `EventPluginHub`) + * + * In the case of `ResponderEventPlugin`: If the `startShouldSetResponder` + * on-demand dispatch returns `true` (and some other details are satisfied) the + * `onResponderGrant` deferred dispatched event is returned from + * `extractEvents`. The sequence of dispatch executions in this case + * will appear as follows: + * + * - `startShouldSetResponder` (`ResponderEventPlugin` dispatches on-demand) + * - `touchStartCapture` (`EventPluginHub` dispatches as usual) + * - `touchStart` (`EventPluginHub` dispatches as usual) + * - `responderGrant/Reject` (`EventPluginHub` dispatches as usual) */ -function recomputePluginOrdering() { - if (!eventPluginOrder) { - // Wait until an `eventPluginOrder` is injected. - return; - } - - for (var pluginName in namesToPlugins) { - var pluginModule = namesToPlugins[pluginName]; - var pluginIndex = eventPluginOrder.indexOf(pluginName); +function setResponderAndExtractTransfer( + topLevelType, + targetInst, + nativeEvent, + nativeEventTarget +) { + var shouldSetEventType = isStartish(topLevelType) + ? eventTypes.startShouldSetResponder + : isMoveish(topLevelType) + ? eventTypes.moveShouldSetResponder + : topLevelType === TOP_SELECTION_CHANGE + ? eventTypes.selectionChangeShouldSetResponder + : eventTypes.scrollShouldSetResponder; // TODO: stop one short of the current responder. - if (!(pluginIndex > -1)) { - throw Error( - "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + - pluginName + - "`." - ); - } + var bubbleShouldSetFrom = !responderInst + ? targetInst + : getLowestCommonAncestor(responderInst, targetInst); // When capturing/bubbling the "shouldSet" event, we want to skip the target + // (deepest ID) if it happens to be the current responder. The reasoning: + // It's strange to get an `onMoveShouldSetResponder` when you're *already* + // the responder. - if (plugins[pluginIndex]) { - continue; - } + var skipOverBubbleShouldSetFrom = bubbleShouldSetFrom === responderInst; + var shouldSetEvent = ResponderSyntheticEvent.getPooled( + shouldSetEventType, + bubbleShouldSetFrom, + nativeEvent, + nativeEventTarget + ); + shouldSetEvent.touchHistory = ResponderTouchHistoryStore.touchHistory; - if (!pluginModule.extractEvents) { - throw Error( - "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + - pluginName + - "` does not." - ); - } + if (skipOverBubbleShouldSetFrom) { + accumulateTwoPhaseDispatchesSkipTarget(shouldSetEvent); + } else { + accumulateTwoPhaseDispatches(shouldSetEvent); + } - plugins[pluginIndex] = pluginModule; - var publishedEvents = pluginModule.eventTypes; + var wantsResponderInst = executeDispatchesInOrderStopAtTrue(shouldSetEvent); - for (var eventName in publishedEvents) { - if ( - !publishEventForPlugin( - publishedEvents[eventName], - pluginModule, - eventName - ) - ) { - throw Error( - "EventPluginRegistry: Failed to publish event `" + - eventName + - "` for plugin `" + - pluginName + - "`." - ); - } - } + if (!shouldSetEvent.isPersistent()) { + shouldSetEvent.constructor.release(shouldSetEvent); } -} -/** - * Publishes an event so that it can be dispatched by the supplied plugin. - * - * @param {object} dispatchConfig Dispatch configuration for the event. - * @param {object} PluginModule Plugin publishing the event. - * @return {boolean} True if the event was successfully published. - * @private - */ -function publishEventForPlugin(dispatchConfig, pluginModule, eventName) { - if (!!eventNameDispatchConfigs.hasOwnProperty(eventName)) { - throw Error( - "EventPluginRegistry: More than one plugin attempted to publish the same event name, `" + - eventName + - "`." - ); + if (!wantsResponderInst || wantsResponderInst === responderInst) { + return null; } - eventNameDispatchConfigs[eventName] = dispatchConfig; - var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; - - if (phasedRegistrationNames) { - for (var phaseName in phasedRegistrationNames) { - if (phasedRegistrationNames.hasOwnProperty(phaseName)) { - var phasedRegistrationName = phasedRegistrationNames[phaseName]; - publishRegistrationName( - phasedRegistrationName, - pluginModule, - eventName - ); - } - } + var extracted; + var grantEvent = ResponderSyntheticEvent.getPooled( + eventTypes.responderGrant, + wantsResponderInst, + nativeEvent, + nativeEventTarget + ); + grantEvent.touchHistory = ResponderTouchHistoryStore.touchHistory; + accumulateDirectDispatches(grantEvent); + var blockHostResponder = executeDirectDispatch(grantEvent) === true; - return true; - } else if (dispatchConfig.registrationName) { - publishRegistrationName( - dispatchConfig.registrationName, - pluginModule, - eventName + if (responderInst) { + var terminationRequestEvent = ResponderSyntheticEvent.getPooled( + eventTypes.responderTerminationRequest, + responderInst, + nativeEvent, + nativeEventTarget ); - return true; - } + terminationRequestEvent.touchHistory = + ResponderTouchHistoryStore.touchHistory; + accumulateDirectDispatches(terminationRequestEvent); + var shouldSwitch = + !hasDispatches(terminationRequestEvent) || + executeDirectDispatch(terminationRequestEvent); - return false; -} -/** - * Publishes a registration name that is used to identify dispatched events. - * - * @param {string} registrationName Registration name to add. - * @param {object} PluginModule Plugin publishing the event. - * @private - */ + if (!terminationRequestEvent.isPersistent()) { + terminationRequestEvent.constructor.release(terminationRequestEvent); + } -function publishRegistrationName(registrationName, pluginModule, eventName) { - if (!!registrationNameModules[registrationName]) { - throw Error( - "EventPluginRegistry: More than one plugin attempted to publish the same registration name, `" + - registrationName + - "`." - ); + if (shouldSwitch) { + var terminateEvent = ResponderSyntheticEvent.getPooled( + eventTypes.responderTerminate, + responderInst, + nativeEvent, + nativeEventTarget + ); + terminateEvent.touchHistory = ResponderTouchHistoryStore.touchHistory; + accumulateDirectDispatches(terminateEvent); + extracted = accumulate(extracted, [grantEvent, terminateEvent]); + changeResponder(wantsResponderInst, blockHostResponder); + } else { + var rejectEvent = ResponderSyntheticEvent.getPooled( + eventTypes.responderReject, + wantsResponderInst, + nativeEvent, + nativeEventTarget + ); + rejectEvent.touchHistory = ResponderTouchHistoryStore.touchHistory; + accumulateDirectDispatches(rejectEvent); + extracted = accumulate(extracted, rejectEvent); + } + } else { + extracted = accumulate(extracted, grantEvent); + changeResponder(wantsResponderInst, blockHostResponder); } - registrationNameModules[registrationName] = pluginModule; - registrationNameDependencies[registrationName] = - pluginModule.eventTypes[eventName].dependencies; - - { - var lowerCasedName = registrationName.toLowerCase(); - } + return extracted; } /** - * Registers plugins so that they can extract and dispatch events. - */ - -/** - * Ordered list of injected plugins. + * A transfer is a negotiation between a currently set responder and the next + * element to claim responder status. Any start event could trigger a transfer + * of responderInst. Any move event could trigger a transfer. + * + * @param {string} topLevelType Record from `BrowserEventConstants`. + * @return {boolean} True if a transfer of responder could possibly occur. */ -var plugins = []; +function canTriggerTransfer(topLevelType, topLevelInst, nativeEvent) { + return ( + topLevelInst && // responderIgnoreScroll: We are trying to migrate away from specifically + // tracking native scroll events here and responderIgnoreScroll indicates we + // will send topTouchCancel to handle canceling touch events instead + ((topLevelType === TOP_SCROLL && !nativeEvent.responderIgnoreScroll) || + (trackedTouchCount > 0 && topLevelType === TOP_SELECTION_CHANGE) || + isStartish(topLevelType) || + isMoveish(topLevelType)) + ); +} /** - * Mapping from event name to dispatch config + * Returns whether or not this touch end event makes it such that there are no + * longer any touches that started inside of the current `responderInst`. + * + * @param {NativeEvent} nativeEvent Native touch end event. + * @return {boolean} Whether or not this touch end event ends the responder. */ -var eventNameDispatchConfigs = {}; -/** - * Mapping from registration name to plugin module - */ +function noResponderTouches(nativeEvent) { + var touches = nativeEvent.touches; -var registrationNameModules = {}; -/** - * Mapping from registration name to event name - */ + if (!touches || touches.length === 0) { + return true; + } -var registrationNameDependencies = {}; + for (var i = 0; i < touches.length; i++) { + var activeTouch = touches[i]; + var target = activeTouch.target; -/** - * Injects an ordering of plugins (by plugin name). This allows the ordering - * to be decoupled from injection of the actual plugins so that ordering is - * always deterministic regardless of packaging, on-the-fly injection, etc. - * - * @param {array} InjectedEventPluginOrder - * @internal - */ + if (target !== null && target !== undefined && target !== 0) { + // Is the original touch location inside of the current responder? + var targetInst = getInstanceFromNode(target); -function injectEventPluginOrder(injectedEventPluginOrder) { - if (!!eventPluginOrder) { - throw Error( - "EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React." - ); - } // Clone the ordering so it cannot be dynamically mutated. + if (isAncestor(responderInst, targetInst)) { + return false; + } + } + } - eventPluginOrder = Array.prototype.slice.call(injectedEventPluginOrder); - recomputePluginOrdering(); + return true; } -/** - * Injects plugins to be used by plugin event system. The plugin names must be - * in the ordering injected by `injectEventPluginOrder`. - * - * Plugins can be injected as part of page initialization or on-the-fly. - * - * @param {object} injectedNamesToPlugins Map from names to plugin modules. - * @internal - */ -function injectEventPluginsByName(injectedNamesToPlugins) { - var isOrderingDirty = false; +var ResponderEventPlugin = { + /* For unit testing only */ + _getResponder: function() { + return responderInst; + }, + eventTypes: eventTypes, - for (var pluginName in injectedNamesToPlugins) { - if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) { - continue; + /** + * We must be resilient to `targetInst` being `null` on `touchMove` or + * `touchEnd`. On certain platforms, this means that a native scroll has + * assumed control and the original touch targets are destroyed. + */ + extractEvents: function( + topLevelType, + targetInst, + nativeEvent, + nativeEventTarget, + eventSystemFlags + ) { + if (isStartish(topLevelType)) { + trackedTouchCount += 1; + } else if (isEndish(topLevelType)) { + if (trackedTouchCount >= 0) { + trackedTouchCount -= 1; + } else { + console.warn( + "Ended a touch event which was not counted in `trackedTouchCount`." + ); + return null; + } } - var pluginModule = injectedNamesToPlugins[pluginName]; + ResponderTouchHistoryStore.recordTouchTrack(topLevelType, nativeEvent); + var extracted = canTriggerTransfer(topLevelType, targetInst, nativeEvent) + ? setResponderAndExtractTransfer( + topLevelType, + targetInst, + nativeEvent, + nativeEventTarget + ) + : null; // Responder may or may not have transferred on a new touch start/move. + // Regardless, whoever is the responder after any potential transfer, we + // direct all touch start/move/ends to them in the form of + // `onResponderMove/Start/End`. These will be called for *every* additional + // finger that move/start/end, dispatched directly to whoever is the + // current responder at that moment, until the responder is "released". + // + // These multiple individual change touch events are are always bookended + // by `onResponderGrant`, and one of + // (`onResponderRelease/onResponderTerminate`). - if ( - !namesToPlugins.hasOwnProperty(pluginName) || - namesToPlugins[pluginName] !== pluginModule - ) { - if (!!namesToPlugins[pluginName]) { - throw Error( - "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - pluginName + - "`." - ); - } + var isResponderTouchStart = responderInst && isStartish(topLevelType); + var isResponderTouchMove = responderInst && isMoveish(topLevelType); + var isResponderTouchEnd = responderInst && isEndish(topLevelType); + var incrementalTouch = isResponderTouchStart + ? eventTypes.responderStart + : isResponderTouchMove + ? eventTypes.responderMove + : isResponderTouchEnd + ? eventTypes.responderEnd + : null; - namesToPlugins[pluginName] = pluginModule; - isOrderingDirty = true; + if (incrementalTouch) { + var gesture = ResponderSyntheticEvent.getPooled( + incrementalTouch, + responderInst, + nativeEvent, + nativeEventTarget + ); + gesture.touchHistory = ResponderTouchHistoryStore.touchHistory; + accumulateDirectDispatches(gesture); + extracted = accumulate(extracted, gesture); } - } - if (isOrderingDirty) { - recomputePluginOrdering(); + var isResponderTerminate = + responderInst && topLevelType === TOP_TOUCH_CANCEL; + var isResponderRelease = + responderInst && + !isResponderTerminate && + isEndish(topLevelType) && + noResponderTouches(nativeEvent); + var finalTouch = isResponderTerminate + ? eventTypes.responderTerminate + : isResponderRelease + ? eventTypes.responderRelease + : null; + + if (finalTouch) { + var finalEvent = ResponderSyntheticEvent.getPooled( + finalTouch, + responderInst, + nativeEvent, + nativeEventTarget + ); + finalEvent.touchHistory = ResponderTouchHistoryStore.touchHistory; + accumulateDirectDispatches(finalEvent); + extracted = accumulate(extracted, finalEvent); + changeResponder(null); + } + + return extracted; + }, + GlobalResponderHandler: null, + injection: { + /** + * @param {{onChange: (ReactID, ReactID) => void} GlobalResponderHandler + * Object that handles any change in responder. Use this to inject + * integration with an existing touch handling system etc. + */ + injectGlobalResponderHandler: function(GlobalResponderHandler) { + ResponderEventPlugin.GlobalResponderHandler = GlobalResponderHandler; + } } -} +}; var customBubblingEventTypes = - ReactNativePrivateInterface.ReactNativeViewConfigRegistry - .customBubblingEventTypes, - customDirectEventTypes = - ReactNativePrivateInterface.ReactNativeViewConfigRegistry - .customDirectEventTypes; + ReactNativePrivateInterface.ReactNativeViewConfigRegistry + .customBubblingEventTypes; +var customDirectEventTypes = + ReactNativePrivateInterface.ReactNativeViewConfigRegistry + .customDirectEventTypes; var ReactNativeBridgeEventPlugin = { eventTypes: {}, + + /** + * @see {EventPluginHub.extractEvents} + */ extractEvents: function( topLevelType, targetInst, @@ -2411,21 +2551,46 @@ var ReactNativeEventPluginOrder = [ * ensures it exists in the dependency graph and can be `require`d. * TODO: require this in packager, not in React #10932517 */ +// Module provided by RN: /** * Inject module for resolving DOM hierarchy and plugin ordering. */ -injectEventPluginOrder(ReactNativeEventPluginOrder); +injection.injectEventPluginOrder(ReactNativeEventPluginOrder); /** * Some important event plugins included by default (without having to require * them). */ -injectEventPluginsByName({ +injection.injectEventPluginsByName({ ResponderEventPlugin: ResponderEventPlugin, ReactNativeBridgeEventPlugin: ReactNativeBridgeEventPlugin }); +var debugRenderPhaseSideEffectsForStrictMode = false; +var enableUserTimingAPI = true; +var replayFailedUnitOfWorkWithInvokeGuardedCallback = true; +var warnAboutDeprecatedLifecycles = true; +var enableProfilerTimer = true; +var enableSchedulerTracing = true; +var enableSuspenseServerRenderer = false; + +var enableFlareAPI = false; +var enableFundamentalAPI = false; +var enableScopeAPI = false; + +var warnAboutUnmockedScheduler = false; +var flushSuspenseFallbacksInTests = true; +var enableSuspenseCallback = false; +var warnAboutDefaultPropsOnFunctionComponents = false; +var warnAboutStringRefs = false; +var disableLegacyContext = false; +var disableSchedulerTimeoutBasedOnReactExpirationTime = false; + +var enableNativeTargetAsInstance = false; // Only used in www builds. + +// Flow magic to verify the exports of this file match the original version. + var instanceCache = new Map(); var instanceProps = new Map(); function precacheFiberNode(hostInst, tag) { @@ -2441,32 +2606,88 @@ function getInstanceFromTag(tag) { } function getTagFromInstance(inst) { - var nativeInstance = inst.stateNode; - var tag = nativeInstance._nativeTag; + if (enableNativeTargetAsInstance) { + var nativeInstance = inst.stateNode; + var tag = nativeInstance._nativeTag; + + if (tag === undefined) { + nativeInstance = nativeInstance.canonical; + tag = nativeInstance._nativeTag; + } + + if (!tag) { + throw Error("All native instances should have a tag."); + } + + return nativeInstance; + } else { + var _tag = inst.stateNode._nativeTag; + + if (_tag === undefined) { + _tag = inst.stateNode.canonical._nativeTag; + } + + if (!_tag) { + throw Error("All native instances should have a tag."); + } + + return _tag; + } +} + +function getFiberCurrentPropsFromNode$1(stateNode) { + return instanceProps.get(stateNode._nativeTag) || null; +} +function updateFiberProps(tag, props) { + instanceProps.set(tag, props); +} + +var PLUGIN_EVENT_SYSTEM = 1; + +var restoreImpl = null; +var restoreTarget = null; +var restoreQueue = null; - if (tag === undefined) { - nativeInstance = nativeInstance.canonical; - tag = nativeInstance._nativeTag; +function restoreStateOfTarget(target) { + // We perform this translation at the end of the event loop so that we + // always receive the correct fiber here + var internalInstance = getInstanceFromNode(target); + + if (!internalInstance) { + // Unmounted + return; } - if (!tag) { - throw Error("All native instances should have a tag."); + if (!(typeof restoreImpl === "function")) { + throw Error( + "setRestoreImplementation() needs to be called to handle a target for controlled events. This error is likely caused by a bug in React. Please file an issue." + ); } - return nativeInstance; -} -function getFiberCurrentPropsFromNode$1(stateNode) { - return instanceProps.get(stateNode._nativeTag) || null; + var props = getFiberCurrentPropsFromNode(internalInstance.stateNode); + restoreImpl(internalInstance.stateNode, internalInstance.type, props); } -function updateFiberProps(tag, props) { - instanceProps.set(tag, props); + +function needsStateRestore() { + return restoreTarget !== null || restoreQueue !== null; } +function restoreStateIfNeeded() { + if (!restoreTarget) { + return; + } -var PLUGIN_EVENT_SYSTEM = 1; + var target = restoreTarget; + var queuedTargets = restoreQueue; + restoreTarget = null; + restoreQueue = null; + restoreStateOfTarget(target); -var enableProfilerTimer = true; -var enableFundamentalAPI = false; -var warnAboutStringRefs = false; + if (queuedTargets) { + for (var i = 0; i < queuedTargets.length; i++) { + restoreStateOfTarget(queuedTargets[i]); + } + } +} // the renderer. Such as when we're dispatching events or if third party // libraries need to call batchedUpdates. Eventually, this API will go away when @@ -2477,7 +2698,25 @@ var warnAboutStringRefs = false; var batchedUpdatesImpl = function(fn, bookkeeping) { return fn(bookkeeping); }; + +var flushDiscreteUpdatesImpl = function() {}; + var isInsideEventHandler = false; +function finishEventHandler() { + // Here we wait until all updates have propagated, which is important + // when using controlled components within layers: + // https://github.com/facebook/react/issues/1698 + // Then we restore state of any controlled component. + var controlledComponentsHavePendingUpdates = needsStateRestore(); + + if (controlledComponentsHavePendingUpdates) { + // If a controlled event was fired, we may need to restore the state of + // the DOM node back to the controlled value. This is necessary when React + // bails out of the update without touching the DOM. + flushDiscreteUpdatesImpl(); + restoreStateIfNeeded(); + } +} function batchedUpdates(fn, bookkeeping) { if (isInsideEventHandler) { @@ -2492,8 +2731,11 @@ function batchedUpdates(fn, bookkeeping) { return batchedUpdatesImpl(fn, bookkeeping); } finally { isInsideEventHandler = false; + finishEventHandler(); } } +// This is for the React Flare event system + function setBatchingImplementation( _batchedUpdatesImpl, _discreteUpdatesImpl, @@ -2501,57 +2743,7 @@ function setBatchingImplementation( _batchedEventUpdatesImpl ) { batchedUpdatesImpl = _batchedUpdatesImpl; -} - -/** - * Internal queue of events that have accumulated their dispatches and are - * waiting to have their dispatches executed. - */ - -var eventQueue = null; -/** - * Dispatches an event and releases it back into the pool, unless persistent. - * - * @param {?object} event Synthetic event to be dispatched. - * @private - */ - -var executeDispatchesAndRelease = function(event) { - if (event) { - executeDispatchesInOrder(event); - - if (!event.isPersistent()) { - event.constructor.release(event); - } - } -}; - -var executeDispatchesAndReleaseTopLevel = function(e) { - return executeDispatchesAndRelease(e); -}; - -function runEventsInBatch(events) { - if (events !== null) { - eventQueue = accumulateInto(eventQueue, events); - } // Set `eventQueue` to null before processing it so that we can tell if more - // events get enqueued while processing. - - var processingEventQueue = eventQueue; - eventQueue = null; - - if (!processingEventQueue) { - return; - } - - forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseTopLevel); - - if (!!eventQueue) { - throw Error( - "processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented." - ); - } // This would be a good time to rethrow if any of the event handlers threw. - - rethrowCaughtError(); + flushDiscreteUpdatesImpl = _flushDiscreteUpdatesImpl; } /** @@ -2631,8 +2823,12 @@ function _receiveRootNodeIDEvent(rootNodeID, topLevelType, nativeEventParam) { var inst = getInstanceFromTag(rootNodeID); var target = null; - if (inst != null) { - target = inst.stateNode; + if (enableNativeTargetAsInstance) { + if (inst != null) { + target = inst.stateNode; + } + } else { + target = nativeEvent.target; } batchedUpdates(function() { @@ -2646,61 +2842,6 @@ function _receiveRootNodeIDEvent(rootNodeID, topLevelType, nativeEventParam) { }); // React Native doesn't use ReactControlledComponent but if it did, here's // where it would do it. } -/** - * Allows registered plugins an opportunity to extract events from top-level - * native browser events. - * - * @return {*} An accumulation of synthetic events. - * @internal - */ - -function extractPluginEvents( - topLevelType, - targetInst, - nativeEvent, - nativeEventTarget, - eventSystemFlags -) { - var events = null; - - for (var i = 0; i < plugins.length; i++) { - // Not every plugin in the ordering may be loaded at runtime. - var possiblePlugin = plugins[i]; - - if (possiblePlugin) { - var extractedEvents = possiblePlugin.extractEvents( - topLevelType, - targetInst, - nativeEvent, - nativeEventTarget, - eventSystemFlags - ); - - if (extractedEvents) { - events = accumulateInto(events, extractedEvents); - } - } - } - - return events; -} - -function runExtractedPluginEventsInBatch( - topLevelType, - targetInst, - nativeEvent, - nativeEventTarget, - eventSystemFlags -) { - var events = extractPluginEvents( - topLevelType, - targetInst, - nativeEvent, - nativeEventTarget, - eventSystemFlags - ); - runEventsInBatch(events); -} /** * Publicly exposed method on module for native objc to invoke when a top * level event is extracted. @@ -2757,7 +2898,10 @@ function receiveTouches(eventTopLevelType, touches, changedIndices) { if (target !== null && target !== undefined) { if (target < 1) { { - error("A view is reporting that a touch occurred on tag zero."); + warningWithoutStack$1( + false, + "A view is reporting that a touch occurred on tag zero." + ); } } else { rootNodeID = target; @@ -2809,13 +2953,38 @@ ResponderEventPlugin.injection.injectGlobalResponderHandler( * Note that this module is currently shared and assumed to be stateless. * If this becomes an actual Map, that will break. */ + +/** + * This API should be called `delete` but we'd have to make sure to always + * transform these to strings for IE support. When this transform is fully + * supported we can rename it. + */ + function get(key) { return key._reactInternalFiber; } + function set(key, value) { key._reactInternalFiber = value; } +var ReactSharedInternals = + React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; // Prevent newer renderers from RTE when used with older react package versions. +// Current owner and dispatcher used to share the same ref, +// but PR #14548 split them out to better support the react-debug-tools package. + +if (!ReactSharedInternals.hasOwnProperty("ReactCurrentDispatcher")) { + ReactSharedInternals.ReactCurrentDispatcher = { + current: null + }; +} + +if (!ReactSharedInternals.hasOwnProperty("ReactCurrentBatchConfig")) { + ReactSharedInternals.ReactCurrentBatchConfig = { + suspense: null + }; +} + // The Symbol used to tag the ReactElement-like types. If there is no native Symbol // nor polyfill, then a plain number is used for performance. var hasSymbol = typeof Symbol === "function" && Symbol.for; @@ -2828,6 +2997,8 @@ var REACT_STRICT_MODE_TYPE = hasSymbol var REACT_PROFILER_TYPE = hasSymbol ? Symbol.for("react.profiler") : 0xead2; var REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for("react.provider") : 0xeacd; var REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for("react.context") : 0xeace; // TODO: We don't use AsyncMode or ConcurrentMode anymore. They were temporary +// (unstable) APIs that have been removed. Can we remove the symbols? + var REACT_CONCURRENT_MODE_TYPE = hasSymbol ? Symbol.for("react.concurrent_mode") : 0xeacf; @@ -2840,7 +3011,11 @@ var REACT_SUSPENSE_LIST_TYPE = hasSymbol : 0xead8; var REACT_MEMO_TYPE = hasSymbol ? Symbol.for("react.memo") : 0xead3; var REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 0xead4; -var REACT_BLOCK_TYPE = hasSymbol ? Symbol.for("react.block") : 0xead9; +var REACT_FUNDAMENTAL_TYPE = hasSymbol + ? Symbol.for("react.fundamental") + : 0xead5; +var REACT_RESPONDER_TYPE = hasSymbol ? Symbol.for("react.responder") : 0xead6; +var REACT_SCOPE_TYPE = hasSymbol ? Symbol.for("react.scope") : 0xead7; var MAYBE_ITERATOR_SYMBOL = typeof Symbol === "function" && Symbol.iterator; var FAUX_ITERATOR_SYMBOL = "@@iterator"; function getIteratorFn(maybeIterable) { @@ -2859,29 +3034,56 @@ function getIteratorFn(maybeIterable) { return null; } -// TODO: Move this to "react" once we can import from externals. +/** + * Similar to invariant but only logs a warning if the condition is not met. + * This can be used to log issues in development environments in critical + * paths. Removing the logging code for production environments will keep the + * same logic and follow the same code paths. + */ + +var warning = warningWithoutStack$1; + +{ + warning = function(condition, format) { + if (condition) { + return; + } + + var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; + var stack = ReactDebugCurrentFrame.getStackAddendum(); // eslint-disable-next-line react-internal/warning-and-invariant-args + + for ( + var _len = arguments.length, + args = new Array(_len > 2 ? _len - 2 : 0), + _key = 2; + _key < _len; + _key++ + ) { + args[_key - 2] = arguments[_key]; + } + + warningWithoutStack$1.apply( + void 0, + [false, format + "%s"].concat(args, [stack]) + ); + }; +} + +var warning$1 = warning; + var Uninitialized = -1; var Pending = 0; var Resolved = 1; var Rejected = 2; - function refineResolvedLazyComponent(lazyComponent) { return lazyComponent._status === Resolved ? lazyComponent._result : null; } function initializeLazyComponentType(lazyComponent) { if (lazyComponent._status === Uninitialized) { - var ctor = lazyComponent._result; - - if (!ctor) { - // TODO: Remove this later. THis only exists in case you use an older "react" package. - ctor = lazyComponent._ctor; - } - - var thenable = ctor(); // Transition to the next state. - - var pending = lazyComponent; - pending._status = Pending; - pending._result = thenable; + lazyComponent._status = Pending; + var ctor = lazyComponent._ctor; + var thenable = ctor(); + lazyComponent._result = thenable; thenable.then( function(moduleObject) { if (lazyComponent._status === Pending) { @@ -2889,27 +3091,24 @@ function initializeLazyComponentType(lazyComponent) { { if (defaultExport === undefined) { - error( + warning$1( + false, "lazy: Expected the result of a dynamic import() call. " + - "Instead received: %s\n\nYour code should look like: \n " + // Break up imports to avoid accidentally parsing them as dependencies. - "const MyComponent = lazy(() => imp" + - "ort('./MyComponent'))", + "Instead received: %s\n\nYour code should look like: \n " + + "const MyComponent = lazy(() => import('./MyComponent'))", moduleObject ); } - } // Transition to the next state. + } - var resolved = lazyComponent; - resolved._status = Resolved; - resolved._result = defaultExport; + lazyComponent._status = Resolved; + lazyComponent._result = defaultExport; } }, function(error) { if (lazyComponent._status === Pending) { - // Transition to the next state. - var rejected = lazyComponent; - rejected._status = Rejected; - rejected._result = error; + lazyComponent._status = Rejected; + lazyComponent._result = error; } } ); @@ -2924,10 +3123,6 @@ function getWrappedName(outerType, innerType, wrapperName) { ); } -function getContextName(type) { - return type.displayName || "Context"; -} - function getComponentName(type) { if (type == null) { // Host root, text node or just invalid type. @@ -2936,7 +3131,8 @@ function getComponentName(type) { { if (typeof type.tag === "number") { - error( + warningWithoutStack$1( + false, "Received an unexpected object in getComponentName(). " + "This is likely a bug in React. Please file an issue." ); @@ -2974,12 +3170,10 @@ function getComponentName(type) { if (typeof type === "object") { switch (type.$$typeof) { case REACT_CONTEXT_TYPE: - var context = type; - return getContextName(context) + ".Consumer"; + return "Context.Consumer"; case REACT_PROVIDER_TYPE: - var provider = type; - return getContextName(provider._context) + ".Provider"; + return "Context.Provider"; case REACT_FORWARD_REF_TYPE: return getWrappedName(type, type.render, "ForwardRef"); @@ -2987,9 +3181,6 @@ function getComponentName(type) { case REACT_MEMO_TYPE: return getComponentName(type.type); - case REACT_BLOCK_TYPE: - return getComponentName(type.render); - case REACT_LAZY_TYPE: { var thenable = type; var resolvedThenable = refineResolvedLazyComponent(thenable); @@ -3065,7 +3256,7 @@ var ShouldCapture = /* */ 4096; -var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner; +var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner; function getNearestMountedFiber(fiber) { var node = fiber; var nearestMounted = fiber; @@ -3102,28 +3293,28 @@ function getNearestMountedFiber(fiber) { return null; } + function isFiberMounted(fiber) { return getNearestMountedFiber(fiber) === fiber; } function isMounted(component) { { - var owner = ReactCurrentOwner.current; + var owner = ReactCurrentOwner$1.current; if (owner !== null && owner.tag === ClassComponent) { var ownerFiber = owner; var instance = ownerFiber.stateNode; - - if (!instance._warnedAboutRefsInRender) { - error( - "%s is accessing isMounted inside its render() function. " + - "render() should be a pure function of props and state. It should " + - "never access something that requires stale data from the previous " + - "render, such as refs. Move this logic to componentDidMount and " + - "componentDidUpdate instead.", - getComponentName(ownerFiber.type) || "A component" - ); - } - + !instance._warnedAboutRefsInRender + ? warningWithoutStack$1( + false, + "%s is accessing isMounted inside its render() function. " + + "render() should be a pure function of props and state. It should " + + "never access something that requires stale data from the previous " + + "render, such as refs. Move this logic to componentDidMount and " + + "componentDidUpdate instead.", + getComponentName(ownerFiber.type) || "A component" + ) + : void 0; instance._warnedAboutRefsInRender = true; } } @@ -3826,49 +4017,71 @@ function mountSafeCallback_NOT_REALLY_SAFE(context, callback) { return callback.apply(context, arguments); }; } +function throwOnStylesProp(component, props) { + if (props.styles !== undefined) { + var owner = component._owner || null; + var name = component.constructor.displayName; + var msg = + "`styles` is not a supported property of `" + + name + + "`, did " + + "you mean `style` (singular)?"; + + if (owner && owner.constructor && owner.constructor.displayName) { + msg += + "\n\nCheck the `" + + owner.constructor.displayName + + "` parent " + + " component."; + } + + throw new Error(msg); + } +} function warnForStyleProps(props, validAttributes) { - { - for (var key in validAttributes.style) { - if (!(validAttributes[key] || props[key] === undefined)) { - error( - "You are setting the style `{ %s" + - ": ... }` as a prop. You " + - "should nest it in a style object. " + - "E.g. `{ style: { %s" + - ": ... } }`", - key, - key - ); - } + for (var key in validAttributes.style) { + if (!(validAttributes[key] || props[key] === undefined)) { + console.error( + "You are setting the style `{ " + + key + + ": ... }` as a prop. You " + + "should nest it in a style object. " + + "E.g. `{ style: { " + + key + + ": ... } }`" + ); } } } +// Modules provided by RN: +/** + * This component defines the same methods as NativeMethodsMixin but without the + * findNodeHandle wrapper. This wrapper is unnecessary for HostComponent views + * and would also result in a circular require.js dependency (since + * ReactNativeFiber depends on this component and NativeMethodsMixin depends on + * ReactNativeFiber). + */ + var ReactNativeFiberHostComponent = /*#__PURE__*/ (function() { - function ReactNativeFiberHostComponent( - tag, - viewConfig, - internalInstanceHandleDEV - ) { + function ReactNativeFiberHostComponent(tag, viewConfig) { this._nativeTag = tag; this._children = []; this.viewConfig = viewConfig; - - { - this._internalFiberInstanceHandleDEV = internalInstanceHandleDEV; - } } var _proto = ReactNativeFiberHostComponent.prototype; _proto.blur = function blur() { - ReactNativePrivateInterface.TextInputState.blurTextInput(this); + ReactNativePrivateInterface.TextInputState.blurTextInput(this._nativeTag); }; _proto.focus = function focus() { - ReactNativePrivateInterface.TextInputState.focusTextInput(this); + ReactNativePrivateInterface.TextInputState.focusTextInput( + this._nativeTag + ); }; _proto.measure = function measure(callback) { @@ -3896,21 +4109,15 @@ var ReactNativeFiberHostComponent = if (typeof relativeToNativeNode === "number") { // Already a node handle relativeNode = relativeToNativeNode; - } else { - var nativeNode = relativeToNativeNode; - - if (nativeNode._nativeTag) { - relativeNode = nativeNode._nativeTag; - } + } else if (relativeToNativeNode._nativeTag) { + relativeNode = relativeToNativeNode._nativeTag; } if (relativeNode == null) { - { - error( - "Warning: ref.measureLayout must be called with a node handle or a ref to a native component." - ); - } - + warningWithoutStack$1( + false, + "Warning: ref.measureLayout must be called with a node handle or a ref to a native component." + ); return; } @@ -3946,15 +4153,60 @@ var ReactNativeFiberHostComponent = // can re-export everything from this module. function shim() { + { + throw Error( + "The current renderer does not support persistence. This error is likely caused by a bug in React. Please file an issue." + ); + } +} // Persistence (when unsupported) + +var supportsPersistence = false; +var cloneInstance = shim; +var cloneFundamentalInstance = shim; +var createContainerChildSet = shim; +var appendChildToContainerChildSet = shim; +var finalizeContainerChildren = shim; +var replaceContainerChildren = shim; +var cloneHiddenInstance = shim; +var cloneHiddenTextInstance = shim; + +// can re-export everything from this module. + +function shim$1() { { throw Error( "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." ); } } // Hydration (when unsupported) -var isSuspenseInstancePending = shim; -var isSuspenseInstanceFallback = shim; -var hydrateTextInstance = shim; + +var supportsHydration = false; +var canHydrateInstance = shim$1; +var canHydrateTextInstance = shim$1; +var canHydrateSuspenseInstance = shim$1; +var isSuspenseInstancePending = shim$1; +var isSuspenseInstanceFallback = shim$1; +var registerSuspenseInstanceRetry = shim$1; +var getNextHydratableSibling = shim$1; +var getFirstHydratableChild = shim$1; +var hydrateInstance = shim$1; +var hydrateTextInstance = shim$1; +var hydrateSuspenseInstance = shim$1; +var getNextHydratableInstanceAfterSuspenseInstance = shim$1; +var commitHydratedContainer = shim$1; +var commitHydratedSuspenseInstance = shim$1; +var clearSuspenseBoundary = shim$1; +var clearSuspenseBoundaryFromContainer = shim$1; +var didNotMatchHydratedContainerTextInstance = shim$1; +var didNotMatchHydratedTextInstance = shim$1; +var didNotHydrateContainerInstance = shim$1; +var didNotHydrateInstance = shim$1; +var didNotFindHydratableContainerInstance = shim$1; +var didNotFindHydratableContainerTextInstance = shim$1; +var didNotFindHydratableContainerSuspenseInstance = shim$1; +var didNotFindHydratableInstance = shim$1; +var didNotFindHydratableTextInstance = shim$1; +var didNotFindHydratableSuspenseInstance = shim$1; var getViewConfigForType = ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get; @@ -3989,6 +4241,7 @@ function recursivelyUncacheFiberNode(node) { node._children.forEach(recursivelyUncacheFiberNode); } } + function appendInitialChild(parentInstance, child) { parentInstance._children.push(child); } @@ -4019,11 +4272,7 @@ function createInstance( rootContainerInstance, // rootTag updatePayload // props ); - var component = new ReactNativeFiberHostComponent( - tag, - viewConfig, - internalInstanceHandle - ); + var component = new ReactNativeFiberHostComponent(tag, viewConfig); 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. @@ -4118,6 +4367,8 @@ function prepareUpdate( function resetAfterCommit(containerInfo) { // Noop } +var isPrimaryRenderer = true; +var warnsIfNotActing = true; var scheduleTimeout = setTimeout; var cancelTimeout = clearTimeout; var noTimeout = -1; @@ -4133,6 +4384,10 @@ function shouldSetTextContent(type, props) { // More context @ github.com/facebook/react/pull/8560#discussion_r92111303 return false; } // ------------------- +// Mutation +// ------------------- + +var supportsMutation = true; function appendChild(parentInstance, child) { var childTag = typeof child === "number" ? child : child._nativeTag; var children = parentInstance._children; @@ -4177,6 +4432,7 @@ function commitTextUpdate(textInstance, oldText, newText) { } // props ); } + function commitUpdate( instance, updatePayloadTODO, @@ -4309,79 +4565,154 @@ function unhideInstance(instance, props) { function unhideTextInstance(textInstance, text) { throw new Error("Not yet implemented."); } +function mountResponderInstance( + responder, + responderInstance, + props, + state, + instance +) { + throw new Error("Not yet implemented."); +} +function unmountResponderInstance(responderInstance) { + throw new Error("Not yet implemented."); +} +function getFundamentalComponentInstance(fundamentalInstance) { + throw new Error("Not yet implemented."); +} +function mountFundamentalComponent(fundamentalInstance) { + throw new Error("Not yet implemented."); +} +function shouldUpdateFundamentalComponent(fundamentalInstance) { + throw new Error("Not yet implemented."); +} +function updateFundamentalComponent(fundamentalInstance) { + throw new Error("Not yet implemented."); +} +function unmountFundamentalComponent(fundamentalInstance) { + throw new Error("Not yet implemented."); +} +function getInstanceFromNode$1(node) { + throw new Error("Not yet implemented."); +} + +var BEFORE_SLASH_RE = /^(.*)[\\\/]/; +var describeComponentFrame = function(name, source, ownerName) { + var sourceInfo = ""; -var loggedTypeFailures = {}; -function checkPropTypes(typeSpecs, values, location, componentName) { - { - // $FlowFixMe This is okay but Flow doesn't know it. - var has = Function.call.bind(Object.prototype.hasOwnProperty); + if (source) { + var path = source.fileName; + var fileName = path.replace(BEFORE_SLASH_RE, ""); - 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. + { + // 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); - 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 (match) { + var pathBeforeSlash = match[1]; - 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 (pathBeforeSlash) { + var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, ""); + fileName = folderName + "/" + fileName; + } } + } + } - if (error$1 && !(error$1 instanceof Error)) { - 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 - ); - } + sourceInfo = " (at " + fileName + ":" + source.lineNumber + ")"; + } else if (ownerName) { + sourceInfo = " (created by " + ownerName + ")"; + } - 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; + return "\n in " + (name || "Unknown") + sourceInfo; +}; - error("Failed %s type: %s", location, error$1.message); - } +var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; + +function describeFiber(fiber) { + switch (fiber.tag) { + case HostRoot: + case HostPortal: + case HostText: + case Fragment: + case ContextProvider: + case ContextConsumer: + return ""; + + default: + var owner = fiber._debugOwner; + var source = fiber._debugSource; + var name = getComponentName(fiber.type); + var ownerName = null; + + if (owner) { + ownerName = getComponentName(owner.type); } + + return describeComponentFrame(name, source, ownerName); + } +} + +function getStackByFiberInDevAndProd(workInProgress) { + var info = ""; + var node = workInProgress; + + do { + info += describeFiber(node); + node = node.return; + } while (node); + + return info; +} +var current = null; +var phase = null; +function getCurrentFiberOwnerNameInDevOrNull() { + { + if (current === null) { + return null; + } + + var owner = current._debugOwner; + + if (owner !== null && typeof owner !== "undefined") { + return getComponentName(owner.type); } } + + return null; +} +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. + + return getStackByFiberInDevAndProd(current); + } + + return ""; +} +function resetCurrentFiber() { + { + ReactDebugCurrentFrame.getCurrentStack = null; + current = null; + phase = null; + } +} +function setCurrentFiber(fiber) { + { + ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackInDev; + current = fiber; + phase = null; + } +} +function setCurrentPhase(lifeCyclePhase) { + { + phase = lifeCyclePhase; + } } // Prefix measurements so that it's possible to filter them. @@ -4560,12 +4891,12 @@ var resumeTimers = function() { }; function recordEffect() { - { + if (enableUserTimingAPI) { effectCountInCurrentCommit++; } } function recordScheduleUpdate() { - { + if (enableUserTimingAPI) { if (isCommitting) { hasScheduledUpdateInCurrentCommit = true; } @@ -4579,8 +4910,9 @@ function recordScheduleUpdate() { } } } + function startWorkTimer(fiber) { - { + if (enableUserTimingAPI) { if (!supportsUserTiming || shouldIgnoreFiber(fiber)) { return; } // If we pause, this is the fiber to unwind from. @@ -4595,7 +4927,7 @@ function startWorkTimer(fiber) { } } function cancelWorkTimer(fiber) { - { + if (enableUserTimingAPI) { if (!supportsUserTiming || shouldIgnoreFiber(fiber)) { return; } // Remember we shouldn't complete measurement for this fiber. @@ -4606,7 +4938,7 @@ function cancelWorkTimer(fiber) { } } function stopWorkTimer(fiber) { - { + if (enableUserTimingAPI) { if (!supportsUserTiming || shouldIgnoreFiber(fiber)) { return; } // If we pause, its parent is the fiber to unwind from. @@ -4622,7 +4954,7 @@ function stopWorkTimer(fiber) { } } function stopFailedWorkTimer(fiber) { - { + if (enableUserTimingAPI) { if (!supportsUserTiming || shouldIgnoreFiber(fiber)) { return; } // If we pause, its parent is the fiber to unwind from. @@ -4642,7 +4974,7 @@ function stopFailedWorkTimer(fiber) { } } function startPhaseTimer(fiber, phase) { - { + if (enableUserTimingAPI) { if (!supportsUserTiming) { return; } @@ -4658,7 +4990,7 @@ function startPhaseTimer(fiber, phase) { } } function stopPhaseTimer() { - { + if (enableUserTimingAPI) { if (!supportsUserTiming) { return; } @@ -4675,7 +5007,7 @@ function stopPhaseTimer() { } } function startWorkLoopTimer(nextUnitOfWork) { - { + if (enableUserTimingAPI) { currentFiber = nextUnitOfWork; if (!supportsUserTiming) { @@ -4691,7 +5023,7 @@ function startWorkLoopTimer(nextUnitOfWork) { } } function stopWorkLoopTimer(interruptedBy, didCompleteRoot) { - { + if (enableUserTimingAPI) { if (!supportsUserTiming) { return; } @@ -4720,7 +5052,7 @@ function stopWorkLoopTimer(interruptedBy, didCompleteRoot) { } } function startCommitTimer() { - { + if (enableUserTimingAPI) { if (!supportsUserTiming) { return; } @@ -4732,7 +5064,7 @@ function startCommitTimer() { } } function stopCommitTimer() { - { + if (enableUserTimingAPI) { if (!supportsUserTiming) { return; } @@ -4753,7 +5085,7 @@ function stopCommitTimer() { } } function startCommitSnapshotEffectsTimer() { - { + if (enableUserTimingAPI) { if (!supportsUserTiming) { return; } @@ -4763,7 +5095,7 @@ function startCommitSnapshotEffectsTimer() { } } function stopCommitSnapshotEffectsTimer() { - { + if (enableUserTimingAPI) { if (!supportsUserTiming) { return; } @@ -4778,7 +5110,7 @@ function stopCommitSnapshotEffectsTimer() { } } function startCommitHostEffectsTimer() { - { + if (enableUserTimingAPI) { if (!supportsUserTiming) { return; } @@ -4788,7 +5120,7 @@ function startCommitHostEffectsTimer() { } } function stopCommitHostEffectsTimer() { - { + if (enableUserTimingAPI) { if (!supportsUserTiming) { return; } @@ -4803,7 +5135,7 @@ function stopCommitHostEffectsTimer() { } } function startCommitLifeCyclesTimer() { - { + if (enableUserTimingAPI) { if (!supportsUserTiming) { return; } @@ -4813,7 +5145,7 @@ function startCommitLifeCyclesTimer() { } } function stopCommitLifeCyclesTimer() { - { + if (enableUserTimingAPI) { if (!supportsUserTiming) { return; } @@ -4846,7 +5178,7 @@ function createCursor(defaultValue) { function pop(cursor, fiber) { if (index < 0) { { - error("Unexpected pop."); + warningWithoutStack$1(false, "Unexpected pop."); } return; @@ -4854,7 +5186,7 @@ function pop(cursor, fiber) { { if (fiber !== fiberStack[index]) { - error("Unexpected Fiber popped."); + warningWithoutStack$1(false, "Unexpected Fiber popped."); } } @@ -4904,7 +5236,9 @@ function getUnmaskedContext( Component, didPushOwnContextIfProvider ) { - { + if (disableLegacyContext) { + return emptyContextObject; + } else { 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 @@ -4918,7 +5252,9 @@ function getUnmaskedContext( } function cacheContext(workInProgress, unmaskedContext, maskedContext) { - { + if (disableLegacyContext) { + return; + } else { var instance = workInProgress.stateNode; instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext; instance.__reactInternalMemoizedMaskedChildContext = maskedContext; @@ -4926,7 +5262,9 @@ function cacheContext(workInProgress, unmaskedContext, maskedContext) { } function getMaskedContext(workInProgress, unmaskedContext) { - { + if (disableLegacyContext) { + return emptyContextObject; + } else { var type = workInProgress.type; var contextTypes = type.contextTypes; @@ -4953,7 +5291,13 @@ function getMaskedContext(workInProgress, unmaskedContext) { { var name = getComponentName(type) || "Unknown"; - checkPropTypes(contextTypes, context, "context", name); + checkPropTypes( + contextTypes, + context, + "context", + name, + getCurrentFiberStackInDev + ); } // 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. @@ -4966,34 +5310,44 @@ function getMaskedContext(workInProgress, unmaskedContext) { } function hasContextChanged() { - { + if (disableLegacyContext) { + return false; + } else { return didPerformWorkStackCursor.current; } } function isContextProvider(type) { - { + if (disableLegacyContext) { + return false; + } else { var childContextTypes = type.childContextTypes; return childContextTypes !== null && childContextTypes !== undefined; } } function popContext(fiber) { - { + if (disableLegacyContext) { + return; + } else { pop(didPerformWorkStackCursor, fiber); pop(contextStackCursor, fiber); } } function popTopLevelContextObject(fiber) { - { + if (disableLegacyContext) { + return; + } else { pop(didPerformWorkStackCursor, fiber); pop(contextStackCursor, fiber); } } function pushTopLevelContextObject(fiber, context, didChange) { - { + if (disableLegacyContext) { + return; + } else { 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." @@ -5006,7 +5360,9 @@ function pushTopLevelContextObject(fiber, context, didChange) { } function processChildContext(fiber, type, parentContext) { - { + if (disableLegacyContext) { + return parentContext; + } else { 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. @@ -5017,8 +5373,8 @@ function processChildContext(fiber, type, parentContext) { if (!warnedAboutMissingGetChildContext[componentName]) { warnedAboutMissingGetChildContext[componentName] = true; - - error( + warningWithoutStack$1( + false, "%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.", @@ -5032,10 +5388,19 @@ function processChildContext(fiber, type, parentContext) { } var childContext; + + { + setCurrentPhase("getChildContext"); + } + startPhaseTimer(fiber, "getChildContext"); childContext = instance.getChildContext(); stopPhaseTimer(); + { + setCurrentPhase(null); + } + for (var contextKey in childContext) { if (!(contextKey in childContextTypes)) { throw Error( @@ -5049,7 +5414,17 @@ function processChildContext(fiber, type, parentContext) { { var name = getComponentName(type) || "Unknown"; - checkPropTypes(childContextTypes, childContext, "child context", name); + checkPropTypes( + childContextTypes, + childContext, + "child context", + name, // In practice, there is one case in which we won't get a stack. It's when + // somebody calls unstable_renderSubtreeIntoContainer() and we process + // context from the parent component instance. The stack will be missing + // because it's outside of the reconciliation, and so the pointer has not + // been set. This is rare and doesn't matter. We'll also remove that API. + getCurrentFiberStackInDev + ); } return Object.assign({}, parentContext, {}, childContext); @@ -5057,7 +5432,9 @@ function processChildContext(fiber, type, parentContext) { } function pushContextProvider(workInProgress) { - { + if (disableLegacyContext) { + return false; + } else { 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. @@ -5079,7 +5456,9 @@ function pushContextProvider(workInProgress) { } function invalidateContextProvider(workInProgress, type, didChange) { - { + if (disableLegacyContext) { + return; + } else { var instance = workInProgress.stateNode; if (!instance) { @@ -5113,7 +5492,9 @@ function invalidateContextProvider(workInProgress, type, didChange) { } function findCurrentUnmaskedContext(fiber) { - { + if (disableLegacyContext) { + return emptyContextObject; + } else { // Currently this is only used with renderSubtreeIntoContainer; not sure if it // makes sense elsewhere if (!(isFiberMounted(fiber) && fiber.tag === ClassComponent)) { @@ -5156,21 +5537,22 @@ var BlockingRoot = 1; var ConcurrentRoot = 2; // 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; - -{ +// CommonJS interop named imports. +var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority; +var Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback; +var Scheduler_cancelCallback = Scheduler.unstable_cancelCallback; +var Scheduler_shouldYield = Scheduler.unstable_shouldYield; +var Scheduler_requestPaint = Scheduler.unstable_requestPaint; +var Scheduler_now = Scheduler.unstable_now; +var Scheduler_getCurrentPriorityLevel = + Scheduler.unstable_getCurrentPriorityLevel; +var Scheduler_ImmediatePriority = Scheduler.unstable_ImmediatePriority; +var Scheduler_UserBlockingPriority = Scheduler.unstable_UserBlockingPriority; +var Scheduler_NormalPriority = Scheduler.unstable_NormalPriority; +var Scheduler_LowPriority = Scheduler.unstable_LowPriority; +var Scheduler_IdlePriority = Scheduler.unstable_IdlePriority; + +if (enableSchedulerTracing) { // Provide explicit error message when production+profiling bundle of e.g. // react-dom is used with production (non-profiling) bundle of // scheduler/tracing @@ -5364,14 +5746,14 @@ var NoWork = 0; // TODO: Think of a better name for Never. The key difference wi var Never = 1; // Idle is slightly higher priority than Never. It must completely finish in // order to be consistent. -var Idle = 2; // Continuous Hydration is slightly higher than Idle and is used to increase +var Idle = 2; // Continuous Hydration is a moving priority. It is slightly higher than Idle var Sync = MAX_SIGNED_31_BIT_INT; var Batched = Sync - 1; var UNIT_SIZE = 10; var MAGIC_NUMBER_OFFSET = Batched - 1; // 1 unit of expiration time represents 10ms. function msToExpirationTime(ms) { - // Always subtract from the offset so that we don't clash with the magic number for NoWork. + // Always add an offset so that we don't clash with the magic number for NoWork. return MAGIC_NUMBER_OFFSET - ((ms / UNIT_SIZE) | 0); } function expirationTimeToMs(expirationTime) { @@ -5430,6 +5812,7 @@ function computeInteractiveExpiration(currentTime) { HIGH_PRIORITY_BATCH_SIZE ); } + function inferPriorityFromExpirationTime(currentTime, expirationTime) { if (expirationTime === Sync) { return ImmediatePriority; @@ -5468,7 +5851,7 @@ function is(x, y) { ); } -var objectIs = typeof Object.is === "function" ? Object.is : is; +var is$1 = typeof Object.is === "function" ? Object.is : is; var hasOwnProperty = Object.prototype.hasOwnProperty; /** @@ -5478,7 +5861,7 @@ var hasOwnProperty = Object.prototype.hasOwnProperty; */ function shallowEqual(objA, objB) { - if (objectIs(objA, objB)) { + if (is$1(objA, objB)) { return true; } @@ -5501,7 +5884,7 @@ function shallowEqual(objA, objB) { for (var i = 0; i < keysA.length; i++) { if ( !hasOwnProperty.call(objB, keysA[i]) || - !objectIs(objA[keysA[i]], objB[keysA[i]]) + !is$1(objA[keysA[i]], objB[keysA[i]]) ) { return false; } @@ -5510,123 +5893,78 @@ function shallowEqual(objA, objB) { return true; } -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]; - - if (pathBeforeSlash) { - var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, ""); - fileName = folderName + "/" + fileName; - } - } - } - } - - sourceInfo = " (at " + fileName + ":" + source.lineNumber + ")"; - } else if (ownerName) { - sourceInfo = " (created by " + ownerName + ")"; - } - - return "\n in " + (name || "Unknown") + sourceInfo; -} - -var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; - -function describeFiber(fiber) { - switch (fiber.tag) { - case HostRoot: - case HostPortal: - case HostText: - case Fragment: - case ContextProvider: - case ContextConsumer: - return ""; - - default: - var owner = fiber._debugOwner; - var source = fiber._debugSource; - var name = getComponentName(fiber.type); - var ownerName = null; - - if (owner) { - ownerName = getComponentName(owner.type); - } - - return describeComponentFrame(name, source, ownerName); - } -} - -function getStackByFiberInDevAndProd(workInProgress) { - var info = ""; - var node = workInProgress; +/** + * Forked from fbjs/warning: + * https://github.com/facebook/fbjs/blob/e66ba20ad5be433eb54423f2b097d829324d9de6/packages/fbjs/src/__forks__/warning.js + * + * Only change is we use console.warn instead of console.error, + * and do nothing when 'console' is not supported. + * This really simplifies the code. + * --- + * Similar to invariant but only logs a warning if the condition is not met. + * This can be used to log issues in development environments in critical + * paths. Removing the logging code for production environments will keep the + * same logic and follow the same code paths. + */ +var lowPriorityWarningWithoutStack = function() {}; - do { - info += describeFiber(node); - node = node.return; - } while (node); +{ + var printWarning = function(format) { + for ( + var _len = arguments.length, + args = new Array(_len > 1 ? _len - 1 : 0), + _key = 1; + _key < _len; + _key++ + ) { + args[_key - 1] = arguments[_key]; + } - return info; -} -var current = null; -var isRendering = false; -function getCurrentFiberOwnerNameInDevOrNull() { - { - if (current === null) { - return null; + var argIndex = 0; + var message = + "Warning: " + + format.replace(/%s/g, function() { + return args[argIndex++]; + }); + + if (typeof console !== "undefined") { + console.warn(message); } - var owner = current._debugOwner; + try { + // --- Welcome to debugging React --- + // This error was thrown as a convenience so that you can use this stack + // to find the callsite that caused this warning to fire. + throw new Error(message); + } catch (x) {} + }; - if (owner !== null && typeof owner !== "undefined") { - return getComponentName(owner.type); + lowPriorityWarningWithoutStack = function(condition, format) { + if (format === undefined) { + throw new Error( + "`lowPriorityWarningWithoutStack(condition, format, ...args)` requires a warning " + + "message argument" + ); } - } - return null; -} -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. + if (!condition) { + for ( + var _len2 = arguments.length, + args = new Array(_len2 > 2 ? _len2 - 2 : 0), + _key2 = 2; + _key2 < _len2; + _key2++ + ) { + args[_key2 - 2] = arguments[_key2]; + } - return getStackByFiberInDevAndProd(current); - } -} -function resetCurrentFiber() { - { - ReactDebugCurrentFrame.getCurrentStack = null; - current = null; - isRendering = false; - } -} -function setCurrentFiber(fiber) { - { - ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackInDev; - current = fiber; - isRendering = false; - } -} -function setIsRendering(rendering) { - { - isRendering = rendering; - } + printWarning.apply(void 0, [format].concat(args)); + } + }; } +var lowPriorityWarningWithoutStack$1 = lowPriorityWarningWithoutStack; + var ReactStrictModeWarnings = { recordUnsafeLifecycleWarnings: function(fiber, instance) {}, flushPendingUnsafeLifecycleWarnings: function() {}, @@ -5797,8 +6135,8 @@ var ReactStrictModeWarnings = { if (UNSAFE_componentWillMountUniqueNames.size > 0) { var sortedNames = setToSortedString(UNSAFE_componentWillMountUniqueNames); - - error( + warningWithoutStack$1( + false, "Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. " + "See https://fb.me/react-unsafe-component-lifecycles for details.\n\n" + "* Move code with side effects to componentDidMount, and set initial state in the constructor.\n" + @@ -5812,7 +6150,8 @@ var ReactStrictModeWarnings = { UNSAFE_componentWillReceivePropsUniqueNames ); - error( + warningWithoutStack$1( + false, "Using UNSAFE_componentWillReceiveProps in strict mode is not recommended " + "and may indicate bugs in your code. " + "See https://fb.me/react-unsafe-component-lifecycles for details.\n\n" + @@ -5830,7 +6169,8 @@ var ReactStrictModeWarnings = { UNSAFE_componentWillUpdateUniqueNames ); - error( + warningWithoutStack$1( + false, "Using UNSAFE_componentWillUpdate in strict mode is not recommended " + "and may indicate bugs in your code. " + "See https://fb.me/react-unsafe-component-lifecycles for details.\n\n" + @@ -5843,7 +6183,8 @@ var ReactStrictModeWarnings = { if (componentWillMountUniqueNames.size > 0) { var _sortedNames3 = setToSortedString(componentWillMountUniqueNames); - warn( + lowPriorityWarningWithoutStack$1( + false, "componentWillMount has been renamed, and is not recommended for use. " + "See https://fb.me/react-unsafe-component-lifecycles for details.\n\n" + "* Move code with side effects to componentDidMount, and set initial state in the constructor.\n" + @@ -5861,7 +6202,8 @@ var ReactStrictModeWarnings = { componentWillReceivePropsUniqueNames ); - warn( + lowPriorityWarningWithoutStack$1( + false, "componentWillReceiveProps has been renamed, and is not recommended for use. " + "See https://fb.me/react-unsafe-component-lifecycles for details.\n\n" + "* Move data fetching code or side effects to componentDidUpdate.\n" + @@ -5880,7 +6222,8 @@ var ReactStrictModeWarnings = { if (componentWillUpdateUniqueNames.size > 0) { var _sortedNames5 = setToSortedString(componentWillUpdateUniqueNames); - warn( + lowPriorityWarningWithoutStack$1( + false, "componentWillUpdate has been renamed, and is not recommended for use. " + "See https://fb.me/react-unsafe-component-lifecycles for details.\n\n" + "* Move data fetching code or side effects to componentDidUpdate.\n" + @@ -5905,11 +6248,11 @@ var ReactStrictModeWarnings = { var strictRoot = findStrictRoot(fiber); if (strictRoot === null) { - error( + warningWithoutStack$1( + false, "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." ); - return; } // Dedup strategy: Warn once per component. @@ -5935,20 +6278,15 @@ var ReactStrictModeWarnings = { ReactStrictModeWarnings.flushLegacyContextWarning = function() { pendingLegacyContextWarning.forEach(function(fiberArray, strictRoot) { - if (fiberArray.length === 0) { - return; - } - - 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); - var firstComponentStack = getStackByFiberInDevAndProd(firstFiber); - - error( + var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot); + warningWithoutStack$1( + false, "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." + @@ -5956,7 +6294,7 @@ var ReactStrictModeWarnings = { "\n\nLearn more about this warning here: https://fb.me/react-legacy-context" + "%s", sortedNames, - firstComponentStack + strictRootComponentStack ); }); }; @@ -6199,6 +6537,9 @@ function scheduleFibersWithFamiliesRecursively( case ForwardRef: candidateType = type.render; break; + + default: + break; } if (resolveFamily === null) { @@ -6298,6 +6639,9 @@ function findHostInstancesForMatchingFibersRecursively( case ForwardRef: candidateType = type.render; break; + + default: + break; } var didMatch = false; @@ -6470,24 +6814,42 @@ function exitDisallowedContextReadInDEV() { function pushProvider(providerFiber, nextValue) { var context = providerFiber.type._context; - { + if (isPrimaryRenderer) { push(valueCursor, context._currentValue, providerFiber); context._currentValue = nextValue; { - if ( - context._currentRenderer !== undefined && - context._currentRenderer !== null && - context._currentRenderer !== rendererSigil - ) { - error( - "Detected multiple renderers concurrently rendering the " + - "same context provider. This is currently unsupported." - ); - } - + !( + context._currentRenderer === undefined || + context._currentRenderer === null || + context._currentRenderer === rendererSigil + ) + ? warningWithoutStack$1( + false, + "Detected multiple renderers concurrently rendering the " + + "same context provider. This is currently unsupported." + ) + : void 0; context._currentRenderer = rendererSigil; } + } else { + push(valueCursor, context._currentValue2, providerFiber); + context._currentValue2 = nextValue; + + { + !( + context._currentRenderer2 === undefined || + context._currentRenderer2 === null || + context._currentRenderer2 === rendererSigil + ) + ? warningWithoutStack$1( + false, + "Detected multiple renderers concurrently rendering the " + + "same context provider. This is currently unsupported." + ) + : void 0; + context._currentRenderer2 = rendererSigil; + } } } function popProvider(providerFiber) { @@ -6495,12 +6857,14 @@ function popProvider(providerFiber) { pop(valueCursor, providerFiber); var context = providerFiber.type._context; - { + if (isPrimaryRenderer) { context._currentValue = currentValue; + } else { + context._currentValue2 = currentValue; } } function calculateChangedBits(context, newValue, oldValue) { - if (objectIs(oldValue, newValue)) { + if (is$1(oldValue, newValue)) { // No change return 0; } else { @@ -6510,13 +6874,14 @@ function calculateChangedBits(context, newValue, oldValue) { : MAX_SIGNED_31_BIT_INT; { - if ((changedBits & MAX_SIGNED_31_BIT_INT) !== changedBits) { - error( - "calculateChangedBits: Expected the return value to be a " + - "31-bit integer. Instead received: %s", - changedBits - ); - } + !((changedBits & MAX_SIGNED_31_BIT_INT) === changedBits) + ? warning$1( + false, + "calculateChangedBits: Expected the return value to be a " + + "31-bit integer. Instead received: %s", + changedBits + ) + : void 0; } return changedBits | 0; @@ -6621,6 +6986,39 @@ function propagateContextChange( } else if (fiber.tag === ContextProvider) { // Don't scan deeper if this is a matching provider nextFiber = fiber.type === workInProgress.type ? null : fiber.child; + } else if ( + enableSuspenseServerRenderer && + fiber.tag === DehydratedFragment + ) { + // If a dehydrated suspense bounudary is in this subtree, we don't know + // if it will have any context consumers in it. The best we can do is + // mark it as having updates. + var parentSuspense = fiber.return; + + if (!(parentSuspense !== null)) { + throw Error( + "We just came from a parent so we must have had a parent. This is a bug in React." + ); + } + + if (parentSuspense.expirationTime < renderExpirationTime) { + parentSuspense.expirationTime = renderExpirationTime; + } + + var _alternate = parentSuspense.alternate; + + if ( + _alternate !== null && + _alternate.expirationTime < renderExpirationTime + ) { + _alternate.expirationTime = renderExpirationTime; + } // This is intentionally passing this fiber as the parent + // because we want to schedule this fiber as having work + // on its children. We'll use the childExpirationTime on + // this fiber to indicate that a context has changed. + + scheduleWorkOnParentPath(parentSuspense, renderExpirationTime); + nextFiber = fiber.sibling; } else { // Traverse down. nextFiber = fiber.child; @@ -6679,19 +7077,22 @@ 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()." - ); - } + !!isDisallowedContextReadInDEV + ? warning$1( + false, + "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()." + ) + : void 0; } - if (lastContextWithAllBitsObserved === context); - else if (observedBits === false || observedBits === 0); - else { + if (lastContextWithAllBitsObserved === context) { + // Nothing to do. We already observe everything in this context. + } else if (observedBits === false || observedBits === 0) { + // Do not observe any updates. + } else { var resolvedObservedBits; // Avoid deopting on observable arguments or heterogeneous types. if ( @@ -6730,9 +7131,85 @@ function readContext(context, observedBits) { } } - return context._currentValue; + return isPrimaryRenderer ? context._currentValue : context._currentValue2; } +// UpdateQueue is a linked list of prioritized updates. +// +// Like fibers, update queues come in pairs: a current queue, which represents +// the visible state of the screen, and a work-in-progress queue, which can be +// mutated and processed asynchronously before it is committed — a form of +// double buffering. If a work-in-progress render is discarded before finishing, +// we create a new work-in-progress by cloning the current queue. +// +// Both queues share a persistent, singly-linked list structure. To schedule an +// update, we append it to the end of both queues. Each queue maintains a +// pointer to first update in the persistent list that hasn't been processed. +// The work-in-progress pointer always has a position equal to or greater than +// the current queue, since we always work on that one. The current queue's +// pointer is only updated during the commit phase, when we swap in the +// work-in-progress. +// +// For example: +// +// Current pointer: A - B - C - D - E - F +// Work-in-progress pointer: D - E - F +// ^ +// The work-in-progress queue has +// processed more updates than current. +// +// The reason we append to both queues is because otherwise we might drop +// updates without ever processing them. For example, if we only add updates to +// the work-in-progress queue, some updates could be lost whenever a work-in +// -progress render restarts by cloning from current. Similarly, if we only add +// updates to the current queue, the updates will be lost whenever an already +// in-progress queue commits and swaps with the current queue. However, by +// adding to both queues, we guarantee that the update will be part of the next +// work-in-progress. (And because the work-in-progress queue becomes the +// current queue once it commits, there's no danger of applying the same +// update twice.) +// +// Prioritization +// -------------- +// +// Updates are not sorted by priority, but by insertion; new updates are always +// appended to the end of the list. +// +// The priority is still important, though. When processing the update queue +// during the render phase, only the updates with sufficient priority are +// included in the result. If we skip an update because it has insufficient +// priority, it remains in the queue to be processed later, during a lower +// priority render. Crucially, all updates subsequent to a skipped update also +// remain in the queue *regardless of their priority*. That means high priority +// updates are sometimes processed twice, at two separate priorities. We also +// keep track of a base state, that represents the state before the first +// update in the queue is applied. +// +// For example: +// +// Given a base state of '', and the following queue of updates +// +// A1 - B2 - C1 - D2 +// +// where the number indicates the priority, and the update is applied to the +// previous state by appending a letter, React will process these updates as +// two separate renders, one per distinct priority level: +// +// First render, at priority 1: +// Base state: '' +// Updates: [A1, C1] +// Result state: 'AC' +// +// Second render, at priority 2: +// Base state: 'A' <- The base state does not include C1, +// because B2 was skipped. +// Updates: [B2, C1, D2] <- C1 was rebased on top of B2 +// Result state: 'ABCD' +// +// Because we process updates in insertion order, and rebase high priority +// updates when preceding updates are skipped, the final result is deterministic +// regardless of priority. Intermediate state may vary according to system +// resources, but the final state is always the same. var UpdateState = 0; var ReplaceState = 1; var ForceUpdate = 2; @@ -6749,32 +7226,38 @@ var currentlyProcessingQueue; currentlyProcessingQueue = null; } -function initializeUpdateQueue(fiber) { +function createUpdateQueue(baseState) { var queue = { - baseState: fiber.memoizedState, - baseQueue: null, - shared: { - pending: null - }, - effects: null + baseState: baseState, + firstUpdate: null, + lastUpdate: null, + firstCapturedUpdate: null, + lastCapturedUpdate: null, + firstEffect: null, + lastEffect: null, + firstCapturedEffect: null, + lastCapturedEffect: 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; - - if (queue === currentQueue) { - var clone = { - baseState: currentQueue.baseState, - baseQueue: currentQueue.baseQueue, - shared: currentQueue.shared, - effects: currentQueue.effects - }; - workInProgress.updateQueue = clone; - } + return queue; +} + +function cloneUpdateQueue(currentQueue) { + var queue = { + baseState: currentQueue.baseState, + firstUpdate: currentQueue.firstUpdate, + lastUpdate: currentQueue.lastUpdate, + // TODO: With resuming, if we bail out and resuse the child tree, we should + // keep these effects. + firstCapturedUpdate: null, + lastCapturedUpdate: null, + firstEffect: null, + lastEffect: null, + firstCapturedEffect: null, + lastCapturedEffect: null + }; + return queue; } + function createUpdate(expirationTime, suspenseConfig) { var update = { expirationTime: expirationTime, @@ -6782,9 +7265,9 @@ function createUpdate(expirationTime, suspenseConfig) { tag: UpdateState, payload: null, callback: null, - next: null + next: null, + nextEffect: null }; - update.next = update; { update.priority = getCurrentPriorityLevel(); @@ -6792,62 +7275,136 @@ function createUpdate(expirationTime, suspenseConfig) { return update; } -function enqueueUpdate(fiber, update) { - var updateQueue = fiber.updateQueue; - if (updateQueue === null) { - // Only occurs if the fiber has been unmounted. - return; +function appendUpdateToQueue(queue, update) { + // Append the update to the end of the list. + if (queue.lastUpdate === null) { + // Queue is empty + queue.firstUpdate = queue.lastUpdate = update; + } else { + queue.lastUpdate.next = update; + queue.lastUpdate = update; } +} + +function enqueueUpdate(fiber, update) { + // Update queues are created lazily. + var alternate = fiber.alternate; + var queue1; + var queue2; - var sharedQueue = updateQueue.shared; - var pending = sharedQueue.pending; + if (alternate === null) { + // There's only one fiber. + queue1 = fiber.updateQueue; + queue2 = null; - if (pending === null) { - // This is the first update. Create a circular list. - update.next = update; + if (queue1 === null) { + queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState); + } } else { - update.next = pending.next; - pending.next = update; + // There are two owners. + queue1 = fiber.updateQueue; + queue2 = alternate.updateQueue; + + if (queue1 === null) { + if (queue2 === null) { + // Neither fiber has an update queue. Create new ones. + queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState); + queue2 = alternate.updateQueue = createUpdateQueue( + alternate.memoizedState + ); + } else { + // Only one fiber has an update queue. Clone to create a new one. + queue1 = fiber.updateQueue = cloneUpdateQueue(queue2); + } + } else { + if (queue2 === null) { + // Only one fiber has an update queue. Clone to create a new one. + queue2 = alternate.updateQueue = cloneUpdateQueue(queue1); + } else { + // Both owners have an update queue. + } + } } - sharedQueue.pending = update; + if (queue2 === null || queue1 === queue2) { + // There's only a single queue. + appendUpdateToQueue(queue1, update); + } else { + // There are two queues. We need to append the update to both queues, + // while accounting for the persistent structure of the list — we don't + // want the same update to be added multiple times. + if (queue1.lastUpdate === null || queue2.lastUpdate === null) { + // One of the queues is not empty. We must add the update to both queues. + appendUpdateToQueue(queue1, update); + appendUpdateToQueue(queue2, update); + } else { + // Both queues are non-empty. The last update is the same in both lists, + // because of structural sharing. So, only append to one of the lists. + appendUpdateToQueue(queue1, update); // But we still need to update the `lastUpdate` pointer of queue2. + + queue2.lastUpdate = update; + } + } { if ( - currentlyProcessingQueue === sharedQueue && + fiber.tag === ClassComponent && + (currentlyProcessingQueue === queue1 || + (queue2 !== null && currentlyProcessingQueue === queue2)) && !didWarnUpdateInsideUpdate ) { - error( + warningWithoutStack$1( + false, "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, update) { - var current = workInProgress.alternate; + // Captured updates go into a separate list, and only on the work-in- + // progress queue. + var workInProgressQueue = workInProgress.updateQueue; - if (current !== null) { - // Ensure the work-in-progress queue is a clone - cloneUpdateQueue(current, workInProgress); - } // Captured updates go only on the work-in-progress queue. + if (workInProgressQueue === null) { + workInProgressQueue = workInProgress.updateQueue = createUpdateQueue( + workInProgress.memoizedState + ); + } else { + // TODO: I put this here rather than createWorkInProgress so that we don't + // clone the queue unnecessarily. There's probably a better way to + // structure this. + workInProgressQueue = ensureWorkInProgressQueueIsAClone( + workInProgress, + workInProgressQueue + ); + } // Append the update to the end of the list. - var queue = workInProgress.updateQueue; // Append the update to the end of the list. + if (workInProgressQueue.lastCapturedUpdate === null) { + // This is the first render phase update + workInProgressQueue.firstCapturedUpdate = workInProgressQueue.lastCapturedUpdate = update; + } else { + workInProgressQueue.lastCapturedUpdate.next = update; + workInProgressQueue.lastCapturedUpdate = update; + } +} - var last = queue.baseQueue; +function ensureWorkInProgressQueueIsAClone(workInProgress, queue) { + var current = workInProgress.alternate; - if (last === null) { - queue.baseQueue = update.next = update; - update.next = update; - } else { - update.next = last.next; - last.next = update; + if (current !== null) { + // If the work-in-progress queue is equal to the current queue, + // we need to clone it first. + if (queue === current.updateQueue) { + queue = workInProgress.updateQueue = cloneUpdateQueue(queue); + } } + + return queue; } function getStateFromUpdate( @@ -6866,6 +7423,13 @@ function getStateFromUpdate( // Updater function { enterDisallowedContextReadInDEV(); + + if ( + debugRenderPhaseSideEffectsForStrictMode && + workInProgress.mode & StrictMode + ) { + payload.call(instance, prevState, nextProps); + } } var nextState = payload.call(instance, prevState, nextProps); @@ -6894,6 +7458,13 @@ function getStateFromUpdate( // Updater function { enterDisallowedContextReadInDEV(); + + if ( + debugRenderPhaseSideEffectsForStrictMode && + workInProgress.mode & StrictMode + ) { + _payload.call(instance, prevState, nextProps); + } } partialState = _payload.call(instance, prevState, nextProps); @@ -6925,171 +7496,163 @@ function getStateFromUpdate( function processUpdateQueue( workInProgress, + queue, props, instance, renderExpirationTime ) { - // This is always non-null on a ClassComponent or HostRoot - var queue = workInProgress.updateQueue; hasForceUpdate = false; + queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue); { - currentlyProcessingQueue = queue.shared; - } // The last rebase update that is NOT part of the base state. - - var baseQueue = queue.baseQueue; // The last pending update that hasn't been processed yet. + currentlyProcessingQueue = queue; + } // These values may change as we process the queue. - var pendingQueue = queue.shared.pending; + var newBaseState = queue.baseState; + var newFirstUpdate = null; + var newExpirationTime = NoWork; // Iterate through the list of updates to compute the result. - if (pendingQueue !== null) { - // We have new updates that haven't been processed yet. - // We'll add them to the base queue. - if (baseQueue !== null) { - // Merge the pending queue and the base queue. - var baseFirst = baseQueue.next; - var pendingFirst = pendingQueue.next; - baseQueue.next = pendingFirst; - pendingQueue.next = baseFirst; - } + var update = queue.firstUpdate; + var resultState = newBaseState; - baseQueue = pendingQueue; - queue.shared.pending = null; // TODO: Pass `current` as argument + while (update !== null) { + var updateExpirationTime = update.expirationTime; - var current = workInProgress.alternate; + if (updateExpirationTime < renderExpirationTime) { + // This update does not have sufficient priority. Skip it. + if (newFirstUpdate === null) { + // This is the first skipped update. It will be the first update in + // the new list. + newFirstUpdate = update; // Since this is the first update that was skipped, the current result + // is the new base state. - if (current !== null) { - var currentQueue = current.updateQueue; + newBaseState = resultState; + } // Since this update will remain in the list, update the remaining + // expiration time. - if (currentQueue !== null) { - currentQueue.baseQueue = pendingQueue; + if (newExpirationTime < updateExpirationTime) { + newExpirationTime = updateExpirationTime; } - } - } // These values may change as we process the queue. + } else { + // This update does have sufficient priority. + // Mark the event time of this update as relevant to this render pass. + // TODO: This should ideally use the true event time of this update rather than + // its priority which is a derived and not reverseable value. + // TODO: We should skip this update if it was already committed but currently + // we have no way of detecting the difference between a committed and suspended + // update here. + markRenderEventTimeAndConfig(updateExpirationTime, update.suspenseConfig); // Process it and compute a new result. + + resultState = getStateFromUpdate( + workInProgress, + queue, + update, + resultState, + props, + instance + ); + var callback = update.callback; - if (baseQueue !== null) { - var first = baseQueue.next; // Iterate through the list of updates to compute the result. + if (callback !== null) { + workInProgress.effectTag |= Callback; // Set this to null, in case it was mutated during an aborted render. - var newState = queue.baseState; - var newExpirationTime = NoWork; - var newBaseState = null; - var newBaseQueueFirst = null; - var newBaseQueueLast = null; + update.nextEffect = null; - if (first !== null) { - var update = first; + if (queue.lastEffect === null) { + queue.firstEffect = queue.lastEffect = update; + } else { + queue.lastEffect.nextEffect = update; + queue.lastEffect = update; + } + } + } // Continue to the next update. - do { - var updateExpirationTime = update.expirationTime; - - if (updateExpirationTime < renderExpirationTime) { - // 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 = { - expirationTime: update.expirationTime, - suspenseConfig: update.suspenseConfig, - tag: update.tag, - payload: update.payload, - callback: update.callback, - next: null - }; + update = update.next; + } // Separately, iterate though the list of captured updates. - if (newBaseQueueLast === null) { - newBaseQueueFirst = newBaseQueueLast = clone; - newBaseState = newState; - } else { - newBaseQueueLast = newBaseQueueLast.next = clone; - } // Update the remaining priority in the queue. + var newFirstCapturedUpdate = null; + update = queue.firstCapturedUpdate; - if (updateExpirationTime > newExpirationTime) { - newExpirationTime = updateExpirationTime; - } - } else { - // This update does have sufficient priority. - if (newBaseQueueLast !== null) { - var _clone = { - expirationTime: Sync, - // This update is going to be committed so we never want uncommit it. - suspenseConfig: update.suspenseConfig, - tag: update.tag, - payload: update.payload, - callback: update.callback, - next: null - }; - newBaseQueueLast = newBaseQueueLast.next = _clone; - } // Mark the event time of this update as relevant to this render pass. - // TODO: This should ideally use the true event time of this update rather than - // its priority which is a derived and not reverseable value. - // TODO: We should skip this update if it was already committed but currently - // we have no way of detecting the difference between a committed and suspended - // update here. - - markRenderEventTimeAndConfig( - updateExpirationTime, - update.suspenseConfig - ); // Process this update. - - newState = getStateFromUpdate( - workInProgress, - queue, - update, - newState, - props, - instance - ); - var callback = update.callback; + while (update !== null) { + var _updateExpirationTime = update.expirationTime; - if (callback !== null) { - workInProgress.effectTag |= Callback; - var effects = queue.effects; + if (_updateExpirationTime < renderExpirationTime) { + // This update does not have sufficient priority. Skip it. + if (newFirstCapturedUpdate === null) { + // This is the first skipped captured update. It will be the first + // update in the new list. + newFirstCapturedUpdate = update; // If this is the first update that was skipped, the current result is + // the new base state. - if (effects === null) { - queue.effects = [update]; - } else { - effects.push(update); - } - } + if (newFirstUpdate === null) { + newBaseState = resultState; } + } // Since this update will remain in the list, update the remaining + // expiration time. + + if (newExpirationTime < _updateExpirationTime) { + newExpirationTime = _updateExpirationTime; + } + } else { + // This update does have sufficient priority. Process it and compute + // a new result. + resultState = getStateFromUpdate( + workInProgress, + queue, + update, + resultState, + props, + instance + ); + var _callback = update.callback; - update = update.next; + if (_callback !== null) { + workInProgress.effectTag |= Callback; // Set this to null, in case it was mutated during an aborted render. - if (update === null || update === first) { - pendingQueue = queue.shared.pending; + update.nextEffect = null; - 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. - update = baseQueue.next = pendingQueue.next; - pendingQueue.next = first; - queue.baseQueue = baseQueue = pendingQueue; - queue.shared.pending = null; - } + if (queue.lastCapturedEffect === null) { + queue.firstCapturedEffect = queue.lastCapturedEffect = update; + } else { + queue.lastCapturedEffect.nextEffect = update; + queue.lastCapturedEffect = update; } - } while (true); + } } - if (newBaseQueueLast === null) { - newBaseState = newState; - } else { - newBaseQueueLast.next = newBaseQueueFirst; - } + update = update.next; + } - queue.baseState = newBaseState; - queue.baseQueue = newBaseQueueLast; // 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. + if (newFirstUpdate === null) { + queue.lastUpdate = null; + } - markUnprocessedUpdateTime(newExpirationTime); - workInProgress.expirationTime = newExpirationTime; - workInProgress.memoizedState = newState; + if (newFirstCapturedUpdate === null) { + queue.lastCapturedUpdate = null; + } else { + workInProgress.effectTag |= Callback; } + if (newFirstUpdate === null && newFirstCapturedUpdate === null) { + // We processed every update, without skipping. That means the new base + // state is the same as the result state. + newBaseState = resultState; + } + + queue.baseState = newBaseState; + queue.firstUpdate = newFirstUpdate; + queue.firstCapturedUpdate = newFirstCapturedUpdate; // 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. + + markUnprocessedUpdateTime(newExpirationTime); + workInProgress.expirationTime = newExpirationTime; + workInProgress.memoizedState = resultState; + { currentlyProcessingQueue = null; } @@ -7112,21 +7675,42 @@ function resetHasForceUpdateBeforeProcessing() { function checkHasForceUpdateAfterProcessing() { return hasForceUpdate; } -function commitUpdateQueue(finishedWork, finishedQueue, instance) { - // Commit the effects - var effects = finishedQueue.effects; - finishedQueue.effects = null; +function commitUpdateQueue( + finishedWork, + finishedQueue, + instance, + renderExpirationTime +) { + // If the finished render included captured updates, and there are still + // lower priority updates left over, we need to keep the captured updates + // in the queue so that they are rebased and not dropped once we process the + // queue again at the lower priority. + if (finishedQueue.firstCapturedUpdate !== null) { + // Join the captured update list to the end of the normal list. + if (finishedQueue.lastUpdate !== null) { + finishedQueue.lastUpdate.next = finishedQueue.firstCapturedUpdate; + finishedQueue.lastUpdate = finishedQueue.lastCapturedUpdate; + } // Clear the list of captured updates. + + finishedQueue.firstCapturedUpdate = finishedQueue.lastCapturedUpdate = null; + } // Commit the effects + + commitUpdateEffects(finishedQueue.firstEffect, instance); + finishedQueue.firstEffect = finishedQueue.lastEffect = null; + commitUpdateEffects(finishedQueue.firstCapturedEffect, instance); + finishedQueue.firstCapturedEffect = finishedQueue.lastCapturedEffect = null; +} - if (effects !== null) { - for (var i = 0; i < effects.length; i++) { - var effect = effects[i]; - var callback = effect.callback; +function commitUpdateEffects(effect, instance) { + while (effect !== null) { + var callback = effect.callback; - if (callback !== null) { - effect.callback = null; - callCallback(callback, instance); - } + if (callback !== null) { + effect.callback = null; + callCallback(callback, instance); } + + effect = effect.nextEffect; } } @@ -7136,7 +7720,7 @@ function requestCurrentSuspenseConfig() { } var fakeInternalInstance = {}; -var isArray = Array.isArray; // React.Component uses a shared frozen object by default. +var isArray$1 = Array.isArray; // React.Component uses a shared frozen object by default. // We'll use it to determine whether we need to initialize legacy refs. var emptyRefsObject = new React.Component().refs; @@ -7171,8 +7755,8 @@ var didWarnAboutInvalidateContextType; if (!didWarnOnInvalidCallback.has(key)) { didWarnOnInvalidCallback.add(key); - - error( + warningWithoutStack$1( + false, "%s(...): Expected the last optional `callback` argument to be a " + "function. Instead received: %s.", callerName, @@ -7187,8 +7771,8 @@ var didWarnAboutInvalidateContextType; if (!didWarnAboutUndefinedDerivedState.has(componentName)) { didWarnAboutUndefinedDerivedState.add(componentName); - - error( + warningWithoutStack$1( + false, "%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. " + "You have returned undefined.", componentName @@ -7222,6 +7806,16 @@ function applyDerivedStateFromProps( ) { var prevState = workInProgress.memoizedState; + { + if ( + debugRenderPhaseSideEffectsForStrictMode && + workInProgress.mode & StrictMode + ) { + // Invoke the function an extra time to help detect side-effects. + getDerivedStateFromProps(nextProps, prevState); + } + } + var partialState = getDerivedStateFromProps(nextProps, prevState); { @@ -7235,9 +7829,9 @@ function applyDerivedStateFromProps( workInProgress.memoizedState = memoizedState; // Once the update queue is empty, persist the derived state onto the // base state. - if (workInProgress.expirationTime === NoWork) { - // Queue is always non-null for classes - var updateQueue = workInProgress.updateQueue; + var updateQueue = workInProgress.updateQueue; + + if (updateQueue !== null && workInProgress.expirationTime === NoWork) { updateQueue.baseState = memoizedState; } } @@ -7336,13 +7930,14 @@ function checkShouldComponentUpdate( stopPhaseTimer(); { - if (shouldUpdate === undefined) { - error( - "%s.shouldComponentUpdate(): Returned undefined instead of a " + - "boolean value. Make sure to return true or false.", - getComponentName(ctor) || "Component" - ); - } + !(shouldUpdate !== undefined) + ? warningWithoutStack$1( + false, + "%s.shouldComponentUpdate(): Returned undefined instead of a " + + "boolean value. Make sure to return true or false.", + getComponentName(ctor) || "Component" + ) + : void 0; } return shouldUpdate; @@ -7366,69 +7961,94 @@ function checkClassInstance(workInProgress, ctor, newProps) { if (!renderPresent) { if (ctor.prototype && typeof ctor.prototype.render === "function") { - error( + warningWithoutStack$1( + false, "%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 - ); + } else { + warningWithoutStack$1( + false, + "%s(...): No `render` method found on the returned component " + + "instance: you may have forgotten to define `render`.", + name + ); + } } - if (instance.contextType) { - error( - "contextType was defined as an instance property on %s. Use a static " + - "property to define contextType instead.", - name - ); - } + var noGetInitialStateOnES6 = + !instance.getInitialState || + instance.getInitialState.isReactClassApproved || + instance.state; + !noGetInitialStateOnES6 + ? warningWithoutStack$1( + false, + "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 + ) + : void 0; + var noGetDefaultPropsOnES6 = + !instance.getDefaultProps || + instance.getDefaultProps.isReactClassApproved; + !noGetDefaultPropsOnES6 + ? warningWithoutStack$1( + false, + "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 + ) + : void 0; + var noInstancePropTypes = !instance.propTypes; + !noInstancePropTypes + ? warningWithoutStack$1( + false, + "propTypes was defined as an instance property on %s. Use a static " + + "property to define propTypes instead.", + name + ) + : void 0; + var noInstanceContextType = !instance.contextType; + !noInstanceContextType + ? warningWithoutStack$1( + false, + "contextType was defined as an instance property on %s. Use a static " + + "property to define contextType instead.", + name + ) + : void 0; + + if (disableLegacyContext) { + if (ctor.childContextTypes) { + warningWithoutStack$1( + false, + "%s uses the legacy childContextTypes API which is no longer supported. " + + "Use React.createContext() instead.", + name + ); + } - { - if (instance.contextTypes) { - error( - "contextTypes was defined as an instance property on %s. Use a static " + - "property to define contextTypes instead.", + if (ctor.contextTypes) { + warningWithoutStack$1( + false, + "%s uses the legacy contextTypes API which is no longer supported. " + + "Use React.createContext() with static contextType instead.", name ); } + } else { + var noInstanceContextTypes = !instance.contextTypes; + !noInstanceContextTypes + ? warningWithoutStack$1( + false, + "contextTypes was defined as an instance property on %s. Use a static " + + "property to define contextTypes instead.", + name + ) + : void 0; if ( ctor.contextType && @@ -7436,8 +8056,8 @@ function checkClassInstance(workInProgress, ctor, newProps) { !didWarnAboutContextTypeAndContextTypes.has(ctor) ) { didWarnAboutContextTypeAndContextTypes.add(ctor); - - error( + warningWithoutStack$1( + false, "%s declares both contextTypes and contextType static properties. " + "The legacy contextTypes property will be ignored.", name @@ -7445,22 +8065,26 @@ function checkClassInstance(workInProgress, ctor, newProps) { } } - if (typeof instance.componentShouldUpdate === "function") { - error( - "%s has a method called " + - "componentShouldUpdate(). Did you mean shouldComponentUpdate()? " + - "The name is phrased as a question because the function is " + - "expected to return a value.", - name - ); - } + var noComponentShouldUpdate = + typeof instance.componentShouldUpdate !== "function"; + !noComponentShouldUpdate + ? warningWithoutStack$1( + false, + "%s has a method called " + + "componentShouldUpdate(). Did you mean shouldComponentUpdate()? " + + "The name is phrased as a question because the function is " + + "expected to return a value.", + name + ) + : void 0; if ( ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== "undefined" ) { - error( + warningWithoutStack$1( + false, "%s has a method called shouldComponentUpdate(). " + "shouldComponentUpdate should not be used when extending React.PureComponent. " + "Please extend React.Component if shouldComponentUpdate is used.", @@ -7468,61 +8092,70 @@ function checkClassInstance(workInProgress, ctor, newProps) { ); } - if (typeof instance.componentDidUnmount === "function") { - error( - "%s has a method called " + - "componentDidUnmount(). But there is no such lifecycle method. " + - "Did you mean componentWillUnmount()?", - name - ); - } - - if (typeof instance.componentDidReceiveProps === "function") { - error( - "%s has a method called " + - "componentDidReceiveProps(). But there is no such lifecycle method. " + - "If you meant to update the state in response to changing props, " + - "use componentWillReceiveProps(). If you meant to fetch data or " + - "run side-effects or mutations after React has updated the UI, use componentDidUpdate().", - name - ); - } - - if (typeof instance.componentWillRecieveProps === "function") { - error( - "%s has a method called " + - "componentWillRecieveProps(). Did you mean componentWillReceiveProps()?", - name - ); - } - - if (typeof instance.UNSAFE_componentWillRecieveProps === "function") { - error( - "%s has a method called " + - "UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?", - name - ); - } - + var noComponentDidUnmount = + typeof instance.componentDidUnmount !== "function"; + !noComponentDidUnmount + ? warningWithoutStack$1( + false, + "%s has a method called " + + "componentDidUnmount(). But there is no such lifecycle method. " + + "Did you mean componentWillUnmount()?", + name + ) + : void 0; + var noComponentDidReceiveProps = + typeof instance.componentDidReceiveProps !== "function"; + !noComponentDidReceiveProps + ? warningWithoutStack$1( + false, + "%s has a method called " + + "componentDidReceiveProps(). But there is no such lifecycle method. " + + "If you meant to update the state in response to changing props, " + + "use componentWillReceiveProps(). If you meant to fetch data or " + + "run side-effects or mutations after React has updated the UI, use componentDidUpdate().", + name + ) + : void 0; + var noComponentWillRecieveProps = + typeof instance.componentWillRecieveProps !== "function"; + !noComponentWillRecieveProps + ? warningWithoutStack$1( + false, + "%s has a method called " + + "componentWillRecieveProps(). Did you mean componentWillReceiveProps()?", + name + ) + : void 0; + var noUnsafeComponentWillRecieveProps = + typeof instance.UNSAFE_componentWillRecieveProps !== "function"; + !noUnsafeComponentWillRecieveProps + ? warningWithoutStack$1( + false, + "%s has a method called " + + "UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?", + name + ) + : void 0; var hasMutatedProps = instance.props !== newProps; - - if (instance.props !== undefined && hasMutatedProps) { - error( - "%s(...): When calling super() in `%s`, make sure to pass " + - "up the same props that your component's constructor was passed.", - name, - name - ); - } - - if (instance.defaultProps) { - error( - "Setting defaultProps as an instance property on %s is not supported and will be ignored." + - " Instead, define defaultProps as a static property on %s.", - name, - name - ); - } + !(instance.props === undefined || !hasMutatedProps) + ? warningWithoutStack$1( + false, + "%s(...): When calling super() in `%s`, make sure to pass " + + "up the same props that your component's constructor was passed.", + name, + name + ) + : void 0; + var noInstanceDefaultProps = !instance.defaultProps; + !noInstanceDefaultProps + ? warningWithoutStack$1( + false, + "Setting defaultProps as an instance property on %s is not supported and will be ignored." + + " Instead, define defaultProps as a static property on %s.", + name, + name + ) + : void 0; if ( typeof instance.getSnapshotBeforeUpdate === "function" && @@ -7530,53 +8163,63 @@ function checkClassInstance(workInProgress, ctor, newProps) { !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor) ) { didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor); - - error( + warningWithoutStack$1( + false, "%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). " + "This component defines getSnapshotBeforeUpdate() only.", getComponentName(ctor) ); } - if (typeof instance.getDerivedStateFromProps === "function") { - error( - "%s: getDerivedStateFromProps() is defined as an instance method " + - "and will be ignored. Instead, declare it as a static method.", - name - ); - } - - if (typeof instance.getDerivedStateFromError === "function") { - error( - "%s: getDerivedStateFromError() is defined as an instance method " + - "and will be ignored. Instead, declare it as a static method.", - name - ); - } + var noInstanceGetDerivedStateFromProps = + typeof instance.getDerivedStateFromProps !== "function"; + !noInstanceGetDerivedStateFromProps + ? warningWithoutStack$1( + false, + "%s: getDerivedStateFromProps() is defined as an instance method " + + "and will be ignored. Instead, declare it as a static method.", + name + ) + : void 0; + var noInstanceGetDerivedStateFromCatch = + typeof instance.getDerivedStateFromError !== "function"; + !noInstanceGetDerivedStateFromCatch + ? warningWithoutStack$1( + false, + "%s: getDerivedStateFromError() is defined as an instance method " + + "and will be ignored. Instead, declare it as a static method.", + name + ) + : void 0; + var noStaticGetSnapshotBeforeUpdate = + typeof ctor.getSnapshotBeforeUpdate !== "function"; + !noStaticGetSnapshotBeforeUpdate + ? warningWithoutStack$1( + false, + "%s: getSnapshotBeforeUpdate() is defined as a static method " + + "and will be ignored. Instead, declare it as an instance method.", + name + ) + : void 0; + var _state = instance.state; - if (typeof ctor.getSnapshotBeforeUpdate === "function") { - error( - "%s: getSnapshotBeforeUpdate() is defined as a static method " + - "and will be ignored. Instead, declare it as an instance method.", + if (_state && (typeof _state !== "object" || isArray$1(_state))) { + warningWithoutStack$1( + false, + "%s.state: must be set to an object or null", name ); } - var _state = instance.state; - - if (_state && (typeof _state !== "object" || isArray(_state))) { - error("%s.state: must be set to an object or null", name); - } - - if ( - typeof instance.getChildContext === "function" && - typeof ctor.childContextTypes !== "object" - ) { - error( - "%s.getChildContext(): childContextTypes must be defined in order to " + - "use getChildContext().", - name - ); + if (typeof instance.getChildContext === "function") { + !(typeof ctor.childContextTypes === "object") + ? warningWithoutStack$1( + false, + "%s.getChildContext(): childContextTypes must be defined in order to " + + "use getChildContext().", + name + ) + : void 0; } } } @@ -7592,7 +8235,12 @@ function adoptClassInstance(workInProgress, instance) { } } -function constructClassInstance(workInProgress, ctor, props) { +function constructClassInstance( + workInProgress, + ctor, + props, + renderExpirationTime +) { var isLegacyContextConsumer = false; var unmaskedContext = emptyContextObject; var context = emptyContextObject; @@ -7630,7 +8278,8 @@ function constructClassInstance(workInProgress, ctor, props) { "}."; } - error( + warningWithoutStack$1( + false, "%s defines an invalid contextType. " + "contextType should point to the Context object returned by React.createContext().%s", getComponentName(ctor) || "Component", @@ -7642,7 +8291,7 @@ function constructClassInstance(workInProgress, ctor, props) { if (typeof contextType === "object" && contextType !== null) { context = readContext(contextType); - } else { + } else if (!disableLegacyContext) { unmaskedContext = getUnmaskedContext(workInProgress, ctor, true); var contextTypes = ctor.contextTypes; isLegacyContextConsumer = @@ -7652,6 +8301,15 @@ function constructClassInstance(workInProgress, ctor, props) { : emptyContextObject; } // Instantiate twice to help detect side-effects. + { + if ( + debugRenderPhaseSideEffectsForStrictMode && + workInProgress.mode & StrictMode + ) { + new ctor(props, context); // eslint-disable-line no-new + } + } + var instance = new ctor(props, context); var state = (workInProgress.memoizedState = instance.state !== null && instance.state !== undefined @@ -7665,8 +8323,8 @@ function constructClassInstance(workInProgress, ctor, props) { if (!didWarnAboutUninitializedState.has(componentName)) { didWarnAboutUninitializedState.add(componentName); - - error( + warningWithoutStack$1( + false, "`%s` uses `getDerivedStateFromProps` but its initial state is " + "%s. This is not recommended. Instead, define the initial state by " + "assigning an object to `this.state` in the constructor of `%s`. " + @@ -7731,8 +8389,8 @@ function constructClassInstance(workInProgress, ctor, props) { if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName)) { didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName); - - error( + warningWithoutStack$1( + false, "Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n" + "%s uses %s but also contains the following legacy lifecycles:%s%s%s\n\n" + "The above lifecycles should be removed. Learn more about this warning here:\n" + @@ -7774,7 +8432,8 @@ function callComponentWillMount(workInProgress, instance) { if (oldState !== instance.state) { { - error( + warningWithoutStack$1( + false, "%s.componentWillMount(): Assigning directly to this.state is " + "deprecated (except inside a component's " + "constructor). Use setState instead.", @@ -7811,8 +8470,8 @@ function callComponentWillReceiveProps( if (!didWarnAboutStateAssignmentForComponent.has(componentName)) { didWarnAboutStateAssignmentForComponent.add(componentName); - - error( + warningWithoutStack$1( + false, "%s.componentWillReceiveProps(): Assigning directly to " + "this.state is deprecated (except inside a component's " + "constructor). Use setState instead.", @@ -7839,11 +8498,12 @@ function mountClassInstance( instance.props = newProps; instance.state = workInProgress.memoizedState; instance.refs = emptyRefsObject; - initializeUpdateQueue(workInProgress); var contextType = ctor.contextType; if (typeof contextType === "object" && contextType !== null) { instance.context = readContext(contextType); + } else if (disableLegacyContext) { + instance.context = emptyContextObject; } else { var unmaskedContext = getUnmaskedContext(workInProgress, ctor, true); instance.context = getMaskedContext(workInProgress, unmaskedContext); @@ -7855,8 +8515,8 @@ function mountClassInstance( if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) { didWarnAboutDirectlyAssigningPropsToState.add(componentName); - - error( + warningWithoutStack$1( + false, "%s: It is not recommended to assign props directly to state " + "because updates to props won't be reflected in state. " + "In most cases, it is better to use props directly.", @@ -7872,7 +8532,7 @@ function mountClassInstance( ); } - { + if (warnAboutDeprecatedLifecycles) { ReactStrictModeWarnings.recordUnsafeLifecycleWarnings( workInProgress, instance @@ -7880,8 +8540,19 @@ function mountClassInstance( } } - processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); - instance.state = workInProgress.memoizedState; + var updateQueue = workInProgress.updateQueue; + + if (updateQueue !== null) { + processUpdateQueue( + workInProgress, + updateQueue, + newProps, + instance, + renderExpirationTime + ); + instance.state = workInProgress.memoizedState; + } + var getDerivedStateFromProps = ctor.getDerivedStateFromProps; if (typeof getDerivedStateFromProps === "function") { @@ -7904,13 +8575,18 @@ function mountClassInstance( callComponentWillMount(workInProgress, instance); // If we had additional state updates during this life-cycle, let's // process them now. - processUpdateQueue( - workInProgress, - newProps, - instance, - renderExpirationTime - ); - instance.state = workInProgress.memoizedState; + updateQueue = workInProgress.updateQueue; + + if (updateQueue !== null) { + processUpdateQueue( + workInProgress, + updateQueue, + newProps, + instance, + renderExpirationTime + ); + instance.state = workInProgress.memoizedState; + } } if (typeof instance.componentDidMount === "function") { @@ -7933,7 +8609,7 @@ function resumeMountClassInstance( if (typeof contextType === "object" && contextType !== null) { nextContext = readContext(contextType); - } else { + } else if (!disableLegacyContext) { var nextLegacyUnmaskedContext = getUnmaskedContext( workInProgress, ctor, @@ -7969,8 +8645,18 @@ function resumeMountClassInstance( resetHasForceUpdateBeforeProcessing(); var oldState = workInProgress.memoizedState; var newState = (instance.state = oldState); - processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); - newState = workInProgress.memoizedState; + var updateQueue = workInProgress.updateQueue; + + if (updateQueue !== null) { + processUpdateQueue( + workInProgress, + updateQueue, + newProps, + instance, + renderExpirationTime + ); + newState = workInProgress.memoizedState; + } if ( oldProps === newProps && @@ -8060,7 +8746,6 @@ function updateClassInstance( renderExpirationTime ) { var instance = workInProgress.stateNode; - cloneUpdateQueue(current, workInProgress); var oldProps = workInProgress.memoizedProps; instance.props = workInProgress.type === workInProgress.elementType @@ -8072,7 +8757,7 @@ function updateClassInstance( if (typeof contextType === "object" && contextType !== null) { nextContext = readContext(contextType); - } else { + } else if (!disableLegacyContext) { var nextUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true); nextContext = getMaskedContext(workInProgress, nextUnmaskedContext); } @@ -8104,8 +8789,18 @@ function updateClassInstance( resetHasForceUpdateBeforeProcessing(); var oldState = workInProgress.memoizedState; var newState = (instance.state = oldState); - processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); - newState = workInProgress.memoizedState; + var updateQueue = workInProgress.updateQueue; + + if (updateQueue !== null) { + processUpdateQueue( + workInProgress, + updateQueue, + newProps, + instance, + renderExpirationTime + ); + newState = workInProgress.memoizedState; + } if ( oldProps === newProps && @@ -8267,8 +8962,8 @@ var warnForMissingKey = function(child) {}; } ownerHasKeyUseWarning[currentComponentErrorInfo] = true; - - error( + warning$1( + false, "Each child in a list should have a unique " + '"key" prop. See https://fb.me/react-warning-keys for ' + "more information." @@ -8276,9 +8971,9 @@ var warnForMissingKey = function(child) {}; }; } -var isArray$1 = Array.isArray; +var isArray = Array.isArray; -function coerceRef(returnFiber, current, element) { +function coerceRef(returnFiber, current$$1, element) { var mixedRef = element.ref; if ( @@ -8289,21 +8984,25 @@ 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 - // because these cannot be automatically converted to an arrow function - // using a codemod. Therefore, we don't have to warn about string refs again. - !( - element._owner && - element._self && - element._owner.stateNode !== element._self - ) - ) { + if (returnFiber.mode & StrictMode || warnAboutStringRefs) { var componentName = getComponentName(returnFiber.type) || "Component"; if (!didWarnAboutStringRefs[componentName]) { - { - error( + if (warnAboutStringRefs) { + warningWithoutStack$1( + false, + 'Component "%s" contains the string ref "%s". Support for string refs ' + + "will be removed in a future major release. We recommend using " + + "useRef() or createRef() instead. " + + "Learn more about using refs safely here: " + + "https://fb.me/react-strict-mode-string-ref%s", + componentName, + mixedRef, + getStackByFiberInDevAndProd(returnFiber) + ); + } else { + warningWithoutStack$1( + false, 'A string ref, "%s", has been found within a strict mode tree. ' + "String refs are a source of potential bugs and should be avoided. " + "We recommend using useRef() or createRef() instead. " + @@ -8328,7 +9027,7 @@ function coerceRef(returnFiber, current, element) { if (!(ownerFiber.tag === ClassComponent)) { throw Error( - "Function components cannot have string refs. We recommend using useRef() instead. Learn more about using refs safely here: https://fb.me/react-strict-mode-string-ref" + "Function components cannot have refs. Did you mean to use React.forwardRef()?" ); } @@ -8346,12 +9045,12 @@ function coerceRef(returnFiber, current, element) { var stringRef = "" + mixedRef; // Check if previous string ref matches new string ref if ( - current !== null && - current.ref !== null && - typeof current.ref === "function" && - current.ref._stringRef === stringRef + current$$1 !== null && + current$$1.ref !== null && + typeof current$$1.ref === "function" && + current$$1.ref._stringRef === stringRef ) { - return current.ref; + return current$$1.ref; } var ref = function(value) { @@ -8416,25 +9115,23 @@ function throwOnInvalidObjectType(returnFiber, newChild) { } function warnOnFunctionType() { - { - var currentComponentErrorInfo = - "Functions are not valid as a React child. This may happen if " + - "you return a Component instead of from render. " + - "Or maybe you meant to call this function rather than return it." + - getCurrentFiberStackInDev(); - - if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) { - return; - } - - ownerHasFunctionTypeWarning[currentComponentErrorInfo] = true; + var currentComponentErrorInfo = + "Functions are not valid as a React child. This may happen if " + + "you return a Component instead of from render. " + + "Or maybe you meant to call this function rather than return it." + + getCurrentFiberStackInDev(); - error( - "Functions are not valid as a React child. This may happen if " + - "you return a Component instead of from render. " + - "Or maybe you meant to call this function rather than return it." - ); + if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) { + return; } + + ownerHasFunctionTypeWarning[currentComponentErrorInfo] = true; + warning$1( + false, + "Functions are not valid as a React child. This may happen if " + + "you return a Component instead of from render. " + + "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 @@ -8501,10 +9198,10 @@ function ChildReconciler(shouldTrackSideEffects) { return existingChildren; } - function useFiber(fiber, pendingProps) { + function useFiber(fiber, pendingProps, expirationTime) { // We currently set sibling to null and index to 0 here because it is easy // to forget to do before returning it. E.g. for the single child case. - var clone = createWorkInProgress(fiber, pendingProps); + var clone = createWorkInProgress(fiber, pendingProps, expirationTime); clone.index = 0; clone.sibling = null; return clone; @@ -8518,10 +9215,10 @@ function ChildReconciler(shouldTrackSideEffects) { return lastPlacedIndex; } - var current = newFiber.alternate; + var current$$1 = newFiber.alternate; - if (current !== null) { - var oldIndex = current.index; + if (current$$1 !== null) { + var oldIndex = current$$1.index; if (oldIndex < lastPlacedIndex) { // This is a move. @@ -8548,8 +9245,13 @@ function ChildReconciler(shouldTrackSideEffects) { return newFiber; } - function updateTextNode(returnFiber, current, textContent, expirationTime) { - if (current === null || current.tag !== HostText) { + function updateTextNode( + returnFiber, + current$$1, + textContent, + expirationTime + ) { + if (current$$1 === null || current$$1.tag !== HostText) { // Insert var created = createFiberFromText( textContent, @@ -8560,48 +9262,48 @@ function ChildReconciler(shouldTrackSideEffects) { return created; } else { // Update - var existing = useFiber(current, textContent); + var existing = useFiber(current$$1, textContent, expirationTime); existing.return = returnFiber; return existing; } } - function updateElement(returnFiber, current, element, expirationTime) { - if (current !== null) { - if ( - 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); - existing.ref = coerceRef(returnFiber, current, element); - existing.return = returnFiber; - - { - existing._debugSource = element._source; - existing._debugOwner = element._owner; - } + function updateElement(returnFiber, current$$1, element, expirationTime) { + if ( + current$$1 !== null && + (current$$1.elementType === element.type || // Keep this check inline so it only runs on the false path: + isCompatibleFamilyForHotReloading(current$$1, element)) + ) { + // Move based on index + var existing = useFiber(current$$1, element.props, expirationTime); + existing.ref = coerceRef(returnFiber, current$$1, element); + existing.return = returnFiber; - return existing; + { + existing._debugSource = element._source; + existing._debugOwner = element._owner; } - } // Insert - var created = createFiberFromElement( - element, - returnFiber.mode, - expirationTime - ); - created.ref = coerceRef(returnFiber, current, element); - created.return = returnFiber; - return created; + return existing; + } else { + // Insert + var created = createFiberFromElement( + element, + returnFiber.mode, + expirationTime + ); + created.ref = coerceRef(returnFiber, current$$1, element); + created.return = returnFiber; + return created; + } } - function updatePortal(returnFiber, current, portal, expirationTime) { + function updatePortal(returnFiber, current$$1, portal, expirationTime) { if ( - current === null || - current.tag !== HostPortal || - current.stateNode.containerInfo !== portal.containerInfo || - current.stateNode.implementation !== portal.implementation + current$$1 === null || + current$$1.tag !== HostPortal || + current$$1.stateNode.containerInfo !== portal.containerInfo || + current$$1.stateNode.implementation !== portal.implementation ) { // Insert var created = createFiberFromPortal( @@ -8613,14 +9315,24 @@ function ChildReconciler(shouldTrackSideEffects) { return created; } else { // Update - var existing = useFiber(current, portal.children || []); + var existing = useFiber( + current$$1, + portal.children || [], + expirationTime + ); existing.return = returnFiber; return existing; } } - function updateFragment(returnFiber, current, fragment, expirationTime, key) { - if (current === null || current.tag !== Fragment) { + function updateFragment( + returnFiber, + current$$1, + fragment, + expirationTime, + key + ) { + if (current$$1 === null || current$$1.tag !== Fragment) { // Insert var created = createFiberFromFragment( fragment, @@ -8632,7 +9344,7 @@ function ChildReconciler(shouldTrackSideEffects) { return created; } else { // Update - var existing = useFiber(current, fragment); + var existing = useFiber(current$$1, fragment, expirationTime); existing.return = returnFiber; return existing; } @@ -8678,7 +9390,7 @@ function ChildReconciler(shouldTrackSideEffects) { } } - if (isArray$1(newChild) || getIteratorFn(newChild)) { + if (isArray(newChild) || getIteratorFn(newChild)) { var _created3 = createFiberFromFragment( newChild, returnFiber.mode, @@ -8761,7 +9473,7 @@ function ChildReconciler(shouldTrackSideEffects) { } } - if (isArray$1(newChild) || getIteratorFn(newChild)) { + if (isArray(newChild) || getIteratorFn(newChild)) { if (key !== null) { return null; } @@ -8847,7 +9559,7 @@ function ChildReconciler(shouldTrackSideEffects) { } } - if (isArray$1(newChild) || getIteratorFn(newChild)) { + if (isArray(newChild) || getIteratorFn(newChild)) { var _matchedFiber3 = existingChildren.get(newIdx) || null; return updateFragment( @@ -8901,7 +9613,8 @@ function ChildReconciler(shouldTrackSideEffects) { break; } - error( + warning$1( + false, "Encountered two children with the same key, `%s`. " + "Keys should be unique so that components maintain their identity " + "across updates. Non-unique keys may cause children to be " + @@ -8909,7 +9622,9 @@ function ChildReconciler(shouldTrackSideEffects) { "could change in a future version.", key ); + break; + default: break; } } @@ -9112,28 +9827,28 @@ function ChildReconciler(shouldTrackSideEffects) { typeof Symbol === "function" && // $FlowFixMe Flow doesn't know about toStringTag newChildrenIterable[Symbol.toStringTag] === "Generator" ) { - if (!didWarnAboutGenerators) { - error( - "Using Generators as children is unsupported and will likely yield " + - "unexpected results because enumerating a generator mutates it. " + - "You may convert it to an array with `Array.from()` or the " + - "`[...spread]` operator before rendering. Keep in mind " + - "you might need to polyfill these features for older browsers." - ); - } - + !didWarnAboutGenerators + ? warning$1( + false, + "Using Generators as children is unsupported and will likely yield " + + "unexpected results because enumerating a generator mutates it. " + + "You may convert it to an array with `Array.from()` or the " + + "`[...spread]` operator before rendering. Keep in mind " + + "you might need to polyfill these features for older browsers." + ) + : void 0; didWarnAboutGenerators = true; } // Warn about using Maps as children if (newChildrenIterable.entries === iteratorFn) { - if (!didWarnAboutMaps) { - error( - "Using Maps as children is unsupported and will likely yield " + - "unexpected results. Convert it to a sequence/iterable of keyed " + - "ReactElements instead." - ); - } - + !didWarnAboutMaps + ? warning$1( + false, + "Using Maps as children is unsupported and will likely yield " + + "unexpected results. Convert it to a sequence/iterable of keyed " + + "ReactElements instead." + ) + : void 0; didWarnAboutMaps = true; } // First, validate keys. // We'll get a different iterator later for the main pass. @@ -9312,7 +10027,7 @@ function ChildReconciler(shouldTrackSideEffects) { // We already have an existing node so let's just update it and delete // the rest. deleteRemainingChildren(returnFiber, currentFirstChild.sibling); - var existing = useFiber(currentFirstChild, textContent); + var existing = useFiber(currentFirstChild, textContent, expirationTime); existing.return = returnFiber; return existing; } // The existing first child is not a text node so we need to create one @@ -9341,55 +10056,33 @@ 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; - - { - existing._debugSource = element._source; - existing._debugOwner = element._owner; - } - - return existing; - } - - break; - } - - case Block: - - // We intentionally fallthrough here if enableBlocksAPI is not on. - // eslint-disable-next-lined no-fallthrough - - default: { - if ( - child.elementType === element.type || // Keep this check inline so it only runs on the false path: + if ( + child.tag === Fragment + ? element.type === REACT_FRAGMENT_TYPE + : child.elementType === element.type || // Keep this check inline so it only runs on the false path: isCompatibleFamilyForHotReloading(child, element) - ) { - deleteRemainingChildren(returnFiber, child.sibling); - - var _existing3 = useFiber(child, element.props); - - _existing3.ref = coerceRef(returnFiber, child, element); - _existing3.return = returnFiber; - - { - _existing3._debugSource = element._source; - _existing3._debugOwner = element._owner; - } - - return _existing3; - } + ) { + deleteRemainingChildren(returnFiber, child.sibling); + var existing = useFiber( + child, + element.type === REACT_FRAGMENT_TYPE + ? element.props.children + : element.props, + expirationTime + ); + existing.ref = coerceRef(returnFiber, child, element); + existing.return = returnFiber; - break; + { + existing._debugSource = element._source; + existing._debugOwner = element._owner; } - } // Didn't match. - deleteRemainingChildren(returnFiber, child); - break; + return existing; + } else { + deleteRemainingChildren(returnFiber, child); + break; + } } else { deleteChild(returnFiber, child); } @@ -9438,7 +10131,7 @@ function ChildReconciler(shouldTrackSideEffects) { child.stateNode.implementation === portal.implementation ) { deleteRemainingChildren(returnFiber, child.sibling); - var existing = useFiber(child, portal.children || []); + var existing = useFiber(child, portal.children || [], expirationTime); existing.return = returnFiber; return existing; } else { @@ -9523,7 +10216,7 @@ function ChildReconciler(shouldTrackSideEffects) { ); } - if (isArray$1(newChild)) { + if (isArray(newChild)) { return reconcileChildrenArray( returnFiber, currentFirstChild, @@ -9591,8 +10284,8 @@ function ChildReconciler(shouldTrackSideEffects) { var reconcileChildFibers = ChildReconciler(true); var mountChildFibers = ChildReconciler(false); -function cloneChildFibers(current, workInProgress) { - if (!(current === null || workInProgress.child === current.child)) { +function cloneChildFibers(current$$1, workInProgress) { + if (!(current$$1 === null || workInProgress.child === current$$1.child)) { throw Error("Resuming work not yet implemented."); } @@ -9601,7 +10294,11 @@ function cloneChildFibers(current, workInProgress) { } var currentChild = workInProgress.child; - var newChild = createWorkInProgress(currentChild, currentChild.pendingProps); + var newChild = createWorkInProgress( + currentChild, + currentChild.pendingProps, + currentChild.expirationTime + ); workInProgress.child = newChild; newChild.return = workInProgress; @@ -9609,7 +10306,8 @@ function cloneChildFibers(current, workInProgress) { currentChild = currentChild.sibling; newChild = newChild.sibling = createWorkInProgress( currentChild, - currentChild.pendingProps + currentChild.pendingProps, + currentChild.expirationTime ); newChild.return = workInProgress; } @@ -9659,7 +10357,7 @@ function pushHostContainer(fiber, nextRootInstance) { // So we push an empty value first. This lets us safely unwind on errors. push(contextStackCursor$1, NO_CONTEXT, fiber); - var nextRootContext = getRootHostContext(); // Now that we know this function doesn't throw, replace it. + var nextRootContext = getRootHostContext(nextRootInstance); // Now that we know this function doesn't throw, replace it. pop(contextStackCursor$1, fiber); push(contextStackCursor$1, nextRootContext, fiber); @@ -9679,7 +10377,7 @@ function getHostContext() { function pushHostContext(fiber) { var rootInstance = requiredContext(rootInstanceStackCursor.current); var context = requiredContext(contextStackCursor$1.current); - var nextContext = getChildHostContext(context, fiber.type); // Don't push this Fiber's context unless it's unique. + var nextContext = getChildHostContext(context, fiber.type, rootInstance); // Don't push this Fiber's context unless it's unique. if (context === nextContext) { return; @@ -9782,8 +10480,8 @@ function findFirstSuspended(row) { if ( dehydrated === null || - isSuspenseInstancePending() || - isSuspenseInstanceFallback() + isSuspenseInstancePending(dehydrated) || + isSuspenseInstanceFallback(dehydrated) ) { return node; } @@ -9823,7 +10521,191 @@ function findFirstSuspended(row) { return null; } -function createDeprecatedResponderListener(responder, props) { +var emptyObject$1 = {}; +var isArray$2 = Array.isArray; +function createResponderInstance( + responder, + responderProps, + responderState, + fiber +) { + return { + fiber: fiber, + props: responderProps, + responder: responder, + rootEventTypes: null, + state: responderState + }; +} + +function mountEventResponder( + responder, + responderProps, + fiber, + respondersMap, + rootContainerInstance +) { + var responderState = emptyObject$1; + var getInitialState = responder.getInitialState; + + if (getInitialState !== null) { + responderState = getInitialState(responderProps); + } + + var responderInstance = createResponderInstance( + responder, + responderProps, + responderState, + fiber + ); + + if (!rootContainerInstance) { + var node = fiber; + + while (node !== null) { + var tag = node.tag; + + if (tag === HostComponent) { + rootContainerInstance = node.stateNode; + break; + } else if (tag === HostRoot) { + rootContainerInstance = node.stateNode.containerInfo; + break; + } + + node = node.return; + } + } + + mountResponderInstance( + responder, + responderInstance, + responderProps, + responderState, + rootContainerInstance + ); + respondersMap.set(responder, responderInstance); +} + +function updateEventListener( + listener, + fiber, + visistedResponders, + respondersMap, + rootContainerInstance +) { + var responder; + var props; + + if (listener) { + responder = listener.responder; + props = listener.props; + } + + if (!(responder && responder.$$typeof === REACT_RESPONDER_TYPE)) { + throw Error( + "An invalid value was used as an event listener. Expect one or many event listeners created via React.unstable_useResponder()." + ); + } + + var listenerProps = props; + + if (visistedResponders.has(responder)) { + // show warning + { + warning$1( + false, + 'Duplicate event responder "%s" found in event listeners. ' + + "Event listeners passed to elements cannot use the same event responder more than once.", + responder.displayName + ); + } + + return; + } + + visistedResponders.add(responder); + var responderInstance = respondersMap.get(responder); + + if (responderInstance === undefined) { + // Mount (happens in either complete or commit phase) + mountEventResponder( + responder, + listenerProps, + fiber, + respondersMap, + rootContainerInstance + ); + } else { + // Update (happens during commit phase only) + responderInstance.props = listenerProps; + responderInstance.fiber = fiber; + } +} + +function updateEventListeners(listeners, fiber, rootContainerInstance) { + var visistedResponders = new Set(); + var dependencies = fiber.dependencies; + + if (listeners != null) { + if (dependencies === null) { + dependencies = fiber.dependencies = { + expirationTime: NoWork, + firstContext: null, + responders: new Map() + }; + } + + var respondersMap = dependencies.responders; + + if (respondersMap === null) { + respondersMap = new Map(); + } + + if (isArray$2(listeners)) { + for (var i = 0, length = listeners.length; i < length; i++) { + var listener = listeners[i]; + updateEventListener( + listener, + fiber, + visistedResponders, + respondersMap, + rootContainerInstance + ); + } + } else { + updateEventListener( + listeners, + fiber, + visistedResponders, + respondersMap, + rootContainerInstance + ); + } + } + + if (dependencies !== null) { + var _respondersMap = dependencies.responders; + + if (_respondersMap !== null) { + // Unmount + var mountedResponders = Array.from(_respondersMap.keys()); + + for (var _i = 0, _length = mountedResponders.length; _i < _length; _i++) { + var mountedResponder = mountedResponders[_i]; + + if (!visistedResponders.has(mountedResponder)) { + var responderInstance = _respondersMap.get(mountedResponder); + + unmountResponderInstance(responderInstance); + + _respondersMap.delete(mountedResponder); + } + } + } + } +} +function createResponderListener(responder, props) { var eventResponderListener = { responder: responder, props: props @@ -9836,19 +10718,33 @@ function createDeprecatedResponderListener(responder, props) { return eventResponderListener; } -var HasEffect = - /* */ - 1; // Represents the phase in which the effect (not the clean-up) fires. - -var Layout = - /* */ +var NoEffect$1 = + /* */ + 0; +var UnmountSnapshot = + /* */ 2; -var Passive$1 = - /* */ +var UnmountMutation = + /* */ 4; +var MountMutation = + /* */ + 8; +var UnmountLayout = + /* */ + 16; +var MountLayout = + /* */ + 32; +var MountPassive = + /* */ + 64; +var UnmountPassive = + /* */ + 128; -var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher, - ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig; +var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher; +var ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig; var didWarnAboutMismatchedHooksForComponent; { @@ -9856,7 +10752,7 @@ var didWarnAboutMismatchedHooksForComponent; } // These are set right before calling the component. -var renderExpirationTime = NoWork; // The work-in-progress fiber. I've named it differently to distinguish it from +var renderExpirationTime$1 = NoWork; // The work-in-progress fiber. I've named it differently to distinguish it from // the work-in-progress hook. var currentlyRenderingFiber$1 = null; // Hooks are stored as a linked list on the fiber's memoizedState field. The @@ -9865,12 +10761,26 @@ var currentlyRenderingFiber$1 = null; // Hooks are stored as a linked list on th // work-in-progress fiber. var currentHook = null; -var workInProgressHook = null; // Whether an update was scheduled at any point during the render phase. This -// does not get reset if we do another render pass; only when we're completely -// finished evaluating this component. This is an optimization so we know -// whether we need to clear render phase updates after a throw. - -var didScheduleRenderPhaseUpdate = false; +var nextCurrentHook = null; +var firstWorkInProgressHook = null; +var workInProgressHook = null; +var nextWorkInProgressHook = null; +var remainingExpirationTime = NoWork; +var componentUpdateQueue = null; +var sideEffectTag = 0; // Updates scheduled during render will trigger an immediate re-render at the +// end of the current pass. We can't store these updates on the normal queue, +// because if the work is aborted, they should be discarded. Because this is +// a relatively rare case, we also don't want to add an additional field to +// either the hook or queue object types. So we store them in a lazily create +// map of queue -> render-phase updates, which are discarded once the component +// completes without re-rendering. +// Whether an update was scheduled during the currently executing render pass. + +var didScheduleRenderPhaseUpdate = false; // Lazily created map of render-phase updates + +var renderPhaseUpdates = null; // Counter to prevent infinite loops. + +var numberOfReRenders = 0; var RE_RENDER_LIMIT = 25; // In DEV, this is the name of the currently executing primitive hook var currentHookNameInDev = null; // In DEV, this list ensures that hooks are called in the same order between renders. @@ -9915,7 +10825,8 @@ function checkDepsAreArrayDev(deps) { if (deps !== undefined && deps !== null && !Array.isArray(deps)) { // Verify deps, but only on mount to avoid extra checks. // It's unlikely their type would change as usually you define them inline. - error( + warning$1( + false, "%s received a final argument that is not an array (instead, received `%s`). When " + "specified, the final argument must be an array.", currentHookNameInDev, @@ -9951,7 +10862,8 @@ function warnOnHookMismatchInDev(currentHookName) { table += row; } - error( + warning$1( + false, "React has detected a change in the order of Hooks called by %s. " + "This will lead to bugs and errors if not fixed. " + "For more information, read the Rules of Hooks: https://fb.me/rules-of-hooks\n\n" + @@ -9985,7 +10897,8 @@ function areHookInputsEqual(nextDeps, prevDeps) { if (prevDeps === null) { { - error( + warning$1( + false, "%s received a final argument during this render, but not during " + "the previous render. Even though the final argument is optional, " + "its type cannot change between renders.", @@ -10000,7 +10913,8 @@ function areHookInputsEqual(nextDeps, prevDeps) { // Don't bother comparing lengths in prod because these arrays should be // passed inline. if (nextDeps.length !== prevDeps.length) { - error( + warning$1( + false, "The final argument passed to %s changed size between renders. The " + "order and size of this array must remain constant.\n\n" + "Previous: %s\n" + @@ -10013,7 +10927,7 @@ function areHookInputsEqual(nextDeps, prevDeps) { } for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) { - if (objectIs(nextDeps[i], prevDeps[i])) { + if (is$1(nextDeps[i], prevDeps[i])) { continue; } @@ -10028,11 +10942,12 @@ function renderWithHooks( workInProgress, Component, props, - secondArg, + refOrContext, nextRenderExpirationTime ) { - renderExpirationTime = nextRenderExpirationTime; + renderExpirationTime$1 = nextRenderExpirationTime; currentlyRenderingFiber$1 = workInProgress; + nextCurrentHook = current !== null ? current.memoizedState : null; { hookTypesDev = current !== null ? current._debugHookTypes : null; @@ -10040,52 +10955,42 @@ function renderWithHooks( ignorePreviousDependencies = current !== null && current.type !== workInProgress.type; - } - - workInProgress.memoizedState = null; - workInProgress.updateQueue = null; - workInProgress.expirationTime = NoWork; // The following should have already been reset + } // The following should have already been reset // currentHook = null; // workInProgressHook = null; + // remainingExpirationTime = NoWork; + // componentUpdateQueue = null; // didScheduleRenderPhaseUpdate = false; + // renderPhaseUpdates = null; + // numberOfReRenders = 0; + // sideEffectTag = 0; // TODO Warn if no hooks are used at all during mount, then some are used during update. - // Currently we will identify the update render as a mount because memoizedState === null. + // Currently we will identify the update render as a mount because nextCurrentHook === null. // This is tricky because it's valid for certain types of components (e.g. React.lazy) - // Using memoizedState to differentiate between mount/update only works if at least one stateful hook is used. + // Using nextCurrentHook to differentiate between mount/update only works if at least one stateful hook is used. // Non-stateful hooks (e.g. context) don't get added to memoizedState, - // so memoizedState would be null during updates and mounts. + // so nextCurrentHook would be null during updates and mounts. { - if (current !== null && current.memoizedState !== null) { - ReactCurrentDispatcher.current = HooksDispatcherOnUpdateInDEV; + if (nextCurrentHook !== null) { + ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV; } else if (hookTypesDev !== null) { // This dispatcher handles an edge case where a component is updating, // but no stateful hooks have been used. // We want to match the production code behavior (which will use HooksDispatcherOnMount), // but with the extra DEV validation to ensure hooks ordering hasn't changed. // This dispatcher does that. - ReactCurrentDispatcher.current = HooksDispatcherOnMountWithHookTypesInDEV; + ReactCurrentDispatcher$1.current = HooksDispatcherOnMountWithHookTypesInDEV; } else { - ReactCurrentDispatcher.current = HooksDispatcherOnMountInDEV; + ReactCurrentDispatcher$1.current = HooksDispatcherOnMountInDEV; } } - var children = Component(props, secondArg); // Check if there was a render phase update - - if (workInProgress.expirationTime === renderExpirationTime) { - // Keep rendering in a loop for as long as render phase updates continue to - // be scheduled. Use a counter to prevent infinite loops. - var numberOfReRenders = 0; + var children = Component(props, refOrContext); + if (didScheduleRenderPhaseUpdate) { do { - workInProgress.expirationTime = NoWork; - - if (!(numberOfReRenders < RE_RENDER_LIMIT)) { - throw Error( - "Too many re-renders. React limits the number of renders to prevent an infinite loop." - ); - } - + didScheduleRenderPhaseUpdate = false; numberOfReRenders += 1; { @@ -10094,33 +10999,46 @@ function renderWithHooks( ignorePreviousDependencies = false; } // Start over from the beginning of the list + nextCurrentHook = current !== null ? current.memoizedState : null; + nextWorkInProgressHook = firstWorkInProgressHook; currentHook = null; workInProgressHook = null; - workInProgress.updateQueue = null; + componentUpdateQueue = null; { // Also validate hook order for cascading updates. hookTypesUpdateIndexDev = -1; } - ReactCurrentDispatcher.current = HooksDispatcherOnRerenderInDEV; - children = Component(props, secondArg); - } while (workInProgress.expirationTime === renderExpirationTime); + ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV; + children = Component(props, refOrContext); + } while (didScheduleRenderPhaseUpdate); + + renderPhaseUpdates = null; + numberOfReRenders = 0; } // We can assume the previous dispatcher is always this one, since we set it // at the beginning of the render phase and there's no re-entrancy. - ReactCurrentDispatcher.current = ContextOnlyDispatcher; + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; + var renderedWork = currentlyRenderingFiber$1; + renderedWork.memoizedState = firstWorkInProgressHook; + renderedWork.expirationTime = remainingExpirationTime; + renderedWork.updateQueue = componentUpdateQueue; + renderedWork.effectTag |= sideEffectTag; { - workInProgress._debugHookTypes = hookTypesDev; + renderedWork._debugHookTypes = hookTypesDev; } // This check uses currentHook so that it works the same in DEV and prod bundles. // hookTypesDev could catch more cases (e.g. context) but only in DEV bundles. var didRenderTooFewHooks = currentHook !== null && currentHook.next !== null; - renderExpirationTime = NoWork; + renderExpirationTime$1 = NoWork; currentlyRenderingFiber$1 = null; currentHook = null; + nextCurrentHook = null; + firstWorkInProgressHook = null; workInProgressHook = null; + nextWorkInProgressHook = null; { currentHookNameInDev = null; @@ -10128,7 +11046,12 @@ function renderWithHooks( hookTypesUpdateIndexDev = -1; } - didScheduleRenderPhaseUpdate = false; + remainingExpirationTime = NoWork; + componentUpdateQueue = null; + sideEffectTag = 0; // These were reset above + // didScheduleRenderPhaseUpdate = false; + // renderPhaseUpdates = null; + // numberOfReRenders = 0; if (!!didRenderTooFewHooks) { throw Error( @@ -10146,37 +11069,20 @@ function bailoutHooks(current, workInProgress, expirationTime) { current.expirationTime = NoWork; } } -function resetHooksAfterThrow() { +function resetHooks() { // We can assume the previous dispatcher is always this one, since we set it // at the beginning of the render phase and there's no re-entrancy. - ReactCurrentDispatcher.current = ContextOnlyDispatcher; - - if (didScheduleRenderPhaseUpdate) { - // There were render phase updates. These are only valid for this render - // phase, which we are now aborting. Remove the updates from the queues so - // they do not persist to the next render. Do not remove updates from hooks - // that weren't processed. - // - // Only reset the updates from the queue if it has a clone. If it does - // not have a clone, that means it wasn't processed, and the updates were - // scheduled before we entered the render phase. - var hook = currentlyRenderingFiber$1.memoizedState; - - while (hook !== null) { - var queue = hook.queue; - - if (queue !== null) { - queue.pending = null; - } + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; // This is used to reset the state of this module when a component throws. + // It's also called inside mountIndeterminateComponent if we determine the + // component is a module-style component. - hook = hook.next; - } - } - - renderExpirationTime = NoWork; + renderExpirationTime$1 = NoWork; currentlyRenderingFiber$1 = null; currentHook = null; + nextCurrentHook = null; + firstWorkInProgressHook = null; workInProgressHook = null; + nextWorkInProgressHook = null; { hookTypesDev = null; @@ -10184,21 +11090,26 @@ function resetHooksAfterThrow() { currentHookNameInDev = null; } + remainingExpirationTime = NoWork; + componentUpdateQueue = null; + sideEffectTag = 0; didScheduleRenderPhaseUpdate = false; + renderPhaseUpdates = null; + numberOfReRenders = 0; } function mountWorkInProgressHook() { var hook = { memoizedState: null, baseState: null, - baseQueue: null, queue: null, + baseUpdate: null, next: null }; if (workInProgressHook === null) { // This is the first hook in the list - currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook; + firstWorkInProgressHook = workInProgressHook = hook; } else { // Append to the end of the list workInProgressHook = workInProgressHook.next = hook; @@ -10213,33 +11124,12 @@ function updateWorkInProgressHook() { // clone, or a work-in-progress hook from a previous render pass that we can // use as a base. When we reach the end of the base list, we must switch to // the dispatcher used for mounts. - var nextCurrentHook; - - if (currentHook === null) { - var current = currentlyRenderingFiber$1.alternate; - - if (current !== null) { - nextCurrentHook = current.memoizedState; - } else { - nextCurrentHook = null; - } - } else { - nextCurrentHook = currentHook.next; - } - - var nextWorkInProgressHook; - - if (workInProgressHook === null) { - nextWorkInProgressHook = currentlyRenderingFiber$1.memoizedState; - } else { - nextWorkInProgressHook = workInProgressHook.next; - } - if (nextWorkInProgressHook !== null) { // There's already a work-in-progress. Reuse it. workInProgressHook = nextWorkInProgressHook; nextWorkInProgressHook = workInProgressHook.next; currentHook = nextCurrentHook; + nextCurrentHook = currentHook !== null ? currentHook.next : null; } else { // Clone from the current hook. if (!(nextCurrentHook !== null)) { @@ -10250,18 +11140,20 @@ function updateWorkInProgressHook() { var newHook = { memoizedState: currentHook.memoizedState, baseState: currentHook.baseState, - baseQueue: currentHook.baseQueue, queue: currentHook.queue, + baseUpdate: currentHook.baseUpdate, next: null }; if (workInProgressHook === null) { // This is the first hook in the list. - currentlyRenderingFiber$1.memoizedState = workInProgressHook = newHook; + workInProgressHook = firstWorkInProgressHook = newHook; } else { // Append to the end of the list. workInProgressHook = workInProgressHook.next = newHook; } + + nextCurrentHook = currentHook.next; } return workInProgressHook; @@ -10274,7 +11166,6 @@ function createFunctionComponentUpdateQueue() { } function basicStateReducer(state, action) { - // $FlowFixMe: Flow doesn't like mixed types return typeof action === "function" ? action(state) : action; } @@ -10290,13 +11181,13 @@ function mountReducer(reducer, initialArg, init) { hook.memoizedState = hook.baseState = initialState; var queue = (hook.queue = { - pending: null, + last: null, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialState }); var dispatch = (queue.dispatch = dispatchAction.bind( - null, + null, // Flow doesn't know this is non-null, but we do. currentlyRenderingFiber$1, queue )); @@ -10314,191 +11205,160 @@ function updateReducer(reducer, initialArg, init) { } queue.lastRenderedReducer = reducer; - var current = currentHook; // The last rebase update that is NOT part of the base state. - var baseQueue = current.baseQueue; // The last pending update that hasn't been processed yet. + if (numberOfReRenders > 0) { + // This is a re-render. Apply the new render phase updates to the previous + // work-in-progress hook. + var _dispatch = queue.dispatch; + + if (renderPhaseUpdates !== null) { + // Render phase updates are stored in a map of queue -> linked list + var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue); + + if (firstRenderPhaseUpdate !== undefined) { + renderPhaseUpdates.delete(queue); + var newState = hook.memoizedState; + var update = firstRenderPhaseUpdate; + + do { + // Process this render phase update. We don't have to check the + // priority because it will always be the same as the current + // render's. + var action = update.action; + newState = reducer(newState, action); + update = update.next; + } while (update !== null); // Mark that the fiber performed work, but only if the new state is + // different from the current state. + + if (!is$1(newState, hook.memoizedState)) { + markWorkInProgressReceivedUpdate(); + } + + hook.memoizedState = newState; // Don't persist the state accumulated from the render phase updates to + // the base state unless the queue is empty. + // TODO: Not sure if this is the desired semantics, but it's what we + // do for gDSFP. I can't remember why. + + if (hook.baseUpdate === queue.last) { + hook.baseState = newState; + } + + queue.lastRenderedState = newState; + return [newState, _dispatch]; + } + } + + return [hook.memoizedState, _dispatch]; + } // The last update in the entire queue + + var last = queue.last; // The last update that is part of the base state. + + var baseUpdate = hook.baseUpdate; + var baseState = hook.baseState; // Find the first unprocessed update. - var pendingQueue = queue.pending; + var first; - if (pendingQueue !== null) { - // We have new updates that haven't been processed yet. - // We'll add them to the base queue. - if (baseQueue !== null) { - // Merge the pending queue and the base queue. - var baseFirst = baseQueue.next; - var pendingFirst = pendingQueue.next; - baseQueue.next = pendingFirst; - pendingQueue.next = baseFirst; + if (baseUpdate !== null) { + if (last !== null) { + // For the first update, the queue is a circular linked list where + // `queue.last.next = queue.first`. Once the first update commits, and + // the `baseUpdate` is no longer empty, we can unravel the list. + last.next = null; } - current.baseQueue = baseQueue = pendingQueue; - queue.pending = null; + first = baseUpdate.next; + } else { + first = last !== null ? last.next : null; } - if (baseQueue !== null) { - // We have a queue to process. - var first = baseQueue.next; - var newState = current.baseState; + if (first !== null) { + var _newState = baseState; var newBaseState = null; - var newBaseQueueFirst = null; - var newBaseQueueLast = null; - var update = first; + var newBaseUpdate = null; + var prevUpdate = baseUpdate; + var _update = first; + var didSkip = false; do { - var updateExpirationTime = update.expirationTime; + var updateExpirationTime = _update.expirationTime; - if (updateExpirationTime < renderExpirationTime) { + if (updateExpirationTime < renderExpirationTime$1) { // 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 = { - expirationTime: update.expirationTime, - suspenseConfig: update.suspenseConfig, - action: update.action, - eagerReducer: update.eagerReducer, - eagerState: update.eagerState, - next: null - }; - - if (newBaseQueueLast === null) { - newBaseQueueFirst = newBaseQueueLast = clone; - newBaseState = newState; - } else { - newBaseQueueLast = newBaseQueueLast.next = clone; + if (!didSkip) { + didSkip = true; + newBaseUpdate = prevUpdate; + newBaseState = _newState; } // Update the remaining priority in the queue. - if (updateExpirationTime > currentlyRenderingFiber$1.expirationTime) { - currentlyRenderingFiber$1.expirationTime = updateExpirationTime; - markUnprocessedUpdateTime(updateExpirationTime); + if (updateExpirationTime > remainingExpirationTime) { + remainingExpirationTime = updateExpirationTime; + markUnprocessedUpdateTime(remainingExpirationTime); } } else { // This update does have sufficient priority. - if (newBaseQueueLast !== null) { - var _clone = { - expirationTime: Sync, - // This update is going to be committed so we never want uncommit it. - suspenseConfig: update.suspenseConfig, - action: update.action, - eagerReducer: update.eagerReducer, - eagerState: update.eagerState, - next: null - }; - newBaseQueueLast = newBaseQueueLast.next = _clone; - } // Mark the event time of this update as relevant to this render pass. + // Mark the event time of this update as relevant to this render pass. // TODO: This should ideally use the true event time of this update rather than // its priority which is a derived and not reverseable value. // TODO: We should skip this update if it was already committed but currently // we have no way of detecting the difference between a committed and suspended // update here. - markRenderEventTimeAndConfig( updateExpirationTime, - update.suspenseConfig + _update.suspenseConfig ); // Process this update. - if (update.eagerReducer === reducer) { + if (_update.eagerReducer === reducer) { // If this update was processed eagerly, and its reducer matches the // current reducer, we can use the eagerly computed state. - newState = update.eagerState; + _newState = _update.eagerState; } else { - var action = update.action; - newState = reducer(newState, action); + var _action = _update.action; + _newState = reducer(_newState, _action); } } - update = update.next; - } while (update !== null && update !== first); + prevUpdate = _update; + _update = _update.next; + } while (_update !== null && _update !== first); - if (newBaseQueueLast === null) { - newBaseState = newState; - } else { - newBaseQueueLast.next = newBaseQueueFirst; + if (!didSkip) { + newBaseUpdate = prevUpdate; + newBaseState = _newState; } // Mark that the fiber performed work, but only if the new state is // different from the current state. - if (!objectIs(newState, hook.memoizedState)) { + if (!is$1(_newState, hook.memoizedState)) { markWorkInProgressReceivedUpdate(); } - hook.memoizedState = newState; + hook.memoizedState = _newState; + hook.baseUpdate = newBaseUpdate; hook.baseState = newBaseState; - hook.baseQueue = newBaseQueueLast; - queue.lastRenderedState = newState; + queue.lastRenderedState = _newState; } var dispatch = queue.dispatch; return [hook.memoizedState, dispatch]; } -function rerenderReducer(reducer, initialArg, init) { - var hook = updateWorkInProgressHook(); - var queue = hook.queue; - - if (!(queue !== null)) { - throw Error( - "Should have a queue. This is likely a bug in React. Please file an issue." - ); - } - - queue.lastRenderedReducer = reducer; // This is a re-render. Apply the new render phase updates to the previous - // work-in-progress hook. - - var dispatch = queue.dispatch; - var lastRenderPhaseUpdate = queue.pending; - var newState = hook.memoizedState; - - if (lastRenderPhaseUpdate !== null) { - // The queue doesn't persist past this render pass. - queue.pending = null; - var firstRenderPhaseUpdate = lastRenderPhaseUpdate.next; - var update = firstRenderPhaseUpdate; - - do { - // Process this render phase update. We don't have to check the - // priority because it will always be the same as the current - // render's. - var action = update.action; - newState = reducer(newState, action); - update = update.next; - } while (update !== firstRenderPhaseUpdate); // Mark that the fiber performed work, but only if the new state is - // different from the current state. - - if (!objectIs(newState, hook.memoizedState)) { - markWorkInProgressReceivedUpdate(); - } - - hook.memoizedState = newState; // Don't persist the state accumulated from the render phase updates to - // the base state unless the queue is empty. - // TODO: Not sure if this is the desired semantics, but it's what we - // do for gDSFP. I can't remember why. - - if (hook.baseQueue === null) { - hook.baseState = newState; - } - - queue.lastRenderedState = newState; - } - - return [newState, dispatch]; -} - function mountState(initialState) { var hook = mountWorkInProgressHook(); if (typeof initialState === "function") { - // $FlowFixMe: Flow doesn't like mixed types initialState = initialState(); } hook.memoizedState = hook.baseState = initialState; var queue = (hook.queue = { - pending: null, + last: null, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState }); var dispatch = (queue.dispatch = dispatchAction.bind( - null, + null, // Flow doesn't know this is non-null, but we do. currentlyRenderingFiber$1, queue )); @@ -10506,11 +11366,7 @@ function mountState(initialState) { } function updateState(initialState) { - return updateReducer(basicStateReducer); -} - -function rerenderState(initialState) { - return rerenderReducer(basicStateReducer); + return updateReducer(basicStateReducer, initialState); } function pushEffect(tag, create, destroy, deps) { @@ -10522,11 +11378,9 @@ function pushEffect(tag, create, destroy, deps) { // Circular next: null }; - var componentUpdateQueue = currentlyRenderingFiber$1.updateQueue; if (componentUpdateQueue === null) { componentUpdateQueue = createFunctionComponentUpdateQueue(); - currentlyRenderingFiber$1.updateQueue = componentUpdateQueue; componentUpdateQueue.lastEffect = effect.next = effect; } else { var lastEffect = componentUpdateQueue.lastEffect; @@ -10566,13 +11420,8 @@ function updateRef(initialValue) { function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var hook = mountWorkInProgressHook(); var nextDeps = deps === undefined ? null : deps; - currentlyRenderingFiber$1.effectTag |= fiberEffectTag; - hook.memoizedState = pushEffect( - HasEffect | hookEffectTag, - create, - undefined, - nextDeps - ); + sideEffectTag |= fiberEffectTag; + hook.memoizedState = pushEffect(hookEffectTag, create, undefined, nextDeps); } function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { @@ -10588,19 +11437,14 @@ function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var prevDeps = prevEffect.deps; if (areHookInputsEqual(nextDeps, prevDeps)) { - pushEffect(hookEffectTag, create, destroy, nextDeps); + pushEffect(NoEffect$1, create, destroy, nextDeps); return; } } } - currentlyRenderingFiber$1.effectTag |= fiberEffectTag; - hook.memoizedState = pushEffect( - HasEffect | hookEffectTag, - create, - destroy, - nextDeps - ); + sideEffectTag |= fiberEffectTag; + hook.memoizedState = pushEffect(hookEffectTag, create, destroy, nextDeps); } function mountEffect(create, deps) { @@ -10611,7 +11455,12 @@ function mountEffect(create, deps) { } } - return mountEffectImpl(Update | Passive, Passive$1, create, deps); + return mountEffectImpl( + Update | Passive, + UnmountPassive | MountPassive, + create, + deps + ); } function updateEffect(create, deps) { @@ -10622,15 +11471,20 @@ function updateEffect(create, deps) { } } - return updateEffectImpl(Update | Passive, Passive$1, create, deps); + return updateEffectImpl( + Update | Passive, + UnmountPassive | MountPassive, + create, + deps + ); } function mountLayoutEffect(create, deps) { - return mountEffectImpl(Update, Layout, create, deps); + return mountEffectImpl(Update, UnmountMutation | MountLayout, create, deps); } function updateLayoutEffect(create, deps) { - return updateEffectImpl(Update, Layout, create, deps); + return updateEffectImpl(Update, UnmountMutation | MountLayout, create, deps); } function imperativeHandleEffect(create, ref) { @@ -10647,13 +11501,14 @@ function imperativeHandleEffect(create, ref) { var refObject = ref; { - if (!refObject.hasOwnProperty("current")) { - error( - "Expected useImperativeHandle() first argument to either be a " + - "ref callback or React.createRef() object. Instead received: %s.", - "an object with keys {" + Object.keys(refObject).join(", ") + "}" - ); - } + !refObject.hasOwnProperty("current") + ? warning$1( + false, + "Expected useImperativeHandle() first argument to either be a " + + "ref callback or React.createRef() object. Instead received: %s.", + "an object with keys {" + Object.keys(refObject).join(", ") + "}" + ) + : void 0; } var _inst2 = create(); @@ -10667,20 +11522,21 @@ function imperativeHandleEffect(create, ref) { function mountImperativeHandle(ref, create, deps) { { - if (typeof create !== "function") { - error( - "Expected useImperativeHandle() second argument to be a function " + - "that creates a handle. Instead received: %s.", - create !== null ? typeof create : "null" - ); - } + !(typeof create === "function") + ? warning$1( + false, + "Expected useImperativeHandle() second argument to be a function " + + "that creates a handle. Instead received: %s.", + create !== null ? typeof create : "null" + ) + : void 0; } // TODO: If deps are provided, should we skip comparing the ref itself? var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null; return mountEffectImpl( Update, - Layout, + UnmountMutation | MountLayout, imperativeHandleEffect.bind(null, create, ref), effectDeps ); @@ -10688,20 +11544,21 @@ function mountImperativeHandle(ref, create, deps) { function updateImperativeHandle(ref, create, deps) { { - if (typeof create !== "function") { - error( - "Expected useImperativeHandle() second argument to be a function " + - "that creates a handle. Instead received: %s.", - create !== null ? typeof create : "null" - ); - } + !(typeof create === "function") + ? warning$1( + false, + "Expected useImperativeHandle() second argument to be a function " + + "that creates a handle. Instead received: %s.", + create !== null ? typeof create : "null" + ) + : void 0; } // TODO: If deps are provided, should we skip comparing the ref itself? var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null; return updateEffectImpl( Update, - Layout, + UnmountMutation | MountLayout, imperativeHandleEffect.bind(null, create, ref), effectDeps ); @@ -10777,14 +11634,17 @@ function mountDeferredValue(value, config) { mountEffect( function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config; + Scheduler.unstable_next(function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + config === undefined ? null : config; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }); }, [value, config] ); @@ -10792,149 +11652,99 @@ function mountDeferredValue(value, config) { } function updateDeferredValue(value, config) { - var _updateState = updateState(), + var _updateState = updateState(value), prevValue = _updateState[0], setValue = _updateState[1]; updateEffect( function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config; - - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }, - [value, config] - ); - return prevValue; -} - -function rerenderDeferredValue(value, config) { - var _rerenderState = rerenderState(), - prevValue = _rerenderState[0], - setValue = _rerenderState[1]; - - updateEffect( - function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config; + Scheduler.unstable_next(function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + config === undefined ? null : config; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }); }, [value, config] ); return prevValue; } -function startTransition(setPending, config, callback) { - var priorityLevel = getCurrentPriorityLevel(); - runWithPriority( - priorityLevel < UserBlockingPriority ? UserBlockingPriority : priorityLevel, - function() { - setPending(true); - } - ); - runWithPriority( - priorityLevel > NormalPriority ? NormalPriority : priorityLevel, - function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config; - - try { - setPending(false); - callback(); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - } - ); -} - function mountTransition(config) { var _mountState2 = mountState(false), isPending = _mountState2[0], setPending = _mountState2[1]; - var start = mountCallback(startTransition.bind(null, setPending, config), [ - setPending, - config - ]); - return [start, isPending]; + var startTransition = mountCallback( + function(callback) { + setPending(true); + Scheduler.unstable_next(function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + config === undefined ? null : config; + + try { + setPending(false); + callback(); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }); + }, + [config, isPending] + ); + return [startTransition, isPending]; } function updateTransition(config) { - var _updateState2 = updateState(), + var _updateState2 = updateState(false), isPending = _updateState2[0], setPending = _updateState2[1]; - var start = updateCallback(startTransition.bind(null, setPending, config), [ - setPending, - config - ]); - return [start, isPending]; -} - -function rerenderTransition(config) { - var _rerenderState2 = rerenderState(), - isPending = _rerenderState2[0], - setPending = _rerenderState2[1]; + var startTransition = updateCallback( + function(callback) { + setPending(true); + Scheduler.unstable_next(function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + config === undefined ? null : config; - var start = updateCallback(startTransition.bind(null, setPending, config), [ - setPending, - config - ]); - return [start, isPending]; + try { + setPending(false); + callback(); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }); + }, + [config, isPending] + ); + return [startTransition, isPending]; } function dispatchAction(fiber, queue, action) { - { - if (typeof arguments[3] === "function") { - error( - "State updates from the useState() and useReducer() Hooks don't support the " + - "second callback argument. To execute a side effect after " + - "rendering, declare it in the component body with useEffect()." - ); - } + if (!(numberOfReRenders < RE_RENDER_LIMIT)) { + throw Error( + "Too many re-renders. React limits the number of renders to prevent an infinite loop." + ); } - var currentTime = requestCurrentTimeForUpdate(); - var suspenseConfig = requestCurrentSuspenseConfig(); - var expirationTime = computeExpirationForFiber( - currentTime, - fiber, - suspenseConfig - ); - var update = { - expirationTime: expirationTime, - suspenseConfig: suspenseConfig, - action: action, - eagerReducer: null, - eagerState: null, - next: null - }; - { - update.priority = getCurrentPriorityLevel(); - } // 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; + !(typeof arguments[3] !== "function") + ? warning$1( + false, + "State updates from the useState() and useReducer() Hooks don't support the " + + "second callback argument. To execute a side effect after " + + "rendering, declare it in the component body with useEffect()." + ) + : void 0; } - queue.pending = update; var alternate = fiber.alternate; if ( @@ -10945,9 +11755,76 @@ 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. didScheduleRenderPhaseUpdate = true; - update.expirationTime = renderExpirationTime; - currentlyRenderingFiber$1.expirationTime = renderExpirationTime; + var update = { + expirationTime: renderExpirationTime$1, + suspenseConfig: null, + action: action, + eagerReducer: null, + eagerState: null, + next: null + }; + + { + update.priority = getCurrentPriorityLevel(); + } + + if (renderPhaseUpdates === null) { + renderPhaseUpdates = new Map(); + } + + var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue); + + if (firstRenderPhaseUpdate === undefined) { + renderPhaseUpdates.set(queue, update); + } else { + // Append the update to the end of the list. + var lastRenderPhaseUpdate = firstRenderPhaseUpdate; + + while (lastRenderPhaseUpdate.next !== null) { + lastRenderPhaseUpdate = lastRenderPhaseUpdate.next; + } + + lastRenderPhaseUpdate.next = update; + } } else { + var currentTime = requestCurrentTimeForUpdate(); + var suspenseConfig = requestCurrentSuspenseConfig(); + var expirationTime = computeExpirationForFiber( + currentTime, + fiber, + suspenseConfig + ); + var _update2 = { + expirationTime: expirationTime, + suspenseConfig: suspenseConfig, + action: action, + eagerReducer: null, + eagerState: null, + next: null + }; + + { + _update2.priority = getCurrentPriorityLevel(); + } // Append the update to the end of the list. + + var last = queue.last; + + if (last === null) { + // This is the first update. Create a circular list. + _update2.next = _update2; + } else { + var first = last.next; + + if (first !== null) { + // Still circular. + _update2.next = first; + } + + last.next = _update2; + } + + queue.last = _update2; + if ( fiber.expirationTime === NoWork && (alternate === null || alternate.expirationTime === NoWork) @@ -10961,8 +11838,8 @@ function dispatchAction(fiber, queue, action) { var prevDispatcher; { - prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; } try { @@ -10972,10 +11849,10 @@ function dispatchAction(fiber, queue, action) { // time we enter the render phase, then the eager state can be used // without calling the reducer again. - update.eagerReducer = lastRenderedReducer; - update.eagerState = eagerState; + _update2.eagerReducer = lastRenderedReducer; + _update2.eagerState = eagerState; - if (objectIs(eagerState, currentState)) { + if (is$1(eagerState, currentState)) { // Fast path. We can bail out without scheduling React to re-render. // It's still possible that we'll need to rebase this update later, // if the component re-renders for a different reason and by that @@ -10986,7 +11863,7 @@ function dispatchAction(fiber, queue, action) { // Suppress the error. It will throw again in the render phase. } finally { { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } } } @@ -11004,14 +11881,6 @@ function dispatchAction(fiber, queue, action) { } } -function mountEventListener(event) { - return undefined; -} - -function updateEventListener(event) { - return undefined; -} - var ContextOnlyDispatcher = { readContext: readContext, useCallback: throwInvalidHookError, @@ -11026,20 +11895,18 @@ var ContextOnlyDispatcher = { useDebugValue: throwInvalidHookError, useResponder: throwInvalidHookError, useDeferredValue: throwInvalidHookError, - useTransition: throwInvalidHookError, - useEvent: throwInvalidHookError + useTransition: throwInvalidHookError }; var HooksDispatcherOnMountInDEV = null; var HooksDispatcherOnMountWithHookTypesInDEV = null; var HooksDispatcherOnUpdateInDEV = null; -var HooksDispatcherOnRerenderInDEV = null; var InvalidNestedHooksDispatcherOnMountInDEV = null; var InvalidNestedHooksDispatcherOnUpdateInDEV = null; -var InvalidNestedHooksDispatcherOnRerenderInDEV = null; { var warnInvalidContextAccess = function() { - error( + warning$1( + false, "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 " + @@ -11048,7 +11915,8 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; }; var warnInvalidHookAccess = function() { - error( + warning$1( + false, "Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks. " + "You can only call Hooks at the top level of your React function. " + "For more information, see " + @@ -11093,25 +11961,25 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; currentHookNameInDev = "useMemo"; mountHookTypesDev(); checkDepsAreArrayDev(deps); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; try { return mountMemo(create, deps); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useReducer: function(reducer, initialArg, init) { currentHookNameInDev = "useReducer"; mountHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; try { return mountReducer(reducer, initialArg, init); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useRef: function(initialValue) { @@ -11122,24 +11990,24 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; useState: function(initialState) { currentHookNameInDev = "useState"; mountHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; try { return mountState(initialState); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useDebugValue: function(value, formatterFn) { currentHookNameInDev = "useDebugValue"; mountHookTypesDev(); - return mountDebugValue(); + return mountDebugValue(value, formatterFn); }, useResponder: function(responder, props) { currentHookNameInDev = "useResponder"; mountHookTypesDev(); - return createDeprecatedResponderListener(responder, props); + return createResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; @@ -11150,11 +12018,6 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; currentHookNameInDev = "useTransition"; mountHookTypesDev(); return mountTransition(config); - }, - useEvent: function(event) { - currentHookNameInDev = "useEvent"; - mountHookTypesDev(); - return mountEventListener(); } }; HooksDispatcherOnMountWithHookTypesInDEV = { @@ -11189,25 +12052,25 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; useMemo: function(create, deps) { currentHookNameInDev = "useMemo"; updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; try { return mountMemo(create, deps); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useReducer: function(reducer, initialArg, init) { currentHookNameInDev = "useReducer"; updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; try { return mountReducer(reducer, initialArg, init); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useRef: function(initialValue) { @@ -11218,24 +12081,24 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; useState: function(initialState) { currentHookNameInDev = "useState"; updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; try { return mountState(initialState); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useDebugValue: function(value, formatterFn) { currentHookNameInDev = "useDebugValue"; updateHookTypesDev(); - return mountDebugValue(); + return mountDebugValue(value, formatterFn); }, useResponder: function(responder, props) { currentHookNameInDev = "useResponder"; updateHookTypesDev(); - return createDeprecatedResponderListener(responder, props); + return createResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; @@ -11246,11 +12109,6 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; currentHookNameInDev = "useTransition"; updateHookTypesDev(); return mountTransition(config); - }, - useEvent: function(event) { - currentHookNameInDev = "useEvent"; - updateHookTypesDev(); - return mountEventListener(); } }; HooksDispatcherOnUpdateInDEV = { @@ -11285,53 +12143,53 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; useMemo: function(create, deps) { currentHookNameInDev = "useMemo"; updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; try { return updateMemo(create, deps); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useReducer: function(reducer, initialArg, init) { currentHookNameInDev = "useReducer"; updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; try { return updateReducer(reducer, initialArg, init); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useRef: function(initialValue) { currentHookNameInDev = "useRef"; updateHookTypesDev(); - return updateRef(); + return updateRef(initialValue); }, useState: function(initialState) { currentHookNameInDev = "useState"; updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; try { return updateState(initialState); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useDebugValue: function(value, formatterFn) { currentHookNameInDev = "useDebugValue"; updateHookTypesDev(); - return updateDebugValue(); + return updateDebugValue(value, formatterFn); }, useResponder: function(responder, props) { currentHookNameInDev = "useResponder"; updateHookTypesDev(); - return createDeprecatedResponderListener(responder, props); + return createResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; @@ -11342,107 +12200,6 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; currentHookNameInDev = "useTransition"; updateHookTypesDev(); return updateTransition(config); - }, - useEvent: function(event) { - currentHookNameInDev = "useEvent"; - updateHookTypesDev(); - return updateEventListener(); - } - }; - HooksDispatcherOnRerenderInDEV = { - readContext: function(context, observedBits) { - return readContext(context, observedBits); - }, - useCallback: function(callback, deps) { - currentHookNameInDev = "useCallback"; - updateHookTypesDev(); - return updateCallback(callback, deps); - }, - useContext: function(context, observedBits) { - currentHookNameInDev = "useContext"; - updateHookTypesDev(); - return readContext(context, observedBits); - }, - useEffect: function(create, deps) { - currentHookNameInDev = "useEffect"; - updateHookTypesDev(); - return updateEffect(create, deps); - }, - useImperativeHandle: function(ref, create, deps) { - currentHookNameInDev = "useImperativeHandle"; - updateHookTypesDev(); - return updateImperativeHandle(ref, create, deps); - }, - useLayoutEffect: function(create, deps) { - currentHookNameInDev = "useLayoutEffect"; - updateHookTypesDev(); - return updateLayoutEffect(create, deps); - }, - useMemo: function(create, deps) { - currentHookNameInDev = "useMemo"; - updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnRerenderInDEV; - - try { - return updateMemo(create, deps); - } finally { - ReactCurrentDispatcher.current = prevDispatcher; - } - }, - useReducer: function(reducer, initialArg, init) { - currentHookNameInDev = "useReducer"; - updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnRerenderInDEV; - - try { - return rerenderReducer(reducer, initialArg, init); - } finally { - ReactCurrentDispatcher.current = prevDispatcher; - } - }, - useRef: function(initialValue) { - currentHookNameInDev = "useRef"; - updateHookTypesDev(); - return updateRef(); - }, - useState: function(initialState) { - currentHookNameInDev = "useState"; - updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnRerenderInDEV; - - try { - return rerenderState(initialState); - } finally { - ReactCurrentDispatcher.current = prevDispatcher; - } - }, - useDebugValue: function(value, formatterFn) { - currentHookNameInDev = "useDebugValue"; - updateHookTypesDev(); - return updateDebugValue(); - }, - useResponder: function(responder, props) { - currentHookNameInDev = "useResponder"; - updateHookTypesDev(); - return createDeprecatedResponderListener(responder, props); - }, - useDeferredValue: function(value, config) { - currentHookNameInDev = "useDeferredValue"; - updateHookTypesDev(); - return rerenderDeferredValue(value, config); - }, - useTransition: function(config) { - currentHookNameInDev = "useTransition"; - updateHookTypesDev(); - return rerenderTransition(config); - }, - useEvent: function(event) { - currentHookNameInDev = "useEvent"; - updateHookTypesDev(); - return updateEventListener(); } }; InvalidNestedHooksDispatcherOnMountInDEV = { @@ -11484,26 +12241,26 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; currentHookNameInDev = "useMemo"; warnInvalidHookAccess(); mountHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; try { return mountMemo(create, deps); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useReducer: function(reducer, initialArg, init) { currentHookNameInDev = "useReducer"; warnInvalidHookAccess(); mountHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; try { return mountReducer(reducer, initialArg, init); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useRef: function(initialValue) { @@ -11516,158 +12273,41 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; currentHookNameInDev = "useState"; warnInvalidHookAccess(); mountHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; try { return mountState(initialState); } finally { - ReactCurrentDispatcher.current = prevDispatcher; - } - }, - useDebugValue: function(value, formatterFn) { - currentHookNameInDev = "useDebugValue"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountDebugValue(); - }, - useResponder: function(responder, props) { - currentHookNameInDev = "useResponder"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return createDeprecatedResponderListener(responder, props); - }, - useDeferredValue: function(value, config) { - currentHookNameInDev = "useDeferredValue"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountDeferredValue(value, config); - }, - useTransition: function(config) { - currentHookNameInDev = "useTransition"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountTransition(config); - }, - useEvent: function(event) { - currentHookNameInDev = "useEvent"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountEventListener(); - } - }; - InvalidNestedHooksDispatcherOnUpdateInDEV = { - 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.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; - - try { - return updateMemo(create, deps); - } finally { - ReactCurrentDispatcher.current = prevDispatcher; - } - }, - useReducer: function(reducer, initialArg, init) { - currentHookNameInDev = "useReducer"; - warnInvalidHookAccess(); - updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; - - try { - return updateReducer(reducer, initialArg, init); - } finally { - ReactCurrentDispatcher.current = prevDispatcher; - } - }, - useRef: function(initialValue) { - currentHookNameInDev = "useRef"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateRef(); - }, - useState: function(initialState) { - currentHookNameInDev = "useState"; - warnInvalidHookAccess(); - updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; - - try { - return updateState(initialState); - } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useDebugValue: function(value, formatterFn) { currentHookNameInDev = "useDebugValue"; warnInvalidHookAccess(); - updateHookTypesDev(); - return updateDebugValue(); + mountHookTypesDev(); + return mountDebugValue(value, formatterFn); }, useResponder: function(responder, props) { currentHookNameInDev = "useResponder"; warnInvalidHookAccess(); - updateHookTypesDev(); - return createDeprecatedResponderListener(responder, props); + mountHookTypesDev(); + return createResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; warnInvalidHookAccess(); - updateHookTypesDev(); - return updateDeferredValue(value, config); + mountHookTypesDev(); + return mountDeferredValue(value, config); }, useTransition: function(config) { currentHookNameInDev = "useTransition"; warnInvalidHookAccess(); - updateHookTypesDev(); - return updateTransition(config); - }, - useEvent: function(event) { - currentHookNameInDev = "useEvent"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateEventListener(); + mountHookTypesDev(); + return mountTransition(config); } }; - InvalidNestedHooksDispatcherOnRerenderInDEV = { + InvalidNestedHooksDispatcherOnUpdateInDEV = { readContext: function(context, observedBits) { warnInvalidContextAccess(); return readContext(context, observedBits); @@ -11706,80 +12346,76 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; currentHookNameInDev = "useMemo"; warnInvalidHookAccess(); updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; try { return updateMemo(create, deps); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useReducer: function(reducer, initialArg, init) { currentHookNameInDev = "useReducer"; warnInvalidHookAccess(); updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; try { - return rerenderReducer(reducer, initialArg, init); + return updateReducer(reducer, initialArg, init); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useRef: function(initialValue) { currentHookNameInDev = "useRef"; warnInvalidHookAccess(); updateHookTypesDev(); - return updateRef(); + return updateRef(initialValue); }, useState: function(initialState) { currentHookNameInDev = "useState"; warnInvalidHookAccess(); updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; try { - return rerenderState(initialState); + return updateState(initialState); } finally { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.current = prevDispatcher; } }, useDebugValue: function(value, formatterFn) { currentHookNameInDev = "useDebugValue"; warnInvalidHookAccess(); updateHookTypesDev(); - return updateDebugValue(); + return updateDebugValue(value, formatterFn); }, useResponder: function(responder, props) { currentHookNameInDev = "useResponder"; warnInvalidHookAccess(); updateHookTypesDev(); - return createDeprecatedResponderListener(responder, props); + return createResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; warnInvalidHookAccess(); updateHookTypesDev(); - return rerenderDeferredValue(value, config); + return updateDeferredValue(value, config); }, useTransition: function(config) { currentHookNameInDev = "useTransition"; warnInvalidHookAccess(); updateHookTypesDev(); - return rerenderTransition(config); - }, - useEvent: function(event) { - currentHookNameInDev = "useEvent"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateEventListener(); + return updateTransition(config); } }; } +// CommonJS interop named imports. + var now$1 = Scheduler.unstable_now; var commitTime = 0; var profilerStartTime = -1; @@ -11789,10 +12425,18 @@ function getCommitTime() { } function recordCommitTime() { + if (!enableProfilerTimer) { + return; + } + commitTime = now$1(); } function startProfilerTimer(fiber) { + if (!enableProfilerTimer) { + return; + } + profilerStartTime = now$1(); if (fiber.actualStartTime < 0) { @@ -11801,10 +12445,18 @@ function startProfilerTimer(fiber) { } function stopProfilerTimerIfRunning(fiber) { + if (!enableProfilerTimer) { + return; + } + profilerStartTime = -1; } function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) { + if (!enableProfilerTimer) { + return; + } + if (profilerStartTime >= 0) { var elapsedTime = now$1() - profilerStartTime; fiber.actualDuration += elapsedTime; @@ -11817,10 +12469,258 @@ function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) { } } -function enterHydrationState(fiber) { +// This may have been an insertion or a hydration. + +var hydrationParentFiber = null; +var nextHydratableInstance = null; +var isHydrating = false; + +function warnIfHydrating() { { + !!isHydrating + ? warning$1( + false, + "We should not be hydrating here. This is a bug in React. Please file a bug." + ) + : void 0; + } +} + +function enterHydrationState(fiber) { + if (!supportsHydration) { + return false; + } + + var parentInstance = fiber.stateNode.containerInfo; + nextHydratableInstance = getFirstHydratableChild(parentInstance); + hydrationParentFiber = fiber; + isHydrating = true; + return true; +} + +function reenterHydrationStateFromDehydratedSuspenseInstance( + fiber, + suspenseInstance +) { + if (!supportsHydration) { return false; } + + nextHydratableInstance = getNextHydratableSibling(suspenseInstance); + popToNextHostParent(fiber); + isHydrating = true; + return true; +} + +function deleteHydratableInstance(returnFiber, instance) { + { + switch (returnFiber.tag) { + case HostRoot: + didNotHydrateContainerInstance( + returnFiber.stateNode.containerInfo, + instance + ); + break; + + case HostComponent: + didNotHydrateInstance( + returnFiber.type, + returnFiber.memoizedProps, + returnFiber.stateNode, + instance + ); + break; + } + } + + var childToDelete = createFiberFromHostInstanceForDeletion(); + childToDelete.stateNode = instance; + childToDelete.return = returnFiber; + childToDelete.effectTag = Deletion; // This might seem like it belongs on progressedFirstDeletion. However, + // these children are not part of the reconciliation list of children. + // Even if we abort and rereconcile the children, that will try to hydrate + // again and the nodes are still in the host tree so these will be + // recreated. + + if (returnFiber.lastEffect !== null) { + returnFiber.lastEffect.nextEffect = childToDelete; + returnFiber.lastEffect = childToDelete; + } else { + returnFiber.firstEffect = returnFiber.lastEffect = childToDelete; + } +} + +function insertNonHydratedInstance(returnFiber, fiber) { + fiber.effectTag = (fiber.effectTag & ~Hydrating) | Placement; + + { + switch (returnFiber.tag) { + case HostRoot: { + var parentContainer = returnFiber.stateNode.containerInfo; + + switch (fiber.tag) { + case HostComponent: + var type = fiber.type; + var props = fiber.pendingProps; + didNotFindHydratableContainerInstance(parentContainer, type, props); + break; + + case HostText: + var text = fiber.pendingProps; + didNotFindHydratableContainerTextInstance(parentContainer, text); + break; + + case SuspenseComponent: + didNotFindHydratableContainerSuspenseInstance(parentContainer); + break; + } + + break; + } + + case HostComponent: { + var parentType = returnFiber.type; + var parentProps = returnFiber.memoizedProps; + var parentInstance = returnFiber.stateNode; + + switch (fiber.tag) { + case HostComponent: + var _type = fiber.type; + var _props = fiber.pendingProps; + didNotFindHydratableInstance( + parentType, + parentProps, + parentInstance, + _type, + _props + ); + break; + + case HostText: + var _text = fiber.pendingProps; + didNotFindHydratableTextInstance( + parentType, + parentProps, + parentInstance, + _text + ); + break; + + case SuspenseComponent: + didNotFindHydratableSuspenseInstance( + parentType, + parentProps, + parentInstance + ); + break; + } + + break; + } + + default: + return; + } + } +} + +function tryHydrate(fiber, nextInstance) { + switch (fiber.tag) { + case HostComponent: { + var type = fiber.type; + var props = fiber.pendingProps; + var instance = canHydrateInstance(nextInstance, type, props); + + if (instance !== null) { + fiber.stateNode = instance; + return true; + } + + return false; + } + + case HostText: { + var text = fiber.pendingProps; + var textInstance = canHydrateTextInstance(nextInstance, text); + + if (textInstance !== null) { + fiber.stateNode = textInstance; + return true; + } + + return false; + } + + case SuspenseComponent: { + if (enableSuspenseServerRenderer) { + var suspenseInstance = canHydrateSuspenseInstance(nextInstance); + + if (suspenseInstance !== null) { + var suspenseState = { + dehydrated: suspenseInstance, + retryTime: Never + }; + fiber.memoizedState = suspenseState; // Store the dehydrated fragment as a child fiber. + // This simplifies the code for getHostSibling and deleting nodes, + // since it doesn't have to consider all Suspense boundaries and + // check if they're dehydrated ones or not. + + var dehydratedFragment = createFiberFromDehydratedFragment( + suspenseInstance + ); + dehydratedFragment.return = fiber; + fiber.child = dehydratedFragment; + return true; + } + } + + return false; + } + + default: + return false; + } +} + +function tryToClaimNextHydratableInstance(fiber) { + if (!isHydrating) { + return; + } + + var nextInstance = nextHydratableInstance; + + if (!nextInstance) { + // Nothing to hydrate. Make it an insertion. + insertNonHydratedInstance(hydrationParentFiber, fiber); + isHydrating = false; + hydrationParentFiber = fiber; + return; + } + + var firstAttemptedInstance = nextInstance; + + if (!tryHydrate(fiber, nextInstance)) { + // If we can't hydrate this instance let's try the next one. + // We use this as a heuristic. It's based on intuition and not data so it + // might be flawed or unnecessary. + nextInstance = getNextHydratableSibling(firstAttemptedInstance); + + if (!nextInstance || !tryHydrate(fiber, nextInstance)) { + // Nothing to hydrate. Make it an insertion. + insertNonHydratedInstance(hydrationParentFiber, fiber); + isHydrating = false; + hydrationParentFiber = fiber; + return; + } // We matched the next one, we'll now assume that the first one was + // superfluous and we'll delete it. Since we can't eagerly delete it + // we'll have to schedule a deletion. To do that, this node needs a dummy + // fiber associated with it. + + deleteHydratableInstance(hydrationParentFiber, firstAttemptedInstance); + } + + hydrationParentFiber = fiber; + nextHydratableInstance = getFirstHydratableChild(nextInstance); } function prepareToHydrateHostInstance( @@ -11828,33 +12728,209 @@ function prepareToHydrateHostInstance( rootContainerInstance, hostContext ) { - { + if (!supportsHydration) { { throw Error( "Expected prepareToHydrateHostInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." ); } } + + var instance = fiber.stateNode; + var updatePayload = hydrateInstance( + instance, + fiber.type, + fiber.memoizedProps, + rootContainerInstance, + hostContext, + fiber + ); // TODO: Type this specific to this type of component. + + fiber.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. + + if (updatePayload !== null) { + return true; + } + + return false; } function prepareToHydrateHostTextInstance(fiber) { - { + if (!supportsHydration) { { throw Error( "Expected prepareToHydrateHostTextInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." ); } } - var shouldUpdate = hydrateTextInstance(); + + var textInstance = fiber.stateNode; + var textContent = fiber.memoizedProps; + var shouldUpdate = hydrateTextInstance(textInstance, textContent, fiber); + + { + if (shouldUpdate) { + // We assume that prepareToHydrateHostTextInstance is called in a context where the + // hydration parent is the parent host component of this host text. + var returnFiber = hydrationParentFiber; + + if (returnFiber !== null) { + switch (returnFiber.tag) { + case HostRoot: { + var parentContainer = returnFiber.stateNode.containerInfo; + didNotMatchHydratedContainerTextInstance( + parentContainer, + textInstance, + textContent + ); + break; + } + + case HostComponent: { + var parentType = returnFiber.type; + var parentProps = returnFiber.memoizedProps; + var parentInstance = returnFiber.stateNode; + didNotMatchHydratedTextInstance( + parentType, + parentProps, + parentInstance, + textInstance, + textContent + ); + break; + } + } + } + } + } + + return shouldUpdate; +} + +function prepareToHydrateHostSuspenseInstance(fiber) { + if (!supportsHydration) { + { + throw Error( + "Expected prepareToHydrateHostSuspenseInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." + ); + } + } + + var suspenseState = fiber.memoizedState; + var suspenseInstance = + suspenseState !== null ? suspenseState.dehydrated : null; + + if (!suspenseInstance) { + throw Error( + "Expected to have a hydrated suspense instance. This error is likely caused by a bug in React. Please file an issue." + ); + } + + hydrateSuspenseInstance(suspenseInstance, fiber); +} + +function skipPastDehydratedSuspenseInstance(fiber) { + if (!supportsHydration) { + { + throw Error( + "Expected skipPastDehydratedSuspenseInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." + ); + } + } + + var suspenseState = fiber.memoizedState; + var suspenseInstance = + suspenseState !== null ? suspenseState.dehydrated : null; + + if (!suspenseInstance) { + throw Error( + "Expected to have a hydrated suspense instance. This error is likely caused by a bug in React. Please file an issue." + ); + } + + return getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance); +} + +function popToNextHostParent(fiber) { + var parent = fiber.return; + + while ( + parent !== null && + parent.tag !== HostComponent && + parent.tag !== HostRoot && + parent.tag !== SuspenseComponent + ) { + parent = parent.return; + } + + hydrationParentFiber = parent; } function popHydrationState(fiber) { - { + if (!supportsHydration) { + return false; + } + + if (fiber !== hydrationParentFiber) { + // We're deeper than the current hydration context, inside an inserted + // tree. + return false; + } + + if (!isHydrating) { + // If we're not currently hydrating but we're in a hydration context, then + // we were an insertion and now need to pop up reenter hydration of our + // siblings. + popToNextHostParent(fiber); + isHydrating = true; return false; } + + var type = fiber.type; // If we have any remaining hydratable nodes, we need to delete them now. + // We only do this deeper than head and body since they tend to have random + // other nodes in them. We also ignore components with pure text content in + // side of them. + // TODO: Better heuristic. + + if ( + fiber.tag !== HostComponent || + (type !== "head" && + type !== "body" && + !shouldSetTextContent(type, fiber.memoizedProps)) + ) { + var nextInstance = nextHydratableInstance; + + while (nextInstance) { + deleteHydratableInstance(fiber, nextInstance); + nextInstance = getNextHydratableSibling(nextInstance); + } + } + + popToNextHostParent(fiber); + + if (fiber.tag === SuspenseComponent) { + nextHydratableInstance = skipPastDehydratedSuspenseInstance(fiber); + } else { + nextHydratableInstance = hydrationParentFiber + ? getNextHydratableSibling(fiber.stateNode) + : null; + } + + return true; } -var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner; +function resetHydrationState() { + if (!supportsHydration) { + return; + } + + hydrationParentFiber = null; + nextHydratableInstance = null; + isHydrating = false; +} + +var ReactCurrentOwner$3 = ReactSharedInternals.ReactCurrentOwner; var didReceiveUpdate = false; var didWarnAboutBadClass; var didWarnAboutModulePatternComponent; @@ -11862,8 +12938,10 @@ var didWarnAboutContextTypeOnFunctionComponent; var didWarnAboutGetDerivedStateOnFunctionComponent; var didWarnAboutFunctionRefs; var didWarnAboutReassigningProps; +var didWarnAboutMaxDuration; var didWarnAboutRevealOrder; var didWarnAboutTailOptions; +var didWarnAboutDefaultPropsOnFunctionComponent; { didWarnAboutBadClass = {}; @@ -11872,17 +12950,19 @@ var didWarnAboutTailOptions; didWarnAboutGetDerivedStateOnFunctionComponent = {}; didWarnAboutFunctionRefs = {}; didWarnAboutReassigningProps = false; + didWarnAboutMaxDuration = false; didWarnAboutRevealOrder = {}; didWarnAboutTailOptions = {}; + didWarnAboutDefaultPropsOnFunctionComponent = {}; } function reconcileChildren( - current, + current$$1, workInProgress, nextChildren, renderExpirationTime ) { - if (current === null) { + if (current$$1 === 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 @@ -11901,7 +12981,7 @@ function reconcileChildren( // let's throw it out. workInProgress.child = reconcileChildFibers( workInProgress, - current.child, + current$$1.child, nextChildren, renderExpirationTime ); @@ -11909,7 +12989,7 @@ function reconcileChildren( } function forceUnmountCurrentAndReconcile( - current, + current$$1, workInProgress, nextChildren, renderExpirationTime @@ -11924,13 +13004,13 @@ function forceUnmountCurrentAndReconcile( // passing null. workInProgress.child = reconcileChildFibers( workInProgress, - current.child, + current$$1.child, null, renderExpirationTime ); // 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. + // the effect of remounting all children regardless of whether their their + // identity matches. workInProgress.child = reconcileChildFibers( workInProgress, @@ -11941,7 +13021,7 @@ function forceUnmountCurrentAndReconcile( } function updateForwardRef( - current, + current$$1, workInProgress, Component, nextProps, @@ -11961,7 +13041,8 @@ function updateForwardRef( innerPropTypes, nextProps, // Resolved props "prop", - getComponentName(Component) + getComponentName(Component), + getCurrentFiberStackInDev ); } } @@ -11974,10 +13055,10 @@ function updateForwardRef( prepareToReadContext(workInProgress, renderExpirationTime); { - ReactCurrentOwner$1.current = workInProgress; - setIsRendering(true); + ReactCurrentOwner$3.current = workInProgress; + setCurrentPhase("render"); nextChildren = renderWithHooks( - current, + current$$1, workInProgress, render, nextProps, @@ -11985,13 +13066,30 @@ function updateForwardRef( renderExpirationTime ); - setIsRendering(false); + if ( + debugRenderPhaseSideEffectsForStrictMode && + workInProgress.mode & StrictMode + ) { + // Only double-render components with Hooks + if (workInProgress.memoizedState !== null) { + nextChildren = renderWithHooks( + current$$1, + workInProgress, + render, + nextProps, + ref, + renderExpirationTime + ); + } + } + + setCurrentPhase(null); } - if (current !== null && !didReceiveUpdate) { - bailoutHooks(current, workInProgress, renderExpirationTime); + if (current$$1 !== null && !didReceiveUpdate) { + bailoutHooks(current$$1, workInProgress, renderExpirationTime); return bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -11999,7 +13097,7 @@ function updateForwardRef( workInProgress.effectTag |= PerformedWork; reconcileChildren( - current, + current$$1, workInProgress, nextChildren, renderExpirationTime @@ -12008,14 +13106,14 @@ function updateForwardRef( } function updateMemoComponent( - current, + current$$1, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime ) { - if (current === null) { + if (current$$1 === null) { var type = Component.type; if ( @@ -12039,7 +13137,7 @@ function updateMemoComponent( } return updateSimpleMemoComponent( - current, + current$$1, workInProgress, resolvedType, nextProps, @@ -12058,7 +13156,8 @@ function updateMemoComponent( innerPropTypes, nextProps, // Resolved props "prop", - getComponentName(type) + getComponentName(type), + getCurrentFiberStackInDev ); } } @@ -12088,12 +13187,13 @@ function updateMemoComponent( _innerPropTypes, nextProps, // Resolved props "prop", - getComponentName(_type) + getComponentName(_type), + getCurrentFiberStackInDev ); } } - var currentChild = current.child; // This is always exactly one child + var currentChild = current$$1.child; // This is always exactly one child if (updateExpirationTime < renderExpirationTime) { // This will be the props with resolved defaultProps, @@ -12103,9 +13203,12 @@ function updateMemoComponent( var compare = Component.compare; compare = compare !== null ? compare : shallowEqual; - if (compare(prevProps, nextProps) && current.ref === workInProgress.ref) { + if ( + compare(prevProps, nextProps) && + current$$1.ref === workInProgress.ref + ) { return bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -12113,7 +13216,11 @@ function updateMemoComponent( } // React DevTools reads this flag. workInProgress.effectTag |= PerformedWork; - var newChild = createWorkInProgress(currentChild, nextProps); + var newChild = createWorkInProgress( + currentChild, + nextProps, + renderExpirationTime + ); newChild.ref = workInProgress.ref; newChild.return = workInProgress; workInProgress.child = newChild; @@ -12121,7 +13228,7 @@ function updateMemoComponent( } function updateSimpleMemoComponent( - current, + current$$1, workInProgress, Component, nextProps, @@ -12151,39 +13258,26 @@ function updateSimpleMemoComponent( outerPropTypes, nextProps, // Resolved (SimpleMemoComponent has no defaultProps) "prop", - getComponentName(outerMemoType) + getComponentName(outerMemoType), + getCurrentFiberStackInDev ); } // Inner propTypes will be validated in the function component path. } } - if (current !== null) { - var prevProps = current.memoizedProps; + if (current$$1 !== null) { + var prevProps = current$$1.memoizedProps; if ( shallowEqual(prevProps, nextProps) && - current.ref === workInProgress.ref && // Prevent bailout if the implementation changed due to hot reload. - workInProgress.type === current.type + current$$1.ref === workInProgress.ref && // Prevent bailout if the implementation changed due to hot reload: + workInProgress.type === current$$1.type ) { didReceiveUpdate = false; if (updateExpirationTime < renderExpirationTime) { - // The pending update priority was cleared at the beginning of - // beginWork. We're about to bail out, but there might be additional - // updates at a lower priority. 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.expirationTime = current.expirationTime; return bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -12192,7 +13286,7 @@ function updateSimpleMemoComponent( } return updateFunctionComponent( - current, + current$$1, workInProgress, Component, nextProps, @@ -12200,10 +13294,10 @@ function updateSimpleMemoComponent( ); } -function updateFragment(current, workInProgress, renderExpirationTime) { +function updateFragment(current$$1, workInProgress, renderExpirationTime) { var nextChildren = workInProgress.pendingProps; reconcileChildren( - current, + current$$1, workInProgress, nextChildren, renderExpirationTime @@ -12211,10 +13305,10 @@ function updateFragment(current, workInProgress, renderExpirationTime) { return workInProgress.child; } -function updateMode(current, workInProgress, renderExpirationTime) { +function updateMode(current$$1, workInProgress, renderExpirationTime) { var nextChildren = workInProgress.pendingProps.children; reconcileChildren( - current, + current$$1, workInProgress, nextChildren, renderExpirationTime @@ -12222,20 +13316,15 @@ function updateMode(current, workInProgress, renderExpirationTime) { return workInProgress.child; } -function updateProfiler(current, workInProgress, renderExpirationTime) { - { - workInProgress.effectTag |= 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; +function updateProfiler(current$$1, workInProgress, renderExpirationTime) { + if (enableProfilerTimer) { + workInProgress.effectTag |= Update; } var nextProps = workInProgress.pendingProps; var nextChildren = nextProps.children; reconcileChildren( - current, + current$$1, workInProgress, nextChildren, renderExpirationTime @@ -12243,12 +13332,12 @@ function updateProfiler(current, workInProgress, renderExpirationTime) { return workInProgress.child; } -function markRef(current, workInProgress) { +function markRef(current$$1, workInProgress) { var ref = workInProgress.ref; if ( - (current === null && ref !== null) || - (current !== null && current.ref !== ref) + (current$$1 === null && ref !== null) || + (current$$1 !== null && current$$1.ref !== ref) ) { // Schedule a Ref effect workInProgress.effectTag |= Ref; @@ -12256,7 +13345,7 @@ function markRef(current, workInProgress) { } function updateFunctionComponent( - current, + current$$1, workInProgress, Component, nextProps, @@ -12273,7 +13362,8 @@ function updateFunctionComponent( innerPropTypes, nextProps, // Resolved props "prop", - getComponentName(Component) + getComponentName(Component), + getCurrentFiberStackInDev ); } } @@ -12281,7 +13371,7 @@ function updateFunctionComponent( var context; - { + if (!disableLegacyContext) { var unmaskedContext = getUnmaskedContext(workInProgress, Component, true); context = getMaskedContext(workInProgress, unmaskedContext); } @@ -12290,10 +13380,10 @@ function updateFunctionComponent( prepareToReadContext(workInProgress, renderExpirationTime); { - ReactCurrentOwner$1.current = workInProgress; - setIsRendering(true); + ReactCurrentOwner$3.current = workInProgress; + setCurrentPhase("render"); nextChildren = renderWithHooks( - current, + current$$1, workInProgress, Component, nextProps, @@ -12301,13 +13391,30 @@ function updateFunctionComponent( renderExpirationTime ); - setIsRendering(false); + if ( + debugRenderPhaseSideEffectsForStrictMode && + workInProgress.mode & StrictMode + ) { + // Only double-render components with Hooks + if (workInProgress.memoizedState !== null) { + nextChildren = renderWithHooks( + current$$1, + workInProgress, + Component, + nextProps, + context, + renderExpirationTime + ); + } + } + + setCurrentPhase(null); } - if (current !== null && !didReceiveUpdate) { - bailoutHooks(current, workInProgress, renderExpirationTime); + if (current$$1 !== null && !didReceiveUpdate) { + bailoutHooks(current$$1, workInProgress, renderExpirationTime); return bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -12315,7 +13422,7 @@ function updateFunctionComponent( workInProgress.effectTag |= PerformedWork; reconcileChildren( - current, + current$$1, workInProgress, nextChildren, renderExpirationTime @@ -12324,7 +13431,7 @@ function updateFunctionComponent( } function updateClassComponent( - current, + current$$1, workInProgress, Component, nextProps, @@ -12341,7 +13448,8 @@ function updateClassComponent( innerPropTypes, nextProps, // Resolved props "prop", - getComponentName(Component) + getComponentName(Component), + getCurrentFiberStackInDev ); } } @@ -12363,18 +13471,23 @@ function updateClassComponent( 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 + if (current$$1 !== null) { + // An class component without an instance only mounts if it suspended + // inside a non- concurrent tree, in an inconsistent state. We want to + // tree it like a new mount, even though an empty version of it already // committed. Disconnect the alternate pointers. - current.alternate = null; + current$$1.alternate = null; workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect workInProgress.effectTag |= Placement; } // In the initial pass we might need to construct the instance. - constructClassInstance(workInProgress, Component, nextProps); + constructClassInstance( + workInProgress, + Component, + nextProps, + renderExpirationTime + ); mountClassInstance( workInProgress, Component, @@ -12382,7 +13495,7 @@ function updateClassComponent( renderExpirationTime ); shouldUpdate = true; - } else if (current === null) { + } else if (current$$1 === null) { // In a resume, we'll already have an instance we can reuse. shouldUpdate = resumeMountClassInstance( workInProgress, @@ -12392,7 +13505,7 @@ function updateClassComponent( ); } else { shouldUpdate = updateClassInstance( - current, + current$$1, workInProgress, Component, nextProps, @@ -12401,7 +13514,7 @@ function updateClassComponent( } var nextUnitOfWork = finishClassComponent( - current, + current$$1, workInProgress, Component, shouldUpdate, @@ -12413,14 +13526,14 @@ function updateClassComponent( var inst = workInProgress.stateNode; if (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 + ? warning$1( + false, + "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" + ) + : void 0; didWarnAboutReassigningProps = true; } } @@ -12429,7 +13542,7 @@ function updateClassComponent( } function finishClassComponent( - current, + current$$1, workInProgress, Component, shouldUpdate, @@ -12437,7 +13550,7 @@ function finishClassComponent( renderExpirationTime ) { // Refs should update even if shouldComponentUpdate returns false - markRef(current, workInProgress); + markRef(current$$1, workInProgress); var didCaptureError = (workInProgress.effectTag & DidCapture) !== NoEffect; if (!shouldUpdate && !didCaptureError) { @@ -12447,7 +13560,7 @@ function finishClassComponent( } return bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -12455,48 +13568,55 @@ function finishClassComponent( var instance = workInProgress.stateNode; // Rerender - ReactCurrentOwner$1.current = workInProgress; + ReactCurrentOwner$3.current = workInProgress; var nextChildren; if ( didCaptureError && typeof Component.getDerivedStateFromError !== "function" ) { - // If we captured an error, but getDerivedStateFromError is not defined, + // If we captured an error, but getDerivedStateFrom catch 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(); + if (enableProfilerTimer) { + stopProfilerTimerIfRunning(workInProgress); } } else { { - setIsRendering(true); + setCurrentPhase("render"); nextChildren = instance.render(); - setIsRendering(false); + if ( + debugRenderPhaseSideEffectsForStrictMode && + workInProgress.mode & StrictMode + ) { + instance.render(); + } + + setCurrentPhase(null); } } // React DevTools reads this flag. workInProgress.effectTag |= PerformedWork; - if (current !== null && didCaptureError) { + if (current$$1 !== 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, + current$$1, workInProgress, nextChildren, renderExpirationTime ); } else { reconcileChildren( - current, + current$$1, workInProgress, nextChildren, renderExpirationTime @@ -12530,11 +13650,11 @@ function pushHostRootContext(workInProgress) { pushHostContainer(workInProgress, root.containerInfo); } -function updateHostRoot(current, workInProgress, renderExpirationTime) { +function updateHostRoot(current$$1, workInProgress, renderExpirationTime) { pushHostRootContext(workInProgress); var updateQueue = workInProgress.updateQueue; - if (!(current !== null && updateQueue !== null)) { + if (!(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." ); @@ -12543,16 +13663,24 @@ function updateHostRoot(current, workInProgress, renderExpirationTime) { var nextProps = workInProgress.pendingProps; var prevState = workInProgress.memoizedState; var prevChildren = prevState !== null ? prevState.element : null; - cloneUpdateQueue(current, workInProgress); - processUpdateQueue(workInProgress, nextProps, null, renderExpirationTime); + processUpdateQueue( + workInProgress, + updateQueue, + nextProps, + null, + renderExpirationTime + ); var nextState = workInProgress.memoizedState; // Caution: React DevTools currently depends on this property // being called "element". var nextChildren = nextState.element; if (nextChildren === prevChildren) { + // If the state is the same as before, that's a bailout because we had + // no work that expires at this time. + resetHydrationState(); return bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -12560,7 +13688,7 @@ function updateHostRoot(current, workInProgress, renderExpirationTime) { var root = workInProgress.stateNode; - if (root.hydrate && enterHydrationState()) { + if (root.hydrate && enterHydrationState(workInProgress)) { // If we don't have any current children this might be the first pass. // We always try to hydrate. If this isn't a hydration pass there won't // be any children to hydrate which is effectively the same thing as @@ -12588,38 +13716,50 @@ function updateHostRoot(current, workInProgress, renderExpirationTime) { // Otherwise reset hydration state in case we aborted and resumed another // root. reconcileChildren( - current, + current$$1, workInProgress, nextChildren, renderExpirationTime ); + resetHydrationState(); } return workInProgress.child; } -function updateHostComponent(current, workInProgress, renderExpirationTime) { +function updateHostComponent(current$$1, workInProgress, renderExpirationTime) { pushHostContext(workInProgress); + if (current$$1 === null) { + tryToClaimNextHydratableInstance(workInProgress); + } + var type = workInProgress.type; var nextProps = workInProgress.pendingProps; - var prevProps = current !== null ? current.memoizedProps : null; + var prevProps = current$$1 !== null ? current$$1.memoizedProps : null; var nextChildren = nextProps.children; + var isDirectTextChild = shouldSetTextContent(type, nextProps); - if (prevProps !== null && shouldSetTextContent()) { + if (isDirectTextChild) { + // We special case a direct text child of a host node. This is a common + // case. We won't handle it as a reified child. We will instead handle + // this in the host environment that also have access to this prop. That + // avoids allocating another HostText fiber and traversing it. + nextChildren = null; + } else if (prevProps !== null && shouldSetTextContent(type, prevProps)) { // 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.effectTag |= ContentReset; } - markRef(current, workInProgress); // Check the host config to see if the children are offscreen/hidden. + markRef(current$$1, workInProgress); // Check the host config to see if the children are offscreen/hidden. if ( workInProgress.mode & ConcurrentMode && renderExpirationTime !== Never && - shouldDeprioritizeSubtree() + shouldDeprioritizeSubtree(type, nextProps) ) { - { + if (enableSchedulerTracing) { markSpawnedWork(Never); } // Schedule this fiber to re-render at offscreen priority. Then bailout. @@ -12628,7 +13768,7 @@ function updateHostComponent(current, workInProgress, renderExpirationTime) { } reconcileChildren( - current, + current$$1, workInProgress, nextChildren, renderExpirationTime @@ -12636,7 +13776,10 @@ function updateHostComponent(current, workInProgress, renderExpirationTime) { return workInProgress.child; } -function updateHostText(current, workInProgress) { +function updateHostText(current$$1, workInProgress) { + if (current$$1 === null) { + tryToClaimNextHydratableInstance(workInProgress); + } // Nothing to do here. This is terminal. We'll do the completion step // immediately after. return null; @@ -12650,7 +13793,7 @@ function mountLazyComponent( renderExpirationTime ) { if (_current !== null) { - // A lazy component only mounts if it suspended inside a non- + // An 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. @@ -12688,7 +13831,7 @@ function mountLazyComponent( resolvedProps, renderExpirationTime ); - return child; + break; } case ClassComponent: { @@ -12705,7 +13848,7 @@ function mountLazyComponent( resolvedProps, renderExpirationTime ); - return child; + break; } case ForwardRef: { @@ -12722,7 +13865,7 @@ function mountLazyComponent( resolvedProps, renderExpirationTime ); - return child; + break; } case MemoComponent: { @@ -12735,7 +13878,8 @@ function mountLazyComponent( outerPropTypes, resolvedProps, // Resolved for outer only "prop", - getComponentName(Component) + getComponentName(Component), + getCurrentFiberStackInDev ); } } @@ -12749,32 +13893,36 @@ function mountLazyComponent( updateExpirationTime, renderExpirationTime ); - return child; + break; } - } - var hint = ""; + default: { + 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. + { + 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 - ); + { + throw Error( + "Element type is invalid. Received a promise that resolves to: " + + Component + + ". Lazy element type must resolve to a class or function." + + hint + ); + } + } } + + return child; } function mountIncompleteClassComponent( @@ -12810,7 +13958,12 @@ function mountIncompleteClassComponent( } prepareToReadContext(workInProgress, renderExpirationTime); - constructClassInstance(workInProgress, Component, nextProps); + constructClassInstance( + workInProgress, + Component, + nextProps, + renderExpirationTime + ); mountClassInstance( workInProgress, Component, @@ -12847,7 +14000,7 @@ function mountIndeterminateComponent( var props = workInProgress.pendingProps; var context; - { + if (!disableLegacyContext) { var unmaskedContext = getUnmaskedContext(workInProgress, Component, false); context = getMaskedContext(workInProgress, unmaskedContext); } @@ -12863,13 +14016,13 @@ function mountIndeterminateComponent( var componentName = getComponentName(Component) || "Unknown"; if (!didWarnAboutBadClass[componentName]) { - error( + warningWithoutStack$1( + false, "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; } } @@ -12878,7 +14031,7 @@ function mountIndeterminateComponent( ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null); } - ReactCurrentOwner$1.current = workInProgress; + ReactCurrentOwner$3.current = workInProgress; value = renderWithHooks( null, workInProgress, @@ -12901,7 +14054,8 @@ function mountIndeterminateComponent( var _componentName = getComponentName(Component) || "Unknown"; if (!didWarnAboutModulePatternComponent[_componentName]) { - error( + warningWithoutStack$1( + false, "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. " + @@ -12911,15 +14065,13 @@ function mountIndeterminateComponent( _componentName, _componentName ); - didWarnAboutModulePatternComponent[_componentName] = 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. + resetHooks(); // 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. @@ -12934,7 +14086,6 @@ function mountIndeterminateComponent( workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null; - initializeUpdateQueue(workInProgress); var getDerivedStateFromProps = Component.getDerivedStateFromProps; if (typeof getDerivedStateFromProps === "function") { @@ -12960,6 +14111,34 @@ function mountIndeterminateComponent( // Proceed under the assumption that this is a function component workInProgress.tag = FunctionComponent; + { + if (disableLegacyContext && Component.contextTypes) { + warningWithoutStack$1( + false, + "%s uses the legacy contextTypes API which is no longer supported. " + + "Use React.createContext() with React.useContext() instead.", + getComponentName(Component) || "Unknown" + ); + } + + if ( + debugRenderPhaseSideEffectsForStrictMode && + workInProgress.mode & StrictMode + ) { + // Only double-render components with Hooks + if (workInProgress.memoizedState !== null) { + value = renderWithHooks( + null, + workInProgress, + Component, + props, + context, + renderExpirationTime + ); + } + } + } + reconcileChildren(null, workInProgress, value, renderExpirationTime); { @@ -12971,70 +14150,86 @@ function mountIndeterminateComponent( } function validateFunctionComponentInDev(workInProgress, Component) { - { - if (Component) { - if (Component.childContextTypes) { - error( + if (Component) { + !!Component.childContextTypes + ? warningWithoutStack$1( + false, "%s(...): childContextTypes cannot be defined on a function component.", Component.displayName || Component.name || "Component" - ); - } - } - - if (workInProgress.ref !== null) { - var info = ""; - var ownerName = getCurrentFiberOwnerNameInDevOrNull(); + ) + : void 0; + } - if (ownerName) { - info += "\n\nCheck the render method of `" + ownerName + "`."; - } + if (workInProgress.ref !== null) { + var info = ""; + var ownerName = getCurrentFiberOwnerNameInDevOrNull(); - var warningKey = ownerName || workInProgress._debugID || ""; - var debugSource = workInProgress._debugSource; + if (ownerName) { + info += "\n\nCheck the render method of `" + ownerName + "`."; + } - if (debugSource) { - warningKey = debugSource.fileName + ":" + debugSource.lineNumber; - } + var warningKey = ownerName || workInProgress._debugID || ""; + var debugSource = workInProgress._debugSource; - if (!didWarnAboutFunctionRefs[warningKey]) { - didWarnAboutFunctionRefs[warningKey] = true; + if (debugSource) { + warningKey = debugSource.fileName + ":" + debugSource.lineNumber; + } - error( - "Function components cannot be given refs. " + - "Attempts to access this ref will fail. " + - "Did you mean to use React.forwardRef()?%s", - info - ); - } + if (!didWarnAboutFunctionRefs[warningKey]) { + didWarnAboutFunctionRefs[warningKey] = true; + warning$1( + false, + "Function components cannot be given refs. " + + "Attempts to access this ref will fail. " + + "Did you mean to use React.forwardRef()?%s", + info + ); } + } - if (typeof Component.getDerivedStateFromProps === "function") { - var _componentName2 = getComponentName(Component) || "Unknown"; + if ( + warnAboutDefaultPropsOnFunctionComponents && + Component.defaultProps !== undefined + ) { + var componentName = getComponentName(Component) || "Unknown"; + + if (!didWarnAboutDefaultPropsOnFunctionComponent[componentName]) { + warningWithoutStack$1( + false, + "%s: Support for defaultProps will be removed from function components " + + "in a future major release. Use JavaScript default parameters instead.", + componentName + ); + didWarnAboutDefaultPropsOnFunctionComponent[componentName] = true; + } + } - if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2]) { - error( - "%s: Function components do not support getDerivedStateFromProps.", - _componentName2 - ); + if (typeof Component.getDerivedStateFromProps === "function") { + var _componentName2 = getComponentName(Component) || "Unknown"; - didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2] = true; - } + if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2]) { + warningWithoutStack$1( + false, + "%s: Function components do not support getDerivedStateFromProps.", + _componentName2 + ); + didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2] = true; } + } - if ( - typeof Component.contextType === "object" && - Component.contextType !== null - ) { - var _componentName3 = getComponentName(Component) || "Unknown"; - - if (!didWarnAboutContextTypeOnFunctionComponent[_componentName3]) { - error( - "%s: Function components do not support contextType.", - _componentName3 - ); + if ( + typeof Component.contextType === "object" && + Component.contextType !== null + ) { + var _componentName3 = getComponentName(Component) || "Unknown"; - didWarnAboutContextTypeOnFunctionComponent[_componentName3] = true; - } + if (!didWarnAboutContextTypeOnFunctionComponent[_componentName3]) { + warningWithoutStack$1( + false, + "%s: Function components do not support contextType.", + _componentName3 + ); + didWarnAboutContextTypeOnFunctionComponent[_componentName3] = true; } } } @@ -13044,17 +14239,17 @@ var SUSPENDED_MARKER = { retryTime: NoWork }; -function shouldRemainOnFallback(suspenseContext, current, workInProgress) { +function shouldRemainOnFallback(suspenseContext, current$$1, workInProgress) { // If the context is telling us that we should show a fallback, and we're not // already showing content, then we should show the fallback instead. return ( hasSuspenseContext(suspenseContext, ForceSuspenseFallback) && - (current === null || current.memoizedState !== null) + (current$$1 === null || current$$1.memoizedState !== null) ); } function updateSuspenseComponent( - current, + current$$1, workInProgress, renderExpirationTime ) { @@ -13071,14 +14266,17 @@ function updateSuspenseComponent( var nextDidTimeout = false; var didSuspend = (workInProgress.effectTag & DidCapture) !== NoEffect; - if (didSuspend || shouldRemainOnFallback(suspenseContext, current)) { + if ( + didSuspend || + shouldRemainOnFallback(suspenseContext, current$$1, workInProgress) + ) { // Something in this boundary's subtree already suspended. Switch to // rendering the fallback children. nextDidTimeout = true; workInProgress.effectTag &= ~DidCapture; } else { // Attempting the main content - if (current === null || current.memoizedState !== null) { + if (current$$1 === null || current$$1.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. @@ -13097,7 +14295,20 @@ function updateSuspenseComponent( } suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); - pushSuspenseContext(workInProgress, suspenseContext); // This next part is a bit confusing. If the children timeout, we switch to + pushSuspenseContext(workInProgress, suspenseContext); + + { + if ("maxDuration" in nextProps) { + if (!didWarnAboutMaxDuration) { + didWarnAboutMaxDuration = true; + warning$1( + false, + "maxDuration has been removed from React. " + + "Remove the maxDuration prop." + ); + } + } + } // This next part is a bit confusing. If the children timeout, we switch to // showing the fallback children in place of the "primary" children. // However, we don't want to delete the primary children because then their // state will be lost (both the React state and the host state, e.g. @@ -13119,10 +14330,28 @@ function updateSuspenseComponent( // custom reconciliation logic to preserve the state of the primary // children. It's essentially a very basic form of re-parenting. - if (current === null) { + if (current$$1 === null) { // If we're currently hydrating, try to hydrate this boundary. // But only if this has a fallback. - if (nextProps.fallback !== undefined); // This is the initial mount. This branch is pretty simple because there's + if (nextProps.fallback !== undefined) { + tryToClaimNextHydratableInstance(workInProgress); // This could've been a dehydrated suspense component. + + if (enableSuspenseServerRenderer) { + var suspenseState = workInProgress.memoizedState; + + if (suspenseState !== null) { + var dehydrated = suspenseState.dehydrated; + + if (dehydrated !== null) { + return mountDehydratedSuspenseComponent( + workInProgress, + dehydrated, + renderExpirationTime + ); + } + } + } + } // This is the initial mount. This branch is pretty simple because there's // no previous state that needs to be preserved. if (nextDidTimeout) { @@ -13180,12 +14409,107 @@ function updateSuspenseComponent( } else { // This is an update. This branch is more complicated because we need to // ensure the state of the primary children is preserved. - var prevState = current.memoizedState; + var prevState = current$$1.memoizedState; if (prevState !== null) { + if (enableSuspenseServerRenderer) { + var _dehydrated = prevState.dehydrated; + + if (_dehydrated !== null) { + if (!didSuspend) { + return updateDehydratedSuspenseComponent( + current$$1, + workInProgress, + _dehydrated, + prevState, + renderExpirationTime + ); + } else if (workInProgress.memoizedState !== null) { + // Something suspended and we should still be in dehydrated mode. + // Leave the existing child in place. + workInProgress.child = current$$1.child; // The dehydrated completion pass expects this flag to be there + // but the normal suspense pass doesn't. + + workInProgress.effectTag |= DidCapture; + return null; + } else { + // Suspended but we should no longer be in dehydrated mode. + // Therefore we now have to render the fallback. Wrap the children + // in a fragment fiber to keep them separate from the fallback + // children. + var _nextFallbackChildren = nextProps.fallback; + + var _primaryChildFragment = createFiberFromFragment( + // It shouldn't matter what the pending props are because we aren't + // going to render this fragment. + null, + mode, + NoWork, + null + ); + + _primaryChildFragment.return = workInProgress; // This is always null since we never want the previous child + // that we're not going to hydrate. + + _primaryChildFragment.child = null; + + if ((workInProgress.mode & BlockingMode) === NoMode) { + // Outside of blocking mode, we commit the effects from the + // partially completed, timed-out tree, too. + var _progressedChild = (_primaryChildFragment.child = + workInProgress.child); + + while (_progressedChild !== null) { + _progressedChild.return = _primaryChildFragment; + _progressedChild = _progressedChild.sibling; + } + } else { + // We will have dropped the effect list which contains the deletion. + // We need to reconcile to delete the current child. + reconcileChildFibers( + workInProgress, + current$$1.child, + null, + renderExpirationTime + ); + } // Because primaryChildFragment is a new fiber that we're inserting as the + // parent of a new tree, we need to set its treeBaseDuration. + + if (enableProfilerTimer && workInProgress.mode & ProfileMode) { + // treeBaseDuration is the sum of all the child tree base durations. + var treeBaseDuration = 0; + var hiddenChild = _primaryChildFragment.child; + + while (hiddenChild !== null) { + treeBaseDuration += hiddenChild.treeBaseDuration; + hiddenChild = hiddenChild.sibling; + } + + _primaryChildFragment.treeBaseDuration = treeBaseDuration; + } // Create a fragment from the fallback children, too. + + var _fallbackChildFragment = createFiberFromFragment( + _nextFallbackChildren, + mode, + renderExpirationTime, + null + ); + + _fallbackChildFragment.return = workInProgress; + _primaryChildFragment.sibling = _fallbackChildFragment; + _fallbackChildFragment.effectTag |= Placement; + _primaryChildFragment.childExpirationTime = NoWork; + workInProgress.memoizedState = SUSPENDED_MARKER; + workInProgress.child = _primaryChildFragment; // Skip the primary children, and continue working on the + // fallback children. + + return _fallbackChildFragment; + } + } + } // The current tree already timed out. That means each child set is // wrapped in a fragment fiber. - var currentPrimaryChildFragment = current.child; + var currentPrimaryChildFragment = current$$1.child; var currentFallbackChildFragment = currentPrimaryChildFragment.sibling; if (nextDidTimeout) { @@ -13195,7 +14519,8 @@ function updateSuspenseComponent( var _primaryChildFragment2 = createWorkInProgress( currentPrimaryChildFragment, - currentPrimaryChildFragment.pendingProps + currentPrimaryChildFragment.pendingProps, + NoWork ); _primaryChildFragment2.return = workInProgress; @@ -13222,7 +14547,7 @@ function updateSuspenseComponent( } // Because primaryChildFragment is a new fiber that we're inserting as the // parent of a new tree, we need to set its treeBaseDuration. - if (workInProgress.mode & ProfileMode) { + if (enableProfilerTimer && workInProgress.mode & ProfileMode) { // treeBaseDuration is the sum of all the child tree base durations. var _treeBaseDuration = 0; var _hiddenChild = _primaryChildFragment2.child; @@ -13238,7 +14563,8 @@ function updateSuspenseComponent( var _fallbackChildFragment2 = createWorkInProgress( currentFallbackChildFragment, - _nextFallbackChildren2 + _nextFallbackChildren2, + currentFallbackChildFragment.expirationTime ); _fallbackChildFragment2.return = workInProgress; @@ -13272,7 +14598,7 @@ function updateSuspenseComponent( } else { // The current tree has not already timed out. That means the primary // children are not wrapped in a fragment fiber. - var _currentPrimaryChild = current.child; + var _currentPrimaryChild = current$$1.child; if (nextDidTimeout) { // Timed out. Wrap the children in a fragment fiber to keep them @@ -13318,7 +14644,7 @@ function updateSuspenseComponent( } // Because primaryChildFragment is a new fiber that we're inserting as the // parent of a new tree, we need to set its treeBaseDuration. - if (workInProgress.mode & ProfileMode) { + if (enableProfilerTimer && workInProgress.mode & ProfileMode) { // treeBaseDuration is the sum of all the child tree base durations. var _treeBaseDuration2 = 0; var _hiddenChild2 = _primaryChildFragment3.child; @@ -13348,7 +14674,7 @@ function updateSuspenseComponent( workInProgress.child = _primaryChildFragment3; return _fallbackChildFragment3; } else { - // Still haven't timed out. Continue rendering the children, like we + // Still haven't timed out. Continue rendering the children, like we // normally do. workInProgress.memoizedState = null; var _nextPrimaryChildren2 = nextProps.children; @@ -13363,6 +14689,197 @@ function updateSuspenseComponent( } } +function retrySuspenseComponentWithoutHydrating( + current$$1, + workInProgress, + renderExpirationTime +) { + // We're now not suspended nor dehydrated. + workInProgress.memoizedState = null; // Retry with the full children. + + var nextProps = workInProgress.pendingProps; + var nextChildren = nextProps.children; // This will ensure that the children get Placement effects and + // that the old child gets a Deletion effect. + // We could also call forceUnmountCurrentAndReconcile. + + reconcileChildren( + current$$1, + workInProgress, + nextChildren, + renderExpirationTime + ); + return workInProgress.child; +} + +function mountDehydratedSuspenseComponent( + workInProgress, + suspenseInstance, + renderExpirationTime +) { + // During the first pass, we'll bail out and not drill into the children. + // Instead, we'll leave the content in place and try to hydrate it later. + if ((workInProgress.mode & BlockingMode) === NoMode) { + { + warning$1( + false, + "Cannot hydrate Suspense in legacy mode. Switch from " + + "ReactDOM.hydrate(element, container) to " + + "ReactDOM.createBlockingRoot(container, { hydrate: true })" + + ".render(element) or remove the Suspense components from " + + "the server rendered components." + ); + } + + workInProgress.expirationTime = Sync; + } else if (isSuspenseInstanceFallback(suspenseInstance)) { + // This is a client-only boundary. Since we won't get any content from the server + // for this, we need to schedule that at a higher priority based on when it would + // have timed out. In theory we could render it in this pass but it would have the + // wrong priority associated with it and will prevent hydration of parent path. + // Instead, we'll leave work left on it to render it in a separate commit. + // TODO This time should be the time at which the server rendered response that is + // a parent to this boundary was displayed. However, since we currently don't have + // a protocol to transfer that time, we'll just estimate it by using the current + // time. This will mean that Suspense timeouts are slightly shifted to later than + // they should be. + var serverDisplayTime = requestCurrentTimeForUpdate(); // Schedule a normal pri update to render this content. + + var newExpirationTime = computeAsyncExpiration(serverDisplayTime); + + if (enableSchedulerTracing) { + markSpawnedWork(newExpirationTime); + } + + workInProgress.expirationTime = newExpirationTime; + } else { + // We'll continue hydrating the rest at offscreen priority since we'll already + // be showing the right content coming from the server, it is no rush. + workInProgress.expirationTime = Never; + + if (enableSchedulerTracing) { + markSpawnedWork(Never); + } + } + + return null; +} + +function updateDehydratedSuspenseComponent( + current$$1, + workInProgress, + suspenseInstance, + suspenseState, + renderExpirationTime +) { + // We should never be hydrating at this point because it is the first pass, + // but after we've already committed once. + warnIfHydrating(); + + if ((workInProgress.mode & BlockingMode) === NoMode) { + return retrySuspenseComponentWithoutHydrating( + current$$1, + workInProgress, + renderExpirationTime + ); + } + + if (isSuspenseInstanceFallback(suspenseInstance)) { + // This boundary is in a permanent fallback state. In this case, we'll never + // get an update and we'll never be able to hydrate the final content. Let's just try the + // client side render instead. + return retrySuspenseComponentWithoutHydrating( + current$$1, + workInProgress, + renderExpirationTime + ); + } // We use childExpirationTime to indicate that a child might depend on context, so if + // any context has changed, we need to treat is as if the input might have changed. + + var hasContextChanged$$1 = + current$$1.childExpirationTime >= renderExpirationTime; + + if (didReceiveUpdate || hasContextChanged$$1) { + // This boundary has changed since the first render. This means that we are now unable to + // hydrate it. We might still be able to hydrate it using an earlier expiration time, if + // we are rendering at lower expiration than sync. + if (renderExpirationTime < Sync) { + if (suspenseState.retryTime <= renderExpirationTime) { + // This render is even higher pri than we've seen before, let's try again + // at even higher pri. + var attemptHydrationAtExpirationTime = renderExpirationTime + 1; + suspenseState.retryTime = attemptHydrationAtExpirationTime; + scheduleWork(current$$1, attemptHydrationAtExpirationTime); // TODO: Early abort this render. + } else { + // We have already tried to ping at a higher priority than we're rendering with + // so if we got here, we must have failed to hydrate at those levels. We must + // now give up. Instead, we're going to delete the whole subtree and instead inject + // a new real Suspense boundary to take its place, which may render content + // or fallback. This might suspend for a while and if it does we might still have + // an opportunity to hydrate before this pass commits. + } + } // If we have scheduled higher pri work above, this will probably just abort the render + // since we now have higher priority work, but in case it doesn't, we need to prepare to + // render something, if we time out. Even if that requires us to delete everything and + // skip hydration. + // Delay having to do this as long as the suspense timeout allows us. + + renderDidSuspendDelayIfPossible(); + return retrySuspenseComponentWithoutHydrating( + current$$1, + workInProgress, + renderExpirationTime + ); + } else if (isSuspenseInstancePending(suspenseInstance)) { + // This component is still pending more data from the server, so we can't hydrate its + // content. We treat it as if this component suspended itself. It might seem as if + // we could just try to render it client-side instead. However, this will perform a + // lot of unnecessary work and is unlikely to complete since it often will suspend + // on missing data anyway. Additionally, the server might be able to render more + // than we can on the client yet. In that case we'd end up with more fallback states + // on the client than if we just leave it alone. If the server times out or errors + // these should update this boundary to the permanent Fallback state instead. + // Mark it as having captured (i.e. suspended). + workInProgress.effectTag |= DidCapture; // Leave the child in place. I.e. the dehydrated fragment. + + workInProgress.child = current$$1.child; // Register a callback to retry this boundary once the server has sent the result. + + registerSuspenseInstanceRetry( + suspenseInstance, + retryDehydratedSuspenseBoundary.bind(null, current$$1) + ); + return null; + } else { + // This is the first attempt. + reenterHydrationStateFromDehydratedSuspenseInstance( + workInProgress, + suspenseInstance + ); + var nextProps = workInProgress.pendingProps; + var nextChildren = nextProps.children; + var child = mountChildFibers( + workInProgress, + null, + nextChildren, + renderExpirationTime + ); + 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.effectTag |= Hydrating; + node = node.sibling; + } + + workInProgress.child = child; + return workInProgress.child; + } +} + function scheduleWorkOnFiber(fiber, renderExpirationTime) { if (fiber.expirationTime < renderExpirationTime) { fiber.expirationTime = renderExpirationTime; @@ -13464,39 +14981,40 @@ function validateRevealOrder(revealOrder) { case "together": case "forwards": case "backwards": { - error( + warning$1( + false, '"%s" is not a valid value for revealOrder on . ' + 'Use lowercase "%s" instead.', revealOrder, revealOrder.toLowerCase() ); - break; } case "forward": case "backward": { - error( + warning$1( + false, '"%s" is not a valid value for revealOrder on . ' + 'React uses the -s suffix in the spelling. Use "%ss" instead.', revealOrder, revealOrder.toLowerCase() ); - break; } default: - error( + warning$1( + false, '"%s" is not a supported revealOrder on . ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder ); - break; } } else { - error( + warning$1( + false, "%s is not a supported value for revealOrder on . " + 'Did you mean "together", "forwards" or "backwards"?', revealOrder @@ -13511,16 +15029,16 @@ function validateTailOptions(tailMode, revealOrder) { if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) { if (tailMode !== "collapsed" && tailMode !== "hidden") { didWarnAboutTailOptions[tailMode] = true; - - error( + warning$1( + false, '"%s" is not a supported value for tail on . ' + 'Did you mean "collapsed" or "hidden"?', tailMode ); } else if (revealOrder !== "forwards" && revealOrder !== "backwards") { didWarnAboutTailOptions[tailMode] = true; - - error( + warning$1( + false, ' is only valid if revealOrder is ' + '"forwards" or "backwards". ' + 'Did you mean to specify revealOrder="forwards"?', @@ -13538,8 +15056,8 @@ function validateSuspenseListNestedChild(childSlot, index) { if (isArray || isIterable) { var type = isArray ? "array" : "iterable"; - - error( + warning$1( + false, "A nested %s was passed to row #%s in . Wrap it in " + "an additional SuspenseList to configure its revealOrder: " + " ... " + @@ -13549,7 +15067,6 @@ function validateSuspenseListNestedChild(childSlot, index) { index, type ); - return false; } } @@ -13590,7 +15107,8 @@ function validateSuspenseListChildren(children, revealOrder) { } } } else { - error( + warning$1( + false, '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?", @@ -13616,7 +15134,6 @@ function initSuspenseListRenderState( workInProgress.memoizedState = { isBackwards: isBackwards, rendering: null, - renderingStartTime: 0, last: lastContentRow, tail: tail, tailExpiration: 0, @@ -13627,7 +15144,6 @@ function initSuspenseListRenderState( // 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.tailExpiration = 0; @@ -13643,7 +15159,7 @@ function initSuspenseListRenderState( // That happens in the completeWork phase without going back to beginWork. function updateSuspenseListComponent( - current, + current$$1, workInProgress, renderExpirationTime ) { @@ -13654,7 +15170,12 @@ function updateSuspenseListComponent( validateRevealOrder(revealOrder); validateTailOptions(tailMode, revealOrder); validateSuspenseListChildren(newChildren, revealOrder); - reconcileChildren(current, workInProgress, newChildren, renderExpirationTime); + reconcileChildren( + current$$1, + workInProgress, + newChildren, + renderExpirationTime + ); var suspenseContext = suspenseStackCursor.current; var shouldForceFallback = hasSuspenseContext( suspenseContext, @@ -13669,7 +15190,7 @@ function updateSuspenseListComponent( workInProgress.effectTag |= DidCapture; } else { var didSuspendBefore = - current !== null && (current.effectTag & DidCapture) !== NoEffect; + current$$1 !== null && (current$$1.effectTag & DidCapture) !== NoEffect; if (didSuspendBefore) { // If we previously forced a fallback, we need to schedule work @@ -13778,11 +15299,15 @@ function updateSuspenseListComponent( return workInProgress.child; } -function updatePortalComponent(current, workInProgress, renderExpirationTime) { +function updatePortalComponent( + current$$1, + workInProgress, + renderExpirationTime +) { pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); var nextChildren = workInProgress.pendingProps; - if (current === null) { + if (current$$1 === 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 @@ -13796,7 +15321,7 @@ function updatePortalComponent(current, workInProgress, renderExpirationTime) { ); } else { reconcileChildren( - current, + current$$1, workInProgress, nextChildren, renderExpirationTime @@ -13806,7 +15331,11 @@ function updatePortalComponent(current, workInProgress, renderExpirationTime) { return workInProgress.child; } -function updateContextProvider(current, workInProgress, renderExpirationTime) { +function updateContextProvider( + current$$1, + workInProgress, + renderExpirationTime +) { var providerType = workInProgress.type; var context = providerType._context; var newProps = workInProgress.pendingProps; @@ -13817,7 +15346,13 @@ function updateContextProvider(current, workInProgress, renderExpirationTime) { var providerPropTypes = workInProgress.type.propTypes; if (providerPropTypes) { - checkPropTypes(providerPropTypes, newProps, "prop", "Context.Provider"); + checkPropTypes( + providerPropTypes, + newProps, + "prop", + "Context.Provider", + getCurrentFiberStackInDev + ); } } @@ -13831,7 +15366,7 @@ function updateContextProvider(current, workInProgress, renderExpirationTime) { // No change. Bailout early if children are the same. if (oldProps.children === newProps.children && !hasContextChanged()) { return bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -13849,13 +15384,22 @@ function updateContextProvider(current, workInProgress, renderExpirationTime) { } var newChildren = newProps.children; - reconcileChildren(current, workInProgress, newChildren, renderExpirationTime); + reconcileChildren( + current$$1, + workInProgress, + newChildren, + renderExpirationTime + ); return workInProgress.child; } var hasWarnedAboutUsingContextAsConsumer = false; -function updateContextConsumer(current, workInProgress, renderExpirationTime) { +function updateContextConsumer( + current$$1, + workInProgress, + renderExpirationTime +) { 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 @@ -13872,8 +15416,8 @@ function updateContextConsumer(current, workInProgress, renderExpirationTime) { if (context !== context.Consumer) { if (!hasWarnedAboutUsingContextAsConsumer) { hasWarnedAboutUsingContextAsConsumer = true; - - error( + warning$1( + false, "Rendering directly is not supported and will be removed in " + "a future major release. Did you mean to render instead?" ); @@ -13888,14 +15432,15 @@ function updateContextConsumer(current, workInProgress, renderExpirationTime) { 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." - ); - } + !(typeof render === "function") + ? warningWithoutStack$1( + false, + "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." + ) + : void 0; } prepareToReadContext(workInProgress, renderExpirationTime); @@ -13903,14 +15448,57 @@ function updateContextConsumer(current, workInProgress, renderExpirationTime) { var newChildren; { - ReactCurrentOwner$1.current = workInProgress; - setIsRendering(true); + ReactCurrentOwner$3.current = workInProgress; + setCurrentPhase("render"); newChildren = render(newValue); - setIsRendering(false); + setCurrentPhase(null); } // React DevTools reads this flag. workInProgress.effectTag |= PerformedWork; - reconcileChildren(current, workInProgress, newChildren, renderExpirationTime); + reconcileChildren( + current$$1, + workInProgress, + newChildren, + renderExpirationTime + ); + return workInProgress.child; +} + +function updateFundamentalComponent$1( + current$$1, + workInProgress, + renderExpirationTime +) { + var fundamentalImpl = workInProgress.type.impl; + + if (fundamentalImpl.reconcileChildren === false) { + return null; + } + + var nextProps = workInProgress.pendingProps; + var nextChildren = nextProps.children; + reconcileChildren( + current$$1, + workInProgress, + nextChildren, + renderExpirationTime + ); + return workInProgress.child; +} + +function updateScopeComponent( + current$$1, + workInProgress, + renderExpirationTime +) { + var nextProps = workInProgress.pendingProps; + var nextChildren = nextProps.children; + reconcileChildren( + current$$1, + workInProgress, + nextChildren, + renderExpirationTime + ); return workInProgress.child; } @@ -13919,20 +15507,20 @@ function markWorkInProgressReceivedUpdate() { } function bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ) { cancelWorkTimer(workInProgress); - if (current !== null) { + if (current$$1 !== null) { // Reuse previous dependencies - workInProgress.dependencies = current.dependencies; + workInProgress.dependencies = current$$1.dependencies; } - { + if (enableProfilerTimer) { // Don't update "base" render times for bailouts. - stopProfilerTimerIfRunning(); + stopProfilerTimerIfRunning(workInProgress); } var updateExpirationTime = workInProgress.expirationTime; @@ -13951,12 +15539,12 @@ function bailoutOnAlreadyFinishedWork( } else { // This fiber doesn't have work, but its subtree does. Clone the child // fibers and continue. - cloneChildFibers(current, workInProgress); + cloneChildFibers(current$$1, workInProgress); return workInProgress.child; } } -function remountFiber(current, oldWorkInProgress, newWorkInProgress) { +function remountFiber(current$$1, oldWorkInProgress, newWorkInProgress) { { var returnFiber = oldWorkInProgress.return; @@ -13965,7 +15553,7 @@ function remountFiber(current, oldWorkInProgress, newWorkInProgress) { } // Disconnect from the old current. // It will get deleted. - current.alternate = null; + current$$1.alternate = null; oldWorkInProgress.alternate = null; // Connect to the new tree. newWorkInProgress.index = oldWorkInProgress.index; @@ -13997,28 +15585,28 @@ function remountFiber(current, oldWorkInProgress, newWorkInProgress) { var last = returnFiber.lastEffect; if (last !== null) { - last.nextEffect = current; - returnFiber.lastEffect = current; + last.nextEffect = current$$1; + returnFiber.lastEffect = current$$1; } else { - returnFiber.firstEffect = returnFiber.lastEffect = current; + returnFiber.firstEffect = returnFiber.lastEffect = current$$1; } - current.nextEffect = null; - current.effectTag = Deletion; + current$$1.nextEffect = null; + current$$1.effectTag = Deletion; newWorkInProgress.effectTag |= Placement; // Restart work from the new fiber. return newWorkInProgress; } } -function beginWork(current, workInProgress, renderExpirationTime) { +function beginWork$1(current$$1, workInProgress, renderExpirationTime) { var updateExpirationTime = workInProgress.expirationTime; { - if (workInProgress._debugNeedsRemount && current !== null) { + if (workInProgress._debugNeedsRemount && current$$1 !== null) { // This will restart the begin phase with a new fiber. return remountFiber( - current, + current$$1, workInProgress, createFiberFromTypeAndProps( workInProgress.type, @@ -14032,14 +15620,14 @@ function beginWork(current, workInProgress, renderExpirationTime) { } } - if (current !== null) { - var oldProps = current.memoizedProps; + if (current$$1 !== null) { + var oldProps = current$$1.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 + workInProgress.type !== current$$1.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). @@ -14052,6 +15640,7 @@ function beginWork(current, workInProgress, renderExpirationTime) { switch (workInProgress.tag) { case HostRoot: pushHostRootContext(workInProgress); + resetHydrationState(); break; case HostComponent: @@ -14060,9 +15649,9 @@ function beginWork(current, workInProgress, renderExpirationTime) { if ( workInProgress.mode & ConcurrentMode && renderExpirationTime !== Never && - shouldDeprioritizeSubtree(workInProgress.type) + shouldDeprioritizeSubtree(workInProgress.type, newProps) ) { - { + if (enableSchedulerTracing) { markSpawnedWork(Never); } // Schedule this fiber to re-render at offscreen priority. Then bailout. @@ -14096,19 +15685,14 @@ function beginWork(current, workInProgress, renderExpirationTime) { } case Profiler: - { + if (enableProfilerTimer) { // Profiler should only call onRender when one of its descendants actually rendered. var hasChildWork = workInProgress.childExpirationTime >= renderExpirationTime; if (hasChildWork) { workInProgress.effectTag |= 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; @@ -14117,6 +15701,19 @@ function beginWork(current, workInProgress, renderExpirationTime) { var state = workInProgress.memoizedState; if (state !== null) { + if (enableSuspenseServerRenderer) { + if (state.dehydrated !== null) { + pushSuspenseContext( + workInProgress, + setDefaultShallowSuspenseContext(suspenseStackCursor.current) + ); // We know that this component will suspend again because if it has + // been unsuspended it has committed as a resolved Suspense component. + // If it needs to be retried, it should have work scheduled on it. + + workInProgress.effectTag |= DidCapture; + break; + } + } // If this boundary is currently timed out, we need to decide // 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. @@ -14132,7 +15729,7 @@ function beginWork(current, workInProgress, renderExpirationTime) { // The primary children have pending work. Use the normal path // to attempt to render the primary children again. return updateSuspenseComponent( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -14144,7 +15741,7 @@ function beginWork(current, workInProgress, renderExpirationTime) { // priority. Bailout. var child = bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -14168,7 +15765,8 @@ function beginWork(current, workInProgress, renderExpirationTime) { } case SuspenseListComponent: { - var didSuspendBefore = (current.effectTag & DidCapture) !== NoEffect; + var didSuspendBefore = + (current$$1.effectTag & DidCapture) !== NoEffect; var _hasChildWork = workInProgress.childExpirationTime >= renderExpirationTime; @@ -14181,7 +15779,7 @@ function beginWork(current, workInProgress, renderExpirationTime) { // tree which will affect the tail. So we need to use the normal // path to compute the correct tail. return updateSuspenseListComponent( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -14217,7 +15815,7 @@ function beginWork(current, workInProgress, renderExpirationTime) { } return bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -14230,18 +15828,14 @@ function beginWork(current, workInProgress, renderExpirationTime) { } } 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. + } // Before entering the begin phase, clear the expiration time. workInProgress.expirationTime = NoWork; switch (workInProgress.tag) { case IndeterminateComponent: { return mountIndeterminateComponent( - current, + current$$1, workInProgress, workInProgress.type, renderExpirationTime @@ -14251,7 +15845,7 @@ function beginWork(current, workInProgress, renderExpirationTime) { case LazyComponent: { var elementType = workInProgress.elementType; return mountLazyComponent( - current, + current$$1, workInProgress, elementType, updateExpirationTime, @@ -14267,7 +15861,7 @@ function beginWork(current, workInProgress, renderExpirationTime) { ? unresolvedProps : resolveDefaultProps(_Component, unresolvedProps); return updateFunctionComponent( - current, + current$$1, workInProgress, _Component, resolvedProps, @@ -14285,7 +15879,7 @@ function beginWork(current, workInProgress, renderExpirationTime) { : resolveDefaultProps(_Component2, _unresolvedProps); return updateClassComponent( - current, + current$$1, workInProgress, _Component2, _resolvedProps, @@ -14294,24 +15888,28 @@ function beginWork(current, workInProgress, renderExpirationTime) { } case HostRoot: - return updateHostRoot(current, workInProgress, renderExpirationTime); + return updateHostRoot(current$$1, workInProgress, renderExpirationTime); case HostComponent: - return updateHostComponent(current, workInProgress, renderExpirationTime); + return updateHostComponent( + current$$1, + workInProgress, + renderExpirationTime + ); case HostText: - return updateHostText(); + return updateHostText(current$$1, workInProgress); case SuspenseComponent: return updateSuspenseComponent( - current, + current$$1, workInProgress, renderExpirationTime ); case HostPortal: return updatePortalComponent( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -14326,7 +15924,7 @@ function beginWork(current, workInProgress, renderExpirationTime) { : resolveDefaultProps(type, _unresolvedProps2); return updateForwardRef( - current, + current$$1, workInProgress, type, _resolvedProps2, @@ -14335,24 +15933,24 @@ function beginWork(current, workInProgress, renderExpirationTime) { } case Fragment: - return updateFragment(current, workInProgress, renderExpirationTime); + return updateFragment(current$$1, workInProgress, renderExpirationTime); case Mode: - return updateMode(current, workInProgress, renderExpirationTime); + return updateMode(current$$1, workInProgress, renderExpirationTime); case Profiler: - return updateProfiler(current, workInProgress, renderExpirationTime); + return updateProfiler(current$$1, workInProgress, renderExpirationTime); case ContextProvider: return updateContextProvider( - current, + current$$1, workInProgress, renderExpirationTime ); case ContextConsumer: return updateContextConsumer( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -14372,7 +15970,8 @@ function beginWork(current, workInProgress, renderExpirationTime) { outerPropTypes, _resolvedProps3, // Resolved for outer only "prop", - getComponentName(_type2) + getComponentName(_type2), + getCurrentFiberStackInDev ); } } @@ -14380,7 +15979,7 @@ function beginWork(current, workInProgress, renderExpirationTime) { _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3); return updateMemoComponent( - current, + current$$1, workInProgress, _type2, _resolvedProps3, @@ -14389,51 +15988,307 @@ function beginWork(current, workInProgress, renderExpirationTime) { ); } - case SimpleMemoComponent: { - return updateSimpleMemoComponent( - current, - workInProgress, - workInProgress.type, - workInProgress.pendingProps, - updateExpirationTime, - renderExpirationTime - ); - } + case SimpleMemoComponent: { + return updateSimpleMemoComponent( + current$$1, + workInProgress, + workInProgress.type, + workInProgress.pendingProps, + updateExpirationTime, + renderExpirationTime + ); + } + + case IncompleteClassComponent: { + var _Component3 = workInProgress.type; + var _unresolvedProps4 = workInProgress.pendingProps; + + var _resolvedProps4 = + workInProgress.elementType === _Component3 + ? _unresolvedProps4 + : resolveDefaultProps(_Component3, _unresolvedProps4); + + return mountIncompleteClassComponent( + current$$1, + workInProgress, + _Component3, + _resolvedProps4, + renderExpirationTime + ); + } + + case SuspenseListComponent: { + return updateSuspenseListComponent( + current$$1, + workInProgress, + renderExpirationTime + ); + } + + case FundamentalComponent: { + if (enableFundamentalAPI) { + return updateFundamentalComponent$1( + current$$1, + workInProgress, + renderExpirationTime + ); + } + + break; + } + + case ScopeComponent: { + if (enableScopeAPI) { + return updateScopeComponent( + current$$1, + workInProgress, + renderExpirationTime + ); + } + + 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 createFundamentalStateInstance(currentFiber, props, impl, state) { + return { + currentFiber: currentFiber, + impl: impl, + instance: null, + prevProps: null, + props: props, + state: state + }; +} + +function isFiberSuspenseAndTimedOut(fiber) { + return fiber.tag === SuspenseComponent && fiber.memoizedState !== null; +} + +function getSuspenseFallbackChild(fiber) { + return fiber.child.sibling.child; +} + +var emptyObject$2 = {}; + +function collectScopedNodes(node, fn, scopedNodes) { + if (enableScopeAPI) { + if (node.tag === HostComponent) { + var _type = node.type, + memoizedProps = node.memoizedProps, + stateNode = node.stateNode; + + var _instance = getPublicInstance(stateNode); + + if ( + _instance !== null && + fn(_type, memoizedProps || emptyObject$2, _instance) === true + ) { + scopedNodes.push(_instance); + } + } + + var child = node.child; + + if (isFiberSuspenseAndTimedOut(node)) { + child = getSuspenseFallbackChild(node); + } + + if (child !== null) { + collectScopedNodesFromChildren(child, fn, scopedNodes); + } + } +} + +function collectFirstScopedNode(node, fn) { + if (enableScopeAPI) { + if (node.tag === HostComponent) { + var _type2 = node.type, + memoizedProps = node.memoizedProps, + stateNode = node.stateNode; + + var _instance2 = getPublicInstance(stateNode); + + if ( + _instance2 !== null && + fn(_type2, memoizedProps, _instance2) === true + ) { + return _instance2; + } + } + + var child = node.child; + + if (isFiberSuspenseAndTimedOut(node)) { + child = getSuspenseFallbackChild(node); + } + + if (child !== null) { + return collectFirstScopedNodeFromChildren(child, fn); + } + } + + return null; +} + +function collectScopedNodesFromChildren(startingChild, fn, scopedNodes) { + var child = startingChild; + + while (child !== null) { + collectScopedNodes(child, fn, scopedNodes); + child = child.sibling; + } +} + +function collectFirstScopedNodeFromChildren(startingChild, fn) { + var child = startingChild; + + while (child !== null) { + var scopedNode = collectFirstScopedNode(child, fn); + + if (scopedNode !== null) { + return scopedNode; + } + + child = child.sibling; + } + + return null; +} + +function collectNearestScopeMethods(node, scope, childrenScopes) { + if (isValidScopeNode(node, scope)) { + childrenScopes.push(node.stateNode.methods); + } else { + var child = node.child; + + if (isFiberSuspenseAndTimedOut(node)) { + child = getSuspenseFallbackChild(node); + } + + if (child !== null) { + collectNearestChildScopeMethods(child, scope, childrenScopes); + } + } +} + +function collectNearestChildScopeMethods(startingChild, scope, childrenScopes) { + var child = startingChild; + + while (child !== null) { + collectNearestScopeMethods(child, scope, childrenScopes); + child = child.sibling; + } +} + +function isValidScopeNode(node, scope) { + return ( + node.tag === ScopeComponent && + node.type === scope && + node.stateNode !== null + ); +} + +function createScopeMethods(scope, instance) { + return { + getChildren: function() { + var currentFiber = instance.fiber; + var child = currentFiber.child; + var childrenScopes = []; + + if (child !== null) { + collectNearestChildScopeMethods(child, scope, childrenScopes); + } + + return childrenScopes.length === 0 ? null : childrenScopes; + }, + getChildrenFromRoot: function() { + var currentFiber = instance.fiber; + var node = currentFiber; + + while (node !== null) { + var parent = node.return; + + if (parent === null) { + break; + } + + node = parent; + + if (node.tag === ScopeComponent && node.type === scope) { + break; + } + } + + var childrenScopes = []; + collectNearestChildScopeMethods(node.child, scope, childrenScopes); + return childrenScopes.length === 0 ? null : childrenScopes; + }, + getParent: function() { + var node = instance.fiber.return; + + while (node !== null) { + if (node.tag === ScopeComponent && node.type === scope) { + return node.stateNode.methods; + } + + node = node.return; + } + + return null; + }, + getProps: function() { + var currentFiber = instance.fiber; + return currentFiber.memoizedProps; + }, + queryAllNodes: function(fn) { + var currentFiber = instance.fiber; + var child = currentFiber.child; + var scopedNodes = []; - case IncompleteClassComponent: { - var _Component3 = workInProgress.type; - var _unresolvedProps4 = workInProgress.pendingProps; + if (child !== null) { + collectScopedNodesFromChildren(child, fn, scopedNodes); + } - var _resolvedProps4 = - workInProgress.elementType === _Component3 - ? _unresolvedProps4 - : resolveDefaultProps(_Component3, _unresolvedProps4); + return scopedNodes.length === 0 ? null : scopedNodes; + }, + queryFirstNode: function(fn) { + var currentFiber = instance.fiber; + var child = currentFiber.child; - return mountIncompleteClassComponent( - current, - workInProgress, - _Component3, - _resolvedProps4, - renderExpirationTime - ); - } + if (child !== null) { + return collectFirstScopedNodeFromChildren(child, fn); + } - case SuspenseListComponent: { - return updateSuspenseListComponent( - current, - workInProgress, - renderExpirationTime - ); - } - } + return null; + }, + containsNode: function(node) { + var fiber = getInstanceFromNode$1(node); - { - throw Error( - "Unknown unit of work tag (" + - workInProgress.tag + - "). This error is likely caused by a bug in React. Please file an issue." - ); - } + while (fiber !== null) { + if ( + fiber.tag === ScopeComponent && + fiber.type === scope && + fiber.stateNode === instance + ) { + return true; + } + + fiber = fiber.return; + } + + return false; + } + }; } function markUpdate(workInProgress) { @@ -14451,7 +16306,7 @@ var updateHostContainer; var updateHostComponent$1; var updateHostText$1; -{ +if (supportsMutation) { // Mutation mode appendAllChildren = function( parent, @@ -14466,8 +16321,13 @@ var updateHostText$1; while (node !== null) { if (node.tag === HostComponent || node.tag === HostText) { appendInitialChild(parent, node.stateNode); - } else if (node.tag === HostPortal); - else if (node.child !== null) { + } else if (enableFundamentalAPI && node.tag === FundamentalComponent) { + appendInitialChild(parent, node.stateNode.instance); + } else if (node.tag === HostPortal) { + // If we have a portal child, then we don't want to traverse + // down its children. Instead, we'll get insertions from each child in + // the portal directly. + } else if (node.child !== null) { node.child.return = node; node = node.child; continue; @@ -14519,7 +16379,14 @@ var updateHostText$1; // component is hitting the resume path. Figure out why. Possibly // related to `hidden`. - var updatePayload = prepareUpdate(); // TODO: Type this specific to this type of component. + var updatePayload = prepareUpdate( + instance, + type, + oldProps, + newProps, + rootContainerInstance, + currentHostContext + ); // TODO: Type this specific to this type of component. 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. @@ -14535,6 +16402,357 @@ var updateHostText$1; markUpdate(workInProgress); } }; +} else if (supportsPersistence) { + // 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 + branches: 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, type, props, node); + } + + 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(_instance, text, node); + } + + appendInitialChild(parent, _instance); + } else if (enableFundamentalAPI && node.tag === FundamentalComponent) { + var _instance2 = node.stateNode.instance; + + if (needsVisibilityToggle && isHidden) { + // This child is inside a timed out tree. Hide it. + var _props = node.memoizedProps; + var _type = node.type; + _instance2 = cloneHiddenInstance(_instance2, _type, _props, node); + } + + appendInitialChild(parent, _instance2); + } else if (node.tag === HostPortal) { + // If we have a portal child, then we don't want to traverse + // down its children. Instead, we'll get insertions from each child in + // the portal directly. + } else if (node.tag === SuspenseComponent) { + if ((node.effectTag & Update) !== NoEffect) { + // 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; + + if (fallbackChildParent !== null) { + fallbackChildParent.return = node; + node = fallbackChildParent; + continue; + } + } + } + } + + 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; + } + + while (node.sibling === null) { + if (node.return === null || node.return === workInProgress) { + return; + } + + node = node.return; + } + + 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; + + while (node !== null) { + // eslint-disable-next-line no-labels + branches: 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, type, props, node); + } + + 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(_instance3, text, node); + } + + appendChildToContainerChildSet(containerChildSet, _instance3); + } else if (enableFundamentalAPI && node.tag === FundamentalComponent) { + var _instance4 = node.stateNode.instance; + + if (needsVisibilityToggle && isHidden) { + // This child is inside a timed out tree. Hide it. + var _props2 = node.memoizedProps; + var _type2 = node.type; + _instance4 = cloneHiddenInstance(_instance4, _type2, _props2, node); + } + + appendChildToContainerChildSet(containerChildSet, _instance4); + } else if (node.tag === HostPortal) { + // If we have a portal child, then we don't want to traverse + // down its children. Instead, we'll get insertions from each child in + // the portal directly. + } else if (node.tag === SuspenseComponent) { + if ((node.effectTag & Update) !== NoEffect) { + // 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; + appendAllChildrenToContainer( + containerChildSet, + primaryChildParent, + true, + newIsHidden + ); + } + + var fallbackChildParent = primaryChildParent.sibling; + + if (fallbackChildParent !== null) { + fallbackChildParent.return = node; + node = fallbackChildParent; + continue; + } + } + } + } + + 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; + } + + while (node.sibling === null) { + if (node.return === null || node.return === workInProgress) { + return; + } + + node = node.return; + } + + node.sibling.return = node.return; + node = node.sibling; + } + }; + + updateHostContainer = function(workInProgress) { + var portalOrRoot = workInProgress.stateNode; + var childrenUnchanged = workInProgress.firstEffect === null; + + if (childrenUnchanged) { + // No changes, just reuse the existing instance. + } 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); + } + }; + + 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 childrenUnchanged = workInProgress.firstEffect === null; + + if (childrenUnchanged && oldProps === newProps) { + // No changes, just reuse the existing instance. + // Note that this might release a previous clone. + workInProgress.stateNode = currentInstance; + return; + } + + var recyclableInstance = workInProgress.stateNode; + var currentHostContext = getHostContext(); + var updatePayload = null; + + if (oldProps !== newProps) { + updatePayload = prepareUpdate( + recyclableInstance, + type, + oldProps, + newProps, + rootContainerInstance, + currentHostContext + ); + } + + if (childrenUnchanged && updatePayload === null) { + // No changes, just reuse the existing instance. + // Note that this might release a previous clone. + workInProgress.stateNode = currentInstance; + return; + } + + var newInstance = cloneInstance( + currentInstance, + updatePayload, + type, + oldProps, + newProps, + workInProgress, + childrenUnchanged, + recyclableInstance + ); + + if ( + finalizeInitialChildren( + newInstance, + type, + newProps, + rootContainerInstance, + currentHostContext + ) + ) { + markUpdate(workInProgress); + } + + workInProgress.stateNode = newInstance; + + if (childrenUnchanged) { + // If there are no other effects in this tree, we need to flag this node as having one. + // Even though we're not going to use it for anything. + // Otherwise parents won't know that there are new children to propagate upwards. + markUpdate(workInProgress); + } else { + // If children might have changed, we have to add them all to the set. + appendAllChildren(newInstance, workInProgress, false, false); + } + }; + + 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. + + markUpdate(workInProgress); + } + }; +} else { + // No host operations + updateHostContainer = function(workInProgress) { + // Noop + }; + + updateHostComponent$1 = function( + current, + workInProgress, + type, + newProps, + rootContainerInstance + ) { + // Noop + }; + + updateHostText$1 = function(current, workInProgress, oldText, newText) { + // Noop + }; } function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { @@ -14612,16 +16830,14 @@ function completeWork(current, workInProgress, renderExpirationTime) { 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; + break; + + case LazyComponent: + break; + + case SimpleMemoComponent: + case FunctionComponent: + break; case ClassComponent: { var Component = workInProgress.type; @@ -14630,7 +16846,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { popContext(workInProgress); } - return null; + break; } case HostRoot: { @@ -14646,7 +16862,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { 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(); + var wasHydrated = popHydrationState(workInProgress); if (wasHydrated) { // If we hydrated, then we'll need to schedule an update for @@ -14656,7 +16872,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { } updateHostContainer(workInProgress); - return null; + break; } case HostComponent: { @@ -14673,6 +16889,15 @@ function completeWork(current, workInProgress, renderExpirationTime) { rootContainerInstance ); + if (enableFlareAPI) { + var prevListeners = current.memoizedProps.listeners; + var nextListeners = newProps.listeners; + + if (prevListeners !== nextListeners) { + markUpdate(workInProgress); + } + } + if (current.ref !== workInProgress.ref) { markRef$1(workInProgress); } @@ -14684,24 +16909,42 @@ function completeWork(current, workInProgress, renderExpirationTime) { ); } // This can happen when we abort work. - 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 + // or completeWork depending on we want to add then top->down or // bottom->up. Top->down is faster in IE11. - var _wasHydrated = popHydrationState(); + var _wasHydrated = popHydrationState(workInProgress); 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 + if ( + prepareToHydrateHostInstance( + workInProgress, + rootContainerInstance, + currentHostContext + ) + ) { + // If changes to the hydrated node needs to be applied at the // commit-phase we mark this as such. markUpdate(workInProgress); } + + if (enableFlareAPI) { + var listeners = newProps.listeners; + + if (listeners != null) { + updateEventListeners( + listeners, + workInProgress, + rootContainerInstance + ); + } + } } else { var instance = createInstance( type, @@ -14713,10 +16956,30 @@ function completeWork(current, workInProgress, renderExpirationTime) { appendAllChildren(instance, workInProgress, false, false); // This needs to be set before we mount Flare event listeners workInProgress.stateNode = instance; + + if (enableFlareAPI) { + var _listeners = newProps.listeners; + + if (_listeners != null) { + updateEventListeners( + _listeners, + workInProgress, + rootContainerInstance + ); + } + } // Certain renderers require commit-time effects for initial mount. // (eg DOM renderer supports auto-focus for certain elements). // Make sure such renderers get scheduled for later work. - if (finalizeInitialChildren(instance)) { + if ( + finalizeInitialChildren( + instance, + type, + newProps, + rootContainerInstance, + currentHostContext + ) + ) { markUpdate(workInProgress); } } @@ -14727,7 +16990,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { } } - return null; + break; } case HostText: { @@ -14751,10 +17014,10 @@ function completeWork(current, workInProgress, renderExpirationTime) { var _currentHostContext = getHostContext(); - var _wasHydrated2 = popHydrationState(); + var _wasHydrated2 = popHydrationState(workInProgress); if (_wasHydrated2) { - if (prepareToHydrateHostTextInstance()) { + if (prepareToHydrateHostTextInstance(workInProgress)) { markUpdate(workInProgress); } } else { @@ -14767,13 +17030,56 @@ function completeWork(current, workInProgress, renderExpirationTime) { } } - return null; + break; } + case ForwardRef: + break; + case SuspenseComponent: { popSuspenseContext(workInProgress); var nextState = workInProgress.memoizedState; + if (enableSuspenseServerRenderer) { + if (nextState !== null && nextState.dehydrated !== null) { + if (current === null) { + var _wasHydrated3 = popHydrationState(workInProgress); + + if (!_wasHydrated3) { + throw Error( + "A dehydrated suspense component was completed without a hydrated node. This is probably a bug in React." + ); + } + + prepareToHydrateHostSuspenseInstance(workInProgress); + + if (enableSchedulerTracing) { + markSpawnedWork(Never); + } + + return null; + } else { + // We should never have been in a hydration state if we didn't have a current. + // However, in some of those paths, we might have reentered a hydration state + // and then we might be inside a hydration state. In that case, we'll need to + // exit out of it. + resetHydrationState(); + + if ((workInProgress.effectTag & DidCapture) === NoEffect) { + // This boundary did not suspend so it's now hydrated and unsuspended. + workInProgress.memoizedState = null; + } // If nothing suspended, we need to schedule an effect to mark this boundary + // as having hydrated so events know that they're free be invoked. + // It's also a signal to replay events and the suspense callback. + // If something suspended, schedule an effect to attach retry listeners. + // So we might as well always mark this. + + workInProgress.effectTag |= Update; + return null; + } + } + } + if ((workInProgress.effectTag & DidCapture) !== NoEffect) { // Something suspended. Re-render with the fallback children. workInProgress.expirationTime = renderExpirationTime; // Do not reset the effect list. @@ -14785,7 +17091,9 @@ function completeWork(current, workInProgress, renderExpirationTime) { var prevDidTimeout = false; if (current === null) { - if (workInProgress.memoizedProps.fallback !== undefined); + if (workInProgress.memoizedProps.fallback !== undefined) { + popHydrationState(workInProgress); + } } else { var prevState = current.memoizedState; prevDidTimeout = prevState !== null; @@ -14850,30 +17158,64 @@ function completeWork(current, workInProgress, renderExpirationTime) { } } - { + if (supportsPersistence) { + // 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 proimse. This flag is also used to hide the + // primary children. + workInProgress.effectTag |= Update; + } + } + + if (supportsMutation) { // 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 + // retry listener to the proimse. 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 + // *unhide* children that were previously hidden, so check if the // is currently timed out, too. workInProgress.effectTag |= Update; } } - return null; + if ( + enableSuspenseCallback && + workInProgress.updateQueue !== null && + workInProgress.memoizedProps.suspenseCallback != null + ) { + // Always notify the callback + workInProgress.effectTag |= Update; + } + + break; } + case Fragment: + break; + + case Mode: + break; + + case Profiler: + break; + case HostPortal: popHostContainer(workInProgress); updateHostContainer(workInProgress); - return null; + break; case ContextProvider: // Pop provider fiber popProvider(workInProgress); - return null; + break; + + case ContextConsumer: + break; + + case MemoComponent: + break; case IncompleteClassComponent: { // Same as class component case. I put it down here so that the tags are @@ -14884,7 +17226,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { popContext(workInProgress); } - return null; + break; } case SuspenseListComponent: { @@ -14892,9 +17234,9 @@ function completeWork(current, workInProgress, renderExpirationTime) { 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; + // We're running in the default, "independent" mode. We don't do anything + // in this mode. + break; } var didSuspendAlready = @@ -15010,10 +17352,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { return null; } } else if ( - // The time it took to render last row is greater than time until - // the expiration. - now() * 2 - renderState.renderingStartTime > - renderState.tailExpiration && + now() > renderState.tailExpiration && renderExpirationTime > Never ) { // We have now passed our CPU deadline and we'll just give up further @@ -15030,7 +17369,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { var nextPriority = renderExpirationTime - 1; workInProgress.expirationTime = workInProgress.childExpirationTime = nextPriority; - { + if (enableSchedulerTracing) { markSpawnedWork(nextPriority); } } @@ -15063,19 +17402,13 @@ function completeWork(current, workInProgress, renderExpirationTime) { // Heuristic for how long we're willing to spend rendering rows // until we just give up and show what we have so far. var TAIL_EXPIRATION_TIMEOUT_MS = 500; - renderState.tailExpiration = now() + TAIL_EXPIRATION_TIMEOUT_MS; // TODO: This is meant to mimic the train model or JND but this - // is a per component value. It should really be since the start - // of the total render or last commit. Consider using something like - // globalMostRecentFallbackTime. That doesn't account for being - // suspended for part of the time or when it's a new render. - // It should probably use a global start time value instead. + renderState.tailExpiration = now() + TAIL_EXPIRATION_TIMEOUT_MS; } // 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. @@ -15096,17 +17429,131 @@ function completeWork(current, workInProgress, renderExpirationTime) { return next; } - 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." - ); + case FundamentalComponent: { + if (enableFundamentalAPI) { + var fundamentalImpl = workInProgress.type.impl; + var fundamentalInstance = workInProgress.stateNode; + + if (fundamentalInstance === null) { + var getInitialState = fundamentalImpl.getInitialState; + var fundamentalState; + + if (getInitialState !== undefined) { + fundamentalState = getInitialState(newProps); + } + + fundamentalInstance = workInProgress.stateNode = createFundamentalStateInstance( + workInProgress, + newProps, + fundamentalImpl, + fundamentalState || {} + ); + + var _instance5 = getFundamentalComponentInstance(fundamentalInstance); + + fundamentalInstance.instance = _instance5; + + if (fundamentalImpl.reconcileChildren === false) { + return null; + } + + appendAllChildren(_instance5, workInProgress, false, false); + mountFundamentalComponent(fundamentalInstance); + } else { + // We fire update in commit phase + var prevProps = fundamentalInstance.props; + fundamentalInstance.prevProps = prevProps; + fundamentalInstance.props = newProps; + fundamentalInstance.currentFiber = workInProgress; + + if (supportsPersistence) { + var _instance6 = cloneFundamentalInstance(fundamentalInstance); + + fundamentalInstance.instance = _instance6; + appendAllChildren(_instance6, workInProgress, false, false); + } + + var shouldUpdate = shouldUpdateFundamentalComponent( + fundamentalInstance + ); + + if (shouldUpdate) { + markUpdate(workInProgress); + } + } + } + + break; + } + + case ScopeComponent: { + if (enableScopeAPI) { + if (current === null) { + var _type3 = workInProgress.type; + var scopeInstance = { + fiber: workInProgress, + methods: null + }; + workInProgress.stateNode = scopeInstance; + scopeInstance.methods = createScopeMethods(_type3, scopeInstance); + + if (enableFlareAPI) { + var _listeners2 = newProps.listeners; + + if (_listeners2 != null) { + var _rootContainerInstance2 = getRootHostContainer(); + + updateEventListeners( + _listeners2, + workInProgress, + _rootContainerInstance2 + ); + } + } + + if (workInProgress.ref !== null) { + markRef$1(workInProgress); + markUpdate(workInProgress); + } + } else { + if (enableFlareAPI) { + var _prevListeners = current.memoizedProps.listeners; + var _nextListeners = newProps.listeners; + + if ( + _prevListeners !== _nextListeners || + workInProgress.ref !== null + ) { + markUpdate(workInProgress); + } + } else { + if (workInProgress.ref !== null) { + markUpdate(workInProgress); + } + } + + if (current.ref !== workInProgress.ref) { + markRef$1(workInProgress); + } + } + } + + break; + } + + default: { + throw Error( + "Unknown unit of work tag (" + + workInProgress.tag + + "). This error is likely caused by a bug in React. Please file an issue." + ); + } } + + return null; } function unwindWork(workInProgress, renderExpirationTime) { @@ -15152,6 +17599,20 @@ function unwindWork(workInProgress, renderExpirationTime) { case SuspenseComponent: { popSuspenseContext(workInProgress); + if (enableSuspenseServerRenderer) { + var suspenseState = workInProgress.memoizedState; + + if (suspenseState !== null && suspenseState.dehydrated !== null) { + if (!(workInProgress.alternate !== null)) { + throw Error( + "Threw in newly mounted dehydrated component. This is likely a bug in React. Please file an issue." + ); + } + + resetHydrationState(); + } + } + var _effectTag2 = workInProgress.effectTag; if (_effectTag2 & ShouldCapture) { @@ -15221,6 +17682,9 @@ function unwindInterruptedWork(interruptedWork) { case ContextProvider: popProvider(interruptedWork); break; + + default: + break; } } @@ -15235,7 +17699,6 @@ function createCapturedValue(value, source) { } // Module provided by RN: - if ( !( typeof ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog === @@ -15283,8 +17746,7 @@ function logCapturedError(capturedError) { // However, the browser would have silenced the original error // so we'll print it first, and then print the stack addendum. - console["error"](error); // Don't transform to our wrapper - // For a more detailed description of this block, see: + console.error(error); // For a more detailed description of this block, see: // https://github.com/facebook/react/pull/13384 } @@ -15321,7 +17783,7 @@ function logCapturedError(capturedError) { // 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 + console.error(combinedMessage); } } @@ -15370,37 +17832,33 @@ function logError(boundary, errorInfo) { } } -var callComponentWillUnmountWithTimer = function(current, instance) { - startPhaseTimer(current, "componentWillUnmount"); - instance.props = current.memoizedProps; - instance.state = current.memoizedState; - - { - instance.componentWillUnmount(); - } - +var callComponentWillUnmountWithTimer = function(current$$1, instance) { + startPhaseTimer(current$$1, "componentWillUnmount"); + instance.props = current$$1.memoizedProps; + instance.state = current$$1.memoizedState; + instance.componentWillUnmount(); stopPhaseTimer(); }; // Capture errors so they don't interrupt unmounting. -function safelyCallComponentWillUnmount(current, instance) { +function safelyCallComponentWillUnmount(current$$1, instance) { { invokeGuardedCallback( null, callComponentWillUnmountWithTimer, null, - current, + current$$1, instance ); if (hasCaughtError()) { var unmountError = clearCaughtError(); - captureCommitPhaseError(current, unmountError); + captureCommitPhaseError(current$$1, unmountError); } } } -function safelyDetachRef(current) { - var ref = current.ref; +function safelyDetachRef(current$$1) { + var ref = current$$1.ref; if (ref !== null) { if (typeof ref === "function") { @@ -15409,7 +17867,7 @@ function safelyDetachRef(current) { if (hasCaughtError()) { var refError = clearCaughtError(); - captureCommitPhaseError(current, refError); + captureCommitPhaseError(current$$1, refError); } } } else { @@ -15418,31 +17876,31 @@ function safelyDetachRef(current) { } } -function safelyCallDestroy(current, destroy) { +function safelyCallDestroy(current$$1, destroy) { { invokeGuardedCallback(null, destroy, null); if (hasCaughtError()) { var error = clearCaughtError(); - captureCommitPhaseError(current, error); + captureCommitPhaseError(current$$1, error); } } } -function commitBeforeMutationLifeCycles(current, finishedWork) { +function commitBeforeMutationLifeCycles(current$$1, finishedWork) { switch (finishedWork.tag) { case FunctionComponent: case ForwardRef: - case SimpleMemoComponent: - case Block: { + case SimpleMemoComponent: { + commitHookEffectList(UnmountSnapshot, NoEffect$1, finishedWork); return; } case ClassComponent: { if (finishedWork.effectTag & Snapshot) { - if (current !== null) { - var prevProps = current.memoizedProps; - var prevState = current.memoizedState; + if (current$$1 !== null) { + var prevProps = current$$1.memoizedProps; + var prevState = current$$1.memoizedState; startPhaseTimer(finishedWork, "getSnapshotBeforeUpdate"); var instance = finishedWork.stateNode; // We could update instance props and state here, // but instead we rely on them being set during last render. @@ -15453,27 +17911,28 @@ function commitBeforeMutationLifeCycles(current, finishedWork) { 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 (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" - ); - } + !(instance.props === finishedWork.memoizedProps) + ? warning$1( + false, + "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" + ) + : void 0; + !(instance.state === finishedWork.memoizedState) + ? warning$1( + false, + "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.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ) + : void 0; } } @@ -15489,8 +17948,8 @@ function commitBeforeMutationLifeCycles(current, finishedWork) { if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) { didWarnSet.add(finishedWork.type); - - error( + warningWithoutStack$1( + false, "%s.getSnapshotBeforeUpdate(): A snapshot value (or null) " + "must be returned. You have returned undefined.", getComponentName(finishedWork.type) @@ -15513,16 +17972,18 @@ function commitBeforeMutationLifeCycles(current, finishedWork) { 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." - ); + 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." + ); + } + } } } -function commitHookEffectListUnmount(tag, finishedWork) { +function commitHookEffectList(unmountTag, mountTag, finishedWork) { var updateQueue = finishedWork.updateQueue; var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; @@ -15531,7 +17992,7 @@ function commitHookEffectListUnmount(tag, finishedWork) { var effect = firstEffect; do { - if ((effect.tag & tag) === tag) { + if ((effect.tag & unmountTag) !== NoEffect$1) { // Unmount var destroy = effect.destroy; effect.destroy = undefined; @@ -15541,36 +18002,22 @@ function commitHookEffectListUnmount(tag, finishedWork) { } } - effect = effect.next; - } while (effect !== firstEffect); - } -} - -function commitHookEffectListMount(tag, finishedWork) { - var updateQueue = finishedWork.updateQueue; - var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; - - if (lastEffect !== null) { - var firstEffect = lastEffect.next; - var effect = firstEffect; - - do { - if ((effect.tag & tag) === tag) { + if ((effect.tag & mountTag) !== NoEffect$1) { // Mount var create = effect.create; effect.destroy = create(); { - var destroy = effect.destroy; + var _destroy = effect.destroy; - if (destroy !== undefined && typeof destroy !== "function") { + if (_destroy !== undefined && typeof _destroy !== "function") { var addendum = void 0; - if (destroy === null) { + 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") { + } 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 " + @@ -15585,10 +18032,11 @@ function commitHookEffectListMount(tag, finishedWork) { "}, [someId]); // Or [] if effect doesn't need props or state\n\n" + "Learn more about data fetching with Hooks: https://fb.me/react-hooks-data-fetching"; } else { - addendum = " You returned: " + destroy; + addendum = " You returned: " + _destroy; } - error( + warningWithoutStack$1( + false, "An effect function must not return anything besides a function, " + "which is used for clean-up.%s%s", addendum, @@ -15608,49 +18056,37 @@ function commitPassiveHookEffects(finishedWork) { switch (finishedWork.tag) { case FunctionComponent: case ForwardRef: - case SimpleMemoComponent: - case Block: { - // TODO (#17945) We should call all passive destroy functions (for all fibers) - // before calling any create functions. The current approach only serializes - // these for a single fiber. - { - commitHookEffectListUnmount(Passive$1 | HasEffect, finishedWork); - commitHookEffectListMount(Passive$1 | HasEffect, finishedWork); - } - + case SimpleMemoComponent: { + commitHookEffectList(UnmountPassive, NoEffect$1, finishedWork); + commitHookEffectList(NoEffect$1, MountPassive, finishedWork); break; } + + default: + break; } } } function commitLifeCycles( finishedRoot, - current, + current$$1, finishedWork, committedExpirationTime ) { switch (finishedWork.tag) { case FunctionComponent: case ForwardRef: - case SimpleMemoComponent: - case Block: { - // 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); - } - - return; + case SimpleMemoComponent: { + commitHookEffectList(UnmountLayout, MountLayout, finishedWork); + break; } case ClassComponent: { var instance = finishedWork.stateNode; if (finishedWork.effectTag & Update) { - if (current === null) { + if (current$$1 === null) { startPhaseTimer(finishedWork, "componentDidMount"); // 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. @@ -15660,41 +18096,42 @@ function commitLifeCycles( 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.props === finishedWork.memoizedProps) + ? warning$1( + false, + "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" + ) + : void 0; + !(instance.state === finishedWork.memoizedState) + ? warning$1( + false, + "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.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ) + : void 0; } } - { - instance.componentDidMount(); - } - + instance.componentDidMount(); stopPhaseTimer(); } else { var prevProps = finishedWork.elementType === finishedWork.type - ? current.memoizedProps - : resolveDefaultProps(finishedWork.type, current.memoizedProps); - var prevState = current.memoizedState; + ? current$$1.memoizedProps + : resolveDefaultProps( + finishedWork.type, + current$$1.memoizedProps + ); + var prevState = current$$1.memoizedState; startPhaseTimer(finishedWork, "componentDidUpdate"); // 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. @@ -15704,38 +18141,36 @@ function commitLifeCycles( 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.props === finishedWork.memoizedProps) + ? warning$1( + false, + "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" + ) + : void 0; + !(instance.state === finishedWork.memoizedState) + ? warning$1( + false, + "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.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ) + : void 0; } } - { - instance.componentDidUpdate( - prevProps, - prevState, - instance.__reactInternalSnapshotBeforeUpdate - ); - } - + instance.componentDidUpdate( + prevProps, + prevState, + instance.__reactInternalSnapshotBeforeUpdate + ); stopPhaseTimer(); } } @@ -15748,33 +18183,39 @@ function commitLifeCycles( 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" - ); - } + !(instance.props === finishedWork.memoizedProps) + ? warning$1( + false, + "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" + ) + : void 0; + !(instance.state === finishedWork.memoizedState) + ? warning$1( + false, + "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.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ) + : void 0; } } // 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); + commitUpdateQueue( + finishedWork, + updateQueue, + instance, + committedExpirationTime + ); } return; @@ -15798,7 +18239,12 @@ function commitLifeCycles( } } - commitUpdateQueue(finishedWork, _updateQueue, _instance); + commitUpdateQueue( + finishedWork, + _updateQueue, + _instance, + committedExpirationTime + ); } return; @@ -15810,7 +18256,7 @@ function commitLifeCycles( // These effects should only be committed when components are first mounted, // aka when there is no current/alternate. - if (current === null && finishedWork.effectTag & Update) { + if (current$$1 === null && finishedWork.effectTag & Update) { var type = finishedWork.type; var props = finishedWork.memoizedProps; } @@ -15829,24 +18275,29 @@ function commitLifeCycles( } case Profiler: { - { - var _finishedWork$memoize2 = finishedWork.memoizedProps, - onCommit = _finishedWork$memoize2.onCommit, - onRender = _finishedWork$memoize2.onRender; - var effectDuration = finishedWork.stateNode.effectDuration; - var commitTime = getCommitTime(); + if (enableProfilerTimer) { + var onRender = finishedWork.memoizedProps.onRender; if (typeof onRender === "function") { - { + if (enableSchedulerTracing) { onRender( finishedWork.memoizedProps.id, - current === null ? "mount" : "update", + current$$1 === null ? "mount" : "update", finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, - commitTime, + getCommitTime(), finishedRoot.memoizedInteractions ); + } else { + onRender( + finishedWork.memoizedProps.id, + current$$1 === null ? "mount" : "update", + finishedWork.actualDuration, + finishedWork.treeBaseDuration, + finishedWork.actualStartTime, + getCommitTime() + ); } } } @@ -15855,6 +18306,7 @@ function commitLifeCycles( } case SuspenseComponent: { + commitSuspenseHydrationCallbacks(finishedRoot, finishedWork); return; } @@ -15863,17 +18315,19 @@ function commitLifeCycles( case FundamentalComponent: case ScopeComponent: 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." - ); + 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." + ); + } + } } } function hideOrUnhideAllChildren(finishedWork, isHidden) { - { + if (supportsMutation) { // 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; @@ -15891,7 +18345,7 @@ function hideOrUnhideAllChildren(finishedWork, isHidden) { var _instance3 = node.stateNode; if (isHidden) { - hideTextInstance(); + hideTextInstance(_instance3); } else { unhideTextInstance(_instance3, node.memoizedProps); } @@ -15946,12 +18400,17 @@ function commitAttachRef(finishedWork) { instanceToUse = instance; } // Moved outside to ensure DCE works with this flag + if (enableScopeAPI && finishedWork.tag === ScopeComponent) { + instanceToUse = instance.methods; + } + if (typeof ref === "function") { ref(instanceToUse); } else { { if (!ref.hasOwnProperty("current")) { - error( + warningWithoutStack$1( + false, "Unexpected ref object provided for %s. " + "Use either a ref-setter function or React.createRef().%s", getComponentName(finishedWork.type), @@ -15965,8 +18424,8 @@ function commitAttachRef(finishedWork) { } } -function commitDetachRef(current) { - var currentRef = current.ref; +function commitDetachRef(current$$1) { + var currentRef = current$$1.ref; if (currentRef !== null) { if (typeof currentRef === "function") { @@ -15979,77 +18438,92 @@ function commitDetachRef(current) { // deletion, so don't let them throw. Host-originating errors should // interrupt deletion, so it's okay -function commitUnmount(finishedRoot, current, renderPriorityLevel) { - onCommitUnmount(current); +function commitUnmount(finishedRoot, current$$1, renderPriorityLevel) { + onCommitUnmount(current$$1); - switch (current.tag) { + switch (current$$1.tag) { case FunctionComponent: case ForwardRef: case MemoComponent: - case SimpleMemoComponent: - case Block: { - var updateQueue = current.updateQueue; + case SimpleMemoComponent: { + var updateQueue = current$$1.updateQueue; if (updateQueue !== null) { var lastEffect = updateQueue.lastEffect; if (lastEffect !== null) { - var firstEffect = lastEffect.next; - - { - // When the owner fiber is deleted, the destroy function of a passive - // effect hook is called during the synchronous commit phase. This is - // a concession to implementation complexity. Calling it in the - // passive effect phase (like they usually are, when dependencies - // change during an update) would require either traversing the - // children of the deleted fiber again, or including unmount effects - // as part of the fiber effect list. - // - // Because this is during the sync commit phase, we need to change - // the priority. - // - // TODO: Reconsider this implementation trade off. - var priorityLevel = - renderPriorityLevel > NormalPriority - ? NormalPriority - : renderPriorityLevel; - runWithPriority(priorityLevel, function() { - var effect = firstEffect; - - do { - var _effect3 = effect, - _destroy = _effect3.destroy, - _tag = _effect3.tag; - - if (_destroy !== undefined) { - { - safelyCallDestroy(current, _destroy); - } - } + var firstEffect = lastEffect.next; // When the owner fiber is deleted, the destroy function of a passive + // effect hook is called during the synchronous commit phase. This is + // a concession to implementation complexity. Calling it in the + // passive effect phase (like they usually are, when dependencies + // change during an update) would require either traversing the + // children of the deleted fiber again, or including unmount effects + // as part of the fiber effect list. + // + // Because this is during the sync commit phase, we need to change + // the priority. + // + // TODO: Reconsider this implementation trade off. + + var priorityLevel = + renderPriorityLevel > NormalPriority + ? NormalPriority + : renderPriorityLevel; + runWithPriority(priorityLevel, function() { + var effect = firstEffect; + + do { + var destroy = effect.destroy; + + if (destroy !== undefined) { + safelyCallDestroy(current$$1, destroy); + } - effect = effect.next; - } while (effect !== firstEffect); - }); - } + effect = effect.next; + } while (effect !== firstEffect); + }); } } - return; + break; } case ClassComponent: { - safelyDetachRef(current); - var instance = current.stateNode; + safelyDetachRef(current$$1); + var instance = current$$1.stateNode; if (typeof instance.componentWillUnmount === "function") { - safelyCallComponentWillUnmount(current, instance); + safelyCallComponentWillUnmount(current$$1, instance); } return; } case HostComponent: { - safelyDetachRef(current); + if (enableFlareAPI) { + var dependencies = current$$1.dependencies; + + if (dependencies !== null) { + var respondersMap = dependencies.responders; + + if (respondersMap !== null) { + var responderInstances = Array.from(respondersMap.values()); + + for ( + var i = 0, length = responderInstances.length; + i < length; + i++ + ) { + var responderInstance = responderInstances[i]; + unmountResponderInstance(responderInstance); + } + + dependencies.responders = null; + } + } + } + + safelyDetachRef(current$$1); return; } @@ -16057,23 +18531,48 @@ function commitUnmount(finishedRoot, current, renderPriorityLevel) { // TODO: this is recursive. // We are also not using this parent because // the portal will get pushed immediately. - { - unmountHostComponents(finishedRoot, current, renderPriorityLevel); + if (supportsMutation) { + unmountHostComponents(finishedRoot, current$$1, renderPriorityLevel); + } else if (supportsPersistence) { + emptyPortalContainer(current$$1); } return; } case FundamentalComponent: { + if (enableFundamentalAPI) { + var fundamentalInstance = current$$1.stateNode; + + if (fundamentalInstance !== null) { + unmountFundamentalComponent(fundamentalInstance); + current$$1.stateNode = null; + } + } + return; } case DehydratedFragment: { + if (enableSuspenseCallback) { + var hydrationCallbacks = finishedRoot.hydrationCallbacks; + + if (hydrationCallbacks !== null) { + var onDeleted = hydrationCallbacks.onDeleted; + + if (onDeleted) { + onDeleted(current$$1.stateNode); + } + } + } + return; } case ScopeComponent: { - return; + if (enableScopeAPI) { + safelyDetachRef(current$$1); + } } } } @@ -16093,7 +18592,7 @@ function commitNestedUnmounts(finishedRoot, root, renderPriorityLevel) { 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 + (!supportsMutation || node.tag !== HostPortal) ) { node.child.return = node; node = node.child; @@ -16117,30 +18616,72 @@ function commitNestedUnmounts(finishedRoot, root, renderPriorityLevel) { } } -function detachFiber(current) { - var alternate = current.alternate; // Cut off the return pointers to disconnect it from the tree. Ideally, we +function detachFiber(current$$1) { + var alternate = current$$1.alternate; // 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. - current.return = null; - current.child = null; - current.memoizedState = null; - current.updateQueue = null; - current.dependencies = null; - current.alternate = null; - current.firstEffect = null; - current.lastEffect = null; - current.pendingProps = null; - current.memoizedProps = null; - current.stateNode = null; + current$$1.return = null; + current$$1.child = null; + current$$1.memoizedState = null; + current$$1.updateQueue = null; + current$$1.dependencies = null; + current$$1.alternate = null; + current$$1.firstEffect = null; + current$$1.lastEffect = null; + current$$1.pendingProps = null; + current$$1.memoizedProps = null; if (alternate !== null) { detachFiber(alternate); } } +function emptyPortalContainer(current$$1) { + if (!supportsPersistence) { + return; + } + + var portal = current$$1.stateNode; + var containerInfo = portal.containerInfo; + var emptyChildSet = createContainerChildSet(containerInfo); + replaceContainerChildren(containerInfo, emptyChildSet); +} + +function commitContainer(finishedWork) { + if (!supportsPersistence) { + return; + } + + switch (finishedWork.tag) { + case ClassComponent: + case HostComponent: + case HostText: + case FundamentalComponent: { + return; + } + + case HostRoot: + case HostPortal: { + var portalOrRoot = finishedWork.stateNode; + var containerInfo = portalOrRoot.containerInfo, + pendingChildren = portalOrRoot.pendingChildren; + replaceContainerChildren(containerInfo, pendingChildren); + return; + } + + 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." + ); + } + } + } +} + function getHostParentFiber(fiber) { var parent = fiber.return; @@ -16218,6 +18759,10 @@ function getHostSibling(fiber) { } function commitPlacement(finishedWork) { + if (!supportsMutation) { + return; + } // Recursively insert all host nodes into the parent. + var parentFiber = getHostParentFiber(finishedWork); // Note: these two variables *must* always be updated together. var parent; @@ -16241,6 +18786,10 @@ function commitPlacement(finishedWork) { break; case FundamentalComponent: + if (enableFundamentalAPI) { + parent = parentStateNode.instance; + isContainer = false; + } // eslint-disable-next-line-no-fallthrough @@ -16252,79 +18801,65 @@ function commitPlacement(finishedWork) { } if (parentFiber.effectTag & ContentReset) { + // Reset the text content of the parent before doing any insertions parentFiber.effectTag &= ~ContentReset; } 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 (isContainer) { - insertOrAppendPlacementNodeIntoContainer(finishedWork, before, parent); - } else { - insertOrAppendPlacementNode(finishedWork, before, parent); - } -} - -function insertOrAppendPlacementNodeIntoContainer(node, before, parent) { - var tag = node.tag; - var isHost = tag === HostComponent || tag === HostText; + var node = finishedWork; - if (isHost || enableFundamentalAPI) { - var stateNode = isHost ? node.stateNode : node.stateNode.instance; - - if (before) { - insertInContainerBefore(parent); - } else { - appendChildToContainer(parent, stateNode); - } - } else if (tag === HostPortal); - else { - var child = node.child; + while (true) { + var isHost = node.tag === HostComponent || node.tag === HostText; - if (child !== null) { - insertOrAppendPlacementNodeIntoContainer(child, before, parent); - var sibling = child.sibling; + if (isHost || (enableFundamentalAPI && node.tag === FundamentalComponent)) { + var stateNode = isHost ? node.stateNode : node.stateNode.instance; - while (sibling !== null) { - insertOrAppendPlacementNodeIntoContainer(sibling, before, parent); - sibling = sibling.sibling; + if (before) { + if (isContainer) { + insertInContainerBefore(parent, stateNode, before); + } else { + insertBefore(parent, stateNode, before); + } + } else { + if (isContainer) { + appendChildToContainer(parent, stateNode); + } else { + appendChild(parent, stateNode); + } } + } else if (node.tag === HostPortal) { + // If the insertion itself is a portal, then we don't want to traverse + // down its children. Instead, we'll get insertions from each child in + // the portal directly. + } else if (node.child !== null) { + node.child.return = node; + node = node.child; + continue; } - } -} -function insertOrAppendPlacementNode(node, before, parent) { - var tag = node.tag; - var isHost = tag === HostComponent || tag === HostText; - - if (isHost || enableFundamentalAPI) { - var stateNode = isHost ? node.stateNode : node.stateNode.instance; - - if (before) { - insertBefore(parent, stateNode, before); - } else { - appendChild(parent, stateNode); + if (node === finishedWork) { + return; } - } 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; + while (node.sibling === null) { + if (node.return === null || node.return === finishedWork) { + return; } + + node = node.return; } + + node.sibling.return = node.return; + node = node.sibling; } } -function unmountHostComponents(finishedRoot, current, renderPriorityLevel) { +function unmountHostComponents(finishedRoot, current$$1, 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 + var node = current$$1; // 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. @@ -16360,6 +18895,12 @@ function unmountHostComponents(finishedRoot, current, renderPriorityLevel) { currentParent = parentStateNode.containerInfo; currentParentIsContainer = true; break findParent; + + case FundamentalComponent: + if (enableFundamentalAPI) { + currentParent = parentStateNode.instance; + currentParentIsContainer = false; + } } parent = parent.return; @@ -16377,6 +18918,37 @@ function unmountHostComponents(finishedRoot, current, renderPriorityLevel) { } else { removeChild(currentParent, node.stateNode); } // Don't visit children because we already visited them. + } else if (enableFundamentalAPI && node.tag === FundamentalComponent) { + var fundamentalNode = node.stateNode.instance; + commitNestedUnmounts(finishedRoot, node, renderPriorityLevel); // After all the children have unmounted, it is now safe to remove the + // node from the tree. + + if (currentParentIsContainer) { + removeChildFromContainer(currentParent, fundamentalNode); + } else { + removeChild(currentParent, fundamentalNode); + } + } else if ( + enableSuspenseServerRenderer && + node.tag === DehydratedFragment + ) { + if (enableSuspenseCallback) { + var hydrationCallbacks = finishedRoot.hydrationCallbacks; + + if (hydrationCallbacks !== null) { + var onDeleted = hydrationCallbacks.onDeleted; + + if (onDeleted) { + onDeleted(node.stateNode); + } + } + } // Delete the dehydrated suspense boundary and all of its content. + + if (currentParentIsContainer) { + clearSuspenseBoundaryFromContainer(currentParent, node.stateNode); + } else { + clearSuspenseBoundary(currentParent, node.stateNode); + } } else if (node.tag === HostPortal) { if (node.child !== null) { // When we go into a portal, it becomes the parent to remove from. @@ -16398,12 +18970,12 @@ function unmountHostComponents(finishedRoot, current, renderPriorityLevel) { } } - if (node === current) { + if (node === current$$1) { return; } while (node.sibling === null) { - if (node.return === null || node.return === current) { + if (node.return === null || node.return === current$$1) { return; } @@ -16421,32 +18993,74 @@ function unmountHostComponents(finishedRoot, current, renderPriorityLevel) { } } -function commitDeletion(finishedRoot, current, renderPriorityLevel) { - { +function commitDeletion(finishedRoot, current$$1, renderPriorityLevel) { + if (supportsMutation) { // Recursively delete all host nodes from the parent. // Detach refs and call componentWillUnmount() on the whole subtree. - unmountHostComponents(finishedRoot, current, renderPriorityLevel); + unmountHostComponents(finishedRoot, current$$1, renderPriorityLevel); + } else { + // Detach refs and call componentWillUnmount() on the whole subtree. + commitNestedUnmounts(finishedRoot, current$$1, renderPriorityLevel); } - detachFiber(current); + detachFiber(current$$1); } -function commitWork(current, finishedWork) { +function commitWork(current$$1, finishedWork) { + if (!supportsMutation) { + switch (finishedWork.tag) { + case FunctionComponent: + case ForwardRef: + case MemoComponent: + case SimpleMemoComponent: { + // Note: We currently never use MountMutation, but useLayout uses + // UnmountMutation. + commitHookEffectList(UnmountMutation, MountMutation, finishedWork); + return; + } + + case Profiler: { + return; + } + + case SuspenseComponent: { + commitSuspenseComponent(finishedWork); + attachSuspenseRetryListeners(finishedWork); + return; + } + + case SuspenseListComponent: { + attachSuspenseRetryListeners(finishedWork); + return; + } + + case HostRoot: { + if (supportsHydration) { + var root = finishedWork.stateNode; + + if (root.hydrate) { + // We've just hydrated. No need to hydrate again. + root.hydrate = false; + commitHydratedContainer(root.containerInfo); + } + } + + break; + } + } + + commitContainer(finishedWork); + return; + } + switch (finishedWork.tag) { case FunctionComponent: case ForwardRef: case MemoComponent: - case SimpleMemoComponent: - case Block: { - // 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); - } - + case SimpleMemoComponent: { + // Note: We currently never use MountMutation, but useLayout uses + // UnmountMutation. + commitHookEffectList(UnmountMutation, MountMutation, finishedWork); return; } @@ -16463,14 +19077,31 @@ function commitWork(current, finishedWork) { // as the newProps. The updatePayload will contain the real change in // this case. - var oldProps = current !== null ? current.memoizedProps : newProps; + var oldProps = + current$$1 !== null ? current$$1.memoizedProps : newProps; var type = finishedWork.type; // TODO: Type the updateQueue to be specific to host components. var updatePayload = finishedWork.updateQueue; finishedWork.updateQueue = null; if (updatePayload !== null) { - commitUpdate(instance, updatePayload, type, oldProps, newProps); + commitUpdate( + instance, + updatePayload, + type, + oldProps, + newProps, + finishedWork + ); + } + + if (enableFlareAPI) { + var prevListeners = oldProps.listeners; + var nextListeners = newProps.listeners; + + if (prevListeners !== nextListeners) { + updateEventListeners(nextListeners, finishedWork, null); + } } } @@ -16489,12 +19120,22 @@ function commitWork(current, finishedWork) { // as the newProps. The updatePayload will contain the real change in // this case. - var oldText = current !== null ? current.memoizedProps : newText; + var oldText = current$$1 !== null ? current$$1.memoizedProps : newText; commitTextUpdate(textInstance, oldText, newText); return; } case HostRoot: { + if (supportsHydration) { + var _root = finishedWork.stateNode; + + if (_root.hydrate) { + // We've just hydrated. No need to hydrate again. + _root.hydrate = false; + commitHydratedContainer(_root.containerInfo); + } + } + return; } @@ -16508,20 +19149,54 @@ function commitWork(current, finishedWork) { return; } - case SuspenseListComponent: { - attachSuspenseRetryListeners(finishedWork); - return; - } + case SuspenseListComponent: { + attachSuspenseRetryListeners(finishedWork); + return; + } + + case IncompleteClassComponent: { + return; + } + + case FundamentalComponent: { + if (enableFundamentalAPI) { + var fundamentalInstance = finishedWork.stateNode; + updateFundamentalComponent(fundamentalInstance); + } + + return; + } + + case ScopeComponent: { + if (enableScopeAPI) { + var scopeInstance = finishedWork.stateNode; + scopeInstance.fiber = finishedWork; + + if (enableFlareAPI) { + var _newProps = finishedWork.memoizedProps; + + var _oldProps = + current$$1 !== null ? current$$1.memoizedProps : _newProps; + + var _prevListeners = _oldProps.listeners; + var _nextListeners = _newProps.listeners; + + if (_prevListeners !== _nextListeners) { + updateEventListeners(_nextListeners, finishedWork, null); + } + } + } - case IncompleteClassComponent: { 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." - ); + 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." + ); + } + } } } @@ -16538,9 +19213,61 @@ function commitSuspenseComponent(finishedWork) { markCommitTimeOfFallback(); } - if (primaryChildParent !== null) { + if (supportsMutation && primaryChildParent !== null) { hideOrUnhideAllChildren(primaryChildParent, newDidTimeout); } + + if (enableSuspenseCallback && newState !== null) { + var suspenseCallback = finishedWork.memoizedProps.suspenseCallback; + + if (typeof suspenseCallback === "function") { + var thenables = finishedWork.updateQueue; + + if (thenables !== null) { + suspenseCallback(new Set(thenables)); + } + } else { + if (suspenseCallback !== undefined) { + warning$1(false, "Unexpected type for suspenseCallback."); + } + } + } +} + +function commitSuspenseHydrationCallbacks(finishedRoot, finishedWork) { + if (!supportsHydration) { + return; + } + + var newState = finishedWork.memoizedState; + + if (newState === null) { + var current$$1 = finishedWork.alternate; + + if (current$$1 !== null) { + var prevState = current$$1.memoizedState; + + if (prevState !== null) { + var suspenseInstance = prevState.dehydrated; + + if (suspenseInstance !== null) { + commitHydratedSuspenseInstance(suspenseInstance); + + if (enableSuspenseCallback) { + var hydrationCallbacks = finishedRoot.hydrationCallbacks; + + if (hydrationCallbacks !== null) { + var onHydrated = hydrationCallbacks.onHydrated; + + if (onHydrated) { + onHydrated(suspenseInstance); + } + } + } + } + } + } + } } function attachSuspenseRetryListeners(finishedWork) { @@ -16562,7 +19289,7 @@ function attachSuspenseRetryListeners(finishedWork) { var retry = resolveRetryThenable.bind(null, finishedWork, thenable); if (!retryCache.has(thenable)) { - { + if (enableSchedulerTracing) { if (thenable.__reactDoNotTraceInteractions !== true) { retry = tracing.unstable_wrap(retry); } @@ -16575,8 +19302,12 @@ function attachSuspenseRetryListeners(finishedWork) { } } -function commitResetTextContent(current) { - resetTextContent(current.stateNode); +function commitResetTextContent(current$$1) { + if (!supportsMutation) { + return; + } + + resetTextContent(current$$1.stateNode); } var PossiblyWeakMap = typeof WeakMap === "function" ? WeakMap : Map; @@ -16606,11 +19337,11 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { var getDerivedStateFromError = fiber.type.getDerivedStateFromError; if (typeof getDerivedStateFromError === "function") { - var error$1 = errorInfo.value; + var error = errorInfo.value; update.payload = function() { logError(fiber, errorInfo); - return getDerivedStateFromError(error$1); + return getDerivedStateFromError(error); }; } @@ -16633,9 +19364,9 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { logError(fiber, errorInfo); } - var error$1 = errorInfo.value; + var error = errorInfo.value; var stack = errorInfo.stack; - this.componentDidCatch(error$1, { + this.componentDidCatch(error, { componentStack: stack !== null ? stack : "" }); @@ -16644,13 +19375,14 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { // 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 (fiber.expirationTime !== Sync) { - 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" - ); - } + !(fiber.expirationTime === Sync) + ? warningWithoutStack$1( + false, + "%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" + ) + : void 0; } } }; @@ -16715,22 +19447,7 @@ function throwException( ) { // This is a thenable. var thenable = 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.expirationTime = currentSource.expirationTime; - } else { - sourceFiber.updateQueue = null; - sourceFiber.memoizedState = null; - } - } - + checkForWrongSuspensePriorityInDEV(sourceFiber); var hasInvisibleParentBoundary = hasSuspenseContext( suspenseStackCursor.current, InvisibleParentSuspenseContext @@ -16904,6 +19621,9 @@ function throwException( } break; + + default: + break; } workInProgress = workInProgress.return; @@ -16911,15 +19631,18 @@ function throwException( } var ceil = Math.ceil; -var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, - ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, - IsSomeRendererActing = ReactSharedInternals.IsSomeRendererActing; +var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher; +var ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner; +var IsSomeRendererActing = ReactSharedInternals.IsSomeRendererActing; var NoContext = /* */ 0; var BatchedContext = /* */ 1; +var EventContext = + /* */ + 2; var DiscreteEventContext = /* */ 4; @@ -16945,7 +19668,7 @@ var workInProgressRoot = null; // The fiber we're working on var workInProgress = null; // The expiration time we're rendering -var renderExpirationTime$1 = NoWork; // Whether to root completed, errored, suspended, etc. +var renderExpirationTime = NoWork; // Whether to root completed, errored, suspended, etc. var workInProgressRootExitStatus = RootIncomplete; // A fatal error, if one is thrown @@ -17030,7 +19753,7 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { if ((executionContext & RenderContext) !== NoContext) { // Use whatever time we're already rendering // TODO: Should there be a way to opt out, like with `runWithPriority`? - return renderExpirationTime$1; + return renderExpirationTime; } var expirationTime; @@ -17074,10 +19797,7 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { // Refactor computeExpirationForFiber + scheduleUpdate so we have access to // the root when we check for this condition. - if ( - workInProgressRoot !== null && - expirationTime === renderExpirationTime$1 - ) { + if (workInProgressRoot !== null && expirationTime === renderExpirationTime) { // This is a trick to move this update into a separate batch expirationTime -= 1; } @@ -17086,7 +19806,7 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { } function scheduleUpdateOnFiber(fiber, expirationTime) { checkForNestedUpdates(); - warnAboutRenderPhaseUpdatesInDEV(fiber); + warnAboutInvalidUpdatesOnClassComponentsInDEV(fiber); var root = markUpdateTimeFromFiberToRoot(fiber, expirationTime); if (root === null) { @@ -17220,7 +19940,7 @@ function markUpdateTimeFromFiberToRoot(fiber, expirationTime) { // scheduled before the root started rendering. Need to track the next // pending expiration time (perhaps by backtracking the return path) and // then trigger a restart in the `renderDidSuspendDelayIfPossible` path. - markRootSuspendedAtTime(root, renderExpirationTime$1); + markRootSuspendedAtTime(root, renderExpirationTime); } } // Mark that the root has a pending update. @@ -17252,17 +19972,9 @@ function getNextRootExpirationTimeToWorkOn(root) { var lastPingedTime = root.lastPingedTime; var nextKnownPendingLevel = root.nextKnownPendingLevel; - var nextLevel = - lastPingedTime > nextKnownPendingLevel - ? lastPingedTime - : nextKnownPendingLevel; - - if (nextLevel <= Idle && firstPendingTime !== nextLevel) { - // Don't work on Idle/Never priority unless everything else is committed. - return NoWork; - } - - return nextLevel; + return lastPingedTime > nextKnownPendingLevel + ? lastPingedTime + : nextKnownPendingLevel; } // 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 // expiration time of the existing task is the same as the expiration time of @@ -17329,6 +20041,11 @@ function ensureRootIsScheduled(root) { if (expirationTime === Sync) { // Sync React callbacks are scheduled on a special internal queue callbackNode = scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root)); + } else if (disableSchedulerTimeoutBasedOnReactExpirationTime) { + callbackNode = scheduleCallback( + priorityLevel, + performConcurrentWorkOnRoot.bind(null, root) + ); } else { callbackNode = scheduleCallback( priorityLevel, @@ -17347,7 +20064,7 @@ function ensureRootIsScheduled(root) { function performConcurrentWorkOnRoot(root, didTimeout) { // 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 = NoWork; // Check if the render expired. + currentEventTime = NoWork; if (didTimeout) { // The render task took too long to complete. Mark the current time as @@ -17362,50 +20079,83 @@ function performConcurrentWorkOnRoot(root, didTimeout) { var expirationTime = getNextRootExpirationTimeToWorkOn(root); - if (expirationTime === NoWork) { - return null; - } + if (expirationTime !== NoWork) { + var originalCallbackNode = root.callbackNode; - var originalCallbackNode = root.callbackNode; + if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { + throw Error("Should not already be working."); + } - if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { - throw Error("Should not already be working."); - } + flushPassiveEffects(); // If the root or expiration time have changed, throw out the existing stack + // and prepare a fresh one. Otherwise we'll continue where we left off. - flushPassiveEffects(); - var exitStatus = renderRootConcurrent(root, expirationTime); + if ( + root !== workInProgressRoot || + expirationTime !== renderExpirationTime + ) { + prepareFreshStack(root, expirationTime); + startWorkOnPendingInteractions(root, expirationTime); + } // If we have a work-in-progress fiber, it means there's still work to do + // in this root. - if (exitStatus !== RootIncomplete) { - if (exitStatus === RootErrored) { - // If something threw an error, try rendering one more time. We'll - // render synchronously to block concurrent data mutations, and we'll - // render at Idle (or lower) so that all pending updates are included. - // If it still fails after the second attempt, we'll give up and commit - // the resulting tree. - expirationTime = expirationTime > Idle ? Idle : expirationTime; - exitStatus = renderRootSync(root, expirationTime); - } + if (workInProgress !== null) { + var prevExecutionContext = executionContext; + executionContext |= RenderContext; + var prevDispatcher = pushDispatcher(root); + var prevInteractions = pushInteractions(root); + startWorkLoopTimer(workInProgress); - if (exitStatus === RootFatalErrored) { - var fatalError = workInProgressRootFatalError; - prepareFreshStack(root, expirationTime); - markRootSuspendedAtTime(root, expirationTime); - ensureRootIsScheduled(root); - throw fatalError; - } // We now have a consistent tree. The next step is either to commit it, - // or, if something suspended, wait to commit it after a timeout. + do { + try { + workLoopConcurrent(); + break; + } catch (thrownValue) { + handleError(root, thrownValue); + } + } while (true); - var finishedWork = (root.finishedWork = root.current.alternate); - root.finishedExpirationTime = expirationTime; - finishConcurrentRender(root, finishedWork, exitStatus, expirationTime); - } + resetContextDependencies(); + executionContext = prevExecutionContext; + popDispatcher(prevDispatcher); - ensureRootIsScheduled(root); + if (enableSchedulerTracing) { + popInteractions(prevInteractions); + } + + if (workInProgressRootExitStatus === RootFatalErrored) { + var fatalError = workInProgressRootFatalError; + stopInterruptedWorkLoopTimer(); + prepareFreshStack(root, expirationTime); + markRootSuspendedAtTime(root, expirationTime); + ensureRootIsScheduled(root); + throw fatalError; + } + + if (workInProgress !== null) { + // There's still work left over. Exit without committing. + stopInterruptedWorkLoopTimer(); + } else { + // We now have a consistent tree. The next step is either to commit it, + // or, if something suspended, wait to commit it after a timeout. + stopFinishedWorkLoopTimer(); + var finishedWork = (root.finishedWork = root.current.alternate); + root.finishedExpirationTime = expirationTime; + finishConcurrentRender( + root, + finishedWork, + workInProgressRootExitStatus, + expirationTime + ); + } + + ensureRootIsScheduled(root); - if (root.callbackNode === originalCallbackNode) { - // The task node scheduled for this root is the same one that's - // currently executed. Need to return a continuation. - return performConcurrentWorkOnRoot.bind(null, root); + if (root.callbackNode === originalCallbackNode) { + // The task node scheduled for this root is the same one that's + // currently executed. Need to return a continuation. + return performConcurrentWorkOnRoot.bind(null, root); + } + } } return null; @@ -17417,6 +20167,9 @@ function finishConcurrentRender( exitStatus, expirationTime ) { + // Set this to null to indicate there's no in-progress render. + workInProgressRoot = null; + switch (exitStatus) { case RootIncomplete: case RootFatalErrored: { @@ -17429,9 +20182,19 @@ function finishConcurrentRender( // if I do. eslint-disable-next-line no-fallthrough case RootErrored: { - // We should have already attempted to retry this tree. If we reached - // this point, it errored again. Commit it. - commitRoot(root); + // If this was an async render, the error may have happened due to + // a mutation in a concurrent event. Try rendering one more time, + // synchronously, to see if the error goes away. If there are + // lower priority updates, let's include those, too, in case they + // fix the inconsistency. Render at Idle to include all updates. + // If it was Idle or Never or some not-yet-invented time, render + // at that time. + markRootExpiredAtTime( + root, + expirationTime > Idle ? Idle : expirationTime + ); // We assume that this second render pass will be synchronous + // and therefore not hit this path again. + break; } @@ -17441,7 +20204,9 @@ function finishConcurrentRender( if (expirationTime === lastSuspendedTime) { root.nextKnownPendingLevel = getRemainingExpirationTime(finishedWork); - } // We have an acceptable loading state. We need to figure out if we + } + + flushSuspensePriorityWarningInDEV(); // We have an acceptable loading state. We need to figure out if we // should immediately commit it or wait a bit. // If we have processed new updates during this render, we may now // have a new loading state ready. We want to ensure that we commit @@ -17452,7 +20217,7 @@ function finishConcurrentRender( if ( hasNotProcessedNewUpdates && // do not delay if we're inside an act() scope - !IsThisRendererActing.current + !(true && flushSuspenseFallbacksInTests && IsThisRendererActing.current) ) { // If we have not processed any new updates during this pass, then // this is either a retry of an existing fallback state or a @@ -17516,7 +20281,12 @@ function finishConcurrentRender( root.nextKnownPendingLevel = getRemainingExpirationTime(finishedWork); } - { + flushSuspensePriorityWarningInDEV(); + + if ( + // do not delay if we're inside an act() scope + !(true && flushSuspenseFallbacksInTests && IsThisRendererActing.current) + ) { // We're suspended in a state that should be avoided. We'll try to // avoid committing it for as long as the timeouts let us. if (workInProgressRootHasPendingPing) { @@ -17606,6 +20376,11 @@ function finishConcurrentRender( // The work completed. Ready to commit. if ( // do not delay if we're inside an act() scope + !( + true && + flushSuspenseFallbacksInTests && + IsThisRendererActing.current + ) && workInProgressRootLatestProcessedExpirationTime !== Sync && workInProgressRootCanSuspendUsingConfig !== null ) { @@ -17643,67 +20418,149 @@ function finishConcurrentRender( // through Scheduler function performSyncWorkOnRoot(root) { - if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { - throw Error("Should not already be working."); - } - - flushPassiveEffects(); + // Check if there's expired work on this root. Otherwise, render at Sync. var lastExpiredTime = root.lastExpiredTime; - var expirationTime; + var expirationTime = lastExpiredTime !== NoWork ? lastExpiredTime : Sync; + + if (root.finishedExpirationTime === expirationTime) { + // There's already a pending commit at this expiration time. + // TODO: This is poorly factored. This case only exists for the + // batch.commit() API. + commitRoot(root); + } else { + if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { + throw Error("Should not already be working."); + } + + flushPassiveEffects(); // If the root or expiration time have changed, throw out the existing stack + // and prepare a fresh one. Otherwise we'll continue where we left off. - if (lastExpiredTime !== NoWork) { - // There's expired work on this root. Check if we have a partial tree - // that we can reuse. if ( - root === workInProgressRoot && - renderExpirationTime$1 >= lastExpiredTime + root !== workInProgressRoot || + expirationTime !== renderExpirationTime ) { - // There's a partial tree with equal or greater than priority than the - // expired level. Finish rendering it before rendering the rest of the - // expired work. - expirationTime = renderExpirationTime$1; - } else { - // Start a fresh tree. - expirationTime = lastExpiredTime; + prepareFreshStack(root, expirationTime); + startWorkOnPendingInteractions(root, expirationTime); + } // If we have a work-in-progress fiber, it means there's still work to do + // in this root. + + if (workInProgress !== null) { + var prevExecutionContext = executionContext; + executionContext |= RenderContext; + var prevDispatcher = pushDispatcher(root); + var prevInteractions = pushInteractions(root); + startWorkLoopTimer(workInProgress); + + do { + try { + workLoopSync(); + break; + } catch (thrownValue) { + handleError(root, thrownValue); + } + } while (true); + + resetContextDependencies(); + executionContext = prevExecutionContext; + popDispatcher(prevDispatcher); + + if (enableSchedulerTracing) { + popInteractions(prevInteractions); + } + + if (workInProgressRootExitStatus === RootFatalErrored) { + var fatalError = workInProgressRootFatalError; + stopInterruptedWorkLoopTimer(); + prepareFreshStack(root, expirationTime); + markRootSuspendedAtTime(root, expirationTime); + ensureRootIsScheduled(root); + throw fatalError; + } + + if (workInProgress !== null) { + // This is a sync render, so we should have finished the whole tree. + { + throw Error( + "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." + ); + } + } else { + // We now have a consistent tree. Because this is a sync render, we + // will commit it even if something suspended. + stopFinishedWorkLoopTimer(); + root.finishedWork = root.current.alternate; + root.finishedExpirationTime = expirationTime; + finishSyncRender(root, workInProgressRootExitStatus, expirationTime); + } // Before exiting, make sure there's a callback scheduled for the next + // pending level. + + ensureRootIsScheduled(root); } - } else { - // There's no expired work. This must be a new, synchronous render. - expirationTime = Sync; } - var exitStatus = renderRootSync(root, expirationTime); + return null; +} + +function finishSyncRender(root, exitStatus, expirationTime) { + // Set this to null to indicate there's no in-progress render. + workInProgressRoot = null; - if (root.tag !== LegacyRoot && exitStatus === RootErrored) { - // If something threw an error, try rendering one more time. We'll - // render synchronously to block concurrent data mutations, and we'll - // render at Idle (or lower) so that all pending updates are included. - // If it still fails after the second attempt, we'll give up and commit - // the resulting tree. - expirationTime = expirationTime > Idle ? Idle : expirationTime; - exitStatus = renderRootSync(root, expirationTime); + { + if (exitStatus === RootSuspended || exitStatus === RootSuspendedWithDelay) { + flushSuspensePriorityWarningInDEV(); + } } - if (exitStatus === RootFatalErrored) { - var fatalError = workInProgressRootFatalError; - prepareFreshStack(root, expirationTime); - markRootSuspendedAtTime(root, expirationTime); - ensureRootIsScheduled(root); - throw fatalError; - } // We now have a consistent tree. Because this is a sync render, we - // will commit it even if something suspended. + commitRoot(root); +} + +function flushDiscreteUpdates() { + // TODO: Should be able to flush inside batchedUpdates, but not inside `act`. + // However, `act` uses `batchedUpdates`, so there's no way to distinguish + // those two cases. Need to fix this before exposing flushDiscreteUpdates + // as a public API. + if ( + (executionContext & (BatchedContext | RenderContext | CommitContext)) !== + NoContext + ) { + if (true && (executionContext & RenderContext) !== NoContext) { + warning$1( + false, + "unstable_flushDiscreteUpdates: Cannot flush updates when React is " + + "already rendering." + ); + } // We're already rendering, so we can't synchronously flush pending work. + // This is probably a nested event dispatch triggered by a lifecycle/effect, + // like `el.focus()`. Exit. - root.finishedWork = root.current.alternate; - root.finishedExpirationTime = expirationTime; - commitRoot(root); // Before exiting, make sure there's a callback scheduled for the next - // pending level. + return; + } - ensureRootIsScheduled(root); - return null; + flushPendingDiscreteUpdates(); // If the discrete updates scheduled passive effects, flush them now so that + // they fire before the next serial event. + + flushPassiveEffects(); } + function syncUpdates(fn, a, b, c) { return runWithPriority(ImmediatePriority, fn.bind(null, a, b, c)); } +function flushPendingDiscreteUpdates() { + if (rootsWithPendingDiscreteUpdates !== null) { + // For each root with pending discrete updates, schedule a callback to + // immediately flush them. + var roots = rootsWithPendingDiscreteUpdates; + rootsWithPendingDiscreteUpdates = null; + roots.forEach(function(expirationTime, root) { + markRootExpiredAtTime(root, expirationTime); + ensureRootIsScheduled(root); + }); // Now flush the immediate queue. + + flushSyncCallbackQueue(); + } +} + function batchedUpdates$1(fn, a) { var prevExecutionContext = executionContext; executionContext |= BatchedContext; @@ -17719,6 +20576,38 @@ function batchedUpdates$1(fn, a) { } } } +function batchedEventUpdates$1(fn, a) { + var prevExecutionContext = executionContext; + executionContext |= EventContext; + + try { + return fn(a); + } finally { + executionContext = prevExecutionContext; + + if (executionContext === NoContext) { + // Flush the immediate callbacks that were scheduled during this batch + flushSyncCallbackQueue(); + } + } +} +function discreteUpdates$1(fn, a, b, c) { + var prevExecutionContext = executionContext; + executionContext |= DiscreteEventContext; + + try { + // Should this + return runWithPriority(UserBlockingPriority, fn.bind(null, a, b, c)); + } finally { + executionContext = prevExecutionContext; + + if (executionContext === NoContext) { + // Flush the immediate callbacks that were scheduled during this batch + flushSyncCallbackQueue(); + } + } +} + function flushSync(fn, a) { if ((executionContext & (RenderContext | CommitContext)) !== NoContext) { { @@ -17765,8 +20654,8 @@ function prepareFreshStack(root, expirationTime) { } workInProgressRoot = root; - workInProgress = createWorkInProgress(root.current, null); - renderExpirationTime$1 = expirationTime; + workInProgress = createWorkInProgress(root.current, null, expirationTime); + renderExpirationTime = expirationTime; workInProgressRootExitStatus = RootIncomplete; workInProgressRootFatalError = null; workInProgressRootLatestProcessedExpirationTime = Sync; @@ -17775,12 +20664,13 @@ function prepareFreshStack(root, expirationTime) { workInProgressRootNextUnprocessedUpdateTime = NoWork; workInProgressRootHasPendingPing = false; - { + if (enableSchedulerTracing) { spawnedWorkDuringRender = null; } { ReactStrictModeWarnings.discardPendingWarnings(); + componentsThatTriggeredHighPriSuspend = null; } } @@ -17789,7 +20679,7 @@ function handleError(root, thrownValue) { try { // Reset module-level state that was set during the render phase. resetContextDependencies(); - resetHooksAfterThrow(); + resetHooks(); resetCurrentFiber(); if (workInProgress === null || workInProgress.return === null) { @@ -17798,14 +20688,7 @@ function handleError(root, thrownValue) { // supposed to capture all errors that weren't caught by an error // boundary. workInProgressRootExitStatus = RootFatalErrored; - workInProgressRootFatalError = thrownValue; // Set `workInProgress` to null. This represents advancing to the next - // sibling, or the parent if there are no siblings. But since the root - // has no siblings nor a parent, we set it to null. Usually this is - // handled by `completeUnitOfWork` or `unwindWork`, but since we're - // interntionally not calling those, we need set it here. - // TODO: Consider calling `unwindWork` to pop the contexts. - - workInProgress = null; + workInProgressRootFatalError = thrownValue; return null; } @@ -17821,7 +20704,7 @@ function handleError(root, thrownValue) { workInProgress.return, workInProgress, thrownValue, - renderExpirationTime$1 + renderExpirationTime ); workInProgress = completeUnitOfWork(workInProgress); } catch (yetAnotherThrownValue) { @@ -17835,8 +20718,8 @@ function handleError(root, thrownValue) { } function pushDispatcher(root) { - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = ContextOnlyDispatcher; if (prevDispatcher === null) { // The React isomorphic package does not include a default dispatcher. @@ -17849,19 +20732,21 @@ function pushDispatcher(root) { } function popDispatcher(prevDispatcher) { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } function pushInteractions(root) { - { + if (enableSchedulerTracing) { var prevInteractions = tracing.__interactionsRef.current; tracing.__interactionsRef.current = root.memoizedInteractions; return prevInteractions; } + + return null; } function popInteractions(prevInteractions) { - { + if (enableSchedulerTracing) { tracing.__interactionsRef.current = prevInteractions; } } @@ -17914,7 +20799,7 @@ function renderDidSuspendDelayIfPossible() { // pending update. // TODO: This should immediately interrupt the current render, instead // of waiting until the next time we yield. - markRootSuspendedAtTime(workInProgressRoot, renderExpirationTime$1); + markRootSuspendedAtTime(workInProgressRoot, renderExpirationTime); markRootUpdatedAtTime( workInProgressRoot, workInProgressRootNextUnprocessedUpdateTime @@ -17944,65 +20829,15 @@ function inferTimeFromExpirationTime(expirationTime) { function inferTimeFromExpirationTimeWithSuspenseConfig( expirationTime, suspenseConfig -) { - // We don't know exactly when the update was scheduled, but we can infer an - // approximate start time from the expiration time by subtracting the timeout - // that was added to the event time. - var earliestExpirationTimeMs = expirationTimeToMs(expirationTime); - return ( - earliestExpirationTimeMs - - (suspenseConfig.timeoutMs | 0 || LOW_PRIORITY_EXPIRATION) - ); -} - -function renderRootSync(root, expirationTime) { - var prevExecutionContext = executionContext; - executionContext |= RenderContext; - var prevDispatcher = pushDispatcher(); // If the root or expiration time have changed, throw out the existing stack - // and prepare a fresh one. Otherwise we'll continue where we left off. - - if ( - root !== workInProgressRoot || - expirationTime !== renderExpirationTime$1 - ) { - prepareFreshStack(root, expirationTime); - startWorkOnPendingInteractions(root, expirationTime); - } - - var prevInteractions = pushInteractions(root); - startWorkLoopTimer(workInProgress); - - do { - try { - workLoopSync(); - break; - } catch (thrownValue) { - handleError(root, thrownValue); - } - } while (true); - - resetContextDependencies(); - - { - popInteractions(prevInteractions); - } - - executionContext = prevExecutionContext; - popDispatcher(prevDispatcher); - - if (workInProgress !== null) { - // This is a sync render, so we should have finished the whole tree. - { - throw Error( - "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." - ); - } - } - - stopFinishedWorkLoopTimer(); // Set this to null to indicate there's no in-progress render. - - workInProgressRoot = null; - return workInProgressRootExitStatus; +) { + // We don't know exactly when the update was scheduled, but we can infer an + // approximate start time from the expiration time by subtracting the timeout + // that was added to the event time. + var earliestExpirationTimeMs = expirationTimeToMs(expirationTime); + return ( + earliestExpirationTimeMs - + (suspenseConfig.timeoutMs | 0 || LOW_PRIORITY_EXPIRATION) + ); } // The work loop is an extremely hot path. Tell Closure not to inline it. /** @noinline */ @@ -18013,55 +20848,6 @@ function workLoopSync() { workInProgress = performUnitOfWork(workInProgress); } } - -function renderRootConcurrent(root, expirationTime) { - var prevExecutionContext = executionContext; - executionContext |= RenderContext; - var prevDispatcher = pushDispatcher(); // If the root or expiration time have changed, throw out the existing stack - // and prepare a fresh one. Otherwise we'll continue where we left off. - - if ( - root !== workInProgressRoot || - expirationTime !== renderExpirationTime$1 - ) { - prepareFreshStack(root, expirationTime); - startWorkOnPendingInteractions(root, expirationTime); - } - - var prevInteractions = pushInteractions(root); - startWorkLoopTimer(workInProgress); - - do { - try { - workLoopConcurrent(); - break; - } catch (thrownValue) { - handleError(root, thrownValue); - } - } while (true); - - resetContextDependencies(); - - { - popInteractions(prevInteractions); - } - - popDispatcher(prevDispatcher); - executionContext = prevExecutionContext; // Check if the tree has completed. - - if (workInProgress !== null) { - // Still work remaining. - stopInterruptedWorkLoopTimer(); - return RootIncomplete; - } else { - // Completed the tree. - stopFinishedWorkLoopTimer(); // Set this to null to indicate there's no in-progress render. - - workInProgressRoot = null; // Return the final exit status. - - return workInProgressRootExitStatus; - } -} /** @noinline */ function workLoopConcurrent() { @@ -18075,17 +20861,17 @@ function performUnitOfWork(unitOfWork) { // The current, flushed, state of this fiber is the alternate. Ideally // nothing should rely on this, but relying on it here means that we don't // need an additional field on the work in progress. - var current = unitOfWork.alternate; + var current$$1 = unitOfWork.alternate; startWorkTimer(unitOfWork); setCurrentFiber(unitOfWork); var next; - if ((unitOfWork.mode & ProfileMode) !== NoMode) { + if (enableProfilerTimer && (unitOfWork.mode & ProfileMode) !== NoMode) { startProfilerTimer(unitOfWork); - next = beginWork$1(current, unitOfWork, renderExpirationTime$1); + next = beginWork$$1(current$$1, unitOfWork, renderExpirationTime); stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true); } else { - next = beginWork$1(current, unitOfWork, renderExpirationTime$1); + next = beginWork$$1(current$$1, unitOfWork, renderExpirationTime); } resetCurrentFiber(); @@ -18109,18 +20895,21 @@ function completeUnitOfWork(unitOfWork) { // The current, flushed, state of this fiber is the alternate. Ideally // nothing should rely on this, but relying on it here means that we don't // need an additional field on the work in progress. - var current = workInProgress.alternate; + var current$$1 = workInProgress.alternate; var returnFiber = workInProgress.return; // Check if the work completed or if something threw. if ((workInProgress.effectTag & Incomplete) === NoEffect) { setCurrentFiber(workInProgress); var next = void 0; - if ((workInProgress.mode & ProfileMode) === NoMode) { - next = completeWork(current, workInProgress, renderExpirationTime$1); + if ( + !enableProfilerTimer || + (workInProgress.mode & ProfileMode) === NoMode + ) { + next = completeWork(current$$1, workInProgress, renderExpirationTime); } else { startProfilerTimer(workInProgress); - next = completeWork(current, workInProgress, renderExpirationTime$1); // Update render duration assuming we didn't error. + next = completeWork(current$$1, workInProgress, renderExpirationTime); // Update render duration assuming we didn't error. stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false); } @@ -18176,9 +20965,12 @@ function completeUnitOfWork(unitOfWork) { // This fiber did not complete because something threw. Pop values off // the stack without entering the complete phase. If this is a boundary, // capture values if possible. - var _next = unwindWork(workInProgress); // Because this fiber did not complete, don't reset its expiration time. + var _next = unwindWork(workInProgress, renderExpirationTime); // Because this fiber did not complete, don't reset its expiration time. - if ((workInProgress.mode & ProfileMode) !== NoMode) { + if ( + enableProfilerTimer && + (workInProgress.mode & ProfileMode) !== NoMode + ) { // Record the render duration for the fiber that errored. stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false); // Include the time spent working on failed children before continuing. @@ -18241,7 +21033,7 @@ function getRemainingExpirationTime(fiber) { function resetChildExpirationTime(completedWork) { if ( - renderExpirationTime$1 !== Never && + renderExpirationTime !== Never && completedWork.childExpirationTime === Never ) { // The children of this component are hidden. Don't bubble their @@ -18251,7 +21043,7 @@ function resetChildExpirationTime(completedWork) { var newChildExpirationTime = NoWork; // Bubble up the earliest expiration time. - if ((completedWork.mode & ProfileMode) !== NoMode) { + if (enableProfilerTimer && (completedWork.mode & ProfileMode) !== NoMode) { // In profiling mode, resetChildExpirationTime is also used to reset // profiler durations. var actualDuration = completedWork.actualDuration; @@ -18322,16 +21114,7 @@ function commitRoot(root) { } function commitRootImpl(root, renderPriorityLevel) { - do { - // `flushPassiveEffects` will call `flushSyncUpdateQueue` at the end, which - // means `flushPassiveEffects` will sometimes result in additional - // passive effects. So we need to keep flushing in a loop until there are - // no more pending effects. - // TODO: Might be better if `flushPassiveEffects` did not automatically - // flush synchronous work at the end, to avoid factoring hazards like this. - flushPassiveEffects(); - } while (rootWithPendingPassiveEffects !== null); - + flushPassiveEffects(); flushRenderPhaseStrictModeWarningsInDEV(); if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { @@ -18375,7 +21158,8 @@ function commitRootImpl(root, renderPriorityLevel) { // We can reset these now that they are finished. workInProgressRoot = null; workInProgress = null; - renderExpirationTime$1 = NoWork; + renderExpirationTime = NoWork; + } else { } // This indicates that the last root we worked on is not the same one that // we're committing now. This most commonly happens when a suspended root // times out. @@ -18433,7 +21217,7 @@ function commitRootImpl(root, renderPriorityLevel) { stopCommitSnapshotEffectsTimer(); - { + if (enableProfilerTimer) { // Mark the current commit time to be shared by all Profilers in this // batch. This enables them to be grouped later. recordCommitTime(); @@ -18507,7 +21291,7 @@ function commitRootImpl(root, renderPriorityLevel) { requestPaint(); - { + if (enableSchedulerTracing) { popInteractions(prevInteractions); } @@ -18521,7 +21305,7 @@ function commitRootImpl(root, renderPriorityLevel) { startCommitSnapshotEffectsTimer(); stopCommitSnapshotEffectsTimer(); - { + if (enableProfilerTimer) { recordCommitTime(); } @@ -18557,7 +21341,7 @@ function commitRootImpl(root, renderPriorityLevel) { var remainingExpirationTime = root.firstPendingTime; if (remainingExpirationTime !== NoWork) { - { + if (enableSchedulerTracing) { if (spawnedWorkDuringRender !== null) { var expirationTimes = spawnedWorkDuringRender; spawnedWorkDuringRender = null; @@ -18579,7 +21363,7 @@ function commitRootImpl(root, renderPriorityLevel) { legacyErrorBoundariesThatAlreadyFailed = null; } - { + if (enableSchedulerTracing) { if (!rootDidHavePassiveEffects) { // If there are no passive effects, then we can complete the pending interactions. // Otherwise, we'll wait until after the passive effects are flushed. @@ -18633,8 +21417,8 @@ function commitBeforeMutationEffects() { if ((effectTag & Snapshot) !== NoEffect) { setCurrentFiber(nextEffect); recordEffect(); - var current = nextEffect.alternate; - commitBeforeMutationLifeCycles(current, nextEffect); + var current$$1 = nextEffect.alternate; + commitBeforeMutationLifeCycles(current$$1, nextEffect); resetCurrentFiber(); } @@ -18665,10 +21449,10 @@ function commitMutationEffects(root, renderPriorityLevel) { } if (effectTag & Ref) { - var current = nextEffect.alternate; + var current$$1 = nextEffect.alternate; - if (current !== null) { - commitDetachRef(current); + if (current$$1 !== null) { + commitDetachRef(current$$1); } } // The following switch statement is only concerned about placement, // updates, and deletions. To avoid needing to add a case for every possible @@ -18740,8 +21524,8 @@ function commitLayoutEffects(root, committedExpirationTime) { if (effectTag & (Update | Callback)) { recordEffect(); - var current = nextEffect.alternate; - commitLifeCycles(root, current, nextEffect); + var current$$1 = nextEffect.alternate; + commitLifeCycles(root, current$$1, nextEffect, committedExpirationTime); } if (effectTag & Ref) { @@ -18781,40 +21565,36 @@ function flushPassiveEffectsImpl() { var prevExecutionContext = executionContext; executionContext |= CommitContext; - var prevInteractions = pushInteractions(root); - - { - // 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 _effect2 = root.current.firstEffect; + var prevInteractions = pushInteractions(root); // 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. - while (_effect2 !== null) { - { - setCurrentFiber(_effect2); - invokeGuardedCallback(null, commitPassiveHookEffects, null, _effect2); - - if (hasCaughtError()) { - if (!(_effect2 !== null)) { - throw Error("Should be working on an effect."); - } + var effect = root.current.firstEffect; - var _error5 = clearCaughtError(); + while (effect !== null) { + { + setCurrentFiber(effect); + invokeGuardedCallback(null, commitPassiveHookEffects, null, effect); - captureCommitPhaseError(_effect2, _error5); + if (hasCaughtError()) { + if (!(effect !== null)) { + throw Error("Should be working on an effect."); } - resetCurrentFiber(); + var error = clearCaughtError(); + captureCommitPhaseError(effect, error); } - var nextNextEffect = _effect2.nextEffect; // Remove nextEffect pointer to assist GC - - _effect2.nextEffect = null; - _effect2 = nextNextEffect; + resetCurrentFiber(); } + + var nextNextEffect = effect.nextEffect; // Remove nextEffect pointer to assist GC + + effect.nextEffect = null; + effect = nextNextEffect; } - { + if (enableSchedulerTracing) { popInteractions(prevInteractions); finishPendingInteractions(root, expirationTime); } @@ -18916,7 +21696,7 @@ function pingSuspendedRoot(root, thenable, suspendedTime) { pingCache.delete(thenable); } - if (workInProgressRoot === root && renderExpirationTime$1 === suspendedTime) { + if (workInProgressRoot === root && renderExpirationTime === suspendedTime) { // Received a ping at the same priority level at which we're currently // rendering. We might want to restart this render. This should mirror // the logic of whether or not a root suspends once it completes. @@ -18936,7 +21716,7 @@ function pingSuspendedRoot(root, thenable, suspendedTime) { ) { // Restart from the root. Don't need to schedule a ping because // we're already working on this tree. - prepareFreshStack(root, renderExpirationTime$1); + prepareFreshStack(root, renderExpirationTime); } else { // Even though we can't restart right now, we might get an // opportunity later. So we mark this render as having a ping. @@ -18959,6 +21739,13 @@ function pingSuspendedRoot(root, thenable, suspendedTime) { } // Mark the time at which this ping was scheduled. root.lastPingedTime = suspendedTime; + + if (root.finishedExpirationTime === suspendedTime) { + // If there's a pending fallback waiting to commit, throw it away. + root.finishedExpirationTime = NoWork; + root.finishedWork = null; + } + ensureRootIsScheduled(root); schedulePendingInteractions(root, suspendedTime); } @@ -18986,12 +21773,45 @@ function retryTimedOutBoundary(boundaryFiber, retryTime) { schedulePendingInteractions(root, retryTime); } } + +function retryDehydratedSuspenseBoundary(boundaryFiber) { + var suspenseState = boundaryFiber.memoizedState; + var retryTime = NoWork; + + if (suspenseState !== null) { + retryTime = suspenseState.retryTime; + } + + retryTimedOutBoundary(boundaryFiber, retryTime); +} function resolveRetryThenable(boundaryFiber, thenable) { var retryTime = NoWork; // Default var retryCache; - { + if (enableSuspenseServerRenderer) { + switch (boundaryFiber.tag) { + case SuspenseComponent: + retryCache = boundaryFiber.stateNode; + var suspenseState = boundaryFiber.memoizedState; + + if (suspenseState !== null) { + retryTime = suspenseState.retryTime; + } + + break; + + case SuspenseListComponent: + retryCache = boundaryFiber.stateNode; + break; + + default: { + throw Error( + "Pinged unknown suspense boundary type. This is probably a bug in React." + ); + } + } + } else { retryCache = boundaryFiber.stateNode; } @@ -19016,16 +21836,16 @@ function jnd(timeElapsed) { return timeElapsed < 120 ? 120 : timeElapsed < 480 - ? 480 - : timeElapsed < 1080 - ? 1080 - : timeElapsed < 1920 - ? 1920 - : timeElapsed < 3000 - ? 3000 - : timeElapsed < 4320 - ? 4320 - : ceil(timeElapsed / 1960) * 1960; + ? 480 + : timeElapsed < 1080 + ? 1080 + : timeElapsed < 1920 + ? 1920 + : timeElapsed < 3000 + ? 3000 + : timeElapsed < 4320 + ? 4320 + : ceil(timeElapsed / 1960) * 1960; } function computeMsUntilSuspenseLoadingDelay( @@ -19074,8 +21894,8 @@ function checkForNestedUpdates() { { if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) { nestedPassiveUpdateCount = 0; - - error( + warning$1( + false, "Maximum update depth exceeded. This can happen when a component " + "calls setState inside useEffect, but useEffect either doesn't " + "have a dependency array, or one of the dependencies changes on " + @@ -19089,7 +21909,7 @@ function flushRenderPhaseStrictModeWarningsInDEV() { { ReactStrictModeWarnings.flushLegacyContextWarning(); - { + if (warnAboutDeprecatedLifecycles) { ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings(); } } @@ -19110,8 +21930,9 @@ function stopInterruptedWorkLoopTimer() { function checkForInterruption(fiberThatReceivedUpdate, updateExpirationTime) { if ( + enableUserTimingAPI && workInProgressRoot !== null && - updateExpirationTime > renderExpirationTime$1 + updateExpirationTime > renderExpirationTime ) { interruptedBy = fiberThatReceivedUpdate; } @@ -19129,12 +21950,11 @@ function warnAboutUpdateOnUnmountedFiberInDEV(fiber) { tag !== FunctionComponent && tag !== ForwardRef && tag !== MemoComponent && - tag !== SimpleMemoComponent && - tag !== Block + tag !== SimpleMemoComponent ) { // Only warn for user-defined components, not internal ones like Suspense. return; - } + } // We show the whole stack but dedupe on the top component's name because // the problematic code almost always lies inside that component. var componentName = getComponentName(fiber.type) || "ReactComponent"; @@ -19149,7 +21969,8 @@ function warnAboutUpdateOnUnmountedFiberInDEV(fiber) { didWarnStateUpdateForUnmountedComponent = new Set([componentName]); } - error( + warningWithoutStack$1( + false, "Can't perform a React state update on an unmounted component. This " + "is a no-op, but it indicates a memory leak in your application. To " + "fix, cancel all subscriptions and asynchronous tasks in %s.%s", @@ -19161,12 +21982,12 @@ function warnAboutUpdateOnUnmountedFiberInDEV(fiber) { } } -var beginWork$1; +var beginWork$$1; -{ +if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) { var dummyFiber = null; - beginWork$1 = function(current, unitOfWork, expirationTime) { + beginWork$$1 = function(current$$1, unitOfWork, expirationTime) { // If a component throws an error, we replay it again in a synchronously // dispatched event, so that the debugger will treat it as an uncaught // error See ReactErrorUtils for more information. @@ -19178,7 +21999,7 @@ var beginWork$1; ); try { - return beginWork(current, unitOfWork, expirationTime); + return beginWork$1(current$$1, unitOfWork, expirationTime); } catch (originalError) { if ( originalError !== null && @@ -19191,7 +22012,7 @@ var beginWork$1; // corresponding changes there. resetContextDependencies(); - resetHooksAfterThrow(); // Don't reset current debug fiber, since we're about to work on the + resetHooks(); // Don't reset current debug fiber, since we're about to work on the // same fiber again. // Unwind the failed stack frame @@ -19199,16 +22020,16 @@ var beginWork$1; assignFiberPropertiesInDEV(unitOfWork, originalWorkInProgressCopy); - if (unitOfWork.mode & ProfileMode) { + if (enableProfilerTimer && unitOfWork.mode & ProfileMode) { // Reset the profiler timer. startProfilerTimer(unitOfWork); } // Run beginWork again. invokeGuardedCallback( null, - beginWork, + beginWork$1, null, - current, + current$$1, unitOfWork, expirationTime ); @@ -19224,37 +22045,42 @@ var beginWork$1; } } }; +} else { + beginWork$$1 = beginWork$1; } var didWarnAboutUpdateInRender = false; +var didWarnAboutUpdateInGetChildContext = false; -function warnAboutRenderPhaseUpdatesInDEV(fiber) { +function warnAboutInvalidUpdatesOnClassComponentsInDEV(fiber) { { - if ((executionContext & RenderContext) !== NoContext) { - switch (fiber.tag) { - case FunctionComponent: - case ForwardRef: - case SimpleMemoComponent: { - error( - "Cannot update a component from inside the function body of a " + - "different component." - ); + if (fiber.tag === ClassComponent) { + switch (phase) { + case "getChildContext": + if (didWarnAboutUpdateInGetChildContext) { + return; + } + warningWithoutStack$1( + false, + "setState(...): Cannot call setState() inside getChildContext()" + ); + didWarnAboutUpdateInGetChildContext = true; break; - } - case ClassComponent: { - if (isRendering && !didWarnAboutUpdateInRender) { - error( - "Cannot update during an existing state transition (such as " + - "within `render`). Render methods should be a pure " + - "function of props and state." - ); - - didWarnAboutUpdateInRender = true; - break; + case "render": + if (didWarnAboutUpdateInRender) { + return; } - } + + warningWithoutStack$1( + false, + "Cannot update during an existing state transition (such as " + + "within `render`). Render methods should be a pure function of " + + "props and state." + ); + didWarnAboutUpdateInRender = true; + break; } } } @@ -19266,20 +22092,20 @@ var IsThisRendererActing = { function warnIfNotScopedWithMatchingAct(fiber) { { if ( + warnsIfNotActing === true && IsSomeRendererActing.current === true && IsThisRendererActing.current !== true ) { - error( + warningWithoutStack$1( + false, "It looks like you're using the wrong act() around your test interactions.\n" + - "Be sure to use the matching version of act() corresponding to your renderer:\n\n" + - "// for react-dom:\n" + // Break up imports to avoid accidentally parsing them as dependencies. - "import {act} fr" + - "om 'react-dom/test-utils';\n" + - "// ...\n" + - "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" + + "Be sure to use the matching version of act() corresponding to your renderer:\n\n" + + "// for react-dom:\n" + + "import {act} from 'react-dom/test-utils';\n" + + "// ...\n" + + "act(() => ...);\n\n" + + "// for react-test-renderer:\n" + + "import TestRenderer from 'react-test-renderer';\n" + "const {act} = TestRenderer;\n" + "// ...\n" + "act(() => ...);" + @@ -19292,11 +22118,13 @@ function warnIfNotScopedWithMatchingAct(fiber) { function warnIfNotCurrentlyActingEffectsInDEV(fiber) { { if ( + warnsIfNotActing === true && (fiber.mode & StrictMode) !== NoMode && IsSomeRendererActing.current === false && IsThisRendererActing.current === false ) { - error( + warningWithoutStack$1( + false, "An update to %s ran an effect, but was not wrapped in act(...).\n\n" + "When testing, code that causes React state updates should be " + "wrapped into act(...):\n\n" + @@ -19318,11 +22146,13 @@ function warnIfNotCurrentlyActingEffectsInDEV(fiber) { function warnIfNotCurrentlyActingUpdatesInDEV(fiber) { { if ( + warnsIfNotActing === true && executionContext === NoContext && IsSomeRendererActing.current === false && IsThisRendererActing.current === false ) { - error( + warningWithoutStack$1( + false, "An update to %s inside a test was not wrapped in act(...).\n\n" + "When testing, code that causes React state updates should be " + "wrapped into act(...):\n\n" + @@ -19356,19 +22186,161 @@ function warnIfUnmockedScheduler(fiber) { ) { if (fiber.mode & BlockingMode || fiber.mode & ConcurrentMode) { didWarnAboutUnmockedScheduler = true; - - error( + warningWithoutStack$1( + false, 'In Concurrent or Sync modes, the "scheduler" module needs to be mocked ' + - "to guarantee consistent behaviour across tests and browsers. " + - "For example, with jest: \n" + // Break up requires to avoid accidentally parsing them as dependencies. - "jest.mock('scheduler', () => require" + - "('scheduler/unstable_mock'));\n\n" + + "to guarantee consistent behaviour across tests and browsers. " + + "For example, with jest: \n" + + "jest.mock('scheduler', () => require('scheduler/unstable_mock'));\n\n" + + "For more info, visit https://fb.me/react-mock-scheduler" + ); + } else if (warnAboutUnmockedScheduler === true) { + didWarnAboutUnmockedScheduler = true; + warningWithoutStack$1( + false, + 'Starting from React v17, the "scheduler" module will need to be mocked ' + + "to guarantee consistent behaviour across tests and browsers. " + + "For example, with jest: \n" + + "jest.mock('scheduler', () => require('scheduler/unstable_mock'));\n\n" + "For more info, visit https://fb.me/react-mock-scheduler" ); } } } } +var componentsThatTriggeredHighPriSuspend = null; +function checkForWrongSuspensePriorityInDEV(sourceFiber) { + { + var currentPriorityLevel = getCurrentPriorityLevel(); + + if ( + (sourceFiber.mode & ConcurrentMode) !== NoEffect && + (currentPriorityLevel === UserBlockingPriority || + currentPriorityLevel === ImmediatePriority) + ) { + var workInProgressNode = sourceFiber; + + while (workInProgressNode !== null) { + // Add the component that triggered the suspense + var current$$1 = workInProgressNode.alternate; + + if (current$$1 !== null) { + // TODO: warn component that triggers the high priority + // suspend is the HostRoot + switch (workInProgressNode.tag) { + case ClassComponent: + // Loop through the component's update queue and see whether the component + // has triggered any high priority updates + var updateQueue = current$$1.updateQueue; + + if (updateQueue !== null) { + var update = updateQueue.firstUpdate; + + while (update !== null) { + var priorityLevel = update.priority; + + if ( + priorityLevel === UserBlockingPriority || + priorityLevel === ImmediatePriority + ) { + if (componentsThatTriggeredHighPriSuspend === null) { + componentsThatTriggeredHighPriSuspend = new Set([ + getComponentName(workInProgressNode.type) + ]); + } else { + componentsThatTriggeredHighPriSuspend.add( + getComponentName(workInProgressNode.type) + ); + } + + break; + } + + update = update.next; + } + } + + break; + + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: + if ( + workInProgressNode.memoizedState !== null && + workInProgressNode.memoizedState.baseUpdate !== null + ) { + var _update = workInProgressNode.memoizedState.baseUpdate; // Loop through the functional component's memoized state to see whether + // the component has triggered any high pri updates + + while (_update !== null) { + var priority = _update.priority; + + if ( + priority === UserBlockingPriority || + priority === ImmediatePriority + ) { + if (componentsThatTriggeredHighPriSuspend === null) { + componentsThatTriggeredHighPriSuspend = new Set([ + getComponentName(workInProgressNode.type) + ]); + } else { + componentsThatTriggeredHighPriSuspend.add( + getComponentName(workInProgressNode.type) + ); + } + + break; + } + + if ( + _update.next === workInProgressNode.memoizedState.baseUpdate + ) { + break; + } + + _update = _update.next; + } + } + + break; + + default: + break; + } + } + + workInProgressNode = workInProgressNode.return; + } + } + } +} + +function flushSuspensePriorityWarningInDEV() { + { + if (componentsThatTriggeredHighPriSuspend !== null) { + var componentNames = []; + componentsThatTriggeredHighPriSuspend.forEach(function(name) { + return componentNames.push(name); + }); + componentsThatTriggeredHighPriSuspend = null; + + if (componentNames.length > 0) { + warningWithoutStack$1( + false, + "%s triggered a user-blocking update that suspended." + + "\n\n" + + "The fix is to split the update into multiple parts: a user-blocking " + + "update to provide immediate feedback, and another update that " + + "triggers the bulk of the changes." + + "\n\n" + + "Refer to the documentation for useTransition to learn how " + + "to implement this pattern.", // TODO: Add link to React docs with more information, once it exists + componentNames.sort().join(", ") + ); + } + } + } +} function computeThreadID(root, expirationTime) { // Interaction threads are unique per root and expiration time. @@ -19376,6 +22348,10 @@ function computeThreadID(root, expirationTime) { } function markSpawnedWork(expirationTime) { + if (!enableSchedulerTracing) { + return; + } + if (spawnedWorkDuringRender === null) { spawnedWorkDuringRender = [expirationTime]; } else { @@ -19384,6 +22360,10 @@ function markSpawnedWork(expirationTime) { } function scheduleInteractions(root, expirationTime, interactions) { + if (!enableSchedulerTracing) { + return; + } + if (interactions.size > 0) { var pendingInteractionMap = root.pendingInteractionMap; var pendingInteractions = pendingInteractionMap.get(expirationTime); @@ -19415,10 +22395,21 @@ function scheduleInteractions(root, expirationTime, interactions) { } function schedulePendingInteractions(root, expirationTime) { + // This is called when work is scheduled on a root. + // It associates the current interactions with the newly-scheduled expiration. + // They will be restored when that expiration is later committed. + if (!enableSchedulerTracing) { + return; + } + scheduleInteractions(root, expirationTime, tracing.__interactionsRef.current); } function startWorkOnPendingInteractions(root, expirationTime) { + // This is called when new work is started on a root. + if (!enableSchedulerTracing) { + return; + } // Determine which interactions this batch of work currently includes, So that // we can accurately attribute time spent working on it, And so that cascading // work triggered during the render phase will be associated with it. @@ -19459,6 +22450,10 @@ function startWorkOnPendingInteractions(root, expirationTime) { } function finishPendingInteractions(root, committedExpirationTime) { + if (!enableSchedulerTracing) { + return; + } + var earliestRemainingTimeAfterCommit = root.firstPendingTime; var subscriber; @@ -19507,7 +22502,6 @@ function finishPendingInteractions(root, committedExpirationTime) { } } -var onScheduleFiberRoot = null; var onCommitFiberRoot = null; var onCommitFiberUnmount = null; var hasLoggedError = false; @@ -19529,7 +22523,8 @@ function injectInternals(internals) { if (!hook.supportsFiber) { { - error( + warningWithoutStack$1( + false, "The installed version of React DevTools is too old and will not work " + "with the current version of React. Please update React DevTools. " + "https://fb.me/react-devtools" @@ -19542,23 +22537,6 @@ function injectInternals(internals) { try { var rendererID = hook.inject(internals); // We have successfully injected, so now it is safe to set up hooks. - if (true) { - // Only used by Fast Refresh - if (typeof hook.onScheduleFiberRoot === "function") { - onScheduleFiberRoot = function(root, children) { - try { - hook.onScheduleFiberRoot(rendererID, root, children); - } catch (err) { - if (true && !hasLoggedError) { - hasLoggedError = true; - - error("React instrumentation encountered an error: %s", err); - } - } - }; - } - } - onCommitFiberRoot = function(root, expirationTime) { try { var didError = (root.current.effectTag & DidCapture) === DidCapture; @@ -19574,12 +22552,13 @@ function injectInternals(internals) { hook.onCommitFiberRoot(rendererID, root, undefined, didError); } } catch (err) { - if (true) { - if (!hasLoggedError) { - hasLoggedError = true; - - error("React instrumentation encountered an error: %s", err); - } + if (true && !hasLoggedError) { + hasLoggedError = true; + warningWithoutStack$1( + false, + "React DevTools encountered an error: %s", + err + ); } } }; @@ -19588,29 +22567,29 @@ function injectInternals(internals) { try { hook.onCommitFiberUnmount(rendererID, fiber); } catch (err) { - if (true) { - if (!hasLoggedError) { - hasLoggedError = true; - - error("React instrumentation encountered an error: %s", err); - } + if (true && !hasLoggedError) { + hasLoggedError = true; + warningWithoutStack$1( + false, + "React DevTools encountered an error: %s", + err + ); } } }; } catch (err) { // Catch all errors because it is unsafe to throw during initialization. { - error("React instrumentation encountered an error: %s.", err); + warningWithoutStack$1( + false, + "React DevTools encountered an error: %s.", + err + ); } } // DevTools exists return true; } -function onScheduleRoot(root, children) { - if (typeof onScheduleFiberRoot === "function") { - onScheduleFiberRoot(root, children); - } -} function onCommitRoot(root, expirationTime) { if (typeof onCommitFiberRoot === "function") { onCommitFiberRoot(root, expirationTime); @@ -19672,7 +22651,7 @@ function FiberNode(tag, pendingProps, key, mode) { this.childExpirationTime = NoWork; this.alternate = null; - { + if (enableProfilerTimer) { // Note: The following is done to avoid a v8 performance cliff. // // Initializing the fields below to smis and later updating them with @@ -19699,7 +22678,7 @@ function FiberNode(tag, pendingProps, key, mode) { } // This is normally DEV-only except www when it adds listeners. // TODO: remove the User Timing integration in favor of Root Events. - { + if (enableUserTimingAPI) { this._debugID = debugCounter++; this._debugIsCurrentlyTiming = false; } @@ -19763,7 +22742,7 @@ function resolveLazyComponentTag(Component) { return IndeterminateComponent; } // This is used to create an alternate fiber to do work on. -function createWorkInProgress(current, pendingProps) { +function createWorkInProgress(current, pendingProps, expirationTime) { var workInProgress = current.alternate; if (workInProgress === null) { @@ -19784,10 +22763,7 @@ function createWorkInProgress(current, pendingProps) { { // DEV-only fields - { - workInProgress._debugID = current._debugID; - } - + workInProgress._debugID = current._debugID; workInProgress._debugSource = current._debugSource; workInProgress._debugOwner = current._debugOwner; workInProgress._debugHookTypes = current._debugHookTypes; @@ -19805,7 +22781,7 @@ function createWorkInProgress(current, pendingProps) { workInProgress.firstEffect = null; workInProgress.lastEffect = null; - { + if (enableProfilerTimer) { // We intentionally reset, rather than copy, actualDuration & actualStartTime. // This prevents time from endlessly accumulating in new commits. // This has the downside of resetting values for different priority renders, @@ -19837,7 +22813,7 @@ function createWorkInProgress(current, pendingProps) { workInProgress.index = current.index; workInProgress.ref = current.ref; - { + if (enableProfilerTimer) { workInProgress.selfBaseDuration = current.selfBaseDuration; workInProgress.treeBaseDuration = current.treeBaseDuration; } @@ -19859,6 +22835,9 @@ function createWorkInProgress(current, pendingProps) { case ForwardRef: workInProgress.type = resolveForwardRefForHotReloading(current.type); break; + + default: + break; } } @@ -19891,7 +22870,7 @@ function resetWorkInProgress(workInProgress, renderExpirationTime) { workInProgress.updateQueue = null; workInProgress.dependencies = null; - { + if (enableProfilerTimer) { // Note: We don't reset the actualTime counts. It's useful to accumulate // actual time across multiple render passes. workInProgress.selfBaseDuration = 0; @@ -19917,7 +22896,7 @@ function resetWorkInProgress(workInProgress, renderExpirationTime) { responders: currentDependencies.responders }; - { + if (enableProfilerTimer) { // Note: We don't reset the actualTime counts. It's useful to accumulate // actual time across multiple render passes. workInProgress.selfBaseDuration = current.selfBaseDuration; @@ -19938,7 +22917,7 @@ function createHostRootFiber(tag) { mode = NoMode; } - if (isDevToolsPresent) { + if (enableProfilerTimer && isDevToolsPresent) { // Always collect profile timings when DevTools are present. // This enables DevTools to start capturing timing at any point– // Without some nodes in the tree having empty base times. @@ -20038,9 +23017,29 @@ function createFiberFromTypeAndProps( resolvedType = null; break getTag; - case REACT_BLOCK_TYPE: - fiberTag = Block; - break getTag; + case REACT_FUNDAMENTAL_TYPE: + if (enableFundamentalAPI) { + return createFiberFromFundamental( + type, + pendingProps, + mode, + expirationTime, + key + ); + } + + break; + + case REACT_SCOPE_TYPE: + if (enableScopeAPI) { + return createFiberFromScope( + type, + pendingProps, + mode, + expirationTime, + key + ); + } } } @@ -20115,11 +23114,38 @@ function createFiberFromFragment(elements, mode, expirationTime, key) { fiber.expirationTime = expirationTime; return fiber; } +function createFiberFromFundamental( + fundamentalComponent, + pendingProps, + mode, + expirationTime, + key +) { + var fiber = createFiber(FundamentalComponent, pendingProps, key, mode); + fiber.elementType = fundamentalComponent; + fiber.type = fundamentalComponent; + fiber.expirationTime = expirationTime; + return fiber; +} + +function createFiberFromScope(scope, pendingProps, mode, expirationTime, key) { + var fiber = createFiber(ScopeComponent, pendingProps, key, mode); + fiber.type = scope; + fiber.elementType = scope; + fiber.expirationTime = expirationTime; + return fiber; +} function createFiberFromProfiler(pendingProps, mode, expirationTime, key) { { - if (typeof pendingProps.id !== "string") { - error('Profiler must specify an "id" as a prop'); + if ( + typeof pendingProps.id !== "string" || + typeof pendingProps.onRender !== "function" + ) { + warningWithoutStack$1( + false, + 'Profiler must specify an "id" string and "onRender" function as props' + ); } } @@ -20128,14 +23154,6 @@ function createFiberFromProfiler(pendingProps, mode, expirationTime, key) { fiber.elementType = REACT_PROFILER_TYPE; fiber.type = REACT_PROFILER_TYPE; fiber.expirationTime = expirationTime; - - { - fiber.stateNode = { - effectDuration: 0, - passiveEffectDuration: 0 - }; - } - return fiber; } @@ -20168,6 +23186,18 @@ function createFiberFromText(content, mode, expirationTime) { fiber.expirationTime = expirationTime; return fiber; } +function createFiberFromHostInstanceForDeletion() { + var fiber = createFiber(HostComponent, null, null, NoMode); // TODO: These should not need a type. + + fiber.elementType = "DELETED"; + fiber.type = "DELETED"; + return fiber; +} +function createFiberFromDehydratedFragment(dehydratedNode) { + var fiber = createFiber(DehydratedFragment, null, null, NoMode); + fiber.stateNode = dehydratedNode; + return fiber; +} function createFiberFromPortal(portal, mode, expirationTime) { var pendingProps = portal.children !== null ? portal.children : []; var fiber = createFiber(HostPortal, pendingProps, portal.key, mode); @@ -20216,20 +23246,17 @@ function assignFiberPropertiesInDEV(target, source) { target.childExpirationTime = source.childExpirationTime; target.alternate = source.alternate; - { + if (enableProfilerTimer) { target.actualDuration = source.actualDuration; target.actualStartTime = source.actualStartTime; target.selfBaseDuration = source.selfBaseDuration; target.treeBaseDuration = source.treeBaseDuration; } - { - target._debugID = source._debugID; - target._debugIsCurrentlyTiming = source._debugIsCurrentlyTiming; - } - + target._debugID = source._debugID; target._debugSource = source._debugSource; target._debugOwner = source._debugOwner; + target._debugIsCurrentlyTiming = source._debugIsCurrentlyTiming; target._debugNeedsRemount = source._debugNeedsRemount; target._debugHookTypes = source._debugHookTypes; return target; @@ -20256,21 +23283,28 @@ function FiberRootNode(containerInfo, tag, hydrate) { this.lastPingedTime = NoWork; this.lastExpiredTime = NoWork; - { + if (enableSchedulerTracing) { this.interactionThreadID = tracing.unstable_getThreadID(); this.memoizedInteractions = new Set(); this.pendingInteractionMap = new Map(); } + + if (enableSuspenseCallback) { + this.hydrationCallbacks = null; + } } function createFiberRoot(containerInfo, tag, hydrate, hydrationCallbacks) { var root = new FiberRootNode(containerInfo, tag, hydrate); + + if (enableSuspenseCallback) { + root.hydrationCallbacks = hydrationCallbacks; + } // Cyclic construction. This cheats the type system right now because // stateNode is any. var uninitializedFiber = createHostRootFiber(tag); root.current = uninitializedFiber; uninitializedFiber.stateNode = root; - initializeUpdateQueue(uninitializedFiber); return root; } function isRootSuspendedAtTime(root, expirationTime) { @@ -20364,6 +23398,15 @@ function markRootExpiredAtTime(root, expirationTime) { } } +// This lets us hook into Fiber to debug what it's doing. +// See https://github.com/facebook/react/pull/8033. +// This is not part of the public API, not even for React DevTools. +// You may only inject a debugTool if you work on React Fiber itself. +var ReactFiberInstrumentation = { + debugTool: null +}; +var ReactFiberInstrumentation_1 = ReactFiberInstrumentation; + var didWarnAboutNestedUpdates; var didWarnAboutFindNodeInStrictMode; @@ -20380,15 +23423,42 @@ function getContextForSubtree(parentComponent) { var fiber = get(parentComponent); var parentContext = findCurrentUnmaskedContext(fiber); - if (fiber.tag === ClassComponent) { - var Component = fiber.type; + if (fiber.tag === ClassComponent) { + var Component = fiber.type; + + if (isContextProvider(Component)) { + return processChildContext(fiber, Component, parentContext); + } + } + + return parentContext; +} + +function findHostInstance(component) { + var fiber = get(component); + + if (fiber === undefined) { + if (typeof component.render === "function") { + { + throw Error("Unable to find node on an unmounted component."); + } + } else { + { + throw Error( + "Argument appears to not be a ReactComponent. Keys: " + + Object.keys(component) + ); + } + } + } + + var hostFiber = findCurrentHostFiber(fiber); - if (isContextProvider(Component)) { - return processChildContext(fiber, Component, parentContext); - } + if (hostFiber === null) { + return null; } - return parentContext; + return hostFiber.stateNode; } function findHostInstanceWithWarning(component, methodName) { @@ -20423,7 +23493,8 @@ function findHostInstanceWithWarning(component, methodName) { didWarnAboutFindNodeInStrictMode[componentName] = true; if (fiber.mode & StrictMode) { - error( + warningWithoutStack$1( + false, "%s is deprecated in StrictMode. " + "%s was passed an instance of %s which is inside StrictMode. " + "Instead, add a ref directly to the element you want to reference. " + @@ -20435,7 +23506,8 @@ function findHostInstanceWithWarning(component, methodName) { getStackByFiberInDevAndProd(hostFiber) ); } else { - error( + warningWithoutStack$1( + false, "%s is deprecated in StrictMode. " + "%s was passed an instance of %s which renders StrictMode children. " + "Instead, add a ref directly to the element you want to reference. " + @@ -20452,33 +23524,44 @@ function findHostInstanceWithWarning(component, methodName) { return hostFiber.stateNode; } + + return findHostInstance(component); } function createContainer(containerInfo, tag, hydrate, hydrationCallbacks) { - return createFiberRoot(containerInfo, tag, hydrate); + return createFiberRoot(containerInfo, tag, hydrate, hydrationCallbacks); } function updateContainer(element, container, parentComponent, callback) { - { - onScheduleRoot(container, element); - } - - var current$1 = container.current; + var current$$1 = container.current; var currentTime = requestCurrentTimeForUpdate(); { // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests if ("undefined" !== typeof jest) { - warnIfUnmockedScheduler(current$1); - warnIfNotScopedWithMatchingAct(current$1); + warnIfUnmockedScheduler(current$$1); + warnIfNotScopedWithMatchingAct(current$$1); } } var suspenseConfig = requestCurrentSuspenseConfig(); var expirationTime = computeExpirationForFiber( currentTime, - current$1, + current$$1, suspenseConfig ); + + { + if (ReactFiberInstrumentation_1.debugTool) { + if (current$$1.alternate === null) { + ReactFiberInstrumentation_1.debugTool.onMountContainer(container); + } else if (element === null) { + ReactFiberInstrumentation_1.debugTool.onUnmountContainer(container); + } else { + ReactFiberInstrumentation_1.debugTool.onUpdateContainer(container); + } + } + } + var context = getContextForSubtree(parentComponent); if (container.context === null) { @@ -20488,10 +23571,10 @@ function updateContainer(element, container, parentComponent, callback) { } { - if (isRendering && current !== null && !didWarnAboutNestedUpdates) { + if (phase === "render" && current !== null && !didWarnAboutNestedUpdates) { didWarnAboutNestedUpdates = true; - - error( + warningWithoutStack$1( + false, "Render methods should be a pure function of props and state; " + "triggering nested component updates from render is not allowed. " + "If necessary, trigger nested updates in componentDidUpdate.\n\n" + @@ -20510,21 +23593,19 @@ function updateContainer(element, container, parentComponent, callback) { callback = callback === undefined ? null : callback; if (callback !== null) { - { - if (typeof callback !== "function") { - error( + !(typeof callback === "function") + ? warningWithoutStack$1( + false, "render(...): Expected the last optional `callback` argument to be a " + "function. Instead received: %s.", callback - ); - } - } - + ) + : void 0; update.callback = callback; } - enqueueUpdate(current$1, update); - scheduleWork(current$1, expirationTime); + enqueueUpdate(current$$1, update); + scheduleWork(current$$1, expirationTime); return expirationTime; } function getPublicRootInstance(container) { @@ -20547,145 +23628,699 @@ var shouldSuspendImpl = function(fiber) { return false; }; -function shouldSuspend(fiber) { - return shouldSuspendImpl(fiber); -} -var overrideHookState = null; -var overrideProps = null; -var scheduleUpdate = null; -var setSuspenseHandler = null; +function shouldSuspend(fiber) { + return shouldSuspendImpl(fiber); +} +var overrideHookState = null; +var overrideProps = null; +var scheduleUpdate = null; +var setSuspenseHandler = null; + +{ + var copyWithSetImpl = function(obj, path, idx, value) { + if (idx >= path.length) { + return value; + } + + var key = path[idx]; + var updated = Array.isArray(obj) ? obj.slice() : Object.assign({}, obj); // $FlowFixMe number or string is fine here + + updated[key] = copyWithSetImpl(obj[key], path, idx + 1, value); + return updated; + }; + + var copyWithSet = function(obj, path, value) { + return copyWithSetImpl(obj, path, 0, value); + }; // Support DevTools editable values for useState and useReducer. + + overrideHookState = function(fiber, id, path, value) { + // For now, the "id" of stateful hooks is just the stateful hook index. + // This may change in the future with e.g. nested hooks. + var currentHook = fiber.memoizedState; + + while (currentHook !== null && id > 0) { + currentHook = currentHook.next; + id--; + } + + if (currentHook !== null) { + var newState = copyWithSet(currentHook.memoizedState, path, value); + currentHook.memoizedState = newState; + currentHook.baseState = newState; // We aren't actually adding an update to the queue, + // because there is no update we can add for useReducer hooks that won't trigger an error. + // (There's no appropriate action type for DevTools overrides.) + // As a result though, React will see the scheduled update as a noop and bailout. + // Shallow cloning props works as a workaround for now to bypass the bailout check. + + fiber.memoizedProps = Object.assign({}, fiber.memoizedProps); + scheduleWork(fiber, Sync); + } + }; // Support DevTools props for function components, forwardRef, memo, host components, etc. + + overrideProps = function(fiber, path, value) { + fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value); + + if (fiber.alternate) { + fiber.alternate.pendingProps = fiber.pendingProps; + } + + scheduleWork(fiber, Sync); + }; + + scheduleUpdate = function(fiber) { + scheduleWork(fiber, Sync); + }; + + setSuspenseHandler = function(newShouldSuspendImpl) { + shouldSuspendImpl = newShouldSuspendImpl; + }; +} + +function injectIntoDevTools(devToolsConfig) { + var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance; + var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher; + return injectInternals( + Object.assign({}, devToolsConfig, { + overrideHookState: overrideHookState, + overrideProps: overrideProps, + setSuspenseHandler: setSuspenseHandler, + scheduleUpdate: scheduleUpdate, + currentDispatcherRef: ReactCurrentDispatcher, + findHostInstanceByFiber: function(fiber) { + var hostFiber = findCurrentHostFiber(fiber); + + if (hostFiber === null) { + return null; + } + + return hostFiber.stateNode; + }, + findFiberByHostInstance: function(instance) { + if (!findFiberByHostInstance) { + // Might not be implemented by the renderer. + return null; + } + + return findFiberByHostInstance(instance); + }, + // React Refresh + findHostInstancesForRefresh: findHostInstancesForRefresh, + scheduleRefresh: scheduleRefresh, + scheduleRoot: scheduleRoot, + setRefreshHandler: setRefreshHandler, + // Enables DevTools to append owner stacks to error messages in DEV mode. + getCurrentFiber: function() { + return current; + } + }) + ); +} + +// This file intentionally does *not* have the Flow annotation. +// Don't add it. See `./inline-typed.js` for an explanation. + +function createPortal( + children, + containerInfo, // TODO: figure out the API for cross-renderer implementation. + implementation +) { + var key = + arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null; + return { + // This tag allow us to uniquely identify this as a React Portal + $$typeof: REACT_PORTAL_TYPE, + key: key == null ? null : "" + key, + children: children, + containerInfo: containerInfo, + implementation: implementation + }; +} + +// TODO: this is special because it gets imported during build. + +var ReactVersion = "16.11.0"; + +var NativeMethodsMixin = function(findNodeHandle, findHostInstance) { + /** + * `NativeMethodsMixin` provides methods to access the underlying native + * component directly. This can be useful in cases when you want to focus + * a view or measure its on-screen dimensions, for example. + * + * The methods described here are available on most of the default components + * provided by React Native. Note, however, that they are *not* available on + * composite components that aren't directly backed by a native view. This will + * generally include most components that you define in your own app. For more + * information, see [Direct + * Manipulation](docs/direct-manipulation.html). + * + * Note the Flow $Exact<> syntax is required to support mixins. + * React createClass mixins can only be used with exact types. + */ + var NativeMethodsMixin = { + /** + * Determines the location on screen, width, and height of the given view and + * returns the values via an async callback. If successful, the callback will + * be called with the following arguments: + * + * - x + * - y + * - width + * - height + * - pageX + * - pageY + * + * Note that these measurements are not available until after the rendering + * has been completed in native. If you need the measurements as soon as + * possible, consider using the [`onLayout` + * prop](docs/view.html#onlayout) instead. + */ + measure: function(callback) { + var maybeInstance; // Fiber errors if findNodeHandle is called for an umounted component. + // Tests using ReactTestRenderer will trigger this case indirectly. + // Mimicking stack behavior, we should silently ignore this case. + // TODO Fix ReactTestRenderer so we can remove this try/catch. + + try { + maybeInstance = findHostInstance(this); + } catch (error) {} // If there is no host component beneath this we should fail silently. + // This is not an error; it could mean a class component rendered null. + + if (maybeInstance == null) { + return; + } + + if (maybeInstance.canonical) { + // We can't call FabricUIManager here because it won't be loaded in paper + // at initialization time. See https://github.com/facebook/react/pull/15490 + // for more info. + nativeFabricUIManager.measure( + maybeInstance.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ); + } else { + ReactNativePrivateInterface.UIManager.measure( + findNodeHandle(this), + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ); + } + }, + + /** + * Determines the location of the given view in the window and returns the + * values via an async callback. If the React root view is embedded in + * another native view, this will give you the absolute coordinates. If + * successful, the callback will be called with the following + * arguments: + * + * - x + * - y + * - width + * - height + * + * Note that these measurements are not available until after the rendering + * has been completed in native. + */ + measureInWindow: function(callback) { + var maybeInstance; // Fiber errors if findNodeHandle is called for an umounted component. + // Tests using ReactTestRenderer will trigger this case indirectly. + // Mimicking stack behavior, we should silently ignore this case. + // TODO Fix ReactTestRenderer so we can remove this try/catch. + + try { + maybeInstance = findHostInstance(this); + } catch (error) {} // If there is no host component beneath this we should fail silently. + // This is not an error; it could mean a class component rendered null. + + if (maybeInstance == null) { + return; + } + + if (maybeInstance.canonical) { + // We can't call FabricUIManager here because it won't be loaded in paper + // at initialization time. See https://github.com/facebook/react/pull/15490 + // for more info. + nativeFabricUIManager.measureInWindow( + maybeInstance.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ); + } else { + ReactNativePrivateInterface.UIManager.measureInWindow( + findNodeHandle(this), + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ); + } + }, + + /** + * Like [`measure()`](#measure), but measures the view relative an ancestor, + * specified as `relativeToNativeNode`. This means that the returned x, y + * are relative to the origin x, y of the ancestor view. + * + * As always, to obtain a native node handle for a component, you can use + * `findNodeHandle(component)`. + */ + measureLayout: function( + relativeToNativeNode, + onSuccess, + onFail + ) /* currently unused */ + { + var maybeInstance; // Fiber errors if findNodeHandle is called for an umounted component. + // Tests using ReactTestRenderer will trigger this case indirectly. + // Mimicking stack behavior, we should silently ignore this case. + // TODO Fix ReactTestRenderer so we can remove this try/catch. + + try { + maybeInstance = findHostInstance(this); + } catch (error) {} // If there is no host component beneath this we should fail silently. + // This is not an error; it could mean a class component rendered null. + + if (maybeInstance == null) { + return; + } + + if (maybeInstance.canonical) { + warningWithoutStack$1( + false, + "Warning: measureLayout on components using NativeMethodsMixin " + + "or ReactNative.NativeComponent is not currently supported in Fabric. " + + "measureLayout must be called on a native ref. Consider using forwardRef." + ); + return; + } else { + var relativeNode; + + if (typeof relativeToNativeNode === "number") { + // Already a node handle + relativeNode = relativeToNativeNode; + } else if (relativeToNativeNode._nativeTag) { + relativeNode = relativeToNativeNode._nativeTag; + } + + if (relativeNode == null) { + warningWithoutStack$1( + false, + "Warning: ref.measureLayout must be called with a node handle or a ref to a native component." + ); + return; + } + + ReactNativePrivateInterface.UIManager.measureLayout( + findNodeHandle(this), + relativeNode, + mountSafeCallback_NOT_REALLY_SAFE(this, onFail), + mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) + ); + } + }, + + /** + * This function sends props straight to native. They will not participate in + * future diff process - this means that if you do not include them in the + * next render, they will remain active (see [Direct + * Manipulation](docs/direct-manipulation.html)). + */ + setNativeProps: function(nativeProps) { + // Class components don't have viewConfig -> validateAttributes. + // Nor does it make sense to set native props on a non-native component. + // Instead, find the nearest host component and set props on it. + // Use findNodeHandle() rather than findNodeHandle() because + // We want the instance/wrapper (not the native tag). + var maybeInstance; // Fiber errors if findNodeHandle is called for an umounted component. + // Tests using ReactTestRenderer will trigger this case indirectly. + // Mimicking stack behavior, we should silently ignore this case. + // TODO Fix ReactTestRenderer so we can remove this try/catch. + + try { + maybeInstance = findHostInstance(this); + } catch (error) {} // If there is no host component beneath this we should fail silently. + // This is not an error; it could mean a class component rendered null. + + if (maybeInstance == null) { + return; + } + + if (maybeInstance.canonical) { + warningWithoutStack$1( + false, + "Warning: setNativeProps is not currently supported in Fabric" + ); + return; + } + + var nativeTag = + maybeInstance._nativeTag || maybeInstance.canonical._nativeTag; + var viewConfig = + maybeInstance.viewConfig || maybeInstance.canonical.viewConfig; + + { + warnForStyleProps(nativeProps, viewConfig.validAttributes); + } + + var updatePayload = create(nativeProps, 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( + nativeTag, + viewConfig.uiViewClassName, + updatePayload + ); + } + }, + + /** + * Requests focus for the given input or view. The exact behavior triggered + * will depend on the platform and type of view. + */ + focus: function() { + ReactNativePrivateInterface.TextInputState.focusTextInput( + findNodeHandle(this) + ); + }, + + /** + * Removes focus from an input or view. This is the opposite of `focus()`. + */ + blur: function() { + ReactNativePrivateInterface.TextInputState.blurTextInput( + findNodeHandle(this) + ); + } + }; + + { + // hide this from Flow since we can't define these properties outside of + // true without actually implementing them (setting them to undefined + // isn't allowed by ReactClass) + var NativeMethodsMixin_DEV = NativeMethodsMixin; + + if ( + !( + !NativeMethodsMixin_DEV.componentWillMount && + !NativeMethodsMixin_DEV.componentWillReceiveProps && + !NativeMethodsMixin_DEV.UNSAFE_componentWillMount && + !NativeMethodsMixin_DEV.UNSAFE_componentWillReceiveProps + ) + ) { + throw Error("Do not override existing functions."); + } // TODO (bvaughn) Remove cWM and cWRP in a future version of React Native, + // Once these lifecycles have been remove from the reconciler. + + NativeMethodsMixin_DEV.componentWillMount = function() { + throwOnStylesProp(this, this.props); + }; + + NativeMethodsMixin_DEV.componentWillReceiveProps = function(newProps) { + throwOnStylesProp(this, newProps); + }; + + NativeMethodsMixin_DEV.UNSAFE_componentWillMount = function() { + throwOnStylesProp(this, this.props); + }; + + NativeMethodsMixin_DEV.UNSAFE_componentWillReceiveProps = function( + newProps + ) { + throwOnStylesProp(this, newProps); + }; // React may warn about cWM/cWRP/cWU methods being deprecated. + // Add a flag to suppress these warnings for this special case. + // TODO (bvaughn) Remove this flag once the above methods have been removed. + + NativeMethodsMixin_DEV.componentWillMount.__suppressDeprecationWarning = true; + NativeMethodsMixin_DEV.componentWillReceiveProps.__suppressDeprecationWarning = true; + } + + return NativeMethodsMixin; +}; + +function _inheritsLoose(subClass, superClass) { + subClass.prototype = Object.create(superClass.prototype); + subClass.prototype.constructor = subClass; + subClass.__proto__ = superClass; +} + +var ReactNativeComponent = function(findNodeHandle, findHostInstance) { + /** + * Superclass that provides methods to access the underlying native component. + * This can be useful when you want to focus a view or measure its dimensions. + * + * Methods implemented by this class are available on most default components + * provided by React Native. However, they are *not* available on composite + * components that are not directly backed by a native view. For more + * information, see [Direct Manipulation](docs/direct-manipulation.html). + * + * @abstract + */ + var ReactNativeComponent = + /*#__PURE__*/ + (function(_React$Component) { + _inheritsLoose(ReactNativeComponent, _React$Component); + + function ReactNativeComponent() { + return _React$Component.apply(this, arguments) || this; + } + + var _proto = ReactNativeComponent.prototype; + + /** + * Due to bugs in Flow's handling of React.createClass, some fields already + * declared in the base class need to be redeclared below. + */ + + /** + * Removes focus. This is the opposite of `focus()`. + */ + _proto.blur = function blur() { + ReactNativePrivateInterface.TextInputState.blurTextInput( + findNodeHandle(this) + ); + }; + /** + * Requests focus. The exact behavior depends on the platform and view. + */ -{ - var copyWithSetImpl = function(obj, path, idx, value) { - if (idx >= path.length) { - return value; - } + _proto.focus = function focus() { + ReactNativePrivateInterface.TextInputState.focusTextInput( + findNodeHandle(this) + ); + }; + /** + * Measures the on-screen location and dimensions. If successful, the callback + * will be called asynchronously with the following arguments: + * + * - x + * - y + * - width + * - height + * - pageX + * - pageY + * + * These values are not available until after natives rendering completes. If + * you need the measurements as soon as possible, consider using the + * [`onLayout` prop](docs/view.html#onlayout) instead. + */ + + _proto.measure = function measure(callback) { + var maybeInstance; // Fiber errors if findNodeHandle is called for an umounted component. + // Tests using ReactTestRenderer will trigger this case indirectly. + // Mimicking stack behavior, we should silently ignore this case. + // TODO Fix ReactTestRenderer so we can remove this try/catch. - var key = path[idx]; - var updated = Array.isArray(obj) ? obj.slice() : Object.assign({}, obj); // $FlowFixMe number or string is fine here + try { + maybeInstance = findHostInstance(this); + } catch (error) {} // If there is no host component beneath this we should fail silently. + // This is not an error; it could mean a class component rendered null. - updated[key] = copyWithSetImpl(obj[key], path, idx + 1, value); - return updated; - }; + if (maybeInstance == null) { + return; + } - var copyWithSet = function(obj, path, value) { - return copyWithSetImpl(obj, path, 0, value); - }; // Support DevTools editable values for useState and useReducer. + if (maybeInstance.canonical) { + // We can't call FabricUIManager here because it won't be loaded in paper + // at initialization time. See https://github.com/facebook/react/pull/15490 + // for more info. + nativeFabricUIManager.measure( + maybeInstance.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ); + } else { + ReactNativePrivateInterface.UIManager.measure( + findNodeHandle(this), + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ); + } + }; + /** + * Measures the on-screen location and dimensions. Even if the React Native + * root view is embedded within another native view, this method will give you + * the absolute coordinates measured from the window. If successful, the + * callback will be called asynchronously with the following arguments: + * + * - x + * - y + * - width + * - height + * + * These values are not available until after natives rendering completes. + */ + + _proto.measureInWindow = function measureInWindow(callback) { + var maybeInstance; // Fiber errors if findNodeHandle is called for an umounted component. + // Tests using ReactTestRenderer will trigger this case indirectly. + // Mimicking stack behavior, we should silently ignore this case. + // TODO Fix ReactTestRenderer so we can remove this try/catch. - overrideHookState = function(fiber, id, path, value) { - // For now, the "id" of stateful hooks is just the stateful hook index. - // This may change in the future with e.g. nested hooks. - var currentHook = fiber.memoizedState; + try { + maybeInstance = findHostInstance(this); + } catch (error) {} // If there is no host component beneath this we should fail silently. + // This is not an error; it could mean a class component rendered null. - while (currentHook !== null && id > 0) { - currentHook = currentHook.next; - id--; - } + if (maybeInstance == null) { + return; + } - if (currentHook !== null) { - var newState = copyWithSet(currentHook.memoizedState, path, value); - currentHook.memoizedState = newState; - currentHook.baseState = newState; // We aren't actually adding an update to the queue, - // because there is no update we can add for useReducer hooks that won't trigger an error. - // (There's no appropriate action type for DevTools overrides.) - // As a result though, React will see the scheduled update as a noop and bailout. - // Shallow cloning props works as a workaround for now to bypass the bailout check. + if (maybeInstance.canonical) { + // We can't call FabricUIManager here because it won't be loaded in paper + // at initialization time. See https://github.com/facebook/react/pull/15490 + // for more info. + nativeFabricUIManager.measureInWindow( + maybeInstance.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ); + } else { + ReactNativePrivateInterface.UIManager.measureInWindow( + findNodeHandle(this), + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ); + } + }; + /** + * Similar to [`measure()`](#measure), but the resulting location will be + * relative to the supplied ancestor's location. + * + * Obtain a native node handle with `ReactNative.findNodeHandle(component)`. + */ + + _proto.measureLayout = function measureLayout( + relativeToNativeNode, + onSuccess, + onFail + ) { + var maybeInstance; // Fiber errors if findNodeHandle is called for an umounted component. + // Tests using ReactTestRenderer will trigger this case indirectly. + // Mimicking stack behavior, we should silently ignore this case. + // TODO Fix ReactTestRenderer so we can remove this try/catch. - fiber.memoizedProps = Object.assign({}, fiber.memoizedProps); - scheduleWork(fiber, Sync); - } - }; // Support DevTools props for function components, forwardRef, memo, host components, etc. + try { + maybeInstance = findHostInstance(this); + } catch (error) {} // If there is no host component beneath this we should fail silently. + // This is not an error; it could mean a class component rendered null. - overrideProps = function(fiber, path, value) { - fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value); + if (maybeInstance == null) { + return; + } - if (fiber.alternate) { - fiber.alternate.pendingProps = fiber.pendingProps; - } + if (maybeInstance.canonical) { + warningWithoutStack$1( + false, + "Warning: measureLayout on components using NativeMethodsMixin " + + "or ReactNative.NativeComponent is not currently supported in Fabric. " + + "measureLayout must be called on a native ref. Consider using forwardRef." + ); + return; + } else { + var relativeNode; - scheduleWork(fiber, Sync); - }; + if (typeof relativeToNativeNode === "number") { + // Already a node handle + relativeNode = relativeToNativeNode; + } else if (relativeToNativeNode._nativeTag) { + relativeNode = relativeToNativeNode._nativeTag; + } - scheduleUpdate = function(fiber) { - scheduleWork(fiber, Sync); - }; + if (relativeNode == null) { + warningWithoutStack$1( + false, + "Warning: ref.measureLayout must be called with a node handle or a ref to a native component." + ); + return; + } - setSuspenseHandler = function(newShouldSuspendImpl) { - shouldSuspendImpl = newShouldSuspendImpl; - }; -} + ReactNativePrivateInterface.UIManager.measureLayout( + findNodeHandle(this), + relativeNode, + mountSafeCallback_NOT_REALLY_SAFE(this, onFail), + mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) + ); + } + }; + /** + * This function sends props straight to native. They will not participate in + * future diff process - this means that if you do not include them in the + * next render, they will remain active (see [Direct + * Manipulation](docs/direct-manipulation.html)). + */ + + _proto.setNativeProps = function setNativeProps(nativeProps) { + // Class components don't have viewConfig -> validateAttributes. + // Nor does it make sense to set native props on a non-native component. + // Instead, find the nearest host component and set props on it. + // Use findNodeHandle() rather than ReactNative.findNodeHandle() because + // We want the instance/wrapper (not the native tag). + var maybeInstance; // Fiber errors if findNodeHandle is called for an umounted component. + // Tests using ReactTestRenderer will trigger this case indirectly. + // Mimicking stack behavior, we should silently ignore this case. + // TODO Fix ReactTestRenderer so we can remove this try/catch. -function injectIntoDevTools(devToolsConfig) { - var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance; - var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher; - return injectInternals({ - bundleType: devToolsConfig.bundleType, - version: devToolsConfig.version, - rendererPackageName: devToolsConfig.rendererPackageName, - rendererConfig: devToolsConfig.rendererConfig, - overrideHookState: overrideHookState, - overrideProps: overrideProps, - setSuspenseHandler: setSuspenseHandler, - scheduleUpdate: scheduleUpdate, - currentDispatcherRef: ReactCurrentDispatcher, - findHostInstanceByFiber: function(fiber) { - var hostFiber = findCurrentHostFiber(fiber); - - if (hostFiber === null) { - return null; - } + try { + maybeInstance = findHostInstance(this); + } catch (error) {} // If there is no host component beneath this we should fail silently. + // This is not an error; it could mean a class component rendered null. - return hostFiber.stateNode; - }, - findFiberByHostInstance: function(instance) { - if (!findFiberByHostInstance) { - // Might not be implemented by the renderer. - return null; - } + if (maybeInstance == null) { + return; + } - return findFiberByHostInstance(instance); - }, - // React Refresh - findHostInstancesForRefresh: findHostInstancesForRefresh, - scheduleRefresh: scheduleRefresh, - scheduleRoot: scheduleRoot, - setRefreshHandler: setRefreshHandler, - // Enables DevTools to append owner stacks to error messages in DEV mode. - getCurrentFiber: function() { - return current; - } - }); -} -var IsSomeRendererActing$1 = ReactSharedInternals.IsSomeRendererActing; + if (maybeInstance.canonical) { + warningWithoutStack$1( + false, + "Warning: setNativeProps is not currently supported in Fabric" + ); + return; + } -function createPortal( - children, - containerInfo, // TODO: figure out the API for cross-renderer implementation. - implementation -) { - var key = - arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null; - return { - // This tag allow us to uniquely identify this as a React Portal - $$typeof: REACT_PORTAL_TYPE, - key: key == null ? null : "" + key, - children: children, - containerInfo: containerInfo, - implementation: implementation - }; -} + var nativeTag = + maybeInstance._nativeTag || maybeInstance.canonical._nativeTag; + var viewConfig = + maybeInstance.viewConfig || maybeInstance.canonical.viewConfig; + var updatePayload = create(nativeProps, 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( + nativeTag, + viewConfig.uiViewClassName, + updatePayload + ); + } + }; -// TODO: this is special because it gets imported during build. -var ReactVersion = "16.13.0"; + return ReactNativeComponent; + })(React.Component); // eslint-disable-next-line no-unused-expressions -var emptyObject$1 = {}; + return ReactNativeComponent; +}; + +var emptyObject$3 = {}; { - Object.freeze(emptyObject$1); + Object.freeze(emptyObject$3); } var getInspectorDataForViewTag; -var getInspectorDataForViewAtPoint; { var traverseOwnerTreeUp = function(hierarchy, instance) { @@ -20717,10 +24352,10 @@ var getInspectorDataForViewAtPoint; var host = findCurrentHostFiber(fiber); if (host) { - return host.memoizedProps || emptyObject$1; + return host.memoizedProps || emptyObject$3; } - return emptyObject$1; + return emptyObject$3; }; var getHostNode = function(fiber, findNodeHandle) { @@ -20748,65 +24383,28 @@ var getInspectorDataForViewAtPoint; name: getComponentName(fiber.type), getInspectorData: function(findNodeHandle) { return { - props: getHostProps(fiber), - source: fiber._debugSource, measure: function(callback) { - // If this is Fabric, we'll find a ShadowNode and use that to measure. - var hostFiber = findCurrentHostFiber(fiber); - var shadowNode = - hostFiber != null && - hostFiber.stateNode !== null && - hostFiber.stateNode.node; - - if (shadowNode) { - nativeFabricUIManager.measure(shadowNode, callback); - } else { - return ReactNativePrivateInterface.UIManager.measure( - getHostNode(fiber, findNodeHandle), - callback - ); - } - } + return ReactNativePrivateInterface.UIManager.measure( + getHostNode(fiber, findNodeHandle), + callback + ); + }, + props: getHostProps(fiber), + source: fiber._debugSource }; } }; }); }; - var getInspectorDataForInstance = function(closestInstance) { - // Handle case where user clicks outside of ReactNative - if (!closestInstance) { - return { - hierarchy: [], - props: emptyObject$1, - selectedIndex: null, - source: null - }; - } - - var fiber = findCurrentFiberUsingSlowPath(closestInstance); - var fiberHierarchy = getOwnerHierarchy(fiber); - var instance = lastNonHostInstance(fiberHierarchy); - var hierarchy = createHierarchy(fiberHierarchy); - var props = getHostProps(instance); - var source = instance._debugSource; - var selectedIndex = fiberHierarchy.indexOf(instance); - return { - hierarchy: hierarchy, - props: props, - selectedIndex: selectedIndex, - source: source - }; - }; - getInspectorDataForViewTag = function(viewTag) { var closestInstance = getInstanceFromTag(viewTag); // Handle case where user clicks outside of ReactNative if (!closestInstance) { return { hierarchy: [], - props: emptyObject$1, - selectedIndex: null, + props: emptyObject$3, + selection: null, source: null }; } @@ -20817,122 +24415,34 @@ var getInspectorDataForViewAtPoint; var hierarchy = createHierarchy(fiberHierarchy); var props = getHostProps(instance); var source = instance._debugSource; - var selectedIndex = fiberHierarchy.indexOf(instance); + var selection = fiberHierarchy.indexOf(instance); return { hierarchy: hierarchy, props: props, - selectedIndex: selectedIndex, + selection: selection, source: source }; }; - - getInspectorDataForViewAtPoint = function( - findNodeHandle, - inspectedView, - locationX, - locationY, - callback - ) { - var closestInstance = null; - - if (inspectedView._internalInstanceHandle != null) { - // For Fabric we can look up the instance handle directly and measure it. - nativeFabricUIManager.findNodeAtPoint( - inspectedView._internalInstanceHandle.stateNode.node, - locationX, - locationY, - function(internalInstanceHandle) { - if (internalInstanceHandle == null) { - callback( - Object.assign( - { - pointerY: locationY, - frame: { - left: 0, - top: 0, - width: 0, - height: 0 - } - }, - getInspectorDataForInstance(closestInstance) - ) - ); - } - - closestInstance = - internalInstanceHandle.stateNode.canonical._internalInstanceHandle; - nativeFabricUIManager.measure( - internalInstanceHandle.stateNode.node, - function(x, y, width, height, pageX, pageY) { - callback( - Object.assign( - { - pointerY: locationY, - frame: { - left: pageX, - top: pageY, - width: width, - height: height - } - }, - getInspectorDataForInstance(closestInstance) - ) - ); - } - ); - } - ); - } else if (inspectedView._internalFiberInstanceHandleDEV != null) { - // For Paper we fall back to the old strategy using the React tag. - ReactNativePrivateInterface.UIManager.findSubviewIn( - findNodeHandle(inspectedView), - [locationX, locationY], - function(nativeViewTag, left, top, width, height) { - var inspectorData = getInspectorDataForInstance( - getInstanceFromTag(nativeViewTag) - ); - callback( - Object.assign({}, inspectorData, { - pointerY: locationY, - frame: { - left: left, - top: top, - width: width, - height: height - }, - touchedViewTag: nativeViewTag - }) - ); - } - ); - } else { - error( - "getInspectorDataForViewAtPoint expects to receieve a host component" - ); - - return; - } - }; } -var ReactCurrentOwner$3 = ReactSharedInternals.ReactCurrentOwner; +var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner; function findHostInstance_DEPRECATED(componentOrHandle) { { - var owner = ReactCurrentOwner$3.current; + var owner = ReactCurrentOwner.current; if (owner !== null && owner.stateNode !== null) { - if (!owner.stateNode._warnedAboutRefsInRender) { - error( - "%s is accessing findNodeHandle inside its render(). " + - "render() should be a pure function of props and state. It should " + - "never access something that requires stale data from the previous " + - "render, such as refs. Move this logic to componentDidMount and " + - "componentDidUpdate instead.", - getComponentName(owner.type) || "A component" - ); - } - + !owner.stateNode._warnedAboutRefsInRender + ? warningWithoutStack$1( + false, + "%s is accessing findNodeHandle inside its render(). " + + "render() should be a pure function of props and state. It should " + + "never access something that requires stale data from the previous " + + "render, such as refs. Move this logic to componentDidMount and " + + "componentDidUpdate instead.", + getComponentName(owner.type) || "A component" + ) + : void 0; owner.stateNode._warnedAboutRefsInRender = true; } } @@ -20972,20 +24482,20 @@ function findHostInstance_DEPRECATED(componentOrHandle) { function findNodeHandle(componentOrHandle) { { - var owner = ReactCurrentOwner$3.current; + var owner = ReactCurrentOwner.current; if (owner !== null && owner.stateNode !== null) { - if (!owner.stateNode._warnedAboutRefsInRender) { - error( - "%s is accessing findNodeHandle inside its render(). " + - "render() should be a pure function of props and state. It should " + - "never access something that requires stale data from the previous " + - "render, such as refs. Move this logic to componentDidMount and " + - "componentDidUpdate instead.", - getComponentName(owner.type) || "A component" - ); - } - + !owner.stateNode._warnedAboutRefsInRender + ? warningWithoutStack$1( + false, + "%s is accessing findNodeHandle inside its render(). " + + "render() should be a pure function of props and state. It should " + + "never access something that requires stale data from the previous " + + "render, such as refs. Move this logic to componentDidMount and " + + "componentDidUpdate instead.", + getComponentName(owner.type) || "A component" + ) + : void 0; owner.stateNode._warnedAboutRefsInRender = true; } } @@ -21028,109 +24538,110 @@ function findNodeHandle(componentOrHandle) { return hostInstance._nativeTag; } -function dispatchCommand(handle, command, args) { - if (handle._nativeTag == null) { - { - error( - "dispatchCommand was called with a ref that isn't a " + - "native component. Use React.forwardRef to get access to the underlying native component" - ); - } +setBatchingImplementation( + batchedUpdates$1, + discreteUpdates$1, + flushDiscreteUpdates, + batchedEventUpdates$1 +); - return; +function computeComponentStackForErrorReporting(reactTag) { + var fiber = getInstanceFromTag(reactTag); + + if (!fiber) { + return ""; } - if (handle._internalInstanceHandle) { - nativeFabricUIManager.dispatchCommand( - handle._internalInstanceHandle.stateNode.node, - command, - args - ); - } else { + return getStackByFiberInDevAndProd(fiber); +} + +var roots = new Map(); +var ReactNativeRenderer = { + NativeComponent: ReactNativeComponent(findNodeHandle, findHostInstance), + // This is needed for implementation details of TouchableNativeFeedback + // Remove this once TouchableNativeFeedback doesn't use cloneElement + findHostInstance_DEPRECATED: findHostInstance_DEPRECATED, + findNodeHandle: findNodeHandle, + dispatchCommand: function(handle, command, args) { + if (handle._nativeTag == null) { + !(handle._nativeTag != null) + ? warningWithoutStack$1( + false, + "dispatchCommand was called with a ref that isn't a " + + "native component. Use React.forwardRef to get access to the underlying native component" + ) + : void 0; + return; + } + ReactNativePrivateInterface.UIManager.dispatchViewManagerCommand( handle._nativeTag, command, args ); - } -} - -function render(element, containerTag, callback) { - var root = roots.get(containerTag); - - 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); - roots.set(containerTag, root); - } - - updateContainer(element, root, null, callback); - return getPublicRootInstance(root); -} - -function unmountComponentAtNode(containerTag) { - var root = roots.get(containerTag); - - if (root) { - // TODO: Is it safe to reset this now or should I wait since this unmount could be deferred? - updateContainer(null, root, null, function() { - roots.delete(containerTag); - }); - } -} - -function unmountComponentAtNodeAndRemoveContainer(containerTag) { - unmountComponentAtNode(containerTag); // Call back into native to remove all of the subviews from this container - - ReactNativePrivateInterface.UIManager.removeRootView(containerTag); -} + }, + render: function(element, containerTag, callback) { + var root = roots.get(containerTag); -function createPortal$1(children, containerTag) { - var key = - arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; - return createPortal(children, containerTag, null, key); -} + 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); + roots.set(containerTag, root); + } -setBatchingImplementation(batchedUpdates$1); + updateContainer(element, root, null, callback); + return getPublicRootInstance(root); + }, + unmountComponentAtNode: function(containerTag) { + var root = roots.get(containerTag); -function computeComponentStackForErrorReporting(reactTag) { - var fiber = getInstanceFromTag(reactTag); + if (root) { + // TODO: Is it safe to reset this now or should I wait since this unmount could be deferred? + updateContainer(null, root, null, function() { + roots.delete(containerTag); + }); + } + }, + unmountComponentAtNodeAndRemoveContainer: function(containerTag) { + ReactNativeRenderer.unmountComponentAtNode(containerTag); // Call back into native to remove all of the subviews from this container - if (!fiber) { - return ""; + ReactNativePrivateInterface.UIManager.removeRootView(containerTag); + }, + createPortal: function(children, containerTag) { + var key = + arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; + return createPortal(children, containerTag, null, key); + }, + unstable_batchedUpdates: batchedUpdates, + __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: { + // Used as a mixin in many createClass-based components + NativeMethodsMixin: NativeMethodsMixin(findNodeHandle, findHostInstance), + computeComponentStackForErrorReporting: computeComponentStackForErrorReporting } - - return getStackByFiberInDevAndProd(fiber); -} - -var roots = new Map(); -var Internals = { - computeComponentStackForErrorReporting: computeComponentStackForErrorReporting }; injectIntoDevTools({ findFiberByHostInstance: getInstanceFromTag, + getInspectorDataForViewTag: getInspectorDataForViewTag, bundleType: 1, version: ReactVersion, - rendererPackageName: "react-native-renderer", - rendererConfig: { - getInspectorDataForViewTag: getInspectorDataForViewTag, - getInspectorDataForViewAtPoint: getInspectorDataForViewAtPoint.bind( - null, - findNodeHandle - ) - } + rendererPackageName: "react-native-renderer" +}); + +var ReactNativeRenderer$2 = Object.freeze({ + default: ReactNativeRenderer }); -exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = Internals; -exports.createPortal = createPortal$1; -exports.dispatchCommand = dispatchCommand; -exports.findHostInstance_DEPRECATED = findHostInstance_DEPRECATED; -exports.findNodeHandle = findNodeHandle; -exports.render = render; -exports.unmountComponentAtNode = unmountComponentAtNode; -exports.unmountComponentAtNodeAndRemoveContainer = unmountComponentAtNodeAndRemoveContainer; -exports.unstable_batchedUpdates = batchedUpdates; +var ReactNativeRenderer$3 = + (ReactNativeRenderer$2 && ReactNativeRenderer) || ReactNativeRenderer$2; + +// TODO: decide on the top-level export form. +// This is hacky but makes it work with both Rollup and Jest. + +var reactNativeRenderer = + ReactNativeRenderer$3.default || ReactNativeRenderer$3; + +module.exports = reactNativeRenderer; })(); } diff --git a/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js b/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js index f32dc562752364..c8107e4934204a 100644 --- a/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js +++ b/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js @@ -5,7 +5,6 @@ * LICENSE file in the root directory of this source tree. * * @noflow - * @nolint * @preventMunge * @generated */ @@ -15,16 +14,85 @@ require("react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore"); var ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/ReactNativePrivateInterface"), React = require("react"), Scheduler = require("scheduler"); -function getParent(inst) { - do inst = inst.return; - while (inst && 5 !== inst.tag); - return inst ? inst : null; +var eventPluginOrder = null, + namesToPlugins = {}; +function recomputePluginOrdering() { + if (eventPluginOrder) + for (var pluginName in namesToPlugins) { + var pluginModule = namesToPlugins[pluginName], + pluginIndex = eventPluginOrder.indexOf(pluginName); + if (!(-1 < pluginIndex)) + throw Error( + "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + + pluginName + + "`." + ); + if (!plugins[pluginIndex]) { + if (!pluginModule.extractEvents) + throw Error( + "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + + pluginName + + "` does not." + ); + plugins[pluginIndex] = pluginModule; + pluginIndex = pluginModule.eventTypes; + for (var eventName in pluginIndex) { + var JSCompiler_inline_result = void 0; + var dispatchConfig = pluginIndex[eventName], + pluginModule$jscomp$0 = pluginModule, + eventName$jscomp$0 = eventName; + if (eventNameDispatchConfigs.hasOwnProperty(eventName$jscomp$0)) + throw Error( + "EventPluginHub: More than one plugin attempted to publish the same event name, `" + + eventName$jscomp$0 + + "`." + ); + eventNameDispatchConfigs[eventName$jscomp$0] = dispatchConfig; + var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; + if (phasedRegistrationNames) { + for (JSCompiler_inline_result in phasedRegistrationNames) + phasedRegistrationNames.hasOwnProperty( + JSCompiler_inline_result + ) && + publishRegistrationName( + phasedRegistrationNames[JSCompiler_inline_result], + pluginModule$jscomp$0, + eventName$jscomp$0 + ); + JSCompiler_inline_result = !0; + } else + dispatchConfig.registrationName + ? (publishRegistrationName( + dispatchConfig.registrationName, + pluginModule$jscomp$0, + eventName$jscomp$0 + ), + (JSCompiler_inline_result = !0)) + : (JSCompiler_inline_result = !1); + if (!JSCompiler_inline_result) + throw Error( + "EventPluginRegistry: Failed to publish event `" + + eventName + + "` for plugin `" + + pluginName + + "`." + ); + } + } + } } -function traverseTwoPhase(inst, fn, arg) { - for (var path = []; inst; ) path.push(inst), (inst = getParent(inst)); - for (inst = path.length; 0 < inst--; ) fn(path[inst], "captured", arg); - for (inst = 0; inst < path.length; inst++) fn(path[inst], "bubbled", arg); +function publishRegistrationName(registrationName, pluginModule) { + if (registrationNameModules[registrationName]) + throw Error( + "EventPluginHub: More than one plugin attempted to publish the same registration name, `" + + registrationName + + "`." + ); + registrationNameModules[registrationName] = pluginModule; } +var plugins = [], + eventNameDispatchConfigs = {}, + registrationNameModules = {}; function invokeGuardedCallbackImpl(name, func, context, a, b, c, d, e, f) { var funcArgs = Array.prototype.slice.call(arguments, 3); try { @@ -95,6 +163,74 @@ function executeDirectDispatch(event) { event._dispatchInstances = null; return dispatchListener; } +function accumulateInto(current, next) { + if (null == next) + throw Error( + "accumulateInto(...): Accumulated items must not be null or undefined." + ); + if (null == current) return next; + if (Array.isArray(current)) { + if (Array.isArray(next)) return current.push.apply(current, next), current; + current.push(next); + return current; + } + return Array.isArray(next) ? [current].concat(next) : [current, next]; +} +function forEachAccumulated(arr, cb, scope) { + Array.isArray(arr) ? arr.forEach(cb, scope) : arr && cb.call(scope, arr); +} +var eventQueue = null; +function executeDispatchesAndReleaseTopLevel(e) { + if (e) { + var dispatchListeners = e._dispatchListeners, + dispatchInstances = e._dispatchInstances; + if (Array.isArray(dispatchListeners)) + for ( + var i = 0; + i < dispatchListeners.length && !e.isPropagationStopped(); + i++ + ) + executeDispatch(e, dispatchListeners[i], dispatchInstances[i]); + else + dispatchListeners && + executeDispatch(e, dispatchListeners, dispatchInstances); + e._dispatchListeners = null; + e._dispatchInstances = null; + e.isPersistent() || e.constructor.release(e); + } +} +var injection = { + injectEventPluginOrder: function(injectedEventPluginOrder) { + if (eventPluginOrder) + throw Error( + "EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React." + ); + eventPluginOrder = Array.prototype.slice.call(injectedEventPluginOrder); + recomputePluginOrdering(); + }, + injectEventPluginsByName: function(injectedNamesToPlugins) { + var isOrderingDirty = !1, + pluginName; + for (pluginName in injectedNamesToPlugins) + if (injectedNamesToPlugins.hasOwnProperty(pluginName)) { + var pluginModule = injectedNamesToPlugins[pluginName]; + if ( + !namesToPlugins.hasOwnProperty(pluginName) || + namesToPlugins[pluginName] !== pluginModule + ) { + if (namesToPlugins[pluginName]) + throw Error( + "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + + pluginName + + "`." + ); + namesToPlugins[pluginName] = pluginModule; + isOrderingDirty = !0; + } + } + isOrderingDirty && recomputePluginOrdering(); + } +}; function getListener(inst, registrationName) { var listener = inst.stateNode; if (!listener) return null; @@ -112,7 +248,6 @@ function getListener(inst, registrationName) { case "onMouseMoveCapture": case "onMouseUp": case "onMouseUpCapture": - case "onMouseEnter": (props = !props.disabled) || ((inst = inst.type), (props = !( @@ -137,21 +272,15 @@ function getListener(inst, registrationName) { ); return listener; } -function accumulateInto(current, next) { - if (null == next) - throw Error( - "accumulateInto(...): Accumulated items must not be null or undefined." - ); - if (null == current) return next; - if (Array.isArray(current)) { - if (Array.isArray(next)) return current.push.apply(current, next), current; - current.push(next); - return current; - } - return Array.isArray(next) ? [current].concat(next) : [current, next]; +function getParent(inst) { + do inst = inst.return; + while (inst && 5 !== inst.tag); + return inst ? inst : null; } -function forEachAccumulated(arr, cb, scope) { - Array.isArray(arr) ? arr.forEach(cb, scope) : arr && cb.call(scope, arr); +function traverseTwoPhase(inst, fn, arg) { + for (var path = []; inst; ) path.push(inst), (inst = getParent(inst)); + for (inst = path.length; 0 < inst--; ) fn(path[inst], "captured", arg); + for (inst = 0; inst < path.length; inst++) fn(path[inst], "bubbled", arg); } function accumulateDirectionalDispatches(inst, phase, event) { if ( @@ -219,8 +348,8 @@ function SyntheticEvent( ((targetInst = dispatchConfig[propName]) ? (this[propName] = targetInst(nativeEvent)) : "target" === propName - ? (this.target = nativeEventTarget) - : (this[propName] = nativeEvent[propName])); + ? (this.target = nativeEventTarget) + : (this[propName] = nativeEvent[propName])); this.isDefaultPrevented = (null != nativeEvent.defaultPrevented ? nativeEvent.defaultPrevented : !1 === nativeEvent.returnValue) @@ -373,27 +502,53 @@ function recordTouchStart(touch) { } function recordTouchMove(touch) { var touchRecord = touchBank[getTouchIdentifier(touch)]; - touchRecord && - ((touchRecord.touchActive = !0), - (touchRecord.previousPageX = touchRecord.currentPageX), - (touchRecord.previousPageY = touchRecord.currentPageY), - (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), - (touchRecord.currentPageX = touch.pageX), - (touchRecord.currentPageY = touch.pageY), - (touchRecord.currentTimeStamp = timestampForTouch(touch)), - (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))); + touchRecord + ? ((touchRecord.touchActive = !0), + (touchRecord.previousPageX = touchRecord.currentPageX), + (touchRecord.previousPageY = touchRecord.currentPageY), + (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), + (touchRecord.currentPageX = touch.pageX), + (touchRecord.currentPageY = touch.pageY), + (touchRecord.currentTimeStamp = timestampForTouch(touch)), + (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))) + : console.warn( + "Cannot record touch move without a touch start.\nTouch Move: %s\n", + "Touch Bank: %s", + printTouch(touch), + printTouchBank() + ); } function recordTouchEnd(touch) { var touchRecord = touchBank[getTouchIdentifier(touch)]; - touchRecord && - ((touchRecord.touchActive = !1), - (touchRecord.previousPageX = touchRecord.currentPageX), - (touchRecord.previousPageY = touchRecord.currentPageY), - (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), - (touchRecord.currentPageX = touch.pageX), - (touchRecord.currentPageY = touch.pageY), - (touchRecord.currentTimeStamp = timestampForTouch(touch)), - (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))); + touchRecord + ? ((touchRecord.touchActive = !1), + (touchRecord.previousPageX = touchRecord.currentPageX), + (touchRecord.previousPageY = touchRecord.currentPageY), + (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), + (touchRecord.currentPageX = touch.pageX), + (touchRecord.currentPageY = touch.pageY), + (touchRecord.currentTimeStamp = timestampForTouch(touch)), + (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))) + : console.warn( + "Cannot record touch end without a touch start.\nTouch End: %s\n", + "Touch Bank: %s", + printTouch(touch), + printTouchBank() + ); +} +function printTouch(touch) { + return JSON.stringify({ + identifier: touch.identifier, + pageX: touch.pageX, + pageY: touch.pageY, + timestamp: timestampForTouch(touch) + }); +} +function printTouchBank() { + var printed = JSON.stringify(touchBank.slice(0, 20)); + 20 < touchBank.length && + (printed += " (original size: " + touchBank.length + ")"); + return printed; } var ResponderTouchHistoryStore = { recordTouchTrack: function(topLevelType, nativeEvent) { @@ -433,10 +588,10 @@ function accumulate(current, next) { return null == current ? next : Array.isArray(current) - ? current.concat(next) - : Array.isArray(next) - ? [current].concat(next) - : [current, next]; + ? current.concat(next) + : Array.isArray(next) + ? [current].concat(next) + : [current, next]; } var responderInst = null, trackedTouchCount = 0; @@ -526,7 +681,13 @@ var eventTypes = { "topTouchCancel" === topLevelType ) if (0 <= trackedTouchCount) --trackedTouchCount; - else return null; + else + return ( + console.warn( + "Ended a touch event which was not counted in `trackedTouchCount`." + ), + null + ); ResponderTouchHistoryStore.recordTouchTrack(topLevelType, nativeEvent); if ( targetInst && @@ -538,10 +699,10 @@ var eventTypes = { var shouldSetEventType = isStartish(topLevelType) ? eventTypes.startShouldSetResponder : isMoveish(topLevelType) - ? eventTypes.moveShouldSetResponder - : "topSelectionChange" === topLevelType - ? eventTypes.selectionChangeShouldSetResponder - : eventTypes.scrollShouldSetResponder; + ? eventTypes.moveShouldSetResponder + : "topSelectionChange" === topLevelType + ? eventTypes.selectionChangeShouldSetResponder + : eventTypes.scrollShouldSetResponder; if (responderInst) b: { var JSCompiler_temp = responderInst; @@ -695,10 +856,10 @@ var eventTypes = { (shouldSetEventType = shouldSetEventType ? eventTypes.responderStart : JSCompiler_temp - ? eventTypes.responderMove - : targetInst - ? eventTypes.responderEnd - : null) + ? eventTypes.responderMove + : targetInst + ? eventTypes.responderEnd + : null) ) (shouldSetEventType = ResponderSyntheticEvent.getPooled( shouldSetEventType, @@ -761,8 +922,8 @@ var eventTypes = { (topLevelType = shouldSetEventType ? eventTypes.responderTerminate : topLevelType - ? eventTypes.responderRelease - : null) + ? eventTypes.responderRelease + : null) ) (nativeEvent = ResponderSyntheticEvent.getPooled( topLevelType, @@ -786,196 +947,89 @@ var eventTypes = { } } }, - eventPluginOrder = null, - namesToPlugins = {}; -function recomputePluginOrdering() { - if (eventPluginOrder) - for (var pluginName in namesToPlugins) { - var pluginModule = namesToPlugins[pluginName], - pluginIndex = eventPluginOrder.indexOf(pluginName); - if (!(-1 < pluginIndex)) - throw Error( - "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + - pluginName + - "`." - ); - if (!plugins[pluginIndex]) { - if (!pluginModule.extractEvents) - throw Error( - "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + - pluginName + - "` does not." - ); - plugins[pluginIndex] = pluginModule; - pluginIndex = pluginModule.eventTypes; - for (var eventName in pluginIndex) { - var JSCompiler_inline_result = void 0; - var dispatchConfig = pluginIndex[eventName], - pluginModule$jscomp$0 = pluginModule, - eventName$jscomp$0 = eventName; - if (eventNameDispatchConfigs.hasOwnProperty(eventName$jscomp$0)) - throw Error( - "EventPluginRegistry: More than one plugin attempted to publish the same event name, `" + - eventName$jscomp$0 + - "`." - ); - eventNameDispatchConfigs[eventName$jscomp$0] = dispatchConfig; - var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; - if (phasedRegistrationNames) { - for (JSCompiler_inline_result in phasedRegistrationNames) - phasedRegistrationNames.hasOwnProperty( - JSCompiler_inline_result - ) && - publishRegistrationName( - phasedRegistrationNames[JSCompiler_inline_result], - pluginModule$jscomp$0, - eventName$jscomp$0 - ); - JSCompiler_inline_result = !0; - } else - dispatchConfig.registrationName - ? (publishRegistrationName( - dispatchConfig.registrationName, - pluginModule$jscomp$0, - eventName$jscomp$0 - ), - (JSCompiler_inline_result = !0)) - : (JSCompiler_inline_result = !1); - if (!JSCompiler_inline_result) - throw Error( - "EventPluginRegistry: Failed to publish event `" + - eventName + - "` for plugin `" + - pluginName + - "`." - ); - } - } - } -} -function publishRegistrationName(registrationName, pluginModule) { - if (registrationNameModules[registrationName]) - throw Error( - "EventPluginRegistry: More than one plugin attempted to publish the same registration name, `" + - registrationName + - "`." - ); - registrationNameModules[registrationName] = pluginModule; -} -var plugins = [], - eventNameDispatchConfigs = {}, - registrationNameModules = {}, customBubblingEventTypes = ReactNativePrivateInterface.ReactNativeViewConfigRegistry .customBubblingEventTypes, customDirectEventTypes = ReactNativePrivateInterface.ReactNativeViewConfigRegistry .customDirectEventTypes; -if (eventPluginOrder) - throw Error( - "EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React." - ); -eventPluginOrder = Array.prototype.slice.call([ +injection.injectEventPluginOrder([ "ResponderEventPlugin", "ReactNativeBridgeEventPlugin" ]); -recomputePluginOrdering(); -var injectedNamesToPlugins$jscomp$inline_94 = { - ResponderEventPlugin: ResponderEventPlugin, - ReactNativeBridgeEventPlugin: { - eventTypes: {}, - extractEvents: function( - topLevelType, - targetInst, - nativeEvent, - nativeEventTarget - ) { - if (null == targetInst) return null; - var bubbleDispatchConfig = customBubblingEventTypes[topLevelType], - directDispatchConfig = customDirectEventTypes[topLevelType]; - if (!bubbleDispatchConfig && !directDispatchConfig) - throw Error( - 'Unsupported top level event type "' + topLevelType + '" dispatched' - ); - topLevelType = SyntheticEvent.getPooled( - bubbleDispatchConfig || directDispatchConfig, - targetInst, - nativeEvent, - nativeEventTarget - ); - if (bubbleDispatchConfig) - forEachAccumulated(topLevelType, accumulateTwoPhaseDispatchesSingle); - else if (directDispatchConfig) - forEachAccumulated(topLevelType, accumulateDirectDispatchesSingle); - else return null; - return topLevelType; - } - } - }, - isOrderingDirty$jscomp$inline_95 = !1, - pluginName$jscomp$inline_96; -for (pluginName$jscomp$inline_96 in injectedNamesToPlugins$jscomp$inline_94) - if ( - injectedNamesToPlugins$jscomp$inline_94.hasOwnProperty( - pluginName$jscomp$inline_96 - ) - ) { - var pluginModule$jscomp$inline_97 = - injectedNamesToPlugins$jscomp$inline_94[pluginName$jscomp$inline_96]; - if ( - !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_96) || - namesToPlugins[pluginName$jscomp$inline_96] !== - pluginModule$jscomp$inline_97 +injection.injectEventPluginsByName({ + ResponderEventPlugin: ResponderEventPlugin, + ReactNativeBridgeEventPlugin: { + eventTypes: {}, + extractEvents: function( + topLevelType, + targetInst, + nativeEvent, + nativeEventTarget ) { - if (namesToPlugins[pluginName$jscomp$inline_96]) + if (null == targetInst) return null; + var bubbleDispatchConfig = customBubblingEventTypes[topLevelType], + directDispatchConfig = customDirectEventTypes[topLevelType]; + if (!bubbleDispatchConfig && !directDispatchConfig) throw Error( - "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - pluginName$jscomp$inline_96 + - "`." + 'Unsupported top level event type "' + topLevelType + '" dispatched' ); - namesToPlugins[ - pluginName$jscomp$inline_96 - ] = pluginModule$jscomp$inline_97; - isOrderingDirty$jscomp$inline_95 = !0; + topLevelType = SyntheticEvent.getPooled( + bubbleDispatchConfig || directDispatchConfig, + targetInst, + nativeEvent, + nativeEventTarget + ); + if (bubbleDispatchConfig) + forEachAccumulated(topLevelType, accumulateTwoPhaseDispatchesSingle); + else if (directDispatchConfig) + forEachAccumulated(topLevelType, accumulateDirectDispatchesSingle); + else return null; + return topLevelType; } } -isOrderingDirty$jscomp$inline_95 && recomputePluginOrdering(); -var instanceCache = new Map(), +}); +var enableNativeTargetAsInstance = require("../shims/ReactFeatureFlags") + .enableNativeTargetAsInstance, + instanceCache = new Map(), instanceProps = new Map(); function getInstanceFromTag(tag) { return instanceCache.get(tag) || null; } -function batchedUpdatesImpl(fn, bookkeeping) { - return fn(bookkeeping); -} -var isInsideEventHandler = !1; -function batchedUpdates(fn, bookkeeping) { - if (isInsideEventHandler) return fn(bookkeeping); - isInsideEventHandler = !0; - try { - return batchedUpdatesImpl(fn, bookkeeping); - } finally { - isInsideEventHandler = !1; - } +var restoreTarget = null, + restoreQueue = null; +function restoreStateOfTarget(target) { + if (getInstanceFromNode(target)) + throw Error( + "setRestoreImplementation() needs to be called to handle a target for controlled events. This error is likely caused by a bug in React. Please file an issue." + ); } -var eventQueue = null; -function executeDispatchesAndReleaseTopLevel(e) { - if (e) { - var dispatchListeners = e._dispatchListeners, - dispatchInstances = e._dispatchInstances; - if (Array.isArray(dispatchListeners)) - for ( - var i = 0; - i < dispatchListeners.length && !e.isPropagationStopped(); - i++ +function batchedUpdatesImpl(fn, bookkeeping) { + return fn(bookkeeping); +} +function flushDiscreteUpdatesImpl() {} +var isInsideEventHandler = !1; +function batchedUpdates(fn, bookkeeping) { + if (isInsideEventHandler) return fn(bookkeeping); + isInsideEventHandler = !0; + try { + return batchedUpdatesImpl(fn, bookkeeping); + } finally { + if ( + ((isInsideEventHandler = !1), + null !== restoreTarget || null !== restoreQueue) + ) + if ( + (flushDiscreteUpdatesImpl(), + restoreTarget && + ((bookkeeping = restoreTarget), + (fn = restoreQueue), + (restoreQueue = restoreTarget = null), + restoreStateOfTarget(bookkeeping), + fn)) ) - executeDispatch(e, dispatchListeners[i], dispatchInstances[i]); - else - dispatchListeners && - executeDispatch(e, dispatchListeners, dispatchInstances); - e._dispatchListeners = null; - e._dispatchInstances = null; - e.isPersistent() || e.constructor.release(e); + for (bookkeeping = 0; bookkeeping < fn.length; bookkeeping++) + restoreStateOfTarget(fn[bookkeeping]); } } var EMPTY_NATIVE_EVENT = {}; @@ -983,7 +1037,9 @@ function _receiveRootNodeIDEvent(rootNodeID, topLevelType, nativeEventParam) { var nativeEvent = nativeEventParam || EMPTY_NATIVE_EVENT, inst = getInstanceFromTag(rootNodeID), target = null; - null != inst && (target = inst.stateNode); + enableNativeTargetAsInstance + ? null != inst && (target = inst.stateNode) + : (target = nativeEvent.target); batchedUpdates(function() { var events = target; for (var events$jscomp$0 = null, i = 0; i < plugins.length; i++) { @@ -1058,11 +1114,17 @@ getFiberCurrentPropsFromNode = function(stateNode) { }; getInstanceFromNode = getInstanceFromTag; getNodeFromInstance = function(inst) { - inst = inst.stateNode; - var tag = inst._nativeTag; - void 0 === tag && ((inst = inst.canonical), (tag = inst._nativeTag)); + if (enableNativeTargetAsInstance) { + inst = inst.stateNode; + var tag = inst._nativeTag; + void 0 === tag && ((inst = inst.canonical), (tag = inst._nativeTag)); + if (!tag) throw Error("All native instances should have a tag."); + return inst; + } + tag = inst.stateNode._nativeTag; + void 0 === tag && (tag = inst.stateNode.canonical._nativeTag); if (!tag) throw Error("All native instances should have a tag."); - return inst; + return tag; }; ResponderEventPlugin.injection.injectGlobalResponderHandler({ onChange: function(from, to, blockNativeResponder) { @@ -1097,9 +1159,11 @@ var hasSymbol = "function" === typeof Symbol && Symbol.for, ? Symbol.for("react.suspense_list") : 60120, REACT_MEMO_TYPE = hasSymbol ? Symbol.for("react.memo") : 60115, - REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 60116, - REACT_BLOCK_TYPE = hasSymbol ? Symbol.for("react.block") : 60121, - MAYBE_ITERATOR_SYMBOL = "function" === typeof Symbol && Symbol.iterator; + REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 60116; +hasSymbol && Symbol.for("react.fundamental"); +hasSymbol && Symbol.for("react.responder"); +hasSymbol && Symbol.for("react.scope"); +var MAYBE_ITERATOR_SYMBOL = "function" === typeof Symbol && Symbol.iterator; function getIteratorFn(maybeIterable) { if (null === maybeIterable || "object" !== typeof maybeIterable) return null; maybeIterable = @@ -1109,10 +1173,9 @@ function getIteratorFn(maybeIterable) { } function initializeLazyComponentType(lazyComponent) { if (-1 === lazyComponent._status) { - var ctor = lazyComponent._result; - ctor || (ctor = lazyComponent._ctor); - ctor = ctor(); lazyComponent._status = 0; + var ctor = lazyComponent._ctor; + ctor = ctor(); lazyComponent._result = ctor; ctor.then( function(moduleObject) { @@ -1149,9 +1212,9 @@ function getComponentName(type) { if ("object" === typeof type) switch (type.$$typeof) { case REACT_CONTEXT_TYPE: - return (type.displayName || "Context") + ".Consumer"; + return "Context.Consumer"; case REACT_PROVIDER_TYPE: - return (type._context.displayName || "Context") + ".Provider"; + return "Context.Provider"; case REACT_FORWARD_REF_TYPE: var innerType = type.render; innerType = innerType.displayName || innerType.name || ""; @@ -1161,8 +1224,6 @@ function getComponentName(type) { ); case REACT_MEMO_TYPE: return getComponentName(type.type); - case REACT_BLOCK_TYPE: - return getComponentName(type.render); case REACT_LAZY_TYPE: if ((type = 1 === type._status ? type._result : null)) return getComponentName(type); @@ -1343,8 +1404,8 @@ function diffNestedProperty( return nextProp ? addNestedProperty(updatePayload, nextProp, validAttributes) : prevProp - ? clearNestedProperty(updatePayload, prevProp, validAttributes) - : updatePayload; + ? clearNestedProperty(updatePayload, prevProp, validAttributes) + : updatePayload; if (!Array.isArray(prevProp) && !Array.isArray(nextProp)) return diffProperties(updatePayload, prevProp, nextProp, validAttributes); if (Array.isArray(prevProp) && Array.isArray(nextProp)) { @@ -1522,10 +1583,10 @@ var ReactNativeFiberHostComponent = (function() { } var _proto = ReactNativeFiberHostComponent.prototype; _proto.blur = function() { - ReactNativePrivateInterface.TextInputState.blurTextInput(this); + ReactNativePrivateInterface.TextInputState.blurTextInput(this._nativeTag); }; _proto.focus = function() { - ReactNativePrivateInterface.TextInputState.focusTextInput(this); + ReactNativePrivateInterface.TextInputState.focusTextInput(this._nativeTag); }; _proto.measure = function(callback) { ReactNativePrivateInterface.UIManager.measure( @@ -1569,7 +1630,7 @@ var ReactNativeFiberHostComponent = (function() { }; return ReactNativeFiberHostComponent; })(); -function shim() { +function shim$1() { throw Error( "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." ); @@ -1607,7 +1668,45 @@ function finalizeInitialChildren(parentInstance) { } var scheduleTimeout = setTimeout, cancelTimeout = clearTimeout, - valueStack = [], + BEFORE_SLASH_RE = /^(.*)[\\\/]/; +function getStackByFiberInDevAndProd(workInProgress) { + var info = ""; + do { + a: switch (workInProgress.tag) { + case 3: + case 4: + case 6: + case 7: + case 10: + case 9: + var JSCompiler_inline_result = ""; + break a; + default: + var owner = workInProgress._debugOwner, + source = workInProgress._debugSource, + name = getComponentName(workInProgress.type); + JSCompiler_inline_result = null; + owner && (JSCompiler_inline_result = getComponentName(owner.type)); + owner = name; + name = ""; + source + ? (name = + " (at " + + source.fileName.replace(BEFORE_SLASH_RE, "") + + ":" + + source.lineNumber + + ")") + : JSCompiler_inline_result && + (name = " (created by " + JSCompiler_inline_result + ")"); + JSCompiler_inline_result = "\n in " + (owner || "Unknown") + name; + } + info += JSCompiler_inline_result; + workInProgress = workInProgress.return; + } while (workInProgress); + return info; +} +new Set(); +var valueStack = [], index = -1; function pop(cursor) { 0 > index || @@ -1644,17 +1743,21 @@ function isContextProvider(type) { type = type.childContextTypes; return null !== type && void 0 !== type; } -function popContext() { - pop(didPerformWorkStackCursor); - pop(contextStackCursor); +function popContext(fiber) { + pop(didPerformWorkStackCursor, fiber); + pop(contextStackCursor, fiber); +} +function popTopLevelContextObject(fiber) { + pop(didPerformWorkStackCursor, fiber); + pop(contextStackCursor, fiber); } 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); + push(contextStackCursor, context, fiber); + push(didPerformWorkStackCursor, didChange, fiber); } function processChildContext(fiber, type, parentContext) { var instance = fiber.stateNode; @@ -1672,13 +1775,17 @@ function processChildContext(fiber, type, parentContext) { return Object.assign({}, parentContext, {}, instance); } function pushContextProvider(workInProgress) { - workInProgress = - ((workInProgress = workInProgress.stateNode) && - workInProgress.__reactInternalMemoizedMergedChildContext) || + var instance = workInProgress.stateNode; + instance = + (instance && instance.__reactInternalMemoizedMergedChildContext) || emptyContextObject; previousContext = contextStackCursor.current; - push(contextStackCursor, workInProgress); - push(didPerformWorkStackCursor, didPerformWorkStackCursor.current); + push(contextStackCursor, instance, workInProgress); + push( + didPerformWorkStackCursor, + didPerformWorkStackCursor.current, + workInProgress + ); return !0; } function invalidateContextProvider(workInProgress, type, didChange) { @@ -1688,21 +1795,18 @@ function invalidateContextProvider(workInProgress, type, didChange) { "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); + ? ((type = processChildContext(workInProgress, type, previousContext)), + (instance.__reactInternalMemoizedMergedChildContext = type), + pop(didPerformWorkStackCursor, workInProgress), + pop(contextStackCursor, workInProgress), + push(contextStackCursor, type, workInProgress)) + : pop(didPerformWorkStackCursor, workInProgress); + push(didPerformWorkStackCursor, didChange, workInProgress); } 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 = @@ -1713,7 +1817,6 @@ var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, Scheduler_LowPriority = Scheduler.unstable_LowPriority, Scheduler_IdlePriority = Scheduler.unstable_IdlePriority, fakeCallbackNode = {}, - shouldYield = Scheduler.unstable_shouldYield, requestPaint = void 0 !== Scheduler_requestPaint ? Scheduler_requestPaint : function() {}, syncQueue = null, @@ -1813,10 +1916,10 @@ function flushSyncCallbackQueueImpl() { function is(x, y) { return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y); } -var objectIs = "function" === typeof Object.is ? Object.is : is, +var is$1 = "function" === typeof Object.is ? Object.is : is, hasOwnProperty = Object.prototype.hasOwnProperty; function shallowEqual(objA, objB) { - if (objectIs(objA, objB)) return !0; + if (is$1(objA, objB)) return !0; if ( "object" !== typeof objA || null === objA || @@ -1830,48 +1933,11 @@ function shallowEqual(objA, objB) { for (keysB = 0; keysB < keysA.length; keysB++) if ( !hasOwnProperty.call(objB, keysA[keysB]) || - !objectIs(objA[keysA[keysB]], objB[keysA[keysB]]) + !is$1(objA[keysA[keysB]], objB[keysA[keysB]]) ) return !1; return !0; } -var BEFORE_SLASH_RE = /^(.*)[\\\/]/; -function getStackByFiberInDevAndProd(workInProgress) { - var info = ""; - do { - a: switch (workInProgress.tag) { - case 3: - case 4: - case 6: - case 7: - case 10: - case 9: - var JSCompiler_inline_result = ""; - break a; - default: - var owner = workInProgress._debugOwner, - source = workInProgress._debugSource, - name = getComponentName(workInProgress.type); - JSCompiler_inline_result = null; - owner && (JSCompiler_inline_result = getComponentName(owner.type)); - owner = name; - name = ""; - source - ? (name = - " (at " + - source.fileName.replace(BEFORE_SLASH_RE, "") + - ":" + - source.lineNumber + - ")") - : JSCompiler_inline_result && - (name = " (created by " + JSCompiler_inline_result + ")"); - JSCompiler_inline_result = "\n in " + (owner || "Unknown") + name; - } - info += JSCompiler_inline_result; - workInProgress = workInProgress.return; - } while (workInProgress); - return info; -} function resolveDefaultProps(Component, baseProps) { if (Component && Component.defaultProps) { baseProps = Object.assign({}, baseProps); @@ -1889,9 +1955,14 @@ var valueCursor = { current: null }, function resetContextDependencies() { lastContextWithAllBitsObserved = lastContextDependency = currentlyRenderingFiber = null; } +function pushProvider(providerFiber, nextValue) { + var context = providerFiber.type._context; + push(valueCursor, context._currentValue, providerFiber); + context._currentValue = nextValue; +} function popProvider(providerFiber) { var currentValue = valueCursor.current; - pop(valueCursor); + pop(valueCursor, providerFiber); providerFiber.type._context._currentValue = currentValue; } function scheduleWorkOnParentPath(parent, renderExpirationTime) { @@ -1946,195 +2017,237 @@ function readContext(context, observedBits) { return context._currentValue; } var hasForceUpdate = !1; -function initializeUpdateQueue(fiber) { - fiber.updateQueue = { - baseState: fiber.memoizedState, - baseQueue: null, - shared: { pending: null }, - effects: null +function createUpdateQueue(baseState) { + return { + baseState: baseState, + firstUpdate: null, + lastUpdate: null, + firstCapturedUpdate: null, + lastCapturedUpdate: null, + firstEffect: null, + lastEffect: null, + firstCapturedEffect: null, + lastCapturedEffect: null }; } -function cloneUpdateQueue(current, workInProgress) { - current = current.updateQueue; - workInProgress.updateQueue === current && - (workInProgress.updateQueue = { - baseState: current.baseState, - baseQueue: current.baseQueue, - shared: current.shared, - effects: current.effects - }); +function cloneUpdateQueue(currentQueue) { + return { + baseState: currentQueue.baseState, + firstUpdate: currentQueue.firstUpdate, + lastUpdate: currentQueue.lastUpdate, + firstCapturedUpdate: null, + lastCapturedUpdate: null, + firstEffect: null, + lastEffect: null, + firstCapturedEffect: null, + lastCapturedEffect: null + }; } function createUpdate(expirationTime, suspenseConfig) { - expirationTime = { + return { expirationTime: expirationTime, suspenseConfig: suspenseConfig, tag: 0, payload: null, callback: null, - next: null + next: null, + nextEffect: null }; - return (expirationTime.next = expirationTime); +} +function appendUpdateToQueue(queue, update) { + null === queue.lastUpdate + ? (queue.firstUpdate = queue.lastUpdate = update) + : ((queue.lastUpdate.next = update), (queue.lastUpdate = update)); } function enqueueUpdate(fiber, update) { - 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; - } + var alternate = fiber.alternate; + if (null === alternate) { + var queue1 = fiber.updateQueue; + var queue2 = null; + null === queue1 && + (queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState)); + } else + (queue1 = fiber.updateQueue), + (queue2 = alternate.updateQueue), + null === queue1 + ? null === queue2 + ? ((queue1 = fiber.updateQueue = createUpdateQueue( + fiber.memoizedState + )), + (queue2 = alternate.updateQueue = createUpdateQueue( + alternate.memoizedState + ))) + : (queue1 = fiber.updateQueue = cloneUpdateQueue(queue2)) + : null === queue2 && + (queue2 = alternate.updateQueue = cloneUpdateQueue(queue1)); + null === queue2 || queue1 === queue2 + ? appendUpdateToQueue(queue1, update) + : null === queue1.lastUpdate || null === queue2.lastUpdate + ? (appendUpdateToQueue(queue1, update), + appendUpdateToQueue(queue2, update)) + : (appendUpdateToQueue(queue1, update), (queue2.lastUpdate = update)); } function enqueueCapturedUpdate(workInProgress, update) { + var workInProgressQueue = workInProgress.updateQueue; + workInProgressQueue = + null === workInProgressQueue + ? (workInProgress.updateQueue = createUpdateQueue( + workInProgress.memoizedState + )) + : ensureWorkInProgressQueueIsAClone(workInProgress, workInProgressQueue); + null === workInProgressQueue.lastCapturedUpdate + ? (workInProgressQueue.firstCapturedUpdate = workInProgressQueue.lastCapturedUpdate = update) + : ((workInProgressQueue.lastCapturedUpdate.next = update), + (workInProgressQueue.lastCapturedUpdate = update)); +} +function ensureWorkInProgressQueueIsAClone(workInProgress, queue) { var current = workInProgress.alternate; - null !== current && cloneUpdateQueue(current, workInProgress); - workInProgress = workInProgress.updateQueue; - current = workInProgress.baseQueue; - null === current - ? ((workInProgress.baseQueue = update.next = update), - (update.next = update)) - : ((update.next = current.next), (current.next = update)); + null !== current && + queue === current.updateQueue && + (queue = workInProgress.updateQueue = cloneUpdateQueue(queue)); + return queue; +} +function getStateFromUpdate( + workInProgress, + queue, + update, + prevState, + nextProps, + instance +) { + switch (update.tag) { + case 1: + return ( + (workInProgress = update.payload), + "function" === typeof workInProgress + ? workInProgress.call(instance, prevState, nextProps) + : workInProgress + ); + case 3: + workInProgress.effectTag = (workInProgress.effectTag & -4097) | 64; + case 0: + workInProgress = update.payload; + nextProps = + "function" === typeof workInProgress + ? workInProgress.call(instance, prevState, nextProps) + : workInProgress; + if (null === nextProps || void 0 === nextProps) break; + return Object.assign({}, prevState, nextProps); + case 2: + hasForceUpdate = !0; + } + return prevState; } function processUpdateQueue( - workInProgress$jscomp$0, + workInProgress, + queue, props, instance, renderExpirationTime ) { - var queue = workInProgress$jscomp$0.updateQueue; hasForceUpdate = !1; - var baseQueue = queue.baseQueue, - pendingQueue = queue.shared.pending; - if (null !== pendingQueue) { - if (null !== baseQueue) { - var baseFirst = baseQueue.next; - baseQueue.next = pendingQueue.next; - pendingQueue.next = baseFirst; - } - baseQueue = pendingQueue; - queue.shared.pending = null; - baseFirst = workInProgress$jscomp$0.alternate; - null !== baseFirst && - ((baseFirst = baseFirst.updateQueue), - null !== baseFirst && (baseFirst.baseQueue = pendingQueue)); - } - if (null !== baseQueue) { - baseFirst = baseQueue.next; - var newState = queue.baseState, + queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue); + for ( + var newBaseState = queue.baseState, + newFirstUpdate = null, newExpirationTime = 0, - newBaseState = null, - newBaseQueueFirst = null, - newBaseQueueLast = null; - if (null !== baseFirst) { - var update = baseFirst; - do { - pendingQueue = update.expirationTime; - if (pendingQueue < renderExpirationTime) { - var clone = { - expirationTime: update.expirationTime, - suspenseConfig: update.suspenseConfig, - tag: update.tag, - payload: update.payload, - callback: update.callback, - next: null - }; - null === newBaseQueueLast - ? ((newBaseQueueFirst = newBaseQueueLast = clone), - (newBaseState = newState)) - : (newBaseQueueLast = newBaseQueueLast.next = clone); - pendingQueue > newExpirationTime && - (newExpirationTime = pendingQueue); - } else { - null !== newBaseQueueLast && - (newBaseQueueLast = newBaseQueueLast.next = { - expirationTime: 1073741823, - suspenseConfig: update.suspenseConfig, - tag: update.tag, - payload: update.payload, - callback: update.callback, - next: null - }); - markRenderEventTimeAndConfig(pendingQueue, update.suspenseConfig); - a: { - var workInProgress = workInProgress$jscomp$0, - update$jscomp$0 = update; - pendingQueue = props; - clone = instance; - switch (update$jscomp$0.tag) { - case 1: - workInProgress = update$jscomp$0.payload; - if ("function" === typeof workInProgress) { - newState = workInProgress.call(clone, newState, pendingQueue); - break a; - } - newState = workInProgress; - break a; - case 3: - workInProgress.effectTag = - (workInProgress.effectTag & -4097) | 64; - case 0: - workInProgress = update$jscomp$0.payload; - pendingQueue = - "function" === typeof workInProgress - ? workInProgress.call(clone, newState, pendingQueue) - : workInProgress; - if (null === pendingQueue || void 0 === pendingQueue) break a; - newState = Object.assign({}, newState, pendingQueue); - break a; - case 2: - hasForceUpdate = !0; - } - } - null !== update.callback && - ((workInProgress$jscomp$0.effectTag |= 32), - (pendingQueue = queue.effects), - null === pendingQueue - ? (queue.effects = [update]) - : pendingQueue.push(update)); - } - update = update.next; - if (null === update || update === baseFirst) - if (((pendingQueue = queue.shared.pending), null === pendingQueue)) - break; - else - (update = baseQueue.next = pendingQueue.next), - (pendingQueue.next = baseFirst), - (queue.baseQueue = baseQueue = pendingQueue), - (queue.shared.pending = null); - } while (1); - } - null === newBaseQueueLast - ? (newBaseState = newState) - : (newBaseQueueLast.next = newBaseQueueFirst); - queue.baseState = newBaseState; - queue.baseQueue = newBaseQueueLast; - markUnprocessedUpdateTime(newExpirationTime); - workInProgress$jscomp$0.expirationTime = newExpirationTime; - workInProgress$jscomp$0.memoizedState = newState; + update = queue.firstUpdate, + resultState = newBaseState; + null !== update; + + ) { + var updateExpirationTime = update.expirationTime; + updateExpirationTime < renderExpirationTime + ? (null === newFirstUpdate && + ((newFirstUpdate = update), (newBaseState = resultState)), + newExpirationTime < updateExpirationTime && + (newExpirationTime = updateExpirationTime)) + : (markRenderEventTimeAndConfig( + updateExpirationTime, + update.suspenseConfig + ), + (resultState = getStateFromUpdate( + workInProgress, + queue, + update, + resultState, + props, + instance + )), + null !== update.callback && + ((workInProgress.effectTag |= 32), + (update.nextEffect = null), + null === queue.lastEffect + ? (queue.firstEffect = queue.lastEffect = update) + : ((queue.lastEffect.nextEffect = update), + (queue.lastEffect = update)))); + update = update.next; + } + updateExpirationTime = null; + for (update = queue.firstCapturedUpdate; null !== update; ) { + var _updateExpirationTime = update.expirationTime; + _updateExpirationTime < renderExpirationTime + ? (null === updateExpirationTime && + ((updateExpirationTime = update), + null === newFirstUpdate && (newBaseState = resultState)), + newExpirationTime < _updateExpirationTime && + (newExpirationTime = _updateExpirationTime)) + : ((resultState = getStateFromUpdate( + workInProgress, + queue, + update, + resultState, + props, + instance + )), + null !== update.callback && + ((workInProgress.effectTag |= 32), + (update.nextEffect = null), + null === queue.lastCapturedEffect + ? (queue.firstCapturedEffect = queue.lastCapturedEffect = update) + : ((queue.lastCapturedEffect.nextEffect = update), + (queue.lastCapturedEffect = update)))); + update = update.next; } + null === newFirstUpdate && (queue.lastUpdate = null); + null === updateExpirationTime + ? (queue.lastCapturedUpdate = null) + : (workInProgress.effectTag |= 32); + null === newFirstUpdate && + null === updateExpirationTime && + (newBaseState = resultState); + queue.baseState = newBaseState; + queue.firstUpdate = newFirstUpdate; + queue.firstCapturedUpdate = updateExpirationTime; + markUnprocessedUpdateTime(newExpirationTime); + workInProgress.expirationTime = newExpirationTime; + workInProgress.memoizedState = resultState; } function commitUpdateQueue(finishedWork, finishedQueue, instance) { - finishedWork = finishedQueue.effects; - finishedQueue.effects = null; - if (null !== finishedWork) - for ( - finishedQueue = 0; - finishedQueue < finishedWork.length; - finishedQueue++ - ) { - var effect = finishedWork[finishedQueue], - callback = effect.callback; - if (null !== callback) { - effect.callback = null; - if ("function" !== typeof callback) - throw Error( - "Invalid argument passed as callback. Expected a function. Instead received: " + - callback - ); - callback.call(instance); - } + null !== finishedQueue.firstCapturedUpdate && + (null !== finishedQueue.lastUpdate && + ((finishedQueue.lastUpdate.next = finishedQueue.firstCapturedUpdate), + (finishedQueue.lastUpdate = finishedQueue.lastCapturedUpdate)), + (finishedQueue.firstCapturedUpdate = finishedQueue.lastCapturedUpdate = null)); + commitUpdateEffects(finishedQueue.firstEffect, instance); + finishedQueue.firstEffect = finishedQueue.lastEffect = null; + commitUpdateEffects(finishedQueue.firstCapturedEffect, instance); + finishedQueue.firstCapturedEffect = finishedQueue.lastCapturedEffect = null; +} +function commitUpdateEffects(effect, instance) { + for (; null !== effect; ) { + var callback = effect.callback; + if (null !== callback) { + effect.callback = null; + if ("function" !== typeof callback) + throw Error( + "Invalid argument passed as callback. Expected a function. Instead received: " + + callback + ); + callback.call(instance); } + effect = effect.nextEffect; + } } var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig, emptyRefsObject = new React.Component().refs; @@ -2151,8 +2264,10 @@ function applyDerivedStateFromProps( ? ctor : Object.assign({}, ctor, getDerivedStateFromProps); workInProgress.memoizedState = getDerivedStateFromProps; - 0 === workInProgress.expirationTime && - (workInProgress.updateQueue.baseState = getDerivedStateFromProps); + nextProps = workInProgress.updateQueue; + null !== nextProps && + 0 === workInProgress.expirationTime && + (nextProps.baseState = getDerivedStateFromProps); } var classComponentUpdater = { isMounted: function(component) { @@ -2171,7 +2286,7 @@ var classComponentUpdater = { null !== callback && (suspenseConfig.callback = callback); enqueueUpdate(inst, suspenseConfig); - scheduleWork(inst, currentTime); + scheduleUpdateOnFiber(inst, currentTime); }, enqueueReplaceState: function(inst, payload, callback) { inst = inst._reactInternalFiber; @@ -2185,7 +2300,7 @@ var classComponentUpdater = { null !== callback && (suspenseConfig.callback = callback); enqueueUpdate(inst, suspenseConfig); - scheduleWork(inst, currentTime); + scheduleUpdateOnFiber(inst, currentTime); }, enqueueForceUpdate: function(inst, callback) { inst = inst._reactInternalFiber; @@ -2198,7 +2313,7 @@ var classComponentUpdater = { null !== callback && (suspenseConfig.callback = callback); enqueueUpdate(inst, suspenseConfig); - scheduleWork(inst, currentTime); + scheduleUpdateOnFiber(inst, currentTime); } }; function checkShouldComponentUpdate( @@ -2214,8 +2329,8 @@ function checkShouldComponentUpdate( return "function" === typeof workInProgress.shouldComponentUpdate ? workInProgress.shouldComponentUpdate(newProps, newState, nextContext) : ctor.prototype && ctor.prototype.isPureReactComponent - ? !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState) - : !0; + ? !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState) + : !0; } function constructClassInstance(workInProgress, ctor, props) { var isLegacyContextConsumer = !1, @@ -2267,7 +2382,6 @@ function mountClassInstance( instance.props = newProps; instance.state = workInProgress.memoizedState; instance.refs = emptyRefsObject; - initializeUpdateQueue(workInProgress); var contextType = ctor.contextType; "object" === typeof contextType && null !== contextType ? (instance.context = readContext(contextType)) @@ -2275,8 +2389,16 @@ function mountClassInstance( ? previousContext : contextStackCursor.current), (instance.context = getMaskedContext(workInProgress, contextType))); - processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); - instance.state = workInProgress.memoizedState; + contextType = workInProgress.updateQueue; + null !== contextType && + (processUpdateQueue( + workInProgress, + contextType, + newProps, + instance, + renderExpirationTime + ), + (instance.state = workInProgress.memoizedState)); contextType = ctor.getDerivedStateFromProps; "function" === typeof contextType && (applyDerivedStateFromProps(workInProgress, ctor, contextType, newProps), @@ -2292,18 +2414,21 @@ function mountClassInstance( instance.UNSAFE_componentWillMount(), ctor !== instance.state && classComponentUpdater.enqueueReplaceState(instance, instance.state, null), - processUpdateQueue( - workInProgress, - newProps, - instance, - renderExpirationTime - ), - (instance.state = workInProgress.memoizedState)); + (contextType = workInProgress.updateQueue), + null !== contextType && + (processUpdateQueue( + workInProgress, + contextType, + newProps, + instance, + renderExpirationTime + ), + (instance.state = workInProgress.memoizedState))); "function" === typeof instance.componentDidMount && (workInProgress.effectTag |= 4); } var isArray = Array.isArray; -function coerceRef(returnFiber, current, element) { +function coerceRef(returnFiber, current$$1, element) { returnFiber = element.ref; if ( null !== returnFiber && @@ -2315,7 +2440,7 @@ function coerceRef(returnFiber, current, element) { if (element) { if (1 !== element.tag) throw Error( - "Function components cannot have string refs. We recommend using useRef() instead. Learn more about using refs safely here: https://fb.me/react-strict-mode-string-ref" + "Function components cannot have refs. Did you mean to use React.forwardRef()?" ); var inst = element.stateNode; } @@ -2327,19 +2452,19 @@ function coerceRef(returnFiber, current, element) { ); var stringRef = "" + returnFiber; if ( - null !== current && - null !== current.ref && - "function" === typeof current.ref && - current.ref._stringRef === stringRef + null !== current$$1 && + null !== current$$1.ref && + "function" === typeof current$$1.ref && + current$$1.ref._stringRef === stringRef ) - return current.ref; - current = function(value) { + return current$$1.ref; + current$$1 = function(value) { var refs = inst.refs; refs === emptyRefsObject && (refs = inst.refs = {}); null === value ? delete refs[stringRef] : (refs[stringRef] = value); }; - current._stringRef = stringRef; - return current; + current$$1._stringRef = stringRef; + return current$$1; } if ("string" !== typeof returnFiber) throw Error( @@ -2391,8 +2516,8 @@ function ChildReconciler(shouldTrackSideEffects) { (currentFirstChild = currentFirstChild.sibling); return returnFiber; } - function useFiber(fiber, pendingProps) { - fiber = createWorkInProgress(fiber, pendingProps); + function useFiber(fiber, pendingProps, expirationTime) { + fiber = createWorkInProgress(fiber, pendingProps, expirationTime); fiber.index = 0; fiber.sibling = null; return fiber; @@ -2417,26 +2542,31 @@ function ChildReconciler(shouldTrackSideEffects) { (newFiber.effectTag = 2); return newFiber; } - function updateTextNode(returnFiber, current, textContent, expirationTime) { - if (null === current || 6 !== current.tag) + function updateTextNode( + returnFiber, + current$$1, + textContent, + expirationTime + ) { + if (null === current$$1 || 6 !== current$$1.tag) return ( - (current = createFiberFromText( + (current$$1 = createFiberFromText( textContent, returnFiber.mode, expirationTime )), - (current.return = returnFiber), - current + (current$$1.return = returnFiber), + current$$1 ); - current = useFiber(current, textContent); - current.return = returnFiber; - return current; + current$$1 = useFiber(current$$1, textContent, expirationTime); + current$$1.return = returnFiber; + return current$$1; } - function updateElement(returnFiber, current, element, expirationTime) { - if (null !== current && current.elementType === element.type) + function updateElement(returnFiber, current$$1, element, expirationTime) { + if (null !== current$$1 && current$$1.elementType === element.type) return ( - (expirationTime = useFiber(current, element.props)), - (expirationTime.ref = coerceRef(returnFiber, current, element)), + (expirationTime = useFiber(current$$1, element.props, expirationTime)), + (expirationTime.ref = coerceRef(returnFiber, current$$1, element)), (expirationTime.return = returnFiber), expirationTime ); @@ -2448,45 +2578,51 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime ); - expirationTime.ref = coerceRef(returnFiber, current, element); + expirationTime.ref = coerceRef(returnFiber, current$$1, element); expirationTime.return = returnFiber; return expirationTime; } - function updatePortal(returnFiber, current, portal, expirationTime) { + function updatePortal(returnFiber, current$$1, portal, expirationTime) { if ( - null === current || - 4 !== current.tag || - current.stateNode.containerInfo !== portal.containerInfo || - current.stateNode.implementation !== portal.implementation + null === current$$1 || + 4 !== current$$1.tag || + current$$1.stateNode.containerInfo !== portal.containerInfo || + current$$1.stateNode.implementation !== portal.implementation ) return ( - (current = createFiberFromPortal( + (current$$1 = createFiberFromPortal( portal, returnFiber.mode, expirationTime )), - (current.return = returnFiber), - current + (current$$1.return = returnFiber), + current$$1 ); - current = useFiber(current, portal.children || []); - current.return = returnFiber; - return current; + current$$1 = useFiber(current$$1, portal.children || [], expirationTime); + current$$1.return = returnFiber; + return current$$1; } - function updateFragment(returnFiber, current, fragment, expirationTime, key) { - if (null === current || 7 !== current.tag) + function updateFragment( + returnFiber, + current$$1, + fragment, + expirationTime, + key + ) { + if (null === current$$1 || 7 !== current$$1.tag) return ( - (current = createFiberFromFragment( + (current$$1 = createFiberFromFragment( fragment, returnFiber.mode, expirationTime, key )), - (current.return = returnFiber), - current + (current$$1.return = returnFiber), + current$$1 ); - current = useFiber(current, fragment); - current.return = returnFiber; - return current; + current$$1 = useFiber(current$$1, fragment, expirationTime); + current$$1.return = returnFiber; + return current$$1; } function createChild(returnFiber, newChild, expirationTime) { if ("string" === typeof newChild || "number" === typeof newChild) @@ -2849,48 +2985,39 @@ function ChildReconciler(shouldTrackSideEffects) { 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; - } + if (isUnkeyedTopLevelFragment.key === isObject) + if ( + 7 === isUnkeyedTopLevelFragment.tag + ? newChild.type === REACT_FRAGMENT_TYPE + : isUnkeyedTopLevelFragment.elementType === newChild.type + ) { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment.sibling + ); + currentFirstChild = useFiber( + isUnkeyedTopLevelFragment, + newChild.type === REACT_FRAGMENT_TYPE + ? newChild.props.children + : newChild.props, + expirationTime + ); + currentFirstChild.ref = coerceRef( + returnFiber, + isUnkeyedTopLevelFragment, + newChild + ); + currentFirstChild.return = returnFiber; + returnFiber = currentFirstChild; + break a; + } else { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment + ); + break; } - deleteRemainingChildren(returnFiber, isUnkeyedTopLevelFragment); - break; - } else deleteChild(returnFiber, isUnkeyedTopLevelFragment); + else deleteChild(returnFiber, isUnkeyedTopLevelFragment); isUnkeyedTopLevelFragment = isUnkeyedTopLevelFragment.sibling; } newChild.type === REACT_FRAGMENT_TYPE @@ -2940,7 +3067,8 @@ function ChildReconciler(shouldTrackSideEffects) { ); currentFirstChild = useFiber( currentFirstChild, - newChild.children || [] + newChild.children || [], + expirationTime ); currentFirstChild.return = returnFiber; returnFiber = currentFirstChild; @@ -2967,7 +3095,11 @@ function ChildReconciler(shouldTrackSideEffects) { (newChild = "" + newChild), null !== currentFirstChild && 6 === currentFirstChild.tag ? (deleteRemainingChildren(returnFiber, currentFirstChild.sibling), - (currentFirstChild = useFiber(currentFirstChild, newChild)), + (currentFirstChild = useFiber( + currentFirstChild, + newChild, + expirationTime + )), (currentFirstChild.return = returnFiber), (returnFiber = currentFirstChild)) : (deleteRemainingChildren(returnFiber, currentFirstChild), @@ -3022,16 +3154,16 @@ function requiredContext(c) { return c; } function pushHostContainer(fiber, nextRootInstance) { - push(rootInstanceStackCursor, nextRootInstance); - push(contextFiberStackCursor, fiber); - push(contextStackCursor$1, NO_CONTEXT); - pop(contextStackCursor$1); - push(contextStackCursor$1, { isInAParentText: !1 }); + push(rootInstanceStackCursor, nextRootInstance, fiber); + push(contextFiberStackCursor, fiber, fiber); + push(contextStackCursor$1, NO_CONTEXT, fiber); + pop(contextStackCursor$1, fiber); + push(contextStackCursor$1, { isInAParentText: !1 }, fiber); } -function popHostContainer() { - pop(contextStackCursor$1); - pop(contextFiberStackCursor); - pop(rootInstanceStackCursor); +function popHostContainer(fiber) { + pop(contextStackCursor$1, fiber); + pop(contextFiberStackCursor, fiber); + pop(rootInstanceStackCursor, fiber); } function pushHostContext(fiber) { requiredContext(rootInstanceStackCursor.current); @@ -3048,19 +3180,23 @@ function pushHostContext(fiber) { ? { isInAParentText: nextContext } : context; context !== nextContext && - (push(contextFiberStackCursor, fiber), - push(contextStackCursor$1, nextContext)); + (push(contextFiberStackCursor, fiber, fiber), + push(contextStackCursor$1, nextContext, fiber)); } function popHostContext(fiber) { contextFiberStackCursor.current === fiber && - (pop(contextStackCursor$1), pop(contextFiberStackCursor)); + (pop(contextStackCursor$1, fiber), pop(contextFiberStackCursor, fiber)); } var suspenseStackCursor = { current: 0 }; function findFirstSuspended(row) { for (var node = row; null !== node; ) { if (13 === node.tag) { var state = node.memoizedState; - if (null !== state && (null === state.dehydrated || shim() || shim())) + if ( + null !== state && + ((state = state.dehydrated), + null === state || shim$1(state) || shim$1(state)) + ) return node; } else if (19 === node.tag && void 0 !== node.memoizedProps.revealOrder) { if (0 !== (node.effectTag & 64)) return node; @@ -3079,16 +3215,24 @@ function findFirstSuspended(row) { } return null; } -function createDeprecatedResponderListener(responder, props) { +function createResponderListener(responder, props) { return { responder: responder, props: props }; } -var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher, +var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig, - renderExpirationTime = 0, + renderExpirationTime$1 = 0, currentlyRenderingFiber$1 = null, currentHook = null, + nextCurrentHook = null, + firstWorkInProgressHook = null, workInProgressHook = null, - didScheduleRenderPhaseUpdate = !1; + nextWorkInProgressHook = null, + remainingExpirationTime = 0, + componentUpdateQueue = null, + sideEffectTag = 0, + didScheduleRenderPhaseUpdate = !1, + renderPhaseUpdates = null, + numberOfReRenders = 0; function throwInvalidHookError() { throw Error( "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem." @@ -3097,7 +3241,7 @@ function throwInvalidHookError() { function areHookInputsEqual(nextDeps, prevDeps) { if (null === prevDeps) return !1; for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) - if (!objectIs(nextDeps[i], prevDeps[i])) return !1; + if (!is$1(nextDeps[i], prevDeps[i])) return !1; return !0; } function renderWithHooks( @@ -3105,85 +3249,92 @@ function renderWithHooks( workInProgress, Component, props, - secondArg, + refOrContext, nextRenderExpirationTime ) { - renderExpirationTime = nextRenderExpirationTime; + renderExpirationTime$1 = nextRenderExpirationTime; currentlyRenderingFiber$1 = workInProgress; - workInProgress.memoizedState = null; - workInProgress.updateQueue = null; - workInProgress.expirationTime = 0; - ReactCurrentDispatcher.current = - null === current || null === current.memoizedState - ? HooksDispatcherOnMount - : HooksDispatcherOnUpdate; - current = Component(props, secondArg); - if (workInProgress.expirationTime === renderExpirationTime) { - nextRenderExpirationTime = 0; - do { - workInProgress.expirationTime = 0; - if (!(25 > nextRenderExpirationTime)) - throw Error( - "Too many re-renders. React limits the number of renders to prevent an infinite loop." - ); - nextRenderExpirationTime += 1; - workInProgressHook = currentHook = null; - workInProgress.updateQueue = null; - ReactCurrentDispatcher.current = HooksDispatcherOnRerender; - current = Component(props, secondArg); - } while (workInProgress.expirationTime === renderExpirationTime); + nextCurrentHook = null !== current ? current.memoizedState : null; + ReactCurrentDispatcher$1.current = + null === nextCurrentHook ? HooksDispatcherOnMount : HooksDispatcherOnUpdate; + workInProgress = Component(props, refOrContext); + if (didScheduleRenderPhaseUpdate) { + do + (didScheduleRenderPhaseUpdate = !1), + (numberOfReRenders += 1), + (nextCurrentHook = null !== current ? current.memoizedState : null), + (nextWorkInProgressHook = firstWorkInProgressHook), + (componentUpdateQueue = workInProgressHook = currentHook = null), + (ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdate), + (workInProgress = Component(props, refOrContext)); + while (didScheduleRenderPhaseUpdate); + renderPhaseUpdates = null; + numberOfReRenders = 0; } - ReactCurrentDispatcher.current = ContextOnlyDispatcher; - workInProgress = null !== currentHook && null !== currentHook.next; - renderExpirationTime = 0; - workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; - didScheduleRenderPhaseUpdate = !1; - if (workInProgress) + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; + current = currentlyRenderingFiber$1; + current.memoizedState = firstWorkInProgressHook; + current.expirationTime = remainingExpirationTime; + current.updateQueue = componentUpdateQueue; + current.effectTag |= sideEffectTag; + current = null !== currentHook && null !== currentHook.next; + renderExpirationTime$1 = 0; + nextWorkInProgressHook = workInProgressHook = firstWorkInProgressHook = nextCurrentHook = currentHook = currentlyRenderingFiber$1 = null; + remainingExpirationTime = 0; + componentUpdateQueue = null; + sideEffectTag = 0; + if (current) throw Error( "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." ); - return current; + return workInProgress; +} +function resetHooks() { + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; + renderExpirationTime$1 = 0; + nextWorkInProgressHook = workInProgressHook = firstWorkInProgressHook = nextCurrentHook = currentHook = currentlyRenderingFiber$1 = null; + remainingExpirationTime = 0; + componentUpdateQueue = null; + sideEffectTag = 0; + didScheduleRenderPhaseUpdate = !1; + renderPhaseUpdates = null; + numberOfReRenders = 0; } function mountWorkInProgressHook() { var hook = { memoizedState: null, baseState: null, - baseQueue: null, queue: null, + baseUpdate: null, next: null }; null === workInProgressHook - ? (currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook) + ? (firstWorkInProgressHook = workInProgressHook = hook) : (workInProgressHook = workInProgressHook.next = hook); return workInProgressHook; } function updateWorkInProgressHook() { - if (null === currentHook) { - var nextCurrentHook = currentlyRenderingFiber$1.alternate; - nextCurrentHook = - null !== nextCurrentHook ? nextCurrentHook.memoizedState : null; - } else nextCurrentHook = currentHook.next; - var nextWorkInProgressHook = - null === workInProgressHook - ? currentlyRenderingFiber$1.memoizedState - : workInProgressHook.next; if (null !== nextWorkInProgressHook) (workInProgressHook = nextWorkInProgressHook), - (currentHook = nextCurrentHook); + (nextWorkInProgressHook = workInProgressHook.next), + (currentHook = nextCurrentHook), + (nextCurrentHook = null !== currentHook ? currentHook.next : null); else { if (null === nextCurrentHook) throw Error("Rendered more hooks than during the previous render."); currentHook = nextCurrentHook; - nextCurrentHook = { + var newHook = { memoizedState: currentHook.memoizedState, baseState: currentHook.baseState, - baseQueue: currentHook.baseQueue, queue: currentHook.queue, + baseUpdate: currentHook.baseUpdate, next: null }; - null === workInProgressHook - ? (currentlyRenderingFiber$1.memoizedState = workInProgressHook = nextCurrentHook) - : (workInProgressHook = workInProgressHook.next = nextCurrentHook); + workInProgressHook = + null === workInProgressHook + ? (firstWorkInProgressHook = newHook) + : (workInProgressHook.next = newHook); + nextCurrentHook = currentHook.next; } return workInProgressHook; } @@ -3198,100 +3349,74 @@ function updateReducer(reducer) { "Should have a queue. This is likely a bug in React. Please file an issue." ); queue.lastRenderedReducer = reducer; - var current = currentHook, - baseQueue = current.baseQueue, - pendingQueue = queue.pending; - if (null !== pendingQueue) { - if (null !== baseQueue) { - var baseFirst = baseQueue.next; - baseQueue.next = pendingQueue.next; - pendingQueue.next = baseFirst; + if (0 < numberOfReRenders) { + var _dispatch = queue.dispatch; + if (null !== renderPhaseUpdates) { + var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue); + if (void 0 !== firstRenderPhaseUpdate) { + renderPhaseUpdates.delete(queue); + var newState = hook.memoizedState; + do + (newState = reducer(newState, firstRenderPhaseUpdate.action)), + (firstRenderPhaseUpdate = firstRenderPhaseUpdate.next); + while (null !== firstRenderPhaseUpdate); + is$1(newState, hook.memoizedState) || (didReceiveUpdate = !0); + hook.memoizedState = newState; + hook.baseUpdate === queue.last && (hook.baseState = newState); + queue.lastRenderedState = newState; + return [newState, _dispatch]; + } } - current.baseQueue = baseQueue = pendingQueue; - queue.pending = null; + return [hook.memoizedState, _dispatch]; } - if (null !== baseQueue) { - baseQueue = baseQueue.next; - current = current.baseState; - var newBaseQueueLast = (baseFirst = pendingQueue = null), - update = baseQueue; + _dispatch = queue.last; + var baseUpdate = hook.baseUpdate; + newState = hook.baseState; + null !== baseUpdate + ? (null !== _dispatch && (_dispatch.next = null), + (_dispatch = baseUpdate.next)) + : (_dispatch = null !== _dispatch ? _dispatch.next : null); + if (null !== _dispatch) { + var newBaseUpdate = (firstRenderPhaseUpdate = null), + _update = _dispatch, + didSkip = !1; do { - var updateExpirationTime = update.expirationTime; - if (updateExpirationTime < renderExpirationTime) { - var clone = { - expirationTime: update.expirationTime, - suspenseConfig: update.suspenseConfig, - action: update.action, - eagerReducer: update.eagerReducer, - eagerState: update.eagerState, - next: null - }; - null === newBaseQueueLast - ? ((baseFirst = newBaseQueueLast = clone), (pendingQueue = current)) - : (newBaseQueueLast = newBaseQueueLast.next = clone); - updateExpirationTime > currentlyRenderingFiber$1.expirationTime && - ((currentlyRenderingFiber$1.expirationTime = updateExpirationTime), - markUnprocessedUpdateTime(updateExpirationTime)); - } else - null !== newBaseQueueLast && - (newBaseQueueLast = newBaseQueueLast.next = { - expirationTime: 1073741823, - suspenseConfig: update.suspenseConfig, - action: update.action, - eagerReducer: update.eagerReducer, - eagerState: update.eagerState, - next: null - }), - markRenderEventTimeAndConfig( + var updateExpirationTime = _update.expirationTime; + updateExpirationTime < renderExpirationTime$1 + ? (didSkip || + ((didSkip = !0), + (newBaseUpdate = baseUpdate), + (firstRenderPhaseUpdate = newState)), + updateExpirationTime > remainingExpirationTime && + ((remainingExpirationTime = updateExpirationTime), + markUnprocessedUpdateTime(remainingExpirationTime))) + : (markRenderEventTimeAndConfig( updateExpirationTime, - update.suspenseConfig + _update.suspenseConfig ), - (current = - update.eagerReducer === reducer - ? update.eagerState - : reducer(current, update.action)); - update = update.next; - } while (null !== update && update !== baseQueue); - null === newBaseQueueLast - ? (pendingQueue = current) - : (newBaseQueueLast.next = baseFirst); - objectIs(current, hook.memoizedState) || (didReceiveUpdate = !0); - hook.memoizedState = current; - hook.baseState = pendingQueue; - hook.baseQueue = newBaseQueueLast; - queue.lastRenderedState = current; - } - return [hook.memoizedState, queue.dispatch]; -} -function rerenderReducer(reducer) { - var hook = updateWorkInProgressHook(), - queue = hook.queue; - if (null === queue) - throw Error( - "Should have a queue. This is likely a bug in React. Please file an issue." - ); - queue.lastRenderedReducer = reducer; - var dispatch = queue.dispatch, - lastRenderPhaseUpdate = queue.pending, - newState = hook.memoizedState; - if (null !== lastRenderPhaseUpdate) { - queue.pending = null; - var update = (lastRenderPhaseUpdate = lastRenderPhaseUpdate.next); - do (newState = reducer(newState, update.action)), (update = update.next); - while (update !== lastRenderPhaseUpdate); - objectIs(newState, hook.memoizedState) || (didReceiveUpdate = !0); + (newState = + _update.eagerReducer === reducer + ? _update.eagerState + : reducer(newState, _update.action))); + baseUpdate = _update; + _update = _update.next; + } while (null !== _update && _update !== _dispatch); + didSkip || + ((newBaseUpdate = baseUpdate), (firstRenderPhaseUpdate = newState)); + is$1(newState, hook.memoizedState) || (didReceiveUpdate = !0); hook.memoizedState = newState; - null === hook.baseQueue && (hook.baseState = newState); + hook.baseUpdate = newBaseUpdate; + hook.baseState = firstRenderPhaseUpdate; queue.lastRenderedState = newState; } - return [newState, dispatch]; + return [hook.memoizedState, queue.dispatch]; } function mountState(initialState) { var hook = mountWorkInProgressHook(); "function" === typeof initialState && (initialState = initialState()); hook.memoizedState = hook.baseState = initialState; initialState = hook.queue = { - pending: null, + last: null, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState @@ -3303,30 +3428,28 @@ function mountState(initialState) { ); return [hook.memoizedState, initialState]; } +function updateState(initialState) { + return updateReducer(basicStateReducer, initialState); +} function pushEffect(tag, create, destroy, deps) { tag = { tag: tag, create: create, destroy: destroy, deps: deps, next: null }; - create = currentlyRenderingFiber$1.updateQueue; - null === create - ? ((create = { lastEffect: null }), - (currentlyRenderingFiber$1.updateQueue = create), - (create.lastEffect = tag.next = tag)) - : ((destroy = create.lastEffect), - null === destroy - ? (create.lastEffect = tag.next = tag) - : ((deps = destroy.next), - (destroy.next = tag), - (tag.next = deps), - (create.lastEffect = tag))); + null === componentUpdateQueue + ? ((componentUpdateQueue = { lastEffect: null }), + (componentUpdateQueue.lastEffect = tag.next = tag)) + : ((create = componentUpdateQueue.lastEffect), + null === create + ? (componentUpdateQueue.lastEffect = tag.next = tag) + : ((destroy = create.next), + (create.next = tag), + (tag.next = destroy), + (componentUpdateQueue.lastEffect = tag))); return tag; } -function updateRef() { - return updateWorkInProgressHook().memoizedState; -} function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var hook = mountWorkInProgressHook(); - currentlyRenderingFiber$1.effectTag |= fiberEffectTag; + sideEffectTag |= fiberEffectTag; hook.memoizedState = pushEffect( - 1 | hookEffectTag, + hookEffectTag, create, void 0, void 0 === deps ? null : deps @@ -3340,21 +3463,18 @@ function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var prevEffect = currentHook.memoizedState; destroy = prevEffect.destroy; if (null !== deps && areHookInputsEqual(deps, prevEffect.deps)) { - pushEffect(hookEffectTag, create, destroy, deps); + pushEffect(0, create, destroy, deps); return; } } - currentlyRenderingFiber$1.effectTag |= fiberEffectTag; - hook.memoizedState = pushEffect(1 | hookEffectTag, create, destroy, deps); + sideEffectTag |= fiberEffectTag; + hook.memoizedState = pushEffect(hookEffectTag, create, destroy, deps); } function mountEffect(create, deps) { - return mountEffectImpl(516, 4, create, deps); + return mountEffectImpl(516, 192, create, deps); } function updateEffect(create, deps) { - return updateEffectImpl(516, 4, create, deps); -} -function updateLayoutEffect(create, deps) { - return updateEffectImpl(4, 2, create, deps); + return updateEffectImpl(516, 192, create, deps); } function imperativeHandleEffect(create, ref) { if ("function" === typeof ref) @@ -3374,15 +3494,6 @@ function imperativeHandleEffect(create, ref) { } ); } -function updateImperativeHandle(ref, create, deps) { - deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; - return updateEffectImpl( - 4, - 2, - imperativeHandleEffect.bind(null, create, ref), - deps - ); -} function mountDebugValue() {} function mountCallback(callback, deps) { mountWorkInProgressHook().memoizedState = [ @@ -3404,79 +3515,72 @@ function updateCallback(callback, deps) { hook.memoizedState = [callback, deps]; return callback; } -function updateMemo(nextCreate, deps) { - var hook = updateWorkInProgressHook(); - deps = void 0 === deps ? null : deps; - var prevState = hook.memoizedState; - if ( - null !== prevState && - null !== deps && - areHookInputsEqual(deps, prevState[1]) - ) - return prevState[0]; - nextCreate = nextCreate(); - hook.memoizedState = [nextCreate, deps]; - return nextCreate; -} -function startTransition(setPending, config, callback) { - var priorityLevel = getCurrentPriorityLevel(); - runWithPriority(98 > priorityLevel ? 98 : priorityLevel, function() { - setPending(!0); - }); - runWithPriority(97 < priorityLevel ? 97 : priorityLevel, function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = void 0 === config ? null : config; - try { - setPending(!1), callback(); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); -} function dispatchAction(fiber, queue, action) { - var currentTime = requestCurrentTimeForUpdate(), - suspenseConfig = ReactCurrentBatchConfig.suspense; - currentTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig); - suspenseConfig = { - expirationTime: currentTime, - suspenseConfig: suspenseConfig, - action: action, - eagerReducer: null, - eagerState: null, - next: null - }; - var pending = queue.pending; - null === pending - ? (suspenseConfig.next = suspenseConfig) - : ((suspenseConfig.next = pending.next), (pending.next = suspenseConfig)); - queue.pending = suspenseConfig; - pending = fiber.alternate; + if (!(25 > numberOfReRenders)) + throw Error( + "Too many re-renders. React limits the number of renders to prevent an infinite loop." + ); + var alternate = fiber.alternate; if ( fiber === currentlyRenderingFiber$1 || - (null !== pending && pending === currentlyRenderingFiber$1) + (null !== alternate && alternate === currentlyRenderingFiber$1) ) - (didScheduleRenderPhaseUpdate = !0), - (suspenseConfig.expirationTime = renderExpirationTime), - (currentlyRenderingFiber$1.expirationTime = renderExpirationTime); + if ( + ((didScheduleRenderPhaseUpdate = !0), + (fiber = { + expirationTime: renderExpirationTime$1, + suspenseConfig: null, + action: action, + eagerReducer: null, + eagerState: null, + next: null + }), + null === renderPhaseUpdates && (renderPhaseUpdates = new Map()), + (action = renderPhaseUpdates.get(queue)), + void 0 === action) + ) + renderPhaseUpdates.set(queue, fiber); + else { + for (queue = action; null !== queue.next; ) queue = queue.next; + queue.next = fiber; + } else { + var currentTime = requestCurrentTimeForUpdate(), + suspenseConfig = ReactCurrentBatchConfig.suspense; + currentTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig); + suspenseConfig = { + expirationTime: currentTime, + suspenseConfig: suspenseConfig, + action: action, + eagerReducer: null, + eagerState: null, + next: null + }; + var last = queue.last; + if (null === last) suspenseConfig.next = suspenseConfig; + else { + var first = last.next; + null !== first && (suspenseConfig.next = first); + last.next = suspenseConfig; + } + queue.last = suspenseConfig; if ( 0 === fiber.expirationTime && - (null === pending || 0 === pending.expirationTime) && - ((pending = queue.lastRenderedReducer), null !== pending) + (null === alternate || 0 === alternate.expirationTime) && + ((alternate = queue.lastRenderedReducer), null !== alternate) ) try { var currentState = queue.lastRenderedState, - eagerState = pending(currentState, action); - suspenseConfig.eagerReducer = pending; + eagerState = alternate(currentState, action); + suspenseConfig.eagerReducer = alternate; suspenseConfig.eagerState = eagerState; - if (objectIs(eagerState, currentState)) return; + if (is$1(eagerState, currentState)) return; } catch (error) { } finally { } - scheduleWork(fiber, currentTime); + scheduleUpdateOnFiber(fiber, currentTime); } } -function updateEventListener() {} var ContextOnlyDispatcher = { readContext: readContext, useCallback: throwInvalidHookError, @@ -3491,8 +3595,7 @@ var ContextOnlyDispatcher = { useDebugValue: throwInvalidHookError, useResponder: throwInvalidHookError, useDeferredValue: throwInvalidHookError, - useTransition: throwInvalidHookError, - useEvent: throwInvalidHookError + useTransition: throwInvalidHookError }, HooksDispatcherOnMount = { readContext: readContext, @@ -3503,13 +3606,13 @@ var ContextOnlyDispatcher = { deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; return mountEffectImpl( 4, - 2, + 36, imperativeHandleEffect.bind(null, create, ref), deps ); }, useLayoutEffect: function(create, deps) { - return mountEffectImpl(4, 2, create, deps); + return mountEffectImpl(4, 36, create, deps); }, useMemo: function(nextCreate, deps) { var hook = mountWorkInProgressHook(); @@ -3523,7 +3626,7 @@ var ContextOnlyDispatcher = { initialArg = void 0 !== init ? init(initialArg) : initialArg; hook.memoizedState = hook.baseState = initialArg; reducer = hook.queue = { - pending: null, + last: null, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialArg @@ -3542,21 +3645,23 @@ var ContextOnlyDispatcher = { }, useState: mountState, useDebugValue: mountDebugValue, - useResponder: createDeprecatedResponderListener, + useResponder: createResponderListener, useDeferredValue: function(value, config) { var _mountState = mountState(value), prevValue = _mountState[0], setValue = _mountState[1]; mountEffect( function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - void 0 === config ? null : config; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } + Scheduler.unstable_next(function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }); }, [value, config] ); @@ -3564,124 +3669,177 @@ var ContextOnlyDispatcher = { }, useTransition: function(config) { var _mountState2 = mountState(!1), - isPending = _mountState2[0]; - _mountState2 = _mountState2[1]; + isPending = _mountState2[0], + setPending = _mountState2[1]; return [ - mountCallback(startTransition.bind(null, _mountState2, config), [ - _mountState2, - config - ]), + mountCallback( + function(callback) { + setPending(!0); + Scheduler.unstable_next(function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setPending(!1), callback(); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }); + }, + [config, isPending] + ), isPending ]; - }, - useEvent: function() {} + } }, HooksDispatcherOnUpdate = { readContext: readContext, useCallback: updateCallback, useContext: readContext, useEffect: updateEffect, - useImperativeHandle: updateImperativeHandle, - useLayoutEffect: updateLayoutEffect, - useMemo: updateMemo, + useImperativeHandle: function(ref, create, deps) { + deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; + return updateEffectImpl( + 4, + 36, + imperativeHandleEffect.bind(null, create, ref), + deps + ); + }, + useLayoutEffect: function(create, deps) { + return updateEffectImpl(4, 36, create, deps); + }, + useMemo: function(nextCreate, deps) { + var hook = updateWorkInProgressHook(); + deps = void 0 === deps ? null : deps; + var prevState = hook.memoizedState; + if ( + null !== prevState && + null !== deps && + areHookInputsEqual(deps, prevState[1]) + ) + return prevState[0]; + nextCreate = nextCreate(); + hook.memoizedState = [nextCreate, deps]; + return nextCreate; + }, useReducer: updateReducer, - useRef: updateRef, - useState: function() { - return updateReducer(basicStateReducer); + useRef: function() { + return updateWorkInProgressHook().memoizedState; }, + useState: updateState, useDebugValue: mountDebugValue, - useResponder: createDeprecatedResponderListener, + useResponder: createResponderListener, useDeferredValue: function(value, config) { - var _updateState = updateReducer(basicStateReducer), + var _updateState = updateState(value), prevValue = _updateState[0], setValue = _updateState[1]; updateEffect( function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - void 0 === config ? null : config; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } + Scheduler.unstable_next(function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }); }, [value, config] ); return prevValue; }, useTransition: function(config) { - var _updateState2 = updateReducer(basicStateReducer), - isPending = _updateState2[0]; - _updateState2 = _updateState2[1]; + var _updateState2 = updateState(!1), + isPending = _updateState2[0], + setPending = _updateState2[1]; return [ - updateCallback(startTransition.bind(null, _updateState2, config), [ - _updateState2, - config - ]), + updateCallback( + function(callback) { + setPending(!0); + Scheduler.unstable_next(function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setPending(!1), callback(); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }); + }, + [config, isPending] + ), isPending ]; - }, - useEvent: updateEventListener + } }, - HooksDispatcherOnRerender = { - readContext: readContext, - useCallback: updateCallback, - useContext: readContext, - useEffect: updateEffect, - useImperativeHandle: updateImperativeHandle, - useLayoutEffect: updateLayoutEffect, - useMemo: updateMemo, - useReducer: rerenderReducer, - useRef: updateRef, - useState: function() { - return rerenderReducer(basicStateReducer); - }, - useDebugValue: mountDebugValue, - useResponder: createDeprecatedResponderListener, - useDeferredValue: function(value, config) { - var _rerenderState = rerenderReducer(basicStateReducer), - prevValue = _rerenderState[0], - setValue = _rerenderState[1]; - updateEffect( - function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - void 0 === config ? null : config; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }, - [value, config] + hydrationParentFiber = null, + nextHydratableInstance = null, + isHydrating = !1; +function tryHydrate(fiber, nextInstance) { + switch (fiber.tag) { + case 5: + return ( + (nextInstance = shim$1(nextInstance, fiber.type, fiber.pendingProps)), + null !== nextInstance ? ((fiber.stateNode = nextInstance), !0) : !1 ); - return prevValue; - }, - useTransition: function(config) { - var _rerenderState2 = rerenderReducer(basicStateReducer), - isPending = _rerenderState2[0]; - _rerenderState2 = _rerenderState2[1]; - return [ - updateCallback(startTransition.bind(null, _rerenderState2, config), [ - _rerenderState2, - config - ]), - isPending - ]; - }, - useEvent: updateEventListener - }, - ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner, + case 6: + return ( + (nextInstance = shim$1(nextInstance, fiber.pendingProps)), + null !== nextInstance ? ((fiber.stateNode = nextInstance), !0) : !1 + ); + case 13: + return !1; + default: + return !1; + } +} +function tryToClaimNextHydratableInstance(fiber$jscomp$0) { + if (isHydrating) { + var nextInstance = nextHydratableInstance; + if (nextInstance) { + var firstAttemptedInstance = nextInstance; + if (!tryHydrate(fiber$jscomp$0, nextInstance)) { + nextInstance = shim$1(firstAttemptedInstance); + if (!nextInstance || !tryHydrate(fiber$jscomp$0, nextInstance)) { + fiber$jscomp$0.effectTag = (fiber$jscomp$0.effectTag & -1025) | 2; + isHydrating = !1; + hydrationParentFiber = fiber$jscomp$0; + return; + } + var returnFiber = hydrationParentFiber, + fiber = createFiber(5, null, null, 0); + fiber.elementType = "DELETED"; + fiber.type = "DELETED"; + fiber.stateNode = firstAttemptedInstance; + fiber.return = returnFiber; + fiber.effectTag = 8; + null !== returnFiber.lastEffect + ? ((returnFiber.lastEffect.nextEffect = fiber), + (returnFiber.lastEffect = fiber)) + : (returnFiber.firstEffect = returnFiber.lastEffect = fiber); + } + hydrationParentFiber = fiber$jscomp$0; + nextHydratableInstance = shim$1(nextInstance); + } else + (fiber$jscomp$0.effectTag = (fiber$jscomp$0.effectTag & -1025) | 2), + (isHydrating = !1), + (hydrationParentFiber = fiber$jscomp$0); + } +} +var ReactCurrentOwner$3 = ReactSharedInternals.ReactCurrentOwner, didReceiveUpdate = !1; function reconcileChildren( - current, + current$$1, workInProgress, nextChildren, renderExpirationTime ) { workInProgress.child = - null === current + null === current$$1 ? mountChildFibers( workInProgress, null, @@ -3690,13 +3848,13 @@ function reconcileChildren( ) : reconcileChildFibers( workInProgress, - current.child, + current$$1.child, nextChildren, renderExpirationTime ); } function updateForwardRef( - current, + current$$1, workInProgress, Component, nextProps, @@ -3706,38 +3864,43 @@ function updateForwardRef( var ref = workInProgress.ref; prepareToReadContext(workInProgress, renderExpirationTime); nextProps = renderWithHooks( - current, + current$$1, workInProgress, Component, nextProps, ref, renderExpirationTime ); - if (null !== current && !didReceiveUpdate) + if (null !== current$$1 && !didReceiveUpdate) return ( - (workInProgress.updateQueue = current.updateQueue), + (workInProgress.updateQueue = current$$1.updateQueue), (workInProgress.effectTag &= -517), - current.expirationTime <= renderExpirationTime && - (current.expirationTime = 0), + current$$1.expirationTime <= renderExpirationTime && + (current$$1.expirationTime = 0), bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ) ); workInProgress.effectTag |= 1; - reconcileChildren(current, workInProgress, nextProps, renderExpirationTime); + reconcileChildren( + current$$1, + workInProgress, + nextProps, + renderExpirationTime + ); return workInProgress.child; } function updateMemoComponent( - current, + current$$1, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime ) { - if (null === current) { + if (null === current$$1) { var type = Component.type; if ( "function" === typeof type && @@ -3750,7 +3913,7 @@ function updateMemoComponent( (workInProgress.tag = 15), (workInProgress.type = type), updateSimpleMemoComponent( - current, + current$$1, workInProgress, type, nextProps, @@ -3758,7 +3921,7 @@ function updateMemoComponent( renderExpirationTime ) ); - current = createFiberFromTypeAndProps( + current$$1 = createFiberFromTypeAndProps( Component.type, null, nextProps, @@ -3766,66 +3929,65 @@ function updateMemoComponent( workInProgress.mode, renderExpirationTime ); - current.ref = workInProgress.ref; - current.return = workInProgress; - return (workInProgress.child = current); + current$$1.ref = workInProgress.ref; + current$$1.return = workInProgress; + return (workInProgress.child = current$$1); } - type = current.child; + type = current$$1.child; if ( updateExpirationTime < renderExpirationTime && ((updateExpirationTime = type.memoizedProps), (Component = Component.compare), (Component = null !== Component ? Component : shallowEqual), Component(updateExpirationTime, nextProps) && - current.ref === workInProgress.ref) + current$$1.ref === workInProgress.ref) ) return bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ); workInProgress.effectTag |= 1; - current = createWorkInProgress(type, nextProps); - current.ref = workInProgress.ref; - current.return = workInProgress; - return (workInProgress.child = current); + current$$1 = createWorkInProgress(type, nextProps, renderExpirationTime); + current$$1.ref = workInProgress.ref; + current$$1.return = workInProgress; + return (workInProgress.child = current$$1); } function updateSimpleMemoComponent( - current, + current$$1, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime ) { - return null !== current && - shallowEqual(current.memoizedProps, nextProps) && - current.ref === workInProgress.ref && + return null !== current$$1 && + shallowEqual(current$$1.memoizedProps, nextProps) && + current$$1.ref === workInProgress.ref && ((didReceiveUpdate = !1), updateExpirationTime < renderExpirationTime) - ? ((workInProgress.expirationTime = current.expirationTime), - bailoutOnAlreadyFinishedWork( - current, + ? bailoutOnAlreadyFinishedWork( + current$$1, workInProgress, renderExpirationTime - )) + ) : updateFunctionComponent( - current, + current$$1, workInProgress, Component, nextProps, renderExpirationTime ); } -function markRef(current, workInProgress) { +function markRef(current$$1, workInProgress) { var ref = workInProgress.ref; if ( - (null === current && null !== ref) || - (null !== current && current.ref !== ref) + (null === current$$1 && null !== ref) || + (null !== current$$1 && current$$1.ref !== ref) ) workInProgress.effectTag |= 128; } function updateFunctionComponent( - current, + current$$1, workInProgress, Component, nextProps, @@ -3837,31 +3999,36 @@ function updateFunctionComponent( context = getMaskedContext(workInProgress, context); prepareToReadContext(workInProgress, renderExpirationTime); Component = renderWithHooks( - current, + current$$1, workInProgress, Component, nextProps, context, renderExpirationTime ); - if (null !== current && !didReceiveUpdate) + if (null !== current$$1 && !didReceiveUpdate) return ( - (workInProgress.updateQueue = current.updateQueue), + (workInProgress.updateQueue = current$$1.updateQueue), (workInProgress.effectTag &= -517), - current.expirationTime <= renderExpirationTime && - (current.expirationTime = 0), + current$$1.expirationTime <= renderExpirationTime && + (current$$1.expirationTime = 0), bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ) ); workInProgress.effectTag |= 1; - reconcileChildren(current, workInProgress, Component, renderExpirationTime); + reconcileChildren( + current$$1, + workInProgress, + Component, + renderExpirationTime + ); return workInProgress.child; } function updateClassComponent( - current, + current$$1, workInProgress, Component, nextProps, @@ -3873,11 +4040,16 @@ function updateClassComponent( } else hasContext = !1; prepareToReadContext(workInProgress, renderExpirationTime); if (null === workInProgress.stateNode) - null !== current && - ((current.alternate = null), + null !== current$$1 && + ((current$$1.alternate = null), (workInProgress.alternate = null), (workInProgress.effectTag |= 2)), - constructClassInstance(workInProgress, Component, nextProps), + constructClassInstance( + workInProgress, + Component, + nextProps, + renderExpirationTime + ), mountClassInstance( workInProgress, Component, @@ -3885,7 +4057,7 @@ function updateClassComponent( renderExpirationTime ), (nextProps = !0); - else if (null === current) { + else if (null === current$$1) { var instance = workInProgress.stateNode, oldProps = workInProgress.memoizedProps; instance.props = oldProps; @@ -3913,14 +4085,17 @@ function updateClassComponent( )); hasForceUpdate = !1; var oldState = workInProgress.memoizedState; - instance.state = oldState; - processUpdateQueue( - workInProgress, - nextProps, - instance, - renderExpirationTime - ); - oldContext = workInProgress.memoizedState; + oldContext = instance.state = oldState; + var updateQueue = workInProgress.updateQueue; + null !== updateQueue && + (processUpdateQueue( + workInProgress, + updateQueue, + nextProps, + instance, + renderExpirationTime + ), + (oldContext = workInProgress.memoizedState)); oldProps !== nextProps || oldState !== oldContext || didPerformWorkStackCursor.current || @@ -3966,7 +4141,6 @@ function updateClassComponent( (nextProps = !1)); } else (instance = workInProgress.stateNode), - cloneUpdateQueue(current, workInProgress), (oldProps = workInProgress.memoizedProps), (instance.props = workInProgress.type === workInProgress.elementType @@ -3995,14 +4169,17 @@ function updateClassComponent( )), (hasForceUpdate = !1), (oldContext = workInProgress.memoizedState), - (instance.state = oldContext), - processUpdateQueue( - workInProgress, - nextProps, - instance, - renderExpirationTime - ), - (oldState = workInProgress.memoizedState), + (oldState = instance.state = oldContext), + (updateQueue = workInProgress.updateQueue), + null !== updateQueue && + (processUpdateQueue( + workInProgress, + updateQueue, + nextProps, + instance, + renderExpirationTime + ), + (oldState = workInProgress.memoizedState)), oldProps !== nextProps || oldContext !== oldState || didPerformWorkStackCursor.current || @@ -4046,12 +4223,12 @@ function updateClassComponent( "function" === typeof instance.getSnapshotBeforeUpdate && (workInProgress.effectTag |= 256)) : ("function" !== typeof instance.componentDidUpdate || - (oldProps === current.memoizedProps && - oldContext === current.memoizedState) || + (oldProps === current$$1.memoizedProps && + oldContext === current$$1.memoizedState) || (workInProgress.effectTag |= 4), "function" !== typeof instance.getSnapshotBeforeUpdate || - (oldProps === current.memoizedProps && - oldContext === current.memoizedState) || + (oldProps === current$$1.memoizedProps && + oldContext === current$$1.memoizedState) || (workInProgress.effectTag |= 256), (workInProgress.memoizedProps = nextProps), (workInProgress.memoizedState = oldState)), @@ -4060,16 +4237,16 @@ function updateClassComponent( (instance.context = contextType), (nextProps = getDerivedStateFromProps)) : ("function" !== typeof instance.componentDidUpdate || - (oldProps === current.memoizedProps && - oldContext === current.memoizedState) || + (oldProps === current$$1.memoizedProps && + oldContext === current$$1.memoizedState) || (workInProgress.effectTag |= 4), "function" !== typeof instance.getSnapshotBeforeUpdate || - (oldProps === current.memoizedProps && - oldContext === current.memoizedState) || + (oldProps === current$$1.memoizedProps && + oldContext === current$$1.memoizedState) || (workInProgress.effectTag |= 256), (nextProps = !1)); return finishClassComponent( - current, + current$$1, workInProgress, Component, nextProps, @@ -4078,35 +4255,35 @@ function updateClassComponent( ); } function finishClassComponent( - current, + current$$1, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime ) { - markRef(current, workInProgress); + markRef(current$$1, workInProgress); var didCaptureError = 0 !== (workInProgress.effectTag & 64); if (!shouldUpdate && !didCaptureError) return ( hasContext && invalidateContextProvider(workInProgress, Component, !1), bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ) ); shouldUpdate = workInProgress.stateNode; - ReactCurrentOwner$1.current = workInProgress; + ReactCurrentOwner$3.current = workInProgress; var nextChildren = didCaptureError && "function" !== typeof Component.getDerivedStateFromError ? null : shouldUpdate.render(); workInProgress.effectTag |= 1; - null !== current && didCaptureError + null !== current$$1 && didCaptureError ? ((workInProgress.child = reconcileChildFibers( workInProgress, - current.child, + current$$1.child, null, renderExpirationTime )), @@ -4117,7 +4294,7 @@ function finishClassComponent( renderExpirationTime ))) : reconcileChildren( - current, + current$$1, workInProgress, nextChildren, renderExpirationTime @@ -4140,7 +4317,7 @@ function pushHostRootContext(workInProgress) { } var SUSPENDED_MARKER = { dehydrated: null, retryTime: 0 }; function updateSuspenseComponent( - current, + current$$1, workInProgress, renderExpirationTime ) { @@ -4152,30 +4329,32 @@ function updateSuspenseComponent( (JSCompiler_temp = 0 !== (workInProgress.effectTag & 64)) || (JSCompiler_temp = 0 !== (suspenseContext & 2) && - (null === current || null !== current.memoizedState)); + (null === current$$1 || null !== current$$1.memoizedState)); JSCompiler_temp ? ((nextDidTimeout = !0), (workInProgress.effectTag &= -65)) - : (null !== current && null === current.memoizedState) || + : (null !== current$$1 && null === current$$1.memoizedState) || void 0 === nextProps.fallback || !0 === nextProps.unstable_avoidThisFallback || (suspenseContext |= 1); - push(suspenseStackCursor, suspenseContext & 1); - if (null === current) { + push(suspenseStackCursor, suspenseContext & 1, workInProgress); + if (null === current$$1) { + void 0 !== nextProps.fallback && + tryToClaimNextHydratableInstance(workInProgress); if (nextDidTimeout) { nextDidTimeout = nextProps.fallback; nextProps = createFiberFromFragment(null, mode, 0, null); nextProps.return = workInProgress; if (0 === (workInProgress.mode & 2)) for ( - current = + current$$1 = null !== workInProgress.memoizedState ? workInProgress.child.child : workInProgress.child, - nextProps.child = current; - null !== current; + nextProps.child = current$$1; + null !== current$$1; ) - (current.return = nextProps), (current = current.sibling); + (current$$1.return = nextProps), (current$$1 = current$$1.sibling); renderExpirationTime = createFiberFromFragment( nextDidTimeout, mode, @@ -4197,14 +4376,15 @@ function updateSuspenseComponent( renderExpirationTime )); } - if (null !== current.memoizedState) { - current = current.child; - mode = current.sibling; + if (null !== current$$1.memoizedState) { + current$$1 = current$$1.child; + mode = current$$1.sibling; if (nextDidTimeout) { nextProps = nextProps.fallback; renderExpirationTime = createWorkInProgress( - current, - current.pendingProps + current$$1, + current$$1.pendingProps, + 0 ); renderExpirationTime.return = workInProgress; if ( @@ -4213,7 +4393,7 @@ function updateSuspenseComponent( null !== workInProgress.memoizedState ? workInProgress.child.child : workInProgress.child), - nextDidTimeout !== current.child) + nextDidTimeout !== current$$1.child) ) for ( renderExpirationTime.child = nextDidTimeout; @@ -4222,7 +4402,7 @@ function updateSuspenseComponent( ) (nextDidTimeout.return = renderExpirationTime), (nextDidTimeout = nextDidTimeout.sibling); - mode = createWorkInProgress(mode, nextProps); + mode = createWorkInProgress(mode, nextProps, mode.expirationTime); mode.return = workInProgress; renderExpirationTime.sibling = mode; renderExpirationTime.childExpirationTime = 0; @@ -4232,31 +4412,31 @@ function updateSuspenseComponent( } renderExpirationTime = reconcileChildFibers( workInProgress, - current.child, + current$$1.child, nextProps.children, renderExpirationTime ); workInProgress.memoizedState = null; return (workInProgress.child = renderExpirationTime); } - current = current.child; + current$$1 = current$$1.child; if (nextDidTimeout) { nextDidTimeout = nextProps.fallback; nextProps = createFiberFromFragment(null, mode, 0, null); nextProps.return = workInProgress; - nextProps.child = current; - null !== current && (current.return = nextProps); + nextProps.child = current$$1; + null !== current$$1 && (current$$1.return = nextProps); if (0 === (workInProgress.mode & 2)) for ( - current = + current$$1 = null !== workInProgress.memoizedState ? workInProgress.child.child : workInProgress.child, - nextProps.child = current; - null !== current; + nextProps.child = current$$1; + null !== current$$1; ) - (current.return = nextProps), (current = current.sibling); + (current$$1.return = nextProps), (current$$1 = current$$1.sibling); renderExpirationTime = createFiberFromFragment( nextDidTimeout, mode, @@ -4274,7 +4454,7 @@ function updateSuspenseComponent( workInProgress.memoizedState = null; return (workInProgress.child = reconcileChildFibers( workInProgress, - current, + current$$1, nextProps.children, renderExpirationTime )); @@ -4301,7 +4481,6 @@ function initSuspenseListRenderState( ? (workInProgress.memoizedState = { isBackwards: isBackwards, rendering: null, - renderingStartTime: 0, last: lastContentRow, tail: tail, tailExpiration: 0, @@ -4310,7 +4489,6 @@ function initSuspenseListRenderState( }) : ((renderState.isBackwards = isBackwards), (renderState.rendering = null), - (renderState.renderingStartTime = 0), (renderState.last = lastContentRow), (renderState.tail = tail), (renderState.tailExpiration = 0), @@ -4318,7 +4496,7 @@ function initSuspenseListRenderState( (renderState.lastEffect = lastEffectBeforeRendering)); } function updateSuspenseListComponent( - current, + current$$1, workInProgress, renderExpirationTime ) { @@ -4326,7 +4504,7 @@ function updateSuspenseListComponent( revealOrder = nextProps.revealOrder, tailMode = nextProps.tail; reconcileChildren( - current, + current$$1, workInProgress, nextProps.children, renderExpirationTime @@ -4335,39 +4513,42 @@ function updateSuspenseListComponent( if (0 !== (nextProps & 2)) (nextProps = (nextProps & 1) | 2), (workInProgress.effectTag |= 64); else { - if (null !== current && 0 !== (current.effectTag & 64)) - a: for (current = workInProgress.child; null !== current; ) { - if (13 === current.tag) - null !== current.memoizedState && - scheduleWorkOnFiber(current, renderExpirationTime); - else if (19 === current.tag) - scheduleWorkOnFiber(current, renderExpirationTime); - else if (null !== current.child) { - current.child.return = current; - current = current.child; + if (null !== current$$1 && 0 !== (current$$1.effectTag & 64)) + a: for (current$$1 = workInProgress.child; null !== current$$1; ) { + if (13 === current$$1.tag) + null !== current$$1.memoizedState && + scheduleWorkOnFiber(current$$1, renderExpirationTime); + else if (19 === current$$1.tag) + scheduleWorkOnFiber(current$$1, renderExpirationTime); + else if (null !== current$$1.child) { + current$$1.child.return = current$$1; + current$$1 = current$$1.child; continue; } - if (current === workInProgress) break a; - for (; null === current.sibling; ) { - if (null === current.return || current.return === workInProgress) + if (current$$1 === workInProgress) break a; + for (; null === current$$1.sibling; ) { + if ( + null === current$$1.return || + current$$1.return === workInProgress + ) break a; - current = current.return; + current$$1 = current$$1.return; } - current.sibling.return = current.return; - current = current.sibling; + current$$1.sibling.return = current$$1.return; + current$$1 = current$$1.sibling; } nextProps &= 1; } - push(suspenseStackCursor, nextProps); + push(suspenseStackCursor, nextProps, workInProgress); if (0 === (workInProgress.mode & 2)) workInProgress.memoizedState = null; else switch (revealOrder) { case "forwards": renderExpirationTime = workInProgress.child; for (revealOrder = null; null !== renderExpirationTime; ) - (current = renderExpirationTime.alternate), - null !== current && - null === findFirstSuspended(current) && + (current$$1 = renderExpirationTime.alternate), + null !== current$$1 && + null === findFirstSuspended(current$$1) && (revealOrder = renderExpirationTime), (renderExpirationTime = renderExpirationTime.sibling); renderExpirationTime = revealOrder; @@ -4389,15 +4570,15 @@ function updateSuspenseListComponent( renderExpirationTime = null; revealOrder = workInProgress.child; for (workInProgress.child = null; null !== revealOrder; ) { - current = revealOrder.alternate; - if (null !== current && null === findFirstSuspended(current)) { + current$$1 = revealOrder.alternate; + if (null !== current$$1 && null === findFirstSuspended(current$$1)) { workInProgress.child = revealOrder; break; } - current = revealOrder.sibling; + current$$1 = revealOrder.sibling; revealOrder.sibling = renderExpirationTime; renderExpirationTime = revealOrder; - revealOrder = current; + revealOrder = current$$1; } initSuspenseListRenderState( workInProgress, @@ -4424,29 +4605,35 @@ function updateSuspenseListComponent( return workInProgress.child; } function bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ) { - null !== current && (workInProgress.dependencies = current.dependencies); + null !== current$$1 && + (workInProgress.dependencies = current$$1.dependencies); var updateExpirationTime = workInProgress.expirationTime; 0 !== updateExpirationTime && markUnprocessedUpdateTime(updateExpirationTime); if (workInProgress.childExpirationTime < renderExpirationTime) return null; - if (null !== current && workInProgress.child !== current.child) + if (null !== current$$1 && workInProgress.child !== current$$1.child) throw Error("Resuming work not yet implemented."); if (null !== workInProgress.child) { - current = workInProgress.child; - renderExpirationTime = createWorkInProgress(current, current.pendingProps); + current$$1 = workInProgress.child; + renderExpirationTime = createWorkInProgress( + current$$1, + current$$1.pendingProps, + current$$1.expirationTime + ); workInProgress.child = renderExpirationTime; for ( renderExpirationTime.return = workInProgress; - null !== current.sibling; + null !== current$$1.sibling; ) - (current = current.sibling), + (current$$1 = current$$1.sibling), (renderExpirationTime = renderExpirationTime.sibling = createWorkInProgress( - current, - current.pendingProps + current$$1, + current$$1.pendingProps, + current$$1.expirationTime )), (renderExpirationTime.return = workInProgress); renderExpirationTime.sibling = null; @@ -4508,323 +4695,18 @@ function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { : (_lastTailNode.sibling = null); } } -function completeWork(current, workInProgress, renderExpirationTime) { - var newProps = workInProgress.pendingProps; - switch (workInProgress.tag) { - case 2: - case 16: - case 15: - case 0: - case 11: - case 7: - case 8: - case 12: - case 9: - case 14: - return null; - case 1: - return isContextProvider(workInProgress.type) && popContext(), null; - case 3: - return ( - popHostContainer(), - pop(didPerformWorkStackCursor), - pop(contextStackCursor), - (current = workInProgress.stateNode), - current.pendingContext && - ((current.context = current.pendingContext), - (current.pendingContext = null)), - updateHostContainer(workInProgress), - null - ); - case 5: - popHostContext(workInProgress); - var rootContainerInstance = requiredContext( - rootInstanceStackCursor.current - ); - renderExpirationTime = workInProgress.type; - if (null !== current && null != workInProgress.stateNode) - updateHostComponent$1( - current, - workInProgress, - renderExpirationTime, - newProps, - rootContainerInstance - ), - current.ref !== workInProgress.ref && - (workInProgress.effectTag |= 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." - ); - return null; - } - requiredContext(contextStackCursor$1.current); - current = allocateTag(); - renderExpirationTime = getViewConfigForType(renderExpirationTime); - var updatePayload = diffProperties( - null, - emptyObject, - newProps, - renderExpirationTime.validAttributes - ); - ReactNativePrivateInterface.UIManager.createView( - current, - renderExpirationTime.uiViewClassName, - rootContainerInstance, - updatePayload - ); - rootContainerInstance = new ReactNativeFiberHostComponent( - current, - renderExpirationTime, - workInProgress - ); - instanceCache.set(current, workInProgress); - instanceProps.set(current, newProps); - appendAllChildren(rootContainerInstance, workInProgress, !1, !1); - workInProgress.stateNode = rootContainerInstance; - finalizeInitialChildren(rootContainerInstance) && - (workInProgress.effectTag |= 4); - null !== workInProgress.ref && (workInProgress.effectTag |= 128); - } - return null; - case 6: - if (current && null != workInProgress.stateNode) - updateHostText$1( - current, - workInProgress, - current.memoizedProps, - newProps - ); - else { - if ("string" !== typeof newProps && null === workInProgress.stateNode) - throw Error( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." - ); - current = requiredContext(rootInstanceStackCursor.current); - if (!requiredContext(contextStackCursor$1.current).isInAParentText) - throw Error( - "Text strings must be rendered within a component." - ); - rootContainerInstance = allocateTag(); - ReactNativePrivateInterface.UIManager.createView( - rootContainerInstance, - "RCTRawText", - current, - { text: newProps } - ); - instanceCache.set(rootContainerInstance, workInProgress); - workInProgress.stateNode = rootContainerInstance; - } - return null; - case 13: - pop(suspenseStackCursor); - newProps = workInProgress.memoizedState; - if (0 !== (workInProgress.effectTag & 64)) - return ( - (workInProgress.expirationTime = renderExpirationTime), workInProgress - ); - newProps = null !== newProps; - rootContainerInstance = !1; - null !== current && - ((renderExpirationTime = current.memoizedState), - (rootContainerInstance = null !== renderExpirationTime), - newProps || - null === renderExpirationTime || - ((renderExpirationTime = current.child.sibling), - null !== renderExpirationTime && - ((updatePayload = workInProgress.firstEffect), - null !== updatePayload - ? ((workInProgress.firstEffect = renderExpirationTime), - (renderExpirationTime.nextEffect = updatePayload)) - : ((workInProgress.firstEffect = workInProgress.lastEffect = renderExpirationTime), - (renderExpirationTime.nextEffect = null)), - (renderExpirationTime.effectTag = 8)))); - if (newProps && !rootContainerInstance && 0 !== (workInProgress.mode & 2)) - if ( - (null === current && - !0 !== workInProgress.memoizedProps.unstable_avoidThisFallback) || - 0 !== (suspenseStackCursor.current & 1) - ) - workInProgressRootExitStatus === RootIncomplete && - (workInProgressRootExitStatus = RootSuspended); - else { - if ( - workInProgressRootExitStatus === RootIncomplete || - workInProgressRootExitStatus === RootSuspended - ) - workInProgressRootExitStatus = RootSuspendedWithDelay; - 0 !== workInProgressRootNextUnprocessedUpdateTime && - null !== workInProgressRoot && - (markRootSuspendedAtTime( - workInProgressRoot, - renderExpirationTime$1 - ), - markRootUpdatedAtTime( - workInProgressRoot, - workInProgressRootNextUnprocessedUpdateTime - )); - } - if (newProps || rootContainerInstance) workInProgress.effectTag |= 4; - return null; - case 4: - return popHostContainer(), updateHostContainer(workInProgress), null; - case 10: - return popProvider(workInProgress), null; - case 17: - return isContextProvider(workInProgress.type) && popContext(), null; - case 19: - pop(suspenseStackCursor); - newProps = workInProgress.memoizedState; - if (null === newProps) return null; - rootContainerInstance = 0 !== (workInProgress.effectTag & 64); - updatePayload = newProps.rendering; - if (null === updatePayload) - if (rootContainerInstance) cutOffTailIfNeeded(newProps, !1); - else { - if ( - workInProgressRootExitStatus !== RootIncomplete || - (null !== current && 0 !== (current.effectTag & 64)) - ) - for (current = workInProgress.child; null !== current; ) { - updatePayload = findFirstSuspended(current); - if (null !== updatePayload) { - workInProgress.effectTag |= 64; - cutOffTailIfNeeded(newProps, !1); - current = updatePayload.updateQueue; - null !== current && - ((workInProgress.updateQueue = current), - (workInProgress.effectTag |= 4)); - null === newProps.lastEffect && - (workInProgress.firstEffect = null); - workInProgress.lastEffect = newProps.lastEffect; - current = renderExpirationTime; - for (newProps = workInProgress.child; null !== newProps; ) - (rootContainerInstance = newProps), - (renderExpirationTime = current), - (rootContainerInstance.effectTag &= 2), - (rootContainerInstance.nextEffect = null), - (rootContainerInstance.firstEffect = null), - (rootContainerInstance.lastEffect = null), - (updatePayload = rootContainerInstance.alternate), - null === updatePayload - ? ((rootContainerInstance.childExpirationTime = 0), - (rootContainerInstance.expirationTime = renderExpirationTime), - (rootContainerInstance.child = null), - (rootContainerInstance.memoizedProps = null), - (rootContainerInstance.memoizedState = null), - (rootContainerInstance.updateQueue = null), - (rootContainerInstance.dependencies = null)) - : ((rootContainerInstance.childExpirationTime = - updatePayload.childExpirationTime), - (rootContainerInstance.expirationTime = - updatePayload.expirationTime), - (rootContainerInstance.child = updatePayload.child), - (rootContainerInstance.memoizedProps = - updatePayload.memoizedProps), - (rootContainerInstance.memoizedState = - updatePayload.memoizedState), - (rootContainerInstance.updateQueue = - updatePayload.updateQueue), - (renderExpirationTime = updatePayload.dependencies), - (rootContainerInstance.dependencies = - null === renderExpirationTime - ? null - : { - expirationTime: - renderExpirationTime.expirationTime, - firstContext: renderExpirationTime.firstContext, - responders: renderExpirationTime.responders - })), - (newProps = newProps.sibling); - push( - suspenseStackCursor, - (suspenseStackCursor.current & 1) | 2 - ); - return workInProgress.child; - } - current = current.sibling; - } - } - else { - if (!rootContainerInstance) - if ( - ((current = findFirstSuspended(updatePayload)), null !== current) - ) { - if ( - ((workInProgress.effectTag |= 64), - (rootContainerInstance = !0), - (current = current.updateQueue), - null !== current && - ((workInProgress.updateQueue = current), - (workInProgress.effectTag |= 4)), - cutOffTailIfNeeded(newProps, !0), - null === newProps.tail && - "hidden" === newProps.tailMode && - !updatePayload.alternate) - ) - return ( - (workInProgress = workInProgress.lastEffect = - newProps.lastEffect), - null !== workInProgress && (workInProgress.nextEffect = null), - null - ); - } else - 2 * now() - newProps.renderingStartTime > newProps.tailExpiration && - 1 < renderExpirationTime && - ((workInProgress.effectTag |= 64), - (rootContainerInstance = !0), - cutOffTailIfNeeded(newProps, !1), - (workInProgress.expirationTime = workInProgress.childExpirationTime = - renderExpirationTime - 1)); - newProps.isBackwards - ? ((updatePayload.sibling = workInProgress.child), - (workInProgress.child = updatePayload)) - : ((current = newProps.last), - null !== current - ? (current.sibling = updatePayload) - : (workInProgress.child = updatePayload), - (newProps.last = updatePayload)); - } - return null !== newProps.tail - ? (0 === newProps.tailExpiration && - (newProps.tailExpiration = now() + 500), - (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; - } - 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) { switch (workInProgress.tag) { case 1: - isContextProvider(workInProgress.type) && popContext(); + isContextProvider(workInProgress.type) && popContext(workInProgress); var effectTag = workInProgress.effectTag; return effectTag & 4096 ? ((workInProgress.effectTag = (effectTag & -4097) | 64), workInProgress) : null; case 3: - popHostContainer(); - pop(didPerformWorkStackCursor); - pop(contextStackCursor); + popHostContainer(workInProgress); + popTopLevelContextObject(workInProgress); effectTag = workInProgress.effectTag; if (0 !== (effectTag & 64)) throw Error( @@ -4836,7 +4718,7 @@ function unwindWork(workInProgress) { return popHostContext(workInProgress), null; case 13: return ( - pop(suspenseStackCursor), + pop(suspenseStackCursor, workInProgress), (effectTag = workInProgress.effectTag), effectTag & 4096 ? ((workInProgress.effectTag = (effectTag & -4097) | 64), @@ -4844,9 +4726,9 @@ function unwindWork(workInProgress) { : null ); case 19: - return pop(suspenseStackCursor), null; + return pop(suspenseStackCursor, workInProgress), null; case 4: - return popHostContainer(), null; + return popHostContainer(workInProgress), null; case 10: return popProvider(workInProgress), null; default: @@ -4903,159 +4785,85 @@ function logError(boundary, errorInfo) { }); } } -function safelyCallComponentWillUnmount(current, instance) { +function safelyCallComponentWillUnmount(current$$1, instance) { try { - (instance.props = current.memoizedProps), - (instance.state = current.memoizedState), + (instance.props = current$$1.memoizedProps), + (instance.state = current$$1.memoizedState), instance.componentWillUnmount(); } catch (unmountError) { - captureCommitPhaseError(current, unmountError); + captureCommitPhaseError(current$$1, unmountError); } } -function safelyDetachRef(current) { - var ref = current.ref; +function safelyDetachRef(current$$1) { + var ref = current$$1.ref; if (null !== ref) if ("function" === typeof ref) try { ref(null); } catch (refError) { - captureCommitPhaseError(current, refError); + captureCommitPhaseError(current$$1, refError); } else ref.current = null; } -function commitBeforeMutationLifeCycles(current, finishedWork) { +function commitBeforeMutationLifeCycles(current$$1, finishedWork) { switch (finishedWork.tag) { case 0: case 11: case 15: - case 22: - return; + commitHookEffectList(2, 0, finishedWork); + break; case 1: - if (finishedWork.effectTag & 256 && null !== current) { - var prevProps = current.memoizedProps, - prevState = current.memoizedState; - current = finishedWork.stateNode; - finishedWork = current.getSnapshotBeforeUpdate( + if (finishedWork.effectTag & 256 && null !== current$$1) { + var prevProps = current$$1.memoizedProps, + prevState = current$$1.memoizedState; + current$$1 = finishedWork.stateNode; + finishedWork = current$$1.getSnapshotBeforeUpdate( finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState ); - current.__reactInternalSnapshotBeforeUpdate = finishedWork; + current$$1.__reactInternalSnapshotBeforeUpdate = finishedWork; } - return; + break; case 3: 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." - ); + 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." + ); + } } -function commitHookEffectListUnmount(tag, finishedWork) { +function commitHookEffectList(unmountTag, mountTag, finishedWork) { finishedWork = finishedWork.updateQueue; finishedWork = null !== finishedWork ? finishedWork.lastEffect : null; if (null !== finishedWork) { var effect = (finishedWork = finishedWork.next); do { - if ((effect.tag & tag) === tag) { + if (0 !== (effect.tag & unmountTag)) { var destroy = effect.destroy; effect.destroy = void 0; void 0 !== destroy && destroy(); } + 0 !== (effect.tag & mountTag) && + ((destroy = effect.create), (effect.destroy = destroy())); effect = effect.next; } while (effect !== finishedWork); } } -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 = effect.create; - effect.destroy = create(); - } - effect = effect.next; - } while (effect !== finishedWork); - } -} -function commitLifeCycles(finishedRoot, current, finishedWork) { - switch (finishedWork.tag) { - case 0: - case 11: - case 15: - case 22: - commitHookEffectListMount(3, finishedWork); - return; - case 1: - finishedRoot = finishedWork.stateNode; - if (finishedWork.effectTag & 4) - if (null === current) finishedRoot.componentDidMount(); - else { - var prevProps = - finishedWork.elementType === finishedWork.type - ? current.memoizedProps - : resolveDefaultProps(finishedWork.type, current.memoizedProps); - finishedRoot.componentDidUpdate( - prevProps, - 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); - } - return; - case 5: - return; - case 6: - return; - case 4: - return; - case 12: - return; - case 13: - return; - case 19: - case 17: - case 20: - case 21: - 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 commitUnmount(finishedRoot, current$jscomp$0, renderPriorityLevel) { +function commitUnmount(finishedRoot, current$$1$jscomp$0, renderPriorityLevel) { "function" === typeof onCommitFiberUnmount && - onCommitFiberUnmount(current$jscomp$0); - switch (current$jscomp$0.tag) { + onCommitFiberUnmount(current$$1$jscomp$0); + switch (current$$1$jscomp$0.tag) { case 0: case 11: case 14: case 15: - case 22: - finishedRoot = current$jscomp$0.updateQueue; + finishedRoot = current$$1$jscomp$0.updateQueue; if ( null !== finishedRoot && ((finishedRoot = finishedRoot.lastEffect), null !== finishedRoot) @@ -5066,13 +4874,13 @@ function commitUnmount(finishedRoot, current$jscomp$0, renderPriorityLevel) { function() { var effect = firstEffect; do { - var _destroy = effect.destroy; - if (void 0 !== _destroy) { - var current = current$jscomp$0; + var destroy = effect.destroy; + if (void 0 !== destroy) { + var current$$1 = current$$1$jscomp$0; try { - _destroy(); + destroy(); } catch (error) { - captureCommitPhaseError(current, error); + captureCommitPhaseError(current$$1, error); } } effect = effect.next; @@ -5082,35 +4890,37 @@ function commitUnmount(finishedRoot, current$jscomp$0, renderPriorityLevel) { } break; case 1: - safelyDetachRef(current$jscomp$0); - renderPriorityLevel = current$jscomp$0.stateNode; + safelyDetachRef(current$$1$jscomp$0); + renderPriorityLevel = current$$1$jscomp$0.stateNode; "function" === typeof renderPriorityLevel.componentWillUnmount && - safelyCallComponentWillUnmount(current$jscomp$0, renderPriorityLevel); + safelyCallComponentWillUnmount( + current$$1$jscomp$0, + renderPriorityLevel + ); break; case 5: - safelyDetachRef(current$jscomp$0); + safelyDetachRef(current$$1$jscomp$0); break; case 4: unmountHostComponents( finishedRoot, - current$jscomp$0, + current$$1$jscomp$0, renderPriorityLevel ); } } -function detachFiber(current) { - var alternate = current.alternate; - current.return = null; - current.child = null; - current.memoizedState = null; - current.updateQueue = null; - current.dependencies = null; - current.alternate = null; - current.firstEffect = null; - current.lastEffect = null; - current.pendingProps = null; - current.memoizedProps = null; - current.stateNode = null; +function detachFiber(current$$1) { + var alternate = current$$1.alternate; + current$$1.return = null; + current$$1.child = null; + current$$1.memoizedState = null; + current$$1.updateQueue = null; + current$$1.dependencies = null; + current$$1.alternate = null; + current$$1.firstEffect = null; + current$$1.lastEffect = null; + current$$1.pendingProps = null; + current$$1.memoizedProps = null; null !== alternate && detachFiber(alternate); } function isHostParent(fiber) { @@ -5173,103 +4983,97 @@ function commitPlacement(finishedWork) { break a; } } - isContainer - ? insertOrAppendPlacementNodeIntoContainer( - finishedWork, - parentFiber, - parent - ) - : insertOrAppendPlacementNode(finishedWork, parentFiber, parent); -} -function insertOrAppendPlacementNodeIntoContainer(node, before, parent) { - var tag = node.tag, - isHost = 5 === tag || 6 === tag; - if (isHost) - if (((node = isHost ? node.stateNode : node.stateNode.instance), before)) { - if ("number" === typeof parent) - throw Error("Container does not support insertBefore operation"); - } else - ReactNativePrivateInterface.UIManager.setChildren(parent, [ - "number" === typeof node ? node : node._nativeTag - ]); - else if (4 !== tag && ((node = node.child), null !== node)) - for ( - insertOrAppendPlacementNodeIntoContainer(node, before, parent), - node = node.sibling; - null !== node; - - ) - insertOrAppendPlacementNodeIntoContainer(node, before, parent), - (node = node.sibling); -} -function insertOrAppendPlacementNode(node, before, parent) { - var tag = node.tag, - isHost = 5 === tag || 6 === tag; - if (isHost) - (node = isHost ? node.stateNode : node.stateNode.instance), - before - ? ((tag = parent._children), - (isHost = tag.indexOf(node)), - 0 <= isHost - ? (tag.splice(isHost, 1), - (before = tag.indexOf(before)), - tag.splice(before, 0, node), - ReactNativePrivateInterface.UIManager.manageChildren( - parent._nativeTag, - [isHost], - [before], - [], - [], - [] - )) - : ((before = tag.indexOf(before)), - tag.splice(before, 0, node), - ReactNativePrivateInterface.UIManager.manageChildren( - parent._nativeTag, - [], - [], - ["number" === typeof node ? node : node._nativeTag], - [before], - [] - ))) - : ((before = "number" === typeof node ? node : node._nativeTag), - (tag = parent._children), - (isHost = tag.indexOf(node)), - 0 <= isHost - ? (tag.splice(isHost, 1), - tag.push(node), + for (var node = finishedWork; ; ) { + var isHost = 5 === node.tag || 6 === node.tag; + if (isHost) { + var stateNode = isHost ? node.stateNode : node.stateNode.instance; + if (parentFiber) + if (isContainer) { + if ("number" === typeof parent) + throw Error("Container does not support insertBefore operation"); + } else { + isHost = parent; + var beforeChild = parentFiber, + children = isHost._children, + index = children.indexOf(stateNode); + 0 <= index + ? (children.splice(index, 1), + (beforeChild = children.indexOf(beforeChild)), + children.splice(beforeChild, 0, stateNode), ReactNativePrivateInterface.UIManager.manageChildren( - parent._nativeTag, - [isHost], - [tag.length - 1], + isHost._nativeTag, + [index], + [beforeChild], [], [], [] )) - : (tag.push(node), + : ((index = children.indexOf(beforeChild)), + children.splice(index, 0, stateNode), ReactNativePrivateInterface.UIManager.manageChildren( - parent._nativeTag, + isHost._nativeTag, [], [], - [before], - [tag.length - 1], + [ + "number" === typeof stateNode + ? stateNode + : stateNode._nativeTag + ], + [index], [] - ))); - else if (4 !== tag && ((node = node.child), null !== node)) - for ( - insertOrAppendPlacementNode(node, before, parent), node = node.sibling; - null !== node; - - ) - insertOrAppendPlacementNode(node, before, parent), (node = node.sibling); + )); + } + else + isContainer + ? ReactNativePrivateInterface.UIManager.setChildren(parent, [ + "number" === typeof stateNode ? stateNode : stateNode._nativeTag + ]) + : ((isHost = parent), + (children = + "number" === typeof stateNode ? stateNode : stateNode._nativeTag), + (index = isHost._children), + (beforeChild = index.indexOf(stateNode)), + 0 <= beforeChild + ? (index.splice(beforeChild, 1), + index.push(stateNode), + ReactNativePrivateInterface.UIManager.manageChildren( + isHost._nativeTag, + [beforeChild], + [index.length - 1], + [], + [], + [] + )) + : (index.push(stateNode), + ReactNativePrivateInterface.UIManager.manageChildren( + isHost._nativeTag, + [], + [], + [children], + [index.length - 1], + [] + ))); + } else if (4 !== node.tag && null !== node.child) { + node.child.return = node; + node = node.child; + continue; + } + if (node === finishedWork) break; + for (; null === node.sibling; ) { + if (null === node.return || node.return === finishedWork) return; + node = node.return; + } + node.sibling.return = node.return; + node = node.sibling; + } } function unmountHostComponents( finishedRoot$jscomp$0, - current, + current$$1, renderPriorityLevel$jscomp$0 ) { for ( - var node = current, + var node = current$$1, currentParentIsValid = !1, currentParent, currentParentIsContainer; @@ -5317,7 +5121,7 @@ function unmountHostComponents( (node$jscomp$0.child.return = node$jscomp$0), (node$jscomp$0 = node$jscomp$0.child); else { - if (node$jscomp$0 === root) break a; + if (node$jscomp$0 === root) break; for (; null === node$jscomp$0.sibling; ) { if (null === node$jscomp$0.return || node$jscomp$0.return === root) break a; @@ -5367,9 +5171,9 @@ function unmountHostComponents( node = node.child; continue; } - if (node === current) break; + if (node === current$$1) break; for (; null === node.sibling; ) { - if (null === node.return || node.return === current) return; + if (null === node.return || node.return === current$$1) return; node = node.return; 4 === node.tag && (currentParentIsValid = !1); } @@ -5377,22 +5181,21 @@ function unmountHostComponents( node = node.sibling; } } -function commitWork(current, finishedWork) { +function commitWork(current$$1, finishedWork) { switch (finishedWork.tag) { case 0: case 11: case 14: case 15: - case 22: - commitHookEffectListUnmount(3, finishedWork); - return; + commitHookEffectList(4, 8, finishedWork); + break; case 1: - return; + break; case 5: var instance = finishedWork.stateNode; if (null != instance) { var newProps = finishedWork.memoizedProps; - current = null !== current ? current.memoizedProps : newProps; + current$$1 = null !== current$$1 ? current$$1.memoizedProps : newProps; var updatePayload = finishedWork.updateQueue; finishedWork.updateQueue = null; null !== updatePayload && @@ -5400,7 +5203,7 @@ function commitWork(current, finishedWork) { instanceProps.set(instance._nativeTag, newProps), (newProps = diffProperties( null, - current, + current$$1, newProps, finishedWork.validAttributes )), @@ -5411,7 +5214,7 @@ function commitWork(current, finishedWork) { newProps )); } - return; + break; case 6: if (null === finishedWork.stateNode) throw Error( @@ -5422,11 +5225,11 @@ function commitWork(current, finishedWork) { "RCTRawText", { text: finishedWork.memoizedProps } ); - return; + break; case 3: - return; + break; case 12: - return; + break; case 13: instance = finishedWork; null === finishedWork.memoizedState @@ -5435,9 +5238,9 @@ function commitWork(current, finishedWork) { (instance = finishedWork.child), (globalMostRecentFallbackTime = now())); if (null !== instance) - a: for (current = instance; ; ) { - if (5 === current.tag) - if (((updatePayload = current.stateNode), newProps)) { + a: for (current$$1 = instance; ; ) { + if (5 === current$$1.tag) + if (((updatePayload = current$$1.stateNode), newProps)) { var viewConfig = updatePayload.viewConfig; var updatePayload$jscomp$0 = diffProperties( null, @@ -5451,8 +5254,8 @@ function commitWork(current, finishedWork) { updatePayload$jscomp$0 ); } else { - updatePayload = current.stateNode; - updatePayload$jscomp$0 = current.memoizedProps; + updatePayload = current$$1.stateNode; + updatePayload$jscomp$0 = current$$1.memoizedProps; viewConfig = updatePayload.viewConfig; var prevProps = Object.assign({}, updatePayload$jscomp$0, { style: [updatePayload$jscomp$0.style, { display: "none" }] @@ -5470,41 +5273,47 @@ function commitWork(current, finishedWork) { ); } else { - if (6 === current.tag) throw Error("Not yet implemented."); + if (6 === current$$1.tag) throw Error("Not yet implemented."); if ( - 13 === current.tag && - null !== current.memoizedState && - null === current.memoizedState.dehydrated + 13 === current$$1.tag && + null !== current$$1.memoizedState && + null === current$$1.memoizedState.dehydrated ) { - updatePayload = current.child.sibling; - updatePayload.return = current; - current = updatePayload; + updatePayload = current$$1.child.sibling; + updatePayload.return = current$$1; + current$$1 = updatePayload; continue; - } else if (null !== current.child) { - current.child.return = current; - current = current.child; + } else if (null !== current$$1.child) { + current$$1.child.return = current$$1; + current$$1 = current$$1.child; continue; } } - if (current === instance) break; - for (; null === current.sibling; ) { - if (null === current.return || current.return === instance) break a; - current = current.return; + if (current$$1 === instance) break a; + for (; null === current$$1.sibling; ) { + if (null === current$$1.return || current$$1.return === instance) + break a; + current$$1 = current$$1.return; } - current.sibling.return = current.return; - current = current.sibling; + current$$1.sibling.return = current$$1.return; + current$$1 = current$$1.sibling; } attachSuspenseRetryListeners(finishedWork); - return; + break; case 19: attachSuspenseRetryListeners(finishedWork); - return; + break; case 17: - return; + break; + case 20: + break; + case 21: + 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." + ); } - 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 thenables = finishedWork.updateQueue; @@ -5560,7 +5369,7 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { return expirationTime; } var ceil = Math.ceil, - ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, + ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, NoContext = 0, LegacyUnbatchedContext = 8, @@ -5575,7 +5384,7 @@ var ceil = Math.ceil, executionContext = NoContext, workInProgressRoot = null, workInProgress = null, - renderExpirationTime$1 = 0, + renderExpirationTime = 0, workInProgressRootExitStatus = RootIncomplete, workInProgressRootFatalError = null, workInProgressRootLatestProcessedExpirationTime = 1073741823, @@ -5600,8 +5409,8 @@ function requestCurrentTimeForUpdate() { return (executionContext & (RenderContext | CommitContext)) !== NoContext ? 1073741821 - ((now() / 10) | 0) : 0 !== currentEventTime - ? currentEventTime - : (currentEventTime = 1073741821 - ((now() / 10) | 0)); + ? currentEventTime + : (currentEventTime = 1073741821 - ((now() / 10) | 0)); } function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { fiber = fiber.mode; @@ -5609,7 +5418,7 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { var priorityLevel = getCurrentPriorityLevel(); if (0 === (fiber & 4)) return 99 === priorityLevel ? 1073741823 : 1073741822; if ((executionContext & RenderContext) !== NoContext) - return renderExpirationTime$1; + return renderExpirationTime; if (null !== suspenseConfig) currentTime = 1073741821 - @@ -5641,11 +5450,11 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { throw Error("Expected a valid priority level"); } null !== workInProgressRoot && - currentTime === renderExpirationTime$1 && + currentTime === renderExpirationTime && --currentTime; return currentTime; } -function scheduleWork(fiber, expirationTime) { +function scheduleUpdateOnFiber(fiber, expirationTime) { if (50 < nestedUpdateCount) throw ((nestedUpdateCount = 0), (rootWithNestedUpdates = null), @@ -5699,7 +5508,7 @@ function markUpdateTimeFromFiberToRoot(fiber, expirationTime) { (workInProgressRoot === root && (markUnprocessedUpdateTime(expirationTime), workInProgressRootExitStatus === RootSuspendedWithDelay && - markRootSuspendedAtTime(root, renderExpirationTime$1)), + markRootSuspendedAtTime(root, renderExpirationTime)), markRootUpdatedAtTime(root, expirationTime)); return root; } @@ -5708,10 +5517,9 @@ function getNextRootExpirationTimeToWorkOn(root) { if (0 !== lastExpiredTime) return lastExpiredTime; lastExpiredTime = root.firstPendingTime; if (!isRootSuspendedAtTime(root, lastExpiredTime)) return lastExpiredTime; - var lastPingedTime = root.lastPingedTime; + lastExpiredTime = root.lastPingedTime; root = root.nextKnownPendingLevel; - root = lastPingedTime > root ? lastPingedTime : root; - return 2 >= root && lastExpiredTime !== root ? 0 : root; + return lastExpiredTime > root ? lastExpiredTime : root; } function ensureRootIsScheduled(root) { if (0 !== root.lastExpiredTime) @@ -5733,18 +5541,18 @@ function ensureRootIsScheduled(root) { 1073741823 === expirationTime ? (priorityLevel = 99) : 1 === expirationTime || 2 === expirationTime - ? (priorityLevel = 95) - : ((priorityLevel = - 10 * (1073741821 - expirationTime) - - 10 * (1073741821 - priorityLevel)), - (priorityLevel = - 0 >= priorityLevel - ? 99 - : 250 >= priorityLevel - ? 98 - : 5250 >= priorityLevel - ? 97 - : 95)); + ? (priorityLevel = 95) + : ((priorityLevel = + 10 * (1073741821 - expirationTime) - + 10 * (1073741821 - priorityLevel)), + (priorityLevel = + 0 >= priorityLevel + ? 99 + : 250 >= priorityLevel + ? 98 + : 5250 >= priorityLevel + ? 97 + : 95)); if (null !== existingCallbackNode) { var existingCallbackPriority = root.callbackPriority; if ( @@ -5771,225 +5579,264 @@ function ensureRootIsScheduled(root) { } function performConcurrentWorkOnRoot(root, didTimeout) { currentEventTime = 0; - if (didTimeout) { - didTimeout = requestCurrentTimeForUpdate(); - var lastExpiredTime = root.lastExpiredTime; - if (0 === lastExpiredTime || lastExpiredTime > didTimeout) - root.lastExpiredTime = didTimeout; - ensureRootIsScheduled(root); - return null; - } - lastExpiredTime = getNextRootExpirationTimeToWorkOn(root); - if (0 === lastExpiredTime) return null; - didTimeout = root.callbackNode; - if ((executionContext & (RenderContext | CommitContext)) !== NoContext) - throw Error("Should not already be working."); - flushPassiveEffects(); - var expirationTime = lastExpiredTime; - var exitStatus = executionContext; - executionContext |= RenderContext; - var prevDispatcher = pushDispatcher(); - (root === workInProgressRoot && expirationTime === renderExpirationTime$1) || - prepareFreshStack(root, expirationTime); - do - try { - workLoopConcurrent(); - break; - } catch (thrownValue) { - handleError(root, thrownValue); - } - while (1); - resetContextDependencies(); - ReactCurrentDispatcher$1.current = prevDispatcher; - executionContext = exitStatus; - null !== workInProgress - ? (exitStatus = RootIncomplete) - : ((workInProgressRoot = null), - (exitStatus = workInProgressRootExitStatus)); - if (exitStatus !== RootIncomplete) { - exitStatus === RootErrored && - ((lastExpiredTime = 2 < lastExpiredTime ? 2 : lastExpiredTime), - (exitStatus = renderRootSync(root, lastExpiredTime))); - if (exitStatus === RootFatalErrored) - throw ((didTimeout = workInProgressRootFatalError), - prepareFreshStack(root, lastExpiredTime), - markRootSuspendedAtTime(root, lastExpiredTime), + if (didTimeout) + return ( + (didTimeout = requestCurrentTimeForUpdate()), + markRootExpiredAtTime(root, didTimeout), ensureRootIsScheduled(root), - didTimeout); - expirationTime = root.finishedWork = root.current.alternate; - root.finishedExpirationTime = lastExpiredTime; - switch (exitStatus) { - case RootIncomplete: - case RootFatalErrored: - throw Error("Root did not complete. This is a bug in React."); - case RootErrored: - commitRoot(root); - break; - case RootSuspended: - markRootSuspendedAtTime(root, lastExpiredTime); - exitStatus = root.lastSuspendedTime; - lastExpiredTime === exitStatus && - (root.nextKnownPendingLevel = getRemainingExpirationTime( - expirationTime - )); - if ( - 1073741823 === workInProgressRootLatestProcessedExpirationTime && - ((expirationTime = - globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now()), - 10 < expirationTime) - ) { - if ( - workInProgressRootHasPendingPing && - ((prevDispatcher = root.lastPingedTime), - 0 === prevDispatcher || prevDispatcher >= lastExpiredTime) - ) { - root.lastPingedTime = lastExpiredTime; - prepareFreshStack(root, lastExpiredTime); - break; - } - prevDispatcher = getNextRootExpirationTimeToWorkOn(root); - if (0 !== prevDispatcher && prevDispatcher !== lastExpiredTime) break; - if (0 !== exitStatus && exitStatus !== lastExpiredTime) { - root.lastPingedTime = exitStatus; - break; - } - root.timeoutHandle = scheduleTimeout( - commitRoot.bind(null, root), - expirationTime - ); - break; - } - commitRoot(root); - break; - case RootSuspendedWithDelay: - markRootSuspendedAtTime(root, lastExpiredTime); - exitStatus = root.lastSuspendedTime; - lastExpiredTime === exitStatus && - (root.nextKnownPendingLevel = getRemainingExpirationTime( - expirationTime - )); - if ( - workInProgressRootHasPendingPing && - ((expirationTime = root.lastPingedTime), - 0 === expirationTime || expirationTime >= lastExpiredTime) - ) { - root.lastPingedTime = lastExpiredTime; - prepareFreshStack(root, lastExpiredTime); - break; - } - expirationTime = getNextRootExpirationTimeToWorkOn(root); - if (0 !== expirationTime && expirationTime !== lastExpiredTime) break; - if (0 !== exitStatus && exitStatus !== lastExpiredTime) { - root.lastPingedTime = exitStatus; - break; - } - 1073741823 !== workInProgressRootLatestSuspenseTimeout - ? (expirationTime = - 10 * (1073741821 - workInProgressRootLatestSuspenseTimeout) - - now()) - : 1073741823 === workInProgressRootLatestProcessedExpirationTime - ? (expirationTime = 0) - : ((expirationTime = - 10 * - (1073741821 - workInProgressRootLatestProcessedExpirationTime) - - 5e3), - (exitStatus = now()), - (lastExpiredTime = - 10 * (1073741821 - lastExpiredTime) - exitStatus), - (expirationTime = exitStatus - expirationTime), - 0 > expirationTime && (expirationTime = 0), - (expirationTime = - (120 > expirationTime - ? 120 - : 480 > expirationTime - ? 480 - : 1080 > expirationTime - ? 1080 - : 1920 > expirationTime - ? 1920 - : 3e3 > expirationTime - ? 3e3 - : 4320 > expirationTime - ? 4320 - : 1960 * ceil(expirationTime / 1960)) - expirationTime), - lastExpiredTime < expirationTime && - (expirationTime = lastExpiredTime)); - if (10 < expirationTime) { - root.timeoutHandle = scheduleTimeout( - commitRoot.bind(null, root), - expirationTime - ); + null + ); + var expirationTime = getNextRootExpirationTimeToWorkOn(root); + if (0 !== expirationTime) { + didTimeout = root.callbackNode; + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) + throw Error("Should not already be working."); + flushPassiveEffects(); + (root === workInProgressRoot && expirationTime === renderExpirationTime) || + prepareFreshStack(root, expirationTime); + if (null !== workInProgress) { + var prevExecutionContext = executionContext; + executionContext |= RenderContext; + var prevDispatcher = pushDispatcher(root); + do + try { + workLoopConcurrent(); break; + } catch (thrownValue) { + handleError(root, thrownValue); } - commitRoot(root); - break; - case RootCompleted: - if ( - 1073741823 !== workInProgressRootLatestProcessedExpirationTime && - null !== workInProgressRootCanSuspendUsingConfig + while (1); + resetContextDependencies(); + executionContext = prevExecutionContext; + ReactCurrentDispatcher.current = prevDispatcher; + if (workInProgressRootExitStatus === RootFatalErrored) + throw ((didTimeout = workInProgressRootFatalError), + prepareFreshStack(root, expirationTime), + markRootSuspendedAtTime(root, expirationTime), + ensureRootIsScheduled(root), + didTimeout); + if (null === workInProgress) + switch ( + ((prevDispatcher = root.finishedWork = root.current.alternate), + (root.finishedExpirationTime = expirationTime), + (prevExecutionContext = workInProgressRootExitStatus), + (workInProgressRoot = null), + prevExecutionContext) ) { - prevDispatcher = workInProgressRootLatestProcessedExpirationTime; - var suspenseConfig = workInProgressRootCanSuspendUsingConfig; - expirationTime = suspenseConfig.busyMinDurationMs | 0; - 0 >= expirationTime - ? (expirationTime = 0) - : ((exitStatus = suspenseConfig.busyDelayMs | 0), - (prevDispatcher = - now() - - (10 * (1073741821 - prevDispatcher) - - (suspenseConfig.timeoutMs | 0 || 5e3))), - (expirationTime = - prevDispatcher <= exitStatus - ? 0 - : exitStatus + expirationTime - prevDispatcher)); - if (10 < expirationTime) { - markRootSuspendedAtTime(root, lastExpiredTime); - root.timeoutHandle = scheduleTimeout( - commitRoot.bind(null, root), - expirationTime + case RootIncomplete: + case RootFatalErrored: + throw Error("Root did not complete. This is a bug in React."); + case RootErrored: + markRootExpiredAtTime( + root, + 2 < expirationTime ? 2 : expirationTime ); break; - } + case RootSuspended: + markRootSuspendedAtTime(root, expirationTime); + prevExecutionContext = root.lastSuspendedTime; + expirationTime === prevExecutionContext && + (root.nextKnownPendingLevel = getRemainingExpirationTime( + prevDispatcher + )); + if ( + 1073741823 === workInProgressRootLatestProcessedExpirationTime && + ((prevDispatcher = + globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now()), + 10 < prevDispatcher) + ) { + if (workInProgressRootHasPendingPing) { + var lastPingedTime = root.lastPingedTime; + if (0 === lastPingedTime || lastPingedTime >= expirationTime) { + root.lastPingedTime = expirationTime; + prepareFreshStack(root, expirationTime); + break; + } + } + lastPingedTime = getNextRootExpirationTimeToWorkOn(root); + if (0 !== lastPingedTime && lastPingedTime !== expirationTime) + break; + if ( + 0 !== prevExecutionContext && + prevExecutionContext !== expirationTime + ) { + root.lastPingedTime = prevExecutionContext; + break; + } + root.timeoutHandle = scheduleTimeout( + commitRoot.bind(null, root), + prevDispatcher + ); + break; + } + commitRoot(root); + break; + case RootSuspendedWithDelay: + markRootSuspendedAtTime(root, expirationTime); + prevExecutionContext = root.lastSuspendedTime; + expirationTime === prevExecutionContext && + (root.nextKnownPendingLevel = getRemainingExpirationTime( + prevDispatcher + )); + if ( + workInProgressRootHasPendingPing && + ((prevDispatcher = root.lastPingedTime), + 0 === prevDispatcher || prevDispatcher >= expirationTime) + ) { + root.lastPingedTime = expirationTime; + prepareFreshStack(root, expirationTime); + break; + } + prevDispatcher = getNextRootExpirationTimeToWorkOn(root); + if (0 !== prevDispatcher && prevDispatcher !== expirationTime) + break; + if ( + 0 !== prevExecutionContext && + prevExecutionContext !== expirationTime + ) { + root.lastPingedTime = prevExecutionContext; + break; + } + 1073741823 !== workInProgressRootLatestSuspenseTimeout + ? (prevExecutionContext = + 10 * (1073741821 - workInProgressRootLatestSuspenseTimeout) - + now()) + : 1073741823 === workInProgressRootLatestProcessedExpirationTime + ? (prevExecutionContext = 0) + : ((prevExecutionContext = + 10 * + (1073741821 - + workInProgressRootLatestProcessedExpirationTime) - + 5e3), + (prevDispatcher = now()), + (expirationTime = + 10 * (1073741821 - expirationTime) - prevDispatcher), + (prevExecutionContext = + prevDispatcher - prevExecutionContext), + 0 > prevExecutionContext && (prevExecutionContext = 0), + (prevExecutionContext = + (120 > prevExecutionContext + ? 120 + : 480 > prevExecutionContext + ? 480 + : 1080 > prevExecutionContext + ? 1080 + : 1920 > prevExecutionContext + ? 1920 + : 3e3 > prevExecutionContext + ? 3e3 + : 4320 > prevExecutionContext + ? 4320 + : 1960 * ceil(prevExecutionContext / 1960)) - + prevExecutionContext), + expirationTime < prevExecutionContext && + (prevExecutionContext = expirationTime)); + if (10 < prevExecutionContext) { + root.timeoutHandle = scheduleTimeout( + commitRoot.bind(null, root), + prevExecutionContext + ); + break; + } + commitRoot(root); + break; + case RootCompleted: + if ( + 1073741823 !== workInProgressRootLatestProcessedExpirationTime && + null !== workInProgressRootCanSuspendUsingConfig + ) { + lastPingedTime = workInProgressRootLatestProcessedExpirationTime; + var suspenseConfig = workInProgressRootCanSuspendUsingConfig; + prevExecutionContext = suspenseConfig.busyMinDurationMs | 0; + 0 >= prevExecutionContext + ? (prevExecutionContext = 0) + : ((prevDispatcher = suspenseConfig.busyDelayMs | 0), + (lastPingedTime = + now() - + (10 * (1073741821 - lastPingedTime) - + (suspenseConfig.timeoutMs | 0 || 5e3))), + (prevExecutionContext = + lastPingedTime <= prevDispatcher + ? 0 + : prevDispatcher + + prevExecutionContext - + lastPingedTime)); + if (10 < prevExecutionContext) { + markRootSuspendedAtTime(root, expirationTime); + root.timeoutHandle = scheduleTimeout( + commitRoot.bind(null, root), + prevExecutionContext + ); + break; + } + } + commitRoot(root); + break; + default: + throw Error("Unknown root exit status."); } - commitRoot(root); - break; - default: - throw Error("Unknown root exit status."); + ensureRootIsScheduled(root); + if (root.callbackNode === didTimeout) + return performConcurrentWorkOnRoot.bind(null, root); } } - ensureRootIsScheduled(root); - return root.callbackNode === didTimeout - ? performConcurrentWorkOnRoot.bind(null, root) - : null; + return null; } function performSyncWorkOnRoot(root) { - if ((executionContext & (RenderContext | CommitContext)) !== NoContext) - throw Error("Should not already be working."); - flushPassiveEffects(); var lastExpiredTime = root.lastExpiredTime; - lastExpiredTime = - 0 !== lastExpiredTime - ? root === workInProgressRoot && renderExpirationTime$1 >= lastExpiredTime - ? renderExpirationTime$1 - : lastExpiredTime - : 1073741823; - var exitStatus = renderRootSync(root, lastExpiredTime); - 0 !== root.tag && - exitStatus === RootErrored && - ((lastExpiredTime = 2 < lastExpiredTime ? 2 : lastExpiredTime), - (exitStatus = renderRootSync(root, lastExpiredTime))); - if (exitStatus === RootFatalErrored) - throw ((exitStatus = workInProgressRootFatalError), - prepareFreshStack(root, lastExpiredTime), - markRootSuspendedAtTime(root, lastExpiredTime), - ensureRootIsScheduled(root), - exitStatus); - root.finishedWork = root.current.alternate; - root.finishedExpirationTime = lastExpiredTime; - commitRoot(root); - ensureRootIsScheduled(root); + lastExpiredTime = 0 !== lastExpiredTime ? lastExpiredTime : 1073741823; + if (root.finishedExpirationTime === lastExpiredTime) commitRoot(root); + else { + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) + throw Error("Should not already be working."); + flushPassiveEffects(); + (root === workInProgressRoot && lastExpiredTime === renderExpirationTime) || + prepareFreshStack(root, lastExpiredTime); + if (null !== workInProgress) { + var prevExecutionContext = executionContext; + executionContext |= RenderContext; + var prevDispatcher = pushDispatcher(root); + do + try { + workLoopSync(); + break; + } catch (thrownValue) { + handleError(root, thrownValue); + } + while (1); + resetContextDependencies(); + executionContext = prevExecutionContext; + ReactCurrentDispatcher.current = prevDispatcher; + if (workInProgressRootExitStatus === RootFatalErrored) + throw ((prevExecutionContext = workInProgressRootFatalError), + prepareFreshStack(root, lastExpiredTime), + markRootSuspendedAtTime(root, lastExpiredTime), + ensureRootIsScheduled(root), + prevExecutionContext); + if (null !== workInProgress) + throw Error( + "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." + ); + root.finishedWork = root.current.alternate; + root.finishedExpirationTime = lastExpiredTime; + workInProgressRoot = null; + commitRoot(root); + ensureRootIsScheduled(root); + } + } return null; } +function flushPendingDiscreteUpdates() { + if (null !== rootsWithPendingDiscreteUpdates) { + var roots = rootsWithPendingDiscreteUpdates; + rootsWithPendingDiscreteUpdates = null; + roots.forEach(function(expirationTime, root) { + markRootExpiredAtTime(root, expirationTime); + ensureRootIsScheduled(root); + }); + flushSyncCallbackQueue(); + } +} function prepareFreshStack(root, expirationTime) { root.finishedWork = null; root.finishedExpirationTime = 0; @@ -6001,27 +5848,26 @@ function prepareFreshStack(root, expirationTime) { var interruptedWork = timeoutHandle; switch (interruptedWork.tag) { case 1: - interruptedWork = interruptedWork.type.childContextTypes; - null !== interruptedWork && - void 0 !== interruptedWork && - popContext(); + var childContextTypes = interruptedWork.type.childContextTypes; + null !== childContextTypes && + void 0 !== childContextTypes && + popContext(interruptedWork); break; case 3: - popHostContainer(); - pop(didPerformWorkStackCursor); - pop(contextStackCursor); + popHostContainer(interruptedWork); + popTopLevelContextObject(interruptedWork); break; case 5: popHostContext(interruptedWork); break; case 4: - popHostContainer(); + popHostContainer(interruptedWork); break; case 13: - pop(suspenseStackCursor); + pop(suspenseStackCursor, interruptedWork); break; case 19: - pop(suspenseStackCursor); + pop(suspenseStackCursor, interruptedWork); break; case 10: popProvider(interruptedWork); @@ -6029,8 +5875,8 @@ function prepareFreshStack(root, expirationTime) { timeoutHandle = timeoutHandle.return; } workInProgressRoot = root; - workInProgress = createWorkInProgress(root.current, null); - renderExpirationTime$1 = expirationTime; + workInProgress = createWorkInProgress(root.current, null, expirationTime); + renderExpirationTime = expirationTime; workInProgressRootExitStatus = RootIncomplete; workInProgressRootFatalError = null; workInProgressRootLatestSuspenseTimeout = workInProgressRootLatestProcessedExpirationTime = 1073741823; @@ -6042,32 +5888,19 @@ function handleError(root$jscomp$0, thrownValue) { do { try { resetContextDependencies(); - ReactCurrentDispatcher.current = ContextOnlyDispatcher; - if (didScheduleRenderPhaseUpdate) - for ( - var hook = currentlyRenderingFiber$1.memoizedState; - null !== hook; - - ) { - var queue = hook.queue; - null !== queue && (queue.pending = null); - hook = hook.next; - } - renderExpirationTime = 0; - workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; - didScheduleRenderPhaseUpdate = !1; + resetHooks(); if (null === workInProgress || null === workInProgress.return) return ( (workInProgressRootExitStatus = RootFatalErrored), (workInProgressRootFatalError = thrownValue), - (workInProgress = null) + null ); a: { var root = root$jscomp$0, returnFiber = workInProgress.return, sourceFiber = workInProgress, value = thrownValue; - thrownValue = renderExpirationTime$1; + thrownValue = renderExpirationTime; sourceFiber.effectTag |= 2048; sourceFiber.firstEffect = sourceFiber.lastEffect = null; if ( @@ -6075,17 +5908,8 @@ function handleError(root$jscomp$0, thrownValue) { "object" === typeof value && "function" === typeof value.then ) { - var thenable = value; - if (0 === (sourceFiber.mode & 2)) { - var currentSource = sourceFiber.alternate; - currentSource - ? ((sourceFiber.updateQueue = currentSource.updateQueue), - (sourceFiber.memoizedState = currentSource.memoizedState), - (sourceFiber.expirationTime = currentSource.expirationTime)) - : ((sourceFiber.updateQueue = null), - (sourceFiber.memoizedState = null)); - } - var hasInvisibleParentBoundary = + var thenable = value, + hasInvisibleParentBoundary = 0 !== (suspenseStackCursor.current & 1), _workInProgress = returnFiber; do { @@ -6100,10 +5924,10 @@ function handleError(root$jscomp$0, thrownValue) { void 0 === props.fallback ? !1 : !0 !== props.unstable_avoidThisFallback - ? !0 - : hasInvisibleParentBoundary - ? !1 - : !0; + ? !0 + : hasInvisibleParentBoundary + ? !1 + : !0; } } if (JSCompiler_temp) { @@ -6210,8 +6034,8 @@ function handleError(root$jscomp$0, thrownValue) { } while (1); } function pushDispatcher() { - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = ContextOnlyDispatcher; return null === prevDispatcher ? ContextOnlyDispatcher : prevDispatcher; } function markRenderEventTimeAndConfig(expirationTime, suspenseConfig) { @@ -6228,43 +6052,19 @@ function markUnprocessedUpdateTime(expirationTime) { expirationTime > workInProgressRootNextUnprocessedUpdateTime && (workInProgressRootNextUnprocessedUpdateTime = expirationTime); } -function renderRootSync(root, expirationTime) { - var prevExecutionContext = executionContext; - executionContext |= RenderContext; - var prevDispatcher = pushDispatcher(); - (root === workInProgressRoot && expirationTime === renderExpirationTime$1) || - prepareFreshStack(root, expirationTime); - do - try { - workLoopSync(); - break; - } catch (thrownValue) { - handleError(root, thrownValue); - } - while (1); - resetContextDependencies(); - executionContext = prevExecutionContext; - ReactCurrentDispatcher$1.current = prevDispatcher; - if (null !== workInProgress) - throw Error( - "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." - ); - workInProgressRoot = null; - return workInProgressRootExitStatus; -} function workLoopSync() { for (; null !== workInProgress; ) workInProgress = performUnitOfWork(workInProgress); } function workLoopConcurrent() { - for (; null !== workInProgress && !shouldYield(); ) + for (; null !== workInProgress && !Scheduler_shouldYield(); ) workInProgress = performUnitOfWork(workInProgress); } function performUnitOfWork(unitOfWork) { - var next = beginWork$1( + var next = beginWork$$1( unitOfWork.alternate, unitOfWork, - renderExpirationTime$1 + renderExpirationTime ); unitOfWork.memoizedProps = unitOfWork.pendingProps; null === next && (next = completeUnitOfWork(unitOfWork)); @@ -6274,30 +6074,366 @@ function performUnitOfWork(unitOfWork) { function completeUnitOfWork(unitOfWork) { workInProgress = unitOfWork; do { - var current = workInProgress.alternate; + var current$$1 = workInProgress.alternate; unitOfWork = workInProgress.return; if (0 === (workInProgress.effectTag & 2048)) { - current = completeWork(current, workInProgress, renderExpirationTime$1); - if ( - 1 === renderExpirationTime$1 || - 1 !== workInProgress.childExpirationTime - ) { + a: { + var current = current$$1; + current$$1 = workInProgress; + var renderExpirationTime$jscomp$0 = renderExpirationTime, + newProps = current$$1.pendingProps; + switch (current$$1.tag) { + case 2: + break; + case 16: + break; + case 15: + case 0: + break; + case 1: + isContextProvider(current$$1.type) && popContext(current$$1); + break; + case 3: + popHostContainer(current$$1); + popTopLevelContextObject(current$$1); + current = current$$1.stateNode; + current.pendingContext && + ((current.context = current.pendingContext), + (current.pendingContext = null)); + updateHostContainer(current$$1); + break; + case 5: + popHostContext(current$$1); + var rootContainerInstance = requiredContext( + rootInstanceStackCursor.current + ); + renderExpirationTime$jscomp$0 = current$$1.type; + if (null !== current && null != current$$1.stateNode) + updateHostComponent$1( + current, + current$$1, + renderExpirationTime$jscomp$0, + newProps, + rootContainerInstance + ), + current.ref !== current$$1.ref && (current$$1.effectTag |= 128); + else if (newProps) { + current = requiredContext(contextStackCursor$1.current); + var internalInstanceHandle = current$$1, + tag = allocateTag(), + viewConfig = getViewConfigForType( + renderExpirationTime$jscomp$0 + ), + updatePayload = diffProperties( + null, + emptyObject, + newProps, + viewConfig.validAttributes + ); + ReactNativePrivateInterface.UIManager.createView( + tag, + viewConfig.uiViewClassName, + rootContainerInstance, + updatePayload + ); + viewConfig = new ReactNativeFiberHostComponent(tag, viewConfig); + instanceCache.set(tag, internalInstanceHandle); + instanceProps.set(tag, newProps); + appendAllChildren(viewConfig, current$$1, !1, !1); + current$$1.stateNode = viewConfig; + finalizeInitialChildren( + viewConfig, + renderExpirationTime$jscomp$0, + newProps, + rootContainerInstance, + current + ) && (current$$1.effectTag |= 4); + null !== current$$1.ref && (current$$1.effectTag |= 128); + } else if (null === current$$1.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." + ); + break; + case 6: + if (current && null != current$$1.stateNode) + updateHostText$1( + current, + current$$1, + current.memoizedProps, + newProps + ); + else { + if ("string" !== typeof newProps && null === current$$1.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." + ); + renderExpirationTime$jscomp$0 = requiredContext( + rootInstanceStackCursor.current + ); + rootContainerInstance = requiredContext( + contextStackCursor$1.current + ); + current = current$$1; + if (!rootContainerInstance.isInAParentText) + throw Error( + "Text strings must be rendered within a component." + ); + rootContainerInstance = allocateTag(); + ReactNativePrivateInterface.UIManager.createView( + rootContainerInstance, + "RCTRawText", + renderExpirationTime$jscomp$0, + { text: newProps } + ); + instanceCache.set(rootContainerInstance, current$$1); + current.stateNode = rootContainerInstance; + } + break; + case 11: + break; + case 13: + pop(suspenseStackCursor, current$$1); + newProps = current$$1.memoizedState; + if (0 !== (current$$1.effectTag & 64)) { + current$$1.expirationTime = renderExpirationTime$jscomp$0; + break a; + } + newProps = null !== newProps; + rootContainerInstance = !1; + null !== current && + ((renderExpirationTime$jscomp$0 = current.memoizedState), + (rootContainerInstance = null !== renderExpirationTime$jscomp$0), + newProps || + null === renderExpirationTime$jscomp$0 || + ((renderExpirationTime$jscomp$0 = current.child.sibling), + null !== renderExpirationTime$jscomp$0 && + ((internalInstanceHandle = current$$1.firstEffect), + null !== internalInstanceHandle + ? ((current$$1.firstEffect = renderExpirationTime$jscomp$0), + (renderExpirationTime$jscomp$0.nextEffect = internalInstanceHandle)) + : ((current$$1.firstEffect = current$$1.lastEffect = renderExpirationTime$jscomp$0), + (renderExpirationTime$jscomp$0.nextEffect = null)), + (renderExpirationTime$jscomp$0.effectTag = 8)))); + if ( + newProps && + !rootContainerInstance && + 0 !== (current$$1.mode & 2) + ) + if ( + (null === current && + !0 !== current$$1.memoizedProps.unstable_avoidThisFallback) || + 0 !== (suspenseStackCursor.current & 1) + ) + workInProgressRootExitStatus === RootIncomplete && + (workInProgressRootExitStatus = RootSuspended); + else { + if ( + workInProgressRootExitStatus === RootIncomplete || + workInProgressRootExitStatus === RootSuspended + ) + workInProgressRootExitStatus = RootSuspendedWithDelay; + 0 !== workInProgressRootNextUnprocessedUpdateTime && + null !== workInProgressRoot && + (markRootSuspendedAtTime( + workInProgressRoot, + renderExpirationTime + ), + markRootUpdatedAtTime( + workInProgressRoot, + workInProgressRootNextUnprocessedUpdateTime + )); + } + if (newProps || rootContainerInstance) current$$1.effectTag |= 4; + break; + case 7: + break; + case 8: + break; + case 12: + break; + case 4: + popHostContainer(current$$1); + updateHostContainer(current$$1); + break; + case 10: + popProvider(current$$1); + break; + case 9: + break; + case 14: + break; + case 17: + isContextProvider(current$$1.type) && popContext(current$$1); + break; + case 19: + pop(suspenseStackCursor, current$$1); + newProps = current$$1.memoizedState; + if (null === newProps) break; + rootContainerInstance = 0 !== (current$$1.effectTag & 64); + internalInstanceHandle = newProps.rendering; + if (null === internalInstanceHandle) + if (rootContainerInstance) cutOffTailIfNeeded(newProps, !1); + else { + if ( + workInProgressRootExitStatus !== RootIncomplete || + (null !== current && 0 !== (current.effectTag & 64)) + ) + for (current = current$$1.child; null !== current; ) { + internalInstanceHandle = findFirstSuspended(current); + if (null !== internalInstanceHandle) { + current$$1.effectTag |= 64; + cutOffTailIfNeeded(newProps, !1); + current = internalInstanceHandle.updateQueue; + null !== current && + ((current$$1.updateQueue = current), + (current$$1.effectTag |= 4)); + null === newProps.lastEffect && + (current$$1.firstEffect = null); + current$$1.lastEffect = newProps.lastEffect; + current = renderExpirationTime$jscomp$0; + for (newProps = current$$1.child; null !== newProps; ) + (rootContainerInstance = newProps), + (renderExpirationTime$jscomp$0 = current), + (rootContainerInstance.effectTag &= 2), + (rootContainerInstance.nextEffect = null), + (rootContainerInstance.firstEffect = null), + (rootContainerInstance.lastEffect = null), + (internalInstanceHandle = + rootContainerInstance.alternate), + null === internalInstanceHandle + ? ((rootContainerInstance.childExpirationTime = 0), + (rootContainerInstance.expirationTime = renderExpirationTime$jscomp$0), + (rootContainerInstance.child = null), + (rootContainerInstance.memoizedProps = null), + (rootContainerInstance.memoizedState = null), + (rootContainerInstance.updateQueue = null), + (rootContainerInstance.dependencies = null)) + : ((rootContainerInstance.childExpirationTime = + internalInstanceHandle.childExpirationTime), + (rootContainerInstance.expirationTime = + internalInstanceHandle.expirationTime), + (rootContainerInstance.child = + internalInstanceHandle.child), + (rootContainerInstance.memoizedProps = + internalInstanceHandle.memoizedProps), + (rootContainerInstance.memoizedState = + internalInstanceHandle.memoizedState), + (rootContainerInstance.updateQueue = + internalInstanceHandle.updateQueue), + (renderExpirationTime$jscomp$0 = + internalInstanceHandle.dependencies), + (rootContainerInstance.dependencies = + null === renderExpirationTime$jscomp$0 + ? null + : { + expirationTime: + renderExpirationTime$jscomp$0.expirationTime, + firstContext: + renderExpirationTime$jscomp$0.firstContext, + responders: + renderExpirationTime$jscomp$0.responders + })), + (newProps = newProps.sibling); + push( + suspenseStackCursor, + (suspenseStackCursor.current & 1) | 2, + current$$1 + ); + current$$1 = current$$1.child; + break a; + } + current = current.sibling; + } + } + else { + if (!rootContainerInstance) + if ( + ((current = findFirstSuspended(internalInstanceHandle)), + null !== current) + ) { + if ( + ((current$$1.effectTag |= 64), + (rootContainerInstance = !0), + (current = current.updateQueue), + null !== current && + ((current$$1.updateQueue = current), + (current$$1.effectTag |= 4)), + cutOffTailIfNeeded(newProps, !0), + null === newProps.tail && + "hidden" === newProps.tailMode && + !internalInstanceHandle.alternate) + ) { + current$$1 = current$$1.lastEffect = newProps.lastEffect; + null !== current$$1 && (current$$1.nextEffect = null); + break; + } + } else + now() > newProps.tailExpiration && + 1 < renderExpirationTime$jscomp$0 && + ((current$$1.effectTag |= 64), + (rootContainerInstance = !0), + cutOffTailIfNeeded(newProps, !1), + (current$$1.expirationTime = current$$1.childExpirationTime = + renderExpirationTime$jscomp$0 - 1)); + newProps.isBackwards + ? ((internalInstanceHandle.sibling = current$$1.child), + (current$$1.child = internalInstanceHandle)) + : ((current = newProps.last), + null !== current + ? (current.sibling = internalInstanceHandle) + : (current$$1.child = internalInstanceHandle), + (newProps.last = internalInstanceHandle)); + } + if (null !== newProps.tail) { + 0 === newProps.tailExpiration && + (newProps.tailExpiration = now() + 500); + current = newProps.tail; + newProps.rendering = current; + newProps.tail = current.sibling; + newProps.lastEffect = current$$1.lastEffect; + current.sibling = null; + newProps = suspenseStackCursor.current; + newProps = rootContainerInstance + ? (newProps & 1) | 2 + : newProps & 1; + push(suspenseStackCursor, newProps, current$$1); + current$$1 = current; + break a; + } + break; + case 20: + break; + case 21: + break; + default: + throw Error( + "Unknown unit of work tag (" + + current$$1.tag + + "). This error is likely caused by a bug in React. Please file an issue." + ); + } + current$$1 = null; + } + current = workInProgress; + if (1 === renderExpirationTime || 1 !== current.childExpirationTime) { + newProps = 0; for ( - var newChildExpirationTime = 0, _child = workInProgress.child; - null !== _child; + rootContainerInstance = current.child; + null !== rootContainerInstance; - ) { - var _childUpdateExpirationTime = _child.expirationTime, - _childChildExpirationTime = _child.childExpirationTime; - _childUpdateExpirationTime > newChildExpirationTime && - (newChildExpirationTime = _childUpdateExpirationTime); - _childChildExpirationTime > newChildExpirationTime && - (newChildExpirationTime = _childChildExpirationTime); - _child = _child.sibling; - } - workInProgress.childExpirationTime = newChildExpirationTime; + ) + (renderExpirationTime$jscomp$0 = + rootContainerInstance.expirationTime), + (internalInstanceHandle = + rootContainerInstance.childExpirationTime), + renderExpirationTime$jscomp$0 > newProps && + (newProps = renderExpirationTime$jscomp$0), + internalInstanceHandle > newProps && + (newProps = internalInstanceHandle), + (rootContainerInstance = rootContainerInstance.sibling); + current.childExpirationTime = newProps; } - if (null !== current) return current; + if (null !== current$$1) return current$$1; null !== unitOfWork && 0 === (unitOfWork.effectTag & 2048) && (null === unitOfWork.firstEffect && @@ -6312,14 +6448,15 @@ function completeUnitOfWork(unitOfWork) { : (unitOfWork.firstEffect = workInProgress), (unitOfWork.lastEffect = workInProgress))); } else { - current = unwindWork(workInProgress); - if (null !== current) return (current.effectTag &= 2047), current; + current$$1 = unwindWork(workInProgress, renderExpirationTime); + if (null !== current$$1) + return (current$$1.effectTag &= 2047), current$$1; null !== unitOfWork && ((unitOfWork.firstEffect = unitOfWork.lastEffect = null), (unitOfWork.effectTag |= 2048)); } - current = workInProgress.sibling; - if (null !== current) return current; + current$$1 = workInProgress.sibling; + if (null !== current$$1) return current$$1; workInProgress = unitOfWork; } while (null !== workInProgress); workInProgressRootExitStatus === RootIncomplete && @@ -6337,8 +6474,7 @@ function commitRoot(root) { return null; } function commitRootImpl(root$jscomp$0, renderPriorityLevel$jscomp$0) { - do flushPassiveEffects(); - while (null !== rootWithPendingPassiveEffects); + flushPassiveEffects(); if ((executionContext & (RenderContext | CommitContext)) !== NoContext) throw Error("Should not already be working."); var finishedWork = root$jscomp$0.finishedWork, @@ -6367,8 +6503,7 @@ function commitRootImpl(root$jscomp$0, renderPriorityLevel$jscomp$0) { expirationTime <= root$jscomp$0.lastExpiredTime && (root$jscomp$0.lastExpiredTime = 0); root$jscomp$0 === workInProgressRoot && - ((workInProgress = workInProgressRoot = null), - (renderExpirationTime$1 = 0)); + ((workInProgress = workInProgressRoot = null), (renderExpirationTime = 0)); 1 < finishedWork.effectTag ? null !== finishedWork.lastEffect ? ((finishedWork.lastEffect.nextEffect = finishedWork), @@ -6400,9 +6535,9 @@ function commitRootImpl(root$jscomp$0, renderPriorityLevel$jscomp$0) { ) { var effectTag = nextEffect.effectTag; if (effectTag & 128) { - var current = nextEffect.alternate; - if (null !== current) { - var currentRef = current.ref; + var current$$1 = nextEffect.alternate; + if (null !== current$$1) { + var currentRef = current$$1.ref; null !== currentRef && ("function" === typeof currentRef ? currentRef(null) @@ -6430,13 +6565,13 @@ function commitRootImpl(root$jscomp$0, renderPriorityLevel$jscomp$0) { commitWork(nextEffect.alternate, nextEffect); break; case 8: - var current$jscomp$0 = nextEffect; + var current$$1$jscomp$0 = nextEffect; unmountHostComponents( root, - current$jscomp$0, + current$$1$jscomp$0, renderPriorityLevel ); - detachFiber(current$jscomp$0); + detachFiber(current$$1$jscomp$0); } nextEffect = nextEffect.nextEffect; } @@ -6450,25 +6585,97 @@ function commitRootImpl(root$jscomp$0, renderPriorityLevel$jscomp$0) { nextEffect = remainingExpirationTimeBeforeCommit; do try { - for (effectTag = root$jscomp$0; null !== nextEffect; ) { + for (effectTag = expirationTime; null !== nextEffect; ) { var effectTag$jscomp$0 = nextEffect.effectTag; - effectTag$jscomp$0 & 36 && - commitLifeCycles(effectTag, nextEffect.alternate, nextEffect); + if (effectTag$jscomp$0 & 36) { + var current$$1$jscomp$1 = nextEffect.alternate; + current$$1 = nextEffect; + currentRef = effectTag; + switch (current$$1.tag) { + case 0: + case 11: + case 15: + commitHookEffectList(16, 32, current$$1); + break; + case 1: + var instance = current$$1.stateNode; + if (current$$1.effectTag & 4) + if (null === current$$1$jscomp$1) + instance.componentDidMount(); + else { + var prevProps = + current$$1.elementType === current$$1.type + ? current$$1$jscomp$1.memoizedProps + : resolveDefaultProps( + current$$1.type, + current$$1$jscomp$1.memoizedProps + ); + instance.componentDidUpdate( + prevProps, + current$$1$jscomp$1.memoizedState, + instance.__reactInternalSnapshotBeforeUpdate + ); + } + var updateQueue = current$$1.updateQueue; + null !== updateQueue && + commitUpdateQueue( + current$$1, + updateQueue, + instance, + currentRef + ); + break; + case 3: + var _updateQueue = current$$1.updateQueue; + if (null !== _updateQueue) { + root = null; + if (null !== current$$1.child) + switch (current$$1.child.tag) { + case 5: + root = current$$1.child.stateNode; + break; + case 1: + root = current$$1.child.stateNode; + } + commitUpdateQueue(current$$1, _updateQueue, root, currentRef); + } + break; + case 5: + break; + case 6: + break; + case 4: + break; + case 12: + break; + case 13: + break; + case 19: + case 17: + case 20: + case 21: + 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 (effectTag$jscomp$0 & 128) { - current = void 0; + current$$1 = void 0; var ref = nextEffect.ref; if (null !== ref) { - var instance = nextEffect.stateNode; + var instance$jscomp$0 = nextEffect.stateNode; switch (nextEffect.tag) { case 5: - current = instance; + current$$1 = instance$jscomp$0; break; default: - current = instance; + current$$1 = instance$jscomp$0; } "function" === typeof ref - ? ref(current) - : (ref.current = current); + ? ref(current$$1) + : (ref.current = current$$1); } } nextEffect = nextEffect.nextEffect; @@ -6557,9 +6764,8 @@ function flushPassiveEffectsImpl() { case 0: case 11: case 15: - case 22: - commitHookEffectListUnmount(5, finishedWork), - commitHookEffectListMount(5, finishedWork); + commitHookEffectList(128, 0, finishedWork), + commitHookEffectList(0, 64, finishedWork); } } catch (error) { if (null === root) throw Error("Should be working on an effect."); @@ -6610,17 +6816,20 @@ function captureCommitPhaseError(sourceFiber, error) { function pingSuspendedRoot(root, thenable, suspendedTime) { var pingCache = root.pingCache; null !== pingCache && pingCache.delete(thenable); - workInProgressRoot === root && renderExpirationTime$1 === suspendedTime + workInProgressRoot === root && renderExpirationTime === suspendedTime ? workInProgressRootExitStatus === RootSuspendedWithDelay || (workInProgressRootExitStatus === RootSuspended && 1073741823 === workInProgressRootLatestProcessedExpirationTime && now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) - ? prepareFreshStack(root, renderExpirationTime$1) + ? prepareFreshStack(root, renderExpirationTime) : (workInProgressRootHasPendingPing = !0) : isRootSuspendedAtTime(root, suspendedTime) && ((thenable = root.lastPingedTime), (0 !== thenable && thenable < suspendedTime) || - ((root.lastPingedTime = suspendedTime), ensureRootIsScheduled(root))); + ((root.lastPingedTime = suspendedTime), + root.finishedExpirationTime === suspendedTime && + ((root.finishedExpirationTime = 0), (root.finishedWork = null)), + ensureRootIsScheduled(root))); } function resolveRetryThenable(boundaryFiber, thenable) { var retryCache = boundaryFiber.stateNode; @@ -6632,12 +6841,12 @@ function resolveRetryThenable(boundaryFiber, thenable) { boundaryFiber = markUpdateTimeFromFiberToRoot(boundaryFiber, thenable); null !== boundaryFiber && ensureRootIsScheduled(boundaryFiber); } -var beginWork$1; -beginWork$1 = function(current, workInProgress, renderExpirationTime) { +var beginWork$$1; +beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { var updateExpirationTime = workInProgress.expirationTime; - if (null !== current) + if (null !== current$$1) if ( - current.memoizedProps !== workInProgress.pendingProps || + current$$1.memoizedProps !== workInProgress.pendingProps || didPerformWorkStackCursor.current ) didReceiveUpdate = !0; @@ -6662,10 +6871,7 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { ); break; case 10: - updateExpirationTime = workInProgress.memoizedProps.value; - var context = workInProgress.type._context; - push(valueCursor, context._currentValue); - context._currentValue = updateExpirationTime; + pushProvider(workInProgress, workInProgress.memoizedProps.value); break; case 13: if (null !== workInProgress.memoizedState) { @@ -6675,40 +6881,52 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { updateExpirationTime >= renderExpirationTime ) return updateSuspenseComponent( - current, + current$$1, workInProgress, renderExpirationTime ); - push(suspenseStackCursor, suspenseStackCursor.current & 1); + push( + suspenseStackCursor, + suspenseStackCursor.current & 1, + workInProgress + ); workInProgress = bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ); return null !== workInProgress ? workInProgress.sibling : null; } - push(suspenseStackCursor, suspenseStackCursor.current & 1); + push( + suspenseStackCursor, + suspenseStackCursor.current & 1, + workInProgress + ); break; case 19: updateExpirationTime = workInProgress.childExpirationTime >= renderExpirationTime; - if (0 !== (current.effectTag & 64)) { + if (0 !== (current$$1.effectTag & 64)) { if (updateExpirationTime) return updateSuspenseListComponent( - current, + current$$1, workInProgress, renderExpirationTime ); workInProgress.effectTag |= 64; } - context = workInProgress.memoizedState; - null !== context && - ((context.rendering = null), (context.tail = null)); - push(suspenseStackCursor, suspenseStackCursor.current); + var renderState = workInProgress.memoizedState; + null !== renderState && + ((renderState.rendering = null), (renderState.tail = null)); + push( + suspenseStackCursor, + suspenseStackCursor.current, + workInProgress + ); if (!updateExpirationTime) return null; } return bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -6720,40 +6938,41 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { switch (workInProgress.tag) { case 2: updateExpirationTime = workInProgress.type; - null !== current && - ((current.alternate = null), + null !== current$$1 && + ((current$$1.alternate = null), (workInProgress.alternate = null), (workInProgress.effectTag |= 2)); - current = workInProgress.pendingProps; - context = getMaskedContext(workInProgress, contextStackCursor.current); + current$$1 = workInProgress.pendingProps; + renderState = getMaskedContext( + workInProgress, + contextStackCursor.current + ); prepareToReadContext(workInProgress, renderExpirationTime); - context = renderWithHooks( + renderState = renderWithHooks( null, workInProgress, updateExpirationTime, - current, - context, + current$$1, + renderState, renderExpirationTime ); workInProgress.effectTag |= 1; if ( - "object" === typeof context && - null !== context && - "function" === typeof context.render && - void 0 === context.$$typeof + "object" === typeof renderState && + null !== renderState && + "function" === typeof renderState.render && + void 0 === renderState.$$typeof ) { workInProgress.tag = 1; - workInProgress.memoizedState = null; - workInProgress.updateQueue = null; + resetHooks(); if (isContextProvider(updateExpirationTime)) { var hasContext = !0; pushContextProvider(workInProgress); } else hasContext = !1; workInProgress.memoizedState = - null !== context.state && void 0 !== context.state - ? context.state + null !== renderState.state && void 0 !== renderState.state + ? renderState.state : null; - initializeUpdateQueue(workInProgress); var getDerivedStateFromProps = updateExpirationTime.getDerivedStateFromProps; "function" === typeof getDerivedStateFromProps && @@ -6761,15 +6980,15 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { workInProgress, updateExpirationTime, getDerivedStateFromProps, - current + current$$1 ); - context.updater = classComponentUpdater; - workInProgress.stateNode = context; - context._reactInternalFiber = workInProgress; + renderState.updater = classComponentUpdater; + workInProgress.stateNode = renderState; + renderState._reactInternalFiber = workInProgress; mountClassInstance( workInProgress, updateExpirationTime, - current, + current$$1, renderExpirationTime ); workInProgress = finishClassComponent( @@ -6785,129 +7004,127 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { reconcileChildren( null, workInProgress, - context, + renderState, renderExpirationTime ), (workInProgress = workInProgress.child); return workInProgress; case 16: - a: { - context = workInProgress.elementType; - null !== current && - ((current.alternate = null), - (workInProgress.alternate = null), - (workInProgress.effectTag |= 2)); - current = workInProgress.pendingProps; - initializeLazyComponentType(context); - if (1 !== context._status) throw context._result; - context = context._result; - workInProgress.type = context; - hasContext = workInProgress.tag = resolveLazyComponentTag(context); - current = resolveDefaultProps(context, current); - switch (hasContext) { - case 0: - workInProgress = updateFunctionComponent( - null, - workInProgress, - context, - current, - renderExpirationTime - ); - break a; - case 1: - workInProgress = updateClassComponent( - null, - workInProgress, - context, - current, - renderExpirationTime - ); - break a; - case 11: - workInProgress = updateForwardRef( - null, - workInProgress, - context, - current, - renderExpirationTime - ); - break a; - case 14: - workInProgress = updateMemoComponent( - null, - workInProgress, - context, - resolveDefaultProps(context.type, current), - updateExpirationTime, - renderExpirationTime - ); - break a; - } - throw Error( - "Element type is invalid. Received a promise that resolves to: " + - context + - ". Lazy element type must resolve to a class or function." - ); + renderState = workInProgress.elementType; + null !== current$$1 && + ((current$$1.alternate = null), + (workInProgress.alternate = null), + (workInProgress.effectTag |= 2)); + current$$1 = workInProgress.pendingProps; + initializeLazyComponentType(renderState); + if (1 !== renderState._status) throw renderState._result; + renderState = renderState._result; + workInProgress.type = renderState; + hasContext = workInProgress.tag = resolveLazyComponentTag(renderState); + current$$1 = resolveDefaultProps(renderState, current$$1); + switch (hasContext) { + case 0: + workInProgress = updateFunctionComponent( + null, + workInProgress, + renderState, + current$$1, + renderExpirationTime + ); + break; + case 1: + workInProgress = updateClassComponent( + null, + workInProgress, + renderState, + current$$1, + renderExpirationTime + ); + break; + case 11: + workInProgress = updateForwardRef( + null, + workInProgress, + renderState, + current$$1, + renderExpirationTime + ); + break; + case 14: + workInProgress = updateMemoComponent( + null, + workInProgress, + renderState, + resolveDefaultProps(renderState.type, current$$1), + updateExpirationTime, + renderExpirationTime + ); + break; + default: + throw Error( + "Element type is invalid. Received a promise that resolves to: " + + renderState + + ". Lazy element type must resolve to a class or function." + ); } return workInProgress; case 0: return ( (updateExpirationTime = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (renderState = workInProgress.pendingProps), + (renderState = workInProgress.elementType === updateExpirationTime - ? context - : resolveDefaultProps(updateExpirationTime, context)), + ? renderState + : resolveDefaultProps(updateExpirationTime, renderState)), updateFunctionComponent( - current, + current$$1, workInProgress, updateExpirationTime, - context, + renderState, renderExpirationTime ) ); case 1: return ( (updateExpirationTime = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (renderState = workInProgress.pendingProps), + (renderState = workInProgress.elementType === updateExpirationTime - ? context - : resolveDefaultProps(updateExpirationTime, context)), + ? renderState + : resolveDefaultProps(updateExpirationTime, renderState)), updateClassComponent( - current, + current$$1, workInProgress, updateExpirationTime, - context, + renderState, renderExpirationTime ) ); case 3: pushHostRootContext(workInProgress); updateExpirationTime = workInProgress.updateQueue; - if (null === current || null === updateExpirationTime) + if (null === updateExpirationTime) 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." ); - updateExpirationTime = workInProgress.pendingProps; - context = workInProgress.memoizedState; - context = null !== context ? context.element : null; - cloneUpdateQueue(current, workInProgress); + renderState = workInProgress.memoizedState; + renderState = null !== renderState ? renderState.element : null; processUpdateQueue( workInProgress, updateExpirationTime, + workInProgress.pendingProps, null, renderExpirationTime ); updateExpirationTime = workInProgress.memoizedState.element; - updateExpirationTime === context + updateExpirationTime === renderState ? (workInProgress = bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime )) : (reconcileChildren( - current, + current$$1, workInProgress, updateExpirationTime, renderExpirationTime @@ -6917,10 +7134,11 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { case 5: return ( pushHostContext(workInProgress), + null === current$$1 && tryToClaimNextHydratableInstance(workInProgress), (updateExpirationTime = workInProgress.pendingProps.children), - markRef(current, workInProgress), + markRef(current$$1, workInProgress), reconcileChildren( - current, + current$$1, workInProgress, updateExpirationTime, renderExpirationTime @@ -6929,10 +7147,13 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { workInProgress ); case 6: - return null; + return ( + null === current$$1 && tryToClaimNextHydratableInstance(workInProgress), + null + ); case 13: return updateSuspenseComponent( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -6943,7 +7164,7 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { workInProgress.stateNode.containerInfo ), (updateExpirationTime = workInProgress.pendingProps), - null === current + null === current$$1 ? (workInProgress.child = reconcileChildFibers( workInProgress, null, @@ -6951,7 +7172,7 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { renderExpirationTime )) : reconcileChildren( - current, + current$$1, workInProgress, updateExpirationTime, renderExpirationTime @@ -6961,23 +7182,23 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { case 11: return ( (updateExpirationTime = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (renderState = workInProgress.pendingProps), + (renderState = workInProgress.elementType === updateExpirationTime - ? context - : resolveDefaultProps(updateExpirationTime, context)), + ? renderState + : resolveDefaultProps(updateExpirationTime, renderState)), updateForwardRef( - current, + current$$1, workInProgress, updateExpirationTime, - context, + renderState, renderExpirationTime ) ); case 7: return ( reconcileChildren( - current, + current$$1, workInProgress, workInProgress.pendingProps, renderExpirationTime @@ -6987,7 +7208,7 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { case 8: return ( reconcileChildren( - current, + current$$1, workInProgress, workInProgress.pendingProps.children, renderExpirationTime @@ -6997,7 +7218,7 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { case 12: return ( reconcileChildren( - current, + current$$1, workInProgress, workInProgress.pendingProps.children, renderExpirationTime @@ -7007,32 +7228,27 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { case 10: a: { updateExpirationTime = workInProgress.type._context; - context = workInProgress.pendingProps; + renderState = 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 updateExpirationTime._calculateChangedBits - ? updateExpirationTime._calculateChangedBits( - context$jscomp$0, - hasContext - ) - : 1073741823) | 0), - 0 === hasContext) - ) { + hasContext = renderState.value; + pushProvider(workInProgress, hasContext); + if (null !== getDerivedStateFromProps) { + var oldValue = getDerivedStateFromProps.value; + hasContext = is$1(oldValue, hasContext) + ? 0 + : ("function" === typeof updateExpirationTime._calculateChangedBits + ? updateExpirationTime._calculateChangedBits( + oldValue, + hasContext + ) + : 1073741823) | 0; + if (0 === hasContext) { if ( - getDerivedStateFromProps.children === context.children && + getDerivedStateFromProps.children === renderState.children && !didPerformWorkStackCursor.current ) { workInProgress = bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -7040,15 +7256,14 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { } } 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; @@ -7058,18 +7273,18 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { dependency.context === updateExpirationTime && 0 !== (dependency.observedBits & hasContext) ) { - 1 === context$jscomp$0.tag && + 1 === oldValue.tag && ((dependency = createUpdate(renderExpirationTime, null)), (dependency.tag = 2), - enqueueUpdate(context$jscomp$0, dependency)); - context$jscomp$0.expirationTime < renderExpirationTime && - (context$jscomp$0.expirationTime = renderExpirationTime); - dependency = context$jscomp$0.alternate; + enqueueUpdate(oldValue, dependency)); + oldValue.expirationTime < renderExpirationTime && + (oldValue.expirationTime = renderExpirationTime); + dependency = oldValue.alternate; null !== dependency && dependency.expirationTime < renderExpirationTime && (dependency.expirationTime = renderExpirationTime); scheduleWorkOnParentPath( - context$jscomp$0.return, + oldValue.return, renderExpirationTime ); list.expirationTime < renderExpirationTime && @@ -7080,16 +7295,16 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { } } 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; ) { @@ -7097,20 +7312,21 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { 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, + current$$1, workInProgress, - context.children, + renderState.children, renderExpirationTime ); workInProgress = workInProgress.child; @@ -7118,15 +7334,18 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { return workInProgress; case 9: return ( - (context = workInProgress.type), + (renderState = workInProgress.type), (hasContext = workInProgress.pendingProps), (updateExpirationTime = hasContext.children), prepareToReadContext(workInProgress, renderExpirationTime), - (context = readContext(context, hasContext.unstable_observedBits)), - (updateExpirationTime = updateExpirationTime(context)), + (renderState = readContext( + renderState, + hasContext.unstable_observedBits + )), + (updateExpirationTime = updateExpirationTime(renderState)), (workInProgress.effectTag |= 1), reconcileChildren( - current, + current$$1, workInProgress, updateExpirationTime, renderExpirationTime @@ -7135,16 +7354,16 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { ); case 14: return ( - (context = workInProgress.type), + (renderState = workInProgress.type), (hasContext = resolveDefaultProps( - context, + renderState, workInProgress.pendingProps )), - (hasContext = resolveDefaultProps(context.type, hasContext)), + (hasContext = resolveDefaultProps(renderState.type, hasContext)), updateMemoComponent( - current, + current$$1, workInProgress, - context, + renderState, hasContext, updateExpirationTime, renderExpirationTime @@ -7152,7 +7371,7 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { ); case 15: return updateSimpleMemoComponent( - current, + current$$1, workInProgress, workInProgress.type, workInProgress.pendingProps, @@ -7162,25 +7381,30 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { case 17: return ( (updateExpirationTime = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (renderState = workInProgress.pendingProps), + (renderState = workInProgress.elementType === updateExpirationTime - ? context - : resolveDefaultProps(updateExpirationTime, context)), - null !== current && - ((current.alternate = null), + ? renderState + : resolveDefaultProps(updateExpirationTime, renderState)), + null !== current$$1 && + ((current$$1.alternate = null), (workInProgress.alternate = null), (workInProgress.effectTag |= 2)), (workInProgress.tag = 1), isContextProvider(updateExpirationTime) - ? ((current = !0), pushContextProvider(workInProgress)) - : (current = !1), + ? ((current$$1 = !0), pushContextProvider(workInProgress)) + : (current$$1 = !1), prepareToReadContext(workInProgress, renderExpirationTime), - constructClassInstance(workInProgress, updateExpirationTime, context), + constructClassInstance( + workInProgress, + updateExpirationTime, + renderState, + renderExpirationTime + ), mountClassInstance( workInProgress, updateExpirationTime, - context, + renderState, renderExpirationTime ), finishClassComponent( @@ -7188,13 +7412,13 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { workInProgress, updateExpirationTime, !0, - current, + current$$1, renderExpirationTime ) ); case 19: return updateSuspenseListComponent( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -7245,6 +7469,9 @@ function FiberNode(tag, pendingProps, key, mode) { this.childExpirationTime = this.expirationTime = 0; this.alternate = null; } +function createFiber(tag, pendingProps, key, mode) { + return new FiberNode(tag, pendingProps, key, mode); +} function shouldConstruct(Component) { Component = Component.prototype; return !(!Component || !Component.isReactComponent); @@ -7262,7 +7489,7 @@ function resolveLazyComponentTag(Component) { function createWorkInProgress(current, pendingProps) { var workInProgress = current.alternate; null === workInProgress - ? ((workInProgress = new FiberNode( + ? ((workInProgress = createFiber( current.tag, pendingProps, current.key, @@ -7278,10 +7505,6 @@ function createWorkInProgress(current, pendingProps) { (workInProgress.nextEffect = null), (workInProgress.firstEffect = null), (workInProgress.lastEffect = null)); - if (null == current) - throw Error("current is " + current + " but it can't be"); - if (null == workInProgress) - throw Error("workInProgress is " + workInProgress + " but it can't be"); workInProgress.childExpirationTime = current.childExpirationTime; workInProgress.expirationTime = current.expirationTime; workInProgress.child = current.child; @@ -7333,7 +7556,7 @@ function createFiberFromTypeAndProps( break; case REACT_PROFILER_TYPE: return ( - (type = new FiberNode(12, pendingProps, key, mode | 8)), + (type = createFiber(12, pendingProps, key, mode | 8)), (type.elementType = REACT_PROFILER_TYPE), (type.type = REACT_PROFILER_TYPE), (type.expirationTime = expirationTime), @@ -7341,7 +7564,7 @@ function createFiberFromTypeAndProps( ); case REACT_SUSPENSE_TYPE: return ( - (type = new FiberNode(13, pendingProps, key, mode)), + (type = createFiber(13, pendingProps, key, mode)), (type.type = REACT_SUSPENSE_TYPE), (type.elementType = REACT_SUSPENSE_TYPE), (type.expirationTime = expirationTime), @@ -7349,7 +7572,7 @@ function createFiberFromTypeAndProps( ); case REACT_SUSPENSE_LIST_TYPE: return ( - (type = new FiberNode(19, pendingProps, key, mode)), + (type = createFiber(19, pendingProps, key, mode)), (type.elementType = REACT_SUSPENSE_LIST_TYPE), (type.expirationTime = expirationTime), type @@ -7373,9 +7596,6 @@ function createFiberFromTypeAndProps( fiberTag = 16; owner = null; break a; - case REACT_BLOCK_TYPE: - fiberTag = 22; - break a; } throw Error( "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + @@ -7383,24 +7603,24 @@ function createFiberFromTypeAndProps( "." ); } - key = new FiberNode(fiberTag, pendingProps, key, mode); + key = createFiber(fiberTag, pendingProps, key, mode); key.elementType = type; key.type = owner; key.expirationTime = expirationTime; return key; } function createFiberFromFragment(elements, mode, expirationTime, key) { - elements = new FiberNode(7, elements, key, mode); + elements = createFiber(7, elements, key, mode); elements.expirationTime = expirationTime; return elements; } function createFiberFromText(content, mode, expirationTime) { - content = new FiberNode(6, content, null, mode); + content = createFiber(6, content, null, mode); content.expirationTime = expirationTime; return content; } function createFiberFromPortal(portal, mode, expirationTime) { - mode = new FiberNode( + mode = createFiber( 4, null !== portal.children ? portal.children : [], portal.key, @@ -7459,6 +7679,11 @@ function markRootUpdatedAtTime(root, expirationTime) { expirationTime > root.nextKnownPendingLevel && (root.nextKnownPendingLevel = expirationTime)); } +function markRootExpiredAtTime(root, expirationTime) { + var lastExpiredTime = root.lastExpiredTime; + if (0 === lastExpiredTime || lastExpiredTime > expirationTime) + root.lastExpiredTime = expirationTime; +} function findHostInstance(component) { var fiber = component._reactInternalFiber; if (void 0 === fiber) { @@ -7473,10 +7698,14 @@ function findHostInstance(component) { return null === component ? null : component.stateNode; } function updateContainer(element, container, parentComponent, callback) { - var current = container.current, + var current$$1 = container.current, currentTime = requestCurrentTimeForUpdate(), suspenseConfig = ReactCurrentBatchConfig.suspense; - currentTime = computeExpirationForFiber(currentTime, current, suspenseConfig); + currentTime = computeExpirationForFiber( + currentTime, + current$$1, + suspenseConfig + ); a: if (parentComponent) { parentComponent = parentComponent._reactInternalFiber; b: { @@ -7527,8 +7756,8 @@ function updateContainer(element, container, parentComponent, callback) { container.payload = { element: element }; callback = void 0 === callback ? null : callback; null !== callback && (container.callback = callback); - enqueueUpdate(current, container); - scheduleWork(current, currentTime); + enqueueUpdate(current$$1, container); + scheduleUpdateOnFiber(current$$1, currentTime); return currentTime; } function createPortal(children, containerInfo, implementation) { @@ -7542,6 +7771,11 @@ function createPortal(children, containerInfo, implementation) { implementation: implementation }; } +function _inheritsLoose(subClass, superClass) { + subClass.prototype = Object.create(superClass.prototype); + subClass.prototype.constructor = subClass; + subClass.__proto__ = superClass; +} function findNodeHandle(componentOrHandle) { if (null == componentOrHandle) return null; if ("number" === typeof componentOrHandle) return componentOrHandle; @@ -7552,15 +7786,8 @@ function findNodeHandle(componentOrHandle) { return null == componentOrHandle ? componentOrHandle : componentOrHandle.canonical - ? componentOrHandle.canonical._nativeTag - : componentOrHandle._nativeTag; -} -function unmountComponentAtNode(containerTag) { - var root = roots.get(containerTag); - root && - updateContainer(null, root, null, function() { - roots.delete(containerTag); - }); + ? componentOrHandle.canonical._nativeTag + : componentOrHandle._nativeTag; } batchedUpdatesImpl = function(fn, a) { var prevExecutionContext = executionContext; @@ -7572,117 +7799,299 @@ batchedUpdatesImpl = function(fn, a) { executionContext === NoContext && flushSyncCallbackQueue(); } }; -var roots = new Map(); -(function(devToolsConfig) { - var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance; - return injectInternals({ - bundleType: devToolsConfig.bundleType, - version: devToolsConfig.version, - rendererPackageName: devToolsConfig.rendererPackageName, - rendererConfig: devToolsConfig.rendererConfig, - overrideHookState: null, - overrideProps: null, - setSuspenseHandler: null, - scheduleUpdate: null, - currentDispatcherRef: ReactSharedInternals.ReactCurrentDispatcher, - findHostInstanceByFiber: function(fiber) { - fiber = findCurrentHostFiber(fiber); - return null === fiber ? null : fiber.stateNode; +flushDiscreteUpdatesImpl = function() { + (executionContext & (1 | RenderContext | CommitContext)) === NoContext && + (flushPendingDiscreteUpdates(), flushPassiveEffects()); +}; +var roots = new Map(), + ReactNativeRenderer = { + NativeComponent: (function(findNodeHandle, findHostInstance) { + return (function(_React$Component) { + function ReactNativeComponent() { + return _React$Component.apply(this, arguments) || this; + } + _inheritsLoose(ReactNativeComponent, _React$Component); + var _proto = ReactNativeComponent.prototype; + _proto.blur = function() { + ReactNativePrivateInterface.TextInputState.blurTextInput( + findNodeHandle(this) + ); + }; + _proto.focus = function() { + ReactNativePrivateInterface.TextInputState.focusTextInput( + findNodeHandle(this) + ); + }; + _proto.measure = function(callback) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + null != maybeInstance && + (maybeInstance.canonical + ? nativeFabricUIManager.measure( + maybeInstance.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ) + : ReactNativePrivateInterface.UIManager.measure( + findNodeHandle(this), + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + )); + }; + _proto.measureInWindow = function(callback) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + null != maybeInstance && + (maybeInstance.canonical + ? nativeFabricUIManager.measureInWindow( + maybeInstance.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ) + : ReactNativePrivateInterface.UIManager.measureInWindow( + findNodeHandle(this), + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + )); + }; + _proto.measureLayout = function( + relativeToNativeNode, + onSuccess, + onFail + ) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + if (null != maybeInstance && !maybeInstance.canonical) { + if ("number" === typeof relativeToNativeNode) + var relativeNode = relativeToNativeNode; + else + relativeToNativeNode._nativeTag && + (relativeNode = relativeToNativeNode._nativeTag); + null != relativeNode && + ReactNativePrivateInterface.UIManager.measureLayout( + findNodeHandle(this), + relativeNode, + mountSafeCallback_NOT_REALLY_SAFE(this, onFail), + mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) + ); + } + }; + _proto.setNativeProps = function(nativeProps) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + if (null != maybeInstance && !maybeInstance.canonical) { + var nativeTag = + maybeInstance._nativeTag || maybeInstance.canonical._nativeTag; + maybeInstance = + maybeInstance.viewConfig || maybeInstance.canonical.viewConfig; + nativeProps = diffProperties( + null, + emptyObject, + nativeProps, + maybeInstance.validAttributes + ); + null != nativeProps && + ReactNativePrivateInterface.UIManager.updateView( + nativeTag, + maybeInstance.uiViewClassName, + nativeProps + ); + } + }; + return ReactNativeComponent; + })(React.Component); + })(findNodeHandle, findHostInstance), + findHostInstance_DEPRECATED: function(componentOrHandle) { + if (null == componentOrHandle) return null; + if (componentOrHandle._nativeTag) return componentOrHandle; + if (componentOrHandle.canonical && componentOrHandle.canonical._nativeTag) + return componentOrHandle.canonical; + componentOrHandle = findHostInstance(componentOrHandle); + return null == componentOrHandle + ? componentOrHandle + : componentOrHandle.canonical + ? componentOrHandle.canonical + : componentOrHandle; + }, + findNodeHandle: findNodeHandle, + dispatchCommand: function(handle, command, args) { + null != handle._nativeTag && + ReactNativePrivateInterface.UIManager.dispatchViewManagerCommand( + handle._nativeTag, + command, + args + ); + }, + 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; + roots.set(containerTag, root); + } + updateContainer(element, root, null, callback); + a: if (((element = root.current), element.child)) + switch (element.child.tag) { + case 5: + element = element.child.stateNode; + break a; + default: + element = element.child.stateNode; + } + else element = null; + return element; }, - findFiberByHostInstance: function(instance) { - return findFiberByHostInstance ? findFiberByHostInstance(instance) : null; + unmountComponentAtNode: function(containerTag) { + var root = roots.get(containerTag); + root && + updateContainer(null, root, null, function() { + roots.delete(containerTag); + }); }, - findHostInstancesForRefresh: null, - scheduleRefresh: null, - scheduleRoot: null, - setRefreshHandler: null, - getCurrentFiber: null - }); + unmountComponentAtNodeAndRemoveContainer: function(containerTag) { + ReactNativeRenderer.unmountComponentAtNode(containerTag); + ReactNativePrivateInterface.UIManager.removeRootView(containerTag); + }, + createPortal: function(children, containerTag) { + return createPortal( + children, + containerTag, + null, + 2 < arguments.length && void 0 !== arguments[2] ? arguments[2] : null + ); + }, + unstable_batchedUpdates: batchedUpdates, + __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: { + NativeMethodsMixin: (function(findNodeHandle, findHostInstance) { + return { + measure: function(callback) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + null != maybeInstance && + (maybeInstance.canonical + ? nativeFabricUIManager.measure( + maybeInstance.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ) + : ReactNativePrivateInterface.UIManager.measure( + findNodeHandle(this), + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + )); + }, + measureInWindow: function(callback) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + null != maybeInstance && + (maybeInstance.canonical + ? nativeFabricUIManager.measureInWindow( + maybeInstance.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ) + : ReactNativePrivateInterface.UIManager.measureInWindow( + findNodeHandle(this), + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + )); + }, + measureLayout: function(relativeToNativeNode, onSuccess, onFail) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + if (null != maybeInstance && !maybeInstance.canonical) { + if ("number" === typeof relativeToNativeNode) + var relativeNode = relativeToNativeNode; + else + relativeToNativeNode._nativeTag && + (relativeNode = relativeToNativeNode._nativeTag); + null != relativeNode && + ReactNativePrivateInterface.UIManager.measureLayout( + findNodeHandle(this), + relativeNode, + mountSafeCallback_NOT_REALLY_SAFE(this, onFail), + mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) + ); + } + }, + setNativeProps: function(nativeProps) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + if (null != maybeInstance && !maybeInstance.canonical) { + var nativeTag = + maybeInstance._nativeTag || maybeInstance.canonical._nativeTag; + maybeInstance = + maybeInstance.viewConfig || maybeInstance.canonical.viewConfig; + nativeProps = diffProperties( + null, + emptyObject, + nativeProps, + maybeInstance.validAttributes + ); + null != nativeProps && + ReactNativePrivateInterface.UIManager.updateView( + nativeTag, + maybeInstance.uiViewClassName, + nativeProps + ); + } + }, + focus: function() { + ReactNativePrivateInterface.TextInputState.focusTextInput( + findNodeHandle(this) + ); + }, + blur: function() { + ReactNativePrivateInterface.TextInputState.blurTextInput( + findNodeHandle(this) + ); + } + }; + })(findNodeHandle, findHostInstance), + computeComponentStackForErrorReporting: function(reactTag) { + return (reactTag = getInstanceFromTag(reactTag)) + ? getStackByFiberInDevAndProd(reactTag) + : ""; + } + } + }; +(function(devToolsConfig) { + var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance; + return injectInternals( + Object.assign({}, devToolsConfig, { + overrideHookState: null, + overrideProps: null, + setSuspenseHandler: null, + scheduleUpdate: null, + currentDispatcherRef: ReactSharedInternals.ReactCurrentDispatcher, + findHostInstanceByFiber: function(fiber) { + fiber = findCurrentHostFiber(fiber); + return null === fiber ? null : fiber.stateNode; + }, + findFiberByHostInstance: function(instance) { + return findFiberByHostInstance + ? findFiberByHostInstance(instance) + : null; + }, + findHostInstancesForRefresh: null, + scheduleRefresh: null, + scheduleRoot: null, + setRefreshHandler: null, + getCurrentFiber: null + }) + ); })({ findFiberByHostInstance: getInstanceFromTag, + getInspectorDataForViewTag: function() { + throw Error("getInspectorDataForViewTag() is not available in production"); + }, bundleType: 0, - version: "16.13.0", - rendererPackageName: "react-native-renderer", - rendererConfig: { - getInspectorDataForViewTag: function() { - throw Error( - "getInspectorDataForViewTag() is not available in production" - ); - }, - getInspectorDataForViewAtPoint: function() { - throw Error( - "getInspectorDataForViewAtPoint() is not available in production." - ); - }.bind(null, findNodeHandle) - } + version: "16.11.0", + rendererPackageName: "react-native-renderer" }); -exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = { - computeComponentStackForErrorReporting: function(reactTag) { - return (reactTag = getInstanceFromTag(reactTag)) - ? getStackByFiberInDevAndProd(reactTag) - : ""; - } -}; -exports.createPortal = function(children, containerTag) { - return createPortal( - children, - containerTag, - null, - 2 < arguments.length && void 0 !== arguments[2] ? arguments[2] : null - ); -}; -exports.dispatchCommand = function(handle, command, args) { - null != handle._nativeTag && - (handle._internalInstanceHandle - ? nativeFabricUIManager.dispatchCommand( - handle._internalInstanceHandle.stateNode.node, - command, - args - ) - : ReactNativePrivateInterface.UIManager.dispatchViewManagerCommand( - handle._nativeTag, - command, - args - )); -}; -exports.findHostInstance_DEPRECATED = function(componentOrHandle) { - if (null == componentOrHandle) return null; - if (componentOrHandle._nativeTag) return componentOrHandle; - if (componentOrHandle.canonical && componentOrHandle.canonical._nativeTag) - return componentOrHandle.canonical; - componentOrHandle = findHostInstance(componentOrHandle); - return null == componentOrHandle - ? componentOrHandle - : componentOrHandle.canonical - ? componentOrHandle.canonical - : componentOrHandle; -}; -exports.findNodeHandle = findNodeHandle; -exports.render = function(element, containerTag, callback) { - var root = roots.get(containerTag); - if (!root) { - root = new FiberRootNode(containerTag, 0, !1); - var uninitializedFiber = new FiberNode(3, null, null, 0); - root.current = uninitializedFiber; - uninitializedFiber.stateNode = root; - initializeUpdateQueue(uninitializedFiber); - roots.set(containerTag, root); - } - updateContainer(element, root, null, callback); - a: if (((element = root.current), element.child)) - switch (element.child.tag) { - case 5: - element = element.child.stateNode; - break a; - default: - element = element.child.stateNode; - } - else element = null; - return element; -}; -exports.unmountComponentAtNode = unmountComponentAtNode; -exports.unmountComponentAtNodeAndRemoveContainer = function(containerTag) { - unmountComponentAtNode(containerTag); - ReactNativePrivateInterface.UIManager.removeRootView(containerTag); -}; -exports.unstable_batchedUpdates = batchedUpdates; +var ReactNativeRenderer$2 = { default: ReactNativeRenderer }, + ReactNativeRenderer$3 = + (ReactNativeRenderer$2 && ReactNativeRenderer) || ReactNativeRenderer$2; +module.exports = ReactNativeRenderer$3.default || ReactNativeRenderer$3; diff --git a/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js b/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js index 31b089c41bfee8..4cc776abd951fd 100644 --- a/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js +++ b/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js @@ -5,7 +5,6 @@ * LICENSE file in the root directory of this source tree. * * @noflow - * @nolint * @providesModule ReactNativeRenderer-prod * @preventMunge * @generated @@ -16,16 +15,85 @@ require("react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore"); var ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/ReactNativePrivateInterface"), React = require("react"), Scheduler = require("scheduler"); -function getParent(inst) { - do inst = inst.return; - while (inst && 5 !== inst.tag); - return inst ? inst : null; +var eventPluginOrder = null, + namesToPlugins = {}; +function recomputePluginOrdering() { + if (eventPluginOrder) + for (var pluginName in namesToPlugins) { + var pluginModule = namesToPlugins[pluginName], + pluginIndex = eventPluginOrder.indexOf(pluginName); + if (!(-1 < pluginIndex)) + throw Error( + "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + + pluginName + + "`." + ); + if (!plugins[pluginIndex]) { + if (!pluginModule.extractEvents) + throw Error( + "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + + pluginName + + "` does not." + ); + plugins[pluginIndex] = pluginModule; + pluginIndex = pluginModule.eventTypes; + for (var eventName in pluginIndex) { + var JSCompiler_inline_result = void 0; + var dispatchConfig = pluginIndex[eventName], + pluginModule$jscomp$0 = pluginModule, + eventName$jscomp$0 = eventName; + if (eventNameDispatchConfigs.hasOwnProperty(eventName$jscomp$0)) + throw Error( + "EventPluginHub: More than one plugin attempted to publish the same event name, `" + + eventName$jscomp$0 + + "`." + ); + eventNameDispatchConfigs[eventName$jscomp$0] = dispatchConfig; + var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; + if (phasedRegistrationNames) { + for (JSCompiler_inline_result in phasedRegistrationNames) + phasedRegistrationNames.hasOwnProperty( + JSCompiler_inline_result + ) && + publishRegistrationName( + phasedRegistrationNames[JSCompiler_inline_result], + pluginModule$jscomp$0, + eventName$jscomp$0 + ); + JSCompiler_inline_result = !0; + } else + dispatchConfig.registrationName + ? (publishRegistrationName( + dispatchConfig.registrationName, + pluginModule$jscomp$0, + eventName$jscomp$0 + ), + (JSCompiler_inline_result = !0)) + : (JSCompiler_inline_result = !1); + if (!JSCompiler_inline_result) + throw Error( + "EventPluginRegistry: Failed to publish event `" + + eventName + + "` for plugin `" + + pluginName + + "`." + ); + } + } + } } -function traverseTwoPhase(inst, fn, arg) { - for (var path = []; inst; ) path.push(inst), (inst = getParent(inst)); - for (inst = path.length; 0 < inst--; ) fn(path[inst], "captured", arg); - for (inst = 0; inst < path.length; inst++) fn(path[inst], "bubbled", arg); +function publishRegistrationName(registrationName, pluginModule) { + if (registrationNameModules[registrationName]) + throw Error( + "EventPluginHub: More than one plugin attempted to publish the same registration name, `" + + registrationName + + "`." + ); + registrationNameModules[registrationName] = pluginModule; } +var plugins = [], + eventNameDispatchConfigs = {}, + registrationNameModules = {}; function invokeGuardedCallbackImpl(name, func, context, a, b, c, d, e, f) { var funcArgs = Array.prototype.slice.call(arguments, 3); try { @@ -96,6 +164,74 @@ function executeDirectDispatch(event) { event._dispatchInstances = null; return dispatchListener; } +function accumulateInto(current, next) { + if (null == next) + throw Error( + "accumulateInto(...): Accumulated items must not be null or undefined." + ); + if (null == current) return next; + if (Array.isArray(current)) { + if (Array.isArray(next)) return current.push.apply(current, next), current; + current.push(next); + return current; + } + return Array.isArray(next) ? [current].concat(next) : [current, next]; +} +function forEachAccumulated(arr, cb, scope) { + Array.isArray(arr) ? arr.forEach(cb, scope) : arr && cb.call(scope, arr); +} +var eventQueue = null; +function executeDispatchesAndReleaseTopLevel(e) { + if (e) { + var dispatchListeners = e._dispatchListeners, + dispatchInstances = e._dispatchInstances; + if (Array.isArray(dispatchListeners)) + for ( + var i = 0; + i < dispatchListeners.length && !e.isPropagationStopped(); + i++ + ) + executeDispatch(e, dispatchListeners[i], dispatchInstances[i]); + else + dispatchListeners && + executeDispatch(e, dispatchListeners, dispatchInstances); + e._dispatchListeners = null; + e._dispatchInstances = null; + e.isPersistent() || e.constructor.release(e); + } +} +var injection = { + injectEventPluginOrder: function(injectedEventPluginOrder) { + if (eventPluginOrder) + throw Error( + "EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React." + ); + eventPluginOrder = Array.prototype.slice.call(injectedEventPluginOrder); + recomputePluginOrdering(); + }, + injectEventPluginsByName: function(injectedNamesToPlugins) { + var isOrderingDirty = !1, + pluginName; + for (pluginName in injectedNamesToPlugins) + if (injectedNamesToPlugins.hasOwnProperty(pluginName)) { + var pluginModule = injectedNamesToPlugins[pluginName]; + if ( + !namesToPlugins.hasOwnProperty(pluginName) || + namesToPlugins[pluginName] !== pluginModule + ) { + if (namesToPlugins[pluginName]) + throw Error( + "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + + pluginName + + "`." + ); + namesToPlugins[pluginName] = pluginModule; + isOrderingDirty = !0; + } + } + isOrderingDirty && recomputePluginOrdering(); + } +}; function getListener(inst, registrationName) { var listener = inst.stateNode; if (!listener) return null; @@ -113,7 +249,6 @@ function getListener(inst, registrationName) { case "onMouseMoveCapture": case "onMouseUp": case "onMouseUpCapture": - case "onMouseEnter": (props = !props.disabled) || ((inst = inst.type), (props = !( @@ -138,21 +273,15 @@ function getListener(inst, registrationName) { ); return listener; } -function accumulateInto(current, next) { - if (null == next) - throw Error( - "accumulateInto(...): Accumulated items must not be null or undefined." - ); - if (null == current) return next; - if (Array.isArray(current)) { - if (Array.isArray(next)) return current.push.apply(current, next), current; - current.push(next); - return current; - } - return Array.isArray(next) ? [current].concat(next) : [current, next]; +function getParent(inst) { + do inst = inst.return; + while (inst && 5 !== inst.tag); + return inst ? inst : null; } -function forEachAccumulated(arr, cb, scope) { - Array.isArray(arr) ? arr.forEach(cb, scope) : arr && cb.call(scope, arr); +function traverseTwoPhase(inst, fn, arg) { + for (var path = []; inst; ) path.push(inst), (inst = getParent(inst)); + for (inst = path.length; 0 < inst--; ) fn(path[inst], "captured", arg); + for (inst = 0; inst < path.length; inst++) fn(path[inst], "bubbled", arg); } function accumulateDirectionalDispatches(inst, phase, event) { if ( @@ -220,8 +349,8 @@ function SyntheticEvent( ((targetInst = dispatchConfig[propName]) ? (this[propName] = targetInst(nativeEvent)) : "target" === propName - ? (this.target = nativeEventTarget) - : (this[propName] = nativeEvent[propName])); + ? (this.target = nativeEventTarget) + : (this[propName] = nativeEvent[propName])); this.isDefaultPrevented = (null != nativeEvent.defaultPrevented ? nativeEvent.defaultPrevented : !1 === nativeEvent.returnValue) @@ -374,27 +503,53 @@ function recordTouchStart(touch) { } function recordTouchMove(touch) { var touchRecord = touchBank[getTouchIdentifier(touch)]; - touchRecord && - ((touchRecord.touchActive = !0), - (touchRecord.previousPageX = touchRecord.currentPageX), - (touchRecord.previousPageY = touchRecord.currentPageY), - (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), - (touchRecord.currentPageX = touch.pageX), - (touchRecord.currentPageY = touch.pageY), - (touchRecord.currentTimeStamp = timestampForTouch(touch)), - (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))); + touchRecord + ? ((touchRecord.touchActive = !0), + (touchRecord.previousPageX = touchRecord.currentPageX), + (touchRecord.previousPageY = touchRecord.currentPageY), + (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), + (touchRecord.currentPageX = touch.pageX), + (touchRecord.currentPageY = touch.pageY), + (touchRecord.currentTimeStamp = timestampForTouch(touch)), + (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))) + : console.warn( + "Cannot record touch move without a touch start.\nTouch Move: %s\n", + "Touch Bank: %s", + printTouch(touch), + printTouchBank() + ); } function recordTouchEnd(touch) { var touchRecord = touchBank[getTouchIdentifier(touch)]; - touchRecord && - ((touchRecord.touchActive = !1), - (touchRecord.previousPageX = touchRecord.currentPageX), - (touchRecord.previousPageY = touchRecord.currentPageY), - (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), - (touchRecord.currentPageX = touch.pageX), - (touchRecord.currentPageY = touch.pageY), - (touchRecord.currentTimeStamp = timestampForTouch(touch)), - (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))); + touchRecord + ? ((touchRecord.touchActive = !1), + (touchRecord.previousPageX = touchRecord.currentPageX), + (touchRecord.previousPageY = touchRecord.currentPageY), + (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), + (touchRecord.currentPageX = touch.pageX), + (touchRecord.currentPageY = touch.pageY), + (touchRecord.currentTimeStamp = timestampForTouch(touch)), + (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))) + : console.warn( + "Cannot record touch end without a touch start.\nTouch End: %s\n", + "Touch Bank: %s", + printTouch(touch), + printTouchBank() + ); +} +function printTouch(touch) { + return JSON.stringify({ + identifier: touch.identifier, + pageX: touch.pageX, + pageY: touch.pageY, + timestamp: timestampForTouch(touch) + }); +} +function printTouchBank() { + var printed = JSON.stringify(touchBank.slice(0, 20)); + 20 < touchBank.length && + (printed += " (original size: " + touchBank.length + ")"); + return printed; } var ResponderTouchHistoryStore = { recordTouchTrack: function(topLevelType, nativeEvent) { @@ -434,10 +589,10 @@ function accumulate(current, next) { return null == current ? next : Array.isArray(current) - ? current.concat(next) - : Array.isArray(next) - ? [current].concat(next) - : [current, next]; + ? current.concat(next) + : Array.isArray(next) + ? [current].concat(next) + : [current, next]; } var responderInst = null, trackedTouchCount = 0; @@ -527,7 +682,13 @@ var eventTypes = { "topTouchCancel" === topLevelType ) if (0 <= trackedTouchCount) --trackedTouchCount; - else return null; + else + return ( + console.warn( + "Ended a touch event which was not counted in `trackedTouchCount`." + ), + null + ); ResponderTouchHistoryStore.recordTouchTrack(topLevelType, nativeEvent); if ( targetInst && @@ -539,10 +700,10 @@ var eventTypes = { var shouldSetEventType = isStartish(topLevelType) ? eventTypes.startShouldSetResponder : isMoveish(topLevelType) - ? eventTypes.moveShouldSetResponder - : "topSelectionChange" === topLevelType - ? eventTypes.selectionChangeShouldSetResponder - : eventTypes.scrollShouldSetResponder; + ? eventTypes.moveShouldSetResponder + : "topSelectionChange" === topLevelType + ? eventTypes.selectionChangeShouldSetResponder + : eventTypes.scrollShouldSetResponder; if (responderInst) b: { var JSCompiler_temp = responderInst; @@ -696,10 +857,10 @@ var eventTypes = { (shouldSetEventType = shouldSetEventType ? eventTypes.responderStart : JSCompiler_temp - ? eventTypes.responderMove - : targetInst - ? eventTypes.responderEnd - : null) + ? eventTypes.responderMove + : targetInst + ? eventTypes.responderEnd + : null) ) (shouldSetEventType = ResponderSyntheticEvent.getPooled( shouldSetEventType, @@ -762,8 +923,8 @@ var eventTypes = { (topLevelType = shouldSetEventType ? eventTypes.responderTerminate : topLevelType - ? eventTypes.responderRelease - : null) + ? eventTypes.responderRelease + : null) ) (nativeEvent = ResponderSyntheticEvent.getPooled( topLevelType, @@ -787,196 +948,87 @@ var eventTypes = { } } }, - eventPluginOrder = null, - namesToPlugins = {}; -function recomputePluginOrdering() { - if (eventPluginOrder) - for (var pluginName in namesToPlugins) { - var pluginModule = namesToPlugins[pluginName], - pluginIndex = eventPluginOrder.indexOf(pluginName); - if (!(-1 < pluginIndex)) - throw Error( - "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + - pluginName + - "`." - ); - if (!plugins[pluginIndex]) { - if (!pluginModule.extractEvents) - throw Error( - "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + - pluginName + - "` does not." - ); - plugins[pluginIndex] = pluginModule; - pluginIndex = pluginModule.eventTypes; - for (var eventName in pluginIndex) { - var JSCompiler_inline_result = void 0; - var dispatchConfig = pluginIndex[eventName], - pluginModule$jscomp$0 = pluginModule, - eventName$jscomp$0 = eventName; - if (eventNameDispatchConfigs.hasOwnProperty(eventName$jscomp$0)) - throw Error( - "EventPluginRegistry: More than one plugin attempted to publish the same event name, `" + - eventName$jscomp$0 + - "`." - ); - eventNameDispatchConfigs[eventName$jscomp$0] = dispatchConfig; - var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; - if (phasedRegistrationNames) { - for (JSCompiler_inline_result in phasedRegistrationNames) - phasedRegistrationNames.hasOwnProperty( - JSCompiler_inline_result - ) && - publishRegistrationName( - phasedRegistrationNames[JSCompiler_inline_result], - pluginModule$jscomp$0, - eventName$jscomp$0 - ); - JSCompiler_inline_result = !0; - } else - dispatchConfig.registrationName - ? (publishRegistrationName( - dispatchConfig.registrationName, - pluginModule$jscomp$0, - eventName$jscomp$0 - ), - (JSCompiler_inline_result = !0)) - : (JSCompiler_inline_result = !1); - if (!JSCompiler_inline_result) - throw Error( - "EventPluginRegistry: Failed to publish event `" + - eventName + - "` for plugin `" + - pluginName + - "`." - ); - } - } - } -} -function publishRegistrationName(registrationName, pluginModule) { - if (registrationNameModules[registrationName]) - throw Error( - "EventPluginRegistry: More than one plugin attempted to publish the same registration name, `" + - registrationName + - "`." - ); - registrationNameModules[registrationName] = pluginModule; -} -var plugins = [], - eventNameDispatchConfigs = {}, - registrationNameModules = {}, customBubblingEventTypes = ReactNativePrivateInterface.ReactNativeViewConfigRegistry .customBubblingEventTypes, customDirectEventTypes = ReactNativePrivateInterface.ReactNativeViewConfigRegistry .customDirectEventTypes; -if (eventPluginOrder) - throw Error( - "EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React." - ); -eventPluginOrder = Array.prototype.slice.call([ +injection.injectEventPluginOrder([ "ResponderEventPlugin", "ReactNativeBridgeEventPlugin" ]); -recomputePluginOrdering(); -var injectedNamesToPlugins$jscomp$inline_94 = { - ResponderEventPlugin: ResponderEventPlugin, - ReactNativeBridgeEventPlugin: { - eventTypes: {}, - extractEvents: function( - topLevelType, - targetInst, - nativeEvent, - nativeEventTarget - ) { - if (null == targetInst) return null; - var bubbleDispatchConfig = customBubblingEventTypes[topLevelType], - directDispatchConfig = customDirectEventTypes[topLevelType]; - if (!bubbleDispatchConfig && !directDispatchConfig) - throw Error( - 'Unsupported top level event type "' + topLevelType + '" dispatched' - ); - topLevelType = SyntheticEvent.getPooled( - bubbleDispatchConfig || directDispatchConfig, - targetInst, - nativeEvent, - nativeEventTarget - ); - if (bubbleDispatchConfig) - forEachAccumulated(topLevelType, accumulateTwoPhaseDispatchesSingle); - else if (directDispatchConfig) - forEachAccumulated(topLevelType, accumulateDirectDispatchesSingle); - else return null; - return topLevelType; - } - } - }, - isOrderingDirty$jscomp$inline_95 = !1, - pluginName$jscomp$inline_96; -for (pluginName$jscomp$inline_96 in injectedNamesToPlugins$jscomp$inline_94) - if ( - injectedNamesToPlugins$jscomp$inline_94.hasOwnProperty( - pluginName$jscomp$inline_96 - ) - ) { - var pluginModule$jscomp$inline_97 = - injectedNamesToPlugins$jscomp$inline_94[pluginName$jscomp$inline_96]; - if ( - !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_96) || - namesToPlugins[pluginName$jscomp$inline_96] !== - pluginModule$jscomp$inline_97 +injection.injectEventPluginsByName({ + ResponderEventPlugin: ResponderEventPlugin, + ReactNativeBridgeEventPlugin: { + eventTypes: {}, + extractEvents: function( + topLevelType, + targetInst, + nativeEvent, + nativeEventTarget ) { - if (namesToPlugins[pluginName$jscomp$inline_96]) + if (null == targetInst) return null; + var bubbleDispatchConfig = customBubblingEventTypes[topLevelType], + directDispatchConfig = customDirectEventTypes[topLevelType]; + if (!bubbleDispatchConfig && !directDispatchConfig) throw Error( - "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - pluginName$jscomp$inline_96 + - "`." + 'Unsupported top level event type "' + topLevelType + '" dispatched' ); - namesToPlugins[ - pluginName$jscomp$inline_96 - ] = pluginModule$jscomp$inline_97; - isOrderingDirty$jscomp$inline_95 = !0; + topLevelType = SyntheticEvent.getPooled( + bubbleDispatchConfig || directDispatchConfig, + targetInst, + nativeEvent, + nativeEventTarget + ); + if (bubbleDispatchConfig) + forEachAccumulated(topLevelType, accumulateTwoPhaseDispatchesSingle); + else if (directDispatchConfig) + forEachAccumulated(topLevelType, accumulateDirectDispatchesSingle); + else return null; + return topLevelType; } } -isOrderingDirty$jscomp$inline_95 && recomputePluginOrdering(); +}); var instanceCache = new Map(), instanceProps = new Map(); function getInstanceFromTag(tag) { return instanceCache.get(tag) || null; } -function batchedUpdatesImpl(fn, bookkeeping) { - return fn(bookkeeping); -} -var isInsideEventHandler = !1; -function batchedUpdates(fn, bookkeeping) { - if (isInsideEventHandler) return fn(bookkeeping); - isInsideEventHandler = !0; - try { - return batchedUpdatesImpl(fn, bookkeeping); - } finally { - isInsideEventHandler = !1; - } -} -var eventQueue = null; -function executeDispatchesAndReleaseTopLevel(e) { - if (e) { - var dispatchListeners = e._dispatchListeners, - dispatchInstances = e._dispatchInstances; - if (Array.isArray(dispatchListeners)) - for ( - var i = 0; - i < dispatchListeners.length && !e.isPropagationStopped(); - i++ +var restoreTarget = null, + restoreQueue = null; +function restoreStateOfTarget(target) { + if (getInstanceFromNode(target)) + throw Error( + "setRestoreImplementation() needs to be called to handle a target for controlled events. This error is likely caused by a bug in React. Please file an issue." + ); +} +function batchedUpdatesImpl(fn, bookkeeping) { + return fn(bookkeeping); +} +function flushDiscreteUpdatesImpl() {} +var isInsideEventHandler = !1; +function batchedUpdates(fn, bookkeeping) { + if (isInsideEventHandler) return fn(bookkeeping); + isInsideEventHandler = !0; + try { + return batchedUpdatesImpl(fn, bookkeeping); + } finally { + if ( + ((isInsideEventHandler = !1), + null !== restoreTarget || null !== restoreQueue) + ) + if ( + (flushDiscreteUpdatesImpl(), + restoreTarget && + ((bookkeeping = restoreTarget), + (fn = restoreQueue), + (restoreQueue = restoreTarget = null), + restoreStateOfTarget(bookkeeping), + fn)) ) - executeDispatch(e, dispatchListeners[i], dispatchInstances[i]); - else - dispatchListeners && - executeDispatch(e, dispatchListeners, dispatchInstances); - e._dispatchListeners = null; - e._dispatchInstances = null; - e.isPersistent() || e.constructor.release(e); + for (bookkeeping = 0; bookkeeping < fn.length; bookkeeping++) + restoreStateOfTarget(fn[bookkeeping]); } } var EMPTY_NATIVE_EVENT = {}; @@ -984,7 +1036,7 @@ function _receiveRootNodeIDEvent(rootNodeID, topLevelType, nativeEventParam) { var nativeEvent = nativeEventParam || EMPTY_NATIVE_EVENT, inst = getInstanceFromTag(rootNodeID), target = null; - null != inst && (target = inst.stateNode); + target = nativeEvent.target; batchedUpdates(function() { var events = target; for (var events$jscomp$0 = null, i = 0; i < plugins.length; i++) { @@ -1059,11 +1111,10 @@ getFiberCurrentPropsFromNode = function(stateNode) { }; getInstanceFromNode = getInstanceFromTag; getNodeFromInstance = function(inst) { - inst = inst.stateNode; - var tag = inst._nativeTag; - void 0 === tag && ((inst = inst.canonical), (tag = inst._nativeTag)); - if (!tag) throw Error("All native instances should have a tag."); - return inst; + var _tag = inst.stateNode._nativeTag; + void 0 === _tag && (_tag = inst.stateNode.canonical._nativeTag); + if (!_tag) throw Error("All native instances should have a tag."); + return _tag; }; ResponderEventPlugin.injection.injectGlobalResponderHandler({ onChange: function(from, to, blockNativeResponder) { @@ -1098,9 +1149,11 @@ var hasSymbol = "function" === typeof Symbol && Symbol.for, ? Symbol.for("react.suspense_list") : 60120, REACT_MEMO_TYPE = hasSymbol ? Symbol.for("react.memo") : 60115, - REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 60116, - REACT_BLOCK_TYPE = hasSymbol ? Symbol.for("react.block") : 60121, - MAYBE_ITERATOR_SYMBOL = "function" === typeof Symbol && Symbol.iterator; + REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 60116; +hasSymbol && Symbol.for("react.fundamental"); +hasSymbol && Symbol.for("react.responder"); +hasSymbol && Symbol.for("react.scope"); +var MAYBE_ITERATOR_SYMBOL = "function" === typeof Symbol && Symbol.iterator; function getIteratorFn(maybeIterable) { if (null === maybeIterable || "object" !== typeof maybeIterable) return null; maybeIterable = @@ -1110,10 +1163,9 @@ function getIteratorFn(maybeIterable) { } function initializeLazyComponentType(lazyComponent) { if (-1 === lazyComponent._status) { - var ctor = lazyComponent._result; - ctor || (ctor = lazyComponent._ctor); - ctor = ctor(); lazyComponent._status = 0; + var ctor = lazyComponent._ctor; + ctor = ctor(); lazyComponent._result = ctor; ctor.then( function(moduleObject) { @@ -1150,9 +1202,9 @@ function getComponentName(type) { if ("object" === typeof type) switch (type.$$typeof) { case REACT_CONTEXT_TYPE: - return (type.displayName || "Context") + ".Consumer"; + return "Context.Consumer"; case REACT_PROVIDER_TYPE: - return (type._context.displayName || "Context") + ".Provider"; + return "Context.Provider"; case REACT_FORWARD_REF_TYPE: var innerType = type.render; innerType = innerType.displayName || innerType.name || ""; @@ -1162,8 +1214,6 @@ function getComponentName(type) { ); case REACT_MEMO_TYPE: return getComponentName(type.type); - case REACT_BLOCK_TYPE: - return getComponentName(type.render); case REACT_LAZY_TYPE: if ((type = 1 === type._status ? type._result : null)) return getComponentName(type); @@ -1344,8 +1394,8 @@ function diffNestedProperty( return nextProp ? addNestedProperty(updatePayload, nextProp, validAttributes) : prevProp - ? clearNestedProperty(updatePayload, prevProp, validAttributes) - : updatePayload; + ? clearNestedProperty(updatePayload, prevProp, validAttributes) + : updatePayload; if (!Array.isArray(prevProp) && !Array.isArray(nextProp)) return diffProperties(updatePayload, prevProp, nextProp, validAttributes); if (Array.isArray(prevProp) && Array.isArray(nextProp)) { @@ -1523,10 +1573,10 @@ var ReactNativeFiberHostComponent = (function() { } var _proto = ReactNativeFiberHostComponent.prototype; _proto.blur = function() { - ReactNativePrivateInterface.TextInputState.blurTextInput(this); + ReactNativePrivateInterface.TextInputState.blurTextInput(this._nativeTag); }; _proto.focus = function() { - ReactNativePrivateInterface.TextInputState.focusTextInput(this); + ReactNativePrivateInterface.TextInputState.focusTextInput(this._nativeTag); }; _proto.measure = function(callback) { ReactNativePrivateInterface.UIManager.measure( @@ -1570,7 +1620,7 @@ var ReactNativeFiberHostComponent = (function() { }; return ReactNativeFiberHostComponent; })(); -function shim() { +function shim$1() { throw Error( "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." ); @@ -1608,7 +1658,45 @@ function finalizeInitialChildren(parentInstance) { } var scheduleTimeout = setTimeout, cancelTimeout = clearTimeout, - valueStack = [], + BEFORE_SLASH_RE = /^(.*)[\\\/]/; +function getStackByFiberInDevAndProd(workInProgress) { + var info = ""; + do { + a: switch (workInProgress.tag) { + case 3: + case 4: + case 6: + case 7: + case 10: + case 9: + var JSCompiler_inline_result = ""; + break a; + default: + var owner = workInProgress._debugOwner, + source = workInProgress._debugSource, + name = getComponentName(workInProgress.type); + JSCompiler_inline_result = null; + owner && (JSCompiler_inline_result = getComponentName(owner.type)); + owner = name; + name = ""; + source + ? (name = + " (at " + + source.fileName.replace(BEFORE_SLASH_RE, "") + + ":" + + source.lineNumber + + ")") + : JSCompiler_inline_result && + (name = " (created by " + JSCompiler_inline_result + ")"); + JSCompiler_inline_result = "\n in " + (owner || "Unknown") + name; + } + info += JSCompiler_inline_result; + workInProgress = workInProgress.return; + } while (workInProgress); + return info; +} +new Set(); +var valueStack = [], index = -1; function pop(cursor) { 0 > index || @@ -1645,17 +1733,21 @@ function isContextProvider(type) { type = type.childContextTypes; return null !== type && void 0 !== type; } -function popContext() { - pop(didPerformWorkStackCursor); - pop(contextStackCursor); +function popContext(fiber) { + pop(didPerformWorkStackCursor, fiber); + pop(contextStackCursor, fiber); +} +function popTopLevelContextObject(fiber) { + pop(didPerformWorkStackCursor, fiber); + pop(contextStackCursor, fiber); } 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); + push(contextStackCursor, context, fiber); + push(didPerformWorkStackCursor, didChange, fiber); } function processChildContext(fiber, type, parentContext) { var instance = fiber.stateNode; @@ -1673,13 +1765,17 @@ function processChildContext(fiber, type, parentContext) { return Object.assign({}, parentContext, {}, instance); } function pushContextProvider(workInProgress) { - workInProgress = - ((workInProgress = workInProgress.stateNode) && - workInProgress.__reactInternalMemoizedMergedChildContext) || + var instance = workInProgress.stateNode; + instance = + (instance && instance.__reactInternalMemoizedMergedChildContext) || emptyContextObject; previousContext = contextStackCursor.current; - push(contextStackCursor, workInProgress); - push(didPerformWorkStackCursor, didPerformWorkStackCursor.current); + push(contextStackCursor, instance, workInProgress); + push( + didPerformWorkStackCursor, + didPerformWorkStackCursor.current, + workInProgress + ); return !0; } function invalidateContextProvider(workInProgress, type, didChange) { @@ -1689,21 +1785,18 @@ function invalidateContextProvider(workInProgress, type, didChange) { "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); + ? ((type = processChildContext(workInProgress, type, previousContext)), + (instance.__reactInternalMemoizedMergedChildContext = type), + pop(didPerformWorkStackCursor, workInProgress), + pop(contextStackCursor, workInProgress), + push(contextStackCursor, type, workInProgress)) + : pop(didPerformWorkStackCursor, workInProgress); + push(didPerformWorkStackCursor, didChange, workInProgress); } 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 = @@ -1714,7 +1807,6 @@ var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, Scheduler_LowPriority = Scheduler.unstable_LowPriority, Scheduler_IdlePriority = Scheduler.unstable_IdlePriority, fakeCallbackNode = {}, - shouldYield = Scheduler.unstable_shouldYield, requestPaint = void 0 !== Scheduler_requestPaint ? Scheduler_requestPaint : function() {}, syncQueue = null, @@ -1814,10 +1906,10 @@ function flushSyncCallbackQueueImpl() { function is(x, y) { return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y); } -var objectIs = "function" === typeof Object.is ? Object.is : is, +var is$1 = "function" === typeof Object.is ? Object.is : is, hasOwnProperty = Object.prototype.hasOwnProperty; function shallowEqual(objA, objB) { - if (objectIs(objA, objB)) return !0; + if (is$1(objA, objB)) return !0; if ( "object" !== typeof objA || null === objA || @@ -1831,48 +1923,11 @@ function shallowEqual(objA, objB) { for (keysB = 0; keysB < keysA.length; keysB++) if ( !hasOwnProperty.call(objB, keysA[keysB]) || - !objectIs(objA[keysA[keysB]], objB[keysA[keysB]]) + !is$1(objA[keysA[keysB]], objB[keysA[keysB]]) ) return !1; return !0; } -var BEFORE_SLASH_RE = /^(.*)[\\\/]/; -function getStackByFiberInDevAndProd(workInProgress) { - var info = ""; - do { - a: switch (workInProgress.tag) { - case 3: - case 4: - case 6: - case 7: - case 10: - case 9: - var JSCompiler_inline_result = ""; - break a; - default: - var owner = workInProgress._debugOwner, - source = workInProgress._debugSource, - name = getComponentName(workInProgress.type); - JSCompiler_inline_result = null; - owner && (JSCompiler_inline_result = getComponentName(owner.type)); - owner = name; - name = ""; - source - ? (name = - " (at " + - source.fileName.replace(BEFORE_SLASH_RE, "") + - ":" + - source.lineNumber + - ")") - : JSCompiler_inline_result && - (name = " (created by " + JSCompiler_inline_result + ")"); - JSCompiler_inline_result = "\n in " + (owner || "Unknown") + name; - } - info += JSCompiler_inline_result; - workInProgress = workInProgress.return; - } while (workInProgress); - return info; -} function resolveDefaultProps(Component, baseProps) { if (Component && Component.defaultProps) { baseProps = Object.assign({}, baseProps); @@ -1890,9 +1945,14 @@ var valueCursor = { current: null }, function resetContextDependencies() { lastContextWithAllBitsObserved = lastContextDependency = currentlyRenderingFiber = null; } +function pushProvider(providerFiber, nextValue) { + var context = providerFiber.type._context; + push(valueCursor, context._currentValue, providerFiber); + context._currentValue = nextValue; +} function popProvider(providerFiber) { var currentValue = valueCursor.current; - pop(valueCursor); + pop(valueCursor, providerFiber); providerFiber.type._context._currentValue = currentValue; } function scheduleWorkOnParentPath(parent, renderExpirationTime) { @@ -1947,195 +2007,237 @@ function readContext(context, observedBits) { return context._currentValue; } var hasForceUpdate = !1; -function initializeUpdateQueue(fiber) { - fiber.updateQueue = { - baseState: fiber.memoizedState, - baseQueue: null, - shared: { pending: null }, - effects: null +function createUpdateQueue(baseState) { + return { + baseState: baseState, + firstUpdate: null, + lastUpdate: null, + firstCapturedUpdate: null, + lastCapturedUpdate: null, + firstEffect: null, + lastEffect: null, + firstCapturedEffect: null, + lastCapturedEffect: null }; } -function cloneUpdateQueue(current, workInProgress) { - current = current.updateQueue; - workInProgress.updateQueue === current && - (workInProgress.updateQueue = { - baseState: current.baseState, - baseQueue: current.baseQueue, - shared: current.shared, - effects: current.effects - }); +function cloneUpdateQueue(currentQueue) { + return { + baseState: currentQueue.baseState, + firstUpdate: currentQueue.firstUpdate, + lastUpdate: currentQueue.lastUpdate, + firstCapturedUpdate: null, + lastCapturedUpdate: null, + firstEffect: null, + lastEffect: null, + firstCapturedEffect: null, + lastCapturedEffect: null + }; } function createUpdate(expirationTime, suspenseConfig) { - expirationTime = { + return { expirationTime: expirationTime, suspenseConfig: suspenseConfig, tag: 0, payload: null, callback: null, - next: null + next: null, + nextEffect: null }; - return (expirationTime.next = expirationTime); +} +function appendUpdateToQueue(queue, update) { + null === queue.lastUpdate + ? (queue.firstUpdate = queue.lastUpdate = update) + : ((queue.lastUpdate.next = update), (queue.lastUpdate = update)); } function enqueueUpdate(fiber, update) { - 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; - } + var alternate = fiber.alternate; + if (null === alternate) { + var queue1 = fiber.updateQueue; + var queue2 = null; + null === queue1 && + (queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState)); + } else + (queue1 = fiber.updateQueue), + (queue2 = alternate.updateQueue), + null === queue1 + ? null === queue2 + ? ((queue1 = fiber.updateQueue = createUpdateQueue( + fiber.memoizedState + )), + (queue2 = alternate.updateQueue = createUpdateQueue( + alternate.memoizedState + ))) + : (queue1 = fiber.updateQueue = cloneUpdateQueue(queue2)) + : null === queue2 && + (queue2 = alternate.updateQueue = cloneUpdateQueue(queue1)); + null === queue2 || queue1 === queue2 + ? appendUpdateToQueue(queue1, update) + : null === queue1.lastUpdate || null === queue2.lastUpdate + ? (appendUpdateToQueue(queue1, update), + appendUpdateToQueue(queue2, update)) + : (appendUpdateToQueue(queue1, update), (queue2.lastUpdate = update)); } function enqueueCapturedUpdate(workInProgress, update) { + var workInProgressQueue = workInProgress.updateQueue; + workInProgressQueue = + null === workInProgressQueue + ? (workInProgress.updateQueue = createUpdateQueue( + workInProgress.memoizedState + )) + : ensureWorkInProgressQueueIsAClone(workInProgress, workInProgressQueue); + null === workInProgressQueue.lastCapturedUpdate + ? (workInProgressQueue.firstCapturedUpdate = workInProgressQueue.lastCapturedUpdate = update) + : ((workInProgressQueue.lastCapturedUpdate.next = update), + (workInProgressQueue.lastCapturedUpdate = update)); +} +function ensureWorkInProgressQueueIsAClone(workInProgress, queue) { var current = workInProgress.alternate; - null !== current && cloneUpdateQueue(current, workInProgress); - workInProgress = workInProgress.updateQueue; - current = workInProgress.baseQueue; - null === current - ? ((workInProgress.baseQueue = update.next = update), - (update.next = update)) - : ((update.next = current.next), (current.next = update)); + null !== current && + queue === current.updateQueue && + (queue = workInProgress.updateQueue = cloneUpdateQueue(queue)); + return queue; +} +function getStateFromUpdate( + workInProgress, + queue, + update, + prevState, + nextProps, + instance +) { + switch (update.tag) { + case 1: + return ( + (workInProgress = update.payload), + "function" === typeof workInProgress + ? workInProgress.call(instance, prevState, nextProps) + : workInProgress + ); + case 3: + workInProgress.effectTag = (workInProgress.effectTag & -4097) | 64; + case 0: + workInProgress = update.payload; + nextProps = + "function" === typeof workInProgress + ? workInProgress.call(instance, prevState, nextProps) + : workInProgress; + if (null === nextProps || void 0 === nextProps) break; + return Object.assign({}, prevState, nextProps); + case 2: + hasForceUpdate = !0; + } + return prevState; } function processUpdateQueue( - workInProgress$jscomp$0, + workInProgress, + queue, props, instance, renderExpirationTime ) { - var queue = workInProgress$jscomp$0.updateQueue; hasForceUpdate = !1; - var baseQueue = queue.baseQueue, - pendingQueue = queue.shared.pending; - if (null !== pendingQueue) { - if (null !== baseQueue) { - var baseFirst = baseQueue.next; - baseQueue.next = pendingQueue.next; - pendingQueue.next = baseFirst; - } - baseQueue = pendingQueue; - queue.shared.pending = null; - baseFirst = workInProgress$jscomp$0.alternate; - null !== baseFirst && - ((baseFirst = baseFirst.updateQueue), - null !== baseFirst && (baseFirst.baseQueue = pendingQueue)); - } - if (null !== baseQueue) { - baseFirst = baseQueue.next; - var newState = queue.baseState, + queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue); + for ( + var newBaseState = queue.baseState, + newFirstUpdate = null, newExpirationTime = 0, - newBaseState = null, - newBaseQueueFirst = null, - newBaseQueueLast = null; - if (null !== baseFirst) { - var update = baseFirst; - do { - pendingQueue = update.expirationTime; - if (pendingQueue < renderExpirationTime) { - var clone = { - expirationTime: update.expirationTime, - suspenseConfig: update.suspenseConfig, - tag: update.tag, - payload: update.payload, - callback: update.callback, - next: null - }; - null === newBaseQueueLast - ? ((newBaseQueueFirst = newBaseQueueLast = clone), - (newBaseState = newState)) - : (newBaseQueueLast = newBaseQueueLast.next = clone); - pendingQueue > newExpirationTime && - (newExpirationTime = pendingQueue); - } else { - null !== newBaseQueueLast && - (newBaseQueueLast = newBaseQueueLast.next = { - expirationTime: 1073741823, - suspenseConfig: update.suspenseConfig, - tag: update.tag, - payload: update.payload, - callback: update.callback, - next: null - }); - markRenderEventTimeAndConfig(pendingQueue, update.suspenseConfig); - a: { - var workInProgress = workInProgress$jscomp$0, - update$jscomp$0 = update; - pendingQueue = props; - clone = instance; - switch (update$jscomp$0.tag) { - case 1: - workInProgress = update$jscomp$0.payload; - if ("function" === typeof workInProgress) { - newState = workInProgress.call(clone, newState, pendingQueue); - break a; - } - newState = workInProgress; - break a; - case 3: - workInProgress.effectTag = - (workInProgress.effectTag & -4097) | 64; - case 0: - workInProgress = update$jscomp$0.payload; - pendingQueue = - "function" === typeof workInProgress - ? workInProgress.call(clone, newState, pendingQueue) - : workInProgress; - if (null === pendingQueue || void 0 === pendingQueue) break a; - newState = Object.assign({}, newState, pendingQueue); - break a; - case 2: - hasForceUpdate = !0; - } - } - null !== update.callback && - ((workInProgress$jscomp$0.effectTag |= 32), - (pendingQueue = queue.effects), - null === pendingQueue - ? (queue.effects = [update]) - : pendingQueue.push(update)); - } - update = update.next; - if (null === update || update === baseFirst) - if (((pendingQueue = queue.shared.pending), null === pendingQueue)) - break; - else - (update = baseQueue.next = pendingQueue.next), - (pendingQueue.next = baseFirst), - (queue.baseQueue = baseQueue = pendingQueue), - (queue.shared.pending = null); - } while (1); - } - null === newBaseQueueLast - ? (newBaseState = newState) - : (newBaseQueueLast.next = newBaseQueueFirst); - queue.baseState = newBaseState; - queue.baseQueue = newBaseQueueLast; - markUnprocessedUpdateTime(newExpirationTime); - workInProgress$jscomp$0.expirationTime = newExpirationTime; - workInProgress$jscomp$0.memoizedState = newState; + update = queue.firstUpdate, + resultState = newBaseState; + null !== update; + + ) { + var updateExpirationTime = update.expirationTime; + updateExpirationTime < renderExpirationTime + ? (null === newFirstUpdate && + ((newFirstUpdate = update), (newBaseState = resultState)), + newExpirationTime < updateExpirationTime && + (newExpirationTime = updateExpirationTime)) + : (markRenderEventTimeAndConfig( + updateExpirationTime, + update.suspenseConfig + ), + (resultState = getStateFromUpdate( + workInProgress, + queue, + update, + resultState, + props, + instance + )), + null !== update.callback && + ((workInProgress.effectTag |= 32), + (update.nextEffect = null), + null === queue.lastEffect + ? (queue.firstEffect = queue.lastEffect = update) + : ((queue.lastEffect.nextEffect = update), + (queue.lastEffect = update)))); + update = update.next; + } + updateExpirationTime = null; + for (update = queue.firstCapturedUpdate; null !== update; ) { + var _updateExpirationTime = update.expirationTime; + _updateExpirationTime < renderExpirationTime + ? (null === updateExpirationTime && + ((updateExpirationTime = update), + null === newFirstUpdate && (newBaseState = resultState)), + newExpirationTime < _updateExpirationTime && + (newExpirationTime = _updateExpirationTime)) + : ((resultState = getStateFromUpdate( + workInProgress, + queue, + update, + resultState, + props, + instance + )), + null !== update.callback && + ((workInProgress.effectTag |= 32), + (update.nextEffect = null), + null === queue.lastCapturedEffect + ? (queue.firstCapturedEffect = queue.lastCapturedEffect = update) + : ((queue.lastCapturedEffect.nextEffect = update), + (queue.lastCapturedEffect = update)))); + update = update.next; } + null === newFirstUpdate && (queue.lastUpdate = null); + null === updateExpirationTime + ? (queue.lastCapturedUpdate = null) + : (workInProgress.effectTag |= 32); + null === newFirstUpdate && + null === updateExpirationTime && + (newBaseState = resultState); + queue.baseState = newBaseState; + queue.firstUpdate = newFirstUpdate; + queue.firstCapturedUpdate = updateExpirationTime; + markUnprocessedUpdateTime(newExpirationTime); + workInProgress.expirationTime = newExpirationTime; + workInProgress.memoizedState = resultState; } function commitUpdateQueue(finishedWork, finishedQueue, instance) { - finishedWork = finishedQueue.effects; - finishedQueue.effects = null; - if (null !== finishedWork) - for ( - finishedQueue = 0; - finishedQueue < finishedWork.length; - finishedQueue++ - ) { - var effect = finishedWork[finishedQueue], - callback = effect.callback; - if (null !== callback) { - effect.callback = null; - if ("function" !== typeof callback) - throw Error( - "Invalid argument passed as callback. Expected a function. Instead received: " + - callback - ); - callback.call(instance); - } + null !== finishedQueue.firstCapturedUpdate && + (null !== finishedQueue.lastUpdate && + ((finishedQueue.lastUpdate.next = finishedQueue.firstCapturedUpdate), + (finishedQueue.lastUpdate = finishedQueue.lastCapturedUpdate)), + (finishedQueue.firstCapturedUpdate = finishedQueue.lastCapturedUpdate = null)); + commitUpdateEffects(finishedQueue.firstEffect, instance); + finishedQueue.firstEffect = finishedQueue.lastEffect = null; + commitUpdateEffects(finishedQueue.firstCapturedEffect, instance); + finishedQueue.firstCapturedEffect = finishedQueue.lastCapturedEffect = null; +} +function commitUpdateEffects(effect, instance) { + for (; null !== effect; ) { + var callback = effect.callback; + if (null !== callback) { + effect.callback = null; + if ("function" !== typeof callback) + throw Error( + "Invalid argument passed as callback. Expected a function. Instead received: " + + callback + ); + callback.call(instance); } + effect = effect.nextEffect; + } } var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig, emptyRefsObject = new React.Component().refs; @@ -2152,8 +2254,10 @@ function applyDerivedStateFromProps( ? ctor : Object.assign({}, ctor, getDerivedStateFromProps); workInProgress.memoizedState = getDerivedStateFromProps; - 0 === workInProgress.expirationTime && - (workInProgress.updateQueue.baseState = getDerivedStateFromProps); + nextProps = workInProgress.updateQueue; + null !== nextProps && + 0 === workInProgress.expirationTime && + (nextProps.baseState = getDerivedStateFromProps); } var classComponentUpdater = { isMounted: function(component) { @@ -2172,7 +2276,7 @@ var classComponentUpdater = { null !== callback && (suspenseConfig.callback = callback); enqueueUpdate(inst, suspenseConfig); - scheduleWork(inst, currentTime); + scheduleUpdateOnFiber(inst, currentTime); }, enqueueReplaceState: function(inst, payload, callback) { inst = inst._reactInternalFiber; @@ -2186,7 +2290,7 @@ var classComponentUpdater = { null !== callback && (suspenseConfig.callback = callback); enqueueUpdate(inst, suspenseConfig); - scheduleWork(inst, currentTime); + scheduleUpdateOnFiber(inst, currentTime); }, enqueueForceUpdate: function(inst, callback) { inst = inst._reactInternalFiber; @@ -2199,7 +2303,7 @@ var classComponentUpdater = { null !== callback && (suspenseConfig.callback = callback); enqueueUpdate(inst, suspenseConfig); - scheduleWork(inst, currentTime); + scheduleUpdateOnFiber(inst, currentTime); } }; function checkShouldComponentUpdate( @@ -2215,8 +2319,8 @@ function checkShouldComponentUpdate( return "function" === typeof workInProgress.shouldComponentUpdate ? workInProgress.shouldComponentUpdate(newProps, newState, nextContext) : ctor.prototype && ctor.prototype.isPureReactComponent - ? !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState) - : !0; + ? !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState) + : !0; } function constructClassInstance(workInProgress, ctor, props) { var isLegacyContextConsumer = !1, @@ -2268,7 +2372,6 @@ function mountClassInstance( instance.props = newProps; instance.state = workInProgress.memoizedState; instance.refs = emptyRefsObject; - initializeUpdateQueue(workInProgress); var contextType = ctor.contextType; "object" === typeof contextType && null !== contextType ? (instance.context = readContext(contextType)) @@ -2276,8 +2379,16 @@ function mountClassInstance( ? previousContext : contextStackCursor.current), (instance.context = getMaskedContext(workInProgress, contextType))); - processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); - instance.state = workInProgress.memoizedState; + contextType = workInProgress.updateQueue; + null !== contextType && + (processUpdateQueue( + workInProgress, + contextType, + newProps, + instance, + renderExpirationTime + ), + (instance.state = workInProgress.memoizedState)); contextType = ctor.getDerivedStateFromProps; "function" === typeof contextType && (applyDerivedStateFromProps(workInProgress, ctor, contextType, newProps), @@ -2293,18 +2404,21 @@ function mountClassInstance( instance.UNSAFE_componentWillMount(), ctor !== instance.state && classComponentUpdater.enqueueReplaceState(instance, instance.state, null), - processUpdateQueue( - workInProgress, - newProps, - instance, - renderExpirationTime - ), - (instance.state = workInProgress.memoizedState)); + (contextType = workInProgress.updateQueue), + null !== contextType && + (processUpdateQueue( + workInProgress, + contextType, + newProps, + instance, + renderExpirationTime + ), + (instance.state = workInProgress.memoizedState))); "function" === typeof instance.componentDidMount && (workInProgress.effectTag |= 4); } var isArray = Array.isArray; -function coerceRef(returnFiber, current, element) { +function coerceRef(returnFiber, current$$1, element) { returnFiber = element.ref; if ( null !== returnFiber && @@ -2316,7 +2430,7 @@ function coerceRef(returnFiber, current, element) { if (element) { if (1 !== element.tag) throw Error( - "Function components cannot have string refs. We recommend using useRef() instead. Learn more about using refs safely here: https://fb.me/react-strict-mode-string-ref" + "Function components cannot have refs. Did you mean to use React.forwardRef()?" ); var inst = element.stateNode; } @@ -2328,19 +2442,19 @@ function coerceRef(returnFiber, current, element) { ); var stringRef = "" + returnFiber; if ( - null !== current && - null !== current.ref && - "function" === typeof current.ref && - current.ref._stringRef === stringRef + null !== current$$1 && + null !== current$$1.ref && + "function" === typeof current$$1.ref && + current$$1.ref._stringRef === stringRef ) - return current.ref; - current = function(value) { + return current$$1.ref; + current$$1 = function(value) { var refs = inst.refs; refs === emptyRefsObject && (refs = inst.refs = {}); null === value ? delete refs[stringRef] : (refs[stringRef] = value); }; - current._stringRef = stringRef; - return current; + current$$1._stringRef = stringRef; + return current$$1; } if ("string" !== typeof returnFiber) throw Error( @@ -2392,8 +2506,8 @@ function ChildReconciler(shouldTrackSideEffects) { (currentFirstChild = currentFirstChild.sibling); return returnFiber; } - function useFiber(fiber, pendingProps) { - fiber = createWorkInProgress(fiber, pendingProps); + function useFiber(fiber, pendingProps, expirationTime) { + fiber = createWorkInProgress(fiber, pendingProps, expirationTime); fiber.index = 0; fiber.sibling = null; return fiber; @@ -2418,26 +2532,31 @@ function ChildReconciler(shouldTrackSideEffects) { (newFiber.effectTag = 2); return newFiber; } - function updateTextNode(returnFiber, current, textContent, expirationTime) { - if (null === current || 6 !== current.tag) + function updateTextNode( + returnFiber, + current$$1, + textContent, + expirationTime + ) { + if (null === current$$1 || 6 !== current$$1.tag) return ( - (current = createFiberFromText( + (current$$1 = createFiberFromText( textContent, returnFiber.mode, expirationTime )), - (current.return = returnFiber), - current + (current$$1.return = returnFiber), + current$$1 ); - current = useFiber(current, textContent); - current.return = returnFiber; - return current; + current$$1 = useFiber(current$$1, textContent, expirationTime); + current$$1.return = returnFiber; + return current$$1; } - function updateElement(returnFiber, current, element, expirationTime) { - if (null !== current && current.elementType === element.type) + function updateElement(returnFiber, current$$1, element, expirationTime) { + if (null !== current$$1 && current$$1.elementType === element.type) return ( - (expirationTime = useFiber(current, element.props)), - (expirationTime.ref = coerceRef(returnFiber, current, element)), + (expirationTime = useFiber(current$$1, element.props, expirationTime)), + (expirationTime.ref = coerceRef(returnFiber, current$$1, element)), (expirationTime.return = returnFiber), expirationTime ); @@ -2449,45 +2568,51 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime ); - expirationTime.ref = coerceRef(returnFiber, current, element); + expirationTime.ref = coerceRef(returnFiber, current$$1, element); expirationTime.return = returnFiber; return expirationTime; } - function updatePortal(returnFiber, current, portal, expirationTime) { + function updatePortal(returnFiber, current$$1, portal, expirationTime) { if ( - null === current || - 4 !== current.tag || - current.stateNode.containerInfo !== portal.containerInfo || - current.stateNode.implementation !== portal.implementation + null === current$$1 || + 4 !== current$$1.tag || + current$$1.stateNode.containerInfo !== portal.containerInfo || + current$$1.stateNode.implementation !== portal.implementation ) return ( - (current = createFiberFromPortal( + (current$$1 = createFiberFromPortal( portal, returnFiber.mode, expirationTime )), - (current.return = returnFiber), - current + (current$$1.return = returnFiber), + current$$1 ); - current = useFiber(current, portal.children || []); - current.return = returnFiber; - return current; + current$$1 = useFiber(current$$1, portal.children || [], expirationTime); + current$$1.return = returnFiber; + return current$$1; } - function updateFragment(returnFiber, current, fragment, expirationTime, key) { - if (null === current || 7 !== current.tag) + function updateFragment( + returnFiber, + current$$1, + fragment, + expirationTime, + key + ) { + if (null === current$$1 || 7 !== current$$1.tag) return ( - (current = createFiberFromFragment( + (current$$1 = createFiberFromFragment( fragment, returnFiber.mode, expirationTime, key )), - (current.return = returnFiber), - current + (current$$1.return = returnFiber), + current$$1 ); - current = useFiber(current, fragment); - current.return = returnFiber; - return current; + current$$1 = useFiber(current$$1, fragment, expirationTime); + current$$1.return = returnFiber; + return current$$1; } function createChild(returnFiber, newChild, expirationTime) { if ("string" === typeof newChild || "number" === typeof newChild) @@ -2850,48 +2975,39 @@ function ChildReconciler(shouldTrackSideEffects) { 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; - } + if (isUnkeyedTopLevelFragment.key === isObject) + if ( + 7 === isUnkeyedTopLevelFragment.tag + ? newChild.type === REACT_FRAGMENT_TYPE + : isUnkeyedTopLevelFragment.elementType === newChild.type + ) { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment.sibling + ); + currentFirstChild = useFiber( + isUnkeyedTopLevelFragment, + newChild.type === REACT_FRAGMENT_TYPE + ? newChild.props.children + : newChild.props, + expirationTime + ); + currentFirstChild.ref = coerceRef( + returnFiber, + isUnkeyedTopLevelFragment, + newChild + ); + currentFirstChild.return = returnFiber; + returnFiber = currentFirstChild; + break a; + } else { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment + ); + break; } - deleteRemainingChildren(returnFiber, isUnkeyedTopLevelFragment); - break; - } else deleteChild(returnFiber, isUnkeyedTopLevelFragment); + else deleteChild(returnFiber, isUnkeyedTopLevelFragment); isUnkeyedTopLevelFragment = isUnkeyedTopLevelFragment.sibling; } newChild.type === REACT_FRAGMENT_TYPE @@ -2941,7 +3057,8 @@ function ChildReconciler(shouldTrackSideEffects) { ); currentFirstChild = useFiber( currentFirstChild, - newChild.children || [] + newChild.children || [], + expirationTime ); currentFirstChild.return = returnFiber; returnFiber = currentFirstChild; @@ -2968,7 +3085,11 @@ function ChildReconciler(shouldTrackSideEffects) { (newChild = "" + newChild), null !== currentFirstChild && 6 === currentFirstChild.tag ? (deleteRemainingChildren(returnFiber, currentFirstChild.sibling), - (currentFirstChild = useFiber(currentFirstChild, newChild)), + (currentFirstChild = useFiber( + currentFirstChild, + newChild, + expirationTime + )), (currentFirstChild.return = returnFiber), (returnFiber = currentFirstChild)) : (deleteRemainingChildren(returnFiber, currentFirstChild), @@ -3023,16 +3144,16 @@ function requiredContext(c) { return c; } function pushHostContainer(fiber, nextRootInstance) { - push(rootInstanceStackCursor, nextRootInstance); - push(contextFiberStackCursor, fiber); - push(contextStackCursor$1, NO_CONTEXT); - pop(contextStackCursor$1); - push(contextStackCursor$1, { isInAParentText: !1 }); + push(rootInstanceStackCursor, nextRootInstance, fiber); + push(contextFiberStackCursor, fiber, fiber); + push(contextStackCursor$1, NO_CONTEXT, fiber); + pop(contextStackCursor$1, fiber); + push(contextStackCursor$1, { isInAParentText: !1 }, fiber); } -function popHostContainer() { - pop(contextStackCursor$1); - pop(contextFiberStackCursor); - pop(rootInstanceStackCursor); +function popHostContainer(fiber) { + pop(contextStackCursor$1, fiber); + pop(contextFiberStackCursor, fiber); + pop(rootInstanceStackCursor, fiber); } function pushHostContext(fiber) { requiredContext(rootInstanceStackCursor.current); @@ -3049,19 +3170,23 @@ function pushHostContext(fiber) { ? { isInAParentText: nextContext } : context; context !== nextContext && - (push(contextFiberStackCursor, fiber), - push(contextStackCursor$1, nextContext)); + (push(contextFiberStackCursor, fiber, fiber), + push(contextStackCursor$1, nextContext, fiber)); } function popHostContext(fiber) { contextFiberStackCursor.current === fiber && - (pop(contextStackCursor$1), pop(contextFiberStackCursor)); + (pop(contextStackCursor$1, fiber), pop(contextFiberStackCursor, fiber)); } var suspenseStackCursor = { current: 0 }; function findFirstSuspended(row) { for (var node = row; null !== node; ) { if (13 === node.tag) { var state = node.memoizedState; - if (null !== state && (null === state.dehydrated || shim() || shim())) + if ( + null !== state && + ((state = state.dehydrated), + null === state || shim$1(state) || shim$1(state)) + ) return node; } else if (19 === node.tag && void 0 !== node.memoizedProps.revealOrder) { if (0 !== (node.effectTag & 64)) return node; @@ -3080,16 +3205,24 @@ function findFirstSuspended(row) { } return null; } -function createDeprecatedResponderListener(responder, props) { +function createResponderListener(responder, props) { return { responder: responder, props: props }; } -var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher, +var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig, - renderExpirationTime = 0, + renderExpirationTime$1 = 0, currentlyRenderingFiber$1 = null, currentHook = null, + nextCurrentHook = null, + firstWorkInProgressHook = null, workInProgressHook = null, - didScheduleRenderPhaseUpdate = !1; + nextWorkInProgressHook = null, + remainingExpirationTime = 0, + componentUpdateQueue = null, + sideEffectTag = 0, + didScheduleRenderPhaseUpdate = !1, + renderPhaseUpdates = null, + numberOfReRenders = 0; function throwInvalidHookError() { throw Error( "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem." @@ -3098,7 +3231,7 @@ function throwInvalidHookError() { function areHookInputsEqual(nextDeps, prevDeps) { if (null === prevDeps) return !1; for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) - if (!objectIs(nextDeps[i], prevDeps[i])) return !1; + if (!is$1(nextDeps[i], prevDeps[i])) return !1; return !0; } function renderWithHooks( @@ -3106,85 +3239,92 @@ function renderWithHooks( workInProgress, Component, props, - secondArg, + refOrContext, nextRenderExpirationTime ) { - renderExpirationTime = nextRenderExpirationTime; + renderExpirationTime$1 = nextRenderExpirationTime; currentlyRenderingFiber$1 = workInProgress; - workInProgress.memoizedState = null; - workInProgress.updateQueue = null; - workInProgress.expirationTime = 0; - ReactCurrentDispatcher.current = - null === current || null === current.memoizedState - ? HooksDispatcherOnMount - : HooksDispatcherOnUpdate; - current = Component(props, secondArg); - if (workInProgress.expirationTime === renderExpirationTime) { - nextRenderExpirationTime = 0; - do { - workInProgress.expirationTime = 0; - if (!(25 > nextRenderExpirationTime)) - throw Error( - "Too many re-renders. React limits the number of renders to prevent an infinite loop." - ); - nextRenderExpirationTime += 1; - workInProgressHook = currentHook = null; - workInProgress.updateQueue = null; - ReactCurrentDispatcher.current = HooksDispatcherOnRerender; - current = Component(props, secondArg); - } while (workInProgress.expirationTime === renderExpirationTime); + nextCurrentHook = null !== current ? current.memoizedState : null; + ReactCurrentDispatcher$1.current = + null === nextCurrentHook ? HooksDispatcherOnMount : HooksDispatcherOnUpdate; + workInProgress = Component(props, refOrContext); + if (didScheduleRenderPhaseUpdate) { + do + (didScheduleRenderPhaseUpdate = !1), + (numberOfReRenders += 1), + (nextCurrentHook = null !== current ? current.memoizedState : null), + (nextWorkInProgressHook = firstWorkInProgressHook), + (componentUpdateQueue = workInProgressHook = currentHook = null), + (ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdate), + (workInProgress = Component(props, refOrContext)); + while (didScheduleRenderPhaseUpdate); + renderPhaseUpdates = null; + numberOfReRenders = 0; } - ReactCurrentDispatcher.current = ContextOnlyDispatcher; - workInProgress = null !== currentHook && null !== currentHook.next; - renderExpirationTime = 0; - workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; - didScheduleRenderPhaseUpdate = !1; - if (workInProgress) + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; + current = currentlyRenderingFiber$1; + current.memoizedState = firstWorkInProgressHook; + current.expirationTime = remainingExpirationTime; + current.updateQueue = componentUpdateQueue; + current.effectTag |= sideEffectTag; + current = null !== currentHook && null !== currentHook.next; + renderExpirationTime$1 = 0; + nextWorkInProgressHook = workInProgressHook = firstWorkInProgressHook = nextCurrentHook = currentHook = currentlyRenderingFiber$1 = null; + remainingExpirationTime = 0; + componentUpdateQueue = null; + sideEffectTag = 0; + if (current) throw Error( "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." ); - return current; + return workInProgress; +} +function resetHooks() { + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; + renderExpirationTime$1 = 0; + nextWorkInProgressHook = workInProgressHook = firstWorkInProgressHook = nextCurrentHook = currentHook = currentlyRenderingFiber$1 = null; + remainingExpirationTime = 0; + componentUpdateQueue = null; + sideEffectTag = 0; + didScheduleRenderPhaseUpdate = !1; + renderPhaseUpdates = null; + numberOfReRenders = 0; } function mountWorkInProgressHook() { var hook = { memoizedState: null, baseState: null, - baseQueue: null, queue: null, + baseUpdate: null, next: null }; null === workInProgressHook - ? (currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook) + ? (firstWorkInProgressHook = workInProgressHook = hook) : (workInProgressHook = workInProgressHook.next = hook); return workInProgressHook; } function updateWorkInProgressHook() { - if (null === currentHook) { - var nextCurrentHook = currentlyRenderingFiber$1.alternate; - nextCurrentHook = - null !== nextCurrentHook ? nextCurrentHook.memoizedState : null; - } else nextCurrentHook = currentHook.next; - var nextWorkInProgressHook = - null === workInProgressHook - ? currentlyRenderingFiber$1.memoizedState - : workInProgressHook.next; if (null !== nextWorkInProgressHook) (workInProgressHook = nextWorkInProgressHook), - (currentHook = nextCurrentHook); + (nextWorkInProgressHook = workInProgressHook.next), + (currentHook = nextCurrentHook), + (nextCurrentHook = null !== currentHook ? currentHook.next : null); else { if (null === nextCurrentHook) throw Error("Rendered more hooks than during the previous render."); currentHook = nextCurrentHook; - nextCurrentHook = { + var newHook = { memoizedState: currentHook.memoizedState, baseState: currentHook.baseState, - baseQueue: currentHook.baseQueue, queue: currentHook.queue, + baseUpdate: currentHook.baseUpdate, next: null }; - null === workInProgressHook - ? (currentlyRenderingFiber$1.memoizedState = workInProgressHook = nextCurrentHook) - : (workInProgressHook = workInProgressHook.next = nextCurrentHook); + workInProgressHook = + null === workInProgressHook + ? (firstWorkInProgressHook = newHook) + : (workInProgressHook.next = newHook); + nextCurrentHook = currentHook.next; } return workInProgressHook; } @@ -3199,100 +3339,74 @@ function updateReducer(reducer) { "Should have a queue. This is likely a bug in React. Please file an issue." ); queue.lastRenderedReducer = reducer; - var current = currentHook, - baseQueue = current.baseQueue, - pendingQueue = queue.pending; - if (null !== pendingQueue) { - if (null !== baseQueue) { - var baseFirst = baseQueue.next; - baseQueue.next = pendingQueue.next; - pendingQueue.next = baseFirst; + if (0 < numberOfReRenders) { + var _dispatch = queue.dispatch; + if (null !== renderPhaseUpdates) { + var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue); + if (void 0 !== firstRenderPhaseUpdate) { + renderPhaseUpdates.delete(queue); + var newState = hook.memoizedState; + do + (newState = reducer(newState, firstRenderPhaseUpdate.action)), + (firstRenderPhaseUpdate = firstRenderPhaseUpdate.next); + while (null !== firstRenderPhaseUpdate); + is$1(newState, hook.memoizedState) || (didReceiveUpdate = !0); + hook.memoizedState = newState; + hook.baseUpdate === queue.last && (hook.baseState = newState); + queue.lastRenderedState = newState; + return [newState, _dispatch]; + } } - current.baseQueue = baseQueue = pendingQueue; - queue.pending = null; + return [hook.memoizedState, _dispatch]; } - if (null !== baseQueue) { - baseQueue = baseQueue.next; - current = current.baseState; - var newBaseQueueLast = (baseFirst = pendingQueue = null), - update = baseQueue; + _dispatch = queue.last; + var baseUpdate = hook.baseUpdate; + newState = hook.baseState; + null !== baseUpdate + ? (null !== _dispatch && (_dispatch.next = null), + (_dispatch = baseUpdate.next)) + : (_dispatch = null !== _dispatch ? _dispatch.next : null); + if (null !== _dispatch) { + var newBaseUpdate = (firstRenderPhaseUpdate = null), + _update = _dispatch, + didSkip = !1; do { - var updateExpirationTime = update.expirationTime; - if (updateExpirationTime < renderExpirationTime) { - var clone = { - expirationTime: update.expirationTime, - suspenseConfig: update.suspenseConfig, - action: update.action, - eagerReducer: update.eagerReducer, - eagerState: update.eagerState, - next: null - }; - null === newBaseQueueLast - ? ((baseFirst = newBaseQueueLast = clone), (pendingQueue = current)) - : (newBaseQueueLast = newBaseQueueLast.next = clone); - updateExpirationTime > currentlyRenderingFiber$1.expirationTime && - ((currentlyRenderingFiber$1.expirationTime = updateExpirationTime), - markUnprocessedUpdateTime(updateExpirationTime)); - } else - null !== newBaseQueueLast && - (newBaseQueueLast = newBaseQueueLast.next = { - expirationTime: 1073741823, - suspenseConfig: update.suspenseConfig, - action: update.action, - eagerReducer: update.eagerReducer, - eagerState: update.eagerState, - next: null - }), - markRenderEventTimeAndConfig( + var updateExpirationTime = _update.expirationTime; + updateExpirationTime < renderExpirationTime$1 + ? (didSkip || + ((didSkip = !0), + (newBaseUpdate = baseUpdate), + (firstRenderPhaseUpdate = newState)), + updateExpirationTime > remainingExpirationTime && + ((remainingExpirationTime = updateExpirationTime), + markUnprocessedUpdateTime(remainingExpirationTime))) + : (markRenderEventTimeAndConfig( updateExpirationTime, - update.suspenseConfig + _update.suspenseConfig ), - (current = - update.eagerReducer === reducer - ? update.eagerState - : reducer(current, update.action)); - update = update.next; - } while (null !== update && update !== baseQueue); - null === newBaseQueueLast - ? (pendingQueue = current) - : (newBaseQueueLast.next = baseFirst); - objectIs(current, hook.memoizedState) || (didReceiveUpdate = !0); - hook.memoizedState = current; - hook.baseState = pendingQueue; - hook.baseQueue = newBaseQueueLast; - queue.lastRenderedState = current; - } - return [hook.memoizedState, queue.dispatch]; -} -function rerenderReducer(reducer) { - var hook = updateWorkInProgressHook(), - queue = hook.queue; - if (null === queue) - throw Error( - "Should have a queue. This is likely a bug in React. Please file an issue." - ); - queue.lastRenderedReducer = reducer; - var dispatch = queue.dispatch, - lastRenderPhaseUpdate = queue.pending, - newState = hook.memoizedState; - if (null !== lastRenderPhaseUpdate) { - queue.pending = null; - var update = (lastRenderPhaseUpdate = lastRenderPhaseUpdate.next); - do (newState = reducer(newState, update.action)), (update = update.next); - while (update !== lastRenderPhaseUpdate); - objectIs(newState, hook.memoizedState) || (didReceiveUpdate = !0); + (newState = + _update.eagerReducer === reducer + ? _update.eagerState + : reducer(newState, _update.action))); + baseUpdate = _update; + _update = _update.next; + } while (null !== _update && _update !== _dispatch); + didSkip || + ((newBaseUpdate = baseUpdate), (firstRenderPhaseUpdate = newState)); + is$1(newState, hook.memoizedState) || (didReceiveUpdate = !0); hook.memoizedState = newState; - null === hook.baseQueue && (hook.baseState = newState); + hook.baseUpdate = newBaseUpdate; + hook.baseState = firstRenderPhaseUpdate; queue.lastRenderedState = newState; } - return [newState, dispatch]; + return [hook.memoizedState, queue.dispatch]; } function mountState(initialState) { var hook = mountWorkInProgressHook(); "function" === typeof initialState && (initialState = initialState()); hook.memoizedState = hook.baseState = initialState; initialState = hook.queue = { - pending: null, + last: null, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState @@ -3304,30 +3418,28 @@ function mountState(initialState) { ); return [hook.memoizedState, initialState]; } +function updateState(initialState) { + return updateReducer(basicStateReducer, initialState); +} function pushEffect(tag, create, destroy, deps) { tag = { tag: tag, create: create, destroy: destroy, deps: deps, next: null }; - create = currentlyRenderingFiber$1.updateQueue; - null === create - ? ((create = { lastEffect: null }), - (currentlyRenderingFiber$1.updateQueue = create), - (create.lastEffect = tag.next = tag)) - : ((destroy = create.lastEffect), - null === destroy - ? (create.lastEffect = tag.next = tag) - : ((deps = destroy.next), - (destroy.next = tag), - (tag.next = deps), - (create.lastEffect = tag))); + null === componentUpdateQueue + ? ((componentUpdateQueue = { lastEffect: null }), + (componentUpdateQueue.lastEffect = tag.next = tag)) + : ((create = componentUpdateQueue.lastEffect), + null === create + ? (componentUpdateQueue.lastEffect = tag.next = tag) + : ((destroy = create.next), + (create.next = tag), + (tag.next = destroy), + (componentUpdateQueue.lastEffect = tag))); return tag; } -function updateRef() { - return updateWorkInProgressHook().memoizedState; -} function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var hook = mountWorkInProgressHook(); - currentlyRenderingFiber$1.effectTag |= fiberEffectTag; + sideEffectTag |= fiberEffectTag; hook.memoizedState = pushEffect( - 1 | hookEffectTag, + hookEffectTag, create, void 0, void 0 === deps ? null : deps @@ -3341,21 +3453,18 @@ function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var prevEffect = currentHook.memoizedState; destroy = prevEffect.destroy; if (null !== deps && areHookInputsEqual(deps, prevEffect.deps)) { - pushEffect(hookEffectTag, create, destroy, deps); + pushEffect(0, create, destroy, deps); return; } } - currentlyRenderingFiber$1.effectTag |= fiberEffectTag; - hook.memoizedState = pushEffect(1 | hookEffectTag, create, destroy, deps); + sideEffectTag |= fiberEffectTag; + hook.memoizedState = pushEffect(hookEffectTag, create, destroy, deps); } function mountEffect(create, deps) { - return mountEffectImpl(516, 4, create, deps); + return mountEffectImpl(516, 192, create, deps); } function updateEffect(create, deps) { - return updateEffectImpl(516, 4, create, deps); -} -function updateLayoutEffect(create, deps) { - return updateEffectImpl(4, 2, create, deps); + return updateEffectImpl(516, 192, create, deps); } function imperativeHandleEffect(create, ref) { if ("function" === typeof ref) @@ -3375,15 +3484,6 @@ function imperativeHandleEffect(create, ref) { } ); } -function updateImperativeHandle(ref, create, deps) { - deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; - return updateEffectImpl( - 4, - 2, - imperativeHandleEffect.bind(null, create, ref), - deps - ); -} function mountDebugValue() {} function mountCallback(callback, deps) { mountWorkInProgressHook().memoizedState = [ @@ -3405,79 +3505,72 @@ function updateCallback(callback, deps) { hook.memoizedState = [callback, deps]; return callback; } -function updateMemo(nextCreate, deps) { - var hook = updateWorkInProgressHook(); - deps = void 0 === deps ? null : deps; - var prevState = hook.memoizedState; - if ( - null !== prevState && - null !== deps && - areHookInputsEqual(deps, prevState[1]) - ) - return prevState[0]; - nextCreate = nextCreate(); - hook.memoizedState = [nextCreate, deps]; - return nextCreate; -} -function startTransition(setPending, config, callback) { - var priorityLevel = getCurrentPriorityLevel(); - runWithPriority(98 > priorityLevel ? 98 : priorityLevel, function() { - setPending(!0); - }); - runWithPriority(97 < priorityLevel ? 97 : priorityLevel, function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = void 0 === config ? null : config; - try { - setPending(!1), callback(); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); -} function dispatchAction(fiber, queue, action) { - var currentTime = requestCurrentTimeForUpdate(), - suspenseConfig = ReactCurrentBatchConfig.suspense; - currentTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig); - suspenseConfig = { - expirationTime: currentTime, - suspenseConfig: suspenseConfig, - action: action, - eagerReducer: null, - eagerState: null, - next: null - }; - var pending = queue.pending; - null === pending - ? (suspenseConfig.next = suspenseConfig) - : ((suspenseConfig.next = pending.next), (pending.next = suspenseConfig)); - queue.pending = suspenseConfig; - pending = fiber.alternate; + if (!(25 > numberOfReRenders)) + throw Error( + "Too many re-renders. React limits the number of renders to prevent an infinite loop." + ); + var alternate = fiber.alternate; if ( fiber === currentlyRenderingFiber$1 || - (null !== pending && pending === currentlyRenderingFiber$1) + (null !== alternate && alternate === currentlyRenderingFiber$1) ) - (didScheduleRenderPhaseUpdate = !0), - (suspenseConfig.expirationTime = renderExpirationTime), - (currentlyRenderingFiber$1.expirationTime = renderExpirationTime); + if ( + ((didScheduleRenderPhaseUpdate = !0), + (fiber = { + expirationTime: renderExpirationTime$1, + suspenseConfig: null, + action: action, + eagerReducer: null, + eagerState: null, + next: null + }), + null === renderPhaseUpdates && (renderPhaseUpdates = new Map()), + (action = renderPhaseUpdates.get(queue)), + void 0 === action) + ) + renderPhaseUpdates.set(queue, fiber); + else { + for (queue = action; null !== queue.next; ) queue = queue.next; + queue.next = fiber; + } else { + var currentTime = requestCurrentTimeForUpdate(), + suspenseConfig = ReactCurrentBatchConfig.suspense; + currentTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig); + suspenseConfig = { + expirationTime: currentTime, + suspenseConfig: suspenseConfig, + action: action, + eagerReducer: null, + eagerState: null, + next: null + }; + var last = queue.last; + if (null === last) suspenseConfig.next = suspenseConfig; + else { + var first = last.next; + null !== first && (suspenseConfig.next = first); + last.next = suspenseConfig; + } + queue.last = suspenseConfig; if ( 0 === fiber.expirationTime && - (null === pending || 0 === pending.expirationTime) && - ((pending = queue.lastRenderedReducer), null !== pending) + (null === alternate || 0 === alternate.expirationTime) && + ((alternate = queue.lastRenderedReducer), null !== alternate) ) try { var currentState = queue.lastRenderedState, - eagerState = pending(currentState, action); - suspenseConfig.eagerReducer = pending; + eagerState = alternate(currentState, action); + suspenseConfig.eagerReducer = alternate; suspenseConfig.eagerState = eagerState; - if (objectIs(eagerState, currentState)) return; + if (is$1(eagerState, currentState)) return; } catch (error) { } finally { } - scheduleWork(fiber, currentTime); + scheduleUpdateOnFiber(fiber, currentTime); } } -function updateEventListener() {} var ContextOnlyDispatcher = { readContext: readContext, useCallback: throwInvalidHookError, @@ -3492,8 +3585,7 @@ var ContextOnlyDispatcher = { useDebugValue: throwInvalidHookError, useResponder: throwInvalidHookError, useDeferredValue: throwInvalidHookError, - useTransition: throwInvalidHookError, - useEvent: throwInvalidHookError + useTransition: throwInvalidHookError }, HooksDispatcherOnMount = { readContext: readContext, @@ -3504,13 +3596,13 @@ var ContextOnlyDispatcher = { deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; return mountEffectImpl( 4, - 2, + 36, imperativeHandleEffect.bind(null, create, ref), deps ); }, useLayoutEffect: function(create, deps) { - return mountEffectImpl(4, 2, create, deps); + return mountEffectImpl(4, 36, create, deps); }, useMemo: function(nextCreate, deps) { var hook = mountWorkInProgressHook(); @@ -3524,7 +3616,7 @@ var ContextOnlyDispatcher = { initialArg = void 0 !== init ? init(initialArg) : initialArg; hook.memoizedState = hook.baseState = initialArg; reducer = hook.queue = { - pending: null, + last: null, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialArg @@ -3543,21 +3635,23 @@ var ContextOnlyDispatcher = { }, useState: mountState, useDebugValue: mountDebugValue, - useResponder: createDeprecatedResponderListener, + useResponder: createResponderListener, useDeferredValue: function(value, config) { var _mountState = mountState(value), prevValue = _mountState[0], setValue = _mountState[1]; mountEffect( function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - void 0 === config ? null : config; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } + Scheduler.unstable_next(function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }); }, [value, config] ); @@ -3565,124 +3659,177 @@ var ContextOnlyDispatcher = { }, useTransition: function(config) { var _mountState2 = mountState(!1), - isPending = _mountState2[0]; - _mountState2 = _mountState2[1]; + isPending = _mountState2[0], + setPending = _mountState2[1]; return [ - mountCallback(startTransition.bind(null, _mountState2, config), [ - _mountState2, - config - ]), + mountCallback( + function(callback) { + setPending(!0); + Scheduler.unstable_next(function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setPending(!1), callback(); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }); + }, + [config, isPending] + ), isPending ]; - }, - useEvent: function() {} + } }, HooksDispatcherOnUpdate = { readContext: readContext, useCallback: updateCallback, useContext: readContext, useEffect: updateEffect, - useImperativeHandle: updateImperativeHandle, - useLayoutEffect: updateLayoutEffect, - useMemo: updateMemo, + useImperativeHandle: function(ref, create, deps) { + deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; + return updateEffectImpl( + 4, + 36, + imperativeHandleEffect.bind(null, create, ref), + deps + ); + }, + useLayoutEffect: function(create, deps) { + return updateEffectImpl(4, 36, create, deps); + }, + useMemo: function(nextCreate, deps) { + var hook = updateWorkInProgressHook(); + deps = void 0 === deps ? null : deps; + var prevState = hook.memoizedState; + if ( + null !== prevState && + null !== deps && + areHookInputsEqual(deps, prevState[1]) + ) + return prevState[0]; + nextCreate = nextCreate(); + hook.memoizedState = [nextCreate, deps]; + return nextCreate; + }, useReducer: updateReducer, - useRef: updateRef, - useState: function() { - return updateReducer(basicStateReducer); + useRef: function() { + return updateWorkInProgressHook().memoizedState; }, + useState: updateState, useDebugValue: mountDebugValue, - useResponder: createDeprecatedResponderListener, + useResponder: createResponderListener, useDeferredValue: function(value, config) { - var _updateState = updateReducer(basicStateReducer), + var _updateState = updateState(value), prevValue = _updateState[0], setValue = _updateState[1]; updateEffect( function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - void 0 === config ? null : config; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } + Scheduler.unstable_next(function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }); }, [value, config] ); return prevValue; }, useTransition: function(config) { - var _updateState2 = updateReducer(basicStateReducer), - isPending = _updateState2[0]; - _updateState2 = _updateState2[1]; + var _updateState2 = updateState(!1), + isPending = _updateState2[0], + setPending = _updateState2[1]; return [ - updateCallback(startTransition.bind(null, _updateState2, config), [ - _updateState2, - config - ]), + updateCallback( + function(callback) { + setPending(!0); + Scheduler.unstable_next(function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setPending(!1), callback(); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }); + }, + [config, isPending] + ), isPending ]; - }, - useEvent: updateEventListener + } }, - HooksDispatcherOnRerender = { - readContext: readContext, - useCallback: updateCallback, - useContext: readContext, - useEffect: updateEffect, - useImperativeHandle: updateImperativeHandle, - useLayoutEffect: updateLayoutEffect, - useMemo: updateMemo, - useReducer: rerenderReducer, - useRef: updateRef, - useState: function() { - return rerenderReducer(basicStateReducer); - }, - useDebugValue: mountDebugValue, - useResponder: createDeprecatedResponderListener, - useDeferredValue: function(value, config) { - var _rerenderState = rerenderReducer(basicStateReducer), - prevValue = _rerenderState[0], - setValue = _rerenderState[1]; - updateEffect( - function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - void 0 === config ? null : config; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }, - [value, config] + hydrationParentFiber = null, + nextHydratableInstance = null, + isHydrating = !1; +function tryHydrate(fiber, nextInstance) { + switch (fiber.tag) { + case 5: + return ( + (nextInstance = shim$1(nextInstance, fiber.type, fiber.pendingProps)), + null !== nextInstance ? ((fiber.stateNode = nextInstance), !0) : !1 ); - return prevValue; - }, - useTransition: function(config) { - var _rerenderState2 = rerenderReducer(basicStateReducer), - isPending = _rerenderState2[0]; - _rerenderState2 = _rerenderState2[1]; - return [ - updateCallback(startTransition.bind(null, _rerenderState2, config), [ - _rerenderState2, - config - ]), - isPending - ]; - }, - useEvent: updateEventListener - }, - ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner, + case 6: + return ( + (nextInstance = shim$1(nextInstance, fiber.pendingProps)), + null !== nextInstance ? ((fiber.stateNode = nextInstance), !0) : !1 + ); + case 13: + return !1; + default: + return !1; + } +} +function tryToClaimNextHydratableInstance(fiber$jscomp$0) { + if (isHydrating) { + var nextInstance = nextHydratableInstance; + if (nextInstance) { + var firstAttemptedInstance = nextInstance; + if (!tryHydrate(fiber$jscomp$0, nextInstance)) { + nextInstance = shim$1(firstAttemptedInstance); + if (!nextInstance || !tryHydrate(fiber$jscomp$0, nextInstance)) { + fiber$jscomp$0.effectTag = (fiber$jscomp$0.effectTag & -1025) | 2; + isHydrating = !1; + hydrationParentFiber = fiber$jscomp$0; + return; + } + var returnFiber = hydrationParentFiber, + fiber = createFiber(5, null, null, 0); + fiber.elementType = "DELETED"; + fiber.type = "DELETED"; + fiber.stateNode = firstAttemptedInstance; + fiber.return = returnFiber; + fiber.effectTag = 8; + null !== returnFiber.lastEffect + ? ((returnFiber.lastEffect.nextEffect = fiber), + (returnFiber.lastEffect = fiber)) + : (returnFiber.firstEffect = returnFiber.lastEffect = fiber); + } + hydrationParentFiber = fiber$jscomp$0; + nextHydratableInstance = shim$1(nextInstance); + } else + (fiber$jscomp$0.effectTag = (fiber$jscomp$0.effectTag & -1025) | 2), + (isHydrating = !1), + (hydrationParentFiber = fiber$jscomp$0); + } +} +var ReactCurrentOwner$3 = ReactSharedInternals.ReactCurrentOwner, didReceiveUpdate = !1; function reconcileChildren( - current, + current$$1, workInProgress, nextChildren, renderExpirationTime ) { workInProgress.child = - null === current + null === current$$1 ? mountChildFibers( workInProgress, null, @@ -3691,13 +3838,13 @@ function reconcileChildren( ) : reconcileChildFibers( workInProgress, - current.child, + current$$1.child, nextChildren, renderExpirationTime ); } function updateForwardRef( - current, + current$$1, workInProgress, Component, nextProps, @@ -3707,38 +3854,43 @@ function updateForwardRef( var ref = workInProgress.ref; prepareToReadContext(workInProgress, renderExpirationTime); nextProps = renderWithHooks( - current, + current$$1, workInProgress, Component, nextProps, ref, renderExpirationTime ); - if (null !== current && !didReceiveUpdate) + if (null !== current$$1 && !didReceiveUpdate) return ( - (workInProgress.updateQueue = current.updateQueue), + (workInProgress.updateQueue = current$$1.updateQueue), (workInProgress.effectTag &= -517), - current.expirationTime <= renderExpirationTime && - (current.expirationTime = 0), + current$$1.expirationTime <= renderExpirationTime && + (current$$1.expirationTime = 0), bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ) ); workInProgress.effectTag |= 1; - reconcileChildren(current, workInProgress, nextProps, renderExpirationTime); + reconcileChildren( + current$$1, + workInProgress, + nextProps, + renderExpirationTime + ); return workInProgress.child; } function updateMemoComponent( - current, + current$$1, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime ) { - if (null === current) { + if (null === current$$1) { var type = Component.type; if ( "function" === typeof type && @@ -3751,7 +3903,7 @@ function updateMemoComponent( (workInProgress.tag = 15), (workInProgress.type = type), updateSimpleMemoComponent( - current, + current$$1, workInProgress, type, nextProps, @@ -3759,7 +3911,7 @@ function updateMemoComponent( renderExpirationTime ) ); - current = createFiberFromTypeAndProps( + current$$1 = createFiberFromTypeAndProps( Component.type, null, nextProps, @@ -3767,66 +3919,65 @@ function updateMemoComponent( workInProgress.mode, renderExpirationTime ); - current.ref = workInProgress.ref; - current.return = workInProgress; - return (workInProgress.child = current); + current$$1.ref = workInProgress.ref; + current$$1.return = workInProgress; + return (workInProgress.child = current$$1); } - type = current.child; + type = current$$1.child; if ( updateExpirationTime < renderExpirationTime && ((updateExpirationTime = type.memoizedProps), (Component = Component.compare), (Component = null !== Component ? Component : shallowEqual), Component(updateExpirationTime, nextProps) && - current.ref === workInProgress.ref) + current$$1.ref === workInProgress.ref) ) return bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ); workInProgress.effectTag |= 1; - current = createWorkInProgress(type, nextProps); - current.ref = workInProgress.ref; - current.return = workInProgress; - return (workInProgress.child = current); + current$$1 = createWorkInProgress(type, nextProps, renderExpirationTime); + current$$1.ref = workInProgress.ref; + current$$1.return = workInProgress; + return (workInProgress.child = current$$1); } function updateSimpleMemoComponent( - current, + current$$1, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime ) { - return null !== current && - shallowEqual(current.memoizedProps, nextProps) && - current.ref === workInProgress.ref && + return null !== current$$1 && + shallowEqual(current$$1.memoizedProps, nextProps) && + current$$1.ref === workInProgress.ref && ((didReceiveUpdate = !1), updateExpirationTime < renderExpirationTime) - ? ((workInProgress.expirationTime = current.expirationTime), - bailoutOnAlreadyFinishedWork( - current, + ? bailoutOnAlreadyFinishedWork( + current$$1, workInProgress, renderExpirationTime - )) + ) : updateFunctionComponent( - current, + current$$1, workInProgress, Component, nextProps, renderExpirationTime ); } -function markRef(current, workInProgress) { +function markRef(current$$1, workInProgress) { var ref = workInProgress.ref; if ( - (null === current && null !== ref) || - (null !== current && current.ref !== ref) + (null === current$$1 && null !== ref) || + (null !== current$$1 && current$$1.ref !== ref) ) workInProgress.effectTag |= 128; } function updateFunctionComponent( - current, + current$$1, workInProgress, Component, nextProps, @@ -3838,31 +3989,36 @@ function updateFunctionComponent( context = getMaskedContext(workInProgress, context); prepareToReadContext(workInProgress, renderExpirationTime); Component = renderWithHooks( - current, + current$$1, workInProgress, Component, nextProps, context, renderExpirationTime ); - if (null !== current && !didReceiveUpdate) + if (null !== current$$1 && !didReceiveUpdate) return ( - (workInProgress.updateQueue = current.updateQueue), + (workInProgress.updateQueue = current$$1.updateQueue), (workInProgress.effectTag &= -517), - current.expirationTime <= renderExpirationTime && - (current.expirationTime = 0), + current$$1.expirationTime <= renderExpirationTime && + (current$$1.expirationTime = 0), bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ) ); workInProgress.effectTag |= 1; - reconcileChildren(current, workInProgress, Component, renderExpirationTime); + reconcileChildren( + current$$1, + workInProgress, + Component, + renderExpirationTime + ); return workInProgress.child; } function updateClassComponent( - current, + current$$1, workInProgress, Component, nextProps, @@ -3874,11 +4030,16 @@ function updateClassComponent( } else hasContext = !1; prepareToReadContext(workInProgress, renderExpirationTime); if (null === workInProgress.stateNode) - null !== current && - ((current.alternate = null), + null !== current$$1 && + ((current$$1.alternate = null), (workInProgress.alternate = null), (workInProgress.effectTag |= 2)), - constructClassInstance(workInProgress, Component, nextProps), + constructClassInstance( + workInProgress, + Component, + nextProps, + renderExpirationTime + ), mountClassInstance( workInProgress, Component, @@ -3886,7 +4047,7 @@ function updateClassComponent( renderExpirationTime ), (nextProps = !0); - else if (null === current) { + else if (null === current$$1) { var instance = workInProgress.stateNode, oldProps = workInProgress.memoizedProps; instance.props = oldProps; @@ -3914,14 +4075,17 @@ function updateClassComponent( )); hasForceUpdate = !1; var oldState = workInProgress.memoizedState; - instance.state = oldState; - processUpdateQueue( - workInProgress, - nextProps, - instance, - renderExpirationTime - ); - oldContext = workInProgress.memoizedState; + oldContext = instance.state = oldState; + var updateQueue = workInProgress.updateQueue; + null !== updateQueue && + (processUpdateQueue( + workInProgress, + updateQueue, + nextProps, + instance, + renderExpirationTime + ), + (oldContext = workInProgress.memoizedState)); oldProps !== nextProps || oldState !== oldContext || didPerformWorkStackCursor.current || @@ -3967,7 +4131,6 @@ function updateClassComponent( (nextProps = !1)); } else (instance = workInProgress.stateNode), - cloneUpdateQueue(current, workInProgress), (oldProps = workInProgress.memoizedProps), (instance.props = workInProgress.type === workInProgress.elementType @@ -3996,14 +4159,17 @@ function updateClassComponent( )), (hasForceUpdate = !1), (oldContext = workInProgress.memoizedState), - (instance.state = oldContext), - processUpdateQueue( - workInProgress, - nextProps, - instance, - renderExpirationTime - ), - (oldState = workInProgress.memoizedState), + (oldState = instance.state = oldContext), + (updateQueue = workInProgress.updateQueue), + null !== updateQueue && + (processUpdateQueue( + workInProgress, + updateQueue, + nextProps, + instance, + renderExpirationTime + ), + (oldState = workInProgress.memoizedState)), oldProps !== nextProps || oldContext !== oldState || didPerformWorkStackCursor.current || @@ -4047,12 +4213,12 @@ function updateClassComponent( "function" === typeof instance.getSnapshotBeforeUpdate && (workInProgress.effectTag |= 256)) : ("function" !== typeof instance.componentDidUpdate || - (oldProps === current.memoizedProps && - oldContext === current.memoizedState) || + (oldProps === current$$1.memoizedProps && + oldContext === current$$1.memoizedState) || (workInProgress.effectTag |= 4), "function" !== typeof instance.getSnapshotBeforeUpdate || - (oldProps === current.memoizedProps && - oldContext === current.memoizedState) || + (oldProps === current$$1.memoizedProps && + oldContext === current$$1.memoizedState) || (workInProgress.effectTag |= 256), (workInProgress.memoizedProps = nextProps), (workInProgress.memoizedState = oldState)), @@ -4061,16 +4227,16 @@ function updateClassComponent( (instance.context = contextType), (nextProps = getDerivedStateFromProps)) : ("function" !== typeof instance.componentDidUpdate || - (oldProps === current.memoizedProps && - oldContext === current.memoizedState) || + (oldProps === current$$1.memoizedProps && + oldContext === current$$1.memoizedState) || (workInProgress.effectTag |= 4), "function" !== typeof instance.getSnapshotBeforeUpdate || - (oldProps === current.memoizedProps && - oldContext === current.memoizedState) || + (oldProps === current$$1.memoizedProps && + oldContext === current$$1.memoizedState) || (workInProgress.effectTag |= 256), (nextProps = !1)); return finishClassComponent( - current, + current$$1, workInProgress, Component, nextProps, @@ -4079,35 +4245,35 @@ function updateClassComponent( ); } function finishClassComponent( - current, + current$$1, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime ) { - markRef(current, workInProgress); + markRef(current$$1, workInProgress); var didCaptureError = 0 !== (workInProgress.effectTag & 64); if (!shouldUpdate && !didCaptureError) return ( hasContext && invalidateContextProvider(workInProgress, Component, !1), bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ) ); shouldUpdate = workInProgress.stateNode; - ReactCurrentOwner$1.current = workInProgress; + ReactCurrentOwner$3.current = workInProgress; var nextChildren = didCaptureError && "function" !== typeof Component.getDerivedStateFromError ? null : shouldUpdate.render(); workInProgress.effectTag |= 1; - null !== current && didCaptureError + null !== current$$1 && didCaptureError ? ((workInProgress.child = reconcileChildFibers( workInProgress, - current.child, + current$$1.child, null, renderExpirationTime )), @@ -4118,7 +4284,7 @@ function finishClassComponent( renderExpirationTime ))) : reconcileChildren( - current, + current$$1, workInProgress, nextChildren, renderExpirationTime @@ -4141,7 +4307,7 @@ function pushHostRootContext(workInProgress) { } var SUSPENDED_MARKER = { dehydrated: null, retryTime: 0 }; function updateSuspenseComponent( - current, + current$$1, workInProgress, renderExpirationTime ) { @@ -4153,30 +4319,32 @@ function updateSuspenseComponent( (JSCompiler_temp = 0 !== (workInProgress.effectTag & 64)) || (JSCompiler_temp = 0 !== (suspenseContext & 2) && - (null === current || null !== current.memoizedState)); + (null === current$$1 || null !== current$$1.memoizedState)); JSCompiler_temp ? ((nextDidTimeout = !0), (workInProgress.effectTag &= -65)) - : (null !== current && null === current.memoizedState) || + : (null !== current$$1 && null === current$$1.memoizedState) || void 0 === nextProps.fallback || !0 === nextProps.unstable_avoidThisFallback || (suspenseContext |= 1); - push(suspenseStackCursor, suspenseContext & 1); - if (null === current) { + push(suspenseStackCursor, suspenseContext & 1, workInProgress); + if (null === current$$1) { + void 0 !== nextProps.fallback && + tryToClaimNextHydratableInstance(workInProgress); if (nextDidTimeout) { nextDidTimeout = nextProps.fallback; nextProps = createFiberFromFragment(null, mode, 0, null); nextProps.return = workInProgress; if (0 === (workInProgress.mode & 2)) for ( - current = + current$$1 = null !== workInProgress.memoizedState ? workInProgress.child.child : workInProgress.child, - nextProps.child = current; - null !== current; + nextProps.child = current$$1; + null !== current$$1; ) - (current.return = nextProps), (current = current.sibling); + (current$$1.return = nextProps), (current$$1 = current$$1.sibling); renderExpirationTime = createFiberFromFragment( nextDidTimeout, mode, @@ -4198,14 +4366,15 @@ function updateSuspenseComponent( renderExpirationTime )); } - if (null !== current.memoizedState) { - current = current.child; - mode = current.sibling; + if (null !== current$$1.memoizedState) { + current$$1 = current$$1.child; + mode = current$$1.sibling; if (nextDidTimeout) { nextProps = nextProps.fallback; renderExpirationTime = createWorkInProgress( - current, - current.pendingProps + current$$1, + current$$1.pendingProps, + 0 ); renderExpirationTime.return = workInProgress; if ( @@ -4214,7 +4383,7 @@ function updateSuspenseComponent( null !== workInProgress.memoizedState ? workInProgress.child.child : workInProgress.child), - nextDidTimeout !== current.child) + nextDidTimeout !== current$$1.child) ) for ( renderExpirationTime.child = nextDidTimeout; @@ -4223,7 +4392,7 @@ function updateSuspenseComponent( ) (nextDidTimeout.return = renderExpirationTime), (nextDidTimeout = nextDidTimeout.sibling); - mode = createWorkInProgress(mode, nextProps); + mode = createWorkInProgress(mode, nextProps, mode.expirationTime); mode.return = workInProgress; renderExpirationTime.sibling = mode; renderExpirationTime.childExpirationTime = 0; @@ -4233,31 +4402,31 @@ function updateSuspenseComponent( } renderExpirationTime = reconcileChildFibers( workInProgress, - current.child, + current$$1.child, nextProps.children, renderExpirationTime ); workInProgress.memoizedState = null; return (workInProgress.child = renderExpirationTime); } - current = current.child; + current$$1 = current$$1.child; if (nextDidTimeout) { nextDidTimeout = nextProps.fallback; nextProps = createFiberFromFragment(null, mode, 0, null); nextProps.return = workInProgress; - nextProps.child = current; - null !== current && (current.return = nextProps); + nextProps.child = current$$1; + null !== current$$1 && (current$$1.return = nextProps); if (0 === (workInProgress.mode & 2)) for ( - current = + current$$1 = null !== workInProgress.memoizedState ? workInProgress.child.child : workInProgress.child, - nextProps.child = current; - null !== current; + nextProps.child = current$$1; + null !== current$$1; ) - (current.return = nextProps), (current = current.sibling); + (current$$1.return = nextProps), (current$$1 = current$$1.sibling); renderExpirationTime = createFiberFromFragment( nextDidTimeout, mode, @@ -4275,7 +4444,7 @@ function updateSuspenseComponent( workInProgress.memoizedState = null; return (workInProgress.child = reconcileChildFibers( workInProgress, - current, + current$$1, nextProps.children, renderExpirationTime )); @@ -4302,7 +4471,6 @@ function initSuspenseListRenderState( ? (workInProgress.memoizedState = { isBackwards: isBackwards, rendering: null, - renderingStartTime: 0, last: lastContentRow, tail: tail, tailExpiration: 0, @@ -4311,7 +4479,6 @@ function initSuspenseListRenderState( }) : ((renderState.isBackwards = isBackwards), (renderState.rendering = null), - (renderState.renderingStartTime = 0), (renderState.last = lastContentRow), (renderState.tail = tail), (renderState.tailExpiration = 0), @@ -4319,7 +4486,7 @@ function initSuspenseListRenderState( (renderState.lastEffect = lastEffectBeforeRendering)); } function updateSuspenseListComponent( - current, + current$$1, workInProgress, renderExpirationTime ) { @@ -4327,7 +4494,7 @@ function updateSuspenseListComponent( revealOrder = nextProps.revealOrder, tailMode = nextProps.tail; reconcileChildren( - current, + current$$1, workInProgress, nextProps.children, renderExpirationTime @@ -4336,39 +4503,42 @@ function updateSuspenseListComponent( if (0 !== (nextProps & 2)) (nextProps = (nextProps & 1) | 2), (workInProgress.effectTag |= 64); else { - if (null !== current && 0 !== (current.effectTag & 64)) - a: for (current = workInProgress.child; null !== current; ) { - if (13 === current.tag) - null !== current.memoizedState && - scheduleWorkOnFiber(current, renderExpirationTime); - else if (19 === current.tag) - scheduleWorkOnFiber(current, renderExpirationTime); - else if (null !== current.child) { - current.child.return = current; - current = current.child; + if (null !== current$$1 && 0 !== (current$$1.effectTag & 64)) + a: for (current$$1 = workInProgress.child; null !== current$$1; ) { + if (13 === current$$1.tag) + null !== current$$1.memoizedState && + scheduleWorkOnFiber(current$$1, renderExpirationTime); + else if (19 === current$$1.tag) + scheduleWorkOnFiber(current$$1, renderExpirationTime); + else if (null !== current$$1.child) { + current$$1.child.return = current$$1; + current$$1 = current$$1.child; continue; } - if (current === workInProgress) break a; - for (; null === current.sibling; ) { - if (null === current.return || current.return === workInProgress) + if (current$$1 === workInProgress) break a; + for (; null === current$$1.sibling; ) { + if ( + null === current$$1.return || + current$$1.return === workInProgress + ) break a; - current = current.return; + current$$1 = current$$1.return; } - current.sibling.return = current.return; - current = current.sibling; + current$$1.sibling.return = current$$1.return; + current$$1 = current$$1.sibling; } nextProps &= 1; } - push(suspenseStackCursor, nextProps); + push(suspenseStackCursor, nextProps, workInProgress); if (0 === (workInProgress.mode & 2)) workInProgress.memoizedState = null; else switch (revealOrder) { case "forwards": renderExpirationTime = workInProgress.child; for (revealOrder = null; null !== renderExpirationTime; ) - (current = renderExpirationTime.alternate), - null !== current && - null === findFirstSuspended(current) && + (current$$1 = renderExpirationTime.alternate), + null !== current$$1 && + null === findFirstSuspended(current$$1) && (revealOrder = renderExpirationTime), (renderExpirationTime = renderExpirationTime.sibling); renderExpirationTime = revealOrder; @@ -4390,15 +4560,15 @@ function updateSuspenseListComponent( renderExpirationTime = null; revealOrder = workInProgress.child; for (workInProgress.child = null; null !== revealOrder; ) { - current = revealOrder.alternate; - if (null !== current && null === findFirstSuspended(current)) { + current$$1 = revealOrder.alternate; + if (null !== current$$1 && null === findFirstSuspended(current$$1)) { workInProgress.child = revealOrder; break; } - current = revealOrder.sibling; + current$$1 = revealOrder.sibling; revealOrder.sibling = renderExpirationTime; renderExpirationTime = revealOrder; - revealOrder = current; + revealOrder = current$$1; } initSuspenseListRenderState( workInProgress, @@ -4425,29 +4595,35 @@ function updateSuspenseListComponent( return workInProgress.child; } function bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ) { - null !== current && (workInProgress.dependencies = current.dependencies); + null !== current$$1 && + (workInProgress.dependencies = current$$1.dependencies); var updateExpirationTime = workInProgress.expirationTime; 0 !== updateExpirationTime && markUnprocessedUpdateTime(updateExpirationTime); if (workInProgress.childExpirationTime < renderExpirationTime) return null; - if (null !== current && workInProgress.child !== current.child) + if (null !== current$$1 && workInProgress.child !== current$$1.child) throw Error("Resuming work not yet implemented."); if (null !== workInProgress.child) { - current = workInProgress.child; - renderExpirationTime = createWorkInProgress(current, current.pendingProps); + current$$1 = workInProgress.child; + renderExpirationTime = createWorkInProgress( + current$$1, + current$$1.pendingProps, + current$$1.expirationTime + ); workInProgress.child = renderExpirationTime; for ( renderExpirationTime.return = workInProgress; - null !== current.sibling; + null !== current$$1.sibling; ) - (current = current.sibling), + (current$$1 = current$$1.sibling), (renderExpirationTime = renderExpirationTime.sibling = createWorkInProgress( - current, - current.pendingProps + current$$1, + current$$1.pendingProps, + current$$1.expirationTime )), (renderExpirationTime.return = workInProgress); renderExpirationTime.sibling = null; @@ -4509,323 +4685,18 @@ function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { : (_lastTailNode.sibling = null); } } -function completeWork(current, workInProgress, renderExpirationTime) { - var newProps = workInProgress.pendingProps; - switch (workInProgress.tag) { - case 2: - case 16: - case 15: - case 0: - case 11: - case 7: - case 8: - case 12: - case 9: - case 14: - return null; - case 1: - return isContextProvider(workInProgress.type) && popContext(), null; - case 3: - return ( - popHostContainer(), - pop(didPerformWorkStackCursor), - pop(contextStackCursor), - (current = workInProgress.stateNode), - current.pendingContext && - ((current.context = current.pendingContext), - (current.pendingContext = null)), - updateHostContainer(workInProgress), - null - ); - case 5: - popHostContext(workInProgress); - var rootContainerInstance = requiredContext( - rootInstanceStackCursor.current - ); - renderExpirationTime = workInProgress.type; - if (null !== current && null != workInProgress.stateNode) - updateHostComponent$1( - current, - workInProgress, - renderExpirationTime, - newProps, - rootContainerInstance - ), - current.ref !== workInProgress.ref && - (workInProgress.effectTag |= 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." - ); - return null; - } - requiredContext(contextStackCursor$1.current); - current = allocateTag(); - renderExpirationTime = getViewConfigForType(renderExpirationTime); - var updatePayload = diffProperties( - null, - emptyObject, - newProps, - renderExpirationTime.validAttributes - ); - ReactNativePrivateInterface.UIManager.createView( - current, - renderExpirationTime.uiViewClassName, - rootContainerInstance, - updatePayload - ); - rootContainerInstance = new ReactNativeFiberHostComponent( - current, - renderExpirationTime, - workInProgress - ); - instanceCache.set(current, workInProgress); - instanceProps.set(current, newProps); - appendAllChildren(rootContainerInstance, workInProgress, !1, !1); - workInProgress.stateNode = rootContainerInstance; - finalizeInitialChildren(rootContainerInstance) && - (workInProgress.effectTag |= 4); - null !== workInProgress.ref && (workInProgress.effectTag |= 128); - } - return null; - case 6: - if (current && null != workInProgress.stateNode) - updateHostText$1( - current, - workInProgress, - current.memoizedProps, - newProps - ); - else { - if ("string" !== typeof newProps && null === workInProgress.stateNode) - throw Error( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." - ); - current = requiredContext(rootInstanceStackCursor.current); - if (!requiredContext(contextStackCursor$1.current).isInAParentText) - throw Error( - "Text strings must be rendered within a component." - ); - rootContainerInstance = allocateTag(); - ReactNativePrivateInterface.UIManager.createView( - rootContainerInstance, - "RCTRawText", - current, - { text: newProps } - ); - instanceCache.set(rootContainerInstance, workInProgress); - workInProgress.stateNode = rootContainerInstance; - } - return null; - case 13: - pop(suspenseStackCursor); - newProps = workInProgress.memoizedState; - if (0 !== (workInProgress.effectTag & 64)) - return ( - (workInProgress.expirationTime = renderExpirationTime), workInProgress - ); - newProps = null !== newProps; - rootContainerInstance = !1; - null !== current && - ((renderExpirationTime = current.memoizedState), - (rootContainerInstance = null !== renderExpirationTime), - newProps || - null === renderExpirationTime || - ((renderExpirationTime = current.child.sibling), - null !== renderExpirationTime && - ((updatePayload = workInProgress.firstEffect), - null !== updatePayload - ? ((workInProgress.firstEffect = renderExpirationTime), - (renderExpirationTime.nextEffect = updatePayload)) - : ((workInProgress.firstEffect = workInProgress.lastEffect = renderExpirationTime), - (renderExpirationTime.nextEffect = null)), - (renderExpirationTime.effectTag = 8)))); - if (newProps && !rootContainerInstance && 0 !== (workInProgress.mode & 2)) - if ( - (null === current && - !0 !== workInProgress.memoizedProps.unstable_avoidThisFallback) || - 0 !== (suspenseStackCursor.current & 1) - ) - workInProgressRootExitStatus === RootIncomplete && - (workInProgressRootExitStatus = RootSuspended); - else { - if ( - workInProgressRootExitStatus === RootIncomplete || - workInProgressRootExitStatus === RootSuspended - ) - workInProgressRootExitStatus = RootSuspendedWithDelay; - 0 !== workInProgressRootNextUnprocessedUpdateTime && - null !== workInProgressRoot && - (markRootSuspendedAtTime( - workInProgressRoot, - renderExpirationTime$1 - ), - markRootUpdatedAtTime( - workInProgressRoot, - workInProgressRootNextUnprocessedUpdateTime - )); - } - if (newProps || rootContainerInstance) workInProgress.effectTag |= 4; - return null; - case 4: - return popHostContainer(), updateHostContainer(workInProgress), null; - case 10: - return popProvider(workInProgress), null; - case 17: - return isContextProvider(workInProgress.type) && popContext(), null; - case 19: - pop(suspenseStackCursor); - newProps = workInProgress.memoizedState; - if (null === newProps) return null; - rootContainerInstance = 0 !== (workInProgress.effectTag & 64); - updatePayload = newProps.rendering; - if (null === updatePayload) - if (rootContainerInstance) cutOffTailIfNeeded(newProps, !1); - else { - if ( - workInProgressRootExitStatus !== RootIncomplete || - (null !== current && 0 !== (current.effectTag & 64)) - ) - for (current = workInProgress.child; null !== current; ) { - updatePayload = findFirstSuspended(current); - if (null !== updatePayload) { - workInProgress.effectTag |= 64; - cutOffTailIfNeeded(newProps, !1); - current = updatePayload.updateQueue; - null !== current && - ((workInProgress.updateQueue = current), - (workInProgress.effectTag |= 4)); - null === newProps.lastEffect && - (workInProgress.firstEffect = null); - workInProgress.lastEffect = newProps.lastEffect; - current = renderExpirationTime; - for (newProps = workInProgress.child; null !== newProps; ) - (rootContainerInstance = newProps), - (renderExpirationTime = current), - (rootContainerInstance.effectTag &= 2), - (rootContainerInstance.nextEffect = null), - (rootContainerInstance.firstEffect = null), - (rootContainerInstance.lastEffect = null), - (updatePayload = rootContainerInstance.alternate), - null === updatePayload - ? ((rootContainerInstance.childExpirationTime = 0), - (rootContainerInstance.expirationTime = renderExpirationTime), - (rootContainerInstance.child = null), - (rootContainerInstance.memoizedProps = null), - (rootContainerInstance.memoizedState = null), - (rootContainerInstance.updateQueue = null), - (rootContainerInstance.dependencies = null)) - : ((rootContainerInstance.childExpirationTime = - updatePayload.childExpirationTime), - (rootContainerInstance.expirationTime = - updatePayload.expirationTime), - (rootContainerInstance.child = updatePayload.child), - (rootContainerInstance.memoizedProps = - updatePayload.memoizedProps), - (rootContainerInstance.memoizedState = - updatePayload.memoizedState), - (rootContainerInstance.updateQueue = - updatePayload.updateQueue), - (renderExpirationTime = updatePayload.dependencies), - (rootContainerInstance.dependencies = - null === renderExpirationTime - ? null - : { - expirationTime: - renderExpirationTime.expirationTime, - firstContext: renderExpirationTime.firstContext, - responders: renderExpirationTime.responders - })), - (newProps = newProps.sibling); - push( - suspenseStackCursor, - (suspenseStackCursor.current & 1) | 2 - ); - return workInProgress.child; - } - current = current.sibling; - } - } - else { - if (!rootContainerInstance) - if ( - ((current = findFirstSuspended(updatePayload)), null !== current) - ) { - if ( - ((workInProgress.effectTag |= 64), - (rootContainerInstance = !0), - (current = current.updateQueue), - null !== current && - ((workInProgress.updateQueue = current), - (workInProgress.effectTag |= 4)), - cutOffTailIfNeeded(newProps, !0), - null === newProps.tail && - "hidden" === newProps.tailMode && - !updatePayload.alternate) - ) - return ( - (workInProgress = workInProgress.lastEffect = - newProps.lastEffect), - null !== workInProgress && (workInProgress.nextEffect = null), - null - ); - } else - 2 * now() - newProps.renderingStartTime > newProps.tailExpiration && - 1 < renderExpirationTime && - ((workInProgress.effectTag |= 64), - (rootContainerInstance = !0), - cutOffTailIfNeeded(newProps, !1), - (workInProgress.expirationTime = workInProgress.childExpirationTime = - renderExpirationTime - 1)); - newProps.isBackwards - ? ((updatePayload.sibling = workInProgress.child), - (workInProgress.child = updatePayload)) - : ((current = newProps.last), - null !== current - ? (current.sibling = updatePayload) - : (workInProgress.child = updatePayload), - (newProps.last = updatePayload)); - } - return null !== newProps.tail - ? (0 === newProps.tailExpiration && - (newProps.tailExpiration = now() + 500), - (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; - } - 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) { switch (workInProgress.tag) { case 1: - isContextProvider(workInProgress.type) && popContext(); + isContextProvider(workInProgress.type) && popContext(workInProgress); var effectTag = workInProgress.effectTag; return effectTag & 4096 ? ((workInProgress.effectTag = (effectTag & -4097) | 64), workInProgress) : null; case 3: - popHostContainer(); - pop(didPerformWorkStackCursor); - pop(contextStackCursor); + popHostContainer(workInProgress); + popTopLevelContextObject(workInProgress); effectTag = workInProgress.effectTag; if (0 !== (effectTag & 64)) throw Error( @@ -4837,7 +4708,7 @@ function unwindWork(workInProgress) { return popHostContext(workInProgress), null; case 13: return ( - pop(suspenseStackCursor), + pop(suspenseStackCursor, workInProgress), (effectTag = workInProgress.effectTag), effectTag & 4096 ? ((workInProgress.effectTag = (effectTag & -4097) | 64), @@ -4845,9 +4716,9 @@ function unwindWork(workInProgress) { : null ); case 19: - return pop(suspenseStackCursor), null; + return pop(suspenseStackCursor, workInProgress), null; case 4: - return popHostContainer(), null; + return popHostContainer(workInProgress), null; case 10: return popProvider(workInProgress), null; default: @@ -4904,159 +4775,85 @@ function logError(boundary, errorInfo) { }); } } -function safelyCallComponentWillUnmount(current, instance) { +function safelyCallComponentWillUnmount(current$$1, instance) { try { - (instance.props = current.memoizedProps), - (instance.state = current.memoizedState), + (instance.props = current$$1.memoizedProps), + (instance.state = current$$1.memoizedState), instance.componentWillUnmount(); } catch (unmountError) { - captureCommitPhaseError(current, unmountError); + captureCommitPhaseError(current$$1, unmountError); } } -function safelyDetachRef(current) { - var ref = current.ref; +function safelyDetachRef(current$$1) { + var ref = current$$1.ref; if (null !== ref) if ("function" === typeof ref) try { ref(null); } catch (refError) { - captureCommitPhaseError(current, refError); + captureCommitPhaseError(current$$1, refError); } else ref.current = null; } -function commitBeforeMutationLifeCycles(current, finishedWork) { +function commitBeforeMutationLifeCycles(current$$1, finishedWork) { switch (finishedWork.tag) { case 0: case 11: case 15: - case 22: - return; + commitHookEffectList(2, 0, finishedWork); + break; case 1: - if (finishedWork.effectTag & 256 && null !== current) { - var prevProps = current.memoizedProps, - prevState = current.memoizedState; - current = finishedWork.stateNode; - finishedWork = current.getSnapshotBeforeUpdate( + if (finishedWork.effectTag & 256 && null !== current$$1) { + var prevProps = current$$1.memoizedProps, + prevState = current$$1.memoizedState; + current$$1 = finishedWork.stateNode; + finishedWork = current$$1.getSnapshotBeforeUpdate( finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState ); - current.__reactInternalSnapshotBeforeUpdate = finishedWork; + current$$1.__reactInternalSnapshotBeforeUpdate = finishedWork; } - return; + break; case 3: 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." - ); + 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." + ); + } } -function commitHookEffectListUnmount(tag, finishedWork) { +function commitHookEffectList(unmountTag, mountTag, finishedWork) { finishedWork = finishedWork.updateQueue; finishedWork = null !== finishedWork ? finishedWork.lastEffect : null; if (null !== finishedWork) { var effect = (finishedWork = finishedWork.next); do { - if ((effect.tag & tag) === tag) { + if (0 !== (effect.tag & unmountTag)) { var destroy = effect.destroy; effect.destroy = void 0; void 0 !== destroy && destroy(); } + 0 !== (effect.tag & mountTag) && + ((destroy = effect.create), (effect.destroy = destroy())); effect = effect.next; } while (effect !== finishedWork); } } -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 = effect.create; - effect.destroy = create(); - } - effect = effect.next; - } while (effect !== finishedWork); - } -} -function commitLifeCycles(finishedRoot, current, finishedWork) { - switch (finishedWork.tag) { - case 0: - case 11: - case 15: - case 22: - commitHookEffectListMount(3, finishedWork); - return; - case 1: - finishedRoot = finishedWork.stateNode; - if (finishedWork.effectTag & 4) - if (null === current) finishedRoot.componentDidMount(); - else { - var prevProps = - finishedWork.elementType === finishedWork.type - ? current.memoizedProps - : resolveDefaultProps(finishedWork.type, current.memoizedProps); - finishedRoot.componentDidUpdate( - prevProps, - 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); - } - return; - case 5: - return; - case 6: - return; - case 4: - return; - case 12: - return; - case 13: - return; - case 19: - case 17: - case 20: - case 21: - 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 commitUnmount(finishedRoot, current$jscomp$0, renderPriorityLevel) { +function commitUnmount(finishedRoot, current$$1$jscomp$0, renderPriorityLevel) { "function" === typeof onCommitFiberUnmount && - onCommitFiberUnmount(current$jscomp$0); - switch (current$jscomp$0.tag) { + onCommitFiberUnmount(current$$1$jscomp$0); + switch (current$$1$jscomp$0.tag) { case 0: case 11: case 14: case 15: - case 22: - finishedRoot = current$jscomp$0.updateQueue; + finishedRoot = current$$1$jscomp$0.updateQueue; if ( null !== finishedRoot && ((finishedRoot = finishedRoot.lastEffect), null !== finishedRoot) @@ -5067,13 +4864,13 @@ function commitUnmount(finishedRoot, current$jscomp$0, renderPriorityLevel) { function() { var effect = firstEffect; do { - var _destroy = effect.destroy; - if (void 0 !== _destroy) { - var current = current$jscomp$0; + var destroy = effect.destroy; + if (void 0 !== destroy) { + var current$$1 = current$$1$jscomp$0; try { - _destroy(); + destroy(); } catch (error) { - captureCommitPhaseError(current, error); + captureCommitPhaseError(current$$1, error); } } effect = effect.next; @@ -5083,35 +4880,37 @@ function commitUnmount(finishedRoot, current$jscomp$0, renderPriorityLevel) { } break; case 1: - safelyDetachRef(current$jscomp$0); - renderPriorityLevel = current$jscomp$0.stateNode; + safelyDetachRef(current$$1$jscomp$0); + renderPriorityLevel = current$$1$jscomp$0.stateNode; "function" === typeof renderPriorityLevel.componentWillUnmount && - safelyCallComponentWillUnmount(current$jscomp$0, renderPriorityLevel); + safelyCallComponentWillUnmount( + current$$1$jscomp$0, + renderPriorityLevel + ); break; case 5: - safelyDetachRef(current$jscomp$0); + safelyDetachRef(current$$1$jscomp$0); break; case 4: unmountHostComponents( finishedRoot, - current$jscomp$0, + current$$1$jscomp$0, renderPriorityLevel ); } } -function detachFiber(current) { - var alternate = current.alternate; - current.return = null; - current.child = null; - current.memoizedState = null; - current.updateQueue = null; - current.dependencies = null; - current.alternate = null; - current.firstEffect = null; - current.lastEffect = null; - current.pendingProps = null; - current.memoizedProps = null; - current.stateNode = null; +function detachFiber(current$$1) { + var alternate = current$$1.alternate; + current$$1.return = null; + current$$1.child = null; + current$$1.memoizedState = null; + current$$1.updateQueue = null; + current$$1.dependencies = null; + current$$1.alternate = null; + current$$1.firstEffect = null; + current$$1.lastEffect = null; + current$$1.pendingProps = null; + current$$1.memoizedProps = null; null !== alternate && detachFiber(alternate); } function isHostParent(fiber) { @@ -5174,103 +4973,97 @@ function commitPlacement(finishedWork) { break a; } } - isContainer - ? insertOrAppendPlacementNodeIntoContainer( - finishedWork, - parentFiber, - parent - ) - : insertOrAppendPlacementNode(finishedWork, parentFiber, parent); -} -function insertOrAppendPlacementNodeIntoContainer(node, before, parent) { - var tag = node.tag, - isHost = 5 === tag || 6 === tag; - if (isHost) - if (((node = isHost ? node.stateNode : node.stateNode.instance), before)) { - if ("number" === typeof parent) - throw Error("Container does not support insertBefore operation"); - } else - ReactNativePrivateInterface.UIManager.setChildren(parent, [ - "number" === typeof node ? node : node._nativeTag - ]); - else if (4 !== tag && ((node = node.child), null !== node)) - for ( - insertOrAppendPlacementNodeIntoContainer(node, before, parent), - node = node.sibling; - null !== node; - - ) - insertOrAppendPlacementNodeIntoContainer(node, before, parent), - (node = node.sibling); -} -function insertOrAppendPlacementNode(node, before, parent) { - var tag = node.tag, - isHost = 5 === tag || 6 === tag; - if (isHost) - (node = isHost ? node.stateNode : node.stateNode.instance), - before - ? ((tag = parent._children), - (isHost = tag.indexOf(node)), - 0 <= isHost - ? (tag.splice(isHost, 1), - (before = tag.indexOf(before)), - tag.splice(before, 0, node), - ReactNativePrivateInterface.UIManager.manageChildren( - parent._nativeTag, - [isHost], - [before], - [], - [], - [] - )) - : ((before = tag.indexOf(before)), - tag.splice(before, 0, node), - ReactNativePrivateInterface.UIManager.manageChildren( - parent._nativeTag, - [], - [], - ["number" === typeof node ? node : node._nativeTag], - [before], - [] - ))) - : ((before = "number" === typeof node ? node : node._nativeTag), - (tag = parent._children), - (isHost = tag.indexOf(node)), - 0 <= isHost - ? (tag.splice(isHost, 1), - tag.push(node), + for (var node = finishedWork; ; ) { + var isHost = 5 === node.tag || 6 === node.tag; + if (isHost) { + var stateNode = isHost ? node.stateNode : node.stateNode.instance; + if (parentFiber) + if (isContainer) { + if ("number" === typeof parent) + throw Error("Container does not support insertBefore operation"); + } else { + isHost = parent; + var beforeChild = parentFiber, + children = isHost._children, + index = children.indexOf(stateNode); + 0 <= index + ? (children.splice(index, 1), + (beforeChild = children.indexOf(beforeChild)), + children.splice(beforeChild, 0, stateNode), ReactNativePrivateInterface.UIManager.manageChildren( - parent._nativeTag, - [isHost], - [tag.length - 1], + isHost._nativeTag, + [index], + [beforeChild], [], [], [] )) - : (tag.push(node), + : ((index = children.indexOf(beforeChild)), + children.splice(index, 0, stateNode), ReactNativePrivateInterface.UIManager.manageChildren( - parent._nativeTag, + isHost._nativeTag, [], [], - [before], - [tag.length - 1], + [ + "number" === typeof stateNode + ? stateNode + : stateNode._nativeTag + ], + [index], [] - ))); - else if (4 !== tag && ((node = node.child), null !== node)) - for ( - insertOrAppendPlacementNode(node, before, parent), node = node.sibling; - null !== node; - - ) - insertOrAppendPlacementNode(node, before, parent), (node = node.sibling); + )); + } + else + isContainer + ? ReactNativePrivateInterface.UIManager.setChildren(parent, [ + "number" === typeof stateNode ? stateNode : stateNode._nativeTag + ]) + : ((isHost = parent), + (children = + "number" === typeof stateNode ? stateNode : stateNode._nativeTag), + (index = isHost._children), + (beforeChild = index.indexOf(stateNode)), + 0 <= beforeChild + ? (index.splice(beforeChild, 1), + index.push(stateNode), + ReactNativePrivateInterface.UIManager.manageChildren( + isHost._nativeTag, + [beforeChild], + [index.length - 1], + [], + [], + [] + )) + : (index.push(stateNode), + ReactNativePrivateInterface.UIManager.manageChildren( + isHost._nativeTag, + [], + [], + [children], + [index.length - 1], + [] + ))); + } else if (4 !== node.tag && null !== node.child) { + node.child.return = node; + node = node.child; + continue; + } + if (node === finishedWork) break; + for (; null === node.sibling; ) { + if (null === node.return || node.return === finishedWork) return; + node = node.return; + } + node.sibling.return = node.return; + node = node.sibling; + } } function unmountHostComponents( finishedRoot$jscomp$0, - current, + current$$1, renderPriorityLevel$jscomp$0 ) { for ( - var node = current, + var node = current$$1, currentParentIsValid = !1, currentParent, currentParentIsContainer; @@ -5318,7 +5111,7 @@ function unmountHostComponents( (node$jscomp$0.child.return = node$jscomp$0), (node$jscomp$0 = node$jscomp$0.child); else { - if (node$jscomp$0 === root) break a; + if (node$jscomp$0 === root) break; for (; null === node$jscomp$0.sibling; ) { if (null === node$jscomp$0.return || node$jscomp$0.return === root) break a; @@ -5368,9 +5161,9 @@ function unmountHostComponents( node = node.child; continue; } - if (node === current) break; + if (node === current$$1) break; for (; null === node.sibling; ) { - if (null === node.return || node.return === current) return; + if (null === node.return || node.return === current$$1) return; node = node.return; 4 === node.tag && (currentParentIsValid = !1); } @@ -5378,22 +5171,21 @@ function unmountHostComponents( node = node.sibling; } } -function commitWork(current, finishedWork) { +function commitWork(current$$1, finishedWork) { switch (finishedWork.tag) { case 0: case 11: case 14: case 15: - case 22: - commitHookEffectListUnmount(3, finishedWork); - return; + commitHookEffectList(4, 8, finishedWork); + break; case 1: - return; + break; case 5: var instance = finishedWork.stateNode; if (null != instance) { var newProps = finishedWork.memoizedProps; - current = null !== current ? current.memoizedProps : newProps; + current$$1 = null !== current$$1 ? current$$1.memoizedProps : newProps; var updatePayload = finishedWork.updateQueue; finishedWork.updateQueue = null; null !== updatePayload && @@ -5401,7 +5193,7 @@ function commitWork(current, finishedWork) { instanceProps.set(instance._nativeTag, newProps), (newProps = diffProperties( null, - current, + current$$1, newProps, finishedWork.validAttributes )), @@ -5412,7 +5204,7 @@ function commitWork(current, finishedWork) { newProps )); } - return; + break; case 6: if (null === finishedWork.stateNode) throw Error( @@ -5423,11 +5215,11 @@ function commitWork(current, finishedWork) { "RCTRawText", { text: finishedWork.memoizedProps } ); - return; + break; case 3: - return; + break; case 12: - return; + break; case 13: instance = finishedWork; null === finishedWork.memoizedState @@ -5436,9 +5228,9 @@ function commitWork(current, finishedWork) { (instance = finishedWork.child), (globalMostRecentFallbackTime = now())); if (null !== instance) - a: for (current = instance; ; ) { - if (5 === current.tag) - if (((updatePayload = current.stateNode), newProps)) { + a: for (current$$1 = instance; ; ) { + if (5 === current$$1.tag) + if (((updatePayload = current$$1.stateNode), newProps)) { var viewConfig = updatePayload.viewConfig; var updatePayload$jscomp$0 = diffProperties( null, @@ -5452,8 +5244,8 @@ function commitWork(current, finishedWork) { updatePayload$jscomp$0 ); } else { - updatePayload = current.stateNode; - updatePayload$jscomp$0 = current.memoizedProps; + updatePayload = current$$1.stateNode; + updatePayload$jscomp$0 = current$$1.memoizedProps; viewConfig = updatePayload.viewConfig; var prevProps = Object.assign({}, updatePayload$jscomp$0, { style: [updatePayload$jscomp$0.style, { display: "none" }] @@ -5471,41 +5263,47 @@ function commitWork(current, finishedWork) { ); } else { - if (6 === current.tag) throw Error("Not yet implemented."); + if (6 === current$$1.tag) throw Error("Not yet implemented."); if ( - 13 === current.tag && - null !== current.memoizedState && - null === current.memoizedState.dehydrated + 13 === current$$1.tag && + null !== current$$1.memoizedState && + null === current$$1.memoizedState.dehydrated ) { - updatePayload = current.child.sibling; - updatePayload.return = current; - current = updatePayload; + updatePayload = current$$1.child.sibling; + updatePayload.return = current$$1; + current$$1 = updatePayload; continue; - } else if (null !== current.child) { - current.child.return = current; - current = current.child; + } else if (null !== current$$1.child) { + current$$1.child.return = current$$1; + current$$1 = current$$1.child; continue; } } - if (current === instance) break; - for (; null === current.sibling; ) { - if (null === current.return || current.return === instance) break a; - current = current.return; + if (current$$1 === instance) break a; + for (; null === current$$1.sibling; ) { + if (null === current$$1.return || current$$1.return === instance) + break a; + current$$1 = current$$1.return; } - current.sibling.return = current.return; - current = current.sibling; + current$$1.sibling.return = current$$1.return; + current$$1 = current$$1.sibling; } attachSuspenseRetryListeners(finishedWork); - return; + break; case 19: attachSuspenseRetryListeners(finishedWork); - return; + break; case 17: - return; + break; + case 20: + break; + case 21: + 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." + ); } - 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 thenables = finishedWork.updateQueue; @@ -5561,7 +5359,7 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { return expirationTime; } var ceil = Math.ceil, - ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, + ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, NoContext = 0, LegacyUnbatchedContext = 8, @@ -5576,7 +5374,7 @@ var ceil = Math.ceil, executionContext = NoContext, workInProgressRoot = null, workInProgress = null, - renderExpirationTime$1 = 0, + renderExpirationTime = 0, workInProgressRootExitStatus = RootIncomplete, workInProgressRootFatalError = null, workInProgressRootLatestProcessedExpirationTime = 1073741823, @@ -5601,8 +5399,8 @@ function requestCurrentTimeForUpdate() { return (executionContext & (RenderContext | CommitContext)) !== NoContext ? 1073741821 - ((now() / 10) | 0) : 0 !== currentEventTime - ? currentEventTime - : (currentEventTime = 1073741821 - ((now() / 10) | 0)); + ? currentEventTime + : (currentEventTime = 1073741821 - ((now() / 10) | 0)); } function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { fiber = fiber.mode; @@ -5610,7 +5408,7 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { var priorityLevel = getCurrentPriorityLevel(); if (0 === (fiber & 4)) return 99 === priorityLevel ? 1073741823 : 1073741822; if ((executionContext & RenderContext) !== NoContext) - return renderExpirationTime$1; + return renderExpirationTime; if (null !== suspenseConfig) currentTime = 1073741821 - @@ -5642,11 +5440,11 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { throw Error("Expected a valid priority level"); } null !== workInProgressRoot && - currentTime === renderExpirationTime$1 && + currentTime === renderExpirationTime && --currentTime; return currentTime; } -function scheduleWork(fiber, expirationTime) { +function scheduleUpdateOnFiber(fiber, expirationTime) { if (50 < nestedUpdateCount) throw ((nestedUpdateCount = 0), (rootWithNestedUpdates = null), @@ -5700,7 +5498,7 @@ function markUpdateTimeFromFiberToRoot(fiber, expirationTime) { (workInProgressRoot === root && (markUnprocessedUpdateTime(expirationTime), workInProgressRootExitStatus === RootSuspendedWithDelay && - markRootSuspendedAtTime(root, renderExpirationTime$1)), + markRootSuspendedAtTime(root, renderExpirationTime)), markRootUpdatedAtTime(root, expirationTime)); return root; } @@ -5709,10 +5507,9 @@ function getNextRootExpirationTimeToWorkOn(root) { if (0 !== lastExpiredTime) return lastExpiredTime; lastExpiredTime = root.firstPendingTime; if (!isRootSuspendedAtTime(root, lastExpiredTime)) return lastExpiredTime; - var lastPingedTime = root.lastPingedTime; + lastExpiredTime = root.lastPingedTime; root = root.nextKnownPendingLevel; - root = lastPingedTime > root ? lastPingedTime : root; - return 2 >= root && lastExpiredTime !== root ? 0 : root; + return lastExpiredTime > root ? lastExpiredTime : root; } function ensureRootIsScheduled(root) { if (0 !== root.lastExpiredTime) @@ -5734,18 +5531,18 @@ function ensureRootIsScheduled(root) { 1073741823 === expirationTime ? (priorityLevel = 99) : 1 === expirationTime || 2 === expirationTime - ? (priorityLevel = 95) - : ((priorityLevel = - 10 * (1073741821 - expirationTime) - - 10 * (1073741821 - priorityLevel)), - (priorityLevel = - 0 >= priorityLevel - ? 99 - : 250 >= priorityLevel - ? 98 - : 5250 >= priorityLevel - ? 97 - : 95)); + ? (priorityLevel = 95) + : ((priorityLevel = + 10 * (1073741821 - expirationTime) - + 10 * (1073741821 - priorityLevel)), + (priorityLevel = + 0 >= priorityLevel + ? 99 + : 250 >= priorityLevel + ? 98 + : 5250 >= priorityLevel + ? 97 + : 95)); if (null !== existingCallbackNode) { var existingCallbackPriority = root.callbackPriority; if ( @@ -5772,225 +5569,264 @@ function ensureRootIsScheduled(root) { } function performConcurrentWorkOnRoot(root, didTimeout) { currentEventTime = 0; - if (didTimeout) { - didTimeout = requestCurrentTimeForUpdate(); - var lastExpiredTime = root.lastExpiredTime; - if (0 === lastExpiredTime || lastExpiredTime > didTimeout) - root.lastExpiredTime = didTimeout; - ensureRootIsScheduled(root); - return null; - } - lastExpiredTime = getNextRootExpirationTimeToWorkOn(root); - if (0 === lastExpiredTime) return null; - didTimeout = root.callbackNode; - if ((executionContext & (RenderContext | CommitContext)) !== NoContext) - throw Error("Should not already be working."); - flushPassiveEffects(); - var expirationTime = lastExpiredTime; - var exitStatus = executionContext; - executionContext |= RenderContext; - var prevDispatcher = pushDispatcher(); - (root === workInProgressRoot && expirationTime === renderExpirationTime$1) || - prepareFreshStack(root, expirationTime); - do - try { - workLoopConcurrent(); - break; - } catch (thrownValue) { - handleError(root, thrownValue); - } - while (1); - resetContextDependencies(); - ReactCurrentDispatcher$1.current = prevDispatcher; - executionContext = exitStatus; - null !== workInProgress - ? (exitStatus = RootIncomplete) - : ((workInProgressRoot = null), - (exitStatus = workInProgressRootExitStatus)); - if (exitStatus !== RootIncomplete) { - exitStatus === RootErrored && - ((lastExpiredTime = 2 < lastExpiredTime ? 2 : lastExpiredTime), - (exitStatus = renderRootSync(root, lastExpiredTime))); - if (exitStatus === RootFatalErrored) - throw ((didTimeout = workInProgressRootFatalError), - prepareFreshStack(root, lastExpiredTime), - markRootSuspendedAtTime(root, lastExpiredTime), + if (didTimeout) + return ( + (didTimeout = requestCurrentTimeForUpdate()), + markRootExpiredAtTime(root, didTimeout), ensureRootIsScheduled(root), - didTimeout); - expirationTime = root.finishedWork = root.current.alternate; - root.finishedExpirationTime = lastExpiredTime; - switch (exitStatus) { - case RootIncomplete: - case RootFatalErrored: - throw Error("Root did not complete. This is a bug in React."); - case RootErrored: - commitRoot(root); - break; - case RootSuspended: - markRootSuspendedAtTime(root, lastExpiredTime); - exitStatus = root.lastSuspendedTime; - lastExpiredTime === exitStatus && - (root.nextKnownPendingLevel = getRemainingExpirationTime( - expirationTime - )); - if ( - 1073741823 === workInProgressRootLatestProcessedExpirationTime && - ((expirationTime = - globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now()), - 10 < expirationTime) - ) { - if ( - workInProgressRootHasPendingPing && - ((prevDispatcher = root.lastPingedTime), - 0 === prevDispatcher || prevDispatcher >= lastExpiredTime) - ) { - root.lastPingedTime = lastExpiredTime; - prepareFreshStack(root, lastExpiredTime); - break; - } - prevDispatcher = getNextRootExpirationTimeToWorkOn(root); - if (0 !== prevDispatcher && prevDispatcher !== lastExpiredTime) break; - if (0 !== exitStatus && exitStatus !== lastExpiredTime) { - root.lastPingedTime = exitStatus; - break; - } - root.timeoutHandle = scheduleTimeout( - commitRoot.bind(null, root), - expirationTime - ); - break; - } - commitRoot(root); - break; - case RootSuspendedWithDelay: - markRootSuspendedAtTime(root, lastExpiredTime); - exitStatus = root.lastSuspendedTime; - lastExpiredTime === exitStatus && - (root.nextKnownPendingLevel = getRemainingExpirationTime( - expirationTime - )); - if ( - workInProgressRootHasPendingPing && - ((expirationTime = root.lastPingedTime), - 0 === expirationTime || expirationTime >= lastExpiredTime) - ) { - root.lastPingedTime = lastExpiredTime; - prepareFreshStack(root, lastExpiredTime); - break; - } - expirationTime = getNextRootExpirationTimeToWorkOn(root); - if (0 !== expirationTime && expirationTime !== lastExpiredTime) break; - if (0 !== exitStatus && exitStatus !== lastExpiredTime) { - root.lastPingedTime = exitStatus; - break; - } - 1073741823 !== workInProgressRootLatestSuspenseTimeout - ? (expirationTime = - 10 * (1073741821 - workInProgressRootLatestSuspenseTimeout) - - now()) - : 1073741823 === workInProgressRootLatestProcessedExpirationTime - ? (expirationTime = 0) - : ((expirationTime = - 10 * - (1073741821 - workInProgressRootLatestProcessedExpirationTime) - - 5e3), - (exitStatus = now()), - (lastExpiredTime = - 10 * (1073741821 - lastExpiredTime) - exitStatus), - (expirationTime = exitStatus - expirationTime), - 0 > expirationTime && (expirationTime = 0), - (expirationTime = - (120 > expirationTime - ? 120 - : 480 > expirationTime - ? 480 - : 1080 > expirationTime - ? 1080 - : 1920 > expirationTime - ? 1920 - : 3e3 > expirationTime - ? 3e3 - : 4320 > expirationTime - ? 4320 - : 1960 * ceil(expirationTime / 1960)) - expirationTime), - lastExpiredTime < expirationTime && - (expirationTime = lastExpiredTime)); - if (10 < expirationTime) { - root.timeoutHandle = scheduleTimeout( - commitRoot.bind(null, root), - expirationTime - ); + null + ); + var expirationTime = getNextRootExpirationTimeToWorkOn(root); + if (0 !== expirationTime) { + didTimeout = root.callbackNode; + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) + throw Error("Should not already be working."); + flushPassiveEffects(); + (root === workInProgressRoot && expirationTime === renderExpirationTime) || + prepareFreshStack(root, expirationTime); + if (null !== workInProgress) { + var prevExecutionContext = executionContext; + executionContext |= RenderContext; + var prevDispatcher = pushDispatcher(root); + do + try { + workLoopConcurrent(); break; + } catch (thrownValue) { + handleError(root, thrownValue); } - commitRoot(root); - break; - case RootCompleted: - if ( - 1073741823 !== workInProgressRootLatestProcessedExpirationTime && - null !== workInProgressRootCanSuspendUsingConfig + while (1); + resetContextDependencies(); + executionContext = prevExecutionContext; + ReactCurrentDispatcher.current = prevDispatcher; + if (workInProgressRootExitStatus === RootFatalErrored) + throw ((didTimeout = workInProgressRootFatalError), + prepareFreshStack(root, expirationTime), + markRootSuspendedAtTime(root, expirationTime), + ensureRootIsScheduled(root), + didTimeout); + if (null === workInProgress) + switch ( + ((prevDispatcher = root.finishedWork = root.current.alternate), + (root.finishedExpirationTime = expirationTime), + (prevExecutionContext = workInProgressRootExitStatus), + (workInProgressRoot = null), + prevExecutionContext) ) { - prevDispatcher = workInProgressRootLatestProcessedExpirationTime; - var suspenseConfig = workInProgressRootCanSuspendUsingConfig; - expirationTime = suspenseConfig.busyMinDurationMs | 0; - 0 >= expirationTime - ? (expirationTime = 0) - : ((exitStatus = suspenseConfig.busyDelayMs | 0), - (prevDispatcher = - now() - - (10 * (1073741821 - prevDispatcher) - - (suspenseConfig.timeoutMs | 0 || 5e3))), - (expirationTime = - prevDispatcher <= exitStatus - ? 0 - : exitStatus + expirationTime - prevDispatcher)); - if (10 < expirationTime) { - markRootSuspendedAtTime(root, lastExpiredTime); - root.timeoutHandle = scheduleTimeout( - commitRoot.bind(null, root), - expirationTime + case RootIncomplete: + case RootFatalErrored: + throw Error("Root did not complete. This is a bug in React."); + case RootErrored: + markRootExpiredAtTime( + root, + 2 < expirationTime ? 2 : expirationTime ); break; - } + case RootSuspended: + markRootSuspendedAtTime(root, expirationTime); + prevExecutionContext = root.lastSuspendedTime; + expirationTime === prevExecutionContext && + (root.nextKnownPendingLevel = getRemainingExpirationTime( + prevDispatcher + )); + if ( + 1073741823 === workInProgressRootLatestProcessedExpirationTime && + ((prevDispatcher = + globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now()), + 10 < prevDispatcher) + ) { + if (workInProgressRootHasPendingPing) { + var lastPingedTime = root.lastPingedTime; + if (0 === lastPingedTime || lastPingedTime >= expirationTime) { + root.lastPingedTime = expirationTime; + prepareFreshStack(root, expirationTime); + break; + } + } + lastPingedTime = getNextRootExpirationTimeToWorkOn(root); + if (0 !== lastPingedTime && lastPingedTime !== expirationTime) + break; + if ( + 0 !== prevExecutionContext && + prevExecutionContext !== expirationTime + ) { + root.lastPingedTime = prevExecutionContext; + break; + } + root.timeoutHandle = scheduleTimeout( + commitRoot.bind(null, root), + prevDispatcher + ); + break; + } + commitRoot(root); + break; + case RootSuspendedWithDelay: + markRootSuspendedAtTime(root, expirationTime); + prevExecutionContext = root.lastSuspendedTime; + expirationTime === prevExecutionContext && + (root.nextKnownPendingLevel = getRemainingExpirationTime( + prevDispatcher + )); + if ( + workInProgressRootHasPendingPing && + ((prevDispatcher = root.lastPingedTime), + 0 === prevDispatcher || prevDispatcher >= expirationTime) + ) { + root.lastPingedTime = expirationTime; + prepareFreshStack(root, expirationTime); + break; + } + prevDispatcher = getNextRootExpirationTimeToWorkOn(root); + if (0 !== prevDispatcher && prevDispatcher !== expirationTime) + break; + if ( + 0 !== prevExecutionContext && + prevExecutionContext !== expirationTime + ) { + root.lastPingedTime = prevExecutionContext; + break; + } + 1073741823 !== workInProgressRootLatestSuspenseTimeout + ? (prevExecutionContext = + 10 * (1073741821 - workInProgressRootLatestSuspenseTimeout) - + now()) + : 1073741823 === workInProgressRootLatestProcessedExpirationTime + ? (prevExecutionContext = 0) + : ((prevExecutionContext = + 10 * + (1073741821 - + workInProgressRootLatestProcessedExpirationTime) - + 5e3), + (prevDispatcher = now()), + (expirationTime = + 10 * (1073741821 - expirationTime) - prevDispatcher), + (prevExecutionContext = + prevDispatcher - prevExecutionContext), + 0 > prevExecutionContext && (prevExecutionContext = 0), + (prevExecutionContext = + (120 > prevExecutionContext + ? 120 + : 480 > prevExecutionContext + ? 480 + : 1080 > prevExecutionContext + ? 1080 + : 1920 > prevExecutionContext + ? 1920 + : 3e3 > prevExecutionContext + ? 3e3 + : 4320 > prevExecutionContext + ? 4320 + : 1960 * ceil(prevExecutionContext / 1960)) - + prevExecutionContext), + expirationTime < prevExecutionContext && + (prevExecutionContext = expirationTime)); + if (10 < prevExecutionContext) { + root.timeoutHandle = scheduleTimeout( + commitRoot.bind(null, root), + prevExecutionContext + ); + break; + } + commitRoot(root); + break; + case RootCompleted: + if ( + 1073741823 !== workInProgressRootLatestProcessedExpirationTime && + null !== workInProgressRootCanSuspendUsingConfig + ) { + lastPingedTime = workInProgressRootLatestProcessedExpirationTime; + var suspenseConfig = workInProgressRootCanSuspendUsingConfig; + prevExecutionContext = suspenseConfig.busyMinDurationMs | 0; + 0 >= prevExecutionContext + ? (prevExecutionContext = 0) + : ((prevDispatcher = suspenseConfig.busyDelayMs | 0), + (lastPingedTime = + now() - + (10 * (1073741821 - lastPingedTime) - + (suspenseConfig.timeoutMs | 0 || 5e3))), + (prevExecutionContext = + lastPingedTime <= prevDispatcher + ? 0 + : prevDispatcher + + prevExecutionContext - + lastPingedTime)); + if (10 < prevExecutionContext) { + markRootSuspendedAtTime(root, expirationTime); + root.timeoutHandle = scheduleTimeout( + commitRoot.bind(null, root), + prevExecutionContext + ); + break; + } + } + commitRoot(root); + break; + default: + throw Error("Unknown root exit status."); } - commitRoot(root); - break; - default: - throw Error("Unknown root exit status."); + ensureRootIsScheduled(root); + if (root.callbackNode === didTimeout) + return performConcurrentWorkOnRoot.bind(null, root); } } - ensureRootIsScheduled(root); - return root.callbackNode === didTimeout - ? performConcurrentWorkOnRoot.bind(null, root) - : null; + return null; } function performSyncWorkOnRoot(root) { - if ((executionContext & (RenderContext | CommitContext)) !== NoContext) - throw Error("Should not already be working."); - flushPassiveEffects(); var lastExpiredTime = root.lastExpiredTime; - lastExpiredTime = - 0 !== lastExpiredTime - ? root === workInProgressRoot && renderExpirationTime$1 >= lastExpiredTime - ? renderExpirationTime$1 - : lastExpiredTime - : 1073741823; - var exitStatus = renderRootSync(root, lastExpiredTime); - 0 !== root.tag && - exitStatus === RootErrored && - ((lastExpiredTime = 2 < lastExpiredTime ? 2 : lastExpiredTime), - (exitStatus = renderRootSync(root, lastExpiredTime))); - if (exitStatus === RootFatalErrored) - throw ((exitStatus = workInProgressRootFatalError), - prepareFreshStack(root, lastExpiredTime), - markRootSuspendedAtTime(root, lastExpiredTime), - ensureRootIsScheduled(root), - exitStatus); - root.finishedWork = root.current.alternate; - root.finishedExpirationTime = lastExpiredTime; - commitRoot(root); - ensureRootIsScheduled(root); + lastExpiredTime = 0 !== lastExpiredTime ? lastExpiredTime : 1073741823; + if (root.finishedExpirationTime === lastExpiredTime) commitRoot(root); + else { + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) + throw Error("Should not already be working."); + flushPassiveEffects(); + (root === workInProgressRoot && lastExpiredTime === renderExpirationTime) || + prepareFreshStack(root, lastExpiredTime); + if (null !== workInProgress) { + var prevExecutionContext = executionContext; + executionContext |= RenderContext; + var prevDispatcher = pushDispatcher(root); + do + try { + workLoopSync(); + break; + } catch (thrownValue) { + handleError(root, thrownValue); + } + while (1); + resetContextDependencies(); + executionContext = prevExecutionContext; + ReactCurrentDispatcher.current = prevDispatcher; + if (workInProgressRootExitStatus === RootFatalErrored) + throw ((prevExecutionContext = workInProgressRootFatalError), + prepareFreshStack(root, lastExpiredTime), + markRootSuspendedAtTime(root, lastExpiredTime), + ensureRootIsScheduled(root), + prevExecutionContext); + if (null !== workInProgress) + throw Error( + "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." + ); + root.finishedWork = root.current.alternate; + root.finishedExpirationTime = lastExpiredTime; + workInProgressRoot = null; + commitRoot(root); + ensureRootIsScheduled(root); + } + } return null; } +function flushPendingDiscreteUpdates() { + if (null !== rootsWithPendingDiscreteUpdates) { + var roots = rootsWithPendingDiscreteUpdates; + rootsWithPendingDiscreteUpdates = null; + roots.forEach(function(expirationTime, root) { + markRootExpiredAtTime(root, expirationTime); + ensureRootIsScheduled(root); + }); + flushSyncCallbackQueue(); + } +} function prepareFreshStack(root, expirationTime) { root.finishedWork = null; root.finishedExpirationTime = 0; @@ -6002,27 +5838,26 @@ function prepareFreshStack(root, expirationTime) { var interruptedWork = timeoutHandle; switch (interruptedWork.tag) { case 1: - interruptedWork = interruptedWork.type.childContextTypes; - null !== interruptedWork && - void 0 !== interruptedWork && - popContext(); + var childContextTypes = interruptedWork.type.childContextTypes; + null !== childContextTypes && + void 0 !== childContextTypes && + popContext(interruptedWork); break; case 3: - popHostContainer(); - pop(didPerformWorkStackCursor); - pop(contextStackCursor); + popHostContainer(interruptedWork); + popTopLevelContextObject(interruptedWork); break; case 5: popHostContext(interruptedWork); break; case 4: - popHostContainer(); + popHostContainer(interruptedWork); break; case 13: - pop(suspenseStackCursor); + pop(suspenseStackCursor, interruptedWork); break; case 19: - pop(suspenseStackCursor); + pop(suspenseStackCursor, interruptedWork); break; case 10: popProvider(interruptedWork); @@ -6030,8 +5865,8 @@ function prepareFreshStack(root, expirationTime) { timeoutHandle = timeoutHandle.return; } workInProgressRoot = root; - workInProgress = createWorkInProgress(root.current, null); - renderExpirationTime$1 = expirationTime; + workInProgress = createWorkInProgress(root.current, null, expirationTime); + renderExpirationTime = expirationTime; workInProgressRootExitStatus = RootIncomplete; workInProgressRootFatalError = null; workInProgressRootLatestSuspenseTimeout = workInProgressRootLatestProcessedExpirationTime = 1073741823; @@ -6043,32 +5878,19 @@ function handleError(root$jscomp$0, thrownValue) { do { try { resetContextDependencies(); - ReactCurrentDispatcher.current = ContextOnlyDispatcher; - if (didScheduleRenderPhaseUpdate) - for ( - var hook = currentlyRenderingFiber$1.memoizedState; - null !== hook; - - ) { - var queue = hook.queue; - null !== queue && (queue.pending = null); - hook = hook.next; - } - renderExpirationTime = 0; - workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; - didScheduleRenderPhaseUpdate = !1; + resetHooks(); if (null === workInProgress || null === workInProgress.return) return ( (workInProgressRootExitStatus = RootFatalErrored), (workInProgressRootFatalError = thrownValue), - (workInProgress = null) + null ); a: { var root = root$jscomp$0, returnFiber = workInProgress.return, sourceFiber = workInProgress, value = thrownValue; - thrownValue = renderExpirationTime$1; + thrownValue = renderExpirationTime; sourceFiber.effectTag |= 2048; sourceFiber.firstEffect = sourceFiber.lastEffect = null; if ( @@ -6076,17 +5898,8 @@ function handleError(root$jscomp$0, thrownValue) { "object" === typeof value && "function" === typeof value.then ) { - var thenable = value; - if (0 === (sourceFiber.mode & 2)) { - var currentSource = sourceFiber.alternate; - currentSource - ? ((sourceFiber.updateQueue = currentSource.updateQueue), - (sourceFiber.memoizedState = currentSource.memoizedState), - (sourceFiber.expirationTime = currentSource.expirationTime)) - : ((sourceFiber.updateQueue = null), - (sourceFiber.memoizedState = null)); - } - var hasInvisibleParentBoundary = + var thenable = value, + hasInvisibleParentBoundary = 0 !== (suspenseStackCursor.current & 1), _workInProgress = returnFiber; do { @@ -6101,10 +5914,10 @@ function handleError(root$jscomp$0, thrownValue) { void 0 === props.fallback ? !1 : !0 !== props.unstable_avoidThisFallback - ? !0 - : hasInvisibleParentBoundary - ? !1 - : !0; + ? !0 + : hasInvisibleParentBoundary + ? !1 + : !0; } } if (JSCompiler_temp) { @@ -6211,8 +6024,8 @@ function handleError(root$jscomp$0, thrownValue) { } while (1); } function pushDispatcher() { - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = ContextOnlyDispatcher; return null === prevDispatcher ? ContextOnlyDispatcher : prevDispatcher; } function markRenderEventTimeAndConfig(expirationTime, suspenseConfig) { @@ -6229,43 +6042,19 @@ function markUnprocessedUpdateTime(expirationTime) { expirationTime > workInProgressRootNextUnprocessedUpdateTime && (workInProgressRootNextUnprocessedUpdateTime = expirationTime); } -function renderRootSync(root, expirationTime) { - var prevExecutionContext = executionContext; - executionContext |= RenderContext; - var prevDispatcher = pushDispatcher(); - (root === workInProgressRoot && expirationTime === renderExpirationTime$1) || - prepareFreshStack(root, expirationTime); - do - try { - workLoopSync(); - break; - } catch (thrownValue) { - handleError(root, thrownValue); - } - while (1); - resetContextDependencies(); - executionContext = prevExecutionContext; - ReactCurrentDispatcher$1.current = prevDispatcher; - if (null !== workInProgress) - throw Error( - "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." - ); - workInProgressRoot = null; - return workInProgressRootExitStatus; -} function workLoopSync() { for (; null !== workInProgress; ) workInProgress = performUnitOfWork(workInProgress); } function workLoopConcurrent() { - for (; null !== workInProgress && !shouldYield(); ) + for (; null !== workInProgress && !Scheduler_shouldYield(); ) workInProgress = performUnitOfWork(workInProgress); } function performUnitOfWork(unitOfWork) { - var next = beginWork$1( + var next = beginWork$$1( unitOfWork.alternate, unitOfWork, - renderExpirationTime$1 + renderExpirationTime ); unitOfWork.memoizedProps = unitOfWork.pendingProps; null === next && (next = completeUnitOfWork(unitOfWork)); @@ -6275,30 +6064,366 @@ function performUnitOfWork(unitOfWork) { function completeUnitOfWork(unitOfWork) { workInProgress = unitOfWork; do { - var current = workInProgress.alternate; + var current$$1 = workInProgress.alternate; unitOfWork = workInProgress.return; if (0 === (workInProgress.effectTag & 2048)) { - current = completeWork(current, workInProgress, renderExpirationTime$1); - if ( - 1 === renderExpirationTime$1 || - 1 !== workInProgress.childExpirationTime - ) { + a: { + var current = current$$1; + current$$1 = workInProgress; + var renderExpirationTime$jscomp$0 = renderExpirationTime, + newProps = current$$1.pendingProps; + switch (current$$1.tag) { + case 2: + break; + case 16: + break; + case 15: + case 0: + break; + case 1: + isContextProvider(current$$1.type) && popContext(current$$1); + break; + case 3: + popHostContainer(current$$1); + popTopLevelContextObject(current$$1); + current = current$$1.stateNode; + current.pendingContext && + ((current.context = current.pendingContext), + (current.pendingContext = null)); + updateHostContainer(current$$1); + break; + case 5: + popHostContext(current$$1); + var rootContainerInstance = requiredContext( + rootInstanceStackCursor.current + ); + renderExpirationTime$jscomp$0 = current$$1.type; + if (null !== current && null != current$$1.stateNode) + updateHostComponent$1( + current, + current$$1, + renderExpirationTime$jscomp$0, + newProps, + rootContainerInstance + ), + current.ref !== current$$1.ref && (current$$1.effectTag |= 128); + else if (newProps) { + current = requiredContext(contextStackCursor$1.current); + var internalInstanceHandle = current$$1, + tag = allocateTag(), + viewConfig = getViewConfigForType( + renderExpirationTime$jscomp$0 + ), + updatePayload = diffProperties( + null, + emptyObject, + newProps, + viewConfig.validAttributes + ); + ReactNativePrivateInterface.UIManager.createView( + tag, + viewConfig.uiViewClassName, + rootContainerInstance, + updatePayload + ); + viewConfig = new ReactNativeFiberHostComponent(tag, viewConfig); + instanceCache.set(tag, internalInstanceHandle); + instanceProps.set(tag, newProps); + appendAllChildren(viewConfig, current$$1, !1, !1); + current$$1.stateNode = viewConfig; + finalizeInitialChildren( + viewConfig, + renderExpirationTime$jscomp$0, + newProps, + rootContainerInstance, + current + ) && (current$$1.effectTag |= 4); + null !== current$$1.ref && (current$$1.effectTag |= 128); + } else if (null === current$$1.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." + ); + break; + case 6: + if (current && null != current$$1.stateNode) + updateHostText$1( + current, + current$$1, + current.memoizedProps, + newProps + ); + else { + if ("string" !== typeof newProps && null === current$$1.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." + ); + renderExpirationTime$jscomp$0 = requiredContext( + rootInstanceStackCursor.current + ); + rootContainerInstance = requiredContext( + contextStackCursor$1.current + ); + current = current$$1; + if (!rootContainerInstance.isInAParentText) + throw Error( + "Text strings must be rendered within a component." + ); + rootContainerInstance = allocateTag(); + ReactNativePrivateInterface.UIManager.createView( + rootContainerInstance, + "RCTRawText", + renderExpirationTime$jscomp$0, + { text: newProps } + ); + instanceCache.set(rootContainerInstance, current$$1); + current.stateNode = rootContainerInstance; + } + break; + case 11: + break; + case 13: + pop(suspenseStackCursor, current$$1); + newProps = current$$1.memoizedState; + if (0 !== (current$$1.effectTag & 64)) { + current$$1.expirationTime = renderExpirationTime$jscomp$0; + break a; + } + newProps = null !== newProps; + rootContainerInstance = !1; + null !== current && + ((renderExpirationTime$jscomp$0 = current.memoizedState), + (rootContainerInstance = null !== renderExpirationTime$jscomp$0), + newProps || + null === renderExpirationTime$jscomp$0 || + ((renderExpirationTime$jscomp$0 = current.child.sibling), + null !== renderExpirationTime$jscomp$0 && + ((internalInstanceHandle = current$$1.firstEffect), + null !== internalInstanceHandle + ? ((current$$1.firstEffect = renderExpirationTime$jscomp$0), + (renderExpirationTime$jscomp$0.nextEffect = internalInstanceHandle)) + : ((current$$1.firstEffect = current$$1.lastEffect = renderExpirationTime$jscomp$0), + (renderExpirationTime$jscomp$0.nextEffect = null)), + (renderExpirationTime$jscomp$0.effectTag = 8)))); + if ( + newProps && + !rootContainerInstance && + 0 !== (current$$1.mode & 2) + ) + if ( + (null === current && + !0 !== current$$1.memoizedProps.unstable_avoidThisFallback) || + 0 !== (suspenseStackCursor.current & 1) + ) + workInProgressRootExitStatus === RootIncomplete && + (workInProgressRootExitStatus = RootSuspended); + else { + if ( + workInProgressRootExitStatus === RootIncomplete || + workInProgressRootExitStatus === RootSuspended + ) + workInProgressRootExitStatus = RootSuspendedWithDelay; + 0 !== workInProgressRootNextUnprocessedUpdateTime && + null !== workInProgressRoot && + (markRootSuspendedAtTime( + workInProgressRoot, + renderExpirationTime + ), + markRootUpdatedAtTime( + workInProgressRoot, + workInProgressRootNextUnprocessedUpdateTime + )); + } + if (newProps || rootContainerInstance) current$$1.effectTag |= 4; + break; + case 7: + break; + case 8: + break; + case 12: + break; + case 4: + popHostContainer(current$$1); + updateHostContainer(current$$1); + break; + case 10: + popProvider(current$$1); + break; + case 9: + break; + case 14: + break; + case 17: + isContextProvider(current$$1.type) && popContext(current$$1); + break; + case 19: + pop(suspenseStackCursor, current$$1); + newProps = current$$1.memoizedState; + if (null === newProps) break; + rootContainerInstance = 0 !== (current$$1.effectTag & 64); + internalInstanceHandle = newProps.rendering; + if (null === internalInstanceHandle) + if (rootContainerInstance) cutOffTailIfNeeded(newProps, !1); + else { + if ( + workInProgressRootExitStatus !== RootIncomplete || + (null !== current && 0 !== (current.effectTag & 64)) + ) + for (current = current$$1.child; null !== current; ) { + internalInstanceHandle = findFirstSuspended(current); + if (null !== internalInstanceHandle) { + current$$1.effectTag |= 64; + cutOffTailIfNeeded(newProps, !1); + current = internalInstanceHandle.updateQueue; + null !== current && + ((current$$1.updateQueue = current), + (current$$1.effectTag |= 4)); + null === newProps.lastEffect && + (current$$1.firstEffect = null); + current$$1.lastEffect = newProps.lastEffect; + current = renderExpirationTime$jscomp$0; + for (newProps = current$$1.child; null !== newProps; ) + (rootContainerInstance = newProps), + (renderExpirationTime$jscomp$0 = current), + (rootContainerInstance.effectTag &= 2), + (rootContainerInstance.nextEffect = null), + (rootContainerInstance.firstEffect = null), + (rootContainerInstance.lastEffect = null), + (internalInstanceHandle = + rootContainerInstance.alternate), + null === internalInstanceHandle + ? ((rootContainerInstance.childExpirationTime = 0), + (rootContainerInstance.expirationTime = renderExpirationTime$jscomp$0), + (rootContainerInstance.child = null), + (rootContainerInstance.memoizedProps = null), + (rootContainerInstance.memoizedState = null), + (rootContainerInstance.updateQueue = null), + (rootContainerInstance.dependencies = null)) + : ((rootContainerInstance.childExpirationTime = + internalInstanceHandle.childExpirationTime), + (rootContainerInstance.expirationTime = + internalInstanceHandle.expirationTime), + (rootContainerInstance.child = + internalInstanceHandle.child), + (rootContainerInstance.memoizedProps = + internalInstanceHandle.memoizedProps), + (rootContainerInstance.memoizedState = + internalInstanceHandle.memoizedState), + (rootContainerInstance.updateQueue = + internalInstanceHandle.updateQueue), + (renderExpirationTime$jscomp$0 = + internalInstanceHandle.dependencies), + (rootContainerInstance.dependencies = + null === renderExpirationTime$jscomp$0 + ? null + : { + expirationTime: + renderExpirationTime$jscomp$0.expirationTime, + firstContext: + renderExpirationTime$jscomp$0.firstContext, + responders: + renderExpirationTime$jscomp$0.responders + })), + (newProps = newProps.sibling); + push( + suspenseStackCursor, + (suspenseStackCursor.current & 1) | 2, + current$$1 + ); + current$$1 = current$$1.child; + break a; + } + current = current.sibling; + } + } + else { + if (!rootContainerInstance) + if ( + ((current = findFirstSuspended(internalInstanceHandle)), + null !== current) + ) { + if ( + ((current$$1.effectTag |= 64), + (rootContainerInstance = !0), + (current = current.updateQueue), + null !== current && + ((current$$1.updateQueue = current), + (current$$1.effectTag |= 4)), + cutOffTailIfNeeded(newProps, !0), + null === newProps.tail && + "hidden" === newProps.tailMode && + !internalInstanceHandle.alternate) + ) { + current$$1 = current$$1.lastEffect = newProps.lastEffect; + null !== current$$1 && (current$$1.nextEffect = null); + break; + } + } else + now() > newProps.tailExpiration && + 1 < renderExpirationTime$jscomp$0 && + ((current$$1.effectTag |= 64), + (rootContainerInstance = !0), + cutOffTailIfNeeded(newProps, !1), + (current$$1.expirationTime = current$$1.childExpirationTime = + renderExpirationTime$jscomp$0 - 1)); + newProps.isBackwards + ? ((internalInstanceHandle.sibling = current$$1.child), + (current$$1.child = internalInstanceHandle)) + : ((current = newProps.last), + null !== current + ? (current.sibling = internalInstanceHandle) + : (current$$1.child = internalInstanceHandle), + (newProps.last = internalInstanceHandle)); + } + if (null !== newProps.tail) { + 0 === newProps.tailExpiration && + (newProps.tailExpiration = now() + 500); + current = newProps.tail; + newProps.rendering = current; + newProps.tail = current.sibling; + newProps.lastEffect = current$$1.lastEffect; + current.sibling = null; + newProps = suspenseStackCursor.current; + newProps = rootContainerInstance + ? (newProps & 1) | 2 + : newProps & 1; + push(suspenseStackCursor, newProps, current$$1); + current$$1 = current; + break a; + } + break; + case 20: + break; + case 21: + break; + default: + throw Error( + "Unknown unit of work tag (" + + current$$1.tag + + "). This error is likely caused by a bug in React. Please file an issue." + ); + } + current$$1 = null; + } + current = workInProgress; + if (1 === renderExpirationTime || 1 !== current.childExpirationTime) { + newProps = 0; for ( - var newChildExpirationTime = 0, _child = workInProgress.child; - null !== _child; + rootContainerInstance = current.child; + null !== rootContainerInstance; - ) { - var _childUpdateExpirationTime = _child.expirationTime, - _childChildExpirationTime = _child.childExpirationTime; - _childUpdateExpirationTime > newChildExpirationTime && - (newChildExpirationTime = _childUpdateExpirationTime); - _childChildExpirationTime > newChildExpirationTime && - (newChildExpirationTime = _childChildExpirationTime); - _child = _child.sibling; - } - workInProgress.childExpirationTime = newChildExpirationTime; + ) + (renderExpirationTime$jscomp$0 = + rootContainerInstance.expirationTime), + (internalInstanceHandle = + rootContainerInstance.childExpirationTime), + renderExpirationTime$jscomp$0 > newProps && + (newProps = renderExpirationTime$jscomp$0), + internalInstanceHandle > newProps && + (newProps = internalInstanceHandle), + (rootContainerInstance = rootContainerInstance.sibling); + current.childExpirationTime = newProps; } - if (null !== current) return current; + if (null !== current$$1) return current$$1; null !== unitOfWork && 0 === (unitOfWork.effectTag & 2048) && (null === unitOfWork.firstEffect && @@ -6313,14 +6438,15 @@ function completeUnitOfWork(unitOfWork) { : (unitOfWork.firstEffect = workInProgress), (unitOfWork.lastEffect = workInProgress))); } else { - current = unwindWork(workInProgress); - if (null !== current) return (current.effectTag &= 2047), current; + current$$1 = unwindWork(workInProgress, renderExpirationTime); + if (null !== current$$1) + return (current$$1.effectTag &= 2047), current$$1; null !== unitOfWork && ((unitOfWork.firstEffect = unitOfWork.lastEffect = null), (unitOfWork.effectTag |= 2048)); } - current = workInProgress.sibling; - if (null !== current) return current; + current$$1 = workInProgress.sibling; + if (null !== current$$1) return current$$1; workInProgress = unitOfWork; } while (null !== workInProgress); workInProgressRootExitStatus === RootIncomplete && @@ -6338,8 +6464,7 @@ function commitRoot(root) { return null; } function commitRootImpl(root$jscomp$0, renderPriorityLevel$jscomp$0) { - do flushPassiveEffects(); - while (null !== rootWithPendingPassiveEffects); + flushPassiveEffects(); if ((executionContext & (RenderContext | CommitContext)) !== NoContext) throw Error("Should not already be working."); var finishedWork = root$jscomp$0.finishedWork, @@ -6368,8 +6493,7 @@ function commitRootImpl(root$jscomp$0, renderPriorityLevel$jscomp$0) { expirationTime <= root$jscomp$0.lastExpiredTime && (root$jscomp$0.lastExpiredTime = 0); root$jscomp$0 === workInProgressRoot && - ((workInProgress = workInProgressRoot = null), - (renderExpirationTime$1 = 0)); + ((workInProgress = workInProgressRoot = null), (renderExpirationTime = 0)); 1 < finishedWork.effectTag ? null !== finishedWork.lastEffect ? ((finishedWork.lastEffect.nextEffect = finishedWork), @@ -6401,9 +6525,9 @@ function commitRootImpl(root$jscomp$0, renderPriorityLevel$jscomp$0) { ) { var effectTag = nextEffect.effectTag; if (effectTag & 128) { - var current = nextEffect.alternate; - if (null !== current) { - var currentRef = current.ref; + var current$$1 = nextEffect.alternate; + if (null !== current$$1) { + var currentRef = current$$1.ref; null !== currentRef && ("function" === typeof currentRef ? currentRef(null) @@ -6431,13 +6555,13 @@ function commitRootImpl(root$jscomp$0, renderPriorityLevel$jscomp$0) { commitWork(nextEffect.alternate, nextEffect); break; case 8: - var current$jscomp$0 = nextEffect; + var current$$1$jscomp$0 = nextEffect; unmountHostComponents( root, - current$jscomp$0, + current$$1$jscomp$0, renderPriorityLevel ); - detachFiber(current$jscomp$0); + detachFiber(current$$1$jscomp$0); } nextEffect = nextEffect.nextEffect; } @@ -6451,25 +6575,97 @@ function commitRootImpl(root$jscomp$0, renderPriorityLevel$jscomp$0) { nextEffect = remainingExpirationTimeBeforeCommit; do try { - for (effectTag = root$jscomp$0; null !== nextEffect; ) { + for (effectTag = expirationTime; null !== nextEffect; ) { var effectTag$jscomp$0 = nextEffect.effectTag; - effectTag$jscomp$0 & 36 && - commitLifeCycles(effectTag, nextEffect.alternate, nextEffect); + if (effectTag$jscomp$0 & 36) { + var current$$1$jscomp$1 = nextEffect.alternate; + current$$1 = nextEffect; + currentRef = effectTag; + switch (current$$1.tag) { + case 0: + case 11: + case 15: + commitHookEffectList(16, 32, current$$1); + break; + case 1: + var instance = current$$1.stateNode; + if (current$$1.effectTag & 4) + if (null === current$$1$jscomp$1) + instance.componentDidMount(); + else { + var prevProps = + current$$1.elementType === current$$1.type + ? current$$1$jscomp$1.memoizedProps + : resolveDefaultProps( + current$$1.type, + current$$1$jscomp$1.memoizedProps + ); + instance.componentDidUpdate( + prevProps, + current$$1$jscomp$1.memoizedState, + instance.__reactInternalSnapshotBeforeUpdate + ); + } + var updateQueue = current$$1.updateQueue; + null !== updateQueue && + commitUpdateQueue( + current$$1, + updateQueue, + instance, + currentRef + ); + break; + case 3: + var _updateQueue = current$$1.updateQueue; + if (null !== _updateQueue) { + root = null; + if (null !== current$$1.child) + switch (current$$1.child.tag) { + case 5: + root = current$$1.child.stateNode; + break; + case 1: + root = current$$1.child.stateNode; + } + commitUpdateQueue(current$$1, _updateQueue, root, currentRef); + } + break; + case 5: + break; + case 6: + break; + case 4: + break; + case 12: + break; + case 13: + break; + case 19: + case 17: + case 20: + case 21: + 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 (effectTag$jscomp$0 & 128) { - current = void 0; + current$$1 = void 0; var ref = nextEffect.ref; if (null !== ref) { - var instance = nextEffect.stateNode; + var instance$jscomp$0 = nextEffect.stateNode; switch (nextEffect.tag) { case 5: - current = instance; + current$$1 = instance$jscomp$0; break; default: - current = instance; + current$$1 = instance$jscomp$0; } "function" === typeof ref - ? ref(current) - : (ref.current = current); + ? ref(current$$1) + : (ref.current = current$$1); } } nextEffect = nextEffect.nextEffect; @@ -6558,9 +6754,8 @@ function flushPassiveEffectsImpl() { case 0: case 11: case 15: - case 22: - commitHookEffectListUnmount(5, finishedWork), - commitHookEffectListMount(5, finishedWork); + commitHookEffectList(128, 0, finishedWork), + commitHookEffectList(0, 64, finishedWork); } } catch (error) { if (null === root) throw Error("Should be working on an effect."); @@ -6611,17 +6806,20 @@ function captureCommitPhaseError(sourceFiber, error) { function pingSuspendedRoot(root, thenable, suspendedTime) { var pingCache = root.pingCache; null !== pingCache && pingCache.delete(thenable); - workInProgressRoot === root && renderExpirationTime$1 === suspendedTime + workInProgressRoot === root && renderExpirationTime === suspendedTime ? workInProgressRootExitStatus === RootSuspendedWithDelay || (workInProgressRootExitStatus === RootSuspended && 1073741823 === workInProgressRootLatestProcessedExpirationTime && now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) - ? prepareFreshStack(root, renderExpirationTime$1) + ? prepareFreshStack(root, renderExpirationTime) : (workInProgressRootHasPendingPing = !0) : isRootSuspendedAtTime(root, suspendedTime) && ((thenable = root.lastPingedTime), (0 !== thenable && thenable < suspendedTime) || - ((root.lastPingedTime = suspendedTime), ensureRootIsScheduled(root))); + ((root.lastPingedTime = suspendedTime), + root.finishedExpirationTime === suspendedTime && + ((root.finishedExpirationTime = 0), (root.finishedWork = null)), + ensureRootIsScheduled(root))); } function resolveRetryThenable(boundaryFiber, thenable) { var retryCache = boundaryFiber.stateNode; @@ -6633,12 +6831,12 @@ function resolveRetryThenable(boundaryFiber, thenable) { boundaryFiber = markUpdateTimeFromFiberToRoot(boundaryFiber, thenable); null !== boundaryFiber && ensureRootIsScheduled(boundaryFiber); } -var beginWork$1; -beginWork$1 = function(current, workInProgress, renderExpirationTime) { +var beginWork$$1; +beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { var updateExpirationTime = workInProgress.expirationTime; - if (null !== current) + if (null !== current$$1) if ( - current.memoizedProps !== workInProgress.pendingProps || + current$$1.memoizedProps !== workInProgress.pendingProps || didPerformWorkStackCursor.current ) didReceiveUpdate = !0; @@ -6663,10 +6861,7 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { ); break; case 10: - updateExpirationTime = workInProgress.memoizedProps.value; - var context = workInProgress.type._context; - push(valueCursor, context._currentValue); - context._currentValue = updateExpirationTime; + pushProvider(workInProgress, workInProgress.memoizedProps.value); break; case 13: if (null !== workInProgress.memoizedState) { @@ -6676,40 +6871,52 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { updateExpirationTime >= renderExpirationTime ) return updateSuspenseComponent( - current, + current$$1, workInProgress, renderExpirationTime ); - push(suspenseStackCursor, suspenseStackCursor.current & 1); + push( + suspenseStackCursor, + suspenseStackCursor.current & 1, + workInProgress + ); workInProgress = bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ); return null !== workInProgress ? workInProgress.sibling : null; } - push(suspenseStackCursor, suspenseStackCursor.current & 1); + push( + suspenseStackCursor, + suspenseStackCursor.current & 1, + workInProgress + ); break; case 19: updateExpirationTime = workInProgress.childExpirationTime >= renderExpirationTime; - if (0 !== (current.effectTag & 64)) { + if (0 !== (current$$1.effectTag & 64)) { if (updateExpirationTime) return updateSuspenseListComponent( - current, + current$$1, workInProgress, renderExpirationTime ); workInProgress.effectTag |= 64; } - context = workInProgress.memoizedState; - null !== context && - ((context.rendering = null), (context.tail = null)); - push(suspenseStackCursor, suspenseStackCursor.current); + var renderState = workInProgress.memoizedState; + null !== renderState && + ((renderState.rendering = null), (renderState.tail = null)); + push( + suspenseStackCursor, + suspenseStackCursor.current, + workInProgress + ); if (!updateExpirationTime) return null; } return bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -6721,40 +6928,41 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { switch (workInProgress.tag) { case 2: updateExpirationTime = workInProgress.type; - null !== current && - ((current.alternate = null), + null !== current$$1 && + ((current$$1.alternate = null), (workInProgress.alternate = null), (workInProgress.effectTag |= 2)); - current = workInProgress.pendingProps; - context = getMaskedContext(workInProgress, contextStackCursor.current); + current$$1 = workInProgress.pendingProps; + renderState = getMaskedContext( + workInProgress, + contextStackCursor.current + ); prepareToReadContext(workInProgress, renderExpirationTime); - context = renderWithHooks( + renderState = renderWithHooks( null, workInProgress, updateExpirationTime, - current, - context, + current$$1, + renderState, renderExpirationTime ); workInProgress.effectTag |= 1; if ( - "object" === typeof context && - null !== context && - "function" === typeof context.render && - void 0 === context.$$typeof + "object" === typeof renderState && + null !== renderState && + "function" === typeof renderState.render && + void 0 === renderState.$$typeof ) { workInProgress.tag = 1; - workInProgress.memoizedState = null; - workInProgress.updateQueue = null; + resetHooks(); if (isContextProvider(updateExpirationTime)) { var hasContext = !0; pushContextProvider(workInProgress); } else hasContext = !1; workInProgress.memoizedState = - null !== context.state && void 0 !== context.state - ? context.state + null !== renderState.state && void 0 !== renderState.state + ? renderState.state : null; - initializeUpdateQueue(workInProgress); var getDerivedStateFromProps = updateExpirationTime.getDerivedStateFromProps; "function" === typeof getDerivedStateFromProps && @@ -6762,15 +6970,15 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { workInProgress, updateExpirationTime, getDerivedStateFromProps, - current + current$$1 ); - context.updater = classComponentUpdater; - workInProgress.stateNode = context; - context._reactInternalFiber = workInProgress; + renderState.updater = classComponentUpdater; + workInProgress.stateNode = renderState; + renderState._reactInternalFiber = workInProgress; mountClassInstance( workInProgress, updateExpirationTime, - current, + current$$1, renderExpirationTime ); workInProgress = finishClassComponent( @@ -6786,129 +6994,127 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { reconcileChildren( null, workInProgress, - context, + renderState, renderExpirationTime ), (workInProgress = workInProgress.child); return workInProgress; case 16: - a: { - context = workInProgress.elementType; - null !== current && - ((current.alternate = null), - (workInProgress.alternate = null), - (workInProgress.effectTag |= 2)); - current = workInProgress.pendingProps; - initializeLazyComponentType(context); - if (1 !== context._status) throw context._result; - context = context._result; - workInProgress.type = context; - hasContext = workInProgress.tag = resolveLazyComponentTag(context); - current = resolveDefaultProps(context, current); - switch (hasContext) { - case 0: - workInProgress = updateFunctionComponent( - null, - workInProgress, - context, - current, - renderExpirationTime - ); - break a; - case 1: - workInProgress = updateClassComponent( - null, - workInProgress, - context, - current, - renderExpirationTime - ); - break a; - case 11: - workInProgress = updateForwardRef( - null, - workInProgress, - context, - current, - renderExpirationTime - ); - break a; - case 14: - workInProgress = updateMemoComponent( - null, - workInProgress, - context, - resolveDefaultProps(context.type, current), - updateExpirationTime, - renderExpirationTime - ); - break a; - } - throw Error( - "Element type is invalid. Received a promise that resolves to: " + - context + - ". Lazy element type must resolve to a class or function." - ); + renderState = workInProgress.elementType; + null !== current$$1 && + ((current$$1.alternate = null), + (workInProgress.alternate = null), + (workInProgress.effectTag |= 2)); + current$$1 = workInProgress.pendingProps; + initializeLazyComponentType(renderState); + if (1 !== renderState._status) throw renderState._result; + renderState = renderState._result; + workInProgress.type = renderState; + hasContext = workInProgress.tag = resolveLazyComponentTag(renderState); + current$$1 = resolveDefaultProps(renderState, current$$1); + switch (hasContext) { + case 0: + workInProgress = updateFunctionComponent( + null, + workInProgress, + renderState, + current$$1, + renderExpirationTime + ); + break; + case 1: + workInProgress = updateClassComponent( + null, + workInProgress, + renderState, + current$$1, + renderExpirationTime + ); + break; + case 11: + workInProgress = updateForwardRef( + null, + workInProgress, + renderState, + current$$1, + renderExpirationTime + ); + break; + case 14: + workInProgress = updateMemoComponent( + null, + workInProgress, + renderState, + resolveDefaultProps(renderState.type, current$$1), + updateExpirationTime, + renderExpirationTime + ); + break; + default: + throw Error( + "Element type is invalid. Received a promise that resolves to: " + + renderState + + ". Lazy element type must resolve to a class or function." + ); } return workInProgress; case 0: return ( (updateExpirationTime = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (renderState = workInProgress.pendingProps), + (renderState = workInProgress.elementType === updateExpirationTime - ? context - : resolveDefaultProps(updateExpirationTime, context)), + ? renderState + : resolveDefaultProps(updateExpirationTime, renderState)), updateFunctionComponent( - current, + current$$1, workInProgress, updateExpirationTime, - context, + renderState, renderExpirationTime ) ); case 1: return ( (updateExpirationTime = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (renderState = workInProgress.pendingProps), + (renderState = workInProgress.elementType === updateExpirationTime - ? context - : resolveDefaultProps(updateExpirationTime, context)), + ? renderState + : resolveDefaultProps(updateExpirationTime, renderState)), updateClassComponent( - current, + current$$1, workInProgress, updateExpirationTime, - context, + renderState, renderExpirationTime ) ); case 3: pushHostRootContext(workInProgress); updateExpirationTime = workInProgress.updateQueue; - if (null === current || null === updateExpirationTime) + if (null === updateExpirationTime) 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." ); - updateExpirationTime = workInProgress.pendingProps; - context = workInProgress.memoizedState; - context = null !== context ? context.element : null; - cloneUpdateQueue(current, workInProgress); + renderState = workInProgress.memoizedState; + renderState = null !== renderState ? renderState.element : null; processUpdateQueue( workInProgress, updateExpirationTime, + workInProgress.pendingProps, null, renderExpirationTime ); updateExpirationTime = workInProgress.memoizedState.element; - updateExpirationTime === context + updateExpirationTime === renderState ? (workInProgress = bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime )) : (reconcileChildren( - current, + current$$1, workInProgress, updateExpirationTime, renderExpirationTime @@ -6918,10 +7124,11 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { case 5: return ( pushHostContext(workInProgress), + null === current$$1 && tryToClaimNextHydratableInstance(workInProgress), (updateExpirationTime = workInProgress.pendingProps.children), - markRef(current, workInProgress), + markRef(current$$1, workInProgress), reconcileChildren( - current, + current$$1, workInProgress, updateExpirationTime, renderExpirationTime @@ -6930,10 +7137,13 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { workInProgress ); case 6: - return null; + return ( + null === current$$1 && tryToClaimNextHydratableInstance(workInProgress), + null + ); case 13: return updateSuspenseComponent( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -6944,7 +7154,7 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { workInProgress.stateNode.containerInfo ), (updateExpirationTime = workInProgress.pendingProps), - null === current + null === current$$1 ? (workInProgress.child = reconcileChildFibers( workInProgress, null, @@ -6952,7 +7162,7 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { renderExpirationTime )) : reconcileChildren( - current, + current$$1, workInProgress, updateExpirationTime, renderExpirationTime @@ -6962,23 +7172,23 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { case 11: return ( (updateExpirationTime = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (renderState = workInProgress.pendingProps), + (renderState = workInProgress.elementType === updateExpirationTime - ? context - : resolveDefaultProps(updateExpirationTime, context)), + ? renderState + : resolveDefaultProps(updateExpirationTime, renderState)), updateForwardRef( - current, + current$$1, workInProgress, updateExpirationTime, - context, + renderState, renderExpirationTime ) ); case 7: return ( reconcileChildren( - current, + current$$1, workInProgress, workInProgress.pendingProps, renderExpirationTime @@ -6988,7 +7198,7 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { case 8: return ( reconcileChildren( - current, + current$$1, workInProgress, workInProgress.pendingProps.children, renderExpirationTime @@ -6998,7 +7208,7 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { case 12: return ( reconcileChildren( - current, + current$$1, workInProgress, workInProgress.pendingProps.children, renderExpirationTime @@ -7008,32 +7218,27 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { case 10: a: { updateExpirationTime = workInProgress.type._context; - context = workInProgress.pendingProps; + renderState = 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 updateExpirationTime._calculateChangedBits - ? updateExpirationTime._calculateChangedBits( - context$jscomp$0, - hasContext - ) - : 1073741823) | 0), - 0 === hasContext) - ) { + hasContext = renderState.value; + pushProvider(workInProgress, hasContext); + if (null !== getDerivedStateFromProps) { + var oldValue = getDerivedStateFromProps.value; + hasContext = is$1(oldValue, hasContext) + ? 0 + : ("function" === typeof updateExpirationTime._calculateChangedBits + ? updateExpirationTime._calculateChangedBits( + oldValue, + hasContext + ) + : 1073741823) | 0; + if (0 === hasContext) { if ( - getDerivedStateFromProps.children === context.children && + getDerivedStateFromProps.children === renderState.children && !didPerformWorkStackCursor.current ) { workInProgress = bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -7041,15 +7246,14 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { } } 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; @@ -7059,18 +7263,18 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { dependency.context === updateExpirationTime && 0 !== (dependency.observedBits & hasContext) ) { - 1 === context$jscomp$0.tag && + 1 === oldValue.tag && ((dependency = createUpdate(renderExpirationTime, null)), (dependency.tag = 2), - enqueueUpdate(context$jscomp$0, dependency)); - context$jscomp$0.expirationTime < renderExpirationTime && - (context$jscomp$0.expirationTime = renderExpirationTime); - dependency = context$jscomp$0.alternate; + enqueueUpdate(oldValue, dependency)); + oldValue.expirationTime < renderExpirationTime && + (oldValue.expirationTime = renderExpirationTime); + dependency = oldValue.alternate; null !== dependency && dependency.expirationTime < renderExpirationTime && (dependency.expirationTime = renderExpirationTime); scheduleWorkOnParentPath( - context$jscomp$0.return, + oldValue.return, renderExpirationTime ); list.expirationTime < renderExpirationTime && @@ -7081,16 +7285,16 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { } } 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; ) { @@ -7098,20 +7302,21 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { 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, + current$$1, workInProgress, - context.children, + renderState.children, renderExpirationTime ); workInProgress = workInProgress.child; @@ -7119,15 +7324,18 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { return workInProgress; case 9: return ( - (context = workInProgress.type), + (renderState = workInProgress.type), (hasContext = workInProgress.pendingProps), (updateExpirationTime = hasContext.children), prepareToReadContext(workInProgress, renderExpirationTime), - (context = readContext(context, hasContext.unstable_observedBits)), - (updateExpirationTime = updateExpirationTime(context)), + (renderState = readContext( + renderState, + hasContext.unstable_observedBits + )), + (updateExpirationTime = updateExpirationTime(renderState)), (workInProgress.effectTag |= 1), reconcileChildren( - current, + current$$1, workInProgress, updateExpirationTime, renderExpirationTime @@ -7136,16 +7344,16 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { ); case 14: return ( - (context = workInProgress.type), + (renderState = workInProgress.type), (hasContext = resolveDefaultProps( - context, + renderState, workInProgress.pendingProps )), - (hasContext = resolveDefaultProps(context.type, hasContext)), + (hasContext = resolveDefaultProps(renderState.type, hasContext)), updateMemoComponent( - current, + current$$1, workInProgress, - context, + renderState, hasContext, updateExpirationTime, renderExpirationTime @@ -7153,7 +7361,7 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { ); case 15: return updateSimpleMemoComponent( - current, + current$$1, workInProgress, workInProgress.type, workInProgress.pendingProps, @@ -7163,25 +7371,30 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { case 17: return ( (updateExpirationTime = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (renderState = workInProgress.pendingProps), + (renderState = workInProgress.elementType === updateExpirationTime - ? context - : resolveDefaultProps(updateExpirationTime, context)), - null !== current && - ((current.alternate = null), + ? renderState + : resolveDefaultProps(updateExpirationTime, renderState)), + null !== current$$1 && + ((current$$1.alternate = null), (workInProgress.alternate = null), (workInProgress.effectTag |= 2)), (workInProgress.tag = 1), isContextProvider(updateExpirationTime) - ? ((current = !0), pushContextProvider(workInProgress)) - : (current = !1), + ? ((current$$1 = !0), pushContextProvider(workInProgress)) + : (current$$1 = !1), prepareToReadContext(workInProgress, renderExpirationTime), - constructClassInstance(workInProgress, updateExpirationTime, context), + constructClassInstance( + workInProgress, + updateExpirationTime, + renderState, + renderExpirationTime + ), mountClassInstance( workInProgress, updateExpirationTime, - context, + renderState, renderExpirationTime ), finishClassComponent( @@ -7189,13 +7402,13 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { workInProgress, updateExpirationTime, !0, - current, + current$$1, renderExpirationTime ) ); case 19: return updateSuspenseListComponent( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -7246,6 +7459,9 @@ function FiberNode(tag, pendingProps, key, mode) { this.childExpirationTime = this.expirationTime = 0; this.alternate = null; } +function createFiber(tag, pendingProps, key, mode) { + return new FiberNode(tag, pendingProps, key, mode); +} function shouldConstruct(Component) { Component = Component.prototype; return !(!Component || !Component.isReactComponent); @@ -7263,7 +7479,7 @@ function resolveLazyComponentTag(Component) { function createWorkInProgress(current, pendingProps) { var workInProgress = current.alternate; null === workInProgress - ? ((workInProgress = new FiberNode( + ? ((workInProgress = createFiber( current.tag, pendingProps, current.key, @@ -7330,7 +7546,7 @@ function createFiberFromTypeAndProps( break; case REACT_PROFILER_TYPE: return ( - (type = new FiberNode(12, pendingProps, key, mode | 8)), + (type = createFiber(12, pendingProps, key, mode | 8)), (type.elementType = REACT_PROFILER_TYPE), (type.type = REACT_PROFILER_TYPE), (type.expirationTime = expirationTime), @@ -7338,7 +7554,7 @@ function createFiberFromTypeAndProps( ); case REACT_SUSPENSE_TYPE: return ( - (type = new FiberNode(13, pendingProps, key, mode)), + (type = createFiber(13, pendingProps, key, mode)), (type.type = REACT_SUSPENSE_TYPE), (type.elementType = REACT_SUSPENSE_TYPE), (type.expirationTime = expirationTime), @@ -7346,7 +7562,7 @@ function createFiberFromTypeAndProps( ); case REACT_SUSPENSE_LIST_TYPE: return ( - (type = new FiberNode(19, pendingProps, key, mode)), + (type = createFiber(19, pendingProps, key, mode)), (type.elementType = REACT_SUSPENSE_LIST_TYPE), (type.expirationTime = expirationTime), type @@ -7370,9 +7586,6 @@ function createFiberFromTypeAndProps( fiberTag = 16; owner = null; break a; - case REACT_BLOCK_TYPE: - fiberTag = 22; - break a; } throw Error( "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + @@ -7380,24 +7593,24 @@ function createFiberFromTypeAndProps( "." ); } - key = new FiberNode(fiberTag, pendingProps, key, mode); + key = createFiber(fiberTag, pendingProps, key, mode); key.elementType = type; key.type = owner; key.expirationTime = expirationTime; return key; } function createFiberFromFragment(elements, mode, expirationTime, key) { - elements = new FiberNode(7, elements, key, mode); + elements = createFiber(7, elements, key, mode); elements.expirationTime = expirationTime; return elements; } function createFiberFromText(content, mode, expirationTime) { - content = new FiberNode(6, content, null, mode); + content = createFiber(6, content, null, mode); content.expirationTime = expirationTime; return content; } function createFiberFromPortal(portal, mode, expirationTime) { - mode = new FiberNode( + mode = createFiber( 4, null !== portal.children ? portal.children : [], portal.key, @@ -7456,6 +7669,11 @@ function markRootUpdatedAtTime(root, expirationTime) { expirationTime > root.nextKnownPendingLevel && (root.nextKnownPendingLevel = expirationTime)); } +function markRootExpiredAtTime(root, expirationTime) { + var lastExpiredTime = root.lastExpiredTime; + if (0 === lastExpiredTime || lastExpiredTime > expirationTime) + root.lastExpiredTime = expirationTime; +} function findHostInstance(component) { var fiber = component._reactInternalFiber; if (void 0 === fiber) { @@ -7470,10 +7688,14 @@ function findHostInstance(component) { return null === component ? null : component.stateNode; } function updateContainer(element, container, parentComponent, callback) { - var current = container.current, + var current$$1 = container.current, currentTime = requestCurrentTimeForUpdate(), suspenseConfig = ReactCurrentBatchConfig.suspense; - currentTime = computeExpirationForFiber(currentTime, current, suspenseConfig); + currentTime = computeExpirationForFiber( + currentTime, + current$$1, + suspenseConfig + ); a: if (parentComponent) { parentComponent = parentComponent._reactInternalFiber; b: { @@ -7524,8 +7746,8 @@ function updateContainer(element, container, parentComponent, callback) { container.payload = { element: element }; callback = void 0 === callback ? null : callback; null !== callback && (container.callback = callback); - enqueueUpdate(current, container); - scheduleWork(current, currentTime); + enqueueUpdate(current$$1, container); + scheduleUpdateOnFiber(current$$1, currentTime); return currentTime; } function createPortal(children, containerInfo, implementation) { @@ -7539,6 +7761,11 @@ function createPortal(children, containerInfo, implementation) { implementation: implementation }; } +function _inheritsLoose(subClass, superClass) { + subClass.prototype = Object.create(superClass.prototype); + subClass.prototype.constructor = subClass; + subClass.__proto__ = superClass; +} function findNodeHandle(componentOrHandle) { if (null == componentOrHandle) return null; if ("number" === typeof componentOrHandle) return componentOrHandle; @@ -7549,15 +7776,8 @@ function findNodeHandle(componentOrHandle) { return null == componentOrHandle ? componentOrHandle : componentOrHandle.canonical - ? componentOrHandle.canonical._nativeTag - : componentOrHandle._nativeTag; -} -function unmountComponentAtNode(containerTag) { - var root = roots.get(containerTag); - root && - updateContainer(null, root, null, function() { - roots.delete(containerTag); - }); + ? componentOrHandle.canonical._nativeTag + : componentOrHandle._nativeTag; } batchedUpdatesImpl = function(fn, a) { var prevExecutionContext = executionContext; @@ -7569,117 +7789,299 @@ batchedUpdatesImpl = function(fn, a) { executionContext === NoContext && flushSyncCallbackQueue(); } }; -var roots = new Map(); -(function(devToolsConfig) { - var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance; - return injectInternals({ - bundleType: devToolsConfig.bundleType, - version: devToolsConfig.version, - rendererPackageName: devToolsConfig.rendererPackageName, - rendererConfig: devToolsConfig.rendererConfig, - overrideHookState: null, - overrideProps: null, - setSuspenseHandler: null, - scheduleUpdate: null, - currentDispatcherRef: ReactSharedInternals.ReactCurrentDispatcher, - findHostInstanceByFiber: function(fiber) { - fiber = findCurrentHostFiber(fiber); - return null === fiber ? null : fiber.stateNode; +flushDiscreteUpdatesImpl = function() { + (executionContext & (1 | RenderContext | CommitContext)) === NoContext && + (flushPendingDiscreteUpdates(), flushPassiveEffects()); +}; +var roots = new Map(), + ReactNativeRenderer = { + NativeComponent: (function(findNodeHandle, findHostInstance) { + return (function(_React$Component) { + function ReactNativeComponent() { + return _React$Component.apply(this, arguments) || this; + } + _inheritsLoose(ReactNativeComponent, _React$Component); + var _proto = ReactNativeComponent.prototype; + _proto.blur = function() { + ReactNativePrivateInterface.TextInputState.blurTextInput( + findNodeHandle(this) + ); + }; + _proto.focus = function() { + ReactNativePrivateInterface.TextInputState.focusTextInput( + findNodeHandle(this) + ); + }; + _proto.measure = function(callback) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + null != maybeInstance && + (maybeInstance.canonical + ? nativeFabricUIManager.measure( + maybeInstance.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ) + : ReactNativePrivateInterface.UIManager.measure( + findNodeHandle(this), + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + )); + }; + _proto.measureInWindow = function(callback) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + null != maybeInstance && + (maybeInstance.canonical + ? nativeFabricUIManager.measureInWindow( + maybeInstance.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ) + : ReactNativePrivateInterface.UIManager.measureInWindow( + findNodeHandle(this), + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + )); + }; + _proto.measureLayout = function( + relativeToNativeNode, + onSuccess, + onFail + ) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + if (null != maybeInstance && !maybeInstance.canonical) { + if ("number" === typeof relativeToNativeNode) + var relativeNode = relativeToNativeNode; + else + relativeToNativeNode._nativeTag && + (relativeNode = relativeToNativeNode._nativeTag); + null != relativeNode && + ReactNativePrivateInterface.UIManager.measureLayout( + findNodeHandle(this), + relativeNode, + mountSafeCallback_NOT_REALLY_SAFE(this, onFail), + mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) + ); + } + }; + _proto.setNativeProps = function(nativeProps) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + if (null != maybeInstance && !maybeInstance.canonical) { + var nativeTag = + maybeInstance._nativeTag || maybeInstance.canonical._nativeTag; + maybeInstance = + maybeInstance.viewConfig || maybeInstance.canonical.viewConfig; + nativeProps = diffProperties( + null, + emptyObject, + nativeProps, + maybeInstance.validAttributes + ); + null != nativeProps && + ReactNativePrivateInterface.UIManager.updateView( + nativeTag, + maybeInstance.uiViewClassName, + nativeProps + ); + } + }; + return ReactNativeComponent; + })(React.Component); + })(findNodeHandle, findHostInstance), + findHostInstance_DEPRECATED: function(componentOrHandle) { + if (null == componentOrHandle) return null; + if (componentOrHandle._nativeTag) return componentOrHandle; + if (componentOrHandle.canonical && componentOrHandle.canonical._nativeTag) + return componentOrHandle.canonical; + componentOrHandle = findHostInstance(componentOrHandle); + return null == componentOrHandle + ? componentOrHandle + : componentOrHandle.canonical + ? componentOrHandle.canonical + : componentOrHandle; + }, + findNodeHandle: findNodeHandle, + dispatchCommand: function(handle, command, args) { + null != handle._nativeTag && + ReactNativePrivateInterface.UIManager.dispatchViewManagerCommand( + handle._nativeTag, + command, + args + ); + }, + 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; + roots.set(containerTag, root); + } + updateContainer(element, root, null, callback); + a: if (((element = root.current), element.child)) + switch (element.child.tag) { + case 5: + element = element.child.stateNode; + break a; + default: + element = element.child.stateNode; + } + else element = null; + return element; }, - findFiberByHostInstance: function(instance) { - return findFiberByHostInstance ? findFiberByHostInstance(instance) : null; + unmountComponentAtNode: function(containerTag) { + var root = roots.get(containerTag); + root && + updateContainer(null, root, null, function() { + roots.delete(containerTag); + }); }, - findHostInstancesForRefresh: null, - scheduleRefresh: null, - scheduleRoot: null, - setRefreshHandler: null, - getCurrentFiber: null - }); + unmountComponentAtNodeAndRemoveContainer: function(containerTag) { + ReactNativeRenderer.unmountComponentAtNode(containerTag); + ReactNativePrivateInterface.UIManager.removeRootView(containerTag); + }, + createPortal: function(children, containerTag) { + return createPortal( + children, + containerTag, + null, + 2 < arguments.length && void 0 !== arguments[2] ? arguments[2] : null + ); + }, + unstable_batchedUpdates: batchedUpdates, + __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: { + NativeMethodsMixin: (function(findNodeHandle, findHostInstance) { + return { + measure: function(callback) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + null != maybeInstance && + (maybeInstance.canonical + ? nativeFabricUIManager.measure( + maybeInstance.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ) + : ReactNativePrivateInterface.UIManager.measure( + findNodeHandle(this), + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + )); + }, + measureInWindow: function(callback) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + null != maybeInstance && + (maybeInstance.canonical + ? nativeFabricUIManager.measureInWindow( + maybeInstance.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ) + : ReactNativePrivateInterface.UIManager.measureInWindow( + findNodeHandle(this), + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + )); + }, + measureLayout: function(relativeToNativeNode, onSuccess, onFail) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + if (null != maybeInstance && !maybeInstance.canonical) { + if ("number" === typeof relativeToNativeNode) + var relativeNode = relativeToNativeNode; + else + relativeToNativeNode._nativeTag && + (relativeNode = relativeToNativeNode._nativeTag); + null != relativeNode && + ReactNativePrivateInterface.UIManager.measureLayout( + findNodeHandle(this), + relativeNode, + mountSafeCallback_NOT_REALLY_SAFE(this, onFail), + mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) + ); + } + }, + setNativeProps: function(nativeProps) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + if (null != maybeInstance && !maybeInstance.canonical) { + var nativeTag = + maybeInstance._nativeTag || maybeInstance.canonical._nativeTag; + maybeInstance = + maybeInstance.viewConfig || maybeInstance.canonical.viewConfig; + nativeProps = diffProperties( + null, + emptyObject, + nativeProps, + maybeInstance.validAttributes + ); + null != nativeProps && + ReactNativePrivateInterface.UIManager.updateView( + nativeTag, + maybeInstance.uiViewClassName, + nativeProps + ); + } + }, + focus: function() { + ReactNativePrivateInterface.TextInputState.focusTextInput( + findNodeHandle(this) + ); + }, + blur: function() { + ReactNativePrivateInterface.TextInputState.blurTextInput( + findNodeHandle(this) + ); + } + }; + })(findNodeHandle, findHostInstance), + computeComponentStackForErrorReporting: function(reactTag) { + return (reactTag = getInstanceFromTag(reactTag)) + ? getStackByFiberInDevAndProd(reactTag) + : ""; + } + } + }; +(function(devToolsConfig) { + var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance; + return injectInternals( + Object.assign({}, devToolsConfig, { + overrideHookState: null, + overrideProps: null, + setSuspenseHandler: null, + scheduleUpdate: null, + currentDispatcherRef: ReactSharedInternals.ReactCurrentDispatcher, + findHostInstanceByFiber: function(fiber) { + fiber = findCurrentHostFiber(fiber); + return null === fiber ? null : fiber.stateNode; + }, + findFiberByHostInstance: function(instance) { + return findFiberByHostInstance + ? findFiberByHostInstance(instance) + : null; + }, + findHostInstancesForRefresh: null, + scheduleRefresh: null, + scheduleRoot: null, + setRefreshHandler: null, + getCurrentFiber: null + }) + ); })({ findFiberByHostInstance: getInstanceFromTag, + getInspectorDataForViewTag: function() { + throw Error("getInspectorDataForViewTag() is not available in production"); + }, bundleType: 0, - version: "16.13.0", - rendererPackageName: "react-native-renderer", - rendererConfig: { - getInspectorDataForViewTag: function() { - throw Error( - "getInspectorDataForViewTag() is not available in production" - ); - }, - getInspectorDataForViewAtPoint: function() { - throw Error( - "getInspectorDataForViewAtPoint() is not available in production." - ); - }.bind(null, findNodeHandle) - } + version: "16.11.0", + rendererPackageName: "react-native-renderer" }); -exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = { - computeComponentStackForErrorReporting: function(reactTag) { - return (reactTag = getInstanceFromTag(reactTag)) - ? getStackByFiberInDevAndProd(reactTag) - : ""; - } -}; -exports.createPortal = function(children, containerTag) { - return createPortal( - children, - containerTag, - null, - 2 < arguments.length && void 0 !== arguments[2] ? arguments[2] : null - ); -}; -exports.dispatchCommand = function(handle, command, args) { - null != handle._nativeTag && - (handle._internalInstanceHandle - ? nativeFabricUIManager.dispatchCommand( - handle._internalInstanceHandle.stateNode.node, - command, - args - ) - : ReactNativePrivateInterface.UIManager.dispatchViewManagerCommand( - handle._nativeTag, - command, - args - )); -}; -exports.findHostInstance_DEPRECATED = function(componentOrHandle) { - if (null == componentOrHandle) return null; - if (componentOrHandle._nativeTag) return componentOrHandle; - if (componentOrHandle.canonical && componentOrHandle.canonical._nativeTag) - return componentOrHandle.canonical; - componentOrHandle = findHostInstance(componentOrHandle); - return null == componentOrHandle - ? componentOrHandle - : componentOrHandle.canonical - ? componentOrHandle.canonical - : componentOrHandle; -}; -exports.findNodeHandle = findNodeHandle; -exports.render = function(element, containerTag, callback) { - var root = roots.get(containerTag); - if (!root) { - root = new FiberRootNode(containerTag, 0, !1); - var uninitializedFiber = new FiberNode(3, null, null, 0); - root.current = uninitializedFiber; - uninitializedFiber.stateNode = root; - initializeUpdateQueue(uninitializedFiber); - roots.set(containerTag, root); - } - updateContainer(element, root, null, callback); - a: if (((element = root.current), element.child)) - switch (element.child.tag) { - case 5: - element = element.child.stateNode; - break a; - default: - element = element.child.stateNode; - } - else element = null; - return element; -}; -exports.unmountComponentAtNode = unmountComponentAtNode; -exports.unmountComponentAtNodeAndRemoveContainer = function(containerTag) { - unmountComponentAtNode(containerTag); - ReactNativePrivateInterface.UIManager.removeRootView(containerTag); -}; -exports.unstable_batchedUpdates = batchedUpdates; +var ReactNativeRenderer$2 = { default: ReactNativeRenderer }, + ReactNativeRenderer$3 = + (ReactNativeRenderer$2 && ReactNativeRenderer) || ReactNativeRenderer$2; +module.exports = ReactNativeRenderer$3.default || ReactNativeRenderer$3; diff --git a/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js b/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js index 2bac9e25f6cf5d..b6719c3c3ecd50 100644 --- a/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js +++ b/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js @@ -5,7 +5,6 @@ * LICENSE file in the root directory of this source tree. * * @noflow - * @nolint * @preventMunge * @generated */ @@ -15,17 +14,86 @@ require("react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore"); var ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/ReactNativePrivateInterface"), React = require("react"), Scheduler = require("scheduler"), - tracing = require("scheduler/tracing"); -function getParent(inst) { - do inst = inst.return; - while (inst && 5 !== inst.tag); - return inst ? inst : null; + tracing = require("scheduler/tracing"), + eventPluginOrder = null, + namesToPlugins = {}; +function recomputePluginOrdering() { + if (eventPluginOrder) + for (var pluginName in namesToPlugins) { + var pluginModule = namesToPlugins[pluginName], + pluginIndex = eventPluginOrder.indexOf(pluginName); + if (!(-1 < pluginIndex)) + throw Error( + "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + + pluginName + + "`." + ); + if (!plugins[pluginIndex]) { + if (!pluginModule.extractEvents) + throw Error( + "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + + pluginName + + "` does not." + ); + plugins[pluginIndex] = pluginModule; + pluginIndex = pluginModule.eventTypes; + for (var eventName in pluginIndex) { + var JSCompiler_inline_result = void 0; + var dispatchConfig = pluginIndex[eventName], + pluginModule$jscomp$0 = pluginModule, + eventName$jscomp$0 = eventName; + if (eventNameDispatchConfigs.hasOwnProperty(eventName$jscomp$0)) + throw Error( + "EventPluginHub: More than one plugin attempted to publish the same event name, `" + + eventName$jscomp$0 + + "`." + ); + eventNameDispatchConfigs[eventName$jscomp$0] = dispatchConfig; + var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; + if (phasedRegistrationNames) { + for (JSCompiler_inline_result in phasedRegistrationNames) + phasedRegistrationNames.hasOwnProperty( + JSCompiler_inline_result + ) && + publishRegistrationName( + phasedRegistrationNames[JSCompiler_inline_result], + pluginModule$jscomp$0, + eventName$jscomp$0 + ); + JSCompiler_inline_result = !0; + } else + dispatchConfig.registrationName + ? (publishRegistrationName( + dispatchConfig.registrationName, + pluginModule$jscomp$0, + eventName$jscomp$0 + ), + (JSCompiler_inline_result = !0)) + : (JSCompiler_inline_result = !1); + if (!JSCompiler_inline_result) + throw Error( + "EventPluginRegistry: Failed to publish event `" + + eventName + + "` for plugin `" + + pluginName + + "`." + ); + } + } + } } -function traverseTwoPhase(inst, fn, arg) { - for (var path = []; inst; ) path.push(inst), (inst = getParent(inst)); - for (inst = path.length; 0 < inst--; ) fn(path[inst], "captured", arg); - for (inst = 0; inst < path.length; inst++) fn(path[inst], "bubbled", arg); +function publishRegistrationName(registrationName, pluginModule) { + if (registrationNameModules[registrationName]) + throw Error( + "EventPluginHub: More than one plugin attempted to publish the same registration name, `" + + registrationName + + "`." + ); + registrationNameModules[registrationName] = pluginModule; } +var plugins = [], + eventNameDispatchConfigs = {}, + registrationNameModules = {}; function invokeGuardedCallbackImpl(name, func, context, a, b, c, d, e, f) { var funcArgs = Array.prototype.slice.call(arguments, 3); try { @@ -96,6 +164,74 @@ function executeDirectDispatch(event) { event._dispatchInstances = null; return dispatchListener; } +function accumulateInto(current, next) { + if (null == next) + throw Error( + "accumulateInto(...): Accumulated items must not be null or undefined." + ); + if (null == current) return next; + if (Array.isArray(current)) { + if (Array.isArray(next)) return current.push.apply(current, next), current; + current.push(next); + return current; + } + return Array.isArray(next) ? [current].concat(next) : [current, next]; +} +function forEachAccumulated(arr, cb, scope) { + Array.isArray(arr) ? arr.forEach(cb, scope) : arr && cb.call(scope, arr); +} +var eventQueue = null; +function executeDispatchesAndReleaseTopLevel(e) { + if (e) { + var dispatchListeners = e._dispatchListeners, + dispatchInstances = e._dispatchInstances; + if (Array.isArray(dispatchListeners)) + for ( + var i = 0; + i < dispatchListeners.length && !e.isPropagationStopped(); + i++ + ) + executeDispatch(e, dispatchListeners[i], dispatchInstances[i]); + else + dispatchListeners && + executeDispatch(e, dispatchListeners, dispatchInstances); + e._dispatchListeners = null; + e._dispatchInstances = null; + e.isPersistent() || e.constructor.release(e); + } +} +var injection = { + injectEventPluginOrder: function(injectedEventPluginOrder) { + if (eventPluginOrder) + throw Error( + "EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React." + ); + eventPluginOrder = Array.prototype.slice.call(injectedEventPluginOrder); + recomputePluginOrdering(); + }, + injectEventPluginsByName: function(injectedNamesToPlugins) { + var isOrderingDirty = !1, + pluginName; + for (pluginName in injectedNamesToPlugins) + if (injectedNamesToPlugins.hasOwnProperty(pluginName)) { + var pluginModule = injectedNamesToPlugins[pluginName]; + if ( + !namesToPlugins.hasOwnProperty(pluginName) || + namesToPlugins[pluginName] !== pluginModule + ) { + if (namesToPlugins[pluginName]) + throw Error( + "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + + pluginName + + "`." + ); + namesToPlugins[pluginName] = pluginModule; + isOrderingDirty = !0; + } + } + isOrderingDirty && recomputePluginOrdering(); + } +}; function getListener(inst, registrationName) { var listener = inst.stateNode; if (!listener) return null; @@ -113,7 +249,6 @@ function getListener(inst, registrationName) { case "onMouseMoveCapture": case "onMouseUp": case "onMouseUpCapture": - case "onMouseEnter": (props = !props.disabled) || ((inst = inst.type), (props = !( @@ -138,21 +273,15 @@ function getListener(inst, registrationName) { ); return listener; } -function accumulateInto(current, next) { - if (null == next) - throw Error( - "accumulateInto(...): Accumulated items must not be null or undefined." - ); - if (null == current) return next; - if (Array.isArray(current)) { - if (Array.isArray(next)) return current.push.apply(current, next), current; - current.push(next); - return current; - } - return Array.isArray(next) ? [current].concat(next) : [current, next]; +function getParent(inst) { + do inst = inst.return; + while (inst && 5 !== inst.tag); + return inst ? inst : null; } -function forEachAccumulated(arr, cb, scope) { - Array.isArray(arr) ? arr.forEach(cb, scope) : arr && cb.call(scope, arr); +function traverseTwoPhase(inst, fn, arg) { + for (var path = []; inst; ) path.push(inst), (inst = getParent(inst)); + for (inst = path.length; 0 < inst--; ) fn(path[inst], "captured", arg); + for (inst = 0; inst < path.length; inst++) fn(path[inst], "bubbled", arg); } function accumulateDirectionalDispatches(inst, phase, event) { if ( @@ -220,8 +349,8 @@ function SyntheticEvent( ((targetInst = dispatchConfig[propName]) ? (this[propName] = targetInst(nativeEvent)) : "target" === propName - ? (this.target = nativeEventTarget) - : (this[propName] = nativeEvent[propName])); + ? (this.target = nativeEventTarget) + : (this[propName] = nativeEvent[propName])); this.isDefaultPrevented = (null != nativeEvent.defaultPrevented ? nativeEvent.defaultPrevented : !1 === nativeEvent.returnValue) @@ -374,27 +503,53 @@ function recordTouchStart(touch) { } function recordTouchMove(touch) { var touchRecord = touchBank[getTouchIdentifier(touch)]; - touchRecord && - ((touchRecord.touchActive = !0), - (touchRecord.previousPageX = touchRecord.currentPageX), - (touchRecord.previousPageY = touchRecord.currentPageY), - (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), - (touchRecord.currentPageX = touch.pageX), - (touchRecord.currentPageY = touch.pageY), - (touchRecord.currentTimeStamp = timestampForTouch(touch)), - (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))); + touchRecord + ? ((touchRecord.touchActive = !0), + (touchRecord.previousPageX = touchRecord.currentPageX), + (touchRecord.previousPageY = touchRecord.currentPageY), + (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), + (touchRecord.currentPageX = touch.pageX), + (touchRecord.currentPageY = touch.pageY), + (touchRecord.currentTimeStamp = timestampForTouch(touch)), + (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))) + : console.warn( + "Cannot record touch move without a touch start.\nTouch Move: %s\n", + "Touch Bank: %s", + printTouch(touch), + printTouchBank() + ); } function recordTouchEnd(touch) { var touchRecord = touchBank[getTouchIdentifier(touch)]; - touchRecord && - ((touchRecord.touchActive = !1), - (touchRecord.previousPageX = touchRecord.currentPageX), - (touchRecord.previousPageY = touchRecord.currentPageY), - (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), - (touchRecord.currentPageX = touch.pageX), - (touchRecord.currentPageY = touch.pageY), - (touchRecord.currentTimeStamp = timestampForTouch(touch)), - (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))); + touchRecord + ? ((touchRecord.touchActive = !1), + (touchRecord.previousPageX = touchRecord.currentPageX), + (touchRecord.previousPageY = touchRecord.currentPageY), + (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), + (touchRecord.currentPageX = touch.pageX), + (touchRecord.currentPageY = touch.pageY), + (touchRecord.currentTimeStamp = timestampForTouch(touch)), + (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))) + : console.warn( + "Cannot record touch end without a touch start.\nTouch End: %s\n", + "Touch Bank: %s", + printTouch(touch), + printTouchBank() + ); +} +function printTouch(touch) { + return JSON.stringify({ + identifier: touch.identifier, + pageX: touch.pageX, + pageY: touch.pageY, + timestamp: timestampForTouch(touch) + }); +} +function printTouchBank() { + var printed = JSON.stringify(touchBank.slice(0, 20)); + 20 < touchBank.length && + (printed += " (original size: " + touchBank.length + ")"); + return printed; } var ResponderTouchHistoryStore = { recordTouchTrack: function(topLevelType, nativeEvent) { @@ -434,10 +589,10 @@ function accumulate(current, next) { return null == current ? next : Array.isArray(current) - ? current.concat(next) - : Array.isArray(next) - ? [current].concat(next) - : [current, next]; + ? current.concat(next) + : Array.isArray(next) + ? [current].concat(next) + : [current, next]; } var responderInst = null, trackedTouchCount = 0; @@ -527,7 +682,13 @@ var eventTypes = { "topTouchCancel" === topLevelType ) if (0 <= trackedTouchCount) --trackedTouchCount; - else return null; + else + return ( + console.warn( + "Ended a touch event which was not counted in `trackedTouchCount`." + ), + null + ); ResponderTouchHistoryStore.recordTouchTrack(topLevelType, nativeEvent); if ( targetInst && @@ -539,10 +700,10 @@ var eventTypes = { var shouldSetEventType = isStartish(topLevelType) ? eventTypes.startShouldSetResponder : isMoveish(topLevelType) - ? eventTypes.moveShouldSetResponder - : "topSelectionChange" === topLevelType - ? eventTypes.selectionChangeShouldSetResponder - : eventTypes.scrollShouldSetResponder; + ? eventTypes.moveShouldSetResponder + : "topSelectionChange" === topLevelType + ? eventTypes.selectionChangeShouldSetResponder + : eventTypes.scrollShouldSetResponder; if (responderInst) b: { var JSCompiler_temp = responderInst; @@ -696,10 +857,10 @@ var eventTypes = { (shouldSetEventType = shouldSetEventType ? eventTypes.responderStart : JSCompiler_temp - ? eventTypes.responderMove - : targetInst - ? eventTypes.responderEnd - : null) + ? eventTypes.responderMove + : targetInst + ? eventTypes.responderEnd + : null) ) (shouldSetEventType = ResponderSyntheticEvent.getPooled( shouldSetEventType, @@ -762,8 +923,8 @@ var eventTypes = { (topLevelType = shouldSetEventType ? eventTypes.responderTerminate : topLevelType - ? eventTypes.responderRelease - : null) + ? eventTypes.responderRelease + : null) ) (nativeEvent = ResponderSyntheticEvent.getPooled( topLevelType, @@ -787,168 +948,67 @@ var eventTypes = { } } }, - eventPluginOrder = null, - namesToPlugins = {}; -function recomputePluginOrdering() { - if (eventPluginOrder) - for (var pluginName in namesToPlugins) { - var pluginModule = namesToPlugins[pluginName], - pluginIndex = eventPluginOrder.indexOf(pluginName); - if (!(-1 < pluginIndex)) - throw Error( - "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + - pluginName + - "`." - ); - if (!plugins[pluginIndex]) { - if (!pluginModule.extractEvents) - throw Error( - "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + - pluginName + - "` does not." - ); - plugins[pluginIndex] = pluginModule; - pluginIndex = pluginModule.eventTypes; - for (var eventName in pluginIndex) { - var JSCompiler_inline_result = void 0; - var dispatchConfig = pluginIndex[eventName], - pluginModule$jscomp$0 = pluginModule, - eventName$jscomp$0 = eventName; - if (eventNameDispatchConfigs.hasOwnProperty(eventName$jscomp$0)) - throw Error( - "EventPluginRegistry: More than one plugin attempted to publish the same event name, `" + - eventName$jscomp$0 + - "`." - ); - eventNameDispatchConfigs[eventName$jscomp$0] = dispatchConfig; - var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; - if (phasedRegistrationNames) { - for (JSCompiler_inline_result in phasedRegistrationNames) - phasedRegistrationNames.hasOwnProperty( - JSCompiler_inline_result - ) && - publishRegistrationName( - phasedRegistrationNames[JSCompiler_inline_result], - pluginModule$jscomp$0, - eventName$jscomp$0 - ); - JSCompiler_inline_result = !0; - } else - dispatchConfig.registrationName - ? (publishRegistrationName( - dispatchConfig.registrationName, - pluginModule$jscomp$0, - eventName$jscomp$0 - ), - (JSCompiler_inline_result = !0)) - : (JSCompiler_inline_result = !1); - if (!JSCompiler_inline_result) - throw Error( - "EventPluginRegistry: Failed to publish event `" + - eventName + - "` for plugin `" + - pluginName + - "`." - ); - } - } - } -} -function publishRegistrationName(registrationName, pluginModule) { - if (registrationNameModules[registrationName]) - throw Error( - "EventPluginRegistry: More than one plugin attempted to publish the same registration name, `" + - registrationName + - "`." - ); - registrationNameModules[registrationName] = pluginModule; -} -var plugins = [], - eventNameDispatchConfigs = {}, - registrationNameModules = {}, customBubblingEventTypes = ReactNativePrivateInterface.ReactNativeViewConfigRegistry .customBubblingEventTypes, customDirectEventTypes = ReactNativePrivateInterface.ReactNativeViewConfigRegistry .customDirectEventTypes; -if (eventPluginOrder) - throw Error( - "EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React." - ); -eventPluginOrder = Array.prototype.slice.call([ +injection.injectEventPluginOrder([ "ResponderEventPlugin", "ReactNativeBridgeEventPlugin" ]); -recomputePluginOrdering(); -var injectedNamesToPlugins$jscomp$inline_94 = { - ResponderEventPlugin: ResponderEventPlugin, - ReactNativeBridgeEventPlugin: { - eventTypes: {}, - extractEvents: function( - topLevelType, - targetInst, - nativeEvent, - nativeEventTarget - ) { - if (null == targetInst) return null; - var bubbleDispatchConfig = customBubblingEventTypes[topLevelType], - directDispatchConfig = customDirectEventTypes[topLevelType]; - if (!bubbleDispatchConfig && !directDispatchConfig) - throw Error( - 'Unsupported top level event type "' + topLevelType + '" dispatched' - ); - topLevelType = SyntheticEvent.getPooled( - bubbleDispatchConfig || directDispatchConfig, - targetInst, - nativeEvent, - nativeEventTarget - ); - if (bubbleDispatchConfig) - forEachAccumulated(topLevelType, accumulateTwoPhaseDispatchesSingle); - else if (directDispatchConfig) - forEachAccumulated(topLevelType, accumulateDirectDispatchesSingle); - else return null; - return topLevelType; - } - } - }, - isOrderingDirty$jscomp$inline_95 = !1, - pluginName$jscomp$inline_96; -for (pluginName$jscomp$inline_96 in injectedNamesToPlugins$jscomp$inline_94) - if ( - injectedNamesToPlugins$jscomp$inline_94.hasOwnProperty( - pluginName$jscomp$inline_96 - ) - ) { - var pluginModule$jscomp$inline_97 = - injectedNamesToPlugins$jscomp$inline_94[pluginName$jscomp$inline_96]; - if ( - !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_96) || - namesToPlugins[pluginName$jscomp$inline_96] !== - pluginModule$jscomp$inline_97 +injection.injectEventPluginsByName({ + ResponderEventPlugin: ResponderEventPlugin, + ReactNativeBridgeEventPlugin: { + eventTypes: {}, + extractEvents: function( + topLevelType, + targetInst, + nativeEvent, + nativeEventTarget ) { - if (namesToPlugins[pluginName$jscomp$inline_96]) + if (null == targetInst) return null; + var bubbleDispatchConfig = customBubblingEventTypes[topLevelType], + directDispatchConfig = customDirectEventTypes[topLevelType]; + if (!bubbleDispatchConfig && !directDispatchConfig) throw Error( - "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - pluginName$jscomp$inline_96 + - "`." + 'Unsupported top level event type "' + topLevelType + '" dispatched' ); - namesToPlugins[ - pluginName$jscomp$inline_96 - ] = pluginModule$jscomp$inline_97; - isOrderingDirty$jscomp$inline_95 = !0; + topLevelType = SyntheticEvent.getPooled( + bubbleDispatchConfig || directDispatchConfig, + targetInst, + nativeEvent, + nativeEventTarget + ); + if (bubbleDispatchConfig) + forEachAccumulated(topLevelType, accumulateTwoPhaseDispatchesSingle); + else if (directDispatchConfig) + forEachAccumulated(topLevelType, accumulateDirectDispatchesSingle); + else return null; + return topLevelType; } } -isOrderingDirty$jscomp$inline_95 && recomputePluginOrdering(); -var instanceCache = new Map(), +}); +var enableNativeTargetAsInstance = require("../shims/ReactFeatureFlags") + .enableNativeTargetAsInstance, + instanceCache = new Map(), instanceProps = new Map(); function getInstanceFromTag(tag) { return instanceCache.get(tag) || null; } +var restoreTarget = null, + restoreQueue = null; +function restoreStateOfTarget(target) { + if (getInstanceFromNode(target)) + throw Error( + "setRestoreImplementation() needs to be called to handle a target for controlled events. This error is likely caused by a bug in React. Please file an issue." + ); +} function batchedUpdatesImpl(fn, bookkeeping) { return fn(bookkeeping); } +function flushDiscreteUpdatesImpl() {} var isInsideEventHandler = !1; function batchedUpdates(fn, bookkeeping) { if (isInsideEventHandler) return fn(bookkeeping); @@ -956,27 +1016,21 @@ function batchedUpdates(fn, bookkeeping) { try { return batchedUpdatesImpl(fn, bookkeeping); } finally { - isInsideEventHandler = !1; - } -} -var eventQueue = null; -function executeDispatchesAndReleaseTopLevel(e) { - if (e) { - var dispatchListeners = e._dispatchListeners, - dispatchInstances = e._dispatchInstances; - if (Array.isArray(dispatchListeners)) - for ( - var i = 0; - i < dispatchListeners.length && !e.isPropagationStopped(); - i++ + if ( + ((isInsideEventHandler = !1), + null !== restoreTarget || null !== restoreQueue) + ) + if ( + (flushDiscreteUpdatesImpl(), + restoreTarget && + ((bookkeeping = restoreTarget), + (fn = restoreQueue), + (restoreQueue = restoreTarget = null), + restoreStateOfTarget(bookkeeping), + fn)) ) - executeDispatch(e, dispatchListeners[i], dispatchInstances[i]); - else - dispatchListeners && - executeDispatch(e, dispatchListeners, dispatchInstances); - e._dispatchListeners = null; - e._dispatchInstances = null; - e.isPersistent() || e.constructor.release(e); + for (bookkeeping = 0; bookkeeping < fn.length; bookkeeping++) + restoreStateOfTarget(fn[bookkeeping]); } } var EMPTY_NATIVE_EVENT = {}; @@ -984,7 +1038,9 @@ function _receiveRootNodeIDEvent(rootNodeID, topLevelType, nativeEventParam) { var nativeEvent = nativeEventParam || EMPTY_NATIVE_EVENT, inst = getInstanceFromTag(rootNodeID), target = null; - null != inst && (target = inst.stateNode); + enableNativeTargetAsInstance + ? null != inst && (target = inst.stateNode) + : (target = nativeEvent.target); batchedUpdates(function() { var events = target; for (var events$jscomp$0 = null, i = 0; i < plugins.length; i++) { @@ -1059,11 +1115,17 @@ getFiberCurrentPropsFromNode = function(stateNode) { }; getInstanceFromNode = getInstanceFromTag; getNodeFromInstance = function(inst) { - inst = inst.stateNode; - var tag = inst._nativeTag; - void 0 === tag && ((inst = inst.canonical), (tag = inst._nativeTag)); + if (enableNativeTargetAsInstance) { + inst = inst.stateNode; + var tag = inst._nativeTag; + void 0 === tag && ((inst = inst.canonical), (tag = inst._nativeTag)); + if (!tag) throw Error("All native instances should have a tag."); + return inst; + } + tag = inst.stateNode._nativeTag; + void 0 === tag && (tag = inst.stateNode.canonical._nativeTag); if (!tag) throw Error("All native instances should have a tag."); - return inst; + return tag; }; ResponderEventPlugin.injection.injectGlobalResponderHandler({ onChange: function(from, to, blockNativeResponder) { @@ -1098,9 +1160,11 @@ var hasSymbol = "function" === typeof Symbol && Symbol.for, ? Symbol.for("react.suspense_list") : 60120, REACT_MEMO_TYPE = hasSymbol ? Symbol.for("react.memo") : 60115, - REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 60116, - REACT_BLOCK_TYPE = hasSymbol ? Symbol.for("react.block") : 60121, - MAYBE_ITERATOR_SYMBOL = "function" === typeof Symbol && Symbol.iterator; + REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 60116; +hasSymbol && Symbol.for("react.fundamental"); +hasSymbol && Symbol.for("react.responder"); +hasSymbol && Symbol.for("react.scope"); +var MAYBE_ITERATOR_SYMBOL = "function" === typeof Symbol && Symbol.iterator; function getIteratorFn(maybeIterable) { if (null === maybeIterable || "object" !== typeof maybeIterable) return null; maybeIterable = @@ -1110,10 +1174,9 @@ function getIteratorFn(maybeIterable) { } function initializeLazyComponentType(lazyComponent) { if (-1 === lazyComponent._status) { - var ctor = lazyComponent._result; - ctor || (ctor = lazyComponent._ctor); - ctor = ctor(); lazyComponent._status = 0; + var ctor = lazyComponent._ctor; + ctor = ctor(); lazyComponent._result = ctor; ctor.then( function(moduleObject) { @@ -1150,9 +1213,9 @@ function getComponentName(type) { if ("object" === typeof type) switch (type.$$typeof) { case REACT_CONTEXT_TYPE: - return (type.displayName || "Context") + ".Consumer"; + return "Context.Consumer"; case REACT_PROVIDER_TYPE: - return (type._context.displayName || "Context") + ".Provider"; + return "Context.Provider"; case REACT_FORWARD_REF_TYPE: var innerType = type.render; innerType = innerType.displayName || innerType.name || ""; @@ -1162,8 +1225,6 @@ function getComponentName(type) { ); case REACT_MEMO_TYPE: return getComponentName(type.type); - case REACT_BLOCK_TYPE: - return getComponentName(type.render); case REACT_LAZY_TYPE: if ((type = 1 === type._status ? type._result : null)) return getComponentName(type); @@ -1344,8 +1405,8 @@ function diffNestedProperty( return nextProp ? addNestedProperty(updatePayload, nextProp, validAttributes) : prevProp - ? clearNestedProperty(updatePayload, prevProp, validAttributes) - : updatePayload; + ? clearNestedProperty(updatePayload, prevProp, validAttributes) + : updatePayload; if (!Array.isArray(prevProp) && !Array.isArray(nextProp)) return diffProperties(updatePayload, prevProp, nextProp, validAttributes); if (Array.isArray(prevProp) && Array.isArray(nextProp)) { @@ -1523,10 +1584,10 @@ var ReactNativeFiberHostComponent = (function() { } var _proto = ReactNativeFiberHostComponent.prototype; _proto.blur = function() { - ReactNativePrivateInterface.TextInputState.blurTextInput(this); + ReactNativePrivateInterface.TextInputState.blurTextInput(this._nativeTag); }; _proto.focus = function() { - ReactNativePrivateInterface.TextInputState.focusTextInput(this); + ReactNativePrivateInterface.TextInputState.focusTextInput(this._nativeTag); }; _proto.measure = function(callback) { ReactNativePrivateInterface.UIManager.measure( @@ -1570,7 +1631,7 @@ var ReactNativeFiberHostComponent = (function() { }; return ReactNativeFiberHostComponent; })(); -function shim() { +function shim$1() { throw Error( "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." ); @@ -1608,7 +1669,45 @@ function finalizeInitialChildren(parentInstance) { } var scheduleTimeout = setTimeout, cancelTimeout = clearTimeout, - valueStack = [], + BEFORE_SLASH_RE = /^(.*)[\\\/]/; +function getStackByFiberInDevAndProd(workInProgress) { + var info = ""; + do { + a: switch (workInProgress.tag) { + case 3: + case 4: + case 6: + case 7: + case 10: + case 9: + var JSCompiler_inline_result = ""; + break a; + default: + var owner = workInProgress._debugOwner, + source = workInProgress._debugSource, + name = getComponentName(workInProgress.type); + JSCompiler_inline_result = null; + owner && (JSCompiler_inline_result = getComponentName(owner.type)); + owner = name; + name = ""; + source + ? (name = + " (at " + + source.fileName.replace(BEFORE_SLASH_RE, "") + + ":" + + source.lineNumber + + ")") + : JSCompiler_inline_result && + (name = " (created by " + JSCompiler_inline_result + ")"); + JSCompiler_inline_result = "\n in " + (owner || "Unknown") + name; + } + info += JSCompiler_inline_result; + workInProgress = workInProgress.return; + } while (workInProgress); + return info; +} +new Set(); +var valueStack = [], index = -1; function pop(cursor) { 0 > index || @@ -1645,17 +1744,21 @@ function isContextProvider(type) { type = type.childContextTypes; return null !== type && void 0 !== type; } -function popContext() { - pop(didPerformWorkStackCursor); - pop(contextStackCursor); +function popContext(fiber) { + pop(didPerformWorkStackCursor, fiber); + pop(contextStackCursor, fiber); +} +function popTopLevelContextObject(fiber) { + pop(didPerformWorkStackCursor, fiber); + pop(contextStackCursor, fiber); } 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); + push(contextStackCursor, context, fiber); + push(didPerformWorkStackCursor, didChange, fiber); } function processChildContext(fiber, type, parentContext) { var instance = fiber.stateNode; @@ -1673,13 +1776,17 @@ function processChildContext(fiber, type, parentContext) { return Object.assign({}, parentContext, {}, instance); } function pushContextProvider(workInProgress) { - workInProgress = - ((workInProgress = workInProgress.stateNode) && - workInProgress.__reactInternalMemoizedMergedChildContext) || + var instance = workInProgress.stateNode; + instance = + (instance && instance.__reactInternalMemoizedMergedChildContext) || emptyContextObject; previousContext = contextStackCursor.current; - push(contextStackCursor, workInProgress); - push(didPerformWorkStackCursor, didPerformWorkStackCursor.current); + push(contextStackCursor, instance, workInProgress); + push( + didPerformWorkStackCursor, + didPerformWorkStackCursor.current, + workInProgress + ); return !0; } function invalidateContextProvider(workInProgress, type, didChange) { @@ -1689,17 +1796,13 @@ function invalidateContextProvider(workInProgress, type, didChange) { "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); + ? ((type = processChildContext(workInProgress, type, previousContext)), + (instance.__reactInternalMemoizedMergedChildContext = type), + pop(didPerformWorkStackCursor, workInProgress), + pop(contextStackCursor, workInProgress), + push(contextStackCursor, type, workInProgress)) + : pop(didPerformWorkStackCursor, workInProgress); + push(didPerformWorkStackCursor, didChange, workInProgress); } var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback, @@ -1826,18 +1929,18 @@ function inferPriorityFromExpirationTime(currentTime, expirationTime) { return 0 >= currentTime ? 99 : 250 >= currentTime - ? 98 - : 5250 >= currentTime - ? 97 - : 95; + ? 98 + : 5250 >= currentTime + ? 97 + : 95; } function is(x, y) { return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y); } -var objectIs = "function" === typeof Object.is ? Object.is : is, +var is$1 = "function" === typeof Object.is ? Object.is : is, hasOwnProperty = Object.prototype.hasOwnProperty; function shallowEqual(objA, objB) { - if (objectIs(objA, objB)) return !0; + if (is$1(objA, objB)) return !0; if ( "object" !== typeof objA || null === objA || @@ -1851,48 +1954,11 @@ function shallowEqual(objA, objB) { for (keysB = 0; keysB < keysA.length; keysB++) if ( !hasOwnProperty.call(objB, keysA[keysB]) || - !objectIs(objA[keysA[keysB]], objB[keysA[keysB]]) + !is$1(objA[keysA[keysB]], objB[keysA[keysB]]) ) return !1; return !0; } -var BEFORE_SLASH_RE = /^(.*)[\\\/]/; -function getStackByFiberInDevAndProd(workInProgress) { - var info = ""; - do { - a: switch (workInProgress.tag) { - case 3: - case 4: - case 6: - case 7: - case 10: - case 9: - var JSCompiler_inline_result = ""; - break a; - default: - var owner = workInProgress._debugOwner, - source = workInProgress._debugSource, - name = getComponentName(workInProgress.type); - JSCompiler_inline_result = null; - owner && (JSCompiler_inline_result = getComponentName(owner.type)); - owner = name; - name = ""; - source - ? (name = - " (at " + - source.fileName.replace(BEFORE_SLASH_RE, "") + - ":" + - source.lineNumber + - ")") - : JSCompiler_inline_result && - (name = " (created by " + JSCompiler_inline_result + ")"); - JSCompiler_inline_result = "\n in " + (owner || "Unknown") + name; - } - info += JSCompiler_inline_result; - workInProgress = workInProgress.return; - } while (workInProgress); - return info; -} function resolveDefaultProps(Component, baseProps) { if (Component && Component.defaultProps) { baseProps = Object.assign({}, baseProps); @@ -1910,9 +1976,14 @@ var valueCursor = { current: null }, function resetContextDependencies() { lastContextWithAllBitsObserved = lastContextDependency = currentlyRenderingFiber = null; } +function pushProvider(providerFiber, nextValue) { + var context = providerFiber.type._context; + push(valueCursor, context._currentValue, providerFiber); + context._currentValue = nextValue; +} function popProvider(providerFiber) { var currentValue = valueCursor.current; - pop(valueCursor); + pop(valueCursor, providerFiber); providerFiber.type._context._currentValue = currentValue; } function scheduleWorkOnParentPath(parent, renderExpirationTime) { @@ -1967,195 +2038,237 @@ function readContext(context, observedBits) { return context._currentValue; } var hasForceUpdate = !1; -function initializeUpdateQueue(fiber) { - fiber.updateQueue = { - baseState: fiber.memoizedState, - baseQueue: null, - shared: { pending: null }, - effects: null +function createUpdateQueue(baseState) { + return { + baseState: baseState, + firstUpdate: null, + lastUpdate: null, + firstCapturedUpdate: null, + lastCapturedUpdate: null, + firstEffect: null, + lastEffect: null, + firstCapturedEffect: null, + lastCapturedEffect: null }; } -function cloneUpdateQueue(current, workInProgress) { - current = current.updateQueue; - workInProgress.updateQueue === current && - (workInProgress.updateQueue = { - baseState: current.baseState, - baseQueue: current.baseQueue, - shared: current.shared, - effects: current.effects - }); +function cloneUpdateQueue(currentQueue) { + return { + baseState: currentQueue.baseState, + firstUpdate: currentQueue.firstUpdate, + lastUpdate: currentQueue.lastUpdate, + firstCapturedUpdate: null, + lastCapturedUpdate: null, + firstEffect: null, + lastEffect: null, + firstCapturedEffect: null, + lastCapturedEffect: null + }; } function createUpdate(expirationTime, suspenseConfig) { - expirationTime = { + return { expirationTime: expirationTime, suspenseConfig: suspenseConfig, tag: 0, payload: null, callback: null, - next: null + next: null, + nextEffect: null }; - return (expirationTime.next = expirationTime); +} +function appendUpdateToQueue(queue, update) { + null === queue.lastUpdate + ? (queue.firstUpdate = queue.lastUpdate = update) + : ((queue.lastUpdate.next = update), (queue.lastUpdate = update)); } function enqueueUpdate(fiber, update) { - 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; - } + var alternate = fiber.alternate; + if (null === alternate) { + var queue1 = fiber.updateQueue; + var queue2 = null; + null === queue1 && + (queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState)); + } else + (queue1 = fiber.updateQueue), + (queue2 = alternate.updateQueue), + null === queue1 + ? null === queue2 + ? ((queue1 = fiber.updateQueue = createUpdateQueue( + fiber.memoizedState + )), + (queue2 = alternate.updateQueue = createUpdateQueue( + alternate.memoizedState + ))) + : (queue1 = fiber.updateQueue = cloneUpdateQueue(queue2)) + : null === queue2 && + (queue2 = alternate.updateQueue = cloneUpdateQueue(queue1)); + null === queue2 || queue1 === queue2 + ? appendUpdateToQueue(queue1, update) + : null === queue1.lastUpdate || null === queue2.lastUpdate + ? (appendUpdateToQueue(queue1, update), + appendUpdateToQueue(queue2, update)) + : (appendUpdateToQueue(queue1, update), (queue2.lastUpdate = update)); } function enqueueCapturedUpdate(workInProgress, update) { + var workInProgressQueue = workInProgress.updateQueue; + workInProgressQueue = + null === workInProgressQueue + ? (workInProgress.updateQueue = createUpdateQueue( + workInProgress.memoizedState + )) + : ensureWorkInProgressQueueIsAClone(workInProgress, workInProgressQueue); + null === workInProgressQueue.lastCapturedUpdate + ? (workInProgressQueue.firstCapturedUpdate = workInProgressQueue.lastCapturedUpdate = update) + : ((workInProgressQueue.lastCapturedUpdate.next = update), + (workInProgressQueue.lastCapturedUpdate = update)); +} +function ensureWorkInProgressQueueIsAClone(workInProgress, queue) { var current = workInProgress.alternate; - null !== current && cloneUpdateQueue(current, workInProgress); - workInProgress = workInProgress.updateQueue; - current = workInProgress.baseQueue; - null === current - ? ((workInProgress.baseQueue = update.next = update), - (update.next = update)) - : ((update.next = current.next), (current.next = update)); + null !== current && + queue === current.updateQueue && + (queue = workInProgress.updateQueue = cloneUpdateQueue(queue)); + return queue; +} +function getStateFromUpdate( + workInProgress, + queue, + update, + prevState, + nextProps, + instance +) { + switch (update.tag) { + case 1: + return ( + (workInProgress = update.payload), + "function" === typeof workInProgress + ? workInProgress.call(instance, prevState, nextProps) + : workInProgress + ); + case 3: + workInProgress.effectTag = (workInProgress.effectTag & -4097) | 64; + case 0: + workInProgress = update.payload; + nextProps = + "function" === typeof workInProgress + ? workInProgress.call(instance, prevState, nextProps) + : workInProgress; + if (null === nextProps || void 0 === nextProps) break; + return Object.assign({}, prevState, nextProps); + case 2: + hasForceUpdate = !0; + } + return prevState; } function processUpdateQueue( - workInProgress$jscomp$0, + workInProgress, + queue, props, instance, renderExpirationTime ) { - var queue = workInProgress$jscomp$0.updateQueue; hasForceUpdate = !1; - var baseQueue = queue.baseQueue, - pendingQueue = queue.shared.pending; - if (null !== pendingQueue) { - if (null !== baseQueue) { - var baseFirst = baseQueue.next; - baseQueue.next = pendingQueue.next; - pendingQueue.next = baseFirst; - } - baseQueue = pendingQueue; - queue.shared.pending = null; - baseFirst = workInProgress$jscomp$0.alternate; - null !== baseFirst && - ((baseFirst = baseFirst.updateQueue), - null !== baseFirst && (baseFirst.baseQueue = pendingQueue)); - } - if (null !== baseQueue) { - baseFirst = baseQueue.next; - var newState = queue.baseState, + queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue); + for ( + var newBaseState = queue.baseState, + newFirstUpdate = null, newExpirationTime = 0, - newBaseState = null, - newBaseQueueFirst = null, - newBaseQueueLast = null; - if (null !== baseFirst) { - var update = baseFirst; - do { - pendingQueue = update.expirationTime; - if (pendingQueue < renderExpirationTime) { - var clone = { - expirationTime: update.expirationTime, - suspenseConfig: update.suspenseConfig, - tag: update.tag, - payload: update.payload, - callback: update.callback, - next: null - }; - null === newBaseQueueLast - ? ((newBaseQueueFirst = newBaseQueueLast = clone), - (newBaseState = newState)) - : (newBaseQueueLast = newBaseQueueLast.next = clone); - pendingQueue > newExpirationTime && - (newExpirationTime = pendingQueue); - } else { - null !== newBaseQueueLast && - (newBaseQueueLast = newBaseQueueLast.next = { - expirationTime: 1073741823, - suspenseConfig: update.suspenseConfig, - tag: update.tag, - payload: update.payload, - callback: update.callback, - next: null - }); - markRenderEventTimeAndConfig(pendingQueue, update.suspenseConfig); - a: { - var workInProgress = workInProgress$jscomp$0, - update$jscomp$0 = update; - pendingQueue = props; - clone = instance; - switch (update$jscomp$0.tag) { - case 1: - workInProgress = update$jscomp$0.payload; - if ("function" === typeof workInProgress) { - newState = workInProgress.call(clone, newState, pendingQueue); - break a; - } - newState = workInProgress; - break a; - case 3: - workInProgress.effectTag = - (workInProgress.effectTag & -4097) | 64; - case 0: - workInProgress = update$jscomp$0.payload; - pendingQueue = - "function" === typeof workInProgress - ? workInProgress.call(clone, newState, pendingQueue) - : workInProgress; - if (null === pendingQueue || void 0 === pendingQueue) break a; - newState = Object.assign({}, newState, pendingQueue); - break a; - case 2: - hasForceUpdate = !0; - } - } - null !== update.callback && - ((workInProgress$jscomp$0.effectTag |= 32), - (pendingQueue = queue.effects), - null === pendingQueue - ? (queue.effects = [update]) - : pendingQueue.push(update)); - } - update = update.next; - if (null === update || update === baseFirst) - if (((pendingQueue = queue.shared.pending), null === pendingQueue)) - break; - else - (update = baseQueue.next = pendingQueue.next), - (pendingQueue.next = baseFirst), - (queue.baseQueue = baseQueue = pendingQueue), - (queue.shared.pending = null); - } while (1); - } - null === newBaseQueueLast - ? (newBaseState = newState) - : (newBaseQueueLast.next = newBaseQueueFirst); - queue.baseState = newBaseState; - queue.baseQueue = newBaseQueueLast; - markUnprocessedUpdateTime(newExpirationTime); - workInProgress$jscomp$0.expirationTime = newExpirationTime; - workInProgress$jscomp$0.memoizedState = newState; + update = queue.firstUpdate, + resultState = newBaseState; + null !== update; + + ) { + var updateExpirationTime = update.expirationTime; + updateExpirationTime < renderExpirationTime + ? (null === newFirstUpdate && + ((newFirstUpdate = update), (newBaseState = resultState)), + newExpirationTime < updateExpirationTime && + (newExpirationTime = updateExpirationTime)) + : (markRenderEventTimeAndConfig( + updateExpirationTime, + update.suspenseConfig + ), + (resultState = getStateFromUpdate( + workInProgress, + queue, + update, + resultState, + props, + instance + )), + null !== update.callback && + ((workInProgress.effectTag |= 32), + (update.nextEffect = null), + null === queue.lastEffect + ? (queue.firstEffect = queue.lastEffect = update) + : ((queue.lastEffect.nextEffect = update), + (queue.lastEffect = update)))); + update = update.next; } + updateExpirationTime = null; + for (update = queue.firstCapturedUpdate; null !== update; ) { + var _updateExpirationTime = update.expirationTime; + _updateExpirationTime < renderExpirationTime + ? (null === updateExpirationTime && + ((updateExpirationTime = update), + null === newFirstUpdate && (newBaseState = resultState)), + newExpirationTime < _updateExpirationTime && + (newExpirationTime = _updateExpirationTime)) + : ((resultState = getStateFromUpdate( + workInProgress, + queue, + update, + resultState, + props, + instance + )), + null !== update.callback && + ((workInProgress.effectTag |= 32), + (update.nextEffect = null), + null === queue.lastCapturedEffect + ? (queue.firstCapturedEffect = queue.lastCapturedEffect = update) + : ((queue.lastCapturedEffect.nextEffect = update), + (queue.lastCapturedEffect = update)))); + update = update.next; + } + null === newFirstUpdate && (queue.lastUpdate = null); + null === updateExpirationTime + ? (queue.lastCapturedUpdate = null) + : (workInProgress.effectTag |= 32); + null === newFirstUpdate && + null === updateExpirationTime && + (newBaseState = resultState); + queue.baseState = newBaseState; + queue.firstUpdate = newFirstUpdate; + queue.firstCapturedUpdate = updateExpirationTime; + markUnprocessedUpdateTime(newExpirationTime); + workInProgress.expirationTime = newExpirationTime; + workInProgress.memoizedState = resultState; } function commitUpdateQueue(finishedWork, finishedQueue, instance) { - finishedWork = finishedQueue.effects; - finishedQueue.effects = null; - if (null !== finishedWork) - for ( - finishedQueue = 0; - finishedQueue < finishedWork.length; - finishedQueue++ - ) { - var effect = finishedWork[finishedQueue], - callback = effect.callback; - if (null !== callback) { - effect.callback = null; - if ("function" !== typeof callback) - throw Error( - "Invalid argument passed as callback. Expected a function. Instead received: " + - callback - ); - callback.call(instance); - } + null !== finishedQueue.firstCapturedUpdate && + (null !== finishedQueue.lastUpdate && + ((finishedQueue.lastUpdate.next = finishedQueue.firstCapturedUpdate), + (finishedQueue.lastUpdate = finishedQueue.lastCapturedUpdate)), + (finishedQueue.firstCapturedUpdate = finishedQueue.lastCapturedUpdate = null)); + commitUpdateEffects(finishedQueue.firstEffect, instance); + finishedQueue.firstEffect = finishedQueue.lastEffect = null; + commitUpdateEffects(finishedQueue.firstCapturedEffect, instance); + finishedQueue.firstCapturedEffect = finishedQueue.lastCapturedEffect = null; +} +function commitUpdateEffects(effect, instance) { + for (; null !== effect; ) { + var callback = effect.callback; + if (null !== callback) { + effect.callback = null; + if ("function" !== typeof callback) + throw Error( + "Invalid argument passed as callback. Expected a function. Instead received: " + + callback + ); + callback.call(instance); } + effect = effect.nextEffect; + } } var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig, emptyRefsObject = new React.Component().refs; @@ -2172,8 +2285,10 @@ function applyDerivedStateFromProps( ? ctor : Object.assign({}, ctor, getDerivedStateFromProps); workInProgress.memoizedState = getDerivedStateFromProps; - 0 === workInProgress.expirationTime && - (workInProgress.updateQueue.baseState = getDerivedStateFromProps); + nextProps = workInProgress.updateQueue; + null !== nextProps && + 0 === workInProgress.expirationTime && + (nextProps.baseState = getDerivedStateFromProps); } var classComponentUpdater = { isMounted: function(component) { @@ -2192,7 +2307,7 @@ var classComponentUpdater = { null !== callback && (suspenseConfig.callback = callback); enqueueUpdate(inst, suspenseConfig); - scheduleWork(inst, currentTime); + scheduleUpdateOnFiber(inst, currentTime); }, enqueueReplaceState: function(inst, payload, callback) { inst = inst._reactInternalFiber; @@ -2206,7 +2321,7 @@ var classComponentUpdater = { null !== callback && (suspenseConfig.callback = callback); enqueueUpdate(inst, suspenseConfig); - scheduleWork(inst, currentTime); + scheduleUpdateOnFiber(inst, currentTime); }, enqueueForceUpdate: function(inst, callback) { inst = inst._reactInternalFiber; @@ -2219,7 +2334,7 @@ var classComponentUpdater = { null !== callback && (suspenseConfig.callback = callback); enqueueUpdate(inst, suspenseConfig); - scheduleWork(inst, currentTime); + scheduleUpdateOnFiber(inst, currentTime); } }; function checkShouldComponentUpdate( @@ -2235,8 +2350,8 @@ function checkShouldComponentUpdate( return "function" === typeof workInProgress.shouldComponentUpdate ? workInProgress.shouldComponentUpdate(newProps, newState, nextContext) : ctor.prototype && ctor.prototype.isPureReactComponent - ? !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState) - : !0; + ? !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState) + : !0; } function constructClassInstance(workInProgress, ctor, props) { var isLegacyContextConsumer = !1, @@ -2288,7 +2403,6 @@ function mountClassInstance( instance.props = newProps; instance.state = workInProgress.memoizedState; instance.refs = emptyRefsObject; - initializeUpdateQueue(workInProgress); var contextType = ctor.contextType; "object" === typeof contextType && null !== contextType ? (instance.context = readContext(contextType)) @@ -2296,8 +2410,16 @@ function mountClassInstance( ? previousContext : contextStackCursor.current), (instance.context = getMaskedContext(workInProgress, contextType))); - processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); - instance.state = workInProgress.memoizedState; + contextType = workInProgress.updateQueue; + null !== contextType && + (processUpdateQueue( + workInProgress, + contextType, + newProps, + instance, + renderExpirationTime + ), + (instance.state = workInProgress.memoizedState)); contextType = ctor.getDerivedStateFromProps; "function" === typeof contextType && (applyDerivedStateFromProps(workInProgress, ctor, contextType, newProps), @@ -2313,18 +2435,21 @@ function mountClassInstance( instance.UNSAFE_componentWillMount(), ctor !== instance.state && classComponentUpdater.enqueueReplaceState(instance, instance.state, null), - processUpdateQueue( - workInProgress, - newProps, - instance, - renderExpirationTime - ), - (instance.state = workInProgress.memoizedState)); + (contextType = workInProgress.updateQueue), + null !== contextType && + (processUpdateQueue( + workInProgress, + contextType, + newProps, + instance, + renderExpirationTime + ), + (instance.state = workInProgress.memoizedState))); "function" === typeof instance.componentDidMount && (workInProgress.effectTag |= 4); } var isArray = Array.isArray; -function coerceRef(returnFiber, current, element) { +function coerceRef(returnFiber, current$$1, element) { returnFiber = element.ref; if ( null !== returnFiber && @@ -2336,7 +2461,7 @@ function coerceRef(returnFiber, current, element) { if (element) { if (1 !== element.tag) throw Error( - "Function components cannot have string refs. We recommend using useRef() instead. Learn more about using refs safely here: https://fb.me/react-strict-mode-string-ref" + "Function components cannot have refs. Did you mean to use React.forwardRef()?" ); var inst = element.stateNode; } @@ -2348,19 +2473,19 @@ function coerceRef(returnFiber, current, element) { ); var stringRef = "" + returnFiber; if ( - null !== current && - null !== current.ref && - "function" === typeof current.ref && - current.ref._stringRef === stringRef + null !== current$$1 && + null !== current$$1.ref && + "function" === typeof current$$1.ref && + current$$1.ref._stringRef === stringRef ) - return current.ref; - current = function(value) { + return current$$1.ref; + current$$1 = function(value) { var refs = inst.refs; refs === emptyRefsObject && (refs = inst.refs = {}); null === value ? delete refs[stringRef] : (refs[stringRef] = value); }; - current._stringRef = stringRef; - return current; + current$$1._stringRef = stringRef; + return current$$1; } if ("string" !== typeof returnFiber) throw Error( @@ -2412,8 +2537,8 @@ function ChildReconciler(shouldTrackSideEffects) { (currentFirstChild = currentFirstChild.sibling); return returnFiber; } - function useFiber(fiber, pendingProps) { - fiber = createWorkInProgress(fiber, pendingProps); + function useFiber(fiber, pendingProps, expirationTime) { + fiber = createWorkInProgress(fiber, pendingProps, expirationTime); fiber.index = 0; fiber.sibling = null; return fiber; @@ -2438,26 +2563,31 @@ function ChildReconciler(shouldTrackSideEffects) { (newFiber.effectTag = 2); return newFiber; } - function updateTextNode(returnFiber, current, textContent, expirationTime) { - if (null === current || 6 !== current.tag) + function updateTextNode( + returnFiber, + current$$1, + textContent, + expirationTime + ) { + if (null === current$$1 || 6 !== current$$1.tag) return ( - (current = createFiberFromText( + (current$$1 = createFiberFromText( textContent, returnFiber.mode, expirationTime )), - (current.return = returnFiber), - current + (current$$1.return = returnFiber), + current$$1 ); - current = useFiber(current, textContent); - current.return = returnFiber; - return current; + current$$1 = useFiber(current$$1, textContent, expirationTime); + current$$1.return = returnFiber; + return current$$1; } - function updateElement(returnFiber, current, element, expirationTime) { - if (null !== current && current.elementType === element.type) + function updateElement(returnFiber, current$$1, element, expirationTime) { + if (null !== current$$1 && current$$1.elementType === element.type) return ( - (expirationTime = useFiber(current, element.props)), - (expirationTime.ref = coerceRef(returnFiber, current, element)), + (expirationTime = useFiber(current$$1, element.props, expirationTime)), + (expirationTime.ref = coerceRef(returnFiber, current$$1, element)), (expirationTime.return = returnFiber), expirationTime ); @@ -2469,45 +2599,51 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime ); - expirationTime.ref = coerceRef(returnFiber, current, element); + expirationTime.ref = coerceRef(returnFiber, current$$1, element); expirationTime.return = returnFiber; return expirationTime; } - function updatePortal(returnFiber, current, portal, expirationTime) { + function updatePortal(returnFiber, current$$1, portal, expirationTime) { if ( - null === current || - 4 !== current.tag || - current.stateNode.containerInfo !== portal.containerInfo || - current.stateNode.implementation !== portal.implementation + null === current$$1 || + 4 !== current$$1.tag || + current$$1.stateNode.containerInfo !== portal.containerInfo || + current$$1.stateNode.implementation !== portal.implementation ) return ( - (current = createFiberFromPortal( + (current$$1 = createFiberFromPortal( portal, returnFiber.mode, expirationTime )), - (current.return = returnFiber), - current + (current$$1.return = returnFiber), + current$$1 ); - current = useFiber(current, portal.children || []); - current.return = returnFiber; - return current; + current$$1 = useFiber(current$$1, portal.children || [], expirationTime); + current$$1.return = returnFiber; + return current$$1; } - function updateFragment(returnFiber, current, fragment, expirationTime, key) { - if (null === current || 7 !== current.tag) + function updateFragment( + returnFiber, + current$$1, + fragment, + expirationTime, + key + ) { + if (null === current$$1 || 7 !== current$$1.tag) return ( - (current = createFiberFromFragment( + (current$$1 = createFiberFromFragment( fragment, returnFiber.mode, expirationTime, key )), - (current.return = returnFiber), - current + (current$$1.return = returnFiber), + current$$1 ); - current = useFiber(current, fragment); - current.return = returnFiber; - return current; + current$$1 = useFiber(current$$1, fragment, expirationTime); + current$$1.return = returnFiber; + return current$$1; } function createChild(returnFiber, newChild, expirationTime) { if ("string" === typeof newChild || "number" === typeof newChild) @@ -2870,48 +3006,39 @@ function ChildReconciler(shouldTrackSideEffects) { 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; - } + if (isUnkeyedTopLevelFragment.key === isObject) + if ( + 7 === isUnkeyedTopLevelFragment.tag + ? newChild.type === REACT_FRAGMENT_TYPE + : isUnkeyedTopLevelFragment.elementType === newChild.type + ) { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment.sibling + ); + currentFirstChild = useFiber( + isUnkeyedTopLevelFragment, + newChild.type === REACT_FRAGMENT_TYPE + ? newChild.props.children + : newChild.props, + expirationTime + ); + currentFirstChild.ref = coerceRef( + returnFiber, + isUnkeyedTopLevelFragment, + newChild + ); + currentFirstChild.return = returnFiber; + returnFiber = currentFirstChild; + break a; + } else { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment + ); + break; } - deleteRemainingChildren(returnFiber, isUnkeyedTopLevelFragment); - break; - } else deleteChild(returnFiber, isUnkeyedTopLevelFragment); + else deleteChild(returnFiber, isUnkeyedTopLevelFragment); isUnkeyedTopLevelFragment = isUnkeyedTopLevelFragment.sibling; } newChild.type === REACT_FRAGMENT_TYPE @@ -2961,7 +3088,8 @@ function ChildReconciler(shouldTrackSideEffects) { ); currentFirstChild = useFiber( currentFirstChild, - newChild.children || [] + newChild.children || [], + expirationTime ); currentFirstChild.return = returnFiber; returnFiber = currentFirstChild; @@ -2988,7 +3116,11 @@ function ChildReconciler(shouldTrackSideEffects) { (newChild = "" + newChild), null !== currentFirstChild && 6 === currentFirstChild.tag ? (deleteRemainingChildren(returnFiber, currentFirstChild.sibling), - (currentFirstChild = useFiber(currentFirstChild, newChild)), + (currentFirstChild = useFiber( + currentFirstChild, + newChild, + expirationTime + )), (currentFirstChild.return = returnFiber), (returnFiber = currentFirstChild)) : (deleteRemainingChildren(returnFiber, currentFirstChild), @@ -3043,16 +3175,16 @@ function requiredContext(c) { return c; } function pushHostContainer(fiber, nextRootInstance) { - push(rootInstanceStackCursor, nextRootInstance); - push(contextFiberStackCursor, fiber); - push(contextStackCursor$1, NO_CONTEXT); - pop(contextStackCursor$1); - push(contextStackCursor$1, { isInAParentText: !1 }); + push(rootInstanceStackCursor, nextRootInstance, fiber); + push(contextFiberStackCursor, fiber, fiber); + push(contextStackCursor$1, NO_CONTEXT, fiber); + pop(contextStackCursor$1, fiber); + push(contextStackCursor$1, { isInAParentText: !1 }, fiber); } -function popHostContainer() { - pop(contextStackCursor$1); - pop(contextFiberStackCursor); - pop(rootInstanceStackCursor); +function popHostContainer(fiber) { + pop(contextStackCursor$1, fiber); + pop(contextFiberStackCursor, fiber); + pop(rootInstanceStackCursor, fiber); } function pushHostContext(fiber) { requiredContext(rootInstanceStackCursor.current); @@ -3069,19 +3201,23 @@ function pushHostContext(fiber) { ? { isInAParentText: nextContext } : context; context !== nextContext && - (push(contextFiberStackCursor, fiber), - push(contextStackCursor$1, nextContext)); + (push(contextFiberStackCursor, fiber, fiber), + push(contextStackCursor$1, nextContext, fiber)); } function popHostContext(fiber) { contextFiberStackCursor.current === fiber && - (pop(contextStackCursor$1), pop(contextFiberStackCursor)); + (pop(contextStackCursor$1, fiber), pop(contextFiberStackCursor, fiber)); } var suspenseStackCursor = { current: 0 }; function findFirstSuspended(row) { for (var node = row; null !== node; ) { if (13 === node.tag) { var state = node.memoizedState; - if (null !== state && (null === state.dehydrated || shim() || shim())) + if ( + null !== state && + ((state = state.dehydrated), + null === state || shim$1(state) || shim$1(state)) + ) return node; } else if (19 === node.tag && void 0 !== node.memoizedProps.revealOrder) { if (0 !== (node.effectTag & 64)) return node; @@ -3100,16 +3236,24 @@ function findFirstSuspended(row) { } return null; } -function createDeprecatedResponderListener(responder, props) { +function createResponderListener(responder, props) { return { responder: responder, props: props }; } -var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher, +var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig, - renderExpirationTime = 0, + renderExpirationTime$1 = 0, currentlyRenderingFiber$1 = null, currentHook = null, + nextCurrentHook = null, + firstWorkInProgressHook = null, workInProgressHook = null, - didScheduleRenderPhaseUpdate = !1; + nextWorkInProgressHook = null, + remainingExpirationTime = 0, + componentUpdateQueue = null, + sideEffectTag = 0, + didScheduleRenderPhaseUpdate = !1, + renderPhaseUpdates = null, + numberOfReRenders = 0; function throwInvalidHookError() { throw Error( "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem." @@ -3118,7 +3262,7 @@ function throwInvalidHookError() { function areHookInputsEqual(nextDeps, prevDeps) { if (null === prevDeps) return !1; for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) - if (!objectIs(nextDeps[i], prevDeps[i])) return !1; + if (!is$1(nextDeps[i], prevDeps[i])) return !1; return !0; } function renderWithHooks( @@ -3126,85 +3270,92 @@ function renderWithHooks( workInProgress, Component, props, - secondArg, + refOrContext, nextRenderExpirationTime ) { - renderExpirationTime = nextRenderExpirationTime; + renderExpirationTime$1 = nextRenderExpirationTime; currentlyRenderingFiber$1 = workInProgress; - workInProgress.memoizedState = null; - workInProgress.updateQueue = null; - workInProgress.expirationTime = 0; - ReactCurrentDispatcher.current = - null === current || null === current.memoizedState - ? HooksDispatcherOnMount - : HooksDispatcherOnUpdate; - current = Component(props, secondArg); - if (workInProgress.expirationTime === renderExpirationTime) { - nextRenderExpirationTime = 0; - do { - workInProgress.expirationTime = 0; - if (!(25 > nextRenderExpirationTime)) - throw Error( - "Too many re-renders. React limits the number of renders to prevent an infinite loop." - ); - nextRenderExpirationTime += 1; - workInProgressHook = currentHook = null; - workInProgress.updateQueue = null; - ReactCurrentDispatcher.current = HooksDispatcherOnRerender; - current = Component(props, secondArg); - } while (workInProgress.expirationTime === renderExpirationTime); + nextCurrentHook = null !== current ? current.memoizedState : null; + ReactCurrentDispatcher$1.current = + null === nextCurrentHook ? HooksDispatcherOnMount : HooksDispatcherOnUpdate; + workInProgress = Component(props, refOrContext); + if (didScheduleRenderPhaseUpdate) { + do + (didScheduleRenderPhaseUpdate = !1), + (numberOfReRenders += 1), + (nextCurrentHook = null !== current ? current.memoizedState : null), + (nextWorkInProgressHook = firstWorkInProgressHook), + (componentUpdateQueue = workInProgressHook = currentHook = null), + (ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdate), + (workInProgress = Component(props, refOrContext)); + while (didScheduleRenderPhaseUpdate); + renderPhaseUpdates = null; + numberOfReRenders = 0; } - ReactCurrentDispatcher.current = ContextOnlyDispatcher; - workInProgress = null !== currentHook && null !== currentHook.next; - renderExpirationTime = 0; - workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; - didScheduleRenderPhaseUpdate = !1; - if (workInProgress) + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; + current = currentlyRenderingFiber$1; + current.memoizedState = firstWorkInProgressHook; + current.expirationTime = remainingExpirationTime; + current.updateQueue = componentUpdateQueue; + current.effectTag |= sideEffectTag; + current = null !== currentHook && null !== currentHook.next; + renderExpirationTime$1 = 0; + nextWorkInProgressHook = workInProgressHook = firstWorkInProgressHook = nextCurrentHook = currentHook = currentlyRenderingFiber$1 = null; + remainingExpirationTime = 0; + componentUpdateQueue = null; + sideEffectTag = 0; + if (current) throw Error( "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." ); - return current; + return workInProgress; +} +function resetHooks() { + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; + renderExpirationTime$1 = 0; + nextWorkInProgressHook = workInProgressHook = firstWorkInProgressHook = nextCurrentHook = currentHook = currentlyRenderingFiber$1 = null; + remainingExpirationTime = 0; + componentUpdateQueue = null; + sideEffectTag = 0; + didScheduleRenderPhaseUpdate = !1; + renderPhaseUpdates = null; + numberOfReRenders = 0; } function mountWorkInProgressHook() { var hook = { memoizedState: null, baseState: null, - baseQueue: null, queue: null, + baseUpdate: null, next: null }; null === workInProgressHook - ? (currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook) + ? (firstWorkInProgressHook = workInProgressHook = hook) : (workInProgressHook = workInProgressHook.next = hook); return workInProgressHook; } function updateWorkInProgressHook() { - if (null === currentHook) { - var nextCurrentHook = currentlyRenderingFiber$1.alternate; - nextCurrentHook = - null !== nextCurrentHook ? nextCurrentHook.memoizedState : null; - } else nextCurrentHook = currentHook.next; - var nextWorkInProgressHook = - null === workInProgressHook - ? currentlyRenderingFiber$1.memoizedState - : workInProgressHook.next; if (null !== nextWorkInProgressHook) (workInProgressHook = nextWorkInProgressHook), - (currentHook = nextCurrentHook); + (nextWorkInProgressHook = workInProgressHook.next), + (currentHook = nextCurrentHook), + (nextCurrentHook = null !== currentHook ? currentHook.next : null); else { if (null === nextCurrentHook) throw Error("Rendered more hooks than during the previous render."); currentHook = nextCurrentHook; - nextCurrentHook = { + var newHook = { memoizedState: currentHook.memoizedState, baseState: currentHook.baseState, - baseQueue: currentHook.baseQueue, queue: currentHook.queue, + baseUpdate: currentHook.baseUpdate, next: null }; - null === workInProgressHook - ? (currentlyRenderingFiber$1.memoizedState = workInProgressHook = nextCurrentHook) - : (workInProgressHook = workInProgressHook.next = nextCurrentHook); + workInProgressHook = + null === workInProgressHook + ? (firstWorkInProgressHook = newHook) + : (workInProgressHook.next = newHook); + nextCurrentHook = currentHook.next; } return workInProgressHook; } @@ -3219,100 +3370,74 @@ function updateReducer(reducer) { "Should have a queue. This is likely a bug in React. Please file an issue." ); queue.lastRenderedReducer = reducer; - var current = currentHook, - baseQueue = current.baseQueue, - pendingQueue = queue.pending; - if (null !== pendingQueue) { - if (null !== baseQueue) { - var baseFirst = baseQueue.next; - baseQueue.next = pendingQueue.next; - pendingQueue.next = baseFirst; + if (0 < numberOfReRenders) { + var _dispatch = queue.dispatch; + if (null !== renderPhaseUpdates) { + var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue); + if (void 0 !== firstRenderPhaseUpdate) { + renderPhaseUpdates.delete(queue); + var newState = hook.memoizedState; + do + (newState = reducer(newState, firstRenderPhaseUpdate.action)), + (firstRenderPhaseUpdate = firstRenderPhaseUpdate.next); + while (null !== firstRenderPhaseUpdate); + is$1(newState, hook.memoizedState) || (didReceiveUpdate = !0); + hook.memoizedState = newState; + hook.baseUpdate === queue.last && (hook.baseState = newState); + queue.lastRenderedState = newState; + return [newState, _dispatch]; + } } - current.baseQueue = baseQueue = pendingQueue; - queue.pending = null; + return [hook.memoizedState, _dispatch]; } - if (null !== baseQueue) { - baseQueue = baseQueue.next; - current = current.baseState; - var newBaseQueueLast = (baseFirst = pendingQueue = null), - update = baseQueue; + _dispatch = queue.last; + var baseUpdate = hook.baseUpdate; + newState = hook.baseState; + null !== baseUpdate + ? (null !== _dispatch && (_dispatch.next = null), + (_dispatch = baseUpdate.next)) + : (_dispatch = null !== _dispatch ? _dispatch.next : null); + if (null !== _dispatch) { + var newBaseUpdate = (firstRenderPhaseUpdate = null), + _update = _dispatch, + didSkip = !1; do { - var updateExpirationTime = update.expirationTime; - if (updateExpirationTime < renderExpirationTime) { - var clone = { - expirationTime: update.expirationTime, - suspenseConfig: update.suspenseConfig, - action: update.action, - eagerReducer: update.eagerReducer, - eagerState: update.eagerState, - next: null - }; - null === newBaseQueueLast - ? ((baseFirst = newBaseQueueLast = clone), (pendingQueue = current)) - : (newBaseQueueLast = newBaseQueueLast.next = clone); - updateExpirationTime > currentlyRenderingFiber$1.expirationTime && - ((currentlyRenderingFiber$1.expirationTime = updateExpirationTime), - markUnprocessedUpdateTime(updateExpirationTime)); - } else - null !== newBaseQueueLast && - (newBaseQueueLast = newBaseQueueLast.next = { - expirationTime: 1073741823, - suspenseConfig: update.suspenseConfig, - action: update.action, - eagerReducer: update.eagerReducer, - eagerState: update.eagerState, - next: null - }), - markRenderEventTimeAndConfig( + var updateExpirationTime = _update.expirationTime; + updateExpirationTime < renderExpirationTime$1 + ? (didSkip || + ((didSkip = !0), + (newBaseUpdate = baseUpdate), + (firstRenderPhaseUpdate = newState)), + updateExpirationTime > remainingExpirationTime && + ((remainingExpirationTime = updateExpirationTime), + markUnprocessedUpdateTime(remainingExpirationTime))) + : (markRenderEventTimeAndConfig( updateExpirationTime, - update.suspenseConfig + _update.suspenseConfig ), - (current = - update.eagerReducer === reducer - ? update.eagerState - : reducer(current, update.action)); - update = update.next; - } while (null !== update && update !== baseQueue); - null === newBaseQueueLast - ? (pendingQueue = current) - : (newBaseQueueLast.next = baseFirst); - objectIs(current, hook.memoizedState) || (didReceiveUpdate = !0); - hook.memoizedState = current; - hook.baseState = pendingQueue; - hook.baseQueue = newBaseQueueLast; - queue.lastRenderedState = current; - } - return [hook.memoizedState, queue.dispatch]; -} -function rerenderReducer(reducer) { - var hook = updateWorkInProgressHook(), - queue = hook.queue; - if (null === queue) - throw Error( - "Should have a queue. This is likely a bug in React. Please file an issue." - ); - queue.lastRenderedReducer = reducer; - var dispatch = queue.dispatch, - lastRenderPhaseUpdate = queue.pending, - newState = hook.memoizedState; - if (null !== lastRenderPhaseUpdate) { - queue.pending = null; - var update = (lastRenderPhaseUpdate = lastRenderPhaseUpdate.next); - do (newState = reducer(newState, update.action)), (update = update.next); - while (update !== lastRenderPhaseUpdate); - objectIs(newState, hook.memoizedState) || (didReceiveUpdate = !0); + (newState = + _update.eagerReducer === reducer + ? _update.eagerState + : reducer(newState, _update.action))); + baseUpdate = _update; + _update = _update.next; + } while (null !== _update && _update !== _dispatch); + didSkip || + ((newBaseUpdate = baseUpdate), (firstRenderPhaseUpdate = newState)); + is$1(newState, hook.memoizedState) || (didReceiveUpdate = !0); hook.memoizedState = newState; - null === hook.baseQueue && (hook.baseState = newState); + hook.baseUpdate = newBaseUpdate; + hook.baseState = firstRenderPhaseUpdate; queue.lastRenderedState = newState; } - return [newState, dispatch]; + return [hook.memoizedState, queue.dispatch]; } function mountState(initialState) { var hook = mountWorkInProgressHook(); "function" === typeof initialState && (initialState = initialState()); hook.memoizedState = hook.baseState = initialState; initialState = hook.queue = { - pending: null, + last: null, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState @@ -3324,30 +3449,28 @@ function mountState(initialState) { ); return [hook.memoizedState, initialState]; } +function updateState(initialState) { + return updateReducer(basicStateReducer, initialState); +} function pushEffect(tag, create, destroy, deps) { tag = { tag: tag, create: create, destroy: destroy, deps: deps, next: null }; - create = currentlyRenderingFiber$1.updateQueue; - null === create - ? ((create = { lastEffect: null }), - (currentlyRenderingFiber$1.updateQueue = create), - (create.lastEffect = tag.next = tag)) - : ((destroy = create.lastEffect), - null === destroy - ? (create.lastEffect = tag.next = tag) - : ((deps = destroy.next), - (destroy.next = tag), - (tag.next = deps), - (create.lastEffect = tag))); + null === componentUpdateQueue + ? ((componentUpdateQueue = { lastEffect: null }), + (componentUpdateQueue.lastEffect = tag.next = tag)) + : ((create = componentUpdateQueue.lastEffect), + null === create + ? (componentUpdateQueue.lastEffect = tag.next = tag) + : ((destroy = create.next), + (create.next = tag), + (tag.next = destroy), + (componentUpdateQueue.lastEffect = tag))); return tag; } -function updateRef() { - return updateWorkInProgressHook().memoizedState; -} function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var hook = mountWorkInProgressHook(); - currentlyRenderingFiber$1.effectTag |= fiberEffectTag; + sideEffectTag |= fiberEffectTag; hook.memoizedState = pushEffect( - 1 | hookEffectTag, + hookEffectTag, create, void 0, void 0 === deps ? null : deps @@ -3361,21 +3484,18 @@ function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var prevEffect = currentHook.memoizedState; destroy = prevEffect.destroy; if (null !== deps && areHookInputsEqual(deps, prevEffect.deps)) { - pushEffect(hookEffectTag, create, destroy, deps); + pushEffect(0, create, destroy, deps); return; } } - currentlyRenderingFiber$1.effectTag |= fiberEffectTag; - hook.memoizedState = pushEffect(1 | hookEffectTag, create, destroy, deps); + sideEffectTag |= fiberEffectTag; + hook.memoizedState = pushEffect(hookEffectTag, create, destroy, deps); } function mountEffect(create, deps) { - return mountEffectImpl(516, 4, create, deps); + return mountEffectImpl(516, 192, create, deps); } function updateEffect(create, deps) { - return updateEffectImpl(516, 4, create, deps); -} -function updateLayoutEffect(create, deps) { - return updateEffectImpl(4, 2, create, deps); + return updateEffectImpl(516, 192, create, deps); } function imperativeHandleEffect(create, ref) { if ("function" === typeof ref) @@ -3395,15 +3515,6 @@ function imperativeHandleEffect(create, ref) { } ); } -function updateImperativeHandle(ref, create, deps) { - deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; - return updateEffectImpl( - 4, - 2, - imperativeHandleEffect.bind(null, create, ref), - deps - ); -} function mountDebugValue() {} function mountCallback(callback, deps) { mountWorkInProgressHook().memoizedState = [ @@ -3425,79 +3536,72 @@ function updateCallback(callback, deps) { hook.memoizedState = [callback, deps]; return callback; } -function updateMemo(nextCreate, deps) { - var hook = updateWorkInProgressHook(); - deps = void 0 === deps ? null : deps; - var prevState = hook.memoizedState; - if ( - null !== prevState && - null !== deps && - areHookInputsEqual(deps, prevState[1]) - ) - return prevState[0]; - nextCreate = nextCreate(); - hook.memoizedState = [nextCreate, deps]; - return nextCreate; -} -function startTransition(setPending, config, callback) { - var priorityLevel = getCurrentPriorityLevel(); - runWithPriority(98 > priorityLevel ? 98 : priorityLevel, function() { - setPending(!0); - }); - runWithPriority(97 < priorityLevel ? 97 : priorityLevel, function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = void 0 === config ? null : config; - try { - setPending(!1), callback(); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); -} function dispatchAction(fiber, queue, action) { - var currentTime = requestCurrentTimeForUpdate(), - suspenseConfig = ReactCurrentBatchConfig.suspense; - currentTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig); - suspenseConfig = { - expirationTime: currentTime, - suspenseConfig: suspenseConfig, - action: action, - eagerReducer: null, - eagerState: null, - next: null - }; - var pending = queue.pending; - null === pending - ? (suspenseConfig.next = suspenseConfig) - : ((suspenseConfig.next = pending.next), (pending.next = suspenseConfig)); - queue.pending = suspenseConfig; - pending = fiber.alternate; + if (!(25 > numberOfReRenders)) + throw Error( + "Too many re-renders. React limits the number of renders to prevent an infinite loop." + ); + var alternate = fiber.alternate; if ( fiber === currentlyRenderingFiber$1 || - (null !== pending && pending === currentlyRenderingFiber$1) + (null !== alternate && alternate === currentlyRenderingFiber$1) ) - (didScheduleRenderPhaseUpdate = !0), - (suspenseConfig.expirationTime = renderExpirationTime), - (currentlyRenderingFiber$1.expirationTime = renderExpirationTime); + if ( + ((didScheduleRenderPhaseUpdate = !0), + (fiber = { + expirationTime: renderExpirationTime$1, + suspenseConfig: null, + action: action, + eagerReducer: null, + eagerState: null, + next: null + }), + null === renderPhaseUpdates && (renderPhaseUpdates = new Map()), + (action = renderPhaseUpdates.get(queue)), + void 0 === action) + ) + renderPhaseUpdates.set(queue, fiber); + else { + for (queue = action; null !== queue.next; ) queue = queue.next; + queue.next = fiber; + } else { + var currentTime = requestCurrentTimeForUpdate(), + suspenseConfig = ReactCurrentBatchConfig.suspense; + currentTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig); + suspenseConfig = { + expirationTime: currentTime, + suspenseConfig: suspenseConfig, + action: action, + eagerReducer: null, + eagerState: null, + next: null + }; + var last = queue.last; + if (null === last) suspenseConfig.next = suspenseConfig; + else { + var first = last.next; + null !== first && (suspenseConfig.next = first); + last.next = suspenseConfig; + } + queue.last = suspenseConfig; if ( 0 === fiber.expirationTime && - (null === pending || 0 === pending.expirationTime) && - ((pending = queue.lastRenderedReducer), null !== pending) + (null === alternate || 0 === alternate.expirationTime) && + ((alternate = queue.lastRenderedReducer), null !== alternate) ) try { var currentState = queue.lastRenderedState, - eagerState = pending(currentState, action); - suspenseConfig.eagerReducer = pending; + eagerState = alternate(currentState, action); + suspenseConfig.eagerReducer = alternate; suspenseConfig.eagerState = eagerState; - if (objectIs(eagerState, currentState)) return; + if (is$1(eagerState, currentState)) return; } catch (error) { } finally { } - scheduleWork(fiber, currentTime); + scheduleUpdateOnFiber(fiber, currentTime); } } -function updateEventListener() {} var ContextOnlyDispatcher = { readContext: readContext, useCallback: throwInvalidHookError, @@ -3512,8 +3616,7 @@ var ContextOnlyDispatcher = { useDebugValue: throwInvalidHookError, useResponder: throwInvalidHookError, useDeferredValue: throwInvalidHookError, - useTransition: throwInvalidHookError, - useEvent: throwInvalidHookError + useTransition: throwInvalidHookError }, HooksDispatcherOnMount = { readContext: readContext, @@ -3524,13 +3627,13 @@ var ContextOnlyDispatcher = { deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; return mountEffectImpl( 4, - 2, + 36, imperativeHandleEffect.bind(null, create, ref), deps ); }, useLayoutEffect: function(create, deps) { - return mountEffectImpl(4, 2, create, deps); + return mountEffectImpl(4, 36, create, deps); }, useMemo: function(nextCreate, deps) { var hook = mountWorkInProgressHook(); @@ -3544,7 +3647,7 @@ var ContextOnlyDispatcher = { initialArg = void 0 !== init ? init(initialArg) : initialArg; hook.memoizedState = hook.baseState = initialArg; reducer = hook.queue = { - pending: null, + last: null, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialArg @@ -3563,21 +3666,23 @@ var ContextOnlyDispatcher = { }, useState: mountState, useDebugValue: mountDebugValue, - useResponder: createDeprecatedResponderListener, + useResponder: createResponderListener, useDeferredValue: function(value, config) { var _mountState = mountState(value), prevValue = _mountState[0], setValue = _mountState[1]; mountEffect( function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - void 0 === config ? null : config; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } + Scheduler.unstable_next(function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }); }, [value, config] ); @@ -3585,113 +3690,112 @@ var ContextOnlyDispatcher = { }, useTransition: function(config) { var _mountState2 = mountState(!1), - isPending = _mountState2[0]; - _mountState2 = _mountState2[1]; + isPending = _mountState2[0], + setPending = _mountState2[1]; return [ - mountCallback(startTransition.bind(null, _mountState2, config), [ - _mountState2, - config - ]), + mountCallback( + function(callback) { + setPending(!0); + Scheduler.unstable_next(function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setPending(!1), callback(); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }); + }, + [config, isPending] + ), isPending ]; - }, - useEvent: function() {} + } }, HooksDispatcherOnUpdate = { readContext: readContext, useCallback: updateCallback, useContext: readContext, useEffect: updateEffect, - useImperativeHandle: updateImperativeHandle, - useLayoutEffect: updateLayoutEffect, - useMemo: updateMemo, - useReducer: updateReducer, - useRef: updateRef, - useState: function() { - return updateReducer(basicStateReducer); - }, - useDebugValue: mountDebugValue, - useResponder: createDeprecatedResponderListener, - useDeferredValue: function(value, config) { - var _updateState = updateReducer(basicStateReducer), - prevValue = _updateState[0], - setValue = _updateState[1]; - updateEffect( - function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - void 0 === config ? null : config; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }, - [value, config] + useImperativeHandle: function(ref, create, deps) { + deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; + return updateEffectImpl( + 4, + 36, + imperativeHandleEffect.bind(null, create, ref), + deps ); - return prevValue; }, - useTransition: function(config) { - var _updateState2 = updateReducer(basicStateReducer), - isPending = _updateState2[0]; - _updateState2 = _updateState2[1]; - return [ - updateCallback(startTransition.bind(null, _updateState2, config), [ - _updateState2, - config - ]), - isPending - ]; + useLayoutEffect: function(create, deps) { + return updateEffectImpl(4, 36, create, deps); }, - useEvent: updateEventListener - }, - HooksDispatcherOnRerender = { - readContext: readContext, - useCallback: updateCallback, - useContext: readContext, - useEffect: updateEffect, - useImperativeHandle: updateImperativeHandle, - useLayoutEffect: updateLayoutEffect, - useMemo: updateMemo, - useReducer: rerenderReducer, - useRef: updateRef, - useState: function() { - return rerenderReducer(basicStateReducer); + useMemo: function(nextCreate, deps) { + var hook = updateWorkInProgressHook(); + deps = void 0 === deps ? null : deps; + var prevState = hook.memoizedState; + if ( + null !== prevState && + null !== deps && + areHookInputsEqual(deps, prevState[1]) + ) + return prevState[0]; + nextCreate = nextCreate(); + hook.memoizedState = [nextCreate, deps]; + return nextCreate; }, + useReducer: updateReducer, + useRef: function() { + return updateWorkInProgressHook().memoizedState; + }, + useState: updateState, useDebugValue: mountDebugValue, - useResponder: createDeprecatedResponderListener, + useResponder: createResponderListener, useDeferredValue: function(value, config) { - var _rerenderState = rerenderReducer(basicStateReducer), - prevValue = _rerenderState[0], - setValue = _rerenderState[1]; + var _updateState = updateState(value), + prevValue = _updateState[0], + setValue = _updateState[1]; updateEffect( function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - void 0 === config ? null : config; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } + Scheduler.unstable_next(function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }); }, [value, config] ); return prevValue; }, useTransition: function(config) { - var _rerenderState2 = rerenderReducer(basicStateReducer), - isPending = _rerenderState2[0]; - _rerenderState2 = _rerenderState2[1]; + var _updateState2 = updateState(!1), + isPending = _updateState2[0], + setPending = _updateState2[1]; return [ - updateCallback(startTransition.bind(null, _rerenderState2, config), [ - _rerenderState2, - config - ]), + updateCallback( + function(callback) { + setPending(!0); + Scheduler.unstable_next(function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setPending(!1), callback(); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }); + }, + [config, isPending] + ), isPending ]; - }, - useEvent: updateEventListener + } }, now$1 = Scheduler.unstable_now, commitTime = 0, @@ -3704,16 +3808,70 @@ function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) { profilerStartTime = -1; } } -var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner, +var hydrationParentFiber = null, + nextHydratableInstance = null, + isHydrating = !1; +function tryHydrate(fiber, nextInstance) { + switch (fiber.tag) { + case 5: + return ( + (nextInstance = shim$1(nextInstance, fiber.type, fiber.pendingProps)), + null !== nextInstance ? ((fiber.stateNode = nextInstance), !0) : !1 + ); + case 6: + return ( + (nextInstance = shim$1(nextInstance, fiber.pendingProps)), + null !== nextInstance ? ((fiber.stateNode = nextInstance), !0) : !1 + ); + case 13: + return !1; + default: + return !1; + } +} +function tryToClaimNextHydratableInstance(fiber$jscomp$0) { + if (isHydrating) { + var nextInstance = nextHydratableInstance; + if (nextInstance) { + var firstAttemptedInstance = nextInstance; + if (!tryHydrate(fiber$jscomp$0, nextInstance)) { + nextInstance = shim$1(firstAttemptedInstance); + if (!nextInstance || !tryHydrate(fiber$jscomp$0, nextInstance)) { + fiber$jscomp$0.effectTag = (fiber$jscomp$0.effectTag & -1025) | 2; + isHydrating = !1; + hydrationParentFiber = fiber$jscomp$0; + return; + } + var returnFiber = hydrationParentFiber, + fiber = createFiber(5, null, null, 0); + fiber.elementType = "DELETED"; + fiber.type = "DELETED"; + fiber.stateNode = firstAttemptedInstance; + fiber.return = returnFiber; + fiber.effectTag = 8; + null !== returnFiber.lastEffect + ? ((returnFiber.lastEffect.nextEffect = fiber), + (returnFiber.lastEffect = fiber)) + : (returnFiber.firstEffect = returnFiber.lastEffect = fiber); + } + hydrationParentFiber = fiber$jscomp$0; + nextHydratableInstance = shim$1(nextInstance); + } else + (fiber$jscomp$0.effectTag = (fiber$jscomp$0.effectTag & -1025) | 2), + (isHydrating = !1), + (hydrationParentFiber = fiber$jscomp$0); + } +} +var ReactCurrentOwner$3 = ReactSharedInternals.ReactCurrentOwner, didReceiveUpdate = !1; function reconcileChildren( - current, + current$$1, workInProgress, nextChildren, renderExpirationTime ) { workInProgress.child = - null === current + null === current$$1 ? mountChildFibers( workInProgress, null, @@ -3722,13 +3880,13 @@ function reconcileChildren( ) : reconcileChildFibers( workInProgress, - current.child, + current$$1.child, nextChildren, renderExpirationTime ); } function updateForwardRef( - current, + current$$1, workInProgress, Component, nextProps, @@ -3738,38 +3896,43 @@ function updateForwardRef( var ref = workInProgress.ref; prepareToReadContext(workInProgress, renderExpirationTime); nextProps = renderWithHooks( - current, + current$$1, workInProgress, Component, nextProps, ref, renderExpirationTime ); - if (null !== current && !didReceiveUpdate) + if (null !== current$$1 && !didReceiveUpdate) return ( - (workInProgress.updateQueue = current.updateQueue), + (workInProgress.updateQueue = current$$1.updateQueue), (workInProgress.effectTag &= -517), - current.expirationTime <= renderExpirationTime && - (current.expirationTime = 0), + current$$1.expirationTime <= renderExpirationTime && + (current$$1.expirationTime = 0), bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ) ); workInProgress.effectTag |= 1; - reconcileChildren(current, workInProgress, nextProps, renderExpirationTime); + reconcileChildren( + current$$1, + workInProgress, + nextProps, + renderExpirationTime + ); return workInProgress.child; } function updateMemoComponent( - current, + current$$1, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime ) { - if (null === current) { + if (null === current$$1) { var type = Component.type; if ( "function" === typeof type && @@ -3782,7 +3945,7 @@ function updateMemoComponent( (workInProgress.tag = 15), (workInProgress.type = type), updateSimpleMemoComponent( - current, + current$$1, workInProgress, type, nextProps, @@ -3790,7 +3953,7 @@ function updateMemoComponent( renderExpirationTime ) ); - current = createFiberFromTypeAndProps( + current$$1 = createFiberFromTypeAndProps( Component.type, null, nextProps, @@ -3798,66 +3961,65 @@ function updateMemoComponent( workInProgress.mode, renderExpirationTime ); - current.ref = workInProgress.ref; - current.return = workInProgress; - return (workInProgress.child = current); + current$$1.ref = workInProgress.ref; + current$$1.return = workInProgress; + return (workInProgress.child = current$$1); } - type = current.child; + type = current$$1.child; if ( updateExpirationTime < renderExpirationTime && ((updateExpirationTime = type.memoizedProps), (Component = Component.compare), (Component = null !== Component ? Component : shallowEqual), Component(updateExpirationTime, nextProps) && - current.ref === workInProgress.ref) + current$$1.ref === workInProgress.ref) ) return bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ); workInProgress.effectTag |= 1; - current = createWorkInProgress(type, nextProps); - current.ref = workInProgress.ref; - current.return = workInProgress; - return (workInProgress.child = current); + current$$1 = createWorkInProgress(type, nextProps, renderExpirationTime); + current$$1.ref = workInProgress.ref; + current$$1.return = workInProgress; + return (workInProgress.child = current$$1); } function updateSimpleMemoComponent( - current, + current$$1, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime ) { - return null !== current && - shallowEqual(current.memoizedProps, nextProps) && - current.ref === workInProgress.ref && + return null !== current$$1 && + shallowEqual(current$$1.memoizedProps, nextProps) && + current$$1.ref === workInProgress.ref && ((didReceiveUpdate = !1), updateExpirationTime < renderExpirationTime) - ? ((workInProgress.expirationTime = current.expirationTime), - bailoutOnAlreadyFinishedWork( - current, + ? bailoutOnAlreadyFinishedWork( + current$$1, workInProgress, renderExpirationTime - )) + ) : updateFunctionComponent( - current, + current$$1, workInProgress, Component, nextProps, renderExpirationTime ); } -function markRef(current, workInProgress) { +function markRef(current$$1, workInProgress) { var ref = workInProgress.ref; if ( - (null === current && null !== ref) || - (null !== current && current.ref !== ref) + (null === current$$1 && null !== ref) || + (null !== current$$1 && current$$1.ref !== ref) ) workInProgress.effectTag |= 128; } function updateFunctionComponent( - current, + current$$1, workInProgress, Component, nextProps, @@ -3869,31 +4031,36 @@ function updateFunctionComponent( context = getMaskedContext(workInProgress, context); prepareToReadContext(workInProgress, renderExpirationTime); Component = renderWithHooks( - current, + current$$1, workInProgress, Component, nextProps, context, renderExpirationTime ); - if (null !== current && !didReceiveUpdate) + if (null !== current$$1 && !didReceiveUpdate) return ( - (workInProgress.updateQueue = current.updateQueue), + (workInProgress.updateQueue = current$$1.updateQueue), (workInProgress.effectTag &= -517), - current.expirationTime <= renderExpirationTime && - (current.expirationTime = 0), + current$$1.expirationTime <= renderExpirationTime && + (current$$1.expirationTime = 0), bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ) ); workInProgress.effectTag |= 1; - reconcileChildren(current, workInProgress, Component, renderExpirationTime); + reconcileChildren( + current$$1, + workInProgress, + Component, + renderExpirationTime + ); return workInProgress.child; } function updateClassComponent( - current, + current$$1, workInProgress, Component, nextProps, @@ -3905,11 +4072,16 @@ function updateClassComponent( } else hasContext = !1; prepareToReadContext(workInProgress, renderExpirationTime); if (null === workInProgress.stateNode) - null !== current && - ((current.alternate = null), + null !== current$$1 && + ((current$$1.alternate = null), (workInProgress.alternate = null), (workInProgress.effectTag |= 2)), - constructClassInstance(workInProgress, Component, nextProps), + constructClassInstance( + workInProgress, + Component, + nextProps, + renderExpirationTime + ), mountClassInstance( workInProgress, Component, @@ -3917,7 +4089,7 @@ function updateClassComponent( renderExpirationTime ), (nextProps = !0); - else if (null === current) { + else if (null === current$$1) { var instance = workInProgress.stateNode, oldProps = workInProgress.memoizedProps; instance.props = oldProps; @@ -3945,14 +4117,17 @@ function updateClassComponent( )); hasForceUpdate = !1; var oldState = workInProgress.memoizedState; - instance.state = oldState; - processUpdateQueue( - workInProgress, - nextProps, - instance, - renderExpirationTime - ); - oldContext = workInProgress.memoizedState; + oldContext = instance.state = oldState; + var updateQueue = workInProgress.updateQueue; + null !== updateQueue && + (processUpdateQueue( + workInProgress, + updateQueue, + nextProps, + instance, + renderExpirationTime + ), + (oldContext = workInProgress.memoizedState)); oldProps !== nextProps || oldState !== oldContext || didPerformWorkStackCursor.current || @@ -3998,7 +4173,6 @@ function updateClassComponent( (nextProps = !1)); } else (instance = workInProgress.stateNode), - cloneUpdateQueue(current, workInProgress), (oldProps = workInProgress.memoizedProps), (instance.props = workInProgress.type === workInProgress.elementType @@ -4027,14 +4201,17 @@ function updateClassComponent( )), (hasForceUpdate = !1), (oldContext = workInProgress.memoizedState), - (instance.state = oldContext), - processUpdateQueue( - workInProgress, - nextProps, - instance, - renderExpirationTime - ), - (oldState = workInProgress.memoizedState), + (oldState = instance.state = oldContext), + (updateQueue = workInProgress.updateQueue), + null !== updateQueue && + (processUpdateQueue( + workInProgress, + updateQueue, + nextProps, + instance, + renderExpirationTime + ), + (oldState = workInProgress.memoizedState)), oldProps !== nextProps || oldContext !== oldState || didPerformWorkStackCursor.current || @@ -4078,12 +4255,12 @@ function updateClassComponent( "function" === typeof instance.getSnapshotBeforeUpdate && (workInProgress.effectTag |= 256)) : ("function" !== typeof instance.componentDidUpdate || - (oldProps === current.memoizedProps && - oldContext === current.memoizedState) || + (oldProps === current$$1.memoizedProps && + oldContext === current$$1.memoizedState) || (workInProgress.effectTag |= 4), "function" !== typeof instance.getSnapshotBeforeUpdate || - (oldProps === current.memoizedProps && - oldContext === current.memoizedState) || + (oldProps === current$$1.memoizedProps && + oldContext === current$$1.memoizedState) || (workInProgress.effectTag |= 256), (workInProgress.memoizedProps = nextProps), (workInProgress.memoizedState = oldState)), @@ -4092,16 +4269,16 @@ function updateClassComponent( (instance.context = contextType), (nextProps = getDerivedStateFromProps)) : ("function" !== typeof instance.componentDidUpdate || - (oldProps === current.memoizedProps && - oldContext === current.memoizedState) || + (oldProps === current$$1.memoizedProps && + oldContext === current$$1.memoizedState) || (workInProgress.effectTag |= 4), "function" !== typeof instance.getSnapshotBeforeUpdate || - (oldProps === current.memoizedProps && - oldContext === current.memoizedState) || + (oldProps === current$$1.memoizedProps && + oldContext === current$$1.memoizedState) || (workInProgress.effectTag |= 256), (nextProps = !1)); return finishClassComponent( - current, + current$$1, workInProgress, Component, nextProps, @@ -4110,26 +4287,26 @@ function updateClassComponent( ); } function finishClassComponent( - current, + current$$1, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime ) { - markRef(current, workInProgress); + markRef(current$$1, workInProgress); var didCaptureError = 0 !== (workInProgress.effectTag & 64); if (!shouldUpdate && !didCaptureError) return ( hasContext && invalidateContextProvider(workInProgress, Component, !1), bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ) ); shouldUpdate = workInProgress.stateNode; - ReactCurrentOwner$1.current = workInProgress; + ReactCurrentOwner$3.current = workInProgress; if ( didCaptureError && "function" !== typeof Component.getDerivedStateFromError @@ -4138,11 +4315,11 @@ function finishClassComponent( profilerStartTime = -1; } else nextChildren = shouldUpdate.render(); workInProgress.effectTag |= 1; - null !== current && didCaptureError + null !== current$$1 && didCaptureError ? ((didCaptureError = nextChildren), (workInProgress.child = reconcileChildFibers( workInProgress, - current.child, + current$$1.child, null, renderExpirationTime )), @@ -4153,7 +4330,7 @@ function finishClassComponent( renderExpirationTime ))) : reconcileChildren( - current, + current$$1, workInProgress, nextChildren, renderExpirationTime @@ -4176,7 +4353,7 @@ function pushHostRootContext(workInProgress) { } var SUSPENDED_MARKER = { dehydrated: null, retryTime: 0 }; function updateSuspenseComponent( - current, + current$$1, workInProgress, renderExpirationTime ) { @@ -4188,30 +4365,32 @@ function updateSuspenseComponent( (JSCompiler_temp = 0 !== (workInProgress.effectTag & 64)) || (JSCompiler_temp = 0 !== (suspenseContext & 2) && - (null === current || null !== current.memoizedState)); + (null === current$$1 || null !== current$$1.memoizedState)); JSCompiler_temp ? ((nextDidTimeout = !0), (workInProgress.effectTag &= -65)) - : (null !== current && null === current.memoizedState) || + : (null !== current$$1 && null === current$$1.memoizedState) || void 0 === nextProps.fallback || !0 === nextProps.unstable_avoidThisFallback || (suspenseContext |= 1); - push(suspenseStackCursor, suspenseContext & 1); - if (null === current) { + push(suspenseStackCursor, suspenseContext & 1, workInProgress); + if (null === current$$1) { + void 0 !== nextProps.fallback && + tryToClaimNextHydratableInstance(workInProgress); if (nextDidTimeout) { nextDidTimeout = nextProps.fallback; nextProps = createFiberFromFragment(null, mode, 0, null); nextProps.return = workInProgress; if (0 === (workInProgress.mode & 2)) for ( - current = + current$$1 = null !== workInProgress.memoizedState ? workInProgress.child.child : workInProgress.child, - nextProps.child = current; - null !== current; + nextProps.child = current$$1; + null !== current$$1; ) - (current.return = nextProps), (current = current.sibling); + (current$$1.return = nextProps), (current$$1 = current$$1.sibling); renderExpirationTime = createFiberFromFragment( nextDidTimeout, mode, @@ -4233,14 +4412,15 @@ function updateSuspenseComponent( renderExpirationTime )); } - if (null !== current.memoizedState) { - current = current.child; - mode = current.sibling; + if (null !== current$$1.memoizedState) { + current$$1 = current$$1.child; + mode = current$$1.sibling; if (nextDidTimeout) { nextProps = nextProps.fallback; renderExpirationTime = createWorkInProgress( - current, - current.pendingProps + current$$1, + current$$1.pendingProps, + 0 ); renderExpirationTime.return = workInProgress; if ( @@ -4249,7 +4429,7 @@ function updateSuspenseComponent( null !== workInProgress.memoizedState ? workInProgress.child.child : workInProgress.child), - nextDidTimeout !== current.child) + nextDidTimeout !== current$$1.child) ) for ( renderExpirationTime.child = nextDidTimeout; @@ -4260,12 +4440,12 @@ function updateSuspenseComponent( (nextDidTimeout = nextDidTimeout.sibling); if (workInProgress.mode & 8) { nextDidTimeout = 0; - for (current = renderExpirationTime.child; null !== current; ) - (nextDidTimeout += current.treeBaseDuration), - (current = current.sibling); + for (current$$1 = renderExpirationTime.child; null !== current$$1; ) + (nextDidTimeout += current$$1.treeBaseDuration), + (current$$1 = current$$1.sibling); renderExpirationTime.treeBaseDuration = nextDidTimeout; } - mode = createWorkInProgress(mode, nextProps); + mode = createWorkInProgress(mode, nextProps, mode.expirationTime); mode.return = workInProgress; renderExpirationTime.sibling = mode; renderExpirationTime.childExpirationTime = 0; @@ -4275,37 +4455,37 @@ function updateSuspenseComponent( } renderExpirationTime = reconcileChildFibers( workInProgress, - current.child, + current$$1.child, nextProps.children, renderExpirationTime ); workInProgress.memoizedState = null; return (workInProgress.child = renderExpirationTime); } - current = current.child; + current$$1 = current$$1.child; if (nextDidTimeout) { nextDidTimeout = nextProps.fallback; nextProps = createFiberFromFragment(null, mode, 0, null); nextProps.return = workInProgress; - nextProps.child = current; - null !== current && (current.return = nextProps); + nextProps.child = current$$1; + null !== current$$1 && (current$$1.return = nextProps); if (0 === (workInProgress.mode & 2)) for ( - current = + current$$1 = null !== workInProgress.memoizedState ? workInProgress.child.child : workInProgress.child, - nextProps.child = current; - null !== current; + nextProps.child = current$$1; + null !== current$$1; ) - (current.return = nextProps), (current = current.sibling); + (current$$1.return = nextProps), (current$$1 = current$$1.sibling); if (workInProgress.mode & 8) { - current = 0; + current$$1 = 0; for (suspenseContext = nextProps.child; null !== suspenseContext; ) - (current += suspenseContext.treeBaseDuration), + (current$$1 += suspenseContext.treeBaseDuration), (suspenseContext = suspenseContext.sibling); - nextProps.treeBaseDuration = current; + nextProps.treeBaseDuration = current$$1; } renderExpirationTime = createFiberFromFragment( nextDidTimeout, @@ -4324,7 +4504,7 @@ function updateSuspenseComponent( workInProgress.memoizedState = null; return (workInProgress.child = reconcileChildFibers( workInProgress, - current, + current$$1, nextProps.children, renderExpirationTime )); @@ -4351,7 +4531,6 @@ function initSuspenseListRenderState( ? (workInProgress.memoizedState = { isBackwards: isBackwards, rendering: null, - renderingStartTime: 0, last: lastContentRow, tail: tail, tailExpiration: 0, @@ -4360,7 +4539,6 @@ function initSuspenseListRenderState( }) : ((renderState.isBackwards = isBackwards), (renderState.rendering = null), - (renderState.renderingStartTime = 0), (renderState.last = lastContentRow), (renderState.tail = tail), (renderState.tailExpiration = 0), @@ -4368,7 +4546,7 @@ function initSuspenseListRenderState( (renderState.lastEffect = lastEffectBeforeRendering)); } function updateSuspenseListComponent( - current, + current$$1, workInProgress, renderExpirationTime ) { @@ -4376,7 +4554,7 @@ function updateSuspenseListComponent( revealOrder = nextProps.revealOrder, tailMode = nextProps.tail; reconcileChildren( - current, + current$$1, workInProgress, nextProps.children, renderExpirationTime @@ -4385,39 +4563,42 @@ function updateSuspenseListComponent( if (0 !== (nextProps & 2)) (nextProps = (nextProps & 1) | 2), (workInProgress.effectTag |= 64); else { - if (null !== current && 0 !== (current.effectTag & 64)) - a: for (current = workInProgress.child; null !== current; ) { - if (13 === current.tag) - null !== current.memoizedState && - scheduleWorkOnFiber(current, renderExpirationTime); - else if (19 === current.tag) - scheduleWorkOnFiber(current, renderExpirationTime); - else if (null !== current.child) { - current.child.return = current; - current = current.child; + if (null !== current$$1 && 0 !== (current$$1.effectTag & 64)) + a: for (current$$1 = workInProgress.child; null !== current$$1; ) { + if (13 === current$$1.tag) + null !== current$$1.memoizedState && + scheduleWorkOnFiber(current$$1, renderExpirationTime); + else if (19 === current$$1.tag) + scheduleWorkOnFiber(current$$1, renderExpirationTime); + else if (null !== current$$1.child) { + current$$1.child.return = current$$1; + current$$1 = current$$1.child; continue; } - if (current === workInProgress) break a; - for (; null === current.sibling; ) { - if (null === current.return || current.return === workInProgress) + if (current$$1 === workInProgress) break a; + for (; null === current$$1.sibling; ) { + if ( + null === current$$1.return || + current$$1.return === workInProgress + ) break a; - current = current.return; + current$$1 = current$$1.return; } - current.sibling.return = current.return; - current = current.sibling; + current$$1.sibling.return = current$$1.return; + current$$1 = current$$1.sibling; } nextProps &= 1; } - push(suspenseStackCursor, nextProps); + push(suspenseStackCursor, nextProps, workInProgress); if (0 === (workInProgress.mode & 2)) workInProgress.memoizedState = null; else switch (revealOrder) { case "forwards": renderExpirationTime = workInProgress.child; for (revealOrder = null; null !== renderExpirationTime; ) - (current = renderExpirationTime.alternate), - null !== current && - null === findFirstSuspended(current) && + (current$$1 = renderExpirationTime.alternate), + null !== current$$1 && + null === findFirstSuspended(current$$1) && (revealOrder = renderExpirationTime), (renderExpirationTime = renderExpirationTime.sibling); renderExpirationTime = revealOrder; @@ -4439,15 +4620,15 @@ function updateSuspenseListComponent( renderExpirationTime = null; revealOrder = workInProgress.child; for (workInProgress.child = null; null !== revealOrder; ) { - current = revealOrder.alternate; - if (null !== current && null === findFirstSuspended(current)) { + current$$1 = revealOrder.alternate; + if (null !== current$$1 && null === findFirstSuspended(current$$1)) { workInProgress.child = revealOrder; break; } - current = revealOrder.sibling; + current$$1 = revealOrder.sibling; revealOrder.sibling = renderExpirationTime; renderExpirationTime = revealOrder; - revealOrder = current; + revealOrder = current$$1; } initSuspenseListRenderState( workInProgress, @@ -4474,30 +4655,36 @@ function updateSuspenseListComponent( return workInProgress.child; } function bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ) { - null !== current && (workInProgress.dependencies = current.dependencies); + null !== current$$1 && + (workInProgress.dependencies = current$$1.dependencies); profilerStartTime = -1; var updateExpirationTime = workInProgress.expirationTime; 0 !== updateExpirationTime && markUnprocessedUpdateTime(updateExpirationTime); if (workInProgress.childExpirationTime < renderExpirationTime) return null; - if (null !== current && workInProgress.child !== current.child) + if (null !== current$$1 && workInProgress.child !== current$$1.child) throw Error("Resuming work not yet implemented."); if (null !== workInProgress.child) { - current = workInProgress.child; - renderExpirationTime = createWorkInProgress(current, current.pendingProps); + current$$1 = workInProgress.child; + renderExpirationTime = createWorkInProgress( + current$$1, + current$$1.pendingProps, + current$$1.expirationTime + ); workInProgress.child = renderExpirationTime; for ( renderExpirationTime.return = workInProgress; - null !== current.sibling; + null !== current$$1.sibling; ) - (current = current.sibling), + (current$$1 = current$$1.sibling), (renderExpirationTime = renderExpirationTime.sibling = createWorkInProgress( - current, - current.pendingProps + current$$1, + current$$1.pendingProps, + current$$1.expirationTime )), (renderExpirationTime.return = workInProgress); renderExpirationTime.sibling = null; @@ -4559,87 +4746,78 @@ function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { : (_lastTailNode.sibling = null); } } -function completeWork(current, workInProgress, renderExpirationTime) { +function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { var newProps = workInProgress.pendingProps; switch (workInProgress.tag) { case 2: + break; case 16: + break; case 15: case 0: - case 11: - case 7: - case 8: - case 12: - case 9: - case 14: - return null; + break; case 1: - return isContextProvider(workInProgress.type) && popContext(), null; + isContextProvider(workInProgress.type) && popContext(workInProgress); + break; case 3: - return ( - popHostContainer(), - pop(didPerformWorkStackCursor), - pop(contextStackCursor), - (current = workInProgress.stateNode), - current.pendingContext && - ((current.context = current.pendingContext), - (current.pendingContext = null)), - updateHostContainer(workInProgress), - null - ); + popHostContainer(workInProgress); + popTopLevelContextObject(workInProgress); + current = workInProgress.stateNode; + current.pendingContext && + ((current.context = current.pendingContext), + (current.pendingContext = null)); + updateHostContainer(workInProgress); + break; case 5: popHostContext(workInProgress); var rootContainerInstance = requiredContext( rootInstanceStackCursor.current ); - renderExpirationTime = workInProgress.type; + renderExpirationTime$jscomp$0 = workInProgress.type; if (null !== current && null != workInProgress.stateNode) updateHostComponent$1( current, workInProgress, - renderExpirationTime, + renderExpirationTime$jscomp$0, newProps, rootContainerInstance ), current.ref !== workInProgress.ref && (workInProgress.effectTag |= 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." - ); - return null; - } - requiredContext(contextStackCursor$1.current); - current = allocateTag(); - renderExpirationTime = getViewConfigForType(renderExpirationTime); - var updatePayload = diffProperties( - null, - emptyObject, - newProps, - renderExpirationTime.validAttributes - ); + else if (newProps) { + current = requiredContext(contextStackCursor$1.current); + var tag = allocateTag(), + viewConfig = getViewConfigForType(renderExpirationTime$jscomp$0), + updatePayload = diffProperties( + null, + emptyObject, + newProps, + viewConfig.validAttributes + ); ReactNativePrivateInterface.UIManager.createView( - current, - renderExpirationTime.uiViewClassName, + tag, + viewConfig.uiViewClassName, rootContainerInstance, updatePayload ); - rootContainerInstance = new ReactNativeFiberHostComponent( - current, - renderExpirationTime, - workInProgress - ); - instanceCache.set(current, workInProgress); - instanceProps.set(current, newProps); - appendAllChildren(rootContainerInstance, workInProgress, !1, !1); - workInProgress.stateNode = rootContainerInstance; - finalizeInitialChildren(rootContainerInstance) && - (workInProgress.effectTag |= 4); + viewConfig = new ReactNativeFiberHostComponent(tag, viewConfig); + instanceCache.set(tag, workInProgress); + instanceProps.set(tag, newProps); + appendAllChildren(viewConfig, workInProgress, !1, !1); + workInProgress.stateNode = viewConfig; + finalizeInitialChildren( + viewConfig, + renderExpirationTime$jscomp$0, + newProps, + rootContainerInstance, + current + ) && (workInProgress.effectTag |= 4); null !== workInProgress.ref && (workInProgress.effectTag |= 128); - } - return null; + } else 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." + ); + break; case 6: if (current && null != workInProgress.stateNode) updateHostText$1( @@ -4668,30 +4846,33 @@ function completeWork(current, workInProgress, renderExpirationTime) { instanceCache.set(rootContainerInstance, workInProgress); workInProgress.stateNode = rootContainerInstance; } - return null; + break; + case 11: + break; case 13: - pop(suspenseStackCursor); + pop(suspenseStackCursor, workInProgress); newProps = workInProgress.memoizedState; if (0 !== (workInProgress.effectTag & 64)) return ( - (workInProgress.expirationTime = renderExpirationTime), workInProgress + (workInProgress.expirationTime = renderExpirationTime$jscomp$0), + workInProgress ); newProps = null !== newProps; rootContainerInstance = !1; null !== current && - ((renderExpirationTime = current.memoizedState), - (rootContainerInstance = null !== renderExpirationTime), + ((renderExpirationTime$jscomp$0 = current.memoizedState), + (rootContainerInstance = null !== renderExpirationTime$jscomp$0), newProps || - null === renderExpirationTime || - ((renderExpirationTime = current.child.sibling), - null !== renderExpirationTime && - ((updatePayload = workInProgress.firstEffect), - null !== updatePayload - ? ((workInProgress.firstEffect = renderExpirationTime), - (renderExpirationTime.nextEffect = updatePayload)) - : ((workInProgress.firstEffect = workInProgress.lastEffect = renderExpirationTime), - (renderExpirationTime.nextEffect = null)), - (renderExpirationTime.effectTag = 8)))); + null === renderExpirationTime$jscomp$0 || + ((renderExpirationTime$jscomp$0 = current.child.sibling), + null !== renderExpirationTime$jscomp$0 && + ((tag = workInProgress.firstEffect), + null !== tag + ? ((workInProgress.firstEffect = renderExpirationTime$jscomp$0), + (renderExpirationTime$jscomp$0.nextEffect = tag)) + : ((workInProgress.firstEffect = workInProgress.lastEffect = renderExpirationTime$jscomp$0), + (renderExpirationTime$jscomp$0.nextEffect = null)), + (renderExpirationTime$jscomp$0.effectTag = 8)))); if (newProps && !rootContainerInstance && 0 !== (workInProgress.mode & 2)) if ( (null === current && @@ -4708,30 +4889,41 @@ function completeWork(current, workInProgress, renderExpirationTime) { workInProgressRootExitStatus = RootSuspendedWithDelay; 0 !== workInProgressRootNextUnprocessedUpdateTime && null !== workInProgressRoot && - (markRootSuspendedAtTime( - workInProgressRoot, - renderExpirationTime$1 - ), + (markRootSuspendedAtTime(workInProgressRoot, renderExpirationTime), markRootUpdatedAtTime( workInProgressRoot, workInProgressRootNextUnprocessedUpdateTime )); } if (newProps || rootContainerInstance) workInProgress.effectTag |= 4; - return null; + break; + case 7: + break; + case 8: + break; + case 12: + break; case 4: - return popHostContainer(), updateHostContainer(workInProgress), null; + popHostContainer(workInProgress); + updateHostContainer(workInProgress); + break; case 10: - return popProvider(workInProgress), null; + popProvider(workInProgress); + break; + case 9: + break; + case 14: + break; case 17: - return isContextProvider(workInProgress.type) && popContext(), null; + isContextProvider(workInProgress.type) && popContext(workInProgress); + break; case 19: - pop(suspenseStackCursor); + pop(suspenseStackCursor, workInProgress); newProps = workInProgress.memoizedState; - if (null === newProps) return null; + if (null === newProps) break; rootContainerInstance = 0 !== (workInProgress.effectTag & 64); - updatePayload = newProps.rendering; - if (null === updatePayload) + tag = newProps.rendering; + if (null === tag) if (rootContainerInstance) cutOffTailIfNeeded(newProps, !1); else { if ( @@ -4739,29 +4931,30 @@ function completeWork(current, workInProgress, renderExpirationTime) { (null !== current && 0 !== (current.effectTag & 64)) ) for (current = workInProgress.child; null !== current; ) { - updatePayload = findFirstSuspended(current); - if (null !== updatePayload) { + tag = findFirstSuspended(current); + if (null !== tag) { workInProgress.effectTag |= 64; cutOffTailIfNeeded(newProps, !1); - current = updatePayload.updateQueue; + current = tag.updateQueue; null !== current && ((workInProgress.updateQueue = current), (workInProgress.effectTag |= 4)); null === newProps.lastEffect && (workInProgress.firstEffect = null); workInProgress.lastEffect = newProps.lastEffect; - current = renderExpirationTime; + current = renderExpirationTime$jscomp$0; for (newProps = workInProgress.child; null !== newProps; ) (rootContainerInstance = newProps), - (updatePayload = current), + (tag = current), (rootContainerInstance.effectTag &= 2), (rootContainerInstance.nextEffect = null), (rootContainerInstance.firstEffect = null), (rootContainerInstance.lastEffect = null), - (renderExpirationTime = rootContainerInstance.alternate), - null === renderExpirationTime + (renderExpirationTime$jscomp$0 = + rootContainerInstance.alternate), + null === renderExpirationTime$jscomp$0 ? ((rootContainerInstance.childExpirationTime = 0), - (rootContainerInstance.expirationTime = updatePayload), + (rootContainerInstance.expirationTime = tag), (rootContainerInstance.child = null), (rootContainerInstance.memoizedProps = null), (rootContainerInstance.memoizedState = null), @@ -4770,34 +4963,35 @@ function completeWork(current, workInProgress, renderExpirationTime) { (rootContainerInstance.selfBaseDuration = 0), (rootContainerInstance.treeBaseDuration = 0)) : ((rootContainerInstance.childExpirationTime = - renderExpirationTime.childExpirationTime), + renderExpirationTime$jscomp$0.childExpirationTime), (rootContainerInstance.expirationTime = - renderExpirationTime.expirationTime), + renderExpirationTime$jscomp$0.expirationTime), (rootContainerInstance.child = - renderExpirationTime.child), + renderExpirationTime$jscomp$0.child), (rootContainerInstance.memoizedProps = - renderExpirationTime.memoizedProps), + renderExpirationTime$jscomp$0.memoizedProps), (rootContainerInstance.memoizedState = - renderExpirationTime.memoizedState), + renderExpirationTime$jscomp$0.memoizedState), (rootContainerInstance.updateQueue = - renderExpirationTime.updateQueue), - (updatePayload = renderExpirationTime.dependencies), + renderExpirationTime$jscomp$0.updateQueue), + (tag = renderExpirationTime$jscomp$0.dependencies), (rootContainerInstance.dependencies = - null === updatePayload + null === tag ? null : { - expirationTime: updatePayload.expirationTime, - firstContext: updatePayload.firstContext, - responders: updatePayload.responders + expirationTime: tag.expirationTime, + firstContext: tag.firstContext, + responders: tag.responders }), (rootContainerInstance.selfBaseDuration = - renderExpirationTime.selfBaseDuration), + renderExpirationTime$jscomp$0.selfBaseDuration), (rootContainerInstance.treeBaseDuration = - renderExpirationTime.treeBaseDuration)), + renderExpirationTime$jscomp$0.treeBaseDuration)), (newProps = newProps.sibling); push( suspenseStackCursor, - (suspenseStackCursor.current & 1) | 2 + (suspenseStackCursor.current & 1) | 2, + workInProgress ); return workInProgress.child; } @@ -4806,9 +5000,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { } else { if (!rootContainerInstance) - if ( - ((current = findFirstSuspended(updatePayload)), null !== current) - ) { + if (((current = findFirstSuspended(tag)), null !== current)) { if ( ((workInProgress.effectTag |= 64), (rootContainerInstance = !0), @@ -4819,72 +5011,74 @@ function completeWork(current, workInProgress, renderExpirationTime) { cutOffTailIfNeeded(newProps, !0), null === newProps.tail && "hidden" === newProps.tailMode && - !updatePayload.alternate) - ) - return ( - (workInProgress = workInProgress.lastEffect = - newProps.lastEffect), - null !== workInProgress && (workInProgress.nextEffect = null), - null - ); + !tag.alternate) + ) { + workInProgress = workInProgress.lastEffect = newProps.lastEffect; + null !== workInProgress && (workInProgress.nextEffect = null); + break; + } } else - 2 * now() - newProps.renderingStartTime > newProps.tailExpiration && - 1 < renderExpirationTime && + now() > newProps.tailExpiration && + 1 < renderExpirationTime$jscomp$0 && ((workInProgress.effectTag |= 64), (rootContainerInstance = !0), cutOffTailIfNeeded(newProps, !1), - (current = renderExpirationTime - 1), + (current = renderExpirationTime$jscomp$0 - 1), (workInProgress.expirationTime = workInProgress.childExpirationTime = current), null === spawnedWorkDuringRender ? (spawnedWorkDuringRender = [current]) : spawnedWorkDuringRender.push(current)); newProps.isBackwards - ? ((updatePayload.sibling = workInProgress.child), - (workInProgress.child = updatePayload)) + ? ((tag.sibling = workInProgress.child), (workInProgress.child = tag)) : ((current = newProps.last), null !== current - ? (current.sibling = updatePayload) - : (workInProgress.child = updatePayload), - (newProps.last = updatePayload)); + ? (current.sibling = tag) + : (workInProgress.child = tag), + (newProps.last = tag)); } - return null !== newProps.tail - ? (0 === newProps.tailExpiration && + if (null !== newProps.tail) + return ( + 0 === newProps.tailExpiration && (newProps.tailExpiration = now() + 500), (current = newProps.tail), (newProps.rendering = current), (newProps.tail = current.sibling), (newProps.lastEffect = workInProgress.lastEffect), - (newProps.renderingStartTime = now()), (current.sibling = null), - (workInProgress = suspenseStackCursor.current), + (newProps = suspenseStackCursor.current), push( suspenseStackCursor, - rootContainerInstance - ? (workInProgress & 1) | 2 - : workInProgress & 1 + rootContainerInstance ? (newProps & 1) | 2 : newProps & 1, + workInProgress ), - current) - : null; + current + ); + break; + case 20: + break; + case 21: + break; + default: + throw Error( + "Unknown unit of work tag (" + + workInProgress.tag + + "). This error is likely caused by a bug in React. Please file an issue." + ); } - throw Error( - "Unknown unit of work tag (" + - workInProgress.tag + - "). This error is likely caused by a bug in React. Please file an issue." - ); + return null; } function unwindWork(workInProgress) { switch (workInProgress.tag) { case 1: - isContextProvider(workInProgress.type) && popContext(); + isContextProvider(workInProgress.type) && popContext(workInProgress); var effectTag = workInProgress.effectTag; return effectTag & 4096 ? ((workInProgress.effectTag = (effectTag & -4097) | 64), workInProgress) : null; case 3: - popHostContainer(); - pop(didPerformWorkStackCursor); - pop(contextStackCursor); + popHostContainer(workInProgress); + popTopLevelContextObject(workInProgress); effectTag = workInProgress.effectTag; if (0 !== (effectTag & 64)) throw Error( @@ -4896,7 +5090,7 @@ function unwindWork(workInProgress) { return popHostContext(workInProgress), null; case 13: return ( - pop(suspenseStackCursor), + pop(suspenseStackCursor, workInProgress), (effectTag = workInProgress.effectTag), effectTag & 4096 ? ((workInProgress.effectTag = (effectTag & -4097) | 64), @@ -4904,9 +5098,9 @@ function unwindWork(workInProgress) { : null ); case 19: - return pop(suspenseStackCursor), null; + return pop(suspenseStackCursor, workInProgress), null; case 4: - return popHostContainer(), null; + return popHostContainer(workInProgress), null; case 10: return popProvider(workInProgress), null; default: @@ -4963,171 +5157,85 @@ function logError(boundary, errorInfo) { }); } } -function safelyCallComponentWillUnmount(current, instance) { +function safelyCallComponentWillUnmount(current$$1, instance) { try { - (instance.props = current.memoizedProps), - (instance.state = current.memoizedState), + (instance.props = current$$1.memoizedProps), + (instance.state = current$$1.memoizedState), instance.componentWillUnmount(); } catch (unmountError) { - captureCommitPhaseError(current, unmountError); + captureCommitPhaseError(current$$1, unmountError); } } -function safelyDetachRef(current) { - var ref = current.ref; +function safelyDetachRef(current$$1) { + var ref = current$$1.ref; if (null !== ref) if ("function" === typeof ref) try { ref(null); } catch (refError) { - captureCommitPhaseError(current, refError); + captureCommitPhaseError(current$$1, refError); } else ref.current = null; } -function commitBeforeMutationLifeCycles(current, finishedWork) { +function commitBeforeMutationLifeCycles(current$$1, finishedWork) { switch (finishedWork.tag) { case 0: case 11: case 15: - case 22: - return; + commitHookEffectList(2, 0, finishedWork); + break; case 1: - if (finishedWork.effectTag & 256 && null !== current) { - var prevProps = current.memoizedProps, - prevState = current.memoizedState; - current = finishedWork.stateNode; - finishedWork = current.getSnapshotBeforeUpdate( + if (finishedWork.effectTag & 256 && null !== current$$1) { + var prevProps = current$$1.memoizedProps, + prevState = current$$1.memoizedState; + current$$1 = finishedWork.stateNode; + finishedWork = current$$1.getSnapshotBeforeUpdate( finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState ); - current.__reactInternalSnapshotBeforeUpdate = finishedWork; + current$$1.__reactInternalSnapshotBeforeUpdate = finishedWork; } - return; + break; case 3: case 5: case 6: case 4: case 17: - return; + 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." + ); } - 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(tag, finishedWork) { +function commitHookEffectList(unmountTag, mountTag, finishedWork) { finishedWork = finishedWork.updateQueue; finishedWork = null !== finishedWork ? finishedWork.lastEffect : null; if (null !== finishedWork) { var effect = (finishedWork = finishedWork.next); do { - if ((effect.tag & tag) === tag) { + if (0 !== (effect.tag & unmountTag)) { var destroy = effect.destroy; effect.destroy = void 0; void 0 !== destroy && destroy(); } + 0 !== (effect.tag & mountTag) && + ((destroy = effect.create), (effect.destroy = destroy())); effect = effect.next; } while (effect !== finishedWork); } } -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 = effect.create; - effect.destroy = create(); - } - effect = effect.next; - } while (effect !== finishedWork); - } -} -function commitLifeCycles(finishedRoot, current, finishedWork) { - switch (finishedWork.tag) { - case 0: - case 11: - case 15: - case 22: - commitHookEffectListMount(3, finishedWork); - return; - case 1: - finishedRoot = finishedWork.stateNode; - if (finishedWork.effectTag & 4) - if (null === current) finishedRoot.componentDidMount(); - else { - var prevProps = - finishedWork.elementType === finishedWork.type - ? current.memoizedProps - : resolveDefaultProps(finishedWork.type, current.memoizedProps); - finishedRoot.componentDidUpdate( - prevProps, - 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); - } - return; - case 5: - return; - case 6: - return; - case 4: - return; - case 12: - prevProps = finishedWork.memoizedProps.onRender; - var commitTime$jscomp$0 = commitTime; - "function" === typeof prevProps && - prevProps( - finishedWork.memoizedProps.id, - null === current ? "mount" : "update", - finishedWork.actualDuration, - finishedWork.treeBaseDuration, - finishedWork.actualStartTime, - commitTime$jscomp$0, - finishedRoot.memoizedInteractions - ); - return; - case 13: - return; - case 19: - case 17: - case 20: - case 21: - 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 commitUnmount(finishedRoot, current$jscomp$0, renderPriorityLevel) { +function commitUnmount(finishedRoot, current$$1$jscomp$0, renderPriorityLevel) { "function" === typeof onCommitFiberUnmount && - onCommitFiberUnmount(current$jscomp$0); - switch (current$jscomp$0.tag) { + onCommitFiberUnmount(current$$1$jscomp$0); + switch (current$$1$jscomp$0.tag) { case 0: case 11: case 14: case 15: - case 22: - finishedRoot = current$jscomp$0.updateQueue; + finishedRoot = current$$1$jscomp$0.updateQueue; if ( null !== finishedRoot && ((finishedRoot = finishedRoot.lastEffect), null !== finishedRoot) @@ -5138,13 +5246,13 @@ function commitUnmount(finishedRoot, current$jscomp$0, renderPriorityLevel) { function() { var effect = firstEffect; do { - var _destroy = effect.destroy; - if (void 0 !== _destroy) { - var current = current$jscomp$0; + var destroy = effect.destroy; + if (void 0 !== destroy) { + var current$$1 = current$$1$jscomp$0; try { - _destroy(); + destroy(); } catch (error) { - captureCommitPhaseError(current, error); + captureCommitPhaseError(current$$1, error); } } effect = effect.next; @@ -5154,35 +5262,37 @@ function commitUnmount(finishedRoot, current$jscomp$0, renderPriorityLevel) { } break; case 1: - safelyDetachRef(current$jscomp$0); - renderPriorityLevel = current$jscomp$0.stateNode; + safelyDetachRef(current$$1$jscomp$0); + renderPriorityLevel = current$$1$jscomp$0.stateNode; "function" === typeof renderPriorityLevel.componentWillUnmount && - safelyCallComponentWillUnmount(current$jscomp$0, renderPriorityLevel); + safelyCallComponentWillUnmount( + current$$1$jscomp$0, + renderPriorityLevel + ); break; case 5: - safelyDetachRef(current$jscomp$0); + safelyDetachRef(current$$1$jscomp$0); break; case 4: unmountHostComponents( finishedRoot, - current$jscomp$0, + current$$1$jscomp$0, renderPriorityLevel ); } } -function detachFiber(current) { - var alternate = current.alternate; - current.return = null; - current.child = null; - current.memoizedState = null; - current.updateQueue = null; - current.dependencies = null; - current.alternate = null; - current.firstEffect = null; - current.lastEffect = null; - current.pendingProps = null; - current.memoizedProps = null; - current.stateNode = null; +function detachFiber(current$$1) { + var alternate = current$$1.alternate; + current$$1.return = null; + current$$1.child = null; + current$$1.memoizedState = null; + current$$1.updateQueue = null; + current$$1.dependencies = null; + current$$1.alternate = null; + current$$1.firstEffect = null; + current$$1.lastEffect = null; + current$$1.pendingProps = null; + current$$1.memoizedProps = null; null !== alternate && detachFiber(alternate); } function isHostParent(fiber) { @@ -5245,103 +5355,97 @@ function commitPlacement(finishedWork) { break a; } } - isContainer - ? insertOrAppendPlacementNodeIntoContainer( - finishedWork, - parentFiber, - parent - ) - : insertOrAppendPlacementNode(finishedWork, parentFiber, parent); -} -function insertOrAppendPlacementNodeIntoContainer(node, before, parent) { - var tag = node.tag, - isHost = 5 === tag || 6 === tag; - if (isHost) - if (((node = isHost ? node.stateNode : node.stateNode.instance), before)) { - if ("number" === typeof parent) - throw Error("Container does not support insertBefore operation"); - } else - ReactNativePrivateInterface.UIManager.setChildren(parent, [ - "number" === typeof node ? node : node._nativeTag - ]); - else if (4 !== tag && ((node = node.child), null !== node)) - for ( - insertOrAppendPlacementNodeIntoContainer(node, before, parent), - node = node.sibling; - null !== node; - - ) - insertOrAppendPlacementNodeIntoContainer(node, before, parent), - (node = node.sibling); -} -function insertOrAppendPlacementNode(node, before, parent) { - var tag = node.tag, - isHost = 5 === tag || 6 === tag; - if (isHost) - (node = isHost ? node.stateNode : node.stateNode.instance), - before - ? ((tag = parent._children), - (isHost = tag.indexOf(node)), - 0 <= isHost - ? (tag.splice(isHost, 1), - (before = tag.indexOf(before)), - tag.splice(before, 0, node), - ReactNativePrivateInterface.UIManager.manageChildren( - parent._nativeTag, - [isHost], - [before], - [], - [], - [] - )) - : ((before = tag.indexOf(before)), - tag.splice(before, 0, node), - ReactNativePrivateInterface.UIManager.manageChildren( - parent._nativeTag, - [], - [], - ["number" === typeof node ? node : node._nativeTag], - [before], - [] - ))) - : ((before = "number" === typeof node ? node : node._nativeTag), - (tag = parent._children), - (isHost = tag.indexOf(node)), - 0 <= isHost - ? (tag.splice(isHost, 1), - tag.push(node), + for (var node = finishedWork; ; ) { + var isHost = 5 === node.tag || 6 === node.tag; + if (isHost) { + var stateNode = isHost ? node.stateNode : node.stateNode.instance; + if (parentFiber) + if (isContainer) { + if ("number" === typeof parent) + throw Error("Container does not support insertBefore operation"); + } else { + isHost = parent; + var beforeChild = parentFiber, + children = isHost._children, + index = children.indexOf(stateNode); + 0 <= index + ? (children.splice(index, 1), + (beforeChild = children.indexOf(beforeChild)), + children.splice(beforeChild, 0, stateNode), ReactNativePrivateInterface.UIManager.manageChildren( - parent._nativeTag, - [isHost], - [tag.length - 1], + isHost._nativeTag, + [index], + [beforeChild], [], [], [] )) - : (tag.push(node), + : ((index = children.indexOf(beforeChild)), + children.splice(index, 0, stateNode), ReactNativePrivateInterface.UIManager.manageChildren( - parent._nativeTag, + isHost._nativeTag, [], [], - [before], - [tag.length - 1], + [ + "number" === typeof stateNode + ? stateNode + : stateNode._nativeTag + ], + [index], [] - ))); - else if (4 !== tag && ((node = node.child), null !== node)) - for ( - insertOrAppendPlacementNode(node, before, parent), node = node.sibling; - null !== node; - - ) - insertOrAppendPlacementNode(node, before, parent), (node = node.sibling); + )); + } + else + isContainer + ? ReactNativePrivateInterface.UIManager.setChildren(parent, [ + "number" === typeof stateNode ? stateNode : stateNode._nativeTag + ]) + : ((isHost = parent), + (children = + "number" === typeof stateNode ? stateNode : stateNode._nativeTag), + (index = isHost._children), + (beforeChild = index.indexOf(stateNode)), + 0 <= beforeChild + ? (index.splice(beforeChild, 1), + index.push(stateNode), + ReactNativePrivateInterface.UIManager.manageChildren( + isHost._nativeTag, + [beforeChild], + [index.length - 1], + [], + [], + [] + )) + : (index.push(stateNode), + ReactNativePrivateInterface.UIManager.manageChildren( + isHost._nativeTag, + [], + [], + [children], + [index.length - 1], + [] + ))); + } else if (4 !== node.tag && null !== node.child) { + node.child.return = node; + node = node.child; + continue; + } + if (node === finishedWork) break; + for (; null === node.sibling; ) { + if (null === node.return || node.return === finishedWork) return; + node = node.return; + } + node.sibling.return = node.return; + node = node.sibling; + } } function unmountHostComponents( finishedRoot$jscomp$0, - current, + current$$1, renderPriorityLevel$jscomp$0 ) { for ( - var node = current, + var node = current$$1, currentParentIsValid = !1, currentParent, currentParentIsContainer; @@ -5389,7 +5493,7 @@ function unmountHostComponents( (node$jscomp$0.child.return = node$jscomp$0), (node$jscomp$0 = node$jscomp$0.child); else { - if (node$jscomp$0 === root) break a; + if (node$jscomp$0 === root) break; for (; null === node$jscomp$0.sibling; ) { if (null === node$jscomp$0.return || node$jscomp$0.return === root) break a; @@ -5439,9 +5543,9 @@ function unmountHostComponents( node = node.child; continue; } - if (node === current) break; + if (node === current$$1) break; for (; null === node.sibling; ) { - if (null === node.return || node.return === current) return; + if (null === node.return || node.return === current$$1) return; node = node.return; 4 === node.tag && (currentParentIsValid = !1); } @@ -5449,22 +5553,21 @@ function unmountHostComponents( node = node.sibling; } } -function commitWork(current, finishedWork) { +function commitWork(current$$1, finishedWork) { switch (finishedWork.tag) { case 0: case 11: case 14: case 15: - case 22: - commitHookEffectListUnmount(3, finishedWork); - return; + commitHookEffectList(4, 8, finishedWork); + break; case 1: - return; + break; case 5: var instance = finishedWork.stateNode; if (null != instance) { var newProps = finishedWork.memoizedProps; - current = null !== current ? current.memoizedProps : newProps; + current$$1 = null !== current$$1 ? current$$1.memoizedProps : newProps; var updatePayload = finishedWork.updateQueue; finishedWork.updateQueue = null; null !== updatePayload && @@ -5472,7 +5575,7 @@ function commitWork(current, finishedWork) { instanceProps.set(instance._nativeTag, newProps), (newProps = diffProperties( null, - current, + current$$1, newProps, finishedWork.validAttributes )), @@ -5483,7 +5586,7 @@ function commitWork(current, finishedWork) { newProps )); } - return; + break; case 6: if (null === finishedWork.stateNode) throw Error( @@ -5494,11 +5597,11 @@ function commitWork(current, finishedWork) { "RCTRawText", { text: finishedWork.memoizedProps } ); - return; + break; case 3: - return; + break; case 12: - return; + break; case 13: instance = finishedWork; null === finishedWork.memoizedState @@ -5507,9 +5610,9 @@ function commitWork(current, finishedWork) { (instance = finishedWork.child), (globalMostRecentFallbackTime = now())); if (null !== instance) - a: for (current = instance; ; ) { - if (5 === current.tag) - if (((updatePayload = current.stateNode), newProps)) { + a: for (current$$1 = instance; ; ) { + if (5 === current$$1.tag) + if (((updatePayload = current$$1.stateNode), newProps)) { var viewConfig = updatePayload.viewConfig; var updatePayload$jscomp$0 = diffProperties( null, @@ -5523,8 +5626,8 @@ function commitWork(current, finishedWork) { updatePayload$jscomp$0 ); } else { - updatePayload = current.stateNode; - updatePayload$jscomp$0 = current.memoizedProps; + updatePayload = current$$1.stateNode; + updatePayload$jscomp$0 = current$$1.memoizedProps; viewConfig = updatePayload.viewConfig; var prevProps = Object.assign({}, updatePayload$jscomp$0, { style: [updatePayload$jscomp$0.style, { display: "none" }] @@ -5542,41 +5645,47 @@ function commitWork(current, finishedWork) { ); } else { - if (6 === current.tag) throw Error("Not yet implemented."); + if (6 === current$$1.tag) throw Error("Not yet implemented."); if ( - 13 === current.tag && - null !== current.memoizedState && - null === current.memoizedState.dehydrated + 13 === current$$1.tag && + null !== current$$1.memoizedState && + null === current$$1.memoizedState.dehydrated ) { - updatePayload = current.child.sibling; - updatePayload.return = current; - current = updatePayload; + updatePayload = current$$1.child.sibling; + updatePayload.return = current$$1; + current$$1 = updatePayload; continue; - } else if (null !== current.child) { - current.child.return = current; - current = current.child; + } else if (null !== current$$1.child) { + current$$1.child.return = current$$1; + current$$1 = current$$1.child; continue; } } - if (current === instance) break; - for (; null === current.sibling; ) { - if (null === current.return || current.return === instance) break a; - current = current.return; + if (current$$1 === instance) break a; + for (; null === current$$1.sibling; ) { + if (null === current$$1.return || current$$1.return === instance) + break a; + current$$1 = current$$1.return; } - current.sibling.return = current.return; - current = current.sibling; + current$$1.sibling.return = current$$1.return; + current$$1 = current$$1.sibling; } attachSuspenseRetryListeners(finishedWork); - return; + break; case 19: attachSuspenseRetryListeners(finishedWork); - return; + break; case 17: - return; + break; + case 20: + break; + case 21: + 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." + ); } - 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 thenables = finishedWork.updateQueue; @@ -5635,7 +5744,7 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { return expirationTime; } var ceil = Math.ceil, - ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, + ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, NoContext = 0, LegacyUnbatchedContext = 8, @@ -5650,7 +5759,7 @@ var ceil = Math.ceil, executionContext = NoContext, workInProgressRoot = null, workInProgress = null, - renderExpirationTime$1 = 0, + renderExpirationTime = 0, workInProgressRootExitStatus = RootIncomplete, workInProgressRootFatalError = null, workInProgressRootLatestProcessedExpirationTime = 1073741823, @@ -5677,8 +5786,8 @@ function requestCurrentTimeForUpdate() { return (executionContext & (RenderContext | CommitContext)) !== NoContext ? 1073741821 - ((now() / 10) | 0) : 0 !== currentEventTime - ? currentEventTime - : (currentEventTime = 1073741821 - ((now() / 10) | 0)); + ? currentEventTime + : (currentEventTime = 1073741821 - ((now() / 10) | 0)); } function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { fiber = fiber.mode; @@ -5686,7 +5795,7 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { var priorityLevel = getCurrentPriorityLevel(); if (0 === (fiber & 4)) return 99 === priorityLevel ? 1073741823 : 1073741822; if ((executionContext & RenderContext) !== NoContext) - return renderExpirationTime$1; + return renderExpirationTime; if (null !== suspenseConfig) currentTime = 1073741821 - @@ -5718,11 +5827,11 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { throw Error("Expected a valid priority level"); } null !== workInProgressRoot && - currentTime === renderExpirationTime$1 && + currentTime === renderExpirationTime && --currentTime; return currentTime; } -function scheduleWork(fiber, expirationTime) { +function scheduleUpdateOnFiber(fiber, expirationTime) { if (50 < nestedUpdateCount) throw ((nestedUpdateCount = 0), (rootWithNestedUpdates = null), @@ -5779,7 +5888,7 @@ function markUpdateTimeFromFiberToRoot(fiber, expirationTime) { (workInProgressRoot === root && (markUnprocessedUpdateTime(expirationTime), workInProgressRootExitStatus === RootSuspendedWithDelay && - markRootSuspendedAtTime(root, renderExpirationTime$1)), + markRootSuspendedAtTime(root, renderExpirationTime)), markRootUpdatedAtTime(root, expirationTime)); return root; } @@ -5788,10 +5897,9 @@ function getNextRootExpirationTimeToWorkOn(root) { if (0 !== lastExpiredTime) return lastExpiredTime; lastExpiredTime = root.firstPendingTime; if (!isRootSuspendedAtTime(root, lastExpiredTime)) return lastExpiredTime; - var lastPingedTime = root.lastPingedTime; + lastExpiredTime = root.lastPingedTime; root = root.nextKnownPendingLevel; - root = lastPingedTime > root ? lastPingedTime : root; - return 2 >= root && lastExpiredTime !== root ? 0 : root; + return lastExpiredTime > root ? lastExpiredTime : root; } function ensureRootIsScheduled(root) { if (0 !== root.lastExpiredTime) @@ -5840,233 +5948,271 @@ function ensureRootIsScheduled(root) { } function performConcurrentWorkOnRoot(root, didTimeout) { currentEventTime = 0; - if (didTimeout) { - didTimeout = requestCurrentTimeForUpdate(); - var lastExpiredTime = root.lastExpiredTime; - if (0 === lastExpiredTime || lastExpiredTime > didTimeout) - root.lastExpiredTime = didTimeout; - ensureRootIsScheduled(root); - return null; - } - lastExpiredTime = getNextRootExpirationTimeToWorkOn(root); - if (0 === lastExpiredTime) return null; - didTimeout = root.callbackNode; - if ((executionContext & (RenderContext | CommitContext)) !== NoContext) - throw Error("Should not already be working."); - flushPassiveEffects(); - var expirationTime = lastExpiredTime, - prevExecutionContext = executionContext; - executionContext |= RenderContext; - var exitStatus = pushDispatcher(); - if (root !== workInProgressRoot || expirationTime !== renderExpirationTime$1) - prepareFreshStack(root, expirationTime), - startWorkOnPendingInteractions(root, expirationTime); - expirationTime = pushInteractions(root); - do - try { - workLoopConcurrent(); - break; - } catch (thrownValue) { - handleError(root, thrownValue); - } - while (1); - resetContextDependencies(); - tracing.__interactionsRef.current = expirationTime; - ReactCurrentDispatcher$1.current = exitStatus; - executionContext = prevExecutionContext; - null !== workInProgress - ? (exitStatus = RootIncomplete) - : ((workInProgressRoot = null), - (exitStatus = workInProgressRootExitStatus)); - if (exitStatus !== RootIncomplete) { - exitStatus === RootErrored && - ((lastExpiredTime = 2 < lastExpiredTime ? 2 : lastExpiredTime), - (exitStatus = renderRootSync(root, lastExpiredTime))); - if (exitStatus === RootFatalErrored) - throw ((didTimeout = workInProgressRootFatalError), - prepareFreshStack(root, lastExpiredTime), - markRootSuspendedAtTime(root, lastExpiredTime), + if (didTimeout) + return ( + (didTimeout = requestCurrentTimeForUpdate()), + markRootExpiredAtTime(root, didTimeout), ensureRootIsScheduled(root), - didTimeout); - prevExecutionContext = root.finishedWork = root.current.alternate; - root.finishedExpirationTime = lastExpiredTime; - switch (exitStatus) { - case RootIncomplete: - case RootFatalErrored: - throw Error("Root did not complete. This is a bug in React."); - case RootErrored: - commitRoot(root); - break; - case RootSuspended: - markRootSuspendedAtTime(root, lastExpiredTime); - exitStatus = root.lastSuspendedTime; - lastExpiredTime === exitStatus && - (root.nextKnownPendingLevel = getRemainingExpirationTime( - prevExecutionContext - )); - if ( - 1073741823 === workInProgressRootLatestProcessedExpirationTime && - ((prevExecutionContext = - globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now()), - 10 < prevExecutionContext) - ) { - if ( - workInProgressRootHasPendingPing && - ((expirationTime = root.lastPingedTime), - 0 === expirationTime || expirationTime >= lastExpiredTime) - ) { - root.lastPingedTime = lastExpiredTime; - prepareFreshStack(root, lastExpiredTime); - break; - } - expirationTime = getNextRootExpirationTimeToWorkOn(root); - if (0 !== expirationTime && expirationTime !== lastExpiredTime) break; - if (0 !== exitStatus && exitStatus !== lastExpiredTime) { - root.lastPingedTime = exitStatus; - break; - } - root.timeoutHandle = scheduleTimeout( - commitRoot.bind(null, root), - prevExecutionContext - ); - break; - } - commitRoot(root); - break; - case RootSuspendedWithDelay: - markRootSuspendedAtTime(root, lastExpiredTime); - exitStatus = root.lastSuspendedTime; - lastExpiredTime === exitStatus && - (root.nextKnownPendingLevel = getRemainingExpirationTime( - prevExecutionContext - )); - if ( - workInProgressRootHasPendingPing && - ((prevExecutionContext = root.lastPingedTime), - 0 === prevExecutionContext || prevExecutionContext >= lastExpiredTime) - ) { - root.lastPingedTime = lastExpiredTime; - prepareFreshStack(root, lastExpiredTime); - break; - } - prevExecutionContext = getNextRootExpirationTimeToWorkOn(root); - if ( - 0 !== prevExecutionContext && - prevExecutionContext !== lastExpiredTime - ) - break; - if (0 !== exitStatus && exitStatus !== lastExpiredTime) { - root.lastPingedTime = exitStatus; - break; - } - 1073741823 !== workInProgressRootLatestSuspenseTimeout - ? (prevExecutionContext = - 10 * (1073741821 - workInProgressRootLatestSuspenseTimeout) - - now()) - : 1073741823 === workInProgressRootLatestProcessedExpirationTime - ? (prevExecutionContext = 0) - : ((prevExecutionContext = - 10 * - (1073741821 - workInProgressRootLatestProcessedExpirationTime) - - 5e3), - (exitStatus = now()), - (lastExpiredTime = - 10 * (1073741821 - lastExpiredTime) - exitStatus), - (prevExecutionContext = exitStatus - prevExecutionContext), - 0 > prevExecutionContext && (prevExecutionContext = 0), - (prevExecutionContext = - (120 > prevExecutionContext - ? 120 - : 480 > prevExecutionContext - ? 480 - : 1080 > prevExecutionContext - ? 1080 - : 1920 > prevExecutionContext - ? 1920 - : 3e3 > prevExecutionContext - ? 3e3 - : 4320 > prevExecutionContext - ? 4320 - : 1960 * ceil(prevExecutionContext / 1960)) - - prevExecutionContext), - lastExpiredTime < prevExecutionContext && - (prevExecutionContext = lastExpiredTime)); - if (10 < prevExecutionContext) { - root.timeoutHandle = scheduleTimeout( - commitRoot.bind(null, root), - prevExecutionContext - ); + null + ); + var expirationTime = getNextRootExpirationTimeToWorkOn(root); + if (0 !== expirationTime) { + didTimeout = root.callbackNode; + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) + throw Error("Should not already be working."); + flushPassiveEffects(); + if (root !== workInProgressRoot || expirationTime !== renderExpirationTime) + prepareFreshStack(root, expirationTime), + startWorkOnPendingInteractions(root, expirationTime); + if (null !== workInProgress) { + var prevExecutionContext = executionContext; + executionContext |= RenderContext; + var prevDispatcher = pushDispatcher(root), + prevInteractions = pushInteractions(root); + do + try { + workLoopConcurrent(); break; + } catch (thrownValue) { + handleError(root, thrownValue); } - commitRoot(root); - break; - case RootCompleted: - if ( - 1073741823 !== workInProgressRootLatestProcessedExpirationTime && - null !== workInProgressRootCanSuspendUsingConfig + while (1); + resetContextDependencies(); + executionContext = prevExecutionContext; + ReactCurrentDispatcher.current = prevDispatcher; + tracing.__interactionsRef.current = prevInteractions; + if (workInProgressRootExitStatus === RootFatalErrored) + throw ((didTimeout = workInProgressRootFatalError), + prepareFreshStack(root, expirationTime), + markRootSuspendedAtTime(root, expirationTime), + ensureRootIsScheduled(root), + didTimeout); + if (null === workInProgress) + switch ( + ((prevDispatcher = root.finishedWork = root.current.alternate), + (root.finishedExpirationTime = expirationTime), + (prevExecutionContext = workInProgressRootExitStatus), + (workInProgressRoot = null), + prevExecutionContext) ) { - expirationTime = workInProgressRootLatestProcessedExpirationTime; - var suspenseConfig = workInProgressRootCanSuspendUsingConfig; - prevExecutionContext = suspenseConfig.busyMinDurationMs | 0; - 0 >= prevExecutionContext - ? (prevExecutionContext = 0) - : ((exitStatus = suspenseConfig.busyDelayMs | 0), - (expirationTime = - now() - - (10 * (1073741821 - expirationTime) - - (suspenseConfig.timeoutMs | 0 || 5e3))), - (prevExecutionContext = - expirationTime <= exitStatus - ? 0 - : exitStatus + prevExecutionContext - expirationTime)); - if (10 < prevExecutionContext) { - markRootSuspendedAtTime(root, lastExpiredTime); - root.timeoutHandle = scheduleTimeout( - commitRoot.bind(null, root), - prevExecutionContext + case RootIncomplete: + case RootFatalErrored: + throw Error("Root did not complete. This is a bug in React."); + case RootErrored: + markRootExpiredAtTime( + root, + 2 < expirationTime ? 2 : expirationTime ); break; - } + case RootSuspended: + markRootSuspendedAtTime(root, expirationTime); + prevExecutionContext = root.lastSuspendedTime; + expirationTime === prevExecutionContext && + (root.nextKnownPendingLevel = getRemainingExpirationTime( + prevDispatcher + )); + if ( + 1073741823 === workInProgressRootLatestProcessedExpirationTime && + ((prevDispatcher = + globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now()), + 10 < prevDispatcher) + ) { + if ( + workInProgressRootHasPendingPing && + ((prevInteractions = root.lastPingedTime), + 0 === prevInteractions || prevInteractions >= expirationTime) + ) { + root.lastPingedTime = expirationTime; + prepareFreshStack(root, expirationTime); + break; + } + prevInteractions = getNextRootExpirationTimeToWorkOn(root); + if (0 !== prevInteractions && prevInteractions !== expirationTime) + break; + if ( + 0 !== prevExecutionContext && + prevExecutionContext !== expirationTime + ) { + root.lastPingedTime = prevExecutionContext; + break; + } + root.timeoutHandle = scheduleTimeout( + commitRoot.bind(null, root), + prevDispatcher + ); + break; + } + commitRoot(root); + break; + case RootSuspendedWithDelay: + markRootSuspendedAtTime(root, expirationTime); + prevExecutionContext = root.lastSuspendedTime; + expirationTime === prevExecutionContext && + (root.nextKnownPendingLevel = getRemainingExpirationTime( + prevDispatcher + )); + if ( + workInProgressRootHasPendingPing && + ((prevDispatcher = root.lastPingedTime), + 0 === prevDispatcher || prevDispatcher >= expirationTime) + ) { + root.lastPingedTime = expirationTime; + prepareFreshStack(root, expirationTime); + break; + } + prevDispatcher = getNextRootExpirationTimeToWorkOn(root); + if (0 !== prevDispatcher && prevDispatcher !== expirationTime) + break; + if ( + 0 !== prevExecutionContext && + prevExecutionContext !== expirationTime + ) { + root.lastPingedTime = prevExecutionContext; + break; + } + 1073741823 !== workInProgressRootLatestSuspenseTimeout + ? (prevExecutionContext = + 10 * (1073741821 - workInProgressRootLatestSuspenseTimeout) - + now()) + : 1073741823 === workInProgressRootLatestProcessedExpirationTime + ? (prevExecutionContext = 0) + : ((prevExecutionContext = + 10 * + (1073741821 - + workInProgressRootLatestProcessedExpirationTime) - + 5e3), + (prevDispatcher = now()), + (expirationTime = + 10 * (1073741821 - expirationTime) - prevDispatcher), + (prevExecutionContext = + prevDispatcher - prevExecutionContext), + 0 > prevExecutionContext && (prevExecutionContext = 0), + (prevExecutionContext = + (120 > prevExecutionContext + ? 120 + : 480 > prevExecutionContext + ? 480 + : 1080 > prevExecutionContext + ? 1080 + : 1920 > prevExecutionContext + ? 1920 + : 3e3 > prevExecutionContext + ? 3e3 + : 4320 > prevExecutionContext + ? 4320 + : 1960 * ceil(prevExecutionContext / 1960)) - + prevExecutionContext), + expirationTime < prevExecutionContext && + (prevExecutionContext = expirationTime)); + if (10 < prevExecutionContext) { + root.timeoutHandle = scheduleTimeout( + commitRoot.bind(null, root), + prevExecutionContext + ); + break; + } + commitRoot(root); + break; + case RootCompleted: + if ( + 1073741823 !== workInProgressRootLatestProcessedExpirationTime && + null !== workInProgressRootCanSuspendUsingConfig + ) { + prevInteractions = workInProgressRootLatestProcessedExpirationTime; + var suspenseConfig = workInProgressRootCanSuspendUsingConfig; + prevExecutionContext = suspenseConfig.busyMinDurationMs | 0; + 0 >= prevExecutionContext + ? (prevExecutionContext = 0) + : ((prevDispatcher = suspenseConfig.busyDelayMs | 0), + (prevInteractions = + now() - + (10 * (1073741821 - prevInteractions) - + (suspenseConfig.timeoutMs | 0 || 5e3))), + (prevExecutionContext = + prevInteractions <= prevDispatcher + ? 0 + : prevDispatcher + + prevExecutionContext - + prevInteractions)); + if (10 < prevExecutionContext) { + markRootSuspendedAtTime(root, expirationTime); + root.timeoutHandle = scheduleTimeout( + commitRoot.bind(null, root), + prevExecutionContext + ); + break; + } + } + commitRoot(root); + break; + default: + throw Error("Unknown root exit status."); } - commitRoot(root); - break; - default: - throw Error("Unknown root exit status."); + ensureRootIsScheduled(root); + if (root.callbackNode === didTimeout) + return performConcurrentWorkOnRoot.bind(null, root); } } - ensureRootIsScheduled(root); - return root.callbackNode === didTimeout - ? performConcurrentWorkOnRoot.bind(null, root) - : null; + return null; } function performSyncWorkOnRoot(root) { - if ((executionContext & (RenderContext | CommitContext)) !== NoContext) - throw Error("Should not already be working."); - flushPassiveEffects(); var lastExpiredTime = root.lastExpiredTime; - lastExpiredTime = - 0 !== lastExpiredTime - ? root === workInProgressRoot && renderExpirationTime$1 >= lastExpiredTime - ? renderExpirationTime$1 - : lastExpiredTime - : 1073741823; - var exitStatus = renderRootSync(root, lastExpiredTime); - 0 !== root.tag && - exitStatus === RootErrored && - ((lastExpiredTime = 2 < lastExpiredTime ? 2 : lastExpiredTime), - (exitStatus = renderRootSync(root, lastExpiredTime))); - if (exitStatus === RootFatalErrored) - throw ((exitStatus = workInProgressRootFatalError), - prepareFreshStack(root, lastExpiredTime), - markRootSuspendedAtTime(root, lastExpiredTime), - ensureRootIsScheduled(root), - exitStatus); - root.finishedWork = root.current.alternate; - root.finishedExpirationTime = lastExpiredTime; - commitRoot(root); - ensureRootIsScheduled(root); + lastExpiredTime = 0 !== lastExpiredTime ? lastExpiredTime : 1073741823; + if (root.finishedExpirationTime === lastExpiredTime) commitRoot(root); + else { + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) + throw Error("Should not already be working."); + flushPassiveEffects(); + if (root !== workInProgressRoot || lastExpiredTime !== renderExpirationTime) + prepareFreshStack(root, lastExpiredTime), + startWorkOnPendingInteractions(root, lastExpiredTime); + if (null !== workInProgress) { + var prevExecutionContext = executionContext; + executionContext |= RenderContext; + var prevDispatcher = pushDispatcher(root), + prevInteractions = pushInteractions(root); + do + try { + workLoopSync(); + break; + } catch (thrownValue) { + handleError(root, thrownValue); + } + while (1); + resetContextDependencies(); + executionContext = prevExecutionContext; + ReactCurrentDispatcher.current = prevDispatcher; + tracing.__interactionsRef.current = prevInteractions; + if (workInProgressRootExitStatus === RootFatalErrored) + throw ((prevExecutionContext = workInProgressRootFatalError), + prepareFreshStack(root, lastExpiredTime), + markRootSuspendedAtTime(root, lastExpiredTime), + ensureRootIsScheduled(root), + prevExecutionContext); + if (null !== workInProgress) + throw Error( + "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." + ); + root.finishedWork = root.current.alternate; + root.finishedExpirationTime = lastExpiredTime; + workInProgressRoot = null; + commitRoot(root); + ensureRootIsScheduled(root); + } + } return null; } +function flushPendingDiscreteUpdates() { + if (null !== rootsWithPendingDiscreteUpdates) { + var roots = rootsWithPendingDiscreteUpdates; + rootsWithPendingDiscreteUpdates = null; + roots.forEach(function(expirationTime, root) { + markRootExpiredAtTime(root, expirationTime); + ensureRootIsScheduled(root); + }); + flushSyncCallbackQueue(); + } +} function prepareFreshStack(root, expirationTime) { root.finishedWork = null; root.finishedExpirationTime = 0; @@ -6078,27 +6224,26 @@ function prepareFreshStack(root, expirationTime) { var interruptedWork = timeoutHandle; switch (interruptedWork.tag) { case 1: - interruptedWork = interruptedWork.type.childContextTypes; - null !== interruptedWork && - void 0 !== interruptedWork && - popContext(); + var childContextTypes = interruptedWork.type.childContextTypes; + null !== childContextTypes && + void 0 !== childContextTypes && + popContext(interruptedWork); break; case 3: - popHostContainer(); - pop(didPerformWorkStackCursor); - pop(contextStackCursor); + popHostContainer(interruptedWork); + popTopLevelContextObject(interruptedWork); break; case 5: popHostContext(interruptedWork); break; case 4: - popHostContainer(); + popHostContainer(interruptedWork); break; case 13: - pop(suspenseStackCursor); + pop(suspenseStackCursor, interruptedWork); break; case 19: - pop(suspenseStackCursor); + pop(suspenseStackCursor, interruptedWork); break; case 10: popProvider(interruptedWork); @@ -6106,8 +6251,8 @@ function prepareFreshStack(root, expirationTime) { timeoutHandle = timeoutHandle.return; } workInProgressRoot = root; - workInProgress = createWorkInProgress(root.current, null); - renderExpirationTime$1 = expirationTime; + workInProgress = createWorkInProgress(root.current, null, expirationTime); + renderExpirationTime = expirationTime; workInProgressRootExitStatus = RootIncomplete; workInProgressRootFatalError = null; workInProgressRootLatestSuspenseTimeout = workInProgressRootLatestProcessedExpirationTime = 1073741823; @@ -6120,25 +6265,12 @@ function handleError(root$jscomp$0, thrownValue) { do { try { resetContextDependencies(); - ReactCurrentDispatcher.current = ContextOnlyDispatcher; - if (didScheduleRenderPhaseUpdate) - for ( - var hook = currentlyRenderingFiber$1.memoizedState; - null !== hook; - - ) { - var queue = hook.queue; - null !== queue && (queue.pending = null); - hook = hook.next; - } - renderExpirationTime = 0; - workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; - didScheduleRenderPhaseUpdate = !1; + resetHooks(); if (null === workInProgress || null === workInProgress.return) return ( (workInProgressRootExitStatus = RootFatalErrored), (workInProgressRootFatalError = thrownValue), - (workInProgress = null) + null ); workInProgress.mode & 8 && stopProfilerTimerIfRunningAndRecordDelta(workInProgress, !0); @@ -6147,7 +6279,7 @@ function handleError(root$jscomp$0, thrownValue) { returnFiber = workInProgress.return, sourceFiber = workInProgress, value = thrownValue; - thrownValue = renderExpirationTime$1; + thrownValue = renderExpirationTime; sourceFiber.effectTag |= 2048; sourceFiber.firstEffect = sourceFiber.lastEffect = null; if ( @@ -6155,17 +6287,8 @@ function handleError(root$jscomp$0, thrownValue) { "object" === typeof value && "function" === typeof value.then ) { - var thenable = value; - if (0 === (sourceFiber.mode & 2)) { - var currentSource = sourceFiber.alternate; - currentSource - ? ((sourceFiber.updateQueue = currentSource.updateQueue), - (sourceFiber.memoizedState = currentSource.memoizedState), - (sourceFiber.expirationTime = currentSource.expirationTime)) - : ((sourceFiber.updateQueue = null), - (sourceFiber.memoizedState = null)); - } - var hasInvisibleParentBoundary = + var thenable = value, + hasInvisibleParentBoundary = 0 !== (suspenseStackCursor.current & 1), _workInProgress = returnFiber; do { @@ -6180,10 +6303,10 @@ function handleError(root$jscomp$0, thrownValue) { void 0 === props.fallback ? !1 : !0 !== props.unstable_avoidThisFallback - ? !0 - : hasInvisibleParentBoundary - ? !1 - : !0; + ? !0 + : hasInvisibleParentBoundary + ? !1 + : !0; } } if (JSCompiler_temp) { @@ -6290,8 +6413,8 @@ function handleError(root$jscomp$0, thrownValue) { } while (1); } function pushDispatcher() { - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = ContextOnlyDispatcher; return null === prevDispatcher ? ContextOnlyDispatcher : prevDispatcher; } function pushInteractions(root) { @@ -6313,33 +6436,6 @@ function markUnprocessedUpdateTime(expirationTime) { expirationTime > workInProgressRootNextUnprocessedUpdateTime && (workInProgressRootNextUnprocessedUpdateTime = expirationTime); } -function renderRootSync(root, expirationTime) { - var prevExecutionContext = executionContext; - executionContext |= RenderContext; - var prevDispatcher = pushDispatcher(); - if (root !== workInProgressRoot || expirationTime !== renderExpirationTime$1) - prepareFreshStack(root, expirationTime), - startWorkOnPendingInteractions(root, expirationTime); - expirationTime = pushInteractions(root); - do - try { - workLoopSync(); - break; - } catch (thrownValue) { - handleError(root, thrownValue); - } - while (1); - resetContextDependencies(); - tracing.__interactionsRef.current = expirationTime; - executionContext = prevExecutionContext; - ReactCurrentDispatcher$1.current = prevDispatcher; - if (null !== workInProgress) - throw Error( - "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." - ); - workInProgressRoot = null; - return workInProgressRootExitStatus; -} function workLoopSync() { for (; null !== workInProgress; ) workInProgress = performUnitOfWork(workInProgress); @@ -6349,35 +6445,43 @@ function workLoopConcurrent() { workInProgress = performUnitOfWork(workInProgress); } function performUnitOfWork(unitOfWork) { - var current = unitOfWork.alternate; + var current$$1 = unitOfWork.alternate; 0 !== (unitOfWork.mode & 8) ? ((profilerStartTime = now$1()), 0 > unitOfWork.actualStartTime && (unitOfWork.actualStartTime = now$1()), - (current = beginWork$1(current, unitOfWork, renderExpirationTime$1)), + (current$$1 = beginWork$$1(current$$1, unitOfWork, renderExpirationTime)), stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, !0)) - : (current = beginWork$1(current, unitOfWork, renderExpirationTime$1)); + : (current$$1 = beginWork$$1(current$$1, unitOfWork, renderExpirationTime)); unitOfWork.memoizedProps = unitOfWork.pendingProps; - null === current && (current = completeUnitOfWork(unitOfWork)); + null === current$$1 && (current$$1 = completeUnitOfWork(unitOfWork)); ReactCurrentOwner$2.current = null; - return current; + return current$$1; } function completeUnitOfWork(unitOfWork) { workInProgress = unitOfWork; do { - var current = workInProgress.alternate; + var current$$1 = workInProgress.alternate; unitOfWork = workInProgress.return; if (0 === (workInProgress.effectTag & 2048)) { if (0 === (workInProgress.mode & 8)) - current = completeWork(current, workInProgress, renderExpirationTime$1); + current$$1 = completeWork( + current$$1, + workInProgress, + renderExpirationTime + ); else { var fiber = workInProgress; profilerStartTime = now$1(); 0 > fiber.actualStartTime && (fiber.actualStartTime = now$1()); - current = completeWork(current, workInProgress, renderExpirationTime$1); + current$$1 = completeWork( + current$$1, + workInProgress, + renderExpirationTime + ); stopProfilerTimerIfRunningAndRecordDelta(workInProgress, !1); } fiber = workInProgress; - if (1 === renderExpirationTime$1 || 1 !== fiber.childExpirationTime) { + if (1 === renderExpirationTime || 1 !== fiber.childExpirationTime) { var newChildExpirationTime = 0; if (0 !== (fiber.mode & 8)) { for ( @@ -6415,7 +6519,7 @@ function completeUnitOfWork(unitOfWork) { (actualDuration = actualDuration.sibling); fiber.childExpirationTime = newChildExpirationTime; } - if (null !== current) return current; + if (null !== current$$1) return current$$1; null !== unitOfWork && 0 === (unitOfWork.effectTag & 2048) && (null === unitOfWork.firstEffect && @@ -6430,7 +6534,7 @@ function completeUnitOfWork(unitOfWork) { : (unitOfWork.firstEffect = workInProgress), (unitOfWork.lastEffect = workInProgress))); } else { - current = unwindWork(workInProgress); + current$$1 = unwindWork(workInProgress, renderExpirationTime); if (0 !== (workInProgress.mode & 8)) { stopProfilerTimerIfRunningAndRecordDelta(workInProgress, !1); fiber = workInProgress.actualDuration; @@ -6443,13 +6547,14 @@ function completeUnitOfWork(unitOfWork) { (newChildExpirationTime = newChildExpirationTime.sibling); workInProgress.actualDuration = fiber; } - if (null !== current) return (current.effectTag &= 2047), current; + if (null !== current$$1) + return (current$$1.effectTag &= 2047), current$$1; null !== unitOfWork && ((unitOfWork.firstEffect = unitOfWork.lastEffect = null), (unitOfWork.effectTag |= 2048)); } - current = workInProgress.sibling; - if (null !== current) return current; + current$$1 = workInProgress.sibling; + if (null !== current$$1) return current$$1; workInProgress = unitOfWork; } while (null !== workInProgress); workInProgressRootExitStatus === RootIncomplete && @@ -6467,8 +6572,7 @@ function commitRoot(root) { return null; } function commitRootImpl(root$jscomp$0, renderPriorityLevel$jscomp$0) { - do flushPassiveEffects(); - while (null !== rootWithPendingPassiveEffects); + flushPassiveEffects(); if ((executionContext & (RenderContext | CommitContext)) !== NoContext) throw Error("Should not already be working."); var finishedWork = root$jscomp$0.finishedWork, @@ -6497,8 +6601,7 @@ function commitRootImpl(root$jscomp$0, renderPriorityLevel$jscomp$0) { expirationTime <= root$jscomp$0.lastExpiredTime && (root$jscomp$0.lastExpiredTime = 0); root$jscomp$0 === workInProgressRoot && - ((workInProgress = workInProgressRoot = null), - (renderExpirationTime$1 = 0)); + ((workInProgress = workInProgressRoot = null), (renderExpirationTime = 0)); 1 < finishedWork.effectTag ? null !== finishedWork.lastEffect ? ((finishedWork.lastEffect.nextEffect = finishedWork), @@ -6532,9 +6635,9 @@ function commitRootImpl(root$jscomp$0, renderPriorityLevel$jscomp$0) { ) { var effectTag = nextEffect.effectTag; if (effectTag & 128) { - var current = nextEffect.alternate; - if (null !== current) { - var currentRef = current.ref; + var current$$1 = nextEffect.alternate; + if (null !== current$$1) { + var currentRef = current$$1.ref; null !== currentRef && ("function" === typeof currentRef ? currentRef(null) @@ -6562,13 +6665,13 @@ function commitRootImpl(root$jscomp$0, renderPriorityLevel$jscomp$0) { commitWork(nextEffect.alternate, nextEffect); break; case 8: - var current$jscomp$0 = nextEffect; + var current$$1$jscomp$0 = nextEffect; unmountHostComponents( root, - current$jscomp$0, + current$$1$jscomp$0, renderPriorityLevel ); - detachFiber(current$jscomp$0); + detachFiber(current$$1$jscomp$0); } nextEffect = nextEffect.nextEffect; } @@ -6582,25 +6685,113 @@ function commitRootImpl(root$jscomp$0, renderPriorityLevel$jscomp$0) { nextEffect = remainingExpirationTimeBeforeCommit; do try { - for (effectTag = root$jscomp$0; null !== nextEffect; ) { + for ( + effectTag = root$jscomp$0, current$$1 = expirationTime; + null !== nextEffect; + + ) { var effectTag$jscomp$0 = nextEffect.effectTag; - effectTag$jscomp$0 & 36 && - commitLifeCycles(effectTag, nextEffect.alternate, nextEffect); + if (effectTag$jscomp$0 & 36) { + renderPriorityLevel = effectTag; + var current$$1$jscomp$1 = nextEffect.alternate; + currentRef = nextEffect; + root = current$$1; + switch (currentRef.tag) { + case 0: + case 11: + case 15: + commitHookEffectList(16, 32, currentRef); + break; + case 1: + var instance = currentRef.stateNode; + if (currentRef.effectTag & 4) + if (null === current$$1$jscomp$1) + instance.componentDidMount(); + else { + var prevProps = + currentRef.elementType === currentRef.type + ? current$$1$jscomp$1.memoizedProps + : resolveDefaultProps( + currentRef.type, + current$$1$jscomp$1.memoizedProps + ); + instance.componentDidUpdate( + prevProps, + current$$1$jscomp$1.memoizedState, + instance.__reactInternalSnapshotBeforeUpdate + ); + } + var updateQueue = currentRef.updateQueue; + null !== updateQueue && + commitUpdateQueue(currentRef, updateQueue, instance, root); + break; + case 3: + var _updateQueue = currentRef.updateQueue; + if (null !== _updateQueue) { + renderPriorityLevel = null; + if (null !== currentRef.child) + switch (currentRef.child.tag) { + case 5: + renderPriorityLevel = currentRef.child.stateNode; + break; + case 1: + renderPriorityLevel = currentRef.child.stateNode; + } + commitUpdateQueue( + currentRef, + _updateQueue, + renderPriorityLevel, + root + ); + } + break; + case 5: + break; + case 6: + break; + case 4: + break; + case 12: + var onRender = currentRef.memoizedProps.onRender; + "function" === typeof onRender && + onRender( + currentRef.memoizedProps.id, + null === current$$1$jscomp$1 ? "mount" : "update", + currentRef.actualDuration, + currentRef.treeBaseDuration, + currentRef.actualStartTime, + commitTime, + renderPriorityLevel.memoizedInteractions + ); + break; + case 13: + break; + case 19: + case 17: + case 20: + case 21: + 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 (effectTag$jscomp$0 & 128) { - current = void 0; + currentRef = void 0; var ref = nextEffect.ref; if (null !== ref) { - var instance = nextEffect.stateNode; + var instance$jscomp$0 = nextEffect.stateNode; switch (nextEffect.tag) { case 5: - current = instance; + currentRef = instance$jscomp$0; break; default: - current = instance; + currentRef = instance$jscomp$0; } "function" === typeof ref - ? ref(current) - : (ref.current = current); + ? ref(currentRef) + : (ref.current = currentRef); } } nextEffect = nextEffect.nextEffect; @@ -6636,13 +6827,13 @@ function commitRootImpl(root$jscomp$0, renderPriorityLevel$jscomp$0) { for ( remainingExpirationTimeBeforeCommit = spawnedWorkDuringRender, spawnedWorkDuringRender = null, - ref = 0; - ref < remainingExpirationTimeBeforeCommit.length; - ref++ + current$$1$jscomp$1 = 0; + current$$1$jscomp$1 < remainingExpirationTimeBeforeCommit.length; + current$$1$jscomp$1++ ) scheduleInteractions( root$jscomp$0, - remainingExpirationTimeBeforeCommit[ref], + remainingExpirationTimeBeforeCommit[current$$1$jscomp$1], root$jscomp$0.memoizedInteractions ); schedulePendingInteractions(root$jscomp$0, renderPriorityLevel$jscomp$0); @@ -6703,28 +6894,27 @@ function flushPassiveEffectsImpl() { executionContext |= CommitContext; for ( var prevInteractions = pushInteractions(root), - _effect2 = root.current.firstEffect; - null !== _effect2; + effect = root.current.firstEffect; + null !== effect; ) { try { - var finishedWork = _effect2; + var finishedWork = effect; if (0 !== (finishedWork.effectTag & 512)) switch (finishedWork.tag) { case 0: case 11: case 15: - case 22: - commitHookEffectListUnmount(5, finishedWork), - commitHookEffectListMount(5, finishedWork); + commitHookEffectList(128, 0, finishedWork), + commitHookEffectList(0, 64, finishedWork); } } catch (error) { - if (null === _effect2) throw Error("Should be working on an effect."); - captureCommitPhaseError(_effect2, error); + if (null === effect) throw Error("Should be working on an effect."); + captureCommitPhaseError(effect, error); } - finishedWork = _effect2.nextEffect; - _effect2.nextEffect = null; - _effect2 = finishedWork; + finishedWork = effect.nextEffect; + effect.nextEffect = null; + effect = finishedWork; } tracing.__interactionsRef.current = prevInteractions; finishPendingInteractions(root, expirationTime); @@ -6773,17 +6963,19 @@ function captureCommitPhaseError(sourceFiber, error) { function pingSuspendedRoot(root, thenable, suspendedTime) { var pingCache = root.pingCache; null !== pingCache && pingCache.delete(thenable); - workInProgressRoot === root && renderExpirationTime$1 === suspendedTime + workInProgressRoot === root && renderExpirationTime === suspendedTime ? workInProgressRootExitStatus === RootSuspendedWithDelay || (workInProgressRootExitStatus === RootSuspended && 1073741823 === workInProgressRootLatestProcessedExpirationTime && now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) - ? prepareFreshStack(root, renderExpirationTime$1) + ? prepareFreshStack(root, renderExpirationTime) : (workInProgressRootHasPendingPing = !0) : isRootSuspendedAtTime(root, suspendedTime) && ((thenable = root.lastPingedTime), (0 !== thenable && thenable < suspendedTime) || ((root.lastPingedTime = suspendedTime), + root.finishedExpirationTime === suspendedTime && + ((root.finishedExpirationTime = 0), (root.finishedWork = null)), ensureRootIsScheduled(root), schedulePendingInteractions(root, suspendedTime))); } @@ -6799,12 +6991,12 @@ function resolveRetryThenable(boundaryFiber, thenable) { (ensureRootIsScheduled(boundaryFiber), schedulePendingInteractions(boundaryFiber, thenable)); } -var beginWork$1; -beginWork$1 = function(current, workInProgress, renderExpirationTime) { +var beginWork$$1; +beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { var updateExpirationTime = workInProgress.expirationTime; - if (null !== current) + if (null !== current$$1) if ( - current.memoizedProps !== workInProgress.pendingProps || + current$$1.memoizedProps !== workInProgress.pendingProps || didPerformWorkStackCursor.current ) didReceiveUpdate = !0; @@ -6829,17 +7021,11 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { ); break; case 10: - updateExpirationTime = workInProgress.memoizedProps.value; - var context = workInProgress.type._context; - push(valueCursor, context._currentValue); - context._currentValue = updateExpirationTime; + pushProvider(workInProgress, workInProgress.memoizedProps.value); break; case 12: workInProgress.childExpirationTime >= renderExpirationTime && (workInProgress.effectTag |= 4); - updateExpirationTime = workInProgress.stateNode; - updateExpirationTime.effectDuration = 0; - updateExpirationTime.passiveEffectDuration = 0; break; case 13: if (null !== workInProgress.memoizedState) { @@ -6849,40 +7035,52 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { updateExpirationTime >= renderExpirationTime ) return updateSuspenseComponent( - current, + current$$1, workInProgress, renderExpirationTime ); - push(suspenseStackCursor, suspenseStackCursor.current & 1); + push( + suspenseStackCursor, + suspenseStackCursor.current & 1, + workInProgress + ); workInProgress = bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ); return null !== workInProgress ? workInProgress.sibling : null; } - push(suspenseStackCursor, suspenseStackCursor.current & 1); + push( + suspenseStackCursor, + suspenseStackCursor.current & 1, + workInProgress + ); break; case 19: updateExpirationTime = workInProgress.childExpirationTime >= renderExpirationTime; - if (0 !== (current.effectTag & 64)) { + if (0 !== (current$$1.effectTag & 64)) { if (updateExpirationTime) return updateSuspenseListComponent( - current, + current$$1, workInProgress, renderExpirationTime ); workInProgress.effectTag |= 64; } - context = workInProgress.memoizedState; - null !== context && - ((context.rendering = null), (context.tail = null)); - push(suspenseStackCursor, suspenseStackCursor.current); + var renderState = workInProgress.memoizedState; + null !== renderState && + ((renderState.rendering = null), (renderState.tail = null)); + push( + suspenseStackCursor, + suspenseStackCursor.current, + workInProgress + ); if (!updateExpirationTime) return null; } return bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -6894,40 +7092,41 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { switch (workInProgress.tag) { case 2: updateExpirationTime = workInProgress.type; - null !== current && - ((current.alternate = null), + null !== current$$1 && + ((current$$1.alternate = null), (workInProgress.alternate = null), (workInProgress.effectTag |= 2)); - current = workInProgress.pendingProps; - context = getMaskedContext(workInProgress, contextStackCursor.current); + current$$1 = workInProgress.pendingProps; + renderState = getMaskedContext( + workInProgress, + contextStackCursor.current + ); prepareToReadContext(workInProgress, renderExpirationTime); - context = renderWithHooks( + renderState = renderWithHooks( null, workInProgress, updateExpirationTime, - current, - context, + current$$1, + renderState, renderExpirationTime ); workInProgress.effectTag |= 1; if ( - "object" === typeof context && - null !== context && - "function" === typeof context.render && - void 0 === context.$$typeof + "object" === typeof renderState && + null !== renderState && + "function" === typeof renderState.render && + void 0 === renderState.$$typeof ) { workInProgress.tag = 1; - workInProgress.memoizedState = null; - workInProgress.updateQueue = null; + resetHooks(); if (isContextProvider(updateExpirationTime)) { var hasContext = !0; pushContextProvider(workInProgress); } else hasContext = !1; workInProgress.memoizedState = - null !== context.state && void 0 !== context.state - ? context.state + null !== renderState.state && void 0 !== renderState.state + ? renderState.state : null; - initializeUpdateQueue(workInProgress); var getDerivedStateFromProps = updateExpirationTime.getDerivedStateFromProps; "function" === typeof getDerivedStateFromProps && @@ -6935,15 +7134,15 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { workInProgress, updateExpirationTime, getDerivedStateFromProps, - current + current$$1 ); - context.updater = classComponentUpdater; - workInProgress.stateNode = context; - context._reactInternalFiber = workInProgress; + renderState.updater = classComponentUpdater; + workInProgress.stateNode = renderState; + renderState._reactInternalFiber = workInProgress; mountClassInstance( workInProgress, updateExpirationTime, - current, + current$$1, renderExpirationTime ); workInProgress = finishClassComponent( @@ -6959,129 +7158,127 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { reconcileChildren( null, workInProgress, - context, + renderState, renderExpirationTime ), (workInProgress = workInProgress.child); return workInProgress; case 16: - a: { - context = workInProgress.elementType; - null !== current && - ((current.alternate = null), - (workInProgress.alternate = null), - (workInProgress.effectTag |= 2)); - current = workInProgress.pendingProps; - initializeLazyComponentType(context); - if (1 !== context._status) throw context._result; - context = context._result; - workInProgress.type = context; - hasContext = workInProgress.tag = resolveLazyComponentTag(context); - current = resolveDefaultProps(context, current); - switch (hasContext) { - case 0: - workInProgress = updateFunctionComponent( - null, - workInProgress, - context, - current, - renderExpirationTime - ); - break a; - case 1: - workInProgress = updateClassComponent( - null, - workInProgress, - context, - current, - renderExpirationTime - ); - break a; - case 11: - workInProgress = updateForwardRef( - null, - workInProgress, - context, - current, - renderExpirationTime - ); - break a; - case 14: - workInProgress = updateMemoComponent( - null, - workInProgress, - context, - resolveDefaultProps(context.type, current), - updateExpirationTime, - renderExpirationTime - ); - break a; - } - throw Error( - "Element type is invalid. Received a promise that resolves to: " + - context + - ". Lazy element type must resolve to a class or function." - ); + renderState = workInProgress.elementType; + null !== current$$1 && + ((current$$1.alternate = null), + (workInProgress.alternate = null), + (workInProgress.effectTag |= 2)); + current$$1 = workInProgress.pendingProps; + initializeLazyComponentType(renderState); + if (1 !== renderState._status) throw renderState._result; + renderState = renderState._result; + workInProgress.type = renderState; + hasContext = workInProgress.tag = resolveLazyComponentTag(renderState); + current$$1 = resolveDefaultProps(renderState, current$$1); + switch (hasContext) { + case 0: + workInProgress = updateFunctionComponent( + null, + workInProgress, + renderState, + current$$1, + renderExpirationTime + ); + break; + case 1: + workInProgress = updateClassComponent( + null, + workInProgress, + renderState, + current$$1, + renderExpirationTime + ); + break; + case 11: + workInProgress = updateForwardRef( + null, + workInProgress, + renderState, + current$$1, + renderExpirationTime + ); + break; + case 14: + workInProgress = updateMemoComponent( + null, + workInProgress, + renderState, + resolveDefaultProps(renderState.type, current$$1), + updateExpirationTime, + renderExpirationTime + ); + break; + default: + throw Error( + "Element type is invalid. Received a promise that resolves to: " + + renderState + + ". Lazy element type must resolve to a class or function." + ); } return workInProgress; case 0: return ( (updateExpirationTime = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (renderState = workInProgress.pendingProps), + (renderState = workInProgress.elementType === updateExpirationTime - ? context - : resolveDefaultProps(updateExpirationTime, context)), + ? renderState + : resolveDefaultProps(updateExpirationTime, renderState)), updateFunctionComponent( - current, + current$$1, workInProgress, updateExpirationTime, - context, + renderState, renderExpirationTime ) ); case 1: return ( (updateExpirationTime = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (renderState = workInProgress.pendingProps), + (renderState = workInProgress.elementType === updateExpirationTime - ? context - : resolveDefaultProps(updateExpirationTime, context)), + ? renderState + : resolveDefaultProps(updateExpirationTime, renderState)), updateClassComponent( - current, + current$$1, workInProgress, updateExpirationTime, - context, + renderState, renderExpirationTime ) ); case 3: pushHostRootContext(workInProgress); updateExpirationTime = workInProgress.updateQueue; - if (null === current || null === updateExpirationTime) + if (null === updateExpirationTime) 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." ); - updateExpirationTime = workInProgress.pendingProps; - context = workInProgress.memoizedState; - context = null !== context ? context.element : null; - cloneUpdateQueue(current, workInProgress); + renderState = workInProgress.memoizedState; + renderState = null !== renderState ? renderState.element : null; processUpdateQueue( workInProgress, updateExpirationTime, + workInProgress.pendingProps, null, renderExpirationTime ); updateExpirationTime = workInProgress.memoizedState.element; - updateExpirationTime === context + updateExpirationTime === renderState ? (workInProgress = bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime )) : (reconcileChildren( - current, + current$$1, workInProgress, updateExpirationTime, renderExpirationTime @@ -7091,10 +7288,11 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { case 5: return ( pushHostContext(workInProgress), + null === current$$1 && tryToClaimNextHydratableInstance(workInProgress), (updateExpirationTime = workInProgress.pendingProps.children), - markRef(current, workInProgress), + markRef(current$$1, workInProgress), reconcileChildren( - current, + current$$1, workInProgress, updateExpirationTime, renderExpirationTime @@ -7103,10 +7301,13 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { workInProgress ); case 6: - return null; + return ( + null === current$$1 && tryToClaimNextHydratableInstance(workInProgress), + null + ); case 13: return updateSuspenseComponent( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -7117,7 +7318,7 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { workInProgress.stateNode.containerInfo ), (updateExpirationTime = workInProgress.pendingProps), - null === current + null === current$$1 ? (workInProgress.child = reconcileChildFibers( workInProgress, null, @@ -7125,7 +7326,7 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { renderExpirationTime )) : reconcileChildren( - current, + current$$1, workInProgress, updateExpirationTime, renderExpirationTime @@ -7135,23 +7336,23 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { case 11: return ( (updateExpirationTime = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (renderState = workInProgress.pendingProps), + (renderState = workInProgress.elementType === updateExpirationTime - ? context - : resolveDefaultProps(updateExpirationTime, context)), + ? renderState + : resolveDefaultProps(updateExpirationTime, renderState)), updateForwardRef( - current, + current$$1, workInProgress, updateExpirationTime, - context, + renderState, renderExpirationTime ) ); case 7: return ( reconcileChildren( - current, + current$$1, workInProgress, workInProgress.pendingProps, renderExpirationTime @@ -7161,7 +7362,7 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { case 8: return ( reconcileChildren( - current, + current$$1, workInProgress, workInProgress.pendingProps.children, renderExpirationTime @@ -7171,11 +7372,8 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { case 12: return ( (workInProgress.effectTag |= 4), - (updateExpirationTime = workInProgress.stateNode), - (updateExpirationTime.effectDuration = 0), - (updateExpirationTime.passiveEffectDuration = 0), reconcileChildren( - current, + current$$1, workInProgress, workInProgress.pendingProps.children, renderExpirationTime @@ -7185,32 +7383,27 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { case 10: a: { updateExpirationTime = workInProgress.type._context; - context = workInProgress.pendingProps; + renderState = 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 updateExpirationTime._calculateChangedBits - ? updateExpirationTime._calculateChangedBits( - context$jscomp$0, - hasContext - ) - : 1073741823) | 0), - 0 === hasContext) - ) { + hasContext = renderState.value; + pushProvider(workInProgress, hasContext); + if (null !== getDerivedStateFromProps) { + var oldValue = getDerivedStateFromProps.value; + hasContext = is$1(oldValue, hasContext) + ? 0 + : ("function" === typeof updateExpirationTime._calculateChangedBits + ? updateExpirationTime._calculateChangedBits( + oldValue, + hasContext + ) + : 1073741823) | 0; + if (0 === hasContext) { if ( - getDerivedStateFromProps.children === context.children && + getDerivedStateFromProps.children === renderState.children && !didPerformWorkStackCursor.current ) { workInProgress = bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -7218,15 +7411,14 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { } } 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; @@ -7236,18 +7428,18 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { dependency.context === updateExpirationTime && 0 !== (dependency.observedBits & hasContext) ) { - 1 === context$jscomp$0.tag && + 1 === oldValue.tag && ((dependency = createUpdate(renderExpirationTime, null)), (dependency.tag = 2), - enqueueUpdate(context$jscomp$0, dependency)); - context$jscomp$0.expirationTime < renderExpirationTime && - (context$jscomp$0.expirationTime = renderExpirationTime); - dependency = context$jscomp$0.alternate; + enqueueUpdate(oldValue, dependency)); + oldValue.expirationTime < renderExpirationTime && + (oldValue.expirationTime = renderExpirationTime); + dependency = oldValue.alternate; null !== dependency && dependency.expirationTime < renderExpirationTime && (dependency.expirationTime = renderExpirationTime); scheduleWorkOnParentPath( - context$jscomp$0.return, + oldValue.return, renderExpirationTime ); list.expirationTime < renderExpirationTime && @@ -7258,16 +7450,16 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { } } 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; ) { @@ -7275,20 +7467,21 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { 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, + current$$1, workInProgress, - context.children, + renderState.children, renderExpirationTime ); workInProgress = workInProgress.child; @@ -7296,15 +7489,18 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { return workInProgress; case 9: return ( - (context = workInProgress.type), + (renderState = workInProgress.type), (hasContext = workInProgress.pendingProps), (updateExpirationTime = hasContext.children), prepareToReadContext(workInProgress, renderExpirationTime), - (context = readContext(context, hasContext.unstable_observedBits)), - (updateExpirationTime = updateExpirationTime(context)), + (renderState = readContext( + renderState, + hasContext.unstable_observedBits + )), + (updateExpirationTime = updateExpirationTime(renderState)), (workInProgress.effectTag |= 1), reconcileChildren( - current, + current$$1, workInProgress, updateExpirationTime, renderExpirationTime @@ -7313,16 +7509,16 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { ); case 14: return ( - (context = workInProgress.type), + (renderState = workInProgress.type), (hasContext = resolveDefaultProps( - context, + renderState, workInProgress.pendingProps )), - (hasContext = resolveDefaultProps(context.type, hasContext)), + (hasContext = resolveDefaultProps(renderState.type, hasContext)), updateMemoComponent( - current, + current$$1, workInProgress, - context, + renderState, hasContext, updateExpirationTime, renderExpirationTime @@ -7330,7 +7526,7 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { ); case 15: return updateSimpleMemoComponent( - current, + current$$1, workInProgress, workInProgress.type, workInProgress.pendingProps, @@ -7340,25 +7536,30 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { case 17: return ( (updateExpirationTime = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (renderState = workInProgress.pendingProps), + (renderState = workInProgress.elementType === updateExpirationTime - ? context - : resolveDefaultProps(updateExpirationTime, context)), - null !== current && - ((current.alternate = null), + ? renderState + : resolveDefaultProps(updateExpirationTime, renderState)), + null !== current$$1 && + ((current$$1.alternate = null), (workInProgress.alternate = null), (workInProgress.effectTag |= 2)), (workInProgress.tag = 1), isContextProvider(updateExpirationTime) - ? ((current = !0), pushContextProvider(workInProgress)) - : (current = !1), + ? ((current$$1 = !0), pushContextProvider(workInProgress)) + : (current$$1 = !1), prepareToReadContext(workInProgress, renderExpirationTime), - constructClassInstance(workInProgress, updateExpirationTime, context), + constructClassInstance( + workInProgress, + updateExpirationTime, + renderState, + renderExpirationTime + ), mountClassInstance( workInProgress, updateExpirationTime, - context, + renderState, renderExpirationTime ), finishClassComponent( @@ -7366,13 +7567,13 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { workInProgress, updateExpirationTime, !0, - current, + current$$1, renderExpirationTime ) ); case 19: return updateSuspenseListComponent( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -7513,6 +7714,9 @@ function FiberNode(tag, pendingProps, key, mode) { this.actualStartTime = -1; this.treeBaseDuration = this.selfBaseDuration = 0; } +function createFiber(tag, pendingProps, key, mode) { + return new FiberNode(tag, pendingProps, key, mode); +} function shouldConstruct(Component) { Component = Component.prototype; return !(!Component || !Component.isReactComponent); @@ -7530,7 +7734,7 @@ function resolveLazyComponentTag(Component) { function createWorkInProgress(current, pendingProps) { var workInProgress = current.alternate; null === workInProgress - ? ((workInProgress = new FiberNode( + ? ((workInProgress = createFiber( current.tag, pendingProps, current.key, @@ -7548,10 +7752,6 @@ function createWorkInProgress(current, pendingProps) { (workInProgress.lastEffect = null), (workInProgress.actualDuration = 0), (workInProgress.actualStartTime = -1)); - if (null == current) - throw Error("current is " + current + " but it can't be"); - if (null == workInProgress) - throw Error("workInProgress is " + workInProgress + " but it can't be"); workInProgress.childExpirationTime = current.childExpirationTime; workInProgress.expirationTime = current.expirationTime; workInProgress.child = current.child; @@ -7605,16 +7805,15 @@ function createFiberFromTypeAndProps( break; case REACT_PROFILER_TYPE: return ( - (type = new FiberNode(12, pendingProps, key, mode | 8)), + (type = createFiber(12, pendingProps, key, mode | 8)), (type.elementType = REACT_PROFILER_TYPE), (type.type = REACT_PROFILER_TYPE), (type.expirationTime = expirationTime), - (type.stateNode = { effectDuration: 0, passiveEffectDuration: 0 }), type ); case REACT_SUSPENSE_TYPE: return ( - (type = new FiberNode(13, pendingProps, key, mode)), + (type = createFiber(13, pendingProps, key, mode)), (type.type = REACT_SUSPENSE_TYPE), (type.elementType = REACT_SUSPENSE_TYPE), (type.expirationTime = expirationTime), @@ -7622,7 +7821,7 @@ function createFiberFromTypeAndProps( ); case REACT_SUSPENSE_LIST_TYPE: return ( - (type = new FiberNode(19, pendingProps, key, mode)), + (type = createFiber(19, pendingProps, key, mode)), (type.elementType = REACT_SUSPENSE_LIST_TYPE), (type.expirationTime = expirationTime), type @@ -7646,9 +7845,6 @@ function createFiberFromTypeAndProps( fiberTag = 16; owner = null; break a; - case REACT_BLOCK_TYPE: - fiberTag = 22; - break a; } throw Error( "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + @@ -7656,24 +7852,24 @@ function createFiberFromTypeAndProps( "." ); } - key = new FiberNode(fiberTag, pendingProps, key, mode); + key = createFiber(fiberTag, pendingProps, key, mode); key.elementType = type; key.type = owner; key.expirationTime = expirationTime; return key; } function createFiberFromFragment(elements, mode, expirationTime, key) { - elements = new FiberNode(7, elements, key, mode); + elements = createFiber(7, elements, key, mode); elements.expirationTime = expirationTime; return elements; } function createFiberFromText(content, mode, expirationTime) { - content = new FiberNode(6, content, null, mode); + content = createFiber(6, content, null, mode); content.expirationTime = expirationTime; return content; } function createFiberFromPortal(portal, mode, expirationTime) { - mode = new FiberNode( + mode = createFiber( 4, null !== portal.children ? portal.children : [], portal.key, @@ -7735,6 +7931,11 @@ function markRootUpdatedAtTime(root, expirationTime) { expirationTime > root.nextKnownPendingLevel && (root.nextKnownPendingLevel = expirationTime)); } +function markRootExpiredAtTime(root, expirationTime) { + var lastExpiredTime = root.lastExpiredTime; + if (0 === lastExpiredTime || lastExpiredTime > expirationTime) + root.lastExpiredTime = expirationTime; +} function findHostInstance(component) { var fiber = component._reactInternalFiber; if (void 0 === fiber) { @@ -7749,10 +7950,14 @@ function findHostInstance(component) { return null === component ? null : component.stateNode; } function updateContainer(element, container, parentComponent, callback) { - var current = container.current, + var current$$1 = container.current, currentTime = requestCurrentTimeForUpdate(), suspenseConfig = ReactCurrentBatchConfig.suspense; - currentTime = computeExpirationForFiber(currentTime, current, suspenseConfig); + currentTime = computeExpirationForFiber( + currentTime, + current$$1, + suspenseConfig + ); a: if (parentComponent) { parentComponent = parentComponent._reactInternalFiber; b: { @@ -7803,8 +8008,8 @@ function updateContainer(element, container, parentComponent, callback) { container.payload = { element: element }; callback = void 0 === callback ? null : callback; null !== callback && (container.callback = callback); - enqueueUpdate(current, container); - scheduleWork(current, currentTime); + enqueueUpdate(current$$1, container); + scheduleUpdateOnFiber(current$$1, currentTime); return currentTime; } function createPortal(children, containerInfo, implementation) { @@ -7818,6 +8023,11 @@ function createPortal(children, containerInfo, implementation) { implementation: implementation }; } +function _inheritsLoose(subClass, superClass) { + subClass.prototype = Object.create(superClass.prototype); + subClass.prototype.constructor = subClass; + subClass.__proto__ = superClass; +} function findNodeHandle(componentOrHandle) { if (null == componentOrHandle) return null; if ("number" === typeof componentOrHandle) return componentOrHandle; @@ -7828,15 +8038,8 @@ function findNodeHandle(componentOrHandle) { return null == componentOrHandle ? componentOrHandle : componentOrHandle.canonical - ? componentOrHandle.canonical._nativeTag - : componentOrHandle._nativeTag; -} -function unmountComponentAtNode(containerTag) { - var root = roots.get(containerTag); - root && - updateContainer(null, root, null, function() { - roots.delete(containerTag); - }); + ? componentOrHandle.canonical._nativeTag + : componentOrHandle._nativeTag; } batchedUpdatesImpl = function(fn, a) { var prevExecutionContext = executionContext; @@ -7848,119 +8051,301 @@ batchedUpdatesImpl = function(fn, a) { executionContext === NoContext && flushSyncCallbackQueue(); } }; -var roots = new Map(); -(function(devToolsConfig) { - var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance; - return injectInternals({ - bundleType: devToolsConfig.bundleType, - version: devToolsConfig.version, - rendererPackageName: devToolsConfig.rendererPackageName, - rendererConfig: devToolsConfig.rendererConfig, - overrideHookState: null, - overrideProps: null, - setSuspenseHandler: null, - scheduleUpdate: null, - currentDispatcherRef: ReactSharedInternals.ReactCurrentDispatcher, - findHostInstanceByFiber: function(fiber) { - fiber = findCurrentHostFiber(fiber); - return null === fiber ? null : fiber.stateNode; +flushDiscreteUpdatesImpl = function() { + (executionContext & (1 | RenderContext | CommitContext)) === NoContext && + (flushPendingDiscreteUpdates(), flushPassiveEffects()); +}; +var roots = new Map(), + ReactNativeRenderer = { + NativeComponent: (function(findNodeHandle, findHostInstance) { + return (function(_React$Component) { + function ReactNativeComponent() { + return _React$Component.apply(this, arguments) || this; + } + _inheritsLoose(ReactNativeComponent, _React$Component); + var _proto = ReactNativeComponent.prototype; + _proto.blur = function() { + ReactNativePrivateInterface.TextInputState.blurTextInput( + findNodeHandle(this) + ); + }; + _proto.focus = function() { + ReactNativePrivateInterface.TextInputState.focusTextInput( + findNodeHandle(this) + ); + }; + _proto.measure = function(callback) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + null != maybeInstance && + (maybeInstance.canonical + ? nativeFabricUIManager.measure( + maybeInstance.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ) + : ReactNativePrivateInterface.UIManager.measure( + findNodeHandle(this), + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + )); + }; + _proto.measureInWindow = function(callback) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + null != maybeInstance && + (maybeInstance.canonical + ? nativeFabricUIManager.measureInWindow( + maybeInstance.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ) + : ReactNativePrivateInterface.UIManager.measureInWindow( + findNodeHandle(this), + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + )); + }; + _proto.measureLayout = function( + relativeToNativeNode, + onSuccess, + onFail + ) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + if (null != maybeInstance && !maybeInstance.canonical) { + if ("number" === typeof relativeToNativeNode) + var relativeNode = relativeToNativeNode; + else + relativeToNativeNode._nativeTag && + (relativeNode = relativeToNativeNode._nativeTag); + null != relativeNode && + ReactNativePrivateInterface.UIManager.measureLayout( + findNodeHandle(this), + relativeNode, + mountSafeCallback_NOT_REALLY_SAFE(this, onFail), + mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) + ); + } + }; + _proto.setNativeProps = function(nativeProps) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + if (null != maybeInstance && !maybeInstance.canonical) { + var nativeTag = + maybeInstance._nativeTag || maybeInstance.canonical._nativeTag; + maybeInstance = + maybeInstance.viewConfig || maybeInstance.canonical.viewConfig; + nativeProps = diffProperties( + null, + emptyObject, + nativeProps, + maybeInstance.validAttributes + ); + null != nativeProps && + ReactNativePrivateInterface.UIManager.updateView( + nativeTag, + maybeInstance.uiViewClassName, + nativeProps + ); + } + }; + return ReactNativeComponent; + })(React.Component); + })(findNodeHandle, findHostInstance), + findHostInstance_DEPRECATED: function(componentOrHandle) { + if (null == componentOrHandle) return null; + if (componentOrHandle._nativeTag) return componentOrHandle; + if (componentOrHandle.canonical && componentOrHandle.canonical._nativeTag) + return componentOrHandle.canonical; + componentOrHandle = findHostInstance(componentOrHandle); + return null == componentOrHandle + ? componentOrHandle + : componentOrHandle.canonical + ? componentOrHandle.canonical + : componentOrHandle; }, - findFiberByHostInstance: function(instance) { - return findFiberByHostInstance ? findFiberByHostInstance(instance) : null; + findNodeHandle: findNodeHandle, + dispatchCommand: function(handle, command, args) { + null != handle._nativeTag && + ReactNativePrivateInterface.UIManager.dispatchViewManagerCommand( + handle._nativeTag, + command, + args + ); }, - findHostInstancesForRefresh: null, - scheduleRefresh: null, - scheduleRoot: null, - setRefreshHandler: null, - getCurrentFiber: null - }); + render: function(element, containerTag, callback) { + var root = roots.get(containerTag); + if (!root) { + root = new FiberRootNode(containerTag, 0, !1); + var uninitializedFiber = 0; + isDevToolsPresent && (uninitializedFiber |= 8); + uninitializedFiber = createFiber(3, null, null, uninitializedFiber); + root.current = uninitializedFiber; + uninitializedFiber.stateNode = root; + roots.set(containerTag, root); + } + updateContainer(element, root, null, callback); + a: if (((element = root.current), element.child)) + switch (element.child.tag) { + case 5: + element = element.child.stateNode; + break a; + default: + element = element.child.stateNode; + } + else element = null; + return element; + }, + unmountComponentAtNode: function(containerTag) { + var root = roots.get(containerTag); + root && + updateContainer(null, root, null, function() { + roots.delete(containerTag); + }); + }, + unmountComponentAtNodeAndRemoveContainer: function(containerTag) { + ReactNativeRenderer.unmountComponentAtNode(containerTag); + ReactNativePrivateInterface.UIManager.removeRootView(containerTag); + }, + createPortal: function(children, containerTag) { + return createPortal( + children, + containerTag, + null, + 2 < arguments.length && void 0 !== arguments[2] ? arguments[2] : null + ); + }, + unstable_batchedUpdates: batchedUpdates, + __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: { + NativeMethodsMixin: (function(findNodeHandle, findHostInstance) { + return { + measure: function(callback) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + null != maybeInstance && + (maybeInstance.canonical + ? nativeFabricUIManager.measure( + maybeInstance.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ) + : ReactNativePrivateInterface.UIManager.measure( + findNodeHandle(this), + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + )); + }, + measureInWindow: function(callback) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + null != maybeInstance && + (maybeInstance.canonical + ? nativeFabricUIManager.measureInWindow( + maybeInstance.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ) + : ReactNativePrivateInterface.UIManager.measureInWindow( + findNodeHandle(this), + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + )); + }, + measureLayout: function(relativeToNativeNode, onSuccess, onFail) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + if (null != maybeInstance && !maybeInstance.canonical) { + if ("number" === typeof relativeToNativeNode) + var relativeNode = relativeToNativeNode; + else + relativeToNativeNode._nativeTag && + (relativeNode = relativeToNativeNode._nativeTag); + null != relativeNode && + ReactNativePrivateInterface.UIManager.measureLayout( + findNodeHandle(this), + relativeNode, + mountSafeCallback_NOT_REALLY_SAFE(this, onFail), + mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) + ); + } + }, + setNativeProps: function(nativeProps) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + if (null != maybeInstance && !maybeInstance.canonical) { + var nativeTag = + maybeInstance._nativeTag || maybeInstance.canonical._nativeTag; + maybeInstance = + maybeInstance.viewConfig || maybeInstance.canonical.viewConfig; + nativeProps = diffProperties( + null, + emptyObject, + nativeProps, + maybeInstance.validAttributes + ); + null != nativeProps && + ReactNativePrivateInterface.UIManager.updateView( + nativeTag, + maybeInstance.uiViewClassName, + nativeProps + ); + } + }, + focus: function() { + ReactNativePrivateInterface.TextInputState.focusTextInput( + findNodeHandle(this) + ); + }, + blur: function() { + ReactNativePrivateInterface.TextInputState.blurTextInput( + findNodeHandle(this) + ); + } + }; + })(findNodeHandle, findHostInstance), + computeComponentStackForErrorReporting: function(reactTag) { + return (reactTag = getInstanceFromTag(reactTag)) + ? getStackByFiberInDevAndProd(reactTag) + : ""; + } + } + }; +(function(devToolsConfig) { + var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance; + return injectInternals( + Object.assign({}, devToolsConfig, { + overrideHookState: null, + overrideProps: null, + setSuspenseHandler: null, + scheduleUpdate: null, + currentDispatcherRef: ReactSharedInternals.ReactCurrentDispatcher, + findHostInstanceByFiber: function(fiber) { + fiber = findCurrentHostFiber(fiber); + return null === fiber ? null : fiber.stateNode; + }, + findFiberByHostInstance: function(instance) { + return findFiberByHostInstance + ? findFiberByHostInstance(instance) + : null; + }, + findHostInstancesForRefresh: null, + scheduleRefresh: null, + scheduleRoot: null, + setRefreshHandler: null, + getCurrentFiber: null + }) + ); })({ findFiberByHostInstance: getInstanceFromTag, + getInspectorDataForViewTag: function() { + throw Error("getInspectorDataForViewTag() is not available in production"); + }, bundleType: 0, - version: "16.13.0", - rendererPackageName: "react-native-renderer", - rendererConfig: { - getInspectorDataForViewTag: function() { - throw Error( - "getInspectorDataForViewTag() is not available in production" - ); - }, - getInspectorDataForViewAtPoint: function() { - throw Error( - "getInspectorDataForViewAtPoint() is not available in production." - ); - }.bind(null, findNodeHandle) - } + version: "16.11.0", + rendererPackageName: "react-native-renderer" }); -exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = { - computeComponentStackForErrorReporting: function(reactTag) { - return (reactTag = getInstanceFromTag(reactTag)) - ? getStackByFiberInDevAndProd(reactTag) - : ""; - } -}; -exports.createPortal = function(children, containerTag) { - return createPortal( - children, - containerTag, - null, - 2 < arguments.length && void 0 !== arguments[2] ? arguments[2] : null - ); -}; -exports.dispatchCommand = function(handle, command, args) { - null != handle._nativeTag && - (handle._internalInstanceHandle - ? nativeFabricUIManager.dispatchCommand( - handle._internalInstanceHandle.stateNode.node, - command, - args - ) - : ReactNativePrivateInterface.UIManager.dispatchViewManagerCommand( - handle._nativeTag, - command, - args - )); -}; -exports.findHostInstance_DEPRECATED = function(componentOrHandle) { - if (null == componentOrHandle) return null; - if (componentOrHandle._nativeTag) return componentOrHandle; - if (componentOrHandle.canonical && componentOrHandle.canonical._nativeTag) - return componentOrHandle.canonical; - componentOrHandle = findHostInstance(componentOrHandle); - return null == componentOrHandle - ? componentOrHandle - : componentOrHandle.canonical - ? componentOrHandle.canonical - : componentOrHandle; -}; -exports.findNodeHandle = findNodeHandle; -exports.render = function(element, containerTag, callback) { - var root = roots.get(containerTag); - if (!root) { - root = new FiberRootNode(containerTag, 0, !1); - var uninitializedFiber = 0; - isDevToolsPresent && (uninitializedFiber |= 8); - uninitializedFiber = new FiberNode(3, null, null, uninitializedFiber); - root.current = uninitializedFiber; - uninitializedFiber.stateNode = root; - initializeUpdateQueue(uninitializedFiber); - roots.set(containerTag, root); - } - updateContainer(element, root, null, callback); - a: if (((element = root.current), element.child)) - switch (element.child.tag) { - case 5: - element = element.child.stateNode; - break a; - default: - element = element.child.stateNode; - } - else element = null; - return element; -}; -exports.unmountComponentAtNode = unmountComponentAtNode; -exports.unmountComponentAtNodeAndRemoveContainer = function(containerTag) { - unmountComponentAtNode(containerTag); - ReactNativePrivateInterface.UIManager.removeRootView(containerTag); -}; -exports.unstable_batchedUpdates = batchedUpdates; +var ReactNativeRenderer$2 = { default: ReactNativeRenderer }, + ReactNativeRenderer$3 = + (ReactNativeRenderer$2 && ReactNativeRenderer) || ReactNativeRenderer$2; +module.exports = ReactNativeRenderer$3.default || ReactNativeRenderer$3; diff --git a/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.js b/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.js index c81740113065d3..f6ef2ae04e6e38 100644 --- a/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.js +++ b/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.js @@ -5,7 +5,6 @@ * LICENSE file in the root directory of this source tree. * * @noflow - * @nolint * @providesModule ReactNativeRenderer-profiling * @preventMunge * @generated @@ -16,17 +15,86 @@ require("react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore"); var ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/ReactNativePrivateInterface"), React = require("react"), Scheduler = require("scheduler"), - tracing = require("scheduler/tracing"); -function getParent(inst) { - do inst = inst.return; - while (inst && 5 !== inst.tag); - return inst ? inst : null; + tracing = require("scheduler/tracing"), + eventPluginOrder = null, + namesToPlugins = {}; +function recomputePluginOrdering() { + if (eventPluginOrder) + for (var pluginName in namesToPlugins) { + var pluginModule = namesToPlugins[pluginName], + pluginIndex = eventPluginOrder.indexOf(pluginName); + if (!(-1 < pluginIndex)) + throw Error( + "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + + pluginName + + "`." + ); + if (!plugins[pluginIndex]) { + if (!pluginModule.extractEvents) + throw Error( + "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + + pluginName + + "` does not." + ); + plugins[pluginIndex] = pluginModule; + pluginIndex = pluginModule.eventTypes; + for (var eventName in pluginIndex) { + var JSCompiler_inline_result = void 0; + var dispatchConfig = pluginIndex[eventName], + pluginModule$jscomp$0 = pluginModule, + eventName$jscomp$0 = eventName; + if (eventNameDispatchConfigs.hasOwnProperty(eventName$jscomp$0)) + throw Error( + "EventPluginHub: More than one plugin attempted to publish the same event name, `" + + eventName$jscomp$0 + + "`." + ); + eventNameDispatchConfigs[eventName$jscomp$0] = dispatchConfig; + var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; + if (phasedRegistrationNames) { + for (JSCompiler_inline_result in phasedRegistrationNames) + phasedRegistrationNames.hasOwnProperty( + JSCompiler_inline_result + ) && + publishRegistrationName( + phasedRegistrationNames[JSCompiler_inline_result], + pluginModule$jscomp$0, + eventName$jscomp$0 + ); + JSCompiler_inline_result = !0; + } else + dispatchConfig.registrationName + ? (publishRegistrationName( + dispatchConfig.registrationName, + pluginModule$jscomp$0, + eventName$jscomp$0 + ), + (JSCompiler_inline_result = !0)) + : (JSCompiler_inline_result = !1); + if (!JSCompiler_inline_result) + throw Error( + "EventPluginRegistry: Failed to publish event `" + + eventName + + "` for plugin `" + + pluginName + + "`." + ); + } + } + } } -function traverseTwoPhase(inst, fn, arg) { - for (var path = []; inst; ) path.push(inst), (inst = getParent(inst)); - for (inst = path.length; 0 < inst--; ) fn(path[inst], "captured", arg); - for (inst = 0; inst < path.length; inst++) fn(path[inst], "bubbled", arg); +function publishRegistrationName(registrationName, pluginModule) { + if (registrationNameModules[registrationName]) + throw Error( + "EventPluginHub: More than one plugin attempted to publish the same registration name, `" + + registrationName + + "`." + ); + registrationNameModules[registrationName] = pluginModule; } +var plugins = [], + eventNameDispatchConfigs = {}, + registrationNameModules = {}; function invokeGuardedCallbackImpl(name, func, context, a, b, c, d, e, f) { var funcArgs = Array.prototype.slice.call(arguments, 3); try { @@ -97,6 +165,74 @@ function executeDirectDispatch(event) { event._dispatchInstances = null; return dispatchListener; } +function accumulateInto(current, next) { + if (null == next) + throw Error( + "accumulateInto(...): Accumulated items must not be null or undefined." + ); + if (null == current) return next; + if (Array.isArray(current)) { + if (Array.isArray(next)) return current.push.apply(current, next), current; + current.push(next); + return current; + } + return Array.isArray(next) ? [current].concat(next) : [current, next]; +} +function forEachAccumulated(arr, cb, scope) { + Array.isArray(arr) ? arr.forEach(cb, scope) : arr && cb.call(scope, arr); +} +var eventQueue = null; +function executeDispatchesAndReleaseTopLevel(e) { + if (e) { + var dispatchListeners = e._dispatchListeners, + dispatchInstances = e._dispatchInstances; + if (Array.isArray(dispatchListeners)) + for ( + var i = 0; + i < dispatchListeners.length && !e.isPropagationStopped(); + i++ + ) + executeDispatch(e, dispatchListeners[i], dispatchInstances[i]); + else + dispatchListeners && + executeDispatch(e, dispatchListeners, dispatchInstances); + e._dispatchListeners = null; + e._dispatchInstances = null; + e.isPersistent() || e.constructor.release(e); + } +} +var injection = { + injectEventPluginOrder: function(injectedEventPluginOrder) { + if (eventPluginOrder) + throw Error( + "EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React." + ); + eventPluginOrder = Array.prototype.slice.call(injectedEventPluginOrder); + recomputePluginOrdering(); + }, + injectEventPluginsByName: function(injectedNamesToPlugins) { + var isOrderingDirty = !1, + pluginName; + for (pluginName in injectedNamesToPlugins) + if (injectedNamesToPlugins.hasOwnProperty(pluginName)) { + var pluginModule = injectedNamesToPlugins[pluginName]; + if ( + !namesToPlugins.hasOwnProperty(pluginName) || + namesToPlugins[pluginName] !== pluginModule + ) { + if (namesToPlugins[pluginName]) + throw Error( + "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + + pluginName + + "`." + ); + namesToPlugins[pluginName] = pluginModule; + isOrderingDirty = !0; + } + } + isOrderingDirty && recomputePluginOrdering(); + } +}; function getListener(inst, registrationName) { var listener = inst.stateNode; if (!listener) return null; @@ -114,7 +250,6 @@ function getListener(inst, registrationName) { case "onMouseMoveCapture": case "onMouseUp": case "onMouseUpCapture": - case "onMouseEnter": (props = !props.disabled) || ((inst = inst.type), (props = !( @@ -139,21 +274,15 @@ function getListener(inst, registrationName) { ); return listener; } -function accumulateInto(current, next) { - if (null == next) - throw Error( - "accumulateInto(...): Accumulated items must not be null or undefined." - ); - if (null == current) return next; - if (Array.isArray(current)) { - if (Array.isArray(next)) return current.push.apply(current, next), current; - current.push(next); - return current; - } - return Array.isArray(next) ? [current].concat(next) : [current, next]; +function getParent(inst) { + do inst = inst.return; + while (inst && 5 !== inst.tag); + return inst ? inst : null; } -function forEachAccumulated(arr, cb, scope) { - Array.isArray(arr) ? arr.forEach(cb, scope) : arr && cb.call(scope, arr); +function traverseTwoPhase(inst, fn, arg) { + for (var path = []; inst; ) path.push(inst), (inst = getParent(inst)); + for (inst = path.length; 0 < inst--; ) fn(path[inst], "captured", arg); + for (inst = 0; inst < path.length; inst++) fn(path[inst], "bubbled", arg); } function accumulateDirectionalDispatches(inst, phase, event) { if ( @@ -221,8 +350,8 @@ function SyntheticEvent( ((targetInst = dispatchConfig[propName]) ? (this[propName] = targetInst(nativeEvent)) : "target" === propName - ? (this.target = nativeEventTarget) - : (this[propName] = nativeEvent[propName])); + ? (this.target = nativeEventTarget) + : (this[propName] = nativeEvent[propName])); this.isDefaultPrevented = (null != nativeEvent.defaultPrevented ? nativeEvent.defaultPrevented : !1 === nativeEvent.returnValue) @@ -375,27 +504,53 @@ function recordTouchStart(touch) { } function recordTouchMove(touch) { var touchRecord = touchBank[getTouchIdentifier(touch)]; - touchRecord && - ((touchRecord.touchActive = !0), - (touchRecord.previousPageX = touchRecord.currentPageX), - (touchRecord.previousPageY = touchRecord.currentPageY), - (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), - (touchRecord.currentPageX = touch.pageX), - (touchRecord.currentPageY = touch.pageY), - (touchRecord.currentTimeStamp = timestampForTouch(touch)), - (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))); + touchRecord + ? ((touchRecord.touchActive = !0), + (touchRecord.previousPageX = touchRecord.currentPageX), + (touchRecord.previousPageY = touchRecord.currentPageY), + (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), + (touchRecord.currentPageX = touch.pageX), + (touchRecord.currentPageY = touch.pageY), + (touchRecord.currentTimeStamp = timestampForTouch(touch)), + (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))) + : console.warn( + "Cannot record touch move without a touch start.\nTouch Move: %s\n", + "Touch Bank: %s", + printTouch(touch), + printTouchBank() + ); } function recordTouchEnd(touch) { var touchRecord = touchBank[getTouchIdentifier(touch)]; - touchRecord && - ((touchRecord.touchActive = !1), - (touchRecord.previousPageX = touchRecord.currentPageX), - (touchRecord.previousPageY = touchRecord.currentPageY), - (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), - (touchRecord.currentPageX = touch.pageX), - (touchRecord.currentPageY = touch.pageY), - (touchRecord.currentTimeStamp = timestampForTouch(touch)), - (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))); + touchRecord + ? ((touchRecord.touchActive = !1), + (touchRecord.previousPageX = touchRecord.currentPageX), + (touchRecord.previousPageY = touchRecord.currentPageY), + (touchRecord.previousTimeStamp = touchRecord.currentTimeStamp), + (touchRecord.currentPageX = touch.pageX), + (touchRecord.currentPageY = touch.pageY), + (touchRecord.currentTimeStamp = timestampForTouch(touch)), + (touchHistory.mostRecentTimeStamp = timestampForTouch(touch))) + : console.warn( + "Cannot record touch end without a touch start.\nTouch End: %s\n", + "Touch Bank: %s", + printTouch(touch), + printTouchBank() + ); +} +function printTouch(touch) { + return JSON.stringify({ + identifier: touch.identifier, + pageX: touch.pageX, + pageY: touch.pageY, + timestamp: timestampForTouch(touch) + }); +} +function printTouchBank() { + var printed = JSON.stringify(touchBank.slice(0, 20)); + 20 < touchBank.length && + (printed += " (original size: " + touchBank.length + ")"); + return printed; } var ResponderTouchHistoryStore = { recordTouchTrack: function(topLevelType, nativeEvent) { @@ -435,10 +590,10 @@ function accumulate(current, next) { return null == current ? next : Array.isArray(current) - ? current.concat(next) - : Array.isArray(next) - ? [current].concat(next) - : [current, next]; + ? current.concat(next) + : Array.isArray(next) + ? [current].concat(next) + : [current, next]; } var responderInst = null, trackedTouchCount = 0; @@ -528,7 +683,13 @@ var eventTypes = { "topTouchCancel" === topLevelType ) if (0 <= trackedTouchCount) --trackedTouchCount; - else return null; + else + return ( + console.warn( + "Ended a touch event which was not counted in `trackedTouchCount`." + ), + null + ); ResponderTouchHistoryStore.recordTouchTrack(topLevelType, nativeEvent); if ( targetInst && @@ -540,10 +701,10 @@ var eventTypes = { var shouldSetEventType = isStartish(topLevelType) ? eventTypes.startShouldSetResponder : isMoveish(topLevelType) - ? eventTypes.moveShouldSetResponder - : "topSelectionChange" === topLevelType - ? eventTypes.selectionChangeShouldSetResponder - : eventTypes.scrollShouldSetResponder; + ? eventTypes.moveShouldSetResponder + : "topSelectionChange" === topLevelType + ? eventTypes.selectionChangeShouldSetResponder + : eventTypes.scrollShouldSetResponder; if (responderInst) b: { var JSCompiler_temp = responderInst; @@ -697,10 +858,10 @@ var eventTypes = { (shouldSetEventType = shouldSetEventType ? eventTypes.responderStart : JSCompiler_temp - ? eventTypes.responderMove - : targetInst - ? eventTypes.responderEnd - : null) + ? eventTypes.responderMove + : targetInst + ? eventTypes.responderEnd + : null) ) (shouldSetEventType = ResponderSyntheticEvent.getPooled( shouldSetEventType, @@ -763,8 +924,8 @@ var eventTypes = { (topLevelType = shouldSetEventType ? eventTypes.responderTerminate : topLevelType - ? eventTypes.responderRelease - : null) + ? eventTypes.responderRelease + : null) ) (nativeEvent = ResponderSyntheticEvent.getPooled( topLevelType, @@ -788,168 +949,65 @@ var eventTypes = { } } }, - eventPluginOrder = null, - namesToPlugins = {}; -function recomputePluginOrdering() { - if (eventPluginOrder) - for (var pluginName in namesToPlugins) { - var pluginModule = namesToPlugins[pluginName], - pluginIndex = eventPluginOrder.indexOf(pluginName); - if (!(-1 < pluginIndex)) - throw Error( - "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + - pluginName + - "`." - ); - if (!plugins[pluginIndex]) { - if (!pluginModule.extractEvents) - throw Error( - "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + - pluginName + - "` does not." - ); - plugins[pluginIndex] = pluginModule; - pluginIndex = pluginModule.eventTypes; - for (var eventName in pluginIndex) { - var JSCompiler_inline_result = void 0; - var dispatchConfig = pluginIndex[eventName], - pluginModule$jscomp$0 = pluginModule, - eventName$jscomp$0 = eventName; - if (eventNameDispatchConfigs.hasOwnProperty(eventName$jscomp$0)) - throw Error( - "EventPluginRegistry: More than one plugin attempted to publish the same event name, `" + - eventName$jscomp$0 + - "`." - ); - eventNameDispatchConfigs[eventName$jscomp$0] = dispatchConfig; - var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; - if (phasedRegistrationNames) { - for (JSCompiler_inline_result in phasedRegistrationNames) - phasedRegistrationNames.hasOwnProperty( - JSCompiler_inline_result - ) && - publishRegistrationName( - phasedRegistrationNames[JSCompiler_inline_result], - pluginModule$jscomp$0, - eventName$jscomp$0 - ); - JSCompiler_inline_result = !0; - } else - dispatchConfig.registrationName - ? (publishRegistrationName( - dispatchConfig.registrationName, - pluginModule$jscomp$0, - eventName$jscomp$0 - ), - (JSCompiler_inline_result = !0)) - : (JSCompiler_inline_result = !1); - if (!JSCompiler_inline_result) - throw Error( - "EventPluginRegistry: Failed to publish event `" + - eventName + - "` for plugin `" + - pluginName + - "`." - ); - } - } - } -} -function publishRegistrationName(registrationName, pluginModule) { - if (registrationNameModules[registrationName]) - throw Error( - "EventPluginRegistry: More than one plugin attempted to publish the same registration name, `" + - registrationName + - "`." - ); - registrationNameModules[registrationName] = pluginModule; -} -var plugins = [], - eventNameDispatchConfigs = {}, - registrationNameModules = {}, customBubblingEventTypes = ReactNativePrivateInterface.ReactNativeViewConfigRegistry .customBubblingEventTypes, customDirectEventTypes = ReactNativePrivateInterface.ReactNativeViewConfigRegistry .customDirectEventTypes; -if (eventPluginOrder) - throw Error( - "EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React." - ); -eventPluginOrder = Array.prototype.slice.call([ +injection.injectEventPluginOrder([ "ResponderEventPlugin", "ReactNativeBridgeEventPlugin" ]); -recomputePluginOrdering(); -var injectedNamesToPlugins$jscomp$inline_94 = { - ResponderEventPlugin: ResponderEventPlugin, - ReactNativeBridgeEventPlugin: { - eventTypes: {}, - extractEvents: function( - topLevelType, - targetInst, - nativeEvent, - nativeEventTarget - ) { - if (null == targetInst) return null; - var bubbleDispatchConfig = customBubblingEventTypes[topLevelType], - directDispatchConfig = customDirectEventTypes[topLevelType]; - if (!bubbleDispatchConfig && !directDispatchConfig) - throw Error( - 'Unsupported top level event type "' + topLevelType + '" dispatched' - ); - topLevelType = SyntheticEvent.getPooled( - bubbleDispatchConfig || directDispatchConfig, - targetInst, - nativeEvent, - nativeEventTarget - ); - if (bubbleDispatchConfig) - forEachAccumulated(topLevelType, accumulateTwoPhaseDispatchesSingle); - else if (directDispatchConfig) - forEachAccumulated(topLevelType, accumulateDirectDispatchesSingle); - else return null; - return topLevelType; - } - } - }, - isOrderingDirty$jscomp$inline_95 = !1, - pluginName$jscomp$inline_96; -for (pluginName$jscomp$inline_96 in injectedNamesToPlugins$jscomp$inline_94) - if ( - injectedNamesToPlugins$jscomp$inline_94.hasOwnProperty( - pluginName$jscomp$inline_96 - ) - ) { - var pluginModule$jscomp$inline_97 = - injectedNamesToPlugins$jscomp$inline_94[pluginName$jscomp$inline_96]; - if ( - !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_96) || - namesToPlugins[pluginName$jscomp$inline_96] !== - pluginModule$jscomp$inline_97 +injection.injectEventPluginsByName({ + ResponderEventPlugin: ResponderEventPlugin, + ReactNativeBridgeEventPlugin: { + eventTypes: {}, + extractEvents: function( + topLevelType, + targetInst, + nativeEvent, + nativeEventTarget ) { - if (namesToPlugins[pluginName$jscomp$inline_96]) + if (null == targetInst) return null; + var bubbleDispatchConfig = customBubblingEventTypes[topLevelType], + directDispatchConfig = customDirectEventTypes[topLevelType]; + if (!bubbleDispatchConfig && !directDispatchConfig) throw Error( - "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - pluginName$jscomp$inline_96 + - "`." + 'Unsupported top level event type "' + topLevelType + '" dispatched' ); - namesToPlugins[ - pluginName$jscomp$inline_96 - ] = pluginModule$jscomp$inline_97; - isOrderingDirty$jscomp$inline_95 = !0; + topLevelType = SyntheticEvent.getPooled( + bubbleDispatchConfig || directDispatchConfig, + targetInst, + nativeEvent, + nativeEventTarget + ); + if (bubbleDispatchConfig) + forEachAccumulated(topLevelType, accumulateTwoPhaseDispatchesSingle); + else if (directDispatchConfig) + forEachAccumulated(topLevelType, accumulateDirectDispatchesSingle); + else return null; + return topLevelType; } } -isOrderingDirty$jscomp$inline_95 && recomputePluginOrdering(); +}); var instanceCache = new Map(), instanceProps = new Map(); function getInstanceFromTag(tag) { return instanceCache.get(tag) || null; } +var restoreTarget = null, + restoreQueue = null; +function restoreStateOfTarget(target) { + if (getInstanceFromNode(target)) + throw Error( + "setRestoreImplementation() needs to be called to handle a target for controlled events. This error is likely caused by a bug in React. Please file an issue." + ); +} function batchedUpdatesImpl(fn, bookkeeping) { return fn(bookkeeping); } +function flushDiscreteUpdatesImpl() {} var isInsideEventHandler = !1; function batchedUpdates(fn, bookkeeping) { if (isInsideEventHandler) return fn(bookkeeping); @@ -957,27 +1015,21 @@ function batchedUpdates(fn, bookkeeping) { try { return batchedUpdatesImpl(fn, bookkeeping); } finally { - isInsideEventHandler = !1; - } -} -var eventQueue = null; -function executeDispatchesAndReleaseTopLevel(e) { - if (e) { - var dispatchListeners = e._dispatchListeners, - dispatchInstances = e._dispatchInstances; - if (Array.isArray(dispatchListeners)) - for ( - var i = 0; - i < dispatchListeners.length && !e.isPropagationStopped(); - i++ + if ( + ((isInsideEventHandler = !1), + null !== restoreTarget || null !== restoreQueue) + ) + if ( + (flushDiscreteUpdatesImpl(), + restoreTarget && + ((bookkeeping = restoreTarget), + (fn = restoreQueue), + (restoreQueue = restoreTarget = null), + restoreStateOfTarget(bookkeeping), + fn)) ) - executeDispatch(e, dispatchListeners[i], dispatchInstances[i]); - else - dispatchListeners && - executeDispatch(e, dispatchListeners, dispatchInstances); - e._dispatchListeners = null; - e._dispatchInstances = null; - e.isPersistent() || e.constructor.release(e); + for (bookkeeping = 0; bookkeeping < fn.length; bookkeeping++) + restoreStateOfTarget(fn[bookkeeping]); } } var EMPTY_NATIVE_EVENT = {}; @@ -985,7 +1037,7 @@ function _receiveRootNodeIDEvent(rootNodeID, topLevelType, nativeEventParam) { var nativeEvent = nativeEventParam || EMPTY_NATIVE_EVENT, inst = getInstanceFromTag(rootNodeID), target = null; - null != inst && (target = inst.stateNode); + target = nativeEvent.target; batchedUpdates(function() { var events = target; for (var events$jscomp$0 = null, i = 0; i < plugins.length; i++) { @@ -1060,11 +1112,10 @@ getFiberCurrentPropsFromNode = function(stateNode) { }; getInstanceFromNode = getInstanceFromTag; getNodeFromInstance = function(inst) { - inst = inst.stateNode; - var tag = inst._nativeTag; - void 0 === tag && ((inst = inst.canonical), (tag = inst._nativeTag)); - if (!tag) throw Error("All native instances should have a tag."); - return inst; + var _tag = inst.stateNode._nativeTag; + void 0 === _tag && (_tag = inst.stateNode.canonical._nativeTag); + if (!_tag) throw Error("All native instances should have a tag."); + return _tag; }; ResponderEventPlugin.injection.injectGlobalResponderHandler({ onChange: function(from, to, blockNativeResponder) { @@ -1099,9 +1150,11 @@ var hasSymbol = "function" === typeof Symbol && Symbol.for, ? Symbol.for("react.suspense_list") : 60120, REACT_MEMO_TYPE = hasSymbol ? Symbol.for("react.memo") : 60115, - REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 60116, - REACT_BLOCK_TYPE = hasSymbol ? Symbol.for("react.block") : 60121, - MAYBE_ITERATOR_SYMBOL = "function" === typeof Symbol && Symbol.iterator; + REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 60116; +hasSymbol && Symbol.for("react.fundamental"); +hasSymbol && Symbol.for("react.responder"); +hasSymbol && Symbol.for("react.scope"); +var MAYBE_ITERATOR_SYMBOL = "function" === typeof Symbol && Symbol.iterator; function getIteratorFn(maybeIterable) { if (null === maybeIterable || "object" !== typeof maybeIterable) return null; maybeIterable = @@ -1111,10 +1164,9 @@ function getIteratorFn(maybeIterable) { } function initializeLazyComponentType(lazyComponent) { if (-1 === lazyComponent._status) { - var ctor = lazyComponent._result; - ctor || (ctor = lazyComponent._ctor); - ctor = ctor(); lazyComponent._status = 0; + var ctor = lazyComponent._ctor; + ctor = ctor(); lazyComponent._result = ctor; ctor.then( function(moduleObject) { @@ -1151,9 +1203,9 @@ function getComponentName(type) { if ("object" === typeof type) switch (type.$$typeof) { case REACT_CONTEXT_TYPE: - return (type.displayName || "Context") + ".Consumer"; + return "Context.Consumer"; case REACT_PROVIDER_TYPE: - return (type._context.displayName || "Context") + ".Provider"; + return "Context.Provider"; case REACT_FORWARD_REF_TYPE: var innerType = type.render; innerType = innerType.displayName || innerType.name || ""; @@ -1163,8 +1215,6 @@ function getComponentName(type) { ); case REACT_MEMO_TYPE: return getComponentName(type.type); - case REACT_BLOCK_TYPE: - return getComponentName(type.render); case REACT_LAZY_TYPE: if ((type = 1 === type._status ? type._result : null)) return getComponentName(type); @@ -1345,8 +1395,8 @@ function diffNestedProperty( return nextProp ? addNestedProperty(updatePayload, nextProp, validAttributes) : prevProp - ? clearNestedProperty(updatePayload, prevProp, validAttributes) - : updatePayload; + ? clearNestedProperty(updatePayload, prevProp, validAttributes) + : updatePayload; if (!Array.isArray(prevProp) && !Array.isArray(nextProp)) return diffProperties(updatePayload, prevProp, nextProp, validAttributes); if (Array.isArray(prevProp) && Array.isArray(nextProp)) { @@ -1524,10 +1574,10 @@ var ReactNativeFiberHostComponent = (function() { } var _proto = ReactNativeFiberHostComponent.prototype; _proto.blur = function() { - ReactNativePrivateInterface.TextInputState.blurTextInput(this); + ReactNativePrivateInterface.TextInputState.blurTextInput(this._nativeTag); }; _proto.focus = function() { - ReactNativePrivateInterface.TextInputState.focusTextInput(this); + ReactNativePrivateInterface.TextInputState.focusTextInput(this._nativeTag); }; _proto.measure = function(callback) { ReactNativePrivateInterface.UIManager.measure( @@ -1571,7 +1621,7 @@ var ReactNativeFiberHostComponent = (function() { }; return ReactNativeFiberHostComponent; })(); -function shim() { +function shim$1() { throw Error( "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." ); @@ -1609,7 +1659,45 @@ function finalizeInitialChildren(parentInstance) { } var scheduleTimeout = setTimeout, cancelTimeout = clearTimeout, - valueStack = [], + BEFORE_SLASH_RE = /^(.*)[\\\/]/; +function getStackByFiberInDevAndProd(workInProgress) { + var info = ""; + do { + a: switch (workInProgress.tag) { + case 3: + case 4: + case 6: + case 7: + case 10: + case 9: + var JSCompiler_inline_result = ""; + break a; + default: + var owner = workInProgress._debugOwner, + source = workInProgress._debugSource, + name = getComponentName(workInProgress.type); + JSCompiler_inline_result = null; + owner && (JSCompiler_inline_result = getComponentName(owner.type)); + owner = name; + name = ""; + source + ? (name = + " (at " + + source.fileName.replace(BEFORE_SLASH_RE, "") + + ":" + + source.lineNumber + + ")") + : JSCompiler_inline_result && + (name = " (created by " + JSCompiler_inline_result + ")"); + JSCompiler_inline_result = "\n in " + (owner || "Unknown") + name; + } + info += JSCompiler_inline_result; + workInProgress = workInProgress.return; + } while (workInProgress); + return info; +} +new Set(); +var valueStack = [], index = -1; function pop(cursor) { 0 > index || @@ -1646,17 +1734,21 @@ function isContextProvider(type) { type = type.childContextTypes; return null !== type && void 0 !== type; } -function popContext() { - pop(didPerformWorkStackCursor); - pop(contextStackCursor); +function popContext(fiber) { + pop(didPerformWorkStackCursor, fiber); + pop(contextStackCursor, fiber); +} +function popTopLevelContextObject(fiber) { + pop(didPerformWorkStackCursor, fiber); + pop(contextStackCursor, fiber); } 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); + push(contextStackCursor, context, fiber); + push(didPerformWorkStackCursor, didChange, fiber); } function processChildContext(fiber, type, parentContext) { var instance = fiber.stateNode; @@ -1674,13 +1766,17 @@ function processChildContext(fiber, type, parentContext) { return Object.assign({}, parentContext, {}, instance); } function pushContextProvider(workInProgress) { - workInProgress = - ((workInProgress = workInProgress.stateNode) && - workInProgress.__reactInternalMemoizedMergedChildContext) || + var instance = workInProgress.stateNode; + instance = + (instance && instance.__reactInternalMemoizedMergedChildContext) || emptyContextObject; previousContext = contextStackCursor.current; - push(contextStackCursor, workInProgress); - push(didPerformWorkStackCursor, didPerformWorkStackCursor.current); + push(contextStackCursor, instance, workInProgress); + push( + didPerformWorkStackCursor, + didPerformWorkStackCursor.current, + workInProgress + ); return !0; } function invalidateContextProvider(workInProgress, type, didChange) { @@ -1690,17 +1786,13 @@ function invalidateContextProvider(workInProgress, type, didChange) { "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); + ? ((type = processChildContext(workInProgress, type, previousContext)), + (instance.__reactInternalMemoizedMergedChildContext = type), + pop(didPerformWorkStackCursor, workInProgress), + pop(contextStackCursor, workInProgress), + push(contextStackCursor, type, workInProgress)) + : pop(didPerformWorkStackCursor, workInProgress); + push(didPerformWorkStackCursor, didChange, workInProgress); } var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback, @@ -1827,18 +1919,18 @@ function inferPriorityFromExpirationTime(currentTime, expirationTime) { return 0 >= currentTime ? 99 : 250 >= currentTime - ? 98 - : 5250 >= currentTime - ? 97 - : 95; + ? 98 + : 5250 >= currentTime + ? 97 + : 95; } function is(x, y) { return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y); } -var objectIs = "function" === typeof Object.is ? Object.is : is, +var is$1 = "function" === typeof Object.is ? Object.is : is, hasOwnProperty = Object.prototype.hasOwnProperty; function shallowEqual(objA, objB) { - if (objectIs(objA, objB)) return !0; + if (is$1(objA, objB)) return !0; if ( "object" !== typeof objA || null === objA || @@ -1852,48 +1944,11 @@ function shallowEqual(objA, objB) { for (keysB = 0; keysB < keysA.length; keysB++) if ( !hasOwnProperty.call(objB, keysA[keysB]) || - !objectIs(objA[keysA[keysB]], objB[keysA[keysB]]) + !is$1(objA[keysA[keysB]], objB[keysA[keysB]]) ) return !1; return !0; } -var BEFORE_SLASH_RE = /^(.*)[\\\/]/; -function getStackByFiberInDevAndProd(workInProgress) { - var info = ""; - do { - a: switch (workInProgress.tag) { - case 3: - case 4: - case 6: - case 7: - case 10: - case 9: - var JSCompiler_inline_result = ""; - break a; - default: - var owner = workInProgress._debugOwner, - source = workInProgress._debugSource, - name = getComponentName(workInProgress.type); - JSCompiler_inline_result = null; - owner && (JSCompiler_inline_result = getComponentName(owner.type)); - owner = name; - name = ""; - source - ? (name = - " (at " + - source.fileName.replace(BEFORE_SLASH_RE, "") + - ":" + - source.lineNumber + - ")") - : JSCompiler_inline_result && - (name = " (created by " + JSCompiler_inline_result + ")"); - JSCompiler_inline_result = "\n in " + (owner || "Unknown") + name; - } - info += JSCompiler_inline_result; - workInProgress = workInProgress.return; - } while (workInProgress); - return info; -} function resolveDefaultProps(Component, baseProps) { if (Component && Component.defaultProps) { baseProps = Object.assign({}, baseProps); @@ -1911,9 +1966,14 @@ var valueCursor = { current: null }, function resetContextDependencies() { lastContextWithAllBitsObserved = lastContextDependency = currentlyRenderingFiber = null; } +function pushProvider(providerFiber, nextValue) { + var context = providerFiber.type._context; + push(valueCursor, context._currentValue, providerFiber); + context._currentValue = nextValue; +} function popProvider(providerFiber) { var currentValue = valueCursor.current; - pop(valueCursor); + pop(valueCursor, providerFiber); providerFiber.type._context._currentValue = currentValue; } function scheduleWorkOnParentPath(parent, renderExpirationTime) { @@ -1968,195 +2028,237 @@ function readContext(context, observedBits) { return context._currentValue; } var hasForceUpdate = !1; -function initializeUpdateQueue(fiber) { - fiber.updateQueue = { - baseState: fiber.memoizedState, - baseQueue: null, - shared: { pending: null }, - effects: null +function createUpdateQueue(baseState) { + return { + baseState: baseState, + firstUpdate: null, + lastUpdate: null, + firstCapturedUpdate: null, + lastCapturedUpdate: null, + firstEffect: null, + lastEffect: null, + firstCapturedEffect: null, + lastCapturedEffect: null }; } -function cloneUpdateQueue(current, workInProgress) { - current = current.updateQueue; - workInProgress.updateQueue === current && - (workInProgress.updateQueue = { - baseState: current.baseState, - baseQueue: current.baseQueue, - shared: current.shared, - effects: current.effects - }); +function cloneUpdateQueue(currentQueue) { + return { + baseState: currentQueue.baseState, + firstUpdate: currentQueue.firstUpdate, + lastUpdate: currentQueue.lastUpdate, + firstCapturedUpdate: null, + lastCapturedUpdate: null, + firstEffect: null, + lastEffect: null, + firstCapturedEffect: null, + lastCapturedEffect: null + }; } function createUpdate(expirationTime, suspenseConfig) { - expirationTime = { + return { expirationTime: expirationTime, suspenseConfig: suspenseConfig, tag: 0, payload: null, callback: null, - next: null + next: null, + nextEffect: null }; - return (expirationTime.next = expirationTime); +} +function appendUpdateToQueue(queue, update) { + null === queue.lastUpdate + ? (queue.firstUpdate = queue.lastUpdate = update) + : ((queue.lastUpdate.next = update), (queue.lastUpdate = update)); } function enqueueUpdate(fiber, update) { - 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; - } + var alternate = fiber.alternate; + if (null === alternate) { + var queue1 = fiber.updateQueue; + var queue2 = null; + null === queue1 && + (queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState)); + } else + (queue1 = fiber.updateQueue), + (queue2 = alternate.updateQueue), + null === queue1 + ? null === queue2 + ? ((queue1 = fiber.updateQueue = createUpdateQueue( + fiber.memoizedState + )), + (queue2 = alternate.updateQueue = createUpdateQueue( + alternate.memoizedState + ))) + : (queue1 = fiber.updateQueue = cloneUpdateQueue(queue2)) + : null === queue2 && + (queue2 = alternate.updateQueue = cloneUpdateQueue(queue1)); + null === queue2 || queue1 === queue2 + ? appendUpdateToQueue(queue1, update) + : null === queue1.lastUpdate || null === queue2.lastUpdate + ? (appendUpdateToQueue(queue1, update), + appendUpdateToQueue(queue2, update)) + : (appendUpdateToQueue(queue1, update), (queue2.lastUpdate = update)); } function enqueueCapturedUpdate(workInProgress, update) { + var workInProgressQueue = workInProgress.updateQueue; + workInProgressQueue = + null === workInProgressQueue + ? (workInProgress.updateQueue = createUpdateQueue( + workInProgress.memoizedState + )) + : ensureWorkInProgressQueueIsAClone(workInProgress, workInProgressQueue); + null === workInProgressQueue.lastCapturedUpdate + ? (workInProgressQueue.firstCapturedUpdate = workInProgressQueue.lastCapturedUpdate = update) + : ((workInProgressQueue.lastCapturedUpdate.next = update), + (workInProgressQueue.lastCapturedUpdate = update)); +} +function ensureWorkInProgressQueueIsAClone(workInProgress, queue) { var current = workInProgress.alternate; - null !== current && cloneUpdateQueue(current, workInProgress); - workInProgress = workInProgress.updateQueue; - current = workInProgress.baseQueue; - null === current - ? ((workInProgress.baseQueue = update.next = update), - (update.next = update)) - : ((update.next = current.next), (current.next = update)); + null !== current && + queue === current.updateQueue && + (queue = workInProgress.updateQueue = cloneUpdateQueue(queue)); + return queue; +} +function getStateFromUpdate( + workInProgress, + queue, + update, + prevState, + nextProps, + instance +) { + switch (update.tag) { + case 1: + return ( + (workInProgress = update.payload), + "function" === typeof workInProgress + ? workInProgress.call(instance, prevState, nextProps) + : workInProgress + ); + case 3: + workInProgress.effectTag = (workInProgress.effectTag & -4097) | 64; + case 0: + workInProgress = update.payload; + nextProps = + "function" === typeof workInProgress + ? workInProgress.call(instance, prevState, nextProps) + : workInProgress; + if (null === nextProps || void 0 === nextProps) break; + return Object.assign({}, prevState, nextProps); + case 2: + hasForceUpdate = !0; + } + return prevState; } function processUpdateQueue( - workInProgress$jscomp$0, + workInProgress, + queue, props, instance, renderExpirationTime ) { - var queue = workInProgress$jscomp$0.updateQueue; hasForceUpdate = !1; - var baseQueue = queue.baseQueue, - pendingQueue = queue.shared.pending; - if (null !== pendingQueue) { - if (null !== baseQueue) { - var baseFirst = baseQueue.next; - baseQueue.next = pendingQueue.next; - pendingQueue.next = baseFirst; - } - baseQueue = pendingQueue; - queue.shared.pending = null; - baseFirst = workInProgress$jscomp$0.alternate; - null !== baseFirst && - ((baseFirst = baseFirst.updateQueue), - null !== baseFirst && (baseFirst.baseQueue = pendingQueue)); - } - if (null !== baseQueue) { - baseFirst = baseQueue.next; - var newState = queue.baseState, + queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue); + for ( + var newBaseState = queue.baseState, + newFirstUpdate = null, newExpirationTime = 0, - newBaseState = null, - newBaseQueueFirst = null, - newBaseQueueLast = null; - if (null !== baseFirst) { - var update = baseFirst; - do { - pendingQueue = update.expirationTime; - if (pendingQueue < renderExpirationTime) { - var clone = { - expirationTime: update.expirationTime, - suspenseConfig: update.suspenseConfig, - tag: update.tag, - payload: update.payload, - callback: update.callback, - next: null - }; - null === newBaseQueueLast - ? ((newBaseQueueFirst = newBaseQueueLast = clone), - (newBaseState = newState)) - : (newBaseQueueLast = newBaseQueueLast.next = clone); - pendingQueue > newExpirationTime && - (newExpirationTime = pendingQueue); - } else { - null !== newBaseQueueLast && - (newBaseQueueLast = newBaseQueueLast.next = { - expirationTime: 1073741823, - suspenseConfig: update.suspenseConfig, - tag: update.tag, - payload: update.payload, - callback: update.callback, - next: null - }); - markRenderEventTimeAndConfig(pendingQueue, update.suspenseConfig); - a: { - var workInProgress = workInProgress$jscomp$0, - update$jscomp$0 = update; - pendingQueue = props; - clone = instance; - switch (update$jscomp$0.tag) { - case 1: - workInProgress = update$jscomp$0.payload; - if ("function" === typeof workInProgress) { - newState = workInProgress.call(clone, newState, pendingQueue); - break a; - } - newState = workInProgress; - break a; - case 3: - workInProgress.effectTag = - (workInProgress.effectTag & -4097) | 64; - case 0: - workInProgress = update$jscomp$0.payload; - pendingQueue = - "function" === typeof workInProgress - ? workInProgress.call(clone, newState, pendingQueue) - : workInProgress; - if (null === pendingQueue || void 0 === pendingQueue) break a; - newState = Object.assign({}, newState, pendingQueue); - break a; - case 2: - hasForceUpdate = !0; - } - } - null !== update.callback && - ((workInProgress$jscomp$0.effectTag |= 32), - (pendingQueue = queue.effects), - null === pendingQueue - ? (queue.effects = [update]) - : pendingQueue.push(update)); - } - update = update.next; - if (null === update || update === baseFirst) - if (((pendingQueue = queue.shared.pending), null === pendingQueue)) - break; - else - (update = baseQueue.next = pendingQueue.next), - (pendingQueue.next = baseFirst), - (queue.baseQueue = baseQueue = pendingQueue), - (queue.shared.pending = null); - } while (1); - } - null === newBaseQueueLast - ? (newBaseState = newState) - : (newBaseQueueLast.next = newBaseQueueFirst); - queue.baseState = newBaseState; - queue.baseQueue = newBaseQueueLast; - markUnprocessedUpdateTime(newExpirationTime); - workInProgress$jscomp$0.expirationTime = newExpirationTime; - workInProgress$jscomp$0.memoizedState = newState; + update = queue.firstUpdate, + resultState = newBaseState; + null !== update; + + ) { + var updateExpirationTime = update.expirationTime; + updateExpirationTime < renderExpirationTime + ? (null === newFirstUpdate && + ((newFirstUpdate = update), (newBaseState = resultState)), + newExpirationTime < updateExpirationTime && + (newExpirationTime = updateExpirationTime)) + : (markRenderEventTimeAndConfig( + updateExpirationTime, + update.suspenseConfig + ), + (resultState = getStateFromUpdate( + workInProgress, + queue, + update, + resultState, + props, + instance + )), + null !== update.callback && + ((workInProgress.effectTag |= 32), + (update.nextEffect = null), + null === queue.lastEffect + ? (queue.firstEffect = queue.lastEffect = update) + : ((queue.lastEffect.nextEffect = update), + (queue.lastEffect = update)))); + update = update.next; } + updateExpirationTime = null; + for (update = queue.firstCapturedUpdate; null !== update; ) { + var _updateExpirationTime = update.expirationTime; + _updateExpirationTime < renderExpirationTime + ? (null === updateExpirationTime && + ((updateExpirationTime = update), + null === newFirstUpdate && (newBaseState = resultState)), + newExpirationTime < _updateExpirationTime && + (newExpirationTime = _updateExpirationTime)) + : ((resultState = getStateFromUpdate( + workInProgress, + queue, + update, + resultState, + props, + instance + )), + null !== update.callback && + ((workInProgress.effectTag |= 32), + (update.nextEffect = null), + null === queue.lastCapturedEffect + ? (queue.firstCapturedEffect = queue.lastCapturedEffect = update) + : ((queue.lastCapturedEffect.nextEffect = update), + (queue.lastCapturedEffect = update)))); + update = update.next; + } + null === newFirstUpdate && (queue.lastUpdate = null); + null === updateExpirationTime + ? (queue.lastCapturedUpdate = null) + : (workInProgress.effectTag |= 32); + null === newFirstUpdate && + null === updateExpirationTime && + (newBaseState = resultState); + queue.baseState = newBaseState; + queue.firstUpdate = newFirstUpdate; + queue.firstCapturedUpdate = updateExpirationTime; + markUnprocessedUpdateTime(newExpirationTime); + workInProgress.expirationTime = newExpirationTime; + workInProgress.memoizedState = resultState; } function commitUpdateQueue(finishedWork, finishedQueue, instance) { - finishedWork = finishedQueue.effects; - finishedQueue.effects = null; - if (null !== finishedWork) - for ( - finishedQueue = 0; - finishedQueue < finishedWork.length; - finishedQueue++ - ) { - var effect = finishedWork[finishedQueue], - callback = effect.callback; - if (null !== callback) { - effect.callback = null; - if ("function" !== typeof callback) - throw Error( - "Invalid argument passed as callback. Expected a function. Instead received: " + - callback - ); - callback.call(instance); - } + null !== finishedQueue.firstCapturedUpdate && + (null !== finishedQueue.lastUpdate && + ((finishedQueue.lastUpdate.next = finishedQueue.firstCapturedUpdate), + (finishedQueue.lastUpdate = finishedQueue.lastCapturedUpdate)), + (finishedQueue.firstCapturedUpdate = finishedQueue.lastCapturedUpdate = null)); + commitUpdateEffects(finishedQueue.firstEffect, instance); + finishedQueue.firstEffect = finishedQueue.lastEffect = null; + commitUpdateEffects(finishedQueue.firstCapturedEffect, instance); + finishedQueue.firstCapturedEffect = finishedQueue.lastCapturedEffect = null; +} +function commitUpdateEffects(effect, instance) { + for (; null !== effect; ) { + var callback = effect.callback; + if (null !== callback) { + effect.callback = null; + if ("function" !== typeof callback) + throw Error( + "Invalid argument passed as callback. Expected a function. Instead received: " + + callback + ); + callback.call(instance); } + effect = effect.nextEffect; + } } var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig, emptyRefsObject = new React.Component().refs; @@ -2173,8 +2275,10 @@ function applyDerivedStateFromProps( ? ctor : Object.assign({}, ctor, getDerivedStateFromProps); workInProgress.memoizedState = getDerivedStateFromProps; - 0 === workInProgress.expirationTime && - (workInProgress.updateQueue.baseState = getDerivedStateFromProps); + nextProps = workInProgress.updateQueue; + null !== nextProps && + 0 === workInProgress.expirationTime && + (nextProps.baseState = getDerivedStateFromProps); } var classComponentUpdater = { isMounted: function(component) { @@ -2193,7 +2297,7 @@ var classComponentUpdater = { null !== callback && (suspenseConfig.callback = callback); enqueueUpdate(inst, suspenseConfig); - scheduleWork(inst, currentTime); + scheduleUpdateOnFiber(inst, currentTime); }, enqueueReplaceState: function(inst, payload, callback) { inst = inst._reactInternalFiber; @@ -2207,7 +2311,7 @@ var classComponentUpdater = { null !== callback && (suspenseConfig.callback = callback); enqueueUpdate(inst, suspenseConfig); - scheduleWork(inst, currentTime); + scheduleUpdateOnFiber(inst, currentTime); }, enqueueForceUpdate: function(inst, callback) { inst = inst._reactInternalFiber; @@ -2220,7 +2324,7 @@ var classComponentUpdater = { null !== callback && (suspenseConfig.callback = callback); enqueueUpdate(inst, suspenseConfig); - scheduleWork(inst, currentTime); + scheduleUpdateOnFiber(inst, currentTime); } }; function checkShouldComponentUpdate( @@ -2236,8 +2340,8 @@ function checkShouldComponentUpdate( return "function" === typeof workInProgress.shouldComponentUpdate ? workInProgress.shouldComponentUpdate(newProps, newState, nextContext) : ctor.prototype && ctor.prototype.isPureReactComponent - ? !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState) - : !0; + ? !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState) + : !0; } function constructClassInstance(workInProgress, ctor, props) { var isLegacyContextConsumer = !1, @@ -2289,7 +2393,6 @@ function mountClassInstance( instance.props = newProps; instance.state = workInProgress.memoizedState; instance.refs = emptyRefsObject; - initializeUpdateQueue(workInProgress); var contextType = ctor.contextType; "object" === typeof contextType && null !== contextType ? (instance.context = readContext(contextType)) @@ -2297,8 +2400,16 @@ function mountClassInstance( ? previousContext : contextStackCursor.current), (instance.context = getMaskedContext(workInProgress, contextType))); - processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); - instance.state = workInProgress.memoizedState; + contextType = workInProgress.updateQueue; + null !== contextType && + (processUpdateQueue( + workInProgress, + contextType, + newProps, + instance, + renderExpirationTime + ), + (instance.state = workInProgress.memoizedState)); contextType = ctor.getDerivedStateFromProps; "function" === typeof contextType && (applyDerivedStateFromProps(workInProgress, ctor, contextType, newProps), @@ -2314,18 +2425,21 @@ function mountClassInstance( instance.UNSAFE_componentWillMount(), ctor !== instance.state && classComponentUpdater.enqueueReplaceState(instance, instance.state, null), - processUpdateQueue( - workInProgress, - newProps, - instance, - renderExpirationTime - ), - (instance.state = workInProgress.memoizedState)); + (contextType = workInProgress.updateQueue), + null !== contextType && + (processUpdateQueue( + workInProgress, + contextType, + newProps, + instance, + renderExpirationTime + ), + (instance.state = workInProgress.memoizedState))); "function" === typeof instance.componentDidMount && (workInProgress.effectTag |= 4); } var isArray = Array.isArray; -function coerceRef(returnFiber, current, element) { +function coerceRef(returnFiber, current$$1, element) { returnFiber = element.ref; if ( null !== returnFiber && @@ -2337,7 +2451,7 @@ function coerceRef(returnFiber, current, element) { if (element) { if (1 !== element.tag) throw Error( - "Function components cannot have string refs. We recommend using useRef() instead. Learn more about using refs safely here: https://fb.me/react-strict-mode-string-ref" + "Function components cannot have refs. Did you mean to use React.forwardRef()?" ); var inst = element.stateNode; } @@ -2349,19 +2463,19 @@ function coerceRef(returnFiber, current, element) { ); var stringRef = "" + returnFiber; if ( - null !== current && - null !== current.ref && - "function" === typeof current.ref && - current.ref._stringRef === stringRef + null !== current$$1 && + null !== current$$1.ref && + "function" === typeof current$$1.ref && + current$$1.ref._stringRef === stringRef ) - return current.ref; - current = function(value) { + return current$$1.ref; + current$$1 = function(value) { var refs = inst.refs; refs === emptyRefsObject && (refs = inst.refs = {}); null === value ? delete refs[stringRef] : (refs[stringRef] = value); }; - current._stringRef = stringRef; - return current; + current$$1._stringRef = stringRef; + return current$$1; } if ("string" !== typeof returnFiber) throw Error( @@ -2413,8 +2527,8 @@ function ChildReconciler(shouldTrackSideEffects) { (currentFirstChild = currentFirstChild.sibling); return returnFiber; } - function useFiber(fiber, pendingProps) { - fiber = createWorkInProgress(fiber, pendingProps); + function useFiber(fiber, pendingProps, expirationTime) { + fiber = createWorkInProgress(fiber, pendingProps, expirationTime); fiber.index = 0; fiber.sibling = null; return fiber; @@ -2439,26 +2553,31 @@ function ChildReconciler(shouldTrackSideEffects) { (newFiber.effectTag = 2); return newFiber; } - function updateTextNode(returnFiber, current, textContent, expirationTime) { - if (null === current || 6 !== current.tag) + function updateTextNode( + returnFiber, + current$$1, + textContent, + expirationTime + ) { + if (null === current$$1 || 6 !== current$$1.tag) return ( - (current = createFiberFromText( + (current$$1 = createFiberFromText( textContent, returnFiber.mode, expirationTime )), - (current.return = returnFiber), - current + (current$$1.return = returnFiber), + current$$1 ); - current = useFiber(current, textContent); - current.return = returnFiber; - return current; + current$$1 = useFiber(current$$1, textContent, expirationTime); + current$$1.return = returnFiber; + return current$$1; } - function updateElement(returnFiber, current, element, expirationTime) { - if (null !== current && current.elementType === element.type) + function updateElement(returnFiber, current$$1, element, expirationTime) { + if (null !== current$$1 && current$$1.elementType === element.type) return ( - (expirationTime = useFiber(current, element.props)), - (expirationTime.ref = coerceRef(returnFiber, current, element)), + (expirationTime = useFiber(current$$1, element.props, expirationTime)), + (expirationTime.ref = coerceRef(returnFiber, current$$1, element)), (expirationTime.return = returnFiber), expirationTime ); @@ -2470,45 +2589,51 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime ); - expirationTime.ref = coerceRef(returnFiber, current, element); + expirationTime.ref = coerceRef(returnFiber, current$$1, element); expirationTime.return = returnFiber; return expirationTime; } - function updatePortal(returnFiber, current, portal, expirationTime) { + function updatePortal(returnFiber, current$$1, portal, expirationTime) { if ( - null === current || - 4 !== current.tag || - current.stateNode.containerInfo !== portal.containerInfo || - current.stateNode.implementation !== portal.implementation + null === current$$1 || + 4 !== current$$1.tag || + current$$1.stateNode.containerInfo !== portal.containerInfo || + current$$1.stateNode.implementation !== portal.implementation ) return ( - (current = createFiberFromPortal( + (current$$1 = createFiberFromPortal( portal, returnFiber.mode, expirationTime )), - (current.return = returnFiber), - current + (current$$1.return = returnFiber), + current$$1 ); - current = useFiber(current, portal.children || []); - current.return = returnFiber; - return current; + current$$1 = useFiber(current$$1, portal.children || [], expirationTime); + current$$1.return = returnFiber; + return current$$1; } - function updateFragment(returnFiber, current, fragment, expirationTime, key) { - if (null === current || 7 !== current.tag) + function updateFragment( + returnFiber, + current$$1, + fragment, + expirationTime, + key + ) { + if (null === current$$1 || 7 !== current$$1.tag) return ( - (current = createFiberFromFragment( + (current$$1 = createFiberFromFragment( fragment, returnFiber.mode, expirationTime, key )), - (current.return = returnFiber), - current + (current$$1.return = returnFiber), + current$$1 ); - current = useFiber(current, fragment); - current.return = returnFiber; - return current; + current$$1 = useFiber(current$$1, fragment, expirationTime); + current$$1.return = returnFiber; + return current$$1; } function createChild(returnFiber, newChild, expirationTime) { if ("string" === typeof newChild || "number" === typeof newChild) @@ -2871,48 +2996,39 @@ function ChildReconciler(shouldTrackSideEffects) { 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; - } + if (isUnkeyedTopLevelFragment.key === isObject) + if ( + 7 === isUnkeyedTopLevelFragment.tag + ? newChild.type === REACT_FRAGMENT_TYPE + : isUnkeyedTopLevelFragment.elementType === newChild.type + ) { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment.sibling + ); + currentFirstChild = useFiber( + isUnkeyedTopLevelFragment, + newChild.type === REACT_FRAGMENT_TYPE + ? newChild.props.children + : newChild.props, + expirationTime + ); + currentFirstChild.ref = coerceRef( + returnFiber, + isUnkeyedTopLevelFragment, + newChild + ); + currentFirstChild.return = returnFiber; + returnFiber = currentFirstChild; + break a; + } else { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment + ); + break; } - deleteRemainingChildren(returnFiber, isUnkeyedTopLevelFragment); - break; - } else deleteChild(returnFiber, isUnkeyedTopLevelFragment); + else deleteChild(returnFiber, isUnkeyedTopLevelFragment); isUnkeyedTopLevelFragment = isUnkeyedTopLevelFragment.sibling; } newChild.type === REACT_FRAGMENT_TYPE @@ -2962,7 +3078,8 @@ function ChildReconciler(shouldTrackSideEffects) { ); currentFirstChild = useFiber( currentFirstChild, - newChild.children || [] + newChild.children || [], + expirationTime ); currentFirstChild.return = returnFiber; returnFiber = currentFirstChild; @@ -2989,7 +3106,11 @@ function ChildReconciler(shouldTrackSideEffects) { (newChild = "" + newChild), null !== currentFirstChild && 6 === currentFirstChild.tag ? (deleteRemainingChildren(returnFiber, currentFirstChild.sibling), - (currentFirstChild = useFiber(currentFirstChild, newChild)), + (currentFirstChild = useFiber( + currentFirstChild, + newChild, + expirationTime + )), (currentFirstChild.return = returnFiber), (returnFiber = currentFirstChild)) : (deleteRemainingChildren(returnFiber, currentFirstChild), @@ -3044,16 +3165,16 @@ function requiredContext(c) { return c; } function pushHostContainer(fiber, nextRootInstance) { - push(rootInstanceStackCursor, nextRootInstance); - push(contextFiberStackCursor, fiber); - push(contextStackCursor$1, NO_CONTEXT); - pop(contextStackCursor$1); - push(contextStackCursor$1, { isInAParentText: !1 }); + push(rootInstanceStackCursor, nextRootInstance, fiber); + push(contextFiberStackCursor, fiber, fiber); + push(contextStackCursor$1, NO_CONTEXT, fiber); + pop(contextStackCursor$1, fiber); + push(contextStackCursor$1, { isInAParentText: !1 }, fiber); } -function popHostContainer() { - pop(contextStackCursor$1); - pop(contextFiberStackCursor); - pop(rootInstanceStackCursor); +function popHostContainer(fiber) { + pop(contextStackCursor$1, fiber); + pop(contextFiberStackCursor, fiber); + pop(rootInstanceStackCursor, fiber); } function pushHostContext(fiber) { requiredContext(rootInstanceStackCursor.current); @@ -3070,19 +3191,23 @@ function pushHostContext(fiber) { ? { isInAParentText: nextContext } : context; context !== nextContext && - (push(contextFiberStackCursor, fiber), - push(contextStackCursor$1, nextContext)); + (push(contextFiberStackCursor, fiber, fiber), + push(contextStackCursor$1, nextContext, fiber)); } function popHostContext(fiber) { contextFiberStackCursor.current === fiber && - (pop(contextStackCursor$1), pop(contextFiberStackCursor)); + (pop(contextStackCursor$1, fiber), pop(contextFiberStackCursor, fiber)); } var suspenseStackCursor = { current: 0 }; function findFirstSuspended(row) { for (var node = row; null !== node; ) { if (13 === node.tag) { var state = node.memoizedState; - if (null !== state && (null === state.dehydrated || shim() || shim())) + if ( + null !== state && + ((state = state.dehydrated), + null === state || shim$1(state) || shim$1(state)) + ) return node; } else if (19 === node.tag && void 0 !== node.memoizedProps.revealOrder) { if (0 !== (node.effectTag & 64)) return node; @@ -3101,16 +3226,24 @@ function findFirstSuspended(row) { } return null; } -function createDeprecatedResponderListener(responder, props) { +function createResponderListener(responder, props) { return { responder: responder, props: props }; } -var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher, +var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig, - renderExpirationTime = 0, + renderExpirationTime$1 = 0, currentlyRenderingFiber$1 = null, currentHook = null, + nextCurrentHook = null, + firstWorkInProgressHook = null, workInProgressHook = null, - didScheduleRenderPhaseUpdate = !1; + nextWorkInProgressHook = null, + remainingExpirationTime = 0, + componentUpdateQueue = null, + sideEffectTag = 0, + didScheduleRenderPhaseUpdate = !1, + renderPhaseUpdates = null, + numberOfReRenders = 0; function throwInvalidHookError() { throw Error( "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem." @@ -3119,7 +3252,7 @@ function throwInvalidHookError() { function areHookInputsEqual(nextDeps, prevDeps) { if (null === prevDeps) return !1; for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) - if (!objectIs(nextDeps[i], prevDeps[i])) return !1; + if (!is$1(nextDeps[i], prevDeps[i])) return !1; return !0; } function renderWithHooks( @@ -3127,85 +3260,92 @@ function renderWithHooks( workInProgress, Component, props, - secondArg, + refOrContext, nextRenderExpirationTime ) { - renderExpirationTime = nextRenderExpirationTime; + renderExpirationTime$1 = nextRenderExpirationTime; currentlyRenderingFiber$1 = workInProgress; - workInProgress.memoizedState = null; - workInProgress.updateQueue = null; - workInProgress.expirationTime = 0; - ReactCurrentDispatcher.current = - null === current || null === current.memoizedState - ? HooksDispatcherOnMount - : HooksDispatcherOnUpdate; - current = Component(props, secondArg); - if (workInProgress.expirationTime === renderExpirationTime) { - nextRenderExpirationTime = 0; - do { - workInProgress.expirationTime = 0; - if (!(25 > nextRenderExpirationTime)) - throw Error( - "Too many re-renders. React limits the number of renders to prevent an infinite loop." - ); - nextRenderExpirationTime += 1; - workInProgressHook = currentHook = null; - workInProgress.updateQueue = null; - ReactCurrentDispatcher.current = HooksDispatcherOnRerender; - current = Component(props, secondArg); - } while (workInProgress.expirationTime === renderExpirationTime); + nextCurrentHook = null !== current ? current.memoizedState : null; + ReactCurrentDispatcher$1.current = + null === nextCurrentHook ? HooksDispatcherOnMount : HooksDispatcherOnUpdate; + workInProgress = Component(props, refOrContext); + if (didScheduleRenderPhaseUpdate) { + do + (didScheduleRenderPhaseUpdate = !1), + (numberOfReRenders += 1), + (nextCurrentHook = null !== current ? current.memoizedState : null), + (nextWorkInProgressHook = firstWorkInProgressHook), + (componentUpdateQueue = workInProgressHook = currentHook = null), + (ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdate), + (workInProgress = Component(props, refOrContext)); + while (didScheduleRenderPhaseUpdate); + renderPhaseUpdates = null; + numberOfReRenders = 0; } - ReactCurrentDispatcher.current = ContextOnlyDispatcher; - workInProgress = null !== currentHook && null !== currentHook.next; - renderExpirationTime = 0; - workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; - didScheduleRenderPhaseUpdate = !1; - if (workInProgress) + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; + current = currentlyRenderingFiber$1; + current.memoizedState = firstWorkInProgressHook; + current.expirationTime = remainingExpirationTime; + current.updateQueue = componentUpdateQueue; + current.effectTag |= sideEffectTag; + current = null !== currentHook && null !== currentHook.next; + renderExpirationTime$1 = 0; + nextWorkInProgressHook = workInProgressHook = firstWorkInProgressHook = nextCurrentHook = currentHook = currentlyRenderingFiber$1 = null; + remainingExpirationTime = 0; + componentUpdateQueue = null; + sideEffectTag = 0; + if (current) throw Error( "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." ); - return current; + return workInProgress; +} +function resetHooks() { + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; + renderExpirationTime$1 = 0; + nextWorkInProgressHook = workInProgressHook = firstWorkInProgressHook = nextCurrentHook = currentHook = currentlyRenderingFiber$1 = null; + remainingExpirationTime = 0; + componentUpdateQueue = null; + sideEffectTag = 0; + didScheduleRenderPhaseUpdate = !1; + renderPhaseUpdates = null; + numberOfReRenders = 0; } function mountWorkInProgressHook() { var hook = { memoizedState: null, baseState: null, - baseQueue: null, queue: null, + baseUpdate: null, next: null }; null === workInProgressHook - ? (currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook) + ? (firstWorkInProgressHook = workInProgressHook = hook) : (workInProgressHook = workInProgressHook.next = hook); return workInProgressHook; } function updateWorkInProgressHook() { - if (null === currentHook) { - var nextCurrentHook = currentlyRenderingFiber$1.alternate; - nextCurrentHook = - null !== nextCurrentHook ? nextCurrentHook.memoizedState : null; - } else nextCurrentHook = currentHook.next; - var nextWorkInProgressHook = - null === workInProgressHook - ? currentlyRenderingFiber$1.memoizedState - : workInProgressHook.next; if (null !== nextWorkInProgressHook) (workInProgressHook = nextWorkInProgressHook), - (currentHook = nextCurrentHook); + (nextWorkInProgressHook = workInProgressHook.next), + (currentHook = nextCurrentHook), + (nextCurrentHook = null !== currentHook ? currentHook.next : null); else { if (null === nextCurrentHook) throw Error("Rendered more hooks than during the previous render."); currentHook = nextCurrentHook; - nextCurrentHook = { + var newHook = { memoizedState: currentHook.memoizedState, baseState: currentHook.baseState, - baseQueue: currentHook.baseQueue, queue: currentHook.queue, + baseUpdate: currentHook.baseUpdate, next: null }; - null === workInProgressHook - ? (currentlyRenderingFiber$1.memoizedState = workInProgressHook = nextCurrentHook) - : (workInProgressHook = workInProgressHook.next = nextCurrentHook); + workInProgressHook = + null === workInProgressHook + ? (firstWorkInProgressHook = newHook) + : (workInProgressHook.next = newHook); + nextCurrentHook = currentHook.next; } return workInProgressHook; } @@ -3220,100 +3360,74 @@ function updateReducer(reducer) { "Should have a queue. This is likely a bug in React. Please file an issue." ); queue.lastRenderedReducer = reducer; - var current = currentHook, - baseQueue = current.baseQueue, - pendingQueue = queue.pending; - if (null !== pendingQueue) { - if (null !== baseQueue) { - var baseFirst = baseQueue.next; - baseQueue.next = pendingQueue.next; - pendingQueue.next = baseFirst; + if (0 < numberOfReRenders) { + var _dispatch = queue.dispatch; + if (null !== renderPhaseUpdates) { + var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue); + if (void 0 !== firstRenderPhaseUpdate) { + renderPhaseUpdates.delete(queue); + var newState = hook.memoizedState; + do + (newState = reducer(newState, firstRenderPhaseUpdate.action)), + (firstRenderPhaseUpdate = firstRenderPhaseUpdate.next); + while (null !== firstRenderPhaseUpdate); + is$1(newState, hook.memoizedState) || (didReceiveUpdate = !0); + hook.memoizedState = newState; + hook.baseUpdate === queue.last && (hook.baseState = newState); + queue.lastRenderedState = newState; + return [newState, _dispatch]; + } } - current.baseQueue = baseQueue = pendingQueue; - queue.pending = null; + return [hook.memoizedState, _dispatch]; } - if (null !== baseQueue) { - baseQueue = baseQueue.next; - current = current.baseState; - var newBaseQueueLast = (baseFirst = pendingQueue = null), - update = baseQueue; + _dispatch = queue.last; + var baseUpdate = hook.baseUpdate; + newState = hook.baseState; + null !== baseUpdate + ? (null !== _dispatch && (_dispatch.next = null), + (_dispatch = baseUpdate.next)) + : (_dispatch = null !== _dispatch ? _dispatch.next : null); + if (null !== _dispatch) { + var newBaseUpdate = (firstRenderPhaseUpdate = null), + _update = _dispatch, + didSkip = !1; do { - var updateExpirationTime = update.expirationTime; - if (updateExpirationTime < renderExpirationTime) { - var clone = { - expirationTime: update.expirationTime, - suspenseConfig: update.suspenseConfig, - action: update.action, - eagerReducer: update.eagerReducer, - eagerState: update.eagerState, - next: null - }; - null === newBaseQueueLast - ? ((baseFirst = newBaseQueueLast = clone), (pendingQueue = current)) - : (newBaseQueueLast = newBaseQueueLast.next = clone); - updateExpirationTime > currentlyRenderingFiber$1.expirationTime && - ((currentlyRenderingFiber$1.expirationTime = updateExpirationTime), - markUnprocessedUpdateTime(updateExpirationTime)); - } else - null !== newBaseQueueLast && - (newBaseQueueLast = newBaseQueueLast.next = { - expirationTime: 1073741823, - suspenseConfig: update.suspenseConfig, - action: update.action, - eagerReducer: update.eagerReducer, - eagerState: update.eagerState, - next: null - }), - markRenderEventTimeAndConfig( + var updateExpirationTime = _update.expirationTime; + updateExpirationTime < renderExpirationTime$1 + ? (didSkip || + ((didSkip = !0), + (newBaseUpdate = baseUpdate), + (firstRenderPhaseUpdate = newState)), + updateExpirationTime > remainingExpirationTime && + ((remainingExpirationTime = updateExpirationTime), + markUnprocessedUpdateTime(remainingExpirationTime))) + : (markRenderEventTimeAndConfig( updateExpirationTime, - update.suspenseConfig + _update.suspenseConfig ), - (current = - update.eagerReducer === reducer - ? update.eagerState - : reducer(current, update.action)); - update = update.next; - } while (null !== update && update !== baseQueue); - null === newBaseQueueLast - ? (pendingQueue = current) - : (newBaseQueueLast.next = baseFirst); - objectIs(current, hook.memoizedState) || (didReceiveUpdate = !0); - hook.memoizedState = current; - hook.baseState = pendingQueue; - hook.baseQueue = newBaseQueueLast; - queue.lastRenderedState = current; - } - return [hook.memoizedState, queue.dispatch]; -} -function rerenderReducer(reducer) { - var hook = updateWorkInProgressHook(), - queue = hook.queue; - if (null === queue) - throw Error( - "Should have a queue. This is likely a bug in React. Please file an issue." - ); - queue.lastRenderedReducer = reducer; - var dispatch = queue.dispatch, - lastRenderPhaseUpdate = queue.pending, - newState = hook.memoizedState; - if (null !== lastRenderPhaseUpdate) { - queue.pending = null; - var update = (lastRenderPhaseUpdate = lastRenderPhaseUpdate.next); - do (newState = reducer(newState, update.action)), (update = update.next); - while (update !== lastRenderPhaseUpdate); - objectIs(newState, hook.memoizedState) || (didReceiveUpdate = !0); + (newState = + _update.eagerReducer === reducer + ? _update.eagerState + : reducer(newState, _update.action))); + baseUpdate = _update; + _update = _update.next; + } while (null !== _update && _update !== _dispatch); + didSkip || + ((newBaseUpdate = baseUpdate), (firstRenderPhaseUpdate = newState)); + is$1(newState, hook.memoizedState) || (didReceiveUpdate = !0); hook.memoizedState = newState; - null === hook.baseQueue && (hook.baseState = newState); + hook.baseUpdate = newBaseUpdate; + hook.baseState = firstRenderPhaseUpdate; queue.lastRenderedState = newState; } - return [newState, dispatch]; + return [hook.memoizedState, queue.dispatch]; } function mountState(initialState) { var hook = mountWorkInProgressHook(); "function" === typeof initialState && (initialState = initialState()); hook.memoizedState = hook.baseState = initialState; initialState = hook.queue = { - pending: null, + last: null, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState @@ -3325,30 +3439,28 @@ function mountState(initialState) { ); return [hook.memoizedState, initialState]; } +function updateState(initialState) { + return updateReducer(basicStateReducer, initialState); +} function pushEffect(tag, create, destroy, deps) { tag = { tag: tag, create: create, destroy: destroy, deps: deps, next: null }; - create = currentlyRenderingFiber$1.updateQueue; - null === create - ? ((create = { lastEffect: null }), - (currentlyRenderingFiber$1.updateQueue = create), - (create.lastEffect = tag.next = tag)) - : ((destroy = create.lastEffect), - null === destroy - ? (create.lastEffect = tag.next = tag) - : ((deps = destroy.next), - (destroy.next = tag), - (tag.next = deps), - (create.lastEffect = tag))); + null === componentUpdateQueue + ? ((componentUpdateQueue = { lastEffect: null }), + (componentUpdateQueue.lastEffect = tag.next = tag)) + : ((create = componentUpdateQueue.lastEffect), + null === create + ? (componentUpdateQueue.lastEffect = tag.next = tag) + : ((destroy = create.next), + (create.next = tag), + (tag.next = destroy), + (componentUpdateQueue.lastEffect = tag))); return tag; } -function updateRef() { - return updateWorkInProgressHook().memoizedState; -} function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var hook = mountWorkInProgressHook(); - currentlyRenderingFiber$1.effectTag |= fiberEffectTag; + sideEffectTag |= fiberEffectTag; hook.memoizedState = pushEffect( - 1 | hookEffectTag, + hookEffectTag, create, void 0, void 0 === deps ? null : deps @@ -3362,21 +3474,18 @@ function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var prevEffect = currentHook.memoizedState; destroy = prevEffect.destroy; if (null !== deps && areHookInputsEqual(deps, prevEffect.deps)) { - pushEffect(hookEffectTag, create, destroy, deps); + pushEffect(0, create, destroy, deps); return; } } - currentlyRenderingFiber$1.effectTag |= fiberEffectTag; - hook.memoizedState = pushEffect(1 | hookEffectTag, create, destroy, deps); + sideEffectTag |= fiberEffectTag; + hook.memoizedState = pushEffect(hookEffectTag, create, destroy, deps); } function mountEffect(create, deps) { - return mountEffectImpl(516, 4, create, deps); + return mountEffectImpl(516, 192, create, deps); } function updateEffect(create, deps) { - return updateEffectImpl(516, 4, create, deps); -} -function updateLayoutEffect(create, deps) { - return updateEffectImpl(4, 2, create, deps); + return updateEffectImpl(516, 192, create, deps); } function imperativeHandleEffect(create, ref) { if ("function" === typeof ref) @@ -3396,15 +3505,6 @@ function imperativeHandleEffect(create, ref) { } ); } -function updateImperativeHandle(ref, create, deps) { - deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; - return updateEffectImpl( - 4, - 2, - imperativeHandleEffect.bind(null, create, ref), - deps - ); -} function mountDebugValue() {} function mountCallback(callback, deps) { mountWorkInProgressHook().memoizedState = [ @@ -3426,79 +3526,72 @@ function updateCallback(callback, deps) { hook.memoizedState = [callback, deps]; return callback; } -function updateMemo(nextCreate, deps) { - var hook = updateWorkInProgressHook(); - deps = void 0 === deps ? null : deps; - var prevState = hook.memoizedState; - if ( - null !== prevState && - null !== deps && - areHookInputsEqual(deps, prevState[1]) - ) - return prevState[0]; - nextCreate = nextCreate(); - hook.memoizedState = [nextCreate, deps]; - return nextCreate; -} -function startTransition(setPending, config, callback) { - var priorityLevel = getCurrentPriorityLevel(); - runWithPriority(98 > priorityLevel ? 98 : priorityLevel, function() { - setPending(!0); - }); - runWithPriority(97 < priorityLevel ? 97 : priorityLevel, function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = void 0 === config ? null : config; - try { - setPending(!1), callback(); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); -} function dispatchAction(fiber, queue, action) { - var currentTime = requestCurrentTimeForUpdate(), - suspenseConfig = ReactCurrentBatchConfig.suspense; - currentTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig); - suspenseConfig = { - expirationTime: currentTime, - suspenseConfig: suspenseConfig, - action: action, - eagerReducer: null, - eagerState: null, - next: null - }; - var pending = queue.pending; - null === pending - ? (suspenseConfig.next = suspenseConfig) - : ((suspenseConfig.next = pending.next), (pending.next = suspenseConfig)); - queue.pending = suspenseConfig; - pending = fiber.alternate; + if (!(25 > numberOfReRenders)) + throw Error( + "Too many re-renders. React limits the number of renders to prevent an infinite loop." + ); + var alternate = fiber.alternate; if ( fiber === currentlyRenderingFiber$1 || - (null !== pending && pending === currentlyRenderingFiber$1) + (null !== alternate && alternate === currentlyRenderingFiber$1) ) - (didScheduleRenderPhaseUpdate = !0), - (suspenseConfig.expirationTime = renderExpirationTime), - (currentlyRenderingFiber$1.expirationTime = renderExpirationTime); + if ( + ((didScheduleRenderPhaseUpdate = !0), + (fiber = { + expirationTime: renderExpirationTime$1, + suspenseConfig: null, + action: action, + eagerReducer: null, + eagerState: null, + next: null + }), + null === renderPhaseUpdates && (renderPhaseUpdates = new Map()), + (action = renderPhaseUpdates.get(queue)), + void 0 === action) + ) + renderPhaseUpdates.set(queue, fiber); + else { + for (queue = action; null !== queue.next; ) queue = queue.next; + queue.next = fiber; + } else { + var currentTime = requestCurrentTimeForUpdate(), + suspenseConfig = ReactCurrentBatchConfig.suspense; + currentTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig); + suspenseConfig = { + expirationTime: currentTime, + suspenseConfig: suspenseConfig, + action: action, + eagerReducer: null, + eagerState: null, + next: null + }; + var last = queue.last; + if (null === last) suspenseConfig.next = suspenseConfig; + else { + var first = last.next; + null !== first && (suspenseConfig.next = first); + last.next = suspenseConfig; + } + queue.last = suspenseConfig; if ( 0 === fiber.expirationTime && - (null === pending || 0 === pending.expirationTime) && - ((pending = queue.lastRenderedReducer), null !== pending) + (null === alternate || 0 === alternate.expirationTime) && + ((alternate = queue.lastRenderedReducer), null !== alternate) ) try { var currentState = queue.lastRenderedState, - eagerState = pending(currentState, action); - suspenseConfig.eagerReducer = pending; + eagerState = alternate(currentState, action); + suspenseConfig.eagerReducer = alternate; suspenseConfig.eagerState = eagerState; - if (objectIs(eagerState, currentState)) return; + if (is$1(eagerState, currentState)) return; } catch (error) { } finally { } - scheduleWork(fiber, currentTime); + scheduleUpdateOnFiber(fiber, currentTime); } } -function updateEventListener() {} var ContextOnlyDispatcher = { readContext: readContext, useCallback: throwInvalidHookError, @@ -3513,8 +3606,7 @@ var ContextOnlyDispatcher = { useDebugValue: throwInvalidHookError, useResponder: throwInvalidHookError, useDeferredValue: throwInvalidHookError, - useTransition: throwInvalidHookError, - useEvent: throwInvalidHookError + useTransition: throwInvalidHookError }, HooksDispatcherOnMount = { readContext: readContext, @@ -3525,13 +3617,13 @@ var ContextOnlyDispatcher = { deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; return mountEffectImpl( 4, - 2, + 36, imperativeHandleEffect.bind(null, create, ref), deps ); }, useLayoutEffect: function(create, deps) { - return mountEffectImpl(4, 2, create, deps); + return mountEffectImpl(4, 36, create, deps); }, useMemo: function(nextCreate, deps) { var hook = mountWorkInProgressHook(); @@ -3545,7 +3637,7 @@ var ContextOnlyDispatcher = { initialArg = void 0 !== init ? init(initialArg) : initialArg; hook.memoizedState = hook.baseState = initialArg; reducer = hook.queue = { - pending: null, + last: null, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialArg @@ -3564,21 +3656,23 @@ var ContextOnlyDispatcher = { }, useState: mountState, useDebugValue: mountDebugValue, - useResponder: createDeprecatedResponderListener, + useResponder: createResponderListener, useDeferredValue: function(value, config) { var _mountState = mountState(value), prevValue = _mountState[0], setValue = _mountState[1]; mountEffect( function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - void 0 === config ? null : config; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } + Scheduler.unstable_next(function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }); }, [value, config] ); @@ -3586,113 +3680,112 @@ var ContextOnlyDispatcher = { }, useTransition: function(config) { var _mountState2 = mountState(!1), - isPending = _mountState2[0]; - _mountState2 = _mountState2[1]; + isPending = _mountState2[0], + setPending = _mountState2[1]; return [ - mountCallback(startTransition.bind(null, _mountState2, config), [ - _mountState2, - config - ]), + mountCallback( + function(callback) { + setPending(!0); + Scheduler.unstable_next(function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setPending(!1), callback(); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }); + }, + [config, isPending] + ), isPending ]; - }, - useEvent: function() {} + } }, HooksDispatcherOnUpdate = { readContext: readContext, useCallback: updateCallback, useContext: readContext, useEffect: updateEffect, - useImperativeHandle: updateImperativeHandle, - useLayoutEffect: updateLayoutEffect, - useMemo: updateMemo, - useReducer: updateReducer, - useRef: updateRef, - useState: function() { - return updateReducer(basicStateReducer); - }, - useDebugValue: mountDebugValue, - useResponder: createDeprecatedResponderListener, - useDeferredValue: function(value, config) { - var _updateState = updateReducer(basicStateReducer), - prevValue = _updateState[0], - setValue = _updateState[1]; - updateEffect( - function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - void 0 === config ? null : config; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }, - [value, config] + useImperativeHandle: function(ref, create, deps) { + deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; + return updateEffectImpl( + 4, + 36, + imperativeHandleEffect.bind(null, create, ref), + deps ); - return prevValue; }, - useTransition: function(config) { - var _updateState2 = updateReducer(basicStateReducer), - isPending = _updateState2[0]; - _updateState2 = _updateState2[1]; - return [ - updateCallback(startTransition.bind(null, _updateState2, config), [ - _updateState2, - config - ]), - isPending - ]; + useLayoutEffect: function(create, deps) { + return updateEffectImpl(4, 36, create, deps); }, - useEvent: updateEventListener - }, - HooksDispatcherOnRerender = { - readContext: readContext, - useCallback: updateCallback, - useContext: readContext, - useEffect: updateEffect, - useImperativeHandle: updateImperativeHandle, - useLayoutEffect: updateLayoutEffect, - useMemo: updateMemo, - useReducer: rerenderReducer, - useRef: updateRef, - useState: function() { - return rerenderReducer(basicStateReducer); + useMemo: function(nextCreate, deps) { + var hook = updateWorkInProgressHook(); + deps = void 0 === deps ? null : deps; + var prevState = hook.memoizedState; + if ( + null !== prevState && + null !== deps && + areHookInputsEqual(deps, prevState[1]) + ) + return prevState[0]; + nextCreate = nextCreate(); + hook.memoizedState = [nextCreate, deps]; + return nextCreate; }, + useReducer: updateReducer, + useRef: function() { + return updateWorkInProgressHook().memoizedState; + }, + useState: updateState, useDebugValue: mountDebugValue, - useResponder: createDeprecatedResponderListener, + useResponder: createResponderListener, useDeferredValue: function(value, config) { - var _rerenderState = rerenderReducer(basicStateReducer), - prevValue = _rerenderState[0], - setValue = _rerenderState[1]; + var _updateState = updateState(value), + prevValue = _updateState[0], + setValue = _updateState[1]; updateEffect( function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - void 0 === config ? null : config; - try { - setValue(value); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } + Scheduler.unstable_next(function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }); }, [value, config] ); return prevValue; }, useTransition: function(config) { - var _rerenderState2 = rerenderReducer(basicStateReducer), - isPending = _rerenderState2[0]; - _rerenderState2 = _rerenderState2[1]; + var _updateState2 = updateState(!1), + isPending = _updateState2[0], + setPending = _updateState2[1]; return [ - updateCallback(startTransition.bind(null, _rerenderState2, config), [ - _rerenderState2, - config - ]), + updateCallback( + function(callback) { + setPending(!0); + Scheduler.unstable_next(function() { + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setPending(!1), callback(); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } + }); + }, + [config, isPending] + ), isPending ]; - }, - useEvent: updateEventListener + } }, now$1 = Scheduler.unstable_now, commitTime = 0, @@ -3705,16 +3798,70 @@ function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) { profilerStartTime = -1; } } -var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner, +var hydrationParentFiber = null, + nextHydratableInstance = null, + isHydrating = !1; +function tryHydrate(fiber, nextInstance) { + switch (fiber.tag) { + case 5: + return ( + (nextInstance = shim$1(nextInstance, fiber.type, fiber.pendingProps)), + null !== nextInstance ? ((fiber.stateNode = nextInstance), !0) : !1 + ); + case 6: + return ( + (nextInstance = shim$1(nextInstance, fiber.pendingProps)), + null !== nextInstance ? ((fiber.stateNode = nextInstance), !0) : !1 + ); + case 13: + return !1; + default: + return !1; + } +} +function tryToClaimNextHydratableInstance(fiber$jscomp$0) { + if (isHydrating) { + var nextInstance = nextHydratableInstance; + if (nextInstance) { + var firstAttemptedInstance = nextInstance; + if (!tryHydrate(fiber$jscomp$0, nextInstance)) { + nextInstance = shim$1(firstAttemptedInstance); + if (!nextInstance || !tryHydrate(fiber$jscomp$0, nextInstance)) { + fiber$jscomp$0.effectTag = (fiber$jscomp$0.effectTag & -1025) | 2; + isHydrating = !1; + hydrationParentFiber = fiber$jscomp$0; + return; + } + var returnFiber = hydrationParentFiber, + fiber = createFiber(5, null, null, 0); + fiber.elementType = "DELETED"; + fiber.type = "DELETED"; + fiber.stateNode = firstAttemptedInstance; + fiber.return = returnFiber; + fiber.effectTag = 8; + null !== returnFiber.lastEffect + ? ((returnFiber.lastEffect.nextEffect = fiber), + (returnFiber.lastEffect = fiber)) + : (returnFiber.firstEffect = returnFiber.lastEffect = fiber); + } + hydrationParentFiber = fiber$jscomp$0; + nextHydratableInstance = shim$1(nextInstance); + } else + (fiber$jscomp$0.effectTag = (fiber$jscomp$0.effectTag & -1025) | 2), + (isHydrating = !1), + (hydrationParentFiber = fiber$jscomp$0); + } +} +var ReactCurrentOwner$3 = ReactSharedInternals.ReactCurrentOwner, didReceiveUpdate = !1; function reconcileChildren( - current, + current$$1, workInProgress, nextChildren, renderExpirationTime ) { workInProgress.child = - null === current + null === current$$1 ? mountChildFibers( workInProgress, null, @@ -3723,13 +3870,13 @@ function reconcileChildren( ) : reconcileChildFibers( workInProgress, - current.child, + current$$1.child, nextChildren, renderExpirationTime ); } function updateForwardRef( - current, + current$$1, workInProgress, Component, nextProps, @@ -3739,38 +3886,43 @@ function updateForwardRef( var ref = workInProgress.ref; prepareToReadContext(workInProgress, renderExpirationTime); nextProps = renderWithHooks( - current, + current$$1, workInProgress, Component, nextProps, ref, renderExpirationTime ); - if (null !== current && !didReceiveUpdate) + if (null !== current$$1 && !didReceiveUpdate) return ( - (workInProgress.updateQueue = current.updateQueue), + (workInProgress.updateQueue = current$$1.updateQueue), (workInProgress.effectTag &= -517), - current.expirationTime <= renderExpirationTime && - (current.expirationTime = 0), + current$$1.expirationTime <= renderExpirationTime && + (current$$1.expirationTime = 0), bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ) ); workInProgress.effectTag |= 1; - reconcileChildren(current, workInProgress, nextProps, renderExpirationTime); + reconcileChildren( + current$$1, + workInProgress, + nextProps, + renderExpirationTime + ); return workInProgress.child; } function updateMemoComponent( - current, + current$$1, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime ) { - if (null === current) { + if (null === current$$1) { var type = Component.type; if ( "function" === typeof type && @@ -3783,7 +3935,7 @@ function updateMemoComponent( (workInProgress.tag = 15), (workInProgress.type = type), updateSimpleMemoComponent( - current, + current$$1, workInProgress, type, nextProps, @@ -3791,7 +3943,7 @@ function updateMemoComponent( renderExpirationTime ) ); - current = createFiberFromTypeAndProps( + current$$1 = createFiberFromTypeAndProps( Component.type, null, nextProps, @@ -3799,66 +3951,65 @@ function updateMemoComponent( workInProgress.mode, renderExpirationTime ); - current.ref = workInProgress.ref; - current.return = workInProgress; - return (workInProgress.child = current); + current$$1.ref = workInProgress.ref; + current$$1.return = workInProgress; + return (workInProgress.child = current$$1); } - type = current.child; + type = current$$1.child; if ( updateExpirationTime < renderExpirationTime && ((updateExpirationTime = type.memoizedProps), (Component = Component.compare), (Component = null !== Component ? Component : shallowEqual), Component(updateExpirationTime, nextProps) && - current.ref === workInProgress.ref) + current$$1.ref === workInProgress.ref) ) return bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ); workInProgress.effectTag |= 1; - current = createWorkInProgress(type, nextProps); - current.ref = workInProgress.ref; - current.return = workInProgress; - return (workInProgress.child = current); + current$$1 = createWorkInProgress(type, nextProps, renderExpirationTime); + current$$1.ref = workInProgress.ref; + current$$1.return = workInProgress; + return (workInProgress.child = current$$1); } function updateSimpleMemoComponent( - current, + current$$1, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime ) { - return null !== current && - shallowEqual(current.memoizedProps, nextProps) && - current.ref === workInProgress.ref && + return null !== current$$1 && + shallowEqual(current$$1.memoizedProps, nextProps) && + current$$1.ref === workInProgress.ref && ((didReceiveUpdate = !1), updateExpirationTime < renderExpirationTime) - ? ((workInProgress.expirationTime = current.expirationTime), - bailoutOnAlreadyFinishedWork( - current, + ? bailoutOnAlreadyFinishedWork( + current$$1, workInProgress, renderExpirationTime - )) + ) : updateFunctionComponent( - current, + current$$1, workInProgress, Component, nextProps, renderExpirationTime ); } -function markRef(current, workInProgress) { +function markRef(current$$1, workInProgress) { var ref = workInProgress.ref; if ( - (null === current && null !== ref) || - (null !== current && current.ref !== ref) + (null === current$$1 && null !== ref) || + (null !== current$$1 && current$$1.ref !== ref) ) workInProgress.effectTag |= 128; } function updateFunctionComponent( - current, + current$$1, workInProgress, Component, nextProps, @@ -3870,31 +4021,36 @@ function updateFunctionComponent( context = getMaskedContext(workInProgress, context); prepareToReadContext(workInProgress, renderExpirationTime); Component = renderWithHooks( - current, + current$$1, workInProgress, Component, nextProps, context, renderExpirationTime ); - if (null !== current && !didReceiveUpdate) + if (null !== current$$1 && !didReceiveUpdate) return ( - (workInProgress.updateQueue = current.updateQueue), + (workInProgress.updateQueue = current$$1.updateQueue), (workInProgress.effectTag &= -517), - current.expirationTime <= renderExpirationTime && - (current.expirationTime = 0), + current$$1.expirationTime <= renderExpirationTime && + (current$$1.expirationTime = 0), bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ) ); workInProgress.effectTag |= 1; - reconcileChildren(current, workInProgress, Component, renderExpirationTime); + reconcileChildren( + current$$1, + workInProgress, + Component, + renderExpirationTime + ); return workInProgress.child; } function updateClassComponent( - current, + current$$1, workInProgress, Component, nextProps, @@ -3906,11 +4062,16 @@ function updateClassComponent( } else hasContext = !1; prepareToReadContext(workInProgress, renderExpirationTime); if (null === workInProgress.stateNode) - null !== current && - ((current.alternate = null), + null !== current$$1 && + ((current$$1.alternate = null), (workInProgress.alternate = null), (workInProgress.effectTag |= 2)), - constructClassInstance(workInProgress, Component, nextProps), + constructClassInstance( + workInProgress, + Component, + nextProps, + renderExpirationTime + ), mountClassInstance( workInProgress, Component, @@ -3918,7 +4079,7 @@ function updateClassComponent( renderExpirationTime ), (nextProps = !0); - else if (null === current) { + else if (null === current$$1) { var instance = workInProgress.stateNode, oldProps = workInProgress.memoizedProps; instance.props = oldProps; @@ -3946,14 +4107,17 @@ function updateClassComponent( )); hasForceUpdate = !1; var oldState = workInProgress.memoizedState; - instance.state = oldState; - processUpdateQueue( - workInProgress, - nextProps, - instance, - renderExpirationTime - ); - oldContext = workInProgress.memoizedState; + oldContext = instance.state = oldState; + var updateQueue = workInProgress.updateQueue; + null !== updateQueue && + (processUpdateQueue( + workInProgress, + updateQueue, + nextProps, + instance, + renderExpirationTime + ), + (oldContext = workInProgress.memoizedState)); oldProps !== nextProps || oldState !== oldContext || didPerformWorkStackCursor.current || @@ -3999,7 +4163,6 @@ function updateClassComponent( (nextProps = !1)); } else (instance = workInProgress.stateNode), - cloneUpdateQueue(current, workInProgress), (oldProps = workInProgress.memoizedProps), (instance.props = workInProgress.type === workInProgress.elementType @@ -4028,14 +4191,17 @@ function updateClassComponent( )), (hasForceUpdate = !1), (oldContext = workInProgress.memoizedState), - (instance.state = oldContext), - processUpdateQueue( - workInProgress, - nextProps, - instance, - renderExpirationTime - ), - (oldState = workInProgress.memoizedState), + (oldState = instance.state = oldContext), + (updateQueue = workInProgress.updateQueue), + null !== updateQueue && + (processUpdateQueue( + workInProgress, + updateQueue, + nextProps, + instance, + renderExpirationTime + ), + (oldState = workInProgress.memoizedState)), oldProps !== nextProps || oldContext !== oldState || didPerformWorkStackCursor.current || @@ -4079,12 +4245,12 @@ function updateClassComponent( "function" === typeof instance.getSnapshotBeforeUpdate && (workInProgress.effectTag |= 256)) : ("function" !== typeof instance.componentDidUpdate || - (oldProps === current.memoizedProps && - oldContext === current.memoizedState) || + (oldProps === current$$1.memoizedProps && + oldContext === current$$1.memoizedState) || (workInProgress.effectTag |= 4), "function" !== typeof instance.getSnapshotBeforeUpdate || - (oldProps === current.memoizedProps && - oldContext === current.memoizedState) || + (oldProps === current$$1.memoizedProps && + oldContext === current$$1.memoizedState) || (workInProgress.effectTag |= 256), (workInProgress.memoizedProps = nextProps), (workInProgress.memoizedState = oldState)), @@ -4093,16 +4259,16 @@ function updateClassComponent( (instance.context = contextType), (nextProps = getDerivedStateFromProps)) : ("function" !== typeof instance.componentDidUpdate || - (oldProps === current.memoizedProps && - oldContext === current.memoizedState) || + (oldProps === current$$1.memoizedProps && + oldContext === current$$1.memoizedState) || (workInProgress.effectTag |= 4), "function" !== typeof instance.getSnapshotBeforeUpdate || - (oldProps === current.memoizedProps && - oldContext === current.memoizedState) || + (oldProps === current$$1.memoizedProps && + oldContext === current$$1.memoizedState) || (workInProgress.effectTag |= 256), (nextProps = !1)); return finishClassComponent( - current, + current$$1, workInProgress, Component, nextProps, @@ -4111,26 +4277,26 @@ function updateClassComponent( ); } function finishClassComponent( - current, + current$$1, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime ) { - markRef(current, workInProgress); + markRef(current$$1, workInProgress); var didCaptureError = 0 !== (workInProgress.effectTag & 64); if (!shouldUpdate && !didCaptureError) return ( hasContext && invalidateContextProvider(workInProgress, Component, !1), bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ) ); shouldUpdate = workInProgress.stateNode; - ReactCurrentOwner$1.current = workInProgress; + ReactCurrentOwner$3.current = workInProgress; if ( didCaptureError && "function" !== typeof Component.getDerivedStateFromError @@ -4139,11 +4305,11 @@ function finishClassComponent( profilerStartTime = -1; } else nextChildren = shouldUpdate.render(); workInProgress.effectTag |= 1; - null !== current && didCaptureError + null !== current$$1 && didCaptureError ? ((didCaptureError = nextChildren), (workInProgress.child = reconcileChildFibers( workInProgress, - current.child, + current$$1.child, null, renderExpirationTime )), @@ -4154,7 +4320,7 @@ function finishClassComponent( renderExpirationTime ))) : reconcileChildren( - current, + current$$1, workInProgress, nextChildren, renderExpirationTime @@ -4177,7 +4343,7 @@ function pushHostRootContext(workInProgress) { } var SUSPENDED_MARKER = { dehydrated: null, retryTime: 0 }; function updateSuspenseComponent( - current, + current$$1, workInProgress, renderExpirationTime ) { @@ -4189,30 +4355,32 @@ function updateSuspenseComponent( (JSCompiler_temp = 0 !== (workInProgress.effectTag & 64)) || (JSCompiler_temp = 0 !== (suspenseContext & 2) && - (null === current || null !== current.memoizedState)); + (null === current$$1 || null !== current$$1.memoizedState)); JSCompiler_temp ? ((nextDidTimeout = !0), (workInProgress.effectTag &= -65)) - : (null !== current && null === current.memoizedState) || + : (null !== current$$1 && null === current$$1.memoizedState) || void 0 === nextProps.fallback || !0 === nextProps.unstable_avoidThisFallback || (suspenseContext |= 1); - push(suspenseStackCursor, suspenseContext & 1); - if (null === current) { + push(suspenseStackCursor, suspenseContext & 1, workInProgress); + if (null === current$$1) { + void 0 !== nextProps.fallback && + tryToClaimNextHydratableInstance(workInProgress); if (nextDidTimeout) { nextDidTimeout = nextProps.fallback; nextProps = createFiberFromFragment(null, mode, 0, null); nextProps.return = workInProgress; if (0 === (workInProgress.mode & 2)) for ( - current = + current$$1 = null !== workInProgress.memoizedState ? workInProgress.child.child : workInProgress.child, - nextProps.child = current; - null !== current; + nextProps.child = current$$1; + null !== current$$1; ) - (current.return = nextProps), (current = current.sibling); + (current$$1.return = nextProps), (current$$1 = current$$1.sibling); renderExpirationTime = createFiberFromFragment( nextDidTimeout, mode, @@ -4234,14 +4402,15 @@ function updateSuspenseComponent( renderExpirationTime )); } - if (null !== current.memoizedState) { - current = current.child; - mode = current.sibling; + if (null !== current$$1.memoizedState) { + current$$1 = current$$1.child; + mode = current$$1.sibling; if (nextDidTimeout) { nextProps = nextProps.fallback; renderExpirationTime = createWorkInProgress( - current, - current.pendingProps + current$$1, + current$$1.pendingProps, + 0 ); renderExpirationTime.return = workInProgress; if ( @@ -4250,7 +4419,7 @@ function updateSuspenseComponent( null !== workInProgress.memoizedState ? workInProgress.child.child : workInProgress.child), - nextDidTimeout !== current.child) + nextDidTimeout !== current$$1.child) ) for ( renderExpirationTime.child = nextDidTimeout; @@ -4261,12 +4430,12 @@ function updateSuspenseComponent( (nextDidTimeout = nextDidTimeout.sibling); if (workInProgress.mode & 8) { nextDidTimeout = 0; - for (current = renderExpirationTime.child; null !== current; ) - (nextDidTimeout += current.treeBaseDuration), - (current = current.sibling); + for (current$$1 = renderExpirationTime.child; null !== current$$1; ) + (nextDidTimeout += current$$1.treeBaseDuration), + (current$$1 = current$$1.sibling); renderExpirationTime.treeBaseDuration = nextDidTimeout; } - mode = createWorkInProgress(mode, nextProps); + mode = createWorkInProgress(mode, nextProps, mode.expirationTime); mode.return = workInProgress; renderExpirationTime.sibling = mode; renderExpirationTime.childExpirationTime = 0; @@ -4276,37 +4445,37 @@ function updateSuspenseComponent( } renderExpirationTime = reconcileChildFibers( workInProgress, - current.child, + current$$1.child, nextProps.children, renderExpirationTime ); workInProgress.memoizedState = null; return (workInProgress.child = renderExpirationTime); } - current = current.child; + current$$1 = current$$1.child; if (nextDidTimeout) { nextDidTimeout = nextProps.fallback; nextProps = createFiberFromFragment(null, mode, 0, null); nextProps.return = workInProgress; - nextProps.child = current; - null !== current && (current.return = nextProps); + nextProps.child = current$$1; + null !== current$$1 && (current$$1.return = nextProps); if (0 === (workInProgress.mode & 2)) for ( - current = + current$$1 = null !== workInProgress.memoizedState ? workInProgress.child.child : workInProgress.child, - nextProps.child = current; - null !== current; + nextProps.child = current$$1; + null !== current$$1; ) - (current.return = nextProps), (current = current.sibling); + (current$$1.return = nextProps), (current$$1 = current$$1.sibling); if (workInProgress.mode & 8) { - current = 0; + current$$1 = 0; for (suspenseContext = nextProps.child; null !== suspenseContext; ) - (current += suspenseContext.treeBaseDuration), + (current$$1 += suspenseContext.treeBaseDuration), (suspenseContext = suspenseContext.sibling); - nextProps.treeBaseDuration = current; + nextProps.treeBaseDuration = current$$1; } renderExpirationTime = createFiberFromFragment( nextDidTimeout, @@ -4325,7 +4494,7 @@ function updateSuspenseComponent( workInProgress.memoizedState = null; return (workInProgress.child = reconcileChildFibers( workInProgress, - current, + current$$1, nextProps.children, renderExpirationTime )); @@ -4352,7 +4521,6 @@ function initSuspenseListRenderState( ? (workInProgress.memoizedState = { isBackwards: isBackwards, rendering: null, - renderingStartTime: 0, last: lastContentRow, tail: tail, tailExpiration: 0, @@ -4361,7 +4529,6 @@ function initSuspenseListRenderState( }) : ((renderState.isBackwards = isBackwards), (renderState.rendering = null), - (renderState.renderingStartTime = 0), (renderState.last = lastContentRow), (renderState.tail = tail), (renderState.tailExpiration = 0), @@ -4369,7 +4536,7 @@ function initSuspenseListRenderState( (renderState.lastEffect = lastEffectBeforeRendering)); } function updateSuspenseListComponent( - current, + current$$1, workInProgress, renderExpirationTime ) { @@ -4377,7 +4544,7 @@ function updateSuspenseListComponent( revealOrder = nextProps.revealOrder, tailMode = nextProps.tail; reconcileChildren( - current, + current$$1, workInProgress, nextProps.children, renderExpirationTime @@ -4386,39 +4553,42 @@ function updateSuspenseListComponent( if (0 !== (nextProps & 2)) (nextProps = (nextProps & 1) | 2), (workInProgress.effectTag |= 64); else { - if (null !== current && 0 !== (current.effectTag & 64)) - a: for (current = workInProgress.child; null !== current; ) { - if (13 === current.tag) - null !== current.memoizedState && - scheduleWorkOnFiber(current, renderExpirationTime); - else if (19 === current.tag) - scheduleWorkOnFiber(current, renderExpirationTime); - else if (null !== current.child) { - current.child.return = current; - current = current.child; + if (null !== current$$1 && 0 !== (current$$1.effectTag & 64)) + a: for (current$$1 = workInProgress.child; null !== current$$1; ) { + if (13 === current$$1.tag) + null !== current$$1.memoizedState && + scheduleWorkOnFiber(current$$1, renderExpirationTime); + else if (19 === current$$1.tag) + scheduleWorkOnFiber(current$$1, renderExpirationTime); + else if (null !== current$$1.child) { + current$$1.child.return = current$$1; + current$$1 = current$$1.child; continue; } - if (current === workInProgress) break a; - for (; null === current.sibling; ) { - if (null === current.return || current.return === workInProgress) + if (current$$1 === workInProgress) break a; + for (; null === current$$1.sibling; ) { + if ( + null === current$$1.return || + current$$1.return === workInProgress + ) break a; - current = current.return; + current$$1 = current$$1.return; } - current.sibling.return = current.return; - current = current.sibling; + current$$1.sibling.return = current$$1.return; + current$$1 = current$$1.sibling; } nextProps &= 1; } - push(suspenseStackCursor, nextProps); + push(suspenseStackCursor, nextProps, workInProgress); if (0 === (workInProgress.mode & 2)) workInProgress.memoizedState = null; else switch (revealOrder) { case "forwards": renderExpirationTime = workInProgress.child; for (revealOrder = null; null !== renderExpirationTime; ) - (current = renderExpirationTime.alternate), - null !== current && - null === findFirstSuspended(current) && + (current$$1 = renderExpirationTime.alternate), + null !== current$$1 && + null === findFirstSuspended(current$$1) && (revealOrder = renderExpirationTime), (renderExpirationTime = renderExpirationTime.sibling); renderExpirationTime = revealOrder; @@ -4440,15 +4610,15 @@ function updateSuspenseListComponent( renderExpirationTime = null; revealOrder = workInProgress.child; for (workInProgress.child = null; null !== revealOrder; ) { - current = revealOrder.alternate; - if (null !== current && null === findFirstSuspended(current)) { + current$$1 = revealOrder.alternate; + if (null !== current$$1 && null === findFirstSuspended(current$$1)) { workInProgress.child = revealOrder; break; } - current = revealOrder.sibling; + current$$1 = revealOrder.sibling; revealOrder.sibling = renderExpirationTime; renderExpirationTime = revealOrder; - revealOrder = current; + revealOrder = current$$1; } initSuspenseListRenderState( workInProgress, @@ -4475,30 +4645,36 @@ function updateSuspenseListComponent( return workInProgress.child; } function bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ) { - null !== current && (workInProgress.dependencies = current.dependencies); + null !== current$$1 && + (workInProgress.dependencies = current$$1.dependencies); profilerStartTime = -1; var updateExpirationTime = workInProgress.expirationTime; 0 !== updateExpirationTime && markUnprocessedUpdateTime(updateExpirationTime); if (workInProgress.childExpirationTime < renderExpirationTime) return null; - if (null !== current && workInProgress.child !== current.child) + if (null !== current$$1 && workInProgress.child !== current$$1.child) throw Error("Resuming work not yet implemented."); if (null !== workInProgress.child) { - current = workInProgress.child; - renderExpirationTime = createWorkInProgress(current, current.pendingProps); + current$$1 = workInProgress.child; + renderExpirationTime = createWorkInProgress( + current$$1, + current$$1.pendingProps, + current$$1.expirationTime + ); workInProgress.child = renderExpirationTime; for ( renderExpirationTime.return = workInProgress; - null !== current.sibling; + null !== current$$1.sibling; ) - (current = current.sibling), + (current$$1 = current$$1.sibling), (renderExpirationTime = renderExpirationTime.sibling = createWorkInProgress( - current, - current.pendingProps + current$$1, + current$$1.pendingProps, + current$$1.expirationTime )), (renderExpirationTime.return = workInProgress); renderExpirationTime.sibling = null; @@ -4560,87 +4736,78 @@ function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { : (_lastTailNode.sibling = null); } } -function completeWork(current, workInProgress, renderExpirationTime) { +function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { var newProps = workInProgress.pendingProps; switch (workInProgress.tag) { case 2: + break; case 16: + break; case 15: case 0: - case 11: - case 7: - case 8: - case 12: - case 9: - case 14: - return null; + break; case 1: - return isContextProvider(workInProgress.type) && popContext(), null; + isContextProvider(workInProgress.type) && popContext(workInProgress); + break; case 3: - return ( - popHostContainer(), - pop(didPerformWorkStackCursor), - pop(contextStackCursor), - (current = workInProgress.stateNode), - current.pendingContext && - ((current.context = current.pendingContext), - (current.pendingContext = null)), - updateHostContainer(workInProgress), - null - ); + popHostContainer(workInProgress); + popTopLevelContextObject(workInProgress); + current = workInProgress.stateNode; + current.pendingContext && + ((current.context = current.pendingContext), + (current.pendingContext = null)); + updateHostContainer(workInProgress); + break; case 5: popHostContext(workInProgress); var rootContainerInstance = requiredContext( rootInstanceStackCursor.current ); - renderExpirationTime = workInProgress.type; + renderExpirationTime$jscomp$0 = workInProgress.type; if (null !== current && null != workInProgress.stateNode) updateHostComponent$1( current, workInProgress, - renderExpirationTime, + renderExpirationTime$jscomp$0, newProps, rootContainerInstance ), current.ref !== workInProgress.ref && (workInProgress.effectTag |= 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." - ); - return null; - } - requiredContext(contextStackCursor$1.current); - current = allocateTag(); - renderExpirationTime = getViewConfigForType(renderExpirationTime); - var updatePayload = diffProperties( - null, - emptyObject, - newProps, - renderExpirationTime.validAttributes - ); + else if (newProps) { + current = requiredContext(contextStackCursor$1.current); + var tag = allocateTag(), + viewConfig = getViewConfigForType(renderExpirationTime$jscomp$0), + updatePayload = diffProperties( + null, + emptyObject, + newProps, + viewConfig.validAttributes + ); ReactNativePrivateInterface.UIManager.createView( - current, - renderExpirationTime.uiViewClassName, + tag, + viewConfig.uiViewClassName, rootContainerInstance, updatePayload ); - rootContainerInstance = new ReactNativeFiberHostComponent( - current, - renderExpirationTime, - workInProgress - ); - instanceCache.set(current, workInProgress); - instanceProps.set(current, newProps); - appendAllChildren(rootContainerInstance, workInProgress, !1, !1); - workInProgress.stateNode = rootContainerInstance; - finalizeInitialChildren(rootContainerInstance) && - (workInProgress.effectTag |= 4); + viewConfig = new ReactNativeFiberHostComponent(tag, viewConfig); + instanceCache.set(tag, workInProgress); + instanceProps.set(tag, newProps); + appendAllChildren(viewConfig, workInProgress, !1, !1); + workInProgress.stateNode = viewConfig; + finalizeInitialChildren( + viewConfig, + renderExpirationTime$jscomp$0, + newProps, + rootContainerInstance, + current + ) && (workInProgress.effectTag |= 4); null !== workInProgress.ref && (workInProgress.effectTag |= 128); - } - return null; + } else 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." + ); + break; case 6: if (current && null != workInProgress.stateNode) updateHostText$1( @@ -4669,30 +4836,33 @@ function completeWork(current, workInProgress, renderExpirationTime) { instanceCache.set(rootContainerInstance, workInProgress); workInProgress.stateNode = rootContainerInstance; } - return null; + break; + case 11: + break; case 13: - pop(suspenseStackCursor); + pop(suspenseStackCursor, workInProgress); newProps = workInProgress.memoizedState; if (0 !== (workInProgress.effectTag & 64)) return ( - (workInProgress.expirationTime = renderExpirationTime), workInProgress + (workInProgress.expirationTime = renderExpirationTime$jscomp$0), + workInProgress ); newProps = null !== newProps; rootContainerInstance = !1; null !== current && - ((renderExpirationTime = current.memoizedState), - (rootContainerInstance = null !== renderExpirationTime), + ((renderExpirationTime$jscomp$0 = current.memoizedState), + (rootContainerInstance = null !== renderExpirationTime$jscomp$0), newProps || - null === renderExpirationTime || - ((renderExpirationTime = current.child.sibling), - null !== renderExpirationTime && - ((updatePayload = workInProgress.firstEffect), - null !== updatePayload - ? ((workInProgress.firstEffect = renderExpirationTime), - (renderExpirationTime.nextEffect = updatePayload)) - : ((workInProgress.firstEffect = workInProgress.lastEffect = renderExpirationTime), - (renderExpirationTime.nextEffect = null)), - (renderExpirationTime.effectTag = 8)))); + null === renderExpirationTime$jscomp$0 || + ((renderExpirationTime$jscomp$0 = current.child.sibling), + null !== renderExpirationTime$jscomp$0 && + ((tag = workInProgress.firstEffect), + null !== tag + ? ((workInProgress.firstEffect = renderExpirationTime$jscomp$0), + (renderExpirationTime$jscomp$0.nextEffect = tag)) + : ((workInProgress.firstEffect = workInProgress.lastEffect = renderExpirationTime$jscomp$0), + (renderExpirationTime$jscomp$0.nextEffect = null)), + (renderExpirationTime$jscomp$0.effectTag = 8)))); if (newProps && !rootContainerInstance && 0 !== (workInProgress.mode & 2)) if ( (null === current && @@ -4709,30 +4879,41 @@ function completeWork(current, workInProgress, renderExpirationTime) { workInProgressRootExitStatus = RootSuspendedWithDelay; 0 !== workInProgressRootNextUnprocessedUpdateTime && null !== workInProgressRoot && - (markRootSuspendedAtTime( - workInProgressRoot, - renderExpirationTime$1 - ), + (markRootSuspendedAtTime(workInProgressRoot, renderExpirationTime), markRootUpdatedAtTime( workInProgressRoot, workInProgressRootNextUnprocessedUpdateTime )); } if (newProps || rootContainerInstance) workInProgress.effectTag |= 4; - return null; + break; + case 7: + break; + case 8: + break; + case 12: + break; case 4: - return popHostContainer(), updateHostContainer(workInProgress), null; + popHostContainer(workInProgress); + updateHostContainer(workInProgress); + break; case 10: - return popProvider(workInProgress), null; + popProvider(workInProgress); + break; + case 9: + break; + case 14: + break; case 17: - return isContextProvider(workInProgress.type) && popContext(), null; + isContextProvider(workInProgress.type) && popContext(workInProgress); + break; case 19: - pop(suspenseStackCursor); + pop(suspenseStackCursor, workInProgress); newProps = workInProgress.memoizedState; - if (null === newProps) return null; + if (null === newProps) break; rootContainerInstance = 0 !== (workInProgress.effectTag & 64); - updatePayload = newProps.rendering; - if (null === updatePayload) + tag = newProps.rendering; + if (null === tag) if (rootContainerInstance) cutOffTailIfNeeded(newProps, !1); else { if ( @@ -4740,29 +4921,30 @@ function completeWork(current, workInProgress, renderExpirationTime) { (null !== current && 0 !== (current.effectTag & 64)) ) for (current = workInProgress.child; null !== current; ) { - updatePayload = findFirstSuspended(current); - if (null !== updatePayload) { + tag = findFirstSuspended(current); + if (null !== tag) { workInProgress.effectTag |= 64; cutOffTailIfNeeded(newProps, !1); - current = updatePayload.updateQueue; + current = tag.updateQueue; null !== current && ((workInProgress.updateQueue = current), (workInProgress.effectTag |= 4)); null === newProps.lastEffect && (workInProgress.firstEffect = null); workInProgress.lastEffect = newProps.lastEffect; - current = renderExpirationTime; + current = renderExpirationTime$jscomp$0; for (newProps = workInProgress.child; null !== newProps; ) (rootContainerInstance = newProps), - (updatePayload = current), + (tag = current), (rootContainerInstance.effectTag &= 2), (rootContainerInstance.nextEffect = null), (rootContainerInstance.firstEffect = null), (rootContainerInstance.lastEffect = null), - (renderExpirationTime = rootContainerInstance.alternate), - null === renderExpirationTime + (renderExpirationTime$jscomp$0 = + rootContainerInstance.alternate), + null === renderExpirationTime$jscomp$0 ? ((rootContainerInstance.childExpirationTime = 0), - (rootContainerInstance.expirationTime = updatePayload), + (rootContainerInstance.expirationTime = tag), (rootContainerInstance.child = null), (rootContainerInstance.memoizedProps = null), (rootContainerInstance.memoizedState = null), @@ -4771,34 +4953,35 @@ function completeWork(current, workInProgress, renderExpirationTime) { (rootContainerInstance.selfBaseDuration = 0), (rootContainerInstance.treeBaseDuration = 0)) : ((rootContainerInstance.childExpirationTime = - renderExpirationTime.childExpirationTime), + renderExpirationTime$jscomp$0.childExpirationTime), (rootContainerInstance.expirationTime = - renderExpirationTime.expirationTime), + renderExpirationTime$jscomp$0.expirationTime), (rootContainerInstance.child = - renderExpirationTime.child), + renderExpirationTime$jscomp$0.child), (rootContainerInstance.memoizedProps = - renderExpirationTime.memoizedProps), + renderExpirationTime$jscomp$0.memoizedProps), (rootContainerInstance.memoizedState = - renderExpirationTime.memoizedState), + renderExpirationTime$jscomp$0.memoizedState), (rootContainerInstance.updateQueue = - renderExpirationTime.updateQueue), - (updatePayload = renderExpirationTime.dependencies), + renderExpirationTime$jscomp$0.updateQueue), + (tag = renderExpirationTime$jscomp$0.dependencies), (rootContainerInstance.dependencies = - null === updatePayload + null === tag ? null : { - expirationTime: updatePayload.expirationTime, - firstContext: updatePayload.firstContext, - responders: updatePayload.responders + expirationTime: tag.expirationTime, + firstContext: tag.firstContext, + responders: tag.responders }), (rootContainerInstance.selfBaseDuration = - renderExpirationTime.selfBaseDuration), + renderExpirationTime$jscomp$0.selfBaseDuration), (rootContainerInstance.treeBaseDuration = - renderExpirationTime.treeBaseDuration)), + renderExpirationTime$jscomp$0.treeBaseDuration)), (newProps = newProps.sibling); push( suspenseStackCursor, - (suspenseStackCursor.current & 1) | 2 + (suspenseStackCursor.current & 1) | 2, + workInProgress ); return workInProgress.child; } @@ -4807,9 +4990,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { } else { if (!rootContainerInstance) - if ( - ((current = findFirstSuspended(updatePayload)), null !== current) - ) { + if (((current = findFirstSuspended(tag)), null !== current)) { if ( ((workInProgress.effectTag |= 64), (rootContainerInstance = !0), @@ -4820,72 +5001,74 @@ function completeWork(current, workInProgress, renderExpirationTime) { cutOffTailIfNeeded(newProps, !0), null === newProps.tail && "hidden" === newProps.tailMode && - !updatePayload.alternate) - ) - return ( - (workInProgress = workInProgress.lastEffect = - newProps.lastEffect), - null !== workInProgress && (workInProgress.nextEffect = null), - null - ); + !tag.alternate) + ) { + workInProgress = workInProgress.lastEffect = newProps.lastEffect; + null !== workInProgress && (workInProgress.nextEffect = null); + break; + } } else - 2 * now() - newProps.renderingStartTime > newProps.tailExpiration && - 1 < renderExpirationTime && + now() > newProps.tailExpiration && + 1 < renderExpirationTime$jscomp$0 && ((workInProgress.effectTag |= 64), (rootContainerInstance = !0), cutOffTailIfNeeded(newProps, !1), - (current = renderExpirationTime - 1), + (current = renderExpirationTime$jscomp$0 - 1), (workInProgress.expirationTime = workInProgress.childExpirationTime = current), null === spawnedWorkDuringRender ? (spawnedWorkDuringRender = [current]) : spawnedWorkDuringRender.push(current)); newProps.isBackwards - ? ((updatePayload.sibling = workInProgress.child), - (workInProgress.child = updatePayload)) + ? ((tag.sibling = workInProgress.child), (workInProgress.child = tag)) : ((current = newProps.last), null !== current - ? (current.sibling = updatePayload) - : (workInProgress.child = updatePayload), - (newProps.last = updatePayload)); + ? (current.sibling = tag) + : (workInProgress.child = tag), + (newProps.last = tag)); } - return null !== newProps.tail - ? (0 === newProps.tailExpiration && + if (null !== newProps.tail) + return ( + 0 === newProps.tailExpiration && (newProps.tailExpiration = now() + 500), (current = newProps.tail), (newProps.rendering = current), (newProps.tail = current.sibling), (newProps.lastEffect = workInProgress.lastEffect), - (newProps.renderingStartTime = now()), (current.sibling = null), - (workInProgress = suspenseStackCursor.current), + (newProps = suspenseStackCursor.current), push( suspenseStackCursor, - rootContainerInstance - ? (workInProgress & 1) | 2 - : workInProgress & 1 + rootContainerInstance ? (newProps & 1) | 2 : newProps & 1, + workInProgress ), - current) - : null; + current + ); + break; + case 20: + break; + case 21: + break; + default: + throw Error( + "Unknown unit of work tag (" + + workInProgress.tag + + "). This error is likely caused by a bug in React. Please file an issue." + ); } - throw Error( - "Unknown unit of work tag (" + - workInProgress.tag + - "). This error is likely caused by a bug in React. Please file an issue." - ); + return null; } function unwindWork(workInProgress) { switch (workInProgress.tag) { case 1: - isContextProvider(workInProgress.type) && popContext(); + isContextProvider(workInProgress.type) && popContext(workInProgress); var effectTag = workInProgress.effectTag; return effectTag & 4096 ? ((workInProgress.effectTag = (effectTag & -4097) | 64), workInProgress) : null; case 3: - popHostContainer(); - pop(didPerformWorkStackCursor); - pop(contextStackCursor); + popHostContainer(workInProgress); + popTopLevelContextObject(workInProgress); effectTag = workInProgress.effectTag; if (0 !== (effectTag & 64)) throw Error( @@ -4897,7 +5080,7 @@ function unwindWork(workInProgress) { return popHostContext(workInProgress), null; case 13: return ( - pop(suspenseStackCursor), + pop(suspenseStackCursor, workInProgress), (effectTag = workInProgress.effectTag), effectTag & 4096 ? ((workInProgress.effectTag = (effectTag & -4097) | 64), @@ -4905,9 +5088,9 @@ function unwindWork(workInProgress) { : null ); case 19: - return pop(suspenseStackCursor), null; + return pop(suspenseStackCursor, workInProgress), null; case 4: - return popHostContainer(), null; + return popHostContainer(workInProgress), null; case 10: return popProvider(workInProgress), null; default: @@ -4964,171 +5147,85 @@ function logError(boundary, errorInfo) { }); } } -function safelyCallComponentWillUnmount(current, instance) { +function safelyCallComponentWillUnmount(current$$1, instance) { try { - (instance.props = current.memoizedProps), - (instance.state = current.memoizedState), + (instance.props = current$$1.memoizedProps), + (instance.state = current$$1.memoizedState), instance.componentWillUnmount(); } catch (unmountError) { - captureCommitPhaseError(current, unmountError); + captureCommitPhaseError(current$$1, unmountError); } } -function safelyDetachRef(current) { - var ref = current.ref; +function safelyDetachRef(current$$1) { + var ref = current$$1.ref; if (null !== ref) if ("function" === typeof ref) try { ref(null); } catch (refError) { - captureCommitPhaseError(current, refError); + captureCommitPhaseError(current$$1, refError); } else ref.current = null; } -function commitBeforeMutationLifeCycles(current, finishedWork) { +function commitBeforeMutationLifeCycles(current$$1, finishedWork) { switch (finishedWork.tag) { case 0: case 11: case 15: - case 22: - return; + commitHookEffectList(2, 0, finishedWork); + break; case 1: - if (finishedWork.effectTag & 256 && null !== current) { - var prevProps = current.memoizedProps, - prevState = current.memoizedState; - current = finishedWork.stateNode; - finishedWork = current.getSnapshotBeforeUpdate( + if (finishedWork.effectTag & 256 && null !== current$$1) { + var prevProps = current$$1.memoizedProps, + prevState = current$$1.memoizedState; + current$$1 = finishedWork.stateNode; + finishedWork = current$$1.getSnapshotBeforeUpdate( finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState ); - current.__reactInternalSnapshotBeforeUpdate = finishedWork; + current$$1.__reactInternalSnapshotBeforeUpdate = finishedWork; } - return; + break; case 3: case 5: case 6: case 4: case 17: - return; + 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." + ); } - 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(tag, finishedWork) { +function commitHookEffectList(unmountTag, mountTag, finishedWork) { finishedWork = finishedWork.updateQueue; finishedWork = null !== finishedWork ? finishedWork.lastEffect : null; if (null !== finishedWork) { var effect = (finishedWork = finishedWork.next); do { - if ((effect.tag & tag) === tag) { + if (0 !== (effect.tag & unmountTag)) { var destroy = effect.destroy; effect.destroy = void 0; void 0 !== destroy && destroy(); } + 0 !== (effect.tag & mountTag) && + ((destroy = effect.create), (effect.destroy = destroy())); effect = effect.next; } while (effect !== finishedWork); } } -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 = effect.create; - effect.destroy = create(); - } - effect = effect.next; - } while (effect !== finishedWork); - } -} -function commitLifeCycles(finishedRoot, current, finishedWork) { - switch (finishedWork.tag) { - case 0: - case 11: - case 15: - case 22: - commitHookEffectListMount(3, finishedWork); - return; - case 1: - finishedRoot = finishedWork.stateNode; - if (finishedWork.effectTag & 4) - if (null === current) finishedRoot.componentDidMount(); - else { - var prevProps = - finishedWork.elementType === finishedWork.type - ? current.memoizedProps - : resolveDefaultProps(finishedWork.type, current.memoizedProps); - finishedRoot.componentDidUpdate( - prevProps, - 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); - } - return; - case 5: - return; - case 6: - return; - case 4: - return; - case 12: - prevProps = finishedWork.memoizedProps.onRender; - var commitTime$jscomp$0 = commitTime; - "function" === typeof prevProps && - prevProps( - finishedWork.memoizedProps.id, - null === current ? "mount" : "update", - finishedWork.actualDuration, - finishedWork.treeBaseDuration, - finishedWork.actualStartTime, - commitTime$jscomp$0, - finishedRoot.memoizedInteractions - ); - return; - case 13: - return; - case 19: - case 17: - case 20: - case 21: - 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 commitUnmount(finishedRoot, current$jscomp$0, renderPriorityLevel) { +function commitUnmount(finishedRoot, current$$1$jscomp$0, renderPriorityLevel) { "function" === typeof onCommitFiberUnmount && - onCommitFiberUnmount(current$jscomp$0); - switch (current$jscomp$0.tag) { + onCommitFiberUnmount(current$$1$jscomp$0); + switch (current$$1$jscomp$0.tag) { case 0: case 11: case 14: case 15: - case 22: - finishedRoot = current$jscomp$0.updateQueue; + finishedRoot = current$$1$jscomp$0.updateQueue; if ( null !== finishedRoot && ((finishedRoot = finishedRoot.lastEffect), null !== finishedRoot) @@ -5139,13 +5236,13 @@ function commitUnmount(finishedRoot, current$jscomp$0, renderPriorityLevel) { function() { var effect = firstEffect; do { - var _destroy = effect.destroy; - if (void 0 !== _destroy) { - var current = current$jscomp$0; + var destroy = effect.destroy; + if (void 0 !== destroy) { + var current$$1 = current$$1$jscomp$0; try { - _destroy(); + destroy(); } catch (error) { - captureCommitPhaseError(current, error); + captureCommitPhaseError(current$$1, error); } } effect = effect.next; @@ -5155,35 +5252,37 @@ function commitUnmount(finishedRoot, current$jscomp$0, renderPriorityLevel) { } break; case 1: - safelyDetachRef(current$jscomp$0); - renderPriorityLevel = current$jscomp$0.stateNode; + safelyDetachRef(current$$1$jscomp$0); + renderPriorityLevel = current$$1$jscomp$0.stateNode; "function" === typeof renderPriorityLevel.componentWillUnmount && - safelyCallComponentWillUnmount(current$jscomp$0, renderPriorityLevel); + safelyCallComponentWillUnmount( + current$$1$jscomp$0, + renderPriorityLevel + ); break; case 5: - safelyDetachRef(current$jscomp$0); + safelyDetachRef(current$$1$jscomp$0); break; case 4: unmountHostComponents( finishedRoot, - current$jscomp$0, + current$$1$jscomp$0, renderPriorityLevel ); } } -function detachFiber(current) { - var alternate = current.alternate; - current.return = null; - current.child = null; - current.memoizedState = null; - current.updateQueue = null; - current.dependencies = null; - current.alternate = null; - current.firstEffect = null; - current.lastEffect = null; - current.pendingProps = null; - current.memoizedProps = null; - current.stateNode = null; +function detachFiber(current$$1) { + var alternate = current$$1.alternate; + current$$1.return = null; + current$$1.child = null; + current$$1.memoizedState = null; + current$$1.updateQueue = null; + current$$1.dependencies = null; + current$$1.alternate = null; + current$$1.firstEffect = null; + current$$1.lastEffect = null; + current$$1.pendingProps = null; + current$$1.memoizedProps = null; null !== alternate && detachFiber(alternate); } function isHostParent(fiber) { @@ -5246,103 +5345,97 @@ function commitPlacement(finishedWork) { break a; } } - isContainer - ? insertOrAppendPlacementNodeIntoContainer( - finishedWork, - parentFiber, - parent - ) - : insertOrAppendPlacementNode(finishedWork, parentFiber, parent); -} -function insertOrAppendPlacementNodeIntoContainer(node, before, parent) { - var tag = node.tag, - isHost = 5 === tag || 6 === tag; - if (isHost) - if (((node = isHost ? node.stateNode : node.stateNode.instance), before)) { - if ("number" === typeof parent) - throw Error("Container does not support insertBefore operation"); - } else - ReactNativePrivateInterface.UIManager.setChildren(parent, [ - "number" === typeof node ? node : node._nativeTag - ]); - else if (4 !== tag && ((node = node.child), null !== node)) - for ( - insertOrAppendPlacementNodeIntoContainer(node, before, parent), - node = node.sibling; - null !== node; - - ) - insertOrAppendPlacementNodeIntoContainer(node, before, parent), - (node = node.sibling); -} -function insertOrAppendPlacementNode(node, before, parent) { - var tag = node.tag, - isHost = 5 === tag || 6 === tag; - if (isHost) - (node = isHost ? node.stateNode : node.stateNode.instance), - before - ? ((tag = parent._children), - (isHost = tag.indexOf(node)), - 0 <= isHost - ? (tag.splice(isHost, 1), - (before = tag.indexOf(before)), - tag.splice(before, 0, node), - ReactNativePrivateInterface.UIManager.manageChildren( - parent._nativeTag, - [isHost], - [before], - [], - [], - [] - )) - : ((before = tag.indexOf(before)), - tag.splice(before, 0, node), - ReactNativePrivateInterface.UIManager.manageChildren( - parent._nativeTag, - [], - [], - ["number" === typeof node ? node : node._nativeTag], - [before], - [] - ))) - : ((before = "number" === typeof node ? node : node._nativeTag), - (tag = parent._children), - (isHost = tag.indexOf(node)), - 0 <= isHost - ? (tag.splice(isHost, 1), - tag.push(node), + for (var node = finishedWork; ; ) { + var isHost = 5 === node.tag || 6 === node.tag; + if (isHost) { + var stateNode = isHost ? node.stateNode : node.stateNode.instance; + if (parentFiber) + if (isContainer) { + if ("number" === typeof parent) + throw Error("Container does not support insertBefore operation"); + } else { + isHost = parent; + var beforeChild = parentFiber, + children = isHost._children, + index = children.indexOf(stateNode); + 0 <= index + ? (children.splice(index, 1), + (beforeChild = children.indexOf(beforeChild)), + children.splice(beforeChild, 0, stateNode), ReactNativePrivateInterface.UIManager.manageChildren( - parent._nativeTag, - [isHost], - [tag.length - 1], + isHost._nativeTag, + [index], + [beforeChild], [], [], [] )) - : (tag.push(node), + : ((index = children.indexOf(beforeChild)), + children.splice(index, 0, stateNode), ReactNativePrivateInterface.UIManager.manageChildren( - parent._nativeTag, + isHost._nativeTag, [], [], - [before], - [tag.length - 1], + [ + "number" === typeof stateNode + ? stateNode + : stateNode._nativeTag + ], + [index], [] - ))); - else if (4 !== tag && ((node = node.child), null !== node)) - for ( - insertOrAppendPlacementNode(node, before, parent), node = node.sibling; - null !== node; - - ) - insertOrAppendPlacementNode(node, before, parent), (node = node.sibling); + )); + } + else + isContainer + ? ReactNativePrivateInterface.UIManager.setChildren(parent, [ + "number" === typeof stateNode ? stateNode : stateNode._nativeTag + ]) + : ((isHost = parent), + (children = + "number" === typeof stateNode ? stateNode : stateNode._nativeTag), + (index = isHost._children), + (beforeChild = index.indexOf(stateNode)), + 0 <= beforeChild + ? (index.splice(beforeChild, 1), + index.push(stateNode), + ReactNativePrivateInterface.UIManager.manageChildren( + isHost._nativeTag, + [beforeChild], + [index.length - 1], + [], + [], + [] + )) + : (index.push(stateNode), + ReactNativePrivateInterface.UIManager.manageChildren( + isHost._nativeTag, + [], + [], + [children], + [index.length - 1], + [] + ))); + } else if (4 !== node.tag && null !== node.child) { + node.child.return = node; + node = node.child; + continue; + } + if (node === finishedWork) break; + for (; null === node.sibling; ) { + if (null === node.return || node.return === finishedWork) return; + node = node.return; + } + node.sibling.return = node.return; + node = node.sibling; + } } function unmountHostComponents( finishedRoot$jscomp$0, - current, + current$$1, renderPriorityLevel$jscomp$0 ) { for ( - var node = current, + var node = current$$1, currentParentIsValid = !1, currentParent, currentParentIsContainer; @@ -5390,7 +5483,7 @@ function unmountHostComponents( (node$jscomp$0.child.return = node$jscomp$0), (node$jscomp$0 = node$jscomp$0.child); else { - if (node$jscomp$0 === root) break a; + if (node$jscomp$0 === root) break; for (; null === node$jscomp$0.sibling; ) { if (null === node$jscomp$0.return || node$jscomp$0.return === root) break a; @@ -5440,9 +5533,9 @@ function unmountHostComponents( node = node.child; continue; } - if (node === current) break; + if (node === current$$1) break; for (; null === node.sibling; ) { - if (null === node.return || node.return === current) return; + if (null === node.return || node.return === current$$1) return; node = node.return; 4 === node.tag && (currentParentIsValid = !1); } @@ -5450,22 +5543,21 @@ function unmountHostComponents( node = node.sibling; } } -function commitWork(current, finishedWork) { +function commitWork(current$$1, finishedWork) { switch (finishedWork.tag) { case 0: case 11: case 14: case 15: - case 22: - commitHookEffectListUnmount(3, finishedWork); - return; + commitHookEffectList(4, 8, finishedWork); + break; case 1: - return; + break; case 5: var instance = finishedWork.stateNode; if (null != instance) { var newProps = finishedWork.memoizedProps; - current = null !== current ? current.memoizedProps : newProps; + current$$1 = null !== current$$1 ? current$$1.memoizedProps : newProps; var updatePayload = finishedWork.updateQueue; finishedWork.updateQueue = null; null !== updatePayload && @@ -5473,7 +5565,7 @@ function commitWork(current, finishedWork) { instanceProps.set(instance._nativeTag, newProps), (newProps = diffProperties( null, - current, + current$$1, newProps, finishedWork.validAttributes )), @@ -5484,7 +5576,7 @@ function commitWork(current, finishedWork) { newProps )); } - return; + break; case 6: if (null === finishedWork.stateNode) throw Error( @@ -5495,11 +5587,11 @@ function commitWork(current, finishedWork) { "RCTRawText", { text: finishedWork.memoizedProps } ); - return; + break; case 3: - return; + break; case 12: - return; + break; case 13: instance = finishedWork; null === finishedWork.memoizedState @@ -5508,9 +5600,9 @@ function commitWork(current, finishedWork) { (instance = finishedWork.child), (globalMostRecentFallbackTime = now())); if (null !== instance) - a: for (current = instance; ; ) { - if (5 === current.tag) - if (((updatePayload = current.stateNode), newProps)) { + a: for (current$$1 = instance; ; ) { + if (5 === current$$1.tag) + if (((updatePayload = current$$1.stateNode), newProps)) { var viewConfig = updatePayload.viewConfig; var updatePayload$jscomp$0 = diffProperties( null, @@ -5524,8 +5616,8 @@ function commitWork(current, finishedWork) { updatePayload$jscomp$0 ); } else { - updatePayload = current.stateNode; - updatePayload$jscomp$0 = current.memoizedProps; + updatePayload = current$$1.stateNode; + updatePayload$jscomp$0 = current$$1.memoizedProps; viewConfig = updatePayload.viewConfig; var prevProps = Object.assign({}, updatePayload$jscomp$0, { style: [updatePayload$jscomp$0.style, { display: "none" }] @@ -5543,41 +5635,47 @@ function commitWork(current, finishedWork) { ); } else { - if (6 === current.tag) throw Error("Not yet implemented."); + if (6 === current$$1.tag) throw Error("Not yet implemented."); if ( - 13 === current.tag && - null !== current.memoizedState && - null === current.memoizedState.dehydrated + 13 === current$$1.tag && + null !== current$$1.memoizedState && + null === current$$1.memoizedState.dehydrated ) { - updatePayload = current.child.sibling; - updatePayload.return = current; - current = updatePayload; + updatePayload = current$$1.child.sibling; + updatePayload.return = current$$1; + current$$1 = updatePayload; continue; - } else if (null !== current.child) { - current.child.return = current; - current = current.child; + } else if (null !== current$$1.child) { + current$$1.child.return = current$$1; + current$$1 = current$$1.child; continue; } } - if (current === instance) break; - for (; null === current.sibling; ) { - if (null === current.return || current.return === instance) break a; - current = current.return; + if (current$$1 === instance) break a; + for (; null === current$$1.sibling; ) { + if (null === current$$1.return || current$$1.return === instance) + break a; + current$$1 = current$$1.return; } - current.sibling.return = current.return; - current = current.sibling; + current$$1.sibling.return = current$$1.return; + current$$1 = current$$1.sibling; } attachSuspenseRetryListeners(finishedWork); - return; + break; case 19: attachSuspenseRetryListeners(finishedWork); - return; + break; case 17: - return; + break; + case 20: + break; + case 21: + 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." + ); } - 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 thenables = finishedWork.updateQueue; @@ -5636,7 +5734,7 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { return expirationTime; } var ceil = Math.ceil, - ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, + ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, NoContext = 0, LegacyUnbatchedContext = 8, @@ -5651,7 +5749,7 @@ var ceil = Math.ceil, executionContext = NoContext, workInProgressRoot = null, workInProgress = null, - renderExpirationTime$1 = 0, + renderExpirationTime = 0, workInProgressRootExitStatus = RootIncomplete, workInProgressRootFatalError = null, workInProgressRootLatestProcessedExpirationTime = 1073741823, @@ -5678,8 +5776,8 @@ function requestCurrentTimeForUpdate() { return (executionContext & (RenderContext | CommitContext)) !== NoContext ? 1073741821 - ((now() / 10) | 0) : 0 !== currentEventTime - ? currentEventTime - : (currentEventTime = 1073741821 - ((now() / 10) | 0)); + ? currentEventTime + : (currentEventTime = 1073741821 - ((now() / 10) | 0)); } function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { fiber = fiber.mode; @@ -5687,7 +5785,7 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { var priorityLevel = getCurrentPriorityLevel(); if (0 === (fiber & 4)) return 99 === priorityLevel ? 1073741823 : 1073741822; if ((executionContext & RenderContext) !== NoContext) - return renderExpirationTime$1; + return renderExpirationTime; if (null !== suspenseConfig) currentTime = 1073741821 - @@ -5719,11 +5817,11 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { throw Error("Expected a valid priority level"); } null !== workInProgressRoot && - currentTime === renderExpirationTime$1 && + currentTime === renderExpirationTime && --currentTime; return currentTime; } -function scheduleWork(fiber, expirationTime) { +function scheduleUpdateOnFiber(fiber, expirationTime) { if (50 < nestedUpdateCount) throw ((nestedUpdateCount = 0), (rootWithNestedUpdates = null), @@ -5780,7 +5878,7 @@ function markUpdateTimeFromFiberToRoot(fiber, expirationTime) { (workInProgressRoot === root && (markUnprocessedUpdateTime(expirationTime), workInProgressRootExitStatus === RootSuspendedWithDelay && - markRootSuspendedAtTime(root, renderExpirationTime$1)), + markRootSuspendedAtTime(root, renderExpirationTime)), markRootUpdatedAtTime(root, expirationTime)); return root; } @@ -5789,10 +5887,9 @@ function getNextRootExpirationTimeToWorkOn(root) { if (0 !== lastExpiredTime) return lastExpiredTime; lastExpiredTime = root.firstPendingTime; if (!isRootSuspendedAtTime(root, lastExpiredTime)) return lastExpiredTime; - var lastPingedTime = root.lastPingedTime; + lastExpiredTime = root.lastPingedTime; root = root.nextKnownPendingLevel; - root = lastPingedTime > root ? lastPingedTime : root; - return 2 >= root && lastExpiredTime !== root ? 0 : root; + return lastExpiredTime > root ? lastExpiredTime : root; } function ensureRootIsScheduled(root) { if (0 !== root.lastExpiredTime) @@ -5841,233 +5938,271 @@ function ensureRootIsScheduled(root) { } function performConcurrentWorkOnRoot(root, didTimeout) { currentEventTime = 0; - if (didTimeout) { - didTimeout = requestCurrentTimeForUpdate(); - var lastExpiredTime = root.lastExpiredTime; - if (0 === lastExpiredTime || lastExpiredTime > didTimeout) - root.lastExpiredTime = didTimeout; - ensureRootIsScheduled(root); - return null; - } - lastExpiredTime = getNextRootExpirationTimeToWorkOn(root); - if (0 === lastExpiredTime) return null; - didTimeout = root.callbackNode; - if ((executionContext & (RenderContext | CommitContext)) !== NoContext) - throw Error("Should not already be working."); - flushPassiveEffects(); - var expirationTime = lastExpiredTime, - prevExecutionContext = executionContext; - executionContext |= RenderContext; - var exitStatus = pushDispatcher(); - if (root !== workInProgressRoot || expirationTime !== renderExpirationTime$1) - prepareFreshStack(root, expirationTime), - startWorkOnPendingInteractions(root, expirationTime); - expirationTime = pushInteractions(root); - do - try { - workLoopConcurrent(); - break; - } catch (thrownValue) { - handleError(root, thrownValue); - } - while (1); - resetContextDependencies(); - tracing.__interactionsRef.current = expirationTime; - ReactCurrentDispatcher$1.current = exitStatus; - executionContext = prevExecutionContext; - null !== workInProgress - ? (exitStatus = RootIncomplete) - : ((workInProgressRoot = null), - (exitStatus = workInProgressRootExitStatus)); - if (exitStatus !== RootIncomplete) { - exitStatus === RootErrored && - ((lastExpiredTime = 2 < lastExpiredTime ? 2 : lastExpiredTime), - (exitStatus = renderRootSync(root, lastExpiredTime))); - if (exitStatus === RootFatalErrored) - throw ((didTimeout = workInProgressRootFatalError), - prepareFreshStack(root, lastExpiredTime), - markRootSuspendedAtTime(root, lastExpiredTime), + if (didTimeout) + return ( + (didTimeout = requestCurrentTimeForUpdate()), + markRootExpiredAtTime(root, didTimeout), ensureRootIsScheduled(root), - didTimeout); - prevExecutionContext = root.finishedWork = root.current.alternate; - root.finishedExpirationTime = lastExpiredTime; - switch (exitStatus) { - case RootIncomplete: - case RootFatalErrored: - throw Error("Root did not complete. This is a bug in React."); - case RootErrored: - commitRoot(root); - break; - case RootSuspended: - markRootSuspendedAtTime(root, lastExpiredTime); - exitStatus = root.lastSuspendedTime; - lastExpiredTime === exitStatus && - (root.nextKnownPendingLevel = getRemainingExpirationTime( - prevExecutionContext - )); - if ( - 1073741823 === workInProgressRootLatestProcessedExpirationTime && - ((prevExecutionContext = - globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now()), - 10 < prevExecutionContext) - ) { - if ( - workInProgressRootHasPendingPing && - ((expirationTime = root.lastPingedTime), - 0 === expirationTime || expirationTime >= lastExpiredTime) - ) { - root.lastPingedTime = lastExpiredTime; - prepareFreshStack(root, lastExpiredTime); - break; - } - expirationTime = getNextRootExpirationTimeToWorkOn(root); - if (0 !== expirationTime && expirationTime !== lastExpiredTime) break; - if (0 !== exitStatus && exitStatus !== lastExpiredTime) { - root.lastPingedTime = exitStatus; - break; - } - root.timeoutHandle = scheduleTimeout( - commitRoot.bind(null, root), - prevExecutionContext - ); - break; - } - commitRoot(root); - break; - case RootSuspendedWithDelay: - markRootSuspendedAtTime(root, lastExpiredTime); - exitStatus = root.lastSuspendedTime; - lastExpiredTime === exitStatus && - (root.nextKnownPendingLevel = getRemainingExpirationTime( - prevExecutionContext - )); - if ( - workInProgressRootHasPendingPing && - ((prevExecutionContext = root.lastPingedTime), - 0 === prevExecutionContext || prevExecutionContext >= lastExpiredTime) - ) { - root.lastPingedTime = lastExpiredTime; - prepareFreshStack(root, lastExpiredTime); - break; - } - prevExecutionContext = getNextRootExpirationTimeToWorkOn(root); - if ( - 0 !== prevExecutionContext && - prevExecutionContext !== lastExpiredTime - ) - break; - if (0 !== exitStatus && exitStatus !== lastExpiredTime) { - root.lastPingedTime = exitStatus; - break; - } - 1073741823 !== workInProgressRootLatestSuspenseTimeout - ? (prevExecutionContext = - 10 * (1073741821 - workInProgressRootLatestSuspenseTimeout) - - now()) - : 1073741823 === workInProgressRootLatestProcessedExpirationTime - ? (prevExecutionContext = 0) - : ((prevExecutionContext = - 10 * - (1073741821 - workInProgressRootLatestProcessedExpirationTime) - - 5e3), - (exitStatus = now()), - (lastExpiredTime = - 10 * (1073741821 - lastExpiredTime) - exitStatus), - (prevExecutionContext = exitStatus - prevExecutionContext), - 0 > prevExecutionContext && (prevExecutionContext = 0), - (prevExecutionContext = - (120 > prevExecutionContext - ? 120 - : 480 > prevExecutionContext - ? 480 - : 1080 > prevExecutionContext - ? 1080 - : 1920 > prevExecutionContext - ? 1920 - : 3e3 > prevExecutionContext - ? 3e3 - : 4320 > prevExecutionContext - ? 4320 - : 1960 * ceil(prevExecutionContext / 1960)) - - prevExecutionContext), - lastExpiredTime < prevExecutionContext && - (prevExecutionContext = lastExpiredTime)); - if (10 < prevExecutionContext) { - root.timeoutHandle = scheduleTimeout( - commitRoot.bind(null, root), - prevExecutionContext - ); + null + ); + var expirationTime = getNextRootExpirationTimeToWorkOn(root); + if (0 !== expirationTime) { + didTimeout = root.callbackNode; + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) + throw Error("Should not already be working."); + flushPassiveEffects(); + if (root !== workInProgressRoot || expirationTime !== renderExpirationTime) + prepareFreshStack(root, expirationTime), + startWorkOnPendingInteractions(root, expirationTime); + if (null !== workInProgress) { + var prevExecutionContext = executionContext; + executionContext |= RenderContext; + var prevDispatcher = pushDispatcher(root), + prevInteractions = pushInteractions(root); + do + try { + workLoopConcurrent(); break; + } catch (thrownValue) { + handleError(root, thrownValue); } - commitRoot(root); - break; - case RootCompleted: - if ( - 1073741823 !== workInProgressRootLatestProcessedExpirationTime && - null !== workInProgressRootCanSuspendUsingConfig + while (1); + resetContextDependencies(); + executionContext = prevExecutionContext; + ReactCurrentDispatcher.current = prevDispatcher; + tracing.__interactionsRef.current = prevInteractions; + if (workInProgressRootExitStatus === RootFatalErrored) + throw ((didTimeout = workInProgressRootFatalError), + prepareFreshStack(root, expirationTime), + markRootSuspendedAtTime(root, expirationTime), + ensureRootIsScheduled(root), + didTimeout); + if (null === workInProgress) + switch ( + ((prevDispatcher = root.finishedWork = root.current.alternate), + (root.finishedExpirationTime = expirationTime), + (prevExecutionContext = workInProgressRootExitStatus), + (workInProgressRoot = null), + prevExecutionContext) ) { - expirationTime = workInProgressRootLatestProcessedExpirationTime; - var suspenseConfig = workInProgressRootCanSuspendUsingConfig; - prevExecutionContext = suspenseConfig.busyMinDurationMs | 0; - 0 >= prevExecutionContext - ? (prevExecutionContext = 0) - : ((exitStatus = suspenseConfig.busyDelayMs | 0), - (expirationTime = - now() - - (10 * (1073741821 - expirationTime) - - (suspenseConfig.timeoutMs | 0 || 5e3))), - (prevExecutionContext = - expirationTime <= exitStatus - ? 0 - : exitStatus + prevExecutionContext - expirationTime)); - if (10 < prevExecutionContext) { - markRootSuspendedAtTime(root, lastExpiredTime); - root.timeoutHandle = scheduleTimeout( - commitRoot.bind(null, root), - prevExecutionContext + case RootIncomplete: + case RootFatalErrored: + throw Error("Root did not complete. This is a bug in React."); + case RootErrored: + markRootExpiredAtTime( + root, + 2 < expirationTime ? 2 : expirationTime ); break; - } + case RootSuspended: + markRootSuspendedAtTime(root, expirationTime); + prevExecutionContext = root.lastSuspendedTime; + expirationTime === prevExecutionContext && + (root.nextKnownPendingLevel = getRemainingExpirationTime( + prevDispatcher + )); + if ( + 1073741823 === workInProgressRootLatestProcessedExpirationTime && + ((prevDispatcher = + globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now()), + 10 < prevDispatcher) + ) { + if ( + workInProgressRootHasPendingPing && + ((prevInteractions = root.lastPingedTime), + 0 === prevInteractions || prevInteractions >= expirationTime) + ) { + root.lastPingedTime = expirationTime; + prepareFreshStack(root, expirationTime); + break; + } + prevInteractions = getNextRootExpirationTimeToWorkOn(root); + if (0 !== prevInteractions && prevInteractions !== expirationTime) + break; + if ( + 0 !== prevExecutionContext && + prevExecutionContext !== expirationTime + ) { + root.lastPingedTime = prevExecutionContext; + break; + } + root.timeoutHandle = scheduleTimeout( + commitRoot.bind(null, root), + prevDispatcher + ); + break; + } + commitRoot(root); + break; + case RootSuspendedWithDelay: + markRootSuspendedAtTime(root, expirationTime); + prevExecutionContext = root.lastSuspendedTime; + expirationTime === prevExecutionContext && + (root.nextKnownPendingLevel = getRemainingExpirationTime( + prevDispatcher + )); + if ( + workInProgressRootHasPendingPing && + ((prevDispatcher = root.lastPingedTime), + 0 === prevDispatcher || prevDispatcher >= expirationTime) + ) { + root.lastPingedTime = expirationTime; + prepareFreshStack(root, expirationTime); + break; + } + prevDispatcher = getNextRootExpirationTimeToWorkOn(root); + if (0 !== prevDispatcher && prevDispatcher !== expirationTime) + break; + if ( + 0 !== prevExecutionContext && + prevExecutionContext !== expirationTime + ) { + root.lastPingedTime = prevExecutionContext; + break; + } + 1073741823 !== workInProgressRootLatestSuspenseTimeout + ? (prevExecutionContext = + 10 * (1073741821 - workInProgressRootLatestSuspenseTimeout) - + now()) + : 1073741823 === workInProgressRootLatestProcessedExpirationTime + ? (prevExecutionContext = 0) + : ((prevExecutionContext = + 10 * + (1073741821 - + workInProgressRootLatestProcessedExpirationTime) - + 5e3), + (prevDispatcher = now()), + (expirationTime = + 10 * (1073741821 - expirationTime) - prevDispatcher), + (prevExecutionContext = + prevDispatcher - prevExecutionContext), + 0 > prevExecutionContext && (prevExecutionContext = 0), + (prevExecutionContext = + (120 > prevExecutionContext + ? 120 + : 480 > prevExecutionContext + ? 480 + : 1080 > prevExecutionContext + ? 1080 + : 1920 > prevExecutionContext + ? 1920 + : 3e3 > prevExecutionContext + ? 3e3 + : 4320 > prevExecutionContext + ? 4320 + : 1960 * ceil(prevExecutionContext / 1960)) - + prevExecutionContext), + expirationTime < prevExecutionContext && + (prevExecutionContext = expirationTime)); + if (10 < prevExecutionContext) { + root.timeoutHandle = scheduleTimeout( + commitRoot.bind(null, root), + prevExecutionContext + ); + break; + } + commitRoot(root); + break; + case RootCompleted: + if ( + 1073741823 !== workInProgressRootLatestProcessedExpirationTime && + null !== workInProgressRootCanSuspendUsingConfig + ) { + prevInteractions = workInProgressRootLatestProcessedExpirationTime; + var suspenseConfig = workInProgressRootCanSuspendUsingConfig; + prevExecutionContext = suspenseConfig.busyMinDurationMs | 0; + 0 >= prevExecutionContext + ? (prevExecutionContext = 0) + : ((prevDispatcher = suspenseConfig.busyDelayMs | 0), + (prevInteractions = + now() - + (10 * (1073741821 - prevInteractions) - + (suspenseConfig.timeoutMs | 0 || 5e3))), + (prevExecutionContext = + prevInteractions <= prevDispatcher + ? 0 + : prevDispatcher + + prevExecutionContext - + prevInteractions)); + if (10 < prevExecutionContext) { + markRootSuspendedAtTime(root, expirationTime); + root.timeoutHandle = scheduleTimeout( + commitRoot.bind(null, root), + prevExecutionContext + ); + break; + } + } + commitRoot(root); + break; + default: + throw Error("Unknown root exit status."); } - commitRoot(root); - break; - default: - throw Error("Unknown root exit status."); + ensureRootIsScheduled(root); + if (root.callbackNode === didTimeout) + return performConcurrentWorkOnRoot.bind(null, root); } } - ensureRootIsScheduled(root); - return root.callbackNode === didTimeout - ? performConcurrentWorkOnRoot.bind(null, root) - : null; + return null; } function performSyncWorkOnRoot(root) { - if ((executionContext & (RenderContext | CommitContext)) !== NoContext) - throw Error("Should not already be working."); - flushPassiveEffects(); var lastExpiredTime = root.lastExpiredTime; - lastExpiredTime = - 0 !== lastExpiredTime - ? root === workInProgressRoot && renderExpirationTime$1 >= lastExpiredTime - ? renderExpirationTime$1 - : lastExpiredTime - : 1073741823; - var exitStatus = renderRootSync(root, lastExpiredTime); - 0 !== root.tag && - exitStatus === RootErrored && - ((lastExpiredTime = 2 < lastExpiredTime ? 2 : lastExpiredTime), - (exitStatus = renderRootSync(root, lastExpiredTime))); - if (exitStatus === RootFatalErrored) - throw ((exitStatus = workInProgressRootFatalError), - prepareFreshStack(root, lastExpiredTime), - markRootSuspendedAtTime(root, lastExpiredTime), - ensureRootIsScheduled(root), - exitStatus); - root.finishedWork = root.current.alternate; - root.finishedExpirationTime = lastExpiredTime; - commitRoot(root); - ensureRootIsScheduled(root); + lastExpiredTime = 0 !== lastExpiredTime ? lastExpiredTime : 1073741823; + if (root.finishedExpirationTime === lastExpiredTime) commitRoot(root); + else { + if ((executionContext & (RenderContext | CommitContext)) !== NoContext) + throw Error("Should not already be working."); + flushPassiveEffects(); + if (root !== workInProgressRoot || lastExpiredTime !== renderExpirationTime) + prepareFreshStack(root, lastExpiredTime), + startWorkOnPendingInteractions(root, lastExpiredTime); + if (null !== workInProgress) { + var prevExecutionContext = executionContext; + executionContext |= RenderContext; + var prevDispatcher = pushDispatcher(root), + prevInteractions = pushInteractions(root); + do + try { + workLoopSync(); + break; + } catch (thrownValue) { + handleError(root, thrownValue); + } + while (1); + resetContextDependencies(); + executionContext = prevExecutionContext; + ReactCurrentDispatcher.current = prevDispatcher; + tracing.__interactionsRef.current = prevInteractions; + if (workInProgressRootExitStatus === RootFatalErrored) + throw ((prevExecutionContext = workInProgressRootFatalError), + prepareFreshStack(root, lastExpiredTime), + markRootSuspendedAtTime(root, lastExpiredTime), + ensureRootIsScheduled(root), + prevExecutionContext); + if (null !== workInProgress) + throw Error( + "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." + ); + root.finishedWork = root.current.alternate; + root.finishedExpirationTime = lastExpiredTime; + workInProgressRoot = null; + commitRoot(root); + ensureRootIsScheduled(root); + } + } return null; } +function flushPendingDiscreteUpdates() { + if (null !== rootsWithPendingDiscreteUpdates) { + var roots = rootsWithPendingDiscreteUpdates; + rootsWithPendingDiscreteUpdates = null; + roots.forEach(function(expirationTime, root) { + markRootExpiredAtTime(root, expirationTime); + ensureRootIsScheduled(root); + }); + flushSyncCallbackQueue(); + } +} function prepareFreshStack(root, expirationTime) { root.finishedWork = null; root.finishedExpirationTime = 0; @@ -6079,27 +6214,26 @@ function prepareFreshStack(root, expirationTime) { var interruptedWork = timeoutHandle; switch (interruptedWork.tag) { case 1: - interruptedWork = interruptedWork.type.childContextTypes; - null !== interruptedWork && - void 0 !== interruptedWork && - popContext(); + var childContextTypes = interruptedWork.type.childContextTypes; + null !== childContextTypes && + void 0 !== childContextTypes && + popContext(interruptedWork); break; case 3: - popHostContainer(); - pop(didPerformWorkStackCursor); - pop(contextStackCursor); + popHostContainer(interruptedWork); + popTopLevelContextObject(interruptedWork); break; case 5: popHostContext(interruptedWork); break; case 4: - popHostContainer(); + popHostContainer(interruptedWork); break; case 13: - pop(suspenseStackCursor); + pop(suspenseStackCursor, interruptedWork); break; case 19: - pop(suspenseStackCursor); + pop(suspenseStackCursor, interruptedWork); break; case 10: popProvider(interruptedWork); @@ -6107,8 +6241,8 @@ function prepareFreshStack(root, expirationTime) { timeoutHandle = timeoutHandle.return; } workInProgressRoot = root; - workInProgress = createWorkInProgress(root.current, null); - renderExpirationTime$1 = expirationTime; + workInProgress = createWorkInProgress(root.current, null, expirationTime); + renderExpirationTime = expirationTime; workInProgressRootExitStatus = RootIncomplete; workInProgressRootFatalError = null; workInProgressRootLatestSuspenseTimeout = workInProgressRootLatestProcessedExpirationTime = 1073741823; @@ -6121,25 +6255,12 @@ function handleError(root$jscomp$0, thrownValue) { do { try { resetContextDependencies(); - ReactCurrentDispatcher.current = ContextOnlyDispatcher; - if (didScheduleRenderPhaseUpdate) - for ( - var hook = currentlyRenderingFiber$1.memoizedState; - null !== hook; - - ) { - var queue = hook.queue; - null !== queue && (queue.pending = null); - hook = hook.next; - } - renderExpirationTime = 0; - workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; - didScheduleRenderPhaseUpdate = !1; + resetHooks(); if (null === workInProgress || null === workInProgress.return) return ( (workInProgressRootExitStatus = RootFatalErrored), (workInProgressRootFatalError = thrownValue), - (workInProgress = null) + null ); workInProgress.mode & 8 && stopProfilerTimerIfRunningAndRecordDelta(workInProgress, !0); @@ -6148,7 +6269,7 @@ function handleError(root$jscomp$0, thrownValue) { returnFiber = workInProgress.return, sourceFiber = workInProgress, value = thrownValue; - thrownValue = renderExpirationTime$1; + thrownValue = renderExpirationTime; sourceFiber.effectTag |= 2048; sourceFiber.firstEffect = sourceFiber.lastEffect = null; if ( @@ -6156,17 +6277,8 @@ function handleError(root$jscomp$0, thrownValue) { "object" === typeof value && "function" === typeof value.then ) { - var thenable = value; - if (0 === (sourceFiber.mode & 2)) { - var currentSource = sourceFiber.alternate; - currentSource - ? ((sourceFiber.updateQueue = currentSource.updateQueue), - (sourceFiber.memoizedState = currentSource.memoizedState), - (sourceFiber.expirationTime = currentSource.expirationTime)) - : ((sourceFiber.updateQueue = null), - (sourceFiber.memoizedState = null)); - } - var hasInvisibleParentBoundary = + var thenable = value, + hasInvisibleParentBoundary = 0 !== (suspenseStackCursor.current & 1), _workInProgress = returnFiber; do { @@ -6181,10 +6293,10 @@ function handleError(root$jscomp$0, thrownValue) { void 0 === props.fallback ? !1 : !0 !== props.unstable_avoidThisFallback - ? !0 - : hasInvisibleParentBoundary - ? !1 - : !0; + ? !0 + : hasInvisibleParentBoundary + ? !1 + : !0; } } if (JSCompiler_temp) { @@ -6291,8 +6403,8 @@ function handleError(root$jscomp$0, thrownValue) { } while (1); } function pushDispatcher() { - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = ContextOnlyDispatcher; return null === prevDispatcher ? ContextOnlyDispatcher : prevDispatcher; } function pushInteractions(root) { @@ -6314,33 +6426,6 @@ function markUnprocessedUpdateTime(expirationTime) { expirationTime > workInProgressRootNextUnprocessedUpdateTime && (workInProgressRootNextUnprocessedUpdateTime = expirationTime); } -function renderRootSync(root, expirationTime) { - var prevExecutionContext = executionContext; - executionContext |= RenderContext; - var prevDispatcher = pushDispatcher(); - if (root !== workInProgressRoot || expirationTime !== renderExpirationTime$1) - prepareFreshStack(root, expirationTime), - startWorkOnPendingInteractions(root, expirationTime); - expirationTime = pushInteractions(root); - do - try { - workLoopSync(); - break; - } catch (thrownValue) { - handleError(root, thrownValue); - } - while (1); - resetContextDependencies(); - tracing.__interactionsRef.current = expirationTime; - executionContext = prevExecutionContext; - ReactCurrentDispatcher$1.current = prevDispatcher; - if (null !== workInProgress) - throw Error( - "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." - ); - workInProgressRoot = null; - return workInProgressRootExitStatus; -} function workLoopSync() { for (; null !== workInProgress; ) workInProgress = performUnitOfWork(workInProgress); @@ -6350,35 +6435,43 @@ function workLoopConcurrent() { workInProgress = performUnitOfWork(workInProgress); } function performUnitOfWork(unitOfWork) { - var current = unitOfWork.alternate; + var current$$1 = unitOfWork.alternate; 0 !== (unitOfWork.mode & 8) ? ((profilerStartTime = now$1()), 0 > unitOfWork.actualStartTime && (unitOfWork.actualStartTime = now$1()), - (current = beginWork$1(current, unitOfWork, renderExpirationTime$1)), + (current$$1 = beginWork$$1(current$$1, unitOfWork, renderExpirationTime)), stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, !0)) - : (current = beginWork$1(current, unitOfWork, renderExpirationTime$1)); + : (current$$1 = beginWork$$1(current$$1, unitOfWork, renderExpirationTime)); unitOfWork.memoizedProps = unitOfWork.pendingProps; - null === current && (current = completeUnitOfWork(unitOfWork)); + null === current$$1 && (current$$1 = completeUnitOfWork(unitOfWork)); ReactCurrentOwner$2.current = null; - return current; + return current$$1; } function completeUnitOfWork(unitOfWork) { workInProgress = unitOfWork; do { - var current = workInProgress.alternate; + var current$$1 = workInProgress.alternate; unitOfWork = workInProgress.return; if (0 === (workInProgress.effectTag & 2048)) { if (0 === (workInProgress.mode & 8)) - current = completeWork(current, workInProgress, renderExpirationTime$1); + current$$1 = completeWork( + current$$1, + workInProgress, + renderExpirationTime + ); else { var fiber = workInProgress; profilerStartTime = now$1(); 0 > fiber.actualStartTime && (fiber.actualStartTime = now$1()); - current = completeWork(current, workInProgress, renderExpirationTime$1); + current$$1 = completeWork( + current$$1, + workInProgress, + renderExpirationTime + ); stopProfilerTimerIfRunningAndRecordDelta(workInProgress, !1); } fiber = workInProgress; - if (1 === renderExpirationTime$1 || 1 !== fiber.childExpirationTime) { + if (1 === renderExpirationTime || 1 !== fiber.childExpirationTime) { var newChildExpirationTime = 0; if (0 !== (fiber.mode & 8)) { for ( @@ -6416,7 +6509,7 @@ function completeUnitOfWork(unitOfWork) { (actualDuration = actualDuration.sibling); fiber.childExpirationTime = newChildExpirationTime; } - if (null !== current) return current; + if (null !== current$$1) return current$$1; null !== unitOfWork && 0 === (unitOfWork.effectTag & 2048) && (null === unitOfWork.firstEffect && @@ -6431,7 +6524,7 @@ function completeUnitOfWork(unitOfWork) { : (unitOfWork.firstEffect = workInProgress), (unitOfWork.lastEffect = workInProgress))); } else { - current = unwindWork(workInProgress); + current$$1 = unwindWork(workInProgress, renderExpirationTime); if (0 !== (workInProgress.mode & 8)) { stopProfilerTimerIfRunningAndRecordDelta(workInProgress, !1); fiber = workInProgress.actualDuration; @@ -6444,13 +6537,14 @@ function completeUnitOfWork(unitOfWork) { (newChildExpirationTime = newChildExpirationTime.sibling); workInProgress.actualDuration = fiber; } - if (null !== current) return (current.effectTag &= 2047), current; + if (null !== current$$1) + return (current$$1.effectTag &= 2047), current$$1; null !== unitOfWork && ((unitOfWork.firstEffect = unitOfWork.lastEffect = null), (unitOfWork.effectTag |= 2048)); } - current = workInProgress.sibling; - if (null !== current) return current; + current$$1 = workInProgress.sibling; + if (null !== current$$1) return current$$1; workInProgress = unitOfWork; } while (null !== workInProgress); workInProgressRootExitStatus === RootIncomplete && @@ -6468,8 +6562,7 @@ function commitRoot(root) { return null; } function commitRootImpl(root$jscomp$0, renderPriorityLevel$jscomp$0) { - do flushPassiveEffects(); - while (null !== rootWithPendingPassiveEffects); + flushPassiveEffects(); if ((executionContext & (RenderContext | CommitContext)) !== NoContext) throw Error("Should not already be working."); var finishedWork = root$jscomp$0.finishedWork, @@ -6498,8 +6591,7 @@ function commitRootImpl(root$jscomp$0, renderPriorityLevel$jscomp$0) { expirationTime <= root$jscomp$0.lastExpiredTime && (root$jscomp$0.lastExpiredTime = 0); root$jscomp$0 === workInProgressRoot && - ((workInProgress = workInProgressRoot = null), - (renderExpirationTime$1 = 0)); + ((workInProgress = workInProgressRoot = null), (renderExpirationTime = 0)); 1 < finishedWork.effectTag ? null !== finishedWork.lastEffect ? ((finishedWork.lastEffect.nextEffect = finishedWork), @@ -6533,9 +6625,9 @@ function commitRootImpl(root$jscomp$0, renderPriorityLevel$jscomp$0) { ) { var effectTag = nextEffect.effectTag; if (effectTag & 128) { - var current = nextEffect.alternate; - if (null !== current) { - var currentRef = current.ref; + var current$$1 = nextEffect.alternate; + if (null !== current$$1) { + var currentRef = current$$1.ref; null !== currentRef && ("function" === typeof currentRef ? currentRef(null) @@ -6563,13 +6655,13 @@ function commitRootImpl(root$jscomp$0, renderPriorityLevel$jscomp$0) { commitWork(nextEffect.alternate, nextEffect); break; case 8: - var current$jscomp$0 = nextEffect; + var current$$1$jscomp$0 = nextEffect; unmountHostComponents( root, - current$jscomp$0, + current$$1$jscomp$0, renderPriorityLevel ); - detachFiber(current$jscomp$0); + detachFiber(current$$1$jscomp$0); } nextEffect = nextEffect.nextEffect; } @@ -6583,25 +6675,113 @@ function commitRootImpl(root$jscomp$0, renderPriorityLevel$jscomp$0) { nextEffect = remainingExpirationTimeBeforeCommit; do try { - for (effectTag = root$jscomp$0; null !== nextEffect; ) { + for ( + effectTag = root$jscomp$0, current$$1 = expirationTime; + null !== nextEffect; + + ) { var effectTag$jscomp$0 = nextEffect.effectTag; - effectTag$jscomp$0 & 36 && - commitLifeCycles(effectTag, nextEffect.alternate, nextEffect); + if (effectTag$jscomp$0 & 36) { + renderPriorityLevel = effectTag; + var current$$1$jscomp$1 = nextEffect.alternate; + currentRef = nextEffect; + root = current$$1; + switch (currentRef.tag) { + case 0: + case 11: + case 15: + commitHookEffectList(16, 32, currentRef); + break; + case 1: + var instance = currentRef.stateNode; + if (currentRef.effectTag & 4) + if (null === current$$1$jscomp$1) + instance.componentDidMount(); + else { + var prevProps = + currentRef.elementType === currentRef.type + ? current$$1$jscomp$1.memoizedProps + : resolveDefaultProps( + currentRef.type, + current$$1$jscomp$1.memoizedProps + ); + instance.componentDidUpdate( + prevProps, + current$$1$jscomp$1.memoizedState, + instance.__reactInternalSnapshotBeforeUpdate + ); + } + var updateQueue = currentRef.updateQueue; + null !== updateQueue && + commitUpdateQueue(currentRef, updateQueue, instance, root); + break; + case 3: + var _updateQueue = currentRef.updateQueue; + if (null !== _updateQueue) { + renderPriorityLevel = null; + if (null !== currentRef.child) + switch (currentRef.child.tag) { + case 5: + renderPriorityLevel = currentRef.child.stateNode; + break; + case 1: + renderPriorityLevel = currentRef.child.stateNode; + } + commitUpdateQueue( + currentRef, + _updateQueue, + renderPriorityLevel, + root + ); + } + break; + case 5: + break; + case 6: + break; + case 4: + break; + case 12: + var onRender = currentRef.memoizedProps.onRender; + "function" === typeof onRender && + onRender( + currentRef.memoizedProps.id, + null === current$$1$jscomp$1 ? "mount" : "update", + currentRef.actualDuration, + currentRef.treeBaseDuration, + currentRef.actualStartTime, + commitTime, + renderPriorityLevel.memoizedInteractions + ); + break; + case 13: + break; + case 19: + case 17: + case 20: + case 21: + 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 (effectTag$jscomp$0 & 128) { - current = void 0; + currentRef = void 0; var ref = nextEffect.ref; if (null !== ref) { - var instance = nextEffect.stateNode; + var instance$jscomp$0 = nextEffect.stateNode; switch (nextEffect.tag) { case 5: - current = instance; + currentRef = instance$jscomp$0; break; default: - current = instance; + currentRef = instance$jscomp$0; } "function" === typeof ref - ? ref(current) - : (ref.current = current); + ? ref(currentRef) + : (ref.current = currentRef); } } nextEffect = nextEffect.nextEffect; @@ -6637,13 +6817,13 @@ function commitRootImpl(root$jscomp$0, renderPriorityLevel$jscomp$0) { for ( remainingExpirationTimeBeforeCommit = spawnedWorkDuringRender, spawnedWorkDuringRender = null, - ref = 0; - ref < remainingExpirationTimeBeforeCommit.length; - ref++ + current$$1$jscomp$1 = 0; + current$$1$jscomp$1 < remainingExpirationTimeBeforeCommit.length; + current$$1$jscomp$1++ ) scheduleInteractions( root$jscomp$0, - remainingExpirationTimeBeforeCommit[ref], + remainingExpirationTimeBeforeCommit[current$$1$jscomp$1], root$jscomp$0.memoizedInteractions ); schedulePendingInteractions(root$jscomp$0, renderPriorityLevel$jscomp$0); @@ -6704,28 +6884,27 @@ function flushPassiveEffectsImpl() { executionContext |= CommitContext; for ( var prevInteractions = pushInteractions(root), - _effect2 = root.current.firstEffect; - null !== _effect2; + effect = root.current.firstEffect; + null !== effect; ) { try { - var finishedWork = _effect2; + var finishedWork = effect; if (0 !== (finishedWork.effectTag & 512)) switch (finishedWork.tag) { case 0: case 11: case 15: - case 22: - commitHookEffectListUnmount(5, finishedWork), - commitHookEffectListMount(5, finishedWork); + commitHookEffectList(128, 0, finishedWork), + commitHookEffectList(0, 64, finishedWork); } } catch (error) { - if (null === _effect2) throw Error("Should be working on an effect."); - captureCommitPhaseError(_effect2, error); + if (null === effect) throw Error("Should be working on an effect."); + captureCommitPhaseError(effect, error); } - finishedWork = _effect2.nextEffect; - _effect2.nextEffect = null; - _effect2 = finishedWork; + finishedWork = effect.nextEffect; + effect.nextEffect = null; + effect = finishedWork; } tracing.__interactionsRef.current = prevInteractions; finishPendingInteractions(root, expirationTime); @@ -6774,17 +6953,19 @@ function captureCommitPhaseError(sourceFiber, error) { function pingSuspendedRoot(root, thenable, suspendedTime) { var pingCache = root.pingCache; null !== pingCache && pingCache.delete(thenable); - workInProgressRoot === root && renderExpirationTime$1 === suspendedTime + workInProgressRoot === root && renderExpirationTime === suspendedTime ? workInProgressRootExitStatus === RootSuspendedWithDelay || (workInProgressRootExitStatus === RootSuspended && 1073741823 === workInProgressRootLatestProcessedExpirationTime && now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) - ? prepareFreshStack(root, renderExpirationTime$1) + ? prepareFreshStack(root, renderExpirationTime) : (workInProgressRootHasPendingPing = !0) : isRootSuspendedAtTime(root, suspendedTime) && ((thenable = root.lastPingedTime), (0 !== thenable && thenable < suspendedTime) || ((root.lastPingedTime = suspendedTime), + root.finishedExpirationTime === suspendedTime && + ((root.finishedExpirationTime = 0), (root.finishedWork = null)), ensureRootIsScheduled(root), schedulePendingInteractions(root, suspendedTime))); } @@ -6800,12 +6981,12 @@ function resolveRetryThenable(boundaryFiber, thenable) { (ensureRootIsScheduled(boundaryFiber), schedulePendingInteractions(boundaryFiber, thenable)); } -var beginWork$1; -beginWork$1 = function(current, workInProgress, renderExpirationTime) { +var beginWork$$1; +beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { var updateExpirationTime = workInProgress.expirationTime; - if (null !== current) + if (null !== current$$1) if ( - current.memoizedProps !== workInProgress.pendingProps || + current$$1.memoizedProps !== workInProgress.pendingProps || didPerformWorkStackCursor.current ) didReceiveUpdate = !0; @@ -6830,17 +7011,11 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { ); break; case 10: - updateExpirationTime = workInProgress.memoizedProps.value; - var context = workInProgress.type._context; - push(valueCursor, context._currentValue); - context._currentValue = updateExpirationTime; + pushProvider(workInProgress, workInProgress.memoizedProps.value); break; case 12: workInProgress.childExpirationTime >= renderExpirationTime && (workInProgress.effectTag |= 4); - updateExpirationTime = workInProgress.stateNode; - updateExpirationTime.effectDuration = 0; - updateExpirationTime.passiveEffectDuration = 0; break; case 13: if (null !== workInProgress.memoizedState) { @@ -6850,40 +7025,52 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { updateExpirationTime >= renderExpirationTime ) return updateSuspenseComponent( - current, + current$$1, workInProgress, renderExpirationTime ); - push(suspenseStackCursor, suspenseStackCursor.current & 1); + push( + suspenseStackCursor, + suspenseStackCursor.current & 1, + workInProgress + ); workInProgress = bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ); return null !== workInProgress ? workInProgress.sibling : null; } - push(suspenseStackCursor, suspenseStackCursor.current & 1); + push( + suspenseStackCursor, + suspenseStackCursor.current & 1, + workInProgress + ); break; case 19: updateExpirationTime = workInProgress.childExpirationTime >= renderExpirationTime; - if (0 !== (current.effectTag & 64)) { + if (0 !== (current$$1.effectTag & 64)) { if (updateExpirationTime) return updateSuspenseListComponent( - current, + current$$1, workInProgress, renderExpirationTime ); workInProgress.effectTag |= 64; } - context = workInProgress.memoizedState; - null !== context && - ((context.rendering = null), (context.tail = null)); - push(suspenseStackCursor, suspenseStackCursor.current); + var renderState = workInProgress.memoizedState; + null !== renderState && + ((renderState.rendering = null), (renderState.tail = null)); + push( + suspenseStackCursor, + suspenseStackCursor.current, + workInProgress + ); if (!updateExpirationTime) return null; } return bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -6895,40 +7082,41 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { switch (workInProgress.tag) { case 2: updateExpirationTime = workInProgress.type; - null !== current && - ((current.alternate = null), + null !== current$$1 && + ((current$$1.alternate = null), (workInProgress.alternate = null), (workInProgress.effectTag |= 2)); - current = workInProgress.pendingProps; - context = getMaskedContext(workInProgress, contextStackCursor.current); + current$$1 = workInProgress.pendingProps; + renderState = getMaskedContext( + workInProgress, + contextStackCursor.current + ); prepareToReadContext(workInProgress, renderExpirationTime); - context = renderWithHooks( + renderState = renderWithHooks( null, workInProgress, updateExpirationTime, - current, - context, + current$$1, + renderState, renderExpirationTime ); workInProgress.effectTag |= 1; if ( - "object" === typeof context && - null !== context && - "function" === typeof context.render && - void 0 === context.$$typeof + "object" === typeof renderState && + null !== renderState && + "function" === typeof renderState.render && + void 0 === renderState.$$typeof ) { workInProgress.tag = 1; - workInProgress.memoizedState = null; - workInProgress.updateQueue = null; + resetHooks(); if (isContextProvider(updateExpirationTime)) { var hasContext = !0; pushContextProvider(workInProgress); } else hasContext = !1; workInProgress.memoizedState = - null !== context.state && void 0 !== context.state - ? context.state + null !== renderState.state && void 0 !== renderState.state + ? renderState.state : null; - initializeUpdateQueue(workInProgress); var getDerivedStateFromProps = updateExpirationTime.getDerivedStateFromProps; "function" === typeof getDerivedStateFromProps && @@ -6936,15 +7124,15 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { workInProgress, updateExpirationTime, getDerivedStateFromProps, - current + current$$1 ); - context.updater = classComponentUpdater; - workInProgress.stateNode = context; - context._reactInternalFiber = workInProgress; + renderState.updater = classComponentUpdater; + workInProgress.stateNode = renderState; + renderState._reactInternalFiber = workInProgress; mountClassInstance( workInProgress, updateExpirationTime, - current, + current$$1, renderExpirationTime ); workInProgress = finishClassComponent( @@ -6960,129 +7148,127 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { reconcileChildren( null, workInProgress, - context, + renderState, renderExpirationTime ), (workInProgress = workInProgress.child); return workInProgress; case 16: - a: { - context = workInProgress.elementType; - null !== current && - ((current.alternate = null), - (workInProgress.alternate = null), - (workInProgress.effectTag |= 2)); - current = workInProgress.pendingProps; - initializeLazyComponentType(context); - if (1 !== context._status) throw context._result; - context = context._result; - workInProgress.type = context; - hasContext = workInProgress.tag = resolveLazyComponentTag(context); - current = resolveDefaultProps(context, current); - switch (hasContext) { - case 0: - workInProgress = updateFunctionComponent( - null, - workInProgress, - context, - current, - renderExpirationTime - ); - break a; - case 1: - workInProgress = updateClassComponent( - null, - workInProgress, - context, - current, - renderExpirationTime - ); - break a; - case 11: - workInProgress = updateForwardRef( - null, - workInProgress, - context, - current, - renderExpirationTime - ); - break a; - case 14: - workInProgress = updateMemoComponent( - null, - workInProgress, - context, - resolveDefaultProps(context.type, current), - updateExpirationTime, - renderExpirationTime - ); - break a; - } - throw Error( - "Element type is invalid. Received a promise that resolves to: " + - context + - ". Lazy element type must resolve to a class or function." - ); + renderState = workInProgress.elementType; + null !== current$$1 && + ((current$$1.alternate = null), + (workInProgress.alternate = null), + (workInProgress.effectTag |= 2)); + current$$1 = workInProgress.pendingProps; + initializeLazyComponentType(renderState); + if (1 !== renderState._status) throw renderState._result; + renderState = renderState._result; + workInProgress.type = renderState; + hasContext = workInProgress.tag = resolveLazyComponentTag(renderState); + current$$1 = resolveDefaultProps(renderState, current$$1); + switch (hasContext) { + case 0: + workInProgress = updateFunctionComponent( + null, + workInProgress, + renderState, + current$$1, + renderExpirationTime + ); + break; + case 1: + workInProgress = updateClassComponent( + null, + workInProgress, + renderState, + current$$1, + renderExpirationTime + ); + break; + case 11: + workInProgress = updateForwardRef( + null, + workInProgress, + renderState, + current$$1, + renderExpirationTime + ); + break; + case 14: + workInProgress = updateMemoComponent( + null, + workInProgress, + renderState, + resolveDefaultProps(renderState.type, current$$1), + updateExpirationTime, + renderExpirationTime + ); + break; + default: + throw Error( + "Element type is invalid. Received a promise that resolves to: " + + renderState + + ". Lazy element type must resolve to a class or function." + ); } return workInProgress; case 0: return ( (updateExpirationTime = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (renderState = workInProgress.pendingProps), + (renderState = workInProgress.elementType === updateExpirationTime - ? context - : resolveDefaultProps(updateExpirationTime, context)), + ? renderState + : resolveDefaultProps(updateExpirationTime, renderState)), updateFunctionComponent( - current, + current$$1, workInProgress, updateExpirationTime, - context, + renderState, renderExpirationTime ) ); case 1: return ( (updateExpirationTime = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (renderState = workInProgress.pendingProps), + (renderState = workInProgress.elementType === updateExpirationTime - ? context - : resolveDefaultProps(updateExpirationTime, context)), + ? renderState + : resolveDefaultProps(updateExpirationTime, renderState)), updateClassComponent( - current, + current$$1, workInProgress, updateExpirationTime, - context, + renderState, renderExpirationTime ) ); case 3: pushHostRootContext(workInProgress); updateExpirationTime = workInProgress.updateQueue; - if (null === current || null === updateExpirationTime) + if (null === updateExpirationTime) 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." ); - updateExpirationTime = workInProgress.pendingProps; - context = workInProgress.memoizedState; - context = null !== context ? context.element : null; - cloneUpdateQueue(current, workInProgress); + renderState = workInProgress.memoizedState; + renderState = null !== renderState ? renderState.element : null; processUpdateQueue( workInProgress, updateExpirationTime, + workInProgress.pendingProps, null, renderExpirationTime ); updateExpirationTime = workInProgress.memoizedState.element; - updateExpirationTime === context + updateExpirationTime === renderState ? (workInProgress = bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime )) : (reconcileChildren( - current, + current$$1, workInProgress, updateExpirationTime, renderExpirationTime @@ -7092,10 +7278,11 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { case 5: return ( pushHostContext(workInProgress), + null === current$$1 && tryToClaimNextHydratableInstance(workInProgress), (updateExpirationTime = workInProgress.pendingProps.children), - markRef(current, workInProgress), + markRef(current$$1, workInProgress), reconcileChildren( - current, + current$$1, workInProgress, updateExpirationTime, renderExpirationTime @@ -7104,10 +7291,13 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { workInProgress ); case 6: - return null; + return ( + null === current$$1 && tryToClaimNextHydratableInstance(workInProgress), + null + ); case 13: return updateSuspenseComponent( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -7118,7 +7308,7 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { workInProgress.stateNode.containerInfo ), (updateExpirationTime = workInProgress.pendingProps), - null === current + null === current$$1 ? (workInProgress.child = reconcileChildFibers( workInProgress, null, @@ -7126,7 +7316,7 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { renderExpirationTime )) : reconcileChildren( - current, + current$$1, workInProgress, updateExpirationTime, renderExpirationTime @@ -7136,23 +7326,23 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { case 11: return ( (updateExpirationTime = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (renderState = workInProgress.pendingProps), + (renderState = workInProgress.elementType === updateExpirationTime - ? context - : resolveDefaultProps(updateExpirationTime, context)), + ? renderState + : resolveDefaultProps(updateExpirationTime, renderState)), updateForwardRef( - current, + current$$1, workInProgress, updateExpirationTime, - context, + renderState, renderExpirationTime ) ); case 7: return ( reconcileChildren( - current, + current$$1, workInProgress, workInProgress.pendingProps, renderExpirationTime @@ -7162,7 +7352,7 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { case 8: return ( reconcileChildren( - current, + current$$1, workInProgress, workInProgress.pendingProps.children, renderExpirationTime @@ -7172,11 +7362,8 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { case 12: return ( (workInProgress.effectTag |= 4), - (updateExpirationTime = workInProgress.stateNode), - (updateExpirationTime.effectDuration = 0), - (updateExpirationTime.passiveEffectDuration = 0), reconcileChildren( - current, + current$$1, workInProgress, workInProgress.pendingProps.children, renderExpirationTime @@ -7186,32 +7373,27 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { case 10: a: { updateExpirationTime = workInProgress.type._context; - context = workInProgress.pendingProps; + renderState = 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 updateExpirationTime._calculateChangedBits - ? updateExpirationTime._calculateChangedBits( - context$jscomp$0, - hasContext - ) - : 1073741823) | 0), - 0 === hasContext) - ) { + hasContext = renderState.value; + pushProvider(workInProgress, hasContext); + if (null !== getDerivedStateFromProps) { + var oldValue = getDerivedStateFromProps.value; + hasContext = is$1(oldValue, hasContext) + ? 0 + : ("function" === typeof updateExpirationTime._calculateChangedBits + ? updateExpirationTime._calculateChangedBits( + oldValue, + hasContext + ) + : 1073741823) | 0; + if (0 === hasContext) { if ( - getDerivedStateFromProps.children === context.children && + getDerivedStateFromProps.children === renderState.children && !didPerformWorkStackCursor.current ) { workInProgress = bailoutOnAlreadyFinishedWork( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -7219,15 +7401,14 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { } } 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; @@ -7237,18 +7418,18 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { dependency.context === updateExpirationTime && 0 !== (dependency.observedBits & hasContext) ) { - 1 === context$jscomp$0.tag && + 1 === oldValue.tag && ((dependency = createUpdate(renderExpirationTime, null)), (dependency.tag = 2), - enqueueUpdate(context$jscomp$0, dependency)); - context$jscomp$0.expirationTime < renderExpirationTime && - (context$jscomp$0.expirationTime = renderExpirationTime); - dependency = context$jscomp$0.alternate; + enqueueUpdate(oldValue, dependency)); + oldValue.expirationTime < renderExpirationTime && + (oldValue.expirationTime = renderExpirationTime); + dependency = oldValue.alternate; null !== dependency && dependency.expirationTime < renderExpirationTime && (dependency.expirationTime = renderExpirationTime); scheduleWorkOnParentPath( - context$jscomp$0.return, + oldValue.return, renderExpirationTime ); list.expirationTime < renderExpirationTime && @@ -7259,16 +7440,16 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { } } 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; ) { @@ -7276,20 +7457,21 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { 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, + current$$1, workInProgress, - context.children, + renderState.children, renderExpirationTime ); workInProgress = workInProgress.child; @@ -7297,15 +7479,18 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { return workInProgress; case 9: return ( - (context = workInProgress.type), + (renderState = workInProgress.type), (hasContext = workInProgress.pendingProps), (updateExpirationTime = hasContext.children), prepareToReadContext(workInProgress, renderExpirationTime), - (context = readContext(context, hasContext.unstable_observedBits)), - (updateExpirationTime = updateExpirationTime(context)), + (renderState = readContext( + renderState, + hasContext.unstable_observedBits + )), + (updateExpirationTime = updateExpirationTime(renderState)), (workInProgress.effectTag |= 1), reconcileChildren( - current, + current$$1, workInProgress, updateExpirationTime, renderExpirationTime @@ -7314,16 +7499,16 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { ); case 14: return ( - (context = workInProgress.type), + (renderState = workInProgress.type), (hasContext = resolveDefaultProps( - context, + renderState, workInProgress.pendingProps )), - (hasContext = resolveDefaultProps(context.type, hasContext)), + (hasContext = resolveDefaultProps(renderState.type, hasContext)), updateMemoComponent( - current, + current$$1, workInProgress, - context, + renderState, hasContext, updateExpirationTime, renderExpirationTime @@ -7331,7 +7516,7 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { ); case 15: return updateSimpleMemoComponent( - current, + current$$1, workInProgress, workInProgress.type, workInProgress.pendingProps, @@ -7341,25 +7526,30 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { case 17: return ( (updateExpirationTime = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (renderState = workInProgress.pendingProps), + (renderState = workInProgress.elementType === updateExpirationTime - ? context - : resolveDefaultProps(updateExpirationTime, context)), - null !== current && - ((current.alternate = null), + ? renderState + : resolveDefaultProps(updateExpirationTime, renderState)), + null !== current$$1 && + ((current$$1.alternate = null), (workInProgress.alternate = null), (workInProgress.effectTag |= 2)), (workInProgress.tag = 1), isContextProvider(updateExpirationTime) - ? ((current = !0), pushContextProvider(workInProgress)) - : (current = !1), + ? ((current$$1 = !0), pushContextProvider(workInProgress)) + : (current$$1 = !1), prepareToReadContext(workInProgress, renderExpirationTime), - constructClassInstance(workInProgress, updateExpirationTime, context), + constructClassInstance( + workInProgress, + updateExpirationTime, + renderState, + renderExpirationTime + ), mountClassInstance( workInProgress, updateExpirationTime, - context, + renderState, renderExpirationTime ), finishClassComponent( @@ -7367,13 +7557,13 @@ beginWork$1 = function(current, workInProgress, renderExpirationTime) { workInProgress, updateExpirationTime, !0, - current, + current$$1, renderExpirationTime ) ); case 19: return updateSuspenseListComponent( - current, + current$$1, workInProgress, renderExpirationTime ); @@ -7514,6 +7704,9 @@ function FiberNode(tag, pendingProps, key, mode) { this.actualStartTime = -1; this.treeBaseDuration = this.selfBaseDuration = 0; } +function createFiber(tag, pendingProps, key, mode) { + return new FiberNode(tag, pendingProps, key, mode); +} function shouldConstruct(Component) { Component = Component.prototype; return !(!Component || !Component.isReactComponent); @@ -7531,7 +7724,7 @@ function resolveLazyComponentTag(Component) { function createWorkInProgress(current, pendingProps) { var workInProgress = current.alternate; null === workInProgress - ? ((workInProgress = new FiberNode( + ? ((workInProgress = createFiber( current.tag, pendingProps, current.key, @@ -7602,16 +7795,15 @@ function createFiberFromTypeAndProps( break; case REACT_PROFILER_TYPE: return ( - (type = new FiberNode(12, pendingProps, key, mode | 8)), + (type = createFiber(12, pendingProps, key, mode | 8)), (type.elementType = REACT_PROFILER_TYPE), (type.type = REACT_PROFILER_TYPE), (type.expirationTime = expirationTime), - (type.stateNode = { effectDuration: 0, passiveEffectDuration: 0 }), type ); case REACT_SUSPENSE_TYPE: return ( - (type = new FiberNode(13, pendingProps, key, mode)), + (type = createFiber(13, pendingProps, key, mode)), (type.type = REACT_SUSPENSE_TYPE), (type.elementType = REACT_SUSPENSE_TYPE), (type.expirationTime = expirationTime), @@ -7619,7 +7811,7 @@ function createFiberFromTypeAndProps( ); case REACT_SUSPENSE_LIST_TYPE: return ( - (type = new FiberNode(19, pendingProps, key, mode)), + (type = createFiber(19, pendingProps, key, mode)), (type.elementType = REACT_SUSPENSE_LIST_TYPE), (type.expirationTime = expirationTime), type @@ -7643,9 +7835,6 @@ function createFiberFromTypeAndProps( fiberTag = 16; owner = null; break a; - case REACT_BLOCK_TYPE: - fiberTag = 22; - break a; } throw Error( "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + @@ -7653,24 +7842,24 @@ function createFiberFromTypeAndProps( "." ); } - key = new FiberNode(fiberTag, pendingProps, key, mode); + key = createFiber(fiberTag, pendingProps, key, mode); key.elementType = type; key.type = owner; key.expirationTime = expirationTime; return key; } function createFiberFromFragment(elements, mode, expirationTime, key) { - elements = new FiberNode(7, elements, key, mode); + elements = createFiber(7, elements, key, mode); elements.expirationTime = expirationTime; return elements; } function createFiberFromText(content, mode, expirationTime) { - content = new FiberNode(6, content, null, mode); + content = createFiber(6, content, null, mode); content.expirationTime = expirationTime; return content; } function createFiberFromPortal(portal, mode, expirationTime) { - mode = new FiberNode( + mode = createFiber( 4, null !== portal.children ? portal.children : [], portal.key, @@ -7732,6 +7921,11 @@ function markRootUpdatedAtTime(root, expirationTime) { expirationTime > root.nextKnownPendingLevel && (root.nextKnownPendingLevel = expirationTime)); } +function markRootExpiredAtTime(root, expirationTime) { + var lastExpiredTime = root.lastExpiredTime; + if (0 === lastExpiredTime || lastExpiredTime > expirationTime) + root.lastExpiredTime = expirationTime; +} function findHostInstance(component) { var fiber = component._reactInternalFiber; if (void 0 === fiber) { @@ -7746,10 +7940,14 @@ function findHostInstance(component) { return null === component ? null : component.stateNode; } function updateContainer(element, container, parentComponent, callback) { - var current = container.current, + var current$$1 = container.current, currentTime = requestCurrentTimeForUpdate(), suspenseConfig = ReactCurrentBatchConfig.suspense; - currentTime = computeExpirationForFiber(currentTime, current, suspenseConfig); + currentTime = computeExpirationForFiber( + currentTime, + current$$1, + suspenseConfig + ); a: if (parentComponent) { parentComponent = parentComponent._reactInternalFiber; b: { @@ -7800,8 +7998,8 @@ function updateContainer(element, container, parentComponent, callback) { container.payload = { element: element }; callback = void 0 === callback ? null : callback; null !== callback && (container.callback = callback); - enqueueUpdate(current, container); - scheduleWork(current, currentTime); + enqueueUpdate(current$$1, container); + scheduleUpdateOnFiber(current$$1, currentTime); return currentTime; } function createPortal(children, containerInfo, implementation) { @@ -7815,6 +8013,11 @@ function createPortal(children, containerInfo, implementation) { implementation: implementation }; } +function _inheritsLoose(subClass, superClass) { + subClass.prototype = Object.create(superClass.prototype); + subClass.prototype.constructor = subClass; + subClass.__proto__ = superClass; +} function findNodeHandle(componentOrHandle) { if (null == componentOrHandle) return null; if ("number" === typeof componentOrHandle) return componentOrHandle; @@ -7825,15 +8028,8 @@ function findNodeHandle(componentOrHandle) { return null == componentOrHandle ? componentOrHandle : componentOrHandle.canonical - ? componentOrHandle.canonical._nativeTag - : componentOrHandle._nativeTag; -} -function unmountComponentAtNode(containerTag) { - var root = roots.get(containerTag); - root && - updateContainer(null, root, null, function() { - roots.delete(containerTag); - }); + ? componentOrHandle.canonical._nativeTag + : componentOrHandle._nativeTag; } batchedUpdatesImpl = function(fn, a) { var prevExecutionContext = executionContext; @@ -7845,119 +8041,301 @@ batchedUpdatesImpl = function(fn, a) { executionContext === NoContext && flushSyncCallbackQueue(); } }; -var roots = new Map(); -(function(devToolsConfig) { - var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance; - return injectInternals({ - bundleType: devToolsConfig.bundleType, - version: devToolsConfig.version, - rendererPackageName: devToolsConfig.rendererPackageName, - rendererConfig: devToolsConfig.rendererConfig, - overrideHookState: null, - overrideProps: null, - setSuspenseHandler: null, - scheduleUpdate: null, - currentDispatcherRef: ReactSharedInternals.ReactCurrentDispatcher, - findHostInstanceByFiber: function(fiber) { - fiber = findCurrentHostFiber(fiber); - return null === fiber ? null : fiber.stateNode; +flushDiscreteUpdatesImpl = function() { + (executionContext & (1 | RenderContext | CommitContext)) === NoContext && + (flushPendingDiscreteUpdates(), flushPassiveEffects()); +}; +var roots = new Map(), + ReactNativeRenderer = { + NativeComponent: (function(findNodeHandle, findHostInstance) { + return (function(_React$Component) { + function ReactNativeComponent() { + return _React$Component.apply(this, arguments) || this; + } + _inheritsLoose(ReactNativeComponent, _React$Component); + var _proto = ReactNativeComponent.prototype; + _proto.blur = function() { + ReactNativePrivateInterface.TextInputState.blurTextInput( + findNodeHandle(this) + ); + }; + _proto.focus = function() { + ReactNativePrivateInterface.TextInputState.focusTextInput( + findNodeHandle(this) + ); + }; + _proto.measure = function(callback) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + null != maybeInstance && + (maybeInstance.canonical + ? nativeFabricUIManager.measure( + maybeInstance.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ) + : ReactNativePrivateInterface.UIManager.measure( + findNodeHandle(this), + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + )); + }; + _proto.measureInWindow = function(callback) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + null != maybeInstance && + (maybeInstance.canonical + ? nativeFabricUIManager.measureInWindow( + maybeInstance.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ) + : ReactNativePrivateInterface.UIManager.measureInWindow( + findNodeHandle(this), + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + )); + }; + _proto.measureLayout = function( + relativeToNativeNode, + onSuccess, + onFail + ) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + if (null != maybeInstance && !maybeInstance.canonical) { + if ("number" === typeof relativeToNativeNode) + var relativeNode = relativeToNativeNode; + else + relativeToNativeNode._nativeTag && + (relativeNode = relativeToNativeNode._nativeTag); + null != relativeNode && + ReactNativePrivateInterface.UIManager.measureLayout( + findNodeHandle(this), + relativeNode, + mountSafeCallback_NOT_REALLY_SAFE(this, onFail), + mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) + ); + } + }; + _proto.setNativeProps = function(nativeProps) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + if (null != maybeInstance && !maybeInstance.canonical) { + var nativeTag = + maybeInstance._nativeTag || maybeInstance.canonical._nativeTag; + maybeInstance = + maybeInstance.viewConfig || maybeInstance.canonical.viewConfig; + nativeProps = diffProperties( + null, + emptyObject, + nativeProps, + maybeInstance.validAttributes + ); + null != nativeProps && + ReactNativePrivateInterface.UIManager.updateView( + nativeTag, + maybeInstance.uiViewClassName, + nativeProps + ); + } + }; + return ReactNativeComponent; + })(React.Component); + })(findNodeHandle, findHostInstance), + findHostInstance_DEPRECATED: function(componentOrHandle) { + if (null == componentOrHandle) return null; + if (componentOrHandle._nativeTag) return componentOrHandle; + if (componentOrHandle.canonical && componentOrHandle.canonical._nativeTag) + return componentOrHandle.canonical; + componentOrHandle = findHostInstance(componentOrHandle); + return null == componentOrHandle + ? componentOrHandle + : componentOrHandle.canonical + ? componentOrHandle.canonical + : componentOrHandle; }, - findFiberByHostInstance: function(instance) { - return findFiberByHostInstance ? findFiberByHostInstance(instance) : null; + findNodeHandle: findNodeHandle, + dispatchCommand: function(handle, command, args) { + null != handle._nativeTag && + ReactNativePrivateInterface.UIManager.dispatchViewManagerCommand( + handle._nativeTag, + command, + args + ); }, - findHostInstancesForRefresh: null, - scheduleRefresh: null, - scheduleRoot: null, - setRefreshHandler: null, - getCurrentFiber: null - }); + render: function(element, containerTag, callback) { + var root = roots.get(containerTag); + if (!root) { + root = new FiberRootNode(containerTag, 0, !1); + var uninitializedFiber = 0; + isDevToolsPresent && (uninitializedFiber |= 8); + uninitializedFiber = createFiber(3, null, null, uninitializedFiber); + root.current = uninitializedFiber; + uninitializedFiber.stateNode = root; + roots.set(containerTag, root); + } + updateContainer(element, root, null, callback); + a: if (((element = root.current), element.child)) + switch (element.child.tag) { + case 5: + element = element.child.stateNode; + break a; + default: + element = element.child.stateNode; + } + else element = null; + return element; + }, + unmountComponentAtNode: function(containerTag) { + var root = roots.get(containerTag); + root && + updateContainer(null, root, null, function() { + roots.delete(containerTag); + }); + }, + unmountComponentAtNodeAndRemoveContainer: function(containerTag) { + ReactNativeRenderer.unmountComponentAtNode(containerTag); + ReactNativePrivateInterface.UIManager.removeRootView(containerTag); + }, + createPortal: function(children, containerTag) { + return createPortal( + children, + containerTag, + null, + 2 < arguments.length && void 0 !== arguments[2] ? arguments[2] : null + ); + }, + unstable_batchedUpdates: batchedUpdates, + __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: { + NativeMethodsMixin: (function(findNodeHandle, findHostInstance) { + return { + measure: function(callback) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + null != maybeInstance && + (maybeInstance.canonical + ? nativeFabricUIManager.measure( + maybeInstance.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ) + : ReactNativePrivateInterface.UIManager.measure( + findNodeHandle(this), + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + )); + }, + measureInWindow: function(callback) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + null != maybeInstance && + (maybeInstance.canonical + ? nativeFabricUIManager.measureInWindow( + maybeInstance.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ) + : ReactNativePrivateInterface.UIManager.measureInWindow( + findNodeHandle(this), + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + )); + }, + measureLayout: function(relativeToNativeNode, onSuccess, onFail) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + if (null != maybeInstance && !maybeInstance.canonical) { + if ("number" === typeof relativeToNativeNode) + var relativeNode = relativeToNativeNode; + else + relativeToNativeNode._nativeTag && + (relativeNode = relativeToNativeNode._nativeTag); + null != relativeNode && + ReactNativePrivateInterface.UIManager.measureLayout( + findNodeHandle(this), + relativeNode, + mountSafeCallback_NOT_REALLY_SAFE(this, onFail), + mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) + ); + } + }, + setNativeProps: function(nativeProps) { + try { + var maybeInstance = findHostInstance(this); + } catch (error) {} + if (null != maybeInstance && !maybeInstance.canonical) { + var nativeTag = + maybeInstance._nativeTag || maybeInstance.canonical._nativeTag; + maybeInstance = + maybeInstance.viewConfig || maybeInstance.canonical.viewConfig; + nativeProps = diffProperties( + null, + emptyObject, + nativeProps, + maybeInstance.validAttributes + ); + null != nativeProps && + ReactNativePrivateInterface.UIManager.updateView( + nativeTag, + maybeInstance.uiViewClassName, + nativeProps + ); + } + }, + focus: function() { + ReactNativePrivateInterface.TextInputState.focusTextInput( + findNodeHandle(this) + ); + }, + blur: function() { + ReactNativePrivateInterface.TextInputState.blurTextInput( + findNodeHandle(this) + ); + } + }; + })(findNodeHandle, findHostInstance), + computeComponentStackForErrorReporting: function(reactTag) { + return (reactTag = getInstanceFromTag(reactTag)) + ? getStackByFiberInDevAndProd(reactTag) + : ""; + } + } + }; +(function(devToolsConfig) { + var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance; + return injectInternals( + Object.assign({}, devToolsConfig, { + overrideHookState: null, + overrideProps: null, + setSuspenseHandler: null, + scheduleUpdate: null, + currentDispatcherRef: ReactSharedInternals.ReactCurrentDispatcher, + findHostInstanceByFiber: function(fiber) { + fiber = findCurrentHostFiber(fiber); + return null === fiber ? null : fiber.stateNode; + }, + findFiberByHostInstance: function(instance) { + return findFiberByHostInstance + ? findFiberByHostInstance(instance) + : null; + }, + findHostInstancesForRefresh: null, + scheduleRefresh: null, + scheduleRoot: null, + setRefreshHandler: null, + getCurrentFiber: null + }) + ); })({ findFiberByHostInstance: getInstanceFromTag, + getInspectorDataForViewTag: function() { + throw Error("getInspectorDataForViewTag() is not available in production"); + }, bundleType: 0, - version: "16.13.0", - rendererPackageName: "react-native-renderer", - rendererConfig: { - getInspectorDataForViewTag: function() { - throw Error( - "getInspectorDataForViewTag() is not available in production" - ); - }, - getInspectorDataForViewAtPoint: function() { - throw Error( - "getInspectorDataForViewAtPoint() is not available in production." - ); - }.bind(null, findNodeHandle) - } + version: "16.11.0", + rendererPackageName: "react-native-renderer" }); -exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = { - computeComponentStackForErrorReporting: function(reactTag) { - return (reactTag = getInstanceFromTag(reactTag)) - ? getStackByFiberInDevAndProd(reactTag) - : ""; - } -}; -exports.createPortal = function(children, containerTag) { - return createPortal( - children, - containerTag, - null, - 2 < arguments.length && void 0 !== arguments[2] ? arguments[2] : null - ); -}; -exports.dispatchCommand = function(handle, command, args) { - null != handle._nativeTag && - (handle._internalInstanceHandle - ? nativeFabricUIManager.dispatchCommand( - handle._internalInstanceHandle.stateNode.node, - command, - args - ) - : ReactNativePrivateInterface.UIManager.dispatchViewManagerCommand( - handle._nativeTag, - command, - args - )); -}; -exports.findHostInstance_DEPRECATED = function(componentOrHandle) { - if (null == componentOrHandle) return null; - if (componentOrHandle._nativeTag) return componentOrHandle; - if (componentOrHandle.canonical && componentOrHandle.canonical._nativeTag) - return componentOrHandle.canonical; - componentOrHandle = findHostInstance(componentOrHandle); - return null == componentOrHandle - ? componentOrHandle - : componentOrHandle.canonical - ? componentOrHandle.canonical - : componentOrHandle; -}; -exports.findNodeHandle = findNodeHandle; -exports.render = function(element, containerTag, callback) { - var root = roots.get(containerTag); - if (!root) { - root = new FiberRootNode(containerTag, 0, !1); - var uninitializedFiber = 0; - isDevToolsPresent && (uninitializedFiber |= 8); - uninitializedFiber = new FiberNode(3, null, null, uninitializedFiber); - root.current = uninitializedFiber; - uninitializedFiber.stateNode = root; - initializeUpdateQueue(uninitializedFiber); - roots.set(containerTag, root); - } - updateContainer(element, root, null, callback); - a: if (((element = root.current), element.child)) - switch (element.child.tag) { - case 5: - element = element.child.stateNode; - break a; - default: - element = element.child.stateNode; - } - else element = null; - return element; -}; -exports.unmountComponentAtNode = unmountComponentAtNode; -exports.unmountComponentAtNodeAndRemoveContainer = function(containerTag) { - unmountComponentAtNode(containerTag); - ReactNativePrivateInterface.UIManager.removeRootView(containerTag); -}; -exports.unstable_batchedUpdates = batchedUpdates; +var ReactNativeRenderer$2 = { default: ReactNativeRenderer }, + ReactNativeRenderer$3 = + (ReactNativeRenderer$2 && ReactNativeRenderer) || ReactNativeRenderer$2; +module.exports = ReactNativeRenderer$3.default || ReactNativeRenderer$3; diff --git a/Libraries/Renderer/shims/NativeMethodsMixin.js b/Libraries/Renderer/shims/NativeMethodsMixin.js new file mode 100644 index 00000000000000..c50f379fde06cc --- /dev/null +++ b/Libraries/Renderer/shims/NativeMethodsMixin.js @@ -0,0 +1,21 @@ +/** + * 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. + * + * @format + * @flow + */ + +'use strict'; + +const { + __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED, +} = require('./ReactNative'); + +import type {NativeMethodsMixinType} from './ReactNativeTypes'; + +const {NativeMethodsMixin} = __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; + +module.exports = ((NativeMethodsMixin: any): $Exact); diff --git a/Libraries/Renderer/shims/ReactFabric.js b/Libraries/Renderer/shims/ReactFabric.js index 536ce9a6f30b65..8f6a708fd20579 100644 --- a/Libraries/Renderer/shims/ReactFabric.js +++ b/Libraries/Renderer/shims/ReactFabric.js @@ -23,10 +23,6 @@ if (__DEV__) { ReactFabric = require('../implementations/ReactFabric-prod'); } -if (global.RN$Bridgeless) { - global.RN$stopSurface = ReactFabric.stopSurface; -} else { - BatchedBridge.registerCallableModule('ReactFabric', ReactFabric); -} +BatchedBridge.registerCallableModule('ReactFabric', ReactFabric); module.exports = (ReactFabric: ReactNativeType); diff --git a/Libraries/Renderer/shims/ReactFeatureFlags.js b/Libraries/Renderer/shims/ReactFeatureFlags.js index 13c548b4bb1e82..9b6ec97a6234c7 100644 --- a/Libraries/Renderer/shims/ReactFeatureFlags.js +++ b/Libraries/Renderer/shims/ReactFeatureFlags.js @@ -12,6 +12,7 @@ const ReactFeatureFlags = { debugRenderPhaseSideEffects: false, + enableNativeTargetAsInstance: false, }; module.exports = ReactFeatureFlags; diff --git a/Libraries/Renderer/shims/ReactNativeTypes.js b/Libraries/Renderer/shims/ReactNativeTypes.js index 10244570b65354..cf20ce938c2760 100644 --- a/Libraries/Renderer/shims/ReactNativeTypes.js +++ b/Libraries/Renderer/shims/ReactNativeTypes.js @@ -8,7 +8,7 @@ * @flow */ -import type {ElementRef, AbstractComponent} from 'react'; +import React, {type ElementRef, type AbstractComponent} from 'react'; export type MeasureOnSuccessCallback = ( x: number, @@ -77,6 +77,31 @@ export type ReactNativeBaseComponentViewConfig< export type ViewConfigGetter = () => ReactNativeBaseComponentViewConfig<>; +/** + * Class only exists for its Flow type. + */ +class ReactNativeComponent extends React.Component { + blur(): void {} + focus(): void {} + measure(callback: MeasureOnSuccessCallback): void {} + measureInWindow(callback: MeasureInWindowOnSuccessCallback): void {} + measureLayout( + relativeToNativeNode: number | ElementRef>, + onSuccess: MeasureLayoutOnSuccessCallback, + onFail?: () => void, + ): void {} + setNativeProps(nativeProps: Object): void {} +} + +// This type is only used for FlowTests. It shouldn't be imported directly +export type _InternalReactNativeComponentClass = Class< + ReactNativeComponent, +>; + +/** + * This type keeps ReactNativeFiberHostComponent and NativeMethodsMixin in sync. + * It can also provide types for ReactNative applications that use NMM or refs. + */ export type NativeMethods = { blur(): void, focus(): void, @@ -91,60 +116,28 @@ export type NativeMethods = { ... }; +export type NativeMethodsMixinType = NativeMethods; export type HostComponent = AbstractComponent>; type SecretInternalsType = { + NativeMethodsMixin: NativeMethodsMixinType, computeComponentStackForErrorReporting(tag: number): string, // TODO (bvaughn) Decide which additional types to expose here? // And how much information to fill in for the above types. ... }; -type InspectorDataProps = $ReadOnly<{ - [propName: string]: string, - ..., -}>; - -type InspectorDataSource = $ReadOnly<{| - fileName?: string, - lineNumber?: number, -|}>; - -type InspectorDataGetter = ( - (componentOrHandle: any) => ?number, -) => $ReadOnly<{| - measure: Function, - props: InspectorDataProps, - source: InspectorDataSource, -|}>; - -export type InspectorData = $ReadOnly<{| - hierarchy: Array<{| - name: ?string, - getInspectorData: InspectorDataGetter, - |}>, - selectedIndex: ?number, - props: InspectorDataProps, - source: ?InspectorDataSource, -|}>; - -export type TouchedViewDataAtPoint = $ReadOnly<{| - pointerY: number, - touchedViewTag?: number, - frame: $ReadOnly<{| - top: number, - left: number, - width: number, - height: number, - |}>, - ...InspectorData, -|}>; +type SecretInternalsFabricType = { + NativeMethodsMixin: NativeMethodsMixinType, + ... +}; /** * Flat ReactNative renderer bundles are too big for Flow to parse efficiently. * Provide minimal Flow typing for the high-level RN API and call it a day. */ export type ReactNativeType = { + NativeComponent: typeof ReactNativeComponent, findHostInstance_DEPRECATED( componentOrHandle: any, ): ?ElementRef>, @@ -164,9 +157,8 @@ export type ReactNativeType = { }; export type ReactFabricType = { - findHostInstance_DEPRECATED( - componentOrHandle: any, - ): ?ElementRef>, + NativeComponent: typeof ReactNativeComponent, + findHostInstance_DEPRECATED(componentOrHandle: any): ?HostComponent, findNodeHandle(componentOrHandle: any): ?number, dispatchCommand(handle: any, command: string, args: Array): void, render( @@ -175,6 +167,7 @@ export type ReactFabricType = { callback: ?Function, ): any, unmountComponentAtNode(containerTag: number): any, + __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: SecretInternalsFabricType, ... }; @@ -211,3 +204,51 @@ export type ReactFaricEvent = { target: number, ... }; + +export type ReactNativeResponderEvent = { + nativeEvent: ReactFaricEvent, + target: null | ReactNativeEventTarget, + type: string, + ... +}; + +export type ReactNativeResponderContext = { + dispatchEvent: ( + eventValue: any, + listener: (any) => void, + eventPriority: EventPriority, + ) => void, + isTargetWithinNode: ( + childTarget: ReactNativeEventTarget, + parentTarget: ReactNativeEventTarget, + ) => boolean, + getTargetBoundingRect( + target: ReactNativeEventTarget, + cb: ({ + left: number, + right: number, + top: number, + bottom: number, + ... + }) => void, + ): void, + addRootEventTypes: (rootEventTypes: Array) => void, + removeRootEventTypes: (rootEventTypes: Array) => void, + getTimeStamp: () => number, + getResponderNode(): ReactNativeEventTarget | null, + ... +}; + +export type PointerType = + | '' + | 'mouse' + | 'keyboard' + | 'pen' + | 'touch' + | 'trackpad'; + +export type EventPriority = 0 | 1 | 2; + +export const DiscreteEvent: EventPriority = 0; +export const UserBlockingEvent: EventPriority = 1; +export const ContinuousEvent: EventPriority = 2; diff --git a/Libraries/Renderer/shims/ReactNativeViewConfigRegistry.js b/Libraries/Renderer/shims/ReactNativeViewConfigRegistry.js index 2c09ddf3caab10..e6e3b13b8e859c 100644 --- a/Libraries/Renderer/shims/ReactNativeViewConfigRegistry.js +++ b/Libraries/Renderer/shims/ReactNativeViewConfigRegistry.js @@ -8,7 +8,7 @@ * @flow strict-local */ -/* eslint-disable react-internal/invariant-args */ +/* eslint-disable react-internal/warning-and-invariant-args */ 'use strict'; diff --git a/Libraries/Renderer/shims/ReactTypes.js b/Libraries/Renderer/shims/ReactTypes.js new file mode 100644 index 00000000000000..e97e5823393490 --- /dev/null +++ b/Libraries/Renderer/shims/ReactTypes.js @@ -0,0 +1,190 @@ +/** + * 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. + * + * @flow + */ + +export type ReactNode = + | React$Element + | ReactPortal + | ReactText + | ReactFragment + | ReactProvider + | ReactConsumer; + +export type ReactEmpty = null | void | boolean; + +export type ReactFragment = ReactEmpty | Iterable; + +export type ReactNodeList = ReactEmpty | React$Node; + +export type ReactText = string | number; + +export type ReactProvider = { + $$typeof: Symbol | number, + type: ReactProviderType, + key: null | string, + ref: null, + props: { + value: T, + children?: ReactNodeList, + ... + }, + ... +}; + +export type ReactProviderType = { + $$typeof: Symbol | number, + _context: ReactContext, + ... +}; + +export type ReactConsumer = { + $$typeof: Symbol | number, + type: ReactContext, + key: null | string, + ref: null, + props: { + children: (value: T) => ReactNodeList, + unstable_observedBits?: number, + ... + }, + ... +}; + +export type ReactContext = { + $$typeof: Symbol | number, + Consumer: ReactContext, + Provider: ReactProviderType, + _calculateChangedBits: ((a: T, b: T) => number) | null, + _currentValue: T, + _currentValue2: T, + _threadCount: number, + // DEV only + _currentRenderer?: Object | null, + _currentRenderer2?: Object | null, + ... +}; + +export type ReactPortal = { + $$typeof: Symbol | number, + key: null | string, + containerInfo: any, + children: ReactNodeList, + // TODO: figure out the API for cross-renderer implementation. + implementation: any, + ... +}; + +export type RefObject = {| + current: any, +|}; + +export type ReactEventResponderInstance = {| + fiber: Object, + props: Object, + responder: ReactEventResponder, + rootEventTypes: null | Set, + state: Object, +|}; + +export type ReactEventResponderListener = {| + props: Object, + responder: ReactEventResponder, +|}; + +export type ReactEventResponder = { + $$typeof: Symbol | number, + displayName: string, + targetEventTypes: null | Array, + targetPortalPropagation: boolean, + rootEventTypes: null | Array, + getInitialState: null | ((props: Object) => Object), + onEvent: + | null + | ((event: E, context: C, props: Object, state: Object) => void), + onRootEvent: + | null + | ((event: E, context: C, props: Object, state: Object) => void), + onMount: null | ((context: C, props: Object, state: Object) => void), + onUnmount: null | ((context: C, props: Object, state: Object) => void), + ... +}; + +export type EventPriority = 0 | 1 | 2; + +export const DiscreteEvent: EventPriority = 0; +export const UserBlockingEvent: EventPriority = 1; +export const ContinuousEvent: EventPriority = 2; + +export type ReactFundamentalComponentInstance = {| + currentFiber: mixed, + instance: mixed, + prevProps: null | Object, + props: Object, + impl: ReactFundamentalImpl, + state: Object, +|}; + +export type ReactFundamentalImpl = { + displayName: string, + reconcileChildren: boolean, + getInitialState?: (props: Object) => Object, + getInstance: (context: C, props: Object, state: Object) => H, + getServerSideString?: (context: C, props: Object) => string, + getServerSideStringClose?: (context: C, props: Object) => string, + onMount: (context: C, instance: mixed, props: Object, state: Object) => void, + shouldUpdate?: ( + context: C, + prevProps: null | Object, + nextProps: Object, + state: Object, + ) => boolean, + onUpdate?: ( + context: C, + instance: mixed, + prevProps: null | Object, + nextProps: Object, + state: Object, + ) => void, + onUnmount?: ( + context: C, + instance: mixed, + props: Object, + state: Object, + ) => void, + onHydrate?: (context: C, props: Object, state: Object) => boolean, + onFocus?: (context: C, props: Object, state: Object) => boolean, + ... +}; + +export type ReactFundamentalComponent = {| + $$typeof: Symbol | number, + impl: ReactFundamentalImpl, +|}; + +export type ReactScope = {| + $$typeof: Symbol | number, +|}; + +export type ReactScopeMethods = {| + getChildren(): null | Array, + getChildrenFromRoot(): null | Array, + getParent(): null | ReactScopeMethods, + getProps(): Object, + queryAllNodes( + (type: string | Object, props: Object, instance: Object) => boolean, + ): null | Array, + queryFirstNode( + (type: string | Object, props: Object, instance: Object) => boolean, + ): null | Object, + containsNode(Object): boolean, +|}; + +export type ReactScopeInstance = {| + fiber: Object, + methods: null | ReactScopeMethods, +|}; diff --git a/Libraries/Settings/RCTSettingsManager.mm b/Libraries/Settings/RCTSettingsManager.mm index bc553e46343f24..2ac7d0d12f66e4 100644 --- a/Libraries/Settings/RCTSettingsManager.mm +++ b/Libraries/Settings/RCTSettingsManager.mm @@ -141,13 +141,10 @@ - (void)userDefaultsDidChange:(NSNotification *)note } } #endif // ]TODO(macOS ISS#2323203) - -- (std::shared_ptr) - getTurboModuleWithJsInvoker:(std::shared_ptr)jsInvoker - nativeInvoker:(std::shared_ptr)nativeInvoker - perfLogger:(id)perfLogger +- (std::shared_ptr)getTurboModuleWithJsInvoker: + (std::shared_ptr)jsInvoker { - return std::make_shared(self, jsInvoker, nativeInvoker, perfLogger); + return std::make_shared(self, jsInvoker); } @end diff --git a/Libraries/Settings/React-RCTSettings.podspec b/Libraries/Settings/React-RCTSettings.podspec index dc8d449d345ca0..f9013df94c94ff 100644 --- a/Libraries/Settings/React-RCTSettings.podspec +++ b/Libraries/Settings/React-RCTSettings.podspec @@ -17,17 +17,17 @@ else end folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32' -folly_version = '2020.01.13.00' +folly_version = '2018.10.22.00' Pod::Spec.new do |s| s.name = "React-RCTSettings" s.version = version s.summary = "A wrapper for NSUserDefaults, a persistent key-value store available only on iOS." - s.homepage = "https://reactnative.dev/" - s.documentation_url = "https://reactnative.dev/docs/settings" + s.homepage = "http://facebook.github.io/react-native/" + s.documentation_url = "https://facebook.github.io/react-native/docs/settings" s.license = package["license"] s.author = "Facebook, Inc. and its affiliates" - s.platforms = { :ios => "10.0", :tvos => "10.0", :osx => "10.13" } # TODO(macOS GH#214) + s.platforms = { :ios => "9.0", :tvos => "9.2", :osx => "10.13" } # TODO(macOS GH#214) s.compiler_flags = folly_compiler_flags + ' -Wno-nullability-completeness' s.source = source s.source_files = "*.{m,mm}" @@ -43,6 +43,5 @@ Pod::Spec.new do |s| s.dependency "FBReactNativeSpec", version s.dependency "RCTTypeSafety", version s.dependency "ReactCommon/turbomodule/core", version - s.dependency "React-jsi", version s.dependency "React-Core/RCTSettingsHeaders", version end diff --git a/Libraries/Share/Share.js b/Libraries/Share/Share.js index aed341e56d04b5..5b61f2919ddb34 100644 --- a/Libraries/Share/Share.js +++ b/Libraries/Share/Share.js @@ -109,11 +109,6 @@ class Share { return new Promise((resolve, reject) => { const tintColor = processColor(options.tintColor); - invariant( - tintColor == null || typeof tintColor === 'number', - 'Unexpected color given for options.tintColor', - ); - invariant( NativeActionSheetManager, 'NativeActionSheetManager is not registered on iOS, but it should be.', @@ -125,7 +120,7 @@ class Share { typeof content.message === 'string' ? content.message : undefined, url: typeof content.url === 'string' ? content.url : undefined, subject: options.subject, - tintColor: typeof tintColor === 'number' ? tintColor : undefined, + tintColor: tintColor != null ? tintColor : undefined, excludedActivityTypes: options.excludedActivityTypes, }, error => reject(error), diff --git a/Libraries/Storage/AsyncStorage.js b/Libraries/Storage/AsyncStorage.js index 67f365a0e03896..5c749a93805d3d 100644 --- a/Libraries/Storage/AsyncStorage.js +++ b/Libraries/Storage/AsyncStorage.js @@ -23,7 +23,7 @@ const RCTAsyncStorage = NativeAsyncStorage; * storage system that is global to the app. It should be used instead of * LocalStorage. * - * See https://reactnative.dev/docs/asyncstorage.html + * See http://facebook.github.io/react-native/docs/asyncstorage.html */ const AsyncStorage = { _getRequests: ([]: Array), @@ -33,7 +33,7 @@ const AsyncStorage = { /** * Fetches an item for a `key` and invokes a callback upon completion. * - * See https://reactnative.dev/docs/asyncstorage.html#getitem + * See http://facebook.github.io/react-native/docs/asyncstorage.html#getitem */ getItem: function( key: string, @@ -58,7 +58,7 @@ const AsyncStorage = { /** * Sets the value for a `key` and invokes a callback upon completion. * - * See https://reactnative.dev/docs/asyncstorage.html#setitem + * See http://facebook.github.io/react-native/docs/asyncstorage.html#setitem */ setItem: function( key: string, @@ -82,7 +82,7 @@ const AsyncStorage = { /** * Removes an item for a `key` and invokes a callback upon completion. * - * See https://reactnative.dev/docs/asyncstorage.html#removeitem + * See http://facebook.github.io/react-native/docs/asyncstorage.html#removeitem */ removeItem: function( key: string, @@ -108,7 +108,7 @@ const AsyncStorage = { * * **NOTE:** This is not supported by all native implementations. * - * See https://reactnative.dev/docs/asyncstorage.html#mergeitem + * See http://facebook.github.io/react-native/docs/asyncstorage.html#mergeitem */ mergeItem: function( key: string, @@ -134,7 +134,7 @@ const AsyncStorage = { * don't want to call this; use `removeItem` or `multiRemove` to clear only * your app's keys. * - * See https://reactnative.dev/docs/asyncstorage.html#clear + * See http://facebook.github.io/react-native/docs/asyncstorage.html#clear */ clear: function(callback?: ?(error: ?Error) => void): Promise { invariant(RCTAsyncStorage, 'RCTAsyncStorage not available'); @@ -153,7 +153,7 @@ const AsyncStorage = { /** * Gets *all* keys known to your app; for all callers, libraries, etc. * - * See https://reactnative.dev/docs/asyncstorage.html#getallkeys + * See http://facebook.github.io/react-native/docs/asyncstorage.html#getallkeys */ getAllKeys: function( callback?: ?(error: ?Error, keys: ?Array) => void, @@ -184,7 +184,7 @@ const AsyncStorage = { /** * Flushes any pending requests using a single batch call to get the data. * - * See https://reactnative.dev/docs/asyncstorage.html#flushgetrequests + * See http://facebook.github.io/react-native/docs/asyncstorage.html#flushgetrequests * */ flushGetRequests: function(): void { const getRequests = this._getRequests; @@ -223,7 +223,7 @@ const AsyncStorage = { * inputs. Your callback will be invoked with an array of corresponding * key-value pairs found. * - * See https://reactnative.dev/docs/asyncstorage.html#multiget + * See http://facebook.github.io/react-native/docs/asyncstorage.html#multiget */ multiGet: function( keys: Array, @@ -265,7 +265,7 @@ const AsyncStorage = { * Use this as a batch operation for storing multiple key-value pairs. When * the operation completes you'll get a single callback with any errors. * - * See https://reactnative.dev/docs/asyncstorage.html#multiset + * See http://facebook.github.io/react-native/docs/asyncstorage.html#multiset */ multiSet: function( keyValuePairs: Array>, @@ -288,7 +288,7 @@ const AsyncStorage = { /** * Call this to batch the deletion of all keys in the `keys` array. * - * See https://reactnative.dev/docs/asyncstorage.html#multiremove + * See http://facebook.github.io/react-native/docs/asyncstorage.html#multiremove */ multiRemove: function( keys: Array, @@ -314,7 +314,7 @@ const AsyncStorage = { * * **NOTE**: This is not supported by all native implementations. * - * See https://reactnative.dev/docs/asyncstorage.html#multimerge + * See http://facebook.github.io/react-native/docs/asyncstorage.html#multimerge */ multiMerge: function( keyValuePairs: Array>, diff --git a/Libraries/StyleSheet/EdgeInsetsPropType.js b/Libraries/StyleSheet/EdgeInsetsPropType.js index 56a51e5481061e..779bca391da9d3 100644 --- a/Libraries/StyleSheet/EdgeInsetsPropType.js +++ b/Libraries/StyleSheet/EdgeInsetsPropType.js @@ -10,6 +10,9 @@ 'use strict'; -import type {Rect} from './Rect'; - -export type EdgeInsetsProp = Rect; +export type EdgeInsetsProp = $ReadOnly<{| + top?: ?number, + left?: ?number, + bottom?: ?number, + right?: ?number, +|}>; diff --git a/Libraries/Image/ImageAnalyticsTagContext.js b/Libraries/StyleSheet/NativeOrDynamicColorType.js similarity index 54% rename from Libraries/Image/ImageAnalyticsTagContext.js rename to Libraries/StyleSheet/NativeOrDynamicColorType.js index ea458bf0c28043..a3a24dc7585f7d 100644 --- a/Libraries/Image/ImageAnalyticsTagContext.js +++ b/Libraries/StyleSheet/NativeOrDynamicColorType.js @@ -4,18 +4,16 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @flow strict * @format + * @flow strict */ 'use strict'; -import * as React from 'react'; - -type ContextType = ?string; - -const Context: React.Context = React.createContext( - null, -); - -export default Context; +export type NativeOrDynamicColorType = { + semantic?: string, + dynamic?: { + light: ?(string | number | NativeOrDynamicColorType), + dark: ?(string | number | NativeOrDynamicColorType), + }, +}; diff --git a/Libraries/StyleSheet/PlatformColorValueTypes.android.js b/Libraries/StyleSheet/PlatformColorValueTypes.android.js deleted file mode 100644 index 1458a9b4396d54..00000000000000 --- a/Libraries/StyleSheet/PlatformColorValueTypes.android.js +++ /dev/null @@ -1,41 +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. - * - * @format - * @flow strict-local - */ - -'use strict'; - -import type {ColorValue} from './StyleSheetTypes'; -import type {ProcessedColorValue} from './processColor'; - -export opaque type NativeColorValue = { - resource_paths?: Array, -}; - -export const PlatformColor = (...names: Array): ColorValue => { - return {resource_paths: names}; -}; - -export const ColorAndroidPrivate = (color: string): ColorValue => { - return {resource_paths: [color]}; -}; - -export const normalizeColorObject = ( - color: NativeColorValue, -): ?ProcessedColorValue => { - if ('resource_paths' in color) { - return color; - } - return null; -}; - -export const processColorObject = ( - color: NativeColorValue, -): ?NativeColorValue => { - return color; -}; diff --git a/Libraries/StyleSheet/PlatformColorValueTypes.ios.js b/Libraries/StyleSheet/PlatformColorValueTypes.ios.js deleted file mode 100644 index d329db9316f2d1..00000000000000 --- a/Libraries/StyleSheet/PlatformColorValueTypes.ios.js +++ /dev/null @@ -1,77 +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. - * - * @format - * @flow strict-local - */ - -'use strict'; - -import type {ColorValue} from './StyleSheetTypes'; -import type {ProcessedColorValue} from './processColor'; - -export opaque type NativeColorValue = { - semantic?: Array, - dynamic?: { - light: ?(ColorValue | ProcessedColorValue), - dark: ?(ColorValue | ProcessedColorValue), - }, -}; - -export const PlatformColor = (...names: Array): ColorValue => { - return {semantic: names}; -}; - -export type DynamicColorIOSTuplePrivate = { - light: ColorValue, - dark: ColorValue, -}; - -export const DynamicColorIOSPrivate = ( - tuple: DynamicColorIOSTuplePrivate, -): ColorValue => { - return {dynamic: {light: tuple.light, dark: tuple.dark}}; -}; - -export const normalizeColorObject = ( - color: NativeColorValue, -): ?ProcessedColorValue => { - if ('semantic' in color) { - // an ios semantic color - return color; - } else if ('dynamic' in color && color.dynamic !== undefined) { - const normalizeColor = require('./normalizeColor'); - - // a dynamic, appearance aware color - const dynamic = color.dynamic; - const dynamicColor: NativeColorValue = { - dynamic: { - light: normalizeColor(dynamic.light), - dark: normalizeColor(dynamic.dark), - }, - }; - return dynamicColor; - } - - return null; -}; - -export const processColorObject = ( - color: NativeColorValue, -): ?NativeColorValue => { - if ('dynamic' in color && color.dynamic != null) { - const processColor = require('./processColor'); - const dynamic = color.dynamic; - const dynamicColor: NativeColorValue = { - dynamic: { - light: processColor(dynamic.light), - dark: processColor(dynamic.dark), - }, - }; - return dynamicColor; - } - return color; -}; diff --git a/Libraries/StyleSheet/PlatformColorValueTypes.macos.js b/Libraries/StyleSheet/PlatformColorValueTypes.macos.js deleted file mode 100644 index 29c62f7c93c33f..00000000000000 --- a/Libraries/StyleSheet/PlatformColorValueTypes.macos.js +++ /dev/null @@ -1,78 +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. - * - * @format - * @flow strict-local - */ -// [TODO(macOS ISS#2323203) -'use strict'; - -import type {ColorValue} from './StyleSheetTypes'; -import type {ProcessedColorValue} from './processColor'; - -export opaque type NativeColorValue = { - semantic?: Array, - dynamic?: { - light: ?(ColorValue | ProcessedColorValue), - dark: ?(ColorValue | ProcessedColorValue), - }, -}; - -export const PlatformColor = (...names: Array): ColorValue => { - return {semantic: names}; -}; - -export type DynamicColorIOSTuplePrivate = { - light: ColorValue, - dark: ColorValue, -}; - -export const DynamicColorIOSPrivate = ( - tuple: DynamicColorIOSTuplePrivate, -): ColorValue => { - return {dynamic: {light: tuple.light, dark: tuple.dark}}; -}; - -export const normalizeColorObject = ( - color: NativeColorValue, -): ?ProcessedColorValue => { - if ('semantic' in color) { - // an ios semantic color - return color; - } else if ('dynamic' in color && color.dynamic !== undefined) { - const normalizeColor = require('./normalizeColor'); - - // a dynamic, appearance aware color - const dynamic = color.dynamic; - const dynamicColor: NativeColorValue = { - dynamic: { - light: normalizeColor(dynamic.light), - dark: normalizeColor(dynamic.dark), - }, - }; - return dynamicColor; - } - - return null; -}; - -export const processColorObject = ( - color: NativeColorValue, -): ?NativeColorValue => { - if ('dynamic' in color && color.dynamic != null) { - const processColor = require('./processColor'); - const dynamic = color.dynamic; - const dynamicColor: NativeColorValue = { - dynamic: { - light: processColor(dynamic.light), - dark: processColor(dynamic.dark), - }, - }; - return dynamicColor; - } - return color; -}; -// ]TODO(macOS ISS#2323203) diff --git a/Libraries/StyleSheet/PlatformColorValueTypesAndroid.android.js b/Libraries/StyleSheet/PlatformColorValueTypesAndroid.android.js deleted file mode 100644 index 58f551098fb5db..00000000000000 --- a/Libraries/StyleSheet/PlatformColorValueTypesAndroid.android.js +++ /dev/null @@ -1,18 +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. - * - * @format - * @flow strict-local - */ - -'use strict'; - -import type {ColorValue} from './StyleSheetTypes'; -import {ColorAndroidPrivate} from './PlatformColorValueTypes'; - -export const ColorAndroid = (color: string): ColorValue => { - return ColorAndroidPrivate(color); -}; diff --git a/Libraries/StyleSheet/PlatformColorValueTypesAndroid.js b/Libraries/StyleSheet/PlatformColorValueTypesAndroid.js deleted file mode 100644 index 647000b3b1e9d0..00000000000000 --- a/Libraries/StyleSheet/PlatformColorValueTypesAndroid.js +++ /dev/null @@ -1,17 +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. - * - * @format - * @flow strict-local - */ - -'use strict'; - -import type {ColorValue} from './StyleSheetTypes'; - -export const ColorAndroid = (color: string): ColorValue => { - throw new Error('ColorAndroid is not available on this platform.'); -}; diff --git a/Libraries/StyleSheet/PlatformColorValueTypesIOS.ios.js b/Libraries/StyleSheet/PlatformColorValueTypesIOS.ios.js deleted file mode 100644 index 2b21c61f3df19e..00000000000000 --- a/Libraries/StyleSheet/PlatformColorValueTypesIOS.ios.js +++ /dev/null @@ -1,23 +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. - * - * @format - * @flow strict-local - */ - -'use strict'; - -import type {ColorValue} from './StyleSheetTypes'; -import {DynamicColorIOSPrivate} from './PlatformColorValueTypes'; - -export type DynamicColorIOSTuple = { - light: ColorValue, - dark: ColorValue, -}; - -export const DynamicColorIOS = (tuple: DynamicColorIOSTuple): ColorValue => { - return DynamicColorIOSPrivate({light: tuple.light, dark: tuple.dark}); -}; diff --git a/Libraries/StyleSheet/PlatformColorValueTypesIOS.js b/Libraries/StyleSheet/PlatformColorValueTypesIOS.js deleted file mode 100644 index cc9aa69e80f96b..00000000000000 --- a/Libraries/StyleSheet/PlatformColorValueTypesIOS.js +++ /dev/null @@ -1,22 +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. - * - * @format - * @flow strict-local - */ - -'use strict'; - -import type {ColorValue} from './StyleSheetTypes'; - -export type DynamicColorIOSTuple = { - light: ColorValue, - dark: ColorValue, -}; - -export const DynamicColorIOS = (tuple: DynamicColorIOSTuple): ColorValue => { - throw new Error('DynamicColorIOS is not available on this platform.'); -}; diff --git a/Libraries/StyleSheet/PlatformColorValueTypesIOS.macos.js b/Libraries/StyleSheet/PlatformColorValueTypesIOS.macos.js deleted file mode 100644 index 12fee85a5070d8..00000000000000 --- a/Libraries/StyleSheet/PlatformColorValueTypesIOS.macos.js +++ /dev/null @@ -1,24 +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. - * - * @format - * @flow strict-local - */ -// [TODO(macOS ISS#2323203) -'use strict'; - -import type {ColorValue} from './StyleSheetTypes'; -import {DynamicColorIOSPrivate} from './PlatformColorValueTypes'; - -export type DynamicColorIOSTuple = { - light: ColorValue, - dark: ColorValue, -}; - -export const DynamicColorIOS = (tuple: DynamicColorIOSTuple): ColorValue => { - return DynamicColorIOSPrivate({light: tuple.light, dark: tuple.dark}); -}; -// ]TODO(macOS ISS#2323203) diff --git a/Libraries/StyleSheet/Rect.js b/Libraries/StyleSheet/Rect.js deleted file mode 100644 index 164909c74d28b2..00000000000000 --- a/Libraries/StyleSheet/Rect.js +++ /dev/null @@ -1,28 +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. - * - * @format - * @flow strict - */ - -'use strict'; - -export type Rect = $ReadOnly<{| - bottom?: ?number, - left?: ?number, - right?: ?number, - top?: ?number, -|}>; - -export type RectOrSize = Rect | number; - -export function createSquare(size: number): Rect { - return {bottom: size, left: size, right: size, top: size}; -} - -export function normalizeRect(rectOrSize: ?RectOrSize): ?Rect { - return typeof rectOrSize === 'number' ? createSquare(rectOrSize) : rectOrSize; -} diff --git a/Libraries/StyleSheet/StyleSheet.js b/Libraries/StyleSheet/StyleSheet.js index 54094d8bd4929e..1a1fea49e4fd3e 100644 --- a/Libraries/StyleSheet/StyleSheet.js +++ b/Libraries/StyleSheet/StyleSheet.js @@ -347,7 +347,7 @@ module.exports = { /** * Creates a StyleSheet style reference from the given object. */ - create<+S: ____Styles_Internal>(obj: S): $ReadOnly { + create<+S: ____Styles_Internal>(obj: S): $ObjMap any> { // TODO: This should return S as the return type. But first, // we need to codemod all the callsites that are typing this // return value as a number (even though it was opaque). diff --git a/Libraries/StyleSheet/StyleSheetTypes.js b/Libraries/StyleSheet/StyleSheetTypes.js index 39ee7da194c656..d39b6541587c4f 100644 --- a/Libraries/StyleSheet/StyleSheetTypes.js +++ b/Libraries/StyleSheet/StyleSheetTypes.js @@ -11,10 +11,9 @@ 'use strict'; const AnimatedNode = require('../Animated/src/nodes/AnimatedNode'); +import type {NativeOrDynamicColorType} from '../StyleSheet/NativeOrDynamicColorType'; // TODO(macOS ISS#2323203) -import type {NativeColorValue} from './PlatformColorValueTypes'; - -export type ColorValue = null | string | NativeColorValue; +export type ColorValue = null | string | NativeOrDynamicColorType; // TODO(macOS ISS#2323203) export type ColorArrayValue = null | $ReadOnlyArray; export type PointValue = {| @@ -467,7 +466,7 @@ type ____LayoutStyle_Internal = $ReadOnly<{| /** `direction` specifies the directional flow of the user interface. * The default is `inherit`, except for root node which will have * value based on the current locale. - * See https://yogalayout.com/docs/layout-direction + * See https://facebook.github.io/yoga/docs/rtl/ * for more details. * @platform ios */ diff --git a/Libraries/StyleSheet/StyleSheetValidation.js b/Libraries/StyleSheet/StyleSheetValidation.js index 456953f7a064f8..6871751eb0dad0 100644 --- a/Libraries/StyleSheet/StyleSheetValidation.js +++ b/Libraries/StyleSheet/StyleSheetValidation.js @@ -51,11 +51,7 @@ class StyleSheetValidation { if (!__DEV__ || global.__RCTProfileIsProfiling) { return; } - if (!styles[name]) { - return; - } - const styleProps = Object.keys(styles[name]); - for (const prop of styleProps) { + for (const prop in styles[name]) { StyleSheetValidation.validateStyleProp( prop, styles[name], diff --git a/Libraries/StyleSheet/__flowtests__/StyleSheet-flowtest.js b/Libraries/StyleSheet/__flowtests__/StyleSheet-flowtest.js index c93c8de63cd9d8..561cb144978b96 100644 --- a/Libraries/StyleSheet/__flowtests__/StyleSheet-flowtest.js +++ b/Libraries/StyleSheet/__flowtests__/StyleSheet-flowtest.js @@ -66,7 +66,6 @@ module.exports = { textStyle, ): ImageStyleProp); - // $FlowExpectedError - Incompatible type. (StyleSheet.compose( // $FlowExpectedError - Incompatible type. [textStyle], diff --git a/Libraries/StyleSheet/__tests__/normalizeColor-test.js b/Libraries/StyleSheet/__tests__/normalizeColor-test.js index 12eac4cfbf8d6d..35e8cfd03e8b1c 100644 --- a/Libraries/StyleSheet/__tests__/normalizeColor-test.js +++ b/Libraries/StyleSheet/__tests__/normalizeColor-test.js @@ -10,7 +10,6 @@ 'use strict'; -const {OS} = require('../../Utilities/Platform'); const normalizeColor = require('../normalizeColor'); describe('normalizeColor', function() { @@ -129,56 +128,4 @@ describe('normalizeColor', function() { const normalizedColor = normalizeColor('red') || 0; expect(normalizeColor(normalizedColor)).toBe(normalizedColor); }); - - describe('iOS', () => { - if (OS === 'ios') { - const PlatformColor = require('../PlatformColorValueTypes.ios') - .PlatformColor; - const DynamicColorIOS = require('../PlatformColorValueTypesIOS.ios') - .DynamicColorIOS; - - it('should normalize iOS PlatformColor colors', () => { - const color = PlatformColor('systemRedColor'); - const normalizedColor = normalizeColor(color); - const expectedColor = {semantic: ['systemRedColor']}; - expect(normalizedColor).toEqual(expectedColor); - }); - - it('should normalize iOS Dynamic colors with named colors', () => { - const color = DynamicColorIOS({light: 'black', dark: 'white'}); - const normalizedColor = normalizeColor(color); - const expectedColor = {dynamic: {light: 'black', dark: 'white'}}; - expect(normalizedColor).toEqual(expectedColor); - }); - - it('should normalize iOS Dynamic colors with PlatformColor colors', () => { - const color = DynamicColorIOS({ - light: PlatformColor('systemBlackColor'), - dark: PlatformColor('systemWhiteColor'), - }); - const normalizedColor = normalizeColor(color); - const expectedColor = { - dynamic: { - light: {semantic: ['systemBlackColor']}, - dark: {semantic: ['systemWhiteColor']}, - }, - }; - expect(normalizedColor).toEqual(expectedColor); - }); - } - }); - - describe('Android', () => { - if (OS === 'android') { - const PlatformColor = require('../PlatformColorValueTypes.android') - .PlatformColor; - - it('should normalize Android PlatformColor colors', () => { - const color = PlatformColor('?attr/colorPrimary'); - const normalizedColor = normalizeColor(color); - const expectedColor = {resource_paths: ['?attr/colorPrimary']}; - expect(normalizedColor).toEqual(expectedColor); - }); - } - }); }); diff --git a/Libraries/StyleSheet/__tests__/processColor-test.js b/Libraries/StyleSheet/__tests__/processColor-test.js index d428b854e8f50e..0b60130e26ebf3 100644 --- a/Libraries/StyleSheet/__tests__/processColor-test.js +++ b/Libraries/StyleSheet/__tests__/processColor-test.js @@ -13,13 +13,6 @@ const {OS} = require('../../Utilities/Platform'); const processColor = require('../processColor'); -const PlatformColorIOS = require('../PlatformColorValueTypes.ios') - .PlatformColor; -const DynamicColorIOS = require('../PlatformColorValueTypesIOS.ios') - .DynamicColorIOS; -const PlatformColorAndroid = require('../PlatformColorValueTypes.android') - .PlatformColor; - const platformSpecific = OS === 'android' ? unsigned => unsigned | 0 //eslint-disable-line no-bitwise @@ -91,33 +84,4 @@ describe('processColor', () => { expect(colorFromString).toEqual(platformSpecific(expectedInt)); }); }); - - describe('iOS', () => { - if (OS === 'ios') { - it('should process iOS PlatformColor colors', () => { - const color = PlatformColorIOS('systemRedColor'); - const processedColor = processColor(color); - const expectedColor = {semantic: ['systemRedColor']}; - expect(processedColor).toEqual(expectedColor); - }); - - it('should process iOS Dynamic colors', () => { - const color = DynamicColorIOS({light: 'black', dark: 'white'}); - const processedColor = processColor(color); - const expectedColor = {dynamic: {light: 0xff000000, dark: 0xffffffff}}; - expect(processedColor).toEqual(expectedColor); - }); - } - }); - - describe('Android', () => { - if (OS === 'android') { - it('should process Android PlatformColor colors', () => { - const color = PlatformColorAndroid('?attr/colorPrimary'); - const processedColor = processColor(color); - const expectedColor = {resource_paths: ['?attr/colorPrimary']}; - expect(processedColor).toEqual(expectedColor); - }); - } - }); }); diff --git a/Libraries/StyleSheet/__tests__/processColorArray-test.js b/Libraries/StyleSheet/__tests__/processColorArray-test.js index 1be389cdb92421..acd45cdd72a761 100644 --- a/Libraries/StyleSheet/__tests__/processColorArray-test.js +++ b/Libraries/StyleSheet/__tests__/processColorArray-test.js @@ -13,13 +13,6 @@ const {OS} = require('../../Utilities/Platform'); const processColorArray = require('../processColorArray'); -const PlatformColorIOS = require('../PlatformColorValueTypes.ios') - .PlatformColor; -const DynamicColorIOS = require('../PlatformColorValueTypesIOS.ios') - .DynamicColorIOS; -const PlatformColorAndroid = require('../PlatformColorValueTypes.android') - .PlatformColor; - const platformSpecific = OS === 'android' ? unsigned => unsigned | 0 //eslint-disable-line no-bitwise @@ -64,48 +57,4 @@ describe('processColorArray', () => { expect(colorFromNoArray).toEqual(null); }); }); - - describe('iOS', () => { - if (OS === 'ios') { - it('should convert array of iOS PlatformColor colors', () => { - const colorFromArray = processColorArray([ - PlatformColorIOS('systemColorWhite'), - PlatformColorIOS('systemColorBlack'), - ]); - const expectedColorValueArray = [ - {semantic: ['systemColorWhite']}, - {semantic: ['systemColorBlack']}, - ]; - expect(colorFromArray).toEqual(expectedColorValueArray); - }); - - it('should process iOS Dynamic colors', () => { - const colorFromArray = processColorArray([ - DynamicColorIOS({light: 'black', dark: 'white'}), - DynamicColorIOS({light: 'white', dark: 'black'}), - ]); - const expectedColorValueArray = [ - {dynamic: {light: 0xff000000, dark: 0xffffffff}}, - {dynamic: {light: 0xffffffff, dark: 0xff000000}}, - ]; - expect(colorFromArray).toEqual(expectedColorValueArray); - }); - } - }); - - describe('Android', () => { - if (OS === 'android') { - it('should convert array of Android PlatformColor colors', () => { - const colorFromArray = processColorArray([ - PlatformColorAndroid('?attr/colorPrimary'), - PlatformColorAndroid('?colorPrimaryDark'), - ]); - const expectedColorValueArray = [ - {resource_paths: ['?attr/colorPrimary']}, - {resource_paths: ['?colorPrimaryDark']}, - ]; - expect(colorFromArray).toEqual(expectedColorValueArray); - }); - } - }); }); diff --git a/Libraries/StyleSheet/normalizeColor.js b/Libraries/StyleSheet/normalizeColor.js index eaee5813b177e1..667222329d1584 100755 --- a/Libraries/StyleSheet/normalizeColor.js +++ b/Libraries/StyleSheet/normalizeColor.js @@ -12,12 +12,15 @@ 'use strict'; -import type {ColorValue} from './StyleSheetTypes'; -import type {ProcessedColorValue} from './processColor'; +import type {NativeOrDynamicColorType} from './NativeOrDynamicColorType'; // TODO(macOS ISS#2323203) function normalizeColor( - color: ?(ColorValue | ProcessedColorValue), -): ?ProcessedColorValue { + color: ?( + | string + | number + | NativeOrDynamicColorType + ) /* TODO(macOS ISS#2323203) */, +): ?(number | NativeOrDynamicColorType) /* TODO(macOS ISS#2323203) */ { const matchers = getMatchers(); let match; @@ -28,20 +31,20 @@ function normalizeColor( return null; } - if (typeof color === 'object' && color != null) { - const normalizeColorObject = require('./PlatformColorValueTypes') - .normalizeColorObject; + // [TODO(macOS ISS#2323203) + if (typeof color === 'object' && color !== null) { + const normalizeColorObject = require('./normalizeColorObject'); // TODO(macOS ISS#2323203) const normalizedColorObj = normalizeColorObject(color); - if (normalizedColorObj != null) { + if (normalizedColorObj !== null) { return color; } } if (typeof color !== 'string') { return null; - } + } // ]TODO(macOS ISS#2323203) // Ordered based on occurrences on Facebook codebase if ((match = matchers.hex6.exec(color))) { diff --git a/Libraries/StyleSheet/normalizeColorObject.android.js b/Libraries/StyleSheet/normalizeColorObject.android.js new file mode 100644 index 00000000000000..bbd5acc0384444 --- /dev/null +++ b/Libraries/StyleSheet/normalizeColorObject.android.js @@ -0,0 +1,22 @@ +/** + * 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. + * + * @format + * @flow + */ +// [TODO(macOS ISS#2323203) +'use strict'; + +import type {NativeOrDynamicColorType} from './NativeOrDynamicColorType'; + +function normalizeColorObject( + color: NativeOrDynamicColorType, +): ?(number | NativeOrDynamicColorType) { + return null; +} + +module.exports = normalizeColorObject; +// ]TODO(macOS ISS#2323203) diff --git a/Libraries/StyleSheet/normalizeColorObject.ios.js b/Libraries/StyleSheet/normalizeColorObject.ios.js new file mode 100644 index 00000000000000..d3f77888dd4d87 --- /dev/null +++ b/Libraries/StyleSheet/normalizeColorObject.ios.js @@ -0,0 +1,39 @@ +/** + * 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. + * + * @format + * @flow + */ +// [TODO(macOS ISS#2323203) +'use strict'; + +import type {NativeOrDynamicColorType} from './NativeOrDynamicColorType'; + +function normalizeColorObject( + color: NativeOrDynamicColorType, +): ?(number | NativeOrDynamicColorType) { + if ('semantic' in color) { + // a macos semantic color + return color; + } else if ('dynamic' in color && color.dynamic !== undefined) { + const normalizeColor = require('./normalizeColor'); + + // a dynamic, appearance aware color + const dynamic = color.dynamic; + const dynamicColor: NativeOrDynamicColorType = { + dynamic: { + light: normalizeColor(dynamic.light), + dark: normalizeColor(dynamic.dark), + }, + }; + return dynamicColor; + } + + return null; +} + +module.exports = normalizeColorObject; +// ]TODO(macOS ISS#2323203) diff --git a/Libraries/StyleSheet/normalizeColorObject.macos.js b/Libraries/StyleSheet/normalizeColorObject.macos.js new file mode 100644 index 00000000000000..d3f77888dd4d87 --- /dev/null +++ b/Libraries/StyleSheet/normalizeColorObject.macos.js @@ -0,0 +1,39 @@ +/** + * 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. + * + * @format + * @flow + */ +// [TODO(macOS ISS#2323203) +'use strict'; + +import type {NativeOrDynamicColorType} from './NativeOrDynamicColorType'; + +function normalizeColorObject( + color: NativeOrDynamicColorType, +): ?(number | NativeOrDynamicColorType) { + if ('semantic' in color) { + // a macos semantic color + return color; + } else if ('dynamic' in color && color.dynamic !== undefined) { + const normalizeColor = require('./normalizeColor'); + + // a dynamic, appearance aware color + const dynamic = color.dynamic; + const dynamicColor: NativeOrDynamicColorType = { + dynamic: { + light: normalizeColor(dynamic.light), + dark: normalizeColor(dynamic.dark), + }, + }; + return dynamicColor; + } + + return null; +} + +module.exports = normalizeColorObject; +// ]TODO(macOS ISS#2323203) diff --git a/Libraries/StyleSheet/processColor.js b/Libraries/StyleSheet/processColor.js index 3bfa9679e00a79..d9df1d427c11ae 100644 --- a/Libraries/StyleSheet/processColor.js +++ b/Libraries/StyleSheet/processColor.js @@ -13,49 +13,46 @@ const Platform = require('../Utilities/Platform'); const normalizeColor = require('./normalizeColor'); - -import type {ColorValue} from './StyleSheetTypes'; -import type {NativeColorValue} from './PlatformColorValueTypes'; - -export type ProcessedColorValue = number | NativeColorValue; +import type {NativeOrDynamicColorType} from '../StyleSheet/NativeOrDynamicColorType'; // TODO(macOS ISS#2323203) /* eslint no-bitwise: 0 */ -function processColor(color?: ?(number | ColorValue)): ?ProcessedColorValue { +function processColor( + color?: ?(string | number | NativeOrDynamicColorType), +): ?(number | NativeOrDynamicColorType) /* TODO(macOS ISS#2323203) */ { if (color === undefined || color === null) { return color; } - let normalizedColor = normalizeColor(color); - if (normalizedColor === null || normalizedColor === undefined) { + let int32Color = normalizeColor(color); + if (int32Color === null || int32Color === undefined) { return undefined; } - if (typeof normalizedColor === 'object') { - const processColorObject = require('./PlatformColorValueTypes') - .processColorObject; + if (typeof int32Color === 'object') { + const processColorObject = require('../StyleSheet/processColorObject'); // [TODO(macOS ISS#2323203) - const processedColorObj = processColorObject(normalizedColor); + const processedColorObj = processColorObject(int32Color); - if (processedColorObj != null) { + if (processedColorObj !== null) { return processedColorObj; } } - if (typeof normalizedColor !== 'number') { + if (typeof int32Color !== 'number') { return null; - } + } // ]TODO(macOS ISS#2323203) // Converts 0xrrggbbaa into 0xaarrggbb - normalizedColor = ((normalizedColor << 24) | (normalizedColor >>> 8)) >>> 0; + int32Color = ((int32Color << 24) | (int32Color >>> 8)) >>> 0; if (Platform.OS === 'android') { // Android use 32 bit *signed* integer to represent the color // We utilize the fact that bitwise operations in JS also operates on // signed 32 bit integers, so that we can use those to convert from // *unsigned* to *signed* 32bit int that way. - normalizedColor = normalizedColor | 0x0; + int32Color = int32Color | 0x0; } - return normalizedColor; + return int32Color; } module.exports = processColor; diff --git a/Libraries/StyleSheet/processColorArray.js b/Libraries/StyleSheet/processColorArray.js index 9bdb026b5bc0c3..4d2490fb0ac9a0 100644 --- a/Libraries/StyleSheet/processColorArray.js +++ b/Libraries/StyleSheet/processColorArray.js @@ -11,13 +11,11 @@ 'use strict'; const processColor = require('./processColor'); - -import type {ColorValue} from './StyleSheetTypes'; -import type {ProcessedColorValue} from './processColor'; +import type {NativeOrDynamicColorType} from '../StyleSheet/NativeOrDynamicColorType'; // TODO(macOS ISS#2323203) function processColorArray( - colors: ?Array, -): ?Array { + colors: ?Array, +): ?Array /* TODO(macOS ISS#2323203) */ { return colors == null ? null : colors.map(processColor); } diff --git a/Libraries/StyleSheet/processColorObject.android.js b/Libraries/StyleSheet/processColorObject.android.js new file mode 100644 index 00000000000000..21a5ade0df425b --- /dev/null +++ b/Libraries/StyleSheet/processColorObject.android.js @@ -0,0 +1,22 @@ +/** + * 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. + * + * @format + * @flow + */ +// [TODO(macOS ISS#2323203) +'use strict'; + +import type {NativeOrDynamicColorType} from '../StyleSheet/NativeOrDynamicColorType'; + +function processColorObject( + color: NativeOrDynamicColorType, +): ?NativeOrDynamicColorType { + return null; +} + +module.exports = processColorObject; +// ]TODO(macOS ISS#2323203) diff --git a/Libraries/StyleSheet/processColorObject.ios.js b/Libraries/StyleSheet/processColorObject.ios.js new file mode 100644 index 00000000000000..d6a7f85ff2d068 --- /dev/null +++ b/Libraries/StyleSheet/processColorObject.ios.js @@ -0,0 +1,33 @@ +/** + * 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. + * + * @format + * @flow + */ +// [TODO(macOS ISS#2323203) +'use strict'; + +import type {NativeOrDynamicColorType} from '../StyleSheet/NativeOrDynamicColorType'; + +function processColorObject( + color: NativeOrDynamicColorType, +): ?NativeOrDynamicColorType { + if ('dynamic' in color && color.dynamic !== undefined) { + const processColor = require('./processColor'); + const dynamic = color.dynamic; + const dynamicColor: NativeOrDynamicColorType = { + dynamic: { + light: processColor(dynamic.light), + dark: processColor(dynamic.dark), + }, + }; + return dynamicColor; + } + return color; +} + +module.exports = processColorObject; +// ]TODO(macOS ISS#2323203) diff --git a/Libraries/StyleSheet/processColorObject.macos.js b/Libraries/StyleSheet/processColorObject.macos.js new file mode 100644 index 00000000000000..d6a7f85ff2d068 --- /dev/null +++ b/Libraries/StyleSheet/processColorObject.macos.js @@ -0,0 +1,33 @@ +/** + * 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. + * + * @format + * @flow + */ +// [TODO(macOS ISS#2323203) +'use strict'; + +import type {NativeOrDynamicColorType} from '../StyleSheet/NativeOrDynamicColorType'; + +function processColorObject( + color: NativeOrDynamicColorType, +): ?NativeOrDynamicColorType { + if ('dynamic' in color && color.dynamic !== undefined) { + const processColor = require('./processColor'); + const dynamic = color.dynamic; + const dynamicColor: NativeOrDynamicColorType = { + dynamic: { + light: processColor(dynamic.light), + dark: processColor(dynamic.dark), + }, + }; + return dynamicColor; + } + return color; +} + +module.exports = processColorObject; +// ]TODO(macOS ISS#2323203) diff --git a/Libraries/StyleSheet/processTransform.js b/Libraries/StyleSheet/processTransform.js index 9f7ccefbbda8a9..1ec96929d667b0 100644 --- a/Libraries/StyleSheet/processTransform.js +++ b/Libraries/StyleSheet/processTransform.js @@ -14,7 +14,7 @@ const MatrixMath = require('../Utilities/MatrixMath'); const Platform = require('../Utilities/Platform'); const invariant = require('invariant'); -const stringifySafe = require('../Utilities/stringifySafe').default; +const stringifySafe = require('../Utilities/stringifySafe'); /** * Generate a transform matrix based on the provided transforms, and use that @@ -174,6 +174,9 @@ function _validateTransform(key, value, transformation) { switch (key) { case 'matrix': invariant( + /* $FlowFixMe(>=0.88.0 site=react_native_fb) This comment suppresses an + * error found when Flow v0.88 was deployed. To see the error, delete + * this comment and run Flow. */ value.length === 9 || value.length === 16, 'Matrix transform must have a length of 9 (2d) or 16 (3d). ' + 'Provided matrix has a length of %s: %s', @@ -186,6 +189,9 @@ function _validateTransform(key, value, transformation) { break; case 'translate': invariant( + /* $FlowFixMe(>=0.88.0 site=react_native_fb) This comment suppresses an + * error found when Flow v0.88 was deployed. To see the error, delete + * this comment and run Flow. */ value.length === 2 || value.length === 3, 'Transform with key translate must be an array of length 2 or 3, found %s: %s', /* $FlowFixMe(>=0.84.0 site=react_native_fb) This comment suppresses an diff --git a/Libraries/Text/React-RCTText.podspec b/Libraries/Text/React-RCTText.podspec index 276ee8ba25787c..b98edce8607f87 100644 --- a/Libraries/Text/React-RCTText.podspec +++ b/Libraries/Text/React-RCTText.podspec @@ -20,11 +20,11 @@ Pod::Spec.new do |s| s.name = "React-RCTText" s.version = version s.summary = "A React component for displaying text." - s.homepage = "https://reactnative.dev/" - s.documentation_url = "https://reactnative.dev/docs/text" + s.homepage = "http://facebook.github.io/react-native/" + s.documentation_url = "https://facebook.github.io/react-native/docs/text" s.license = package["license"] s.author = "Facebook, Inc. and its affiliates" - s.platforms = { :ios => "10.0", :tvos => "10.0", :osx => "10.13" } # TODO(macOS GH#214) + s.platforms = { :ios => "9.0", :tvos => "9.2", :osx => "10.13" } # TODO(macOS GH#214) s.source = source s.source_files = "**/*.{h,m}" s.ios.exclude_files = "**/macOS/*" # TODO(macOS ISS#2323203) diff --git a/Libraries/Text/Text.js b/Libraries/Text/Text.js index 660dd87976121f..92da79d44901fc 100644 --- a/Libraries/Text/Text.js +++ b/Libraries/Text/Text.js @@ -22,7 +22,7 @@ const nullthrows = require('nullthrows'); const processColor = require('../StyleSheet/processColor'); import type {PressEvent} from '../Types/CoreEventTypes'; -import type {HostComponent} from '../Renderer/shims/ReactNativeTypes'; +import type {NativeComponent} from '../Renderer/shims/ReactNative'; import type {PressRetentionOffset, TextProps} from './TextProps'; type ResponseHandlers = $ReadOnly<{| @@ -83,7 +83,7 @@ const viewConfig = { /** * A React component for displaying text. * - * See https://reactnative.dev/docs/text.html + * See https://facebook.github.io/react-native/docs/text.html */ class TouchableText extends React.Component { static defaultProps = { @@ -291,12 +291,6 @@ TextToExport.displayName = 'Text'; * and run Flow. */ TextToExport.propTypes = DeprecatedTextPropTypes; -type TextStatics = $ReadOnly<{| - propTypes: typeof DeprecatedTextPropTypes, -|}>; - -module.exports = ((TextToExport: any): React.AbstractComponent< - TextProps, - React.ElementRef>, -> & - TextStatics); +module.exports = ((TextToExport: $FlowFixMe): Class< + NativeComponent, +>); diff --git a/Libraries/Text/Text/RCTTextShadowView.m b/Libraries/Text/Text/RCTTextShadowView.m index 28bf15b4a13b21..b30a9994a7b8de 100644 --- a/Libraries/Text/Text/RCTTextShadowView.m +++ b/Libraries/Text/Text/RCTTextShadowView.m @@ -230,7 +230,6 @@ - (NSTextStorage *)textStorageAndLayoutManagerThatFitsSize:(CGSize)size textContainer.maximumNumberOfLines = _maximumNumberOfLines; NSLayoutManager *layoutManager = [NSLayoutManager new]; - layoutManager.usesFontLeading = NO; [layoutManager addTextContainer:textContainer]; NSTextStorage *textStorage = diff --git a/Libraries/Text/Text/RCTTextView.m b/Libraries/Text/Text/RCTTextView.m index b2b46747821a86..25b31f4ad29c95 100644 --- a/Libraries/Text/Text/RCTTextView.m +++ b/Libraries/Text/Text/RCTTextView.m @@ -173,7 +173,6 @@ - (void)setTextStorage:(NSTextStorage *)textStorage - (void)drawRect:(CGRect)rect { - [super drawRect:rect]; if (!_textStorage) { return; } diff --git a/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputViewManager.m b/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputViewManager.m index 7b5790e5321891..000b81fd2bbd74 100644 --- a/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputViewManager.m +++ b/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputViewManager.m @@ -6,6 +6,7 @@ */ #import + #import @implementation RCTMultilineTextInputViewManager diff --git a/Libraries/Text/TextInput/Multiline/RCTUITextView.h b/Libraries/Text/TextInput/Multiline/RCTUITextView.h index f77d8b5011c988..6f15f97a1d9ee2 100644 --- a/Libraries/Text/TextInput/Multiline/RCTUITextView.h +++ b/Libraries/Text/TextInput/Multiline/RCTUITextView.h @@ -9,8 +9,9 @@ #import "RCTTextUIKit.h" // TODO(macOS ISS#2323203) -#import -#import +#import "RCTBackedTextInputViewProtocol.h" + +#import "RCTBackedTextInputDelegate.h" NS_ASSUME_NONNULL_BEGIN diff --git a/Libraries/Text/TextInput/Multiline/RCTUITextView.m b/Libraries/Text/TextInput/Multiline/RCTUITextView.m index 522fc5c794ba7e..188e36c828da07 100644 --- a/Libraries/Text/TextInput/Multiline/RCTUITextView.m +++ b/Libraries/Text/TextInput/Multiline/RCTUITextView.m @@ -165,10 +165,6 @@ - (BOOL)becomeFirstResponder - (void)setDefaultTextAttributes:(NSDictionary *)defaultTextAttributes { - if ([_defaultTextAttributes isEqualToDictionary:defaultTextAttributes]) { - return; - } - _defaultTextAttributes = defaultTextAttributes; self.typingAttributes = defaultTextAttributes; [self _updatePlaceholder]; @@ -336,19 +332,6 @@ - (void)setTextContainerInsets:(UIEdgeInsets)textContainerInsets #endif // ]TODO(macOS ISS#2323203) -- (void)selectAll:(id)sender -{ - [super selectAll:sender]; - -#if !TARGET_OS_OSX // [TODO(macOS v0.63) - // `selectAll:` does not work for UITextView when it's being called inside UITextView's delegate methods. - dispatch_async(dispatch_get_main_queue(), ^{ - UITextRange *selectionRange = [self textRangeFromPosition:self.beginningOfDocument toPosition:self.endOfDocument]; - [self setSelectedTextRange:selectionRange notifyDelegate:NO]; - }); -#endif // ]TODO(macOS v0.63) -} - #pragma mark - Layout - (CGFloat)preferredMaxLayoutWidth diff --git a/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h b/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h index a9388f1c77b6b3..c4c5844c0e6db3 100644 --- a/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h +++ b/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h @@ -31,9 +31,12 @@ NS_ASSUME_NONNULL_BEGIN @protocol RCTBackedTextInputViewProtocol #endif // ]TODO(macOS ISS#2323203) +@property (nonatomic, strong, nullable) RCTUIColor *textColor; // TODO(OSS Candidate ISS#2710739) +@property (nonatomic, strong, nullable) UIFont *font; @property (nonatomic, copy, nullable) NSAttributedString *attributedText; @property (nonatomic, copy, nullable) NSString *placeholder; @property (nonatomic, strong, nullable) RCTUIColor *placeholderColor; // TODO(OSS Candidate ISS#2710739) +@property (nonatomic, assign) NSTextAlignment textAlignment; #if !TARGET_OS_OSX // TODO(macOS ISS#2323203) @property (nonatomic, assign, readonly) BOOL textWasPasted; #else // [TODO(macOS ISS#2323203) @@ -46,14 +49,6 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, weak, nullable) id textInputDelegate; @property (nonatomic, readonly) CGSize contentSize; @property (nonatomic, strong, nullable) NSDictionary *defaultTextAttributes; -@property (nonatomic, assign) BOOL contextMenuHidden; -@property (nonatomic, assign, getter=isEditable) BOOL editable; -@property (nonatomic, assign) BOOL caretHidden; -@property (nonatomic, assign) BOOL enablesReturnKeyAutomatically; -#if !TARGET_OS_OSX // [TODO(macOS v0.63) -@property (nonatomic, assign) UITextFieldViewMode clearButtonMode; -#endif // ]TODO(macOS v0.63) -@property (nonatomic, getter=isScrollEnabled) BOOL scrollEnabled; // This protocol disallows direct access to `selectedTextRange` property because // unwise usage of it can break the `delegate` behavior. So, we always have to diff --git a/Libraries/Text/TextInput/RCTBaseTextInputView.h b/Libraries/Text/TextInput/RCTBaseTextInputView.h index 7345ff02528a6d..98aaff61200c24 100644 --- a/Libraries/Text/TextInput/RCTBaseTextInputView.h +++ b/Libraries/Text/TextInput/RCTBaseTextInputView.h @@ -44,7 +44,6 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, copy, nullable) RCTDirectEventBlock onScroll; @property (nonatomic, assign) NSInteger mostRecentEventCount; -@property (nonatomic, assign, readonly) NSInteger nativeEventCount; @property (nonatomic, assign) BOOL autoFocus; @property (nonatomic, assign) BOOL blurOnSubmit; @property (nonatomic, assign) BOOL selectTextOnFocus; @@ -59,12 +58,6 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, assign) UIKeyboardType keyboardType; #endif // TODO(macOS ISS#2323203) -/** - Sets selection intext input if both start and end are within range of the text input. - **/ -- (void)setSelectionStart:(NSInteger)start - selectionEnd:(NSInteger)end; - @end NS_ASSUME_NONNULL_END diff --git a/Libraries/Text/TextInput/RCTBaseTextInputView.m b/Libraries/Text/TextInput/RCTBaseTextInputView.m index 1a63addbdc0a76..6bf2741349bf67 100644 --- a/Libraries/Text/TextInput/RCTBaseTextInputView.m +++ b/Libraries/Text/TextInput/RCTBaseTextInputView.m @@ -24,7 +24,8 @@ @implementation RCTBaseTextInputView { __weak RCTBridge *_bridge; __weak RCTEventDispatcher *_eventDispatcher; BOOL _hasInputAccesoryView; - // TODO(OSS Candidate ISS#2710739): remove explicit _predictedText ivar declaration + // TODO(OSS Candidate ISS#2710739): remove _predictedText ivar + NSInteger _nativeEventCount; BOOL _didMoveToWindow; } @@ -69,13 +70,7 @@ - (void)enforceTextAttributesIfNeeded { if (![self ignoresTextAttributes]) { // TODO(OSS Candidate ISS#2710739) id backedTextInputView = self.backedTextInputView; - - NSDictionary *textAttributes = [[_textAttributes effectiveTextAttributes] mutableCopy]; - if ([textAttributes valueForKey:NSForegroundColorAttributeName] == nil) { - [textAttributes setValue:[RCTUIColor blackColor] forKey:NSForegroundColorAttributeName]; // TODO(macOS ISS#2323203) - } - - backedTextInputView.defaultTextAttributes = textAttributes; + backedTextInputView.defaultTextAttributes = [_textAttributes effectiveTextAttributes]; } // TODO(OSS Candidate ISS#2710739) } @@ -238,82 +233,70 @@ - (void)setSelection:(RCTTextSelection *)selection } } -- (void)setSelectionStart:(NSInteger)start - selectionEnd:(NSInteger)end -{ -#if !TARGET_OS_OSX // [TODO(macOS v0.63) - UITextPosition *startPosition = [self.backedTextInputView positionFromPosition:self.backedTextInputView.beginningOfDocument - offset:start]; - UITextPosition *endPosition = [self.backedTextInputView positionFromPosition:self.backedTextInputView.beginningOfDocument - offset:end]; - if (startPosition && endPosition) { - UITextRange *range = [self.backedTextInputView textRangeFromPosition:startPosition toPosition:endPosition]; - [self.backedTextInputView setSelectedTextRange:range notifyDelegate:NO]; - } -#endif // ]TODO(macOS v0.63) -} - - (void)setTextContentType:(NSString *)type { - #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) - static dispatch_once_t onceToken; - static NSDictionary *contentTypeMap; - - dispatch_once(&onceToken, ^{ - contentTypeMap = @{@"none": @"", - @"URL": UITextContentTypeURL, - @"addressCity": UITextContentTypeAddressCity, - @"addressCityAndState":UITextContentTypeAddressCityAndState, - @"addressState": UITextContentTypeAddressState, - @"countryName": UITextContentTypeCountryName, - @"creditCardNumber": UITextContentTypeCreditCardNumber, - @"emailAddress": UITextContentTypeEmailAddress, - @"familyName": UITextContentTypeFamilyName, - @"fullStreetAddress": UITextContentTypeFullStreetAddress, - @"givenName": UITextContentTypeGivenName, - @"jobTitle": UITextContentTypeJobTitle, - @"location": UITextContentTypeLocation, - @"middleName": UITextContentTypeMiddleName, - @"name": UITextContentTypeName, - @"namePrefix": UITextContentTypeNamePrefix, - @"nameSuffix": UITextContentTypeNameSuffix, - @"nickname": UITextContentTypeNickname, - @"organizationName": UITextContentTypeOrganizationName, - @"postalCode": UITextContentTypePostalCode, - @"streetAddressLine1": UITextContentTypeStreetAddressLine1, - @"streetAddressLine2": UITextContentTypeStreetAddressLine2, - @"sublocality": UITextContentTypeSublocality, - @"telephoneNumber": UITextContentTypeTelephoneNumber, - }; - - #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* __IPHONE_11_0 */ - if (@available(iOS 11.0, tvOS 11.0, *)) { - NSDictionary * iOS11extras = @{@"username": UITextContentTypeUsername, - @"password": UITextContentTypePassword}; - - NSMutableDictionary * iOS11baseMap = [contentTypeMap mutableCopy]; - [iOS11baseMap addEntriesFromDictionary:iOS11extras]; - - contentTypeMap = [iOS11baseMap copy]; - } - #endif - - #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 120000 /* __IPHONE_12_0 */ - if (@available(iOS 12.0, tvOS 12.0, *)) { - NSDictionary * iOS12extras = @{@"newPassword": UITextContentTypeNewPassword, - @"oneTimeCode": UITextContentTypeOneTimeCode}; - - NSMutableDictionary * iOS12baseMap = [contentTypeMap mutableCopy]; - [iOS12baseMap addEntriesFromDictionary:iOS12extras]; - - contentTypeMap = [iOS12baseMap copy]; - } - #endif - }); - - // Setting textContentType to an empty string will disable any - // default behaviour, like the autofill bar for password inputs - self.backedTextInputView.textContentType = contentTypeMap[type] ?: type; + #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 + if (@available(iOS 10.0, *)) { + + static dispatch_once_t onceToken; + static NSDictionary *contentTypeMap; + + dispatch_once(&onceToken, ^{ + contentTypeMap = @{@"none": @"", + @"URL": UITextContentTypeURL, + @"addressCity": UITextContentTypeAddressCity, + @"addressCityAndState":UITextContentTypeAddressCityAndState, + @"addressState": UITextContentTypeAddressState, + @"countryName": UITextContentTypeCountryName, + @"creditCardNumber": UITextContentTypeCreditCardNumber, + @"emailAddress": UITextContentTypeEmailAddress, + @"familyName": UITextContentTypeFamilyName, + @"fullStreetAddress": UITextContentTypeFullStreetAddress, + @"givenName": UITextContentTypeGivenName, + @"jobTitle": UITextContentTypeJobTitle, + @"location": UITextContentTypeLocation, + @"middleName": UITextContentTypeMiddleName, + @"name": UITextContentTypeName, + @"namePrefix": UITextContentTypeNamePrefix, + @"nameSuffix": UITextContentTypeNameSuffix, + @"nickname": UITextContentTypeNickname, + @"organizationName": UITextContentTypeOrganizationName, + @"postalCode": UITextContentTypePostalCode, + @"streetAddressLine1": UITextContentTypeStreetAddressLine1, + @"streetAddressLine2": UITextContentTypeStreetAddressLine2, + @"sublocality": UITextContentTypeSublocality, + @"telephoneNumber": UITextContentTypeTelephoneNumber, + }; + + #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* __IPHONE_11_0 */ + if (@available(iOS 11.0, tvOS 11.0, *)) { + NSDictionary * iOS11extras = @{@"username": UITextContentTypeUsername, + @"password": UITextContentTypePassword}; + + NSMutableDictionary * iOS11baseMap = [contentTypeMap mutableCopy]; + [iOS11baseMap addEntriesFromDictionary:iOS11extras]; + + contentTypeMap = [iOS11baseMap copy]; + } + #endif + + #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 120000 /* __IPHONE_12_0 */ + if (@available(iOS 12.0, tvOS 12.0, *)) { + NSDictionary * iOS12extras = @{@"newPassword": UITextContentTypeNewPassword, + @"oneTimeCode": UITextContentTypeOneTimeCode}; + + NSMutableDictionary * iOS12baseMap = [contentTypeMap mutableCopy]; + [iOS12baseMap addEntriesFromDictionary:iOS12extras]; + + contentTypeMap = [iOS12baseMap copy]; + } + #endif + }); + + // Setting textContentType to an empty string will disable any + // default behaviour, like the autofill bar for password inputs + self.backedTextInputView.textContentType = contentTypeMap[type] ?: type; + } #endif } diff --git a/Libraries/Text/TextInput/RCTBaseTextInputViewManager.m b/Libraries/Text/TextInput/RCTBaseTextInputViewManager.m index 2072f10629cdc2..fa8763678ddfd6 100644 --- a/Libraries/Text/TextInput/RCTBaseTextInputViewManager.m +++ b/Libraries/Text/TextInput/RCTBaseTextInputViewManager.m @@ -21,7 +21,6 @@ #if !TARGET_OS_OSX // TODO(macOS ISS#2323203) #import #endif // TODO(macOS ISS#2323203) -#import // TODO(macOS ISS#2323203) @interface RCTBaseTextInputViewManager () @@ -46,6 +45,7 @@ @implementation RCTBaseTextInputViewManager RCT_REMAP_VIEW_PROPERTY(placeholder, backedTextInputView.placeholder, NSString) RCT_REMAP_VIEW_PROPERTY(placeholderTextColor, backedTextInputView.placeholderColor, UIColor) RCT_REMAP_NOT_OSX_VIEW_PROPERTY(returnKeyType, backedTextInputView.returnKeyType, UIReturnKeyType) // TODO(macOS ISS#2323203) +RCT_REMAP_NOT_OSX_VIEW_PROPERTY(secureTextEntry, backedTextInputView.secureTextEntry, BOOL) // TODO(macOS ISS#2323203) RCT_REMAP_NOT_OSX_VIEW_PROPERTY(selectionColor, backedTextInputView.tintColor, UIColor) // TODO(macOS ISS#2323203) RCT_REMAP_OSX_VIEW_PROPERTY(selectionColor, backedTextInputView.selectionColor, UIColor) // TODO(macOS ISS#2323203) RCT_REMAP_NOT_OSX_VIEW_PROPERTY(spellCheck, backedTextInputView.spellCheckingType, UITextSpellCheckingType) // TODO(macOS ISS#2323203) @@ -53,7 +53,6 @@ @implementation RCTBaseTextInputViewManager RCT_REMAP_NOT_OSX_VIEW_PROPERTY(caretHidden, backedTextInputView.caretHidden, BOOL) // TODO(macOS ISS#2323203) RCT_REMAP_NOT_OSX_VIEW_PROPERTY(clearButtonMode, backedTextInputView.clearButtonMode, UITextFieldViewMode) // TODO(macOS ISS#2323203) RCT_REMAP_VIEW_PROPERTY(scrollEnabled, backedTextInputView.scrollEnabled, BOOL) -RCT_REMAP_NOT_OSX_VIEW_PROPERTY(secureTextEntry, backedTextInputView.secureTextEntry, BOOL) // TODO(macOS ISS#2323203) RCT_EXPORT_VIEW_PROPERTY(autoFocus, BOOL) RCT_EXPORT_VIEW_PROPERTY(blurOnSubmit, BOOL) RCT_EXPORT_NOT_OSX_VIEW_PROPERTY(clearTextOnFocus, BOOL) // TODO(macOS ISS#2323203) @@ -76,11 +75,6 @@ @implementation RCTBaseTextInputViewManager RCT_EXPORT_SHADOW_PROPERTY(placeholder, NSString) RCT_EXPORT_SHADOW_PROPERTY(onContentSizeChange, RCTBubblingEventBlock) -RCT_CUSTOM_VIEW_PROPERTY(multiline, BOOL, RCTUIView) // TODO(macOS ISS#2323203) -{ - // No op. - // This View Manager doesn't use this prop but it must be exposed here via ViewConfig to enable Fabric component use it. -} - (RCTShadowView *)shadowView { @@ -111,45 +105,6 @@ - (void)setBridge:(RCTBridge *)bridge #endif // TODO(macOS ISS#2323203) } -RCT_EXPORT_METHOD(focus : (nonnull NSNumber *)viewTag) -{ - [self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary *viewRegistry) { // TODO(macOS ISS#2323203) - RCTUIView *view = viewRegistry[viewTag]; // TODO(macOS ISS#2323203) - [view reactFocus]; - }]; -} - -RCT_EXPORT_METHOD(blur : (nonnull NSNumber *)viewTag) -{ - [self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary *viewRegistry) { // TODO(macOS ISS#2323203) - RCTUIView *view = viewRegistry[viewTag]; // TODO(macOS ISS#2323203) - [view reactBlur]; - }]; -} - -RCT_EXPORT_METHOD(setTextAndSelection : (nonnull NSNumber *)viewTag - mostRecentEventCount : (NSInteger)mostRecentEventCount - value : (NSString *)value - start : (NSInteger)start - end : (NSInteger)end) -{ - [self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary *viewRegistry) { // TODO(macOS ISS#2323203) - RCTBaseTextInputView *view = (RCTBaseTextInputView *)viewRegistry[viewTag]; - NSInteger eventLag = view.nativeEventCount - mostRecentEventCount; - if (eventLag != 0) { - return; - } - RCTExecuteOnUIManagerQueue(^{ - RCTBaseTextInputShadowView *shadowView = (RCTBaseTextInputShadowView *)[self.bridge.uiManager shadowViewForReactTag:viewTag]; - [shadowView setText:value]; - [self.bridge.uiManager setNeedsLayout]; - RCTExecuteOnMainQueue(^{ - [view setSelectionStart:start selectionEnd:end]; - }); - }); - }]; -} - #pragma mark - RCTUIManagerObserver - (void)uiManagerWillPerformMounting:(__unused RCTUIManager *)uiManager diff --git a/Libraries/Text/TextInput/Singleline/RCTUITextField.h b/Libraries/Text/TextInput/Singleline/RCTUITextField.h index ae767255a9dda1..d48d3b96bf8398 100644 --- a/Libraries/Text/TextInput/Singleline/RCTUITextField.h +++ b/Libraries/Text/TextInput/Singleline/RCTUITextField.h @@ -9,8 +9,7 @@ #import "RCTTextUIKit.h" // TODO(macOS ISS#2323203) -#import -#import +#import "RCTBackedTextInputViewProtocol.h" NS_ASSUME_NONNULL_BEGIN @@ -40,10 +39,8 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, assign, getter=isEditable) BOOL editable; #else // [TODO(macOS ISS#2323203) @property (assign, getter=isEditable) BOOL editable; -#endif // ]TODO(macOS ISS#2323203) -@property (nonatomic, getter=isScrollEnabled) BOOL scrollEnabled; - -#if TARGET_OS_OSX // [TODO(macOS ISS#2323203) +#endif +#if TARGET_OS_OSX @property (nonatomic, copy, nullable) NSString *text; @property (nonatomic, copy, nullable) NSAttributedString *attributedText; @property (nonatomic, copy) NSDictionary *defaultTextAttributes; diff --git a/Libraries/Text/TextInput/Singleline/RCTUITextField.m b/Libraries/Text/TextInput/Singleline/RCTUITextField.m index 420e7fea252fe4..b36546f97f4e04 100644 --- a/Libraries/Text/TextInput/Singleline/RCTUITextField.m +++ b/Libraries/Text/TextInput/Singleline/RCTUITextField.m @@ -9,6 +9,7 @@ #import #import + #import #import // TODO(OSS Candidate ISS#2710739) #import @@ -116,7 +117,6 @@ - (instancetype)initWithFrame:(CGRect)frame #endif // ]TODO(macOS ISS#2323203) _textInputDelegateAdapter = [[RCTBackedTextFieldDelegateAdapter alloc] initWithTextField:self]; - _scrollEnabled = YES; } return self; @@ -248,10 +248,6 @@ - (void)setPlaceholderColor:(RCTUIColor *)placeholderColor // TODO(OSS Candidate - (void)setDefaultTextAttributes:(NSDictionary *)defaultTextAttributes { - if ([_defaultTextAttributes isEqualToDictionary:defaultTextAttributes]) { - return; - } - _defaultTextAttributes = defaultTextAttributes; #if !TARGET_OS_OSX // TODO(macOS ISS#2323203) [super setDefaultTextAttributes:defaultTextAttributes]; @@ -296,6 +292,16 @@ - (void)setEditable:(BOOL)editable #if !TARGET_OS_OSX // TODO(macOS ISS#2323203) +- (void)setScrollEnabled:(BOOL)enabled +{ + // Do noting, compatible with multiline textinput +} + +- (BOOL)scrollEnabled +{ + return NO; +} + - (void)setSecureTextEntry:(BOOL)secureTextEntry { if (self.secureTextEntry == secureTextEntry) { diff --git a/Libraries/Text/TextProps.js b/Libraries/Text/TextProps.js index 009929e8ff7076..b14dfbfa88cdfc 100644 --- a/Libraries/Text/TextProps.js +++ b/Libraries/Text/TextProps.js @@ -30,13 +30,13 @@ export type PressRetentionOffset = $ReadOnly<{| |}>; /** - * @see https://reactnative.dev/docs/text.html#reference + * @see https://facebook.github.io/react-native/docs/text.html#reference */ export type TextProps = $ReadOnly<{| /** * Indicates whether the view is an accessibility element. * - * See https://reactnative.dev/docs/text.html#accessible + * See https://facebook.github.io/react-native/docs/text.html#accessible */ accessible?: ?boolean, accessibilityHint?: ?Stringish, @@ -47,14 +47,14 @@ export type TextProps = $ReadOnly<{| /** * Whether font should be scaled down automatically. * - * See https://reactnative.dev/docs/text.html#adjustsfontsizetofit + * See https://facebook.github.io/react-native/docs/text.html#adjustsfontsizetofit */ adjustsFontSizeToFit?: ?boolean, /** * Whether fonts should scale to respect Text Size accessibility settings. * - * See https://reactnative.dev/docs/text.html#allowfontscaling + * See https://facebook.github.io/react-native/docs/text.html#allowfontscaling */ allowFontScaling?: ?boolean, children?: ?Node, @@ -63,7 +63,7 @@ export type TextProps = $ReadOnly<{| * When `numberOfLines` is set, this prop defines how text will be * truncated. * - * See https://reactnative.dev/docs/text.html#ellipsizemode + * See https://facebook.github.io/react-native/docs/text.html#ellipsizemode */ ellipsizeMode?: ?('clip' | 'head' | 'middle' | 'tail'), @@ -79,35 +79,35 @@ export type TextProps = $ReadOnly<{| /** * Used to locate this view from native code. * - * See https://reactnative.dev/docs/text.html#nativeid + * See https://facebook.github.io/react-native/docs/text.html#nativeid */ nativeID?: ?string, /** * Used to truncate the text with an ellipsis. * - * See https://reactnative.dev/docs/text.html#numberoflines + * See https://facebook.github.io/react-native/docs/text.html#numberoflines */ numberOfLines?: ?number, /** * Invoked on mount and layout changes. * - * See https://reactnative.dev/docs/text.html#onlayout + * See https://facebook.github.io/react-native/docs/text.html#onlayout */ onLayout?: ?(event: LayoutEvent) => mixed, /** * This function is called on long press. * - * See https://reactnative.dev/docs/text.html#onlongpress + * See https://facebook.github.io/react-native/docs/text.html#onlongpress */ onLongPress?: ?(event: PressEvent) => mixed, /** * This function is called on press. * - * See https://reactnative.dev/docs/text.html#onpress + * See https://facebook.github.io/react-native/docs/text.html#onpress */ onPress?: ?(event: PressEvent) => mixed, onResponderGrant?: ?(event: PressEvent, dispatchID: string) => void, @@ -123,14 +123,14 @@ export type TextProps = $ReadOnly<{| * Defines how far your touch may move off of the button, before * deactivating the button. * - * See https://reactnative.dev/docs/text.html#pressretentionoffset + * See https://facebook.github.io/react-native/docs/text.html#pressretentionoffset */ pressRetentionOffset?: ?PressRetentionOffset, /** * Lets the user select text. * - * See https://reactnative.dev/docs/text.html#selectable + * See https://facebook.github.io/react-native/docs/text.html#selectable */ selectable?: ?boolean, style?: ?TextStyleProp, @@ -138,7 +138,7 @@ export type TextProps = $ReadOnly<{| /** * Used to locate this view in end-to-end tests. * - * See https://reactnative.dev/docs/text.html#testid + * See https://facebook.github.io/react-native/docs/text.html#testid */ testID?: ?string, @@ -149,14 +149,14 @@ export type TextProps = $ReadOnly<{| /** * Specifies the disabled state of the text view for testing purposes. * - * See https://reactnative.dev/docs/text.html#disabled + * See https://facebook.github.io/react-native/docs/text.html#disabled */ disabled?: ?boolean, /** * The highlight color of the text. * - * See https://reactnative.dev/docs/text.html#selectioncolor + * See https://facebook.github.io/react-native/docs/text.html#selectioncolor */ selectionColor?: ?string, @@ -165,7 +165,7 @@ export type TextProps = $ReadOnly<{| /** * Set text break strategy on Android. * - * See https://reactnative.dev/docs/text.html#textbreakstrategy + * See https://facebook.github.io/react-native/docs/text.html#textbreakstrategy */ textBreakStrategy?: ?('balanced' | 'highQuality' | 'simple'), @@ -177,14 +177,14 @@ export type TextProps = $ReadOnly<{| /** * Smallest possible scale a font can reach. * - * See https://reactnative.dev/docs/text.html#minimumfontscale + * See https://facebook.github.io/react-native/docs/text.html#minimumfontscale */ minimumFontScale?: ?number, /** * When `true`, no visual change is made when text is pressed down. * - * See https://reactnative.dev/docs/text.html#supperhighlighting + * See https://facebook.github.io/react-native/docs/text.html#supperhighlighting */ suppressHighlighting?: ?boolean, |}>; diff --git a/Libraries/TurboModule/RCTExport.js b/Libraries/TurboModule/RCTExport.js index f90568d0e5bfc0..a0fc78fc96c746 100644 --- a/Libraries/TurboModule/RCTExport.js +++ b/Libraries/TurboModule/RCTExport.js @@ -25,7 +25,7 @@ * information, native base classes, etc. For now, simply use `void` type as * there's nothing to give hint about. * - * NOTE: This export is deprecated. Please use TurboModule. + * NOTE: This export is deprecated. Please us TurboModule. */ // eslint-disable-next-line no-unused-vars @@ -33,4 +33,5 @@ export interface DEPRECATED_RCTExport { +getConstants?: () => {...}; } +// eslint-disable-next-line lint/react-native-modules export interface TurboModule extends DEPRECATED_RCTExport {} diff --git a/Libraries/TypeSafety/RCTConvertHelpers.mm b/Libraries/TypeSafety/RCTConvertHelpers.mm index 69fb3e4a3de4f4..116cf566e51b1d 100644 --- a/Libraries/TypeSafety/RCTConvertHelpers.mm +++ b/Libraries/TypeSafety/RCTConvertHelpers.mm @@ -24,7 +24,7 @@ bool RCTBridgingToBool(id value) NSString *RCTBridgingToString(id value) { - return [RCTConvert NSString:RCTNilIfNull(value)]; + return [RCTConvert NSString:value]; } folly::Optional RCTBridgingToOptionalDouble(id value) diff --git a/Libraries/TypeSafety/RCTTypeSafety.podspec b/Libraries/TypeSafety/RCTTypeSafety.podspec index 5cd02a9f8119ca..ecd296099fdadc 100644 --- a/Libraries/TypeSafety/RCTTypeSafety.podspec +++ b/Libraries/TypeSafety/RCTTypeSafety.podspec @@ -17,16 +17,16 @@ else end folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32' -folly_version = '2020.01.13.00' +folly_version = '2018.10.22.00' Pod::Spec.new do |s| s.name = "RCTTypeSafety" s.version = version s.summary = "-" # TODO - s.homepage = "https://reactnative.dev/" + s.homepage = "http://facebook.github.io/react-native/" s.license = package["license"] s.author = "Facebook, Inc. and its affiliates" - s.platforms = { :ios => "10.0", :tvos => "10.0", :osx => "10.13" } # TODO(macOS ISS#2323203) + s.platforms = { :ios => "9.0", :tvos => "9.2", :osx => "10.13" } # TODO(macOS ISS#2323203) s.compiler_flags = folly_compiler_flags s.source = source s.source_files = "**/*.{c,h,m,mm,cpp}" diff --git a/Libraries/Utilities/Dimensions.js b/Libraries/Utilities/Dimensions.js index b3e5822c401bb3..3cc28bc0ff6195 100644 --- a/Libraries/Utilities/Dimensions.js +++ b/Libraries/Utilities/Dimensions.js @@ -134,6 +134,8 @@ if (!initialDims) { Dimensions.set(update); }, ); + // Can't use NativeDeviceInfo in ComponentScript because it does not support NativeModules, + // but has nativeExtensions instead. initialDims = NativeDeviceInfo.getConstants().Dimensions; } diff --git a/Libraries/Utilities/HMRClient.js b/Libraries/Utilities/HMRClient.js index 80e60b0da7c21a..a5c3ebfd1fc14d 100644 --- a/Libraries/Utilities/HMRClient.js +++ b/Libraries/Utilities/HMRClient.js @@ -10,11 +10,10 @@ 'use strict'; -const DevSettings = require('./DevSettings'); +const Platform = require('./Platform'); const invariant = require('invariant'); + const MetroHMRClient = require('metro/src/lib/bundle-modules/HMRClient'); -const Platform = require('./Platform'); -const prettyFormat = require('pretty-format'); import NativeRedBox from '../NativeModules/specs/NativeRedBox'; import * as LogBoxData from '../LogBox/Data/LogBoxData'; @@ -31,7 +30,6 @@ type LogLevel = | 'trace' | 'info' | 'warn' - | 'error' | 'log' | 'group' | 'groupCollapsed' @@ -115,23 +113,36 @@ const HMRClient: HMRClientNativeInterface = { return; } try { - hmrClient.send( - JSON.stringify({ + let message; + if (global.Symbol) { + message = JSON.stringify({ type: 'log', level, data: data.map(item => typeof item === 'string' ? item - : prettyFormat(item, { + : require('pretty-format')(item, { escapeString: true, highlight: true, maxDepth: 3, min: true, - plugins: [prettyFormat.plugins.ReactElement], + plugins: [require('pretty-format').plugins.ReactElement], }), ), - }), - ); + }); + } else { + try { + message = JSON.stringify({type: 'log', level, data}); + } catch (error) { + message = JSON.stringify({ + type: 'log', + level, + data: [error.message], + }); + } + } + + hmrClient.send(message); } catch (error) { // If sending logs causes any failures we want to silently ignore them // to ensure we do not cause infinite-logging loops. @@ -148,8 +159,8 @@ const HMRClient: HMRClientNativeInterface = { isEnabled: boolean, ) { invariant(platform, 'Missing required parameter `platform`'); - invariant(bundleEntry, 'Missing required parameter `bundleEntry`'); - invariant(host, 'Missing required parameter `host`'); + invariant(bundleEntry, 'Missing required paramenter `bundleEntry`'); + invariant(host, 'Missing required paramenter `host`'); invariant(!hmrClient, 'Cannot initialize hmrClient twice'); // Moving to top gives errors due to NativeModules not being initialized @@ -266,11 +277,6 @@ function setHMRUnavailableReason(reason) { } function registerBundleEntryPoints(client) { - if (hmrUnavailableReason) { - DevSettings.reload('Bundle Splitting – Metro disconnected'); - return; - } - if (pendingEntryPoints.length > 0) { client.send( JSON.stringify({ diff --git a/Libraries/Utilities/LoadingView.ios.js b/Libraries/Utilities/LoadingView.ios.js index e8f7d133f5caf3..782bedfbbb69c0 100644 --- a/Libraries/Utilities/LoadingView.ios.js +++ b/Libraries/Utilities/LoadingView.ios.js @@ -16,21 +16,13 @@ import NativeDevLoadingView from './NativeDevLoadingView'; module.exports = { showMessage(message: string, type: 'load' | 'refresh') { if (NativeDevLoadingView) { - const green = processColor('#005a00'); - const blue = processColor('#2584e8'); - const white = processColor('#ffffff'); - NativeDevLoadingView.showMessage( message, // Use same colors as iOS "Personal Hotspot" bar. - typeof white === 'number' ? white : null, + processColor('#ffffff'), type && type === 'load' - ? typeof green === 'number' - ? green - : null - : typeof blue === 'number' - ? blue - : null, + ? processColor('#275714') + : processColor('#2584e8'), ); } }, diff --git a/Libraries/Utilities/MatrixMath.js b/Libraries/Utilities/MatrixMath.js index 2a943a8961ac03..85d2bb7c1e5b94 100755 --- a/Libraries/Utilities/MatrixMath.js +++ b/Libraries/Utilities/MatrixMath.js @@ -8,6 +8,8 @@ * @noflow */ +/* eslint-disable space-infix-ops */ + 'use strict'; const invariant = require('invariant'); diff --git a/Libraries/Utilities/NativeDevLoadingView.js b/Libraries/Utilities/NativeDevLoadingView.js index 8938fb6df5ccbf..e672771778b8a1 100644 --- a/Libraries/Utilities/NativeDevLoadingView.js +++ b/Libraries/Utilities/NativeDevLoadingView.js @@ -16,8 +16,8 @@ import * as TurboModuleRegistry from '../TurboModule/TurboModuleRegistry'; export interface Spec extends TurboModule { +showMessage: ( message: string, - withColor: ?number, - withBackgroundColor: ?number, + color: Object, + backgroundColor: Object, ) => void; +hide: () => void; } diff --git a/Libraries/Utilities/NativeJSDevSupport.js b/Libraries/Utilities/NativeJSDevSupport.js index 0c140f0f9621f3..3128d3d83bd214 100644 --- a/Libraries/Utilities/NativeJSDevSupport.js +++ b/Libraries/Utilities/NativeJSDevSupport.js @@ -18,7 +18,7 @@ export interface Spec extends TurboModule { ERROR_CODE_EXCEPTION: number, ERROR_CODE_VIEW_NOT_FOUND: number, |}; - +onSuccess: (data: string) => void; + +onSuccess: (data: Object) => void; +onFailure: (errorCode: number, error: string) => void; } diff --git a/Libraries/Utilities/NativePlatformConstantsAndroid.js b/Libraries/Utilities/NativePlatformConstantsAndroid.js index 39aa25d8c49055..dcf276ae2ac3f4 100644 --- a/Libraries/Utilities/NativePlatformConstantsAndroid.js +++ b/Libraries/Utilities/NativePlatformConstantsAndroid.js @@ -27,7 +27,7 @@ export interface Spec extends TurboModule { Serial: string, Fingerprint: string, Model: string, - ServerHost?: string, + ServerHost: string, uiMode: string, |}; +getAndroidID: () => string; diff --git a/Libraries/Utilities/PixelRatio.js b/Libraries/Utilities/PixelRatio.js index 06813b3a6d4967..99521348a578ab 100644 --- a/Libraries/Utilities/PixelRatio.js +++ b/Libraries/Utilities/PixelRatio.js @@ -92,9 +92,9 @@ class PixelRatio { * * If a font scale is not set, this returns the device pixel ratio. * - * This reflects the user preference set in: - * - Settings > Display > Font size on Android, - * - Settings > Display & Brightness > Text Size on iOS. + * Currently this is only implemented on Android and reflects the user preference set in + * Settings > Display > Font size, on iOS it will always return the default pixel ratio. + * @platform android */ static getFontScale(): number { return Dimensions.get('window').fontScale || PixelRatio.get(); diff --git a/Libraries/Utilities/Platform.android.js b/Libraries/Utilities/Platform.android.js index 3785bc8790a5b0..13b0586701eac5 100644 --- a/Libraries/Utilities/Platform.android.js +++ b/Libraries/Utilities/Platform.android.js @@ -38,7 +38,7 @@ const Platform = { Serial: string, Fingerprint: string, Model: string, - ServerHost?: string, + ServerHost: string, uiMode: string, |} { if (this.__constants == null) { diff --git a/Libraries/Utilities/RCTLog.js b/Libraries/Utilities/RCTLog.js index def04d6c3b2d73..b6a368907b0cdf 100644 --- a/Libraries/Utilities/RCTLog.js +++ b/Libraries/Utilities/RCTLog.js @@ -29,7 +29,7 @@ const RCTLog = { if (typeof global.nativeLoggingHook === 'undefined') { RCTLog.logToConsole(level, ...args); } else { - // Report native warnings to LogBox + // Report native warnings to YellowBox if (warningHandler && level === 'warn') { warningHandler(...args); } diff --git a/Libraries/Utilities/ReactNativeTestTools.js b/Libraries/Utilities/ReactNativeTestTools.js index cd018a6fc5e3cc..fbe4e094ca4aa4 100644 --- a/Libraries/Utilities/ReactNativeTestTools.js +++ b/Libraries/Utilities/ReactNativeTestTools.js @@ -16,30 +16,15 @@ const React = require('react'); const ReactTestRenderer = require('react-test-renderer'); const ShallowRenderer = require('react-test-renderer/shallow'); -/* $FlowFixMe(>=0.122.0 site=react_native_fb) This comment suppresses an error - * found when Flow v0.122.0 was deployed. To see the error, delete this comment - * and run Flow. */ const shallowRenderer = new ShallowRenderer(); -import type {ReactTestRenderer as ReactTestRendererType} from 'react-test-renderer'; +const {Switch, Text, TextInput, VirtualizedList} = require('react-native'); -export type ReactTestInstance = $PropertyType; - -export type Predicate = (node: ReactTestInstance) => boolean; - -type $ReturnType = $Call<((...A) => Ret) => Ret, Fn>; -/* $FlowFixMe(>=0.122.0 site=react_native_fb) This comment suppresses an error - * found when Flow v0.122.0 was deployed. To see the error, delete this comment - * and run Flow. */ -export type ReactTestRendererJSON = $ReturnType; - -const { - Switch, - Text, - TextInput, - View, - VirtualizedList, -} = require('react-native'); +import type { + ReactTestInstance, + ReactTestRendererNode, + Predicate, +} from 'react-test-renderer'; function byClickable(): Predicate { return withMessage( @@ -51,18 +36,10 @@ function byClickable(): Predicate { typeof node.props.onPress === 'function') || // note: Special casing since it doesn't use touchable (node.type === Switch && node.props && node.props.disabled !== true) || - (node.type === View && - node?.props?.onStartShouldSetResponder?.testOnly_pressabilityConfig) || // HACK: Find components that use `Pressability`. node.instance?.state?.pressability != null || // TODO: Remove this after deleting `Touchable`. - /* $FlowFixMe(>=0.122.0 site=react_native_fb) This comment suppresses an - * error found when Flow v0.122.0 was deployed. To see the error, delete - * this comment and run Flow. */ (node.instance && - /* $FlowFixMe(>=0.122.0 site=react_native_fb) This comment suppresses - * an error found when Flow v0.122.0 was deployed. To see the error, - * delete this comment and run Flow. */ typeof node.instance.touchableHandlePress === 'function'), 'is clickable', ); @@ -77,9 +54,6 @@ function byTestID(testID: string): Predicate { function byTextMatching(regex: RegExp): Predicate { return withMessage( - /* $FlowFixMe(>=0.122.0 site=react_native_fb) This comment suppresses an - * error found when Flow v0.122.0 was deployed. To see the error, delete - * this comment and run Flow. */ node => node.props && regex.exec(node.props.children), `text content matches ${regex.toString()}`, ); @@ -93,7 +67,7 @@ function enter(instance: ReactTestInstance, text: string) { // Returns null if there is no error, otherwise returns an error message string. function maximumDepthError( - tree: ReactTestRendererType, + tree: {toJSON: () => ReactTestRendererNode, ...}, maxDepthLimit: number, ): ?string { const maxDepth = maximumDepthOfJSON(tree.toJSON()); @@ -165,7 +139,7 @@ function expectRendersMatchingSnapshot( } // Takes a node from toJSON() -function maximumDepthOfJSON(node: ?ReactTestRendererJSON): number { +function maximumDepthOfJSON(node: ReactTestRendererNode): number { if (node == null) { return 0; } else if (typeof node === 'string' || node.children == null) { @@ -184,7 +158,7 @@ function renderAndEnforceStrictMode(element: React.Node): any { return renderWithStrictMode(element); } -function renderWithStrictMode(element: React.Node): ReactTestRendererType { +function renderWithStrictMode(element: React.Node): any { const WorkAroundBugWithStrictModeInTestRenderer = prps => prps.children; const StrictMode = (React: $FlowFixMe).StrictMode; return ReactTestRenderer.create( @@ -203,16 +177,6 @@ function tap(instance: ReactTestInstance) { const {onChange, onValueChange} = touchable.props; onChange && onChange({nativeEvent: {value}}); onValueChange && onValueChange(value); - } else if ( - touchable?.props?.onStartShouldSetResponder?.testOnly_pressabilityConfig - ) { - const { - onPress, - disabled, - } = touchable.props.onStartShouldSetResponder.testOnly_pressabilityConfig(); - if (!disabled) { - onPress({nativeEvent: {}}); - } } else { // Only tap when props.disabled isn't set (or there aren't any props) if (!touchable.props || !touchable.props.disabled) { diff --git a/Libraries/Utilities/SceneTracker.js b/Libraries/Utilities/SceneTracker.js index 23b0c7dcae39ea..ff3bbe07c62f68 100644 --- a/Libraries/Utilities/SceneTracker.js +++ b/Libraries/Utilities/SceneTracker.js @@ -10,7 +10,7 @@ 'use strict'; -export type Scene = {name: string, ...}; +type Scene = {name: string, ...}; let _listeners: Array<(scene: Scene) => void> = []; diff --git a/Libraries/Utilities/__tests__/stringifySafe-test.js b/Libraries/Utilities/__tests__/stringifySafe-test.js index 9ab85e566cbda3..c259caf20a7fd6 100644 --- a/Libraries/Utilities/__tests__/stringifySafe-test.js +++ b/Libraries/Utilities/__tests__/stringifySafe-test.js @@ -5,15 +5,14 @@ * LICENSE file in the root directory of this source tree. * * @format - * @flow strict-local * @emails oncall+react_native */ 'use strict'; -import stringifySafe, {createStringifySafeWithLimits} from '../stringifySafe'; - describe('stringifySafe', () => { + const stringifySafe = require('../stringifySafe'); + it('stringifySafe stringifies undefined values', () => { expect(stringifySafe(undefined)).toEqual('undefined'); }); @@ -42,8 +41,9 @@ describe('stringifySafe', () => { }); it('stringifySafe stringifies circular objects without toString', () => { - const arg = {x: {}, toString: undefined}; - arg.x = arg; + const arg = {}; + arg.arg = arg; + arg.toString = undefined; const result = stringifySafe(arg); expect(result).toEqual('["object" failed to stringify]'); }); @@ -53,38 +53,4 @@ describe('stringifySafe', () => { const result = stringifySafe(error); expect(result).toEqual('Error: error'); }); - - it('stringifySafe truncates long strings', () => { - const stringify = createStringifySafeWithLimits({maxStringLimit: 3}); - expect(stringify('abcdefghijklmnopqrstuvwxyz')).toEqual( - '"abc...(truncated)..."', - ); - expect(stringify({a: 'abcdefghijklmnopqrstuvwxyz'})).toEqual( - '{"a":"abc...(truncated)..."}', - ); - }); - - it('stringifySafe truncates large arrays', () => { - const stringify = createStringifySafeWithLimits({maxArrayLimit: 3}); - expect(stringify([1, 2, 3, 4, 5])).toEqual( - '[1,2,3,"... extra 2 values truncated ..."]', - ); - expect(stringify({a: [1, 2, 3, 4, 5]})).toEqual( - '{"a":[1,2,3,"... extra 2 values truncated ..."]}', - ); - }); - - it('stringifySafe truncates large objects', () => { - const stringify = createStringifySafeWithLimits({maxObjectKeysLimit: 3}); - expect(stringify({a: 1, b: 2, c: 3, d: 4, e: 5})).toEqual( - '{"a":1,"b":2,"c":3,"...(truncated keys)...":2}', - ); - }); - - it('stringifySafe truncates deep objects', () => { - const stringify = createStringifySafeWithLimits({maxDepth: 3}); - expect(stringify({a: {a: {a: {x: 0, y: 1, z: 2}}}})).toEqual( - '{"a":{"a":{"a":"{ ... object with 3 keys ... }"}}}', - ); - }); }); diff --git a/Libraries/Utilities/createPerformanceLogger.js b/Libraries/Utilities/createPerformanceLogger.js index 2bfdb34258169e..fdd5ca9e3cfc27 100644 --- a/Libraries/Utilities/createPerformanceLogger.js +++ b/Libraries/Utilities/createPerformanceLogger.js @@ -29,7 +29,7 @@ type Timespan = { export type IPerformanceLogger = { addTimespan(string, number, string | void): void, startTimespan(string, string | void): void, - stopTimespan(string, options?: {update?: boolean}): void, + stopTimespan(string): void, clear(): void, clearCompleted(): void, clearExceptTimespans(Array): void, @@ -107,7 +107,7 @@ function createPerformanceLogger(): IPerformanceLogger { } }, - stopTimespan(key: string, options?: {update?: boolean}) { + stopTimespan(key: string) { const timespan = this._timespans[key]; if (!timespan || !timespan.startTime) { if (PRINT_TO_CONSOLE && __DEV__) { @@ -118,7 +118,7 @@ function createPerformanceLogger(): IPerformanceLogger { } return; } - if (timespan.endTime && !options?.update) { + if (timespan.endTime) { if (PRINT_TO_CONSOLE && __DEV__) { infoLog( 'PerformanceLogger: Attempting to end a timespan that has already ended ', @@ -134,10 +134,8 @@ function createPerformanceLogger(): IPerformanceLogger { infoLog('PerformanceLogger.js', 'end: ' + key); } - if (_cookies[key] != null) { - Systrace.endAsyncEvent(key, _cookies[key]); - delete _cookies[key]; - } + Systrace.endAsyncEvent(key, _cookies[key]); + delete _cookies[key]; }, clear() { diff --git a/Libraries/Utilities/deprecatedPropType.js b/Libraries/Utilities/deprecatedPropType.js index 480cf4cbeda6f6..a147ec9b9f8fc1 100644 --- a/Libraries/Utilities/deprecatedPropType.js +++ b/Libraries/Utilities/deprecatedPropType.js @@ -22,7 +22,6 @@ function deprecatedPropType( return function validate(props, propName, componentName, ...rest) { // Don't warn for native components. if ( - !global.RN$Bridgeless && !UIManager.getViewManagerConfig(componentName) && props[propName] !== undefined ) { diff --git a/Libraries/Utilities/differ/__tests__/matricesDiffer-test.js b/Libraries/Utilities/differ/__tests__/matricesDiffer-test.js deleted file mode 100644 index 26cc35ce3f5b24..00000000000000 --- a/Libraries/Utilities/differ/__tests__/matricesDiffer-test.js +++ /dev/null @@ -1,45 +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. - * - * @format - * @emails oncall+react_native - */ - -'use strict'; - -const matricesDiffer = require('../matricesDiffer'); - -describe('matricesDiffer', function() { - it('diffs matrices with single element', () => { - var x = [1]; - var y = [2]; - expect(matricesDiffer(x, y)).toBe(true); - - x = [1]; - y = [1]; - expect(matricesDiffer(x, y)).toBe(false); - }); - - it('diffs matrices with different number of elements', () => { - var x = [1, 1, 1, 1]; - var y = [1, 1, 1, 2]; - expect(matricesDiffer(x, y)).toBe(true); - }); - - it('diffs matrices with 16 elements', () => { - var x = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]; - var y = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]; - expect(matricesDiffer(x, y)).toBe(false); - - x = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]; - y = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1]; - expect(matricesDiffer(x, y)).toBe(true); - - x = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]; - y = [2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]; - expect(matricesDiffer(x, y)).toBe(true); - }); -}); diff --git a/Libraries/Utilities/differ/matricesDiffer.js b/Libraries/Utilities/differ/matricesDiffer.js index 1726ad361e37d2..ade2a5fc3f9246 100644 --- a/Libraries/Utilities/differ/matricesDiffer.js +++ b/Libraries/Utilities/differ/matricesDiffer.js @@ -30,7 +30,6 @@ const matricesDiffer = function(one, two) { one[14] !== two[14] || one[5] !== two[5] || one[10] !== two[10] || - one[0] !== two[0] || one[1] !== two[1] || one[2] !== two[2] || one[3] !== two[3] || diff --git a/Libraries/Utilities/dismissKeyboard.js b/Libraries/Utilities/dismissKeyboard.js index 16625a98894d65..98a5cda003ab63 100644 --- a/Libraries/Utilities/dismissKeyboard.js +++ b/Libraries/Utilities/dismissKeyboard.js @@ -15,7 +15,7 @@ const TextInputState = require('../Components/TextInput/TextInputState'); function dismissKeyboard() { - TextInputState.blurTextInput(TextInputState.currentlyFocusedInput()); + TextInputState.blurTextInput(TextInputState.currentlyFocusedField()); } module.exports = dismissKeyboard; diff --git a/Libraries/Utilities/infoLog.js b/Libraries/Utilities/infoLog.js index 6cac4bd149bc67..fd90c86b97038b 100644 --- a/Libraries/Utilities/infoLog.js +++ b/Libraries/Utilities/infoLog.js @@ -5,7 +5,6 @@ * LICENSE file in the root directory of this source tree. * * @format - * @flow strict */ 'use strict'; @@ -13,7 +12,7 @@ /** * Intentional info-level logging for clear separation from ad-hoc console debug logging. */ -function infoLog(...args: Array): void { +function infoLog(...args) { return console.log(...args); } diff --git a/Libraries/Utilities/registerGeneratedViewConfig.js b/Libraries/Utilities/registerGeneratedViewConfig.js index 947b3b06642b72..7ce2c2f01f39de 100644 --- a/Libraries/Utilities/registerGeneratedViewConfig.js +++ b/Libraries/Utilities/registerGeneratedViewConfig.js @@ -50,25 +50,25 @@ function registerGeneratedViewConfig( const mergedViewConfig = { uiViewClassName: componentName, Commands: {}, - /* $FlowFixMe(>=0.122.0 site=react_native_fb) This comment suppresses an - * error found when Flow v0.122.0 was deployed. To see the error, delete - * this comment and run Flow. */ bubblingEventTypes: { ...ReactNativeViewViewConfig.bubblingEventTypes, + /* $FlowFixMe(>=0.111.0 site=react_native_fb) This comment suppresses an + * error found when Flow v0.111 was deployed. To see the error, delete + * this comment and run Flow. */ ...(viewConfig.bubblingEventTypes || {}), }, - /* $FlowFixMe(>=0.122.0 site=react_native_fb) This comment suppresses an - * error found when Flow v0.122.0 was deployed. To see the error, delete - * this comment and run Flow. */ directEventTypes: { ...ReactNativeViewViewConfig.directEventTypes, + /* $FlowFixMe(>=0.111.0 site=react_native_fb) This comment suppresses an + * error found when Flow v0.111 was deployed. To see the error, delete + * this comment and run Flow. */ ...(viewConfig.directEventTypes || {}), }, - /* $FlowFixMe(>=0.122.0 site=react_native_fb) This comment suppresses an - * error found when Flow v0.122.0 was deployed. To see the error, delete - * this comment and run Flow. */ validAttributes: { ...ReactNativeViewViewConfig.validAttributes, + /* $FlowFixMe(>=0.111.0 site=react_native_fb) This comment suppresses an + * error found when Flow v0.111 was deployed. To see the error, delete + * this comment and run Flow. */ ...(viewConfig.validAttributes || {}), }, }; diff --git a/Libraries/Utilities/stringifySafe.js b/Libraries/Utilities/stringifySafe.js index effeedcd2994dc..d562a911e976ca 100644 --- a/Libraries/Utilities/stringifySafe.js +++ b/Libraries/Utilities/stringifySafe.js @@ -5,117 +5,46 @@ * LICENSE file in the root directory of this source tree. * * @format - * @flow strict-local + * @flow */ 'use strict'; -import invariant from 'invariant'; - /** * Tries to stringify with JSON.stringify and toString, but catches exceptions * (e.g. from circular objects) and always returns a string and never throws. */ -export function createStringifySafeWithLimits(limits: {| - maxDepth?: number, - maxStringLimit?: number, - maxArrayLimit?: number, - maxObjectKeysLimit?: number, -|}): mixed => string { - const { - maxDepth = Number.POSITIVE_INFINITY, - maxStringLimit = Number.POSITIVE_INFINITY, - maxArrayLimit = Number.POSITIVE_INFINITY, - maxObjectKeysLimit = Number.POSITIVE_INFINITY, - } = limits; - const stack = []; - function replacer(key: string, value: mixed): mixed { - while (stack.length && this !== stack[0]) { - stack.shift(); - } - - if (typeof value === 'string') { - const truncatedString = '...(truncated)...'; - if (value.length > maxStringLimit + truncatedString.length) { - return value.substring(0, maxStringLimit) + truncatedString; - } - return value; - } - if (typeof value !== 'object' || value === null) { - return value; +function stringifySafe(arg: any): string { + let ret; + const type = typeof arg; + if (arg === undefined) { + ret = 'undefined'; + } else if (arg === null) { + ret = 'null'; + } else if (type === 'string') { + ret = '"' + arg + '"'; + } else if (type === 'function') { + try { + ret = arg.toString(); + } catch (e) { + ret = '[function unknown]'; } - - let retval = value; - if (Array.isArray(value)) { - if (stack.length >= maxDepth) { - retval = `[ ... array with ${value.length} values ... ]`; - } else if (value.length > maxArrayLimit) { - retval = value - .slice(0, maxArrayLimit) - .concat([ - `... extra ${value.length - maxArrayLimit} values truncated ...`, - ]); - } - } else { - // Add refinement after Array.isArray call. - invariant(typeof value === 'object', 'This was already found earlier'); - let keys = Object.keys(value); - if (stack.length >= maxDepth) { - retval = `{ ... object with ${keys.length} keys ... }`; - } else if (keys.length > maxObjectKeysLimit) { - // Return a sample of the keys. - retval = {}; - for (let k of keys.slice(0, maxObjectKeysLimit)) { - retval[k] = value[k]; - } - const truncatedKey = '...(truncated keys)...'; - retval[truncatedKey] = keys.length - maxObjectKeysLimit; + } else if (arg instanceof Error) { + ret = arg.name + ': ' + arg.message; + } else { + // Perform a try catch, just in case the object has a circular + // reference or stringify throws for some other reason. + try { + ret = JSON.stringify(arg); + } catch (e) { + if (typeof arg.toString === 'function') { + try { + ret = arg.toString(); + } catch (E) {} } } - stack.unshift(retval); - return retval; } - - return function stringifySafe(arg: mixed): string { - if (arg === undefined) { - return 'undefined'; - } else if (arg === null) { - return 'null'; - } else if (typeof arg === 'function') { - try { - return arg.toString(); - } catch (e) { - return '[function unknown]'; - } - } else if (arg instanceof Error) { - return arg.name + ': ' + arg.message; - } else { - // Perform a try catch, just in case the object has a circular - // reference or stringify throws for some other reason. - try { - const ret = JSON.stringify(arg, replacer); - if (ret === undefined) { - return '["' + typeof arg + '" failed to stringify]'; - } - return ret; - } catch (e) { - if (typeof arg.toString === 'function') { - try { - // $FlowFixMe: toString shouldn't take any arguments in general. - return arg.toString(); - } catch (E) {} - } - } - } - return '["' + typeof arg + '" failed to stringify]'; - }; + return ret || '["' + type + '" failed to stringify]'; } -const stringifySafe: mixed => string = createStringifySafeWithLimits({ - maxDepth: 10, - maxStringLimit: 100, - maxArrayLimit: 50, - maxObjectKeysLimit: 50, -}); - -export default stringifySafe; +module.exports = stringifySafe; diff --git a/Libraries/Utilities/useWindowDimensions.js b/Libraries/Utilities/useWindowDimensions.js index f298649c943ccc..3de619a5eab877 100644 --- a/Libraries/Utilities/useWindowDimensions.js +++ b/Libraries/Utilities/useWindowDimensions.js @@ -15,26 +15,19 @@ import {type DisplayMetrics} from './NativeDeviceInfo'; import {useEffect, useState} from 'react'; export default function useWindowDimensions(): DisplayMetrics { - const [dimensions, setDimensions] = useState(() => Dimensions.get('window')); + const [dims, setDims] = useState(() => Dimensions.get('window')); useEffect(() => { function handleChange({window}) { - if ( - dimensions.width !== window.width || - dimensions.height !== window.height || - dimensions.scale !== window.scale || - dimensions.fontScale !== window.fontScale - ) { - setDimensions(window); - } + setDims(window); } Dimensions.addEventListener('change', handleChange); // We might have missed an update between calling `get` in render and // `addEventListener` in this handler, so we set it here. If there was // no change, React will filter out this update as a no-op. - handleChange({window: Dimensions.get('window')}); + setDims(Dimensions.get('window')); return () => { Dimensions.removeEventListener('change', handleChange); }; - }, [dimensions]); - return dimensions; + }, []); + return dims; } diff --git a/Libraries/Vibration/RCTVibration.mm b/Libraries/Vibration/RCTVibration.mm index 2bbf168acd0d9e..f78599df385774 100644 --- a/Libraries/Vibration/RCTVibration.mm +++ b/Libraries/Vibration/RCTVibration.mm @@ -30,12 +30,10 @@ - (void)vibrate [self vibrate]; } -- (std::shared_ptr) - getTurboModuleWithJsInvoker:(std::shared_ptr)jsInvoker - nativeInvoker:(std::shared_ptr)nativeInvoker - perfLogger:(id)perfLogger +- (std::shared_ptr)getTurboModuleWithJsInvoker: + (std::shared_ptr)jsInvoker { - return std::make_shared(self, jsInvoker, nativeInvoker, perfLogger); + return std::make_shared(self, jsInvoker); } RCT_EXPORT_METHOD(vibrateByPattern:(NSArray *)pattern diff --git a/Libraries/Vibration/React-RCTVibration.podspec b/Libraries/Vibration/React-RCTVibration.podspec index 4b4bb0512eae0e..92cc50e2770445 100644 --- a/Libraries/Vibration/React-RCTVibration.podspec +++ b/Libraries/Vibration/React-RCTVibration.podspec @@ -17,17 +17,17 @@ else end folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32' -folly_version = '2020.01.13.00' +folly_version = '2018.10.22.00' Pod::Spec.new do |s| s.name = "React-RCTVibration" s.version = version s.summary = "An API for controlling the vibration hardware of the device." - s.homepage = "https://reactnative.dev/" - s.documentation_url = "https://reactnative.dev/docs/vibration" + s.homepage = "http://facebook.github.io/react-native/" + s.documentation_url = "https://facebook.github.io/react-native/docs/vibration" s.license = package["license"] s.author = "Facebook, Inc. and its affiliates" - s.platforms = { :ios => "10.0", :tvos => "10.0", :osx => "10.13" } # TODO(macOS GH#214) + s.platforms = { :ios => "9.0", :tvos => "9.2", :osx => "10.13" } # TODO(macOS GH#214) s.compiler_flags = folly_compiler_flags + ' -Wno-nullability-completeness' s.source = source s.source_files = "*.{m,mm}" @@ -43,6 +43,5 @@ Pod::Spec.new do |s| s.dependency "RCT-Folly", folly_version s.dependency "FBReactNativeSpec", version s.dependency "ReactCommon/turbomodule/core", version - s.dependency "React-jsi", version s.dependency "React-Core/RCTVibrationHeaders", version end diff --git a/Libraries/Vibration/Vibration.js b/Libraries/Vibration/Vibration.js index 4a2d8444ea702b..6165258ddfffa6 100644 --- a/Libraries/Vibration/Vibration.js +++ b/Libraries/Vibration/Vibration.js @@ -17,7 +17,7 @@ const Platform = require('../Utilities/Platform'); /** * Vibration API * - * See https://reactnative.dev/docs/vibration.html + * See https://facebook.github.io/react-native/docs/vibration.html */ let _vibrating: boolean = false; @@ -68,7 +68,7 @@ const Vibration = { /** * Trigger a vibration with specified `pattern`. * - * See https://reactnative.dev/docs/vibration.html#vibrate + * See https://facebook.github.io/react-native/docs/vibration.html#vibrate */ vibrate: function( pattern: number | Array = _default_vibration_length, @@ -98,7 +98,7 @@ const Vibration = { /** * Stop vibration * - * See https://reactnative.dev/docs/vibration.html#cancel + * See https://facebook.github.io/react-native/docs/vibration.html#cancel */ cancel: function() { if (Platform.OS === 'ios') { diff --git a/Libraries/WebSocket/RCTReconnectingWebSocket.m b/Libraries/WebSocket/RCTReconnectingWebSocket.m index cd85e9b81ea654..6c6401ee91f6d2 100644 --- a/Libraries/WebSocket/RCTReconnectingWebSocket.m +++ b/Libraries/WebSocket/RCTReconnectingWebSocket.m @@ -20,7 +20,6 @@ @interface RCTReconnectingWebSocket () @implementation RCTReconnectingWebSocket { NSURL *_url; RCTSRWebSocket *_socket; - BOOL _stopped; } - (instancetype)initWithURL:(NSURL *)url queue:(dispatch_queue_t)queue @@ -45,7 +44,6 @@ - (void)send:(id)data - (void)start { [self stop]; - _stopped = NO; _socket = [[RCTSRWebSocket alloc] initWithURL:_url]; _socket.delegate = self; [_socket setDelegateDispatchQueue:_delegateDispatchQueue]; @@ -54,7 +52,6 @@ - (void)start - (void)stop { - _stopped = YES; _socket.delegate = nil; [_socket closeWithCode:1000 reason:@"Invalidated"]; _socket = nil; @@ -67,17 +64,11 @@ - (void)webSocket:(RCTSRWebSocket *)webSocket didReceiveMessage:(id)message - (void)reconnect { - if (_stopped) { - return; - } - __weak RCTSRWebSocket *socket = _socket; - __weak __typeof(self) weakSelf = self; - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ - [weakSelf start]; + [self start]; if (!socket) { - [weakSelf reconnect]; + [self reconnect]; } }); } diff --git a/Libraries/WebSocket/WebSocket.js b/Libraries/WebSocket/WebSocket.js index 0b051c48e4cd9b..a1679bd50accd1 100644 --- a/Libraries/WebSocket/WebSocket.js +++ b/Libraries/WebSocket/WebSocket.js @@ -14,6 +14,7 @@ const Blob = require('../Blob/Blob'); const BlobManager = require('../Blob/BlobManager'); const EventTarget = require('event-target-shim'); const NativeEventEmitter = require('../EventEmitter/NativeEventEmitter'); +const Platform = require('../Utilities/Platform'); const WebSocketEvent = require('./WebSocketEvent'); const base64 = require('base64-js'); diff --git a/Libraries/YellowBox/Data/YellowBoxCategory.js b/Libraries/YellowBox/Data/YellowBoxCategory.js new file mode 100644 index 00000000000000..e4ad9234123b41 --- /dev/null +++ b/Libraries/YellowBox/Data/YellowBoxCategory.js @@ -0,0 +1,155 @@ +/** + * 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. + * + * @flow strict-local + * @format + */ + +'use strict'; + +const React = require('react'); +const Text = require('../../Text/Text'); +const UTFSequence = require('../../UTFSequence'); + +const stringifySafe = require('../../Utilities/stringifySafe'); + +import type {TextStyleProp} from '../../StyleSheet/StyleSheet'; + +export type Category = string; +export type Message = $ReadOnly<{| + content: string, + substitutions: $ReadOnlyArray< + $ReadOnly<{| + length: number, + offset: number, + |}>, + >, +|}>; + +const SUBSTITUTION = UTFSequence.BOM + '%s'; + +const YellowBoxCategory = { + parse( + args: $ReadOnlyArray, + ): $ReadOnly<{| + category: Category, + message: Message, + |}> { + const categoryParts = []; + const contentParts = []; + const substitutionOffsets = []; + + const remaining = [...args]; + + if (typeof remaining[0] === 'string') { + const formatString = String(remaining.shift()); + const formatStringParts = formatString.split('%s'); + const substitutionCount = formatStringParts.length - 1; + const substitutions = remaining.splice(0, substitutionCount); + + let categoryString = ''; + let contentString = ''; + + let substitutionIndex = 0; + for (const formatStringPart of formatStringParts) { + categoryString += formatStringPart; + contentString += formatStringPart; + + if (substitutionIndex < substitutionCount) { + if (substitutionIndex < substitutions.length) { + // Don't stringify a string type. + // It adds quotation mark wrappers around the string, + // which causes the yellow box to look odd. + const substitution = + typeof substitutions[substitutionIndex] === 'string' + ? substitutions[substitutionIndex] + : stringifySafe(substitutions[substitutionIndex]); + substitutionOffsets.push({ + length: substitution.length, + offset: contentString.length, + }); + + categoryString += SUBSTITUTION; + contentString += substitution; + } else { + substitutionOffsets.push({ + length: 2, + offset: contentString.length, + }); + + categoryString += '%s'; + contentString += '%s'; + } + + substitutionIndex++; + } + } + + categoryParts.push(categoryString); + contentParts.push(contentString); + } + + const remainingArgs = remaining.map(arg => { + // Don't stringify a string type. + // It adds quotation mark wrappers around the string, + // which causes the yellow box to look odd. + return typeof arg === 'string' ? arg : stringifySafe(arg); + }); + categoryParts.push(...remainingArgs); + contentParts.push(...remainingArgs); + + return { + category: categoryParts.join(' '), + message: { + content: contentParts.join(' '), + substitutions: substitutionOffsets, + }, + }; + }, + + render( + {content, substitutions}: Message, + substitutionStyle: TextStyleProp, + ): React.Node { + const elements = []; + + const lastOffset = substitutions.reduce( + (prevOffset, substitution, index) => { + const key = String(index); + + if (substitution.offset > prevOffset) { + const prevPart = content.substr( + prevOffset, + substitution.offset - prevOffset, + ); + elements.push({prevPart}); + } + + const substititionPart = content.substr( + substitution.offset, + substitution.length, + ); + elements.push( + + {substititionPart} + , + ); + + return substitution.offset + substitution.length; + }, + 0, + ); + + if (lastOffset < content.length) { + const lastPart = content.substr(lastOffset); + elements.push({lastPart}); + } + + return elements; + }, +}; + +module.exports = YellowBoxCategory; diff --git a/Libraries/YellowBox/Data/YellowBoxRegistry.js b/Libraries/YellowBox/Data/YellowBoxRegistry.js new file mode 100644 index 00000000000000..d430d3fbed792f --- /dev/null +++ b/Libraries/YellowBox/Data/YellowBoxRegistry.js @@ -0,0 +1,154 @@ +/** + * 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. + * + * @flow strict-local + * @format + */ + +'use strict'; + +const YellowBoxWarning = require('./YellowBoxWarning'); + +import type {Category, Message} from './YellowBoxCategory'; +import type {Stack} from './YellowBoxSymbolication'; +export type Registry = Map>; + +export type Observer = (registry: Registry) => void; + +export type IgnorePattern = string | RegExp; + +export type Subscription = $ReadOnly<{| + unsubscribe: () => void, +|}>; + +const observers: Set<{observer: Observer, ...}> = new Set(); +const ignorePatterns: Set = new Set(); +const registry: Registry = new Map(); + +let disabled = false; +let projection = new Map(); +let updateTimeout = null; + +function handleUpdate(): void { + projection = new Map(); + if (!disabled) { + for (const [category, warnings] of registry) { + const filtered = warnings.filter( + warning => !YellowBoxRegistry.isWarningIgnored(warning.message), + ); + if (filtered.length > 0) { + projection.set(category, filtered); + } + } + } + if (updateTimeout == null) { + updateTimeout = setImmediate(() => { + updateTimeout = null; + for (const {observer} of observers) { + observer(projection); + } + }); + } +} + +const YellowBoxRegistry = { + isWarningIgnored(message: Message): boolean { + for (const pattern of ignorePatterns) { + if (pattern instanceof RegExp && pattern.test(message.content)) { + return true; + } else if ( + typeof pattern === 'string' && + message.content.includes(pattern) + ) { + return true; + } + } + return false; + }, + add({ + category, + message, + stack, + }: $ReadOnly<{| + category: Category, + message: Message, + stack: Stack, + |}>): void { + let warnings = registry.get(category); + if (warnings == null) { + warnings = []; + } + warnings = [...warnings, new YellowBoxWarning(message, stack)]; + + registry.delete(category); + registry.set(category, warnings); + + handleUpdate(); + }, + + delete(category: Category): void { + if (registry.has(category)) { + registry.delete(category); + handleUpdate(); + } + }, + + clear(): void { + if (registry.size > 0) { + registry.clear(); + handleUpdate(); + } + }, + + addIgnorePatterns(patterns: $ReadOnlyArray): void { + const newPatterns = patterns.filter((pattern: IgnorePattern) => { + if (pattern instanceof RegExp) { + for (const existingPattern of ignorePatterns.entries()) { + if ( + existingPattern instanceof RegExp && + existingPattern.toString() === pattern.toString() + ) { + return false; + } + } + return true; + } + return !ignorePatterns.has(pattern); + }); + if (newPatterns.length === 0) { + return; + } + for (const pattern of newPatterns) { + ignorePatterns.add(pattern); + } + handleUpdate(); + }, + + setDisabled(value: boolean): void { + if (value === disabled) { + return; + } + disabled = value; + handleUpdate(); + }, + + isDisabled(): boolean { + return disabled; + }, + + observe(observer: Observer): Subscription { + const subscription = {observer}; + observers.add(subscription); + observer(projection); + return { + unsubscribe(): void { + observers.delete(subscription); + }, + }; + }, +}; + +module.exports = YellowBoxRegistry; diff --git a/Libraries/YellowBox/Data/YellowBoxSymbolication.js b/Libraries/YellowBox/Data/YellowBoxSymbolication.js new file mode 100644 index 00000000000000..a33c3501e9bbb8 --- /dev/null +++ b/Libraries/YellowBox/Data/YellowBoxSymbolication.js @@ -0,0 +1,89 @@ +/** + * 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. + * + * @flow strict-local + * @format + */ + +'use strict'; + +const symbolicateStackTrace = require('../../Core/Devtools/symbolicateStackTrace'); + +import type {StackFrame} from '../../Core/NativeExceptionsManager'; +import type {SymbolicatedStackTrace} from '../../Core/Devtools/symbolicateStackTrace'; + +type CacheKey = string; + +export type Stack = Array; + +const cache: Map> = new Map(); + +const YellowBoxSymbolication = { + delete(stack: Stack): void { + cache.delete(getCacheKey(stack)); + }, + + symbolicate(stack: Stack): Promise { + const key = getCacheKey(stack); + + let promise = cache.get(key); + if (promise == null) { + promise = symbolicateStackTrace(stack).then(sanitize); + cache.set(key, promise); + } + + return promise; + }, +}; + +const getCacheKey = (stack: Stack): CacheKey => { + return JSON.stringify(stack); +}; + +/** + * Sanitize because sometimes, `symbolicateStackTrace` gives us invalid values. + */ +const sanitize = (data: SymbolicatedStackTrace): Stack => { + const maybeStack = data?.stack; + if (!Array.isArray(maybeStack)) { + throw new Error('Expected stack to be an array.'); + } + const stack = []; + for (const maybeFrame of maybeStack) { + if (typeof maybeFrame !== 'object' || maybeFrame == null) { + throw new Error('Expected each stack frame to be an object.'); + } + if (typeof maybeFrame.column !== 'number' && maybeFrame.column != null) { + throw new Error('Expected stack frame `column` to be a nullable number.'); + } + if (typeof maybeFrame.file !== 'string') { + throw new Error('Expected stack frame `file` to be a string.'); + } + if (typeof maybeFrame.lineNumber !== 'number') { + throw new Error('Expected stack frame `lineNumber` to be a number.'); + } + if (typeof maybeFrame.methodName !== 'string') { + throw new Error('Expected stack frame `methodName` to be a string.'); + } + let collapse = false; + if ('collapse' in maybeFrame) { + if (typeof maybeFrame.collapse !== 'boolean') { + throw new Error('Expected stack frame `collapse` to be a boolean.'); + } + collapse = maybeFrame.collapse; + } + stack.push({ + column: maybeFrame.column, + file: maybeFrame.file, + lineNumber: maybeFrame.lineNumber, + methodName: maybeFrame.methodName, + collapse, + }); + } + return stack; +}; + +module.exports = YellowBoxSymbolication; diff --git a/Libraries/YellowBox/Data/YellowBoxWarning.js b/Libraries/YellowBox/Data/YellowBoxWarning.js new file mode 100644 index 00000000000000..7b86eb4a1e94c4 --- /dev/null +++ b/Libraries/YellowBox/Data/YellowBoxWarning.js @@ -0,0 +1,126 @@ +/** + * 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. + * + * @flow strict-local + * @format + */ + +'use strict'; + +const YellowBoxCategory = require('./YellowBoxCategory'); +const YellowBoxSymbolication = require('./YellowBoxSymbolication'); + +const parseErrorStack = require('../../Core/Devtools/parseErrorStack'); + +import type {Category, Message} from './YellowBoxCategory'; +import type {Stack} from './YellowBoxSymbolication'; + +export type SymbolicationRequest = $ReadOnly<{| + abort: () => void, +|}>; + +class YellowBoxWarning { + static parse({ + args, + }: $ReadOnly<{| + args: $ReadOnlyArray, + |}>): {| + category: Category, + message: Message, + stack: Stack, + |} { + let mutableArgs: Array = [...args]; + + // This detects a very narrow case of a simple warning string, + // with a component stack appended by React DevTools. + // In this case, we convert the component stack to a substituion, + // because YellowBox formats those pleasantly. + // If there are other subtituations or formatting, + // we bail to avoid potentially corrupting the data. + if (mutableArgs.length === 2) { + const first = mutableArgs[0]; + const last = mutableArgs[1]; + if ( + typeof first === 'string' && + typeof last === 'string' && + /^\n {4}in/.exec(last) + ) { + mutableArgs[0] = first + '%s'; + } + } + + return { + ...YellowBoxCategory.parse(mutableArgs), + // TODO: Use Error.captureStackTrace on Hermes + stack: parseErrorStack(new Error()), + }; + } + + message: Message; + stack: Stack; + symbolicated: + | $ReadOnly<{|error: null, stack: null, status: 'NONE'|}> + | $ReadOnly<{|error: null, stack: null, status: 'PENDING'|}> + | $ReadOnly<{|error: null, stack: Stack, status: 'COMPLETE'|}> + | $ReadOnly<{|error: Error, stack: null, status: 'FAILED'|}> = { + error: null, + stack: null, + status: 'NONE', + }; + + constructor(message: Message, stack: Stack) { + this.message = message; + this.stack = stack; + } + + getAvailableStack(): Stack { + return this.symbolicated.status === 'COMPLETE' + ? this.symbolicated.stack + : this.stack; + } + + retrySymbolicate(callback: () => void): SymbolicationRequest { + YellowBoxSymbolication.delete(this.stack); + return this.symbolicate(callback); + } + + symbolicate(callback: () => void): SymbolicationRequest { + let aborted = false; + + if (this.symbolicated.status !== 'COMPLETE') { + const updateStatus = (error: ?Error, stack: ?Stack): void => { + if (error != null) { + this.symbolicated = {error, stack: null, status: 'FAILED'}; + } else if (stack != null) { + this.symbolicated = {error: null, stack, status: 'COMPLETE'}; + } else { + this.symbolicated = {error: null, stack: null, status: 'PENDING'}; + } + if (!aborted) { + callback(); + } + }; + + updateStatus(null, null); + YellowBoxSymbolication.symbolicate(this.stack).then( + stack => { + updateStatus(null, stack); + }, + error => { + updateStatus(error, null); + }, + ); + } + + return { + abort(): void { + aborted = true; + }, + }; + } +} + +module.exports = YellowBoxWarning; diff --git a/Libraries/YellowBox/Data/__tests__/YellowBoxCategory-test.js b/Libraries/YellowBox/Data/__tests__/YellowBoxCategory-test.js new file mode 100644 index 00000000000000..5a325dc92e7c79 --- /dev/null +++ b/Libraries/YellowBox/Data/__tests__/YellowBoxCategory-test.js @@ -0,0 +1,185 @@ +/** + * 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. + * + * @emails oncall+react_native + * @format + * @flow strict-local + */ + +'use strict'; + +const YellowBoxCategory = require('../YellowBoxCategory'); + +describe('YellowBoxCategory', () => { + it('parses strings', () => { + expect(YellowBoxCategory.parse(['A'])).toEqual({ + category: 'A', + message: { + content: 'A', + substitutions: [], + }, + }); + }); + + it('parses strings with arguments', () => { + expect(YellowBoxCategory.parse(['A', 'B', 'C'])).toEqual({ + category: 'A B C', + message: { + content: 'A B C', + substitutions: [], + }, + }); + }); + + it('parses formatted strings', () => { + expect(YellowBoxCategory.parse(['%s', 'A'])).toEqual({ + category: '\ufeff%s', + message: { + content: 'A', + substitutions: [ + { + length: 1, + offset: 0, + }, + ], + }, + }); + }); + + it('parses formatted strings with insufficient arguments', () => { + expect(YellowBoxCategory.parse(['%s %s', 'A'])).toEqual({ + category: '\ufeff%s %s', + message: { + content: 'A %s', + substitutions: [ + { + length: 1, + offset: 0, + }, + { + length: 2, + offset: 2, + }, + ], + }, + }); + }); + + it('parses formatted strings with excess arguments', () => { + expect(YellowBoxCategory.parse(['%s', 'A', 'B'])).toEqual({ + category: '\ufeff%s B', + message: { + content: 'A B', + substitutions: [ + { + length: 1, + offset: 0, + }, + ], + }, + }); + }); + + it('treats "%s" in arguments as literals', () => { + expect(YellowBoxCategory.parse(['%s', '%s', 'A'])).toEqual({ + category: '\ufeff%s A', + message: { + content: '%s A', + substitutions: [ + { + length: 2, + offset: 0, + }, + ], + }, + }); + }); + + it('renders content with no substitutions', () => { + expect( + YellowBoxCategory.render( + {content: 'A', substitutions: []}, + {fontWeight: 'bold'}, + ), + ).toMatchSnapshot(); + }); + + it('renders a single substitution', () => { + expect( + YellowBoxCategory.render( + { + content: 'A', + substitutions: [ + { + length: 1, + offset: 0, + }, + ], + }, + {fontWeight: 'bold'}, + ), + ).toMatchSnapshot(); + }); + + it('renders multiple substitutions', () => { + expect( + YellowBoxCategory.render( + { + content: 'A B C', + substitutions: [ + { + length: 1, + offset: 0, + }, + { + length: 1, + offset: 2, + }, + { + length: 1, + offset: 4, + }, + ], + }, + {fontWeight: 'bold'}, + ), + ).toMatchSnapshot(); + }); + + it('renders substitutions with leading content', () => { + expect( + YellowBoxCategory.render( + { + content: '!A', + substitutions: [ + { + length: 1, + offset: 1, + }, + ], + }, + {fontWeight: 'bold'}, + ), + ).toMatchSnapshot(); + }); + + it('renders substitutions with trailing content', () => { + expect( + YellowBoxCategory.render( + { + content: 'A!', + substitutions: [ + { + length: 1, + offset: 0, + }, + ], + }, + {fontWeight: 'bold'}, + ), + ).toMatchSnapshot(); + }); +}); diff --git a/Libraries/YellowBox/Data/__tests__/YellowBoxRegistry-test.js b/Libraries/YellowBox/Data/__tests__/YellowBoxRegistry-test.js new file mode 100644 index 00000000000000..a93f96befd90e4 --- /dev/null +++ b/Libraries/YellowBox/Data/__tests__/YellowBoxRegistry-test.js @@ -0,0 +1,281 @@ +/** + * 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. + * + * @emails oncall+react_native + * @format + * @flow strict-local + */ + +'use strict'; + +const YellowBoxWarning = require('../YellowBoxWarning'); +const YellowBoxCategory = require('../YellowBoxCategory'); +const YellowBoxRegistry = require('../YellowBoxRegistry'); + +const registry = () => { + const observer = jest.fn(); + YellowBoxRegistry.observe(observer).unsubscribe(); + return observer.mock.calls[0][0]; +}; + +const observe = () => { + const observer = jest.fn(); + return { + observer, + subscription: YellowBoxRegistry.observe(observer), + }; +}; + +describe('YellowBoxRegistry', () => { + beforeEach(() => { + jest.resetModules(); + }); + + it('adds and deletes warnings', () => { + YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['A']})); + const {category: categoryA} = YellowBoxCategory.parse(['A']); + + expect(registry().size).toBe(1); + expect(registry().get(categoryA)).not.toBe(undefined); + + YellowBoxRegistry.delete(categoryA); + expect(registry().size).toBe(0); + expect(registry().get(categoryA)).toBe(undefined); + }); + + it('clears all warnings', () => { + YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['A']})); + YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['B']})); + YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['C']})); + + expect(registry().size).toBe(3); + + YellowBoxRegistry.clear(); + expect(registry().size).toBe(0); + }); + + it('sorts warnings in chronological order', () => { + YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['A']})); + YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['B']})); + YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['C']})); + + const {category: categoryA} = YellowBoxCategory.parse(['A']); + const {category: categoryB} = YellowBoxCategory.parse(['B']); + const {category: categoryC} = YellowBoxCategory.parse(['C']); + + expect(Array.from(registry().keys())).toEqual([ + categoryA, + categoryB, + categoryC, + ]); + + YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['A']})); + + // Expect `A` to be hoisted to the end of the registry. + expect(Array.from(registry().keys())).toEqual([ + categoryB, + categoryC, + categoryA, + ]); + }); + + it('ignores warnings matching patterns', () => { + YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['A!']})); + YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['B?']})); + YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['C!']})); + expect(registry().size).toBe(3); + + YellowBoxRegistry.addIgnorePatterns(['!']); + expect(registry().size).toBe(1); + + YellowBoxRegistry.addIgnorePatterns(['?']); + expect(registry().size).toBe(0); + }); + + it('ignores warnings matching regexs or pattern', () => { + YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['There are 4 dogs']})); + YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['There are 3 cats']})); + YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['There are H cats']})); + expect(registry().size).toBe(3); + + YellowBoxRegistry.addIgnorePatterns(['dogs']); + expect(registry().size).toBe(2); + + YellowBoxRegistry.addIgnorePatterns([/There are \d+ cats/]); + expect(registry().size).toBe(1); + + YellowBoxRegistry.addIgnorePatterns(['cats']); + expect(registry().size).toBe(0); + }); + + it('ignores all warnings when disabled', () => { + YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['A!']})); + YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['B?']})); + YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['C!']})); + expect(registry().size).toBe(3); + + YellowBoxRegistry.setDisabled(true); + expect(registry().size).toBe(0); + + YellowBoxRegistry.setDisabled(false); + expect(registry().size).toBe(3); + }); + + it('groups warnings by simple categories', () => { + YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['A']})); + expect(registry().size).toBe(1); + + YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['A']})); + expect(registry().size).toBe(1); + + YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['B']})); + expect(registry().size).toBe(2); + }); + + it('groups warnings by format string categories', () => { + YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['%s', 'A']})); + expect(registry().size).toBe(1); + + YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['%s', 'B']})); + expect(registry().size).toBe(1); + + YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['A']})); + expect(registry().size).toBe(2); + + YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['B']})); + expect(registry().size).toBe(3); + }); + + it('groups warnings with consideration for arguments', () => { + YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['A', 'B']})); + expect(registry().size).toBe(1); + + YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['A', 'B']})); + expect(registry().size).toBe(1); + + YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['A', 'C']})); + expect(registry().size).toBe(2); + + YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['%s', 'A', 'A']})); + expect(registry().size).toBe(3); + + YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['%s', 'B', 'A']})); + expect(registry().size).toBe(3); + + YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['%s', 'B', 'B']})); + expect(registry().size).toBe(4); + }); + + it('does not ignore warnings formatted to start with "(ADVICE)"', () => { + YellowBoxRegistry.add( + YellowBoxWarning.parse({args: ['%s ...', '(ADVICE)']}), + ); + expect(registry().size).toBe(1); + }); + + it('immediately updates new observers', () => { + const {observer} = observe(); + + expect(observer.mock.calls.length).toBe(1); + expect(observer.mock.calls[0][0]).toBe(registry()); + }); + + it('sends batched updates asynchronously', () => { + const {observer} = observe(); + expect(observer.mock.calls.length).toBe(1); + + YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['A']})); + YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['B']})); + jest.runAllImmediates(); + expect(observer.mock.calls.length).toBe(2); + }); + + it('stops sending updates to unsubscribed observers', () => { + const {observer, subscription} = observe(); + subscription.unsubscribe(); + + expect(observer.mock.calls.length).toBe(1); + expect(observer.mock.calls[0][0]).toBe(registry()); + }); + + it('updates observers when a warning is added or deleted', () => { + const {observer} = observe(); + expect(observer.mock.calls.length).toBe(1); + + YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['A']})); + jest.runAllImmediates(); + expect(observer.mock.calls.length).toBe(2); + + const {category: categoryA} = YellowBoxCategory.parse(['A']); + YellowBoxRegistry.delete(categoryA); + jest.runAllImmediates(); + expect(observer.mock.calls.length).toBe(3); + + // Does nothing when category does not exist. + YellowBoxRegistry.delete(categoryA); + jest.runAllImmediates(); + expect(observer.mock.calls.length).toBe(3); + }); + + it('updates observers when cleared', () => { + const {observer} = observe(); + expect(observer.mock.calls.length).toBe(1); + + YellowBoxRegistry.add(YellowBoxWarning.parse({args: ['A']})); + jest.runAllImmediates(); + expect(observer.mock.calls.length).toBe(2); + + YellowBoxRegistry.clear(); + jest.runAllImmediates(); + expect(observer.mock.calls.length).toBe(3); + + // Does nothing when already empty. + YellowBoxRegistry.clear(); + jest.runAllImmediates(); + expect(observer.mock.calls.length).toBe(3); + }); + + it('updates observers when an ignore pattern is added', () => { + const {observer} = observe(); + expect(observer.mock.calls.length).toBe(1); + + YellowBoxRegistry.addIgnorePatterns(['?']); + jest.runAllImmediates(); + expect(observer.mock.calls.length).toBe(2); + + YellowBoxRegistry.addIgnorePatterns(['!']); + jest.runAllImmediates(); + expect(observer.mock.calls.length).toBe(3); + + // Does nothing for an existing ignore pattern. + YellowBoxRegistry.addIgnorePatterns(['!']); + jest.runAllImmediates(); + expect(observer.mock.calls.length).toBe(3); + }); + + it('updates observers when disabled or enabled', () => { + const {observer} = observe(); + expect(observer.mock.calls.length).toBe(1); + + YellowBoxRegistry.setDisabled(true); + jest.runAllImmediates(); + expect(observer.mock.calls.length).toBe(2); + + // Does nothing when already disabled. + YellowBoxRegistry.setDisabled(true); + jest.runAllImmediates(); + expect(observer.mock.calls.length).toBe(2); + + YellowBoxRegistry.setDisabled(false); + jest.runAllImmediates(); + expect(observer.mock.calls.length).toBe(3); + + // Does nothing when already enabled. + YellowBoxRegistry.setDisabled(false); + jest.runAllImmediates(); + expect(observer.mock.calls.length).toBe(3); + }); +}); diff --git a/Libraries/YellowBox/Data/__tests__/YellowBoxSymbolication-test.js b/Libraries/YellowBox/Data/__tests__/YellowBoxSymbolication-test.js new file mode 100644 index 00000000000000..f125ff380f040a --- /dev/null +++ b/Libraries/YellowBox/Data/__tests__/YellowBoxSymbolication-test.js @@ -0,0 +1,52 @@ +/** + * 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. + * + * @emails oncall+react_native + * @format + * @flow + */ + +'use strict'; + +import type {StackFrame} from '../../../Core/NativeExceptionsManager'; + +jest.mock('../../../Core/Devtools/symbolicateStackTrace'); + +const YellowBoxSymbolication = require('../YellowBoxSymbolication'); + +const symbolicateStackTrace: JestMockFn< + $ReadOnlyArray>, + Promise>, +> = (require('../../../Core/Devtools/symbolicateStackTrace'): any); + +const createStack = methodNames => + methodNames.map(methodName => ({ + column: null, + file: 'file://path/to/file.js', + lineNumber: 1, + methodName, + })); + +describe('YellowBoxSymbolication', () => { + beforeEach(() => { + jest.resetModules(); + symbolicateStackTrace.mockImplementation(async stack => stack); + }); + + it('symbolicates different stacks', () => { + YellowBoxSymbolication.symbolicate(createStack(['A', 'B', 'C'])); + YellowBoxSymbolication.symbolicate(createStack(['D', 'E', 'F'])); + + expect(symbolicateStackTrace.mock.calls.length).toBe(2); + }); + + it('batch symbolicates equivalent stacks', () => { + YellowBoxSymbolication.symbolicate(createStack(['A', 'B', 'C'])); + YellowBoxSymbolication.symbolicate(createStack(['A', 'B', 'C'])); + + expect(symbolicateStackTrace.mock.calls.length).toBe(1); + }); +}); diff --git a/Libraries/YellowBox/Data/__tests__/YellowBoxWarning-test.js b/Libraries/YellowBox/Data/__tests__/YellowBoxWarning-test.js new file mode 100644 index 00000000000000..3bbca34dd569e7 --- /dev/null +++ b/Libraries/YellowBox/Data/__tests__/YellowBoxWarning-test.js @@ -0,0 +1,126 @@ +/** + * 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. + * + * @emails oncall+react_native + * @format + * @flow + */ + +'use strict'; + +import type {StackFrame} from '../../../Core/NativeExceptionsManager'; + +jest.mock('../YellowBoxSymbolication'); + +const YellowBoxSymbolication: {| + symbolicate: JestMockFn< + $ReadOnlyArray>, + Promise>, + >, +|} = (require('../YellowBoxSymbolication'): any); +const YellowBoxWarning = require('../YellowBoxWarning'); + +const createStack = methodNames => + methodNames.map(methodName => ({ + column: null, + file: 'file://path/to/file.js', + lineNumber: 1, + methodName, + })); + +describe('YellowBoxWarning', () => { + beforeEach(() => { + jest.resetModules(); + + YellowBoxSymbolication.symbolicate.mockImplementation(async stack => + createStack(stack.map(frame => `S(${frame.methodName})`)), + ); + }); + + it('starts without a symbolicated stack', () => { + const warning = new YellowBoxWarning( + {content: '...', substitutions: []}, + createStack(['A', 'B', 'C']), + ); + + expect(warning.symbolicated).toEqual({ + error: null, + stack: null, + status: 'NONE', + }); + }); + + it('updates when symbolication is in progress', () => { + const warning = new YellowBoxWarning( + {content: '...', substitutions: []}, + createStack(['A', 'B', 'C']), + ); + const callback = jest.fn(); + warning.symbolicate(callback); + + expect(callback.mock.calls.length).toBe(1); + expect(warning.symbolicated).toEqual({ + error: null, + stack: null, + status: 'PENDING', + }); + }); + + it('updates when symbolication finishes', () => { + const warning = new YellowBoxWarning( + {content: '...', substitutions: []}, + createStack(['A', 'B', 'C']), + ); + const callback = jest.fn(); + warning.symbolicate(callback); + + jest.runAllTicks(); + + expect(callback.mock.calls.length).toBe(2); + expect(warning.symbolicated).toEqual({ + error: null, + stack: createStack(['S(A)', 'S(B)', 'S(C)']), + status: 'COMPLETE', + }); + }); + + it('updates when symbolication fails', () => { + const error = new Error('...'); + YellowBoxSymbolication.symbolicate.mockImplementation(async stack => { + throw error; + }); + + const warning = new YellowBoxWarning( + {content: '...', substitutions: []}, + createStack(['A', 'B', 'C']), + ); + const callback = jest.fn(); + warning.symbolicate(callback); + + jest.runAllTicks(); + + expect(callback.mock.calls.length).toBe(2); + expect(warning.symbolicated).toEqual({ + error, + stack: null, + status: 'FAILED', + }); + }); + + it('does not update aborted requests', () => { + const warning = new YellowBoxWarning( + {content: '...', substitutions: []}, + createStack(['A', 'B', 'C']), + ); + const callback = jest.fn(); + const request = warning.symbolicate(callback); + request.abort(); + + jest.runAllTicks(); + + expect(callback.mock.calls.length).toBe(1); + }); +}); diff --git a/Libraries/YellowBox/Data/__tests__/__snapshots__/YellowBoxCategory-test.js.snap b/Libraries/YellowBox/Data/__tests__/__snapshots__/YellowBoxCategory-test.js.snap new file mode 100644 index 00000000000000..b72d36d98181c5 --- /dev/null +++ b/Libraries/YellowBox/Data/__tests__/__snapshots__/YellowBoxCategory-test.js.snap @@ -0,0 +1,95 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`YellowBoxCategory renders a single substitution 1`] = ` +Array [ + + A + , +] +`; + +exports[`YellowBoxCategory renders content with no substitutions 1`] = ` +Array [ + + A + , +] +`; + +exports[`YellowBoxCategory renders multiple substitutions 1`] = ` +Array [ + + A + , + + + , + + B + , + + + , + + C + , +] +`; + +exports[`YellowBoxCategory renders substitutions with leading content 1`] = ` +Array [ + + ! + , + + A + , +] +`; + +exports[`YellowBoxCategory renders substitutions with trailing content 1`] = ` +Array [ + + A + , + + ! + , +] +`; diff --git a/Libraries/YellowBox/UI/YellowBoxButton.js b/Libraries/YellowBox/UI/YellowBoxButton.js new file mode 100644 index 00000000000000..67885298f6c56c --- /dev/null +++ b/Libraries/YellowBox/UI/YellowBoxButton.js @@ -0,0 +1,53 @@ +/** + * 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. + * + * @flow strict-local + * @format + */ + +'use strict'; + +const React = require('react'); +const StyleSheet = require('../../StyleSheet/StyleSheet'); +const Text = require('../../Text/Text'); +const YellowBoxPressable = require('./YellowBoxPressable'); +const YellowBoxStyle = require('./YellowBoxStyle'); + +import type {EdgeInsetsProp} from '../../StyleSheet/EdgeInsetsPropType'; + +type Props = $ReadOnly<{| + hitSlop?: ?EdgeInsetsProp, + label: string, + onPress: () => void, +|}>; + +const YellowBoxButton = (props: Props): React.Node => ( + + + {props.label} + + +); + +const styles = StyleSheet.create({ + root: { + borderRadius: 14, + height: 28, + justifyContent: 'center', + paddingHorizontal: 12, + }, + label: { + color: YellowBoxStyle.getTextColor(1), + fontSize: 12, + includeFontPadding: false, + lineHeight: 16, + }, +}); + +module.exports = YellowBoxButton; diff --git a/Libraries/YellowBox/UI/YellowBoxInspector.js b/Libraries/YellowBox/UI/YellowBoxInspector.js new file mode 100644 index 00000000000000..d70134612d52a6 --- /dev/null +++ b/Libraries/YellowBox/UI/YellowBoxInspector.js @@ -0,0 +1,213 @@ +/** + * 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. + * + * @flow strict-local + * @format + */ + +'use strict'; + +const Platform = require('../../Utilities/Platform'); +const React = require('react'); +const ScrollView = require('../../Components/ScrollView/ScrollView'); +const StyleSheet = require('../../StyleSheet/StyleSheet'); +const Text = require('../../Text/Text'); +const View = require('../../Components/View/View'); +const YellowBoxCategory = require('../Data/YellowBoxCategory'); +const YellowBoxInspectorFooter = require('./YellowBoxInspectorFooter'); +const YellowBoxInspectorHeader = require('./YellowBoxInspectorHeader'); +const YellowBoxInspectorSourceMapStatus = require('./YellowBoxInspectorSourceMapStatus'); +const YellowBoxInspectorStackFrame = require('./YellowBoxInspectorStackFrame'); +const YellowBoxStyle = require('./YellowBoxStyle'); + +const openFileInEditor = require('../../Core/Devtools/openFileInEditor'); + +import type YellowBoxWarning from '../Data/YellowBoxWarning'; +import type {SymbolicationRequest} from '../Data/YellowBoxWarning'; + +type Props = $ReadOnly<{| + onDismiss: () => void, + onMinimize: () => void, + warnings: $ReadOnlyArray, +|}>; + +type State = {| + selectedIndex: number, +|}; + +class YellowBoxInspector extends React.Component { + _symbolication: ?SymbolicationRequest; + + state: State = { + selectedIndex: 0, + }; + + render(): React.Node { + const {warnings} = this.props; + const {selectedIndex} = this.state; + + const warning = warnings[selectedIndex]; + + return ( + + + + + + Warning + + + {YellowBoxCategory.render( + warning.message, + styles.substitutionText, + )} + + + + + Stack + + + {warning.getAvailableStack().map((frame, index) => { + const {file, lineNumber, collapse = false} = frame; + if (collapse) { + return null; + } + return ( + { + openFileInEditor(file, lineNumber); + } + : null + } + /> + ); + })} + + + + + ); + } + + componentDidMount(): void { + this._handleSymbolication(); + } + + componentDidUpdate(prevProps: Props, prevState: State): void { + if ( + prevProps.warnings !== this.props.warnings || + prevState.selectedIndex !== this.state.selectedIndex + ) { + this._cancelSymbolication(); + this._handleSymbolication(); + } + } + + componentWillUnmount(): void { + this._cancelSymbolication(); + } + + _handleRetrySymbolication = () => { + this._cancelSymbolication(); + this.forceUpdate(() => { + const warning = this.props.warnings[this.state.selectedIndex]; + this._symbolication = warning.retrySymbolicate(() => { + this.forceUpdate(); + }); + }); + }; + + _handleSymbolication(): void { + const warning = this.props.warnings[this.state.selectedIndex]; + if (warning.symbolicated.status !== 'COMPLETE') { + this._symbolication = warning.symbolicate(() => { + this.forceUpdate(); + }); + } + } + + _cancelSymbolication(): void { + if (this._symbolication != null) { + this._symbolication.abort(); + this._symbolication = null; + } + } + + _handleSelectIndex = (selectedIndex: number): void => { + this.setState({selectedIndex}); + }; +} + +const styles = StyleSheet.create({ + root: { + elevation: Platform.OS === 'android' ? Number.MAX_SAFE_INTEGER : undefined, + height: '100%', + }, + body: { + backgroundColor: YellowBoxStyle.getBackgroundColor(0.95), + borderBottomColor: YellowBoxStyle.getDividerColor(0.95), + borderBottomWidth: StyleSheet.hairlineWidth, + borderTopColor: YellowBoxStyle.getDividerColor(0.95), + borderTopWidth: StyleSheet.hairlineWidth, + flex: 1, + }, + bodyContent: { + paddingVertical: 12, + }, + bodyHeading: { + alignItems: 'center', + flexDirection: 'row', + marginBottom: 6, + paddingHorizontal: 12, + }, + bodyHeadingText: { + color: YellowBoxStyle.getTextColor(1), + flex: 1, + fontSize: 20, + fontWeight: '600', + includeFontPadding: false, + lineHeight: 28, + }, + bodyText: { + color: YellowBoxStyle.getTextColor(1), + fontSize: 14, + includeFontPadding: false, + lineHeight: 18, + paddingHorizontal: 12, + }, + substitutionText: { + color: YellowBoxStyle.getTextColor(0.6), + }, + bodySection: { + marginTop: 20, + }, +}); + +module.exports = YellowBoxInspector; diff --git a/Libraries/YellowBox/UI/YellowBoxInspectorFooter.js b/Libraries/YellowBox/UI/YellowBoxInspectorFooter.js new file mode 100644 index 00000000000000..5dda52a848f99a --- /dev/null +++ b/Libraries/YellowBox/UI/YellowBoxInspectorFooter.js @@ -0,0 +1,76 @@ +/** + * 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. + * + * @flow strict-local + * @format + */ + +'use strict'; + +const React = require('react'); +const SafeAreaView = require('../../Components/SafeAreaView/SafeAreaView'); +const StyleSheet = require('../../StyleSheet/StyleSheet'); +const Text = require('../../Text/Text'); +const View = require('../../Components/View/View'); +const YellowBoxPressable = require('./YellowBoxPressable'); +const YellowBoxStyle = require('./YellowBoxStyle'); + +type Props = $ReadOnly<{| + onDismiss: () => void, + onMinimize: () => void, +|}>; + +const YellowBoxInspectorFooter = (props: Props): React.Node => ( + + + + Minimize + + + + + + Dismiss + + + + +); + +const styles = StyleSheet.create({ + root: { + backgroundColor: YellowBoxStyle.getBackgroundColor(0.95), + flexDirection: 'row', + }, + button: { + flex: 1, + }, + content: { + alignItems: 'center', + height: 48, + justifyContent: 'center', + }, + label: { + color: YellowBoxStyle.getTextColor(1), + fontSize: 14, + includeFontPadding: false, + lineHeight: 18, + }, +}); + +module.exports = YellowBoxInspectorFooter; diff --git a/Libraries/YellowBox/UI/YellowBoxInspectorHeader.js b/Libraries/YellowBox/UI/YellowBoxInspectorHeader.js new file mode 100644 index 00000000000000..b415481e30c976 --- /dev/null +++ b/Libraries/YellowBox/UI/YellowBoxInspectorHeader.js @@ -0,0 +1,116 @@ +/** + * 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. + * + * @flow strict-local + * @format + */ + +'use strict'; + +const Image = require('../../Image/Image'); +const Platform = require('../../Utilities/Platform'); +const React = require('react'); +const SafeAreaView = require('../../Components/SafeAreaView/SafeAreaView'); +const StyleSheet = require('../../StyleSheet/StyleSheet'); +const Text = require('../../Text/Text'); +const View = require('../../Components/View/View'); +const YellowBoxPressable = require('./YellowBoxPressable'); +const YellowBoxStyle = require('./YellowBoxStyle'); + +import type YellowBoxWarning from '../Data/YellowBoxWarning'; + +type Props = $ReadOnly<{| + onSelectIndex: (selectedIndex: number) => void, + selectedIndex: number, + warnings: $ReadOnlyArray, +|}>; + +const YellowBoxInspectorHeader = (props: Props): React.Node => { + const prevIndex = props.selectedIndex - 1; + const nextIndex = props.selectedIndex + 1; + + const titleText = + props.warnings.length === 1 + ? 'Single Occurrence' + : `Occurrence ${props.selectedIndex + 1} of ${props.warnings.length}`; + + return ( + + + props.onSelectIndex(prevIndex)} + /> + + {titleText} + + props.onSelectIndex(nextIndex)} + /> + + + ); +}; + +const YellowBoxInspectorHeaderButton = ( + props: $ReadOnly<{| + disabled: boolean, + image: number, + onPress?: ?() => void, + |}>, +): React.Node => ( + + {props.disabled ? null : ( + + )} + +); + +const styles = StyleSheet.create({ + root: { + backgroundColor: YellowBoxStyle.getBackgroundColor(0.95), + }, + header: { + flexDirection: 'row', + height: Platform.select({ + android: 48, + ios: 44, + }), + }, + headerButton: { + alignItems: 'center', + aspectRatio: 1, + justifyContent: 'center', + }, + headerButtonImage: { + height: 14, + width: 8, + tintColor: YellowBoxStyle.getTextColor(1), + }, + headerTitle: { + alignItems: 'center', + flex: 1, + justifyContent: 'center', + }, + headerTitleText: { + color: YellowBoxStyle.getTextColor(1), + fontSize: 16, + fontWeight: '600', + includeFontPadding: false, + lineHeight: 20, + }, +}); + +module.exports = YellowBoxInspectorHeader; diff --git a/Libraries/YellowBox/UI/YellowBoxInspectorSourceMapStatus.js b/Libraries/YellowBox/UI/YellowBoxInspectorSourceMapStatus.js new file mode 100644 index 00000000000000..2da3efbe784199 --- /dev/null +++ b/Libraries/YellowBox/UI/YellowBoxInspectorSourceMapStatus.js @@ -0,0 +1,155 @@ +/** + * 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. + * + * @flow strict-local + * @format + */ + +'use strict'; + +const Animated = require('../../Animated/src/Animated'); +const Easing = require('../../Animated/src/Easing'); +const React = require('react'); +const StyleSheet = require('../../StyleSheet/StyleSheet'); +const Text = require('../../Text/Text'); +const YellowBoxPressable = require('./YellowBoxPressable'); +const YellowBoxStyle = require('./YellowBoxStyle'); + +import type {CompositeAnimation} from '../../Animated/src/AnimatedImplementation'; +import type AnimatedInterpolation from '../../Animated/src/nodes/AnimatedInterpolation'; +import type {PressEvent} from '../../Types/CoreEventTypes'; + +type Props = $ReadOnly<{| + onPress?: ?(event: PressEvent) => void, + status: 'COMPLETE' | 'FAILED' | 'NONE' | 'PENDING', +|}>; + +type State = {| + animation: ?CompositeAnimation, + rotate: ?AnimatedInterpolation, +|}; + +class YellowBoxInspectorSourceMapStatus extends React.Component { + state: State = { + animation: null, + rotate: null, + }; + + render(): React.Node { + let image; + + switch (this.props.status) { + case 'FAILED': + image = require('../../LogBox/UI/LogBoxImages/alert-triangle.png'); + break; + case 'PENDING': + image = require('../../LogBox/UI/LogBoxImages/loader.png'); + break; + } + + return image == null ? null : ( + + + Source Map + + ); + } + + componentDidMount(): void { + this._updateAnimation(); + } + + componentDidUpdate(): void { + this._updateAnimation(); + } + + componentWillUnmount(): void { + if (this.state.animation != null) { + this.state.animation.stop(); + } + } + + _updateAnimation(): void { + if (this.props.status === 'PENDING') { + if (this.state.animation == null) { + const animated = new Animated.Value(0); + const animation = Animated.loop( + Animated.timing(animated, { + duration: 2000, + easing: Easing.linear, + toValue: 1, + useNativeDriver: true, + }), + ); + this.setState( + { + animation, + rotate: animated.interpolate({ + inputRange: [0, 1], + outputRange: ['0deg', '360deg'], + }), + }, + () => { + animation.start(); + }, + ); + } + } else { + if (this.state.animation != null) { + this.state.animation.stop(); + this.setState({ + animation: null, + rotate: null, + }); + } + } + } +} + +const styles = StyleSheet.create({ + root: { + alignItems: 'center', + borderRadius: 12, + flexDirection: 'row', + height: 24, + paddingHorizontal: 8, + }, + pending: { + backgroundColor: YellowBoxStyle.getTextColor(0.6), + }, + image: { + height: 14, + width: 16, + marginEnd: 4, + tintColor: YellowBoxStyle.getBackgroundColor(1), + }, + text: { + color: YellowBoxStyle.getBackgroundColor(1), + fontSize: 12, + includeFontPadding: false, + lineHeight: 16, + }, +}); + +module.exports = YellowBoxInspectorSourceMapStatus; diff --git a/Libraries/YellowBox/UI/YellowBoxInspectorStackFrame.js b/Libraries/YellowBox/UI/YellowBoxInspectorStackFrame.js new file mode 100644 index 00000000000000..01c6f03c5aa7df --- /dev/null +++ b/Libraries/YellowBox/UI/YellowBoxInspectorStackFrame.js @@ -0,0 +1,93 @@ +/** + * 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. + * + * @flow strict-local + * @format + */ + +'use strict'; + +const React = require('react'); +const StyleSheet = require('../../StyleSheet/StyleSheet'); +const Text = require('../../Text/Text'); +const YellowBoxPressable = require('./YellowBoxPressable'); +const YellowBoxStyle = require('./YellowBoxStyle'); + +import type {PressEvent} from '../../Types/CoreEventTypes'; +import type {StackFrame} from '../../Core/NativeExceptionsManager'; + +type Props = $ReadOnly<{| + frame: StackFrame, + onPress?: ?(event: PressEvent) => void, +|}>; + +const YellowBoxInspectorStackFrame = (props: Props): React.Node => { + const {frame, onPress} = props; + + return ( + + {frame.methodName} + + {formatFrameLocation(frame)} + + + ); +}; + +const formatFrameLocation = (frame: StackFrame): string => { + const {file, lineNumber, column} = frame; + if (file == null) { + return ''; + } + const queryIndex = file.indexOf('?'); + const query = queryIndex < 0 ? '' : file.substr(queryIndex); + + const path = queryIndex < 0 ? file : file.substr(0, queryIndex); + let location = path.substr(path.lastIndexOf('/') + 1) + query; + + if (lineNumber == null) { + return location; + } + + location = location + ':' + lineNumber; + + if (column == null) { + return location; + } + + return location + ':' + column; +}; + +const styles = StyleSheet.create({ + frame: { + paddingHorizontal: 12, + paddingVertical: 4, + }, + frameName: { + color: YellowBoxStyle.getTextColor(1), + fontSize: 14, + includeFontPadding: false, + lineHeight: 18, + }, + frameLocation: { + color: YellowBoxStyle.getTextColor(0.7), + fontSize: 12, + fontWeight: '300', + includeFontPadding: false, + lineHeight: 16, + }, +}); + +module.exports = YellowBoxInspectorStackFrame; diff --git a/Libraries/YellowBox/UI/YellowBoxList.js b/Libraries/YellowBox/UI/YellowBoxList.js new file mode 100644 index 00000000000000..c7fa200d1d7052 --- /dev/null +++ b/Libraries/YellowBox/UI/YellowBoxList.js @@ -0,0 +1,142 @@ +/** + * 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. + * + * @flow strict-local + * @format + */ + +'use strict'; + +const Dimensions = require('../../Utilities/Dimensions'); +const FlatList = require('../../Lists/FlatList'); +const React = require('react'); +const SafeAreaView = require('../../Components/SafeAreaView/SafeAreaView'); +const StyleSheet = require('../../StyleSheet/StyleSheet'); +const View = require('../../Components/View/View'); +const YellowBoxButton = require('./YellowBoxButton'); +const YellowBoxInspector = require('./YellowBoxInspector'); +const YellowBoxListRow = require('./YellowBoxListRow'); +const YellowBoxStyle = require('./YellowBoxStyle'); + +import type {Category} from '../Data/YellowBoxCategory'; +import type {Registry} from '../Data/YellowBoxRegistry'; + +type Props = $ReadOnly<{| + onDismiss: (category: Category) => void, + onDismissAll: () => void, + registry: Registry, +|}>; + +type State = {| + selectedCategory: ?Category, +|}; + +const VIEWPORT_RATIO = 0.5; +const MAX_ITEMS = Math.floor( + (Dimensions.get('window').height * VIEWPORT_RATIO) / + (YellowBoxListRow.GUTTER + YellowBoxListRow.HEIGHT), +); + +class YellowBoxList extends React.Component { + state: State = { + selectedCategory: null, + }; + + render(): React.Node { + const selectedWarnings = + this.state.selectedCategory == null + ? null + : this.props.registry.get(this.state.selectedCategory); + + if (selectedWarnings != null) { + return ( + + + + ); + } + + const items = []; + for (const [category, warnings] of this.props.registry) { + items.unshift({category, warnings}); + } + + const listStyle = { + height: + // Additional `0.5` so the (N + 1)th row can peek into view. + Math.min(items.length, MAX_ITEMS + 0.5) * + (YellowBoxListRow.GUTTER + YellowBoxListRow.HEIGHT), + }; + + return items.length === 0 ? null : ( + + + + + item.category} + renderItem={({item}) => ( + + )} + scrollEnabled={items.length > MAX_ITEMS} + scrollsToTop={false} + style={listStyle} + /> + + + ); + } + + _handleInspectorDismiss = () => { + const category = this.state.selectedCategory; + if (category == null) { + return; + } + this.setState({selectedCategory: null}, () => { + this.props.onDismiss(category); + }); + }; + + _handleInspectorMinimize = () => { + this.setState({selectedCategory: null}); + }; + + _handleRowPress = (category: Category) => { + this.setState({selectedCategory: category}); + }; +} + +const styles = StyleSheet.create({ + list: { + bottom: 0, + position: 'absolute', + width: '100%', + }, + dismissAll: { + bottom: '100%', + flexDirection: 'row', + justifyContent: 'flex-end', + paddingBottom: 4, + paddingEnd: 4, + position: 'absolute', + width: '100%', + }, + safeArea: { + backgroundColor: YellowBoxStyle.getBackgroundColor(0.95), + marginTop: StyleSheet.hairlineWidth, + }, +}); + +module.exports = YellowBoxList; diff --git a/Libraries/YellowBox/UI/YellowBoxListRow.js b/Libraries/YellowBox/UI/YellowBoxListRow.js new file mode 100644 index 00000000000000..367a40e9c6835d --- /dev/null +++ b/Libraries/YellowBox/UI/YellowBoxListRow.js @@ -0,0 +1,100 @@ +/** + * 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. + * + * @flow strict-local + * @format + */ + +'use strict'; + +const React = require('react'); +const StyleSheet = require('../../StyleSheet/StyleSheet'); +const Text = require('../../Text/Text'); +const View = require('../../Components/View/View'); +const YellowBoxCategory = require('../Data/YellowBoxCategory'); +const YellowBoxPressable = require('./YellowBoxPressable'); +const YellowBoxStyle = require('./YellowBoxStyle'); +const YellowBoxWarning = require('../Data/YellowBoxWarning'); + +import type {Category} from '../Data/YellowBoxCategory'; + +type Props = $ReadOnly<{| + category: Category, + warnings: $ReadOnlyArray, + onPress: (category: Category) => void, +|}>; + +class YellowBoxListRow extends React.Component { + static GUTTER: number = StyleSheet.hairlineWidth; + static HEIGHT: number = 48; + + shouldComponentUpdate(nextProps: Props): boolean { + const prevProps = this.props; + return ( + prevProps.category !== nextProps.category || + prevProps.onPress !== nextProps.onPress || + prevProps.warnings.length !== nextProps.warnings.length || + prevProps.warnings.some( + (prevWarning, index) => prevWarning !== nextProps.warnings[index], + ) + ); + } + + render(): React.Node { + const {warnings} = this.props; + + return ( + + + {warnings.length < 2 ? null : ( + {'(' + warnings.length + ') '} + )} + + {YellowBoxCategory.render( + warnings[warnings.length - 1].message, + styles.substitutionText, + )} + + + + ); + } + + _handlePress = () => { + this.props.onPress(this.props.category); + }; +} + +const styles = StyleSheet.create({ + root: { + height: YellowBoxListRow.HEIGHT, + justifyContent: 'center', + marginTop: YellowBoxListRow.GUTTER, + paddingHorizontal: 12, + }, + content: { + alignItems: 'flex-start', + flexDirection: 'row', + }, + bodyText: { + color: YellowBoxStyle.getTextColor(1), + flex: 1, + fontSize: 14, + includeFontPadding: false, + lineHeight: 18, + }, + metaText: { + color: YellowBoxStyle.getTextColor(0.5), + fontSize: 14, + includeFontPadding: false, + lineHeight: 18, + }, + substitutionText: { + color: YellowBoxStyle.getTextColor(0.6), + }, +}); + +module.exports = YellowBoxListRow; diff --git a/Libraries/YellowBox/UI/YellowBoxPressable.js b/Libraries/YellowBox/UI/YellowBoxPressable.js new file mode 100644 index 00000000000000..766ed2600dd94d --- /dev/null +++ b/Libraries/YellowBox/UI/YellowBoxPressable.js @@ -0,0 +1,88 @@ +/** + * 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. + * + * @flow strict-local + * @format + */ + +'use strict'; + +const React = require('react'); +const StyleSheet = require('../../StyleSheet/StyleSheet'); +const TouchableWithoutFeedback = require('../../Components/Touchable/TouchableWithoutFeedback'); +const View = require('../../Components/View/View'); +const YellowBoxStyle = require('./YellowBoxStyle'); + +import type {EdgeInsetsProp} from '../../StyleSheet/EdgeInsetsPropType'; +import type {ViewStyleProp} from '../../StyleSheet/StyleSheet'; +import type {PressEvent} from '../../Types/CoreEventTypes'; + +type Props = $ReadOnly<{| + backgroundColor: $ReadOnly<{| + default: string, + pressed: string, + |}>, + children?: React.Node, + hitSlop?: ?EdgeInsetsProp, + onPress?: ?(event: PressEvent) => void, + style?: ViewStyleProp, +|}>; + +type State = {| + pressed: boolean, +|}; + +class YellowBoxPressable extends React.Component { + static defaultProps: {| + backgroundColor: {|default: string, pressed: string|}, + |} = { + backgroundColor: { + default: YellowBoxStyle.getBackgroundColor(0.95), + pressed: YellowBoxStyle.getHighlightColor(1), + }, + }; + + state: State = { + pressed: false, + }; + + render(): React.Node { + const content = ( + + {this.props.children} + + ); + return this.props.onPress == null ? ( + content + ) : ( + + {content} + + ); + } + + _handlePressIn = () => { + this.setState({pressed: true}); + }; + + _handlePressOut = () => { + this.setState({pressed: false}); + }; +} + +module.exports = YellowBoxPressable; diff --git a/Libraries/YellowBox/UI/YellowBoxStyle.js b/Libraries/YellowBox/UI/YellowBoxStyle.js new file mode 100644 index 00000000000000..d984514abd7000 --- /dev/null +++ b/Libraries/YellowBox/UI/YellowBoxStyle.js @@ -0,0 +1,31 @@ +/** + * 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. + * + * @flow strict + * @format + */ + +'use strict'; + +const YellowBoxStyle = { + getBackgroundColor(opacity: number): string { + return `rgba(250, 186, 48, ${opacity})`; + }, + + getDividerColor(opacity: number): string { + return `rgba(255, 255, 255, ${opacity})`; + }, + + getHighlightColor(opacity: number): string { + return `rgba(252, 176, 29, ${opacity})`; + }, + + getTextColor(opacity: number): string { + return `rgba(255, 255, 255, ${opacity})`; + }, +}; + +module.exports = YellowBoxStyle; diff --git a/Libraries/YellowBox/YellowBox.js b/Libraries/YellowBox/YellowBox.js new file mode 100644 index 00000000000000..c77aba67d79fd1 --- /dev/null +++ b/Libraries/YellowBox/YellowBox.js @@ -0,0 +1,234 @@ +/** + * 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. + * + * @flow + * @format + */ + +'use strict'; + +const React = require('react'); + +import type {Registry, IgnorePattern} from './Data/YellowBoxRegistry'; +import YellowBoxWarning from './Data/YellowBoxWarning'; + +import * as LogBoxData from '../LogBox/Data/LogBoxData'; +import NativeLogBox from '../NativeModules/specs/NativeLogBox'; + +type Props = $ReadOnly<{||}>; +type State = {| + registry: ?Registry, +|}; + +let YellowBox; + +/** + * YellowBox displays warnings at the bottom of the screen. + * + * Warnings help guard against subtle yet significant issues that can impact the + * quality of the app. This "in your face" style of warning allows developers to + * notice and correct these issues as quickly as possible. + * + * YellowBox is only enabled in `__DEV__`. Set the following flag to disable it: + * + * console.disableYellowBox = true; + * + * Ignore specific warnings by calling: + * + * YellowBox.ignoreWarnings(['Warning: ...']); + * + * Strings supplied to `YellowBox.ignoreWarnings` only need to be a substring of + * the ignored warning messages. + */ +if (__DEV__) { + const Platform = require('../Utilities/Platform'); + const RCTLog = require('../Utilities/RCTLog'); + const YellowBoxContainer = require('./YellowBoxContainer').default; + const LogBox = require('../LogBox/LogBox'); + const YellowBoxRegistry = require('./Data/YellowBoxRegistry'); + const LogBoxNotificationContainer = require('../LogBox/LogBoxNotificationContainer') + .default; + + // YellowBox needs to insert itself early, + // in order to access the component stacks appended by React DevTools. + const {error, warn} = console; + let errorImpl = error; + let warnImpl = warn; + let _isLogBoxEnabled = false; + let _isInstalled = false; + (console: any).error = function(...args) { + errorImpl(...args); + }; + (console: any).warn = function(...args) { + warnImpl(...args); + }; + + // eslint-disable-next-line no-shadow + YellowBox = class YellowBox extends React.Component { + static ignoreWarnings(patterns: $ReadOnlyArray): void { + LogBoxData.addIgnorePatterns(patterns); + YellowBoxRegistry.addIgnorePatterns(patterns); + } + + static install(): void { + if (_isLogBoxEnabled) { + LogBox.install(); + return; + } + _isInstalled = true; + + errorImpl = function(...args) { + registerError(...args); + }; + + warnImpl = function(...args) { + registerWarning(...args); + }; + + if ((console: any).disableYellowBox === true) { + YellowBoxRegistry.setDisabled(true); + } + (Object.defineProperty: any)(console, 'disableYellowBox', { + configurable: true, + get: () => YellowBoxRegistry.isDisabled(), + set: value => YellowBoxRegistry.setDisabled(value), + }); + + if (Platform.isTesting) { + (console: any).disableYellowBox = true; + } + + RCTLog.setWarningHandler((...args) => { + registerWarning(...args); + }); + } + + static uninstall(): void { + if (_isLogBoxEnabled) { + LogBox.uninstall(); + return; + } + _isInstalled = false; + errorImpl = error; + warnImpl = warn; + delete (console: any).disableYellowBox; + } + + static __unstable_enableLogBox(): void { + if (NativeLogBox == null) { + // The native module is required to enable LogBox. + return; + } + + if (_isInstalled) { + throw new Error( + 'LogBox must be enabled before AppContainer is required so that it can properly wrap the console methods.\n\nPlease enable LogBox earlier in your app.\n\n', + ); + } + _isLogBoxEnabled = true; + + // TODO: Temporary hack to prevent cycles with the ExceptionManager. + global.__unstable_isLogBoxEnabled = true; + } + + static __unstable_isLogBoxEnabled(): boolean { + return !!_isLogBoxEnabled; + } + + render(): React.Node { + if (_isLogBoxEnabled) { + return ; + } + + // TODO: Ignore warnings that fire when rendering `YellowBox` itself. + return ; + } + }; + + const registerWarning = (...args): void => { + if (typeof args[0] === 'string' && args[0].startsWith('(ADVICE)')) { + return; + } + + const {category, message, stack} = YellowBoxWarning.parse({ + args, + }); + + if (!YellowBoxRegistry.isWarningIgnored(message)) { + YellowBoxRegistry.add({category, message, stack}); + warn.call(console, ...args); + } + }; + + const registerError = (...args): void => { + // Only show YellowBox for the `warning` module, otherwise pass through and skip. + if (typeof args[0] !== 'string' || !args[0].startsWith('Warning: ')) { + error.call(console, ...args); + return; + } + + const format = args[0].replace('Warning: ', ''); + const filterResult = LogBoxData.checkWarningFilter(format); + if (filterResult.suppressCompletely) { + return; + } + + args[0] = filterResult.finalFormat; + const {category, message, stack} = YellowBoxWarning.parse({ + args, + }); + + if (YellowBoxRegistry.isWarningIgnored(message)) { + return; + } + + if (filterResult.forceDialogImmediately === true) { + // This will pop a redbox. Do not downgrade. These are real bugs with same severity as throws. + error.call(console, message.content); + } else { + // Unfortunately, we need to add the Warning: prefix back so we don't show a redbox later. + args[0] = `Warning: ${filterResult.finalFormat}`; + + // Note: YellowBox has no concept of "soft errors" so we're showing YellowBox for those. + YellowBoxRegistry.add({category, message, stack}); + error.call(console, ...args); + } + }; +} else { + YellowBox = class extends React.Component { + static ignoreWarnings(patterns: $ReadOnlyArray): void { + // Do nothing. + } + + static install(): void { + // Do nothing. + } + + static uninstall(): void { + // Do nothing. + } + + static __unstable_enableLogBox(): void { + // Do nothing. + } + static __unstable_isLogBoxEnabled(): boolean { + return false; + } + + render(): React.Node { + return null; + } + }; +} + +module.exports = (YellowBox: Class> & { + ignoreWarnings($ReadOnlyArray): void, + install(): void, + uninstall(): void, + __unstable_enableLogBox(): void, + __unstable_isLogBoxEnabled(): boolean, + ... +}); diff --git a/Libraries/YellowBox/YellowBoxContainer.js b/Libraries/YellowBox/YellowBoxContainer.js new file mode 100644 index 00000000000000..b66bdd2d274119 --- /dev/null +++ b/Libraries/YellowBox/YellowBoxContainer.js @@ -0,0 +1,65 @@ +/** + * 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. + * + * @flow + * @format + */ + +'use strict'; + +const React = require('react'); + +import type {Category} from './Data/YellowBoxCategory'; +import type {Registry, Subscription} from './Data/YellowBoxRegistry'; + +type Props = $ReadOnly<{||}>; +type State = $ReadOnly<{| + registry: ?Registry, +|}>; + +const YellowBoxList = require('./UI/YellowBoxList'); +const YellowBoxRegistry = require('./Data/YellowBoxRegistry'); + +class YellowBoxContainer extends React.Component { + _subscription: ?Subscription; + + state: State = { + registry: null, + }; + + render(): React.Node { + // TODO: Ignore warnings that fire when rendering `YellowBox` itself. + return this.state.registry == null ? null : ( + + ); + } + + componentDidMount(): void { + this._subscription = YellowBoxRegistry.observe(registry => { + this.setState({registry}); + }); + } + + componentWillUnmount(): void { + if (this._subscription != null) { + this._subscription.unsubscribe(); + } + } + + _handleDismiss = (category: Category): void => { + YellowBoxRegistry.delete(category); + }; + + _handleDismissAll(): void { + YellowBoxRegistry.clear(); + } +} + +export default YellowBoxContainer; diff --git a/Libraries/YellowBox/YellowBoxDeprecated.js b/Libraries/YellowBox/YellowBoxDeprecated.js deleted file mode 100644 index 46ba16eeeda5a3..00000000000000 --- a/Libraries/YellowBox/YellowBoxDeprecated.js +++ /dev/null @@ -1,75 +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. - * - * @flow - * @format - */ - -'use strict'; - -const React = require('react'); - -const LogBox = require('../LogBox/LogBox'); - -import type {IgnorePattern} from '../LogBox/Data/LogBoxData'; - -type Props = $ReadOnly<{||}>; - -let YellowBox; -if (__DEV__) { - YellowBox = class extends React.Component { - static ignoreWarnings(patterns: $ReadOnlyArray): void { - console.warn( - 'YellowBox has been replaced with LogBox. Please call LogBox.ignoreLogs() instead.', - ); - - LogBox.ignoreLogs(patterns); - } - - static install(): void { - console.warn( - 'YellowBox has been replaced with LogBox. Please call LogBox.install() instead.', - ); - LogBox.install(); - } - - static uninstall(): void { - console.warn( - 'YellowBox has been replaced with LogBox. Please call LogBox.uninstall() instead.', - ); - LogBox.uninstall(); - } - - render(): React.Node { - return null; - } - }; -} else { - YellowBox = class extends React.Component { - static ignoreWarnings(patterns: $ReadOnlyArray): void { - // Do nothing. - } - - static install(): void { - // Do nothing. - } - - static uninstall(): void { - // Do nothing. - } - - render(): React.Node { - return null; - } - }; -} - -module.exports = (YellowBox: Class> & { - ignoreWarnings($ReadOnlyArray): void, - install(): void, - uninstall(): void, - ... -}); diff --git a/Libraries/YellowBox/__tests__/YellowBox-test.js b/Libraries/YellowBox/__tests__/YellowBox-test.js new file mode 100644 index 00000000000000..e9a89f3fcdbd0c --- /dev/null +++ b/Libraries/YellowBox/__tests__/YellowBox-test.js @@ -0,0 +1,270 @@ +/** + * 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. + * + * @emails oncall+react_native + * @format + * @flow + */ + +'use strict'; + +import * as React from 'react'; +const YellowBoxRegistry = require('../Data/YellowBoxRegistry'); +const LogBoxData = require('../../LogBox/Data/LogBoxData'); +const render = require('../../../jest/renderer'); +jest.mock('../../NativeModules/specs/NativeLogBox', () => true); +jest.mock('../../LogBox/LogBoxNotificationContainer', () => ({ + __esModule: true, + default: 'LogBoxNotificationContainer', +})); + +type Overrides = {| + forceDialogImmediately?: boolean, + suppressDialog_LEGACY?: boolean, + suppressCompletely?: boolean, +|}; + +const setFilter = (options?: Overrides) => { + LogBoxData.setWarningFilter(format => ({ + finalFormat: format, + forceDialogImmediately: false, + suppressDialog_LEGACY: false, + suppressCompletely: false, + monitorEvent: null, + monitorListVersion: 0, + monitorSampleRate: 0, + ...options, + })); +}; + +const install = () => { + const YellowBox = require('../YellowBox'); + YellowBox.install(); +}; + +const uninstall = () => { + const YellowBox = require('../YellowBox'); + YellowBox.uninstall(); +}; + +describe('YellowBox', () => { + const {error, warn} = console; + const mockError = jest.fn(); + const mockWarn = jest.fn(); + + beforeEach(() => { + jest.resetModules(); + + mockError.mockClear(); + mockWarn.mockClear(); + + (console: any).error = mockError; + (console: any).warn = mockWarn; + }); + + afterEach(() => { + uninstall(); + (console: any).error = error; + (console: any).warn = warn; + }); + + it('can set `disableYellowBox` after installing', () => { + expect((console: any).disableYellowBox).toBe(undefined); + + install(); + + expect((console: any).disableYellowBox).toBe(false); + expect(YellowBoxRegistry.isDisabled()).toBe(false); + + (console: any).disableYellowBox = true; + + expect((console: any).disableYellowBox).toBe(true); + expect(YellowBoxRegistry.isDisabled()).toBe(true); + }); + + it('can set `disableYellowBox` before installing', () => { + expect((console: any).disableYellowBox).toBe(undefined); + + (console: any).disableYellowBox = true; + install(); + + expect((console: any).disableYellowBox).toBe(true); + expect(YellowBoxRegistry.isDisabled()).toBe(true); + }); + + it('registers warnings', () => { + jest.mock('../Data/YellowBoxRegistry'); + + install(); + + expect(YellowBoxRegistry.add).not.toBeCalled(); + (console: any).warn('...'); + expect(YellowBoxRegistry.add).toBeCalled(); + expect(mockWarn).toBeCalledTimes(1); + expect(mockWarn).toBeCalledWith('...'); + }); + + it('registers errors', () => { + jest.mock('../Data/YellowBoxRegistry'); + + install(); + + (console: any).error('...'); + expect(YellowBoxRegistry.add).not.toBeCalled(); + expect(mockError).toBeCalledTimes(1); + expect(mockError).toBeCalledWith('...'); + }); + + it('skips ADVICE warnings', () => { + jest.mock('../Data/YellowBoxRegistry'); + + install(); + + (console: any).warn('(ADVICE) Ignore me'); + expect(YellowBoxRegistry.add).not.toBeCalled(); + expect(mockWarn).not.toBeCalled(); + }); + + it('skips ignored warnings', () => { + jest.mock('../Data/YellowBoxRegistry'); + + install(); + + (YellowBoxRegistry: any).isWarningIgnored.mockReturnValue(true); + (console: any).warn('Ignore me'); + expect(YellowBoxRegistry.add).not.toBeCalled(); + expect(mockWarn).not.toBeCalled(); + }); + + it('registers Warning module errors with default options to YellowBox', () => { + jest.mock('../Data/YellowBoxRegistry'); + + setFilter(); + install(); + + (console: any).error('Warning: ...'); + expect(YellowBoxRegistry.add).toBeCalled(); + expect(mockError).toBeCalled(); + expect(mockError).toBeCalledTimes(1); + expect(mockWarn).not.toBeCalled(); + }); + + it('skips Warning module errors with forceDialogImmediately', () => { + jest.mock('../Data/YellowBoxRegistry'); + + setFilter({ + suppressCompletely: true, + }); + install(); + + (console: any).error('Warning: ...'); + expect(YellowBoxRegistry.add).not.toBeCalled(); + expect(mockError).not.toBeCalled(); + expect(mockWarn).not.toBeCalled(); + }); + + it('registers Warning errors with forceDialogImmediately as console.error (with interpolation)', () => { + jest.mock('../Data/YellowBoxRegistry'); + + setFilter({ + forceDialogImmediately: true, + }); + + install(); + + (console: any).error('Warning: %s', 'Something'); + expect(YellowBoxRegistry.add).not.toBeCalled(); + expect(mockWarn).not.toBeCalled(); + expect(mockError).toBeCalledTimes(1); + + // We expect this to be the interpolated value because we don't do interpolation downstream. + // We also strip the "Warning" prefix, otherwise the redbox would be skipped downstream. + expect(mockError).toBeCalledWith('Something'); + }); + + it('registers Warning errors with suppressDialog_LEGACY to YellowBox', () => { + jest.mock('../Data/YellowBoxRegistry'); + + setFilter({ + suppressDialog_LEGACY: true, + }); + + install(); + + (console: any).error('Warning: Something'); + expect(YellowBoxRegistry.add).toBeCalledTimes(1); + expect(mockWarn).not.toBeCalled(); + expect(mockError).toBeCalledTimes(1); + + // We cannot strip the "Warning" prefix or it would pop a redbox. + expect(mockError).toBeCalledWith('Warning: Something'); + }); + + it('skips Warning errors sent to YellowBox but ignored by patterns', () => { + jest.mock('../Data/YellowBoxRegistry'); + + setFilter({ + suppressDialog_LEGACY: true, + }); + + install(); + (YellowBoxRegistry: any).isWarningIgnored.mockReturnValue(true); + + (console: any).error('Warning: ...'); + expect(YellowBoxRegistry.add).not.toBeCalled(); + expect(mockWarn).not.toBeCalled(); + expect(mockError).not.toBeCalled(); + }); + + it('if LogBox is enabled, installs and uninstalls LogBox', () => { + jest.mock('../../LogBox/Data/LogBoxData'); + jest.mock('../Data/YellowBoxRegistry'); + const YellowBox = require('../YellowBox'); + YellowBox.__unstable_enableLogBox(); + install(); + + (console: any).warn('Some warning'); + expect(YellowBoxRegistry.add).not.toBeCalled(); + expect(LogBoxData.addLog).toBeCalled(); + expect(require('../YellowBox').__unstable_isLogBoxEnabled()).toBe(true); + + uninstall(); + (LogBoxData.addLog: any).mockClear(); + + (console: any).warn('Some warning'); + expect(YellowBoxRegistry.add).not.toBeCalled(); + expect(LogBoxData.addLog).not.toBeCalled(); + expect(YellowBox.__unstable_isLogBoxEnabled()).toBe(true); + }); + + it('throws if LogBox is enabled after YellowBox is installed', () => { + jest.mock('../Data/YellowBoxRegistry'); + const YellowBox = require('../YellowBox'); + install(); + + expect(() => YellowBox.__unstable_enableLogBox()).toThrow( + 'LogBox must be enabled before AppContainer is required so that it can properly wrap the console methods.\n\nPlease enable LogBox earlier in your app.\n\n', + ); + }); + + it('should render YellowBoxContainer by default', () => { + const YellowBox = require('../YellowBox'); + + const output = render.shallowRender(); + + expect(output).toMatchSnapshot(); + }); + + it('should render LogBoxNotificationContainer when LogBox is enabled', () => { + const YellowBox = require('../YellowBox'); + + YellowBox.__unstable_enableLogBox(); + + const output = render.shallowRender(); + + expect(output).toMatchSnapshot(); + }); +}); diff --git a/Libraries/YellowBox/__tests__/YellowBoxDeprecated-test.js b/Libraries/YellowBox/__tests__/YellowBoxDeprecated-test.js deleted file mode 100644 index 4adadb6e87f227..00000000000000 --- a/Libraries/YellowBox/__tests__/YellowBoxDeprecated-test.js +++ /dev/null @@ -1,53 +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. - * - * @emails oncall+react_native - * @format - * @flow - */ - -'use strict'; - -const LogBox = require('../../LogBox/LogBox'); -const YellowBox = require('../YellowBoxDeprecated'); - -describe('YellowBox', () => { - beforeEach(() => { - jest.restoreAllMocks(); - }); - it('calling ignoreWarnings proxies to LogBox.ignoreLogs', () => { - jest.spyOn(LogBox, 'ignoreLogs'); - jest.spyOn(console, 'warn').mockImplementation(() => {}); - YellowBox.ignoreWarnings(['foo']); - - expect(LogBox.ignoreLogs).toBeCalledWith(['foo']); - expect(console.warn).toBeCalledWith( - 'YellowBox has been replaced with LogBox. Please call LogBox.ignoreLogs() instead.', - ); - }); - - it('calling install proxies to LogBox.install', () => { - jest.spyOn(LogBox, 'install'); - jest.spyOn(console, 'warn').mockImplementation(() => {}); - YellowBox.install(); - - expect(LogBox.install).toBeCalled(); - expect(console.warn).toBeCalledWith( - 'YellowBox has been replaced with LogBox. Please call LogBox.install() instead.', - ); - }); - - it('calling uninstall proxies to LogBox.uninstall', () => { - jest.spyOn(LogBox, 'uninstall'); - jest.spyOn(console, 'warn').mockImplementation(() => {}); - YellowBox.uninstall(); - - expect(LogBox.uninstall).toBeCalled(); - expect(console.warn).toBeCalledWith( - 'YellowBox has been replaced with LogBox. Please call LogBox.uninstall() instead.', - ); - }); -}); diff --git a/Libraries/YellowBox/__tests__/__snapshots__/YellowBox-test.js.snap b/Libraries/YellowBox/__tests__/__snapshots__/YellowBox-test.js.snap new file mode 100644 index 00000000000000..974f032a963f2e --- /dev/null +++ b/Libraries/YellowBox/__tests__/__snapshots__/YellowBox-test.js.snap @@ -0,0 +1,5 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`YellowBox should render LogBoxNotificationContainer when LogBox is enabled 1`] = ``; + +exports[`YellowBox should render YellowBoxContainer by default 1`] = ``; diff --git a/Libraries/__flowtests__/ReactNativeTypes-flowtest.js b/Libraries/__flowtests__/ReactNativeTypes-flowtest.js index e6c0bb124d5902..cb21b05ab4582c 100644 --- a/Libraries/__flowtests__/ReactNativeTypes-flowtest.js +++ b/Libraries/__flowtests__/ReactNativeTypes-flowtest.js @@ -11,10 +11,13 @@ 'use strict'; import * as React from 'react'; -import type {HostComponent} from '../Renderer/shims/ReactNativeTypes'; +import type { + HostComponent, + _InternalReactNativeComponentClass, +} from '../Renderer/shims/ReactNativeTypes'; function takesHostComponentInstance( - instance: React.ElementRef> | null, + instance: React$ElementRef> | null, ): void {} const MyHostComponent = (('Host': any): HostComponent); @@ -30,3 +33,20 @@ const MyHostComponent = (('Host': any): HostComponent); hostComponentRef.measureLayout(hostComponentRef, () => {}); }} />; + +declare var NativeComponent: _InternalReactNativeComponentClass<{...}>; +class MyNativeComponent extends NativeComponent {} + + { + // $FlowExpectedError - NativeComponent cannot be passed as HostComponent. + takesHostComponentInstance(nativeComponentRef); + + if (nativeComponentRef == null) { + return; + } + + // $FlowExpectedError - NativeComponent cannot be passed as HostComponent. + nativeComponentRef.measureLayout(nativeComponentRef, () => {}); + }} +/>; diff --git a/Libraries/vendor/core/ErrorUtils.js b/Libraries/vendor/core/ErrorUtils.js index 2d60c4fc378371..0c0f140280a4ba 100644 --- a/Libraries/vendor/core/ErrorUtils.js +++ b/Libraries/vendor/core/ErrorUtils.js @@ -8,7 +8,7 @@ * @flow strict */ -import type {ErrorUtilsT} from '../../polyfills/error-guard'; +import type {ErrorUtilsT} from '../../polyfills/error-guard.js'; /** * The particular require runtime that we are using looks for a global diff --git a/RNTester/Podfile b/RNTester/Podfile index 7dce319e13851e..04f0b4304c0803 100644 --- a/RNTester/Podfile +++ b/RNTester/Podfile @@ -1,6 +1,6 @@ -require_relative '../scripts/react_native_pods' source 'https://cdn.cocoapods.org/' -platform :ios, '10.0' + +require_relative '../scripts/autolink-ios' # TODO(macOS GH#214) # Otherwise duplicate UUIDs are being generated between the iOS and macOS targets. @@ -37,16 +37,16 @@ def flipper_pods() pod 'FlipperKit/FlipperKitReactPlugin', '~>' + flipperkit_version, :configuration => 'Debug' if ENV['USE_FRAMEWORKS'] == '1' - static_frameworks = ['FlipperKit', 'Flipper', 'Flipper-Folly', + $static_framework = ['FlipperKit', 'Flipper', 'Flipper-Folly', 'CocoaAsyncSocket', 'ComponentKit', 'Flipper-DoubleConversion', 'Flipper-Glog', 'Flipper-PeerTalk', 'Flipper-RSocket', 'CocoaLibEvent', 'OpenSSL-Universal', 'boost-for-react-native'] - + pre_install do |installer| Pod::Installer::Xcode::TargetValidator.send(:define_method, :verify_no_static_framework_transitive_dependencies) {} installer.pod_targets.each do |pod| - if static_frameworks.include?(pod.name) - def pod.build_type + if $static_framework.include?(pod.name) + def pod.build_type; Pod::Target::BuildType.static_library end end @@ -74,54 +74,53 @@ def flipper_post_install(installer) end target 'RNTester' do - platform :ios, '10.0' + platform :ios, '9.0' pods() flipper_pods() - # use_flipper! end target 'RNTester-macOS' do - platform :osx, '10.14' + platform :osx, '10.13' pods(:hermes_enabled => true) end target 'RNTesterUnitTests' do - platform :ios, '10.0' + platform :ios, '9.0' pods() - pod 'React-RCTTest', :path => "./RCTTest" + pod 'React-RCTTest', :path => "RCTTest" end target 'RNTester-macOSUnitTests' do - platform :osx, '10.14' + platform :osx, '10.13' pods() - pod 'React-RCTTest', :path => "./RCTTest" + pod 'React-RCTTest', :path => "RCTTest" end target 'RNTesterIntegrationTests' do - platform :ios, '10.0' + platform :ios, '9.0' pods() - pod 'React-RCTTest', :path => "./RCTTest" + pod 'React-RCTTest', :path => "RCTTest" end target 'RNTester-macOSIntegrationTests' do - platform :osx, '10.14' + platform :osx, '10.13' pods() - pod 'React-RCTTest', :path => "./RCTTest" + pod 'React-RCTTest', :path => "RCTTest" end # [TODO(macOS ISS#2323203): these are special targets used by the internal Microsoft build pipeline target 'iosDeviceBuild' do - platform :ios, '10.0' + platform :ios, '9.0' pods() end target 'iosSimulatorBuild' do - platform :ios, '10.0' + platform :ios, '9.0' pods() end target 'macOSBuild' do - platform :osx, '10.14' + platform :osx, '10.13' pods() end # ]TODO(macOS ISS#2323203) diff --git a/RNTester/Podfile.lock b/RNTester/Podfile.lock index fa2df22bf04c5f..5227fa2cdce4c1 100644 --- a/RNTester/Podfile.lock +++ b/RNTester/Podfile.lock @@ -5,7 +5,7 @@ PODS: - DoubleConversion (1.1.6) - FBLazyVector (1000.0.0) - FBReactNativeSpec (1000.0.0): - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2018.10.22.00) - RCTRequired (= 1000.0.0) - RCTTypeSafety (= 1000.0.0) - React-Core (= 1000.0.0) @@ -58,7 +58,7 @@ PODS: - FlipperKit/Core - FlipperKit/FlipperKitNetworkPlugin - glog (0.3.5) - - hermes (0.5.1) + - hermes (0.4.3) - libevent (2.1.11): - libevent/core (= 2.1.11) - libevent/core (2.1.11): @@ -67,16 +67,16 @@ PODS: - OpenSSL-Universal (1.0.2.19): - OpenSSL-Universal/Static (= 1.0.2.19) - OpenSSL-Universal/Static (1.0.2.19) - - RCT-Folly (2020.01.13.00): + - RCT-Folly (2018.10.22.00): - boost-for-react-native - DoubleConversion - glog - - RCT-Folly/Default (= 2020.01.13.00) - - RCT-Folly/Default (2020.01.13.00): + - RCT-Folly/Default (= 2018.10.22.00) + - RCT-Folly/Default (2018.10.22.00): - boost-for-react-native - DoubleConversion - glog - - RCT-Folly/Futures (2020.01.13.00): + - RCT-Folly/Futures (2018.10.22.00): - boost-for-react-native - DoubleConversion - glog @@ -84,7 +84,7 @@ PODS: - RCTRequired (1000.0.0) - RCTTypeSafety (1000.0.0): - FBLazyVector (= 1000.0.0) - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2018.10.22.00) - RCTRequired (= 1000.0.0) - React-Core (= 1000.0.0) - React (1000.0.0): @@ -102,10 +102,9 @@ PODS: - React-RCTVibration (= 1000.0.0) - React-ART (1000.0.0): - React-Core/ARTHeaders (= 1000.0.0) - - React-callinvoker (1000.0.0) - React-Core (1000.0.0): - glog - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2018.10.22.00) - React-Core/Default (= 1000.0.0) - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) @@ -113,7 +112,7 @@ PODS: - Yoga - React-Core/ARTHeaders (1000.0.0): - glog - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2018.10.22.00) - React-Core/Default - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) @@ -121,7 +120,7 @@ PODS: - Yoga - React-Core/CoreModulesHeaders (1000.0.0): - glog - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2018.10.22.00) - React-Core/Default - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) @@ -129,14 +128,14 @@ PODS: - Yoga - React-Core/Default (1000.0.0): - glog - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2018.10.22.00) - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) - React-jsiexecutor (= 1000.0.0) - Yoga - React-Core/DevSupport (1000.0.0): - glog - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2018.10.22.00) - React-Core/Default (= 1000.0.0) - React-Core/RCTWebSocket (= 1000.0.0) - React-cxxreact (= 1000.0.0) @@ -146,8 +145,8 @@ PODS: - Yoga - React-Core/Hermes (1000.0.0): - glog - - hermes (~> 0.5.0) - - RCT-Folly (= 2020.01.13.00) + - hermes (~> 0.4.1) + - RCT-Folly (= 2018.10.22.00) - RCT-Folly/Futures - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) @@ -155,7 +154,7 @@ PODS: - Yoga - React-Core/RCTActionSheetHeaders (1000.0.0): - glog - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2018.10.22.00) - React-Core/Default - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) @@ -163,7 +162,7 @@ PODS: - Yoga - React-Core/RCTAnimationHeaders (1000.0.0): - glog - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2018.10.22.00) - React-Core/Default - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) @@ -171,7 +170,7 @@ PODS: - Yoga - React-Core/RCTBlobHeaders (1000.0.0): - glog - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2018.10.22.00) - React-Core/Default - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) @@ -179,7 +178,7 @@ PODS: - Yoga - React-Core/RCTImageHeaders (1000.0.0): - glog - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2018.10.22.00) - React-Core/Default - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) @@ -187,7 +186,7 @@ PODS: - Yoga - React-Core/RCTLinkingHeaders (1000.0.0): - glog - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2018.10.22.00) - React-Core/Default - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) @@ -195,7 +194,7 @@ PODS: - Yoga - React-Core/RCTNetworkHeaders (1000.0.0): - glog - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2018.10.22.00) - React-Core/Default - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) @@ -203,7 +202,7 @@ PODS: - Yoga - React-Core/RCTPushNotificationHeaders (1000.0.0): - glog - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2018.10.22.00) - React-Core/Default - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) @@ -211,7 +210,7 @@ PODS: - Yoga - React-Core/RCTSettingsHeaders (1000.0.0): - glog - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2018.10.22.00) - React-Core/Default - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) @@ -219,7 +218,7 @@ PODS: - Yoga - React-Core/RCTTextHeaders (1000.0.0): - glog - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2018.10.22.00) - React-Core/Default - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) @@ -227,7 +226,7 @@ PODS: - Yoga - React-Core/RCTVibrationHeaders (1000.0.0): - glog - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2018.10.22.00) - React-Core/Default - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) @@ -235,7 +234,7 @@ PODS: - Yoga - React-Core/RCTWebSocket (1000.0.0): - glog - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2018.10.22.00) - React-Core/Default (= 1000.0.0) - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) @@ -243,34 +242,32 @@ PODS: - Yoga - React-CoreModules (1000.0.0): - FBReactNativeSpec (= 1000.0.0) - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2018.10.22.00) - RCTTypeSafety (= 1000.0.0) - React-Core/CoreModulesHeaders (= 1000.0.0) - - React-jsi (= 1000.0.0) - React-RCTImage (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - React-cxxreact (1000.0.0): - boost-for-react-native (= 1.63.0) - DoubleConversion - glog - - RCT-Folly (= 2020.01.13.00) - - React-callinvoker (= 1000.0.0) + - RCT-Folly (= 2018.10.22.00) - React-jsinspector (= 1000.0.0) - React-jsi (1000.0.0): - boost-for-react-native (= 1.63.0) - DoubleConversion - glog - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2018.10.22.00) - React-jsi/Default (= 1000.0.0) - React-jsi/Default (1000.0.0): - boost-for-react-native (= 1.63.0) - DoubleConversion - glog - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2018.10.22.00) - React-jsiexecutor (1000.0.0): - DoubleConversion - glog - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2018.10.22.00) - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) - React-jsinspector (1000.0.0) @@ -278,14 +275,13 @@ PODS: - React-Core/RCTActionSheetHeaders (= 1000.0.0) - React-RCTAnimation (1000.0.0): - FBReactNativeSpec (= 1000.0.0) - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2018.10.22.00) - RCTTypeSafety (= 1000.0.0) - React-Core/RCTAnimationHeaders (= 1000.0.0) - - React-jsi (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - React-RCTBlob (1000.0.0): - FBReactNativeSpec (= 1000.0.0) - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2018.10.22.00) - React-Core/RCTBlobHeaders (= 1000.0.0) - React-Core/RCTWebSocket (= 1000.0.0) - React-jsi (= 1000.0.0) @@ -293,67 +289,63 @@ PODS: - ReactCommon/turbomodule/core (= 1000.0.0) - React-RCTImage (1000.0.0): - FBReactNativeSpec (= 1000.0.0) - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2018.10.22.00) - RCTTypeSafety (= 1000.0.0) - React-Core/RCTImageHeaders (= 1000.0.0) - - React-jsi (= 1000.0.0) - React-RCTNetwork (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - React-RCTLinking (1000.0.0): - FBReactNativeSpec (= 1000.0.0) - React-Core/RCTLinkingHeaders (= 1000.0.0) - - React-jsi (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - React-RCTNetwork (1000.0.0): - FBReactNativeSpec (= 1000.0.0) - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2018.10.22.00) - RCTTypeSafety (= 1000.0.0) - React-Core/RCTNetworkHeaders (= 1000.0.0) - - React-jsi (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - React-RCTPushNotification (1000.0.0): - FBReactNativeSpec (= 1000.0.0) - RCTTypeSafety (= 1000.0.0) - React-Core/RCTPushNotificationHeaders (= 1000.0.0) - - React-jsi (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - React-RCTSettings (1000.0.0): - FBReactNativeSpec (= 1000.0.0) - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2018.10.22.00) - RCTTypeSafety (= 1000.0.0) - React-Core/RCTSettingsHeaders (= 1000.0.0) - - React-jsi (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - React-RCTTest (1000.0.0): - - RCT-Folly (= 2020.01.13.00) - React-Core (= 1000.0.0) - React-CoreModules (= 1000.0.0) - - React-jsi (= 1000.0.0) - - ReactCommon/turbomodule/core (= 1000.0.0) - React-RCTText (1000.0.0): - React-Core/RCTTextHeaders (= 1000.0.0) - React-RCTVibration (1000.0.0): - FBReactNativeSpec (= 1000.0.0) - - RCT-Folly (= 2020.01.13.00) + - RCT-Folly (= 2018.10.22.00) - React-Core/RCTVibrationHeaders (= 1000.0.0) - - React-jsi (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) + - ReactCommon/callinvoker (1000.0.0): + - DoubleConversion + - glog + - RCT-Folly (= 2018.10.22.00) + - React-cxxreact (= 1000.0.0) - ReactCommon/turbomodule/core (1000.0.0): - DoubleConversion - glog - - RCT-Folly (= 2020.01.13.00) - - React-callinvoker (= 1000.0.0) + - RCT-Folly (= 2018.10.22.00) - React-Core (= 1000.0.0) - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) + - ReactCommon/callinvoker (= 1000.0.0) - ReactCommon/turbomodule/samples (1000.0.0): - DoubleConversion - glog - - RCT-Folly (= 2020.01.13.00) - - React-callinvoker (= 1000.0.0) + - RCT-Folly (= 2018.10.22.00) - React-Core (= 1000.0.0) - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) + - ReactCommon/callinvoker (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - Yoga (1.14.0) - YogaKit (1.18.1): @@ -377,7 +369,6 @@ DEPENDENCIES: - RCTTypeSafety (from `../Libraries/TypeSafety`) - React (from `../`) - React-ART (from `../Libraries/ART`) - - React-callinvoker (from `../ReactCommon/callinvoker`) - React-Core (from `../`) - React-Core/DevSupport (from `../`) - React-Core/Hermes (from `../`) @@ -395,15 +386,16 @@ DEPENDENCIES: - React-RCTNetwork (from `../Libraries/Network`) - React-RCTPushNotification (from `../Libraries/PushNotificationIOS`) - React-RCTSettings (from `../Libraries/Settings`) - - React-RCTTest (from `./RCTTest`) + - React-RCTTest (from `RCTTest`) - React-RCTText (from `../Libraries/Text`) - React-RCTVibration (from `../Libraries/Vibration`) + - ReactCommon/callinvoker (from `../ReactCommon`) - ReactCommon/turbomodule/core (from `../ReactCommon`) - ReactCommon/turbomodule/samples (from `../ReactCommon`) - Yoga (from `../ReactCommon/yoga`) SPEC REPOS: - https://cdn.cocoapods.org/: + trunk: - CocoaAsyncSocket - CocoaLibEvent - Flipper @@ -441,8 +433,6 @@ EXTERNAL SOURCES: :path: "../" React-ART: :path: "../Libraries/ART" - React-callinvoker: - :path: "../ReactCommon/callinvoker" React-Core: :path: "../" React-CoreModules: @@ -472,7 +462,7 @@ EXTERNAL SOURCES: React-RCTSettings: :path: "../Libraries/Settings" React-RCTTest: - :path: "./RCTTest" + :path: RCTTest React-RCTText: :path: "../Libraries/Text" React-RCTVibration: @@ -483,12 +473,12 @@ EXTERNAL SOURCES: :path: "../ReactCommon/yoga" SPEC CHECKSUMS: - boost-for-react-native: a110407d9db2642fd2e1bcd7c5a51c81f2521dc9 + boost-for-react-native: dabda8622e76020607c2ae1e65cc0cda8b61479d CocoaAsyncSocket: eafaa68a7e0ec99ead0a7b35015e0bf25d2c8987 CocoaLibEvent: 2fab71b8bd46dd33ddb959f7928ec5909f838e3f - DoubleConversion: a1bc12a74baa397a2609e0f10e19b8062d864053 - FBLazyVector: 013c754530acf200c794982a91221cae2d73186a - FBReactNativeSpec: 205d67e3c1809fe430adc7be677d28a32e4000ac + DoubleConversion: 681b789128e5512811c81706e9b361209f40d21e + FBLazyVector: 400431a0922224a5497bc50a6be9b1bdef19c23b + FBReactNativeSpec: afd0b576c189e459fb30a609a3f9d830dcee69e1 Flipper: 10b225e352595f521be0e5badddd90e241336e89 Flipper-DoubleConversion: 38631e41ef4f9b12861c67d17cb5518d06badc41 Flipper-Folly: c12092ea368353b58e992843a990a3225d4533c3 @@ -496,37 +486,36 @@ SPEC CHECKSUMS: Flipper-PeerTalk: 116d8f857dc6ef55c7a5a75ea3ceaafe878aadc9 Flipper-RSocket: 64e7431a55835eb953b0bf984ef3b90ae9fdddd7 FlipperKit: 88b7f0d0cf907ddc2137b85eeb7f3d4d8d9395c8 - glog: b3f6d74f3e2d33396addc0ee724d2b2b79fc3e00 - hermes: 12d049af0d8e8379c5b3b54ffb1919d670045bdc - libevent: c2d56c8554ac18101d9c5f4c66ef762798209682 + glog: d86cb3634e15ec6d8cd9a1c7c1b9d6fa295beb37 + hermes: e6c81c75290bb87d1d62d594c269fba09b84e216 + libevent: ee9265726a1fc599dea382964fa304378affaa5f OpenSSL-Universal: 8b48cc0d10c1b2923617dfe5c178aa9ed2689355 - RCT-Folly: 1347093ffe75e152d846f7e45a3ef901b60021aa - RCTRequired: a35e388bfd87cfae16052677bc19332723c3adf1 - RCTTypeSafety: ca911637f851c632e50a5b45cc64eab3d2095060 - React: 21af9a5655a1db8877643ae7d2f5be19fbb47bfd - React-ART: 3f4d3b94140d58fe5ece4a87bdb5580991e4e1fb - React-callinvoker: 595e477e1cbbfe3797d9d234119a13b6ee85b398 - React-Core: 15d21e9ae6eb47f7bcbe993bcd0a96cce614f378 - React-CoreModules: feb2df372bf41cf30bd8544a7877ea893a06b7e1 - React-cxxreact: 9542dd531c5e32be8af79730a1872efd97d53684 - React-jsi: 5b0fca1241f693a72a8a8d4c304f40c4974ca091 - React-jsiexecutor: 63cb155b06c33c3fa419bf28cfeb8233ef3b0307 - React-jsinspector: 01ef3dbf108f91ad18fa116a535549a0011df122 - React-RCTActionSheet: 40d0e005ede6d2467c71afeb7ffa2ee6401141ed - React-RCTAnimation: cd11932218e9b897008e2d318b865c93aa505212 - React-RCTBlob: 6df18a5bce5d5e80416f669e9718b43a5938c242 - React-RCTImage: fdbdaa9388e56484e54c494fca08353a0eb86bda - React-RCTLinking: ef6a633aae7bfcdd93bbd561c0bc270f3550066e - React-RCTNetwork: b1f15c879b25c7450948fd02e5865319fe7bc4ae - React-RCTPushNotification: 39643b44ffc839ab7b08e77d67c87155eeb6be57 - React-RCTSettings: 0b0507c7bca2943d18eba209ded78a24d0a385b5 - React-RCTTest: 6feb342f17fd908c570180f70b68b0fdc0b1956e - React-RCTText: a41b641c73e5ec0ec550e134b2da92c5cd5ff43d - React-RCTVibration: 4eadd5837934450223a859e5c7323c6c6102a36f - ReactCommon: d2c0a0c8eb10562cfbd5b7da17072f956d66b200 - Yoga: 52f1483134f196a52b290ed0982f07efc8c90011 + RCT-Folly: 71ece0166f9c96c1ec9279eeb0317baf533c020f + RCTRequired: 039450730eeffde3f7bed7ba52eb2f307b69bed1 + RCTTypeSafety: 54bcf1b9aa76bb4acaa1495e1ba85c25936fe0d1 + React: 9dcf1d3e01570722c0c2ebbe0d63bf153725bee9 + React-ART: f44c068eb3cee3976c8201f2f1f79702857073d4 + React-Core: e2fb745f8aa333a091c1f41a54800f53b5f05ddb + React-CoreModules: 1134e8e6c1bf21d8b5d642666f2bbc8a37292d26 + React-cxxreact: b2b9575868a5eb1f7d6ac0de8cbbc6cd90a9ae1b + React-jsi: cf94d3ca73c9c6a799033833895d8a06dd19ff8d + React-jsiexecutor: c97ecea1c4599a2b3e45fe3310bcb219de56c3c3 + React-jsinspector: 444837ef05559864a5ca83b28abebe113a58c748 + React-RCTActionSheet: 79ea92217b954519079a9811aa852d5632a1581d + React-RCTAnimation: d0f6702230f56146d86a374241fcbd4b96e7bce9 + React-RCTBlob: 2574bc088ef2b93e575357f8250169524f988e62 + React-RCTImage: 8370e436d956768d0d1d2db49ea244cec8fb129d + React-RCTLinking: 84e1949bbdc3134d0862cc9708c7b8963a0ca003 + React-RCTNetwork: 28cdfc801e77e5f1a3818ba2d1ce04f9783a02a0 + React-RCTPushNotification: 114587b6e2d45fbdeaf8bef480ca445a89904820 + React-RCTSettings: e2abda34b07d937f856642648daadc546dd2fd7c + React-RCTTest: 2eb3b4b0ac61d1a5c03d8c8cf3da94472ebc3e51 + React-RCTText: f3232089c4a96ccd6d1973f3ba53e7588157ab29 + React-RCTVibration: 98372b990afbac98325b72ac0120109b08dd0c00 + ReactCommon: ff5c621355270d8e82e4801f86da20cc748105fe + Yoga: 9561510b9e44840446c02f490733cfb0f4d2bec5 YogaKit: f782866e155069a2cca2517aafea43200b01fd5a -PODFILE CHECKSUM: f92cb3c61bb71bceed9b9afe3944fbd8451be8b9 +PODFILE CHECKSUM: 8a50297c26ad9d948d1614b33e20d755094cb377 -COCOAPODS: 1.8.4 +COCOAPODS: 1.9.3 diff --git a/RNTester/RCTTest/RCTTestModule.m b/RNTester/RCTTest/RCTTestModule.m new file mode 100644 index 00000000000000..7f894b636513a4 --- /dev/null +++ b/RNTester/RCTTest/RCTTestModule.m @@ -0,0 +1,89 @@ +/* + * 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 "RCTTestModule.h" + +#import +#import +#import +#import + +#import "FBSnapshotTestController.h" + +@implementation RCTTestModule { + NSMutableDictionary *_snapshotCounter; +} + +@synthesize bridge = _bridge; + +RCT_EXPORT_MODULE() + +- (dispatch_queue_t)methodQueue +{ + return _bridge.uiManager.methodQueue; +} + +RCT_EXPORT_METHOD(verifySnapshot:(RCTResponseSenderBlock)callback) +{ + RCTAssert(_controller != nil, @"No snapshot controller configured."); + + [_bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary *viewRegistry) { // TODO(macOS ISS#3536887) + NSString *testName = NSStringFromSelector(self->_testSelector); + if (!self->_snapshotCounter) { + self->_snapshotCounter = [NSMutableDictionary new]; + } + + NSNumber *counter = @([self->_snapshotCounter[testName] integerValue] + 1); + self->_snapshotCounter[testName] = counter; + + NSError *error = nil; + NSString *identifier = [counter stringValue]; + if (self->_testSuffix) { + identifier = [identifier stringByAppendingString:self->_testSuffix]; + } + BOOL success = [self->_controller compareSnapshotOfView:self->_view + selector:self->_testSelector + identifier:identifier + error:&error]; + if (!success) { + RCTLogInfo(@"Failed to verify snapshot %@ (error: %@)", identifier, error); + } + callback(@[@(success)]); + }]; +} + +RCT_EXPORT_METHOD(sendAppEvent:(NSString *)name body:(nullable id)body) +{ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + [_bridge.eventDispatcher sendAppEventWithName:name body:body]; +#pragma clang diagnostic pop +} + +RCT_REMAP_METHOD(shouldResolve, shouldResolve_resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) +{ + resolve(@1); +} + +RCT_REMAP_METHOD(shouldReject, shouldReject_resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) +{ + reject(nil, nil, nil); +} + +RCT_EXPORT_METHOD(markTestCompleted) +{ + [self markTestPassed:YES]; +} + +RCT_EXPORT_METHOD(markTestPassed:(BOOL)success) +{ + [_bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, __unused NSDictionary *viewRegistry) { // TODO(macOS ISS#3536887) + self->_status = success ? RCTTestStatusPassed : RCTTestStatusFailed; + }]; +} + +@end diff --git a/RNTester/RCTTest/RCTTestModule.mm b/RNTester/RCTTest/RCTTestModule.mm deleted file mode 100644 index d5aa9ba1dc1f6e..00000000000000 --- a/RNTester/RCTTest/RCTTestModule.mm +++ /dev/null @@ -1,161 +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. - */ - -#import "RCTTestModule.h" - -#import -#import -#import -#import -#import - -#import "FBSnapshotTestController.h" - -#import "RCTTestPlugins.h" - -@protocol NativeTestModuleSpec - -- (void)markTestCompleted; -- (void)markTestPassed:(BOOL)success; -- (void)verifySnapshot:(RCTResponseSenderBlock)callback; - -@end - -namespace facebook { - namespace react { - /** - * ObjC++ class for module 'TestModule' - */ - - class JSI_EXPORT NativeTestModuleSpecJSI : public ObjCTurboModule { - public: - NativeTestModuleSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); - - }; - } // namespace react -} // namespace facebook - -namespace facebook { - namespace react { - - - static facebook::jsi::Value __hostFunction_NativeTestModuleSpecJSI_markTestCompleted(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, "markTestCompleted", @selector(markTestCompleted), args, count); - } - - static facebook::jsi::Value __hostFunction_NativeTestModuleSpecJSI_markTestPassed(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, "markTestPassed", @selector(markTestPassed:), args, count); - } - - static facebook::jsi::Value __hostFunction_NativeTestModuleSpecJSI_verifySnapshot(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, "verifySnapshot", @selector(verifySnapshot:), args, count); - } - - - NativeTestModuleSpecJSI::NativeTestModuleSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) - : ObjCTurboModule("TestModule", instance, jsInvoker, nativeInvoker, perfLogger) { - - methodMap_["markTestCompleted"] = MethodMetadata {0, __hostFunction_NativeTestModuleSpecJSI_markTestCompleted}; - - - methodMap_["markTestPassed"] = MethodMetadata {1, __hostFunction_NativeTestModuleSpecJSI_markTestPassed}; - - - methodMap_["verifySnapshot"] = MethodMetadata {1, __hostFunction_NativeTestModuleSpecJSI_verifySnapshot}; - } - - } // namespace react -} // namespace facebook - -@interface RCTTestModule() -@end - -@implementation RCTTestModule { - NSMutableDictionary *_snapshotCounter; -} - -@synthesize bridge = _bridge; - -RCT_EXPORT_MODULE() - -- (dispatch_queue_t)methodQueue -{ - return _bridge.uiManager.methodQueue; -} - -RCT_EXPORT_METHOD(verifySnapshot:(RCTResponseSenderBlock)callback) -{ - RCTAssert(_controller != nil, @"No snapshot controller configured."); - - [_bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary *viewRegistry) { // TODO(macOS ISS#3536887) - NSString *testName = NSStringFromSelector(self->_testSelector); - if (!self->_snapshotCounter) { - self->_snapshotCounter = [NSMutableDictionary new]; - } - - NSNumber *counter = @([self->_snapshotCounter[testName] integerValue] + 1); - self->_snapshotCounter[testName] = counter; - - NSError *error = nil; - NSString *identifier = [counter stringValue]; - if (self->_testSuffix) { - identifier = [identifier stringByAppendingString:self->_testSuffix]; - } - BOOL success = [self->_controller compareSnapshotOfView:self->_view - selector:self->_testSelector - identifier:identifier - error:&error]; - if (!success) { - RCTLogInfo(@"Failed to verify snapshot %@ (error: %@)", identifier, error); - } - callback(@[@(success)]); - }]; -} - -RCT_EXPORT_METHOD(sendAppEvent:(NSString *)name body:(nullable id)body) -{ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - [_bridge.eventDispatcher sendAppEventWithName:name body:body]; -#pragma clang diagnostic pop -} - -RCT_REMAP_METHOD(shouldResolve, shouldResolve_resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) -{ - resolve(@1); -} - -RCT_REMAP_METHOD(shouldReject, shouldReject_resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) -{ - reject(nil, nil, nil); -} - -RCT_EXPORT_METHOD(markTestCompleted) -{ - [self markTestPassed:YES]; -} - -RCT_EXPORT_METHOD(markTestPassed:(BOOL)success) -{ - [_bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, __unused NSDictionary *viewRegistry) { // TODO(macOS ISS#3536887) - self->_status = success ? RCTTestStatusPassed : RCTTestStatusFailed; - }]; -} - -- (std::shared_ptr) - getTurboModuleWithJsInvoker:(std::shared_ptr)jsInvoker - nativeInvoker:(std::shared_ptr)nativeInvoker - perfLogger:(id)perfLogger -{ - return std::make_shared(self, jsInvoker, nativeInvoker, perfLogger); -} - -@end - -Class RCTTestModuleCls(void) { - return RCTTestModule.class; -} diff --git a/RNTester/RCTTest/RCTTestPlugins.h b/RNTester/RCTTest/RCTTestPlugins.h deleted file mode 100644 index 1572f3a603a1a4..00000000000000 --- a/RNTester/RCTTest/RCTTestPlugins.h +++ /dev/null @@ -1,40 +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. - * - * @generated by an internal plugin build system - */ - -#ifdef RN_DISABLE_OSS_PLUGIN_HEADER - -// FB Internal: FBRCTTestPlugins.h is autogenerated by the build system. -#import - -#else - -// OSS-compatibility layer - -#import - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wreturn-type-c-linkage" - -#ifdef __cplusplus -extern "C" { -#endif - -// RCTTurboModuleManagerDelegate should call this to resolve module classes. -Class RCTTestClassProvider(const char *name); - -// Lookup functions -Class RCTTestModuleCls(void) __attribute__((used)); - -#ifdef __cplusplus -} -#endif - -#pragma GCC diagnostic pop - -#endif // RN_DISABLE_OSS_PLUGIN_HEADER diff --git a/RNTester/RCTTest/RCTTestPlugins.mm b/RNTester/RCTTest/RCTTestPlugins.mm deleted file mode 100644 index a057177b619d66..00000000000000 --- a/RNTester/RCTTest/RCTTestPlugins.mm +++ /dev/null @@ -1,32 +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. - * - * @generated by an internal plugin build system - */ - -#ifndef RN_DISABLE_OSS_PLUGIN_HEADER - -// OSS-compatibility layer - -#import "RCTTestPlugins.h" - -#import -#import - -Class RCTTestClassProvider(const char *name) { - static std::unordered_map sCoreModuleClassMap = { - {"TestModule", RCTTestModuleCls}, - }; - - auto p = sCoreModuleClassMap.find(name); - if (p != sCoreModuleClassMap.end()) { - auto classFunc = p->second; - return classFunc(); - } - return nil; -} - -#endif // RN_DISABLE_OSS_PLUGIN_HEADER diff --git a/RNTester/RCTTest/React-RCTTest.podspec b/RNTester/RCTTest/React-RCTTest.podspec index fa90f9eed2ebc2..f69065f8368280 100644 --- a/RNTester/RCTTest/React-RCTTest.podspec +++ b/RNTester/RCTTest/React-RCTTest.podspec @@ -16,32 +16,20 @@ else source[:tag] = "v#{version}" end -folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32' -folly_version = '2020.01.13.00' - Pod::Spec.new do |s| s.name = "React-RCTTest" s.version = version s.summary = "Tools for integration and snapshot testing." - s.homepage = "https://reactnative.dev/" + s.homepage = "http://facebook.github.io/react-native/" s.license = package["license"] s.author = "Facebook, Inc. and its affiliates" - s.platforms = { :ios => "10.0", :tvos => "10.0", :osx => "10.13" } # TODO(macOS GH#214) - s.compiler_flags = folly_compiler_flags + ' -Wno-nullability-completeness' + s.platforms = { :ios => "9.0", :tvos => "9.2", :osx => "10.13" } # TODO(macOS GH#214) s.source = source - s.source_files = "**/*.{h,m,mm}" + s.source_files = "**/*.{h,m}" s.preserve_paths = "package.json", "LICENSE", "LICENSE-docs" s.framework = "XCTest" s.header_dir = "RCTTest" - s.pod_target_xcconfig = { - "USE_HEADERMAP" => "YES", - "CLANG_CXX_LANGUAGE_STANDARD" => "c++14", - "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/RCT-Folly\"" - } - s.dependency "RCT-Folly", folly_version s.dependency "React-Core", version s.dependency "React-CoreModules", version - s.dependency "ReactCommon/turbomodule/core", version - s.dependency "React-jsi", version end diff --git a/RNTester/README.md b/RNTester/README.md index 4efa9b297ab165..a85e0845709857 100644 --- a/RNTester/README.md +++ b/RNTester/README.md @@ -8,7 +8,7 @@ Before running the app, make sure you ran: git clone https://github.com/facebook/react-native.git cd react-native - yarn install + npm install ### Running on iOS @@ -32,7 +32,7 @@ _Note: Building for the first time can take a while._ Open the RNTester app in your emulator. If you want to use a physical device, run `adb devices`, then `adb -s reverse tcp:8081 tcp:8081`. -See [Running on Device](https://reactnative.dev/docs/running-on-device.html) for additional instructions on using a physical device. +See [Running on Device](https://facebook.github.io/react-native/docs/running-on-device.html) for additional instructions on using a physical device. ### Running with Buck diff --git a/RNTester/RNTester-macOS/AppDelegate.mm b/RNTester/RNTester-macOS/AppDelegate.mm index 54c1b1945712c9..ec2081a88475d8 100644 --- a/RNTester/RNTester-macOS/AppDelegate.mm +++ b/RNTester/RNTester-macOS/AppDelegate.mm @@ -18,8 +18,6 @@ #import #import "../NativeModuleExample/ScreenshotMacOS.h" -#import - NSString *kBundleNameJS = @"RNTesterApp"; @interface AppDelegate () @@ -93,8 +91,7 @@ - (NSURL *)sourceURLForBridge:(__unused RCTBridge *)bridge if (strongSelf) { strongSelf->_turboModuleManagerDelegate = [ScreenshotManagerTurboModuleManagerDelegate new]; strongSelf->_turboModuleManager = [[RCTTurboModuleManager alloc] initWithBridge:bridge - delegate:strongSelf->_turboModuleManagerDelegate - jsInvoker:bridge.jsCallInvoker]; + delegate:strongSelf->_turboModuleManagerDelegate]; [strongSelf->_turboModuleManager installJSBindingWithRuntime:&runtime]; } }); diff --git a/RNTester/RNTester/AppDelegate.mm b/RNTester/RNTester/AppDelegate.mm index ac15022b495250..8d1ac2aa4c4f30 100644 --- a/RNTester/RNTester/AppDelegate.mm +++ b/RNTester/RNTester/AppDelegate.mm @@ -8,7 +8,6 @@ #import "AppDelegate.h" #import -#import #import #import #import @@ -152,21 +151,17 @@ - (void)loadSourceForBridge:(RCTBridge *)bridge - (std::unique_ptr)jsExecutorFactoryForBridge:(RCTBridge *)bridge { - _turboModuleManager = [[RCTTurboModuleManager alloc] initWithBridge:bridge - delegate:self - jsInvoker:bridge.jsCallInvoker]; + _turboModuleManager = [[RCTTurboModuleManager alloc] initWithBridge:bridge delegate:self]; __weak __typeof(self) weakSelf = self; - return std::make_unique( - facebook::react::RCTJSIExecutorRuntimeInstaller([weakSelf, bridge](facebook::jsi::Runtime &runtime) { - if (!bridge) { - return; - } - __typeof(self) strongSelf = weakSelf; - if (strongSelf) { - [strongSelf->_turboModuleManager installJSBindingWithRuntime:&runtime]; - } - }) - ); + return std::make_unique([weakSelf, bridge](facebook::jsi::Runtime &runtime) { + if (!bridge) { + return; + } + __typeof(self) strongSelf = weakSelf; + if (strongSelf) { + [strongSelf->_turboModuleManager installJSBindingWithRuntime:&runtime]; + } + }); } #pragma mark RCTTurboModuleManagerDelegate @@ -185,10 +180,8 @@ - (Class)getModuleClassFromName:(const char *)name - (std::shared_ptr)getTurboModule:(const std::string &)name instance:(id)instance jsInvoker:(std::shared_ptr)jsInvoker - nativeInvoker:(std::shared_ptr)nativeInvoker - perfLogger:(id)perfLogger { - return facebook::react::RNTesterTurboModuleProvider(name, instance, jsInvoker, nativeInvoker, perfLogger); + return facebook::react::RNTesterTurboModuleProvider(name, instance, jsInvoker); } - (id)getModuleInstanceFromClass:(Class)moduleClass diff --git a/RNTester/RNTester/Base.lproj/LaunchScreen.xib b/RNTester/RNTester/Base.lproj/LaunchScreen.xib new file mode 100644 index 00000000000000..f7722dde9ba78c --- /dev/null +++ b/RNTester/RNTester/Base.lproj/LaunchScreen.xib @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/RNTester/RNTester/LaunchScreen.storyboard b/RNTester/RNTester/LaunchScreen.storyboard deleted file mode 100644 index 373f89ee18c77e..00000000000000 --- a/RNTester/RNTester/LaunchScreen.storyboard +++ /dev/null @@ -1,58 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/RNTester/RNTester/RNTesterTurboModuleProvider.h b/RNTester/RNTester/RNTesterTurboModuleProvider.h index 4c61336a6df343..1d684d3ee4c725 100644 --- a/RNTester/RNTester/RNTesterTurboModuleProvider.h +++ b/RNTester/RNTester/RNTesterTurboModuleProvider.h @@ -25,9 +25,7 @@ std::shared_ptr RNTesterTurboModuleProvider(const std::string &name */ std::shared_ptr RNTesterTurboModuleProvider(const std::string &name, id instance, - std::shared_ptr jsInvoker, - std::shared_ptr nativeInvoker, - id perfLogger); + std::shared_ptr jsInvoker); } // namespace react } // namespace facebook diff --git a/RNTester/RNTester/RNTesterTurboModuleProvider.mm b/RNTester/RNTester/RNTesterTurboModuleProvider.mm index 9c2707654fd76a..70dca8cf2505aa 100644 --- a/RNTester/RNTester/RNTesterTurboModuleProvider.mm +++ b/RNTester/RNTester/RNTesterTurboModuleProvider.mm @@ -30,11 +30,9 @@ Class RNTesterTurboModuleClassProvider(const char *name) { std::shared_ptr RNTesterTurboModuleProvider(const std::string &name, id instance, - std::shared_ptr jsInvoker, - std::shared_ptr nativeInvoker, - id perfLogger) { + std::shared_ptr jsInvoker) { if (name == "SampleTurboModule") { - return std::make_shared(instance, jsInvoker, nativeInvoker, perfLogger); + return std::make_shared(instance, jsInvoker); } return nullptr; diff --git a/RNTester/RNTesterIntegrationTests/ReferenceImages/RNTester-js-RNTesterApp.ios/testLayoutExample_1-iOS13@2x.png b/RNTester/RNTesterIntegrationTests/ReferenceImages/RNTester-js-RNTesterApp.ios/testLayoutExample_1-iOS13@2x.png index 271e80d3f6b48708ddb8a2c9c8745b85d6eddb4d..dc942bca73cc235771421df23a993d7561df05b0 100644 GIT binary patch literal 170852 zcmeFZby$_%+cvoAP*OoDK_vtvloF|pC`fmwA_#0kx?4m9L`6b6q}g;MrGzv{Y-*Fz z-3_xgh|lx>zL{gbnLp;3Z|3DV;NIMO-RoX?t?N3^bFBacISB%MN_+?eLLm9{u@VG= z?gfDmCE#L%J7y*DK5#*^Rg!oF$?2e;2md%3X-FE&%0gJcXIuy-8YKh^l?40>qf!0+ zERJ>uf^l{q9Rl$;g<$?kBL}XipAX;{_00JdBLVGCYH%+B{USBGR|3YxXQBj<8j=f@ zdJQgkubyh!LLlS}s9!WmCHggRliKvLyb8F27ovV}y1<`1=U4CU%caKLD$a#a-TiAw$G69okl z1x1B?R&?}Ryb8o0leSz|u`p+aIv28ScUI;LcUQ`11>!r)D_=Sq@9>T7$5wWBEVbR` zakTWEz`$^W(AMItp`BgKnsCCC3Semk8L$P)e{TQAz=di-P0<=J(ye(@ZlYlt1gk!f z_YmBlz}SNbdl8L;3pz2{Pi5La|A0$xBoQ41mi^s%VJd^@pA3n;aG`Mre_jeM35{+L zGz~+t4rN+-_rIA5dqEyUHhTTfaz4wGX9feemNM&A+=0`=kH3XM!=yw1kS6?3Mbhul zLLvPcew)2b|1Jz2gv3j5`=8Q6gZClmd5tVFX~O?53AzKWiq{!l~%OPHgtu=t0%RcFeskev_P}qMZirc zXbdk1CLII~_o~GB;c5+EPpT|Y(PwVeK3pg>!g+J%n!40;(SK5L-^zP6@g0h(<_A#; zP0>2Ry?7kt6h@*TolvB@Q0dioAW>>%6eeqid+`D~^aaB35~(UkZ)+gt-@6br5zMb} zB@PJBPy{H#MdERPuOc$^E+T0g@AI;OFH}XrxFzd*{qgS$YiZFi6GXy)WBz?G(+7+) zmQ1|cH!m{t5<$m>dfsiu`&&&FEHIr^Rj!CX`dcYaOk%GSjZat3ngLaYbbNH&+RSvu zpx1w2e}YQ~InJkN`ddZ?GVoMfrs>3YKjVX~`8b=~RJcXd=%GyVg#EGR{0vF-sDft3 zL(n-TXgZ>JTHQ|eXN{XbG4MY>vU8g2N;Iz8?&o67&hshX?$`EwsQAP+Sv>f@1dYAQ zTKU8qs;J(L5{uzCh?B`cj;O66ox7UoX|WDbnlAGx?P}T&7T~u%C9`fo4LDQI_7ccH=Q@VKX!U@ zO|O{WQzVh(p1@Jb^MqHp=)}07ExE4Gv`1gV6*&wMLO6uV^4?pmIrX@Wm>;cjb+Uah z@%jp7Z0;M3c4v$!#;{?rUY}%~%kI4_y0W4~s>9}mvTMU1h>w;EJ2RV)y82yLtN4!G zISSkE&+OKmR+%CziktFtna?!S5ep-~tMP%aVpQO+F`ZP7OfP|YTkCGhXzhz0zA?8ecJZ?n4*5;eRg$vN zyzRYxePq#9rA`C{1jdu~0mj`)PewQHepb}NGH`cy?{Iv6DJ&y$lTuN?Lo9r0W0^`| zxk!1hvUB^!D^RqJ^|syNPqdx!A|m=5F|$!qr5}2(%Ym6>M3U}|mcDzCo$fjn%(wAK z1(A#WZjQ@gX@GOZ3k}0Z@jd0d({z~no2KHPH2L_o5eyiOu#hz^@_HHI2gP zh%8PI5H(SCzBrYVKaQVU87$27-+3DBR5H@9>!@ox;dd=+eX7ZSKdc~hl`+MQ9y88q z60dM~)HOOxU5~#kXS89+Wf9(P-9+w8oTC&k zVLse#UAuVhskCmp$YS zgc=_kvX|j5e9g8Krq5UZfaH2rqpl+|jOXB2yM)gzOFHR$e0e%0!$*8zwkN1^UV@V7 zC-E`!1!z$cKAcO?Fy5({`~}zMZ48Av`ikdQ-2QGM=*YUB ztd?f-VJ~m}q5Z;DAsP<^t}T^S{acbc>tgm{!}1b&;r$np64f-tkYPcOlg;?qpo1Y; zuHX85!Hu8d>-0xR@>kJml|tLS%2e&Uvn6rv$J+?aeXSBw4dqmsdmFTTB95o;SaW_# z!D^l^H3fGSn{I!gn=q}(5-5#K@P8Q1h}em9UBN4qTG+j<-zAo0-i498P2&0t@1f9= z1{JOIZxUCQfr=WofT6;Uhpa)co`L0+%GJ0+iKLOSM=3im$=+}fdwHp&^Kd{oD&~^b zXp^)Y*sJ%RCwn@iync=~4l<{}Un~h!(&F!E#fBIaBCvTbNrym z>Qpj|hjWNw2_M>^?t)h(M#x{U<9WO-4(D8H*Jfj=n5anXB3J@;kkCTIb-6fLD}ery zW%d4yK@>GC-csE1(redXox>GbmWKpETCdGVT_iTYZFX=~GzSD*&a80Xwv--|=BT=w zdbn)mN#$y4Uz1xhWF{&|uwpGSXr>QmUn%CHd&=fY8ceFZGxE%zra!&1fD|n~JpA-z zx2Eo8tbIRTZt}<49VZpsdU8(NE`JC$pQVn8?~y8zRBrV_rZX@QGFfWyAefwsa1mh2PM{LDJ=c{KFvmw21pTmo_ z$}DuHp@UOq&V@Id$3hmRSppY&u>%xf!-@Vk%!vH8cT2Y`$Bx`}&!Hq`)d8BWe@xquK1UaYn!uW~B0O{Dl-mXEZ!C4-Db|Bf1j z#j2fY4!ihW88U-3QOITMRWc@@@S(ik@Lb?r4y4x^uL#tMg_X#DwG4^uj($>26{$sN zhoLt5d>Wrk_py(PZhpTw(oGs~MYe^^i`0ZvD>I}|T_5ST)h!WRpjui|l_P++JJ}Ez zTv4*b9}sDx5K%3ZD=KXH!Kq}Hz9kv%wvdYWJ;vLS5}~)iNK`?)T&|=IK?bq7CX@YQMdEd|J8}!}Rrrdi=mmT2Vf<3&6%ℑ|V&M z-)k`^i&mTTz_ha=cAM6%#Iq9bqJOVSz+*NyCe9W(Qpq*ZSV&c3|QR!4U!=EBov1jD$j>mn8 z8jWah>5G#xs9hwoKaY=o)j`vcxsmfW^t#=T(?icwj^C6_IwLE2FXNmUWmps~wV(6~ zWsp6a^tnN3UX?-CMpHCiGNe)ou}c&Em>Wi_v;H~jlE!7LZ|jW%=6y*f6s?4OW$;}y zyr4^@v@Vf_&fNZxt@Xq1(>uf33FMLih6vAMDM_7Ip4v4BeYru{aSd2iKVTFY_FdSt zHCWTCImi8kC13`70(X-3OQxU1s@L&)i05T3t|gHlb87Nk-77s{8s|6NpwjkrdD*Ea z0e^2T%3(VEz*0J5vI1QJS-J1SYKJTz+`xlQo94#mx{f&9%iu}>-0im_o2i0!$J*GU zCwP>A)@@DHX@$sh&)1cOxMo2~O{+MrEIEG~hgaTSbNbTCVH5@q;pOBKdbIQvhgLD7 zdy~pbPlumlB?#cMyp9~SK2}=QuBdbO+-T<;vy(Sku4IdBzX@?a_Tb(xg5!iCg} zqG_2_)uRD>moZElk~yq-1wTu!mvjp_ru^5*vegJ$*;yd=?!$hW;qs23lf@;6?JNWR zf0glN&hf`O`aTY5Z=!(@eZovAE4RIa@jRGMyQvSa zf%)d7A<*w0Qg9g$CAMT&RlYV1S}pD6N3>g{%aPWbZf^kN6l&w zK0Z}ykgNIrn3qi(7g{RV= z!eIRtH8vbnmB`4v%qDEdL|a~p#XwXLNwQN8v5T=nu7VGbL$J#RY?p^iJGFz9<@gzb zSZ`X1Nt1f9gpRr&_QaoDEqSOZ?2xr9UFooF7D#KUTlXpV(t`-ERt5-9X-ZW|YEtvH z-d`3|yv2~M4SR}-DVYG&xI+UXqvyW zQUZodRxc}OU=gOzu?>4jgD2DeW5&U=2@e`TI9xDMeR~gBB!UtE*NV*}G z^hJ~X$9(h*5PO1QKmE7C0vca4uo70sLiBFuZ)dPf<#IWTHx-U^NE`tja1)CMb|{&iK(sB{5RX@#K=`0Mp}&<53rs>yViw61Qv z+lFMM_^O)tk66c1iZ}$d?f&&;+VIzqUOzTk_5e&ayue7*P9-&>M8I8J$WVF6m9Qlv(x`{i`(d}`$D_l zpf1q>86oIVmwP(Cw39ws(@USZh8AL}semnU{A`nv47E7fFF9LfEMZ1Dito*W3;1$$ z(7R%PD8T7f4m!J;EncJzFQ+?Svt>J-CcNJ*7`UQxZ-KDbp`jg~x>$DQDy!v9v^x`8 za<8-%lY1}*k48Rbrr<(T5Z^*p46g6qyeWw`S0b0e&`%auq5~pAi@Zl~;ej*6Ucw$C zX48diIWBVw5#?(1`O__Z6|*NL+@W5F(WOB}eItRq998`WzMva7SP&jCoU^&+9YyX% zxs*tL=`ck8%C`z-=d!XsDU&pQMK?$095C+&OB%?vU&xwe+oVsoS{w(yw`^yE6zfD8 zeT@#Oyc}orbvK*)kqTU9DEvM}(OLH%RwubC7a)3n*_N=X?@W_=Y30bmJ>Q{XX{usI zvoVYLJm(=ez1#qVkkLDXoTQY`7_Up5M8`-kP2U!4Oyls zJ%Nf&S@f=) zmbF&>llvO+>Y-Aw4O8`OldZ41j{Oy?!f5FaR$^dU1=7B^?J#~-8d8=oIT)D@1uOZS zwNs_w7fS^#nn&BWw2RRLv@CQLsJ}ue67LOKdpeX$e6y-g7@hq*jglTv{^nwfKataP7nO z0z|)>$F1(P@;l4c0k)N6)aVKhY8!{vOlI#-R;|@rto5b4dB}hXx4R7XWVMf(FpT8T zZbB%*Iu9?(CK-WE@+Upb()o zF#v_%mS{Ih&3XUeW_ma!o1}dcjbpu%d^AL5H)#gn&g$|3Q_XV8Fr{P8!%|K^%!Em) zfsF0e>cAIP)GqM~Y-!!mA<>@I?z@cB_|OzZ$0V(`5povYU7{}mvBi&LE27{updlg$ zs4^xcw3TcI`OF76le>Q?lBBX572ln9N$Z$l%7^z0mj=qRS(>?jmeqRJI7G_?36noP zIS#Jy=?gQTTJSqi@)?y^;j0iZdE#vP=oxYZiC3JAu7K!1w5M!Ka>+x!m&&zS&ig@_ zD&|k9saw-ul1l7V5xyXajE=hh)K{!m%Y4jF))(?Qc>2g=1cz?7%5eIn?@UvXM`E}! zobaFg^X#)aUpKbY_6_QPAm(Rl@`nhlTMPtAauhjz7tHr)o9Y2rA2R3#W%m`!b@9R zG|$NGx?}E|J_pxGUmO~}W8ZU^VXiUb<0rE|u(+ZsWTdpi-g3+iV^ z%-$Y!cRNCTw@f^DAvE_%5kQ2VAz?Qp(a#{!$Tk)^-}|e%d``!Arv=0)B!9{RU$0Xf z8E3YCmA3S-bfmjzU46pDmPBE(#N9{?85xD&U~#Mz7>XS*kP*_0pN_yj$BDfl<|F{R z56TsXPr)irmef|imTzu1r2RH2CVn-`p+W3I>3pkCy) zsEmzWPO@`Plkpw{L4}++&t|#~7H~pSOD*$&Mf#IB{UZokB(B z(tzUP2JzF^09Pl;eu4kD4Sz|4r$#I4?*Fa)2VBt5w=|ls{>}Mo1bC{--q+~jRZuz- z(9njV8EdKPtJPasjYs3@PCHF|6Bv5Yoa~)PcASW zn|2M3PU3|t`kM0}I`8WUV8Y^XReXn<#N(va&q+hT-$8}P1-j59Z5ld>;%SBdNlyn6 zA{lS055fC~`pay<5p0gI&pjnywBBu{A zL{7ilpYi@D<@Ujb7B?(9jRw=8g*7HE<9A%D!6ohUEWORv(c~*Q+OYqV%~M*zNVM53 z@`cDa`>D5v;yG+w4ZdI)>1Q$G?DQkS`2MdnCaCwL=^0ZTw8#zoSyPtsH0FWt{|Dl;#hp&YGR}e63r}?~dvLSuYqN4&WWN3v#pI?)d6B~yqRSWDtT*{2 zMn&o3ja=8Nm3_%l50~?9SVhkpm5JJd?;iznwD+3!$cp_yFMQGbiTHuQ#VA%0K|>DP zhajr-cHNMNvmJ1G8QcTLH;^qB$YQ(t6jLPL6{hHhz-xy&tQ!~8mCg^-t`kwEPf5p2 zGFLf(3k^Y6SkNbgUd-==9o(lFM_r_Io}6#3qHv+|=nBWDX6UKYouz@FXwPR$!b6be z=_UGgxdbafvw*%ZruaKZ(v~tb#7)SFEpiZi|=4u9~22(J81lN6m&@PH!#(B ziok%_uM_)Y#OOd#h$iLnDbaos;s2TX-exyZ47XZf?sKM#nH~pB8Yq=cfceEtPbUYD zVj2|hu{d1Vr||%gE81Lh*iY>L&g%beTe)oZ0ffGPscLt0Vz&BlWiyxtB))7D}%>bH( z*AZzS;S3^+wy%<*1(VYU_dQRJvSH+*>}F}^uYP=HRt_qgw_U5ld0B-qPz*z?#dLH6 zGFi4o_-q^(DWHaI0v|$72~rIp)0x*-J$6dsDop0eU>Br<;$IT7b^kc$SVr)C`Hj4yEqaWTNQ!1}UvA3!2hdaE^ z$!zF(B&39Az6TWjyiY8{UPDk!tYJeRK5Mpt2LP#}WciT2>Go_aWl3zB+7`vCYSi}b zkC)>H2*4Z?yx!(!~-8S3X0a0_^^`xMcJ+Mj;os;|$&RMZ*xlo#x zu4w6faxdW5$7%uwq!6?Bra$#_Yy!#`fI%f5f;*0M0ER8wiS#)N^tqm9Fp+ICsMMbvLP9U~zcIl{#CW?c1b$vL( zcoXuYjY}X1-N7^ufML)C2jG;Ec#VD=D}|`A#*3#6$tRMO?T&eRhSxq^F6t?0DOs&P zG>%2gjp&FXTXP_G+E>C-U3XVBXVtYWc(}}Z({%>1ns{6^**q<)QNXhrC8hy6VfA^3 zJv#5OoM~-HxLIU{maet^z%zd%BkR?wUE^306cyMp%rVs%-1?5`-gN@X?nS*tfLn!# z2ON8JiQ*Wg1eV;r1u@LGCO)&bf>+K5mC6w2IG}2xR7(I_d!67${&x$cJ%T6j8b`;w zWR7mdCK>?;^Q#iR^5()rW_eQgZayr~K=xZgAr;&M0OJ$tO3#tD~l`0<}#{&-%-xl|sAr8_j9q4;f^gJM1EmXY{4Q=k10qt4s zKb>2;O*lQK0k^!m;NWqXnpU%U*~A-TAem?;Rkuc0z>x0Ov2Ev!n^~~^0U&kCIOP)} zk)u4z6<0NGTnge1(vzypU^T8hand6KHf+N(NRa40>HtWkw z`ep?b33n4yRt7*;LxLxJQ^o^%&qNW~0%5ISB7Gtgk%P1(%*A*|ZFXWizVd%P9m8+C zl#vZ*bSXhs(I$X0Gn!Z!@F8<5SE9nQsnOCMsgQ!n(skw63@EQhU>~BI$qYE*U`cI1 zbiV|x8lJ_EwnSD;7Z(HTt+{TCR||%%0BhXLk#c%&E?-Wb00{7G^sInMYipS*8MbVt zKnPinI?sZEGIX8H%cV14!D%+uv0wxA!>vZ=GZ+1=PRICe__bCw$Gp8_;;Wm~_b z3x7Rs2$Rk2J9DXf_fpsj;NgBsZS2p+znspp zT&=lW&2M5#Ag3wRBiI^K+oVAlO3nT!lPZx+qyr?I+@Q zIgQT<^ovXs!<`D}0mcg-dNyV1y4lVbZQrlSBHesCGw-6E*(+Y%k~ut%lXW<>)Ikp9>Vwi}uB&%A;Gt0K`?MmO z36>GtK)u{g5Q50Isia$7aG=u_ip3*)UggL@M` zm)PF|DkBW$3ZSsxZF=zd?l5ti>EtQWq(ykCo{0pg#>($G`hLq%GYk52lh+EsA>fZ} z+KizqypbHqE@)v%EVFKShg9EP0~#LV#vqDNvfK}lnEOUjYOP<|IVyy$ZbG$K*dr8* z0leI@0oTXK7L!s{X6nyA3+zlyM9G?YKTern(XGq`0R@b%f6W?c+AM_YB ziul4&b97&wJotT9rF!eHClO`J9%d;^$V$h^)T?Oej~6C|e}51QQoCinDFWvH55d7R z{hfC>h^^m3vRPL9EA69LSAP(RT%K9Z>fJ-}RML5a%+Ffd)mJ&CKI|+aI_;K+`b=!h z>?_S)Nt90j2$L5B`!Z(~j^Z%h6~?Q`C%SDsJPA*n%>o3@1A$)bGo#5XD3tnnbGDOD zin{QAr{s5z^_)1j4-NU87Eeu*yv$INlCuP8+!CN)VqcL3;h?S z8tvZDfw&iB>uVR2Y~1ryx#*QjkBjgV;>~gkmGijt-k_V?Z79Tr)T_|AlPlhHJw@}I zQ~v71TOt>bP^Om`w^xxDw>Oz(bxCz#2xN;MqFNWq=ni9)iCLn+qCYxJJq z%}vl`(y>0!${%|%vs$FaG8+nF3^8?UA7^63y+G#s~Q$?VStF!DbXe0vX1%5e;3D0Sk?NM zd3*yUoosQO2+bowoBIdggLr4&MCGKrM{oWZa*)GtQCMh#87}?J9Jg!2{|~<68*!wd zb3r#{a4|7CyN(G6(ey4oNdeFi1XD?Z4$peJ@`L06a4mJE$$s;h_1>}VRg}Pr2l!8- zPfVu3ylGmjak!p~XkKoyA)yFv*wjVftJr)-@est+ft;)yR}^EtWkHcX;B3q&d$5m3XUm|LqXL zUojx~m}#W4;=V2M{;tN=;v>l;O+r-sUdP=>J%NH%S}TBeuWGB9M+4pjRRy?AhXtpt zkQ?SN$F*k>(GsM*L-+LoelS6Rd>8393?kHaMxMSqkUsY>xo+LIEUO^YBMs-TNVXia zC>dn@sr+cIuv0itJR@oqFl2nBP6xorDof6)^L0};CRwN*s zzCMg~)NP6BS+c#XIwa@YMvF1<$2t%9fs*M(XbCRxqGhy=mpMvDY!YkppTGKI6n+n( z@9D0wGS>kF`oUUC5+OHegj7|>;yn)L^Oj!5Sc}UIgYZH3_RTx@z;H!{^r?Ur0*?3k z19gZVaPS$X2T8Rci;IheE#F==lWqdlSzdk5WBcR>4_~z~r@dZ( zN8_gW4${kmO?1Ot4anOSF!g{Y_F)X!`v;S64KVY>(WLXrC%iBSaXXG@_-gP7v&;dS zC*t$5=y`XhDl4B$UhYaC*c-xk-4x~wuUx5^`F@Fm`?=_E`-reDqY<}0A;eMmCyingAHXM}eb?#Sp1;#V6L73!X zOn3)hgeqWah)!AZO!884R|N&z0-39Xe6+Cp!RuKb+~mZ>M8%jg3{+&(ouga1rloCJ zZj@~9IAof(=BARZrMO)fe|*DjS`>8Sag=EEzNoew+&H0vlqY z`Ks!(2g)aMJ&$3d+{2cY7T2pBS4W?X^vH_{39hUZS&az?87@1NqTtW@zO0C7`VmLx z3_q1=`<{x!4P8{I;;nW2e7Nn?V~qpYBS@=yN!GRIc!vvMPuxIC{*{0A+h$u7EQcbd zXKoOn8b)Cfe4eF;+dzqn-pnvzB4n?y2pCMwI7SZ0Kc87IX%v`_Dj$jw3DIL9eeW#9bm|`Z3PpKHHWd? z)E~{*RA5PLzFJIUPE!QY7G=fg3cl98X3TXi0ItKDR*;?sCWd+@@j;*9!o$1VXIzsM z9jXDs$Jxu18JQuvqSpPIFL|_>e=O^%@);Fv%S<-mW83FSePafI6wkyu5QTF)PCW1U zd>itzJt~X`5ieec(ixlhA!r;&CKw5J8@|7X>H#G+WxHtlE?S7dN?G0rsFr1ZpYN`yu0S?K zRq>7Q9R1Vq(07UbG@t#R0XQ(+03{`#uGeY_D- z)5bsdgUr@?)js18F}lWja$&0ce~A>PgH)9Zi*i~BCLGjRKDZg{H6qC#^0JshAI&-u9s03@}Jm2wl-R92H- zsR-7i$!j&Z{3f66auV28*Og%L;wr=Aa+;e!tvLLH!Ge{{%W`+Am7^wRbBNTvq=N_m zP1#QDxd26GU5q)N6n09Fjy^*m!q0FYy(1)0v1auAY; zE8!$%w~hz6zfh3lxHnE?c=IxT$@iObcN-bsQ{R<uG}p&wk!YY|(6oWsqaz z1~k0S4gfsFiZFTrl;zNbC+GCTgA!KAroCdL?%jAuF9h2)l*1v5{HspgGH-A1E!)|S zb~2vTbsNm_u0*lImZS_xRCmVQGkg<$cO;^VIs7BlsyEIJ+>KW~u$=EUVhreA#iGdG z{qGU_9u(o~KK%qakhX?PXmg~70HICiIU`@L#mh@U%zD$vSefG8Y&cugF|KU5#{u|k z;J)d~!%{4{eY1*Cn@9ZUUGB3o$nNgux1hyyWEW;SntlrHg4F;M_eF^Kj@BsG%Z|G^ z!5NPs>{>;4TCwesv-k@`#U*A?e=1@xc7ijWh5Ib_=iPaC|2>e!@(lHj{+0(DRPNtB zyczJ?FIM>R-i>ESMx&l$Z?k{_Uxbp-eMZE%ChKcRo7IMDX1R}IK zIX7gAbi|_u6T6f8EAp3@+xo(CA9iis^S|L@!da?U6xc`R)kJM8lMI`KR+}1(n40}o zFZWTC%eNl@+aR+|aBJ^UyP?piuD2-YX5c4t3;&1Dkk4!@^j+mMi`o-4mX z$a)MoneRFJ#ose{6htxPvc0-`IZ^v%611-IJnGYv(3X8nea#IQsy<-$j$GF93PG|& z2rrdIkz(y*ZO7noum?-HNEPGJr1-=r*jo6En(fCmf|c>h#ZN0RJj_SjP-7ywXiEHc zCESy84F%f{XZy0Db6&#HN3C((XP`Z=%{v=HdS-~dErPN{?Xl_fCE3JV*4qPyAr$Qs z#+?>`L`%)dVZZBBA2*X-IIDYaq5~_v_!$azx1!_~Te}B0t!)WBK*|Z{h8~yij$`hnAM*-t0 zhLVMgeLiF`MY~hUjaD$TXDg8@b^YmHEN~a=pqCIHrHktDr$BTJ2TVu=^~S^^m!(+&9Ve@s?utxS!C)Spcec_DI3>Xh|XIT}dF!S8DyD^%!ij9Q-zO z=NRlcdO6bnC`I4CPt}*~0e%Vs_c{DDDE*c3_dhvw=?Pg+Xi2Eu>js_(} zN#(0gw?gUYE^sUX`L*y7h)qHk+hQigs66|0eeHTo)E5_=eg;d)7rXsPD@S zSwh{PcmZ6$Qn@V_y+4AuoIflcxKmmW;U(@DeU=O zfY*G`2hXAGJ_Mad{0soT7m-$Wkt>QsJi`Brr`--K#GSBaV zCw}IhKM$-F<(Y@pAK9v`bCD}JPJj`jI`LlwaJE9GbkQMJnryVi&WA(n)2z3nLqLpf zK3ZKOIWSk*c7ecoK{qfz5vy0j<^Gq9XaDxi|I$(Uf7jyw9SBJrY##9ReBg+P8fUzU;LFK-S14*X<0gGOvPo`7?jP8+V0llhT5(> zyM+p{CiX$dk>Bl1Q?{5>>GJ@9HqVxv3ICWwGd~nM#aD>}p$i4C33z)Ri+)u%(+|o93Bo5ygO-ZUkH?+%XQ8@d0uKNcbO)ho}wFKI(`f zPEwZ$0P?BnxFgm*j~DePtc&k1REZ9=3;^7R?mc$mK;C*I6;2a(ROFwfFWvsES7rY6 zDn1@mx8wa<)!t;_rk<{^Sh%jkAT$r`eYe-N#<_f*n0m~za@l7JAWeAnV*m%FZtO9* z5>Sr{bsq2k=i%?;{|nb3}NoK^@KN?`2y_Jo}UYOAedSYya9@5_2LZk)RAt$ zg|=@p<)=ELO{IF}Ga|vT**%3_Ppb2j>$|%914u^1P}iaJi<~RD3@`jk>$q zU7{0GJ?O(4fZVY;?5sMT~HT@qK_g{AAFsN7mOp_}0ZRrZbR1O^`RtXhm@h%I@$&QD1a-qC1=hCt@RKR83+mKZT7=E2(6SHT%Zoa%7gaS)lcL>iw zD&ScZOQG=IXruF?tCWwf5CIBji!osg5S62Bg`Ru>^0r^56&B3(Lm^U;{{7_dFO_6z zIHRzN;K1+q&ixOlEGa;F_p!gcKEruc-a%9x;r);kfa+4bdl0}KP>WKQ7=xo9u;5@O zZ2A;MojkeiJ>_%AK7j&ZulfCsMJsub4QT=r63e|&Zg9*cvL~hiXWdN z{R$tv!W*c$EPduh#@RNXB5ur-46okjE2`-(G9B(W*_RULG-06y`)0Vfa`kwej;|h} zeZCI#OBp_xpUy|Wth_;E8~@DUHNAU$_GJwtQ6%n2mmRL-(UXC1TpLteZsxHR{Lk|D zojy%q_%d#KpZGGlka?1ZR$~CqZf-d3j5mdb5=RQ;b_njbZHlsvO$i-Fd(+BW6i^BJ zkc!530-ZcFxq5Z9u_>DQr_)`Xv)vm|gRZWRsmH-IGNozy+&^lvCHA^2B3Niq9wqC6 z`tkhBcq(Dev(vc7nP~UsLKSCrDrxUW=sUybHy4^_f{9+Pd5bm(f5_#@jj=_kf*a8D zs-JmZoZ>|uIcPfzPSWx09dRBrG@gre;d*}bT$nR`0B4I>@%_)%2$UNBG31s3$r|86 z$Lnxr`ucDtbG17o+HmyU)z@Wd*WWsofW0tVd|F>j4Ol+8i!i8_$}`9xZ!S``{mkE# z-9;Ej?S#nlTpQgF<}W{{w>2LQsFOH+m}>hjxlBsAnTJ(UTODCw{66v}qy3j>jk-d8 zLBj3@`&&N)WDfJ+8F*{c4#bp+$KYQu5R1uGYc} zi`bB98GWPK)8@$Gc#!Cq`*;HJ^p1nD;7@61Mq?}Y#!(6iS6}k#U$6BIKSt*Bg{q4& zc79!oRpjg2inFops!-2d3v5(pP25n5lN^+;ZoVXPFYcjxs;R5Hz-D6}Ucktad-1K0 z^4ldcw?NRP$_CM=;T4!04aP5*s>zDha6YUalyx_C=&GV3vkCK1=gZ&Nu~_{cqPL&u zTBU1CxH`Ps>EYAKKyzM8s`FQyq;DsyB~xv)8{u+hDR`_4hD58z)dM{OP_ z<|M*Y&8*yYkwkD0l8OHGC%NA@%`|(9SxQQU4XwHsBG^VKOXpM_^bqNtI$27tvql?p zLMdXB$ZykcAL)uAGJExY@x`uPS(F@;;X>#+R#9y1f2+4VDH>6=YK_gU5CbzeOAgY} z5>#NhIqe0L|CaYP+u6N z+GjC?qP-V+Tl-79zn2p6d9stty9krF>I18UAi~I)zN{K4I|C;fqj%Zd?R)oFxNrCq z%2KF>LCoJ->a!jsY3o+@dd|sqFT?IWF2OZhe4U1P8LAEA$kY zys%WhR6V!-LhPP$y@?iiaGQl$-L- zn=16;Kgut|y*?Z+LW8we@6D5Y?~43t7d$=i2j?I{uI!#67c7_wGc$qj@@Ed%wef|z zVV2eD*I_xU1t}k@+6RG@GagCaLpBnlTch|0R#kFW*!O0?f2vR}O7hV60xcH+b14#C|a+|9MAPGhy8`R6On>6H{aMq-MHM_|w? zb3mAkwR*TkZEf+Y=j@H7tI5P>jgkCTxi>b5wNXUXj`a_!f* zWomY1W-Dn4g^$N*Vna2@_{86=n;+>6k8%(+f057lHb%kUpkuF^HNJV!m0LAUHS|%F zN^3d~kvF_s6RF=@jFOu5UV^f9laoDbKi1`)K9I;^7;+2X)8GG@sMCfmSSgojmg|E#YZyfTs9uFvU7&jC@VzxXSP(HSqQD%w$ zij~k}-r6pDA4M2W)1Y<)vlu_@kdckpDAXKQ zUs|u&{&kmw++K`B)#T1ednuCat#`Pv=eRV6MD(I%*}bd6Y7lTv!>-WA3u1k^5%Ta` z-0tQ^!abw)kgP&bH8%C(#o=g@Fa5O-sJ5U66a+NN5oAqi5I6gu*LzM{xrPx#pZ}uHTGB((p=Ne<_(dx-jo`)h7RrP**_5djs>E4dC9R*|58q zdt8rsCXPtZ4`MGs(-T>$ITq1uhJ^L4p~9~GJfw$Whe=A13wo)JB?;p&oN$uMC@9-wS6NR)*cbJ%6w-^)I(>qN5a~^6rquM0^%*A;@j-#Z2P+Jls zV0dI`K+PrdlDqfxy9bV}@KUTphAS+LN_&Z=hWfw5mVqhX; zR?vZ}w^lx+?s*m+e4c&g+ISw~q}I5f4EA7{NCh%Idis&H9f@Ow9JrG-#nG#Mm!OFwx4817{O3=VmaInbFU$q* z2tRLRa{CplRkt~OU>JMA>^)r6L6~l(Q_8m}UHQI8e70$Bf`4^R%Xe=(b=u!cuv>s! zG?x2LQ2xkD*+h}0r@y7AeudGWA*`>!jN=NfvQ4IwLiB;zjqxJmOhqoI4^2ESdJ0O58759_ zOO>*;O;;HZO*xm%goUeo5M?IpIZY?fzc-H^1yxq-d-nWERBCOEU3WhsP`U-7FJz4# zv3^r8FZp>tIv_M3s$6TgdjL-bpws?VQx-LuOGY!G#(3{Bj?>ex0Pbf=j=C<1ND@!f-4C-q`|8tiHqHK2N!RfbGP_@)no0E9o0le{EmH6&bucHIgh8tQrh)W{?b0 zKSUpoF#9|b;MfcEWNs@$jh`*jaasCZNWV3d8*Cl)d8Eq4=`3B)MEkB7#TvS#ZF@Gz z;A0$?e~kd>BVEzA>`R(2P0~5PUpl+l_uDFV|1FoD@170$$3{oHK<6|p0iosaj=4Z= z`=0|7u}k?i=YKVO|E}svP5JyKe~=4as=HDcOYwLWHvh=N@;uHfIA@^d_I{=UNU@a& zbJ8#kBHO^wR~^RAEGJ6e$*?@G$poyU;`!S^AG?#9@!2>*1YN;Y&LgvL_D=W7XZm<9 ze$Pdzk|f60P@{G#Z}*_*ig{EX>Ed4!xWt|AATqkI8vV24b$_14sPsh08B|HV{8Wji zS(s$8(J+6Ru5(Sbpz)K7o+Lxzt6maVd*3NL@LVz#r_dRF8z1uBhcd6&P35a*wnt_R zxYYPkO5LRP13=PEVfisJi4wR{_yjA9!DqCsy0bvq zSSnAiSr?mqBAY6XKxv(Iax{uf6UyGU{u2?=%N0A#vl*YVKR7r@dcEnC6$y4o`yea}ySxpY0KAMd+IGSiFI;Y5?dw7o=w%*5aS@dg<16cKI zn~0^*C{9{Q!tZ!>q>|Ar-(4%i=|0T~I^V7KGGN>=WshP_vewgtW*HoE_9$LZ=y{N} zWhfzvWT1%J*F(4~k#%Ue_s^IL$RpGxSf3h?FIvApHcNrBm9wfg{j)WmUM#K{Gc3|3 zy!)sCn>QcqWI+ZbNEXEU&O+{s9e$GqbOGOw1@b1;8e5a2J{xR!_f%$xs=F0&q}OjN zdOl8(BqyB@dRTPc$y{-U(QLk2?&)KpjGG3WarwQg01z7D@_R?q>BX6wnOidIp_H$t zJ2f>&ff6_LT77P1I-c&ew=Qu*Qs>U#@K)u;hUH@7zVfN_5JStEPxrKc8D4d8@oNS=L*=%`Xx9vyV;5YYM(OsWYzHpvrbD($Oq z(I`80PDfyQKJAD>72oNF@3y3!K(qCK=u!RHBJkX3VaY){3Cc5Fx84I6=aJv)@s_5Il_)H_M7YYRZwuMK+GYvltH zgdZbU8Ed75SRlDKk`GPLDAmKHv=Kb9n(DfQA%_Qxm;IxFxwKDKlb>Jb!IBR5jj@9|*i80r-YbO`lh-dEnY{x!Xc>CK!9lz4?8J?R-nNXd zj=QlqV=D{I6uI68#sE?6D!!FU}a&-2q6T=o)F1Jj0!Fad0HM)D;Ybmi{ zp?E90eaX=``op8?yPxz%W}i2u*p(k8&+G-G1nhz{^A3gi`V)wmwBTNR&SfdRIf)w z22rYMh;_4bdV*-d_&ZB!i=hkgPliT##jm-m&QU24CKkwo0he+=vdg|4&^{Pna3#7* zbyi8hGLBrQ1h)8}REpqD;=I~EWw%wePbPG>je+{I$A^yK+B+4Jf4<&oixu=1oJjr_ zm?72W-u7I0ZTgq9g+5khB&WbYa(;UM)i#w6`P2DIyJVXkm-zFP`wmA8iMVtdzhJ2oj!Lu%;3{N)?RQI=T?_)%QXejTmMC}vsWz2(ANPJCS;d?^n#VQPKF z#BTM9@P`aM1ZY+Zdvh4F>^X&1iwF!Szxpph8+B^WNV)H=NBvZTnB=5{k= z;+4O|mOiKIt>|!79k4{+b%dMv77yJF7A6_B-$yxUWA+IS>1aC z(B=&<&!43kV+y4K(sxU&hD0hx}Y|cvFj9VQ#K!c zoz0{la}qD}4c&0-P2g3EF9mWTRo~;8EF@{8PT)O3N6(G7`(q&FWk9k%(YrsQ$rm8G zUI%#`%KK%_E>pOZy|LSuNh73N@Bt<8Z`j?hy7v`bTX++UwDe)WKt!OkpQ*p~6$==2 zqRJ(?%5at++;Y7=ruO%i2@lv3Lk6B>+h*VAf4LTq#`{!zw^4u45UUus8-3UC_^A7A zt;%}3?U?Aw@|!;Cp9U?|s8w^FQ-U_ZBTp_rOr_y0zV%q@S$zN40HJPuPe5;^OEC>6 zsL04ywRzlF7?49PJ1}Pd=o7~as}ExXp5a0US(`W@{lMDFm*6~x;NTP*poBGn!SJg8FN)Pa@oRj&g7TPtVZoKdWPU) z*ZJJzwsB&1@N2YN+eK{A(I*vICMKD;p596tFKFTX#Q#NlES!Sn>=jWbd40vyRIzmI z&fqieJs%AQ)Xqw8;tUJaH+)|AwynR-mGF4EC-^cC+1ZG`OXsShyq_zNjoS`52p9kq z&6G!lYvfIWsLHk}fq$8PEyWY&Fhi}9wa?NZ`vuC)B;t*RdPx`B&3+O07t2*$30ocX z(yv3iWbFuGvz zo~>>H(_?k%9hYQrRCfKZ6$0iC&hQ>HSH2w}FVqf^)-a0s4R^BgH)%%OBh|RdOUeVi z#hXXdVWOJR_h7h8VVok>XhvK^)0}1(o!z91?cBECTD&9^a;uWZUdLT@Vgyt}|l?i*_rWdk$wWhy_(7d0EpiK@aM?#ZTnOU~C8nh3xnb1@BR zRl5DE?bP^ug2+Ra8~{fxX5xM7yw$C6Wz8EO^0GMO?`nh;f!Sp_OPWXzvFjrJBVdY2`be+BLDOsaES zh^Mht8e6jJ97{C&(au$MwyLs0&i6NZJv!o5#+5E7j{R>6e5#5`SxTGJgp&YKmP=&W ztve0(;XandA4@Cc+Z5^kk>*!$Byz={m7IP1`rEwGjCM2Xm9)$7=70Q2W~G#xhi}Tt zC!*yZ#Xp%Ip14za@+bHU9gw_DWRtwo)A3Vxtgf*wSuA*|y07*XD}k?oxi}n_0}$fv zjt2mjvz1_ukmV$sQEye_S&{tpU`LQEWOjCwPrGPC*`Qv2`$2H1tsVgAitzViu8KrF z-{3IIrX2``pKBq@^NVfDaB4)gXX`qTCc{_$9epdA)+P`c!-Sn zd-4Q6NKFpc2Yq`y696NcRZx*|PZ0gX_m_s7wMDfo-)guI9=;iGPgFK9x}|%=ihwh; zo8#5H<)Yuh^6@7BafvM6uv<5;J@wLXk)mCew6f(}p$TH<>g7K|pGBTWS#X*!8^Jz; zA0ylwR!n?Dd3Ws6`$V$U^^9Ei>o0<3V-Tq3DwVd5N||d5z{CCd1J8TD(J+qF z-aIJE^=S3&%c@xJG3Ka%I2PMUMnM|5-B>U5B=d4 z+SOTpj_Qs>WX90mWqn`4xIeuM*AxKagy;C{d`34GwY#)o#WLUDL{M+*(GVEbDbK^JsQvbLDa$OC8ZC}bJ*1~W079D zRM*YU{pre4UKDJva^R)RV*f<)nlha+Zm~cH(O6MtujWb#V|157JlQF)-%^)ye7?Om zy+p2o{o7K*dl(YRq3y`h}_MnoY z6qx*VA-{ULs2H|n_wi9LEA!3v=MiT(Bgm~SsS@CR?D%q5BiT_XT5SKoFo9*eUq)#0 zqcr+sQ*mkX^D!7lUe#gxMM}icY9Vj5Qi)CxTmuMCT%+fXFbp7YoC$A;x?=q}jz$&G z;M2PA)i5Mz3=~wqX4cNvQN0#ip7oV$wjcO3|8Ytlbd{Rz4T@ZQ^2IpdJXe6iA~=u- zH)X*0i3ukCww%Zdq&=9mmJwzAL6x>%)c1@T;Wt*!^S2o;5zNyqokiT3*V?atPK%YD zZJ7Tsnq)X03nJFtOC7SVf91S!`J(sp`@e$Z;sZjfTjWnNs;~%Im0-v0$m0JW5~2P# zhg|(1j3lCRwErG{{-y*RWlZi3D*w-d`Y+c&2274NTm}F{81%8n!|4P=yE%qO&ACP0 z_su|E93eQqsMZQp^U+=}R_mQO-YK0t3r;{W?=PQ^h701naD_{}SoUO?CMI1o4}(u| z!O72l4zdyYtU*S|EJ$L1^&3?8DV#zZ-p_0KkmS*PxS9M%01gyYj^>zteTT^s>!i4W`lD z`d=J{!Yal<;eyte^w$cz@3IeGhm(f-Z+O##>iKRyAiBZY$$)^h^=)GygDstB^`Jiw zI65HwRlpL6EHDOfHT7%5&41vM8qJHKKTRTb;3NuKeJ2$SFYg<`rT zzQT78;l!dQ_c4%5GvWo3Ol;rS*9@ZdJ{kGl*lfM#XdvT~=($qFR*q>j zf%8GGkK9D9T zDO3T9Ky+trtFDJh9=lO4FRG`>ahJ1RulZHj5|=9TJn(lWgBwV0BWu?OS!O>RT<^>% zk5d@ghAcdzHK03Z2=d`tQ*Qc?ves4W9QV%T7u`AMa4UVYzV|(ac0Z_$Wb^iU^FFAg zG6aVk`O!IFRQpoj_S_r8;K?w9ds$7X!m(StNzOxe@+`DK29WWyFn-&w@$I!Ez@!X%sxD0pWh|+sAQckCuZheBf?{0+jeQSjX^%mS4#8Y;aVm(v zcOz3e)ytU7IY^`G5J76op24logASAcu|BWjD<^&4>k%8EFr`bC!{M$^%F4YA2Qf0W z6r8EbPMl}MK%Q2D3KG)B3#an^4QUG|DJ`}I=ji-cZ;D`h?p_IUx9S}9Jwcjbov6FY z`E1*}LDWMF_(Y$}9p`3`=Jkbz%dpqL@j))2_yLNOJAHR+u{T{ zsn{4roa~k8N!OH_#67kMU%_dkb$rF-9D}H zOrK47STU?0g}%$@oaN?`+%=Pd#hLvF4lL_?m_O++mtT1U&h&w>>(79oDr(o6sYkG0 z`Q&yiTYr`HY_Et3UL!caK#y1HAZ!@q+{ICAPFxaUHMUl6N!uvNd%75J&ZW)4qoZ90hbfkZe`280dBSE zd~cqrtv5sNbBPR*s;ifnK-KtA9d2(22b+^(P50SA%>*}cg;8W;81xo|pK^2N-+r~Y2hQN2J(mn>!mu2(N?R*OXG|eScct<@YQUWk z48G3ssrTuJ{BE!0`4>~hx{!@~-~M2Q>uQ=rm#vz@oNM5*vXix@=3&ywn6EDnyW4>DBt1>tXu%%UV%5JVsTbg9GDizEm-R6pj7@)3eV*WM4vj8oOW zzz30s4=+3<7sh*8RSR;<7=!7G$7R2Qvt(!z1}etKiR zrm(?{1AxJUEF@8Io|Ah>$*;&K`fWLE2bU741O{a%rqSJk$_*~Xv^uh^(WIb9`9&)Z zRW(;cw;kA4ck1h_Xpm}EEXrr$9$C^*g(bpr|7BDzSmmX~r*!8_go+^XYVfen+iI>I zPF{I5ZP9HqlX|IzHGc~2l4sG4+ZKO(eZAn@>sKJj3=T$?!J=aP_Hen=!k~(?v`0}i zw(R#7mC{(hOEw*;b(et1;)T*xvEj;JF2IH$$zY z%Fz%+ge-yehG{UB`=NrOjXw{!kR&F4Rape??1IKmrPpw04_oCVbYEI1X8_o*gxHcu zAP+n3o`0Wuj-ctbZF0L+@N0+InX##-m-#i$iGH5~i=Gvg0@q85`$CF(u9oSyWSQUt zZA3#wN@n_uNEDvtg0ugmueq%mJ*tnxR~U4>8StH1bWc`)q**EA>Kw7o+#qoS2#xNa zuevufwf|>Gl#=&eF#pl?HmzMH_)l|PFH&4tS)+d)y6H{se#=RZN>lR;HF>OlA~in! zLzMoVnea2tkut8b-)@SzKzQfyaaGJ7rg#RfBz>;PdAzbW7cWDlJ*3{J9(gAAwRVkH z(&A!v^UJ-BP~nF ze^0B4e%CT1NSp!@r%2fm@1b(WAFp_GG4o-gs+J~t;;N+lx$dflYq58K_Bgznxlmj? z1uUpfIi=n{?T$%3S7ml-Y)c1IjU#`@c6eosao|)9kU`l`f7*0Wh2-B=9GBFhb@G~K zn3z8sGRx3gvhzBDxnL}CpYc7OfX(NFl?vh1&ZzVDJ+cA|?*~e#?h@;%CwZ_6J}ho7 z(zIXl9_v<;8n$&vm8*E-PKKup;VB!r;Ca>d{VLum4SYq1ReL;a)L-oR44?Yld4(|? zw+``LYwS>?o8)f5BrU4)))qmfhly~EYt*<}5%B3q{?`4%nO}B6|6A?H13aniovcPV zS{bdq?$5QF2k}WS%2kcf-brKaJM+#unyXf2ZeVv~cYL|?@l|C|wy;NJyx@IuNiS~S zS^SdHz0b}TiZc2|Z_e#2G%ntcb}FyDjYTDeMHQou#cVI=nRk@;b;yKUm-Uz{GLfIR zx8XND=DfcVLTKAd%|PZr55W(6D7M68^LG2ei!+eZ*!{Q9vDs0`kMdbS-^iuJ-7^=V zd2}Q@hU(xeDFT2wI0r;m!Js;wIaQcWK9M42NwtQhneRG&=OvVqu7RHEmth31I9A@5q7)|H=F6;R6D>B@1BAMKLL?VVkt3omiKQ@;p8`y!}lX0 zsmW*_2)QLTIe-HhT|{dK#1lY-(1t=^kFdHTu8$I~dS@xk*z4JyrWvz^VaK*Nf{pRl zZl4z3)NJG1Tp8u@nfI;w&`}iD-zW5J*;8$IHjCP9DUhUfC&=BbaZvBG<91y`ZW5*B zR?T>ixz3%X#eC6c4HX>0uG&`SF0~zWkDfzK!bJ>YnXD?Sd!6dTuiw*L<7G zZg_N^bsRiYar|ESdN1|Qc9KMoh>qrnNf0gMgyZ}4E<_HsI`Nv_2p^)6I;%nUQsGrh zOG5`g$%@GL1h+W}0KSEmsMEVI3}gaN?GjCVqSfh8snxub>*e(oLczP)?Bn$+l_cqI z2W}P&HX|>ZzjKZ^y++gD@JuY<4p(v9tajbq?i3ondrHrdB}(wV9yQa&!DRp>c#&O|P7j%O91wVfAl z{pUue7!3`D%?%2LR>qcS54)FgqLodvT79PQAS@{;{9#M=o7<8^fzHoKnl~P=E(sl8 zWg1uT*XtiRds$;BfA>*K2ImUncpI@#-iTF(~UCAUVN z2|BXXjGNp`R-}|U)&uL@RX&fzD&s*}i;sfxxrLsgwBSHx@U>5K0bN$c55;Rco)cs& z7H57~`B@$4PT(iqmx|_Jl~HTRH>lCDj~_~pUUuwLaXn+l6|7n1bH(2ANXNN19bLGn z8*dw?|WLvHJ7H=CiA6Y7J?bAGkT^+e)eymGwW@!vuy{pzBs?FBR9tUd~sHn}1&u7$@y|hRv2JIm>u_^;|Z0-w>Ap;43h++WdQIy4XLi)$)*$ zWeRgE?a4_`N{RcaRJwmj#%t6kzb@6G)5{Rec33Pm35okHhPF^1gR0thl~O#WHv(!{ zab1>(5DLMqtxI(>eSb7KAZ@s>?Yv7;?tbb(XI@US@oSy;{*6};4N1Hg=G?BAb+~QP z?G$%L`)G_E?Vrb7H}4y}g6YzMyhP&Z%i|w}Pmz`FqPUyy%4m;&JSgYAMQi#l_3G-t zkse)I2!FS7)b5fG_o*&fdQ0|}17}Iv!1=V70&i!I&^^!211b^%Vlvj8#}-)e!&mSe zQ0pn2Zyv4mlC!&ugac2%1AAUPMy5) z+@~jeutgb!S;~FYQu#>TV(rs8>SamCxmav`uMsoTY=7v3&L^_Fjd^~g)+z5=OqyST zqaWEPk|E%ED-Oyj9>yCLb<;>UgIVUGD9e%)MV?0b*eyY{x;%>Yn`)?2{KGf>mwX<-+Xs49hP# z>rrJF*Kl{0y=+at&9q2;j&4!;Q(?^+_6)`KMH(ARLeBkSM6@akgu)E6Vd=AOF^vXqkRxvCg9u&jU1e zmEz3&cwI2p^791`_zH4gt6<0t2pG&h@kDi(@skd4Xtti@3@k^q_%9uOw$B>uUaoR~ zENfroOT$e)^3qLHb{%~d?X1^6%UGX7hx!5>em-fSAtTI7)RW!!i=Hy09t`Jv<_^OxtCu0k9oPM#}t z@eJ^9^y^8?^$hIL$_rz;M$eHmIq=I-VY~CPR!{$XGb?0Toh^9==Ry3I?YqmZc$DgqiSbvfUW!_8eSr6p>{h4t?L6Q@U@;@FI`l|)Zq(24unU_lWCmk)& zcOUv%B4j#cbzHMWC2-A8F!T4HZt>S2I$mlzuDq|~d^-ToV)*PIIh_B2LOc*Jse`sb z2QCNH$*7Et$}rU~`4uNG&v)YnWwQ>4{o0p1FDr^k#9BOwySLw5N^%+5f1xsQ|9UD~ zJT;BYBdQ7K6qY$wb-xWgwhMvhvIiqQw(WZ=X8S%JnH^2oocUZTr-uy@=DsD;c+pp7 zSWftkdaAo-X=zT7)^86_iW}QfeEk5G(|@+GW&_w3F;)6g6p+*|n;HwALd#FA3_k|~ zlswKfEr_Yf*#5SPldog-{kR#JDn>glL2?k}7s+2oT!7x?q`X;yBX#-d4haZ_8S|Lh z#nQ|ZH1VAQ)()>{#kWfkYDFniiZ~ARc$B!E5qiRTy$1T8H>sm^C^4B`9Qf;_7qGF+ z?4rwXA#$xNl)2X zIUt%IGh7cF7J1KK;tNy1G=5-hDJeg|F#8=Z9eJ24K2&o~XCQ>Ej6()7vaq4CWaVY7 zj%&kF^*GU?$<*f{jts?p8{N|D*C91|#_1}K;8G)?U~0I6vs5cDnm>1yG^+2tGVaK& zOA9}1QVC7AUNIkTbLnpJ1X^zJiTx!qfn$QoH7Q>vx_BnO^KEE5tCqjD00=U*s8m0= zSohw(2qjRG#$##Hqw{S@GeQ12nE8-<)=)><;J*mgTzy z%S5ewgiv~hDl44LHN8paULC2i}hK7 zMas(o2iTnW_54u{VAmJe7{sf1YNx~-Jyof|sevfnG&+w^*Taoa%oEf49!Cvd zJh7-{D*kG@k;~6ri2Qew`_tZl)}*xF(03BVI9`7p{^#>%&Ei?MV;z4i%4Y zI>^*zi!ydtf25_pPL+!mttY^k2!nh#o$jBjBqN+%@XPXOODLU<89lG;oV`-LD>!U+ z@Xeuo7dN|opJly2&5b8`s;!(&*||R*eb84bGzJ?6Emhz`_KMGRVsOcgg~NhTPi*xM ziz`$-$f^bzHR5(%aafapVoC{w`h;eP{hmtp-B|PK7Y4spO!CN7s;X4pkTyEytCHxy zC|bp5NJw><1?-M7-dG-7;$t=Q(!ZmvxEy3l6wm?HiHWC-mx%@Xt2auC`!48F)WQ$@*3X{VSq336H$!Q1GF4y5fTg=G6C$?{rq=)wuYMdXp{=8Pje4KDio);cdjN>hJss=Ac^jQVWKk<8|<3FKeZ zVC9@Qehu%GMm?Vg^~qdkJ2qThxR#ghyd>NBpLR))DHeLt-O^9?KGtFVT>RrYc@O(} zlKIo;@~*ii@Y>pn8aw~jkD2wmY&uoPK$$UX}mVTjV8;w12+g*UdhOldrd039t;QfxKJpC%bSI_Is6D0=@Ea_y2=?ed4Qj z*4C|FTj|W9%;1D+4ql3E45A_B_XN|;a!fbXjNCy%_jow*f2t8=n;&3bOnv+pSa^;A z3rQzb!;2z-XxJsx(=l+w0|dYz#0)B{b_1%#uK$2})$aiZObQYhGy(VmwH6bkm9nQ6 zia{mr!>EMSd3cRQ+rGzc!GTDqlCxDX=tmZeesBd~I_G5PuBxg!`|?^lFDP)g)JB=S zck45#FAxKAvRLDmYc;%Q8$GH+1%6`nJYLgR#Q#Mv0w*z0dH-*AFIsx4X7_P8=9)2C#|M zi7jb&@B;^HW;wvN<3_AU%eu}vw(^;Q@^<{-MB=Y)IR@JtK!Mz;xTJr4DO%51;_wGq zJa7>Gp6z<&52>sHr%~()f&!ftHvl5vM&`4I;|NMD z#ZxL?udCd8&tvliE|#J5c(l+|Zd8uF(|zzOlNo%(yqoSe9dTuEd}hZAplj)J6PV)( zP{H~vR<6e{pY;&K82D5chmLnU>IFnzhC7AP^;Ir#!hRd<;aWX_Y3L@JcX3dThXztV z#$n#8EpuJ3m^jKW2mYoucsPy#6clhi==~rOIi4_ZB5J(hfMFk}NTIEN!f;*4q`wy{ zFU8M!2XG8cJG(T>!jm9*{iS&fT-R{m_xC#z-J=?vF$N{JV~=-0eGfNAtbt%^P92RV z9H`jvL&B5$a#bDv&}sezWo}6RZc-}oGBd24;j*(_ z@q8eBaHHd-E1e%fSF$JQ%ycJ!fjViOy}SNSycGL=bzp*B2mEQLL36SLxrDzAcdWSsHbl z4s{sSx%0KHsUACJCy#RU=qH<`rL8Y0v3Xf|&i6!s>F&btr80}Y5NuBm%C7lHcH3u8 z-XP3@tz0f8_)21Kz&QW-!7YfK$#Dr z?Q+tXV8NyNb~VDN-FU;+({}>L3g21o7aBmdE=F$#`#H zzkY2XWSJi^>f+>7^xLPxSKwB*NAF0C9#9!dUQ?7!9J2QM!LdK2o=%bw)<|_RV9fHC>f;G&3=);n27!PgF@L*2%U63;j#*(GA z->TU9oCmc$HOtem(on~Pe&NSJMxV2O6Ce<4?Q2-8saUib!x~6vrtP=`9AOl1l<}k8 zC+eg3vQ?XndHn28;4=sr=&Pp^bzQO6z=4F`PcolSb^acpYM*MocP_$Zukd4R)b-1) zJZJYA(<;}#ki?IGu!@>xoj%d=^)R=w58}&~TuaV4wT195+ zLlxVd<#gC98WQ5DM4hl*j1t6G2kQmtS-B6(a1UJ`c%pV28ynkjnAT8qY1Mo6JT6yn zMu_J$D!qb>EUbI%j{&A|t#KQ{BcX8`)o{ckKE#cKHJWb!5`{>PAMOH?t}kw5dHQDqqS6gVG6#*uOCse;jm3G#7J zprUOz;?Fs7Fp|PuIm3G+q|jV@B7@y-tGPsv1^1V&3s7HWKnXzvQ*Dv-33{HH22;9N z5#IYTmUe&p7T^waHiLh!YSPAAx2Hb~3JTn8D}Zus_xeF%Xd$iPkuP;~Fv)X;-Z!6L z;A-y1mS_z)XJOn6c!h0jb3BPZMB73!l~r*oKde@_b0!!b569A0&CA{f7Qdys`^oZR ziYzZxC(BEw*mjcm@%k&fFK=zf%zT;6v8>t?ZrqlsTbPN`wGFaMHyh~rw8rH5tLv)V zDl@3~!A0vk$dATKxvVJx4!_cER*?@@FqN1(^NKf4x1(Qi)C_!eC6RHzGe4;az74UOAmcBK~WYi0f_EbH$$e`6&D4 zC|f9VTi9;g8Wg)FOs{Ys zN!qaI_IO4|SJC1LC4F{8tDt&LSn1uR5Aqc&+3Gnj1K+W+u`TP0ok(YG=M}iOA@i8t z{tuA<|F`x`@BPxzee43Oh9qp1t_((A9^q$9~YyV;nHsOd2 zpbflg)#+hAE2e-54>#~2;E51J5gd9zko7HLd;3iY!ojLt@c5dmb;E|c@<~-}jmhY_ zDvQt?*2kGQOvdjXVmt$|k$P9iCxUc8jR&?(S?=i8$SZj@wI6zusvw)#mipz8IY@yshwV0nr)TqZ>aJ-dTQw5 zy-ksQHS%8fdW2Iawf;KnSE=`e0Fow0ijw>IpP=nGYU}rcg;FroSOK;Cuu<=EYqJ&t zwW+pyP4TLRN;Da>Lw-(6{7$(NHwBM27>tq-iaHGm-;yj7TR7xfT{Hio?3|@Yq3#ew zyxheE6J@d=2W*_QI3P7Uy`;7104WdbvCGVFZg~7_6U5LzcrRl+UxF5iy(OD?CnU)#87Y1RW!e_9l$I;(8XNHC<~}>!d^zkYAc2e z1CnZMiw-PEGvK752#?1N2%CR_G|&JyKqm%;z3fYr-}psLC#Wspdg{vMhYo2{u3&&` zCUn35JG-YftXcC8BWU8%Zy-}z z0S|)L0@6DHAD;z>vc4530+pu_5^U@un+{SGtwFg23_kwbmlJAC#E_e*zwQx|c9FxR z4X-(ASBm0%#xFy{JaqUn2kk|w+P|p6gq@_ zozQmy-g;Ji3V!r7%s1J~FwdSk3&j$mhlyTLo>~t1m+24y09lza1r8DY7&3=_J16u3 zUa=cb>MZP4>)0>X-+r3w^7Ngzr6Jtj;z@hXlZlQ)=t)SKPhIfJC&Pp_M6&xZ1SW&U z=>%7L&61PMV)4){&gDe+f`DC zgO7{Do?Xj1;@oq#8{Pdyf`B*Fk)cHqLmx62X5Vc#K3OGFOU$llZbEran>>eULdS$q zFbh&{vixdNP0qfjn#kJlPZq*nAj>r(gD8WgsH;ui%6Hw)DnFj}7xbYuB0R zY>_T3V0B(DcwOM(HBxqSg)!I0$x}G;Vav38S;WORF!`${ zf4IYJ!HI*4xafTC$&QHQ()sk+S?|@ArBs`uyk-`aXVIA!l*73HqT@WEgy7i~-T&&P zWMwFA!WZwNgr6i2L%P%pUHAFj;N~Vw`b66hc0ESqez~XdSEt+0Av|*l>d#;>>w6mX zk00@_$jY13I%${S!KJuirUkP1c=R<_%%xTIP}@jNKRY5o-RnylsRhoz=r6!NRSxc7 z3@NY|h@2vv?v9`6zj1`@98l|Dk6c7iu#!#@mJLvS5YzXS6V_eCxXt27WD40BDTGfH z0U}jV*bv~Gzn(Arj2BlV92_=I7LlRnCzWMviBdpDiEDS*VDvs+rf+8TCM!hCo zqkQiMztsof93i5QX`l`##kOmfcw8?sJ?5^&&>OP-RAz(%*AWVI!qbb7F8#>axug~b zSaa~MLH#A3qC1{21!^Zx)S&&*M%JXqpQ}_HLT@@In+TRWPs0{xBp# z1&97r*V~ZxENVogAE5zIRjbz@iVZSJ)!*Kr7yF&UIQ#?VJIn%zPl_sKED%Ao^T(+- zv?q&~k^M>c=)U~yaQQBL1Ue?+&&FINBMNs+%HgDA%76VO|K`KE&@SUCeyrL$O0s(l z%ZNg$$EYiOsX$bS0y(S27Sd0(9(XG0fbKkVSCEp7jcS-08C~wl=s-rWF(oe1SqxqK z5c~`DTOL=x?b}zPXD;>dV5yei2?v8Mr`9VVdWsu*jELdmlP}f+XwFvLM4&9oh$_PP zBA>=JzV7@YPB0bff0r;3=uZ3TRiE16ti>k3qiI}Zna#{cI^hN-`~&g_ebXBIc6X$^ ze*~~JFh4)JhG2axf@EM=+4HgC&kOLePg^GaluBO0jMnAQ^?&1SVlJJhZ;I=EDEc6SU&JU#Jk>H-9b=m$&l8S_1pGX@?u8aIt-&cU{yrTd1$Mm96WD_3q*9gMAWVehq(0w`@gh{fn zlnJu`1xyafGPq83s^uQ)=-ZN;(RGZHCyR^t-0IC{f(310K_dep!&O>-+2k$pq!#3yQ63v;dTNfOs{zkrxc@&Y} zYfyS~Q_~6I#sEYMg3$=|hsD`watVpjGCywpQo3_u1!sPdQ!65}c?zp4dxUeZibFy| z@-a4&hGjX=KPs)oV+E@q!6yG!1DDNYaJrlXd%*D^tU2~?sBLcQA}h)$GM*M9RPiu~ z+n_3Io9}AbEBC-zQqgB+biGHw)kT5GS0%!IUeNX8ChMB{vTC2{XuMPEn&SUf4VOc_ zNOZ*2>kZ_0l~~AI-`+%cEZ7aP$nj9?^-T27ow<6q56+PhX#T97VzscP1|EBh z%mpZG-78CfBptuBUCtX|V%Tq@H0nkR*2;H(#lTW~swshF@#r&47BGebS>xo>4qq_? z8nLIJJfiip^W!tggH~nUrs|hXNipkOfOqa8e7FV;#?U!m1MvgnUo8qPR_LTJC|rJU z+(-s@pbb$mKu&3FN_M&4n%Aq9_$RvExQVF3HPkk2rUjCsw)drWceY7`(XRI5!EH=; z#Uj)YW$ueQ~A8VJXS(}Os21Q0tf)0Q$Xq_m`GQcK?W1WDagH;_?mZ0|$ zaPNT?J?gVi3ER4n3r1`jii$7+vBZoJ3Au?g2^b3>=F1q zwVr~&oWa@3r|yjPW@M~M_p&ifD_@3t1!8XIal63(MkfO_Gbot~rZmOulTW&2LbzA$ zANlPW4d#u>=6`fCVN<($Vfwks0C)&x9VgfMNn5=MID<&Iz(p|d+Q`4{T(EePm}7G1 zh8qz)sDIl3sbRm%n9IstgivV`OY?+|pA0_6Cx(!b+H%m?|f^CK7JZUE)w@giLYFY{7T3-#GtRmasS6G zCLi&s=7r7TH*+`d>nBj1^t$+jodySaAD-C70|XalUXNmCn?(uv!WBrFpgt--pB*-g zf4ZX{(6ZrTW_0bxU-JTDf5IM%66=95V@Urfa)B`FnzP8(P$EU?@?x_+H$=lvYn zUgVq`5he>A(!YU!thXs|-T^^-H_13k zE}lP`xp~aGj58Uf(3Lki^Gu@9zHA{C<1(BFA64bso2x=NT<%m z?3F=DM<0XMtHrZFCyg22@MDG^fb0*iGDH2s0IoeZFkp9Bh)P||zT+I|K~71_Mu(y1 zJct$rNCh|a5)NFGBnhiv2~Vo^p**$Z_yAEA0SgGnQbQ}~!HXlG@}Hr7lBa(d&7OM4 zMuq7S2eJZ#-5xNReNx-D_x0!~W`(sq=qzaAZ-4*^cux*Ciy5Zt4#jpgs7x5Js9}|P zaGM8t!0qG#qt`MumUm6quUFn`XnH1uET&t?f(T3&XV)@k4RQ69y6+_e21e4pkorr?-8~>|p`$=hWVT0ME$FuMzXAy=*(=d&I z4S5pv^gp~BR!|OW_=`hZN!Fdjc?gUAK-kG2zm^=-psM*TC&?-FM*Dix%aRm~qO3wp zF>wDAh$>PNzeWJ%)*kWRc(~>BMGF3UAHojUsGJ_7fh8*_JmRLaB7V^&n;?Qf;1FVg ztz&*%F+HLnO7dl}cLp1r#*@pyXqE^<1%$N2lIHgVk!RRC#<}+Ip5{N}^zWV?CAKZ2 zpkQMeW`GGDj_f_bdX+n{1j~g#638P&p)L_boY+MVKY~HV=!Br#o2`GtZ&)vuHW8le z6~i&>iyQQ>u`@xpA`R1|t%?Bj0Av?gbMeVgBJ(FPFfV%qlk)^!$OIym0F|I)_{taqIeP?&`Bwd=1;q*zcdLV-QR2cVTag zlA+^=y9~?;69Vru69QQgOs5gSN8}dP&p+cO|5ags0_a5u_k5Z6lX7kJj^1aJw)NSU zufMh(synt;itdIm@1Mk06q8OUe%*Ju@7c)&6AufcYMPUgTEJ&4q!npy8Xd;QLWU>FPG zSqxbF>t%9c7C})63m9YO4qFOv2$AnS!gp++22B9Gi`mDn z{52EA0=>Dm-Y2UIH#O>S+>|RqqB*EAFbblK;jmwTUj)l(B(Qg4aOr=K9yjP?Ux-b| zAS@X45?C;fo9`dyW)1{D3s9H;BJJvg7+GZ)B$N!b3!-p4aoc3E4ABPlUl?UZSy?D< zh+yFDzt8*=T6ECsYNHN!o2PYP)n0b~q6S5MTbU9ujN z-fHqQx%%7P&61X>H{uWxF8r$#-&=K%f*{j>|8jKhjsF>07JKw_4FQh>3fayJ+>$}q z@fcy~lz#<}-$nX%OFIf6V>kJ`;XmK@CmJ81A{5O@0iEQe|DraqYDIVHEn?`QR>_AB zZ=@XIW>4UBfCrO*ipNO|2ns`3RV@539-)UT{pJ4UtC$VPB$n_=FT%k=R_Eqf<(&|k zoNRW0ZUsfhC^YyVu1oqLM$gHNkfK1CWt*Skms@w>k3vj${{b+nY-vWFJEb%iGCtTi z{Dvbdf7X5b!>WmSjy(ic0ifMpKc}HR?K-R!V~&=aiU|qf7!!sCgIhB}jTv|3?@~&0 z($v3|h;dVR`hT(a9za!e-I{QdMMM-Nh$I!kKvF<597GACfB}%4bC#UJ04fp$36epQ zC^?4%C`mvhgXEk+a!#|m5BR>{z3<$a`RmTyzow?B(yDX1`|RFf?X}l>o@XKF)gylh zjwIis^p7Hi5rMGp_q{gV+6@Dl{w6fePfWbwdW6Th+#zH=M^}57*7<$lV`ZC2f}rp zdZRi%6*t&el3ioIh+UHM(3rD1wIobP0k3ZmU7bLj91zi9c=RWt zLF(L1DzG#HyPf(+A?38Jznta(R9cfm4G|d4$H*!1i80iU^~p$yizf!4-sHXNwNohr zT{{AWcAh7Lcf|~dG>J!NGqQO80;N@k)Nn0JlhSGM% zEU_Wa8^~e*IWFpK5CJvP3E=w0Nvu(azaf%oybWEd3ROxfa!QjK)Yz3qj0)2HsnixY z$Nx~KHWgvum0u4)V8s5{rZ)c*X<7flivTc}j*iX*Ko=P9KFKqd_k1VEeZ(FUL)c?Y z81@)IT>(9U-XEYM2Ze~+!OkEh72zSSD;C9vaKJYDFuis)QxM8TEq$U!z!S0W5g^^I zO$^uUe-9+gxgjDv{069u>*WXvkyu1;RxyWzdXSZK0E#qW9kUbpVIJETXcK%uKw)O| z%K_eDlR^uQAQ|8svjw1F{ntkTUMk%l-B3Dx-{JsW4lhPQC~*Kx}La^ao4yqst-e8s@?~-Ay&~i!gL75>#ho zUHhVxQv*XPI4m3+R7PBb@H5=jJ~x&+uKd_un^oz&UrxnXW^)!nX?VtCM!Om_+HdN~ zcF_Q|V5jn;MXcNx2=Q=wAyRPTgbUDMpbvtg0FX<1gi**n?07Ot}@ zW(|sG*#R8Pcc`^mdv+JViHrw!CwL0lw^Ag8QWKBoH8iNNXNTC%2~R6+!=*)xy2T$Y z^)0w<_!JZkJtI;UmM$v)!OgEE=ACgH zvVilcFI2wOXz?Q`W_K*4scpv&NI~#)$?kK$Vym0qqKBvV8wCWY$qeI{{8Wqp1`aL- z>@S=2A7J334Jlcb+aKdfU(fXZ0Loe47*G)M!e(D%n#tJ#0t9Bx%K+}g zQ?}$Q4t*ZT(Ez1OCu&9Zt@=1WxyqYjYhd{}&EqP7n#5+M3$XUa=zOkU#WnO3sz+NS zE<-q@1J&TQOT>rHhw%-0;Di?gP*}`e3*lxHl}RG?#buuB1zFm<`MA95iU`x0?RS zJdf|V_UbBA^#K?H^rf3-k(bIQWR^)_vvcMPLS>c4;C})uB$@9C{RHJ^&L++#7&#N* zofNQ}GfZE3=kJnGloop(Z5Z|x6cP68I&GQuBr9GoSP+uiu>~c!a@#*sPDWbGaM}_3 z=AWC$kG<$&%0={t$Ub(hw4Zh?z5YZEB+~Ru*)l) zrxX9RA=OCrji8GS*OSI#|c(fX@+ zAG-2^wVCT@KQRPRGflZOPRb}G=}9- z{3NbT`|B#G?PXR{-;-w&v8@Wqle5k~p=v9$Rkp!;-LauqzAfKi{ETuf)7CkGogvHC z4qHKfaS)W_ZsZU0=zQq7I^yrXt7DA@5YHx7diNn5`d1>(lLCX?%Vp|Q23S4Gilrmu ztTB3NJcJ%mZsp0xSqrb?yDl|XGoV?NMrRXGcEX@lPeH_NjjqEGw#?ww2w|ej7cX9P z4UR-mhO_z97vzOzKHOz z!9k#M&^QmohkBN`3d;B9Ck*oaR#!y!+C=h9b!O-CWs8Tz$EWN=d&=6xHZ=1oU0fEN z2TeXnWTn2ftE^xLwsy3s6>Xz5dmme~;IjkwnT%^6(iEtp;d;sDxJz&W_y#vd4P9S$ zC5i(Wk%fAPOrD*?$>Rz`7iANumuKy#4OFl~gtVC53lQX@&K)S$jPkQRdsA@$W09ex z3grVs6}4a5lxnZyHf-W*Ha81h1>AlrTVy~f^){C>oDNo1%2)S|-o$LJOg2%`{iN1t z__>S?Testn5$i^KIM8U`b=*{dd8BA$Hz``xvqI`X z1zaP0-|W+bS*}p{8ooU;srZ#%^BrsYR2pKO*>9&<*_~Q^MmF5Qp8fOkO%wEUNR$8Ap50>X^OMHE-JcqY zn7B+AJ0PIJI|w#z!3Rd2d#5F6l@bUJVJ#6pLJLGu5Ep$SxI-e~nCX;k>MvbVBKj+v zOEI=WmSYL1?F^RDirC|zhy?oGbnJoD(oNZQXo$^dO+}`cZQAjiO4Y(}^{o0v@e_@& zWkYw(QnpAtlBO@2pxFQ-W_reaXI%8r_%E;)^J)HlzZ?QHneB+rvZ>^MF`Et#P-J#j ztBRAdpVww4?zA{Ie;d8dx#QCQK%%@w;!_n-B+|^*W@z6IZEha=D4l|88dS! zbVIT7HDN$ihq?3j615}+)7ywcBG^1-|E!hIRqKtK zVw2L$JUL`5zcIK!KN!yLzSU5d8gXDUa95x(_)UeUrikgeSro98FDGq78lnY@*LXK`L1}-E(b-yz?xv#Bod0EojJfW&mLR@0%qA{r1pi&Q^$+_B)I1 zW|X``X|KF0aHro^Y{Rb8<&Cn45WV)(UY51>;~wkUC)ZSoDTCtR_+?yKV4X%II1;bio?94Y(VX@^;QyLLsfLQx5-o|A zDJ|X$b4{D9JSp&He1t?roCj)uttKQ}_Y~yc+nkHBA6w6MH({YZ&!ijlud_M^e{pLF z#nqoqD#<;zUcwq~-E15gU7OW!_q?cw2mzU&~C3ns6{{BAu*~wVY zu|xl^V*ypdxuLBiWg823 z^n%iC$OiiEK;v!UDZR4^1L|0EYbIeERfdwvA|#T(BQ)j6tb0p3Y~I)gZ1M+J@4y>K zKmiO-T@yY$6MR~>apv6{(hw`07I=`L5ViDB(Z^V2FGQ}=qHeh8?6r+8FSmxI^V2dL z$@4jdams3y6WIEm@7Myro78<&ca+&6rW;dmcB~2w?QDOJeVIcLv6M4g|H~O( zkxe{{%&%}EBK(T1>C@IAgrfgdjo<^>LSJ%*H%vKuj!Q1{ES}Yn2yVCsJrc}FVw3aT zC{f?0#a0JIOgL_`@q3NPZF;RkIwkutlT@v2>k%U03=#}u;fB-!zjA5OoO&#~tdk?F zo=J*4CczM=2M&7*4q+mcccIACuK4KUpq(Q@jb{Xz0TEx|>OI2y&m)u3!s z^(7V=3PU7@VTt5XSnwd@Bk_O$4-iJj>;BI-gLn-+;H}>blv`(f;bn+Gg8l$!qXCx?P+NXUDsM5f za!DXj!areA7&x`g<34ThPw_>N2RdYzUo;wz$!(@-MEboOX%jRQwR3{&#|cPZ7R6|V ziSwK}%1oWbW@EY@5YR#kcY~bSVGQ>B9fl4WRHUXMj3`|^?BG}|5PEzgb%IeB6Z3tH zq*dWW(rKGKvQx}dJ;>abdwUo-1eyAO!nvBP6)RbGiQ=dwMnvaVkDGvOy<|X#Oh7I> zjC@7OANFJH$x@)(a{MGj{zyIud#9R^1Zklw(!xcE_ok5cEg(vtb(x7&ca4k@gJF`x z{POm}L0CIAbqKzWL-1%31-2#iB&nX4TTJGcdRrMpWn|Jr4N@eB2vhvR0R&VU2KbdHUEbbgVT`f-K5f-vXH}R0ITQsDzNgBUK-jpl!C)5{04cU4aD^oN! zPHJZx2FGQG&Ac4bSQ~5FAGQ+Y=tJ7jiW7TZ``^bKS1g$&dScc=T>J2C>Y-R6IWS~J z|0d@$s-?a5d-_j`zT>8ybF|bpVkrdWY>`14hcagfSa)h)BLEH$f@~!6j8!pZ|3Zm` zF<$}+t{;I}5Dcp(+{*w5_P4aqhq5@*YeH9%2V>G~AhBd4TKhjzA?hqT_QK-8k8rYGKh_VbP>t zy|U_R#Ea3J!?DaxNYdjQf+#pj%P+r{jy}=?_>-c~0V(dvLQ2Zyt&=-q0 zY(u>18H1a8SYjRW{xgizg;M+&2-J}02(nVfu`3WEnw+6RB7kURG@^{jHNu#G%A@(1 z?jw{@z0rDFVXyN1xq?r(W^*z^J_cMuw@7@mum{R651GA^vU-3DIIDy4NJRSn4y|1|Y*Fio;Ow?4p*}dydz5B4Db@ zkt1UO@^2YkjX$})@p;bX0s#$qDcm^%W^Tm%St6-{O8g2#w@*Mi3&v5s*5y;J3tUe^ z!;K3>8uza$`cHRXd$*-99$UY=vQ8|v}V(@MPpul{)(Mcw~(OdJInH_c%>2 zH$KA0ON9cVh)TNjs@rBUn^1F-zL*yPv60i?rnwg=29pcB7dYgs(PxPLCt#y6XCad(WcSz@v(lWEbDRKZw!Ju=5K$=GxBvSw6g8GI(a*IAO za}>uwXY!Ed1Y=d`KTYjwJhX-JK6fTQ(CSz(&@w5I3`cGr%C;fssY!yLhMt&o5IK^r z1Q@4lZq3-K9orN#&aKg4LY_e&Xn;u|UN((E9{nB2>a&?76}4&!n&?6B4VjxTnrd(t z@iQDWzatIm0MP>6?5oAcbd>;jDzW7b!=wbIXQXT9^ZIZo1#DFR;X(!Jkr{jhs z@VxTSK&Ax%gJs=7Yny$Vmrtr^TH2HnoO+WEuR>2u zQXSwbl+6?~G>-SFK99v9TT`{k$hSWt_=AcxWNsZHTX`qZZc#%IU^Ou*Ve=por+8-A zip63e_0pXA;N02f(d35Q+hQ07w{C zzzZ2;jA5NFZc4Akw7!jkr}ecu;Oj9AN)R^26!eNa>qG%>Jg;a={&ZwCn5i%T7htp; z01v?js40qF5c|rg7bEo{dkMC(j)xv_MNL&o1W>`+v*QS72^a7Rh+UCvZue}0(|pJh zgF#h3`8MpTEg9rN8P5ZsN^QbD1x^zfhwmoT`InQtcKPNY!R2vlQl$MuSoFw3ip8@0 z3)U)p@@_q2H)cwCSR7iJBUtN-tH(oOW_VV?zmL2hjF-~jXNM^S|9tD{E`pc(=Uc@< z{l5JPc0e$2p?UvaDjQjyLs)}{?P|V_Fbu-F9+;Mq$kk6WB0pS#BaBR7XegHKHjW2m ziD!OnVYKSj2Z)I7*b%So1}=>o>G_s6akw`;moa%#d?1~4MdRV{ZBzu3mi~4G1_0%C z{^@F_XKep;b>DHeUB+AS$-aoG8%Hc509~y)_0Org9I?DwuW7V?Y&7IVjIllr;3R7O z9n<<6_nQ>LzyWz{3<-=5I%gtrUykgS#LB^yq-?s?szyR0cqBazE%oF0p7oWNUstiO zQUo&BAr=VSJa=elVf^?hrk4sQ-X#7Y5X!P{J;Vq@fWrmMu##EP^cz^L2j_KA6@sw> zNq6M+L+~NnOme<6KbqMI%jXDVHkUZS1U%wCe(5sS-?>veK0pTC;{qW|2d3AEs|29* ze>@t>OyRsMipSm#v!~|#AmGokj>r7=A+*~Cx_k@QGZw^M=1WrV~R)UfYs08tKICS01xMZ zJO{v}B7RVleOxjd#R$dB_doVx^*0D)JY23A82VYrlr90lq)K7EmpSa5y;h+2vSn=# zG!nfz{$hE}w%lx-zqWdgWc_sz;`Tr!xyV2RTa3l4c?daJL@B~cgaMKaoC;^`akU;3 za>AgD#}R@YY<3~!+*pAlhQJeWA@8}^Nfqa!^1L>;To|v*hO|By2PUcf8~vEPqVcGU z6aG7cw0{IUjn7dMoY4yi!1jN5@4mqB>Ue+qJQ=|eNQQJ94y&!0$P}#Z`4~3 zkzPDPiGIg0K7=3{-;T!AN6i0%mHP2iGmG^#g6;$U42IoD4gITzuZSyqaGqeUoW94j9(nU!)@-OmXObF@~(!f@%q175MCC9li`^}t+l;Xz* zuLwAyW1?W&r<&l?q@KkPOs2=kgpJGBJ+;R2RC+GK%firc{Bd=V4*IMaa@v zM3rNH0g648Qv~b+#$Jm+Jy*fM-3;Sa{~oVkTsalQcYPR+X>4P#xPT7Eqd{Hs#wqQ| zHsALrp$Ts>J8&GvbP!b3m6*sdIojd9#TeorV$u^;&zZqEOku#72)!VEs8OEp&8HX~ zUt6gk7(;vt<7ojrWe4@YP;JlC{;2v^hlg3>P8dKWvBzJce``*$S#(lILvrL|{*m!} zX~RKA#EiHYpbg062FLpWt8WgOLLP6@x^R5gB;Qvmq6 zZ507rV$$K5u1$G{*ggzi%8ZZ5yDLGeA8+fix`4JclZP;47ilL&NIW zC#mmoe^JU9BYV&xqZJzpj;vuHeBuBwRtyhLYQ!fr8o|M%R1A6vVE%?w@?s0)G&|Jt za4YsLA7UDwj2Oem&=a7w8eHp#vBx~GpYoDjnwKd7i%pIj>25%nBmis81&LOCwp+{* ziEPGr1{C4JYiMq|x6|CPVEmi1GUHhhDg2`dL^LumHz3{{>O7OG`9EojG}~z$MkF;z z%s!gQVSFkLNi?t~32-zx$TIA0I{oM=G zh0^>-I8;pFArYs7IEdJ~bxUVpxanKm%)=VEmH8)%?dky005q$8R2+J}r_8`)*D z4^1=(7dMiZ7G0IN{>~-)68+HwtdIu)FSmGrYHFY?9hLEjuh>3Q`=TRxXz5YZ`}q+Z zmHb*Vtj#J1BD?>@d0hmeZ3O>auI(iISy(#tT%Ez<*mFBW3|kn1>jKkEhc>*AM2!E5 z#*u$s-sfo2QVde@fD!rH%yRc0l#xIVdT6{mM;J9d5FV^LI<&m<1-# z*bMx+#mI(EJP?rhN3Jc+*^EO$&HoP9RuHTl*b5FxWyW9k4}yIthu9v>9EISeb!dDg z-*(8nJq%PIstrIW+E+k41TnrTP7gH?c$biaKq@9b1GEm#A8H+(`5bfRP-a036BYb7 zS_jTlf!I6W>;4|-2DVq~FRg>B8RpwPVK>1hs`&)7GXSlFNQBOXXdMu0J&`#!$E*$_ z#YlXgg<%VWZ9e)#Fyxu{??5V{^m>J_hOL79UL##rE zL0#XU2$h-jA!LDKbVPmT_>y3x)H}Q6elXlr_{gxrVh5T3vtkFxx%&T`*ue=>Nbla? zl<{K--j3>Z1AXf2)w*1h=G()(w?{A5^tXx{xTeA2RGqsPKy1Hj=iXncfcuCD(?M%6tHuVGZjyI zMs=y7-%qa3Tshp-LG~nvfX3!={+T#-#`HC+dLvC$A4x~XtFUc`U@KPP6#H_3rWAr` z*BHJBsq|80cn)rN7qAK2p~rmuMy>-_)`^`&WCqlp&&$E2f5)`AI{0J zjKpIQ$09!cx`p7J$RIfBz`p{Ka48Qp0!4m6*-=5PClW9^RY;(U(#Spm-!Q2{GU#%2 z^^hlHY0)M<@Y=UJksS?r2JUYx%H~iO9Oy*p*R9Ul0^vVz!9Zxiwod@`Ps-LX;D7j6 zJ)JA?Rxbfg`|;!FMn75sRqwx< zKdh^n){{S9VRhD=V4#4fMtU$Fv_`CHY|M``AtgPkNaA6Emv7olDh3Ezx1p4DjkVn@ zOgR+r?}-fT8NxGUg>*(XX_v(+{21iX?k9GN^O=tp1ghvvvt?!&1ld4O^r)~q{ZUGP z>a572?m^H=LTKCL@yYXt%6=%% zbAa#%3_qN|ItnmdoU#tz$bKB`xF0mR%$sP;7ET^)xE~nok8A8#m(H76a3Z+#vYp>1 zKw`7UYOhrIRAKs)tZ#4Mz6}Ef^~U8{*J4qMcuqp;#T2B?-t@ae1dTw+P-JCyQe+Sa zK?=uy@AH0`mv5aRw|QwBRIG8HhrzbC*BT!Vc#G_6t$^B%d~SU%D~&l{Xa{P+eBuVQ z29;fh`bW{NH!BXdVh*kY)zaq?v)!=LUZ0)opvC@nS2mW!^0oMpFZD@;J$wExt19a24rqAEV}>zHx~d9rn_H+ls1IcT(T)s2l&uR{JsM{NS@26(v8eAZ#6GImWPb>| z!qm&QJ2JvyaA>3L;7asHf+FFBZL0vJ>E0OVMdLW)*yOA(OL--QdF#5r)O^D9sSD>d0kEn^jQTUKJ%Eg|Rrbn()uc%Sg=vtw?c z6k8K@U@VF9w#()@ZGR zKG5Tx?SCeY?ky>t*z~YAvGS~GghsN&uPiI_!@OXMhX)ofZ3G&{Bl-)SV)WZ`IdG*j zP$15m6Ey_*8wrlp*VMJ5*S;8VlkMox@BG>nLc0%n65RZ}1=elLmjfb=&08yb7yWp( z#n19TFmx7L@3km*P>ae`->O%<+0aa06h-0rp(CL;z{Y8($@RB&c-Q_} z^{&38Hau+XvL?6noQY4euEy4C#4oSZWVno9({D?QEM?8#=B#Ug@2k`=xVw>^_4J_keb@#K^{DKeouN&*j_KR)897g?X#X?^=mQ->2Km zgnY}19cq*WjrmV3QhaS_Y;jOn%P@7|i9t!a;PNxd(ux#&KGz?;#R9a7+k!ssrd$2d zK|O|pK+&|mXuStO_Ko&*=`z=*My@)~9sd<5-J=8W?iM-=(i*|`yGymqiv9;(vNG?> z$3)UTdb@qIT5XXy=jfV$r}qG;%&M)7aM2QFICXp;8EhW_BE+l_8_qv$O-gjX)}t+) z+9K{P^LD;8s?R6~3nlP#{%%a?=NO%Az?iUs!RNMLOe;uWl<>)4RL{*j38A&dcBXvu zN@+!PM?GsHwWv___fxHkB|T5)S3sTDf!2%bKuH&^l%&SIwHr@~PEop_?Je7E5L&(! zQ9iBgg{ornrnP%wt)@oPYQ(oW1Pr~B8{4Xc2^L+?XHGq8rcWBc{Yy+ zB+8@#W?OXzQL#Nyf741WJnt-!%`dJ&^i-y6?DgqL15PQvQ4{i$+;#(E)R$ zDN*uxVz*(7(s&52|>!j1#3M9j$Fha>W&BNz=W(d zJyd{MsGEP0xtT#jq=>s)7u71~8P{R60>-t6Bt{~&x+TjF7D>Q$G1h189)N+)VQKfb z2YLWXz^azEk@2HN;j<5k(xEk#s&`ZC;v&Y{PXMls-xkpI)d^&_Tw9(J5|ZH?e?Q@7 zch}A!+EKqWy=<$O@w025-sRW5Kd}R8T1FixlA{*a-fbj@=fTD9($r8;cm+)t5f8oee~s-T8ht%~Tic#0uJX$SZPh z^zR3ahvn)m_Q3@RJJ2=zB5Ppeez^5^J8Xmo7^lrYVVvZWBwbvvuA(NV9M? z$+`DcY#W!4pPxFW!W3OR#8|{AJESbp9JVhspkxr$@kNaJYSjBS=~jU#H=M8+4)@E0 z_UCn;Zpvto@~{28Eb}$SNj%6$lefDv{C8SQF?#c|l0Mx5=yJ1^>XY+8cs<(8-9G8s zxB1Xhu30UuV9me0BbTBxi?F_?lOjgeg4_emf}(E=IrcF+cjlq59Wd%h?Sp=wk6yQb zs;(g)cE#L$t0H0Di@;r>0KhWY0KQn`?f4+^a%pzv-{y5PYnMb8a6Ob|?FqA9 z7tww>u0A&@vfbjJDPJkVq7`5Q95QyXS=iHcCWg|Pr@9brg^PpA2VFLtetdlP&`DWL<~kGB%~88jFpDUw9yhIxte@+&lc00d<@Ay%*Xg7jDc|cYH%l+D9R3y}r$!URinpxo1=|(z zOJ@g>x&c`aw)+J?$f@FJE*G#BOMAQVbTyH`LPr*sToN#Pw_AD+V)7o^-(NT=yCd%D zbg=OP0F=;aS`aw zzt6JGE8*v!jN|57DtW+3U*JOyb5N%;h=fO`MlLuAOF_g1Pzl{ z56T;6)(v^aLfLA|kX{^HWecagfqwGp^wh8Db`~gwokXDk_F~OHu^slH(I<|j3!i*P zX33#6;hqV&C`A12wl)hWPwfUl{+Ux~Nw@QNH{M+8$}1O9u!u=_D3E^oei)eVMAwpx z$!oI_E{ms;>`x=IG@TuA0M3?N^}QJ@Lt&XTBD_?#{jbqBex-!r%{Z7aFU5e(5DhUZTbosXN-mGvyWn zi@!ITb)4%YfeJoP0t%>U2#*TOv-9Wdvkh1Qi7vfQp}(#q9P}Xrb zTW!+~hei|iwzqBSQD(DJ(WZfB+9F*mtOb3oed?7d(}|S8_m(Pm1JtyhFO|mOZZiA( z9B9{VThga2kZ}|!!q8?V^vruq_B03#%;@hG8`iP`B9_-xZjopve+80hk=;s>Dn&ez zjiM&A5WdTh{*r&c_p0^7b4Gnckny>_7Zv$Z+XW_4ymRZE&u#o8eD9;R?KTxEE9PBH z2c;(jUHMw#=^RSX+H+%iDjLafr<#TSaFlY8{ry~9QoS!YT~=fBOUQKeJ<3|$Vqx_H zxFo>eN`g&)exZBIirC}$ZRV`KjlpuhGloHLTsu4B=F^{ct|VvaMmwdej$^)$4b(o@m?rVL|K|S76)eZE_;%=#1^HywHbsmLdHFB zWTX|Kdo{*7(ep||XTaLap5_wK3I@`yPwjpQI?CsiUYqAC4SV4Ygx<3Q%PHrR_F|#1 zYLPlSnSGICkopE(N0^uI&8-9L!HwzX%nlw5ml?2SZy)qAXwrp_SqYv9r7=dy-5xtO zwsfB47^(Fs25m`3{Kv;cFR2bYNETwhu)NK1UMV|5&pxNyTK{QRxf{7j>!UWIHX*f+ zHuTPHlRL%to-uqtvPH~(?4(~I4Z&`7(B$OK^ zEkCj{AZLt)TAk_O5h>Twv{~NFI42exi}P|rM3=VHg8EAW)+y>W_vr!qcn&cf8*GJZ z9ZzOV*3y?Wcm^h0y3X1sVJ{H%bl~TUuSCjF>U^EPbOpMdVG$+l)$>()p+k6LC-^4a zO|ANO>r95e(a{bB8LiBwO_mA6FKH}@8T_W>R3LjNO+6unhysb5KZ&tXCuU|{nNJS3 zT*0c`hwd)=MHbNL(n9D3&+vuPZ^?zwR3rP_9N&?C(kOiMRF6vwq!V9hR|nJmYMo1!i5b4pIF7x$ zOUC~swumCf!O(YN$B5t8*kqw$&?B3H9lbOp>f6KN!dAY!JaYcTuPQ7x89c*si1$ukZ<*^)UHL_W zkAEOH&0(m`+Yito40Cp}`;zX(Kx+;$fCBmHnp7N}mhP3nv|2{zkOSy<;56p`U{;_p!|%(p-D zEJQCnD1uNP*+rUDr(KC12r^qmF6ci&n~iFbCDBZ;1}ZCJqe|J6G&*Yqe2ejWaPJrr zV^>)J#m16$1#Ma1U#13umO#tR#6DL-)z&+m$a-0?A($VDb(T6>o_rs^HO4_j~ zE#<>+?Xn_WvXV%JgTL0n!&06#P)Y)=^k2I@;!1F$G9iq}Nqi>hO2Q}}s{N@J$K%!g z>Qw`WF_|XPXDjzmi)F9g9+d4F|Ge5i7ZAPSKm}D*RHy7!uElmgw3l0S-VE=0 zWOR{_ReyxV9J5MCqbpI6pZvdMO|$fe&F~cMREw zB07!zBvP70CvkT#KJ&K^u%IbGW=?KMLT4~^in>&2D$hM7_#|F#9R6Ac$w-A>isq z37z)daOD;>wbc2xNH}Fg;LwgUctKDB%*kDdu>5yhgrlGFC~o34iGRIqt-P^OqJE zYaT!0rCjKrM{f*N^FqT^s9z<&uu<=^(#X5KCUj4f52w{tSK_qQO|LATJooc!rSnMD z>r};5VXrv5d%yCKJ}%v7TtZVr+9&P^O>yjs)?%^WGxQaOrlQW`EJ1IfZ&Sg?zl(3R zjCP#g=fW8R4tJvd7^+*ek?FTiSi_UhbLg5W?16Ce`O}>@p;JqmH7BF!l2Bq2EPVz` zY+P>72ja9jPL&lo9Gt!#Jrezb+PIGZ#5?KF9BkdDcGDsDIvj>uB*y!z+_B_X87V{Z zIJsQ0@u((?x6WtWK2B(l@)*_B%|9eit&lf5zEq%U$OzRmg$7btk}a2Qes=)l zO6p$Z1$PnM~ie2Wz4E+_uwhr=c4U^UIAS&j~{d&MXZYNuozBAADFLmr-Ay zyZYqK)QcQTY+<5U9H0Gn(y-j2GuByanV%H=e%Pp4DB_?J{M}FGDu$}reaJ{)fT}FI zRGw#ywwSc{ITKuw<%EnIMNQiC<7(O#ge1(uS)toz&X+Xu#64069pW~HzL~g24^nTO z<0=Vfy-*m!QO>s@)Io{1JL>R~&YP6blw6f; zBRRf6LUSKVIlK5-srlWoh%wjs55o`65gZdG_V;VUMOAr5+z5|<@MsF}LHk`zQ|@-b z?fxm7?I~7oKK%zeaVBG@WY{~*?FL4*uud(AJDH^Y2#vMv$@{V-(**J>L%n3w!tqz= z_$ya0-$|zRAYOhjiPdTNO`Jw_!K?=xr79Ah-NN#6i8c@4ngT!4n{L7|eLVy#l4P+` ztlp)IP%HD7)33+ZBupMk|F!^@qr}v~;skx^&UC@lU}85R?&OI5%j}7?MDIzeDH=Jy zLG;fY7A%H(YNw?58j^sK4OzeGV9;TukU)E`vw&@dM0@0L%=D*6$>DXOrWXZ&zaHqh z^`dr`Bh2%o@}@D|b?nC=D~%eODynW&C>FZL*~=}@fBS;z9+Rz$YN!BM;q{MR7u3EK z$JQ(r{6s~4-`dda9H;)c7v z2U1`9IMI;Ea4k%o)9#B?*=?;|(_xsa3t}eX%F|I!PuYqatrl=kVZEJ0kNRpV-Z5FE zj-!m`q~A;=XcpVYIcCBt;kG2+9r~E>O?=&2kq6_Z-$`-RIbILt&LZo{RJ!%e{;j5iS|?&i{+%}SrXyb9y7+h;vaHe>Ol2&O!2JRn1(Gp1BV&RIgY3W$93Gm0{5y_0@V zOz3m-rWb7Sq}ZEiY&`FhAee$^V{z83JRnKvi)`I&@+WO|wf?csT@DtPQxvsC@?MAD z$6Vt_%K(u=w3OGy7i=qVQ763R=3Q@EIJhO_*dRZvS&4Fr}pha2EF z%ufWk5*+iut(XhdR>%7D;i)?0?uVYkb(pKbGf?YDV{l|B4ISkxBBu&esh&sThluUqn?tz zK7PHOJuk(3yMAmU9fUM@<7A=7wcb=UU;ul5UaC19CGeGQ4Lk*QM*iP7|E~}J&(DKI z_iCV7W_;aoS$Aoa{@_WZO{}TBX_LW4yfZC5}_E{#l@Mjj&V7 z+L%%c&sy=um!~E(l=JS=IL~EiN7;5>*|M>*Nol5c+tji;IA>9M`hs}$tv|M*&=PEa z-JR30b7sd@xB0vLVE@7ptyR@&?YUoBBcGC^NgG1h6+f-nLoPrdt6E-BEm2rHl+88( zrzQSgM6}_I<4sIUs;t11s#``WJHa*(8`E}uBMLa=$07S3BWBMYl=buiw7EIzPl;7j zQqr5tyfmLXE!77xNy1H;szny0-Qh{|Mwu9i&||Ehv7*mibeMrXb0xyJZ$)ehY6Q8G z67eSC2A>pMMB#ZDPOPc`(}gO3`qdRw9UC@bcrGN%`1r(7;;o z7%Bv5Lh_BMr}bB=-+#j%dV7|$3OHn!)_>`cWYsZ6yi&98m$zke+#L392oC{O6V0w` zRzPcxi(d(Rj6P_jqt}&ff8L=~V+5r)jp+PJ_mV~Sq#}W$+lYzAPWUg=oW}PGsR&&FolVu5ra6NQci5NU{&b%;=3T&=D8a{O70qz*97TW~- z*`^Vr@IXFfLxbXkcT%o9A80#+H2JlpGx$)gKfT8FGN62cB##jra0A;j-147NZ*lB$iKqIMGCQwKU7o*D8K<>Z5xSfmff5YM9C8`05DmN5^ zCiidb%v&yE-X~doj)#|Tpch^@@(ild*!NlK)mE++-yyzid>;<91!K`&z-@K|+JAD? z`v8kkz(`E&(OduoYhD@auzLN6O@fB*^Ykag;@^*P>O(!cpntYoFI27FvC^A_hs1}7 zy;P1CM^J0gs67CSqD#$QZE1IIl2KlsORDmz#_NIz@VuTBc}N z8gPa;{B0gxJIyvLbpOSt)$0VN_^Q|ttR3cK)RshuGWu0bVHu}Gz!m%Gwfz$Ikn;k1 zQfO?aKZI`Zdr=U^F?%=fJ!@{jxHj}1x-42W;L%#GzEAz&Sk+~|Q_FqI zSf^Taj!}9LhubCJ`#?G~+O_+JF0c4oQq!X&Er1UcOIkA8lf zxrV|B6YPbaxNd4%9ETlEfVOF|Dl z3Tpz4`F~*p%>T=K{HsQA=Zp2y?^p3cDc%8Jscfw%_WXwI%T{Q)PaN00de8e6uh9jT z0dg81^T-)jAFk^TIYlq9P^Bub7B%*lLvaKuPtXZIi4udjXeSQ$mKV10!|w~sIl>RG zET$hW<%Jx8M%lHLuO%L$+;$xa_rkfPsy(e%DcDp~Do8l;K)&htThXwpr@-`HBbM9% zOP*D#6&zKw4pyb8nobQbp5=R*FrbzXqlD6bW)XV00lPJEXt$;~k?A{u>>g3lH_CXS zS6a$kyQ=p6wq-L;PEPFtc5uz)ZeAC|)PB2OGkF>~w=VBcdND=7*JV~^@VJXXGtc#y zD2I&&xSDZzV53FNX<*96|sd^jQs6=mq1#dkg6NJ@1LAHj2igjedKL*G?zu-&$XvS^5bVU;w=_cFXHqVy8O8&X0kO z>aq2LQ{qR8laDfnBVk3(0kP@@Lw<388A*~ZbdNvfTU&|{dD4LWWM;*9 zUN?TU)uf8kecy$9l5NDVSkrvuZWOzvSxQTlC8ucH=$-pHty>+dkB>L#9Qrt{$cqyk zzWD!d&oRpNi6j#)jGJ);EI3Dh<_#W+wRYF3f$RFVuay$+q>vjxf7C_mipZ*m-qByh zgR>Pmo$Djm>DjTsd|nAX=J7&fAE)95=5Hwf#3_g12?JtVL`O!f0?(XmGv5%<{?Pf6>qy-FgS*WM>i8>u9scugW> zbY_9RT+VfocE|F>=c zhG`;wIBYw5FRs~1qRk#!__UWu&Zsf2)nmSmOkD1BnrW2En6PUiZKD)nVB*$b7w0}n zT1k!nDvrqS0liDDFij;NFQwMZM8?M+LUsRMZ;`#ka$J{)On1s(0fZULWb4{-w-58|WmzVy?P) zjo6>}bOCD=fAj}h*}p%^rf@a3(0ZDi521aMT|2cQQTjy4tI(5pb8G7&Ct9MvwKfm{RR|TgEpADySAb+^} z9S@V)S$j*1eIi@-?CxL}dVyeF@8RxYN)W(23v4s zpe_9|EAyw=nJT$@L_O_l5aulHsLh$wF~LlsI+xGbWy_Mbcd+{pHdwX!{w zWq;S_)`anaTPqAB92SKSYslxAi;m%6jh>g3j$$$5;UILKVIy`ob?ri!2GS6g!y)RuV%V|OH zb`)r`2L+4n^xo}E(6DL%q+DN%E~fE%34Z;WR; zo6q;rp@PM5z&D}qu3=Mn=hr2AnuPayHTTm9Ib(TK4zGU2cWhfsxQsk1pZ7XgerR*d zKP`cYGR>?I+ooj7Cylu>DoJs$D%FHo(Z}^0g_Y%GD^){dFm7)X_Ix9S72D%}H#(H> zhP{N3k4b{pEA+$dhkcIW?gNWqSt1)oYP(FwE;ziGQgqlI#;i#Rn^!{pFB0(MmPOJODr>czgHR0Ds3#4xbS#K%f?T+N_^sNdV#o9m6%K?>#eta z{Rie{j|Ek^OLu4d-t4rvZ?dBsY!-$s==N0zy}L{gGEi(Oc{>_#W^jg)oz6VPFgz<0 zSJ9NQSC|v_neBa|9&7MSY@`|ArhQC8&E+ny7Iek2fYA$P3P1ps&3hJN7-&@ZLwS(6ih>VFGe{Z)y*&1v?us@L!5 zCbm~-r5Uc?AN^_x{_czMuZ`an^_rm_ZrNz@iR>ltrlA=AW2-{t$ae`+uNi@L6cAh$ z1Yl|AdlKX@P)d+dn;3aTPXRIbEna)1g(WO8M`7hmrckPYH%&}eUrgHCp#ltjNAa;a z;QQ(5&Iqf9rI`4#BJ7p%>=5nV5H}-cLhp<*roo|07x_Zepr;9>>w=#t!2hiG>`aXJ zH1SWJoSEl}HSQmOiQRi2_U%m0Ux$zfiox!kN0h=oDlxlvrEf~!(&dQxs|0%*8aLQS zLxT}a<^Z2b>46oNRu2wpbI#+Z8V;BI0!NZyEmOg+Ao!U!%sskPsawQQgr z%yXR5NnnW=<+!)Vy}@IbJ-Q51?`JtK&(kmx6R}ag)-Oh%{q?jkrc6oE1| zFw0DHYV19$qDqLzsfIqOOl%#N;yb;fsoz5T`Y@&B1uCy92^*ZA+eJURHY`{P*Qa29 zA_8J!(BsW~2E)906g3TPLMm!ZN;XEWzM`fJ28sgX4@Dax5ixcq*zr>*`*=tH#t-Ll zuWi1t=w|eY3PT8GgYkQyk_tgvHzs^He&MYfCo})!{_>^K`wM!6c*KdDk8V^x%*EDW z6L{P&S~&gb!yu-Vv}WbiFmKRGOOKxEX;?$MnIl7t@AF4}bVl{7zXY()E@!wd4pGpj z%@0;E@>dTKV%GETqg>OAM)ZX6t_`O#T5m1mUR{sextn=3(qh)U8S^c3F_NDW@R1`o z*Z9S|!_fMPXFb>aMg<$f{EU@^BIVXMd!uh4f4UxdApiR1<)_16C157a>nb)eeKEF* z%sp+bMXej#<{L|k&kfo5_2Y!G&M2lZsBw30U37S}mm;xozV+xfQoyE~2fE`purLq8 zO>-nR#yak?AXWp8#`2pKn3Q{;_$>!wB3;QJ*9fd?l#k`=Xe1%PGEvi za6CakUj3*{7kSNrrzazIrqlg%k|0;mj6uq6)%JK7zsO>{8~nK0rsLWc2MU!1kJ!Pk zevtKvjTpV-Eb+kJyNH$wCc79D%%d|q2V0<{5iu#7V+avWcHHiA&C2P%Sbu%Rpy70C zy{tgoFX4Z)b7<0!)J3}nh0#; z^&uJ#T07=k9_h-*-7`)k{wBAJeeAtWZ<`R5W;L782eP**b9-vnE!F39SX#hS$3Cy% z+^j4}z7dtES7){^iu*^wjfr~OHCybKBhB`cNBzYNhBEb>48D3)QclEsKQbIcvVhRe z%@1ydN(N6$v}Z_Uph!-Z`^D@9DzqW;THJkX4{Ywf+B@gow2ZhsfoWMAew<_D># z#UCslDs*)CTpYHD7Ns#nP}zMRXxzpl29Ki<{Wv^uV4I3rLi&ip+0Cb)IyuSe*@~Zn z{$Guc*J5i`a-Hk=g(JECd?nQFe0s~+&7Y{-R-LHk?p%AOUm;{z%)P53*hARg!IrD; zTuxz>-hX-DxTnasCZ{#cCSf+#h<;TN;;yHtk6BrHKjuHim{}^lVD-}VZi?PeO1Y`X zl}ruKqZf+OH?9sUD7djEHi)vQX>^e(WJoz4BQaA^$?mHT@) zFT@{%Y2-t2AJsPRB*#I3gh!ikW2cZ55R!KtB8wOBme#3T2~&=ACC?Q|SF*}F(v@DV zZR2^L?nJg6(PkexAb(}cVM@h9`Yq4nwf%VtOareLD?RojwGYClxyQ8T@M&Ipx-3xW zZ$be1memx1$&`S`z-^=s1 zcRIbes5mqcG(SOTa1g|38tO?U-gdZvB>N3uot?95uk+lmKL8lxW-Cy_IU=}pwNEvJ z6>jbbKOVJjuu?ntK~S)$cP!Juj12h8{kFl9Lh4xQ-N~|%DWUnz3{J5kp|sL{1C<*+@>Ag4 zsDPYL4J~IQQZoC-?di{-KVRg3?y`OO^||a*V!_WyXaON;g^py1j{u46DvQ$9wFaYM z$f3jQ&J{@xl<$IHOF-XRpnu%II|gXT)cfrpz?VUQM1@2W41x9OK~l_v^z~jQya#=!466A($aN-4YkW zaV)K;)(-l*1B#VV`9OiCrk{Z^~yy}BrMl)^EtliE6N#-u!T3)j@zn46|$ILg-ea$}9 zqj1is*x2Mjz>Z=MT9LwsxATqIU3ai5h5E|Z`C);+y7_!FMq+JXZeXN5RKIJ*s-CB( zYmf40=TH6Rb6V+OQU5Tj4&JplcK$7nx6r8LOM)=|Rg(B|Ox^OOf?yF+fylAzmLs5o zVhXr+&N`ihX>g&Dz$Ur{Mak1#J#FxW6s42Q0j-De)DR<3vK6Sy`d3NYbH}dN_wzQ> zPmk*U@aTxW(zwc9wQcl?_rV=_jUS1K+!KlAqTZG|SEmGHTz6qm^D4`O+xsNIT1Yp4 zI{2OR3Stl@D9Njb$ZVrdou~&bjE;`(Y~xkaHX6!D0PB&1Fe|NzS-_Vm7jw&VMYa+H z7%$zBhEG7T-!JyZo&iSkHpA}M#{8J{f|~$r1Q?3coKw_pq~kP#kh$`6#5rrgAH+S> zNqlmNn`p9JMFLf2Du)|FVb)bUGtZ6t4F!<(dybGo}9&xQqFR870H?+(B$tNCM}Y#`G&tbS*4 zOfnY=k%^u5(BKVedJ#N@bJS~fVFaLMeR~L$YqzlyZ6#S&?V&W-S)WX5J8FisYP6oh z$(_PXV66HER=&x(ZnVaL6vP<3#{}<2(`RoJsOp#m)g9eP3o9!%>3G;zYd}A1qBa$n zGB$htM5f~;_pRfvh#MGOYr=?u(QGhIHd5=qMN+O{x?27uy66*Q$d7|FgDwzaWf4$a zh+sVhD=#OkYr>6Qw%7sdjpV`b72ii)YPY!p@MixNnxCo3$;r+wWU};$KaKHTL%O}^ z3N=wg#o@tj_SlDDD$XB_1Zw5#IXJ6;GHcL+<)>_3HRK4r@j7sMNFVMt`fzZ5l-08B z@nt}=Qyu2I5?Pz^yjdUF9#@iuB^U-zqpb=2SA|^}R!vEXpnwn;44*mRVz0Kgc3+ee z4aE+?q7TUu+TLMObLnW(ORQw;?`NUxl9exH#LK9vzC;OWbk_J>@oZ-$(ousWiPJNl zHC(OKL-x-nK2jCZNIpw&3@p}$E%We+3+SwhZm&g=(8(l=M_Qg#n_P5cQO@gkAa;vD zOosr8FJ{PVTj0<3_O`Ttnt?-Ykxdl-wfNxEq8kY_910V z(sM@B^_r1}nW?xR#Iwtw_csCohg=I|j=hSFz-@dVhfqykiz-m`Bpyf@9ST*XUBnZ$ zKA#@1=YAd${&=_?P9lsP0i7P@czk_DZPYEzYVyE*Z@D%McfdrkI}!}xFhk5H>Jg`L zkAC+$IlA$7>|&1${1KPgxZth;2aFF<4xi~$v;#Rsz``aGlJT3cjNC ziqs!Bb51tRd1FK2S4hIfz}vqgt+ddW)~4c;s(x~V9cz4{H|vBaMhzEE?m(9h#}!CC zGR>?|IUeCb83whG3e+XVYeezauOK7P0cOUp2mgbjk9-?Ye9Hj(PP*pf@h42~Rr#-& zTu-$6n#&UzL=#$;ZY)6OGk$#$lX)`o5SCAL^sfxe-)ns5N*XK|KR=aghQBDOoGY`+ zfm-T^{qC)AF%~ve%%+`-lrQ7&p7B?-p!Aa!3U&w(2=bAp>&G2`N7`&l(s4b?)#XJi zWdjhClFX&bqr9ZEw^x0yPx-0RHtsfa-}yssPo*xL!Jlh(|H3sx^x)JALnTiSF7*0wF10kj?8aMX!&ptR@AND(v50v;9=u@T zQ@t@SUB9FP*#ev)-6Ys{Hyk=Rwe+@vW#wH+zu>)BOZHqG&o4jl?8Qoj^dI{d*bkt3 zh=n|$jv2z0U3^hNv;Nsgt(=;2uWkLdd|(+OJ)6$?mb@PS$WWTaR+4YLi?{_o84&PO zOS`(+)US#eDH7{n1224y&*67;0(+y!D*C=~ZD!F{nN4Vr1gYeOWHV2LgT)3fr4@}N z{=JCEwV%YRy*qNC%AEpd5$$fE;8mz9u!3TycA{%<2)sLf&MF7!19#fX**-Ro$^a3+ zBvrM!5atPlYHn;$HJE9sQd4haJ&~oAWB*Ppbbi{520Y^EQmPBrz?R%GcdpX3flgRy z0c~Ye^XBxm z__3d00h};Y7Ld;sl7=*-Y^K~td8X-KGNNHxY2F^N)+*m(3Rlx6M}8RhVU zc&2}BL~H*`G%xl%*q1vAj;~JP;WEtMM6z=v#ivt&l(vqD%+FA(i%-aWg0I)lpGUgE zK$A)!$|26;kYDat#Sac1tGbPG>L17AkdR5^ZAe{2-!mY_)53TK_0*da6=AHc^aC2XR8SHEP5z4E)Rf#Ss~bohMw>y@!^9!p8(g&ZE^ zkN52#kq~w1aDyv)Le)XjQ=QmJxPS6Uv|$Y=5`Bfx?G-15Zd1as2aRw=y=P-9f9d*1 zAFMdthkVPN*N`tYlD9hWZ~>_KX6yZT>qn|`eaIYecjwzbS!S46>koS4 zDR!yPaIg67caWnW)JHn~OE&I64N1%Wd8?kaD4Mj3wa`@sX#9zg3@%S+ntrt7_5AX4 zS903bD;6U1sX$=|It3*D+u}oV_*OOQs3rn^`CGlgiKs8m6Z7vyeb@yKjuQc*O@5}? z_w9=dI%Yb}6bw#uXRNsG1fnN(%^JK|D^71#$2^ao1!3vrzzT4}1-vug5*v``1KFQE|1S8C?FY#K=7o5PlL~zk z;sHSQS7Nrt2#-VVVfanFw$_K{FQ6jvyoPYV5(dBlc7)#aIBcT{(umDYrjyQq6=u(D z2EOc*Fp9~H>-!Uz$XDZo2Q;ey)w|{nCUd%PA+9&z0-S&glsWp5NcKs1{Vp3Yt-xS^ zp;T)gGc#Yo^+agG5bL9uNk@Q#NZED55EB17o>W|{@kEK|dRpyx}^mkTFH>3u&BYoe*sz<$X4(OyT<)R~(0 z3ZiJ<{@Iu9yvIUG2M^C?y&5-Wyc>(s2H#GhY^MGGKwgoL2T;uNsd=)@Ozg)IS;O5H}85#}+jWup?zc`9g337)P28zYHW zCAQsqLqvlm=5w~5T*tGUq7g3*XLNgCI0F!HZP*ia>3i$9h8Ed8c?ciOm<&@E@9fL` zjTIy>EdPTOtn7Lpjg$L~TqBV!xH7U%1!&p7Se(dB^yL#|4O7osHJhq*_S<-OR?qjo z)w0oBP()x3*61%ogg;1%d4kk@UbzXJ#dUpnzen#Gx?+|H0FIO>-WVU+&<<7 znKPXnhXrU}(7$w7zCAuuW5AlVoBl1zgR?IMOa>s3P>ZUr(ht5rW|Q;);+a^;b)ULr z1sKb341niWe?6Uuy3&vA{woqD!_6dB|KPFOK)#y+VO_2!|6$Kd25~%3!xomKA$QdT zb9>L)>>nUt+Z?};^bcJh0E0-L;k}O9e2y$ZWs)uqnU6b;)9&~FyKn%{%hROYhUs{; zH>Co4ea>xP0L8OSz8gSsG>Ov=mEZNE$p63vmT@8nQg>h0P*@eWF@!+#Ye)Co!KgU6 zYLVfau?*%wFugYSC;jqE;$@-3A5fv>A#YU`@yp{L?(=;{`pO;OD6u>Z1yAcB8o^98 zBF53TsG!^B0i-CWzg}0w=Ir15YF^Hk_R&&YbkI*bNKoEe>8lzl~JZH;wL0GyfApfOnNKQNCrdqrpRwqgRMmeDBvI zPHX_rS}#we9kF5b_;ojlj!KikRuhk;kQM{rwtv?u3zzg=AMnbZ6G9avfX;a;kh@>6#P<2 z@|C0|CuI#c8lz|=OpSk!BtR?!I7Ng5&9^>{Y7(8Us`bbMq zMvG|!f0;Ib-9r{*LP>P_oHCsm7Z$RY%;^gj(rN6nDRewiA1w&}Y=pG4Wt|sm41g98 zz;KCaztV|fbPZCS7X`Y=1Ctc!5`Dzc*vIOxuvgL58aO3P4=l`G^^P3oVP#kF5;oVM zE^`wSb^jKv`~SDsW3<1Y)f4zI0{pbF&ZV8~(oz5tjBXmjY=KXaa=Lu#Df`p4d2Vlol+u3nyFpD&GL_|J2O!Ip zUWmg&UuNTeu_wkJKm(qQ!kfhln*dpGLw<+xxnqFAJv$5fpmx50`mu0*t_}KuCkq4!k zdJ0I-Er2%2rvT;P(3=GSMT?4YFnQ9US5b(PTF2IB8<=a(=y`0a*?}!VP%6tyV^Ge= zON=CNRa2JZKz?s1#C=E*?QeoAaH9+ED#)8b1`;P0`%)pF>vJ2y$e3+_HItg}eh0^U z%)X_0R6gWjXf$?aBHP9A@$N5cov8Iwb2s~r;}}h7ao}q}F>3*4hY-~;wJpxUAa5T} zBLxUeZ%yR9BI*tmqcK;~ypEeBjHB>GutbVLP9HijTRO6AO~IHg@?f0aNHOb#i)4i% zOTgx^aJ8=_y7dXQUPdTLc^41jfP}`~Rcoh!7|ISQ!s{C!zr5E`sVrr@Yo%37F3_z60j@{q(|o5?|hS!OE*gfYh9W=j+75a zcLGg+bpjwRze^JLV*VAtB`#eO1u2~RT%c?VLoTDEqf;Q!Uy?{Dn{iHa-bG3u3>2Q~ z{Pc3j8d!*3v5`0*^By+mO7)@V+Eso-=scR~9YUO(K5bobn4zez23Zjsjpw!#Yi)s# zzj5DFf0cv7z0)q>-C;x?{t?Y5%t+g&P zDZf+54CM>kahE(n7C7q8-q{#Sv+mX?UgN%PQvLgpQ$arnQQgnQEn$_ptD;9LuNg!Mj(n$>2{|Kc4XW(0 zr070E5M{SxHNBTGspF{1Qzv$?JBKIdQZCWMhv9b<2GOsqm_^Lltt7h z7}%O3y8_A18Z~CZjmxNrBWPgd5v(LIqYRq31CaeQ?CGb&X0JV5jQk|&t4G$qadZU= z{i6Z}>g9OTRS?qLG1gGL?0;R7o+im;vhE4NUjDPSA3QjQBiJjW^G>@mVT`(}jsPJU zBaF;wbjWdDkZ3E51`bKuGFrm?bf!FyPWch~l>7cTWujh8gW6fp6xP)SdwY}99KLuR z?l*QNO3Qahs&b~ONN-nE&EgVj@{Tz4xAkX)b;; z+waV}lU}HT_IKvjcc<#?9^8qY&1*PUwriy67 zw}YI9p0>5Xq!r7QqI4EygY$6+IQSX?uh)6oE#>eXz!HrlPv8Sx5H`iDef3}_ z={^EO_*XwFdRF6$46T`|zqorBM|Ps}iYQ?E*W~5pweHwqAjph}kT!Yd?t^h=;RiK7 zaLT|bQH*>J!m?x3bi~--oy<5oabQU$qyj#oD-{l8`LN4TSK#YkQE>LoI8hA)O^Voc z&}r0dWpz1LfWa=)fkb%1yCz!39ge%?{_V9!!&)uBs_`t=js_RS&r3WEyr6di zLK9NDctL#7BsqUEZ5<}Zrc3do%WJ(|Lqiu$+fl5bX>vaAoZVNl`#{>>;eFfLWc@?z zQ`4_UB`Z5Y?SDDg{>bn}!*s%aM8Z!W?Q#0wW6#A%@u>CZ69J4T5GJ1pV3-KTFO6m( ziiFo*ULSInXt&VsO{_mj{hQrh)&$n6{Uw;Nti>1Hy;Pkuuv4Bpq<=*KeF3479D(1h zMbVl{d>SoMwOrNu+BV z^4mB<-mH(Az_1O!1_@2?JVWd}KN86!7xGLJfMx@SxAZ z8iBerRhdjJb7aLxL5Flwa)*#-H^-fA2qZt_fdFx8vPK|c%ci{V3&$qc3)i#mU>o7( z(3Fjm4Z)`%YBYE<{tcHuhwzyr7Sxv%2~__OHSDK9J--mfc;oXGkF?RGdA*JqV0Gc0 zdDocri2KrZ^lWkj!j45r<6A~LD>smOREyni*LGfIDt;VDX!oJ#?wlDp`y0l0Y5v@2 zwqN^9eZ;r~3>^wUX0VEMRU_8tUu6%tmZ{OC77h;n^2U-1o!3v#&2t8J7o>4<&8ZQF0YAow<;PFLwEm^n ze_Jes;#+evH~DIE-pX*#*!6Lo$@%QMu9BCv$&Ow6gSOJS`MHc<8l{F!Scvh>*5&6Y z7fTA8^&JjKk(#K~c@F zru&cqGlur&jN1oD2nyZ^)u-pVrY%=!TIrGrBFCSthU&*UJXhCC)5-=Bo{>>q?!^w< zy)}VF;ijyW$FhOu8r$u8oH}Ey>T@ly|BgdLJx`0ziyR0)rw%F*nwe}66FP!x9Pmso z_zA`N;+~-KMd<|A^lwBrtNqQRF|L2)%P6)W3C$1+GSw&cn4vX~*~uwA0$L4Bg$HZ4 z?Zey=7+WT=xXTI`{o4?W>F|8uWK+YbnWpMveI za+mW)2@zQ14ytt1361f$4D+9`nTVTw{*K&jTBpAbQSlh%&w-B=!>A?T-^l){OhTn= z-h^oDFuWf=>nvUO7F#m2v@V1t{?pJE9;8F1cc%iicH3#`V=X!y_VIG~hs)jjIF(m$bc8v{Q=VzqJ6M8wJEm%q(Q+j!F8;m9M})!~r3KXh=|lbqLB7L(>D%Z%zHp3uXX!2>oLqJ|!M@#MC$RjX zT^;LQ|IWNIaMXF>dpFYgR`J>{Q`yehn0VoaSt~(YCfW;VaYr7FF*S1T8(`brXuybt zQekB`E%-J=E$Gp7C+DPN3KqihFrN5uIiZWG^dJRTH}*T?-}{5B>izfZMw|P%5>wgW z{c5TyzFU)6{d!-qciW2%eM&SAomhEA52Rx;Iv?yP`PP`p^0ejHQy30G)kt@e+NW-SEFQy>TKwVzZ z)79Yzt-qJ6>jI9SKbu+a!4wE=0e3{}DBTDaa*I^c13rP$OD`r0i63|aAt2^z+U7JH zaRb18%BP;#p$QNaGm%CF(~wh?bWJZFiv!28<>_G>?1b}qCdWMpJtOW@IOXTVkx`0ij|LUAMFq1$&5m1;-VzOe2A)rFu05<_n zLI7Zqzi%Jd;g+j*wBw{ia05nZ+UT&s5VUy-4rUfdu93=vfpn2Y$TecP$>p{cjkb!I zfoX(IoFzu&4Y0Li$+_Trv3J)*`bi7*up#jjBKm$7Zy=c{B-dD#rzh04{ogU64Z-7v zi8IE$@yyrKS6{3ZdCNv}s3=*_P02snN%7cIBHJI+`5OtHS^fxJ=5OoB zKX6dW$tl8Z5RyV9-_Il1ba6yJ97CW@k$=yF)PI~5#XffK(kRk7ggNToX{43TsrFjA z729R*?YDaP_;%ze$jV$fliRi*2_kjh)Q=YU1Xd|G`e2hudA|Zi7dYAJW}B5=)gr z9G>@|C3C_5L5Suyl5=@E2%BaKc{TZ`kUEC`u0dI<@nMEqcdQcV6SP9Y*XNsdJ_;i= zfK9~l*X==?2opuCgg(06QDmmZBYu3oKKVOwzubvhec$aoAfkFEjEEdp<`xmF7WiY< zaQQ9{Evu&CZ>NYSsT}n#@MmKEMn;oTG5WC}oZ}B)$adqh5tHdGKt@sNLYMH)5Y?%p zChJRPAfx7QvLws-;b`DzIuIDWYVm%OhsbhO=e5t6yJXv&L3TEY(rZL9eV1^;tkv5a zGDhovgPjm|vHq#{|91z;o#4TtHFv##gtdJ_nNB?~Xj1e%v6@)x`P-$X4|~wLx}}Vf zKyy>8=dLC%zoX{Ars(Y)x!=*Y^-72G`$6-;ObFn1q)w*A%``RY`#$M6qq|hk8|&vl z#uf^U>VP}u4?la{Y&?2zY9xUsqUIyooBtaXF=B-M3sm&@n@LlMhB5E;QhK-EJ{~(H;_Z9MKG8utob9azJV~h$a~Qwvr%C(ZSB#WB;e_2@+m~6nzL08MQ_62BkD# zI|6D6HfUv76dGqiGB4h$YxKg4Zwng$5IUVLeV9Jjz5n(Q7H7!kfdP1 z#=Qjvovksn(q z${{(g93)Wu!E!hMhoq^)rxFm@`Cyi*ADtAiXX+@-m~hYWDppO=-jcjpcXLvT7uSvT{56kh7%n&^yxzvwXyds~ z2XU>HOp|dpSJ#G&+sO@3%=<|uu0W7`N_%fXqxuxUXEH-OGoh#XOz~^t=9L8f1M2GuF9xWcym>28IsUj zrn*FJ8Swb*zsgl+-`fWZrch1mmf0EtA3(#J=)%LZm4o_Ty7S#}HYgP8)e7VV`3%(K z#y4)?Gh1Au3VgTA(8BS;G88v#mP(YwR|C?Q-NAxaFqwMtxCgz5iQA3=FvP{^v2h#w zmZ|Uqxb>LZiWpznu-<$7RA0twTURCn5>n4<>{TbQ{7%Gtzaj9TNb_2c2v;XqjBl?^ z!|Tt40)NXHo(Fw!J=osYm$w?gVmL12Mc~vt*4p?wv1CZOE11*s)bap;+Pyp{zS*bh z(c5DPJJf{TcO6fU_tZ|q2+s?HXeYO5C?YV4!hPq3Z77|MOSY1fh*)+2nIP&pSE(9EA;12un3R2Ep6$BaI zhK=^1)l#w^O8)|MhXU}F!p|V0ynhWKp!Xb0Pbt|UDKalKdB(acK@yXBy@fq55X#l| zRZ_xrW3FHof?zOasd4=CvCM2ru^G7xJd2gqeO$wu{II07?_eP#U(9nGAD@u8E4$&E z`My~$`J&VoCtAv(rNd{DYfEAwGT99QuQ4bco%^=!J7Ay6HqPj`0MN@H%5K&Y3E7Gm zWVfMPxh(C;saK&HN60)5xMTknw5UJ183|!B8b-SW!FC-S68ek|Nl)iUaC==x<@Djq zEn5)xJpf_!x3c8{exUwNMi4_f-3G}$*#;eI&Tg^_&AZDc;rAt_bMg0{OdwHV5wBYP69W0jtfa6|x%O)_g0S z8$QQxhlyE1h)Q@aC=P6D-do|nLf0QIGuM3l5*th_%zwzjfkIU_J6;2xq*Rem6bsCJ z;ej%(!skgqhsibVd=fw z9p-tDEe~}wQ8Dr~k+l_9{O-u?onK~31M)i6(>kR%$T@!@vm`-kBv0tHpO^1ZYv}=& z2ryeNcTb9tlh{rY^m4)IB9$o;)@>~Xp0-HISn=~_qn|%(_MtiFt;OYKPTwBD+%!jQ zJfp?jO18m@Mmb}o?jRf8(*T>1FMaMndnGY>EUS03Yn? zuA#cWW<~07X;hf@eZ}Vd5MiC2Q*x>dXXO+Q48mfs#mAaAxK{D)>iGIzB#pqRDqBG( za;uoBE656e7=7Sx_@iQ6IzLBGqH%V9IwN*aeUtWgJ?UmAl?y$6L z-4`;`8-%LXh&N#k(#l?|Q+wVR@P@Zqg)Kcjux$vLE=9eEui%|gaufz>>f76=dr;C09c&O4Kzk8dyuWf$olwZ%~t!a11@Gg0J*yH&Ah{LVJgZLltVk_6~!3P%E zMPk=T4ySZM#!HaxE2jrnc>#Mx6_ev(4ztKDW-A+7k@)TyO>VpWP`6P%*v4XD%EMEz zVsafYa)&=cH~B>qiWS?*+R(Jy{43^VNSh%jL)%jTEG8jWK>mr&7GJe%p&I$7dI`)B_ z5ofP9HOpIo{*A>_0r|tCX4mI~|EczM*BvNfYsE~)ipqj;9VYV+#^UVNjN)Q7134P^ zL$DfRPO^$+1s5#mZjC*NfS;VA+(<<62uD`fF6&MlnmA(R3NR#zG){{P1Aw zHAw~GQ(oG{PfOQ)oUXrPDy-dG4Uo7qzA5UfCuX+?ssk3%MhT6#Jfd*YWJndr=x!x(E|D=%vF-F4KDRJn|I|f{cO7VIHGP9Hwd8LrW zEp7gVpTGm~EZ_ph`Bn}-GGa|{=7l;Mkxi?Z^}Pm{u2f_5;Ix}r46H29uk+-@|0MT& zsG-dR6YOYo4*qzyI!%{|D%4?uuSvVXsoI`ma7B1f5%%^~>s1*LnnZ;*of${oCBpWV ze6ltn4sd3RX?zV_kCfbReySoE2TANam+y@$hD0#0gK3Qx@kU4)@9Mi!LBchI?`rh* zxW%%+gzJpOb>?anm_MX}G#o^czHD-jaS@ZFk`>whhBtU@`B3Z+_dJcUlV+5eWMy%P z)I-2J;wB5D(!>mNc*%hJTI?lbAPT)FP>4hDRGfSgtyeKJ=J@UCZLPVY?rMZ72BtYx zWaBC~`JU$BAp+~r_1G}qM`u@5%HMHJt5FEJJw3=0u2i&XeaG2s5_r1zI; zc535oewFfM5&P{f=LbH5DPr0>*};aXSPQYb>22Lb&|LQIBX+^N&c_0DLoWUiY^c{o z6oL{VCiA`+;uWytv5#`9gav9BiheIkPMPJIs%L2tc_46$7Iu+Vdd$03<#I0pz~SpeV+S217ma`sbc=> z2w^PjJv8&Tuy+nXtTQh22EkHYF=kL(RgbSde1Kq>c`&|4d?20po_#Ardp zUK>f0JP0Eq+VxEv)uwXfkqk5DXG*5Fe1*Nj%mvm+%@Do$xokG+^ycQEzD9eS=Zcj2 zQ>GO%%rV|}2GsLpu8h+;1E9lt8xLbr`Y?G1eIhsE(hN2%SB5)aWC?Jc_{Ks;6-2g}S7 z;vr?@@3QRBWr^!GxVRjZ10{KwN56eU;9DOR0-0YuMxYzPqfT~c&>`#lH?v>~QG=`I zE*2XAG9FK_Z|iQ?&JxP+{Fy^Av<3F2xC9EG=TVRTj|AFUzM>>FC(!XKv-xo*_@*)_ zsZ}7zJ=OSiHX_jQrFP>)cl*?cp`y`5m&|6Z)3LVUFGN==6vOQ0@L$7o-ED6sJ0EU8 zS@2sqiM&;IA6emH`u3I!cwB7f7I%65(&b-J>DkijKqPKDGr^BxU~H)e z)MhR&+Ocy=bUidj{=lid1RBA;_QL;|FmU5)#cZ*wn&!wk^$H%Pw~S7qh_gz8N67?> z(>iUtf0Tv4-0A09&(@k5JQJ-?hISG9RmrYbQdMia(lr(hlsB&4x$B zWClisDf$C`o->>&pY~Qe!=6@cI0n5A)1#hes1`N|Ec$V|{VD2~=!DvbgNn91LGX~r z)`A_ldRkifqxHMJ?&`kh;!WJKIAPp3kA9H=2CN0=_FP!P1$??~T#woFM^sJV4yz@U zT#z`F08@)xb4_x27ZE9N6_^uongtM=m5)AYIIu=7*EfSyM$q^3RTP;)j}&$BxACwd z^Sa;D<8*;3?Ry0A`dNjtZKk@!4{r}4AOPqC>dw|zUxm=9SuVQz4*=h8}RsOMt<8sP;bTm zzM*C3iJ?}XLC3?a{a$8#V)`>__IelxJRB$PL*Z)*-}dT$18%=@1TTApkoNm^nw2GqPj*i2C1l<2&GVP2G*z{=6`#MX1M&-!pBkdjxl(-s zwW)OdH_(aR#9)Fg!{<)uG;j`{a-Uw*iz>YQv5?cC!Js>qw?U%%&y<2QAuIa^rkvp=oYU(JgN+#OXuXZ)KUur+U z4U}-l<-6JgT@4kNI@w?A+dnNSUNs?{nriejpN`W1w)5nKaJ#HO1uX<*jr$v+cJWf! ztGe^m{t0U4XEC;`B$!bdm>Dy=Fy660v!gxp^C9umu2*4KK6%8q-T$gV45b^CF*EXX z@znUilpWiajXor>3(M-)mLzBjz|?uab5T)uIo@C1tXJY(?%)V4vTfl8v_ZDoR_<|5v_ff>pQ%`ujB_EeDDuPv{5N8mWsU@yAS zfO88_v`~cb@&Suo<;;xGvEPtx-F#Wv;@EO%te4Zy?){2CD3 z{;QZ1N_|w!)+BZ?l=|@KYy{R`{Bbt@XZ|>wEIY7-A7a>14{9SI2O~ex!Q1g2zQL|E zFFBpO_dBU483&*36#Zm*{g(kT3cNZK0JGQXEHmth;LPAK=m}3;h$pwm0M&HJ2MXUH z4O$csk_dT!-&aGsBoSQ_s|<;p74gX(k{jIin(5+gD}S?(S9|Bv7}WWh^~ZL5%t|Gf;)K`N z+?!1c2%re?`K07&M-#R5mD2Mra4U-LG#VN}m4|8erG6{{m#E8=ajJCRR#5IGVKBYv!h~AP zRMI4HDMH>uVj)w{0oU+9jf>A*iUsq2*sE;!Pj}oHRptTBp^g2P-lVwSo<+pY>w?;Z z#GoBDl*W~44Up_t?4h3|$YnS`P8Hzu4mWEFTj%U*bZv!V&4rBV^kOJO;f=$`{=myybXC_#RYNkqufOLh#8Bgx&9f9LChlY%=XP^JP zcarK*n|koTr6frgG$t5AJL=ZK4wgPhN$?zUK=PtHq_#g39U2{km+88aFPVQzH&Qku zQXuARi|^T6`*j<{%9+zp(9$L}WD+*UvKDM!%y80{$S@nf3~Wm>pGCud60yvcCipcNQ90K<32dgbFYd zhw)*1U--yi&p3S!Y-DLqU?SVns3QCMh>g(4TO#F?duA+m)xm}%D}fKe!97%!_El14 zM$(V1pmZ!2TjD+5YKx0uy6Utk% zJ^Vz%#4A}hE9tFtdMV;^LV`Z*PgGuaMUeMAz}I z)zAdiDq~?@5Ob6wMTE;SKdw9rLA>Bo_QkR9^q-S*o&!TE zjv-5Z+hN)4Iq!4cV*W6T=e#17dq!mBDV#I1;PD zJR(=ahA7-=XG24|1lDsN39S7*ZLxPfXJLQ({LW~D*=RlKXn9${{nh`6y|<2vvU~qV z2N)Vj=^8>%x<#ZL5fqgMNeStcX6TLwloaW1X{4kTl6b%Op)BjTgubRit}0AtIGXkWMz4bkFz<)?PS?$onu=0dk^Oh z)zL1F*N^y=LsuPiJksM@?v(|Lt36bEl7O zpZZmVzP*)$1_MzNvNRl{R;~rLE(R1si)4fk)=9g9xA2kZ#i7CC=J>V}C0Rr}l5&LN z>pB_2h&Qjll*Wfq3sWBqd6Uk7ndZo$LUVH_@U^EDP@QPj_4ZHwe?gxL#ovwkb1n$M z-CM{U-R~S1bl2pO@1`jJs{wD(kVuyv3H{=5WJG%V{mxegM60fw@W>C2ZGR`lg;Xd8 z@@SQCnc%uzh$du9AR4XQfK9CcT&qI%{=OJ|pF!9UUmXSJ+5d&hc`6B27CkWzm_rm+ zlHAVcL0m?f9k_zR&MHj2b#UD+wneV-7<{*o^}J590Y(*nbq3OW6MX9?k|Bt8h$EUI zJNnO$r5R&HL*m%l@;JbU8Hl@-f#ue!^UpOu3WQ+lf8hz=AVi{vg(9x5AdR{Af6Lb^ z`SPH21fA9cpJKM*fnhs_6TqhL`b$hlgQ{P0c@`ygvYwYGt2tu@zYhp4aNghEsb&cvcD2aWmR<1DZQv)g$J>K!ex&icU&jEs4qxI^Yss}af z(`>Kq4_x#k{8oJ)pi? z_6J>an)2zu?Wc5YeTdR#KyE0Cx@R0Xu*zCo8RG^3#_b=M2j?fhJ)dP<1X4?^h?})i zbt4c}QVLFE_Nw7$8>8Abx3D+nD1}{YjWztm09sGq#^f2zR7_!k4~u?I#2n2qgj8r% zJ(1HIwNATwf7T_FoKX<{ug>2bw`5dft9?gurivKzS9WJhOofVl~ z;WXt3%eR|H(BB=_G##)v4+^v`o`dR7cuTq)82`ck=VHc0$vHMq_fyT^lVu%4ayqK28Kw@8? z0d`4xZh0oK-xxFT_DN$oo={@9NVNLh#su6@OBpod&%ui@;_p?Dg zw^1jQ{R={Xy0NvzM|-vk`z<64dVwnbFEkLCM5quEmx2coSFu(Gfwal@Yo%Jej>cQ2 zd#(UPZEH9_a_kx7>0x^=vp|o+?$$pzNVs+cmv>k)t6w-rR7Hwn?R=l~^K`THXorD%u`_~~R`oq7R5;%x zM%aR-;UWPZRP1$_ms&;4P4haZU)7ry)N}N%PREF~w!}Ra1eG4)m&Bnw7-ko+X})k~ zFIDa9N6u=?uu%I1A{30{YB)F1GGhM6)>?c6|}e2D3sPtysOi5-7;l zb#jC#(3V(J_SQh}{aoHIY;{Q$y*EQWL5L!m^%tID2WTg>vaOansNz}Most3#Db%w?5#czCct-Xpx z1g40fmZIKc5Ki4H759L$1`w~-%k^OzVrLV5x0y2Z%}Lr1z|gxJel{eO0L2&DIIGf1 z%GlR(U4D15yEfSfa7LqxUJl*IYAwgDT4IkS2RM|p=%kEv!yty=q$4m*?8fX7a`7F~ z6T=)<8|2`L1$h*$yA}@|8W=J4*|UzrK`{OhjF{~sVsBO~_atdX(c3B9G%U&9@sMZ= zfS95YUmVv)0Z&TMN6T~eL%W6b6I7k^9;;!ETwx@Rg(MlZl$F^(%Z-2jU@grr2FCC_mCtD0I zBg@q2F(@jizDL-iCI5>Y5ex{fg8}o+BI_Bo>ssW{yKUf{OL#n*1=Y1%n+>v8e^cU%cGc=+UZ(D_4UB)9zK0_=LUIl%d)9Ii@vFNe3V2hq}#Y zGFW1grBEZP?xB2wAr0s4%7f=zaXsRVu1EZ5oz`(Noc1{&OH~~<#5dB;`3i6GLJ+MN8QXancVNyLsKfW82NjdIYs_41O`wAV79EwU0GVF}+UWb!)h{91XrWb{Gi({oS6D#j~c*oTl|Ua zbw}+%bX4Cu|Ln(Qs+26x*zj>$O@y}4GU7wZO-)`u^KE=XKr{0OrUvtcX&+5HL^b#G zelVajO^()ogC*Ry101VwePB2To*na>ekJlVlg30XfJk-18%IF1d0?;wGnq9^5oVjV ztR@U7CJv61qW0FaQNP88dn<^9CtRdmnZzYBgzGdhL@DNXrTK`)7z5l4b(rV{S2E>H zYYS%a`NRr2pae;eQh0i{zrMI* z=zGlVPT>k*Z&0P2PzsqWF6@80+SWRM_E~ZJr|W)}R=^Wi^rTf8H;GN3d-;jjMJ2sS z>|1z?c{A*7Qsq2N{hfh#77y|H@iC}z<$6hEH;KOklvtrT;L#J=a!lBgPua#DU3|2e zUXAIAw;^f`d5!+x*ykM2-I!QPBzXD*Qbx0t3PYSkbj63u;!8Ur#}+XqJ9INDx^req zGGY0LVIKXon6*K79QJ1iI51!s%vxDa=Yo>nGmR0#Na>?tj%IMQ79J(>8G#4l z*x`#?D&}d&C_tR7e_aoio0hNLglV27AGQcuu~{1f?y(@=257E97L;8VBT9|2l5CV- z&nHcWd96uijFsg|mWqj4zmvOOh}-W$NE=yul-Q+U|3igw+4CGFi)lgbNP+~I7?%(F zNo>0T6_eIfbgn`hQwZ}{P9|S*Z^v~8cE_8YTUrCp#VZ@;0*--HzLJ}5T{hZs06`0y z3^y4FIX6e)6M?|PVlrIbSO<2CTmt9TA~BHqj`+drofSC7A8{E09kDAP5J7WjDOg{F zP+WrRUg+N&)W?XeT7pW~;R<4_Hop7m01=YT6a)0@h=u;yt->g;7x~}*ukJjtmIvL9 zI$17*k-)}VoHFfJKic#p{Am?+u$@E+^1LK7;tFqnrE1ts(fxh=@6EU|N}fe_3bwr} z8fbrjeF!vqDV`ScXS4oe6iptoOj5*zWJ!-KSW}@GL33aImiz0R`h`ff5z`i9r(R;B zk@*X)bK38Aczr+6y$AwPwN8 zlU2Y!+aEVVf9pylTi7RutNNREEtdr6r0UfEhruJ==H`DL=uWpaC9*Xoyp`)Z{^X!6 zb;&^NOWW+({BS--N4{F8T)sc|P1Cv174 zU7c2^K1p1MT9#e){Faw-piudhw3F>zoU|A)*y_IP_W7yw#Y&}PL7Wfoa6%h%!5i;= z^9)*0bi?>Ix0TFTzQw8ZK?iS50jG_KR{rLp!oC#9EQM#}Rs^3qIk}AY?Uto(AsQg>! zi$1%`tls1BI}!G$H$#MCtism^uCvF8rhYptJ3_qK{B<`Pb3*2k#ek!04tS3fB0QsHdd_sZ-b=c zyEksw#NKjUt!iRnwW?KX*&dN`9m<>~lG!2|Y~7E$l=0k~M@nOARcqF=-6I8s8f$qJ z)n{uvgPUjC7BBPF|2dH=bV~tbvlJjwSV7efbTT2p zRb?mTOFjc>onYP_M^gIB!-?0Io}`Qvi}8VE^d-ui-zBp|vZ%UWlq%z$nbRC%b{=Q{ z3ab@r6y#MhnkAEK7yD#XUGKSf^?=zsi3?O4OuT=HNDnf?)zaakwQOHf6_Aq~@8B2P zX~u}fLIpe()5a*`@0<*^4>0?DnCt*V)+THxzZL)cmA;AfsDEE1p3qX2 zG|qMJ_(6{xTyK>cZdpPFKBBi>{y?-u5;sW_EAJakgJo&G#GS9`^UjRGr1p`oS8r_ocFNOo;_ zsC;L)%*OcoOhOVhkGE|8Dvkv$77#(A60x?P*Sg}X^S9O{!O-ji3FyPts!Q`{7&9L` z8G4Ral*n{zN5zyl(zW9>jH$;Oobk@WNj#J(@Em(6qSzMCY`<#M(5!Sy7K}8JW zA)*$8C*RoEkp4d7ufqkWtJlbXPAE$Ipt1~#4~~`@wey@^G0=PZ_eZjin~QHg`ujwz zKh4O>a?Haw$vswwo*W&nTG&^fR?)>H>#MSxc(;TASf%mgp2!9OU0r~F$ z#0y2XKhJ~2;Fqb$N}s4?4I8$9(IQLhLSKE)7sYyqtD?-#&O47AQU5v?7>%Fe7 zFBCjnp%TO5D^pJDp^9?O!BcMm#9f`FzX_K-0;a?H#=j#DC^;BAIgA}m7YNAh;`oh=*LvBeFuMmqgZRfQEIl}C~MTQe~wypcFrd{d%`wt*x!#?|4O2L zFBFuYP>gusVK^V>>!aMy&Z)x_GB)LM*`pox-6qGTy;py2czrz%6HRyKok7koq_Z!e zH)!Kf2pu?XJrv$L^R}0_CKAaoxh=)K7MD$p81rBRwPW8u{);?-0p5SFrxjLOtA$2l zBc{LhmK5}^Gq5TkiG)bzvT=8_mT;Q5jFX0gR}H(}JhO6IHY`*~{{M`31xO=lI#_@Z zn@gCjA*X!gz~2kDQC7@l8T9S%M-^K30prD4DK!tP3buc6#=7>FAJ?^gY-AoREVRQv zaWVF{%?{neWBVBCurW=dnuVI4j_vrB0v)Vyz#2zpM*Kc*>dOQ*@wFHygJ@F^qLL44 z3D){+G0dQ^UUV#u5$6!&*Bhr?3NM}+1_pUbV89%|5QP;jHhFKPVh>?q=zdfdTVS}J z9CV~1+NRD0^lVtSsM8c_P$gg5RX^E&A)|4dLP$Km!M2-Wwxrs;03%FN3VkgG9nH04 zVr1Pw4=$4q1a@B#(@)C4KtX63Czm6f!&P4#3t!Ws)l-E-A)VUTokkMS%qfOOqE1WJSUElxtV|-5RpkP`aworZWWiRP^ z3hSqbZ##S%&X&qCnI#MsBzO~tDn78Vu{$XCa~fFeL+O>syI) z&ttNoF{Xmi2bkHcXp-H&^Ruqv;~gKEcW}ks^*+_8!->Qg@ziryyOpGs=p!*wPa%;l zUPd46FSO-yFZ+Hbq};=Vo=Cl~8&5RYxtZZQu??D{%_4d-fO477y(cx~;r9WGc$qg` z3udQrVpErmV9inQcVRteVslbaex&99aSiwIlc$5V=f}B|hSERBc7IxaVx)BaWXwog zNBNmv)h1BmBz_Z`mm(EEh)j4pZ|KZrEU@Vx<(9Cy`k$A05mt>1|2a65X65w3pO>!6 z$NlTPf97G5d0sty&&XGrWdf<~h6B+^n%}C2!#a7^33@*2TZx8rWYD2}OtQ+4&q}bk z(unJ@xwTJXrbeJ$)6ul^1zu#Ly&+?ixF7sVlcXAL=jTIG2t*vBAT9CY5gW<2!A|k- zF-yfp#txmcu8(XQ$xjT+&AQ=54RLM*=2#DJ7EPTn`029wuWpQLGYjJ#gp+P}|DH>D zGwJ60Cl7D`=S|qkFYYl7C#B@PG8t_KcXS4vR>{D)E~9hdmVcqX$*+R&%s(Y9Y=8G* zpS%W)!8$+dASOoc`W7a@AseJN)~4|kBGx4ohr^GZI;e{a`ru#wM|^c{SGcnjVpSw0 zR6pEXGda>eWt#Vkw5s4JDs|}%QKl2#Klm)<8pyQ9BhTN~3(%ITwV57fhLnnNp^!y&MJavOKot;ep3{atqSXU7)ei6TJr zjMmX*+*@#!o!{`(Y9sOsX#u5{+u8pBLO*xZzF8&WxXy=NE<6)U^i2^YlmlRInx+-} zdia28cUQ0Ao0d553?nnxM8a9G(P1`5B!7cFIUF;Tzc-fO(cYF(KG<7+@!l}9hNk3# zNKK`#zdXL!anj=Mz3ssbK{sYe1Mj?`u#Z~{e;8gMdUg+?DlgsJK0U$-= zeyHQ@(|^JAlF$~+mELv23xzguUqCl>OVBxxZU8cLrPutZ z4kCzznFjgHB83g(ai6Tz^yg-<*fFL;-j`jg#nx*EbY-NOCab(fxyGAGWscEhq?^-wcYhUIAGD zQ%yQ#TE;;azGWV+LD(}IY?f;(#Z5-1^45#8`##u&;^}ISQY3`;US)$c&z~VBK8Xeu z)C<5sO#8o>^vyGKg-Nph47UC)fv2Bmp&W?StODfE&mq!8cWZB9*fwDiFv3y$c1^Ap z3{Fo*o?Iu7z*&7tu=bej5UbYiQqh040?QhOFstva1hU31&Z;_Iv&X+q$n_<;9YMH( zHJ|=7)USU=K3eoS8m9hd-uHT*=Np;-X?F{w4dFFw=D)m~_Co+Bar&4X(J))DgI|SF zf09~=v&J?kyhrR}_Wu2@kM9&5y3YG58bTu6b~4iSUz+?FT!`}j$%WAVmnQ!|cp+E> zEfWXD^XqEeZdyTR1`RNGz6=v2V}>E!hH1Q7L+*q<{ZD=qjsYi%h6rFHIZ8Y`!TQfnE=#q@92M|k zaX4Cj)ocOeo*adL$UR>}uF)v}|CRy&o|G$4Pd^*)ijG78Z&BhEjXU4sWD1roUUM6 z&TtigML$pVzO1Ws(feS&L+gEB9xM12_}a}LnJC(5Zhy>O+eSbJi#LgPtiQ%)XG;)9 z?uEc7pyz4^csbBD71(Tpl9&bRr7tgcfZX<$@Q)s{r6*#amgBU2O?<%gD z)gq}%e$)qap6V%pz4IDiyjYgE1Zn`+q0q*2Q~R3k@;q0WxUIeN2w=q8kF9BZAD@lx zG>T@hU7JvxtfrO%6&CKuz<|p0jt{#{V~^7g$|eRa?xe;)xM4}P-GHXI=@A~o#Kdc$ zk|ps%;c1*ET@n<3rYYH~I+2q|8lRo_l|$Y+pN|MYp9_X*`Cq?11=7{+D`4E~{X%5* z)*B2qjWY2R&%+6c%QX+Iha3Pe+yJPEsnV;3m2C5!SIqDn&!BmeS#1ERs-}v1(ue3j zaha>~X)h1>@b+bjHBDFqqCch>{sAF_8xXqd0-lKHpA(5Q6d(j0K=yoFi+mP1@$^Cc$eXZW2sjaJUxF%6@Lv>#VM4Jp=RdXTM2Hwi79d{g%` zff%5_c6&cTt<2~8nJ^|fYNxkJqMmN=e9fF@0StuPyhh>$I5LIj^Rm;A<|>aqNJHAT zDBC1Ick$r>D*Q zn<7CeS>RiPs?+Sq$Z}1)nn<1l3bBWUg$1?Vgjgpu>Q$U3Q`y*#_tn`(MW1Nc3n&qP zZxlr|X(eou!#dk$@{^WLyB%6#NgkD2qqY-_ z5#kDjb0-*vGQrTco6Ny znw*59($(b!3OR6v(Fwpf_Oldu`3qb`DzLnXJ$H|;0`+hU5pM1q2s3#M(j)o;-*bdw zxf(d1AAm~Aye*iFD1fLLrjU@#W#B8R;aIi))iFOi?%Bib%2=^}Q8t{P6YB^Yhhb2O zHM42&UFoqs{t>7htimmdZ8Qtm8`#aSNR7CfFSc#YbTg~aerI-Ukv1O(OnUtO=0{@S zcD)LA}KysOSSIy>B^)DPN!@?NmKB$)Yw3%xv^ZO}LKcs@=gcXTA^{3q}L zNASFlrRHY)zt#d%=zN5Ewv(86;4R7(BkYGGhwv|KF!i!`T=#+b{SVKUcE;#AK)QP2 zgR!Z0u4Vl7E%~dt99mCYLT69|0^JRei9TZa4>?xNzL^TtbD2k-8y$V=Zl$*Z>?+Jc z_xdP5cir~gz1q3DX#U}cv@?m|b$IudD9sXZH4Ot)J(9AvGp%+!{uD2oWdxygsZ#syKV%Je;A!vciy4494Y*D; z(+F=B^WzdxepcyZh&3oc>+>E#5o6h9h!Q4zp;d3o7lk0o2?1Ojg&a@p+%^D5sYRS- zAapmv#)Dzk;_K%JET6JCz=NFV^CBU~TR@)pNX_C~3cO?Z+tMv~dlT2C3+I8wHzf-? zBea+rIHI_%IjjYSk}=LX=dr2l*mZQD4{{{$98 zm^94a6o+QHHGib};bJYlZrmqWVkih8%~CqUe%Kn9DyFMJh*z~+_MP}r?%^fI!WO7$;ueRnDaa-H~;H zMS;FwcEqEvEmwa73LXu?I<3+HX z9^Z?2zbUVprF7g^9{SN{O8v6K^u(X=S+@R||ML=-ev!PXBdpKbVhg8~81 z%_gMZJdESgw5l38H#N(r6mm3^(a>3YB%Mpd?gcY4)9ml7v@9n2nd&@gE{ZE)AU&N! zDdy#oM#+WXwv@^O6PbSdz);t3{9`yDR_os5)qiplvTH||)-j!YAfM%|@O!ZGi1z#k z`lU2cWfR?;0jHS(kJCA#x^gB~BpA$dC}Q1;OGK7P&M1R6m zE2XKjggT;Ou?dBIw3$kEwb}?eeykpbZ~jn*^-kQX&#c*JAy7c%Lahi;0@?B3q0wTH z3)?CXEFjfUX8 zmAy)-Z}>yCZnh%tgF-#ks*Fa^-y~{qF%o99Ugr?abOElMK|r4m={3Kl0Tdjes$7>QvkArp*oxyL{Y@Rno0SAUcOQK-Q^=hQTW~fxO zE9jjv|0kGIkd(U_ zK6$kDqt0C165hsq<1FgOH`#uflWdK(02$!#v3aP}z#)d9kMptoVH3#geE_~)U>7-- zzs{xnh;$!OGyWuRVY&!^kx+aKE8~@4t%1IGf;%v!LiXO(3xmiyrDk+I>Ixv~WGs1! zN}ih`E)j)=CsYJVf~yA9j-oGiSAIB5kg3>f0IX!E=pSazi&B9iYJ@bvTjaC2=sp*< z?SNh8!o33CAf~hcp%6rsUSB@?V&_-n%$x+N<~u5F45EO@2ji$rOa6Xdb~-h8X(EdC zU4mp^nzW*dkmj)=+|I?^c|6~A&PTEnv);3+SYLr`XoOxm=T^`+!BP9c1wZ@8n?X^< zTtRgB$7|A?tfF~a@Sz>yz}#@^hXRiyLemAzUftJ5`sUF|5nkOW3B#Bl z1C&=-BN>X)m;(WVv_D{fL(ON8398z3G&lhyU$u7MR+%Si;$bqw;zkvc;ffF?`#Nyj z)Y~myrUeiNq>h%8AmK2GLVub@P*!VaFAhdyb?=_7cTk=uO78R?QMy1q-#B$6mS@#|4L)0xOYb zKR!q-BW^5<Y?N@fuVzUy7or~ihI&w-qscbOptaWDMmY<@~ z?rU;-zw!%|9>TM2m)yw-qnF+VG(xTQ3>__xrqhv9w9|Q%8UoTWl8nKyBe|(bKtNR&UbNO%Xq7VL>&-gK+K(nZmBUy45Hcz-N zrh^I6?RZF%Ze&8))1LKEe79kGxJplY0=w86h0?+X@H=P0av0qRq_ob9{!o_sV3Z&s z>3flIW}J8bj6#A6#j@keNhtpK`tBs2mWc#cKTk*~rm=8-Tdx5-=SJ|)@3pwbDm@a| zVItU7aa7?pBL;s7Om%!w^yl8b0Nm-19ndki_mm66)gk3oFvr@Ur~bk$IJd7eHe*M7X z?dwl`+LzxvWFJs1_a;sp%6YsXo8@G_9!rFO1Q$d=b1+9Xb1s%_&XY-LbNu{~O-Ko5S{@ z_fEwN@SjzKBi-ia??v9q?LcRTub_ud9K1|7O9?|<(JVGcEv(zLcdvB0zp>D&b-Gl@ zS~S`D8wp@$#$P2O*rK6`D`vTsm-D}9WwOIngoJ@u;Buit=oXB_ zZY(h@CUK>y?k9EqemSe8NYIRUZ@HR=eTTCh>xI^#^;aAQxJ%?b358;1J(H7Nhy+!g z0%qES&D+vFFWosdJcBswEXghh7c%Ei^r`qc$bJpmUw1u?GR@WU871qk!Y<9WE8ad~ zBH_s7K1Mi_vB+gRVCtg%(Ifby#yKGcsO4+n>b;xf>@1roQ41hb6*oLje~E=+&^ z8;FQdqbH-%@>Ei$8J>xskT=I0Y~-^GZ$+z5lMDlVt!Y>gnZZ4UBZbC+z|6gob9)t`1JHgoz+=J5NS(W9 z2|##Ld`8D@tFq5%8^C~akOfr^pQ%w1lo^95IWHWK@0^1Fcr=kq}VE&7n`7G_cWl*A;Hz-Y?Qg*5Xu?pfRg$8{ae}zI4H0QDyf%15J z)~EIapyR7A`x>49nRxU$421vU=pHB_%Ei95X}->-k=x@~#nP^Y$|xT&>!;DvxrENf zQTPQ-tGBE%(d#82a&U=EF=gcV9i$m!H#y=6qEV!wp2`+l60D}*-yaemGEnmv2REaH z#`#gBY~9gVc<~_uuno*2H6^qCvqj6KF-%Af}KJ2D~vKDNb+GGs>to#Y1jClqNw!p3$3{$grP@uqZl9}Ry;6(L%pefY z`aHcXwMkn|%H=F5zMOyIPc3oT$|TdCFFb_b0>lD$UpzGsN<89H6fAg%tzo>*b=hnA ziu(ZPVV7~H8|_28y^nE?$?K&ukO2x~wP}OXg;^j((XGlcy6G3zge`Zed(U9(hu`ny zY+ZMW(T{^aP{_wg8$O5_;TQo;483;6B9Oc6OXBIjDnU0l%aSYV~6E%{TRQGNR1Usu}>V=MA3B|-9MZ{sKzzOB{YPpHFrWzo1}XE{Dx zs^U?J;~ylFT%6xR)`-2P8r-TL6lDaSb>T7~Hd9{8(UX{sxrQ@n(fP1yQMTzILIjRf zsp;%>jQF!CdnZ2&rXK3s@2i~g?@Gq>xB6Q@cW;O)rVOTGLCa!(t)lbraopJ2hpvRj zYk46qale=&u-l<18@~*E?^tqmV(Wf3SlnFr8krn#w=8qgMy9>B9ZsH>APl#tw}ygM zBp#(>m!T}zZt;<|bJw&dlL0o_?;tu_*kFGf&B_2ZWnZwkAXovYx;&1Ua{^&YfAK_R zJbFyWA)+1>i96SOQDX=g{T*9FUt*a_1w>u|`NFmE63%+Pk@qZp8m*l*<4A<@_1J|LZ#PY?-~L^F2j=%W*CzAbu{mIGlPy4K#!W6%|9? z2<@g5Fn&I3#w21A9E2PG9klR$+z|P-gN4VZ(+F%t!GSLD3Kg3q4^h7K00_Vr#(=GD zkk{44k>6QqRFmD)>IX?GNz-Al=CaHkQ*- z#S@r6K=Mk@X;jnnq}lcN%7bnnWBRb1Cp_Eh$v0PeEo09fU}h^qOr34f%C0+L4}XaH z0|=>$`zg#mnJ~lgM342wqgQ(qjoM;QoCfy4P(fsY`~%3E4X;D5;GaPKp#ccBzc33n zx*y@bLtwRJugMw|Zd#pq9TAyZ|86pfp4%SC!Peio5G)%q6HF@(jVmT8L9a6w^70sabD zO1~%tvhR1^(=I?S?wOe2dFu#hv-1&Ei9LbsuBsw?)!TY7cVC=EtSzE1(IO@xIL1EN z^)0l$p1s~G_6h%fEdF|HqPZ57gB|fpSio=j?1w(~_Dv_bDRgfiGnjM%As19tR19mP zrn>r_dIja7b@}1*!;67Ap#h1IJWkCMPjM#UCrBF?tkW6~I>K5Ci#|RwCW~GGnWQnC zg;X(M@$N;2KM2zPlI#_|Jj6V}U0iEU@0n)-{lcvqHOpO*>v($iMsbooQDIt0s^>9q zWmUhPBRVg*5X|7~ZepP-f_w~o)=$}0Vb8#ZFNy-JohcqV7uD}HogttKqUc0~0lDPa z=%`vi2s6f;79{i+!pRTcluQCq^0_JSiP!0G`vtSSK zTh?g=w^}H{dl+g9w8AeC?a;F8ASNC>2LkqQUAtiB{&jI@AeSEb<)1k_>e}i7t?Ta| zs>qAB3pPPmT8-kcHWPx(Ga^QtkUMctOMzLt3|9ZgTHgsdc_+hys64FuwHCS| zs_Vt+K_MY(iZ@Wz=Mk%ENNfXuQMGTew_XPOu9i|Wz;0d;2xCCgFFNlx&2J*=y5`g4 z0-4)fl0`}WMsXFHTxuu=LV1iB3nJH!6%_TSyH{F^V3~{7RlQTBjA$JCkdI z^`@uy#o18}Z6T4e;Ad~NJ^zl}0ZFuvwFrC}01x$Fy$30IO?r2i{qzkY+Om{GZPz)> zDr1tqGs4Go-=v(}-Pd`P`gH#9ks5G=KbHML#A4$EA=Y4zDq1ImP%yuC9ybU&xr`Lr z$Yb%=(B1(_=$tDm-A*mqN~*vI_)7ly2Nk52XmwDe^V6~B5*pVf0@P;|V+sTukGJ5s z2`>zVVj)0;_Gu-v-{GF8WWaBxn{jZP013s#u#k0l2jL^!l6q)En;y2##WAq&m-rQN@t_fx z%QZqtUfaJJ{WpPhbXS`Tq11K)fasYWmHSrtC7GN^4oFG9f8dZq?K$E^=vjdL8=;~G zqx0=`t0?gQegLH^$iZrSv6YEX)(xu5%s7Vu-Om`F7l$c~yNf$zB<=U4mG9h}y@2Ou4ahrT2maFQsO{6^jLwJFiuDw%=0f zEnArd-W7$d?R0PrLfM|rZlPwn?M15wZGk7e5!{7ZL^^~mEWxgRH*wz(k)`Yi7plIG zxVFwfv8FCQ=u=KQKmLtDK@r(qbg^TfW*n^U7w<6%%on6J!igJzh5p4vO)yc|{V5Jy zr1o)1|EtlOCgKO=IZskWn`jBeDGgo{-K>9gKu{~Jwd*=SsAyYi*O+%fFZux71w`{d zYqaE%d~z!Q@^$JaoTAL5_1x4`u*-T4%2qtr@Z-XM157?ngkZA>K#u+q5F}e%nLp9! z!=K;%ba}dYuwAhDrs+5JTofY`&QLCk;q3K;!uO%M_Hels`LAwkm`I}J#Zmji_v!ZJ z)YJvHGcYP}8WHkXD*&MNhzB{s0_1#`j3JLX!UODhqo{bvC^Wm3!Y|I|@x0e;zK~Qe zV)(+Wvru$f6S@tAEQxZ5$f_AIwFt_?(9hTS66Wn9QM0PTE1_i{M4hJ_m=HY%@IbB` z67lbbNK*GYk1U~`jTqXQ)q*+nM2izmBOvF!W2bACrbs0qI;fdNIHhO|~GYOv{e z9YaK$J-1tYq^|RXj3+=)i5JSirp-IJ>eTYSL90K^6JhQP+<@Y(II+%-CCB(jHKYtA zEZQ-HMn5B=pdCNVHlrRSY!N(taj%;a(JCbReuit89Ur@!{f_J2AgDlXY<+@8@4wyO zD`GW};@-nv^TI4jCUKrLOtcxG6U2SC>2L6n?Ao)U_;9rwBqAeifDOGG%+HNgXc}SJ zf5EX<=5jdg&QFd-< zL*ggbn=h4r8pDVI(>m)X3|6?E1f372mOKQxB<~&F=T4Qa2AllHCo?-&7c3ZIv>%ElhVws;D9<9o_;p2+MLRvWw z#RAV?#p?>}`jyOsRe&BHI~i@TEg_UEQZ(mM7^rZspPbJ%Stc?eHAu4jAbpS|k8*^U2inG=cMOf}N~#cSy)N8^2yqJ@9) z*IJ5iVW>{|kO3tvK8NE1Vq=@$`x$#~fk@P^um;PuG?ilo|P9ZdZd0yn-J59o?s zCrE#PZVed5Ws2Vt8GbV$^@c#cCr)L*q!Q7-swdiGwJx236zBJg*A`lUV%>Fc z@OC|A<1clSe2bmLobNP(GSp|e*3@=48q&>2shH1&hIOCxz3{Y2E>J#psKFKN5)t;J zT|YKYt?UyNkU7)QFsV2%V)W$b>0^Z2zMdl8Xj)y(Qw)0iocVC4WambWYKe5)@Ga!o zq(ZqaJ6Ju~X+v^roC?yT`t~t9K6`4vcu$Lg-U_pPFZtkWpMy=G8nfQReCzkX5lqFN zqHb<*G9OKhr_CLcc{F0K6N=E7QiMDNAdk`12<_!S0d6DT%UN;tV;M4kB|>%f=2Vxg zp9K$d^QAcQOVJUwUc)iutK{3UhvZ$#W~l=^cY2=GESpjxk8k`{U$~P<@abIG`-euk z8vi%mEZ1o4n6D(_={liO5V`QA<(mBoDDzK#Ei^g?WhARp3GB(Vt6urX4fsq}o7$Vb z%1(>B>t2dR(~hzyQrP#5C2|r)Lw-jwzj4v?e@`~@l?l6gH@?3~ds%&@aD7L|3r_mYZuTHjRclDkap^Rj*kK4x-jb4MX zBN+3ckMN8oOc+k5uXMDFN=Nf*2PiPe6&7+lN0~TOG~{M-J!Kaa&Wf1$RCZW;`fQ6{ z6SR0Y56{}3+><%4d=Ia~OaTU3(U1)L4wve@uNebp(d0qU4Azpok8LS|xSjbTH}+MHh9!Bd3tXW>k&2eu_g?+?i% z*|&M$kFVLomsce}g|LWag2;9`_%=1ER)IReMGpoHMf`zxgVO;^sBEfKH3wg7Bw07D zX|G=6F&)Ft_GkglD8~9{o9kJr3>@v`ahGmKIx%9!dN1fqHUqg;2aBWaI-!H2Z3>~^ zn=9oeO$D3EoF+~A35-uP%{dL0P05hj6PhcRb8r6|vPWKFa+E~Y;6V=NRyAjhcAK|| zz-$knb(>!l4Pr~K93MNj{}yv@K0{zS7$@#Hu(4YbWmoUV9U`TL*IoI$yCKI@O-*3% z*uu54&-T4}>N{xkvT1F~`1OzY<6SiIyA8K1ZQN}?L*{0L-=T*mD1|6cMo<_{+Xged zcIJw63SrItAlA+EMQYrYWTr{Qjs7QBO6yO97}?3vj=LhQKN(82h@{Hi$|jYBl?mG6 z@npsYr+Wsf3#e%1G(I^i>P$Y=RDfuDsZC+bKKyiEi3y9d`|GY)c5rGO5!d~6BEl9z z0&%vfnCih`N*cQW0_q|qVs%*&?`UF@pr# z)aD?5qht@s-aK_AVMvrTMm#Qcq}re<>~4kA0}~?gqGi)lt9>1!`}vvpJJ{`@pZG%z z8>mKqS`6dI21@A|810v_$vo3kxujEUh943r66>!Ry%;b0DHY_V*sfpPRJ32d7^20D zk1aIim0dzN^__DvciR0g##FP^k=h~A)st5wJ$j{A>aOdCWM#C0hes^z~)^5tx-(qWnjyQ-N{o}Tv zdFlZxC8b=x#iZ$-!^%F_3`PI!sv(~7TqQ_(q1>b+L&No$n5^F-VL}@g{ z$=T}R+BwdlYuCk_hq-qe78elwsuumKgfQd`&nkS$QV*ztgg|+zFiUHKb}yB z=of}h&WumUk35H#!B1p=eR6LhcNyBNwB`>jV}#X~_T z3`&Y6n{9-rd-j6a3tY!Cr&yMjR!6KtebBKO8FB8%ADN}j91n?VdNH|@%qjWd<})#zz8lU% z)MN(r@!1v=%zW?TKv`v<^?6%8+#H;m@3oP6EAfn|6>>Mnk4{WF%rq3_wU08)8y&c3 zF`fF}@z@ekH23cxkyPCkPD^IeICVK}+0r(#x=8aIm7}fr0F^xJt?>;|>K7$lkr-#h zpJd)1;<$gn|Mf{S#GViXQ$K@AWj|Z-VFha0T~soRz@FkCfg;P+CxjQR_uc%hll0e( z;&>}E_XBaYXgzz~$jK&6FNxW<9Smsv*-@mB~c~WguaL0qK~XX;*xr z-=PLoRA+03QHyz`V(Xr3CY#A}9fq5?s4W{mzQjm6O!P)oJPUuB_x@1ftg=VRGhz?i zb{&i)XxUR}*g3dUH{#wq#a90L^w&Iu7Y%BZDSv4k2 z!)$(^&hSN5KAFsA@;KxUhh*H3(*DdZi~IoXX&&eJ7Ba_I9!it+PzOi!E^;Cav0aOx zn$oZ`mwa9EH4D%z?O|}k+-XBvD8_5Z>m z8I}YZMNmH>MCwEsJo+0o%29F49FsgcdwCLs!M)I~>e9+F(01mYzNH-l@O-{SzoZ^Y zEI5A)##Q8~;)Xo31|hP>+v4i2P`%T7OH>V&cpvWH%a^N@&xj3S-q8kMEBnk-zp#F& z^zXx^m4%q6Vjp#6dk%_jAIaz~Qe#>m4Kr@eaaP^e@p`?$^nbATo>5UX-MZ)^35WuM z1Vw_PU?2*Tp;1IciAv6jNCpuQ$sj5U0w%K1N|r1+g9HJ|Ip>^XH=zTkR-^Ct?Q{3O z=g%GY>>I}D;dozq^;)&6W>w9a&wQTg+%2I90%l;Qs!vdRN|m04EpqL(pnheUze=h?5m+P-)dR(0!e{`9*g zmIF@k38F8fz29>pT3&-1p}NK9&PD}_9P%Sa`FJV?ylCjm2Xt1|}_NYFo!WMZv z8d&Bsmk&H{ir6P?`3wfkKdK{Sm5#mD_liY4v59+|5H;N+@p>V2mW|TnEy&gzIT1f> zFa27q`tmN%YN+igW|K{S@4Q(N$5Rg6ElfNo{PH`qP57QE%l4i1BDh4zgr^fobfobG zmV#r)R&t}EPMNJ-<@XuqhRiegOrlL5yk$lYxhuD*LBTX0Idcg{?o;`Hvj(?hE~h-H2)%xMSn7zNa1yyxuwj@P`T z%9!-?K2?6esJmxU_z<6HtBQI`!HHRPwFnQp&&*6X349!diMvAh!L`I7oy9l&!VQ_) zKTAD~3Nprp8N;a~qr@q1ev!bRW3@!?X=Fdp|7ltJ)$WHb3eZA+o$iQ{d=G6i`bFhQ3?hRBu=idtq4U2grOtfL5n*t!K=UI zh2;stfcoll!P4V*&zv6!CH6YOl{HXN0#QpATkF@;nP*J(bPNgs!-`6dU{PrQ>jo(5|mB zYvvn;#?_TPQo54!KN~Jk^04d)ImCOGe7CSfE>L_eP#-kk8svsm0)P@PUxQmUkatVI zTpicmPE>Nf?xbN}5YL&@@>*xpct$D|e_W3D278h2SI^(?)xNvmK`v&nB@nQ^fO(@IC-6(}zE1Y3v{vf@R4~xub&I)7DSc6{A}-03(Vq3rple}F zm(0`v+-A^fB1)4|Q7!d2h77ie93&{C!K)i-qR+Q1`L?CLjZLf$nHOJg@$eosLDweh z(eURU!%KG_UdK53r9EQ1mdi6}E`>RyPV#UN-JBSiwe1VPKnavZawD%$CrKOCUB|o& zp|`!vp04B7TOUK9Qf7Z8rDY(mc$7QeDto4r*E@Z8k*Uh8{tbFyYpbYP&Y=J@ z)hRu;kRCElLCZ7rgXUBH9jn8p3Yg_z5r<8GM5?Au_n#cI(4}ut$MpY76`y-Y-Dc`? z{Wj0^4=~oIcO*k=KBF7UedeBjVoUTYPaw4v2Py{X2{B>3&H!qyxTDkF$lz4_QK$2e z_2y$sVguOJN_9TK(@W`pbu`P8o}K*I!_Ai~m*}wLx!e~5_pjY4@4t70K(NdC^Mx#(tk+)G z;rqyb8h{S%?Nj+Swz_qdDq4r$`hRLRzxV%b&91sZC(F#`UHey2%7SFoMwYVl1E;Y{ z-KE*)?_6fpmoGC(ppV{{YLSLnyYuvnKxVkpGU;D3%vA(5Ag}lTM_2!sI?x(VUE%x& zQ1Upp+mA*@XY;d~=V82;gBS(JycX-Dn*HGb)2Es1Av@(DUi{st+->iCc0G3(<@v)n zR1!fP_DIhm5&>=rPFHQRsj7#OnzwKqkM0s}O)h*JQ)o=d2(VEv6-H_uJ_t_BRfp3p zfMPc9N0=FAS2S@Xze`2(JHP=IGD;Rx7ZniuA0*bwwz^?OYN1|$?_7CTHv}TGJunQR zW#Ay6U&pAQ0wZ2<1nk2DRmm0Md{AsL1w`ALc7#CrSCA2oyJMTv$Yqt^qqXH+3|KBb zWv*M7AH8D{ZKd(gh6Rkr$jU&-mV74|f!{rPu>TMQ(iVY?tp3+B_tJ5y0pNF&=7WySLNJaPFKV%IpVYZ1 zgR^*8_*JvbL5^PO{e2<372T!Ri6+&<0M?r>>^@8VzE#RjY3a1y zgp-a_$gN^nT)YAss%@m}3BuzHqr$~Ew5^y0{pS4H+!|D(9LR2rr7DGe|MyUGk5WF9w1aA4utvvG_GMKS)50B~A$l&HWD60tMR-RiR|U!!5o z-;AO*s=rTjCD0|433N#y-6`l91r_Awo&V?o;_mwofSEZs|Gt!b6A#PD!~D@bFEEK) z1H^=huz*N*-(jpQ;;Px5uTyVMa02~jS83uR7(kmiq0K9O?NG0GvRwjZG%)PA{=pb; za?rpr=>?}EIASXh?zA(1^h)}BomA>H%12)~xl|+gsEhB&K^^&2FHS3nu8`wf9K0Ny zgu810i#{?0-AN=46A;fe>g>=YQ07_#3WJd|NM-250W{Q|!J+o7wj~9}xte~t`L~%P zViMIM;#z{i!3=LF$qsQhS|Wb}{b;e|uu<8=fp&XGmy9wP7{aVO9{k`l=7d{y7ea0F zlCwIgab7-R3Js7A(|R1cdALee!@nnNZLsw8J!|WhYM%L21kK-7hXPJbpiH|>EM~3} z{&Dwgu3<6E1C_acLz}PQ4wWNZ_k4}KsUj~wpUeo(#yF4(Q;QUMaO26C)X#?mnQVl< zOJ{=OY`ji}HA)YHa|Mn4Z3{;VZWL5J2a>S3IgVmj;kUxjp;qN0EOne^4l*Dw$9{mc zs($`4lZI17bXCNku26QG|9+wfB`ZhIt_4xOAU)^L+m)mevzX=TFaH7NERmD`HoCIj zrHVM-+lB$fpjXz4Iso;u@-#iS%Jxo6kK_}R5aXe`v)U+%uUyF%LA5gFT-SRxzB%7_ z(KbDIl+ph+K=s?Y0rDOv{J{{cXMW}qHfLD#joJRDu@v2cB}3Gje}TI3a*5%0iPWo= zba=j`E7AvBoR!ngUddizc}Cpf^~2QPNJDpQ2tY6%_bmN`+6x%6Km6*f64Q^?{z0*1Nza^x-NK7jdOFQ}aH{n$ z(ii8yq3i%KtR8Oc<=V30*e}YAp^ z!)~z2(bWmUiuRzjmu#5&1_mN8roS{#AMcu*4m1aT4U=0Z|IR~zHdDfmX4Tb!E6x`Po&ekoQd$n+AD(fo5pVhzr5pLSO2H(bgXf0hjDG~>wZ{*q2=Kpzy87n zpa0}Y1CS#@b=J|Wx`RV8(s8B-QHf7XCAKmeK17gqe zBzO8dWJ(1eQ*r1+1H?KX8LR#inNTGyi4n4MKP=8r{p(Pc{`XKuO8TUhB^SGD7~POq zeoIvFQE9qQlG2(+NZHl9hVE^`&giO3i~R^^m-|zP1!DRV`92#OQr8(vVBR})^2{d1rd_(#0+*-uW-AP{(ZWF}~3Q@US+(ChgY{%bAiwJ}gxQZ&5S zbo}}^&yt^^=*xarR&qtake~NS*^5~RaGy~TDE&oeW(#@uY0sl z#GYpX=y6E^8BHZvMw1Z z0+nmq8KByKnTs0=XHQR-ip-?gjv!1kX4dxU+Z|h-}v8H_fvae{-yy5PEP{ zh(C^&k^e|{vaH+r^Sw9hrFzt@ z)He0!57bR_&%GD(Z;pE}%cD8|ut4wLm#=ce7aq3DM{9V+<5?D{@wJ@J+9Tr1tWOnj z)$Crtpz}uRq&sDnriLskh9)ckzL~xAamIYbrJWBkMO&p6(rxJ3_O5?sZjYos$x5Ts z`dD;c(v#CA~HfiWg4%eM)qH~M9YB0|Xa{2YlwMp;wy=T?>+Fj!RvrDy7Tpv|w z9VM}_xXOPHZuEs1r^%~9ia!GUD7h?e2k)gNb57p5DmeYB&|EZuee!z0-kv?eG1A3h zv%1$GE#6khFgRD;dt=bt_NhkJvf{o}t7Npxo^A+KA(52(ZL@2df^P2Y8NMD~x+>zr zd#_K(zSC9QC+0#SA1RGHvWbiB4JtZ2zhK|ZzcQD-6!tylT%Z)Uvdd?09!5j^`uAmA zsV^tY$4U>13v`S#)E5-2IUe;tt;w`R4rpaI2*Htj4s*n0S1NFgj=^S$5b zwg~}gYSyYr2ucaiTa=kh5tU@dC{XXKZZ=X=+_z^pvgzOoWxOQbuE@lQK4Fbgtox*) zQtnLL;l`BQRA^N8UOnr=d-SQS$?yKooFK}ar)tRe1N-iPZE;g50E(O8SKhPyDEfAb zmO6Zqkr1N|v$afkYH|M9WGC63{vRhclTot$0+B`JPx~82EA$G|IGqB{W$I)PXqKU- z&#hkM5%f~c8KTLt3ZhK#{FU{5amKoHF0YMotd|gbFOw|60-6=`R(JvSGlyr=I}IED z^8%D6fV%xl@WD#O`Cl==_$LES7y4%o3+J2=NtJxQT~z$tEV+mGvXoOU$b_-En^U9k zdHL2F=W2@Wl)&3~^!&A3zTpkgZq1_`SUg{@Yf4D8ZE{#}kZ^(yjo?etH;I z2l_L1A8BQmM?2mSB~ki`tyG_6@cbg^jhcM*PT+<3^7myu@udX|guk5#TYq66IvjP) zDH~ONmCv$-FRl}cd~mn6U1lrG$r8z1(b6TeRalq38Q*}mq?hHHI;ZY+2MFrix?I3S z7eRoa^ow4VYw)d|Rf*Oyxs|2y<-J*x%a5|4&lT-0y*q>M)A|D+7pVY*k{xDzPuu|~ zSHQ}?B6M&k99=9x1HxxR4|R0!J;DIUv3HZ|u3V=(m+L1nnu#ah?LH9DK=!eOU*Ww7 z0HC??EPd35I4QvKx z?>cI@eT~kr51YCgzx{%`z^K26^SAdP=Dlsb0;ajLGtrZ;nFIh!1y4pw zb?5u-SjExvt#V=psrn$6020KOu6*A}M1_d01Q^|;>D%l|8lyJW@XYPKvb4MG(cYJd zdctd*EVroh=WlVFZTW1OGYW}m9T@o@CO05{x^r4N`IO3w?Z~V5ew4olvOnj2KD=Jt zf91?O=5gXeYhbE=s4gjgQ9pM9W2+;AOzHB|jHvCj1M=BV8TPHx|X zLMD}acS6pNimKdOk|! zCX+)9C?sOapM2YN+KpU0#dLX%OWNReB@5MOO?lnhWB;IY@AYjPHE%zj`8-|LpnuA8 z(wq%wqE3m_WE^FwZ}mtn(tL1X;wPptL%3A%(r>LO5u%&+Y=tkZ-;q8&_EpU|dw}fS z3)A_j)n_gORJLC@`93N2&-vlIc4gjDST}X`IZ75s7RNB!Q^9>R|P}dy&fLCJ-QYg$-aL^gibp+4>4#iI?%D_%h}XsXAoe5d_bDr zGepg2yJyKaan6D7CNHrdkbXViRQ0tzf&f$Z6Zl1YEBo6b{38N=QPBHT*zP;Cd!Yi(%XIV^7 zPm-bcalpq=lqXPNwUKUFy6aywls{7qN)*+uL>INym2V`Tt18?}R@`;5 zrnZa36tSqa@Ie+ngffsCg-mA%jdC& z2|x~yED?NN%Xz^F{QU69 zSbkSN!Y$XcrTS{f)-(HM6C-*aT9h}VtX)}~(loI%Z z#BTtir3la<8=IEO>`W`VDv4UY)u|$Yn9MUT2eZm$+nxa>DwksIVt)~Q;PWw`zfCnv z_0KwYnJW?liF&1Itz$M}?JQS6D(&7*D@m6~m`nNK3%3K{(}+$xUw}W^O0IrcBxK~(`5zX?z;Vg6sADweXArv4%%uA9mWW$OuFtE-e&cB`Uzv!!;&9+4^gE55-g%K4*vX;k%I74HM{>BwPO5FYH{Ach>||M73?9-kW4Z3 zmh&(}bCvYmXYrGA|AZVq)4)ON(`1Lq?EjZnx%?Ay_>YOC{|$@>tb>s3p4iUHP`JRS|}a3w)dWHAL4%oIccF+I$W50C^TeFLbvkqVT7 zYJm_4ipmfOIeCBS5ipB-g}y4k&q)82r%XRd2uRHf652KXPrHU}3u9EFHh^NOEu8oHmMvDS zNIXxfb(9d5`kxp}fJ{*^Xc{7o9lLWSW17AS)n|+-ashHUM+ECG_;4x&Ybda}CJb7{ z2XzAxvNSlt=l!%11c^0!^0A;Sa4KLrj2#?jl@NZ@BqM%+-SR{LW>Q=f!n*<|wt-q6 z$nCk-XAu8v*g+wGHp)7cLEAvx_D3D#A_z@t0cAvogfj4ME%iq%eOY8Yihx*)SE7Kf zDGW;Ks{=vWd!P_!+3i!$eRR8FKFA;_TGtJTURff;Pvqdrqbcg~xArD(L)O*x{)Ddk zck~Sq&;YS(H=!+dFD(mH4n%PziIF~8AOCr6CdT2{DPJj1;*W24wTxWNdOADf?8)mv zg(ie=GvKFj6phVOHjKeShYj79J@s&gKCJ!tZSp$v#2U;Qix7^lS)2krkomYJis7;; zc6UQ&q1&rv3TWqL+LbJD$rCdlWwk#H@Kv2Vq=^xjcAxKZ$njU~#vKefbt!v3bp&No zNq39@EsP_{jdUI8foZ^8Gk#O#LEC8Yt3mY{%QAWOT5_@z@;|92{dT|71iaYicr&=q zArVjWLdfX!sh>V^!oo7oPu;4I6jpzC^HqVr#XIFP;fE{{s~3&9I&QUDsFC~>vyHBu zp7v6CsuEZoh0}CfxnGJ-9n4R|Td$?&db6|++*z-oDRpd<7JcguO2=Ms zm_L%FdgJj|=qUI&oqR*2-CO;uffKSYyc6@>IhF{v)L|f-fRqjVdU2cahtKWzE`WGg z0+UqCX}WXf^s9T*b-N6c=1yEQroE_>fzi!*q)4Y)SW0F%5Tb|QG|{k>hAyiD_{07g zYPyhIX$0T8_ykNe=N-qMR87yNv^Mz>i5)%2$CFNwgiH-0Q~Me(d#osjQREgIk?hjF z#o9CyAFFb@JPKmZO5XtR5aBh&Gn zG0U)dCq?Yjo7nw!&NuCjr~r42(>-Dy;sk(=O767z#f^F$_uQ6>HF~-J^*n795=nEx z85GgHAsVBK#Az8}=OWEx6+5qZsk2=h{h`Ooummu}jWq5tHfRm7`eOGM*d?DW&(B(q zlsJ#bFANQT3pXsGl%y{S%3SFpj?j8#c~X`Le6qk8ZT`rpFr7XDu~x3?*1v zG~LjdFYKIio}08Mvo04M^AHNH8Et$()IOF(J;QB3Dn}#TovTjcvsis$?Gw2VT=J9H z874%IrjG2%WI-m{bX>3zKxFrh*7~GrJpa_l>`DqL2PBE!)`T=pO7nBS>C6~`RSLU} z(R&hg1Lf|8T|z!=4Z>Uw7h^hCM@mJDL(_(eUA>12Z0~nY$9o-|)V9A|31Hg9&0Qb} zyVvt+O#*_II-l*_Z4+bk>>m5Jc@$#&UV9aOwFm>kXh;3qXm1-f3_qzkp8s?fc|t?< z;^G%w+HJu9>TBJZV#{nO8nZd~C&}IIG3`U1a6;alI_a4tErnKEW(3{+fk0In<*Z=p*k9 z^Opr&a&vPVpV-YIy(`?eI~3eI=e06k-|N~}l}2ggD78`Shu?xV3Wv>)xDy}W{igqW z@O4Rihko(5kk_vF*%Ir~D?{!dyNP7UN&p7^X@zS2hW$CJ*es9_aXx615<)k$(GV=c zx03Ldb^rdBIaB`p^hNVCl+M%{Z9qsxZqLpP7 z^G@tse~;~hG4*X=){zNBQ0|2)`$G%81b2GqznVk*HRm(irt*8oLCfS~P>?xkC@yiR z7^GTwsIF?K>wMtpqd0r|BQIuy^9{urxs1mH+kRfwEF~@J*ag)>GwGB2uHi;*--n7F z&5ct^pcJ1)5&>LqUJ~xE@E{(fRDAJCNg}GMIA?MMUP`~pD!_xn`_Ei8C-Sjcxqo*Y z>{7#IJihO4wYG~D4+Mt-c|7Z6JN3`AzT|8atD$zRNU&2VM#0imE(ssTe~Sx=+VqdZ z3bd<2zJnFAN~RFMenEON!&TO5Vu(T2{w&gE)K&U)3|QkD3wnO$bDV;duCxgsHbM_H zA~e`ukd-q8`YPXe^W8W7sMAMm0a>?^iq$o`Gw{UeIAw2Fxim{d-$Yey)P+xKZ0NPI zH5tsZkm$8*Gqba^Hx%PqyKK#WrsU-eXQf1Pi4pEx)z1L$6_O0_jh!!@pdqZ>@Zx<9 zOxr6{>C3(K;cjOX?R|tTI&yYms&Y^6@fn%LBxXNzuo2tD+%9)$-|`%^kLpD zxC_g-4re0W#^JI6{?#LF5TkqW!jN(I?ejlR@FC7n=Qv`ZyXFDUgj}krZto$*trSy9nkdJ;&{YPrwaVpP2VSMjxn&3dJ{wtEtK9vnu@{ovfB}$p!qBgKg%SK4T3LypVp&gkn!{>^GYL8 zc?Sy(j~xx<1D-$u5&IlAUEsmtl~1av-7*)Mb~L4D?(R(zNvZuJ`E#AY-W2?}^{SVy z5Zr(&O3C>qgHs=0Gm;YiJc)(~_k%dJ!KMSZ?SIET3r<2btu3WN`qU*oYs=0dSy9jK zhIy~qd3r>b?sa4|B9pGEHhsQjnXeKV;4Az^cF_&;p8QtA7EmmM$3~ODot13{6*;@L z;-0Or?F1$c4F}QKvM#DFSs2#6(JiKPf2xY#b$r@XalBp{Z?MiycxPUss)cgL)yT0m z6}_F;WR*5<`E-}V9u|D-()%@z5{waK;z#rZJzl0iYWY2l%FVC0Pb4p+ zPHiBUX5zQZYrb7aC%yWMm33_N-i#P}!r;6n9gNEPBAJ_z zOLtZHNbIIsVqgTqc^nnyo!eCT@Y1Z9%6XgI1JV$LyMFG5d8NWH*WvND2`t>F8RS)w zty@nIayNYRH)id2n&zGrd3!yaI3=WP9UFEjs53bC#pyg-R7?1)9}d8+IWi+!j!i_Y zz72D!Q?XA|?%K`WNq974jH5zOrH-Gg#b*Y97K73KL^Em$*#gx~a+ zIJPEyn#<8Ub|<+tt|^$AjvntJGjzmvSE%)E4~EFQmqZr(7VgCCP^iex%Dc03PW4EQ zSDKlcU=*qE={Vbd+?yC9*V73f>^gq6`iG2#4gK5|T5W`XtK|p(Rx^tP*hw1n1l{g& z^<^Z2s2kU7d%o@rsrZj@Ym?2(rkLK5gX>FIRDbJ_;+HNQZ!*UpnNb+B+6+9q>nO~v zwMLH>KLbswVk0vN?YIV|{9fA7?3&F`4iLAa7%rOmy63g`>CuS&3@;5--=qD&$m^Fl zyLT{pdeJio(R7^yUyGD@tYMCEgBK`$5+6b1_snSDr{0jRXO@?_y(y8JE7eN!{^Az* zgu1ur52P$sJeHmZ&qMCBOYgn!HrNN-LH|*xTj%-h3{lT~w-_yyq%IySFYS}wHkKTTIVfIFDk9A5q>HykuY$XNO7rkTkdweIT9D}N zL)Jj!t)7UIK19Sq9>?mURA!#E>jQQEhn9LJDu1gG2q#X2||!BMQH~!Zf%$g61rNt)dQz{ z1WJ}v+gZBiey0yvsrRFpW;|zDVA4*Z5b;XN z7{r`qYMI%N;S_o{k-f)b=4^D<@)`{Sp|)^=q1-0UId|hm<;L7|)$H9|W@v*Of2^l5 z6+uokjudUtOhu$+-|UcpzJ4H0fxAT8+`1 z@m!mh%pY^wt_`zSfV|4iPH2f$OV{lT-+&LnkukrJQ#-u)W^&m6wiZQukn+%O@9Tlz zD07Cei+c4G-X#w#h-?(8zTR4E5PFinH~1KRlYKwqH)`ZSdOQqo7hby5N7Z)I0t`bs zk5a*LXwCSC>GaG;Ui+D|8hla7y`@(RJ#qzeD;eTbF3@_5Y>@^cXyndp3C-ncRicrgmpfiS>He3Xw8KC98b!-twPNSZhr6Nh9`_spxG994fFgiE?|PDaz+;XSkd5+w02Xlt5;}O;cEy|K7CM4DUh#^#ldV z<8;Y319}A~E9{sFw+s$27&_(~WjC|$m%QjQx-wqiOghr7Z?o8xWi@b2PxVJ`MHO-i z@$+l3AS=S zuc6MmJI_m{982ZXUQQzBz)KyIs_j4gXfnrTT3*O^z%JR?gL>*F^9z zDHp%`ChFF8Bugkm2Y+*>66NvrNI@38=&zFB_vZ)dlAe*ot4lwe{~8gn($wTV)wWTP zJ>Eu!+b}OPt+a~ibn<>oq!#a{G19l~CNH3ErW-!|jti;^gG}zTJ=7}Xv-InW)Z(F` zU055-%s5!Ljq!NZs~Owry4|I`LLo8Bo2AwyfH#2NzxRIFR)eJ4pHf|Hdk|cxrqHeh z%(vl+Ui}+P$%DfimI$hidDWaTkhf%L^3&LNU)nafTJf->B;FwDx2)@(xeirP=Zj)# zM|lz)=YfebLFW^6n_YKvwcW9bI9>GfCYGbEsd%0j#h05(rXLFvK?S5xbmxcfJ-**a zgf-ONv)yKQ;@5TrvO3j_JSuLComP{wAL-x1namD&1nn~l;Fn*$@1Kbc2K!h(%?R-? zWclet9KCzVar`vndf7lx9U|>Uf&9{&dl?A%p|l*HTWn@`ydU<})Wmzls}3D4PY}Ee zeHoRUi)z1=xB0bf_bG)Z*qd2dAgiHoQbGH`IteTBGFVVQ(&3l;E{W`3^3umflF1qo zf2V#4eLazpM5M;O$93$nOn`nBn?Fqa`TUMlb7VSJ%_d zq5{9k@n>*~jNWK#w#6h0Z}igV4AqBNyFf%PbX!ya8dp<}`=JkM`mT(M&fVH5NG$kf z`)d5*Nq&GPmwLP_e38H6WE7BeU|+hDZS8m2^tk$V_!`a3tbI4@^}8%s@xf0#pp}wY z@lUY>Sv_ARl2$iG_JpW>oJfyDBGi!P+l=UdvCB!e(?3;~?M!lpVpfLt*|e9U3SwGR zJJt|E*>(4ZF8>Y;3wnA{49SEQkD|{ArUbWg9#wm_n`@j_;-j7CH3Yx^NUiC`A}iVk z-tpUoKAsmCx5(aJr&(Uqjf!Bsj`39TURx?l5xPUsU69w}#P(aIa=U)lP{4x4Y;&ux z^~n=wav@di&49!Rzk(pdRIJU0xsEY*V5l(%q4FK!j-yLO$U$Nwr>HaSaJn;|FXEiv zwa2l%F7(mgWXwiHprqX`M(db`v;`R?%QM=Yn!kYt$ieYq;+?2?V@#-1Q9e%*8V1IOo9Fy{#c&LOOYuX;YkU$fcT1 zG2yfdd5E~9B7CIc7tg@30O)x1tfphiZcD)e|TYPABidyI&@doWrXrX|@ zZKbb9$1dr69D(|xv9>oycGLgd9#+0ofk8V zvsMcqF07b1pNRJ&#)(|ZaMgQUTyEpl6IbNWbiHstro1ut132;^hq=&u?JGhpT|&Wk z;`5yK&*r*b+|sZ4WjWkvX8o)fqrH6FXJk%YHq%uvN%)RF*W*y(#dEhj6TjCO1VxQ+ zeYI@qx|;Z%uGE4RZ0>>BiEwa^a27$$5r1uD5nO7!3eA64G^|ZQ$~rUR0u!m`BnfV_ zGKkr^X72}oP#7f^xy%~bsU6_4qjhB7m+kOOXfomZ0LorokUnAn`fR`nK6!^}ddo^c z?|-+%J>@(iQw<-cr`;hay?4%dzTg@p1}*>Q3%j%@M*^QS;WM;@v>Lk1K*aD}Z+^}Y zUo;;G<5uM?exm*xAu#D6L}ugz{&zBsqKD#xWlMUh$pL6 z$r8nE^#I0H1527S^kjvEf$Ks0#+Bu9>iN}qMQ{xGBd<}(sg-g6r%DThHMIKHyx%jPDuO9Y+H zzqe038STe#7!Lv$WTSnEwootO(9af^iFFr!NWjU%FS$lYq_-chlfW?o*}v22`PT_H z0h5YYTF9h^%A+$2lse7a-+(6?Xhri*RdgK+5bOzbvp$_b0)$OZ{HMVKhoVjX9w&$hIE$Z_}>xbQK6YP z$a1V`#l@0r+a6zGY!44Ui_n|fI3R+cg9G%I+LyoOe3wTo-3IqYqQ^(KPM-0trj_++q2cm-^~nd4zfDVP^4>>`sP62M3Vu?a z6T`t%&nCZ(IB}0pdySg4_AD-)w(Bu8-;r=Z@aFG3xu7bNd)*d$FGX#MEQk(YxrYg$Cqi#+Frr# zC!yTJX{mp1SEpnW{3I0jyUihl*aRK+2r?UOk*?bA%v}1!&Kal zsi=i^uT*YcS;|H;7;iB6S5z?Z8R(QRL{}{A&*(uOgI%%D=9}Glajz5EYm5T#1Dk>{^zg~X)Dn|d8XPwY&QT>ARDl5cqR956RbH%vW4Yy>B7`f5M zZffE_NsoL!Z+g(dj_Z)% zR@#OEhLKkHx+JC(fe>Yfe&#x)J^UsTbAY1$p*14Yo{^%|l$4eHjz9Hi@|Rr1_P ztF+4|8Pe9Ut!q-d-J2&LGW=JBjt%7Me{$M zZUghG(gA1gy;SJ6B*?$>fF1pSyz)SheM>M6fuBMcRW1{{ch*c_EP8bc*??u@PB zM%Tu7MmKrKo}#kAsA*$KKBLVaLN+^N_-kmV-Uo<^z39rl#ccQ8l`;GZ3W-@j;um_3 ziw7>}X(pC*S)=7+o=0j%|< zv7yW-noL1@j83nTIHP~Vmt$HUw^)aUtMD}c0&1k@A@xcERZ6j zSP`-+v>5L+ev|)Tb2jh{7Mq{txv~h44~^06%INBf7Fb*kwj;s=bFpBS>|OCf9H~O< ztZl2T)3z1cw{4NMpOi5NurFx!UDq7nJ zv7*6;TQqqnPqBOoR9Ki5de;!|-h3?lttFLhc}wW30?MmqAtBuiT+Np)WV4 zf#i2zB?_LDDZ#U3jXcmfXqYIDO`K zVu26Rc@xMx28tV$Vo-(i0zN5lOctI~V|xSQiAp9W(bj>@kT zO%ad77MxY1j@h17AHz@b;~(Oljve5}4kDPWCv5gLo?!e>taN=_!Rx)Z^qox~n_L=^ z`Pf&HAEH)}<=5YOkeaohit5-fraq|V$5!w6CA(W1Urq8{h-k4FgxF9tVj>64>IhiJ zwj#ER+oPJ>VB?`681pr@os3trmVohlVgK>rTuvv<<$!+XmxBt6GE+h_Q~hfj@we*9 zs(=Rd!qV3b{MrFNO?B_Hs`xgh-gCG(HOEd+pHSsy?*FSVyud_Wf_{dgMXLQZtvx4}KTo?v71W z9QpwW zz2s$H-L&0*V=ReL#ZRmDvY)`hn`!--p$e5TFp1zD&B(i@q8?OyUGnD1+4C7$Dj*W@(%|#5t$M!759UwioGa)AWQAAbT_d`K`TY`{X&AaLVQ8t{%VuIw^l+5S zlx3ll(EZw0256|IE<}VCh1wrPJhNbLu^#hAn|q@J`WAq9#omY9xBX^)lxKxqLTMt$ z(=x)aBA>rRDyGNF##oLYFBkqC4H6f<>zWF}?GKiIsgHq<*jSs%KNz*!(#K?NCwaf@ zWZNo&`n@X2RsmQ4Ai#7Gq4yTEo1nU%aK&p(_0Yo)6C@&1gOol}}ZAVqz2fH#U-me5IS1z0JOD-1RN(c_T?8Kop zwTY9Ml>S6lf)KKcosg6=!hRx)EOs{o#~HG)Gn9N=w6ae1I6G=*7A!*#5FrOeanhrT z2Lk8tW0h-LGHZ_gAC`=VM8JAvidaxo)vK)NT9U@~<9i%2ldWBCAyhuR+jR#^&-aD8 zLRRkA`UC$1rToX?yeLiRH6jTY$VPOag5oLWv^TGZ()9#f|BJCcZ(LuNNaf8t*lv4_ z0wZvr(%8023izk!5WItUuW{Xq{DU8lN|K*>Z+Mf5FPEV&EiKF-_q&tX(B}?YglNYH zKf=^=^J=Kf6|y5%x@1;3ZX!VS0I(cff(k-n3l8|~_ASPpj4;Cc4-STY@4q%Y^d&wc z;pHhzp~TgXcfNeLj$el2WxeNvX>^v!P~V{SSaRh~p{o|g71J;v!tc_L%)nZ&Sko4W zOM?Qi`Xi6A7awC0Z}n4vY=@+_H<;O#CBPjmlxU(lJX&_g!nf~bTwE3&I$gUXM+qrv|Hox*0Xn14>p zTmlD#lc@_h0Q`42%>KXXWd7gvWfFLSGq$rCy7m~h7J;g&vLhcyZL>lmK{-Vl)shG} z6p=8KC%St#+<2+<6v3th1U~tqD?~6uXC|yDK@fw>RuMYs#Q+^)Hu3RwJx<{huFb?Z z?ZE^El2!$V^JUppPE9U~7Y-M?&9=;G_ZfNbEM96WvqmMDf05iB%^b?gAG7A~GAh7D zrlB59dChr#6f)ilvLBLK&wfO+G3rvz2su_8Q+*&F*QEBDYcY8}ii z%&DNtagk{Ap;M(5>b97Q$y!yq<9A8%68JN!3r_FAoq1;3pX&Pg1I!l zwPUC^vRk*&3|v(ggQePAsq znum77`Mt)+yGo<4+w~y}Rp|?JMaN8@;fgVy+iyob*gfOseEoO7RFlwj)C?1T(g5wY z*EOXrvG3g;$-KUnfEZ(om+sB{AMIUvRFl`X{}==nFj}iXxqz*0Q>_ewf)+@q+ES|( ztuvwoClm<*K>{WrP(_?*9IniQUdQVIDD#j6#hFAvlqrTV8N?6*1QJ3>^3Iol@~m&I z_ug7>-S^%){)y*&XP+w4VzU_~m?T&d}ky_7V@_X543QqYEi_7Yf9}@C_p2K32^X%t8;2rEH4Z z7T_tE13%%KW83u2RU%nKJad}0d|wY)iS?24qc;SEk^pJ^-qlqVp^_ECArHVx-<3!Z z{l_10v0D>F5f~op%Mw8?{$8r2DHnD+;|gZoR(Few*%76eQJd;bb}PEFLlW1_%qg_Olz z2^>|1>ewr46|R)nY!A-%(sY|FR{YuKOwOPZtgs1(WR!OP{>(h;Pw#`JzJ(4O4!+h{ zv_+FCOBM?FLh>0RAZpLy_?sgCtdK%(v2IF%<{x%A|Mf+|^6-~d$x6Oz(km)Cvo(~2 zMLA@Q*;rMvM&fmFqy#m0Q)0yUV0@)UY?b+12&TO3AxaZos)X*RQ%TSN#<+`eiP#%* zz&(hid8-NoT$*Q%kl5|piy7+Qywk9d)I9y43L$sDlNEh|pY)CYHUlh|ELC|) zGQoipx{#stEj`}@FPKSW-7684Vb@8yX}hRi3$~_ZD^|^HVz>{;a}?@J@~R1*dO6_; z6^K)%QF#O@jg-^lDp~%LD&1`_yS0*FfNzH{n~zZ-4)Tl`+QUbF9DoZ_`Qz@FTBw< zZZOGDnC4np(HxAPm5I$TrGcucQG%o-U?r}F4BF;%W!N=-!Y@gQeaC1eE`HMU^YUz?T3Wxxq{ZGE8f+Cl|v73@6V?<J^%8LzI&7JBCsfgYD@Gc6 z_DU1>4i^J3okLx&G6%;quk zC_lV2t5fw9d@tn_qp?h4GEic(-F>%WyqLCKeWFpsyB@a6kiT;RAgEkUO7D?(d*2XJ zWQ`BW-CpP(eztP=rD3p4e2Pd8mI;}r*E>Q>n!?Hnq_&lOQ7=AGS^%Wc?1d^ryc|fQ zOCeD(6FuP>Hi40gx>Qen*$#j`Cnm;-%~~A%M#|S~z9W>z69pE0Nmr&XS3cl;LQ?IG zvOeMG$m{L?Jo)!24k$-YOo}m64{q#Rdry4FTluInx{&?{&{hF61jk4eA`q?Hr~=w6 zV0RDqgRK-@AJwbDCD)W*`n(+lk8xtFbS1xMc^$PdZ7tO}I(45;52f0yQmS{=Cz*pN z%1;x@jnrxr+EN1LZV)4?&ecUu8994fVS~>c`cpX%6`L9}Ouk3@po+6uosMc!d&K3f zc=kRI9J9%$eV(m?N8J(5j>mVU0>ynyl0z;=_Yxhs=}0_RZX2dTMaSF{x#oIQmXyq6 z?>ynX-?CoJsU4Zn)fK&JxJHE=HVk5c@aIt{jQfL5Q=7=6HbT}+lr|u6MlV<$zbbt; zh)q&^zEC$=if<8FFDo|-7V*K+xM?j?6+eS+Yj>okB3)}=hLA;FY}$RN`>kg)pO;}0KhxJk*F5`r#5ZOfUT%qX*MkHN@#1lQhAdnDJnYn+)jQw zBTA}xm0vHQ_3mw}v**cWU5{n^#PX)fyd)xh_pp>n4`)kRJDgCfTszJxPbg=a!~m;1 zB$cubIr>R=#poGju~2{fbHr9bIh=8l1O8$`Abf4075&LE`i@#BgJ5Ln2}b>`J0be= z5z&FcY1Uv=O9(ouh^$xb*N+=X@DMGp2FUmENsW(`WOe2TvGO~=2Uwv@N2<>t9 z(rZM^E5R;1_OOIJ5wWqIvk&N#lx+0iaLDkI64t3;s_{Kwjt_~V?jI_)r)QxHyhYx! zSM~d0ACi~3_fGXF+7|uGoeD+7cPI``V=!CG$^tca6j_=<-g0^~J%gpBXOmx_r7R?9tc|nxBm~n|C&m(1Si!QxD zSfyNy1)TC-hjjPt65@_X5mKFT6UUbCC|fpu%kVi zjByl}DotIvk1{2-RK`KK0a0n3ft06F0RI7)(gyV<#WkGhorcdIdY-$rkP;{_P<-7L z9rniwg^&|kD;|*2QY1oNW~PL`=T3VWx+O3zQfX~oNgE&?#5Mr~|MZDUIKdnk;Ws;7 z)I}I6pQ@Bf%R&f=O8g3RPu56gSS4*2h!GTWvCHLY<~|%(QsVrf-|Cf)0&XE5FVIwP ze;nn83iu1X-W1nN2d#C-Sr!Y*s<*SEa?_XijfC0?OBJ%t&ZyS%d2)Ip02XRGC@TJc z_QN^%&FLA<{=w>oQJUjsqBLLS%cQhq?H)Vh402yxHLB&%J8;=bQuh&bdJBuNZ*5T5+EudyYAR z;_LETfG-CWUyR9galL#m%Zq6}Jg73Ylcg4J97Xeac6jek`xun?I;p&=p0W>kk<(8r z`F3T=0LpG%;4PYv@{)JaugYZd?&8ec&jEG)dO047*WlifqyUC7>1@VSzNB&KNks-N z0vpGcDV2)^XPa$Q>S!Yi3ZIybs+gllq?)zDSVQh|k+cY@DYCeusI)x*(l&EDM;;W$ zs~chIq>a60wIf@Vo{6fzuaE-l1va(MV590%j2QUhPT}lp7-u16IE84XZmJYZsfD!C zf&EI$-Q9x&?^T9Tv}*mxx)4ftE$(TNKx~kp2*%&6JFx|SYF5m#}5 z`UYC8_u`49jrII+Z#lzoRFUCP62+H4~Q8@TQAA2UW3?W5fv~IxF1S zh^k9Rpe{pDb=jHc53XWk`m)w|qVpD+cBN3jx2`?-Z)Iaxlp$-Ky8ZZ%OU5}%BybMbrk=9c&V z9$*Qq!Mv#f;)9m=9%Kx6gX=G1Zi`&Qo(Pls{xIZ_^}L^MT!^n#Q*K2(3U7XmFA+p# zb^uSQGukRbUG|7WZdL$U)SBX_|FJ2S)i7mD+VCBfkCG{K67S+=rl_eBTX4bk-Vb~g zrr@eabD5Ci8o)x40_^75rO(eETAVr?*w`Gl&csqXB-0L_aW>H2%}<-6>CC4{17SGW zNEaXC1Q5=Rh$lEiwysKPyFc46j4Y+}+hu_i^gb8TL2%1W$eVDI25b>eF zVMJS#AQ=1~C}a5F8Z7y5)nxo1+f4f@z23Slet&0LjVqZ6(YKrKTNJW*kRr1%EWbPf zbZuX;5xnCKkwuTIlDRM`Z(g-iEGQ<(@%fdjPGo}mj>w1aUKf|%CDnc?b1_LRKTpos zlE3oQdFQ)cEwf`L>E+ug?io9%NNx1*C|=`AWy%fheIwt_GRa#x3;EXY);Cnc96Mz* z#dgsqs`8f$-o_3scCW^YjXdugHYrDBr`fW93KAz6mLKk||7_rQeZrPVWixJoH#LuK z*wn)(I}>y+Dc&qkJ}9O|Qv~=oh+YWDj;k(i>wKdY&57_;2=O8U$WFVZcYKslZw&iYciHS{o0!&m7O z7g;f-?x&s5;M&RHmg577z0-km`W&&;k#V6Y_ArP1aGE}$FOJb1S*G^E>jJk)*%L{Y z_-P>dO1V)^KH0Eqkr8VSy=@9i%$>3y`Kz+Y54{j0-!q{NRT0r zAx2O+K;`f$D+84SR1Q!%=sYec3s4rIEI?U!f1`q4G`x6%n>e%!&@Mo`0PO;_3osxF zT>|J5K$k$5AAzz^*{hcU8ijfy=+F7W91V1pwRuA*7tlsP8v$(un*WD+H<)*Wc{iOd zfU*E(0m=fDg>gl0FtiRs>;F0*$;JiQZCYjd{?-4tIS)Vsf)%e*DK2B})Er~2znz8j zIJ(ncjpD6XCd~X`+6Eb%!~kCi;60G zN7jsWqyx?3+Q7_jg1H{LR$XWZhVm((V*%MB10SgEYol%Aw;~eGu>8tBCq`;)z`-w*Tqbl7Yb&6Rw&FEH!~h=-OaS> zLnk@M*l$)5!23W@DxCMAv1HuB-z|FV?KS|tp|9LTe{HY>;s1Ty8hiEa z*5(JDJ7538pv9V8w*5fQ>#ZwNZ&Tj)TyTs%GrdUqJnUxT?Ptd2#|-jVRtH z8jPH0AyW!M5^hDz&b3wgqx8M?M?1gd<8^x%(qHWHDJ)%V^0i9>h;0-qYVLcq&8n#A89H+r{h7B_HBV^$0$qg0m={A z`Odz{f71OpS{vm!Xz>YBdu?vt-?1lKxAaSwS>UaOkFBoU+0=A5=NI*7u{NI~wan{g zuSL`Mx~20$!-Bu?z3Ar+rKcMiDs8`m0mn~~>fsajxO$tej{7?CQ+!`|w<&=W-5swb zHU3kiN^0i1ACZlR$j5w#5P=YZ5Yg!~ox+1!gwa7;{5kdq)1o|R6uV~ZERIs+|$K60C2=nO_zVRUtTJPHQj zKMpp)0Q^VsC-u1DJ?JUrB{-lTRX_dVb_&pNT zs>a6Y8B`;f+;zemxRe#n4t#moFNk+6LbZK5D5?o5DBn; z2^Mj|N;dG65i$WXLDx(NA^{=+A_3Mp!(wk(@ea%W(I$5PFWx?cl$@HE^~_4_h=6~~ Ne_FLHYYE|xe*?cFYmWc` literal 169616 zcmeFZcUV(Tw>G>(7ewqJ)e5K-6#~+uC@4s8(ovLNq(f-IhKhg+QbGsmCG;MO2q+K& zgk}gukkD)B_1gjU=XuU~-sk<}`{%u`;{_z{J$q)&%$k|C?sc#IT2)z|k)D+v0073j zcW$Wz00ja7nBwVZz$;e8*CU!}oo@f5#HQy}6ge}89+ z2TKDen8I`LaOjkR1-49mLW)ebNXK_n5h^8jZJC1%7=i+7rM(WVKR-$3d9>();Q@Qzj0 z3b8;gLcZw7O#*=4N7St`Ty8$UOM(5Q0~~w&_iF;L3P;icHQbk<%x;uU)%~dq?Bu%& z>E8{y$A6Oq01;h3r=CVbu3yzdz)KVe!txKu?_x?s2$1`YKDt7Bc4JS_y+(n|DqLOcM#CZA#~C-^TZ0B|bH{t^<|LJ63JoVf1h z{kIgrY2fQ$Lbg5P1c0clnzE^pzoYAC>n|z(A0DdHyg+NjLdq$boeM(n zB^J^aNpSu)wYM-tq4W+8YJvhm)XA>r9Y$v_-w(FAT!OXSk6NDdU?EdF`>@7xjl3hflLm0gb_NkIb;KQIypujyw9@q#i zCFi^K?Z-|(QTGPoGx)Sfv|A6x`D6>&?SCsXFNP9@7U93+l)K6bE7H&W9{!X++ob(K z%pd*n<6}w_yKggEajI7WnEY`&cD?SauAG_J!0%>M%W0SH#rI|qA*yKai@hBTC$rn= z|EL@9Pe|Sg;7%$%!1m{w#aXfnYWBXErMll3bN2UgAujAqc;o-DHfE7yvqAYOS^I12 zbTj3@QL+NC##Y0Bt?@5C|FhcuuWFP!u{K;k7g;hGTYuo^U2K-b$*`Wm{^_@;P;6+| zSNWOM`AIFjLXvHzpo$A29=Ar95tGB05`QM&7Bn~~_g0wAzA|rpn7P_Qpkg{dal(4x zIr7SbM6sXmWRvVSSC~sCuNGRnJ*b?!8^T>QS!JEa$9gfvG+3%Tt9&xUtk1RtT40V% z@5}Gnty%6FGzpU4uqf!WtB5jm>xXXGHfQi-x!7d!p-!0&f&-SLm}^ZH?BKxeLSS90 z&Qsk|v}gSz?0ra4W*@b*UsqY9(8cTDu|9UK*GKM=h*9>*Mm5UP>p!n=gWqG3DbY7A z0}AV2G6n?y(5c?g%H*sQ^j&XuAH+(MY%*sn_zUgAyfcU@^XAxOBXmxBbN-2~ZLn*v zg6lZ3GCK>wYwq~Pt&2Z-TKN(2?_}=x5Ox5-30Rx0Af25r@SWDhp}c3TiQmoTzxZyf z{487U)*lI|doRz~^$@M3(~K*wL^!-}+Bv4q7-V;4Nh{l#-;?)LlwC$K*x_-)VY(nL znS`9-l15yTJa%o%$hN4fh0}AZCE9mqotWUy85EpK9u0GFG%jxv6mS8L$Gh%vTEKy5 ziB%3#|D2EL&NE}vKxhlfciY-&wrmX98dJdnePEkce{x|1+GBttc+Pn*a8*N_b04U% z`o+gm7dB5?;=`D)2&jMeEzc26RgTei8|YZ?O2rnL4S#v)I9;E}8g0 zx8BKBp1siLj8h8S`5HpgcKe=Eok%~pBuxi=cb}b{_|VsdoBP#sT(%pKmFjf*a(CR; zPo9Oc-QfUJ4eVyIq;LLkw_|Jev{U9gyDZrfvw0Yfa>%Y?=Hzafv6q8?r;OXFA2DtN zP&jAX%^@djVADPQ42J>lRl@>{_Ti`N<7IW~;)#!DG%!z+CB2MisqbAy?`*KCkvzJq z6b+4LZ%<~I42Y1%1bNf+(>Dcp`ai!2XeqSBVLa#1gI1e4T7W^W$pfNL-lzrgqqfxK z<+5+;236>V?Kxi=>A8YfO1owfkD@HUptIe#MiLQ&`r2&kAaGnus6Db(onlV<*sh`61l)UpxX%Xn05{l-d3we2C9Ejl6R@wUqC$U@&@Muqw*So_hUd{@GMjM>JxbLTumGrsY?ZMsp&4SIYrS#O7jh0JZiLsW&Qz2tv zb_8K{za5osy(!Y}ON>Zg%hufP4yrxyW50l{-nTMU+bv6n+^j7IDP)2!k`~DcP@g#Y z=)-&%_kDc6#4OA4F$aP}JoAtfH= zIMX1plzMkxyP5By7d1$WMR@vLvsN$MR~b8>*)5sfb!?^W%vJgo9DE#a>k@K$zOcG0 z+PZ{axJxOfpW7Ob_6)v`QXLDfjE}liAI~N?b%d<~p)4vP07cuo1SdsR&*9fR z4VE(^uH~dw3G?DRns5P4wrVNm6yPA|{G4A3ZB6y|OyL@n8dM@R#`?>df%Yt2FUOgTW%K9^mS}Tid^UNq@imV^av2Z`s2OVb z=3I4k*?8iLT+x-;dVT1H@}cs^`_mMzGetf1S8Ymvyp$`t_4J)`jJSN=&)zlXtB%&E z3Eqz|70l^BuUyGElJ7Bf3Ilfgcv3)gVS7D+!|Y4;gy(#%|L}~@{4=hf9GQW#n7OH} z0_9NU7*B#xF;XWxpu*mTP8|~)uXg2e4~P4ZA3ySPCU}MwMtcw=+gCGq*zFM!K>?7E1@jrBCjo^L$67ikn$uLi3_R7ceGvbE}LoArRl;h99tB*)^G z1NxJxS|om({-&)BE&CH#B_YQRo89j=cupZRAw&84kLPLAnwO_zWp_z3ySTGVabq{j z7Wzg^CU=K}Q!MaHK$d9*wrM%0_(jhBcZ_@eH|(VcG%~ z6Zfe;S-mN`IypSWX`1J;dUli|9#D!;UcB$t?}CZADp>qg2ZML5o;^+A^2+^^X4#x` z?92HP)sQMfl(O_JytcrQhgYS0F+I}gnQx!4d5nwpz{>3H3IZ!kG{`CrvIIdGmOH-= zCM`A#VkMO8;e+0*Z0p*ipUezJchmt@)(kOqOxtWR1rxMiFOWKFc0*#W^0HB?a7MCo zkF}9eVV||$C7^u0wDBGBTr#7_PFk1-XJO+5>vd=4zFmPBp2bgWCB%Lw#lGe-0oWxB z0zx@l`H?%_v}o)mbb%+>e-OsNIX?z!H7xQj=D2I+wN0KWWi3VLPBr<+%{kxrdakTu z!4rVXSj-lwYXwf}-#-}ZIU8BdR1zs)?ggdW|x`kuB z+-*)e-GkwsW+@ZezW2df@^JPBR=^#SB$q*Mi0mw5TqbR}m;u_Xa1knILh#Zp%<<7yJAbxd83q3 zsmLsXWC&@NgjA7U*NiTH52#{hw3+(9+=)~7#D~!%?09%}OnbuN109BA(lYC7Bf(?Y zPPj5?ge?S7)yl;vZQFdK(av7I(`J?vB{3JPKO3b;5JvVm)r#0lFX6Mqeah_Z zO9v1cKb+!jTskhx3S?Ne+l`3COo3`4DYg|XUfS!zA@0oQ&hEQ4!ZlJz;o+GD_DY;v zYO{E*YO|q8S({6ui=|#Hu7-NcD1{i0y(FHbvZryzfKtUCH zBttZPo8%IuVRZoT-Rv7YxfRk=>a@aQSGkaK-4<-eD4TR zW%fY3)Xy4|;AzHn6LeRghobtnVrURg59t^DkUqDTZSOr$1{?a2h3>fBHLHORV&L$P z{a$F<&l;ulcR4N{K+cH=|f zW!uRWZg#1S7vwHqVp_gb%*>%L^e)UTxtT!Tke(i>FqR5`6qQWaPP6Pyxl0L4)(Sy) zq**E|8Jac*1(dWGe6;gHR&PvZjx4j93X~0OqrY)SeX;CE-s-u`Y~-$H#yLxRa0XD# z)AM$I;3lzC+L+KPC1Q96a4u=Dj78((KfCJppD!IfeiT?vd)jZWP0L@OhO~>yDT1hO zuDa}uzij06=a5ya?xK{@6<8_pv`ZK35l~THHZ~!3`#v|E8!^cB&^lV(AC^AIAOlZK zm2B$-+*kWozxcvguYDO%okV1+uLc8Rm{Q^{y(#qC(zcB$RSh6Dcy`tzaFzI5cea_I!$kphXIkdw`d-6<%9=B5Sse|~v zzDuLVjY6lTmnX&gLNnL$0acW>#!OttIOCZNrOrxy+yhdf1|zRcu(2m}NI1vYE(CrDIF6`rm|E9a?een9agFLtcF+gngGr72vYXv( zj8l(1DfD^og=Kr%O|0#1^i&t|%EW9Iuj^P6M5B4Dt+3RiYL;8yMt+p|(!p@VuEKPP zYJ;0+*#uSvyFOvd1aI~e_zKTaEIPL$b}jj?2t)T#0AF&=YkSH#cmSJuBN=;rq($<+ z+T7jE0bS2UW(rucL!$xiaz&@uP3F^55-G9Gb{Z)!`*YXBuDJ-R3jpOP9vroTy}xQ1 zuQuB6R#CA)s5vD5VJ@Xs#b}!Ofr4QT{xFGmg^S$|R&A!}19cqAW2BO}pTQ{ZCyv(j zq2a|nrz_wLZwG4P?-OdvaDZx&|6+6%>ynPtH?0&qe*NyNy`!v@?Zkw1fd;F^E*8%w z<9Y7V0!srxlhaNqDqhEjxowh0;qj+|GS@y0m2Jh?lrs?3yaO+%tDqlMsJvMNIs}-b z`_@4ftJlS>j~wcZ-kNh53>}dUd)Pc6Rbr!*yQDV8+m*rP@l(wMo!-^X<58e7Q>Lo4 zwQ@Z|MDUa9%8#b135Y7OgSz8TzLnr{T@Ax4{Z~f{y}|t-sO2~<;=!JAwG{LZNCF+= zFCPMF0Z%=d<63%lx^MHQtK=Q)B`Z}LzW3&)=1edRx_DE73Ss9|-J$6JFy>OHWLD5I zk=?@dmkD=+7%YQzp8TY+a@;JyN=vYs5Cl{xVS(6`GdAGiH8Xbb2e{=!KL&ln%S8pJ zP;{M<%^#%BGSjr2vI`LrbiX4K?oR{bC}2plGq_~hnY**OT`$2j8!x+gN*GU&9YxpOdv!Meya=ioFqx%D zJO(q3Oiw?@NTsEbq@!-=(xsK|8&pJturlhr?>GD6hVNpZeKp#lF~dn^3+#R&g+!On zck}ntFJ!UDGKj(+3l1bf;W?vE20*8Xm9l1Fq`qwOwv~xFI#F2(BNB8I;8mJ_p*ax( zy{Nko$i5z}HuvNF^YpvAP(@vA=l3nDzKj{Cs9w#H6uf->C()MPHBd{|CFg6N$tl%Z zDHK~S!_fWm7d52f(#)JoaBmhn5TDCStxGwg-12Eu*QeISUCh+Pdd=jMdmLtR>kbh+ z6eUKX+xQ4QN}x#aV+c|d`skgwe_C;`G=n|^kj8RZ%$LA+dbP|n6P3csg$s+ZLN13L zt^k!q(>jxTaU@tq+D9e77`Gc0tHIapRQPQrBEM=2m;lhTDTCFped z;Y^QD=2#;&A@g*5sV5{$jE5WVakpH{+7PQUDy_*ULzlU`c+p#n&2nfXt#b*3Rf__l z!B%+ZBS?wWnEX{9{!V9G!O(JxlXxA+7=h@?i|Kk&98P7iZBC9)ZEEj8;S<9~t@_#@ z8WRS~+pJI9K!2oU3l`to?1^x^6yRv>88FK65N$VWQ^qr>#s1K@evxl%t9|$Vc2k|M zN1rf~JL*Y6al26AqO%xw>JrMam0DC_aKW5|xtWBr9QWhY1r5JrK*R-2enBinjb2b$ zk!i(j`IIT0s{9K$5Z>LLHn5UPTnKPP>n!tYo`cs?&kX1HT>r4_8vUi2njMU|90qHE z)VxHW&iJkYjidM(D6+97cBzZXWd>jLAXw~6+^uY4I^K5k>r3QS=RkI}LlnIGb{&@BghjVkyrSM=byKlNc+8fmNzQ%qWuFhGork>v4aehZlj}F{ zOb616hF*O9Wk z5=sn+e~p!<(K4;cDFTNNQ$7DDEXukH0ONQ4;PKuMf94$j6BT+#>*bpU$#NJT`!eEssK!d{>e3mYyW8O@-ReY?U=bN<7p^Da@B8N!NKC4rL+$nNy3ysx4U0YbIbt; zN9Mp^H%~{?N;()vGyY5L_3tN~L{H4x(c8A4+!tuFo-(#nu$AUtLY`Ix%By7_NC;qE zSu-`-`uuuX!0!m~;nx57L|GKQo9K&Ti-3Kx$Q>atn^XQv7#BM07eSE300^kj(6XcX z&1k~ykzblmH})T&ASk`4h`Om?Sid)de((hZ&ul;eb`c-$No`SG&O#-X?^Re*Z` z2d@e->~jh1DKhHuGTf{O!f3rzytys`<9Rfy)H0SGm(3 z@uxopFM|BDoPc0~@f{wHgbmUIh*&_C$!}5&klw!u{>5Y>?!)d4Rh(=qNd)3~08N$C zQU{x8f61*H?{VTV!>a=Tj0tf;VR?JO@XF*NWqaenFz8W_WqH8_pp)Q;U}XKlZUU0j9y0o@%GjqxPI+mov9ROhMG!_o_R(-n>AWRS1*(> z9XSU?XnwDo10xs>S@}(u7D@~&Tsa*tFvQVUg3yB5msdv?+!luGr3-ij_m+>JxY}td zgLUbp!&fN~Rf-qGxd0ZJCRTTcC|dm*VwfxKK5v5cJT0+b7_Pckc=lfkQy^lgFYFab z(*Q;JXn*nM7dl`=AlbkNFagx0%ntzYlcCe(Eg)X`1RX@DDwz(Hbi5+eaUFty+**#l z0F3LZ=F5W1-A`PL+(y{hTW^8*IrXN|9#&wjRbnpULEX#9DEq4Kh4zC3&Xb+r2<{_+ zW}RtjL@*SnB$ZJz0B^n*BM#kZjgygq8agH{I+ftIs&}{N9_3dK3YoQBS?za=n`lq+ zFPs0&pfopt#>g^BJtDS5hJ*`DHTrY;M3i9FixnHvSqRul57Jv_oZIg9D%O)G*LQbk zK|I@c4!ufHij?2mk}OpB`kDTxpJyQR^~}b?@?749x?n_l5onlkshmiO0wdBAQNc1h z*XPESWww_pZCAjEL*=rrOsvnwMCFVK;Yr;+;P}$^Vt93n;#@;9I7v~UT%D3&093ak zAWUZQ>p3uJ(2&zRw!J!t?UQpTj|1a!eD-KI9mk#dIwm*K$DDhL5PxHTWa)p8>~gI6e!hOXc1`3%d2r9Xp6(iwZt8;>s5#YMYxg9dyId@|i3)>SSyee~|TrVTXS zDl<~Ru)G(ee-Bb~@D!}=be%9zjh;Bq*|PKs zT0rCRgEM=3A;O$IvSWvp_P4LlW~?aSv-pjNNDdis!pNZ{v!(HNVp6d5n_w8WG{&*% zqQ?Z)Loj@#5S;=-X&zG{2o|0#Y|EF|$4DIvG&0~wRz8BSv{A&x%z`elSxdxK2XR}{ zmt!gsF|PQFg4tFSIK(w7VDX@d0ej27mANHP-m3KpzZE^s9$>%r=nkjwfkZ+||Iah* zPii0@6B5qjhj~1IaeGWuucGI^cP$800S%F3X5-Y;8MTt+F%U-W9R|qXgDo=%r0Gd7 zD-;brlzL(hhU+A2#23CCBLyv*%WUcnz?WMw8)+WjsbM7|YJFh*mBVAI$I#7C=y6kM z)^y_NBsvQzBRY8C823+GN`UySmT7-6!}bo4gqQm#OWBqerAgVDjP$M-ndC6EU;qe4 z2-t7m<%tO`8Q6&sb22j$uQgdr;zZ9@DND>0KKjr(NJiTST)!c216Q;}PVSrD?%Lq` z^*Hq290=#rec7t$h2;jne{3qP;PZ4c<%r|tN^m$UjAsJT`KeF6auVrO&P}$A@Nx0 zO`9Y7+Vta-7 zXwE3`)cq!&?+)j6E9ii*#Iu(B21)iWTNJ7=Pngi(B<(KT8t72WnB9)>sz)M&UQVQCl&=(1P6wdMp-7G_UXN**bdmwp#kx{?eRZa<$B+Xf zsGEOYFt7s?D^+p3ypZ}^Nq|k+Xqd-0phi+`&2N8b?vP!vC9~}FSw+@8IT@8GkZ2^? zrtUO-M4tTt$SiObvLlqHS$1uJw9I6WIo6Rg9xXfHbMEim6w3mvpPV${cEEzn%+jAq zNS+X_S_rIMwv?fYn-v)ahU%DPqQfpU@6S7{!TumR!~tnN=rYximF~BXhCuC+9T3q4 z(q=j(XNai0T`C9H$kQ2ZH8={MC~X|H`+i-TSza5@x>rJRl(aW|fE$;h)ZDCt8PG^o z#wd>LsPaUD3hh+D7uPC9TsW*y6<9~J zv(U&jRvXoy1A@%i93n9(ItC6ezFQ;(4nIzfg=b)-T`pbMY&<3!%wOF5`Oz{>tgxlJ z5h=e|(R!dO&ujFu@waB3Ieuj}l&atMgo9=n~^jeT(fN@?t~K5Dl3^PAd-GN&;lxJ#$rW{l`hISgES2A(Dt z1br)FQtGWph2HrmRr_o~`U(*wbqQstb$a?~C8hc$hvcR?P!%9VzE@^>x%JtK3OyNu zCFwL;PJaeZmoJUkZbvg|IvR}WfRJYf*3)0W!%b##hR^VX;J#V!*PugQi0CrO1BjD% znj*{5c2Kjy$xIaIv%n~o{IF>TT)Z_0Rz zV}vYlL%&KW&3!o5B}qUT%Lth^ysdPu2c8U6dU!z1MXG;pdITK!q*MRcF9U;9cHwgy z^mfbROF~{}o}6C!mJUBLHIl+lg;2;0;`!z^Z4ao@FOVDhr(;yWrBcvWVy%rH=(oOc zTLWr5*=1LJw-f}W2by{?8YEq%0)@Ec_WMuac27Xe$?|>NqUJQniOTU92^7uGx5zWV zpyB+6iznQgREk1Z2Yr1jmBfIwz|Jq;Lw>ZZ=+|E`yCBg>HkwCh-$x1DTeRIDE0%3y z8k#&OlEV`nHZvG^N=Jg4DMcjC-%DPfJS7L2cy~tj-tNwJAWf=vL8iEy=7tBj(PMHS z)V*!E(dpcsrF%hCEj(Yv#X>C>UeEDs!icKm35%+mxG2B=!=DRD=5jFss4^llG?ee= z-VlSG2Z`)d09$kWV|Gk(xDk@p*Q&}zA|dqsiM#u&UNt`FI2r9Lzh(oiwQ73=tv|#i zO(2^paxwCRvE5dg-7TwpbN#&|40H|I$di_9*P>?|KdJh@OW!TZw)m>mQR1^-ZXYI| zyibWd!zP)62%8kiYRhJ35bLudl;p-l+MjrspPAa8==D<#)G$WxM7?SutYpEEgm07_ z`=R6e##Q>BR4G?08z$K#-E&U~nH|KSl{6;VdH1Xq7?J`cuSO6V!v1(}!nx#2y)`Su zw*4&z{M)fti?DI-!9TXU-wASeX^KVtU;YxA_gxBE=9KlPkNNU~mZ0klm>>o3|B` zG}?Rf-aEj~`bP|K$V`qwh9a(-Vwyf)#(CBJQ=D53#&??g{_tx*8|kW121t5luZg$P ziBEIEs9qcCW89UG!ua)x689GWw3&8}`U}NFie}oXlqxX&Ku<3X8fMV)Xj-J0xsS`yU)b3B)m&w_bzw3Y4xR zSG|7%@$!J?narWvyBQSSP5_)GbfC7%R`ItGZN>EC_#ErXoaJ)j6rPKI=L>U{3=nS) z6n;Xj_)1Y_#KI;I2_&p1LVmNY8|D!?Gvy6adR)ViGR?fQU4SkdI?RObg&bM`b zqqjSfLkE0^ZJf^yS9l>E*(XLm4mLf_-{XygDA7Jv2j;4r{*%z4I>I^s#oIvyFbQP7?q(P0FeWFa9<+}H zss{df;_qw&=;wm8W2e6y3m5eY99Er*l|EgRCs>{yc_icEq)1FzYw72p|Jks20RU-*@d#&LCEZ|JLw^$k5?$4CB7ftt70XX;Qwyfzs9lBk37#7hnU7AVOMXYo9I}T?*r2yCVJD+QMB=!l9)#8 zujTob5_J2?I{*At-bGIcC1UH;@eLspj-CDW9!v`YPh`lMjDvJghT&CzuOOukLt_ekZteqR38r^pcWihm-%Hq}y63^f4GQ zfQ9`n>t7p`U&=BW7A5ac4xgj4o+kjbyO6APa-9uC+6O|zCunOR4@eU~$h>zl3DA9?O> zGtqNSffg~FQ`5y%WDtkoRl&+DDdShu$>|<0<6Tq8#JH3Ef>pw$AO#8h^7`Bc3 z0hYD!8Va!6#q)oUiWKD#nfJW*)b315+ft*ErxSXThaL_;B*#Q#2YEt{T($pybQM$)+S5HfFxa&30pwvBh>*!32KPW`RJ_s4+i_5)r?V?-)FTZa!9q7Wg#c*7@U0psmS9aB03kdu4%x-(8w9F;N> zDKsby@_5f{&{{5SOxZ`c4aS5=rnK$MNQ0ST1|2I2z&u8DaIr&7PAYi$pm~C+83(gH zd6fG9UK?4mfY(gXMPeaNIT)#DTQJF7HBU{##qD%1&GePjQyW491~&&*6X!s*=26PM zNc`DA<#}>ak3+e-gmEayr)mVDQ`2re>lqdbvTJ=ZkKJp&R*lJInc`$_nXmLeIS64> zy*u;%GPk5Glk2N@mQj^Ucx_B3sJ)(@xbDfKb~(1l>a9_foL>2QD#m&+6v(X-$Xuc^I?2}Nxa*1tX3#8f$NwSO+{;Iw$2oW0ZI@1d0q1IF+umHow$u^pj~@ni zqxd6Ie=U;SR^SP~aDr%Uys38(a?*m34kvJ{s51(h;@IKi5BR&8Se?x)jbg5x6fo#K zt8`6eTYwoT!qhXny;?0=?(Qq>#jb+bvAg$CZGKJf^=9Ls*dqq^=;h%;@v8HH5t!Fd zxvWho(QlQRtp`i-j2?^gy-_b2@~F0QJ|`KUS3Cm5ShS0 zu+@+-dtl*YXS$PSlDW&)4<_FTJRbqfYH;_QQ7L*gS-DtJ9dmLjS@P2=xH!4yR?DYy zM9pJ8QXFom7TM^fpjPZ%_-PPm&(&`M4?qIp71nd=MK3ax3LE3`-x@hR`C5C3_7K$= z2TkjXCQ|b?lu0A1N~0(BZH|m32rm<+@SH*#@zmfRw0u9Pk*cZ^nvGWt}{%HhwFE3K(mNj1ujRgV&aC@=^o*?qpcd zqYv-(>BWp+Wi1U`AZ3ovvbRAx?e41{hK%W| z88G7jV1NvTs7ODiiWPZTNZbZJNl~L}ki{a0eTLt*wt}d7(Cxfr@)Z|U{`jKOWc7X4 z4HweG*nmsmNf$W&_en@Y1@rSqYA|^BD>J-+Lsa6V&%I0m^BkrkW26lt6g_hkG1V&% zQTVKI<5+eX9c^VCYWr9k6;PC&jn?3US7C^$mg&I#wD2N{ntZEv!q!ZsmGq30_aK-} z1STBVp4aB7E$(lK$%x#dm09ysn@N0Gb+@WDTMv)~aj{{R{Fm?F`>ynkm^+l`7*-JL zCn-$uNf2>PsX5Ew2IyG#;n$TeD=Y*yCa6>2=)JODvZM#el9G)#ZZK+O0s}OaV&HZsH_Gcu zN|}d$W)6{2gSE5OV0t2(pCaCEEXFMeM-I8%Lq}97)t+SUFv$x&R(+IAElVukRFoQZFAVr7$3L8?V|C*4#JANu5qIx|`-=??8SHOp1K))PwHJFFE--Z$-N1AE$u1 znB+3AtEXn%Q0NN|E5p2G)%yv?i7@w~KKh60P>}J|7KxLLO2e~Bnm{zv+I7HHgvn1i zowaO&oLLtdSAlN0RJa}{kxc{ivvl4wv=|KGsXoeuLUb!lQJ91o0jHVmdxTm>{LM&z zAL~<8K-U!Rb5lE*1+~1W)%g78AebdVtVKwrLtSI^DO0_mgx7|~t%XMc=QuG9Cuhei z!&Z>Cz`Gd23t`6|C8Y4h4%kAPIjYMOG-FO!YA^y-s{@-JSJNh>GYvWmtxdK34~cRB zU+W3Wl%zEXQ{mEI##D_s1h(v2#JmnhE4k;+8n+(ce;IA~==Zw-a&zna>4I#Ir6I1^ zs*XJLsK`xT>R6Ulhdaov68euwydO$G$MTHLJH`@DbT#p7{?<}PZSy4cq5g}OK^ za$bZv^n`4FB%wc5!XWS^jbjf4!M{6g=p7-?1)ip0n2AiHARD0fd4TI?Edf{C#!tb} zVObw!1l&v>Ez@@apHGGga~kD~ z0`&8oB9`4heg7{fmolKrlO{pu-0kk28n?5W=Ai?H&m!vZJL_ZejY`!SFEni9!!qk$ zQ`0drYP81PNC#=5x0h9mHrq8RkEG5t(*ortnP>Eb2}+K}$9R;5!I-JXr`IX75>LT| zfY|HWE_8RNUi5(px7P!W>cU$FXQC5W@0QdBE9ujbbw^PmTQpyPvqUbZu31qK9m-4# z&R#z}@S;%-<-~tkW*m@sfmyhJ_6uJ0`c2t1x*U-4&z*FYFkP-B+TYm{SAF^=q&Bu8 zt6<77;z=V#XT<|Bv(={3Fi+;~d4Lln%C@tK9q*g--SsR0B}3YS$pZ^MGds&c_$=Z> zE+DORx#3WS40_@gN)x9l8Z5bJu_P|;mKFix$A#C;x~9L+be+1TG?&q(VSXeqHLa)p z`?94eBY3u2FTj&=o6jp;rtGL(wR>&?X~G%n1)FWwbHdUIaEB>=o(wHb4@eemFgZL4|j6bBbQHLmA6(1clsJH}W49z_M0T_|n35=>=VhJv;p8p*1R$o7DrpL&0#)3EIVP7U~-oS3A zU-C@vQ*s2P68jK}5T~ilM-r=7icm#B?VQhQ1$XvJyA?f9yj4(wzjB)mTu?v3gYEx3BBAsm`3E$~ z{@YdD^IZqOx)rjsK}Gf|?)ck213ggS4@gn?_lf!S?qDI0lv`tRKS$CraggcO_Vw@e za~gDe|A1P0pe&hWH~cvmjoov4tKQF9h>2L)>^c9*9)CM5AT;v}t8tIF{Cn?s7gA-Z z0-p_1tdNl7asCXNlJCj4f18s3K~(Q^gYAwsoxOX0w!(ioC;pqC{re0%&Et)WT_SLV zySlwq9)JGde5?Pns2g%sNu#}Kd9`GaCzSY)ozzNA0(OMGT2M6<|Ab9_+GU15PDH+$*GvN$^m&b1?~&OCnx5> zFd?t+Xymfk#&}Yau$1S@J*8_dlbsgmVbCPiwqpH70EveQ?J*FiPLkK7)5QY=+PaTV zIIWL{M{Te42_k#!y{i{LqJGYREFrsQeS6&Z3AZW|2l!%(#7bMaK-LrXB+z*t%f4^sEPiEi?Cjz=>@)|kK))z-z zg$f);6$(HH@z&JF>KvC~i4d7hQ`ma*XSA5pbcQ<|Oj^Ee86>l_=6>o|V3oJ+?H-v% ze2+|Hpl}kPHsOhJR;RN0W_T}31d~V-2 zU*Dfga;6X~DYjdg{=TpX@&p<@BuOno?T#~>Ah|-=8uU%>K1~x(=9Q`c_M1tIG$e2H z`Z%(U5Uco&V(654^!vyHI2FU^4&;;mzyWYpSeD9NXC`y5O%5eU(lD|f7nGT+Bqcu1 zIMZnkQu2a*GE?)mw-$nZ--a1Fx8HU>qVZd5G7<8l{ndS`lOFn1qWYBqHLtM-MvVLu@)S=_$JG4=wI#ym5Vn}JfRmGrf+wOU&H?4Z(?xU^xniG ze@$#XpjuHNn>Dz*I2g8{~v3uV7dSIkvWuS!4o{G6_r$^lH=)iA;bOK*H7 z6B61t)=6V*j0cjO!3FDMRBl_+-A!jJrpyF-p&;RdOm-B2>sb4>jbHBh7|h2ts3 zt+ohZ-wseDI#70LdV-7ZlvH1;3u~b+%1v?eUYxX)LK3%8@;3Ocn!&S?RxHqgc%=dm zV=KN>NAX(`wD%N&|Cb_w`Q;Vc&Bi-N{i3LEbgk*C;__X3413;k$yAvl7c(8 zkMDr5mATz#wZ^={P9a&jdm`s}(54O5RW0|BMIHBIP1h1{WO|siofC9_ zAyfNljtMk!H&%}C@!4USyt$7it~vF1KT}E-2#@TW^KN;Il&tO&m_ za-PVeWxV7kKlB|A082gkkq=BVK3DD9WtqiU&28`~8(YyF(zhumNDpqIdnAay;@GS5 zt`QvGP}F0+RAB}EnVpP&pM}z7vsV59Obf$UlqF9q6t&}8?D2S4w_S&%m*S$3RM<6( z!q3Pc#cI7I^W${aO=wBqZBrw#8|)A6VV@vUyP<=rP3j3{2CgN$7rMv*Ut5Q@uXT{0W83O6{ME2T#mBee8sJMnYZs z=eY}m^Fus=V}f2-=gPu>Q_^s?j0G;B{W0&pc7OLU`M6Cw+Q4OfW zfK|-mmYab6;6jkmmI;_DPB(r@H`VOn=!}HXqBX}_NGs*6R}BH)SXaYU+)6LY97IYOKc)pJ5H1H0F*Gf!-9MwKeO=2|v}Wqg)u!JWVzC4lWG8K#VUkQR%8~#y=L{Llv!Pwmm(g??t9Hp(bS7N!=E(~g zt2r+Ux{+3KCmN%s(E11QUMQX59||K{f651j&*(Algz+0c5SSr!NlG}_wf&irTja_w z12%zXgM4XOpTtU`NbiEvc^`;F-4-jDr%ejTXWp(Wyv#>0TOP98D+HEtxsjv(#OHAn zTgsG{l%I^%?o&@PacPPM=(>20p;gb?LySYV^WS_;GO!@UR7D4!nGAhTZJu2Oek)?~ zV`B7ZB8Xc&nGcYGx-IKFjb%=gDQg0NYF&Psxt+D2QMb==*^9DYEbgCNZn5QWYsLpZ z zDczw0Qqmx`L6Pom_|3I8_)aU&K={9JMKTaS!>OH=JP!BiO;kx8A&;P=gb9} zuepyW=XAIk*`KODecqnKIUPBm9UoD^P+LvOS3u?~g0U}ibKSfF086V!kd)a{sJhT< zTj7f#n?j9s-)i*Z8r3Mjf!ryPV=oc~@r#T*ZBLw#GbgrbN*caM+Hp#E0Q$L>Mn67v zEYIIy*Q@)&Yb9re-;-<$(b2X(jN2jZ#zwFBV-|ZZjekgHc~^}EEY@5s zq8^&h1JAe{)HQJB4P{SH6-fo(4cm!Z*EDqwxL4~aD`J?A8Cma@wb5N)bq=}sxL|GJ znk{Mj;m2+dZp~ebf9m6A#QwD^6eoOx+zqo@UTC}OHCw_K*(R_#74h3q*sEuC|5Dw< z@w<2AZK969#R$>pwsCJu2(5G3ZuNUjuAxQA%P7Roz4fR_Rk&+L45(O$0_}cNM+euy z{vd#D=Dcmi$IMJ$o)VwhP%5CP^z>9m3|8H53=-K0C@dtX{IkE-U!38(cK8R?UG;KK zTb;{RE=C>#-s4qrrRXx6jWU9l&!2|4t@dd&VtQJV>BkM;ZTn7nT|c*b~*){@s5!94~QJI zs`TMV${;ajURYPaiC!2EVB^5t!OTVD2@h9M-8CtvI{av6s77l^ec5LCV$Rln=DXbA z#%=>R@!XSReos3L+B047aDyehM@AEpqU1#NsQq8!$Ae(yy-XLGse3xk_5NQ;yyH%b zS6tZZY~&P#`bRrBaPQH*qxQEU%8=ptp&1@gcL|cXV)C?PcA2APDmm`gxvZ-zaVY36 zYuO1(QZn>OhkJdMzgjfB1GwBi>t3}nZ|UCGdZ%X9;0mPLhjEJoPI>l1>Lu=$+JQT` z5)ox_FYP}wkH!=})cyP6)==T%r9D*js_C>^I&*PF{Lq9#T7+KT&{YWwZBh{cfmHCI z4a1JqanM2p~!kFTIf=XwmAW2r?_PEcOZPIYAHEzIS*+blV>hE zhSF&8Qri)`5oAL)Qf(AyNexlyEc;!V2(J|)K?iW1S*T~)>E?vs4pv447RjI%M|DBZ zpK;CV=n1lsrHHS z$$|afA;J5GTDu0NS-e`>v|`Ns$6eyNfm6& z+mA5ZkOZ&b&Y9}y8 z!@hzMA%7mSw7&CHW~x+wh~w#>`QE|PwqlN}q@xMPG@+lVE5_qXue0AZI0T(peSR=8 zV}`T-2~A=vF%D*M*rVcZo)B1|EkcR8ZzV!HxbRwdI}flSKefM!@zB@?_dwp^fm~;7 zv-|3Mt;pi<%hfe46h8Z64=MA;uWA|i-Z)`Le_B{rpkldXHemh=kyRgw+xPFiALsCb zrsdnX2v2J5wBRV!eheXwaGtVQ-R*zOFQpQ5My8^ab;0!xs`_&_&&yGH+_X;;5{AELoZcQ3j5jQO_N*$D5KTem(XQ)V+nuz4_GoF! zlMFOel+u_LV|O{Z{5yY8j$;2UHI(sdV#ZS{E?U+M%6L)}muGU*(HwU-$*#@7#{kaQjdCA%Z(S(DxRtkOH;@P%*;qURQNq8)5vzmg1 zT%^lL5>nCjo5e*A1)8n2)}}^(=4IoW28!ZujF?%nht0Pi?_Se%M)9T}bN%+o?U8){ zK^{-VgD#HZUZxN&-JNfnNUoDIt;yU)MuQEZA9B8E9Ef@@myh`gw`KmIxelVV%64$M7i64FwEv zQl~~4#5HvDQxBM4nE??5TrO8n`9?PWX`qpOCJa&!c2mvu`PM5x`&j7KHtKGLZIc=n z#rDcTDL>Bgl!wzbW<2h%$`?cqAoF+q8Hpf*r?LJh{Gfr_eASs$d?iWyYyMo5mO3#s z&2=WA*85&U5^dpmCWGKuqw@WpGW#gqvzfh%{5WIw_gO=QfhWr$-CkKf?L$-JD5hRU z)*LU}+?|HQVN8b|3W@&QH5g|Z%dph(KH!&<6dcBffnKo~`Y_%;x#%m6QeMDU#GzEE z?#5M7?UXs-V*QTecdaR~2CbL<;X3hH0?RcLIloKMJ^0o4ZJQ_=*(t=InG{j*ap6PV zg4Qo(TUko|FAlsDbj^(_4C9_FxgDJ~Xig2u2xXRdnftWLzk8edI@TlqbFyzLSLd|{ zk^r;LyudAt6Bon<+CsN3QTl*?URA^YP(y>0In=*59cy@K1VbxNlcv15>t;z5c5Q1$ z=svaRyys-(xfsGQYe^_m?^6HWq&+vlO=FYDUidgsQ_Yf2<_2F(6=ADL?ip z@dp*xqd3&V)2Dr)@4UQ5s8>dYDRV2R#{ko-`+uDGSCk;Nb#2XT_ZKxLP4B4n8ACN92TC7!n6<`^3BE)QA+Y_xV;GbTVmC_`>p z6RHlN^cV5nWYix!UP{A@E4_m&Mc_wHf+ocygL>E@;i6Y3Ip)uGXhb7%Za%;p=I{VP)<0ijr?S1g3_>`U4qdqE9=mm zj5rcB1%++j*(txF0uhR!<+d`Hp|Q#dIaIYN%a0fCOf+=3$}t+Vk7i1w89tk!;s^L{ zKDeS@$^+$a?!GwLiKqLum912vdi(kwIDT5%u%50BT{D#&+bGdj6Y3$+J3hXl8X)RWc8BX}jb{2oWL zc4dawq*n>`<3S^BU1(Npv8H)$?Y&;|V4hFob@70__0b1zY>?~qtcdLU?TZ3W)>COO zdknhUWGVNn_8Ox`RTU??H-kYeisYhje%9HI8cEm|FD$W&hsZ9D{ z2|4ji?@WG-!j-BGb^7pr=#t1&)nI^l1$z1Rmq^!Hh&`#{ zB!R*zJr<%r?&)=GEjJsvsdcj3QB8^;^m}mK=fQ{KT)j(i3%AC8;f#FJ;%I48xf}G< zzrn9e6`-_1hPvI_4f44JcH@J_LWF3bc3<17nQ5{hhhTl00}})8h)8+IKdKiVSX2ku z-Q-TnaGmhnlxac6A2GIe3@x%=HnBqDWrH5uu^+8Z6|p@bzbYTcC<~}o{H##$bWA1f zf>Jg?Cnc+P^3q~#bUCA~2Mr|jBd)UlrA1y>!wrS{y#;U1ACe^eTq)CTWr8WU>vShw z*dW$-dE)UrrN!4B-_LVQu1bu>_ImBhkUNFC8BYEzAMM$9;&g9a0(^S#zTO95F^Jc< zytMfi^HWup-y0n?oK-mrEZIxagou5aUO=ee_sjkCj zBlRy{OTr+*5q}C;C3;Bl*u(GBGyrQv#u*|t&f4F556!Zpe5Gnt1u-{ETrKf%BpYf~ zIWdG22KNLgQ#1o=o3;!6tDR{Ic`obTrnVz(>9*;Mtt=f$XOh*)ncck15OhnbqH(zgc=#d zZ&KhQCC)s3O71hspNL)A8Yvir7X?Wkkls|I2;7<6c~dk7^$cZFuKVN-f?RR z_jY}WZwrwAd@3+v&6*Gm^vH+$@1hPe!bzx}j0>s1w^*`jQR$DbOWW%ZLyI|W?ds+6 zo&Lj^)4NtQ)=gQmV~?_H&QHAJ8hNg&sb~DdUK)$)Irc&8A-A=hd!l5wVhCQ?^xt1e z#ED;4>9@3*q^a`#T9=V(aWxOaoH4;@txfhukCVm4iw{!kzhv-!%Z=$j24L3Sqi3fXD9_$2hFD+Gg{GgIZ~Kri)i=SC;DVc6qsP_+ANEho2NnUy zN4-~1%NM<)dvU-Co+o65-o2{D5=C`Ab!p$@3zM}z2{`75Z0zZlTkDc+F6fdb)`__< z`D334M>tyJ`s!s*8>LO1VV9!(liHI)X?TpY%aa3AQR<^H^fV{UzBYzdT#NDTPA_;p><387sp);FIXWh zhn)5dD8dn9PF4|Dz%mh|I?4irNV3fdd1sP znMr7)HKseiY}};rPEO24s8#X3&RxnBqdS7{11jD1TWB74*-I1>+C^jy(Js5fMo=4+ zvQNfz=<$y(Im?{MUu9E$mjC(JQrcaa=a`zty!Ye`%)qMlj}MPty(MQ@BlPJJagpTx zcFMi%I@k5P3AIUzOy|XX@)JQIA*9(07Dt|}>35#6vRfE`SKwYAw@aFlmS+zEd$#IR zcQz5lX#KCbn;B$k`iZ1#_csjY)qtrh>4(PKoMm?7lnDFL{3#*Mz}9}Lv07!GH4>lY z+V?Khe=Pb%Z{i9TF*D{Ygpp~jm^M+tmN$B6?unZ1L>osxyPHc+VSC{d%%ai8sAXD_ z!z7h;Sh<+yfZ4z`+s#F)SL_9YGI>!_KQCbJHs4_faS`j~m z7GvNo3f~$(=3!*o|8rzK-4mWtBdBd}<^4MkvJPM&NTC1fv#_SvCGYw0S)Yu7(1Jyz z`#O7YN9jOe?e6bKaxL$5sOi=)G0wjSQzAFR_Ds)sb(g0j2LAzSzS5mtvvItYrSIM{ z6)uuxbD^!#FFfe2C5Xegf`K7&s z9nCanLSmNdaSLXA_xuLArYgfOPIr(=W2k@=Ux)JtL2VN(BV?)K?{+LL zFDn^ODr;VRK@!Z}@7Z1*L73(?BimnCe(bS`ubRjSL7fByqC^ z8=|=)2YPEe+MV2koC1?k9t?H`5}+g1n=b>;AkIDCX)4W<<+~0O6%^4N+4JTym4Zdn zBu)i1?uFU(;j}8(VI$=JaL8F~(ycb@;+NtGg@~psUfg;5`*l^H&r+@`TXsKZ>`|}B z0|yqa{d`RXAc}QF)|Xi>BC>3r&Pvp&qBH2_6A&l-^%%e-BbsOh7QXu)*dR8hHRIr1Ma~qKh?Qvk-*5uO#w# zHNapUCIB2EaCIAmXsmSjtoNCY1NhLu^+zB-=1->FzU!aYvL7Ac>rS+C45cyC6cU@& zy5M@0*IDe(K-PP`=Yq$uzyY{Jq!|SAMn?4Psn}>?fcJX*@kvEqvH9W$YT=@F2x8D$ z*Ik>!)RnQxH&G}Otka%d6~qnRJ9W!97|z0@rYwJR&#&m7x>l_&KzBI)(+uN{MB)I0 zuys)_05^Bpj#==m=hV(;wWag*Q~0-WI5+}hpSQ-Nle2i7egP03+A$_OfIyxC!}*MQ zaU9qTm5v!Zfh$-3WERyMC4;mO6Mgr+%OJ-r!5Z)G6A7G~V@!KPFGm(YdV=)0chz=x zcGOg7a#{4ZmBjEdfS>db+|(jzJb(Ss-WZS1ixq_*Y9HnJDZH`VLM;gd{G@TdnazX; zWHO`IPD?@tfMdPz@W5qEa;w*7074c|+E{KR`5FFi8K3KDRifaVcar2HxMhSaHZUI9 zSHL{AxX)zLWDWp?kmlvFra2RnvBoeHe=_0cJ!=cYlKM8LAo8iyEapkt6^HSk_m);u z5<&tx0L1#zQtllSPH6gaVV_BKipd~e_TQG!^ALf#3yalpFI2tDc4R$|H0dNyX-G!=yN;i;F z802AKV6K_yBl|aC%m$Md^Zp{+VQO;_nv`c26ZJNI zOB3qy?#kc(9mtbpvH@}zPj`E>4>9a7627&X?v?=qb(&qfm`uSdDgyAOW#=-* z4t7^Y$L51VuDg*`57KtR(OvD!NHhk$c>mDFD2K5 zROYe}Te1hxz0S_veZ*Fm|5C~}kgM={N2>FWJpe`~p`8^~n%@eCM4MG4t-~NslUJ^q z$B%Djyv*bavk9o#3sntgr!=n~zEveEZ%o%Mp98Wkl~hLfHWjm-)1EH=#$Caoq7^%$uzgPF5YPiDT9^5M=0LR`do$br8+v{k8{Aj@*`u824nMBAnXl=zoqztB zp_`N4R)-_SL@QC{WZItDPbxTcY~v&`a?*>f`zNQSPX` zP3o8hp_c6*0cy#Os_wwc$28Mw?%p;3V4ExZC{+l(?s{*>6)>NORR!S$i_0_vT{|6e zJU8nTOl-=m28$o9=Om=o?R9>(yn1adgWI?&yK>t?pFT0v7(-CP;9jRXk~wZ8RK-C+ zSC30^^;N{+Gj6vt%eaU}5^n|X%|7W^Giw=gu~$)fv^%tx_jkK;sd3OPv(- zsHbq=Uc4&x@|qLj!g^w0+0lk+gf~nWjr0+ zp9sz2R=KKq-r`m}f zc89lxwf9;DEbg2YXG(Dt4gNl#$SLF$!V;xU>oNQJSwmqLarK-apEfu5&O{SWpW{{# zA(FRI0q1S3g*zHejClFzdP%F7 zP1MsK>iJdEvVgGhWQny@#b>Abdnq7xTo*0DzK_Qn=C^BT+a7_N4xI~bu8>XZ?$}Sr z&N_aKO~^+lITQ|i@0=pGro|B<``EC*rX7xR+c&-AZr~@D4D~2yyrOl>+ma~rWJw0^ zsZj16q=T-8_u;&X7Y=g^&nbm*(0gGuk7YNA$?n|Ji_*q*1-h-GuS^aj(V%VBo+!6L zxX=jD4Q~JFUa^T`l&LRkJ)sZMiTf@R`^?io-TlebJY-LE785h8HF~3Co?mI@<%%f@}GY@?G!NDfB?7p0&aq6+OZZfNg%{(_V#p`6+kIKCB3b&W# zg!Lq_=*ZRI;GCJ06aB--&s*U^I~@LuvgtD#tuK$MfpoLFhe9EYXKubpsfIyK8+0GL zW!^t8uUBNF$IlR_eNV)?|I~%Rhpz%lXA8JcB^)wzcoNmy>{TuO*aq|$ylX^ zyQi9Xfk@|gS8WwZPpeQ~Z!<3qk7SL!f&1etV?TkVgWN)a((u&jb2_CJf!gc(L%A*{O&AjG_1Mnbjg0V$ z%m|ESTxBO;v`&4v^}^&JnMvPPf=T;}^kzRM*=8FwnXkGW14Q5pD~-6wR- z%z3gcsWjRA^@;{Ib2)?q=i>Z6wHbz7~3+ykL$I~Nt-Yp^FPhPWAl0johSJnIzKUcRXB$HxJUan*QNct zi~vATa9GVh?l2OXc=+PxEF3WD8zt2}ys-0<+mJEo7VqeLlPQz6y5j;4-T9U1Y&u4E zuEaBUWFOE)L}ywiZ{T|lK`Q2KEr#n^)_oqvO&AGu_Q2;mmKk9ttR5mkR{Sn8l}S7! zGX&4?$eBOQb$PhPva%Lwxs6k4gHFj0HIZD0Ax)rLMaBlw331TZ&n-+g`Y00|FG;!pVtGpAe|~vI@;ztg)U>p zGjIM`a9y9zRIj6AfNV0rGuh^T;!rwlMuI)Q;)Fr^xFq!`?+=0_dEGn|C&Hfb?06M! zkJZF4FPdc6t4or2_hoA1diBj5z4m}#OMhIRtknnB8UW)`9qV_K2leCuRP~Cs*lg<& zrqpv~q;+0H-(SCJFFo1SdZ`IlYEDBRcfiBENxwDI+ihxSxY1JCgC-`YQ76Kdez$KA z{!^*aEUbuo`08ffPFU{^?355eil^2|ov*wb z`((~K7}Mfkpu8h=zc{6Ww!-q4m8Q;^R+oM-roc`(BXfDyga;WbWZ28t&V^n)HzGnx zMw&1nLct#BNJs(yU<5yQ&d#>;a8gf^)5{du(yRUb;XFf502|Zbv9?R))3(J2T?M_^ z_a=C1rYuAMp3Krm68E|wYl4B^IcTvw9wUM5Ocx@K0iQtV+_V)N=>@uTn=AZ=`w%3 zev*?b>7v7TBi-TQ`Hb1tA$8LB>9bly96Jt0RM+!GWvRb3?hjhmQXYP4szD0F*&oi4 zBW>FWYhzpkVV}NG!Yb{LnN}lB<2=#!bJkq#>cWf0E4{go+}15#6z2N!L|0ig=4r^~ zhmm>q?Ha$e#4eTEzO{4>8D+VxGly>En88EqVNMYK#u>frsrvV~{Tx?Lp)K`KPoJLt z8n<<7tpO1dt4hhHq^ll*8FSJ2!ozWY>w^q+l_gV!ap!Kxjdc;{&J|=va;z5FK}_3e|q#?#R`qh^Q^VjFQ2UPjtDaeRYO2f zh&G6%eOF;3lMk^D#WNVqc;kyn)=ITciYWS%7w;r6%W_V;4d?d z_Mf>_j;}8lq?ts}sJZsFa8V(DE?@N4nRM@;)Riv^W7G-TiO+t?`w|-?{=?b zGbfgxD=Hk=N|vOUzvDpS(#(+AV3lQ7 zqyXjJ39&*jTV()Wr2_<;vznjGuTM8S#w})iI!%hN4=6}lrDRD2CqYZ z=@~kG{Vc)3sV_2+-J<<%fQ5;Am5X}3+tkh2S-puXmE=1$XdfYxk}$j{kK6h0zHiF( z^kvvJC?t4C)XxC%A9vJ*9$uJS50J#uEtuflOonwh{|LD^I1mv!l#KC@K^B1)@ec+l z_mnR9lCAjPeW__PMzT9{a9Yr=|IPJ}(Zn*sV_PNz0bdi4pZy;CO_=XVetkW;Y^|69 zay@DQ>g!$R?NknS-NvLjQ@a8_Q?#zfz25D85|qY0py#ft-2pW9n}7`?a+d;#;B)7o z#-yv_Hs{1eM4?cHl6C#=ToHa~uph25aUvs_95TKeTOnYQ3IBpO@MZ7DNX5LE)m#d& zf&(_(8#1F_0_UIF^XShv&F?ulLafotjgD5MA15JY;j#X*kH)qSq02}Qfvi4_wC6z+ zY!!4^9}z?@Xr2(|;dRiCqgmeJXlsKRtxvNw90%7aO2u16evi}XReVW+W8Cz3UB53^ z?H$_pPTm~E`FSE1KjCQTYm;h+N03Wkg+TAp+Ur-`7C|8)gZx=7^d9{g~! zzm-BG#nrFKPI(eQO&!%hbj#V|hmuw3AA~zaL|}*kM=x{%i}6MWRg`Zv*^LQ{$mFP? zQWjpdSfFy~34^~7?IQsq8O;7qzRQlpr)P2Tn%bly^=c{{_e{K0O*HIy^r}W@xju6g zM`R6WR2VzsZ*;6h7Zf#TjVS6>^+;gFG2p^vH?n>C)d^K%3v*{((y1;tKd;)_b-$h7 znZ{7j?{&}|UUA*#m|AQ_e}uRqhux{jQsY++qM6&T3pf^5fUZXCE*HPtoF}`3Z0b+T z3$zzY@hK}4ZrZ&=1pM_Ga&;iw2Y_%VCBq5ptzOsf&vm&)>FUFgEj_2__+^n%*^SI% zp@D{s0=)h&qMV3a4)^OMId{igw9DS%56cD0QvX25o$)@gp!tytLzQmpj{OeAq7O8X|glcmp`mm%b6@h0#r z7IyN;{@0(5dF^|O{`}X1$kn6Va3uitjt4Sdskw&|U_l z!fVHqN_tltCKKoN4wduF$QHWs$esDhHnY`vAS@3070P`qN5CoINPV|i_!wTHQ8WwG zt08CUCVhnqUg}Ml9_%6ET}$SJra~Yh3G!xlRX`&oA!l!wzOcoZzG#;lD#L2`TmzUb z5|MXuCNF7&G2+hK%b%h*U!}?g>rZ34k;BMr{E;vvKYNRS?8bYF@((C*`gxiTCzoIm z0*Ec!QF6Zl8H_O!KGPZ<{A1Hm(S?L&30(7{0K4s^q2XH>T#5xC76X*p2e~ zU2r=}LqRbeRJjtfAZY8}8QuI6SnCH@07P8RpVQ|=`1w1W2W2IeU;im%*c~Bk*oWN% z<3kJHMQ$B$V;?&A8Plv_HY$4uf#+lD%1lqDKpdE_mie*;8~CP(l}3%q4py?U_9>p| zeSni~A+hL7@eY7Vbzfco{8GV_&uLmM&uwK~F*%O{J8O$l=V3$6wWp3(*d7N%hBVJ; z_UM?>5vww&gj zGJv?(=?RQI>xEzSSE70^4#VJg!tjOS?(Z#!6Tltpc#HD@2msH0Xkpf)W)aRn4lk4_ zo`SFboqt!^;o2Uk{}3-?_sE*E_zPanuiPTRFlA&t6E7bwbxQ98Xz3@>ecn5BE$}4; z$OR%GUA*o+fcF|_=5f1C41#9*d;9GNbB*OX?y$DG{b6D-50TiO{G(fNnz+0xDrJEl zOstDl104Z0U(l;B1Eo`!_2rpH1Mo~v^T@7(Mq%FtIfLzvPu=t2zc;|lr)WP{f6hhM zJ~rg|tnmTJ>ezcGvHIcm%x~rh-TOABQ!E0OJ)C*Kh?eNR^X-zvYw?&??1o1Z62pc( zD*jJRx8Y4+cDek!1`d;Sh&~LvR>yo^DnHY|)x9UL*^Ist;yvs2 z^khBUM*%#;O73%6!?PP!NBA_WFt%!UHrdH@46r77A$wzK58N_f>HO2^8J;SPMKvgZ zZ)5BFmF^971$>Lg6~&>tLMjEy$c<#v75bHT^%vb9>U?>MLM!=fcZx+7ns+9BGFF9L zfX&iG6dw$f}5-?WW0n4{_b<&pVh$vt!T{ol2LL!E8_KNEuYeEcgIBnKR_5qHYHqq>Hl@})Nmp>N9 zc*Q$SQN~jpi52hP(2vHJ0k@l@PqN7Lg?kbf){X~Ya11*?>jyapFgnmxkoDicK0uL> zkdW$=i?%{70zys^_Z)NvXbe+ZRRD9f&a0IiKo}uo+k=s0*DSx@sDB2u+4tXPygYq6 zZeLw@VzGo~T*5V+h@J}^oIODQ8Tj%njtb8~)}PVR1y?~exw z{J2#kKNPdK>jl7B6ftQcjJQBg2z;ehJlw;ZwC405%iy*rdLPLSl2t@R$sdM>sZ5;s3_)z z1zE{$6^rYbtLP!^Nl!%%?=cptmOcglwMvK~y!(z`vh4*obh}2KlLY7}-K}a|3M)BT;RfNvtrS`DMl&1nXdW(fPx|3DkN<&4 zx;-kaq}vk`&s=}hCQX>wibtH$#Z?Zx!qImXuOu>6Yu(KkeNN#1bK)3RXzCNi&RVnE z#fo4o%JsIG^1gE5U>DJD`I?lP*)tp?=~LN0_{3Qf`q}Vx_A6F$m%_YlYh8s1n2CY+ z?6y+V*CEGFh1)b)P)3|27e%te8s{${d&0_YXiJ*+KLA)9iV56PYcstAdVhJ6;16VC zPF_bQhPeY?EL<}EA`v4|H45V1>onsK5H@Ld&s0IiMDWJAnT)}~u zaHlvWb4v+4U8T>T| z8Cs)RE5dQX8MpMpaB8%s`N@>uL~5b9W5^H|5oI}p6WX>~Yx2J_Cf&9~=eT%j{|4N_ z&}<}4`yv$U+0JgOSLwEBy1~KYcWNo;8KAIm&kv`)FOs#vQq)RlOM1M9< zkb%J}$0Bb}Kq=;0g8VL;@evU(tqcR+E#pv!;aAGSz1wU@D#wAEX180uFzVHK`%y@r zmBcpO3BQw}Kx@Y^kr)~KnAE;n_M@gEz?LMKZ?a8oC4Iywr%DD>AerDuU)LQS&A}vH%8Ta3p^h z^quk5HUR@WbtCn^)&&gyA?>?mKV084!wK+0Pa|X$L<>a{l~&d~3wV-?PH=?%2(M~kC>NMPr{2TGJ2VU39rDNR zmBoJ!PhUzlGWqV1u3#=7Y*NCj+a{1{42Ro`pGPKs5~VEitJgH^1u*K!4dH^KW6zMH zMTaDHIoJK|q0NRUXpKB5lxHlEpiOEBguMb%hNOm`gB_#c&Jk~w;-NgUowA8g`Wn(J zbpnX$RpTsi(oE4l>h+zM{4$_jHl*DX_n2&dc`S2A9_p z$H%?GFCO_JIcsWt>}rxXPr>z3A|#O`46^dh(Y16q^h5zurHM@xxG5##M|;T~e>9bC z^+zjKI+*RF84$7_L)m@(&f?HJ_1BHYB3-BSs^;b9aimHtZ|Z=GmvfzNZ`g>$b1cV{ zz6cYR=BSLn8L7;IkZ}!`VDP2lfLH2O%2gske?nT%=M-4(i(Q^$=s-oyvCJkBiv3yd zv6~|S9Cj-7p@cAL81iDf0x2iBZ~;e9`qg8?{`hpe&khiJTf(w$eDv4J^%nm-rT(MG zbk#0|;{T(lF{JFzzdT~4xpU?;zh?D$!%<0ij8bQ@^a#cO!_DK%cKGdj9Qx}~VZqVdLIoYki&{ipsNjwO4{&<{Km!Q1#*4l0OIY3Ryv4tR$V-iZ#Qs|L{Z2**El#HoxkwvBW)S^9HDZ+(uxo>OOwtj9949-waE zQT_z{zV zAWYB07{0OMHX@|mR)r<)_iB{A!*j|cD(21)CWu00M8+wI{Z`m#(dWw-rG$B;RL4WFz%$d0a7S{;Nq}3_sJpGy zKTJap7wWw^h7g-s5{OPR(~#NYU$zl8@Zt17Zk_n z&#=SJB|au7wPORqm|t# z%?Kz2k5sVVM`CfI$}!-`txx02kyU-uO_?5~&{5&ckG#aabVt)LGxm zTZW_m`Fkf^Td{@3$t1tm3V0FoHTVZ342U=?NBH<8%5LV~gbX1%_eC|etzp8UE+OTD z^n4Y%TzFpvc1#j+5BZbq*C37hx*`m-9o#7S9qbiZ;6Qv5Pi?DwRJi)vp^zT=*$Ob;izb8TdAW8q->E28liZbY5p?5sqHzg z6iUw}grP8cV>cnBES(tCEggCZ#kG%?Iin(jkU!>V=L`*Q7>F914b?OTqC0e?YLqsQ zAw)!mlx9XLqfAZ@)i~~`GrdyzrHrU~zJ~`se5s*X+R)?o9dkM!R?GU-JRS+GLI}7U ztF_WXR91q2)za=`_th?kQXy30gH%3-YQt=5$6S}or_vJBoS4*A-<*_uu6dAG>w@%g z8WDb$xM-V^zH+nJ5`*Xf?>p|K;Ft5H9xxuJ{ExP(?wKWqTm zB01sEEh$!N%0)VFeK&!0ZiHtOMQD5MFMG*6i?*Wc5>F_>)1g zE(ez=(w!g3Tx;WujFV+bGrANJ_-4df6lPkH;b?j1@G*gBNAYc<;ZXY(sS%o8M5Rqh zMkJIlAd$~PWX)!lwC|{%6-g~{9fphHmAMm$HHO(E%y?G;?jw*oX9s>p5xLK;9tDft zj^EUY2RI8j$m;N5*A_6?(jHYipq=_~c>|NrFq=Z6LUp=Eb;4CPC3rN|xL5+giEmY} zy2_|Vk4M5ziXCQ3^r7H%J(yAg5HQm^>d8J|g+>zP0ElH%k4Y>3CB)**yLh4FYTv8$Q$=a9$0^DHRV}E)_Xu z{*$K)MxPO6b7=$zc3-f9@M-fOELH6pR4t_Z8mqWq%hEz3e}j2sMyyOmJ`EyzMA{KY zSt#520*B$;6Nd~X!%icl9EnVD3Mwb)o}?AY@C_YxLUWV0Pr0840qaURQuYQ5?d{>y zcqX|t+A^LWOO8qiL;6q5G|x@?EkLOMXJJ96otq^8t}GE0Ql7~85C^SB+mbHG>d<(W ztP7!WU|Oil*|*iF5zwn%Bl1%-35DgdLKiHQ>d4TfI3J?jf*Mm_gq`dSns1lVM5qZI z^96a00Ar>;KujP}N3#OX^O3$Uh+o(v3ixA0ACn80d-B8S2#%dO@H_qp{2vU+S3VVLSopCgUwt z6=d3{(~#XG2u;^@{Z&gTS7&HfOJG&`s4$@vU30$Zvv4zxT<08c#LZZgHq3XwA4m;2 zSW4a@$C<>WM2j>FYz%oB@!xkHXl(GAW5HAj**!e?Q}I90ORtgs@9Cxgzp=&t{!Cvy zi;;}hN^ccT=DPAtUaQ;`8?sA);=rJ9_9+X)+!-Z_WpubB)4@z8Ah5>^WgsG@rhVrv z)!G~n_+yCl=h!I!p;^R~sfmju3=AoJ;JZ|>mjR;>qEDA{RuRZh(=Llua5(C^ZMslQM z%n$%DHhVaqBgMnR05i`=cs!s26e1W9%cABnh%;|Sgv8$wpN8Txo~0*Z`+AOL4dRf6 zQwZndu)RpC>%WN%)h-@d1F%}9JJfX)d3mFajoR@@c4E!IfcO55j68|T*o9=yC=(!~ zx_`(9?P|75{@XMCdeoW!@tJ-#Q5FgEBf39E$k&MG2Xg|Ets)j9V0JtTB|Pr9O(D8T z8i%m<#-kJeB`ypHVoRmukbM4El|~d1MyS}e_1ddr&^m)1QO71JJdu=G1BeCmiR5yK zlyr5{Swyp0L!=&Hexx|58r2_gK3oM`{m9G?j_FChFPM}mbJ(zEk_u$0Rd5+kO80V% zDElhMB6D^5=&@W)?QvG3pN9*ee>jE8sEK^$XQyZrqeXn;Uhd_-Fx1R8yyd0}7Z$vY z$P97lhqjk9%t510u@Ayy8!k2OnUSBw#8^iC*q+k4!AW zX?)6pPm~o#jF`%lm9RSosG2FwS%#(FGiUHp2U#^hucA^AZgvWqX5o6^L^;;?4XP2k z%ZKH3h=9oe9Q3qa{%-LHCqfP$97Azj#<4pkaF^AvEE|yc$^k2;$+sR zPoJBKZSr8phnE1b-ZG@=a7c55E@CFZ9#P}teWj5lhYV+~e37=f@S_%C1>mSAgftQg zu^KJ^D|O?Gd9~|)*?80yT)x`vwb2jFc`sNV2M;*$d%p7G@7Ne-Tz3=|c^q7s9l45i z#zPb%zKe*zFq0hiyOxFCI*JQ{=u?7#r#@^UkmCQ%H+ST1LH73eb%t%_<;G*46I6X7Mycn}t9={sYKIVE z=kSg^1;p9D^$^@E3(;5OhQYU*EzcntR7mX8|Fq~-_LTL{oEm^}KU5BKY(Z5z|;NP1H_WoRz22=`UPNQQf)}|^66}VoO!cWx>hm@*za=nck(TxHUNgp z!oJ_l0oK=#fMF{#CT9Z`Jvx_pN|tXfc~ZKTPlMu*qn`rZ%m@9FZzV<4MhZEIlr%^P z)q@0ez3WnBKR>AP>Fe~FIy&gp9YK}X)f#1+Y5-YO%qlF?zA{Kx*5L|ja`5}n@zgO{ zx-Z8upONSWB_LkZ&8#|%zw=?OjJEGG8KRgH(mOMc?cbHSJ_j&NW-t4;HkN9QB$mSC z8JJcxeZoO`z#^`gk?OF>p+Lz#0Bn-@nfsGC!?`u3hOTV=DxZi*m%aJwZUJ@#cte&rb6OUPg zC%0!7TqDX=?-rc@uTRLan^K4Cv9Z3M099D50xk}cEPY|#Y0w7x4x_N%0guy9`KITq zaAj4kS*<+t>zW7DHsD#s55ya6AEj#^B-AxkXmOwf7!J|AVRC$Et;>w(6k2VnbGkFT z)-X&bH0Q>oreS2cM)`YnQO{OTRpq6bBmkAYT(b2q=fE1>y)hxV{EkvVla8lw`0%ND zs+#Hie)r^liG^oM_my~-J4ZLX=!#jcV_P%abHgtf$_;9DHzhw-OEf(iGGqEvO+G%> z1XSRV;j)J@Suf{Wz#H8=Ir~-WR2IWC+Bsv zn0mJ1IwI*>PPWdY=>~~9_FZDkYXy}fqvy`v6#BTR>i3|pU#N89#W1~{w^er@m-vkl zcE_d-I#62>(_b1)yBwv<-9QgK^CCB|GG%dKnwm48UYN zvgE+)-zpM@r8sk*vGeJw(x$PN^q4J#3tbmQf0QPylI4<}?dJvgHJZg81hSSkbi%AH z_4>BWHyVu`MuWRI+C$fpP^a6TL{S8-i)opvsD1kySlsdIKLhpv=rTc>nW|ap|`uE zG4C}V5AUvac_s#Lc&DL%ij28vZ_N7$IJbmp1pk&k_R&vufsr%I5k6cBkL|bW(g5HjmwFd=F}_m1R5K&j$h?KHYVn zoa~EO$qQ6OoM&&2jg{mOWi!q%fPyP!T+E#x`9!wUp`E`=Z9B zC3vwHny=~R?o8Y%n_e+_9&<}c+)jIKK6W)%hm#rEna{vbzKzniF!q#5{(9QQJUlfA zBT0`4y}D@8Mt(N7x7L>)rD~e>jMYXQM4OJ>q_fD^$TQ3hqm|O)Ud$a`!2(?HgvVbNK(s!^AItgiDcs3g?8V*P?&O~To_e|w4u zeeA$T8w~kBx3-kB^*eZ}~C$ z_hr5I-CUh({kz-!LoXTm`%gk|1TNK6FxfUpPplN_V7rax~qKYN$3X=)1@`yTRY9^Wc$tSh4m}^FGC=al`xj3Eq1w8w1a)@i% z*5&(bcFeZ9W+y(HvOvB5QP-oNb=@7KTTBwgvvwKsTO1v9+Q|n6^xjwTV}*=MB>+{& z#5R9>AvXEZbbst>r)>v9!>(FI$kqxl91-C7cCd3Xs?(Dfwg6bV{k)yRkCZAs?~D8s z>D$>ML{mpEiK=95*I5P%kG>h!j*4Nt4#pz6UO~w^CXVf_S7e>fo#;%1S`>{_b5K%K zM-71XVEtDIC6}&dfAzKT<)mkEdaGGsXKchCgf(VYb{h#%ip@*KjS-BDO_v{WNzL;f z?&g3@Ro9O9ugll~QJ$hZNpk{L2~k7JlDB)xq^E6~fBpMpwmFxkThb*q=TtB6DZPh0 zG=hdc+aDLXc{Kc@DXe+Mz!(OVViB9Yua5l6E%~# z$`}(x*(mN1!QJGcAgKjyJPnNWu%M{ zr1~vAlud}S^K^HP(kUr{{OD~aC`Z>#KLzL@t7JKc))PM1P)NxkSuNT&sgs@>nidO) zs^f^T%78vp(&iAn&Ar}rOCvY&=_h3lW4oALn;A~im`I{I+#??qBMOp) zkkw2RV7abf5b3m^YLUYCJoVfm5N-iyXCw-3kVeR`RScE; zLU17I0SFe24vw(BnUD|UP3qZD=d)Xg|4scr)9{#_f1M5&tcH`t=syJv zrPf#TA>p9RCdhGSye8fy|9At< zhGOqmxkxD*+1U3CI9LoC2bcRRaOf4#AL}i-z;+A-s`fIYXHfI+M=G7B7HhpFi}aih zrB+d@?`K!%aVQ7|$aEQ0zPW4hn$5FPZ=fP<4-JW=bu({57yT{!#XiJ~7WC*}HT2v? z;x~I4xj(YmzGVZKSt`SjfYTx_re%Pv`1dF?v-=M&~W%E7_YNp6KA%a&3mq!iG2vwm;Lx1(4_FCg#gOZY+afx zX2=GfGUWq%A+tY{FGt0oLtk+q%vc5_y3zt&belNTmyz@^bLH1IZkB=zT970?2uHWPfEP}a7RvB)uQy)1>^B@56Mb%yrTW$_lehx@; zCNlxfaT!M-D@hOsHEq7rAa}|ZsBxX7{(!2>6D9|e}G;6h&aujs>|M! zl7~{UFRE8mgpuHNLpcllY5=@xh2a;A(4nzG1ltGR3i2Ze!SUad)_S>m$sO|5q{zC) zJ>gKO;D3^A`45mF3+?-P0nui8X%~wLovkLO5^QYKn^^R}9nU;_yov~3;RCY2Gu8z? z<~pJ!`!Xem?{5(t-STBd-r2%FQdO%>XQzF(cSmyz1NQ4%LZ6ygjla?5oTaWJfP2FM ztHB!@ht)zzUK4vhn3wV{7VtCN*8ShH{=F9X=qoz`2$b{nG=F})eZB-#%NxvRVv zk<7qB1nL6f%fIbu#e+94hxiA0B}g!*Jqu$qea126qCl$9Fd;cU zz~}lWGE@MH2;P1VR4!!xDH(I|rmd4O6cpR-(eTX(&c=As?TT*0A# zLV8INJ_jm52tH^)&3*p;!LtZIMd~4LjzggFBkC{l4O!B8RJP9nV$}yXk8nsa4iuV{ z7OX2>7_QD@{hGO8e=hu$PmC-<5;MePf&^xJlNh&d&jI-3SvWIuec(BO$I<=`Ts#6P z3vI(B{WQ_rPKS(%$oSVOafE^2;5?dZPa7F;PGhlfrZBROEc&k&D@htpU80k0Y-m-?sD88pG!S1> zgaus=k>^{R%=1RMM4mai&KYi-iU6#HcV!GXzVl>A!)Rpp?E>J1=WYDF;AG?}JZEiC z=eQ?KMO2Xv3iw0a@H$vC#QNH+H_iZi%WTc%+(WqG#|o{ zJqSS84Ry`VU9_89?Hm+pT#&nELOnl8Gk;d8iW;`H^JwIVm z-GR5FOtB)yOuF7UwiCHq09Ye39IoihT;=19??i==hAaYXNh~+=r5ub|KXAS)U(fm# z`He%D36;Z0(Nj{@#5Oui9IjnB(l7XO zUnS@tK`DQEsCFcfHa-mw(1>db!01cwo%R#kbq|OXtD;~yOzb4mHQ@P_rttU!|5U3L zA6mWj?C-FmKcJQmh!oi6|AZv{g|uuvL1In5_k2f@?Q)2yyzOf>b?(>KDHr0PB_0L>JR`&nf95J2^g^5=hmsXOp#RP7iV&oF>!@*O;z;Z*tU zU7-xWaP9$T0%>->Dv-qWWJUNmLqt+Uo()wp9LM3g36VSQyWcnPzwj)v?pzp)XoL?8 z@BZ>osR=Fu7UQH=CCdG;jhPz6zIG2WB)w1QCjPXDQcoW?&C8ZH!E*zhIV^`rpPY5dvo!Zv76i z^Z;i0wQQwo0+w_+V0ZZ?cLhRX0%8!zZ3D)|bB;_+?73INag5^g0BqA@3`ZZlqSdRlt) zdJGzY+DhSnLGDQ%VApMWJSJYj8Sad`y+Om5=MgAXtmj=E!Q%iLBaE0)9#2Pl&o^QX z@Z9@?JT`Sei_QizVZMzOav>;Yg5kTw_ZKhQfCqL^9&x;YxBBA!Z*TPk2_*+f2&E=K zn8hAMo*9g?y!iJtHw%@P_@}F6ppTY2NFTt6TD8>r0XdKKQr@HIivebw(v~_Vx9oh{ z-`!PdX4r7-pC?k!KyBOKM>apaMP7rkJ{A0nKz+tJz&a?>*9He$fyh-6zZzDHgLrW- zn;&sfNFc%K#Eh;C)#(I7Ld2Iu@Wr>~A%>`;3Qkdv7EY0eukTn7`xcJO$k*0lIj{e= zp;Jw&cO8B6+cLW8*uzg*+!{$U}g1`6J{WH)$bFz}U z;KP-(WPdjO!;s$3L|-odjvxy>aS#(QqyK*5|9Yqxbbte=?E4m(h@czLa}yh&N?l+? zo+l1y1kUuW!dX=6t48VvpPfRh1S?a3DHH37bD;iaPLpmo{Dz;G{`-kPa}obH2j@9r z+Tw`H8w-!W-#hV(eZ!;NcW)osK@~mT z8NpZ>R)*Vdfng3OiHOz8kF8#bH35IVw{PV+31$C*Sfnh}W8uT?XUR_g&m^9(=xjlR z9$7U?AXgQU1=AF9q@-~ayi#B=d$MH(dg`4Q4v>m?g!JMNJ4>(KW(0iJr#c-;efpdk zLN*jZb_n2X9+wde$DQ>P0xHmE?_d7W8XSsLl{K9@G4NR*AC)DHdYP4&3VfFjDTuQH z&iavH#sQ2_GRdUoA!{AuaR zf~j}9_p8uc_Sb)5PB!e>d9-gwhHN(8xPSuef#UQ!uV)_R>==;zm%|MMBE{Ln$e=Xv{_s1_ zKbzvC_rx{p%Y!QLC{TM;=)rxoFksZmj8c#-FD?cHHM&Oiyz~H))qAcKZ*YnQ$HBiJ&6z~qoDkwTi@G~i-2O=v7cKvQ z`W-C&N7j#H!*zK?H1Z$90(j_K&q1uT!=wDfwILkAfML&h2C>qMc!a3PM~EZXg7`Hc zKyiU2UKiy9PL&8N{_DQ;8cxLePl(JL1Ueb$%Y>I;v?H1b_ZETA2~g^?u`K$xa9fx2 z-sU4k`1UvJoW6~N{$}(mI7*LWVguUNKI=RLkFZ_t8;*639I8Mh^f&ALi!?zKI6l zOe);Tv;~3yKOC^mALCf((b7RxFJQh%>@(a_1FZ8V9P9ibl{Oy@Lc)v19V~%!;nnz? zbq=-hK{wN1alrT5iu4Lt=U?_%=RS$*6xu>vviK|eo+r)Q-v{_WXJScqp(;A~sDN{M zfj{r`2kZQxLOOkc{c<4DBm&5VS?5y!!aCn17EhtednEw>I`R_;bJFSm2J1Wlv5^4E zzi;IJAF$5wQtJQd8JM4jbX{iVYV~%qY8^I${*wArK0)bA_?2L) zJkXi#!|Mxz6^v-ON|DTv$H1SvH9;$ynY1wrbg=Ruo zuT0uq&(0XvQz#ds9@k3${o5?ulpoSHqB1agI%W5Olnk}D+B>oiE^~oxIRa-A)x19x z;U|+(tt%gwF56-;=D&`+B*+T6G0z`&?8N6)hTT(9T`Ai*Yf!Z(=1|onC1)Ak2iHhjGlHrx!au^w_q-Lm zRy5nJdyd&Ap!;q zxAE-zA8&oEU1hE;V4kLQ4~mX4EvH^f_z9s=pm20IT_jM5>(d6a{{=%088hz50dGBt zNVPqsPNSFku*5C!+cM6}7IXHc)USfUP6XOlCST@RauUnA; zo4c(u)wMdik&(C*AUt1`@Fyu~sc%cn=dL`KG`V1la+$qwW)MroG#rX2(+gYDfY-Y8F~e9HVo$asPFz4cP^qjsZDKcp<=` zI5^IX?DwEGzdDRuhu;(2=WwFcv_j09S~MF<#SUz)fmgQRse~lUwOf-4hhhZ`O zVdaMlPT%>WgPE4%*~EX6I0s7ZJbss7kaj1#jlpq1I+-i)(qztdOOk|PTShUw&C=W8N`%E(P&@kqy&-79Nq*E|f}hBlL% zU2?~F0b;kh#N7@%3%CH!$_TyMb%c1B^Uy{t8*{Y`u6YHl)D)^(kByw8E| z%eP^8dIT(ZXwg3hfZ-2-h~rTDIhPlPZuTBxTN6rT?{l*?7|ELhqgcjX-BO(C^l9>M z&CM%CDVL7h>pfXkYZJmKEq_tqDe(YOwq5o!m>p1zuws-<@6F4pvf$v6(YH3GmZSAC zF)lZLm@U4x&sfvGV>mV?5*e)scpmWH1Upoya(*f7hl189Q;sT!;-M&$t}hh4yQ@~a zpcDlNa|41A$i+sXh zG6;(Q=qh<1X?eNTQ7IwV>RU&SLYJoJ_S`V7_6G<$DtbZu>RuExa_+h&*k z#EW%_)?8->^(&KhIzF{l@m#bGJh!R4HvayqU#<9BYQ2KevC^Rc$$ZU8jZvm%E{{mr z3~}nKbA^_IZg2 zzjBm`ge10e#AF8+;ceaq6*sZp6W%?)G&TiB{$8@PaxN}?MiJ9Anu{O?v5BIXLJVnzs++3T9zin9`-=%S+1zP{z$)v~N>6F4s;RW@EfGc(n_tF+2BTni|W)0iOHYC{Wv+ zE#Tj546e1htwr}JUVh4foFd`}Q40C%;Mq7!=&Y2)?$#2uWVb;=@E8ER%cNC1)o+jX zYGheZZQro9*z8+*k)8%5Th;*qpgnolw)i-)x%)9~!#N#PWN(IrxnJn7dvlUILz2hVB-+aPzqJDkG-e@KFlM;jS}#74_yt==PFlTrl0Z8Fczz0C zLn~Le{`vgGu+bV_g4WUTuw-)cUQF17TFgmt#ki%cJoW}d*`hAnnbndxH!Cf_4z2#p zHhu*c|01^vGTorjp}hG6o8~*9faY;b;t8rxm8E0ibJqh~2dIi9i`>RUDQ^U354;jj zY&KF8Yum|i9pNaPC>kS8RSTYIHG%v!8?>eJCW^Gwl%v>{@(Hi&)J@9S)Z6r@+@vZr4lIgEHvI3KM}Jw)2uKVb3cRLi5WSLWG%}ju$v0cLJ^n-7 zihfS#$Dtll(-AuH{=}@>>|YUP=?WRUHZfRj(w3-Mm0VJ@7IQX_Za2I)Rvs>5=rQnu z%&4}9b;64JS6)m{$KPFZENQ1?a#1LnUVQs-2U}EzEn3EQTVii@ucd!q_8)*1o0o4V zgcFuiE3UhCuLpK9zEnDSeSQ&YimrmqUuL5!@J|o>wrlqE^QvP16 zvUYVH{z=`Nnh`e>+f_11g9JS+2x}}cSNk}uHohcchuI`Mjia-H3~epRO+x%t(OQ=` zGpu$T^BN_SYCnx{O0NJLe!^z(8K|LC)TAOGn|q7b$Zb3{M#i*z+v|u+vE~WFi*3;` zbwtLSk>J_n%YGos`f`q6B%9i|qe@0Up7yX>0ESh3K7&>wf8|zX!6`9pV{onmyncpb zz

kkv%pMZd9ov%NWIwM5>8zW$tIn2IVN9>z6;ZnD2TL`ZQu$eWrUc%0cgEy7Y30 zgU+mbyHHjJ9c1g_JIU~kNvKvAQkI|*n{)-71>&@v-CC>Y$i$VE43AS>Y%6jf+AnLW z-?-@)y^`ciBVtDu^YDB4#Q7>E$)@-bgMf`|$FEJeXEsZ(xYXNmh;9r6lAB4kv}9<~ z4dHXo>P^4px5r*wliXdBoXFMkpm?Oz#osadCC2rSZC5{K-p9%2u{lZ%)WB`lUj!A3 zO?vFkl_!hJRVen7c23QXbf!J?io%v?9?Nzb&yHSr$jn-=&LkpZbD*ny++Ny2uD&;E zmcb=DuajGCtwXne4iN23BD{Re2@9=%&0HsZu+)mC7P834Yd`PxeR|0;DaKtU!iSw* zt;+J4^PDN0)salHg$Q?9u4+pW%e5%?)5E!SKL9j9Q>J%`@QWpxSzfM8Wdy=N8_VWWgryss*MaG6pGbbhq~jB3NEP}EeYg8gB; zwbF-LZFbQ-+h@}hdD?~8*HTMGqfRl7Yo?6~khY1Z(?KnTat2*FCKh8|w()A)KN=n$ zdmI8>%FC1L`GO>EGlgBcoe>Y@7wX*mCx`>F1-|a%1!GfgJZswdS=etp?%@(oPl<|% zyDx;-yRzo0bp6b`rUkWZT%G$lZMRUktqc75eP>NyQTd>qcLC}us%ms7j%hY#`Z<& z-$^r`byzJi&kd=Y3O6d!)5>kqieis0=+{n7!^&V%}X*zj^8pbKgd8ewEih?YOclek?Y%8n75u zVmu7n$q94>q^@%V^>}6k~_EUyZr*DKRIdHou4dBwaie|0Y%9Q zgA7m&QGHjJETw7Mxmsnv?11y_Abz`=tH)U2=NYQPQ zB4b`;+{Q&rYekl6HI@f+Ry)$L-e{?!n=%``Za(BB)rilmQJIgQRv2 zy^X3CMNyIN(IIs~%kYl5+$hmC%(AOp9HxK5jYp&^I%Iq6JzdG!+Ao{@MRqZgHPPUy zTnZqRVqE$ZxNY__aG=8N$gi-nV)j}+Z+mm+5-1kKE+84r8mLY-0TX8LtIpd*FZJ-( zzK1UQx=#z-&ri1+9s)LYZ2SV9tY8`_;9~|1zUn7@UE3-!i2bZBBpUhD^IifkVQ0 z1k%w;tEIMRz4WW=m%5;QsBLsirXut~UAWs~Ho!F0enixc2Q%M54!sV=78?uo(-D?S zFAs%gV@pY(oz;AeB+Yia2h4ZIX`m&3))x~JZNo;QOo;h&(zFV$?*))?eUwM zmNho0hFocp$c?+0BuU@QbV6Zn{sT&7Hd9_+{g|2G$rn%cq zIWf6Jd8exmNW`Y8L|N(r3lW{YVak0GyPXL-EVbB)FqNe&QChB&(3^HDCR?;fIW4# zk?&DD#YYPCtW9jEk?u&6G^&A%r#9(gaKOwOT!`UOe==c%SIO+N_aWRx3m846D*#5mSg%NsaSi)S6SAw5-1;JUTF?aj z1Y?%_+$Z-u)-|Hm;C&i)K0lVTKFm_&H`iS0g;t~Vy>6gtdj8eg%`3U{v2QrH%E zKblbA^3EB!p?cJWKOr}luHR^;-H7?M0*}b#D~BI$+{*V+4LS#829gh9+5$Tp)AIbY zo6EEF z_91nzjY!)ICrh%}Qkx{pM+RPzK7B>_0a*{fSBi(%2G-B8fN%~ZrNorU{^MG zuV{UkW*om{=*nIDE+55J+peUsG4o?x7#k{k5nZzOluP+z1-*@y4oR%3wOE=t3e(0b zJ+n5dCm`k6wmhsWiI?K-?yD-D%kNJ`_Gjh+0kpKMt9RYRn~k+%vt!R{ zEkW}Qmnjw8=IRW_bYnD!EjCnXpae7Wr&;aqXt~9CCUlefK((c`rh7|`;;+EVsGoCg zFKSv^k~u!bq#{2fx!o*zW=ZEkQM?W`ZCn47NN5z0d!iD*yM1LbD-!iEwbzvc3q?>; z0v|niP7~4+%FKwA4%zHNx0<92<>UR3a5;0l$EciNL9UJag@2CDt*S~wsoX~<7gS&D zv@RMsC!TgGmHE-BcF9(oma2z1cx9^SR`s2H{UlJ53GBEE+No`lI)NCj8R&`PYpYdf zjGMYtzTrE|QAKZd+tRIJb>m}BZx}DWKM-u8d5k}J#V@_$l6OG0ZaxoWOB{Yb>3L>p zP=9J#=LX5ld1ec8#RkelB|X zMk$f8)I)i_wpT3=D@2%a=vfHRf05XYBVL|avfQj=ykor7%}5HzyU(y{poazdLbT+#w%CtrJbeGEYilBg#u5Cx+f*uXJt+ymMq=FX8~*oEey{;x~5t2TbDmMU}gXwH;2Jl zM$cfW+i^DuJDUQdG8CP@9z??ty!%%vOk}wtpBrdacWi#Q6evP>H(9vFr%^(xB9%Gn z)0rD42l&aq-hA7d-GCwPO}@u}sMO56uSk+WE%Etv(|76&j+LT);XCW9Oi`o9rbnV} z40HiL)mw9CTHphnbl`_^74O~pzHsz)6^3c%Ijn@_b^e9YK^g&-p?>_U3%+d8CwvdT zKW{8ndgaoQdA{Lh$}2i3B`Pn+uij@48GMaBB&sRvxu{Z!EzhRb?dT{ zl7rHkt(rr9U3WcSjjaQtRhe4%cHGAlQgL$Qv*nBEi-9gjc4VU3V~4E3v|7tP5d>X> zYBs)b3F(}iJ6W{qoyI5|KRWxX&cx1p~xR#N)# z^4eroPKJ8yAn_ft+d6*R59p6TGrRIK(ew3FPt0B`1zF`#bR_jDw-2qpm~|L?Kffy0 zz-TeY3WBFjch8Bqh;6kIqIWmjyYHlso+WpD)3LN=pBtFQw{itk0>R&b&aOJHr%l}r z$zT#*5-5qGgn}h^yko^C`*-Pt`&j(xph2tlKCg@>m44&Ge5ISw4 zYYb|_lXy}&dDxAQ{CKLpqh#OuPZg{G>M4C#CY_&>ElbdTc-X4Wz1{|2D&G5gZ0}+o zvkm_3udORW$yHDLJLicdNzepR?Z@3ucyQ7OCo&ybm9(}+#Tu5U8A^|M@2bR+{XEK? z_7F{#Gyj1<3i9Q*z9plCRm^cCncq1zIaU1_29uXIEbUj9 zq)}9JGF@6}Z+WCsipe%~F*$NQ4=WkdPrdtf3N!eQ?}zWrgI%bOSO&GD1IKkbu6>y* zQP6>Wr(`t*F$uh7aZTt$iHcUb`Rd`)4!I>1EMn!9l;_q5{k`3EC?j20esEcZRC+-y zeTH9L4AuvFm4w76=bD5`2<|R8Ji$D$O7IzbGtQtKQ0Aic;2Qz@gBgAJb6QEM=iMHU z-s(=^NyU?8UY0L%Qzmx3QhjuXZyT_;i$Y&FJzg(h>(U}S#GLWvt#Mj;Fpqm_nJ`wo zo(y`Z_x;${H=RAewOK#R(`UU}?*?g5anFFb% zXj%;K#$7pl|4YjeoC129j$@Qdb|~$h9f!9(66FV-MEjkp>3F7{#4a|L#98{PBw0SJ zW^NCBmKozbdCoK4p0k=JPfQg9nx#D%U&TLru}DSjVsk%Q{naNu2}t~vBs#Ofc{t2H z$mU^d9E;{4DgHIDIePsg8qqr9%sE**AW#>2YI?!JXPdYEAjuc;qo=$Ml?7ongUW;@ z6@F0fs(kG~we#hdkZ_Kkh*;8EXDzK%9`qCwK2NFK&pZI~77?D3#XodNQnSRCUlW(a zho$1D;wPvQ!}A3%_7|-RmYh(hSI@ohb}6&b+|J6eUemzpe%FhiC^C`H_(yzjAq$FE z2KtJ@e5}@R8!9=Gq4ET?(-2O-pBKB z3UVjAfQ5LzP_at;*|Bo z8#fpoJ2V(1e7kpuZ|{BNQjt5{isSht>Ab@urn5_Co`{w`bdpYzvYKqd#dWkdb=YwxaO#pP>f)kM17cYQX>N2Ab0G3Ca)SOI5s}Xh4Zb z5syQRXPw|jQ2uiFR4mFCjr+4)EegD^%$7;9jIg~6rGARSuP1bi8HoPj<1SP-MFyOp zKIT;NyJ;WNbaZgtY- z*>C#N0cpA+38c^A(Si$OTNvOsBcE2c0jnbN5gKguAU+{De{Xjodc1i*A?S zZ#s;;5c!=zkgG@S-M;{G|2I>Xigov!o|!|ME_x8~?>&)msbpc~{xzeFyPmzL@!>lr-eO4b(Rzc=sChjH{dWQkeWO@Xj% z4b+#M6wUrUfRO_PCZ=L(TchYtR*;q;457$1$yBOmWCO^;}2h%c)ij zNc1Yd1=?1NaK`pJ)B}#-e3jhA^Pg{QN~5gXQtu2_abz69&XtvQJgVlpx;EQ8GVl^) zlev@3oOZT020`7uuo#efF_Ni;(OqNC;~!08K4r^SsUn_m;;S7adPH z-@meR8MiQWzQc=__okuyQmqi5@({ze-!{mu35U2-K@5`a#a7Nj{jN5w;w$(APm1&U z-Cb1F)DkF+O7(#9*Nupgk&*DBCtKwMny<(GMJ?97)Ztsx>Kmr(e0_PMnGK)M z(9rNs#MI;@0Z}wdA0eG~key}gN40w~ZmYp#n=4accIiP;AinN!Aq~u9?Ssq`+LLCM zmb4xqsg=zSNO(1m;Ddl3!4;Y8iF=%@FT&B3Xed z9lz%FnMg*6*>M1cJ=flkSuS9$+go`-rnuXt;U|TdT&6!APUkLNzo#c&;<6U{D;+cW z@vZe6tvTShl!^s%8zc~O`B)y8qJFp~QFkB`6$X{V3W9?`zla9i6dTDs@VT7AxIFeS z_5pD@(5~xJD%@#Hs1$g}6pvfQs>pOQO^GEfAPpya0MHB}%HAp&AS&ZMChIv^LCie; z5eq;hw2qP#=*RW%e3;m~y1RA01RNLQrdE97;C|W9?TgE^RbKjJS0HBhj84~4I!~nQ zi-?C0D&20X?I&%`0cuv?qFIdm=mMzNs$Dwtq0eL)zdSLK)o4{1dv|&G%IN-{v47_U z%Fq>#2*$2y^vKHbUnPk)DmoRuWIqEL2myu#55MDvER$?54b%Iz~CnL_Q@PSM*&U+}K{pv|m8_=PiUid4|oSG??u zHA%j0SN)ycN5hSVuNnA%R7cB0HJ{$>ZKf=-$evsN@ulSLBarH?ANm29vyslS^K6nE z&)yOd^3vRwy7Efw5ZxT91gM7iXqjvA>u_xy7YQ`jd+BRGsQ4;I{N*6SMdha_AQ8q< z3EYApK%AO`ni`8w{qWHELtI@Yow!D^P;-@D_AS%Odx6Im6?J z=5Wo^7PKqSC!9*tJ*m4i;XTf0tsP6lMR?Ma9nUAmO=jYou6OBZ7ufOb>$na&<{2I(WiFQ%lzc!?eXksa!!^hS%ThjUKeqoI7P z(ykvE*#AaKGvN@3kWM@tt#!ls9OEL0Kh$Mva|C)!;%~2J?Y&}pUYI{mz^v`Ziq(Py zbDcrv6A?E2+q?RB58jFb?ZPb9V09bRAcOj>Z`NH5eXd;Pb+)L}rNGLj4rd5}2 zSrN_$n>f3T8@P*zH+)6`e7@x(r41M$yGe4x_=VV~cXsn&&k5y7I7_aA;`NPY@D$r~ zvvfYgTY|FI)c{g7)jhpMa+b#<4bx^_??u;u-d}Z-|Ml=gv>_7pF_Mx~4E8OgCn4E` zn_wW%gyQ2CMF-IM1p3NcSAB-qq8;B)d)Zfyfuf{8q*y)=c1?4H)kKSHeP*uv)X!ccP-1d?Xk%GV1B8G?>4chDb zaqdEc0OEMwx)ZXn)A#a>{MXbw*s@96I3dj-&kJ%HX^*|gmT07uzc|2C)Isl6-{x) z9`=3xwV%C#_S|8Vh_W^^Prj)cB!~X?%Y3I1zpU`^`8^{8d&vdJVEt0Q-{kt;nyM4o z=O3N9hxgk*lX{3awlW_-#kgvoSbsU$DJ>H>6Fg@q*F~D|)u*bVkmqkDJeb=|yoo<(fDlx&Ff7q7N@gWRC8r)vC0D z$3zD1@F;U~fFGrAs1Qjnl%}%GeCHH5(@mO5?~A^E{5Q7V6($reRtu^KB&xXDJLTT) zFfjQ*Imp7@WG&zQ_0y{1>wCTal~=~7-5xu}YT&-%eOJp>yDBJe6_Vfp6t2HF9UnwG z>uC~vnCjem?|hnj4*jQ`eEO{67G>tI(%SKNFCA|_jn1U7EkRDRwBk@(O9rh$_3=xn z7-p7}T=6E8Pun%KHC@F&o;WhUfjZfADI#$>PpIv=T}IdwJPApuE1K7u-}Hgsj7tzA znBRDERdYriT+)``>br;ueuu87qza~O;!g;huotJ&4-b714xfUrlA|-~EJAyW+@&;r z2-{Mhvgj51K5{G4a4ns=f#wlK@7HTu`F#RQdK-BzLihb*n4v)i%(LJ;`;yvF-OiHZ z>EG%pp@$SE>7Sa~(i{|T6;Ai9;A1Y;y^EwbnQE(EmZLs$dsZjA2R`5fm5!)1cikXg zG27lP+q_LD>642M2^vNzF?3WXDJ`4@z@JbjH1X{wT01Al2%r799HyJtEN}unqKO%i z13Mw@8EEI>&8R$XJ)ZSjmBAVZdW?`KCQZ)Y^UYnFwGsS zk_3%gVOFKKZCXxOTSb%YgMPPEE%DdG1eIsaVGNbvjv1kQ%jsU(1*O48?}RS-_o-Ra zwhJwCs`ALpv0wC?I_^Z9+79FiD7$Q9Dt&)lTKVg0=c5@@plnlKPBo|y197rL{&C&y zWb9<1Le#(gqfNNu6z6GLz#x;&&!AJy5-rGKUVSVcT9%D0{;T+C`d7aQjUF;m^6?UQ zUnm~nOdq;S^i*H@Dc##|c49TA9_Y>NHkF0e@_2z|2@fO(#Ch@3<)Cx-c)9$ZHJ08*9XjT9 z9o`E<+zm@r#K$gPy)hv%f53&)#RWMm`Qbq!)0=jm^@Gv}P8YdH@zTe0T>P1?$99@% zf>beUs{Oz-X^aj^Z~Je*=Q0_v8KqQEj51}G&pAWx zTDSG?`h<voqB z(lw1KG+viT1>uBrB^F?j^euSE@94B;G3B$vr_wKIAa14w#j?vTKasP#r3DGITPT(r ztGX%oW8i{U1D6;8LZ*mnGs=WW)3E&?X%|WQBKezm8#;$7WuL8f(Fo{=iDl zl76F8MV?Ld=vrM#RZ9e0DROtjt{ZRZlj6q&)KOBf#fdQ5aF8@73@IT&+zU9!jx~T? zN>a>=TOMC*B(@Aa^n{A?6Vza;|Ad~)b*7!P+jFBE)q=aAhUYPx2!=~fubxCk;tG`$ z3rXTO`PeZO9v`0rD~T8?J`;Hlnz;M8n3z)3b{215+!=*@hM7Ti&GEk)!aEhPFcoz9 z3%+w?DGsV|!EJW^x#$Dgby0m!^#)>Ir#YPmvwQ+!@vrlQ*%fr1W!V-jY0Ivt!-3pACdg(QPQhwQGogmsCMIMD;erD@MZT^Ux=n>z*UMjn)VlK$h@jZ7^Gsm2EI=J_)Q zYIif)r&F9EZ=$1gX)_n~s;l2*Rsrus<|nXGOP8OAj|7)}cVkUt6loVT-vi&`Y-T7s z(LMhLNH=PQ*mo^oX7Hs+Q+0#VJSJb03d?iUJ{sugn;=8Vocr0zFKbXxQuVQeL%>rc zuRJ~>Ve4BZ&hHKfzG6*b#`5sAfCY^`*qj@fs?$Qmo|_4@+3iHXOonH~n`LAqR2cIX z1shBQ_(k>YBr401iEF4`lXZO?@q36yV<>37;lo4Wn10St4=w{#q_7rOKghj2n%e5h)$~hj2O_CicmxlVa;!cPUB#+GyaeVCWnP;Msb$EPkutL{)9KA)^ieRw%ne9*K z*+5W(c(5X2Q+zwsT%^T$1O>~(3jq}qf<`WGAxcx9vn!)pUncDdym$a2DHCph?OJ4N zBkUt_mPrPOv6%}~bRe&owl;=oFrYH^Mb4ycl3 zw5Si(Y?Wl9DxxJ7|FX$;R%KS-j)<*It)Z{l&#TCt)iv4G*6lvL$;ZyQwuWJhA#)g? zzQi`wHv6xmWv*2FmZvK1KhSAVM|~d$CUUE>LjO)$m`M4}my~oGYOJNtU5L|8@5H!J zeBsKaFd*rs<9|M^u&yb+xx?hyR!VkYX2iexyV zvb`eZiUt4b^=UiIaqIX79Lh!%(nMAnF{R=;A7`dh8iVq3%b=!(8oxRc<*@Gmlm>%$j~2;fX$I8k+%#X^@A{b~5e$_z*U zB)@KE<>#xu3l4rxswg0_0FVg7FSHJ4t~qazI1E_(Is)>+)kdfINkUbrBj6OudhL32 zJ{R;`vJwd|a9Q_T6g~&}){gb%tM$~MXOli~M7t~ro_)~x?lPzfvhz$}r3&*isC{xF zpMd(RysfRRQNrqEs9vL^UnxNSzjBNKG+5YXq0c<489&SZL38-U%(AsxIlm5n`m+}f z+_haE(us7Mde8IAs$y3Lt7)&mT)Wgh!*QccR(g4;eA2GwlI3w57_)_c=kB9cb8i-L zs3J!-lw{+6wg1tT)t&KIrBehu!ef4nPsWmY?SB|kz(8|P5hUYX3am(VK}w>t@9SZp zGCU&UimB_)sBg5v8@d|d!qxFFKkJKkry`>6OjNYPH{_OvO3$-pxKIZl5%Do~#RcE= z_KYsLZBE_Q1cg@w=F>l2povvYw;HY(+nxSE0qhp!z!{k&u)k7!Wn^QemiXc1%c5&8 zTkodZ4E?%GfDcOR+Xped07`C2fIo|_4Ipr67^tYJKaCm6R(AoZJJZ!cTV-odxWMmg z&?SF>%)T(~NPKS7B6uli8{DwB&xgCanLtK4?XKWVjF%B*o$41+fUe1F?1uq#AF9LX zbKac0$fOv_%)-J_C&yWSVQ*tL=qo0BOpAi4$}SD~$qgG`pX13iE4Hm4JpvG05z43@ zsR?%nGmeY4)~RY4Nzu+Mm+Zu&&1g@w{wTeLLqx+o9!G885-BKX-L_T;QoftGD6}6- zv^Zg@H~fOD+O#;)+(zOFyqc7v z8M@6rI;V+K?+-x*6iy*w;ZIL57fGt8Qiq*e(fhThewH3NwIymG3egDJCI`F{St0t+ zkFDdfm>){u8zT2Jk#`9=f}*JwM|UHRIw$fbJYrdv!+nk~H?(kFYGcJTLJ3CSMpujfk}9OME*=H~1jJLNY0Jj0H)s7FbQX#g3~j zjS#n8#JKHcqHI7ibQrBi61ZhPW_3J9Gtt5$^d@R>(YOWY@?*cGqN0*a2yprZDNySC z9P{UV5vu1dxI7Jd+}B1%)B%lr9Ef8{bxI|8&j%dnd}g5f#PLG-xMLFt!9#l!A3Ray zyyF`5H`{$Oue;fV-;tkO6c(EG8a^p3aXz;uX$l<`zq)V2$OR0J22q(f6jy<0h8u75 z>5P<#sTUz3_8IhW14>Ox3sU|7O#rte$M<(#x9Ckam4k%Fqa-#hKiIg7fA^-j1i%v~lA1cf!>HZi-8)bA;To=?A3P zrCR;IP%>6EqoAiMMy>(z1BIEQ)d6TLa~3F3Zk$cXswFVVUVP^oa>;A8>X}gu!8Dqn>!>F<%`|c*n~I6Iay-i?Fy6L0JAgtq&qr&0e^!Y3 z+Ii(fXFFdau|~Ynz;x_Pz7x%AG6RW+A$PHe!4y^;&9zo zX^dP`%h&y5KUjKKzkT93d`hQx;CL826NG|6xVzNNj)fcIIJ_vf$t+n${^`+J14JZD zsI{nJYF6j1-^(eJ$1r}~c{?!d#PJOfx-E~o1)o*)Qi6Yfx^)D`uaje`xPP}*+n6vE ze$Cj`qa>O^@(;}UlO02QZQn&6@R^yr>`&=y==bNgh}>roN5C^QkBk*UKFnAO1YaMZ zl7x%&);q*OtALPpRgb_^c!58;LRq(hx+Dwj>%1j}gpB!qc&Pp%wwLLytdpIrDjz*` z;c&w?iV`fR-LIBuZqTV+`~wTqA1$WuI6aI?o>6BM-8Bu~DVn~!TWv*CE9foJ`*G7= zrG>)$q2ihOCg0~Rc$iYtVRFwLXGDJQQMXy3>8!5dJkMU<#9p2sGDIbpwTb@tY<3M( z20(sL3uzG@VU2gHn`E_>Lh1xs?bqE`sJ}cWG9bBXTK=ulak&S^f-Yb%LFCKy9_l65 z>fL$Itvjfsf4$)w8#|{OD+(ShZZL8vsk#4PO0DO80nh;QlP+w8n-Vm2(p1*)llSHB zW=DBj(KcB>9Oq|y3`Aq+1A8|L?m0)Wl{c}K^MwqN0OWbVo;9!tL@;QwC3d|cXAIdQ zzaA1vg@(Sz+M8U#ljsLM^4w7N7gZ=K0f1B2-Y!gHd_Uc z>$j_>ar|zaG!1X>AJSm$F4rZ;-`R&wnVwU)4?k}Qf-kI^rXV-X*8;m}4XZIW&dc~5 zBiHYA6U`5!$&t+BAK;s>8fco^+rX?M*7}g0C(WC!gD>c7Y4|Zi zYdL&3%eB9pIv0&X!(esk&;x*j4H5Q?P2(U1e0h5`01hpjl%j3Fyob;^H{Gfb0P2z% zJL{Z0yd8b~Wwyj8kCEwX8~-sfy*WZ`48zhW9DOrpXZ+(|STu2EW3^phiEH_Y60NN6 zoz2V-JW^VrSrq#z;|;92L(Xzpi5$bOv+0FvFH#-uE;9UuVxO%vuc2=YM&0()kpI*< z@N9?QGPWlZ{Y>-(x3hZnJ?-I!Pq)h{%hLctY&CH&Ti1NUQq-iwjgHahWS9T%z2}U} zGEaIiYoYEa0H0yj~g+C~+%~c{^CGLp_0yWq0&p zfbbapjYF>hwEX2C9D0=t^EwwZBU|1q5&Z*wTx?@UaF$;Lxx7hcPDmdgf)6s(BoFu& zcygm`&C`cLxlaGTycK-^X$rv6)yHtOe83jrNxy#uva2o|;(FTSqHjG4@q7yq6-t73 zvPh$zEK+PxtoG86&3W%S2A%4g_6I`exIwTQY8NAQF3`G|y`OKs06<%!-TX@BX_t$W z%kAZ+26jZ3yf2n77aHQKO+S{@X#eTX>H{9-|J#k<$*$kpcAs+%$;Eojj(mhLI;n5w zNqvk(e|2J1{rMZEzV%`K&tFoM7k{JFm)%;dexuY$ic6tPXVB_I41F_t+&`%EW)+)} zh2Ev?*&$yLzV~N)N+I$H$u`GvnPvZL9}!(m2DB6r51Hc1z^2g|4kFyKf?B6sHLf zj3Cuu-Rt@YW7v_-!j}kcSe!&b=$5kzrYH52U>rU@)d~$LhyF~!d3H1&gf;p~P%(LI znc)FMAM*-fkeEyU2^h~m+6d5mkfof0B`)`88;rt}LX5Tp#&O{@y3H3dXMOPk7cjb2 z1i&(|occ|F?eyDNRWv$1_3R;=0(>rln=f#_-$b7k09+FDux@LBQ}yK#WJiPTO$Y6z z%YT{|3qAG;@j&sL5HG9b zM^af~|zJ z8)bQb0*2umeHO%PQi*v?am5oBPszC?fk;v`R*aQJNg zNsR5)%F{!Bx8`LgREL83EYSOw{^tm`-SA&6PmH8Kg#RNpM(oAm>ud9O2va=80rKoH zIB$%4l~&l+9&s91`=Kd-qsuIf%os>C*JdYo+da{f9-uomugCs{VAH++-$AfRp_2<` zL2dH3Su$vt%pOrHs8hvlj|gocWS*&=>MCx2UWg%i{dRd%($z~t__%};o0;!_-5Se4 zwvuRAeM;aTRjc9)@riMs<_$jjJCC;MfEV1qfQCF5E1Q{)0F7VUiSh<5;1jiP&I2|U z2C|1~%JERhw%wdUE^C-hWdg#sMJUt?y^H|!83ts1Mb6NUWa9m@%-sJbpdC!kd^}3t zxyEoPkit>0q(4En8LJ^EAc`x6o^LN)1+U%!fXn&*9FeZoB$?{+$3BT12?j9bhOU-! z{2plAu3b3BvJKAuFR*MKih;5@)!y-=wy0qX`BBqi8;4QS2JqGr?BF_geEx$~OKgHU z6Gp19d_%sfa?bbzYCoMj+KmavmE`bg=k?<`8uSrDq9Y7iBGDP|iH+S!K+7H@+C`># zPYC|{b6hh!L87sQTvR59!ACNqR0@7}iI)bNi@Z^H9!ZarIMqsBNioC6_hth!sT^h3=wxA1vUyJIdqh%-MLnA6JX2Il~g|z_N~7sV9?txk5RUqBdB4DZHs;=JL#HZKP3eg zLQ$mHuKf!8txl2}zjx^yXId?d?`kitX*Um~T++6j4Gy}Y*#DKS`ek9aNVpjP%8F4~7oCwx-i=OTFh+2D(N^wc5#97RBbB`Fa5 z8yxyJWIwv2kFpZXgrm8yi%^{5+I8Y%xxWU^w=Pc%HS^6tL&GSYVS*&u{mfvAUDIB= zMvf#lKq|gp`7-RXe68?;qkIr1KYNC2%Bdu2j{DaF#^Qd z9IaF{1Gq><*>8)aP_t9hJCv6}ry9o5`YF)(|JPf~uy`Hng~jWgc*x8GO2HctuOTZb z>Tw*1hhdD*1_s>#lfhaJqwg3aKp{RCE`(_9B4@Z2!(_V zp!<8#p(Li`4&ZTNJR}gbJ52RHqtFfedYKt&3Fni8%Q_qWI@qSrvMf%R87eQO(Ov^i zfk|6-Ao|mb^f=sIyJFh@QC_!&-V2-Xt-;>*GG}*|-m(a-vj-@TJ_gEaQvCNAe4@j6 zApb3^$Lzg{^6$^PulnoZ5_I)=`^s6X5JMpeF_?a(m2+AI&qGjyL|0-jD{e1tw zk+B~_`?S_|r{42+<)<#|*#D4b)68q&bAlLa1|5do?s+{>(cW|eRl;9PO+D!0WnpE# zXq%e7wG41ejexUPWJn;LjByEc1KfFqqCJXH_+;>D{TU#sfAhhMNa#jQGnu;f8^NnU zsxPm&3q1y~w&ADdt3jq4|4z-W4b<%Kc~|2zGZpnm@Wf|8c0+?up;;G84!}?wY!3D| zn}pOGT1xEZrM^dBGj;~z(0Fn4L6D-x-g;Wlu+C3j7l-CC(&W*jZ(k)5BgeozB8y2W znvI-8n;8^FW@-_fj{Igf1k4M9tJc@>MGO1PSgjZHdtSg|XHaEUmVj1Bh2}}aIiA4} z`xBRVXcaMo?w>mn>?2WZf<^jq|Dc$pt@`Xw;SWd$3CWW&4Hjp(k+^^K?DP1oxk;Ke zK+axi)H3QOMT2t!LoMDC6Nl*CY-}lY>*PS|+B8-?ZW=@q?hfj?3&c0MVTH{c+V4GX z=Ib%aTnE%m%kx))6m52yWem`iMjaYn6Vexi!B=W?G#7Vo7NEa*x(H3k(`-mQNh+Nu z7i4RFeQaW3V+kTqqeKdUK?5JzTIRHVfz2|nO~w$wm@Ol*+x>lg6F==+od9{_T<D^L5jGTQKX&@H4`4e>D<~k3+#PdvZtz7pU1*1#2;L;Z6GRbLZFmjX|-4Kze zcK8WRzr78P#>kXR^!#B_ICvo&dTm)Wiv9f+hID|tUH^(G9kwL%Z4BJ}!opH4vhn)B zCU51@sNvSQg0^_srj;ARN{rpYGHHzM&Rahos@m>mKr6ufVApN^vnAKKiKk@9aXj$b zWf%U!e*I8+@p+t*wl`v0&|>BaKYBD|h6gOP2=s)wPQrb;B%p%lPoeFLB$+CBwW8Zm zoSdm&7a?Sqs$j77JsV0cNg3R5q^0IDx}lbc4{<;9@0r3v*7_2M-Y#su+V3dcOrx%e zhde8{_;su7Yt_u+o5@IZaq64+zb(W(f z1t}>v?I+`ed*+pObOK|Z)RuYNpkNHvb6x!`P9?TGK}x3ME{mvw%XGh=uMvLfPCX^; zt%ecvK~4n49y9Bp24eo-qdYT|ocOwUCeHu-W#wgDL#i|KEd;pEBc3?t6H?CKFCoVY z34=;sv*SaCsg%LLK=*R{1jj#0K^t~{mrxTy!Xj$QN&elXfJi-+?D3Hn{$_n1^9@Yp zJT{#Ym8bMu++P9zFfk16z*Ps23nz!avczAd^12_S^DA%>G zJRVSV{|%$6_2TJh)>`pPfDUk9LeoZ79w>&q`R|jMNSi4N0WgEnK1%f!gl33$A&C-6V{MpXWsf-D5-2lCICGEX_ zpx!h&8N{7IpvF+Wxd7|-f?AzGWnO+tZQJDTz(r)2nkmBj4P|oi+Sy-U+65kLe^n8KCW+a4bl?%B|7yQQf5nM^Qjz@k3 zHdGtBf82(y(L#Q|Vg4$N2K`Bb^q~1jja`4v3X(8#ER^US#8&jI4!JC|*P=x40Hc-J z5)g3NdSu;w@1gM!p41`4osJMO>r75pyWw&g$mnMc&a4^u(uPd7fsmr}>-8skkVY6W zgHDHu=rObuj1`U16)%TTqs6;`YTnj_=f)xus$YrS z$I%ZsZiD|9&=fwZ5Dt>IuVlvbs&P+ajXJO4O zC;Lk~TE>1Vbm-p-;{6n?A`%L}wwHpst@mdMR{=|5QP}Q>5(64)9++?&np$xieN930 z8u29M;5O=iWV*evJwMcoCGU56;z7MYf~u9-oVtI`B;jv0yXq@Vb2a}gSw8RIM8eQk zy=D&33?9=FR2}^fW-anId?3-v>>Fu=w>sVp?G;en0SdxnA-%x{8ceX)@+mR(F0ST! zWGZn_d-7mz;K7gbc^unkk=OaT+q>Op0bKGoBVk!?K2^D9v2EEvE+z)mq2%+6&Jpb8 zxi0+LXsvv^_WcCFQ$!{{`RhnTsi8-J8Rjt8(;*GYmm?2TiDn*cu0NHUh?T2sQ4{05 zAw^fRF$XqbNKV8mWYvRB3{vJX9OXh<2W1SWoKCdK9Z?USmgEwa%mmk0uH3@`NQmNZ zmSHYmg($P5dvYGjV@?3384li^`^`w8a1lOG>s0Pxd9b=ld5{^7>HON}Q!zUlr^$}v zV>?-$*|oeNqO@{F2Z!sJd1#%lnb83cViT`odPI1{s`yyW~J&o&b-RX&<7;=xfhQD9vM|oYVku*FvSZxgigc1pQ4lrPUY^lGig~P>M zd$MIri0%)|P)k5i9Yeqgbo!2Ap64jvog(kE_5DjiuZwvdr9ESyKTL7k`O;QWC(_>k z;`v`%_kWSTqu)*#wS>$5^udxf!R3(#APYA)5Y00jiRMqrOx0sK>+Xts^`GHB!VGRe zMzlAKX>Y(D!=S^k@hh<466($Z^OZIR;)F_EL%iQK&&q{E52)f2U1 z^NISE5-Sd-g*6xN9sVI3CU2fI|0(3Duq_Idz<;;~rE;tz1-*uFubkEIeST~ngLK^r z)$U#+Rv7xH?ezbs<&!Rffls+-FG>G24A8SoCuMFbRbK!qcZ>Xudfri+URNPDz#x#Z zuir)Q^-lK)C;K))(i!MEe4_HgeAUFP0>I);Y@C&^RiG#d#d5&V%Ckd~S}%vlfbbY& zL=zzO%Nst{@P5k9C@33v3T&?5=Enx{9zp4t$1?cR45GJnsr0GOIEM@WQpbbMPss$@ z@sWQi>MitWy^k6u96gbeiiz1|h8DpKWX`Aufx2HXyAsL80Au+f@eai(p?Xxv)uf@^ z)Cv?8kboWt)5c z@z>T=6bI4~@gK4ciASR#hW?aKj3vQ76U1~6u>Vw^Zy^&(Iy_`eL38vq{?p2Nc@vWF z*`3(M6#k1Ib3g0CS6||Fru}T93tBk6{~#o$51#5&6_ZTY6HC0BonpXACHAZHkv`4|?5E6^11ao>>pTWvl-Xlp4MQYZlA3jqp!Y)zC+J6FK*g%|Vx*b^}TS zw+~Pn=VumhD)EXMTh8r8gGG4N%;b4xkUL>mf>F0Zg`f519|T4&{XWwOi?HvE3%qQK z5A~P#gfw=%f?6e(OK#E5h~+ZbDOZaJg;svh(Tyre(T@T8cHjiN%TGpt7UC=XP~nOS z0gN4>)=_eOqaJ^tU}!#}P38rJ35j>lgRfrTzkJBiyvJp!d4CQ(8kf!8?+Qap@@IAU z$8%6x`ZMuks4|&JqvX)R?tEn zsnHfp(`ZhkzapK-4hZ+7QQ~*ZDtnks+mJnA#**TQdet+Lt-2KM;n60 zpI8#KP-AW51>NlQ1hRqigh7(mG4m$YWAYyWk$y=PEYe4L*m%=V5&-qRI#?v|W6fh+ zzh0Vf@dG?dzwx;l8;j74{M}`z>qpA&JpKTMsn9ywS=yi&i;cZdB@0DZjsJ8`=gO~O zlmtH;=m4y0GLYtMfZS*?Wl@6vK5*Q`W9FNy7k#SlpQyetC;nEaTB5`~D*D0?GMbO` zJt_QXg}$IO=^tVvTdOClUG`|k1<^5{ojslx)NmxC=M2tnQU61fe@bP0Z_Oa5@WlD= zF?*4t*%-0|?4Fis?gDmBi(*Hj{MiJYFX&N-{;+}{uaX+~dyX_$i_prKn|3*NIKa!+ zqxK&$8I4KDONsR%=C#2aj?oO1>a>3G!bPtw^|Iz)pKc{=BeH!B*>HS@k^4dH$AuY@|YOhmt@w@#0FdS#n zd%{Do*zHP6y#M(}_QDk1{f#3c5@7UpF(&hn+BBH#o~6?U2>8tx*7y!%=DoJjh{BZ1 zBg?htLM!c`nXLK$3!O0<>TqrvrM|BfDmO47u_o!UdiF|^clYz(d`1+j>(1muG4!v# zyTaM$TY2!HemG(9yx*GMk(P+d*#X#G7nqi=rQiBZCiH%sm;ax08X1N0PbxHoZQ`nC z27!vGVv)&xM&w-jZ$Uk2PrunLuzKao5IArYZZzKf$PN@cy7MR(?LR!OT+V>Q&RSri zEBNSJg)>+x;A4a9m3`;;%sWASvy=MNIO!0Yo*2tGW;o#03Yy1Y&O!U2PD6LNcmMVY zPt5@k?XN-q!SfpLdP~cicp9%8gIZ^Ts$2Ne^V^yH~#$^EUGPQtI z4~@0^OlZMrD<2BSiQ<9vrofn>%SHsshl9x6`_=#zY*dn!m1XN`mPZTv#Is-^FiY~> z@gq2eKc*>Em7<)~sCFYysvs|~?#bXcZ#0s&0Sj3-SS~=C#6RrW>Cap(90PuIje$wo zO%&pu2V{Wq+}g7kV!=cRE_M(5XY&jY`4a7Yw8Xp$8>I*&%$KOmn*QLSt8LTFHwHB1 z6k1m0`Mscq$!EYdFdy!I_b5qp2UGxxixAl!uvv38HckleXqCYEx`RXK7_&3U>2aBy zU2}qJ*nI`S>?EPuPo9g@Oa$_RG#GqqKv4MSoA>m2P3>D+Sdamzd<;+~Bp_47w-=<$ zNx!1IR!8eFa1MYZ<&i5bn4carpGIEMUJlW+ybLQgTSV67opgp>*8{IOR{vCl_JQWL z4%}kKd`plMf`Vl`L8wbvnNzxU@m*&dIB*9}PkB_jSTF|4J&=OEA~bT1ZYu5r?x`VH z2x#_sbgDq=zzY!{9#`-q7)3sec9Nl+A1rlHq?&^=F|FyGXU^F%&;Nu2lRlQ(&bFu9 z^gbVR=$)5w2jc$B&Uox$6?JvFVVA9i%l5qnIM!7NoCasQkC_bDPzD0ek0>Kyey0Qh z_RMgl2R6Zqd)T_ytXw4Z2<9l@mPA+Ej&i3gwwPCE~brQAmf zitG$tts3V3LK76P{(11xr{=oxS7J-#s&v#K>*t~NM{7WzxYQH6)DXduG~{qlj?Vg! zQIJ9%2<=&VFH)B669W1a{PeSx|21zSM*O9f!%Xb6$6c5s0cpr@y) z;^oI(*ZZ}pCpaCyqtjq_y$S>XeWcs}f?+x$CNM{}FudZn(3>L|j?U$HeHCsu;_P;7 z4wXNnTp27YcBc$?Rz~CE;v{+b`Tb#KaGcTy(f7WS@vlU~gFk@G!vPCGp5$UJf^Y{f z$LS~sDJQ4mqER1eqmw7;azU`m2NN^1#uu-mB)qVV+bj3x(u~un*FY28{tTF=IyEhe zi{JGgS7QlU_he{YY7v@ebE0E+aQnGM2E7M)I{w1TWmo1Ueu2h2UH1VtCNN0qW$BjJ z)jcPj%*TAN*b~?-O&bBuqtgx4@d!eCpDJ$kB-UJp6k0#6w+I8gZs+_ZE$u6snIzck zQ7bcW(#-nwcM3+C0Fs{zpI(Xhs%6yI*URrKi5;kfGy#(d>vzUOvBOnjCxXc?kn~iG z(csW$dg<&G$b_jX#z>f#C|C$nqCOH%y@kx~6wZSUdI*NOZ8&19Vm)fv z4+OO~hn6TM zf)4Nu40Mq*S7EO8AaDNwbc`1;&6T+9T?FF8epul3A|4l8r1IhEL?WS|J{%?!f!~#t zt{ID6^k6IlP7BH(r8aFCzDr_t((0cMB5%!rKKEw2jpqbIV98}jD!PbH{_EJl;lZ*; z6USq33Atb!YJtZwo!)9)f;LkEN=+e^fO6CEvEB=;l8`~LBH=9jH$kGhc*v`&54no- zZTfA#Uo)n(y_CkDI(#Qn3&CJpOKp2cm|vW$W!&r632T%^>f=%7#eo#-8|Rg0i-)WgKdJ5Ib`k@rB)a?Y8~yVAKK>nV-qEv~H}6vhx|` zn`g4{7zpNk-2BHJI_C>8M*xqpn49aa=e|36_a~qkL+m0^z6j4eRK$o`N|58W0s^yw zn`$dD!tyj{*~(Lm9K&Z1feWN-=2jMxG8ttJ5n+-K8=-piBiHz}Xj}UhI4Ly(z_Jx^ z81QDcKfnNP^#%A(JsNG#$IIRxNJi6C( zYe!6&vN>P_t`zmnw2PJqxzX-FPMICQ?+(a>E32!FxX^hTY)1wU7uT-0{^XL6=5(aW zY*MZwbCvm9q*sOK?D|1DdzKX5G^-u##Y-PtbA{?q4ia$|^f0XY4bX}TG=O$kL-_f| z?2UZh1tYs25ZN1D%;=u*5tB5j2KVI&Ux{9vu?iZl#sEu3`4o>PRq=i&N&+GOP zm&O_^mWR#+hpr3M+(&x%0YYZ~Tj4<^DCYE$-o!#VqU1r+)yji&-5Z=+?99;Nw#To+ zZ}j3RSId;}vQ;vk0?MRp(JA>!y@_GI^d|bOEg0Um--J{YSAZ+PGY=i6lNImidy?4R zHZaabsTxbBNf9JIv5H|KXN1=KSC+!4EX?Tx`-g@&I$hMEbhtVZ2Id_uRope0Q^y+m zsZ6y1%2#7f?`ztX*^cU5t&{feYT~S2R$otM zv)V{M0c=hbn-+e=rr}_T2lPto`qDWk2l#f&SJ58^#ay-JWc&syo85Q9jStCrb*Ii= zqy8(iyKK27MhpwLdj~?ORTX6l2<$fgM(iiJ!PUk^w=ffuXN3lt-Tkhj_2oq_+lr`H3DWMm` zcd{a&Fjb=gAQFi=i84jh-wot$`}CCk=R_4g)aK@&shzb5TpB^E2z*MBm;yL#aZLa_ z)-kY7S}wG)p9qOO-DUB}LrF0qqk?;tQ}gvoPS%a54g_yFh7>*(E~GdzRggjF^?th8 zw3I=4bK%_V0evf(@y>Q{txfH_8KuBtR9EdEq@q!;r_CiBbtd|_~5 zqqRb3+1AWU=uUrq(CGPl6PVH z9hdD%!x}^H90&TbeYjRY!#I+wkeu80)O|9Ny3b#TkbYSZmQLK3L(5}D3$VHfvd+Qx zb`x&`G6kdX4-&$XDw4m5iSiU8sIKMxqi zN=&N0`^1u3pCG)gD}AU(c{Dry!y0Lj-A{`!h}wXA_P#O5vg#xD;i3w`Gphu`12fFk3qk5ckOtF(&y+ z3=S@a5iC1scpm-cDwAkI;e&Iu>E$nMc49VfM9I3Q`<}d}fhU!}A&4O9NQgOkdKDq% z=s>cZYM^;qejs4!R&YhXwx@}p$~5awQrbt0IBl8^i=`tgr6xir5o|=zFZZm zc?aVQ_j?|?8hFAkL8xxi*I+P{ryvF2(k*+RjOP*>&M`|iSI6wnKfM_^%71qTm4aVFEI zU#k}O+({N$4YYK~0`{oOChDtXXHt1@ySJE{s5n22w3boREz+$j=}*LtXVA&I?5ZNi zRx?3;ith8WBBLv76fL(Q|kZnor-gED3&yFx3-(b$7F@ zdSt>a^IdM+?|T_)o&k$cvNt3`Lccr_`?;04LWO3Nu&OGLbEc2os1_m(5RlpCmdWw? zu|hNk(!+R4YU={2$On_*CI7+$dl!m!PPZ~yT*ogw4l^=DU^?I()_}B?j!v^;(%gifFx2s^Gl||LGe1x~a&E==qkbRzRhE{fKQ8k~lyR#?sQQR3heZVF z9c5C-{x6CSW3%FYV8y$;ZxPW6p)LqepO1V1DOYn$8_qH+^gy4;A6#T zPK9gOOeB}M?aN{nKi`%h`u%$D$m^8e#`nTl{TYVr^E4;(Ygn?J)5=1$CRNRY)dN*^ zyK#|$sQ^J^b1o( z|29P|X1IF)<(Tr%+*>)8_4ngImW!lFD{Ci?H3@~OR9jV1byIP9GfNf|IKz9Bs`rD{ z{ZQd!G1Jx8I6Kn-fcqIp+zsp6hYTCuDqnXa!LfcLb8eRuoRKs!l5aEZbMM-3YZmz$ z&S!yLt1zG{|J)N#b(}4Bb9vo`zB~S3h*O`g>Xquo0{F{i(#j;E4|*EF?=|be^{aMA z<)8MgD*@Pmm&r~>tN>~GUk)wWsaMYp)`u?ueD?2%u@H$v9^ARM|6<+}PA2j>sg`IS zp0W0Juyj;&A07@~GqpbuJi+SAAlhuo68a~oY>|PA#0T&%Y?@FfIxdWHhMu%`cbLHr z9WACWxD$Gv!~?c-A^M}(*3+XknUK=NuP4;t zKRK#L=YA-kO8fCRjBGLqYZ?{Lg(-deiR|Wsct)ITeNae&9SdbP3Gk}^_|W*w*5=b&_Bg(kv!B}*=dpqph=|m6 zQRL~xQm@)zGP)u7O*JF@Mjd7Qn(d)Q#oG`bTe>1KuRk5$Ibv2@JkM1(o;->lqoF*V zo(_2&<&sTTz1E+6c9cApFS9Yyi9bKFH&U^Qd1IACgCLsSEg9m9wMg zf>GYCA7l%9x+qiE8=dMy<6v80_&WW2qd{v1YZz!1uw4yp-2yJHGAmb&s9HROo69zz zNw(K&=4cdg<(xmT`V@tB6=ry-Ieq3G<2Mo2=B_I*JBlZB$fT46$ao?hlq03pUN!xV zKK$|ZsY^YWzxmVO@>hXrd7++;h(+}Q~wV! z`s?+MOD*A_5HbxJ>c$&RcN+RC6!kmGi4|_qSAJ?r2U%naUJSfBk-1HH?q_n*X=K-f z(8p839C<38kz#(J%!OyMCB}5PMDmAC1;?XP0l6iIaQZZK zsTuZ{zI7C?O1F{O&{x^u8dm>s950Nb?!C-X)nx{iX# z0*&)y(?_JIpQM%D?E?{HY*~bps%l;QFzfpJloAcr9%h9A^4H_W{^8bCsL$6A<(e3% z1Dy*#euF*`Z1TdmjlQzu$g)(_PY7=L#p`Kz;heKM;^)J|L;K{>IlS=q)IaH4d3~BV z8b$h|Z_zok^tD^2z~q%vcJ*CP>&2u5*oUTa4@F?06UiRe5-JVe#zhuKGh4N9DL`z| zxsrqDAaW(AQ_!ZTs+?SDYdH#j-xd#A?`U>nm=l$n8;Ub~QqLcI>KE%BVmW&R#dif_ z<9d#fvCEv`jnchQD}SA;&&s+B7%f;AE(v@8=xLTXAx`m>P?>=x-4te3$BIE;`Ygc! zcA`0PSH$=t;3Mw#yMz;_Y{i>{+VJwPPx!Yw`KT}-6J(olL`Trk-HpU8acuM_l|Y{m{J)d+c@xmc zZes#-SP}XZ5=OwWiq2@m$0|VmPZ9c*5gdyTVz6`tQ|L$7`}Opy`;%)xWi*EhK4VK8 z$enYIQ<_VB>d6Fm!RnwEV>PFQM_^C5*Y)@%lqyM@v9aS@!sxL7(NOmII7IdnT z)5jC}65)ulL*Ke#YD=W*eJYsztmEmsEz{@^63wy$vsXyJ31U|*nmZgZ=yb!h4g! zJbca-zB&NH)Y5J|bDS#LgeKl<&HMluwv*Ws4u+xf`ACQqBgyyG2ns z*z`yz9`romD>D!*4kdNHd_=lFM71kv1U%zQQ!zaQk!RM2=d8tkGWBYH5+Vzdyl-e` zVz6rz`fBhMnCFjp)rGzt;lhEw{`9rn?jZ##3_!JN$P^oY6iKm4J7pSnhKedidiE~t z=YfZLmW4E%2vRF7Z|u!4wN}g2^kw%%^95Jc#7*=CcSA|{?;UZkp2oqI=|)a`T9d(# zSx2bkFq>FCoWSIbreINn1RE73g{6qHhwWO~w?xPT4t8OWP#p~HSfA$kweO8Cvwh9f zw?FV<%>uD#gC*`=Zg3nR8w(`$SphbWr5u{<&@N4d*3B_A1WlgFj2r<2i5G)Xi0V%6 z+euY1HjsUmexqg$A50eML{CKy(BCTrNj*Cp|5(yn;`JtUnEurF$;z{8M4A2>!jw)q z@@t{bLuKca2%f`lon}W?^^J=vhFG$~z}^&17d48Dc6n3mZ^O}PO$uHIlt3<{@ecC4 zMI-CLRqA%K^2ZM=-W^)ho6UD%uB~3!>QYwQ>3@NWL33_oeYvDxX{qRVCAP2(Ov-gL`X9d{=$)JJJ?KqiQ-2toK1vV<-02HNbq$)wv!v-*!!05k3CI>of=*`%3h(&S3e}9iiJiM7H+!FDwU3zJ8zh8YDMW;uMSGSW#JR!bhGGkneWe z2s{bhKzC&5TP+$FpsMm6C8%t@q?&0@izbr zXUoNi*9MQ`c`(VEho5&ERwJQ<<(PQ@$Rn+${|*F!Bh_F{xSFS$A=tE`*IVqV9@=D8&h zXT`ZxzOCEV)^-jTd9T367l7WUZD3zmK`T1vtOhgRZ z8XBaW)r~W-jaG}uBwZPgp%w(K(bqey0jpR{+_|Y=&B32d0Wiy zhauBQxC%JWmjU-kx2+#M18_0>^p1{11;7EVwtD`O7g(=9WQurn9u&!mAnU2H0Vh;k ze|_LOk)RYWAD?lH&6(^$K@^gE24$acL$#gacc3K3@K@hia3UN&#Pl2>GEE8y^LK!; zhy#vIb83z2`dV?BS)yqWWXv&YwH~hciur+nH`#Zgq5jmCMG^&jBeCVf?mxf!7F-i` zC#K?M4mt!iHrTZWU;hG?Z8&`hshL`zJlg?5X`WY7HI6dlCY-7s4p+Dtr?oBo`1BcA z+}>l+gK9aC758U5lH|mt_R5_%Pm^9!eAh!1maoSjbK?v7q-JoB$=PQ^<1d933C{9J zJuNizd{z%vI_OsNmUs^>w7vBq=SK=@-n6y^(tr@_sGfwA(4A1lYnv*oQOmBf1*hW_ zW9(Kuap+#N=iQ>$#Et3)jsIcFDFaY7!{jWzHNrWW5$T*qFeU;OQ9>zi*Wukk~7@`;uJqgOK&RqD7pMi3d7 z_QPHAqHPmZw`a7rD!9=+>|#MDM>>~-Uk8PQGWFC?u6C?_3Yup8?5Hf!fK z-+Wl3%3i=u!}VHv+(k$%u+?Vpr=U-dMu~ts>Ealy4zh@X$IRx0JmAu6^qmEA03AW$~!Y4~eorj7^>+be-;RQZwXTbKaD_9^4Az1+_q1qp!q zJ}&L|D#1xUc`sJ-WKpZq{a|91{$NISt5&eGtt4d*OAE4D7==OAk|J1JQ)mni)O?|* zhuoBjm0j;|z}1Z}=sJ#K<$w}d-v`dTOFs2M7tzL(4`<;08=^CYl{7)X)~L5V&Jj!p>fXkkjq1-2ir;q_VcG@&l_ZsS-bz->*z9D1*ol-r_ zL;T9(-fu#~7+c^G%^`Z&$6p;ctK&|$xRMQXdYClPpJ|=Bj5bAY{+$8!E^iY z9kwte885Wd(>{@44rC#rt8GU`a(YW`xit{W6nk!5xY8DPGRaJtvkriPj)_Hy>&5?I z?>&H`?3#7aAxV-fK|nwe5RsrTAd*EuMLByIGs-vW`FLzHqjqiFh9*h6ngX5B#PHm66qDJ+lD6;kG@Sv;p;wnhxdk3 zhioU!KhG2M#>5X<)hBgdSswRDJ@PX6lA~|nh2ywqt{awb&h+?X-XcR3Dl*DDic}F1 zF>*%<&)cP)E~OWbWx1FCpky)qsEjh~Lj&f6*3>u=mlOtoomr)h>1XQ$IuC2Ft~2i_UX5(hLEKjKJ!@nc+;Wm$_|d5S&imprw59xnQv-ejmksP#u2M# zgO)vca|GWulw*r1tTmwNEt12>Lu;p&*m0^vUtos|kE1Yu8a9Enp!x`EJn;YmEmDY= zgap(3lC2;eJVr842HPiYXFX&dpr{j6!<)SzAwsvsl-wZ-nt7`WI%u7(LCyGf;k(lm zZ0D|>huA^0!i{orJT%zaI| z*QI3f_KWGem-zg9$-Uw$e0Q6_M5=x>Uey`Ro)g07z?b-tNyuHn17FbS=lf!-^x4>+ zKnFPv>TZ$2`cKg52{Xa)8x|JIN|4`C0^GE@8AnhU;*i*MCUdSC+0bsusW_zVl_prQ z8Elb}_PzQ0jxtf?A%iIkp-#UzjZ1rD(l7VH0?iB|eDPk)A&lF!?U{yplL?ygdTC^R z{Oy_@0;|a;ZdarWt(O8)hcrgfnOAfHgUh;mWw!#YFm8Ehdp$60i!i37Xw2?Hw!Ci4 zT*Gq+rNMrw$@PX9Tl^&-GwDO^gP$DlgYm>WN)uSdZob*>4j<6;IN4#|Obn&ZQ18@l zK_)9$eH^4@A-Cqwz)qyJc#v%P1Uk#=L2gP;x+`h{)l@H38-f8c+IZUALNqMw5CesG zz4D7cTzc9vnqzdL(i&SeWe0S&+J9Qf{8&=IAt^Ut;9-DVdNtZijStP7HM>iCs+urt z`_xetS!}AT^4hfiHsgxSyWb`)^yLnAco?^8Q)x};s*AS9`K>q9L1}V51e>_ z=UHPcc|PV8(POU4HdRjnS+S6q4u5bo6&lff?5H^|km=k{$&v;Y0;T7oq={QUUD8US zN*h&>`&iW1@-ws0(hB6WEfhImKF8oAS6e14|Di1Rp3bVmrl80sth1|fORG>bO)<~L zjDxHc;G!RyVR1xf!-`GpbAL|$qccu%*DYVrQySV=+7}uLUk}(M+3`@LP&<;b2OCHN8CiA$y?H!=cADJxQ(dxctDx`kgd=da5#WM8I(m?q-(^ zW6%lL8!G|5)+DG^^itEUXWtlUYvPaDx0J=6^%k)!1dM6jjLpcQ#k+CVn~+_wfrUW| z!64;fMNe0=KdO^;F~Q7{RUQFxB*^*eGlduF)NP}lQg0t1Vg%i34hEU0-ex0EI|Tho zxDEzSVx#h$Ho66aHx1L3c;dk?UlCx7L(s1`H^BATzz2>w=;>rz&&WRk5&|jZD1R)f z?t7g#0a|(Cjh=GDDD-#S=E-+2ehdB{UIMpoah#Ie_lIo9$PQe{48&fbJ6GHXl1XOF zPGzpqvl?$-F&#d>P0Hj~|AkWe3uF+9TE(;N@$eFt8fQOp_Wfe$uJ$m^C? zo<=fXUvIbpp<$%aDPPs+2{SfQ16lrM_!#)A`4g-o9HJFMyebDh^oQSmmL1-+YW`em zzLxvjXJ-2+#Y zWi4$rSRML%p4}O?m$iyHb~aVSI!bXaRu6&+VWgPlu@BonH5+v;HJCI|L|F<+^tVHy z6s-<1-2sqCkQ(H#eBaw1{>Dye{ z{#1S+w=C)HPh|qNN|XKm99Jyq z8ehLwh*j8r{ye4HwQg-{#@I@`jAGXDJDWxw99d-v<;3p7LfKxG$*kk@4p%O|@;lZ( z?(eTWNT9>;2Vy4Si3g1pPGzKJPGv}b?=)lNd)xmpKdtCve*a>Y?c|}} zWAxfm`Bq^m^xJb2x8ZL24byP~xN2Q1Q7pGzM(G33^>hs*MdGRk5CP@=faj6-y}Sku zm3dtIm;RRw^graM{U%weAth@0MQ)@L!`S0>o%Y)omfvX)##_CvszWkzWozyz_mCSlo$z-qgWFM8K6v+C z8EH)#PoP;*QRcxU1zIr26VLqp<%(XVD8n~O$$|$mO7C|Lot~>+?pmUMLe{rDEunGu zQM&C-DfR4NT!Ti^KVM#J{CM#+IoBbDkF>IJVE5b)dX^PmsWfD>487&t|GL?le7k#W z`F_FQSIxB3{9&>MJDM9T)8Ps#36=de#vh7w39Iyvw^B{DNj-sjUP?k7@{6pLat=hp z6jZ43D*dyg3f)59weRJ+F5ytAG!3>7RXwSlJ5m=_36kWVS~j#8Pk4!PyMuV^CDm*5 zFTb7k1f4}(fnF4CR!z?`BEDIvP!p*9EC$P8Vfsn_E2S!x58x-92nVCTu1_l(xVC~d zE!((m{>SF8;@i0?53+Fmtg>}h5tJcYnNNj*kTqV^o)oNH8JQ5!A{CxW6BM=WQ%LE# zm1!!R7P!7h*O7L9>6N0rwu0DLO;r-+^D31fnb1wSXb(*boH*BXazZc;tS4|@a;u)? zKwV>s;@#{&>t-D4ne9KYkU3gns#M>p@7u5+`n20C@iuo!Mz>aQNDX(fF^#dvHyc^B z1c*E?1bO|lBh7*cG`SU!vsA(`VwO?_{Y#Qk-o4E8YvciG({C;1v5w$t7|FQFgFKH^wV*7Hv@51ySyt5Dn; zPiw#gV~O4gqh$Izuc;Om_~Z_0+Nb3)&gA~0OMf0e5@xA9Oe=n%$^!b)z?XKQzu>P+ z*R~es3Ntal-Cuc~&oMI3P^t%(7=94#Fd?{26)GqAu>+E7u}kG@01{J-Kar% z#D}p*>;m_6@pp@lEX;y>@?lu@<M zBB{M;I84Zzz$$@moplEPqJL}SClb78%k!&VpQQt4|Bogoj zx5)WkC4zcB!yW~9p^yNwvc6lpz6;*x(~7gcW0(|ydM>`>O|{*kSH_}QUVbB_(hteI zGV<8#xl|^C4p+8zhu9_T-SYL_J2?Hk7{8RPnJZ+#jF+|dr3dYj-#nrhdQqPGawdc$ zOnMnW28;|>liqz%h^Mp?(CIia+#8a^VMb^($}FGS=F<)IgXrf0pXR0m(!Omw#)ZF= z*^F5HVCGQ0QS{GxP=n0Ud@h7>3z2pU`|Y)+Knm&}c}PpL?zEEBafh~t=_+=dYub&~ z%1_ggK13^KtdLpdY@5^@r|EMs7e9MkPKWzfTPBjSrfiVekfWSWeJ5-Tx=QGVr8&kd z%fi}YRnc$GB}1EMbW2F%#$mbsHa5o87|1t;tYDQD=5uT43+btM=r%x^F=NikQsRi~ zOzi`sTS(@$mB>}{VzP;9<>gt%SHbcu((!1XhCv!6X5BR7NQU+?3uF6$44aYh*Yx&Gu#8nt;Y;KldP zug`H_y=SjZtuFd2Ji$YS{zA$#JaG|gH3i)sl&1K>^Tv8u@qJ*fQ|1djx4v5fF*|^r z9z4G$rMXPiq#QsyuvbF$T(pNM{Pr>0DvM;}d?QgwfN~Op^??*)0kn6s(wu;yAZc9x zdrxc9goN3l+^g}6e=KUN{N!rA`?jMRs>0=JD@_jzX_(Hn^&V)eE1*~6O0pXduJbVZ zzj>zDmdLU5&w@NY7i)UOFTrcNs=&%3YJ&4AV^QN_O!nK}V7@yStMEtA!khg;TMjc~ zRc#ZJg}B%#ht81}xHn~g+*EYfni2OkEe+e8si!Et=N%%zaJxyh*M2m6ZX++dH<(YH z@eKQR79V4psNeZy=EaU<_<0-djaxY=klva8L(r)+$}K-9`{Ezo-0Zl2J}K#Mud*Bh zJ0M^S=rB_Jq`dDv3?vR~m$U<};#c0O03>UlgxQvZSLR+(cZLXM_!&UuE$l^jV7#Itp z&y|z7_<(ia2I;)+Z35tfDO0uDdFoklYu-mkTbi5-%$aZ`_>VrpN%-tX{==##d zZeNeXcl1@Bs}0ss6WxG-^kp%?{p-f}!4B)_`=#BW^DV#PfaUaLRiCiSpFKZltEppv z*OXNh?DuK@xg#SFdb>&HsY6iX?o_jxTgZe3{b<;uMAWaOhUjx z==46?miH+^K1Te@$;g_XC)Oi`RgNo>-Pcb`D$+D}A*i{$=- zQ2RgUF}&dO6WsFu;R()>OAnN&JU=mt$61l$UC(l56Gb1}#!KIeppU8Omsi!fZz*Q~ zzi;yYxw@vs32Fc_W$*FPc*ntS#+AR1>f2s1m{lZ($TzDq}X<6yx~%hpKJMtf4Wrkp}3|vyr%f~1`!6-Gu9Lm+6BrE z6TrqeG4+*u60G_=;=v1L4>GR)#As$noOa_ zeA~YqlkHdycTdD2^^9#$5#z%skIYPieG!ilpB3_W3BjE}4}I&Gc5lSj-&Ud|`Hsql z>WWt=8Fh|CcX8ib$sw7@nJliqdxz3}BC-LCc$i=TA#DVU_PG7}x zubM(cpvtI?pi{qKVb}DU%qk@M6`#Wnj2|sWD#21l%0YZHXIN z+L6SVIdfNk_bZ-eGv{D(Tr@|MNxzYB^okcf=V5LaUJ-B~@peH{4gm!ryc)RCzVXS| z>pHH9^?xMz)q$Z<#?9{y)`P8H+&_1Q5cfo5<-S1`ctbLreNpz`&X(~qY6#Fy76`61 z$A2o8sAjePV`|vqUlMHD)`YADw4;rw>rUB;N>-YbgR*c+;-o(N&(bJ%2!WuY+KZ1D}gEkpx z1OL}#!)ir47STiTJ@9M(k`&7!5rOS{qkI%}L;8WD^lkoM{L-zjpJ_go{oJj1nHUKE zx3D?EI1`d2BIX5wL^!<@S6Bg>(i40$F2xS|kjzT|I&QHt@8L`9M zLHDB$X%9e#>lo5G3{b=Egt{A;`D1UFBd_ur^6SJiE$T?z)67Ni8d<)s-4<#GV0tqK z4_8Ifs#4eLvs2u64PDs>yv7|zaf!t+XF<(l;_F$jX6Mempfv>86QGu38yMLpMFXz_ z7C^|zBW8KF2o$u7qEuDCepo)~Tm5ryp;djVLzfQl9PDdW3x8&dby5m!+H68}I-c$k z{x&!UR>6uFcFhxub@|mQTL^cHg#ja>_lJ6W9wzHO(mx?HX{qL<)igp5Zx#u?o9`v31POSw~vS zwNkaJt3nyc-2ZP-{H>;0v840 zyXHlpH)&k(LjmW+pgABo0MQvMY3Ms3y~zv0g^v+n#N6Qx-kM8n-4pJRp>(pN^J}%5 z+=KU5u%5c~rt9{;&u-jYwel!`;;@smxp#!JM1Bb;jAyCjA2kO~czfUgaf-aUyTQhk z{+6jXdh-W$<*nNrYFZYBB@<_T#Z|psxO+YkS3Fe?7;iJ|;e3E(C`>vH=!tz0ysftd zC?m#>mtjb)k~GbE$I4|L8+9n5LbQ{P?EOu)b=mRRBV%$;lVjE5&m37Ld0o|xM>LX? zm4KEY${976JVmplksKDnNp)*nx2m03lI}ZLLNdeKtpLK&I7Q6O`l)|?>Y9)wi&Aa!GY_7wJ z8WAG91Jy%GHmAopigM;cLMHv&??6gN)6kH7Irp|8(T3BaEQ}VlgT=V-sZp}A`AiJ@ zy#6HRi<2VJtL}~pZnyCDCm6Td%E+XrY5V@`V2K(&FKlL?zGL?>T;={ZCUQz0d@0wy0O0T)ifJvMD}~s z?Wn%@B~^QZp|*P;>|JYWFgyFcR!mW5^W09T+D_zd^r&#s~4=t3DcChp)+^m{+y?2)BS9eVsv)lEv8mPl2EJpXe_{pT2ng)o|Sl_f*d= z8$Ptsx(y)yxd#)tVl?&z3gt5MUl*hK7O7A^+^)45g?*Y|t~G)LC79I`B2m=J%4K-? z2V7^TcI2fu(T}7qhnNGE*F}I2A%aL?geQwk6*=K2x~&JwP0oKKPuDQvczfz6cB~f| z(=BGdB$)~l-9SDH$J92Sqs?z!Zg@D?I17YjpBNMYM12W%<(rB!y*hq8R~(W1nq+Yw z#)NOe$QMDhnWl7(vd(Z4ZHdZ{p%zj6Yqmhvp6 z`KRM_}O*QVvtr+ z7&Pp5ofT(7X#C*!z;D1e(Lp5y$W=^^yYqbF%dZJoMjz}JS6>_6KUwEC$jUH`_cP37j@}MZHu5avl&%&H8~%(hxmonpW>E?htK5NEtSci8w?wa%FTTi}L`QjF z2$5e;TiqY(-<7T88sEMV_DkVseE4iD?DRN*k>>Aq?|+I?k*Ken1M%F)JH)t}9KK?HUonN5HdD^0IWJF5rjLHm2hDAMc*xxNBkRMrg$_ktwDLzz^WCM6f3L-1kwR9FDj;SZ-Jh{BT~}I;m$oeazSSsL-m#aZ?KV zEGxMBcs6^g#5@`xuHVp0JEyvmQ#a6kkajuyNoO_EeP@LL3u?rXG3#^xyJqU0E|clv z;XCfb%O+a=VvX~@CT#w96jWqW7oBH{O>;z1ksXf;)d6#ksd@Tk(XIKCY4@wIQ}%D> zy9SYkp|$2Lqj!>Oy9|WY%9>jEY1lN+fBS7MDEcKI}2wOQ^8A5ZTuOMVeso|h{*UN zPGoWRXD#*h!hT)OLSv7ERwA4HPuS{tMLlxK@Zfd8ew}2OCf%B(sD)2nEEb9Fb?NB< z4}fOR!`B>-JQ+Zqs9gVhA8WPzP~C_$iGuwXl`+BxefNo;f?)d=D9bmzEo;rT-Wmng zDIdQ_-e$7u%LeAtUzzN(IkH&>>~t7Ko`$&S?5&qf%Ws~fP1nUR6_N%gi z%@q4~U@2P!4&qP2{U zgij|3KMk{5Dtj4K?PK(&M&}-ag|?AsIlgH6=QZl4>))5d#x3vf%J`99zMl0JGi${L z9cK^n6KRli-RV_p!tt+?AHCnB&_cD1IP6J=XO&KlP`}c}NKuisQ#TUjnRA=4FQUPwotOaamd!JKCOqiKZiMIWdfrIDn~;B8fC|9YA& zItA8LnE zx;7u76A8?PSFS%!E?qX)a|Q{D(8lj|jl`kJTs^k2!2lJ9+< zwvjJdMB!=jL#C)_aAYhyiK*W``9z-kmoPU$<&4EKZQNJNUfaCMW-=&pK&7>G&G-_ zCM~ij;K{3z!cZd^vtMRqMkZVcHK0WELCQ=9dZ$@2WpyRRBfV11MAo-GB)qI?_6Tw2 z>K1U#tbf;5IXWzANsB`w+4eBy>9m)~{G6ZYs|=vB6tM`A@%AE$YNUA?w0Eg>$+wyO z5yAAE`x?`R7T+3W3?dr)8%Kva%G+CgGPcV)Dhyv3Q)i1l<>VfPdk7#@h>ZrVWenNG zrt;S&E6(;zC?o!Dy~7iy;uxHC-r33KVu!!{1csA3vzbA(}k?6C9v zmnt(bA;Wl<3L$n<1&!rMRc|%(!$N!1b&eQS9y?|TrQfA@#wTjScA?vfZc-ufqB@Mo zT{lAUViT291G%N>xqu{tT$8W&Wqq5Ex~-ZV`wiicXT+~^Pwj@vmYJ2t+))n|G%bk%XV%*eu-OHk=80ob2A$6<4sZ>$7zT%35K*);1 zT_aTKFaGx>PYFu$ny$M(f?Oi?95&CF)7}`sOhNKnJSleIZpgq?VrI6`HubgKBQ5ck zI#h(1KFX9!pIcK--j?^EV0~s>ceA54KLb+W9Cs>Wz)i5TQz5wS~f$ds=(zT@!y{)S4;my&)NLEO1aOepAN0&gT52wT9~ptOfU)61jB^nuM4RbmzH)eL%q7?ptRC z_g4g=>zcx&J87u7{8lqlh)gjJSW;UEs%B2m5BQeK^H8bJSea7Tlo*-PnIYylR>*if zfy?QmQBM6z6(be?P-~$Qu%lV!nh?rRE)?-r)a}JXdW>bF`eq8Q^2fv!IqSx%X4q?C zMac3^+zJKix|Jx1VQ#@2iyRK(NHz8{J=XC1ESXYx<+53`%c;Jnn#{F?JdW`UsE^00f> z*?EW>VTF;xXI%51Bd&~$>&cj%%N+^RgA|Kock3zm95R0|WjtLdrS5RDYCC^RNe}ei zP&dCU#IpLt=rwHntK)ieK0=LVCRgPVBu#Z_6_#uw|J6ocWSt<~ubx1SiqWwwKBMdB z+e4|o1~YG*4^ampvhlo2oujU(ga|_Td!6`d&Ln5lRdiIGLAQ^FY-|*! zQ5#;th%sOweUtaO_)uNVo+^}W*C*vm=;}&3)$fzrjzS5`RTo2cuhcfi1bcb>)Zz7t zpQ(M%c$?egukkW`aVSia-be9GELT9f5Wd};DsH+tx^Wtc-j*~&e!(wxvEfF=n9oIJ znNm%xV(k0wf+TTRG)bQTK5O|?|2li-SDBoQT8=}slO9ta*b4VEoL(p|?&c~DWTdKX z%^3()m7BDZgXD&2I@`Ge!E5Uln>sq2@AFIIGKF3VX7gCPH4k+#L!h*-uCH&i$O*nK z&60RzBHIf#*eGjt_prvMYb)_vlFFGkk?Rf;UH1Z;mz_&HxhmJ*PfR__Gw+<)uyStw zMW5K*=Y^iZk07jtl3%71JULtfAsMBR7aljXKBud)DNul}%G)!JRGC&orlHu-kU>h7JMw5#Taov%&g91gZ-+3_ zSfm@A+XduM8zzmOGgt0_!9PkMez35s(JlK#+0FPPc~D=^H<2}5$z)oAsJYKt_IlQ8 z&R1*QwF@5jC&ehvyKFYKBMP2)WFnkVdDq4>IW6+BV034PS(aLR?j;A(K&t`J<>Qz1I7|{&7gIIMY;$Pa%4PoO3^G41Eq?8RY?KN7sJ+nNU_c%>9kZ-D}tJz^O z8>jSaEfE^ zlE)3ycp^VALs}L)qXuWmK<>r)()VXKxrjAz>zR4&bBA=yCaOm!?aU^-z26LReAiTn zz7X}V`3$6bek1C22r}D#@?!j&96_e&howgrY`hLpM@zRL(C+8UHA`mW{2FX(k8{*d zQtx79ZM>1WO`w1;_F+>WcGCqG8=l;busnj?4lX3lhkNOq^{6Q?cD>rJv^*?y8pte( zr@a@B3>$Vh$_;j_=*k!nP8%9SjLbE+I=DKn7E*W;u(_wR{+f&0Q9DS6+ho3*9?Cy* z_VFSbw;Yy-d~BUcO!8AAf}6e*n)N837a{S}ft5El4RxMOxiA~7f3+IeE=bh$n!K(gh zS3SB)Za(YzuFJ>@uakDG;3}QzZezKG8t8}$cQ!91j2A5eSUUwi%opCcb|YNJaXK6U z!J_6p^yy@^b;Zd1NZ)J{u9OZ$nd{@nt-<;N!39o&0{5r56m3*xbxkBIap zVW2xPfO7nf76gY3bm6(l+4}^gpOZJ3FLO%*hxesOEU=A3FOgzsx0K?3x8uC6GH*;n z?2)xuFK+QJx5W^?fbdZT{om0L;QapE^nZGYk@6+ip&4 z`)&zlKEJEUXx`l@OL!3z8bUkHZ*%N_-SY#E_4@=kasFAvotB)4;U`0DW;YXrBuvY3 z-ITa?I{(-D8)1!vTig=?Zr%&`{;zs;(lYx*3j4k6;H8pSkRlIY* zzgsM~WZiRb5HA2Rlu>k8;_q`7I(qh3P|54x?)llz{UzgDkmRwaCUPKq3Zi(Q{m@$e z%YE@5qZEJdG`2cPRwNPgt)F>%m@dL-0_czddab5Mhe<$$0}m|=Izsspt)0IQE;HX5 z2mE5Q54%oO6i&ZZ0}akh0!4&gu{H=sA8gQ}|BLV=g!u9ubfbCixSc)FC&u#t%lyH; zo0p+@Xw7?dwg00do0m8fJN;+98@QJ)dIgM`sDBwVSR9a$i8q)33dZs{;Q^m+mEvWf z`_BK4-2cg2_Xra)-3lMnaD|=w{n;zAh z?G8NzUYI6KXHSj4vq*i&RY@mYWSn{GxKrv*@+bjI7PcNa_R`=JOK9C$!-r_ zj&A>W{Ooj(o(doHufb1>i4GhVBhY7t!{3R%mE)(o#kn=$aMa%Rge^utt8!Np1^8-Z za*4_y6@YxMt+@JRb;0UjYZl{8Ttsu(fpVM6L+^9s!#8w3%k61}p-OaXN!N9@MyRXz z8y`ce=AhYk(}CeI%12U29%8(be$xG z@c}y0^f}rNB7Ca0%@8yBd(UtX32w)+nOTG#LzVVk=3=wX-cR^)M z^Q||N(}Y|lHLf6Da}OQkYXhu~^ap7LXx4JeT&Tm!0ABEU0E%J*@Y&M7wyP%+C>Y`O zICVv#9cr!+vOHguigj|=+vT_Fm2&G}m0s!=ms$6&Ls91Mf z=j8@M0%^~oBopV_VGl?1S2p}$6+BdHO3y6Pq*rFZa5`K} zE-oxSJ3VUJUHSAreCjO-!Wn?5ot{F|Fh_R9y&~s9gYd@r^1-eNq7T0c3WjXqOFvKC z)@%`Gbh@v)Po6-s^IC34?mfPOW@%mH>^cQ8AIec?i9-ORY_0&YA&b1bmLny%v=u!x zZ%kpMku{#;9216y-wS z_kbF%7HEQP6rfXvqereGKsX0Cw(W0DM^zw%9J9J=C`QqY$pSiPlw>>L?4{Eg25hV2C7;U57qU-VAsN|wKv9GUe65bH6!+UN=-3EcDGn~8h2=QuL;bVAhf#5!1(QX!_4Hd{TFyot8SLJ#Mhm1lswV7b7o|>^uVx9mND0cs)5rIBEjOnvBvp_?MKfl>ThDRkKJB)mxyp zsc$Mfx`?V_kC;5>6Avqoqv3W?sZ^;x)?vuR=02ThX(;!a!U_2(4{ho(=z65KU6+(% zW;`8#DeRH82&#=&kq8i5#F`L;Sn91$=;PMXwDA!iaJUjub3KzDf1}-i2#XTLIA6y) z`_DHX80d6~b9LBrKvV+eKJu%*G+5-VRaTDGU13ZfB7@%-tH2DpgIg%9zVM*eVyb4ZXuWbu&wJVI z+BeO63S0n@$IPLunR~Cl=I}EP7tN6SoY7M+I0pfR`sl9JTw5do{P3tr>{PF(U%tJM zwnWb-a&Dx2yIWRktr;BaSpo~=53Z<`rzmy+xVzH580AE5q^3Ibs;C8-AA`j=a7~R-LdbYVlJW4lA)>bDmy&$i z`Z&<-rty=a0!kUXfGO1nJvTGF=+_il8wUB3G9UlYe3Uu$orj-j?PRDQySqQiQVq@TK$Wz|ycYF>%kRG{El z9s=>>)1)T}tJ+t1eD>UShs7gUWLG`9s$F1w zWCWCWZf25R-f!s#<}>%lL`8ZX@7QZaHP)-4tma)HtKV zbd@940Vm2@q7zK6iB>V42aT7VoA|izODqJRGXR+HAl%4bSxJdqBk#oyyMi_0?mD)h zJjlnsd6ldc`WV=3Ruo~ZQhe@FWAR|E6cVHH&KBlaI96-5-3G4fl}8o zXW?219vS%vv)z-%&x5IC$)^R`wql2f*Q`;5oz`_5MkgT^eSl(B+Yjr zcJ1Z+uSn~K?5WuZ+m0#O&T49z|iHCr$C0WKdECO{}(Mj)m zNROJ0_j~op_#9jNuz^Hu(uhsBR-vVX@6-D`VgYzH-w!$>0?rs3##6C$Euqe&>pF&*wqCl|XF|f^-)8AdtioRLEoB~k0w_{BtAEM)?}iY_sX4qH?- zA2Gz1HqhJFR*bmc%2<0c#Qyd&5Rl<_O~*=J)E2M#L8J`ix4D0r4K;V0j=THWz;Z=z znnui|7OoFzY7gjyL}AR0rRIPi@Tvr-UoIJNiNRmW;%xOP{CBN{`J>NU6z)m6CbXD0 zWuwLTRcr8T`ww?J0x|nTa$BePzPndpU9Sf}XUcCDmb=d;NEs$e2N`#j*axp!7?qDg z_ciEI`V6%l=9edpHj@-vI#k;p;Ma(a?dnf%*_K;r`#=g>3fuS}t!iHN=w2h5e9eZj zpoLxN@`Wwip80eoATto}Tio-Itio9{j;K+B$(#HSs(xID_Z+XaiUCOqN*=^0hgfQe z>BlPzH!p7>VW;&SyXtivs)`}54EE0sB0nhu2PW&NWs3qflUz;W66P>|O?*ekIAB7m z$ct1pzS)t=E|A@xVLi%+dvxWBhCBNw{kH)O2xklD+R#~qIrXMYp`%98$5?J93Ouo4 z!mu9$!y6mCbZYyNT$bj}5(k3y`k@F7%;!*#-9e5rDd6_-#;f^E@+Ox0S*)l>3ZH#0_vIPMKKsVdrsM*i>y3yVfpk*Y!+24ZQNE)gC!p9CBpa!_VZgVWNu%`j z9d@phMn#Z>WBSQwng{6E(|q=`gAc&3@|N1Oe`G0Jnr(SD{{Gijbqq%-C;6LmnK(TQ zIxY$T6l;Qvc1&j-N;_^v(rfG2$mmuZahu$_?#p+;KP)ppoLPa37;B^;a2KFvFR zM&T)S$u&Ww9vsu+)G$gmJ{Tl|_h0x{qc8d1$||6)OtODco*ZSH7fR*l!liGa#D+li z_-ewSkL!&P)$&#BSq@l|e4)~8bfdZ*@Ee!hi>i#v8t-?wZSY>R+84Zm$u5Qz{CY<$ z1mIyyW}Gh#`=F7ml>{~Un7f>^`*^P_wH^mw<0o#_cnM>3_^V3gHap#l(zc^6+k`av%W`drL#sLJ5(1Xg_wx=zwgwOi{+@jH)u_dz#g#Ihk_Xt?$Sycj4*TF+rdE^XBmB zU3{zILkVYjF>Tz}>J>aXq{&ekulEN(3La}Sglc?4WR5%*l_@%YMo=T!aa-&cIdJA} zvqB2rJ^WhnJs7EaIrS-IH*fLA2eag)B1=|h`JY{@xl{5KuQhw)wW4CyLRR&oH}X-f zNfcS5x_*fEf%=YF-T5c0Vd1+~?h`vu}xhRMhVK zTC3*WN39e-A9=G!3k;@P0(F_8QbA9BiUUHV2{Ul&gyQ} zdcx+&xvEVIcur zw{QNr)`32%ZuC=miYx3(o@gs>KijI>DE4JBm!o$+psi#mMtujFYfG5G=m^ZwofQYn z$Wg+F*c1M~9EI})HJ_mmG)U}*!V4OFf(<7!$Z7!gY0WuElZs)Blf8iWe(oWBFu`N% z`l4E|xA=sS6)a~8``A^Kr2CRrjlzE99f8%{mW~97J}Dk%&ht>?g+kBe7oGsUE8$kx`Z;a&t4R=`%wZi6auJK6) zzK>-M=mW-+D|jQ{VflG{*cH)T^(qaq)uJqK@eB_&`7HstAajlKX3pa~r&GBVTZKM| zjgYPUecK3ryoRc*GpFGY9Y_0zVAgX6mkpI+KIa~}eUy7EYeu%}R(Syhptc9wa@@u5;z$7mdzFmR1;%TI# zHHxRv80uQ9W;0?XM`Is@_aIU&t#Ua@P;##z{lIn_^sQTS()q~4zyqdn2sb?T3*b-S zw(P~G;uJ%ZFx36%sJzY&p%%?;TiMLtKz_PK+&Eh`l0LLvEWu>2L%_vZ-Q$t{tA^C4 zeF+tA$mqViixb6HQ{bihTNQ4pE)g%zUW??Z3HKJ2W!{k?8`_)%xw z{a}pR(py${F6Fgrwv8N$*dKm<%I2e*?~QKF2DIkV zT-Raf6+Z9miP%7HVS_d9PVZGEmDDPa80@%TE;}<)iI;qhYy8XyaK94||AljYpl9pT zB)IngAJ*90jCi2!hv==)pER<;NSViSuT$8BfOb}7F>Y;fsTZ_G+qBm`MCF+L<_F-- zWu`0Ij7iW->~`ehDzI<>Sk^c)Qsq$zp8EB%`qTWR(SG=y;}vH4jJLO&&{))!&x#SAulBQ0QC5W9CguzoF%mXg+PeZGJ}wUN;hlMj?-dY z$Dt$J)fpok_qpjmKlu)MF*yoA$9bwMw@~-GzDjC3z8R51wPCRR<}be{*e#=c^dQ-c zAU?-nYHDl=`^Iqwv6+(&z1jZYRo?R$le#iS%EPk_f^aQm?F!=u)bN*l@5qknYcX|u zNC@`_MHMdK%0W1By0=yMjP^};XITcSYOV$C*L2jjqTHwM9=FZ?5e6g}=%s&Zzb=j2 zY8Z*Zc(Q$?rhkQ6Lc@H*=)QUD9MPV#yP*xbuOC5ny&yeU8SKQa?(HqA0?L*8l&sN= z=422tT%oh&)8qOM)$@+Ps}UvhEb{DK!qvn~k1F&Ad)xN%ckhBiEX*eHSr;Q}I_$J3 zWJRpK5X=W?1nUjR(KARH_t!rM5ou=Mra%NGlw#d=;d1;r(pI`25bKof<%ubgzLTQ4 zGhsxdJ(A&_^{$CAHRzeJ;3peUjovd0#fl6@|9m?;H{*ZTdUIpQtG~0~EhiK22`W+H! zw}ri`y-GtLN>%?y6DbOJ@X?VZKttwq?jVc%Lqm2r!ho66!ArU)agN9)Ky!RizG0G? zKxdNKLc|^eiWKi}!wHnIXHid)zGXE39cC@8KN1wbXO6^Fgq{D}Pq zwl)&?4J;J8)|*9!g7D^hMOXz12;!hIWIWkUjT~*#bQb#P!kQ5vSC9`i28fH74FQoV z4=8Z!eq|2ST!jM6nOYlwf2rm#rKL+((F6KGLl9Y$<7WWn85jNsd+#09zGGC?X;y6sZA1M@k4a zg%s|3gL{8|-|zhHJ?Ec$$GGQ=k>MU&ll885uDRNL=JQNs7w3lw@qn$cr2wdc)tIBo zC=dRJIF$nu=nd*lEr1wbPHALLS}3Rvnso%E9n{om(l;d-9iCc*#2~-Df?zmDkPiaG z5n-&%LpGy^5nS)7AhbP>H-=97wr`4==24tHC~tQI1lctJ1Y%HZa{odvjz2?)f)TfPYasFOkKD%1s~5;MLeO;%Ayk_g?5SRgTt!sy?#$7%s^W!vXFO$oHU$tf?qWE2($ zKxfMu!9+j{CPK76S!*Vk{WA%<_R03-pg&FR=%khbA?a|`egyc$p>PC7F5`bLca`!NTYMD2Z1smO_DzqKa7Q2C}n!>?Ak zaQr%`5@`kNJ-dRy>>G!i_FW+ypeOy9j{b7Ica4clt5F=1xF;d1IHIopKn{ z`R}}fctI$XvjK*EhOb^+os`;qv_DwQEJc5yz2h&5qq!gN)x6%{P;C3Ccre`DY~pe) z)y{Gza(4}b;zYgM6{uLTkm`g@9xOO_#cz+x=r;!ubLzphXFKRHc4RxcCg8;NNa-i~ z7WjrB%bT#c@GiBqP+K#&Ol4G>>mv39315Z<>(~sz!7Vg@b|B0!643OHtU|%1FB1oW ztT6?ISP@U=L8lHim$iF0Yemj!vIoMpbAZZ6at%<^Ze3FosCXzLQ9@0W4=~vkT`GRz zErg6P0b=x)vo>IUGJ!YH3iIA}N82iQ5$0TgT6gtqgY@r^CnWyx1U#!~PVlS(Dw<&m z`d3B_4bo2HOs=||^hsZGy#*l4fSUHPy_sj~k`3%pkQBv00RAtF545J^MWKg#^@o);n{iZ=|xYw=yTHD)wyx*gWj=chGoB`U>0^n9xPz=1*xb5($(oo5|G#??FrH9`xFdax;g5-8`Yc@RjKFi z!r41C^?A>Qe>$ZjSPCZuOX2>AgIz(X>@#+j4zjNj?LISYEs2ge3`nLDx|8I@?i@z8 zJ`Hj~=tTM!-Vcphw5ApuM8~*)-v6rerkYk!%@_i(yOnEWG&LgUPaK;7$ZTDfy~+If zR6@*8Q>>T+l{molee-CQtdC?#3hp6b4ms_()GS+{+OD7X0`t1EvL-73Z|97Kmm;k~ z5CloUy=srg0qt^&9nXHgOipNQ!~uzAlQp_cL@hq6-{l#QsoZxoea|HrmSq(czN>lx zQ*ZU&xdl9W)Ty6u+j_JaasKG>r#_s9!TaeM z7)LF51liwzAhHNm$#3_CW-n#SfqAkD*8(6>CH!!0lx*r#MZX)q2ehyZ_|uP*&k5HD8a3kS{ki&hCb9lp9ju|bhbFjj0=_lT|K=K-nSBE4w zAeY4H)N}7|bjZ4p6`Rr5f}2k2KsGN)1KZ^1Uq)9XEK-j|N52Q@kCl2G!<7W^2UrVq z;q&FPvi(Xj9`s^nBv6R%+J`0 zON&WrK;#ny$ZofVS(=wdY_-!n)4?QnFtViqIIKE;+%R5}xcEKzdJulGL|jL5rR9#r zzpBS?f~~RA*KgkB{1yhtT#k4weu;he%XKs*Evc_7#M{uUNGs28i& z8oVA=J?{SXZ01b-KOjrl@-wBnN5`gC1rX-GFO3bD^^v>x_kC!!ZxaAWz|GofCgGU)N?+_YC}2qGkb;Fe>2JMEOmFa- z$5sv6>n1b3$9pV1$9t?5zb)Q?WR~;ZQM5V!+hNv7uj01 zrO}5ee6<18zst^L%>L1hB}Bp3_OJqZSd;?bE$R=?*32 z>)6Xpc|xd6^uR5)G-_!We9yC@N|uNQg}+ftGrhym+Ph#S?%%9kkZT{mejfL<+rWF} zBdw&v)$hjwPY1nCv_K<2eY~Px&H9<_-D}N`uzjI7*+dY3_&eU9FZ2Pa_o+*txMf;? zth*jd{UIK@H&W?K#%RtFR*jvkdkn&q*f#UULX7;0?oZ&O)54`DGmGHg8{OIlT&K-L zxIXFdDC5?ui|0Q$=cp7~Is^swKkFl3KX1GQ+4y>Xs0gKUa47*<>B9yx*;@hySX!ce zcNy7P#iUx4)m{uY))ek?a!F4;*Se+xzgayX`UrU(Ta%K<{V6ck*?(QQzRjpS3{`x8 z#BwM)dX}fSn0K~jkJ4XZly_vpu*IgT+XrGTH`{%>zv5l~L%2uy{J`TNu9>J!cuAlUNH_lld<{EwvH71{w?a){FE+S> z#Mldnqy93zH^QM=_F&|iZCx!(EM3P|4}F(#ttFD=4rm^lPaZLZLl!pvmkM3CHoZRU zn$)lL`p&aQ^CNCw2FD8e_8w3j`0?m)*T>HX&NQ%Kuq(o(%5LinNQ>UVYk)(x;j)vN zo=47Sbvl<1V{Us};M`aF;)`fiWrM@+)I3R{w$q0P^W}ja@sr$BuU8;}JcFI1G`jlz zVf$!u%t z5SXfDzpa7Q>vo%(8|(>dO_WaZ{xS}f>j2?8z1kRQy70ohwz*XirCGcBLx(1s==MqC zA%ShFMVv0r7C~vYUMe?ajUd%JatE!$p-Z*s>DZ!5*s(vR1)Uc1G%jgKIDJtu?R~vV zXyHn{ddRtL89?MSl?GsffkbK-{q_rMG;XhBtE>l_$1Jd6)J_}Zbj*QA6nleUyl(Dl z*7{eXF9~eIadTXvgw7mW(MYiVSc+Ob$MC;c_F>41$|h&?IJQ4(?GzNR8oN%u{1~K9 zsSC^;$FPU`;;>5X#x0KRoXqg2iU)eOr^|eK^R-02oXk~;E%KC=ScIexA^^eZ@4lf23&BgoX$ZlFKecZ9YD?f&%skg^T3`KzXjX{A*?m-Ws!?Z`WrWjd z0+8#@1=SD~5HD~x8)VUpF!#p9$8g9we{X2d@C*h*d6O${zPSLS9dU^+r}d9NcU^2< z?(Trux{pn|PHY&yOK28mTyK^cGfZ;m7?tW*{((w8qrd^rkU1^%>qd`WILb!kSPzKZ z7fjBuwR{Q1!`IE)FIa7wNL84Po?uwwpPqoX@$ac?h2BiJkSKLE%I2pJB~KsZKhkj<@AG3+;Me9fA-D@mUOTAOgEt==@8I(cgB(Pe;6 z74PzNFMrt{k@}vuSHVbmw9qH{9mxjgKcK%?Wy94yf!6JlA8{q*T_G*KnEQn7)y)@h zAy)BUvXo(1E=K#MHLxv+pEVrO9y=Kd)qL9}m6Uc<}4q0C!1Pq>HNY!O!8$`j-h5q&S zy!>%(^LrQMRu0~aUtfCc)@6%=`W^oPV(A=h=U~VcQf|7l6P73i`dmAqH+Nde)w|Q%^rb3K6q1L9 zR?~o`C)G4%daTveZHhjQUX7`SQL$}zmRO}Oi6e%88ejTaT{Jk=VtQ(AlyTuU&OT9- zqRHEP@`lVr0r0m}e{G1>Uu@GN`zdfwD!K&J6h6_{>6f}G2#<(d`7})ZUb`(}twl$y zn}b{R`#s7U69fFJ2r_w77v*Dpeer4UiTy!uhE+b$t`8~W+!uP^=$}!#9b2RKwDYBb z9V*|Sz@AZh;?RCWTdj(lQQ3FOl+)EMgVI~_p;pFW4@%GZqXI91bHVwyJ1aHCn{-0_H4iC=~X zjT#M^tV!2T>9;OKr^%RdU=%AgJ#rm_JN^{xh&1zk`%GXQkS?6dty$&kwb4U!3yfH7 zy5MRto*<#K_U2Z-CDl1f`-1FuP8_W817O?kW*BTspLFe)dZTL&4Rj5a-W;9X`Krz~ zy-I&=QjlpOwz=D_DLUT!XftOtjN`6zSE1S6NhsVeDr zeDBJu&j=cllr%EIPBUKym5c%43m5U1vL1NcJ$C(RXf!ni>334>kq^i%k(Az1n>qdM z@zKf5q>-`dujV_JJ<#C}7-VTZ)o&ail2zKZ&^A@9;|R3&5g%6%h4`I_!1psXl47H~ zL$)DzmfJ=yJ2WB>a&F$OJ$@lSYeK{T};z?tT^@{-2o0+#NJJ^kdE7#W(nOAd-SXOt;))c9&61B z{`V9`O2<{P#EKO7p26uxUyzdw&GQgaJ_vojZPI>UXe&#K8 z>s9%GgNT;cp4$f?B8O{NT2qaCP6cMxSK1`w)|BcQWX&I#9Za%!YZ^EII(+_GZxTxW z3bK?u-AA6@4DhBURvxbWghSHXAx-hZqKFwu9rI^4$!m`vYz}N$ZcK|!jcpMen(~;l z<^0~Yb+;1pe5~Gv)FJ_}q5E72f%K8NC4vjbx0e~>`&6o2Sw~)TVeA1224A}TiH_C~ zRyB=#n%EBnSqmME?E*4~B1dn3G3vT8{L$8$VAs3kuay9F(w>e#6)S!53hPZRNRWXK zf*<}$@%HSsO3bg<_d5 z9Ju-Hh$N~>ke~vtb~@0f$rd2KO1gbZk$y?#0e5-}ZA2w>hw`Kv;@s)Z!)am~AhSXZ zJP*vd)nF9YnDKPn0KkHF z?UG@wt*mHR@8+%WA$?j9G(_i zENPN|55#ldfOOt%^WKAs==BmMAnLAwWVVxW>LGj5p&}sbS1U`L6cxw^zA`qeN-1V^ zH1xcfA)`nMHf(@&93-%7tlyGgnYs|gd{>|!se26s#1S)~df6@&StJgS*=qoAMry`S z#-}9Z^S2E{Ytudb+wZ)4S_Al*n`eH#3%%XJ0Z}yhYwxmtc>qC`$aJ4UMcoI7j4j-n zKdhSrrRWY-N2rjq;-xm6NV85PHH2$T!Z>DSF6c=dN(E}YivN~v^$?1-X=VBslEq`M(8q$%UnH@C1U~td8 z)A07vM!5RUi6rSUM>MNUHgdJ0R>Ky^D87G@7g2&=WTtF{2Dlll}6$C z7kwYc>47SjvoTA0zCKx98-(WeegF19=H!UB0#442sE#*_q#TKOz>*=3bO22%8(0GD zR|gQVX}*^l^}sq7^9?TM`MlVKG~cY7?FRgU8f?2Q6o5E~)8<;yR3J7Qw^LFP(xCdd zX7&XtZn$>nTGONR`3H5)6`v#${g+Ln@X~DzW?SWhzXDc7mjC7J zhcYvuPfr9>bf;5jNNUNY8IM%~D%cTym!o7rLL@ zgk_d2PmnHt0k6r%{Jfxds~Zo9P ztC&-JH~8;`g0;(q+Jt3(6C5@O)^tBO;P`Lk9Q*%5&gq<-%)tD^&QVC+b6G?G&SmxqI7NN^H*~KT;lXO+m^ZGjUmVU!SIQZL>}PGZ6Pi^+UWQ=-KHmC?IRO3 z*3Ad$pobM->1*@d85HmW%Yu%eC(r-siD_wb?Lk#o1aHTc9nXkB{^u6oH2ywZT6i>JfzD3ee)(R+&&6KY1kk{$BJts67kPI;HQ))x?@G$QK? zmu6a%LwE%MzwFa@RP*Stia2a_L$CH%AYp@!>{`a+YPk<~m~5JzV3MSFx{TjbgqqKe z2IjmM*Vi;=rHov)H_DhO>qf!Vj=3Z5ix3>f33DXPsBTsf8qFLUp+L_OP z!5h12&F8Xpu~6!krpT{0y=&Zi%lt1GrA4}C@^9Bge~fD|oZ(lc>F$LYdHFs?fZRu; zHRJ?C+%7s!Hc215iNZTbjrRc@o#RjJ1S@r(z{(B3Y0m;Omb>H|GNAb-Xk}uT9Fh*) zWgRYl6f9@;51`C2RMW_&sJo5K~?Pwb_oSRr}W!MiR~=$B7E+@ls#qgSK5)*xJe^ zoL+s}ns-U_11LxkvY}+(%fmA8Li*q-43KSXfEQBi@Wpb=^+F$P%ywLv^#CYOf>$mm zp?c>?E=U|Wk~;YV%IsawGZ`IrQ4v6|)8%P+q^lw5*)F=_ z(UJGR3XH`YUf5R=VDioW)RukgiA|sT&Z}i|n+TD&Qg>$!BLT}L@`&qD*6Y2B(5>^X zP{F&zY^S9SyWs=M%<~n^Na2i~Qvc0zMh<{3IS_1xTg~iJuUMV_erIr5YFJeC6?S}p z{DH`IC$ABK*k@wm8H38Pl+1H$ZiB+Tbysb6%nb#H!N5N({?>=|3q&6~YX^mH)JXfd zuJKUsap*^^?pCL)23-TWRO0;Th0e$xvu!}?V%u+|**6IGj}GQ%L3TrEw8Wj`29aiB zG*IO@MC{(plL>w+&E6W|P4$yUEPqpLY>@lRvc8{vbD#pQRec)(Pd0zuk2T87{Q4nd z`b}Egxf`1VYf{{>z_nMeg*Qw3)iU|ta2DXT3eGU+d={NS!h6w0z@OL$aBnoH77uAV z{}7!QP|4_DVL1mtVE#iFUSshgzmqfmS04hH7#xIW{U5pqWp_)O>@?L^AG=!dO`Enz z33i<=QL)I0{+AH=ipL^et@C{U6(+nMu=X1%gPSDyXhRg)ssEgCl@(7u>x)O zPlJouWCM2DDnw(N)7R4n*zAXY+ zhplA(LjhwE8WYzcau>xUtV#q$BDO(G$K!{Sarf}eVWa^SkiUlc{r5o2oxP|cU*h{a z&2M?ze@a}yAT7AzKxNK<88u9Y# za@nOl3RkBq5>~j2{hiK7{_o1&iC>7j9wv+AJ`{0NUfMG({yTRQB-_Vh^lMK?)T-=Y zbx525M3m57-+~fwF>zxB8zgiLF30^-XidZD>(%`>7k*|% z-OBxiIkdL=c6)>{lY=oWCl6sXdXo^AY%gT5^?t#x-yMUxRd2OL`+%~1#YVTIv~lW< zm1hOXuKmez61S2f3}jEc7-#K)F*vc+Xm8BM-?My|4o$9}u~b!Y$tg4|@r5 z?H}y0OZ>I_*BFEM-D}A`*;l`8uB%A=cz2jb#WMiOC8kqPY~ju>T+F_jVg4I<6J#9& z6c8s5vW->lzcueNPb8SHycVI65`IT9GNitD&`4pS`NYN!89Nd>@&TN)oP1aaRk+$0 z;6|UW!lkA-=b(A}T}mCnKTj`vmER309maD09Y2!XZ5p>o&pnV_i*HQp`@|_(!7|;9 z=mCk-Ae}x*sY%fJRla%z6uGeNnE^*<)>ab)XXqnm0+Sp=2hG*lVvc$v%H>$sh|ys>r%Ii~N2 zw*>%ru&?9H9CMurm?7mo_((7-yPw`Ms`A%FRR(jcmtB#$QX`p~lvURo%O|{_= zJN)Zk`Z;a|DzkG%)!($WT%Q~ny3e&(3I=^gQ?whP%rNiz6Jjb5AP{MD3(#7$gq?36 z|M|4=FkY&e8Ctwt==HAfz*woRX@T?gd%*S;COnzqJ5#+Av8>|N+*=t8ad{X@;d4gi zw9*^*R3NLsw1pv`ouTRW!RNb2>ibk65VZ_rGy+11ix2iLU~S3z3E)$wy(o||h5Cb` zH@+i!`YN3F55l>C`5Fd5GA+E#36;C&ToQ^0juVpa?r>PCwZ@pZvk5ivmV3zdWPkNW zOMnC24Q+lO)oN^fxZT+ykycLbCR+7cdka_?X6(f2%oylWm}3Vv1^_`u9T`E7_ih9- zk6&`I4xpfqq)zR5>Jw*Tx~%E`fqy4^Zhbim*B;G2So+L8jk=@MplJ+#(lP+vGK0AQQ$LLJldN|DzQT~o81dXN?6(&!WG#dQNZj+8 zVDa$0u=?sR*T{-z<+rvu8I%-mZs+ajTo?7loc#qdu0wF z-VN01wV$m9(NK=8eaDuaFsTjT=xWKqO=>T8K|#w{r!t>{qy?|lzLy#3&o>=gWimES zS<`Y>`|;GJ&sv}}BEMDi(Y&M7Pc9Sm38sbo-Nq)s?Th@jQ_-h;W)X8_EwpPAw_1b0Y45WYeZCJ5{}r@k)hdOrg!?^``u@giTqq|m-Os6aFiAL1`?!qb zI2b(Uayxo}S=~00*|<0M%~y9z)Mx6~&)S0*?(NAK!JScKX6aevj}VWem~KmR)mPq2 zwXk0&f|~zvP-DvyB$HY)wCnyOa;4Y`WN&6Vvf523bTeyZlAq95NVyRTFPf1>i|1$b zeScHk5`I51Um_EtLJKvdvYx@*1??_qJF@c*N^Nsrr!5sIg0e?lA(;?T$6wU^F8aViJ27 zlj^qZ4q4%Dpk}i$vQ=z{s@m{6Wb1sn!rbsPI~9$UvueX`ozD*6!VY2^DbE))bHu*g4@N%R+Gb=hX@A*fcbYS9#2vBLor>9`V#Dtvo1HJBU!l{> zuMfH4*2ES{$suWJLGd*u!(ko61-`vAr=LDLpnhv%9qX+07K;+OlE21SnDixYb+L8K zl$XY~duK7qBA#PDeiIvZ`5Vi>jEG*>TS&*f!M_SWzg3a;EYwqzxn)IyG+{>L%VhpX zjN`LaK8~YnMpuv>6nzrKp8d5&u4HtXm2}V>a)aom;F<_jo6-&SoEJv&$8b3gD%isd zMmh=Y5lQ(;eix8Eu6*5fNR2~e1EVE`sH0C)R|jlrl_Y!=y17AanU$N^u0vBuXgbav9ao#UDI7T zx+VYe+D4xQ0*cd3vOkuPoYgqnM0Qmcm2G@P#%wTS)r@uKUfK%Um7IGrmvabdB=SLH z%2d)ZTH@x4?_QfK-#?36w$`L*&S$Uj-PYR;(w!Q@hmqvNJ~rR{)}2v2=Y5Lx!z5`! zwsYh4A)9w`4X*-SO*$q=C~aldmT1;h!;EOlcRvYsx9`qb*FoJ{=;e+- z>?O~Nlpj=87CSG?+=wtFeAII2S!-?PGJrJK5*?3Pax}t{Ro8T7iPD*6&fg8GElo>? z_NEhkesRdsgfn~79Be8`rNafK685I{y_ske*0_dmf%-?(!j-vZ!V!@V-#BB4h0WOG zp@yYcaTQkHhX)mdrAbT>&`A> zev#=i@e%LONVp4MO8pF3o$gAd!|pS(X{SfYMdz?$=cQR~LR;l@mc=Ct{XCf}<@KXv z#b(VGR`7m5qZ;&wuLqTavh&*xHS3@9{%-u>;6B}@iXjdn$TQRLleXU|P`g+2OhM7c zvd4Aa!1qc3xhQ1vjmE(dH#vMFzw@Vkl+dN^X$pSF#|)Qk0Ya?MXc^IC!QPEMIueIz zJ7^sh((u`3Q1xI+TIUN7;cW72N2&w6VSL(5*si9d^r&tnqxL*WsVkmjlSbSRh)u7F z82+Q7zc^#O;;kabvz)3l@rBdEg!0zg{^X+GAcAn&aN_fJH>GbRBYfH%ZaPXA5PU|w^ErY{KEe1|QberI#w=PgDf2XB!gw@R)- zQgZ$rY0e;F{~^Ok%<%n_`y~itVuyz$ksnbvyNf62=E3d#BUz4qHGmXU>Fs+uI& zL`)1n*IQ=wabA;A4qZH5@oLRAPxwnh-eRi0{X^VpH|ZOYhg@MJL3HQB9Y{n~@F6aH znNyv>!Dv}18Wi3`g=$@g^qZ|wYjlJJAHRw{J=fAwPJ+m;Sbf3E$1I_7!~UgN5aXe#{SOPd^sQQr_8je6b;+HFtD{WL$4yr{ytUA+v~8 zQ}K{woZxftoo_(?7bFILcB=jp*6$}kqLCL$%CDLdiuC07`?e&U@cI1&U*X!_aHkBr zw};BP15tV;#e5-f8W<&UD{Cc;DKGT zUMN3P8S%%koD#waVeT)LsXM!ny0Zk@u(rOpcW&lB&dLJ$$EZFNo)!+(77}y*A`-5j z&Chfns;ty7*3+wOY2WcL`#)OqO!k>V24j88s>vnwza-)$=O-tJn^VnmQ>!2UYhX8= z*OAw;Ea~9xL5`u8#l;J09m&T}wV6zyLwzv{^&3q7?w()4n)BxA>Sza20d7!K)mL}u zlfQCLUdG%nlNG;qo*#_C9~8Jam}AGEBr*b0%yLJ#4Y27f+8`_<*I2Yr1d z%eqLvd01tlaq+=canVBCsjVj;fMxz}>(bxzPxbr}kr-DsNh?TE#d#v+2R)=-G8J?a z?&%NT=k&3+rOh0^z{3?KYET>CQH2Ng!1~|*lf)j6 zj=G?uWj4&jLlCsE5HD_g{O=la<6YLz5-68<-MJ+dA}Ch@KB=jg!qcvW|G$qYHK%~wTpcISf|bAnP2{?>%x8$q7o}ij+w0LlYGxV zPG~q+Ve0eh)thWZSK5y`8n5&5#<|OvThiz$bJ1b+DAQMSz8pHfV(ZL;0*d`HV0_^K zo$lF!Wfspmw_1=7cVd~^0YLI`X8M(s`>6^242{zQBM)nOUYM2uvhboRHK<8T{DZz+!Bt0W=HzE6jV5Zsd7l};UwnxE2YabF1`I~lxKMpr+^p(NBU5HtW@F6D;RSH0H0 z;~uAFw@y zW9PM1N+Z|5YD@YG#~B8w3G9`T;3o%t^)8{paSFUIhF-O-mfE)9n#V$7w>4C^T|IeM zzd#QDM`$;6;Qy5;S;a#vJ^bu!If)xV@S0xmz%!ZRxBcDKI8t$y!!cUGezsO8^3MFg zy41jL6L$QY;lk{@<%qcph-ThG1hzdwuim>cEcTvfiHN-O^g<=Jv$7)81bdM`g;>B( z9j5U3JSr7Gp}o*e=i!QICb&V97>+ybGeCbsp8|bIrv-)-HD}bmGr}Vg9&+R|V5R4s zFO+pV-$Ac8L8Or=;+|uj`)e#_X`Esz=VVE{Ib`ogFO|VLYjv-iuJbPCgwR=ao`p-1 zlYRl53Gaq{C(cL0yv`+ttzCOHT(8@F_GH@B9` zEn7g%ze61ruIm=I^6ta^Nb))JFdM;ZKs>FyJAay2ir{XYa#vch5V0`La-}kqy8D#+ z9PkTFg3kmchOg~I)m$wYXv(2K#{;9DQ|no{4k8WN5g9eP*daB-dMDzi7&&JDW&&cze@bjo`KR2T`^JD4kSZgAU z%&j4RqaeqxEsWOW9^ox<+&XoHjG6Gqi+$!rlDO5RqeYYcOt%=!Jo7M)#IpqD%cxgJ zg8NO0b9KN;nFK$at1NA65-+* z;em-L->;QZIoD3$wFhW;XKHA&4^ih+sb1w2(rf}A?^$z0-t|BPV}zxiY=WONK^2V^ z632Sgko{^hB>or)S5847D0pt@0;h`Jgi9xIfrJDmNV>yCx4dL!t|G<(y5Y3<| z;QAEgahzQIaE)4sHJdSy?xdA02g~0!*fbX>f^NW$o0kc(#;vJX&!}8Xl=$gND38aW zE^z3DdtPR#sJQw>F(USzL#;Rab%f6?ET$B0ww!${OPy6u!q-l5(6cAeYe)=hJY(2# z-i^+mpyQ@z=o}*5n?+t=oAfy>l;iV`q~tie7looYnbuV27R{n^&1i1t7;$1uK9)b5 zM4gm9-;v%fR^q-ubGm^bA04B#;%KeNXg3)Y(-nmvO@QV&GN`H5D3?3Eb17<;!)}(t zlZ7PCLZ>sKGN09=xf%F!9P!Vk%wr7%^ciKNeP+kxPITzK$Mr15O-@RYCZz)K94FH3 zq^{GfuEN#?|5r_=iP*qd1L~~7_ODv}sRfgV;S7ztp@<4Q#8wWNX{oIISlM(mw*npP zO3|ClAtn0f_49IkTX5;?B0EB{-NV>!X(!6W6e~yRp(EL*wGv`&NT1pe;Nes0aTG&g zG>{DW1BOWUsUCG7+>|WdCAyh^@pP0SXZ9|K@*OcLgm69{=RImfa4)B4OZy_&&k>mE zVOfece!LPl-b>{b(vd!m3fRWpIZOIwgoHhl)8fQyQ6St$Vo5~wfP2pK?Vj`qP~V-9ALbAiZ$w zvbmze{AM(7t}4lxvYxixlY-9VsbNV|8%daHSH#SIgzGe?c+i|UDDA|_tK>PkAZShB zD6SoI`=K0al7Ahz?YK=L=P(S9K1t)umNj&;6V7j{qUye zCp7t#%6ck8+ioh$Bk}sGWO+(GAU{L_X*-wW#K{@vCxkk@wnMzp^@GkRqfB3V-m zS-qU$+%X5JsEc$BJD);JdTTD%$>)xM>2YU-LBoyZ;yCrl4ej#!Qr)d{vMxEy0U-J( z=lxk$Y;?n)8#U;&++F2)hFoArQ29xr$t2up()LZ+hEB1}>(j}kd3+@WTdv_#Zs62f z);?uaN>kCzG7QM!*!`6#8aY!}+#Kpeg4{W$EWJ65l|LA6D=2IN`;AOcW-i_poQzlj z{gt82M&ix0oW}i0c(Mb;opa?2SB{`vyP1TkVC%2Z$Vm~@uA;jV{Kr1&#B6#AdaS~0R0%4%yUZbX zo{`!;np!8l1GwLUQFJR()Tc$S({cD@GB3ZdKf=srYZk8q!7W8-v9&u0t#S`YAb~li8#!m*n-?1k!E@H>kw# z>T}|La|)*RgH;<(oQw@&4pBPj%fMuoyHfq9jWs2FsbDYP^jE(ta@h48Kir8EMU>?& z6^ywX8oz zo#IrI_TBZN^ye0X*&jdDPhI6`oim1?aUu@X6W{A|3UKhQ>C=XbWWI&k_#X@V>G+o1 zN>qOvjzCyoFU*zYYLB&YK4*6~wB=&e&XYl3U%lk?y%y}BJD?oWl-IITNhF^iw4yj} z7qxh{o+x)uGa37Jf_3tx`4;=qN%y*=yqwBVR(2+S(1cHBJ?_cHQgXZQIdYC-D?{aQ z)ww?UKDET9C|2oI#L066D)7jNZ%67rVGrKr4DSoI&M}lmP=`SG%KE2TqvsqrZ+}+0 zrX3|^)-i9)b(^+5iBVOJ__uX_6=>nW5wWKXYse5U@w!{~Jx#BpLpHb@H}Z;!Aux|* z;kDl}Q<|J|r7u^K>Ki85MWMg4Rbm=(L~Q)8{?=wYbQ66xzmm=rE1~HP=AbuDdYoW;zx^J-^Cyt~eFT9Z33`gfstjR4kk!yE&xy3)bd!a?$r}l>#5F zWGsdFsGFfuU{8k6qf;BZbBeJX6OA0F%;E`YUkWOsm5(W;t)~_6jJzsI4;yjhAYm&G zdtKhbkkdqQZ!{yqIETaPk>U4j#PMh8BOF&^e};+oEvp51Z#d-$Un(v@ofjZ`{O8`S zGMG~j6B+a#_-w1q{t2d?HBCP?tE7?d^jC`i%l;rEDQ`O1aMq$0zA7O1;~Y8J5Jm3` zAGEKEn_!K3lN^}$iUJt4a(PC2opv&hNXd0*rR|Spdd~q%qIcWiFmh#;;lM4D(XBv{D6K*bgl-9xZv^3 z{Z4?|#y{86&0s*5_%xFkQ*q)dNg|gxI4Qi+q&*>nrh?f-&A|rV!b1X=w(Hr2k@H2|ngxU^{d@cx*1AZ(Y>oVNWRFU*m znsr!6?e9-Nf}GD)NpKNvArL!!yNpq-W8w#;0f$zOFx)3HD1 zSqwDGAMM#oZwFnYH}QjSa;g=SF3FRfsQe)O)HQ{z^P(y&3Tw(7*r1__L9W=0+Tf{` zj@`gZ!8;75RE|`R5?Pd|U8))Xwj7>a?&~q_|6a6sfkDO5cdW3S^?y#G-giLTrStGy zSG;wXHRro2nG!Q+r?_y1v*Dq`Ic7J9DwEo)^5!FFd9lfOk&DQ-o zN?p$`X5Z+kgLlkr`8zG(o5JKzO}t@|Cg*GNVJD$yeu2tet0R^L?*|u^orA=~w-@iX zp-}9B$=8)yLzDCA3-byK@G_Xnj*blVICi63;!Se?0cY($$7;6DpyV2SQMR%&{qywu z>ojRR%#uQk&2g9*s)Iyc{duR`4N3YgUd{K}{W;0CM+%@fx&Nsf zak>NAkfQG4YVGTH=FjfImv8t&CL|UP-^l)X(b(B)9Cg_2AV6UT9^N;`iQz0>UrOYXcMn zb6M5q2u)&P+Jx(|5GAzeb`O?iF|*qjo{F1zgUPOHqc0pcnG6X6V8MsBK*T=h1>TVb zDPMo#o+di3z1PLitEzV?p6wqHfSP6p;CUi=SI;&kl0LBD-i1ryUG5PIj)Z=#$qZ{5iZ|&;HuQQm-|X=kDE$b89PY+zY0XQhAbqMryS!PmbX>OskBT$k zWYdC^wc;IzTMMY4=?`mKeR9cq@}6y(0kmRk3n^dWo>#~v9Y`vHN2TE;S=}5Z^ z*J@N9#m6bO%0+!WH4?nx=BW&Xj49ni`KTWJ{q+!HN?+wH=OvvXI-N4c@V1!UG0Hx| z^yW*YvtvOmQOV&^+eKB zt?#WJ1_2&(l-AEV=XR!A1ltY7`SOw>P)zS>0XDwV5CL(^IU z42rUFj~i~U8|Qv|nm5v|52vzFW=o79blD_ZW2rv19%J_d#+c5U@k%oeAh4O?1KFcX z@tpgYdkeanFoq|fRT6I~N}0 zY1NjJ)FJPAUS$lQ2!gEP%Y8$=8})yHIEhmdA!9;=F52ufb2}facdtktJ)>=QhdS*% ztR0P8a7iMmfQ>6bq{oe`xPc;D5tK%rx19&SIQbL&0uz1%?!T1$L{Wg|X4bg{92l-E zMJIwA9;%&A8Gg!+q_>F5 zcyyPKFcBW}oW=HW-iCNG^8Bs{#)KVhgAMB&R?jWnxiIGX7;yXv^z@Bjs z>xUuU9xd*jUTkIQ=s2Y5?g+kBESBRmJZGO0l{w^{Btjjb8iJwHU#dg6SnGXZdQWVT zsUy`zJ{^Q9L)UfWYE3#T$|Q-j|6@S@#gm|usDT)bYMK;hs>7$2c_$uQEh3XU?fhqR zXycv0RuP!*QG*PBo+t2b@2q;_pkIJF=J4k46SGX%q3%Jm{;y^%PhjI)!DG>Fp{<~U zdQvoVdC$C8|7O|wq~>YM6TBugCbN^6f%tE`N0Vsa$4}E%e=N(!YhlNO3V|INm^u-e zOs~AAcqa}AxIJ(*)-Q#kysMBsGYh-TA-#*OLa*~ zUvzw*y5fZ^%1{pQOTtNyOO>lw{jPJhSQ-&S{~d*~bZgo8s{+w*a_x z*M{EskbrKc;u|Lg_$Ly+(tJ0ZZT7Iy&Ll!KSb{_aOAuC}`(JAiaH3$rl$qEI$_ZXr`lH#yLK4qi!Rp^aQUZle^vE$IP; z?$)dj#nE06ZS^4&Y8f$%Tky!`x_f@0_kN-~dEtxUcRv8B_jvR*B}cFiR$&a0Oz#=6 z=yq#`(KN@BEu+A~A`LIr!^MayE=Eg?9J>ZbYx7tRo+CK5Zd?I_OOvngA@xDe7m>V_n>xVa z;BU`Ew*^Po8ed>eN#7vt5fj@y`Q*@F@R7h8{v~KJ4mE&ftVWLc*TW8O<0PNMobXDy zHIu4|1`R~-g60p%+(6%f_ilO(a|rY$trEd>z zYl@+U!Q*!nnokPjHl3z;Y=RBmGhY`VsYWH&z&6PhQk@~-HR)6tN3a!3MRIt<_=%Cj zPBX=rU6t)OeF~?2GGlY=+707ACsQb|7Tp2a7h&o7-E(QXt1hQFZN97zN0vD{+=Ay(AAE)UP%$W85*-_JSdt|>{ha$YEJ&OH_;@L zev6QV>p~t6F1Elq!Na?_4|{cMc2xTut>rP6Zk(YJnlZX6^HXbwKp}ACve#W+negGG zYe@-XDObg7sfPkCt?M{lDuGkX)44&+MP*W4P%}Q>gotj(;RjDGXLC zYEq+B9-?SxdFMAv1#*h7KHE>Nu1(cgQg@VUu8rVv+l5N5w!{X(@4F4M98S7uNOGmI zFGX^Sec-Q>C$gF|iKu=b(Kp!-f_Z4i1$YNQLOFPso)nLpt?V1L*gEe97m|sL>X7%` zddpevYa1dcQp;lv9`nmjRnvfXNCbr7J(P`*@`b+~e-C_FMeyY{kaZ*w=R1xfo_qFr zteOTNnZRzX!v5@CEn4DkI9&WIkD44HE7*G_ebs82MZ@t3($(Fnxo$(d7B@z4ur$q| z1QGfUu=NHdaB8KLhoUs9-?h_n)oPftGh}9~go-^3BCX4Ro#`LDhjAF^adY3hC+D7X&+q)sd6^yFOr*||pG=0lb*~@m^trW-$7vN8 zsgj4+q>)~(nJEq48nUEN{)G;2IOIRLqmH@ZYDWR`pW>z8E35BBh?1`QIup0uly_yT zlrpQ?QQm_=)Y!tI`drze9z}8?@}2Z`nk;&#)HD9OXj|bVwRoxmrrj<((h-Mq6yI11iMzB z30vKrRaU+hOZFU@$FUPfT)}Bb-$#{y20YQxpjI(xsYEUi?cXZpD-E1cOLRa z>${u8I60vCZE-!f*sm^4Xm9w&!yRwRhr2ZRBVA^y^SML6>^CXFgMHE94r;KeDrgwJ zE&53#!=5IMJEkx=*ldoz6g$`h?PGLGH&Q;#+2E5nmz2Blsy zdfrZdZu#PpN6nYR4m=#}GD{x|OJ>uLiaKR2Uet!^3OKB2@$o_Oc(|6R)}UkRL|awk z!HD|^;#_mHKP+zK+>>MmJwmG4|9LOZPioj_)r%YA7~*Zz$M$Z1h9imly1z@3$UT+ zKO*XEE22~^*SSOZ8Vo)C3Ga(oDQQoplk;Dib&~)eR5_!rV9}rYEX@Z61zE0Mzz9H?-K8?-G3ZjC3 zL7n=bO}V$a$>)cw$@_eU**Xb#aLzxqye%qsWpGVE$Iimk_MQvZvY0A)Z$0OAvJFl(9k&dn{QV;VX(M=ReAuoEMxi zb}g~3_*1d^9Di}gs5X+7vy)1{NjVBlTW+aW^zXYSR(lsc8kE!hk+bYg4AZV`yv|e>v|!hi zPZNaM6sc=j$=!{J0V3T;Iz>sa?)^2415p&O;-m@QN4CVmpcgT8C+&@sdd{;`xrZ(U zeWsuEOuh1Wn{Rq$#=-Xw9o5T(z^kzyWHDo(3vSL95gapz~3xgZu4`}QrnloNy#&%DHS z9L<*r<8IMUcre+CDX0|eC@?5sPr;plH-*CloTcC>2`6a?Byi*gaTJ7+5Jdxs02m5D zNPwUraPtK!2>>GCrvM)Vdj4n7^MbhrYGW?|oH+sGLS=lwwt{U1+X}Yz&)8P5r{GQu z1Ojj;;7-7ufI9(q0z?-ex&YAyh%P{M0ip{KU4ZEFou$Ctg#MyYgj0#!++0#Wf1u-x zu|-6tfVegF|Jg1pOiU6=k8&!fKI1?vH#V9;7t=QS6WjN8*cBN&MhIqG2xwHh3H)0U zF>fwG-&UEr$JlFvh2E}dHZ|Q}@(A*^za#IbU2drJFq!8@{Y#mcT^4lj%01L4@y!wa ztVsJr)EG6f%d$OpmC2GRv7mLtoc?W#;!+|}-6QO=8xU!Q^{t)16P&-!JoI9$Vwu*A z{j0snUQaxa??cYu@Nm8=(0DhKd0Qh*T{n~meY;5aASu99gf zZzFCSjSW7E-b?xJbSOL4_7duXy89BUG3-26VHHx570*vBowS_)qDY12mLMXBE_nK> za+lviwY8)_UgfQ^+IJ>DiRu|Dk!-P~jlDLsCBCV6Ru+nmNHV-lG^zs7UH2|IUKd*t z)r{M|O8k%GDwsE(rEXZc`g37kcg%6JBES*R{83@iEpiNDmS&5;*3qx$cLeqSgPbmf zhc35sVU~YHEla%{ z*Y>pDL;UXJ#(ZQ9pB67X0xK;?4 z$5QL9{Hmh(tEg~wJ-+Hzi|c4(dF0<|ZY7!IRyh%4ef#H4RI?a)#&qkwe@A`qPG7T# zl)?u#(+F+I+O_udgLkMqYnM;A-USat3(oKqbn;m(rW2aqxwT#&`RpcLKP!B?^==Pn z3l6x-&_>`fHan*i+PX4}=-7N}g?-J_t#?n1Ha14RJDeOtDalJh10?|^0VR29Q-CG; zuT24#BoCAX+>NoM5zZuVCV_)199(gD4bjcZAt6LJ5CTI83^)nkBmkxXm`35AfVkQK z;tH@l!15?#2Vfe2Y5#}0n=-w4(%Z?DAa*)*D?OHZC)k_0M2?PU@X6Gn3(dmcB*u7X z_D6Za^p)JwHy@T6@^zyqarlaVfiZ)Ll8>yuj`*&t4 z8+#2&RD^fr5oN{937`p}34k&I)CPDXvI8Il5CXvOkb{6k z3}mAqC5LMDKnNfNitz=S0Ga@r0E7)-tpIfgWp6+TAOx!O1ZVS69J!aT;EA&WL^zNuZzgYc~ZJtzjMh52a4yiU0rr diff --git a/RNTester/RNTesterPods.xcodeproj/project.pbxproj b/RNTester/RNTesterPods.xcodeproj/project.pbxproj index ba6e0afe25a133..43690a406335ed 100644 --- a/RNTester/RNTesterPods.xcodeproj/project.pbxproj +++ b/RNTester/RNTesterPods.xcodeproj/project.pbxproj @@ -8,6 +8,7 @@ /* Begin PBXBuildFile section */ 10F9D0AD3F8E4C0DD7187464 /* libPods-RNTester-macOSUnitTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7E39630912E65B1C853EA5C8 /* libPods-RNTester-macOSUnitTests.a */; }; + 13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; }; 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; 272E6B3F1BEA849E001FCF37 /* UpdatePropertiesExampleView.m in Sources */ = {isa = PBXBuildFile; fileRef = 272E6B3C1BEA849E001FCF37 /* UpdatePropertiesExampleView.m */; }; 27F441EC1BEBE5030039B79C /* FlexibleSizeExampleView.m in Sources */ = {isa = PBXBuildFile; fileRef = 27F441E81BEBE5030039B79C /* FlexibleSizeExampleView.m */; }; @@ -47,7 +48,6 @@ 383838E0244BC5A0005FAC75 /* RCTUIManagerScenarioTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E7DB215F22B2F3EC005AC45F /* RCTUIManagerScenarioTests.m */; }; 383838E1244BC5A4005FAC75 /* RNTesterSnapshotTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E7DB216022B2F3EC005AC45F /* RNTesterSnapshotTests.m */; }; 383838E2244BC5A8005FAC75 /* RNTesterTestModule.m in Sources */ = {isa = PBXBuildFile; fileRef = E7DB215D22B2F3EC005AC45F /* RNTesterTestModule.m */; }; - 383889DA23A7398900D06C3E /* RCTConvert_UIColorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 383889D923A7398900D06C3E /* RCTConvert_UIColorTests.m */; }; 3882C0E22445657000E92FB9 /* OCMock.framework in Copy Files (1 item) */ = {isa = PBXBuildFile; fileRef = 38A93816244532460025DABB /* OCMock.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 38A9383C244532470025DABB /* libOCMock.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 38A9381B244532460025DABB /* libOCMock.a */; }; 38B2630B2444F5EB006AB4D5 /* UpdatePropertiesExampleView.m in Sources */ = {isa = PBXBuildFile; fileRef = 272E6B3C1BEA849E001FCF37 /* UpdatePropertiesExampleView.m */; }; @@ -64,11 +64,8 @@ 5101985B23ADA00B00118BF1 /* legacy_image@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 3D2AFAF41D646CF80089D1A3 /* legacy_image@2x.png */; }; 5C60EB1C226440DB0018C04F /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5C60EB1B226440DB0018C04F /* AppDelegate.mm */; }; 5CB07C9B226467E60039471C /* RNTesterTurboModuleProvider.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5CB07C99226467E60039471C /* RNTesterTurboModuleProvider.mm */; }; - 6766440649168A1FAD1DB4A4 /* libPods-RNTesterIntegrationTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5F836A7C97EC1BA121BA5A2A /* libPods-RNTesterIntegrationTests.a */; }; 7BD4120C2ED6C1CC8686E344 /* libPods-macOSBuild.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FB624ED465B02C53F121EBC8 /* libPods-macOSBuild.a */; }; 7C718C7B78F06C4CD1D1771A /* libPods-RNTester-macOSIntegrationTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1B8A3294D74D7AC1BE88DC4E /* libPods-RNTester-macOSIntegrationTests.a */; }; - 8145AE06241172D900A3F8DA /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8145AE05241172D900A3F8DA /* LaunchScreen.storyboard */; }; - 85C7978AB28C149170A56955 /* libPods-RNTesterUnitTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 11941849F77C552FDC3EED77 /* libPods-RNTesterUnitTests.a */; }; 8BBFF9F061783A02D50DD2EC /* libPods-RNTesterIntegrationTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8210317F3CE28B1945488740 /* libPods-RNTesterIntegrationTests.a */; }; 9F15345F233AB2C4006DFE44 /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9F15345E233AB2C4006DFE44 /* AppDelegate.mm */; }; 9F153461233AB2C7006DFE44 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9F153460233AB2C7006DFE44 /* Assets.xcassets */; }; @@ -185,9 +182,9 @@ /* Begin PBXFileReference section */ 0A355204268D03CF69ABC11D /* libPods-RNTester-macOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNTester-macOS.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 0BFED72B21FBD987A97E30B9 /* Pods-RNTester-macOSIntegrationTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTester-macOSIntegrationTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-RNTester-macOSIntegrationTests/Pods-RNTester-macOSIntegrationTests.release.xcconfig"; sourceTree = ""; }; - 11941849F77C552FDC3EED77 /* libPods-RNTesterUnitTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNTesterUnitTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 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 = ""; }; + 13B07FB21A68108700A75B9A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = RNTester/Info.plist; sourceTree = ""; }; 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = RNTester/main.m; sourceTree = ""; }; 1B8A3294D74D7AC1BE88DC4E /* libPods-RNTester-macOSIntegrationTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNTester-macOSIntegrationTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -201,7 +198,6 @@ 34028D6B10F47E490042EB27 /* Pods-RNTesterUnitTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTesterUnitTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests.debug.xcconfig"; sourceTree = ""; }; 38360C8B244E7D8B007B212D /* RNTester.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = RNTester.entitlements; path = RNTester/RNTester.entitlements; sourceTree = ""; }; 383838BF244BC3AE005FAC75 /* libPods-RNTesterUnitTests.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libPods-RNTesterUnitTests.a"; path = "../../../Library/Developer/Xcode/DerivedData/RNTesterPods-bpqvwgykvczlrybljbollkvfwjik/Build/Products/Debug-iphoneos/libPods-RNTesterUnitTests.a"; sourceTree = ""; }; - 383889D923A7398900D06C3E /* RCTConvert_UIColorTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTConvert_UIColorTests.m; sourceTree = ""; }; 387847D1245631D80035033A /* libiosDeviceBuild.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libiosDeviceBuild.a; sourceTree = BUILT_PRODUCTS_DIR; }; 387847DE245631F50035033A /* libiosSimulatorBuild.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libiosSimulatorBuild.a; sourceTree = BUILT_PRODUCTS_DIR; }; 387847EB2456320C0035033A /* libmacOSBuild.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libmacOSBuild.a; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -220,11 +216,9 @@ 5C60EB1B226440DB0018C04F /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AppDelegate.mm; path = RNTester/AppDelegate.mm; sourceTree = ""; }; 5CB07C99226467E60039471C /* RNTesterTurboModuleProvider.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = RNTesterTurboModuleProvider.mm; path = RNTester/RNTesterTurboModuleProvider.mm; sourceTree = ""; }; 5CB07C9A226467E60039471C /* RNTesterTurboModuleProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNTesterTurboModuleProvider.h; path = RNTester/RNTesterTurboModuleProvider.h; sourceTree = ""; }; - 5F836A7C97EC1BA121BA5A2A /* libPods-RNTesterIntegrationTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNTesterIntegrationTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 72247071A1BF06D54F0FECC7 /* libPods-RNTesterUnitTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNTesterUnitTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 7D51F73F0DA20287418D98BD /* Pods-RNTesterIntegrationTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTesterIntegrationTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests.release.xcconfig"; sourceTree = ""; }; 7E39630912E65B1C853EA5C8 /* libPods-RNTester-macOSUnitTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNTester-macOSUnitTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - 8145AE05241172D900A3F8DA /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = RNTester/LaunchScreen.storyboard; sourceTree = ""; }; 8210317F3CE28B1945488740 /* libPods-RNTesterIntegrationTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNTesterIntegrationTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 84C1A5DCCB6A5B4ABD3C2C93 /* Pods-macOSBuild.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-macOSBuild.debug.xcconfig"; path = "Pods/Target Support Files/Pods-macOSBuild/Pods-macOSBuild.debug.xcconfig"; sourceTree = ""; }; 972A459EE6CF8CC63531A088 /* Pods-RNTesterIntegrationTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNTesterIntegrationTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests.debug.xcconfig"; sourceTree = ""; }; @@ -283,7 +277,6 @@ B2CEBEBA250D8D3200D92658 /* Windows.Foundation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Windows.Foundation.h; path = TurboModuleCxx/winrt/Windows.Foundation.h; sourceTree = ""; }; B2F2040824E76D7600863BE1 /* ScreenshotMacOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ScreenshotMacOS.h; path = NativeModuleExample/ScreenshotMacOS.h; sourceTree = SOURCE_ROOT; }; B2F2040924E76D7600863BE1 /* ScreenshotMacOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ScreenshotMacOS.mm; path = NativeModuleExample/ScreenshotMacOS.mm; sourceTree = SOURCE_ROOT; }; - B5C8E567A4E6281113811CB1 /* libPods-RNTester.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNTester.a"; sourceTree = BUILT_PRODUCTS_DIR; }; C81D39A606858D29861E5930 /* Pods-iosSimulatorBuild.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-iosSimulatorBuild.debug.xcconfig"; path = "Pods/Target Support Files/Pods-iosSimulatorBuild/Pods-iosSimulatorBuild.debug.xcconfig"; sourceTree = ""; }; E65D2B0329006BC5338BB7D5 /* libPods-iosSimulatorBuild.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-iosSimulatorBuild.a"; sourceTree = BUILT_PRODUCTS_DIR; }; E68A0B7D2448B4F300228B0B /* RNTesterUnitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RNTesterUnitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -429,7 +422,6 @@ 383838C1244BC3D9005FAC75 /* JavaScriptCore.framework in Frameworks */, 38A9383C244532470025DABB /* libOCMock.a in Frameworks */, E59A0FBD0170A092274A6207 /* libPods-RNTesterUnitTests.a in Frameworks */, - 85C7978AB28C149170A56955 /* libPods-RNTesterUnitTests.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -440,7 +432,6 @@ E7DB218C22B41FCD005AC45F /* XCTest.framework in Frameworks */, E7DB216722B2F69F005AC45F /* JavaScriptCore.framework in Frameworks */, 8BBFF9F061783A02D50DD2EC /* libPods-RNTesterIntegrationTests.a in Frameworks */, - 6766440649168A1FAD1DB4A4 /* libPods-RNTesterIntegrationTests.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -467,7 +458,7 @@ 5CB07C99226467E60039471C /* RNTesterTurboModuleProvider.mm */, 13B07FB71A68108700A75B9A /* main.m */, 2DDEF00F1F84BF7B00DBDF73 /* Images.xcassets */, - 8145AE05241172D900A3F8DA /* LaunchScreen.storyboard */, + 13B07FB11A68108700A75B9A /* LaunchScreen.xib */, 272E6B3A1BEA846C001FCF37 /* NativeExampleViews */, 1323F18D1C04ABAC0091BED0 /* Supporting Files */, ); @@ -521,9 +512,6 @@ 287A4762E82517B7FACCE7D3 /* libPods-iosDeviceBuild.a */, E65D2B0329006BC5338BB7D5 /* libPods-iosSimulatorBuild.a */, FB624ED465B02C53F121EBC8 /* libPods-macOSBuild.a */, - B5C8E567A4E6281113811CB1 /* libPods-RNTester.a */, - 5F836A7C97EC1BA121BA5A2A /* libPods-RNTesterIntegrationTests.a */, - 11941849F77C552FDC3EED77 /* libPods-RNTesterUnitTests.a */, ); name = Frameworks; sourceTree = ""; @@ -685,7 +673,6 @@ E7DB20CC22B2BAA5005AC45F /* RCTComponentPropsTests.m */, E7DB20CA22B2BAA5005AC45F /* RCTConvert_NSURLTests.m */, E7DB20CE22B2BAA5005AC45F /* RCTConvert_YGValueTests.m */, - 383889D923A7398900D06C3E /* RCTConvert_UIColorTests.m */, E7DB20C822B2BAA5005AC45F /* RCTDevMenuTests.m */, E7DB20C022B2BAA4005AC45F /* RCTEventDispatcherTests.m */, E7DB20AF22B2BAA4005AC45F /* RCTFontTests.m */, @@ -763,13 +750,12 @@ isa = PBXNativeTarget; buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "RNTester" */; buildPhases = ( - D9BE43355C8C29497EED268E /* [CP] Check Pods Manifest.lock */, + F9CB97B0D9633939D43E75E0 /* [CP] Check Pods Manifest.lock */, 13B07F871A680F5B00A75B9A /* Sources */, 13B07F8C1A680F5B00A75B9A /* Frameworks */, 13B07F8E1A680F5B00A75B9A /* Resources */, 68CD48B71D2BCB2C007E06A9 /* Build JS Bundle */, 5CF0FD27207FC6EC00C13D65 /* Start Metro */, - 8BA2D8960038381F0B753726 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -784,7 +770,7 @@ isa = PBXNativeTarget; buildConfigurationList = 387847D7245631D80035033A /* Build configuration list for PBXNativeTarget "iosDeviceBuild" */; buildPhases = ( - 79A2B74F37E4F8AF8B3D0A7A /* [CP] Check Pods Manifest.lock */, + F45233491ACAD25C16E8F1CA /* [CP] Check Pods Manifest.lock */, 387847CD245631D80035033A /* Sources */, 387847CE245631D80035033A /* Frameworks */, 387847CF245631D80035033A /* CopyFiles */, @@ -802,7 +788,7 @@ isa = PBXNativeTarget; buildConfigurationList = 387847E4245631F50035033A /* Build configuration list for PBXNativeTarget "iosSimulatorBuild" */; buildPhases = ( - DBAEBACAAEA09D5E7591E051 /* [CP] Check Pods Manifest.lock */, + 258A8D3EFB14581FF1CA788D /* [CP] Check Pods Manifest.lock */, 387847DA245631F50035033A /* Sources */, 387847DB245631F50035033A /* Frameworks */, 387847DC245631F50035033A /* CopyFiles */, @@ -820,7 +806,7 @@ isa = PBXNativeTarget; buildConfigurationList = 387847F12456320C0035033A /* Build configuration list for PBXNativeTarget "macOSBuild" */; buildPhases = ( - 26905525A793EABD06A4E9DD /* [CP] Check Pods Manifest.lock */, + DFD62DE759BFAB8AABFA4179 /* [CP] Check Pods Manifest.lock */, 387847E72456320C0035033A /* Headers */, 387847E82456320C0035033A /* Sources */, 387847E92456320C0035033A /* Frameworks */, @@ -838,14 +824,13 @@ isa = PBXNativeTarget; buildConfigurationList = 9F153485233AB2C7006DFE44 /* Build configuration list for PBXNativeTarget "RNTester-macOS" */; buildPhases = ( - 840572194E08440DE712816E /* [CP] Check Pods Manifest.lock */, + 26ED73F8C59C75926FA607C9 /* [CP] Check Pods Manifest.lock */, 9F153457233AB2C4006DFE44 /* Sources */, 9F153458233AB2C4006DFE44 /* Frameworks */, 9F153459233AB2C4006DFE44 /* Resources */, 38C8132424577FB500BFFA62 /* Build JS Bundle */, 51B9D81723C4D5A4002B30E1 /* Start Metro */, - 912CCA057E7BE90E9EC53D33 /* [CP] Embed Pods Frameworks */, - 33B976C36DF90C0A044DC053 /* [CP] Copy Pods Resources */, + 4733C3A4FBA299F6E1E956BA /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -860,12 +845,11 @@ isa = PBXNativeTarget; buildConfigurationList = 9F153486233AB2C7006DFE44 /* Build configuration list for PBXNativeTarget "RNTester-macOSUnitTests" */; buildPhases = ( - 8BEE9E647FF71296D5EFD137 /* [CP] Check Pods Manifest.lock */, + 0DDB94B4378380EBD190814A /* [CP] Check Pods Manifest.lock */, 9F153469233AB2C7006DFE44 /* Sources */, 9F15346A233AB2C7006DFE44 /* Frameworks */, 9F15346B233AB2C7006DFE44 /* Resources */, 3882C0E12445655100E92FB9 /* Copy Files (1 item) */, - DCF7F2DA774E70B7DE02783C /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -881,11 +865,10 @@ isa = PBXNativeTarget; buildConfigurationList = 9F153487233AB2C7006DFE44 /* Build configuration list for PBXNativeTarget "RNTester-macOSIntegrationTests" */; buildPhases = ( - B8BFFD6300CD470A1DF043B6 /* [CP] Check Pods Manifest.lock */, + 599A88804E613F1AA7525CB9 /* [CP] Check Pods Manifest.lock */, 9F153474233AB2C7006DFE44 /* Sources */, 9F153475233AB2C7006DFE44 /* Frameworks */, 9F153476233AB2C7006DFE44 /* Resources */, - 4BDC0C5271A785332898B818 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -901,11 +884,10 @@ isa = PBXNativeTarget; buildConfigurationList = E7DB20A622B2BA84005AC45F /* Build configuration list for PBXNativeTarget "RNTesterUnitTests" */; buildPhases = ( - 1FD7CC5A44DCEE15C8D13E0A /* [CP] Check Pods Manifest.lock */, + 64C8C8D2305EEDFDE304A0E6 /* [CP] Check Pods Manifest.lock */, E7DB209B22B2BA84005AC45F /* Sources */, E7DB209C22B2BA84005AC45F /* Frameworks */, E7DB209D22B2BA84005AC45F /* Resources */, - D3E745B9771EC6F02AC52196 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -920,11 +902,10 @@ isa = PBXNativeTarget; buildConfigurationList = E7DB215A22B2F332005AC45F /* Build configuration list for PBXNativeTarget "RNTesterIntegrationTests" */; buildPhases = ( - A7D95A9E84DEB30F42E4B186 /* [CP] Check Pods Manifest.lock */, + 56D84768A7BBB2750D674CF3 /* [CP] Check Pods Manifest.lock */, E7DB214F22B2F332005AC45F /* Sources */, E7DB215022B2F332005AC45F /* Frameworks */, E7DB215122B2F332005AC45F /* Resources */, - 186E435C9BE5B7CC0656A19C /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -942,7 +923,7 @@ 83CBB9F71A601CBA00E9B192 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 1130; + LastUpgradeCheck = 0940; ORGANIZATIONNAME = Facebook; TargetAttributes = { 387847D0245631D80035033A = { @@ -979,9 +960,10 @@ }; buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "RNTesterPods" */; compatibilityVersion = "Xcode 9.3"; - developmentRegion = en; + developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( + English, en, Base, ); @@ -1009,8 +991,8 @@ buildActionMask = 2147483647; files = ( 2DDEF0101F84BF7B00DBDF73 /* Images.xcassets in Resources */, - 8145AE06241172D900A3F8DA /* LaunchScreen.storyboard in Resources */, 3D2AFAF51D646CF80089D1A3 /* legacy_image@2x.png in Resources */, + 13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1057,24 +1039,7 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 186E435C9BE5B7CC0656A19C /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests-resources-${CONFIGURATION}-input-files.xcfilelist", - ); - name = "[CP] Copy Pods Resources"; - outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests-resources-${CONFIGURATION}-output-files.xcfilelist", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; - 1FD7CC5A44DCEE15C8D13E0A /* [CP] Check Pods Manifest.lock */ = { + 0DDB94B4378380EBD190814A /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -1089,14 +1054,14 @@ outputFileListPaths = ( ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-RNTesterUnitTests-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-RNTester-macOSUnitTests-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; 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; }; - 26905525A793EABD06A4E9DD /* [CP] Check Pods Manifest.lock */ = { + 258A8D3EFB14581FF1CA788D /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -1111,28 +1076,33 @@ outputFileListPaths = ( ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-macOSBuild-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-iosSimulatorBuild-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; 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; }; - 33B976C36DF90C0A044DC053 /* [CP] Copy Pods Resources */ = { + 26ED73F8C59C75926FA607C9 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-RNTester-macOS/Pods-RNTester-macOS-resources-${CONFIGURATION}-input-files.xcfilelist", ); - name = "[CP] Copy Pods Resources"; + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-RNTester-macOS/Pods-RNTester-macOS-resources-${CONFIGURATION}-output-files.xcfilelist", + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-RNTester-macOS-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTester-macOS/Pods-RNTester-macOS-resources.sh\"\n"; + 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; }; 38C8132424577FB500BFFA62 /* Build JS Bundle */ = { @@ -1153,21 +1123,21 @@ shellPath = /bin/sh; shellScript = "export NODE_BINARY=node\nexport PROJECT_ROOT=$SRCROOT/..\nexport SOURCEMAP_FILE=sourcemap.macOS.map\n# export FORCE_BUNDLING=true\n$SRCROOT/../scripts/react-native-xcode.sh RNTester/js/RNTesterApp.macos.js\n"; }; - 4BDC0C5271A785332898B818 /* [CP] Copy Pods Resources */ = { + 4733C3A4FBA299F6E1E956BA /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-RNTester-macOSIntegrationTests/Pods-RNTester-macOSIntegrationTests-resources-${CONFIGURATION}-input-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-RNTester-macOS/Pods-RNTester-macOS-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); - name = "[CP] Copy Pods Resources"; + name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-RNTester-macOSIntegrationTests/Pods-RNTester-macOSIntegrationTests-resources-${CONFIGURATION}-output-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-RNTester-macOS/Pods-RNTester-macOS-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTester-macOSIntegrationTests/Pods-RNTester-macOSIntegrationTests-resources.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTester-macOS/Pods-RNTester-macOS-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; 51B9D81723C4D5A4002B30E1 /* Start Metro */ = { @@ -1189,36 +1159,7 @@ shellScript = "export RCT_METRO_PORT=\"${RCT_METRO_PORT:=8081}\"\necho \"export RCT_METRO_PORT=${RCT_METRO_PORT}\" > \"${SRCROOT}/../scripts/.packager.env\"\nif [ -z \"${RCT_NO_LAUNCH_PACKAGER+xxx}\" ] ; then\n if nc -w 5 -z localhost ${RCT_METRO_PORT} ; then\n if ! curl -s \"http://localhost:${RCT_METRO_PORT}/status\" | grep -q \"packager-status:running\" ; then\n echo \"Port ${RCT_METRO_PORT} already in use, packager is either not running or not running correctly\"\n exit 2\n fi\n else\n open \"$SRCROOT/../scripts/launchPackager.command\" || echo \"Can't start packager automatically\"\n fi\nfi\n"; showEnvVarsInLog = 0; }; - 5CF0FD27207FC6EC00C13D65 /* Start Metro */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Start Metro"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "export RCT_METRO_PORT=\"${RCT_METRO_PORT:=8081}\"\necho \"export RCT_METRO_PORT=${RCT_METRO_PORT}\" > \"${SRCROOT}/../scripts/.packager.env\"\nif [ -z \"${RCT_NO_LAUNCH_PACKAGER+xxx}\" ] ; then\n if nc -w 5 -z localhost ${RCT_METRO_PORT} ; then\n if ! curl -s \"http://localhost:${RCT_METRO_PORT}/status\" | grep -q \"packager-status:running\" ; then\n echo \"Port ${RCT_METRO_PORT} already in use, packager is either not running or not running correctly\"\n exit 2\n fi\n else\n open \"$SRCROOT/../scripts/launchPackager.command\" || echo \"Can't start packager automatically\"\n fi\nfi\n"; - showEnvVarsInLog = 0; - }; - 68CD48B71D2BCB2C007E06A9 /* Build JS Bundle */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Build JS Bundle"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "export NODE_BINARY=node\nexport PROJECT_ROOT=$SRCROOT/..\nexport SOURCEMAP_FILE=../sourcemap.ios.map\n# export FORCE_BUNDLING=true\nPROJECT_ROOT=$SRCROOT/.. $SRCROOT/../scripts/react-native-xcode.sh RNTester/js/RNTesterApp.ios.js\n"; - }; - 79A2B74F37E4F8AF8B3D0A7A /* [CP] Check Pods Manifest.lock */ = { + 56D84768A7BBB2750D674CF3 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -1233,14 +1174,14 @@ outputFileListPaths = ( ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-iosDeviceBuild-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-RNTesterIntegrationTests-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; 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; }; - 840572194E08440DE712816E /* [CP] Check Pods Manifest.lock */ = { + 599A88804E613F1AA7525CB9 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -1255,31 +1196,29 @@ outputFileListPaths = ( ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-RNTester-macOS-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-RNTester-macOSIntegrationTests-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; 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; }; - 8BA2D8960038381F0B753726 /* [CP] Copy Pods Resources */ = { + 5CF0FD27207FC6EC00C13D65 /* Start Metro */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); - inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-RNTester/Pods-RNTester-resources-${CONFIGURATION}-input-files.xcfilelist", + inputPaths = ( ); - name = "[CP] Copy Pods Resources"; - outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-RNTester/Pods-RNTester-resources-${CONFIGURATION}-output-files.xcfilelist", + name = "Start Metro"; + outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTester/Pods-RNTester-resources.sh\"\n"; + shellScript = "export RCT_METRO_PORT=\"${RCT_METRO_PORT:=8081}\"\necho \"export RCT_METRO_PORT=${RCT_METRO_PORT}\" > \"${SRCROOT}/../scripts/.packager.env\"\nif [ -z \"${RCT_NO_LAUNCH_PACKAGER+xxx}\" ] ; then\n if nc -w 5 -z localhost ${RCT_METRO_PORT} ; then\n if ! curl -s \"http://localhost:${RCT_METRO_PORT}/status\" | grep -q \"packager-status:running\" ; then\n echo \"Port ${RCT_METRO_PORT} already in use, packager is either not running or not running correctly\"\n exit 2\n fi\n else\n open \"$SRCROOT/../scripts/launchPackager.command\" || echo \"Can't start packager automatically\"\n fi\nfi\n"; showEnvVarsInLog = 0; }; - 8BEE9E647FF71296D5EFD137 /* [CP] Check Pods Manifest.lock */ = { + 64C8C8D2305EEDFDE304A0E6 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -1294,53 +1233,28 @@ outputFileListPaths = ( ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-RNTester-macOSUnitTests-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-RNTesterUnitTests-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; 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; }; - 912CCA057E7BE90E9EC53D33 /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-RNTester-macOS/Pods-RNTester-macOS-frameworks-${CONFIGURATION}-input-files.xcfilelist", - ); - name = "[CP] Embed Pods Frameworks"; - outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-RNTester-macOS/Pods-RNTester-macOS-frameworks-${CONFIGURATION}-output-files.xcfilelist", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTester-macOS/Pods-RNTester-macOS-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; - A7D95A9E84DEB30F42E4B186 /* [CP] Check Pods Manifest.lock */ = { + 68CD48B71D2BCB2C007E06A9 /* Build JS Bundle */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); - inputFileListPaths = ( - ); inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( ); + name = "Build JS Bundle"; outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-RNTesterIntegrationTests-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - 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; + shellScript = "export NODE_BINARY=node\nPROJECT_ROOT=$SRCROOT/.. $SRCROOT/../scripts/react-native-xcode.sh RNTester/js/RNTesterApp.ios.js\n"; }; - B8BFFD6300CD470A1DF043B6 /* [CP] Check Pods Manifest.lock */ = { + DFD62DE759BFAB8AABFA4179 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -1355,31 +1269,14 @@ outputFileListPaths = ( ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-RNTester-macOSIntegrationTests-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-macOSBuild-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; 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; }; - D3E745B9771EC6F02AC52196 /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests-resources-${CONFIGURATION}-input-files.xcfilelist", - ); - name = "[CP] Copy Pods Resources"; - outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests-resources-${CONFIGURATION}-output-files.xcfilelist", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTesterUnitTests/Pods-RNTesterUnitTests-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; - D9BE43355C8C29497EED268E /* [CP] Check Pods Manifest.lock */ = { + F45233491ACAD25C16E8F1CA /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -1394,52 +1291,31 @@ outputFileListPaths = ( ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-RNTester-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-iosDeviceBuild-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; 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; }; - DBAEBACAAEA09D5E7591E051 /* [CP] Check Pods Manifest.lock */ = { + F9CB97B0D9633939D43E75E0 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); - inputFileListPaths = ( - ); inputPaths = ( "${PODS_PODFILE_DIR_PATH}/Podfile.lock", "${PODS_ROOT}/Manifest.lock", ); name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-iosSimulatorBuild-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-RNTester-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; 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; }; - DCF7F2DA774E70B7DE02783C /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-RNTester-macOSUnitTests/Pods-RNTester-macOSUnitTests-resources-${CONFIGURATION}-input-files.xcfilelist", - ); - name = "[CP] Copy Pods Resources"; - outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-RNTester-macOSUnitTests/Pods-RNTester-macOSUnitTests-resources-${CONFIGURATION}-output-files.xcfilelist", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTester-macOSUnitTests/Pods-RNTester-macOSUnitTests-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -1565,7 +1441,6 @@ E7DB20D322B2BAA6005AC45F /* RCTBlobManagerTests.m in Sources */, E7DB20DC22B2BAA6005AC45F /* RCTUIManagerTests.m in Sources */, E7DB20E322B2BAA6005AC45F /* RCTAllocationTests.m in Sources */, - 383889DA23A7398900D06C3E /* RCTConvert_UIColorTests.m in Sources */, E7DB20E622B2BAA6005AC45F /* RCTImageLoaderHelpers.m in Sources */, E7DB20D622B2BAA6005AC45F /* RCTFontTests.m in Sources */, E7DB20DB22B2BAA6005AC45F /* RCTNativeAnimatedNodesManagerTests.m in Sources */, @@ -1618,6 +1493,15 @@ /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ + 13B07FB11A68108700A75B9A /* LaunchScreen.xib */ = { + isa = PBXVariantGroup; + children = ( + 13B07FB21A68108700A75B9A /* Base */, + ); + name = LaunchScreen.xib; + path = RNTester; + sourceTree = ""; + }; 5101985523AD9EE600118BF1 /* Main.storyboard */ = { isa = PBXVariantGroup; children = ( @@ -1637,22 +1521,47 @@ CLANG_CXX_LANGUAGE_STANDARD = "c++14"; CODE_SIGN_ENTITLEMENTS = RNTester/RNTester.entitlements; DEVELOPMENT_TEAM = ""; - GCC_PREPROCESSOR_DEFINITIONS = ( + HEADER_SEARCH_PATHS = ( "$(inherited)", - "FB_SONARKIT_ENABLED=1", + "\"${PODS_ROOT}/Headers/Public\"", + "\"${PODS_ROOT}/Headers/Public/DoubleConversion\"", + "\"${PODS_ROOT}/Headers/Public/React-ART\"", + "\"${PODS_ROOT}/Headers/Public/React-Core\"", + "\"${PODS_ROOT}/Headers/Public/React-Fabric\"", + "\"${PODS_ROOT}/Headers/Public/React-RCTActionSheet\"", + "\"${PODS_ROOT}/Headers/Public/React-RCTAnimation\"", + "\"${PODS_ROOT}/Headers/Public/React-RCTBlob\"", + "\"${PODS_ROOT}/Headers/Public/React-RCTFabric\"", + "\"${PODS_ROOT}/Headers/Public/React-RCTGeolocation\"", + "\"${PODS_ROOT}/Headers/Public/React-RCTImage\"", + "\"${PODS_ROOT}/Headers/Public/React-RCTLinking\"", + "\"${PODS_ROOT}/Headers/Public/React-RCTNetwork\"", + "\"${PODS_ROOT}/Headers/Public/React-RCTPushNotification\"", + "\"${PODS_ROOT}/Headers/Public/React-RCTSettings\"", + "\"${PODS_ROOT}/Headers/Public/React-RCTText\"", + "\"${PODS_ROOT}/Headers/Public/React-RCTVibration\"", + "\"${PODS_ROOT}/Headers/Public/React-cxxreact\"", + "\"${PODS_ROOT}/Headers/Public/React-fishhook\"", + "\"${PODS_ROOT}/Headers/Public/React-jsi\"", + "\"${PODS_ROOT}/Headers/Public/React-jsiexecutor\"", + "\"${PODS_ROOT}/Headers/Public/React-jsinspector\"", + "\"${PODS_ROOT}/Headers/Public/glog\"", + "\"${PODS_ROOT}/Headers/Public/libevent\"", + "\"$(PODS_ROOT)/boost-for-react-native\"", + "\"$(PODS_ROOT)/Folly\"", + "\"$(PODS_ROOT)/DoubleConversion\"", ); INFOPLIST_FILE = "$(SRCROOT)/RNTester/Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = ( /usr/lib/swift, - "$(inherited)", + "@executable_path/Frameworks", ); LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)", "$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)", ); - "LIBRARY_SEARCH_PATHS[arch=*]" = "$(inherited)"; OTHER_CFLAGS = ( "$(inherited)", "-DFB_SONARKIT_ENABLED=1", @@ -1664,7 +1573,6 @@ "-framework", "\"JavaScriptCore\"", ); - OTHER_SWIFT_FLAGS = "$(inherited) -Xcc -DFB_SONARKIT_ENABLED"; PRODUCT_BUNDLE_IDENTIFIER = com.facebook.react.uiapp; PRODUCT_NAME = RNTester; TARGETED_DEVICE_FAMILY = "1,2"; @@ -1679,11 +1587,41 @@ CLANG_CXX_LANGUAGE_STANDARD = "c++14"; CODE_SIGN_ENTITLEMENTS = RNTester/RNTester.entitlements; DEVELOPMENT_TEAM = ""; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "\"${PODS_ROOT}/Headers/Public\"", + "\"${PODS_ROOT}/Headers/Public/DoubleConversion\"", + "\"${PODS_ROOT}/Headers/Public/React-ART\"", + "\"${PODS_ROOT}/Headers/Public/React-Core\"", + "\"${PODS_ROOT}/Headers/Public/React-Fabric\"", + "\"${PODS_ROOT}/Headers/Public/React-RCTActionSheet\"", + "\"${PODS_ROOT}/Headers/Public/React-RCTAnimation\"", + "\"${PODS_ROOT}/Headers/Public/React-RCTBlob\"", + "\"${PODS_ROOT}/Headers/Public/React-RCTFabric\"", + "\"${PODS_ROOT}/Headers/Public/React-RCTGeolocation\"", + "\"${PODS_ROOT}/Headers/Public/React-RCTImage\"", + "\"${PODS_ROOT}/Headers/Public/React-RCTLinking\"", + "\"${PODS_ROOT}/Headers/Public/React-RCTNetwork\"", + "\"${PODS_ROOT}/Headers/Public/React-RCTPushNotification\"", + "\"${PODS_ROOT}/Headers/Public/React-RCTSettings\"", + "\"${PODS_ROOT}/Headers/Public/React-RCTText\"", + "\"${PODS_ROOT}/Headers/Public/React-RCTVibration\"", + "\"${PODS_ROOT}/Headers/Public/React-cxxreact\"", + "\"${PODS_ROOT}/Headers/Public/React-fishhook\"", + "\"${PODS_ROOT}/Headers/Public/React-jsi\"", + "\"${PODS_ROOT}/Headers/Public/React-jsiexecutor\"", + "\"${PODS_ROOT}/Headers/Public/React-jsinspector\"", + "\"${PODS_ROOT}/Headers/Public/glog\"", + "\"${PODS_ROOT}/Headers/Public/libevent\"", + "\"$(PODS_ROOT)/boost-for-react-native\"", + "\"$(PODS_ROOT)/Folly\"", + "\"$(PODS_ROOT)/DoubleConversion\"", + ); INFOPLIST_FILE = "$(SRCROOT)/RNTester/Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = ( /usr/lib/swift, - "$(inherited)", + "@executable_path/Frameworks", ); LIBRARY_SEARCH_PATHS = ( "$(inherited)", @@ -1701,7 +1639,6 @@ "-framework", "\"JavaScriptCore\"", ); - OTHER_SWIFT_FLAGS = "$(inherited) -Xcc -DFB_SONARKIT_ENABLED"; PRODUCT_BUNDLE_IDENTIFIER = com.facebook.react.uiapp; PRODUCT_NAME = RNTester; TARGETED_DEVICE_FAMILY = "1,2"; @@ -1852,7 +1789,6 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; @@ -1908,7 +1844,7 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_LABEL = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; OTHER_CPLUSPLUSFLAGS = ( @@ -1934,7 +1870,6 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; @@ -1983,7 +1918,7 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_LABEL = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; MTL_ENABLE_DEBUG_INFO = NO; OTHER_CPLUSPLUSFLAGS = ( "$(OTHER_CFLAGS)", @@ -2293,7 +2228,6 @@ "$(inherited)", "-DFB_SONARKIT_ENABLED=1", ); - OTHER_SWIFT_FLAGS = "$(inherited) -Xcc -DFB_SONARKIT_ENABLED"; PRODUCT_BUNDLE_IDENTIFIER = com.facebook.RNTesterUnitTests; PRODUCT_NAME = "$(TARGET_NAME)"; TARGETED_DEVICE_FAMILY = "1,2"; @@ -2329,7 +2263,6 @@ "$(inherited)", "-DFB_SONARKIT_ENABLED=1", ); - OTHER_SWIFT_FLAGS = "$(inherited) -Xcc -DFB_SONARKIT_ENABLED"; PRODUCT_BUNDLE_IDENTIFIER = com.facebook.RNTesterUnitTests; PRODUCT_NAME = "$(TARGET_NAME)"; TARGETED_DEVICE_FAMILY = "1,2"; @@ -2366,7 +2299,6 @@ "$(inherited)", "-DFB_SONARKIT_ENABLED=1", ); - OTHER_SWIFT_FLAGS = "$(inherited) -Xcc -DFB_SONARKIT_ENABLED"; PRODUCT_BUNDLE_IDENTIFIER = com.facebook.RNTesterIntegrationTests; PRODUCT_NAME = "$(TARGET_NAME)"; TARGETED_DEVICE_FAMILY = "1,2"; @@ -2400,7 +2332,6 @@ "$(inherited)", "-DFB_SONARKIT_ENABLED=1", ); - OTHER_SWIFT_FLAGS = "$(inherited) -Xcc -DFB_SONARKIT_ENABLED"; PRODUCT_BUNDLE_IDENTIFIER = com.facebook.RNTesterIntegrationTests; PRODUCT_NAME = "$(TARGET_NAME)"; TARGETED_DEVICE_FAMILY = "1,2"; diff --git a/RNTester/RNTesterPods.xcodeproj/xcshareddata/xcschemes/RNTester.xcscheme b/RNTester/RNTesterPods.xcodeproj/xcshareddata/xcschemes/RNTester.xcscheme index aa5eb07b7a0e40..500b06c03557b1 100644 --- a/RNTester/RNTesterPods.xcodeproj/xcshareddata/xcschemes/RNTester.xcscheme +++ b/RNTester/RNTesterPods.xcodeproj/xcshareddata/xcschemes/RNTester.xcscheme @@ -1,6 +1,6 @@ - - - - - - - - @@ -65,6 +49,24 @@ + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - + + + + - - - - - - - - @@ -84,6 +68,17 @@ + + + + + + + + = 130000 if (@available(iOS 13.0, *)) { id savedTraitCollection = [UITraitCollection currentTraitCollection]; + [UITraitCollection setCurrentTraitCollection:[UITraitCollection traitCollectionWithUserInterfaceStyle:UIUserInterfaceStyleLight]]; CGFloat rgba[4]; RCTGetRGBAColorComponents([value CGColor], rgba); @@ -80,12 +69,14 @@ - (void)testDynamicColor XCTAssertEqual(rgba[1], 0); XCTAssertEqual(rgba[2], 0); XCTAssertEqual(rgba[3], 0); + [UITraitCollection setCurrentTraitCollection:[UITraitCollection traitCollectionWithUserInterfaceStyle:UIUserInterfaceStyleDark]]; RCTGetRGBAColorComponents([value CGColor], rgba); XCTAssertEqual(rgba[0], 1); XCTAssertEqual(rgba[1], 1); XCTAssertEqual(rgba[2], 1); XCTAssertEqual(rgba[3], 0); + [UITraitCollection setCurrentTraitCollection:savedTraitCollection]; } #endif @@ -100,15 +91,27 @@ - (void)testCompositeDynamicColor #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 if (@available(iOS 13.0, *)) { id savedTraitCollection = [UITraitCollection currentTraitCollection]; - + [UITraitCollection setCurrentTraitCollection:[UITraitCollection traitCollectionWithUserInterfaceStyle:UIUserInterfaceStyleLight]]; - - XCTAssertTrue(CGColorsAreEqual([value CGColor], [[UIColor systemRedColor] CGColor])); - + + CGFloat rgba1[4]; + CGFloat rgba2[4]; + RCTGetRGBAColorComponents([value CGColor], rgba1); + RCTGetRGBAColorComponents([[UIColor systemRedColor] CGColor], rgba2); + XCTAssertEqual(rgba1[0], rgba2[0]); + XCTAssertEqual(rgba1[1], rgba2[1]); + XCTAssertEqual(rgba1[2], rgba2[2]); + XCTAssertEqual(rgba1[3], rgba2[3]); + [UITraitCollection setCurrentTraitCollection:[UITraitCollection traitCollectionWithUserInterfaceStyle:UIUserInterfaceStyleDark]]; - - XCTAssertTrue(CGColorsAreEqual([value CGColor], [[UIColor systemBlueColor] CGColor])); - + + RCTGetRGBAColorComponents([value CGColor], rgba1); + RCTGetRGBAColorComponents([[UIColor systemBlueColor] CGColor], rgba2); + XCTAssertEqual(rgba1[0], rgba2[0]); + XCTAssertEqual(rgba1[1], rgba2[1]); + XCTAssertEqual(rgba1[2], rgba2[2]); + XCTAssertEqual(rgba1[3], rgba2[3]); + [UITraitCollection setCurrentTraitCollection:savedTraitCollection]; } #endif @@ -154,10 +157,12 @@ - (void)testGenerateFallbacks @"systemGray5Color": @(0xFFe5e5ea), @"systemGray6Color": @(0xFFf2f2f7), }; + #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 id savedTraitCollection = nil; if (@available(iOS 13.0, *)) { savedTraitCollection = [UITraitCollection currentTraitCollection]; + [UITraitCollection setCurrentTraitCollection:[UITraitCollection traitCollectionWithUserInterfaceStyle:UIUserInterfaceStyleLight]]; } #endif @@ -186,6 +191,7 @@ - (void)testGenerateFallbacks XCTAssertEqual(blue1, blue2); XCTAssertEqual(alpha1, alpha2); } + #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 if (@available(iOS 13.0, *)) { [UITraitCollection setCurrentTraitCollection:savedTraitCollection]; diff --git a/RNTester/RNTesterUnitTests/RCTImageLoaderTests.m b/RNTester/RNTesterUnitTests/RCTImageLoaderTests.m index 7a791930591e42..5e17c5056cfe0e 100644 --- a/RNTester/RNTesterUnitTests/RCTImageLoaderTests.m +++ b/RNTester/RNTesterUnitTests/RCTImageLoaderTests.m @@ -51,7 +51,7 @@ - (void)testImageLoading NS_VALID_UNTIL_END_OF_SCOPE RCTBridge *bridge = [[RCTBridge alloc] initWithBundleURL:_bundleURL moduleProvider:^{ return @[loader]; } launchOptions:nil]; - NSURLRequest *urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:@"https://reactnative.dev/img/opengraph.png"]]; + NSURLRequest *urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:@"https://facebook.github.io/react-native/img/opengraph.png"]]; [[bridge moduleForClass:[RCTImageLoader class]] loadImageWithURLRequest:urlRequest size:CGSizeMake(100, 100) @@ -89,7 +89,7 @@ - (void)testImageLoaderUsesImageURLLoaderWithHighestPriority NS_VALID_UNTIL_END_OF_SCOPE RCTBridge *bridge = [[RCTBridge alloc] initWithBundleURL:_bundleURL moduleProvider:^{ return @[loader1, loader2]; } launchOptions:nil]; - NSURLRequest *urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:@"https://reactnative.dev/img/opengraph.png"]]; + NSURLRequest *urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:@"https://facebook.github.io/react-native/img/opengraph.png"]]; [[bridge moduleForClass:[RCTImageLoader class]] loadImageWithURLRequest:urlRequest size:CGSizeMake(100, 100) diff --git a/RNTester/android/app/build.gradle b/RNTester/android/app/build.gradle index 0a36475ade519b..d27f7d9804e8f9 100644 --- a/RNTester/android/app/build.gradle +++ b/RNTester/android/app/build.gradle @@ -65,13 +65,12 @@ plugins { */ project.ext.react = [ - cliPath: "$rootDir/cli.js", bundleAssetName: "RNTesterApp.android.bundle", entryFile: file("../../js/RNTesterApp.android.js"), root: "$rootDir", inputExcludes: ["android/**", "./**", ".gradle/**"], composeSourceMapsPath: "$rootDir/scripts/compose-source-maps.js", - hermesCommand: "../../../node_modules/hermes-engine/%OS-BIN%/hermesc", + hermesCommand: "../../../node_modules/hermes-engine/%OS-BIN%/hermes", enableHermesForVariant: { def v -> v.name.contains("hermes") } ] @@ -104,6 +103,13 @@ def useIntlJsc = false android { compileSdkVersion 29 + packagingOptions { + pickFirst '**/armeabi-v7a/libc++_shared.so' + pickFirst '**/x86/libc++_shared.so' + pickFirst '**/x86_64/libc++_shared.so' + pickFirst '**/arm64-v8a/libc++_shared.so' + } + compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 @@ -121,12 +127,10 @@ android { defaultConfig { applicationId "com.facebook.react.uiapp" - minSdkVersion 18 + minSdkVersion 16 targetSdkVersion 29 versionCode 1 versionName "1.0" - testBuildType System.getProperty('testBuildType', 'debug') // This will later be used to control the test apk build type - testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' } signingConfigs { release { @@ -152,17 +156,10 @@ android { minifyEnabled enableProguardInReleaseBuilds proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' signingConfig signingConfigs.release - // Detox-specific additions to pro-guard - proguardFile "${rootProject.projectDir}/../node_modules/detox/android/detox/proguard-rules-app.pro" } } } -configurations { - hermesDebugImplementation {} - hermesReleaseImplementation {} -} - dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) @@ -172,8 +169,8 @@ dependencies { implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0" def hermesPath = '$projectDir/../../../../node_modules/hermes-engine/android/' - hermesDebugImplementation files(hermesPath + "hermes-debug.aar") - hermesReleaseImplementation files(hermesPath + "hermes-release.aar") + debugImplementation files(hermesPath + "hermes-debug.aar") + releaseImplementation files(hermesPath + "hermes-release.aar") debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") { exclude group:'com.facebook.fbjni' @@ -188,12 +185,8 @@ dependencies { } if (useIntlJsc) { - jscImplementation 'org.webkit:android-jsc-intl:+' + implementation 'org.webkit:android-jsc-intl:+' } else { - jscImplementation 'org.webkit:android-jsc:+' + implementation 'org.webkit:android-jsc:+' } - - // Use detox test library - androidTestImplementation('com.wix:detox:+') { transitive = true } - androidTestImplementation 'junit:junit:4.12' } diff --git a/RNTester/android/app/gradle.properties b/RNTester/android/app/gradle.properties index 4ff9751aab7d8b..3d9a626c164f38 100644 --- a/RNTester/android/app/gradle.properties +++ b/RNTester/android/app/gradle.properties @@ -9,4 +9,4 @@ android.useAndroidX=true android.enableJetifier=true # Version of flipper SDK to use with React Native -FLIPPER_VERSION=0.37.0 +FLIPPER_VERSION=0.33.1 diff --git a/RNTester/android/app/src/androidTest/java/com/facebook/react/uiapp/DetoxTest.java b/RNTester/android/app/src/androidTest/java/com/facebook/react/uiapp/DetoxTest.java deleted file mode 100644 index f9febfa3b3845f..00000000000000 --- a/RNTester/android/app/src/androidTest/java/com/facebook/react/uiapp/DetoxTest.java +++ /dev/null @@ -1,33 +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. - */ - -// This uses instructions from -// https://github.com/wix/Detox/blob/master/docs/Introduction.Android.md#4-create-android-test-class - -package com.facebook.react.uiapp; - -import androidx.test.ext.junit.runners.AndroidJUnit4; -import androidx.test.filters.LargeTest; -import androidx.test.rule.ActivityTestRule; -import com.wix.detox.Detox; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; - -@RunWith(AndroidJUnit4.class) -@LargeTest -public class DetoxTest { - - @Rule - public ActivityTestRule mActivityRule = - new ActivityTestRule<>(RNTesterActivity.class, false, false); - - @Test - public void runDetoxTests() { - Detox.runTests(mActivityRule); - } -} diff --git a/RNTester/e2e/__tests__/DatePickerIOS-test.js b/RNTester/e2e/__tests__/DatePickerIOS-test.js index 11c73fcb2d5f4b..6a7c961991aecf 100644 --- a/RNTester/e2e/__tests__/DatePickerIOS-test.js +++ b/RNTester/e2e/__tests__/DatePickerIOS-test.js @@ -44,7 +44,7 @@ describe('DatePickerIOS', () => { await testElement.setColumnToValue(3, 'AM'); await expect(dateIndicator).toHaveText('12/4/2006'); - await expect(timeIndicator).toHaveText('04:10 AM'); + await expect(timeIndicator).toHaveText('4:10 AM'); }); it('Should change indicator with date-only picker', async () => { diff --git a/RNTester/e2e/__tests__/TextInput-test.js b/RNTester/e2e/__tests__/TextInput-test.js deleted file mode 100644 index db1933ab6262f6..00000000000000 --- a/RNTester/e2e/__tests__/TextInput-test.js +++ /dev/null @@ -1,62 +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. - * - * @emails oncall+react_native - * @format - */ - -/* global device, element, by, expect */ -const { - openComponentWithLabel, - openExampleWithTitle, -} = require('../e2e-helpers'); - -describe('TextInput', () => { - beforeAll(async () => { - await device.reloadReactNative(); - await openComponentWithLabel( - '', - 'Single and multi-line text inputs.', - ); - }); - - it('Live rewrite with spaces should replace spaces and enforce max length', async () => { - await openExampleWithTitle('Live Re-Write \\('); - - await element(by.id('rewrite_sp_underscore_input')).typeText( - 'this is a long sentence', - ); - await expect(element(by.id('rewrite_sp_underscore_input'))).toHaveText( - 'this_is_a_long_sente', - ); - }); - - it('Live rewrite with no spaces should remove spaces', async () => { - await openExampleWithTitle('Live Re-Write \\(no spaces'); - - await element(by.id('rewrite_no_sp_input')).typeText( - 'this is a long sentence', - ); - await expect(element(by.id('rewrite_no_sp_input'))).toHaveText( - 'thisisalongsentence', - ); - }); - - it('Live rewrite with clear should remove spaces and clear', async () => { - await openExampleWithTitle('and clear'); - - await element(by.id('rewrite_clear_input')).typeText( - 'this is a long sentence', - ); - await expect(element(by.id('rewrite_clear_input'))).toHaveText( - 'thisisalongsentence', - ); - - await element(by.id('rewrite_clear_button')).tap(); - - await expect(element(by.id('rewrite_clear_input'))).toHaveText(''); - }); -}); diff --git a/RNTester/e2e/test-init.js b/RNTester/e2e/test-init.js index 4e95bbe7c3e8ab..5c70397a520b79 100644 --- a/RNTester/e2e/test-init.js +++ b/RNTester/e2e/test-init.js @@ -3,36 +3,19 @@ * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. - * - * @format */ /* eslint-env jasmine */ -/* global device */ const detox = require('detox'); const config = require('../../package.json').detox; const adapter = require('detox/runners/jest/adapter'); -jest.setTimeout(120000); + +jest.setTimeout(480000); jasmine.getEnv().addReporter(adapter); beforeAll(async () => { - await detox.init(config, {launchApp: false}); - await device.launchApp({ - launchArgs: { - newInstance: true, - // see https://github.com/wix/Detox/blob/master/docs/Troubleshooting.Synchronization.md - // and uncomment below if app fails to launch - // detoxPrintBusyIdleResources: 'YES', - }, - permissions: { - notifications: 'YES', - camera: 'YES', - medialibrary: 'YES', - photos: 'YES', - microphone: 'YES', - }, - }); + await detox.init(config); }); beforeEach(async function() { diff --git a/RNTester/js/RNTesterApp.android.js b/RNTester/js/RNTesterApp.android.js index d7371b4ee6a79c..fd3655deec2d86 100644 --- a/RNTester/js/RNTesterApp.android.js +++ b/RNTester/js/RNTesterApp.android.js @@ -316,8 +316,6 @@ class RNTesterApp extends React.Component { /* $FlowFixMe(>=0.78.0 site=react_native_android_fb) This issue was found * when making Flow check .android.js files. */ this._exampleRef && - /* $FlowFixMe(>=0.78.0 site=react_native_android_fb) This issue was found - * when making Flow check .android.js files. */ this._exampleRef.handleBackAction && /* $FlowFixMe(>=0.78.0 site=react_native_android_fb) This issue was found * when making Flow check .android.js files. */ diff --git a/RNTester/js/RNTesterApp.ios.js b/RNTester/js/RNTesterApp.ios.js index 1786d4ddc8133b..9526a00f33a3c6 100644 --- a/RNTester/js/RNTesterApp.ios.js +++ b/RNTester/js/RNTesterApp.ios.js @@ -27,14 +27,12 @@ const { Linking, NativeModules, // TODO(OSS Candidate ISS#2710739) Platform, // TODO(OSS Candidate ISS#2710739) - PlatformColor, // TODO(OSS Candidate ISS#2710739) - DynamicColorIOS, // TODO(OSS Candidate ISS#2710739) SafeAreaView, StyleSheet, Text, useColorScheme, View, - LogBox, + YellowBox, } = require('react-native'); const {TestModule} = NativeModules; // TODO(OSS Candidate ISS#2710739) @@ -48,7 +46,9 @@ import type {ColorSchemeName} from '../../Libraries/Utilities/NativeAppearance'; type Props = {exampleFromAppetizeParams?: ?string, ...}; -LogBox.ignoreLogs(['Module RCTImagePickerManager requires main queue setup']); +YellowBox.ignoreWarnings([ + 'Module RCTImagePickerManager requires main queue setup', +]); const APP_STATE_KEY = 'RNTesterAppState.v2'; @@ -221,14 +221,14 @@ class RNTesterApp extends React.Component { const styles = StyleSheet.create({ headerContainer: { borderBottomWidth: StyleSheet.hairlineWidth, - borderBottomColor: PlatformColor('separatorColor'), // TODO(OSS Candidate ISS#2710739) + borderBottomColor: {semantic: 'separatorColor'}, // TODO(OSS Candidate ISS#2710739) ...Platform.select({ // [TODO(macOS ISS#2323203) ios: { - backgroundColor: PlatformColor('tertiarySystemBackgroundColor'), + backgroundColor: {semantic: 'tertiarySystemBackgroundColor'}, }, macos: { - backgroundColor: PlatformColor('windowBackgroundColor'), + backgroundColor: {semantic: 'windowBackgroundColor'}, }, }), // ]TODO(macOS ISS#2323203) @@ -249,7 +249,7 @@ const styles = StyleSheet.create({ fontSize: 19, fontWeight: '600', textAlign: 'center', - color: DynamicColorIOS({light: 'black', dark: 'white'}), // TODO(OSS Candidate ISS#2710739) + color: {dynamic: {light: 'black', dark: 'white'}}, // TODO(OSS Candidate ISS#2710739) }, exampleContainer: { flex: 1, diff --git a/RNTester/js/components/RNTesterBlock.js b/RNTester/js/components/RNTesterBlock.js index 9af3d0b61e3de2..2bf61daf7b4756 100644 --- a/RNTester/js/components/RNTesterBlock.js +++ b/RNTester/js/components/RNTesterBlock.js @@ -12,7 +12,7 @@ const React = require('react'); -const {PlatformColor, StyleSheet, Text, View} = require('react-native'); +const {StyleSheet, Text, View} = require('react-native'); import {Platform} from 'react-native'; // TODO(macOS ISS#2323203) import {RNTesterThemeContext} from './RNTesterTheme'; @@ -82,12 +82,12 @@ const styles = StyleSheet.create({ borderWidth: 0.5, ...Platform.select({ macos: { - borderColor: PlatformColor('separatorColor'), - backgroundColor: PlatformColor('windowBackgroundColor'), + borderColor: {semantic: 'separatorColor'}, + backgroundColor: {semantic: 'windowBackgroundColor'}, }, ios: { - borderColor: PlatformColor('separatorColor'), - backgroundColor: PlatformColor('tertiarySystemBackgroundColor'), + borderColor: {semantic: 'separatorColor'}, + backgroundColor: {semantic: 'tertiarySystemBackgroundColor'}, }, default: { borderColor: '#d6d7da', @@ -104,12 +104,12 @@ const styles = StyleSheet.create({ borderTopRightRadius: 2.5, ...Platform.select({ macos: { - borderBottomColor: PlatformColor('separatorColor'), - backgroundColor: PlatformColor('controlBackgroundColor'), + borderBottomColor: {semantic: 'separatorColor'}, + backgroundColor: {semantic: 'controlBackgroundColor'}, }, ios: { - borderBottomColor: PlatformColor('separatorColor'), - backgroundColor: PlatformColor('tertiarySystemBackgroundColor'), + borderBottomColor: {semantic: 'separatorColor'}, + backgroundColor: {semantic: 'tertiarySystemBackgroundColor'}, }, default: { borderBottomColor: '#d6d7da', @@ -122,10 +122,10 @@ const styles = StyleSheet.create({ titleText: { ...Platform.select({ macos: { - color: PlatformColor('labelColor'), + color: {semantic: 'labelColor'}, }, ios: { - color: PlatformColor('labelColor'), + color: {semantic: 'labelColor'}, }, default: undefined, }), @@ -136,10 +136,10 @@ const styles = StyleSheet.create({ fontSize: 14, ...Platform.select({ macos: { - color: PlatformColor('secondaryLabelColor'), + color: {semantic: 'secondaryLabelColor'}, }, ios: { - color: PlatformColor('secondaryLabelColor'), + color: {semantic: 'secondaryLabelColor'}, }, default: undefined, }), diff --git a/RNTester/js/components/RNTesterExampleList.js b/RNTester/js/components/RNTesterExampleList.js index ee30dcde1359ea..ae598b8ca3693d 100644 --- a/RNTester/js/components/RNTesterExampleList.js +++ b/RNTester/js/components/RNTesterExampleList.js @@ -16,7 +16,6 @@ const React = require('react'); const { Platform, - PlatformColor, SectionList, StyleSheet, Text, @@ -253,10 +252,10 @@ const styles = StyleSheet.create({ ...Platform.select({ // [TODO(macOS ISS#2323203) macos: { - backgroundColor: PlatformColor('controlBackgroundColor'), + backgroundColor: {semantic: 'controlBackgroundColor'}, }, ios: { - backgroundColor: PlatformColor('systemBackgroundColor'), + backgroundColor: {semantic: 'systemBackgroundColor'}, }, default: { // ]TODO(macOS ISS#2323203) @@ -271,13 +270,13 @@ const styles = StyleSheet.create({ backgroundColor: { semantic: 'unemphasizedSelectedContentBackgroundColor', }, - color: PlatformColor('headerTextColor'), + color: {semantic: 'headerTextColor'}, }, ios: { backgroundColor: { semantic: 'systemGroupedBackgroundColor', }, - color: PlatformColor('secondaryLabelColor'), + color: {semantic: 'secondaryLabelColor'}, }, default: { // ]TODO(macOS ISS#2323203) @@ -293,10 +292,10 @@ const styles = StyleSheet.create({ ...Platform.select({ // [TODO(macOS ISS#2323203) macos: { - backgroundColor: PlatformColor('controlBackgroundColor'), + backgroundColor: {semantic: 'controlBackgroundColor'}, }, ios: { - backgroundColor: PlatformColor('secondarySystemGroupedBackgroundColor'), + backgroundColor: {semantic: 'secondarySystemGroupedBackgroundColor'}, }, default: { // ]TODO(macOS ISS#2323203) @@ -320,10 +319,10 @@ const styles = StyleSheet.create({ ...Platform.select({ // [TODO(macOS ISS#2323203) macos: { - backgroundColor: PlatformColor('separatorColor'), + backgroundColor: {semantic: 'separatorColor'}, }, ios: { - backgroundColor: PlatformColor('separatorColor'), + backgroundColor: {semantic: 'separatorColor'}, }, default: { // ]TODO(macOS ISS#2323203) @@ -337,8 +336,8 @@ const styles = StyleSheet.create({ }, sectionListContentContainer: Platform.select({ // [TODO(macOS ISS#2323203) - macos: {backgroundColor: PlatformColor('separatorColor')}, - ios: {backgroundColor: PlatformColor('separatorColor')}, + macos: {backgroundColor: {semantic: 'separatorColor'}}, + ios: {backgroundColor: {semantic: 'separatorColor'}}, default: {backgroundColor: 'white'}, }), // ]TODO(macOS ISS#2323203) rowTitleText: { @@ -347,10 +346,10 @@ const styles = StyleSheet.create({ ...Platform.select({ // [TODO(macOS ISS#2323203) macos: { - color: PlatformColor('controlTextColor'), + color: {semantic: 'controlTextColor'}, }, ios: { - color: PlatformColor('labelColor'), + color: {semantic: 'labelColor'}, }, default: { // ]TODO(macOS ISS#2323203) diff --git a/RNTester/js/components/RNTesterTheme.js b/RNTester/js/components/RNTesterTheme.js index 7bc14ea3ebd99d..b78a8344fe29be 100644 --- a/RNTester/js/components/RNTesterTheme.js +++ b/RNTester/js/components/RNTesterTheme.js @@ -12,29 +12,28 @@ import * as React from 'react'; import {Appearance} from 'react-native'; -import type {ColorValue} from '../../../Libraries/StyleSheet/StyleSheetTypes'; export type RNTesterTheme = { - LabelColor: ColorValue, - SecondaryLabelColor: ColorValue, - TertiaryLabelColor: ColorValue, - QuaternaryLabelColor: ColorValue, - PlaceholderTextColor: ColorValue, - SystemBackgroundColor: ColorValue, - SecondarySystemBackgroundColor: ColorValue, - TertiarySystemBackgroundColor: ColorValue, - GroupedBackgroundColor: ColorValue, - SecondaryGroupedBackgroundColor: ColorValue, - TertiaryGroupedBackgroundColor: ColorValue, - SystemFillColor: ColorValue, - SecondarySystemFillColor: ColorValue, - TertiarySystemFillColor: ColorValue, - QuaternarySystemFillColor: ColorValue, - SeparatorColor: ColorValue, - OpaqueSeparatorColor: ColorValue, - LinkColor: ColorValue, - SystemPurpleColor: ColorValue, - ToolbarColor: ColorValue, + LabelColor: string, + SecondaryLabelColor: string, + TertiaryLabelColor: string, + QuaternaryLabelColor: string, + PlaceholderTextColor: string, + SystemBackgroundColor: string, + SecondarySystemBackgroundColor: string, + TertiarySystemBackgroundColor: string, + GroupedBackgroundColor: string, + SecondaryGroupedBackgroundColor: string, + TertiaryGroupedBackgroundColor: string, + SystemFillColor: string, + SecondarySystemFillColor: string, + TertiarySystemFillColor: string, + QuaternarySystemFillColor: string, + SeparatorColor: string, + OpaqueSeparatorColor: string, + LinkColor: string, + SystemPurpleColor: string, + ToolbarColor: string, ... }; diff --git a/RNTester/js/examples/Alert/AlertMacOSExample.js b/RNTester/js/examples/Alert/AlertMacOSExample.js index 07fcb334f18d0b..a57a84671d3e5d 100644 --- a/RNTester/js/examples/Alert/AlertMacOSExample.js +++ b/RNTester/js/examples/Alert/AlertMacOSExample.js @@ -10,11 +10,11 @@ 'use strict'; -const React = require('react'); -const ReactNative = require('react-native'); -const {StyleSheet, View, Text, TouchableHighlight, AlertMacOS} = ReactNative; +var React = require('react'); +var ReactNative = require('react-native'); +var {StyleSheet, View, Text, TouchableHighlight, AlertMacOS} = ReactNative; -const {SimpleAlertExampleBlock} = require('./AlertExample'); +var {SimpleAlertExampleBlock} = require('./AlertExample'); exports.framework = 'React'; exports.title = 'AlertMacOS'; diff --git a/RNTester/js/examples/Appearance/AppearanceExample.js b/RNTester/js/examples/Appearance/AppearanceExample.js index bc2d074b2be75e..ab99e9213bf256 100644 --- a/RNTester/js/examples/Appearance/AppearanceExample.js +++ b/RNTester/js/examples/Appearance/AppearanceExample.js @@ -191,9 +191,7 @@ exports.examples = [ paddingVertical: 2, color: theme.LabelColor, }}> - {typeof theme[key] === 'string' - ? theme[key] - : JSON.stringify(theme[key])} + {theme[key]} diff --git a/RNTester/js/examples/DarkModeExample/DarkModeExample.js b/RNTester/js/examples/DarkModeExample/DarkModeExample.js index 5ca95686088aeb..7e178ea9ec9b49 100644 --- a/RNTester/js/examples/DarkModeExample/DarkModeExample.js +++ b/RNTester/js/examples/DarkModeExample/DarkModeExample.js @@ -13,7 +13,7 @@ const React = require('react'); const ReactNative = require('react-native'); import {Platform} from 'react-native'; -const {PlatformColor, Text, View} = ReactNative; +const {Text, View} = ReactNative; class SemanticColorsExample extends React.Component<{}> { createTable() { @@ -45,8 +45,8 @@ class SemanticColorsExample extends React.Component<{}> { // Table Colors 'gridColor', 'headerTextColor', - 'alternatingEvenContentBackgroundColor', - 'alternatingOddContentBackgroundColor', + 'alternatingContentBackgroundColorEven', + 'alternatingContentBackgroundColorOdd', // Control Colors 'controlAccentColor', 'controlColor', @@ -138,7 +138,7 @@ class SemanticColorsExample extends React.Component<{}> { style={{ flex: 1, alignItems: 'stretch', - color: PlatformColor('labelColor'), + color: {semantic: 'labelColor'}, }}> {color} @@ -146,7 +146,7 @@ class SemanticColorsExample extends React.Component<{}> { style={{ flex: 0.25, alignItems: 'stretch', - backgroundColor: PlatformColor(color), + backgroundColor: {semantic: `${color}`}, }} /> , diff --git a/RNTester/js/examples/DatePicker/DatePickerMacOSExample.js b/RNTester/js/examples/DatePicker/DatePickerMacOSExample.js index 5f058554d3ab50..759b56df251b2f 100644 --- a/RNTester/js/examples/DatePicker/DatePickerMacOSExample.js +++ b/RNTester/js/examples/DatePicker/DatePickerMacOSExample.js @@ -8,9 +8,9 @@ */ 'use strict'; -const React = require('react'); -const ReactNative = require('react-native'); -const { +var React = require('react'); +var ReactNative = require('react-native'); +var { DatePickerMacOS, StyleSheet, Text, diff --git a/RNTester/js/examples/FocusEventsExample/FocusEventsExample.js b/RNTester/js/examples/FocusEventsExample/FocusEventsExample.js index 9c60a0bbeaba7d..65be0afd2cb575 100644 --- a/RNTester/js/examples/FocusEventsExample/FocusEventsExample.js +++ b/RNTester/js/examples/FocusEventsExample/FocusEventsExample.js @@ -10,10 +10,10 @@ 'use strict'; // TODO(OSS Candidate ISS#2710739) -const React = require('react'); -const ReactNative = require('react-native'); +var React = require('react'); +var ReactNative = require('react-native'); import {Platform} from 'react-native'; -const {Button, PlatformColor, StyleSheet, Text, View, TextInput} = ReactNative; +var {Button, StyleSheet, Text, View, TextInput} = ReactNative; type State = { eventStream: string, @@ -46,7 +46,7 @@ class FocusEventExample extends React.Component<{}, State> { }} placeholder={'TextInput'} placeholderTextColor={ - Platform.OS === 'macos' ? PlatformColor('textColor') : 'black' + Platform.OS === 'macos' ? {semantic: 'textColor'} : 'black' } style={styles.textInput} /> @@ -103,7 +103,7 @@ class FocusEventExample extends React.Component<{}, State> { style={styles.textInput} placeholder={'Nested Singleline TextInput'} placeholderTextColor={ - Platform.OS === 'macos' ? PlatformColor('textColor') : 'black' + Platform.OS === 'macos' ? {semantic: 'textColor'} : 'black' } /> @@ -244,7 +244,7 @@ class FocusEventExample extends React.Component<{}, State> { multiline={true} placeholder={'Nested Multiline TextInput'} placeholderTextColor={ - Platform.OS === 'macos' ? PlatformColor('textColor') : 'black' + Platform.OS === 'macos' ? {semantic: 'textColor'} : 'black' } /> @@ -260,9 +260,9 @@ var styles = StyleSheet.create({ textInput: { ...Platform.select({ macos: { - color: PlatformColor('textColor'), - backgroundColor: PlatformColor('textBackgroundColor'), - borderColor: PlatformColor('gridColor'), + color: {semantic: 'textColor'}, + backgroundColor: {semantic: 'textBackgroundColor'}, + borderColor: {semantic: 'gridColor'}, }, default: { borderColor: '#0f0f0f', diff --git a/RNTester/js/examples/Image/ImageExample.js b/RNTester/js/examples/Image/ImageExample.js index 7a2173f590d094..b0d95ac5fdfce2 100644 --- a/RNTester/js/examples/Image/ImageExample.js +++ b/RNTester/js/examples/Image/ImageExample.js @@ -781,9 +781,6 @@ exports.examples = [ source={image} /> - {/* $FlowFixMe(>=0.115.0 site=react_native_fb) This comment - * suppresses an error found when Flow v0.115 was deployed. - * To see the error, delete this comment and run Flow. */} Cover - {/* $FlowFixMe(>=0.115.0 site=react_native_fb) This comment - * suppresses an error found when Flow v0.115 was deployed. - * To see the error, delete this comment and run Flow. */} Repeat - {/* $FlowFixMe(>=0.115.0 site=react_native_fb) This comment - * suppresses an error found when Flow v0.115 was deployed. - * To see the error, delete this comment and run Flow. */} Center =0.115.0 site=react_native_fb) This comment suppresses an - * error found when Flow v0.115 was deployed. To see the error, delete - * this comment and run Flow. */ return ; }, }, diff --git a/RNTester/js/examples/Layout/LayoutEventsExample.js b/RNTester/js/examples/Layout/LayoutEventsExample.js index 5abb07d95e7dc4..4791cba84a9312 100644 --- a/RNTester/js/examples/Layout/LayoutEventsExample.js +++ b/RNTester/js/examples/Layout/LayoutEventsExample.js @@ -102,7 +102,8 @@ class LayoutEventExample extends React.Component { onLayout={this.onImageLayout} style={styles.image} source={{ - uri: 'https://www.facebook.com/favicon.ico', + uri: + 'https://fbcdn-dragon-a.akamaihd.net/hphotos-ak-prn1/t39.1997/p128x128/851561_767334496626293_1958532586_n.png', }} /> diff --git a/RNTester/js/examples/MaskedView/MaskedViewExample.js b/RNTester/js/examples/MaskedView/MaskedViewExample.js index 7ad01c6e41cda1..2b9f99c19a0aa6 100644 --- a/RNTester/js/examples/MaskedView/MaskedViewExample.js +++ b/RNTester/js/examples/MaskedView/MaskedViewExample.js @@ -35,12 +35,12 @@ class AnimatedMaskExample extends React.Component { Animated.sequence([ Animated.timing(this._maskScaleAnimatedValue, { toValue: 1.3, - duration: 750, + timing: 750, useNativeDriver: true, }), Animated.timing(this._maskScaleAnimatedValue, { toValue: 1, - duration: 750, + timing: 750, useNativeDriver: true, }), ]), @@ -49,7 +49,7 @@ class AnimatedMaskExample extends React.Component { Animated.loop( Animated.timing(this._maskRotateAnimatedValue, { toValue: 360, - duration: 2000, + timing: 2000, useNativeDriver: true, }), ).start(); @@ -76,9 +76,6 @@ class AnimatedMaskExample extends React.Component { { rotate: this._maskRotateAnimatedValue.interpolate({ inputRange: [0, 360], - /* $FlowFixMe(>=0.38.0) - Flow error detected during the - * deployment of v0.38.0. To see the error, remove this - * comment and run flow */ outputRange: ['0deg', '360deg'], }), }, diff --git a/RNTester/js/examples/NativeAnimation/NativeAnimationsExample.js b/RNTester/js/examples/NativeAnimation/NativeAnimationsExample.js index e6c4fcb591c631..cd20cb7ca504bd 100644 --- a/RNTester/js/examples/NativeAnimation/NativeAnimationsExample.js +++ b/RNTester/js/examples/NativeAnimation/NativeAnimationsExample.js @@ -145,9 +145,6 @@ class LoopExample extends React.Component<{...}, $FlowFixMeState> { { opacity: this.state.value.interpolate({ inputRange: [0, 0.5, 1], - /* $FlowFixMe(>=0.38.0) - Flow error detected during the - * deployment of v0.38.0. To see the error, remove this comment - * and run flow */ outputRange: [0, 1, 0], }), }, @@ -243,9 +240,6 @@ class EventExample extends React.Component<{...}, $FlowFixMeState> { { rotate: this.state.anim.interpolate({ inputRange: [0, 1], - /* $FlowFixMe(>=0.38.0) - Flow error detected during the - * deployment of v0.38.0. To see the error, remove this - * comment and run flow */ outputRange: ['0deg', '1deg'], }), }, diff --git a/RNTester/js/examples/Picker/PickerExample.js b/RNTester/js/examples/Picker/PickerExample.js index c4d1e2bfcf4902..7672b9ea420a8d 100644 --- a/RNTester/js/examples/Picker/PickerExample.js +++ b/RNTester/js/examples/Picker/PickerExample.js @@ -125,25 +125,6 @@ class ColorPickerExample extends React.Component<{...}, ColorState> { ); } } -class AccessibilityLabelPickerExample extends React.Component<{||}, State> { - state: State = { - value: '3', - }; - - render(): React.Node { - return ( - this.setState({value: v})}> - - - - - ); - } -} const styles = StyleSheet.create({ picker: { @@ -179,12 +160,6 @@ exports.examples = [ return ; }, }, - { - title: 'Accessibility Label pickers', - render: function(): React.Element { - return ; - }, - }, { title: 'Picker with no listener', render: function(): React.Element { @@ -211,10 +186,4 @@ exports.examples = [ return ; }, }, - { - title: 'AccessibilityLabel pickers', - render: function(): React.Element { - return ; - }, - }, ]; diff --git a/RNTester/js/examples/PlatformColor/PlatformColorExample.js b/RNTester/js/examples/PlatformColor/PlatformColorExample.js deleted file mode 100644 index c440808d2123e1..00000000000000 --- a/RNTester/js/examples/PlatformColor/PlatformColorExample.js +++ /dev/null @@ -1,358 +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. - * - * @format - * @flow - */ - -'use strict'; - -const React = require('react'); -const ReactNative = require('react-native'); -import Platform from '../../../../Libraries/Utilities/Platform'; -const { - ColorAndroid, - DynamicColorIOS, - PlatformColor, - StyleSheet, - Text, - View, -} = ReactNative; - -function PlatformColorsExample() { - function createTable() { - let colors = []; - if (Platform.OS === 'ios') { - colors = [ - // https://developer.apple.com/documentation/uikit/uicolor/ui_element_colors - // Label Colors - {label: 'label', color: PlatformColor('label')}, - { - label: 'secondaryLabel', - color: PlatformColor('secondaryLabel'), - }, - { - label: 'tertiaryLabel', - color: PlatformColor('tertiaryLabel'), - }, - { - label: 'quaternaryLabel', - color: PlatformColor('quaternaryLabel'), - }, - // Fill Colors - {label: 'systemFill', color: PlatformColor('systemFill')}, - { - label: 'secondarySystemFill', - color: PlatformColor('secondarySystemFill'), - }, - { - label: 'tertiarySystemFill', - color: PlatformColor('tertiarySystemFill'), - }, - { - label: 'quaternarySystemFill', - color: PlatformColor('quaternarySystemFill'), - }, - // Text Colors - { - label: 'placeholderText', - color: PlatformColor('placeholderText'), - }, - // Standard Content Background Colors - { - label: 'systemBackground', - color: PlatformColor('systemBackground'), - }, - { - label: 'secondarySystemBackground', - color: PlatformColor('secondarySystemBackground'), - }, - { - label: 'tertiarySystemBackground', - color: PlatformColor('tertiarySystemBackground'), - }, - // Grouped Content Background Colors - { - label: 'systemGroupedBackground', - color: PlatformColor('systemGroupedBackground'), - }, - { - label: 'secondarySystemGroupedBackground', - color: PlatformColor('secondarySystemGroupedBackground'), - }, - { - label: 'tertiarySystemGroupedBackground', - color: PlatformColor('tertiarySystemGroupedBackground'), - }, - // Separator Colors - {label: 'separator', color: PlatformColor('separator')}, - { - label: 'opaqueSeparator', - color: PlatformColor('opaqueSeparator'), - }, - // Link Color - {label: 'link', color: PlatformColor('link')}, - // Nonadaptable Colors - {label: 'darkText', color: PlatformColor('darkText')}, - {label: 'lightText', color: PlatformColor('lightText')}, - // https://developer.apple.com/documentation/uikit/uicolor/standard_colors - // Adaptable Colors - {label: 'systemBlue', color: PlatformColor('systemBlue')}, - {label: 'systemBrown', color: PlatformColor('systemBrown')}, - {label: 'systemGreen', color: PlatformColor('systemGreen')}, - {label: 'systemIndigo', color: PlatformColor('systemIndigo')}, - {label: 'systemOrange', color: PlatformColor('systemOrange')}, - {label: 'systemPink', color: PlatformColor('systemPink')}, - {label: 'systemPurple', color: PlatformColor('systemPurple')}, - {label: 'systemRed', color: PlatformColor('systemRed')}, - {label: 'systemTeal', color: PlatformColor('systemTeal')}, - {label: 'systemYellow', color: PlatformColor('systemYellow')}, - // Adaptable Gray Colors - {label: 'systemGray', color: PlatformColor('systemGray')}, - {label: 'systemGray2', color: PlatformColor('systemGray2')}, - {label: 'systemGray3', color: PlatformColor('systemGray3')}, - {label: 'systemGray4', color: PlatformColor('systemGray4')}, - {label: 'systemGray5', color: PlatformColor('systemGray5')}, - {label: 'systemGray6', color: PlatformColor('systemGray6')}, - ]; - } else if (Platform.OS === 'android') { - colors = [ - {label: '?attr/colorAccent', color: PlatformColor('?attr/colorAccent')}, - { - label: '?attr/colorBackgroundFloating', - color: PlatformColor('?attr/colorBackgroundFloating'), - }, - { - label: '?attr/colorButtonNormal', - color: PlatformColor('?attr/colorButtonNormal'), - }, - { - label: '?attr/colorControlActivated', - color: PlatformColor('?attr/colorControlActivated'), - }, - { - label: '?attr/colorControlHighlight', - color: PlatformColor('?attr/colorControlHighlight'), - }, - { - label: '?attr/colorControlNormal', - color: PlatformColor('?attr/colorControlNormal'), - }, - { - label: '?android:colorError', - color: PlatformColor('?android:colorError'), - }, - { - label: '?android:attr/colorError', - color: PlatformColor('?android:attr/colorError'), - }, - { - label: '?attr/colorPrimary', - color: PlatformColor('?attr/colorPrimary'), - }, - {label: '?colorPrimaryDark', color: PlatformColor('?colorPrimaryDark')}, - { - label: '@android:color/holo_purple', - color: PlatformColor('@android:color/holo_purple'), - }, - { - label: '@android:color/holo_green_light', - color: PlatformColor('@android:color/holo_green_light'), - }, - { - label: '@color/catalyst_redbox_background', - color: PlatformColor('@color/catalyst_redbox_background'), - }, - { - label: '@color/catalyst_logbox_background', - color: PlatformColor('@color/catalyst_logbox_background'), - }, - ]; - } - - let table = []; - for (let color of colors) { - table.push( - - {color.label} - - , - ); - } - return table; - } - - return {createTable()}; -} - -function FallbackColorsExample() { - let color = {}; - if ( - Platform.OS === 'ios' || - Platform.OS === 'macos' // TODO(macOS ISS#2323203) - ) { - color = { - label: "PlatformColor('bogus', 'systemGreenColor')", - color: PlatformColor('bogus', 'systemGreenColor'), - }; - } else if (Platform.OS === 'android') { - color = { - label: "PlatformColor('bogus', '@color/catalyst_redbox_background')", - color: PlatformColor('bogus', '@color/catalyst_redbox_background'), - }; - } else { - throw 'Unexpected Platform.OS: ' + Platform.OS; - } - - return ( - - - {color.label} - - - - ); -} - -function DynamicColorsExample() { - return Platform.OS === 'ios' ? ( - - - - DynamicColorIOS({'{\n'} - {' '}light: 'red', dark: 'blue'{'\n'} - {'}'}) - - - - - - DynamicColorIOS({'{\n'} - {' '}light: PlatformColor('systemBlueColor'),{'\n'} - {' '}dark: PlatformColor('systemRedColor'),{'\n'} - {'}'}) - - - - - ) : ( - Not applicable on this platform - ); -} - -function AndroidColorsExample() { - return Platform.OS === 'android' ? ( - - - ColorAndroid('?attr/colorAccent') - - - - ) : ( - Not applicable on this platform - ); -} - -function VariantColorsExample() { - return ( - - - - {Platform.OS === 'ios' || Platform.OS === 'macos' // TODO(macOS ISS#2323203) - ? "DynamicColorIOS({light: 'red', dark: 'blue'})" - : "ColorAndroid('?attr/colorAccent')"} - - - - - ); -} - -const styles = StyleSheet.create({ - column: {flex: 1, flexDirection: 'column'}, - row: {flex: 0.75, flexDirection: 'row'}, - labelCell: { - flex: 1, - alignItems: 'stretch', - ...Platform.select({ - ios: {color: PlatformColor('labelColor')}, - default: {color: 'black'}, - }), - }, - colorCell: {flex: 0.25, alignItems: 'stretch'}, -}); - -exports.title = 'PlatformColor'; -exports.description = - 'Examples that show how PlatformColors may be used in an app.'; -exports.examples = [ - { - title: 'Platform Colors', - render(): React.Element { - return ; - }, - }, - { - title: 'Fallback Colors', - render(): React.Element { - return ; - }, - }, - { - title: 'iOS Dynamic Colors', - render(): React.Element { - return ; - }, - }, - { - title: 'Android Colors', - render(): React.Element { - return ; - }, - }, - { - title: 'Variant Colors', - render(): React.Element { - return ; - }, - }, -]; diff --git a/RNTester/js/examples/Pressable/PressableExample.js b/RNTester/js/examples/Pressable/PressableExample.js deleted file mode 100644 index 1dadac6b1c4c13..00000000000000 --- a/RNTester/js/examples/Pressable/PressableExample.js +++ /dev/null @@ -1,469 +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. - * - * @format - * @flow strict-local - */ - -'use strict'; - -import * as React from 'react'; -import { - Animated, - Pressable, - StyleSheet, - Text, - Platform, - View, -} from 'react-native'; - -const {useEffect, useRef, useState} = React; - -const forceTouchAvailable = - (Platform.OS === 'ios' && Platform.constants.forceTouchAvailable) || false; - -function ContentPress() { - const [timesPressed, setTimesPressed] = useState(0); - - let textLog = ''; - if (timesPressed > 1) { - textLog = timesPressed + 'x onPress'; - } else if (timesPressed > 0) { - textLog = 'onPress'; - } - - return ( - <> - - { - setTimesPressed(current => current + 1); - }}> - {({pressed}) => ( - {pressed ? 'Pressed!' : 'Press Me'} - )} - - - - {textLog} - - - ); -} - -function TextOnPressBox() { - const [timesPressed, setTimesPressed] = useState(0); - - let textLog = ''; - if (timesPressed > 1) { - textLog = timesPressed + 'x text onPress'; - } else if (timesPressed > 0) { - textLog = 'text onPress'; - } - - return ( - <> - { - setTimesPressed(prev => prev + 1); - }}> - Text has built-in onPress handling - - - {textLog} - - - ); -} - -function PressableFeedbackEvents() { - const [eventLog, setEventLog] = useState([]); - - function appendEvent(eventName) { - const limit = 6; - setEventLog(current => { - return [eventName].concat(current.slice(0, limit - 1)); - }); - } - - return ( - - - appendEvent('press')} - onPressIn={() => appendEvent('pressIn')} - onPressOut={() => appendEvent('pressOut')} - onLongPress={() => appendEvent('longPress')}> - Press Me - - - - {eventLog.map((e, ii) => ( - {e} - ))} - - - ); -} - -function PressableDelayEvents() { - const [eventLog, setEventLog] = useState([]); - - function appendEvent(eventName) { - const limit = 6; - const newEventLog = eventLog.slice(0, limit - 1); - newEventLog.unshift(eventName); - setEventLog(newEventLog); - } - - return ( - - - appendEvent('press')} - onPressIn={() => appendEvent('pressIn')} - onPressOut={() => appendEvent('pressOut')} - delayLongPress={800} - onLongPress={() => appendEvent('longPress - 800ms delay')}> - Press Me - - - - {eventLog.map((e, ii) => ( - {e} - ))} - - - ); -} - -function ForceTouchExample() { - const [force, setForce] = useState(0); - - const consoleText = forceTouchAvailable - ? 'Force: ' + force.toFixed(3) - : '3D Touch is not available on this device'; - - return ( - - - {consoleText} - - - true} - onResponderMove={event => setForce(event.nativeEvent.force)} - onResponderRelease={event => setForce(0)}> - Press Me - - - - ); -} - -function PressableHitSlop() { - const [timesPressed, setTimesPressed] = useState(0); - - let log = ''; - if (timesPressed > 1) { - log = timesPressed + 'x onPress'; - } else if (timesPressed > 0) { - log = 'onPress'; - } - - return ( - - - setTimesPressed(num => num + 1)} - style={styles.hitSlopWrapper} - hitSlop={{top: 30, bottom: 30, left: 60, right: 60}} - testID="pressable_hit_slop_button"> - Press Outside This View - - - - {log} - - - ); -} - -function PressableNativeMethods() { - const [status, setStatus] = useState(null); - const ref = useRef(null); - - useEffect(() => { - setStatus(ref.current != null && typeof ref.current.measure === 'function'); - }, []); - - return ( - <> - - - - - - {status == null - ? 'Missing Ref!' - : status === true - ? 'Native Methods Exist' - : 'Native Methods Missing!'} - - - - ); -} - -function PressableDisabled() { - return ( - <> - - Disabled Pressable - - - [ - {opacity: pressed ? 0.5 : 1}, - styles.row, - styles.block, - ]}> - Enabled Pressable - - - ); -} - -const styles = StyleSheet.create({ - row: { - justifyContent: 'center', - flexDirection: 'row', - }, - centered: { - justifyContent: 'center', - }, - text: { - fontSize: 16, - }, - block: { - padding: 10, - }, - button: { - color: '#007AFF', - }, - disabledButton: { - color: '#007AFF', - opacity: 0.5, - }, - hitSlopButton: { - color: 'white', - }, - wrapper: { - borderRadius: 8, - }, - wrapperCustom: { - borderRadius: 8, - padding: 6, - }, - hitSlopWrapper: { - backgroundColor: 'red', - marginVertical: 30, - }, - logBox: { - padding: 20, - margin: 10, - borderWidth: StyleSheet.hairlineWidth, - borderColor: '#f0f0f0', - backgroundColor: '#f9f9f9', - }, - eventLogBox: { - padding: 10, - margin: 10, - height: 120, - borderWidth: StyleSheet.hairlineWidth, - borderColor: '#f0f0f0', - backgroundColor: '#f9f9f9', - }, - forceTouchBox: { - padding: 10, - margin: 10, - borderWidth: StyleSheet.hairlineWidth, - borderColor: '#f0f0f0', - backgroundColor: '#f9f9f9', - alignItems: 'center', - }, - textBlock: { - fontWeight: '500', - color: 'blue', - }, -}); - -exports.displayName = (undefined: ?string); -exports.description = 'Component for making views pressable.'; -exports.title = ''; -exports.examples = [ - { - title: 'Change content based on Press', - render(): React.Node { - return ; - }, - }, - { - title: 'Change style based on Press', - render(): React.Node { - return ( - - [ - { - backgroundColor: pressed ? 'rgb(210, 230, 255)' : 'white', - }, - styles.wrapperCustom, - ]}> - Press Me - - - ); - }, - }, - { - title: 'Pressable feedback events', - description: (' components accept onPress, onPressIn, ' + - 'onPressOut, and onLongPress as props.': string), - render: function(): React.Node { - return ; - }, - }, - { - title: 'Pressable with Ripple and Animated child', - description: ('Pressable can have an AnimatedComponent as a direct child.': string), - platform: 'android', - render: function(): React.Node { - const mScale = new Animated.Value(1); - Animated.timing(mScale, { - toValue: 0.3, - duration: 1000, - useNativeDriver: false, - }).start(); - const style = { - backgroundColor: 'rgb(180, 64, 119)', - width: 200, - height: 100, - transform: [{scale: mScale}], - }; - return ( - - - - - - ); - }, - }, - { - title: 'Pressable with custom Ripple', - description: ("Pressable can specify ripple's radius and borderless params": string), - platform: 'android', - render: function(): React.Node { - const nativeFeedbackButton = { - textAlign: 'center', - margin: 10, - }; - return ( - - - - - radius 30 - - - - - - - - radius 150 - - - - - - - - radius 70, with border - - - - - ); - }, - }, - { - title: ' with highlight', - render: function(): React.Node { - return ; - }, - }, - { - title: 'Pressable delay for events', - description: (' also accept delayPressIn, ' + - 'delayPressOut, and delayLongPress as props. These props impact the ' + - 'timing of feedback events.': string), - render: function(): React.Node { - return ; - }, - }, - { - title: '3D Touch / Force Touch', - description: - 'iPhone 8 and 8 plus support 3D touch, which adds a force property to touches', - render: function(): React.Node { - return ; - }, - platform: 'ios', - }, - { - title: 'Pressable Hit Slop', - description: (' components accept hitSlop prop which extends the touch area ' + - 'without changing the view bounds.': string), - render: function(): React.Node { - return ; - }, - }, - { - title: 'Pressable Native Methods', - description: (' components expose native methods like `measure`.': string), - render: function(): React.Node { - return ; - }, - }, - { - title: 'Disabled Pressable', - description: (' components accept disabled prop which prevents ' + - 'any interaction with component': string), - render: function(): React.Node { - return ; - }, - }, -]; diff --git a/RNTester/js/examples/PushNotificationIOS/PushNotificationIOSExample.js b/RNTester/js/examples/PushNotificationIOS/PushNotificationIOSExample.js index 93127afb755999..c291a7a6e5ef07 100644 --- a/RNTester/js/examples/PushNotificationIOS/PushNotificationIOSExample.js +++ b/RNTester/js/examples/PushNotificationIOS/PushNotificationIOSExample.js @@ -49,6 +49,8 @@ class NotificationExample extends React.Component<{...}> { 'localNotification', this._onLocalNotification, ); + + PushNotificationIOS.requestPermissions(); } componentWillUnmount() { @@ -171,51 +173,18 @@ class NotificationPermissionExample extends React.Component< return (