diff --git a/.ado/templates/apple-job-javascript.yml b/.ado/templates/apple-job-javascript.yml index 0f0277e097aac1..1eb7f5b9e400fc 100644 --- a/.ado/templates/apple-job-javascript.yml +++ b/.ado/templates/apple-job-javascript.yml @@ -17,10 +17,6 @@ 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' @@ -42,4 +38,4 @@ steps: displayName: 'yarn lint' - script: 'yarn format-check' - displayName: 'yarn format-check' \ No newline at end of file + displayName: 'yarn format-check' diff --git a/.ado/templates/apple-job-react-native.yml b/.ado/templates/apple-job-react-native.yml index 5ba1fc0dc98d08..70bdd2440fc00f 100644 --- a/.ado/templates/apple-job-react-native.yml +++ b/.ado/templates/apple-job-react-native.yml @@ -28,13 +28,9 @@ 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 deleted file mode 100644 index ed8162cf135899..00000000000000 --- a/.appveyor/config.yml +++ /dev/null @@ -1,47 +0,0 @@ -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 14ee0b460b6e1c..dc22ddc157f629 100644 --- a/.buckconfig +++ b/.buckconfig @@ -1,6 +1,6 @@ [android] - target = android-28 + target = android-29 [download] max_number_of_retries = 3 diff --git a/.circleci/Dockerfiles/Dockerfile.android b/.circleci/Dockerfiles/Dockerfile.android index 6d7e400c534fc6..2fa8e3f8e0d240 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-9-4 +FROM reactnativecommunity/react-native-android:2019-10-18 LABEL Description="React Native Android Test Image" LABEL maintainer="Héctor Ramos " diff --git a/.circleci/config.yml b/.circleci/config.yml index a749a0110bf58e..e50d25cbc858dd 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,5 +1,12 @@ version: 2.1 +# ------------------------- +# ORBS +# ------------------------- + +orbs: + win: circleci/windows@2.4.0 + # ------------------------- # DEFAULTS # ------------------------- @@ -7,23 +14,29 @@ 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: - node8: + nodelts: <<: *defaults docker: - - image: circleci/node:8 - nodelts: + - image: circleci/node:12 + nodeprevlts: <<: *defaults docker: - - image: circleci/node:lts + - image: circleci/node:10 reactnativeandroid: <<: *defaults docker: - - image: reactnativecommunity/react-native-android:2019-9-4 + - image: reactnativecommunity/react-native-android:2019-10-18 resource_class: "large" environment: - TERM: "dumb" @@ -31,10 +44,13 @@ 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: "10.3.0" + xcode: &_XCODE_VERSION "11.3.1" # ------------------------- # COMMANDS @@ -53,7 +69,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: @@ -62,7 +78,7 @@ commands: - v4-yarn-cache-{{ arch }}-{{ checksum "yarn.lock" }} - v4-yarn-cache-{{ arch }} - run: - name: Run Yarn + name: "Yarn: Install Dependencies" command: | # Skip yarn install on metro bump commits as the package is not yet # available on npm @@ -94,13 +110,21 @@ 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: HOMEBREW_NO_AUTO_UPDATE=1 brew install << parameters.package >> >/dev/null + - run: + name: "Brew: Install << parameters.package >>" + command: HOMEBREW_NO_AUTO_UPDATE=1 brew install << parameters.package >> >/dev/null with_brew_cache_span: parameters: @@ -109,15 +133,15 @@ commands: steps: - restore_cache: keys: - - v2-brew + - v3-brew - steps: << parameters.steps >> - save_cache: paths: - /usr/local/Homebrew - ~/Library/Caches/Homebrew - key: v2-brew + key: v3-brew - with_pods_cache_span: + with_rntester_pods_cache_span: parameters: steps: type: steps @@ -158,24 +182,33 @@ commands: name: Download Dependencies Using Buck command: ./scripts/circleci/buck_fetch.sh - # ------------------------- - # COMMANDS: Disabled Tests - # ------------------------- - run_podspec_tests: - steps: - - run: - name: Test CocoaPods - command: ./scripts/process-podspecs.sh - run_e2e_tests: + 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 steps: - run: - name: Full End-to-End Test Suite - command: node ./scripts/run-ci-e2e-tests.js --android --ios --js --retries 3; - run_android_e2e_tests: + 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"] steps: + - install_github_bot_deps - run: - name: Android End-to-End Test Suite - command: node ./scripts/run-ci-e2e-tests.js --android --retries 3; + 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 >> # ------------------------- # JOBS @@ -185,7 +218,7 @@ jobs: parameters: executor: type: executor - default: node8 + default: nodelts checkout_type: type: string default: node @@ -205,23 +238,16 @@ 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 dependencies - command: | - sudo apt update && sudo apt install -y shellcheck jq - cd bots && yarn install --non-interactive --cache-folder ~/.cache/yarn + name: Install additional GitHub bot dependencies + command: sudo apt update && sudo apt install -y shellcheck jq - run: name: Run linters against modified files (analysis-bot) @@ -239,7 +265,7 @@ jobs: # JOBS: Analyze Code # ------------------------- analyze_code: - executor: node8 + executor: nodelts steps: - restore_cache_checkout: checkout_type: node @@ -248,7 +274,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: @@ -274,42 +300,70 @@ 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: node8 + default: nodelts + run_disabled_tests: + type: boolean + default: false 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: JavaScript Test Suite + name: "Run Tests: JavaScript Tests" 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" + - REPORTS_DIR: "./reports/junit" steps: - restore_cache_checkout: checkout_type: ios @@ -323,119 +377,103 @@ jobs: name: Boot iPhone Simulator command: source scripts/.tests.env && xcrun simctl boot "$IOS_DEVICE" || true - - run: - name: Fetch CocoaPods Specs - command: | - curl https://cocoapods-specs.circleci.com/fetch-cocoapods-repo-from-s3.sh | bash -s cf - - - when: - condition: << parameters.use_frameworks >> - steps: - - run: - name: Set USE_FRAMEWORKS=1 - command: echo "export USE_FRAMEWORKS=1" >> $BASH_ENV - - - 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: Boot iPhone Simulator - command: source scripts/.tests.env && xcrun simctl boot "$IOS_DEVICE" || true - - run: name: Configure Environment Variables command: | - echo 'export PATH=/usr/local/opt/node@8/bin:$PATH' >> $BASH_ENV + echo 'export PATH=/usr/local/opt/node@10/bin:$PATH' >> $BASH_ENV source $BASH_ENV - # Brew - with_brew_cache_span: steps: - brew_install: - package: node@8 - - run: HOMEBREW_NO_AUTO_UPDATE=1 brew tap wix/brew >/dev/null + package: watchman - brew_install: - package: applesimutils + package: node@10 + - run: + name: "Brew: Tap wix/brew" + command: HOMEBREW_NO_AUTO_UPDATE=1 brew tap wix/brew >/dev/null - brew_install: - package: watchman - # Configure Watchman - - run: touch .watchmanconfig - - - restore_cache: - keys: - - v1-cocoapods-{{ checksum "template/ios/Podfile" }} - - v1-cocoapods- - - - run: pod setup + package: applesimutils - run: - name: Generate RNTesterPods Workspace - command: pushd RNTester && pod install --verbose && popd + name: Configure Watchman + command: touch .watchmanconfig - - run: - name: Run Detox iOS End-to-End Tests - command: yarn run build-ios-e2e && yarn run test-ios-e2e - when: always + - when: + condition: << parameters.use_frameworks >> + steps: + - run: + name: Set USE_FRAMEWORKS=1 + command: echo "export USE_FRAMEWORKS=1" >> $BASH_ENV - run: - name: Run iOS End-to-End Tests + name: Fetch CocoaPods Specs 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" }} + curl https://cocoapods-specs.circleci.com/fetch-cocoapods-repo-from-s3.sh | bash -s cf + - run: + name: Setup the CocoaPods environment + command: pod setup - test_js_e2e: - executor: node8 - steps: - - restore_cache_checkout: - checkout_type: node - - setup_artifacts - - run_yarn - - run: sudo apt-get install rsync + - with_rntester_pods_cache_span: + steps: + - run: + name: Generate RNTesterPods Workspace + command: cd RNTester && pod install --verbose - run: - name: Run JavaScript End-to-End Tests - command: node ./scripts/run-ci-e2e-tests.js --js --retries 3 + name: Generate RNTesterPods Xcode Workspace + command: pushd RNTester && pod install --verbose && popd + + # ------------------------- + # 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 + + # Optionally, run disabled tests + - when: + condition: << parameters.run_disabled_tests >> + 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 + # ------------------------- + # 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 @@ -458,6 +496,10 @@ 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 @@ -490,37 +532,48 @@ jobs: name: Wait for Android Virtual Device command: source scripts/android-setup.sh && waitForAVD - # Test Suite - run: - name: Run Unit Tests - command: buck test ReactAndroid/src/test/... --config build.threads=$BUILD_THREADS --xml ~/reports/buck/all-results-raw.xml + name: Assemble RNTester App + command: ./gradlew RNTester:android:app:assembleRelease + # ------------------------- + # 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 Instrumentation Tests + name: "Run Tests: Android 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 - - run: - name: Build Android RNTester App - command: ./gradlew RNTester:android:app:assembleRelease + # Optionally, run disabled tests + - when: + condition: << parameters.run_disabled_tests >> + steps: + - run: echo "Failing tests may be moved here temporarily." + - run_e2e: + platform: android + # ------------------------- # 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 - ./tooling/junit/buck_to_junit.sh ~/react-native/reports/buck/all-results-raw.xml ~/react-native/reports/junit/all-results-junit.xml + cd ~/okbuck + ./tooling/junit/buck_to_junit.sh ~/react-native/reports/buck/all-results-raw.xml ~/react-native/reports/junit/results.xml fi when: always - - store_test_results: - path: ~/reports/junit + path: ./reports/junit # ------------------------- # JOBS: Test Docker @@ -539,12 +592,89 @@ 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: node8 + executor: nodelts environment: - CI_BRANCH: $CIRCLE_BRANCH - CI_PULL_REQUEST: $CIRCLE_PULL_REQUEST @@ -556,11 +686,12 @@ jobs: - setup_artifacts - run_yarn - run: - name: Test coverage + name: Collect test coverage information command: | - yarn test --coverage --maxWorkers=2 - cat ./coverage/lcov.info | ./node_modules/.bin/coveralls - when: always + 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 - store_artifacts: path: ~/react-native/coverage/ @@ -569,6 +700,10 @@ jobs: # ------------------------- # Publishes a new version onto npm publish_npm_package: + parameters: + publish_npm_args: + type: string + default: --nonightly executor: reactnativeandroid steps: - run: @@ -587,12 +722,25 @@ 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 + - 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" # ------------------------- # WORK FLOWS # ------------------------- workflows: + version: 2 + tests: jobs: - setup: @@ -616,35 +764,40 @@ 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_frameworks + name: test_ios_unit_frameworks use_frameworks: true + run_unit_tests: true requires: - setup_ios - - test_ios_e2e: + - 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 requires: - setup_ios - - test_js - test_js: - name: test_js_lts - executor: nodelts + name: test_js_prev_lts + executor: nodeprevlts requires: - setup_js - test_docker: @@ -652,6 +805,12 @@ 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: @@ -707,3 +866,26 @@ 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 f485f90b89c3ca..479b10a7655330 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,14 +1,16 @@ # node_modules ignored by default -**/staticBundle.js **/main.js -Libraries/vendor/**/* +**/staticBundle.js +bots/node_modules +docs/generatedComponentApiDocs.js +flow/ Libraries/Renderer/* +Libraries/vendor/**/* 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 9385a7481c3ce6..7795e95b40cd3c 100644 --- a/.eslintrc +++ b/.eslintrc @@ -13,6 +13,7 @@ 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 6c780e7543d1cd..87fd42b63f3ac5 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.113.0 +^0.122.0 diff --git a/.flowconfig.android b/.flowconfig.android index f0aadb57289f21..25c6ad92d010e2 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.113.0 +^0.122.0 diff --git a/.flowconfig.macos b/.flowconfig.macos index c13da62f1bad21..228c57f1770316 100644 --- a/.flowconfig.macos +++ b/.flowconfig.macos @@ -75,7 +75,6 @@ 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 @@ -90,4 +89,4 @@ untyped-import untyped-type-import [version] -^0.113.0 +^0.122.0 diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index b18fb13e017294..d16bc898be18a2 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,2 +1,3 @@ ** @acoates-ms ** @tom-un +** @alloy diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 44f933bfbf8528..015f815215f18b 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,3 +1 @@ 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 new file mode 100644 index 00000000000000..7821e038ec89ee --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,14 @@ +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 deleted file mode 100644 index e82b973392fa06..00000000000000 --- a/.github/ISSUE_TEMPLATE/question.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -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 dab90d600d4308..f34e5777e55052 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -23,7 +23,9 @@ 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 d229644aa40f9d..4e313c997e3094 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://facebook.github.io/react-native/help). +> For a full list of community resources, check out [React Native's Community page](https://reactnative.dev/help). diff --git a/.github/label-actions.yml b/.github/label-actions.yml new file mode 100644 index 00000000000000..e0636f4c614438 --- /dev/null +++ b/.github/label-actions.yml @@ -0,0 +1,52 @@ +# 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 new file mode 100644 index 00000000000000..e5c1a979653171 --- /dev/null +++ b/.github/workflows/needs-attention.yml @@ -0,0 +1,21 @@ +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 new file mode 100644 index 00000000000000..2c63100f6e8392 --- /dev/null +++ b/.github/workflows/process-label-actions.yml @@ -0,0 +1,16 @@ +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 90688e0daa381d..b316422451ca77 100644 --- a/.gitignore +++ b/.gitignore @@ -31,14 +31,16 @@ 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/armeabi-v7a/ -/ReactAndroid/src/main/jni/prebuilt/lib/x86/ +/ReactAndroid/src/main/jni/prebuilt/lib/ /ReactAndroid/src/main/gen # Android Studio diff --git a/IntegrationTests/IntegrationTestsApp.js b/IntegrationTests/IntegrationTestsApp.js index c52fe515221ede..1e52877b7b9908 100644 --- a/IntegrationTests/IntegrationTestsApp.js +++ b/IntegrationTests/IntegrationTestsApp.js @@ -79,6 +79,9 @@ 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 93a9efee9fd04f..2e557b948103fa 100644 --- a/Libraries/ART/ARTSurfaceView.m +++ b/Libraries/ART/ARTSurfaceView.m @@ -47,9 +47,7 @@ - (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 23794a425375da..e04351c9dca68a 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 = "http://facebook.github.io/react-native/" + s.homepage = "https://reactnative.dev/" s.license = package["license"] s.author = "Facebook, Inc. and its affiliates" - s.platforms = { :ios => "9.0", :tvos => "9.2", :osx => "10.13" } # TODO(macOS GH#214) + s.platforms = { :ios => "10.0", :tvos => "10.0", :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 accb7e1abdb07c..e330253df81b08 100644 --- a/Libraries/ActionSheetIOS/ActionSheetIOS.js +++ b/Libraries/ActionSheetIOS/ActionSheetIOS.js @@ -14,12 +14,13 @@ import RCTActionSheetManager from './NativeActionSheetManager'; const invariant = require('invariant'); const processColor = require('../StyleSheet/processColor'); -import type {NativeOrDynamicColorType} from '../StyleSheet/NativeOrDynamicColorType'; // TODO(macOS ISS#2323203) +import type {ColorValue} from '../StyleSheet/StyleSheetTypes'; +import type {ProcessedColorValue} from '../StyleSheet/processColor'; /** * Display action sheets and share sheets on iOS. * - * See http://facebook.github.io/react-native/docs/actionsheetios.html + * See https://reactnative.dev/docs/actionsheetios.html */ const ActionSheetIOS = { /** @@ -36,7 +37,7 @@ const ActionSheetIOS = { * The 'callback' function takes one parameter, the zero-based index * of the selected item. * - * See http://facebook.github.io/react-native/docs/actionsheetios.html#showactionsheetwithoptions + * See https://reactnative.dev/docs/actionsheetios.html#showactionsheetwithoptions */ showActionSheetWithOptions( options: {| @@ -46,7 +47,8 @@ const ActionSheetIOS = { +destructiveButtonIndex?: ?number | ?Array, +cancelButtonIndex?: ?number, +anchor?: ?number, - +tintColor?: number | string | NativeOrDynamicColorType, // TODO(macOS ISS#2323203) + +tintColor?: ColorValue | ProcessedColorValue, + +userInterfaceStyle?: string, |}, callback: (buttonIndex: number) => void, ) { @@ -66,10 +68,15 @@ 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: processColor(tintColor), + tintColor: processedTintColor, destructiveButtonIndices, }, callback, @@ -97,7 +104,7 @@ const ActionSheetIOS = { * - a boolean value signifying success or failure * - a string that, in the case of success, indicates the method of sharing * - * See http://facebook.github.io/react-native/docs/actionsheetios.html#showshareactionsheetwithoptions + * See https://reactnative.dev/docs/actionsheetios.html#showshareactionsheetwithoptions */ showShareActionSheetWithOptions( options: Object, diff --git a/Libraries/ActionSheetIOS/NativeActionSheetManager.js b/Libraries/ActionSheetIOS/NativeActionSheetManager.js index f96fc7ec63aef7..be3b8c3afffdbe 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 {NativeOrDynamicColorType} from '../StyleSheet/NativeOrDynamicColorType'; // TODO(macOS ISS#2323203) +import type {ProcessedColorValue} from '../StyleSheet/processColor'; // TODO(macOS ISS#2323203) export interface Spec extends TurboModule { +getConstants: () => {||}; @@ -24,7 +24,8 @@ export interface Spec extends TurboModule { +destructiveButtonIndices?: ?Array, +cancelButtonIndex?: ?number, +anchor?: ?number, - +tintColor?: ?(number | NativeOrDynamicColorType), // TODO(macOS ISS#2323203) + +tintColor?: ?ProcessedColorValue, // TODO(macOS ISS#2323203) + +userInterfaceStyle?: ?string, |}, callback: (buttonIndex: number) => void, ) => void; @@ -34,8 +35,9 @@ export interface Spec extends TurboModule { +url?: ?string, +subject?: ?string, +anchor?: ?number, - +tintColor?: ?(number | NativeOrDynamicColorType), // TODO(macOS ISS#2323203) + +tintColor?: ?ProcessedColorValue, // 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 9574165e410882..1ba2b9c8d4d284 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 = "http://facebook.github.io/react-native/" - s.documentation_url = "https://facebook.github.io/react-native/docs/actionsheetios" + s.homepage = "https://reactnative.dev/" + s.documentation_url = "https://reactnative.dev/docs/actionsheetios" s.license = package["license"] s.author = "Facebook, Inc. and its affiliates" - s.platforms = { :ios => "9.0", :tvos => "9.2", :osx => "10.13" } # TODO(macOS GH#214) + s.platforms = { :ios => "10.0", :tvos => "10.0", :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 4f4f75d462b0ca..613d40c530f215 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 http://facebook.github.io/react-native/docs/alert.html + * See https://reactnative.dev/docs/alert.html */ class Alert { static alert( @@ -115,28 +115,6 @@ 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 a42c0d395ba25c..450fc1c0264f13 100644 --- a/Libraries/Animated/src/Animated.js +++ b/Libraries/Animated/src/Animated.js @@ -18,7 +18,8 @@ import type {AnimatedComponentType} from './createAnimatedComponent'; const AnimatedMock = require('./AnimatedMock'); const AnimatedImplementation = require('./AnimatedImplementation'); -const Animated = ((Platform.isTesting +//TODO(T57411659): Remove the bridgeless check when Animated perf regressions are fixed. +const Animated = ((Platform.isTesting || global.RN$Bridgeless ? AnimatedMock : AnimatedImplementation): typeof AnimatedMock); diff --git a/Libraries/Animated/src/AnimatedEvent.js b/Libraries/Animated/src/AnimatedEvent.js index e3c0b814cf8888..91eb29ce413e29 100644 --- a/Libraries/Animated/src/AnimatedEvent.js +++ b/Libraries/Animated/src/AnimatedEvent.js @@ -22,14 +22,13 @@ export type Mapping = {[key: string]: Mapping, ...} | AnimatedValue; export type EventConfig = { listener?: ?Function, useNativeDriver: boolean, - ... }; function attachNativeEvent( viewRef: any, eventName: string, - argMapping: Array, -): {|detach: () => void|} { + argMapping: $ReadOnlyArray, +): {detach: () => void} { // Find animated values in `argMapping` and create an array representing their // key path inside the `nativeEvent` object. Ex.: ['contentOffset', 'x']. const eventMappings = []; @@ -58,7 +57,6 @@ function attachNativeEvent( traverse(argMapping[0].nativeEvent, []); const viewTag = ReactNative.findNodeHandle(viewRef); - if (viewTag != null) { eventMappings.forEach(mapping => { NativeAnimatedHelper.API.addAnimatedEventToView( @@ -84,19 +82,64 @@ 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: Array; + _argMapping: $ReadOnlyArray; _listeners: Array = []; _callListeners: Function; _attachedEvent: ?{detach: () => void, ...}; __isNative: boolean; - constructor(argMapping: Array, config: EventConfig) { + constructor(argMapping: $ReadOnlyArray, config: EventConfig) { this._argMapping = argMapping; if (config == null) { console.warn('Animated.event now requires a second argument for options'); - config = {}; + config = {useNativeDriver: false}; } if (config.listener) { @@ -105,10 +148,6 @@ class AnimatedEvent { this._callListeners = this._callListeners.bind(this); this._attachedEvent = null; this.__isNative = shouldUseNativeDriver(config); - - if (__DEV__) { - this._validateMapping(); - } } __addListener(callback: Function): void { @@ -143,28 +182,45 @@ class AnimatedEvent { __getHandler(): any | ((...args: any) => void) { if (this.__isNative) { - return this._callListeners; + if (__DEV__) { + let validatedMapping = false; + return (...args: any) => { + if (!validatedMapping) { + validateMapping(this._argMapping, args); + validatedMapping = true; + } + this._callListeners(...args); + }; + } else { + return this._callListeners; + } } + let validatedMapping = false; return (...args: any) => { + if (__DEV__ && !validatedMapping) { + validateMapping(this._argMapping, args); + validatedMapping = true; + } + const traverse = (recMapping, recEvt, key) => { - if (typeof recEvt === 'number' && recMapping instanceof AnimatedValue) { - recMapping.setValue(recEvt); + if (recMapping instanceof AnimatedValue) { + if (typeof recEvt === 'number') { + recMapping.setValue(recEvt); + } } else if (typeof recMapping === 'object') { for (const mappingKey in recMapping) { - /* $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. */ + /* $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. */ 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); }; } @@ -172,33 +228,6 @@ 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 a1ce333acd214e..5045ed398ffa5b 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,9 +170,6 @@ 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); }, @@ -227,9 +224,6 @@ 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); }, @@ -272,9 +266,6 @@ 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); }, @@ -522,7 +513,10 @@ function unforkEvent( } } -const event = function(argMapping: Array, config: EventConfig): any { +const event = function( + argMapping: $ReadOnlyArray, + config: EventConfig, +): any { const animatedEvent = new AnimatedEvent(argMapping, config); if (animatedEvent.__isNative) { return animatedEvent; @@ -539,33 +533,33 @@ const event = function(argMapping: Array, config: EventConfig): any { * If additional transforms are added, be sure to include them in * AnimatedMock.js as well. * - * See http://facebook.github.io/react-native/docs/animated.html + * See https://reactnative.dev/docs/animated.html */ module.exports = { /** * Standard value class for driving animations. Typically initialized with * `new Animated.Value(0);` * - * See http://facebook.github.io/react-native/docs/animated.html#value + * See https://reactnative.dev/docs/animated.html#value */ Value: AnimatedValue, /** * 2D value class for driving 2D animations, such as pan gestures. * - * See https://facebook.github.io/react-native/docs/animatedvaluexy.html + * See https://reactnative.dev/docs/animatedvaluexy.html */ ValueXY: AnimatedValueXY, /** * Exported to use the Interpolation type in flow. * - * See http://facebook.github.io/react-native/docs/animated.html#interpolation + * See https://reactnative.dev/docs/animated.html#interpolation */ Interpolation: AnimatedInterpolation, /** * Exported for ease of type checking. All animated values derive from this * class. * - * See http://facebook.github.io/react-native/docs/animated.html#node + * See https://reactnative.dev/docs/animated.html#node */ Node: AnimatedNode, @@ -573,21 +567,21 @@ module.exports = { * Animates a value from an initial velocity to zero based on a decay * coefficient. * - * See http://facebook.github.io/react-native/docs/animated.html#decay + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/animated.html#timing + * See https://reactnative.dev/docs/animated.html#timing */ timing, /** * Animates a value according to an analytical spring model based on * damped harmonic oscillation. * - * See http://facebook.github.io/react-native/docs/animated.html#spring + * See https://reactnative.dev/docs/animated.html#spring */ spring, @@ -595,7 +589,7 @@ module.exports = { * Creates a new Animated value composed from two Animated values added * together. * - * See http://facebook.github.io/react-native/docs/animated.html#add + * See https://reactnative.dev/docs/animated.html#add */ add, @@ -603,7 +597,7 @@ module.exports = { * Creates a new Animated value composed by subtracting the second Animated * value from the first Animated value. * - * See http://facebook.github.io/react-native/docs/animated.html#subtract + * See https://reactnative.dev/docs/animated.html#subtract */ subtract, @@ -611,7 +605,7 @@ module.exports = { * Creates a new Animated value composed by dividing the first Animated value * by the second Animated value. * - * See http://facebook.github.io/react-native/docs/animated.html#divide + * See https://reactnative.dev/docs/animated.html#divide */ divide, @@ -619,7 +613,7 @@ module.exports = { * Creates a new Animated value composed from two Animated values multiplied * together. * - * See http://facebook.github.io/react-native/docs/animated.html#multiply + * See https://reactnative.dev/docs/animated.html#multiply */ multiply, @@ -627,7 +621,7 @@ module.exports = { * Creates a new Animated value that is the (non-negative) modulo of the * provided Animated value. * - * See http://facebook.github.io/react-native/docs/animated.html#modulo + * See https://reactnative.dev/docs/animated.html#modulo */ modulo, @@ -636,14 +630,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 http://facebook.github.io/react-native/docs/animated.html#diffclamp + * See https://reactnative.dev/docs/animated.html#diffclamp */ diffClamp, /** * Starts an animation after the given delay. * - * See http://facebook.github.io/react-native/docs/animated.html#delay + * See https://reactnative.dev/docs/animated.html#delay */ delay, /** @@ -651,7 +645,7 @@ module.exports = { * before starting the next. If the current running animation is stopped, no * following animations will be started. * - * See http://facebook.github.io/react-native/docs/animated.html#sequence + * See https://reactnative.dev/docs/animated.html#sequence */ sequence, /** @@ -659,21 +653,21 @@ module.exports = { * of the animations is stopped, they will all be stopped. You can override * this with the `stopTogether` flag. * - * See http://facebook.github.io/react-native/docs/animated.html#parallel + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/animated.html#stagger + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/animated.html#loop + * See https://reactnative.dev/docs/animated.html#loop */ loop, @@ -681,14 +675,14 @@ module.exports = { * Takes an array of mappings and extracts values from each arg accordingly, * then calls `setValue` on the mapped outputs. * - * See http://facebook.github.io/react-native/docs/animated.html#event + * See https://reactnative.dev/docs/animated.html#event */ event, /** * Make any React component Animatable. Used to create `Animated.View`, etc. * - * See http://facebook.github.io/react-native/docs/animated.html#createanimatedcomponent + * See https://reactnative.dev/docs/animated.html#createanimatedcomponent */ createAnimatedComponent, @@ -696,7 +690,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 http://facebook.github.io/react-native/docs/animated.html#attachnativeevent + * See https://reactnative.dev/docs/animated.html#attachnativeevent */ attachNativeEvent, @@ -704,7 +698,7 @@ module.exports = { * Advanced imperative API for snooping on animated events that are passed in * through props. Use values directly where possible. * - * See http://facebook.github.io/react-native/docs/animated.html#forkevent + * See https://reactnative.dev/docs/animated.html#forkevent */ forkEvent, unforkEvent, diff --git a/Libraries/Animated/src/NativeAnimatedHelper.js b/Libraries/Animated/src/NativeAnimatedHelper.js index 25fde53b6286a6..f21066bb07ff65 100644 --- a/Libraries/Animated/src/NativeAnimatedHelper.js +++ b/Libraries/Animated/src/NativeAnimatedHelper.js @@ -172,6 +172,7 @@ const STYLES_WHITELIST = { borderTopRightRadius: true, borderTopStartRadius: true, elevation: true, + zIndex: true, /* ios styles */ shadowOpacity: true, shadowRadius: true, @@ -276,7 +277,9 @@ 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 ' + @@ -291,7 +294,7 @@ function shouldUseNativeDriver(config: AnimationConfig | EventConfig): boolean { 'animated module is missing. Falling back to JS-based animation. To ' + 'resolve this, add `RCTAnimation` module to this app, or remove ' + '`useNativeDriver`. ' + - 'More info: https://github.com/facebook/react-native/issues/11094#issuecomment-263240420', + 'Make sure to run `pod install` first. Read more about autolinking: https://github.com/react-native-community/cli/blob/master/docs/autolinking.md', ); _warnedMissingNativeAnimated = true; } diff --git a/Libraries/Animated/src/__tests__/AnimatedNative-test.js b/Libraries/Animated/src/__tests__/AnimatedNative-test.js index c511638be6add8..89024cdb883fe4 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({foo: 42}); + handler({nativeEvent: {foo: 42}}); expect(listener).toHaveBeenCalledTimes(1); - expect(listener).toBeCalledWith({foo: 42}); + expect(listener).toBeCalledWith({nativeEvent: {foo: 42}}); }); }); diff --git a/Libraries/Animated/src/animations/Animation.js b/Libraries/Animated/src/animations/Animation.js index 4d2ac80752330a..fd0c2218858452 100644 --- a/Libraries/Animated/src/animations/Animation.js +++ b/Libraries/Animated/src/animations/Animation.js @@ -22,7 +22,6 @@ 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 6f4039cf40e604..c3dce534f84baa 100644 --- a/Libraries/Animated/src/animations/DecayAnimation.js +++ b/Libraries/Animated/src/animations/DecayAnimation.js @@ -17,7 +17,8 @@ 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 | { @@ -26,13 +27,12 @@ export type DecayAnimationConfig = AnimationConfig & { ... }, 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 61ff7cfa7cc0f5..aec87e5cecb732 100644 --- a/Libraries/Animated/src/animations/SpringAnimation.js +++ b/Libraries/Animated/src/animations/SpringAnimation.js @@ -12,6 +12,7 @@ const AnimatedValue = require('../nodes/AnimatedValue'); const AnimatedValueXY = require('../nodes/AnimatedValueXY'); +const AnimatedInterpolation = require('../nodes/AnimatedInterpolation'); const Animation = require('./Animation'); const SpringConfig = require('../SpringConfig'); @@ -21,7 +22,8 @@ const {shouldUseNativeDriver} = require('../NativeAnimatedHelper'); import type {AnimationConfig, EndCallback} from './Animation'; -export type SpringAnimationConfig = AnimationConfig & { +export type SpringAnimationConfig = { + ...AnimationConfig, toValue: | number | AnimatedValue @@ -30,7 +32,8 @@ export type SpringAnimationConfig = AnimationConfig & { y: number, ... } - | AnimatedValueXY, + | AnimatedValueXY + | AnimatedInterpolation, overshootClamping?: boolean, restDisplacementThreshold?: number, restSpeedThreshold?: number, @@ -49,11 +52,11 @@ export type SpringAnimationConfig = AnimationConfig & { damping?: number, mass?: number, delay?: number, - ... }; -export type SpringAnimationConfigSingle = AnimationConfig & { - toValue: number | AnimatedValue, +export type SpringAnimationConfigSingle = { + ...AnimationConfig, + toValue: number | AnimatedValue | AnimatedInterpolation, overshootClamping?: boolean, restDisplacementThreshold?: number, restSpeedThreshold?: number, @@ -66,7 +69,6 @@ export type SpringAnimationConfigSingle = AnimationConfig & { 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 f88f7207e60d88..ffe8c8313be2f7 100644 --- a/Libraries/Animated/src/animations/TimingAnimation.js +++ b/Libraries/Animated/src/animations/TimingAnimation.js @@ -12,13 +12,15 @@ 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 @@ -27,19 +29,19 @@ export type TimingAnimationConfig = AnimationConfig & { y: number, ... } - | AnimatedValueXY, + | AnimatedValueXY + | AnimatedInterpolation, easing?: (value: number) => number, duration?: number, delay?: number, - ... }; -export type TimingAnimationConfigSingle = AnimationConfig & { - toValue: number | AnimatedValue, +export type TimingAnimationConfigSingle = { + ...AnimationConfig, + toValue: number | AnimatedValue | AnimatedInterpolation, 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 a17a13e9e9fcc4..ca2922aaf4cd5f 100644 --- a/Libraries/Animated/src/components/AnimatedFlatList.js +++ b/Libraries/Animated/src/components/AnimatedFlatList.js @@ -13,9 +13,10 @@ import * as React from 'react'; const FlatList = require('../../../Lists/FlatList'); - const createAnimatedComponent = require('../createAnimatedComponent'); +import type {AnimatedComponentType} from '../createAnimatedComponent'; + /** * @see https://github.com/facebook/react-native/commit/b8c8562 */ @@ -25,4 +26,7 @@ const FlatListWithEventThrottle = React.forwardRef((props, ref) => ( module.exports = (createAnimatedComponent( FlatListWithEventThrottle, -): $FlowFixMe); +): AnimatedComponentType< + React.ElementConfig, + React.ElementRef, +>); diff --git a/Libraries/Animated/src/components/AnimatedImage.js b/Libraries/Animated/src/components/AnimatedImage.js index 89fee4d29ea8da..f5e801845f32b2 100644 --- a/Libraries/Animated/src/components/AnimatedImage.js +++ b/Libraries/Animated/src/components/AnimatedImage.js @@ -10,8 +10,16 @@ 'use strict'; -const Image = require('../../../Image/Image'); +import * as React from 'react'; +const Image = require('../../../Image/Image'); const createAnimatedComponent = require('../createAnimatedComponent'); -module.exports = (createAnimatedComponent(Image): $FlowFixMe); +import type {AnimatedComponentType} from '../createAnimatedComponent'; + +module.exports = (createAnimatedComponent( + (Image: $FlowFixMe), +): AnimatedComponentType< + React.ElementConfig, + React.ElementRef, +>); diff --git a/Libraries/Animated/src/components/AnimatedScrollView.js b/Libraries/Animated/src/components/AnimatedScrollView.js index 9938b594868881..afed39b31cfa06 100644 --- a/Libraries/Animated/src/components/AnimatedScrollView.js +++ b/Libraries/Animated/src/components/AnimatedScrollView.js @@ -13,9 +13,10 @@ import * as React from 'react'; const ScrollView = require('../../../Components/ScrollView/ScrollView'); - const createAnimatedComponent = require('../createAnimatedComponent'); +import type {AnimatedComponentType} from '../createAnimatedComponent'; + /** * @see https://github.com/facebook/react-native/commit/b8c8562 */ @@ -25,4 +26,7 @@ const ScrollViewWithEventThrottle = React.forwardRef((props, ref) => ( module.exports = (createAnimatedComponent( ScrollViewWithEventThrottle, -): $FlowFixMe); +): AnimatedComponentType< + React.ElementConfig, + React.ElementRef, +>); diff --git a/Libraries/Animated/src/components/AnimatedSectionList.js b/Libraries/Animated/src/components/AnimatedSectionList.js index 49e95e4adc7431..002f8a14c7646b 100644 --- a/Libraries/Animated/src/components/AnimatedSectionList.js +++ b/Libraries/Animated/src/components/AnimatedSectionList.js @@ -13,9 +13,10 @@ import * as React from 'react'; const SectionList = require('../../../Lists/SectionList'); - const createAnimatedComponent = require('../createAnimatedComponent'); +import type {AnimatedComponentType} from '../createAnimatedComponent'; + /** * @see https://github.com/facebook/react-native/commit/b8c8562 */ @@ -25,4 +26,7 @@ const SectionListWithEventThrottle = React.forwardRef((props, ref) => ( module.exports = (createAnimatedComponent( SectionListWithEventThrottle, -): $FlowFixMe); +): AnimatedComponentType< + React.ElementConfig, + React.ElementRef, +>); diff --git a/Libraries/Animated/src/components/AnimatedText.js b/Libraries/Animated/src/components/AnimatedText.js index 81b016cca18d41..55b8fb8c42fd01 100644 --- a/Libraries/Animated/src/components/AnimatedText.js +++ b/Libraries/Animated/src/components/AnimatedText.js @@ -10,8 +10,16 @@ 'use strict'; -const Text = require('../../../Text/Text'); +import * as React from 'react'; +const Text = require('../../../Text/Text'); const createAnimatedComponent = require('../createAnimatedComponent'); -module.exports = (createAnimatedComponent(Text): $FlowFixMe); +import type {AnimatedComponentType} from '../createAnimatedComponent'; + +module.exports = (createAnimatedComponent( + (Text: $FlowFixMe), +): AnimatedComponentType< + React.ElementConfig, + React.ElementRef, +>); diff --git a/Libraries/Animated/src/components/AnimatedView.js b/Libraries/Animated/src/components/AnimatedView.js index 3396337eda3f50..6e7badcced34d7 100644 --- a/Libraries/Animated/src/components/AnimatedView.js +++ b/Libraries/Animated/src/components/AnimatedView.js @@ -10,12 +10,11 @@ 'use strict'; -const View = require('../../../Components/View/View'); +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 0672962354a97f..099e71c8faaaaf 100644 --- a/Libraries/Animated/src/createAnimatedComponent.js +++ b/Libraries/Animated/src/createAnimatedComponent.js @@ -79,7 +79,28 @@ 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 + 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.forceUpdate(); } else if (!this._propsAnimated.__isNative) { diff --git a/Libraries/Animated/src/nodes/AnimatedInterpolation.js b/Libraries/Animated/src/nodes/AnimatedInterpolation.js index 0fad54dc4085ca..a32bb9c2a7c190 100644 --- a/Libraries/Animated/src/nodes/AnimatedInterpolation.js +++ b/Libraries/Animated/src/nodes/AnimatedInterpolation.js @@ -22,17 +22,12 @@ const normalizeColor = require('../../../StyleSheet/normalizeColor'); type ExtrapolateType = 'extend' | 'identity' | 'clamp'; export type InterpolationConfigType = { - 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, + inputRange: $ReadOnlyArray, + outputRange: $ReadOnlyArray | $ReadOnlyArray, easing?: (input: number) => number, extrapolate?: ExtrapolateType, extrapolateLeft?: ExtrapolateType, extrapolateRight?: ExtrapolateType, - ... }; const linear = t => t; @@ -169,20 +164,17 @@ function interpolate( } function colorToRgba(input: string): string { - let int32Color = normalizeColor(input); - if ( - int32Color === null || - typeof int32Color !== 'number' /* TODO(macOS ISS#2323203) */ - ) { + let normalizedColor = normalizeColor(input); + if (normalizedColor === null || typeof normalizedColor !== 'number') { return input; } - int32Color = int32Color || 0; + normalizedColor = normalizedColor || 0; - const r = (int32Color & 0xff000000) >>> 24; - const g = (int32Color & 0x00ff0000) >>> 16; - const b = (int32Color & 0x0000ff00) >>> 8; - const a = (int32Color & 0x000000ff) / 255; + const r = (normalizedColor & 0xff000000) >>> 24; + const g = (normalizedColor & 0x00ff0000) >>> 16; + const b = (normalizedColor & 0x0000ff00) >>> 8; + const a = (normalizedColor & 0x000000ff) / 255; return `rgba(${r}, ${g}, ${b}, ${a})`; } @@ -226,11 +218,10 @@ 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, @@ -261,7 +252,7 @@ function isRgbOrRgba(range) { return typeof range === 'string' && range.startsWith('rgb'); } -function checkPattern(arr: Array) { +function checkPattern(arr: $ReadOnlyArray) { const pattern = arr[0].replace(stringShapeRegex, ''); for (let i = 1; i < arr.length; ++i) { invariant( @@ -271,7 +262,7 @@ function checkPattern(arr: Array) { } } -function findRange(input: number, inputRange: Array) { +function findRange(input: number, inputRange: $ReadOnlyArray) { let i; for (i = 1; i < inputRange.length - 1; ++i) { if (inputRange[i] >= input) { @@ -281,7 +272,7 @@ function findRange(input: number, inputRange: Array) { return i - 1; } -function checkValidInputRange(arr: Array) { +function checkValidInputRange(arr: $ReadOnlyArray) { invariant(arr.length >= 2, 'inputRange must have at least 2 elements'); for (let i = 1; i < arr.length; ++i) { invariant( @@ -297,7 +288,7 @@ function checkValidInputRange(arr: Array) { } } -function checkInfiniteRange(name: string, arr: Array) { +function checkInfiniteRange(name: string, arr: $ReadOnlyArray) { invariant(arr.length >= 2, name + ' must have at least 2 elements'); invariant( arr.length !== 2 || arr[0] !== -Infinity || arr[1] !== Infinity, @@ -367,6 +358,8 @@ 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 4b6a079bf732ad..7371d49fd5b355 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 http://facebook.github.io/react-native/docs/animatedvalue.html#addlistener + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/animatedvalue.html#removelistener + * See https://reactnative.dev/docs/animatedvalue.html#removelistener */ removeListener(id: string): void { delete this._listeners[id]; @@ -92,7 +92,7 @@ class AnimatedNode { /** * Remove all registered listeners. * - * See http://facebook.github.io/react-native/docs/animatedvalue.html#removealllisteners + * See https://reactnative.dev/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 4fa35ed27c20ab..7306fc77b94c05 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 http://facebook.github.io/react-native/docs/animatedvalue.html + * See https://reactnative.dev/docs/animatedvalue.html */ class AnimatedValue extends AnimatedWithChildren { _value: number; @@ -77,6 +77,9 @@ 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; @@ -95,7 +98,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 http://facebook.github.io/react-native/docs/animatedvalue.html#setvalue + * See https://reactnative.dev/docs/animatedvalue.html#setvalue */ setValue(value: number): void { if (this._animation) { @@ -116,7 +119,7 @@ class AnimatedValue extends AnimatedWithChildren { * `setValue`, an animation, or `Animated.event`. Useful for compensating * things like the start of a pan gesture. * - * See http://facebook.github.io/react-native/docs/animatedvalue.html#setoffset + * See https://reactnative.dev/docs/animatedvalue.html#setoffset */ setOffset(offset: number): void { this._offset = offset; @@ -129,7 +132,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 http://facebook.github.io/react-native/docs/animatedvalue.html#flattenoffset + * See https://reactnative.dev/docs/animatedvalue.html#flattenoffset */ flattenOffset(): void { this._value += this._offset; @@ -143,7 +146,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 http://facebook.github.io/react-native/docs/animatedvalue.html#extractoffset + * See https://reactnative.dev/docs/animatedvalue.html#extractoffset */ extractOffset(): void { this._offset += this._value; @@ -158,7 +161,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 http://facebook.github.io/react-native/docs/animatedvalue.html#stopanimation + * See https://reactnative.dev/docs/animatedvalue.html#stopanimation */ stopAnimation(callback?: ?(value: number) => void): void { this.stopTracking(); @@ -170,7 +173,7 @@ class AnimatedValue extends AnimatedWithChildren { /** * Stops any animation and resets the value to its original. * - * See http://facebook.github.io/react-native/docs/animatedvalue.html#resetanimation + * See https://reactnative.dev/docs/animatedvalue.html#resetanimation */ resetAnimation(callback?: ?(value: number) => void): void { this.stopAnimation(callback); @@ -193,7 +196,7 @@ class AnimatedValue extends AnimatedWithChildren { * Typically only used internally, but could be used by a custom Animation * class. * - * See http://facebook.github.io/react-native/docs/animatedvalue.html#animate + * See https://reactnative.dev/docs/animatedvalue.html#animate */ animate(animation: Animation, callback: ?EndCallback): void { let handle = null; @@ -239,6 +242,10 @@ 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 2e845b26219d84..28d3395db8a802 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 http://facebook.github.io/react-native/docs/animatedvaluexy.html + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/animatedvaluexy.html#setvalue + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/animatedvaluexy.html#setoffset + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/animatedvaluexy.html#flattenoffset + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/animatedvaluexy.html#extractoffset + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/animatedvaluexy.html#resetanimation + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/animatedvaluexy.html#stopanimation + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/animatedvaluexy.html#addlistener + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/animatedvaluexy.html#removelistener + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/animatedvaluexy.html#removealllisteners + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/animatedvaluexy.html#getlayout + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/animatedvaluexy.html#gettranslatetransform + * See https://reactnative.dev/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 30a0808f4400b3..b5fb59bd9fd5db 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 http://facebook.github.io/react-native/docs/appstate.html + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/appstate.html#addeventlistener + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/appstate.html#removeeventlistener + * See https://reactnative.dev/docs/appstate.html#removeeventlistener */ removeEventListener(type: string, handler: Function) { invariant( diff --git a/Libraries/BatchedBridge/MessageQueue.js b/Libraries/BatchedBridge/MessageQueue.js index 8c35ee9f8eaa95..3756b083fbd412 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'); +const stringifySafe = require('../Utilities/stringifySafe').default; const warnOnce = require('../Utilities/warnOnce'); export type SpyData = { @@ -74,9 +74,6 @@ 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, @@ -115,18 +112,12 @@ class MessageQueue { return this.flushedQueue(); } + // Deprecated. T61834641: Remove me once native clients have updated callFunctionReturnResultAndFlushedQueue( module: string, method: string, args: any[], - ): $TEMPORARY$array, Array, Array, number]> { - let result; - this.__guard(() => { - result = this.__callFunction(module, method, args); - }); - - return [result, this.flushedQueue()]; - } + ): void {} invokeCallbackAndReturnFlushedQueue( cbID: number, @@ -398,7 +389,7 @@ class MessageQueue { Systrace.endEvent(); } - __callFunction(module: string, method: string, args: any[]): any { + __callFunction(module: string, method: string, args: any[]): void { this._lastFlush = Date.now(); this._eventLoopStartTime = this._lastFlush; if (__DEV__ || this.__spy) { @@ -422,9 +413,8 @@ class MessageQueue { method, module, ); - const result = moduleMethods[method].apply(moduleMethods, args); + 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 fc769f8a544a72..15a8b44d0bb522 100644 --- a/Libraries/Blob/FileReader.js +++ b/Libraries/Blob/FileReader.js @@ -85,9 +85,15 @@ 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) { @@ -106,9 +112,15 @@ 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 4810cd89f88431..ab2572bd0ea8b7 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 c4ab554f088faf..1f68ec27aa5345 100755 --- a/Libraries/Blob/RCTBlobManager.mm +++ b/Libraries/Blob/RCTBlobManager.mm @@ -38,6 +38,7 @@ @implementation RCTBlobManager @synthesize bridge = _bridge; @synthesize methodQueue = _methodQueue; +@synthesize turboModuleLookupDelegate = _turboModuleLookupDelegate; - (void)setBridge:(RCTBridge *)bridge { @@ -139,9 +140,17 @@ - (void)remove:(NSString *)blobId RCT_EXPORT_METHOD(addNetworkingHandler) { - dispatch_async(_bridge.networking.methodQueue, ^{ - [self->_bridge.networking addRequestHandler:self]; - [self->_bridge.networking addResponseHandler:self]; + 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]; }); } @@ -301,9 +310,12 @@ - (id)processWebsocketMessage:(id)message }; } -- (std::shared_ptr)getTurboModuleWithJsInvoker:(std::shared_ptr)jsInvoker +- (std::shared_ptr) + getTurboModuleWithJsInvoker:(std::shared_ptr)jsInvoker + nativeInvoker:(std::shared_ptr)nativeInvoker + perfLogger:(id)perfLogger { - return std::make_shared(self, jsInvoker); + return std::make_shared(self, jsInvoker, nativeInvoker, perfLogger); } @end diff --git a/Libraries/Blob/RCTFileReaderModule.mm b/Libraries/Blob/RCTFileReaderModule.mm index 5cf41adc991fd5..7d6eda4d5c4f3b 100644 --- a/Libraries/Blob/RCTFileReaderModule.mm +++ b/Libraries/Blob/RCTFileReaderModule.mm @@ -71,10 +71,12 @@ @implementation RCTFileReaderModule } } -- (std::shared_ptr)getTurboModuleWithJsInvoker: - (std::shared_ptr)jsInvoker +- (std::shared_ptr) + getTurboModuleWithJsInvoker:(std::shared_ptr)jsInvoker + nativeInvoker:(std::shared_ptr)nativeInvoker + perfLogger:(id)perfLogger { - return std::make_shared(self, jsInvoker); + return std::make_shared(self, jsInvoker, nativeInvoker, perfLogger); } @end diff --git a/Libraries/Blob/React-RCTBlob.podspec b/Libraries/Blob/React-RCTBlob.podspec index 8b295657043a94..f13d6b5a403d42 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 = '2018.10.22.00' +folly_version = '2020.01.13.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 = "http://facebook.github.io/react-native/" + s.homepage = "https://reactnative.dev/" s.license = package["license"] s.author = "Facebook, Inc. and its affiliates" - s.platforms = { :ios => "9.0", :tvos => "9.2", :osx => "10.13" } # TODO(macOS GH#214) + 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.source = source s.source_files = "*.{m,mm}" @@ -41,6 +41,7 @@ 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 106d94d8475f07..279ca7218c589b 100644 --- a/Libraries/CameraRoll/RCTCameraRollManager.mm +++ b/Libraries/CameraRoll/RCTCameraRollManager.mm @@ -8,7 +8,6 @@ #import "RCTCameraRollManager.h" #import -#import #import #import // TODO(macOS ISS#2323203) #import @@ -356,9 +355,12 @@ static void checkPhotoLibraryConfig() #endif } -- (std::shared_ptr)getTurboModuleWithJsInvoker:(std::shared_ptr)jsInvoker +- (std::shared_ptr) + getTurboModuleWithJsInvoker:(std::shared_ptr)jsInvoker + nativeInvoker:(std::shared_ptr)nativeInvoker + perfLogger:(id)perfLogger { - return std::make_shared(self, jsInvoker); + return std::make_shared(self, jsInvoker, nativeInvoker, perfLogger); } @end diff --git a/Libraries/CameraRoll/RCTImagePickerManager.mm b/Libraries/CameraRoll/RCTImagePickerManager.mm index 5180a1365bdc63..5319a856c9ceaf 100644 --- a/Libraries/CameraRoll/RCTImagePickerManager.mm +++ b/Libraries/CameraRoll/RCTImagePickerManager.mm @@ -236,6 +236,9 @@ - (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) { @@ -246,9 +249,12 @@ - (void)cameraChanged:(NSNotification *)notification } } -- (std::shared_ptr)getTurboModuleWithJsInvoker:(std::shared_ptr)jsInvoker +- (std::shared_ptr) + getTurboModuleWithJsInvoker:(std::shared_ptr)jsInvoker + nativeInvoker:(std::shared_ptr)nativeInvoker + perfLogger:(id)perfLogger { - return std::make_shared(self, jsInvoker); + return std::make_shared(self, jsInvoker, nativeInvoker, perfLogger); } @end diff --git a/Libraries/Components/AccessibilityInfo/AccessibilityInfo.android.js b/Libraries/Components/AccessibilityInfo/AccessibilityInfo.android.js index 1840dfce692a0d..9a99eb6fb6bae9 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 http://facebook.github.io/react-native/docs/accessibilityinfo.html + * See https://reactnative.dev/docs/accessibilityinfo.html */ const AccessibilityInfo = { @@ -93,7 +93,7 @@ const AccessibilityInfo = { */ get fetch(): () => Promise { console.warn( - 'AccessibilityInfo.fetch is deprecated, call Accessibility.isScreenReaderEnabled instead', + 'AccessibilityInfo.fetch is deprecated, call AccessibilityInfo.isScreenReaderEnabled instead', ); return this.isScreenReaderEnabled; }, @@ -138,7 +138,7 @@ const AccessibilityInfo = { /** * Set accessibility focus to a react component. * - * See http://facebook.github.io/react-native/docs/accessibilityinfo.html#setaccessibilityfocus + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/accessibilityinfo.html#announceforaccessibility + * See https://reactnative.dev/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 4627b70d2ae003..9e721a776b75cc 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 http://facebook.github.io/react-native/docs/accessibilityinfo.html + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/accessibilityinfo.html#isBoldTextEnabled + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/accessibilityinfo.html#isGrayscaleEnabled + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/accessibilityinfo.html#isInvertColorsEnabled + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/accessibilityinfo.html#isReduceMotionEnabled + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/accessibilityinfo.html#isReduceTransparencyEnabled + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/accessibilityinfo.html#isScreenReaderEnabled + * See https://reactnative.dev/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 Accessibility.isScreenReaderEnabled instead', + 'AccessibilityInfo.fetch is deprecated, call AccessibilityInfo.isScreenReaderEnabled instead', ); return this.isScreenReaderEnabled; }, @@ -201,7 +201,7 @@ const AccessibilityInfo = { * - `success`: A boolean indicating whether the announcement was * successfully made. * - * See http://facebook.github.io/react-native/docs/accessibilityinfo.html#addeventlistener + * See https://reactnative.dev/docs/accessibilityinfo.html#addeventlistener */ addEventListener: function( eventName: ChangeEventName, @@ -231,7 +231,7 @@ const AccessibilityInfo = { /** * Set accessibility focus to a react component. * - * See http://facebook.github.io/react-native/docs/accessibilityinfo.html#setaccessibilityfocus + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/accessibilityinfo.html#announceforaccessibility + * See https://reactnative.dev/docs/accessibilityinfo.html#announceforaccessibility */ announceForAccessibility: function(announcement: string): void { if (NativeAccessibilityManager) { @@ -253,7 +253,7 @@ const AccessibilityInfo = { /** * Remove an event handler. * - * See http://facebook.github.io/react-native/docs/accessibilityinfo.html#removeeventlistener + * See https://reactnative.dev/docs/accessibilityinfo.html#removeeventlistener */ removeEventListener: function( eventName: ChangeEventName, diff --git a/Libraries/Components/ActivityIndicator/ActivityIndicator.js b/Libraries/Components/ActivityIndicator/ActivityIndicator.js index 98c3c5313ebf29..9d0df8f0a739e7 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 {NativeOrDynamicColorType} from '../../StyleSheet/NativeOrDynamicColorType'; // ]TODO(macOS ISS#2323203) +import type {ColorValue} from '../../StyleSheet/StyleSheetTypes'; const PlatformActivityIndicator = Platform.OS === 'android' @@ -31,7 +31,7 @@ type IOSProps = $ReadOnly<{| /** * Whether the indicator should hide when not animating (true by default). * - * See http://facebook.github.io/react-native/docs/activityindicator.html#hideswhenstopped + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/activityindicator.html#animating + * See https://reactnative.dev/docs/activityindicator.html#animating */ animating?: ?boolean, /** * The foreground color of the spinner (default is gray). * - * See http://facebook.github.io/react-native/docs/activityindicator.html#color + * See https://reactnative.dev/docs/activityindicator.html#color */ - color?: ?(string | NativeOrDynamicColorType), // TODO(macOS ISS#2323203) + color?: ?ColorValue, /** * Size of the indicator (default is 'small'). * Passing a number to the size prop is only supported on Android. * - * See http://facebook.github.io/react-native/docs/activityindicator.html#size + * See https://reactnative.dev/docs/activityindicator.html#size */ size?: ?IndicatorSize, |}>; @@ -65,7 +65,7 @@ type Props = $ReadOnly<{| /** * Displays a circular loading indicator. * - * See http://facebook.github.io/react-native/docs/activityindicator.html + * See https://reactnative.dev/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 a91460f31fed94..37898d2607ae04 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 http://facebook.github.io/react-native/docs/activityindicator.html#hideswhenstopped + * See https://reactnative.dev/docs/activityindicator.html#hideswhenstopped */ hidesWhenStopped?: WithDefault, /** * Whether to show the indicator (true, the default) or hide it (false). * - * See http://facebook.github.io/react-native/docs/activityindicator.html#animating + * See https://reactnative.dev/docs/activityindicator.html#animating */ animating?: WithDefault, /** * The foreground color of the spinner (default is gray). * - * See http://facebook.github.io/react-native/docs/activityindicator.html#color + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/activityindicator.html#size + * See https://reactnative.dev/docs/activityindicator.html#size */ size?: WithDefault<'small' | 'large', 'small'>, |}>; diff --git a/Libraries/Components/Button.js b/Libraries/Components/Button.js index 3293d9a404c32d..73d32d1285fab0 100644 --- a/Libraries/Components/Button.js +++ b/Libraries/Components/Button.js @@ -22,6 +22,7 @@ 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<{| /** @@ -42,7 +43,7 @@ type ButtonProps = $ReadOnly<{| /** * Color of the text (iOS), or background color of the button (Android) */ - color?: ?string, + color?: ?ColorValue, /** * TV preferred focus (see documentation for the View component). diff --git a/Libraries/Components/CheckBox/AndroidCheckBoxNativeComponent.js b/Libraries/Components/CheckBox/AndroidCheckBoxNativeComponent.js index 29fd1d954a8d6a..2afb9892690d05 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 {NativeOrDynamicColorType} from '../../StyleSheet/NativeOrDynamicColorType'; // TODO(macOS ISS#2323203) +import type {ProcessedColorValue} from '../../StyleSheet/processColor'; type CheckBoxEvent = SyntheticEvent< $ReadOnly<{| @@ -50,8 +50,8 @@ type NativeProps = $ReadOnly<{| enabled?: boolean, tintColors: | {| - true: ?(number | NativeOrDynamicColorType), // TODO(macOS ISS#2323203) - false: ?(number | NativeOrDynamicColorType), // TODO(macOS ISS#2323203) + true: ?ProcessedColorValue, + false: ?ProcessedColorValue, |} | typeof undefined, |}>; diff --git a/Libraries/Components/CheckBox/CheckBox.android.js b/Libraries/Components/CheckBox/CheckBox.android.js index b953fdc2a60ead..aed9cd9eb389c4 100644 --- a/Libraries/Components/CheckBox/CheckBox.android.js +++ b/Libraries/Components/CheckBox/CheckBox.android.js @@ -12,12 +12,15 @@ 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 from './AndroidCheckBoxNativeComponent'; +import AndroidCheckBoxNativeComponent, { + Commands as AndroidCheckBoxCommands, +} from './AndroidCheckBoxNativeComponent'; import type {ViewProps} from '../View/ViewPropTypes'; import type {SyntheticEvent} from '../../Types/CoreEventTypes'; @@ -141,7 +144,7 @@ class CheckBox extends React.Component { _onChange = (event: CheckBoxEvent) => { const value = this.props.value ?? false; - nullthrows(this._nativeRef).setNativeProps({value: value}); + AndroidCheckBoxCommands.setNativeValue(nullthrows(this._nativeRef), 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); @@ -150,12 +153,26 @@ class CheckBox extends React.Component { }; _getTintColors(tintColors) { - return tintColors - ? { - true: processColor(tintColors.true), - false: processColor(tintColors.false), - } - : undefined; + 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; + } } render() { diff --git a/Libraries/Components/DatePicker/RCTDatePickerNativeComponent.js b/Libraries/Components/DatePicker/RCTDatePickerNativeComponent.js index d4690e86945b43..b569ae2bea5515 100644 --- a/Libraries/Components/DatePicker/RCTDatePickerNativeComponent.js +++ b/Libraries/Components/DatePicker/RCTDatePickerNativeComponent.js @@ -11,7 +11,6 @@ '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 04ccdb8d78d061..0d6de69389714e 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 {NativeComponent} from '../../Renderer/shims/ReactNative'; +import type {HostComponent} from '../../Renderer/shims/ReactNativeTypes'; type Event = SyntheticEvent< $ReadOnly<{| @@ -34,7 +34,7 @@ type NativeProps = $ReadOnly<{| pickerStyle?: ?['textfield-stepper', 'clock-calendar', 'textfield'], timeZoneOffsetInMinutes?: ?number, |}>; -type RCTDatePickerNativeType = Class>; +type RCTDatePickerNativeType = HostComponent; module.exports = ((requireNativeComponent( 'RCTDatePicker', diff --git a/Libraries/Components/DrawerAndroid/DrawerLayoutAndroid.android.js b/Libraries/Components/DrawerAndroid/DrawerLayoutAndroid.android.js index b09f2fc8e8dd38..3758c669fd1de6 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; + Platform.Version >= 21 && this.props.statusBarBackgroundColor != null; const drawerViewWrapper = ( ; type PickerItemSelectEvent = $ReadOnly<{| @@ -41,6 +41,7 @@ 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 e557859c322c2e..bf0b9e9ead63ec 100644 --- a/Libraries/Components/Picker/AndroidDropdownPickerNativeComponent.js +++ b/Libraries/Components/Picker/AndroidDropdownPickerNativeComponent.js @@ -14,7 +14,6 @@ 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, @@ -24,11 +23,12 @@ 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?: ?Int32 | ?NativeOrDynamicColorType, // TODO(macOS ISS#2323203) + color?: ?ProcessedColorValue, |}>; type PickerItemSelectEvent = $ReadOnly<{| @@ -41,6 +41,7 @@ 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 9547b2850632f9..edac8099e960a1 100644 --- a/Libraries/Components/Picker/Picker.js +++ b/Libraries/Components/Picker/Picker.js @@ -96,6 +96,12 @@ 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 @@ -106,6 +112,10 @@ 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 4fddefb8014887..a47d29bd5ec6a7 100644 --- a/Libraries/Components/Picker/PickerAndroid.android.js +++ b/Libraries/Components/Picker/PickerAndroid.android.js @@ -10,12 +10,18 @@ 'use strict'; -import AndroidDropdownPickerNativeComponent from './AndroidDropdownPickerNativeComponent'; -import AndroidDialogPickerNativeComponent from './AndroidDialogPickerNativeComponent'; +import AndroidDropdownPickerNativeComponent, { + Commands as AndroidDropdownPickerCommands, +} from './AndroidDropdownPickerNativeComponent'; +import AndroidDialogPickerNativeComponent, { + Commands as AndroidDialogPickerCommands, +} 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'; @@ -31,6 +37,7 @@ type Props = $ReadOnly<{| accessibilityLabel?: ?Stringish, children?: React.Node, style?: ?TextStyleProp, + backgroundColor?: ?ColorValue, selectedValue?: ?PickerItemValue, enabled?: ?boolean, mode?: ?('dialog' | 'dropdown'), @@ -57,8 +64,13 @@ 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 : processColor(color), + color: color == null ? null : processedColor, label, }; }); @@ -83,13 +95,22 @@ function PickerAndroid(props: Props): React.Node { onValueChange(null, position); } } - const {current} = pickerRef; if (current != null && position !== selected) { - current.setNativeProps({selected}); + const Commands = + props.mode === 'dropdown' + ? AndroidDropdownPickerCommands + : AndroidDialogPickerCommands; + Commands.setNativeSelectedPosition(current, selected); } }, - [props.children, props.onValueChange, props.selectedValue, selected], + [ + props.children, + props.onValueChange, + props.selectedValue, + props.mode, + selected, + ], ); const rootProps = { @@ -104,6 +125,7 @@ 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 90296128e6b279..9cdacdf3c86eac 100644 --- a/Libraries/Components/Picker/PickerIOS.ios.js +++ b/Libraries/Components/Picker/PickerIOS.ios.js @@ -16,6 +16,8 @@ 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, { @@ -23,9 +25,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<{| @@ -37,7 +39,7 @@ type PickerIOSChangeEvent = SyntheticEvent< type RCTPickerIOSItemType = $ReadOnly<{| label: ?Label, value: ?(number | string), - textColor: ?(number | NativeOrDynamicColorType), // TODO(macOS ISS#2323203) + textColor: ?ProcessedColorValue, |}>; type Label = Stringish | number; @@ -49,6 +51,7 @@ type Props = $ReadOnly<{| onChange?: ?(event: PickerIOSChangeEvent) => mixed, onValueChange?: ?(itemValue: string | number, itemIndex: number) => mixed, selectedValue: ?(number | string), + accessibilityLabel?: ?string, |}>; type State = {| @@ -86,10 +89,15 @@ 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: processColor(child.props.color), + textColor: processedTextColor, }); }); return {selectedIndex, items}; @@ -107,6 +115,7 @@ 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 ab95ab8aa81a3a..ca42471b6025ce 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: ?(number | NativeOrDynamicColorType), // TODO(macOS ISS#2323203) + textColor: ?ProcessedColorValue, |}>; type Label = Stringish | number; @@ -40,6 +40,7 @@ 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 new file mode 100644 index 00000000000000..c35c9e3337a6d3 --- /dev/null +++ b/Libraries/Components/Pressable/Pressable.js @@ -0,0 +1,240 @@ +/** + * 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 new file mode 100644 index 00000000000000..a8c5af535e8518 --- /dev/null +++ b/Libraries/Components/Pressable/__tests__/Pressable-test.js @@ -0,0 +1,34 @@ +/** + * 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 new file mode 100644 index 00000000000000..5c82f9ab1c7e67 --- /dev/null +++ b/Libraries/Components/Pressable/__tests__/__snapshots__/Pressable-test.js.snap @@ -0,0 +1,49 @@ +// 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 new file mode 100644 index 00000000000000..44972fb860f669 --- /dev/null +++ b/Libraries/Components/Pressable/useAndroidRippleForView.js @@ -0,0 +1,105 @@ +/** + * 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 a2651088bbdc39..7b10a0521522f1 100644 --- a/Libraries/Components/ProgressBarAndroid/ProgressBarAndroid.android.js +++ b/Libraries/Components/ProgressBarAndroid/ProgressBarAndroid.android.js @@ -15,6 +15,7 @@ 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, @@ -49,7 +50,7 @@ export type ProgressBarAndroidProps = $ReadOnly<{| /** * Color of the progress bar. */ - color?: ?string, + color?: ?ColorValue, /** * 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 553a3a46ba0603..8134b8a486fd7e 100644 --- a/Libraries/Components/RefreshControl/PullToRefreshViewNativeComponent.js +++ b/Libraries/Components/RefreshControl/PullToRefreshViewNativeComponent.js @@ -61,4 +61,5 @@ 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 43ebf012308822..f3ffa4980d4fe3 100644 --- a/Libraries/Components/RefreshControl/RefreshControl.js +++ b/Libraries/Components/RefreshControl/RefreshControl.js @@ -15,8 +15,12 @@ const React = require('react'); import type {ColorValue} from '../../StyleSheet/StyleSheetTypes'; import type {ViewProps} from '../View/ViewPropTypes'; -import AndroidSwipeRefreshLayoutNativeComponent from './AndroidSwipeRefreshLayoutNativeComponent'; -import PullToRefreshViewNativeComponent from './PullToRefreshViewNativeComponent'; +import AndroidSwipeRefreshLayoutNativeComponent, { + Commands as AndroidSwipeRefreshLayoutCommands, +} from './AndroidSwipeRefreshLayoutNativeComponent'; +import PullToRefreshViewNativeComponent, { + Commands as PullToRefreshCommands, +} from './PullToRefreshViewNativeComponent'; let RefreshLayoutConsts: any; if (Platform.OS === 'android') { @@ -79,7 +83,7 @@ export type RefreshControlProps = $ReadOnly<{| /** * Called when the view starts refreshing. */ - onRefresh?: ?() => void, + onRefresh?: ?() => void | Promise, /** * Whether the view should be indicating an active refresh. @@ -135,7 +139,10 @@ export type RefreshControlProps = $ReadOnly<{| class RefreshControl extends React.Component { static SIZE: any = RefreshLayoutConsts.SIZE; - _setNativePropsOnRef: ?({refreshing: boolean, ...}) => void; + _nativeRef: ?React.ElementRef< + | typeof PullToRefreshViewNativeComponent + | typeof AndroidSwipeRefreshLayoutNativeComponent, + >; _lastNativeRefreshing = false; componentDidMount() { @@ -150,18 +157,24 @@ class RefreshControl extends React.Component { this._lastNativeRefreshing = this.props.refreshing; } else if ( this.props.refreshing !== this._lastNativeRefreshing && - this._setNativePropsOnRef + this._nativeRef ) { - this._setNativePropsOnRef({ - refreshing: this.props.refreshing, - }); + if (Platform.OS === 'android') { + AndroidSwipeRefreshLayoutCommands.setNativeRefreshing( + this._nativeRef, + this.props.refreshing, + ); + } else { + PullToRefreshCommands.setNativeRefreshing( + this._nativeRef, + 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, @@ -174,7 +187,7 @@ class RefreshControl extends React.Component { return ( ); @@ -183,7 +196,7 @@ class RefreshControl extends React.Component { return ( ); @@ -199,6 +212,15 @@ 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 fe8652ca65c016..a520d17d2875fd 100644 --- a/Libraries/Components/ScrollResponder.js +++ b/Libraries/Components/ScrollResponder.js @@ -183,12 +183,12 @@ const ScrollResponderMixin = { return false; } - const currentlyFocusedTextInput = TextInputState.currentlyFocusedField(); + const currentlyFocusedInput = TextInputState.currentlyFocusedInput(); if ( this.props.keyboardShouldPersistTaps === 'handled' && - currentlyFocusedTextInput != null && - ReactNative.findNodeHandle(e.target) !== currentlyFocusedTextInput + currentlyFocusedInput != null && + e.target !== currentlyFocusedInput ) { return true; } @@ -224,17 +224,26 @@ 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.currentlyFocusedField(); + const currentlyFocusedTextInput = TextInputState.currentlyFocusedInput(); const {keyboardShouldPersistTaps} = this.props; const keyboardNeverPersistTaps = !keyboardShouldPersistTaps || keyboardShouldPersistTaps === 'never'; - const reactTag = ReactNative.findNodeHandle(e.target); + 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; + } + if ( keyboardNeverPersistTaps && currentlyFocusedTextInput != null && - reactTag && - !TextInputState.isTextInput(reactTag) + e.target != null && + !TextInputState.isTextInput(e.target) ) { return true; } @@ -300,14 +309,24 @@ 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.currentlyFocusedField(); + const currentlyFocusedTextInput = TextInputState.currentlyFocusedInput(); if ( this.props.keyboardShouldPersistTaps !== true && this.props.keyboardShouldPersistTaps !== 'always' && currentlyFocusedTextInput != null && - ReactNative.findNodeHandle(e.target) !== currentlyFocusedTextInput && + e.target !== currentlyFocusedTextInput && !this.state.observedScrollSinceBecomingResponder && !this.state.becameResponderWhileAnimating ) { @@ -570,10 +589,7 @@ const ScrollResponderMixin = { * down to make it meet the keyboard's top. Default is false. */ scrollResponderScrollNativeHandleToKeyboard: function( - nodeHandle: - | number - | React.ElementRef> - | React.ElementRef>>, + nodeHandle: number | React.ElementRef>, additionalOffset?: number, preventNegativeScrollOffset?: boolean, ) { diff --git a/Libraries/Components/ScrollView/ScrollView.js b/Libraries/Components/ScrollView/ScrollView.js index dc4cfa04ea7a2b..fe43061b80826a 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,25 +63,31 @@ if (Platform.OS === 'android') { ) { RCTScrollView = ScrollViewNativeComponent; RCTScrollContentView = ScrollContentViewNativeComponent; -} else { - RCTScrollView = requireNativeComponent('RCTScrollView'); - RCTScrollContentView = requireNativeComponent('RCTScrollContentView'); } -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. +// Public methods for ScrollView +export type ScrollViewImperativeMethods = $ReadOnly<{| + getScrollResponder: $PropertyType, getScrollableNode: $PropertyType, getInnerViewNode: $PropertyType, getInnerViewRef: $PropertyType, getNativeScrollRef: $PropertyType, - setNativeProps: $PropertyType, scrollTo: $PropertyType, + scrollToEnd: $PropertyType, flashScrollIndicators: $PropertyType, - ...typeof ScrollResponder.Mixin, - ... -}; + + // ScrollResponder.Mixin public methods + scrollResponderZoomTo: $PropertyType< + typeof ScrollResponder.Mixin, + 'scrollResponderZoomTo', + >, + scrollResponderScrollNativeHandleToKeyboard: $PropertyType< + typeof ScrollResponder.Mixin, + 'scrollResponderScrollNativeHandleToKeyboard', + >, +|}>; + +export type ScrollResponderType = ScrollViewImperativeMethods; type IOSProps = $ReadOnly<{| /** @@ -418,8 +424,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 horizontal pagination when the page is less than the width of - * the ScrollView. The default value is false. + * 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. */ disableIntervalMomentum?: ?boolean, /** @@ -596,6 +602,19 @@ 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 = {| @@ -619,11 +638,14 @@ function createScrollResponder( } type ContextType = {|horizontal: boolean|} | null; -const Context = React.createContext(null); +const Context: React.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 @@ -641,7 +663,7 @@ const standardVerticalContext: ContextType = Object.freeze({horizontal: false}); * view from becoming the responder. * * - * `` vs [``](/react-native/docs/flatlist.html) - which one to use? + * `` vs [``](https://reactnative.dev/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. @@ -733,11 +755,9 @@ class ScrollView extends React.Component { UNSAFE_componentWillMount() { this._scrollResponder.UNSAFE_componentWillMount(); this._scrollAnimatedValue = new AnimatedImplementation.Value( - this.props.contentOffset ? this.props.contentOffset.y : 0, - ); - this._scrollAnimatedValue.setOffset( - this.props.contentInset ? this.props.contentInset.top || 0 : 0, + this.props.contentOffset?.y ?? 0, ); + this._scrollAnimatedValue.setOffset(this.props.contentInset?.top ?? 0); this._stickyHeaderRefs = new Map(); this._headerLayoutYs = new Map(); } @@ -769,9 +789,37 @@ class ScrollView extends React.Component { } } - setNativeProps(props: {[key: string]: mixed, ...}) { - this._scrollViewRef && this._scrollViewRef.setNativeProps(props); - } + _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; + } + }, + }); /** * Returns a reference to the underlying scroll responder, which supports @@ -779,26 +827,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. @@ -811,7 +859,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, @@ -822,7 +870,18 @@ 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( @@ -842,7 +901,7 @@ class ScrollView extends React.Component { y: y || 0, animated: animated !== false, }); - } + }; /** * If this is a vertical ScrollView scrolls to the bottom. @@ -852,22 +911,24 @@ class ScrollView extends React.Component { * `scrollToEnd({animated: false})` for immediate scrolling. * If no options are passed, `animated` defaults to true. */ - scrollToEnd(options?: ?{animated?: boolean, ...}) { + scrollToEnd: (options?: ?{animated?: boolean, ...}) => void = ( + 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() { + flashScrollIndicators: () => void = () => { this._scrollResponder.scrollResponderFlashScrollIndicators(); - } + }; _getKeyForIndex(index, childArray) { const child = childArray[index]; @@ -1051,14 +1112,14 @@ class ScrollView extends React.Component { }; _scrollViewRef: ?React.ElementRef> = null; - _setScrollViewRef = (ref: ?React.ElementRef>) => { - this._scrollViewRef = ref; - }; - _innerViewRef: ?React.ElementRef> = null; - _setInnerViewRef = (ref: ?React.ElementRef>) => { - this._innerViewRef = ref; - }; + _innerViewRef: ?React.ElementRef = null; + _setInnerViewRef = setAndForwardRef({ + getForwardedRef: () => this.props.innerViewRef, + setLocalRef: ref => { + this._innerViewRef = ref; + }, + }); render(): React.Node | React.Element { let ScrollViewClass; @@ -1277,7 +1338,10 @@ 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} @@ -1295,14 +1359,14 @@ class ScrollView extends React.Component { + ref={this._setNativeRef}> {contentContainer} , ); } } return ( - + {contentContainer} ); @@ -1327,4 +1391,22 @@ const styles = StyleSheet.create({ }, }); -module.exports = ScrollView; +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); diff --git a/Libraries/Components/ScrollView/__mocks__/ScrollViewMock.js b/Libraries/Components/ScrollView/__mocks__/ScrollViewMock.js deleted file mode 100644 index 30e8cee004192b..00000000000000 --- a/Libraries/Components/ScrollView/__mocks__/ScrollViewMock.js +++ /dev/null @@ -1,39 +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 - */ - -/* 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 new file mode 100644 index 00000000000000..fb7aa74a55703e --- /dev/null +++ b/Libraries/Components/ScrollView/__tests__/ScrollView-test.js @@ -0,0 +1,51 @@ +/** + * 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 new file mode 100644 index 00000000000000..4e91eb9ba4bf20 --- /dev/null +++ b/Libraries/Components/ScrollView/__tests__/__snapshots__/ScrollView-test.js.snap @@ -0,0 +1,93 @@ +// 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 405ab500acc589..8923582c394f74 100644 --- a/Libraries/Components/SegmentedControlIOS/RCTSegmentedControlNativeComponent.js +++ b/Libraries/Components/SegmentedControlIOS/RCTSegmentedControlNativeComponent.js @@ -33,6 +33,8 @@ 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 aab461272d19ff..a84731b08c8311 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,11 +43,8 @@ class StaticContainer extends React.Component { return !!nextProps.shouldUpdate; } - render(): null | React$Node { - const child = this.props.children; - return child === null || child === false - ? null - : React.Children.only(child); + render(): React.Node { + return this.props.children; } } diff --git a/Libraries/Components/StatusBar/NativeStatusBarManagerAndroid.js b/Libraries/Components/StatusBar/NativeStatusBarManagerAndroid.js index bff7570477c502..b04ef0ff552604 100644 --- a/Libraries/Components/StatusBar/NativeStatusBarManagerAndroid.js +++ b/Libraries/Components/StatusBar/NativeStatusBarManagerAndroid.js @@ -12,17 +12,14 @@ import type {TurboModule} from '../../TurboModule/RCTExport'; import * as TurboModuleRegistry from '../../TurboModule/TurboModuleRegistry'; -import type {NativeOrDynamicColorType} from '../../StyleSheet/NativeOrDynamicColorType'; // TODO(macOS ISS#2323203) +import type {ProcessedColorValue} from '../../StyleSheet/processColor'; // TODO(macOS ISS#2323203) export interface Spec extends TurboModule { +getConstants: () => {| +HEIGHT: number, +DEFAULT_BACKGROUND_COLOR: number, |}; - +setColor: ( - color: number | NativeOrDynamicColorType, - animated: boolean, - ) => void; // TODO(macOS ISS#2323203) + +setColor: (color: ProcessedColorValue, 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 e994f9fd5f00b6..6c588584e29a91 100644 --- a/Libraries/Components/StatusBar/StatusBar.js +++ b/Libraries/Components/StatusBar/StatusBar.js @@ -13,11 +13,12 @@ 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 @@ -62,7 +63,7 @@ type AndroidProps = $ReadOnly<{| * The background color of the status bar. * @platform android */ - backgroundColor?: ?ColorValue, // TODO(macOS ISS#2323203) + backgroundColor?: ?ColorValue, /** * If the status bar is translucent. * When translucent is set to true, the app will draw under the status bar. @@ -323,6 +324,10 @@ class StatusBar extends React.Component { ); return; } + invariant( + typeof processedColor === 'number', + 'Unexpected color given for StatusBar.setBackgroundColor', + ); NativeStatusBarManagerAndroid.setColor(processedColor, animated); } @@ -456,31 +461,25 @@ class StatusBar extends React.Component { ); } } else if (Platform.OS === 'android') { - 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, + //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 (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 b5adfc8c5b050f..eddc96080e8632 100644 --- a/Libraries/Components/Switch/AndroidSwitchNativeComponent.js +++ b/Libraries/Components/Switch/AndroidSwitchNativeComponent.js @@ -11,7 +11,6 @@ 'use strict'; import * as React from 'react'; -import type {NativeOrDynamicColorType} from '../../StyleSheet/NativeOrDynamicColorType'; // TODO(macOS ISS#2323203) import type { WithDefault, @@ -22,7 +21,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 {ColorValue} from '../../StyleSheet/StyleSheetTypes'; +import type {ProcessedColorValue} from '../../StyleSheet/processColor'; // TODO(macOS ISS#2323203) import type {ViewProps} from '../View/ViewPropTypes'; type SwitchChangeEvent = $ReadOnly<{| @@ -35,13 +34,13 @@ type NativeProps = $ReadOnly<{| // Props disabled?: WithDefault, enabled?: WithDefault, - thumbColor?: ?(string | NativeOrDynamicColorType), // TODO(macOS ISS#2323203) - trackColorForFalse?: ?(string | NativeOrDynamicColorType), // TODO(macOS ISS#2323203) - trackColorForTrue?: ?(string | NativeOrDynamicColorType), // TODO(macOS ISS#2323203) + thumbColor?: ?(string | ProcessedColorValue), // TODO(macOS ISS#2323203) + trackColorForFalse?: ?(string | ProcessedColorValue), // TODO(macOS ISS#2323203) + trackColorForTrue?: ?(string | ProcessedColorValue), // TODO(macOS ISS#2323203) value?: WithDefault, on?: WithDefault, - thumbTintColor?: ?(string | NativeOrDynamicColorType), // TODO(macOS ISS#2323203) - trackTintColor?: ?(string | NativeOrDynamicColorType), // TODO(macOS ISS#2323203) + thumbTintColor?: ?(string | ProcessedColorValue), // TODO(macOS ISS#2323203) + trackTintColor?: ?(string | ProcessedColorValue), // TODO(macOS ISS#2323203) // Events onChange?: BubblingEventHandler, diff --git a/Libraries/Components/Switch/Switch.js b/Libraries/Components/Switch/Switch.js index 36fba9446b8d1f..caf191c74a917e 100644 --- a/Libraries/Components/Switch/Switch.js +++ b/Libraries/Components/Switch/Switch.js @@ -11,9 +11,9 @@ 'use strict'; -const Platform = require('../../Utilities/Platform'); -const React = require('react'); -const StyleSheet = require('../../StyleSheet/StyleSheet'); +import Platform from '../../Utilities/Platform'; +import * as React from 'react'; +import StyleSheet from '../../StyleSheet/StyleSheet'; import AndroidSwitchNativeComponent, { Commands as AndroidSwitchCommands, @@ -113,48 +113,18 @@ class Switch extends React.Component { ...props } = this.props; - // 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.', - ); - } - } + const trackColorForFalse = trackColor?.false; + const trackColorForTrue = trackColor?.true; 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 ( @@ -172,7 +142,7 @@ class Switch extends React.Component { const platformProps = { disabled, - onTintColor: _trackColorForTrue, + onTintColor: trackColorForTrue, style: StyleSheet.compose( {height: 31, width: 51}, StyleSheet.compose( @@ -185,8 +155,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 c1916e10839574..4e1ced169fb2de 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 | NativeOrDynamicColorType), // TODO(macOS ISS#2323203) - onTintColor?: ?(ColorValue | NativeOrDynamicColorType), // TODO(macOS ISS#2323203) - thumbTintColor?: ?(ColorValue | NativeOrDynamicColorType), // TODO(macOS ISS#2323203) + tintColor?: ?(ColorValue | ProcessedColorValue), // TODO(macOS ISS#2323203) + onTintColor?: ?(ColorValue | ProcessedColorValue), // TODO(macOS ISS#2323203) + thumbTintColor?: ?(ColorValue | ProcessedColorValue), // TODO(macOS ISS#2323203) // Deprecated props - thumbColor?: ?(ColorValue | NativeOrDynamicColorType), // TODO(macOS ISS#2323203) - trackColorForFalse?: ?(ColorValue | NativeOrDynamicColorType), // TODO(macOS ISS#2323203) - trackColorForTrue?: ?(ColorValue | NativeOrDynamicColorType), // TODO(macOS ISS#2323203) + thumbColor?: ?(ColorValue | ProcessedColorValue), // TODO(macOS ISS#2323203) + trackColorForFalse?: ?(ColorValue | ProcessedColorValue), // TODO(macOS ISS#2323203) + trackColorForTrue?: ?(ColorValue | ProcessedColorValue), // TODO(macOS ISS#2323203) // Events onChange?: ?BubblingEventHandler, diff --git a/Libraries/Components/TextInput/AndroidTextInputNativeComponent.js b/Libraries/Components/TextInput/AndroidTextInputNativeComponent.js index c14b13ea10ab21..2ac53e759b825d 100644 --- a/Libraries/Components/TextInput/AndroidTextInputNativeComponent.js +++ b/Libraries/Components/TextInput/AndroidTextInputNativeComponent.js @@ -24,7 +24,10 @@ 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 @@ -538,33 +541,23 @@ export type NativeProps = $ReadOnly<{| type NativeType = HostComponent; -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; -} +type NativeCommands = TextInputNativeCommands; export const Commands: NativeCommands = codegenNativeCommands({ - supportedCommands: [ - 'focus', - 'blur', - 'setMostRecentEventCount', - 'setTextAndSelection', - ], + supportedCommands: ['focus', 'blur', 'setTextAndSelection'], }); -const AndroidTextInputNativeComponent: HostComponent = requireNativeComponent( - 'AndroidTextInput', -); +let AndroidTextInputNativeComponent; +if (global.RN$Bridgeless) { + ReactNativeViewConfigRegistry.register('AndroidTextInput', () => { + return AndroidTextInputViewConfig; + }); + AndroidTextInputNativeComponent = 'AndroidTextInput'; +} else { + AndroidTextInputNativeComponent = requireNativeComponent( + 'AndroidTextInput', + ); +} -export default AndroidTextInputNativeComponent; +// flowlint-next-line unclear-type:off +export default ((AndroidTextInputNativeComponent: any): HostComponent); diff --git a/Libraries/Components/TextInput/AndroidTextInputViewConfig.js b/Libraries/Components/TextInput/AndroidTextInputViewConfig.js new file mode 100644 index 00000000000000..c4a43a773398cb --- /dev/null +++ b/Libraries/Components/TextInput/AndroidTextInputViewConfig.js @@ -0,0 +1,84 @@ +/** + * 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 67d314ca5a6c30..b35920d5bcb23d 100644 --- a/Libraries/Components/TextInput/InputAccessoryView.js +++ b/Libraries/Components/TextInput/InputAccessoryView.js @@ -10,7 +10,6 @@ 'use strict'; -const DeprecatedColorPropType = require('../../DeprecatedPropTypes/DeprecatedColorPropType'); const Platform = require('../../Utilities/Platform'); const React = require('react'); const StyleSheet = require('../../StyleSheet/StyleSheet'); @@ -18,6 +17,7 @@ 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?: ?DeprecatedColorPropType, + backgroundColor?: ?ColorValue, |}>; class InputAccessoryView extends React.Component { diff --git a/Libraries/Components/TextInput/RCTMultilineTextInputNativeComponent.js b/Libraries/Components/TextInput/RCTMultilineTextInputNativeComponent.js new file mode 100644 index 00000000000000..a0dd8841123f6d --- /dev/null +++ b/Libraries/Components/TextInput/RCTMultilineTextInputNativeComponent.js @@ -0,0 +1,32 @@ +/** + * 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 new file mode 100644 index 00000000000000..8a6f85756a6af6 --- /dev/null +++ b/Libraries/Components/TextInput/RCTSingelineTextInputNativeComponent.js @@ -0,0 +1,43 @@ +/** + * 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 new file mode 100644 index 00000000000000..4836323d1a3615 --- /dev/null +++ b/Libraries/Components/TextInput/RCTSinglelineTextInputViewConfig.js @@ -0,0 +1,134 @@ +/** + * 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 dc65b89fd4387e..585738e8105d18 100644 --- a/Libraries/Components/TextInput/TextInput.js +++ b/Libraries/Components/TextInput/TextInput.js @@ -22,7 +22,6 @@ 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'; @@ -31,27 +30,35 @@ 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 RCTMultilineTextInputView; +let AndroidTextInputCommands; let RCTSinglelineTextInputView; +let RCTSinglelineTextInputNativeCommands; +let RCTMultilineTextInputView; +let RCTMultilineTextInputNativeCommands; if (Platform.OS === 'android') { AndroidTextInput = require('./AndroidTextInputNativeComponent').default; + AndroidTextInputCommands = require('./AndroidTextInputNativeComponent') + .Commands; } else if ( Platform.OS === 'ios' || Platform.OS === 'macos' /* TODO(macOS ISS#2323203) */ ) { - RCTMultilineTextInputView = requireNativeComponent( - 'RCTMultilineTextInputView', - ); - RCTSinglelineTextInputView = requireNativeComponent( - 'RCTSinglelineTextInputView', - ); + RCTSinglelineTextInputView = require('./RCTSingelineTextInputNativeComponent') + .default; + RCTSinglelineTextInputNativeCommands = require('./RCTSingelineTextInputNativeComponent') + .Commands; + RCTMultilineTextInputView = require('./RCTMultilineTextInputNativeComponent') + .default; + RCTMultilineTextInputNativeCommands = require('./RCTMultilineTextInputNativeComponent') + .Commands; } export type ChangeEvent = SyntheticEvent< @@ -285,9 +292,19 @@ type IOSProps = $ReadOnly<{| */ textContentType?: ?TextContentType, - PasswordRules?: ?PasswordRules, + /** + * 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, /* + * 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, @@ -704,42 +721,6 @@ 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 @@ -867,7 +848,15 @@ function useFocusOnMount( function InternalTextInput(props: Props): React.Node { const inputRef = useRef>>(null); - const selection: ?Selection = + // 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 = props.selection == null ? null : { @@ -875,10 +864,37 @@ 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 [lastNativeSelection, setLastNativeSelection] = useState( - selection, - ); + 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 + : ''; // 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 @@ -898,23 +914,42 @@ function InternalTextInput(props: Props): React.Node { lastNativeSelection.end !== selection.end) ) { nativeUpdate.selection = selection; - setLastNativeSelection(selection); + setLastNativeSelection({selection, mostRecentEventCount}); } - if (Object.keys(nativeUpdate).length > 0 && inputRef.current) { - inputRef.current.setNativeProps(nativeUpdate); + if (Object.keys(nativeUpdate).length === 0) { + return; } - }, [inputRef, props.value, lastNativeText, selection, lastNativeSelection]); - useFocusOnMount(props.autoFocus, inputRef); + 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, + ]); useEffect(() => { - const tag = ReactNative.findNodeHandle(inputRef.current); - if (tag != null) { - TextInputState.registerInput(tag); + const inputRefValue = inputRef.current; + + if (inputRefValue != null) { + TextInputState.registerInput(inputRefValue); return () => { - TextInputState.unregisterInput(tag); + TextInputState.unregisterInput(inputRefValue); }; } }, [inputRef]); @@ -930,30 +965,25 @@ function InternalTextInput(props: Props): React.Node { function clear(): void { if (inputRef.current != null) { - inputRef.current.setNativeProps({text: ''}); + viewCommands.setTextAndSelection( + inputRef.current, + mostRecentEventCount, + '', + 0, + 0, + ); } } // TODO: Fix this returning true on null === null, when no input is focused function isFocused(): boolean { - return ( - TextInputState.currentlyFocusedField() === - ReactNative.findNodeHandle(inputRef.current) - ); + return TextInputState.currentlyFocusedInput() === 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 => { @@ -996,48 +1026,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) { + if (inputRef.current == null) { // 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) { + if (inputRef.current == null) { // calling `props.onSelectionChange` // may clean up the input itself. Exits here. return; } - setLastNativeSelection(event.nativeEvent.selection); + setLastNativeSelection({ + selection: event.nativeEvent.selection, + mostRecentEventCount, + }); }; const _onFocus = (event: FocusEvent) => { - TextInputState.focusField(ReactNative.findNodeHandle(inputRef.current)); + TextInputState.focusInput(inputRef.current); if (props.onFocus) { props.onFocus(event); } }; const _onBlur = (event: BlurEvent) => { - TextInputState.blurField(ReactNative.findNodeHandle(inputRef.current)); + TextInputState.blurInput(inputRef.current); if (props.onBlur) { props.onBlur(event); } @@ -1076,6 +1106,7 @@ function InternalTextInput(props: Props): React.Node { ref={_setNativeRef} {...props} dataDetectorTypes={props.dataDetectorTypes} + mostRecentEventCount={mostRecentEventCount} onBlur={_onBlur} onChange={_onChange} onContentSizeChange={props.onContentSizeChange} @@ -1085,7 +1116,7 @@ function InternalTextInput(props: Props): React.Node { onSelectionChangeShouldSetResponder={emptyFunctionThatReturnsTrue} selection={selection} style={style} - text={_getText()} + text={text} /> ); } else if (Platform.OS === 'android') { @@ -1111,15 +1142,17 @@ function InternalTextInput(props: Props): React.Node { autoCapitalize={autoCapitalize} children={children} disableFullscreenUI={props.disableFullscreenUI} - mostRecentEventCount={0} + mostRecentEventCount={mostRecentEventCount} 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={_getText()} + text={text} textBreakStrategy={props.textBreakStrategy} /> ); @@ -1170,6 +1203,8 @@ ExportedForwardRef.propTypes = DeprecatedTextInputPropTypes; // $FlowFixMe ExportedForwardRef.State = { + currentlyFocusedInput: TextInputState.currentlyFocusedInput, + currentlyFocusedField: TextInputState.currentlyFocusedField, focusTextInput: TextInputState.focusTextInput, blurTextInput: TextInputState.blurTextInput, @@ -1177,6 +1212,7 @@ 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 new file mode 100644 index 00000000000000..2584b7516c804b --- /dev/null +++ b/Libraries/Components/TextInput/TextInputNativeCommands.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-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 2f68e612a46604..8d16b0ca1c6e0b 100644 --- a/Libraries/Components/TextInput/TextInputState.js +++ b/Libraries/Components/TextInput/TextInputState.js @@ -14,30 +14,62 @@ 'use strict'; +const React = require('react'); const Platform = require('../../Utilities/Platform'); -const UIManager = require('../../ReactNative/UIManager'); +const {findNodeHandle} = require('../../Renderer/shims/ReactNative'); +import {Commands as AndroidTextInputCommands} from '../../Components/TextInput/AndroidTextInputNativeComponent'; +import {Commands as iOSTextInputCommands} from '../../Components/TextInput/RCTSingelineTextInputNativeComponent'; -let currentlyFocusedID: ?number = null; +import type {HostComponent} from '../../Renderer/shims/ReactNativeTypes'; +type ComponentRef = React.ElementRef>; + +let currentlyFocusedInputRef: ?ComponentRef = 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 { - return currentlyFocusedID; + 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; + } } function focusField(textFieldID: ?number): void { - if (currentlyFocusedID !== textFieldID && textFieldID != null) { - currentlyFocusedID = textFieldID; + if (__DEV__) { + console.error('focusField no longer works. Use focusInput'); } + + return; } function blurField(textFieldID: ?number) { - if (currentlyFocusedID === textFieldID && textFieldID != null) { - currentlyFocusedID = null; + if (__DEV__) { + console.error('blurField no longer works. Use blurInput'); } + + return; } /** @@ -45,21 +77,31 @@ function blurField(textFieldID: ?number) { * Focuses the specified text field * noop if the text field was already focused */ -function focusTextInput(textFieldID: ?number) { - if (currentlyFocusedID !== textFieldID && textFieldID != null) { - focusField(textFieldID); +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); if ( Platform.OS === 'ios' || Platform.OS === 'macos' /* TODO(macOS ISS#2323203) */ ) { - UIManager.focus(textFieldID); + // 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); } else if (Platform.OS === 'android') { - UIManager.dispatchViewManagerCommand( - textFieldID, - UIManager.getViewManagerConfig('AndroidTextInput').Commands - .focusTextInput, - null, - ); + AndroidTextInputCommands.focus(textField); } } } @@ -69,38 +111,81 @@ function focusTextInput(textFieldID: ?number) { * Unfocuses the specified text field * noop if it wasn't focused */ -function blurTextInput(textFieldID: ?number) { - if (currentlyFocusedID === textFieldID && textFieldID != null) { - blurField(textFieldID); +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); if ( Platform.OS === 'ios' || Platform.OS === 'macos' /* TODO(macOS ISS#2323203) */ ) { - UIManager.blur(textFieldID); + // 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); } else if (Platform.OS === 'android') { - UIManager.dispatchViewManagerCommand( - textFieldID, - UIManager.getViewManagerConfig('AndroidTextInput').Commands - .blurTextInput, - null, - ); + AndroidTextInputCommands.blur(textField); } } } -function registerInput(textFieldID: number) { - inputs.add(textFieldID); +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.', + ); + } + + return; + } + + inputs.add(textField); } -function unregisterInput(textFieldID: number) { - inputs.delete(textFieldID); +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 isTextInput(textFieldID: number): boolean { - return inputs.has(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; + } + + return inputs.has(textField); } 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 8eb8a477185dc8..38a64dccb6936c 100644 --- a/Libraries/Components/TextInput/__tests__/TextInput-test.js +++ b/Libraries/Components/TextInput/__tests__/TextInput-test.js @@ -87,6 +87,10 @@ 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() @@ -97,13 +101,17 @@ describe('TextInput tests', () => { return 2; }); - const inputTag = ReactNative.findNodeHandle(textInputRef.current); - - TextInput.State.focusTextInput(inputTag); + TextInput.State.focusTextInput(textInputRef.current); expect(textInputRef.current.isFocused()).toBe(true); - expect(TextInput.State.currentlyFocusedField()).toBe(inputTag); - TextInput.State.blurTextInput(inputTag); + 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(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); }); @@ -141,16 +149,20 @@ describe('TextInput tests', () => { const inputTag1 = ReactNative.findNodeHandle(textInputRe1.current); const inputTag2 = ReactNative.findNodeHandle(textInputRe2.current); - TextInput.State.focusTextInput(inputTag1); + TextInput.State.focusTextInput(textInputRe1.current); 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(inputTag2); + TextInput.State.focusTextInput(textInputRe2.current); 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 0f2f841dc5a432..6e14c9f23e84d5 100644 --- a/Libraries/Components/TextInput/__tests__/__snapshots__/TextInput-test.js.snap +++ b/Libraries/Components/TextInput/__tests__/__snapshots__/TextInput-test.js.snap @@ -8,6 +8,7 @@ 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]} @@ -36,6 +37,7 @@ 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 8b827d0810846a..01e51ba766509a 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.js'; +import ReactNative from '../../Renderer/shims/ReactNative'; import type { BlurEvent, FocusEvent, diff --git a/Libraries/Components/Touchable/TouchableBounce.js b/Libraries/Components/Touchable/TouchableBounce.js index 2d24a59fcfa775..af315ce36d60b4 100644 --- a/Libraries/Components/Touchable/TouchableBounce.js +++ b/Libraries/Components/Touchable/TouchableBounce.js @@ -10,11 +10,13 @@ 'use strict'; -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 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 {Animated, Platform} from 'react-native'; import * as React from 'react'; @@ -39,21 +41,20 @@ class TouchableBounce extends React.Component { _tvTouchable: ?TVTouchable; state: State = { - 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, + 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, onBlur: event => { if (Platform.isTV) { this._bounceTo(1, 0.4, 0); @@ -115,12 +116,8 @@ 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, @@ -222,6 +219,10 @@ 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 476a90c41f46fe..5e2f9c0b6f1341 100644 --- a/Libraries/Components/Touchable/TouchableHighlight.js +++ b/Libraries/Components/Touchable/TouchableHighlight.js @@ -10,12 +10,14 @@ 'use strict'; -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 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 Platform from '../../Utilities/Platform'; import View from '../../Components/View/View'; import * as React from 'react'; @@ -159,21 +161,21 @@ class TouchableHighlight extends React.Component { _tvTouchable: ?TVTouchable; state: State = { - 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, + 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, onBlur: event => { if (Platform.isTV) { this._hideUnderlay(); @@ -227,13 +229,8 @@ 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 { @@ -384,6 +381,10 @@ 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 691cce92eaeaeb..2911c785c17d00 100644 --- a/Libraries/Components/Touchable/TouchableNativeFeedback.js +++ b/Libraries/Components/Touchable/TouchableNativeFeedback.js @@ -10,18 +10,22 @@ 'use strict'; -import Pressability from '../../Pressability/Pressability.js'; -import {PressabilityDebugView} from '../../Pressability/PressabilityDebug.js'; -import TVTouchable from './TVTouchable.js'; -import typeof TouchableWithoutFeedback from './TouchableWithoutFeedback.js'; +import Pressability, { + type PressabilityConfig, +} from '../../Pressability/Pressability'; +import {PressabilityDebugView} from '../../Pressability/PressabilityDebug'; +import TVTouchable from './TVTouchable'; +import typeof TouchableWithoutFeedback from './TouchableWithoutFeedback'; 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, @@ -38,11 +42,13 @@ type Props = $ReadOnly<{| attribute: | 'selectableItemBackground' | 'selectableItemBackgroundBorderless', + rippleRadius: ?number, |}> | $ReadOnly<{| type: 'RippleAndroid', color: ?number, borderless: boolean, + rippleRadius: ?number, |}> ), @@ -98,24 +104,32 @@ 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: () => $ReadOnly<{| + static SelectableBackground: ( + rippleRadius: ?number, + ) => $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: () => $ReadOnly<{| + static SelectableBackgroundBorderless: ( + rippleRadius: ?number, + ) => $ReadOnly<{| attribute: 'selectableItemBackgroundBorderless', type: 'ThemeAttrAndroid', - |}> = () => ({ + rippleRadius: ?number, + |}> = (rippleRadius: ?number) => ({ type: 'ThemeAttrAndroid', attribute: 'selectableItemBackgroundBorderless', + rippleRadius, }); /** @@ -126,15 +140,25 @@ class TouchableNativeFeedback extends React.Component { static Ripple: ( color: string, borderless: boolean, + rippleRadius: ?number, ) => $ReadOnly<{| borderless: boolean, - color: ?(number | NativeOrDynamicColorType) /* TODO(macOS ISS#2323203) */, + color: ?number, + rippleRadius: ?number, type: 'RippleAndroid', - |}> = (color: string, borderless: boolean) => ({ - type: 'RippleAndroid', - color: processColor(color), - borderless, - }); + |}> = (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, + }; + }; /** * Whether `useForeground` is supported. @@ -145,31 +169,21 @@ class TouchableNativeFeedback extends React.Component { _tvTouchable: ?TVTouchable; state: State = { - 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); - } - }, + 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, onPressIn: event => { if (Platform.OS === 'android') { this._dispatchPressedStateChange(true); @@ -192,11 +206,8 @@ 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') { @@ -313,6 +324,10 @@ 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 53d9cab5ed7590..248ddd6ed6848f 100644 --- a/Libraries/Components/Touchable/TouchableOpacity.js +++ b/Libraries/Components/Touchable/TouchableOpacity.js @@ -10,10 +10,12 @@ 'use strict'; -import Pressability from '../../Pressability/Pressability.js'; -import {PressabilityDebugView} from '../../Pressability/PressabilityDebug.js'; -import TVTouchable from './TVTouchable.js'; -import typeof TouchableWithoutFeedback from './TouchableWithoutFeedback.js'; +import Pressability, { + type PressabilityConfig, +} from '../../Pressability/Pressability'; +import {PressabilityDebugView} from '../../Pressability/PressabilityDebug'; +import TVTouchable from './TVTouchable'; +import typeof TouchableWithoutFeedback from './TouchableWithoutFeedback'; 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'; @@ -134,20 +136,18 @@ class TouchableOpacity extends React.Component { state: State = { anim: new Animated.Value(this._getChildStyleOpacityWithDefault()), - 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, + 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, onBlur: event => { if (Platform.isTV) { this._opacityInactive(250); @@ -164,16 +164,8 @@ class TouchableOpacity extends React.Component { 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); - } - }, + onLongPress: this.props.onLongPress, + onPress: this.props.onPress, onPressIn: event => { this._opacityActive( event.dispatchConfig.registrationName === 'onResponderGrant' @@ -190,11 +182,8 @@ class TouchableOpacity extends React.Component { this.props.onPressOut(event); } }, - onResponderTerminationRequest: () => - !this.props.rejectResponderTermination, - onStartShouldSetResponder: () => !this.props.disabled, - }), - }; + }; + } /** * Animate the touchable to a new opacity. @@ -313,6 +302,7 @@ 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 5e3d8216eb79f6..4157b18db2ee97 100755 --- a/Libraries/Components/Touchable/TouchableWithoutFeedback.js +++ b/Libraries/Components/Touchable/TouchableWithoutFeedback.js @@ -10,9 +10,11 @@ 'use strict'; -import Pressability from '../../Pressability/Pressability.js'; -import {PressabilityDebugView} from '../../Pressability/PressabilityDebug.js'; -import TVTouchable from './TVTouchable.js'; +import Pressability, { + type PressabilityConfig, +} from '../../Pressability/Pressability'; +import {PressabilityDebugView} from '../../Pressability/PressabilityDebug'; +import TVTouchable from './TVTouchable'; import type { AccessibilityActionEvent, AccessibilityActionInfo, @@ -118,55 +120,7 @@ class TouchableWithoutFeedback extends React.Component { _tvTouchable: ?TVTouchable; state: State = { - 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, - }), + pressability: new Pressability(createPressabilityConfig(this.props)), }; render(): React.Node { @@ -232,6 +186,10 @@ class TouchableWithoutFeedback extends React.Component { } } + componentDidUpdate(): void { + this.state.pressability.configure(createPressabilityConfig(this.props)); + } + componentWillUnmount(): void { if (Platform.isTV) { if (this._tvTouchable != null) { @@ -242,4 +200,23 @@ 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 1d17f3e3bac1a5..8858f62d5b0be4 100644 --- a/Libraries/Components/View/ReactNativeViewViewConfig.js +++ b/Libraries/Components/View/ReactNativeViewViewConfig.js @@ -11,6 +11,7 @@ 'use strict'; import ReactNativeViewViewConfigAndroid from './ReactNativeViewViewConfigAndroid'; import ReactNativeViewViewConfigMacOS from './ReactNativeViewViewConfigMacOS'; // TODO(macOS ISS#2323203) +import {Platform} from 'react-native'; const ReactNativeViewConfig = { uiViewClassName: 'RCTView', @@ -325,7 +326,9 @@ const ReactNativeViewConfig = { textTransform: true, tintColor: {process: require('../../StyleSheet/processColor')}, top: true, - transform: {diff: require('../../Utilities/differ/matricesDiffer')}, + transform: ((Platform.OS === 'ios' || Platform.OS === 'macos' // TODO(macOS ISS#2323203) + ? {diff: require('../../Utilities/differ/matricesDiffer')} + : {process: require('../../StyleSheet/processTransform')}): any), transformMatrix: true, translateX: true, translateY: true, @@ -335,7 +338,9 @@ const ReactNativeViewConfig = { }, testID: true, top: true, - transform: {diff: require('../../Utilities/differ/matricesDiffer')}, + transform: ((Platform.OS === 'ios' || Platform.OS === 'macos' // TODO(macOS ISS#2323203) + ? {diff: require('../../Utilities/differ/matricesDiffer')} + : {process: require('../../StyleSheet/processTransform')}): any), translateX: true, translateY: true, width: true, diff --git a/Libraries/Components/View/View.js b/Libraries/Components/View/View.js index bd2c26f0e5d7d0..0fd0d938676524 100644 --- a/Libraries/Components/View/View.js +++ b/Libraries/Components/View/View.js @@ -11,7 +11,10 @@ 'use strict'; import type {ViewProps} from './ViewPropTypes'; -import type {ViewNativeComponentType} from './ViewNativeComponent'; + +const React = require('react'); +import ViewNativeComponent from './ViewNativeComponent'; +const TextAncestor = require('../../Text/TextAncestor'); export type Props = ViewProps; @@ -20,7 +23,19 @@ export type Props = ViewProps; * supports layout with flexbox, style, some touch handling, and accessibility * controls. * - * @see http://facebook.github.io/react-native/docs/view.html + * @see https://reactnative.dev/docs/view.html */ -module.exports = (require('./ViewNativeComponent') - .default: ViewNativeComponentType); +const View: React.AbstractComponent< + ViewProps, + React.ElementRef, +> = React.forwardRef((props: ViewProps, forwardedRef) => { + return ( + + + + ); +}); + +View.displayName = 'View'; + +module.exports = View; diff --git a/Libraries/Components/View/ViewNativeComponent.js b/Libraries/Components/View/ViewNativeComponent.js index 568f38f7fda9a3..902414c4eb45e3 100644 --- a/Libraries/Components/View/ViewNativeComponent.js +++ b/Libraries/Components/View/ViewNativeComponent.js @@ -53,8 +53,7 @@ let viewConfig: }, |}; -// Only use the JS view config in DEV -if (__DEV__) { +if (__DEV__ || global.RN$Bridgeless) { // 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 a481193fceb285..395901478ae312 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 http://facebook.github.io/react-native/docs/view.html#onaccessibilitytap + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/view.html#onlayout + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/view.html#onmagictap + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/view.html#onaccessibilityescape + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/view.html#onmoveshouldsetresponder + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/view.html#onMoveShouldsetrespondercapture + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/view.html#onrespondergrant + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/view.html#onrespondermove + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/view.html#onresponderreject + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/view.html#onresponderrelease + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/view.html#onresponderterminate + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/view.html#onresponderterminationrequest + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/view.html#onstartshouldsetresponder + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/view.html#onstartshouldsetrespondercapture + * See https://reactnative.dev/docs/view.html#onstartshouldsetrespondercapture */ onStartShouldSetResponderCapture?: ?(e: PressEvent) => boolean, |}>; @@ -254,6 +254,7 @@ type AndroidDrawableRipple = $ReadOnly<{| type: 'RippleAndroid', color?: ?number, borderless?: ?boolean, + rippleRadius?: ?number, |}>; type AndroidDrawable = AndroidDrawableThemeAttr | AndroidDrawableRipple; @@ -268,7 +269,7 @@ type AndroidViewProps = $ReadOnly<{| * * @platform android * - * See http://facebook.github.io/react-native/docs/view.html#rendertohardwaretextureandroid + * See https://reactnative.dev/docs/view.html#rendertohardwaretextureandroid */ renderToHardwareTextureAndroid?: ?boolean, @@ -280,7 +281,7 @@ type AndroidViewProps = $ReadOnly<{| * * @platform android * - * See http://facebook.github.io/react-native/docs/view.html#collapsable + * See https://reactnative.dev/docs/view.html#collapsable */ collapsable?: ?boolean, @@ -290,7 +291,7 @@ type AndroidViewProps = $ReadOnly<{| * * @platform android * - * See http://facebook.github.io/react-native/docs/view.html#needsoffscreenalphacompositing + * See https://reactnative.dev/docs/view.html#needsoffscreenalphacompositing */ needsOffscreenAlphaCompositing?: ?boolean, @@ -317,7 +318,7 @@ type AndroidViewProps = $ReadOnly<{| * * @platform android * - * See http://facebook.github.io/react-native/docs/view.html#accessibilityliveregion + * See https://reactnative.dev/docs/view.html#accessibilityliveregion */ accessibilityLiveRegion?: ?('none' | 'polite' | 'assertive'), @@ -335,7 +336,7 @@ type AndroidViewProps = $ReadOnly<{| * * @platform android * - * See http://facebook.github.io/react-native/docs/view.html#importantforaccessibility + * See https://reactnative.dev/docs/view.html#importantforaccessibility */ importantForAccessibility?: ?('auto' | 'yes' | 'no' | 'no-hide-descendants'), @@ -413,7 +414,7 @@ type IOSViewProps = $ReadOnly<{| * * @platform ios * - * See http://facebook.github.io/react-native/docs/view.html#accessibilityviewismodal + * See https://reactnative.dev/docs/view.html#accessibilityviewismodal */ accessibilityViewIsModal?: ?boolean, @@ -423,7 +424,7 @@ type IOSViewProps = $ReadOnly<{| * * @platform ios * - * See http://facebook.github.io/react-native/docs/view.html#accessibilityElementsHidden + * See https://reactnative.dev/docs/view.html#accessibilityElementsHidden */ accessibilityElementsHidden?: ?boolean, @@ -441,7 +442,7 @@ type IOSViewProps = $ReadOnly<{| * When `accessible` is `true`, the system will invoke this function when the * user performs the magic tap gesture. * - * See http://facebook.github.io/react-native/docs/view.html#shouldrasterizeios + * See https://reactnative.dev/docs/view.html#shouldrasterizeios */ shouldRasterizeIOS?: ?boolean, |}>; @@ -462,7 +463,7 @@ export type ViewProps = $ReadOnly<{| * When `true`, indicates that the view is an accessibility element. * By default, all the touchable elements are accessible. * - * See http://facebook.github.io/react-native/docs/view.html#accessible + * See https://reactnative.dev/docs/view.html#accessible */ accessible?: ?boolean, @@ -471,7 +472,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 http://facebook.github.io/react-native/docs/view.html#accessibilitylabel + * See https://reactnative.dev/docs/view.html#accessibilitylabel */ accessibilityLabel?: ?Stringish, @@ -481,7 +482,7 @@ export type ViewProps = $ReadOnly<{| * accessibility label. * * - * See http://facebook.github.io/react-native/docs/view.html#accessibilityHint + * See https://reactnative.dev/docs/view.html#accessibilityHint */ accessibilityHint?: ?Stringish, @@ -507,7 +508,7 @@ export type ViewProps = $ReadOnly<{| * * > This disables the 'layout-only view removal' optimization for this view! * - * See http://facebook.github.io/react-native/docs/view.html#testid + * See https://reactnative.dev/docs/view.html#testid */ testID?: ?string, @@ -516,7 +517,7 @@ export type ViewProps = $ReadOnly<{| * * > This disables the 'layout-only view removal' optimization for this view! * - * See http://facebook.github.io/react-native/docs/view.html#nativeid + * See https://reactnative.dev/docs/view.html#nativeid */ nativeID?: ?string, @@ -529,14 +530,14 @@ export type ViewProps = $ReadOnly<{| * > of sibling views always takes precedence if a touch hits two overlapping * > views. * - * See http://facebook.github.io/react-native/docs/view.html#hitslop + * See https://reactnative.dev/docs/view.html#hitslop */ hitSlop?: ?EdgeInsetsProp, /** * Controls whether the `View` can be the target of touch events. * - * See http://facebook.github.io/react-native/docs/view.html#pointerevents + * See https://reactnative.dev/docs/view.html#pointerevents */ pointerEvents?: ?('auto' | 'box-none' | 'box-only' | 'none'), @@ -548,7 +549,7 @@ export type ViewProps = $ReadOnly<{| * subviews must also have `overflow: hidden`, as should the containing view * (or one of its superviews). * - * See http://facebook.github.io/react-native/docs/view.html#removeclippedsubviews + * See https://reactnative.dev/docs/view.html#removeclippedsubviews */ removeClippedSubviews?: ?boolean, diff --git a/Libraries/Core/ExceptionsManager.js b/Libraries/Core/ExceptionsManager.js index d26f824ab5c280..fd6ce28ad6e732 100644 --- a/Libraries/Core/ExceptionsManager.js +++ b/Libraries/Core/ExceptionsManager.js @@ -52,7 +52,11 @@ function preprocessException(data: ExceptionData): ExceptionData { * Handles the developer-visible aspect of errors and exceptions */ let exceptionID = 0; -function reportException(e: ExtendedError, isFatal: boolean) { +function reportException( + e: ExtendedError, + isFatal: boolean, + reportToConsole: boolean, // only true when coming from handleException; the error has not yet been logged +) { const NativeExceptionsManager = require('./NativeExceptionsManager').default; if (NativeExceptionsManager) { const parseErrorStack = require('./Devtools/parseErrorStack'); @@ -64,26 +68,15 @@ function reportException(e: ExtendedError, isFatal: boolean) { 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 && global.__unstable_isLogBoxEnabled === true; + const isHandledByLogBox = e.forceRedbox !== true; const data = preprocessException({ message, @@ -104,6 +97,13 @@ function reportException(e: ExtendedError, isFatal: boolean) { }, }); + 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,6 +134,11 @@ function reportException(e: ExtendedError, isFatal: boolean) { 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); } } @@ -143,6 +148,10 @@ 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 */ @@ -157,21 +166,61 @@ function handleException(e: mixed, isFatal: boolean) { // `throw ''` somewhere in your codebase. error = new SyntheticError(e); } - reportException(error, isFatal); + try { + inExceptionHandler = true; + reportException(error, isFatal, /*reportToConsole*/ true); + } finally { + inExceptionHandler = false; + } } function reactConsoleErrorHandler() { + // bubble up to any original handlers + console._errorOriginal.apply(console, arguments); if (!console.reportErrorsAsExceptions) { - console._errorOriginal.apply(console, arguments); + 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_) return; } if (arguments[0] && arguments[0].stack) { // reportException will console.error this with high enough fidelity. - reportException(arguments[0], /* isFatal */ false); + reportException( + arguments[0], + /* isFatal */ false, + /*reportToConsole*/ false, + ); } else { - console._errorOriginal.apply(console, arguments); - const stringifySafe = require('../Utilities/stringifySafe'); + const stringifySafe = require('../Utilities/stringifySafe').default; const str = Array.prototype.map .call(arguments, value => typeof value === 'string' ? value : stringifySafe(value), @@ -186,7 +235,7 @@ function reactConsoleErrorHandler() { } const error: ExtendedError = new SyntheticError(str); error.name = 'console.error'; - reportException(error, /* isFatal */ false); + reportException(error, /* isFatal */ false, /*reportToConsole*/ false); } } diff --git a/Libraries/Core/InitializeCore.js b/Libraries/Core/InitializeCore.js index 8f12f11b8612db..e00120aa4b48a5 100644 --- a/Libraries/Core/InitializeCore.js +++ b/Libraries/Core/InitializeCore.js @@ -29,6 +29,7 @@ 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 a247a2ad6ca889..d329e2d27bd4cb 100644 --- a/Libraries/Core/ReactFiberErrorDialog.js +++ b/Libraries/Core/ReactFiberErrorDialog.js @@ -9,13 +9,9 @@ */ 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 0c88a4c9abd4fa..bf4b32f41b0ac3 100644 --- a/Libraries/Core/ReactNativeVersion.js +++ b/Libraries/Core/ReactNativeVersion.js @@ -11,7 +11,7 @@ exports.version = { major: 0, - minor: 62, + minor: 63, patch: 2, prerelease: null, }; diff --git a/Libraries/Core/Timers/JSTimers.js b/Libraries/Core/Timers/JSTimers.js index feaeddf89a0c94..4c154db519deb2 100644 --- a/Libraries/Core/Timers/JSTimers.js +++ b/Libraries/Core/Timers/JSTimers.js @@ -113,16 +113,11 @@ function _callTimer(timerID: number, frameTime: number, didTimeout: ?boolean) { } if (__DEV__) { - Systrace.beginEvent('Systrace.callTimer: ' + type); + Systrace.beginEvent(type + ' [invoke]'); } // Clear the metadata - if ( - type === 'setTimeout' || - type === 'setImmediate' || - type === 'requestAnimationFrame' || - type === 'requestIdleCallback' - ) { + if (type !== 'setInterval') { _clearIndex(timerIndex); } @@ -167,21 +162,23 @@ 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 - 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); - } + 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 (__DEV__) { @@ -381,8 +378,7 @@ const JSTimers = { 'Cannot call `callTimers` with an empty list of IDs.', ); - // $FlowFixMe: optionals do not allow assignment from null - errors = null; + errors = (null: ?Array); for (let i = 0; i < timersToCall.length; i++) { _callTimer(timersToCall[i], 0); } @@ -413,10 +409,9 @@ const JSTimers = { return; } - // $FlowFixMe: optionals do not allow assignment from null - errors = null; + errors = (null: ?Array); if (requestIdleCallbacks.length > 0) { - const passIdleCallbacks = requestIdleCallbacks.slice(); + const passIdleCallbacks = requestIdleCallbacks; requestIdleCallbacks = []; for (let i = 0; i < passIdleCallbacks.length; ++i) { @@ -442,7 +437,7 @@ const JSTimers = { * before we hand control back to native. */ callImmediates() { - errors = null; + errors = (null: ?Array); while (_callImmediatesPass()) {} if (errors) { errors.forEach(error => @@ -501,6 +496,7 @@ 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 @@ -512,8 +508,6 @@ if (!NativeTiming) { ExportedJSTimers = JSTimers; } -BatchedBridge.setImmediatesCallback( - ExportedJSTimers.callImmediates.bind(ExportedJSTimers), -); +BatchedBridge.setImmediatesCallback(JSTimers.callImmediates); module.exports = ExportedJSTimers; diff --git a/Libraries/Core/Timers/__tests__/JSTimers-test.js b/Libraries/Core/Timers/__tests__/JSTimers-test.js new file mode 100644 index 00000000000000..baa281f03e6bcd --- /dev/null +++ b/Libraries/Core/Timers/__tests__/JSTimers-test.js @@ -0,0 +1,413 @@ +/** + * 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 a34fc2d06f168b..71e3be3cb94164 100644 --- a/Libraries/Core/__tests__/ExceptionsManager-test.js +++ b/Libraries/Core/__tests__/ExceptionsManager-test.js @@ -137,8 +137,9 @@ describe('ExceptionsManager', () => { message + '\n\n' + 'This error is located at:' + - capturedErrorDefaults.componentStack, - // JS engine omitted here! + capturedErrorDefaults.componentStack + + ', js engine: ' + + jsEngine, ); }); @@ -293,7 +294,8 @@ describe('ExceptionsManager', () => { ); expect(exceptionData.isFatal).toBe(false); expect(mockError.mock.calls[0]).toHaveLength(1); - expect(mockError.mock.calls[0][0]).toBe(formattedMessage); + expect(mockError.mock.calls[0][0]).toBeInstanceOf(Error); + expect(mockError.mock.calls[0][0].toString()).toBe(formattedMessage); }); test('logging a string', () => { @@ -461,6 +463,23 @@ 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 => ({ @@ -509,7 +528,7 @@ describe('ExceptionsManager', () => { expect(nativeReportException).toHaveBeenCalled(); }); - test('prevents decorator recursion', () => { + test('prevents decorator recursion from error handler', () => { const error = new Error('Some error happened'); const decorator = jest.fn().mockImplementation(data => { console.error('Logging an error within the decorator'); @@ -519,11 +538,35 @@ describe('ExceptionsManager', () => { }; }); - ExceptionsManager.installConsoleErrorReporter(); ExceptionsManager.unstable_setExceptionDecorator(decorator); ExceptionsManager.handleException(error, true); - expect(decorator).toHaveBeenCalled(); + 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(nativeReportException).toHaveBeenCalledTimes(2); expect(nativeReportException.mock.calls[0][0].message).toMatch( /Logging an error within the decorator/, @@ -531,6 +574,52 @@ 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 8f6db0ec2f1e2a..d718f3c8355f50 100644 --- a/Libraries/Core/setUpBatchedBridge.js +++ b/Libraries/Core/setUpBatchedBridge.js @@ -10,52 +10,37 @@ 'use strict'; -/** - * 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. - */ +let registerModule; +if (global.RN$Bridgeless && global.RN$registerCallableModule) { + registerModule = global.RN$registerCallableModule; +} else { const BatchedBridge = require('../BatchedBridge/BatchedBridge'); - 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'), - ); + 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'), +); - if (__DEV__ && !global.__RCTProfileIsProfiling) { - BatchedBridge.registerLazyCallableModule('HMRClient', () => - require('../Utilities/HMRClient'), - ); - } else { - BatchedBridge.registerLazyCallableModule('HMRClient', () => - require('../Utilities/HMRClientProdShim'), - ); - } +if (__DEV__ && !global.__RCTProfileIsProfiling) { + registerModule('HMRClient', () => require('../Utilities/HMRClient')); +} else { + registerModule('HMRClient', () => require('../Utilities/HMRClientProdShim')); } diff --git a/Libraries/Core/setUpDeveloperTools.js b/Libraries/Core/setUpDeveloperTools.js index 6fe91a5f0b9a1f..3ee84d8727349d 100644 --- a/Libraries/Core/setUpDeveloperTools.js +++ b/Libraries/Core/setUpDeveloperTools.js @@ -54,6 +54,7 @@ if (__DEV__) { 'trace', 'info', 'warn', + 'error', 'log', 'group', 'groupCollapsed', diff --git a/Libraries/Core/setUpPerformance.js b/Libraries/Core/setUpPerformance.js new file mode 100644 index 00000000000000..6fd0a1e42b8213 --- /dev/null +++ b/Libraries/Core/setUpPerformance.js @@ -0,0 +1,26 @@ +/** + * 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 084b2c7f577ca9..2ba4c5dc6a41b0 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.js'); + const viewConfig = require('../Components/View/ReactNativeViewViewConfig'); reactDevTools.connectToDevTools({ isAppActive, resolveRNStyle: require('../StyleSheet/flattenStyle'), diff --git a/Libraries/DeprecatedPropTypes/DeprecatedTextPropTypes.js b/Libraries/DeprecatedPropTypes/DeprecatedTextPropTypes.js index f053e8e283d6ce..f14635ab3a8cfe 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://facebook.github.io/react-native/docs/text.html#ellipsizemode + * See https://reactnative.dev/docs/text.html#ellipsizemode */ ellipsizeMode: (PropTypes.oneOf([ 'head', @@ -38,13 +38,13 @@ module.exports = { /** * Used to truncate the text with an ellipsis. * - * See https://facebook.github.io/react-native/docs/text.html#numberoflines + * See https://reactnative.dev/docs/text.html#numberoflines */ numberOfLines: PropTypes.number, /** * Set text break strategy on Android. * - * See https://facebook.github.io/react-native/docs/text.html#textbreakstrategy + * See https://reactnative.dev/docs/text.html#textbreakstrategy */ textBreakStrategy: (PropTypes.oneOf([ 'simple', @@ -54,63 +54,63 @@ module.exports = { /** * Invoked on mount and layout changes. * - * See https://facebook.github.io/react-native/docs/text.html#onlayout + * See https://reactnative.dev/docs/text.html#onlayout */ onLayout: PropTypes.func, /** * This function is called on press. * - * See https://facebook.github.io/react-native/docs/text.html#onpress + * See https://reactnative.dev/docs/text.html#onpress */ onPress: PropTypes.func, /** * This function is called on long press. * - * See https://facebook.github.io/react-native/docs/text.html#onlongpress + * See https://reactnative.dev/docs/text.html#onlongpress */ onLongPress: PropTypes.func, /** * Defines how far your touch may move off of the button, before * deactivating the button. * - * See https://facebook.github.io/react-native/docs/text.html#pressretentionoffset + * See https://reactnative.dev/docs/text.html#pressretentionoffset */ pressRetentionOffset: DeprecatedEdgeInsetsPropType, /** * Lets the user select text. * - * See https://facebook.github.io/react-native/docs/text.html#selectable + * See https://reactnative.dev/docs/text.html#selectable */ selectable: PropTypes.bool, /** * The highlight color of the text. * - * See https://facebook.github.io/react-native/docs/text.html#selectioncolor + * See https://reactnative.dev/docs/text.html#selectioncolor */ selectionColor: DeprecatedColorPropType, /** * When `true`, no visual change is made when text is pressed down. * - * See https://facebook.github.io/react-native/docs/text.html#supperhighlighting + * See https://reactnative.dev/docs/text.html#supperhighlighting */ suppressHighlighting: PropTypes.bool, style: stylePropType, /** * Used to locate this view in end-to-end tests. * - * See https://facebook.github.io/react-native/docs/text.html#testid + * See https://reactnative.dev/docs/text.html#testid */ testID: PropTypes.string, /** * Used to locate this view from native code. * - * See https://facebook.github.io/react-native/docs/text.html#nativeid + * See https://reactnative.dev/docs/text.html#nativeid */ nativeID: PropTypes.string, /** * Whether fonts should scale to respect Text Size accessibility settings. * - * See https://facebook.github.io/react-native/docs/text.html#allowfontscaling + * See https://reactnative.dev/docs/text.html#allowfontscaling */ allowFontScaling: PropTypes.bool, /** @@ -124,31 +124,31 @@ module.exports = { /** * Indicates whether the view is an accessibility element. * - * See https://facebook.github.io/react-native/docs/text.html#accessible + * See https://reactnative.dev/docs/text.html#accessible */ accessible: PropTypes.bool, /** * Whether font should be scaled down automatically. * - * See https://facebook.github.io/react-native/docs/text.html#adjustsfontsizetofit + * See https://reactnative.dev/docs/text.html#adjustsfontsizetofit */ adjustsFontSizeToFit: PropTypes.bool, /** * Smallest possible scale a font can reach. * - * See https://facebook.github.io/react-native/docs/text.html#minimumfontscale + * See https://reactnative.dev/docs/text.html#minimumfontscale */ minimumFontScale: PropTypes.number, /** * Specifies the disabled state of the text view for testing purposes. * - * See https://facebook.github.io/react-native/docs/text.html#disabled + * See https://reactnative.dev/docs/text.html#disabled */ disabled: PropTypes.bool, /** * Determines the types of data converted to clickable URLs in text. * - * See https://facebook.github.io/react-native/docs/text.html#dataDetectorType + * See https://reactnative.dev/docs/text.html#dataDetectorType */ dataDetectorType: (PropTypes.oneOf( DataDetectorTypes, diff --git a/Libraries/DeprecatedPropTypes/DeprecatedViewPropTypes.js b/Libraries/DeprecatedPropTypes/DeprecatedViewPropTypes.js index 6268a7f3faedf1..c008361311a7a2 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 http://facebook.github.io/react-native/docs/view.html#accessible + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/view.html#accessibilitylabel + * See https://reactnative.dev/docs/view.html#accessibilitylabel */ accessibilityLabel: PropTypes.node, @@ -45,7 +45,7 @@ module.exports = { * accessibility label. * * - * See http://facebook.github.io/react-native/docs/view.html#accessibilityHint + * See https://reactnative.dev/docs/view.html#accessibilityHint */ accessibilityHint: PropTypes.string, @@ -108,7 +108,7 @@ module.exports = { * * @platform android * - * See http://facebook.github.io/react-native/docs/view.html#accessibilityliveregion + * See https://reactnative.dev/docs/view.html#accessibilityliveregion */ accessibilityLiveRegion: (PropTypes.oneOf([ 'none', @@ -123,7 +123,7 @@ module.exports = { * * @platform android * - * See http://facebook.github.io/react-native/docs/view.html#importantforaccessibility + * See https://reactnative.dev/docs/view.html#importantforaccessibility */ importantForAccessibility: (PropTypes.oneOf([ 'auto', @@ -139,7 +139,7 @@ module.exports = { * * @platform ios * - * See http://facebook.github.io/react-native/docs/view.html#accessibilityviewismodal + * See https://reactnative.dev/docs/view.html#accessibilityviewismodal */ accessibilityViewIsModal: PropTypes.bool, @@ -149,7 +149,7 @@ module.exports = { * * @platform ios * - * See http://facebook.github.io/react-native/docs/view.html#accessibilityElementsHidden + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/view.html#onaccessibilitytap + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/view.html#onmagictap + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/view.html#testid + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/view.html#nativeid + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/view.html#onrespondergrant + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/view.html#onrespondermove + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/view.html#onresponderreject + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/view.html#onresponderrelease + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/view.html#onresponderterminate + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/view.html#onresponderterminationrequest + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/view.html#onstartshouldsetresponder + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/view.html#onstartshouldsetrespondercapture + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/view.html#onmoveshouldsetresponder + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/view.html#onMoveShouldsetrespondercapture + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/view.html#hitslop + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/view.html#onlayout + * See https://reactnative.dev/docs/view.html#onlayout */ onLayout: PropTypes.func, /** * Controls whether the `View` can be the target of touch events. * - * See http://facebook.github.io/react-native/docs/view.html#pointerevents + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/style.html + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/view.html#removeclippedsubviews + * See https://reactnative.dev/docs/view.html#removeclippedsubviews */ removeClippedSubviews: PropTypes.bool, @@ -371,7 +371,7 @@ module.exports = { * * @platform android * - * See http://facebook.github.io/react-native/docs/view.html#rendertohardwaretextureandroid + * See https://reactnative.dev/docs/view.html#rendertohardwaretextureandroid */ renderToHardwareTextureAndroid: PropTypes.bool, @@ -380,7 +380,7 @@ module.exports = { * * @platform ios * - * See http://facebook.github.io/react-native/docs/view.html#shouldrasterizeios + * See https://reactnative.dev/docs/view.html#shouldrasterizeios */ shouldRasterizeIOS: PropTypes.bool, @@ -392,7 +392,7 @@ module.exports = { * * @platform android * - * See http://facebook.github.io/react-native/docs/view.html#collapsable + * See https://reactnative.dev/docs/view.html#collapsable */ collapsable: PropTypes.bool, @@ -402,7 +402,7 @@ module.exports = { * * @platform android * - * See http://facebook.github.io/react-native/docs/view.html#needsoffscreenalphacompositing + * See https://reactnative.dev/docs/view.html#needsoffscreenalphacompositing */ needsOffscreenAlphaCompositing: PropTypes.bool, }; diff --git a/Libraries/Experimental/Incremental.js b/Libraries/Experimental/Incremental.js deleted file mode 100644 index 11174c0c833294..00000000000000 --- a/Libraries/Experimental/Incremental.js +++ /dev/null @@ -1,198 +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 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 6c3c798d9ca06b..ea6c50f49ffb9e 100644 --- a/Libraries/FBLazyVector/BUCK +++ b/Libraries/FBLazyVector/BUCK @@ -3,10 +3,12 @@ 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/isolation/infra.react_native"], + labels = ["supermodule:ios/default/public.react_native.infra"], link_whole = False, visibility = ["PUBLIC"], ) diff --git a/Libraries/FBLazyVector/FBLazyVector.podspec b/Libraries/FBLazyVector/FBLazyVector.podspec index 7fd46967222772..2589deedb00f28 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 = "http://facebook.github.io/react-native/" + s.homepage = "https://reactnative.dev/" s.license = package["license"] s.author = "Facebook, Inc. and its affiliates" - s.platforms = { :ios => "9.0", :tvos => "9.2", :osx => "10.13" } # TODO(macOS ISS#2323203) + s.platforms = { :ios => "10.0", :tvos => "10.0", :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 72cb95bac5beb6..dcef02f8165068 100644 --- a/Libraries/FBReactNativeSpec/BUCK +++ b/Libraries/FBReactNativeSpec/BUCK @@ -10,15 +10,16 @@ fb_apple_library( prefix = "FBReactNativeSpec", ), contacts = ["oncall+react_native@xmail.facebook.com"], + extension_api_only = True, frameworks = [ "Foundation", "UIKit", ], - labels = ["supermodule:ios/isolation/infra.react_native"], + labels = ["supermodule:ios/default/public.react_native.infra"], reexport_all_header_dependencies = True, deps = [ - "fbsource//xplat/js/react-native-github:RCTTypeSafety", - "fbsource//xplat/js/react-native-github/Libraries/RCTRequired:RCTRequired", + "//xplat/js/react-native-github:RCTTypeSafety", + "//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 b31fd71130016a..918eb2f371c314 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 = '2018.10.22.00' +folly_version = '2020.01.13.00' Pod::Spec.new do |s| s.name = "FBReactNativeSpec" s.version = version s.summary = "-" # TODO - s.homepage = "http://facebook.github.io/react-native/" + s.homepage = "https://reactnative.dev/" s.license = package["license"] s.author = "Facebook, Inc. and its affiliates" - s.platforms = { :ios => "9.0", :tvos => "9.2", :osx => "10.13" } # TODO(macOS ISS#2323203) + s.platforms = { :ios => "10.0", :tvos => "10.0", :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 bce1dea35f5dce..1856699aa3f140 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) - : ObjCTurboModule("AccessibilityInfo", instance, jsInvoker) { + NativeAccessibilityInfoSpecJSI::NativeAccessibilityInfoSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("AccessibilityInfo", instance, jsInvoker, nativeInvoker, perfLogger) { methodMap_["isReduceMotionEnabled"] = MethodMetadata {1, __hostFunction_NativeAccessibilityInfoSpecJSI_isReduceMotionEnabled}; @@ -103,8 +103,8 @@ + (RCTManagedPointer *)JS_NativeAccessibilityManager_SpecSetAccessibilityContent } - NativeAccessibilityManagerSpecJSI::NativeAccessibilityManagerSpecJSI(id instance, std::shared_ptr jsInvoker) - : ObjCTurboModule("AccessibilityManager", instance, jsInvoker) { + NativeAccessibilityManagerSpecJSI::NativeAccessibilityManagerSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("AccessibilityManager", instance, jsInvoker, nativeInvoker, perfLogger) { methodMap_["getCurrentBoldTextState"] = MethodMetadata {2, __hostFunction_NativeAccessibilityManagerSpecJSI_getCurrentBoldTextState}; @@ -170,8 +170,8 @@ + (RCTManagedPointer *)JS_NativeActionSheetManager_SpecShowShareActionSheetWithO } - NativeActionSheetManagerSpecJSI::NativeActionSheetManagerSpecJSI(id instance, std::shared_ptr jsInvoker) - : ObjCTurboModule("ActionSheetManager", instance, jsInvoker) { + NativeActionSheetManagerSpecJSI::NativeActionSheetManagerSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("ActionSheetManager", instance, jsInvoker, nativeInvoker, perfLogger) { 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) - : ObjCTurboModule("AlertManager", instance, jsInvoker) { + NativeAlertManagerSpecJSI::NativeAlertManagerSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("AlertManager", instance, jsInvoker, nativeInvoker, perfLogger) { 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) - : ObjCTurboModule("AnimatedModule", instance, jsInvoker) { + NativeAnimatedModuleSpecJSI::NativeAnimatedModuleSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("AnimatedModule", instance, jsInvoker, nativeInvoker, perfLogger) { 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) - : ObjCTurboModule("AnimationsDebugModule", instance, jsInvoker) { + NativeAnimationsDebugModuleSpecJSI::NativeAnimationsDebugModuleSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("AnimationsDebugModule", instance, jsInvoker, nativeInvoker, perfLogger) { methodMap_["startRecordingFps"] = MethodMetadata {0, __hostFunction_NativeAnimationsDebugModuleSpecJSI_startRecordingFps}; @@ -426,8 +426,8 @@ + (RCTManagedPointer *)JS_NativeAppState_SpecGetCurrentAppStateSuccessAppState:( } - NativeAppStateSpecJSI::NativeAppStateSpecJSI(id instance, std::shared_ptr jsInvoker) - : ObjCTurboModule("AppState", instance, jsInvoker) { + NativeAppStateSpecJSI::NativeAppStateSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("AppState", instance, jsInvoker, nativeInvoker, perfLogger) { methodMap_["getCurrentAppState"] = MethodMetadata {2, __hostFunction_NativeAppStateSpecJSI_getCurrentAppState}; @@ -463,8 +463,8 @@ + (RCTManagedPointer *)JS_NativeAppState_SpecGetCurrentAppStateSuccessAppState:( } - NativeAppearanceSpecJSI::NativeAppearanceSpecJSI(id instance, std::shared_ptr jsInvoker) - : ObjCTurboModule("Appearance", instance, jsInvoker) { + NativeAppearanceSpecJSI::NativeAppearanceSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("Appearance", instance, jsInvoker, nativeInvoker, perfLogger) { 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) - : ObjCTurboModule("AsyncStorage", instance, jsInvoker) { + NativeAsyncStorageSpecJSI::NativeAsyncStorageSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("AsyncStorage", instance, jsInvoker, nativeInvoker, perfLogger) { 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) - : ObjCTurboModule("BlobModule", instance, jsInvoker) { + NativeBlobModuleSpecJSI::NativeBlobModuleSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("BlobModule", instance, jsInvoker, nativeInvoker, perfLogger) { 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) - : ObjCTurboModule("BugReporting", instance, jsInvoker) { + NativeBugReportingSpecJSI::NativeBugReportingSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("BugReporting", instance, jsInvoker, nativeInvoker, perfLogger) { 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) - : ObjCTurboModule("CameraRollManager", instance, jsInvoker) { + NativeCameraRollManagerSpecJSI::NativeCameraRollManagerSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("CameraRollManager", instance, jsInvoker, nativeInvoker, perfLogger) { 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) - : ObjCTurboModule("Clipboard", instance, jsInvoker) { + NativeClipboardSpecJSI::NativeClipboardSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("Clipboard", instance, jsInvoker, nativeInvoker, perfLogger) { 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) - : ObjCTurboModule("DatePickerAndroid", instance, jsInvoker) { + NativeDatePickerAndroidSpecJSI::NativeDatePickerAndroidSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("DatePickerAndroid", instance, jsInvoker, nativeInvoker, perfLogger) { 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:color:backgroundColor:), args, count); + return static_cast(turboModule).invokeObjCMethod(rt, VoidKind, "showMessage", @selector(showMessage:withColor:withBackgroundColor:), 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) - : ObjCTurboModule("DevLoadingView", instance, jsInvoker) { + NativeDevLoadingViewSpecJSI::NativeDevLoadingViewSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("DevLoadingView", instance, jsInvoker, nativeInvoker, perfLogger) { 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) - : ObjCTurboModule("DevMenu", instance, jsInvoker) { + NativeDevMenuSpecJSI::NativeDevMenuSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("DevMenu", instance, jsInvoker, nativeInvoker, perfLogger) { methodMap_["show"] = MethodMetadata {0, __hostFunction_NativeDevMenuSpecJSI_show}; @@ -931,13 +931,21 @@ + (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) - : ObjCTurboModule("DevSettings", instance, jsInvoker) { + NativeDevSettingsSpecJSI::NativeDevSettingsSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("DevSettings", instance, jsInvoker, nativeInvoker, perfLogger) { methodMap_["reload"] = MethodMetadata {0, __hostFunction_NativeDevSettingsSpecJSI_reload}; @@ -963,6 +971,12 @@ + (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}; @@ -980,8 +994,8 @@ + (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifiersPage:(id)json } - NativeDeviceEventManagerSpecJSI::NativeDeviceEventManagerSpecJSI(id instance, std::shared_ptr jsInvoker) - : ObjCTurboModule("DeviceEventManager", instance, jsInvoker) { + NativeDeviceEventManagerSpecJSI::NativeDeviceEventManagerSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("DeviceEventManager", instance, jsInvoker, nativeInvoker, perfLogger) { methodMap_["invokeDefaultBackPressHandler"] = MethodMetadata {0, __hostFunction_NativeDeviceEventManagerSpecJSI_invokeDefaultBackPressHandler}; @@ -1000,8 +1014,8 @@ + (RCTManagedPointer *)JS_NativeCameraRollManager_PhotoIdentifiersPage:(id)json } - NativeDeviceInfoSpecJSI::NativeDeviceInfoSpecJSI(id instance, std::shared_ptr jsInvoker) - : ObjCTurboModule("DeviceInfo", instance, jsInvoker) { + NativeDeviceInfoSpecJSI::NativeDeviceInfoSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("DeviceInfo", instance, jsInvoker, nativeInvoker, perfLogger) { methodMap_["getConstants"] = MethodMetadata {0, __hostFunction_NativeDeviceInfoSpecJSI_getConstants}; @@ -1030,8 +1044,8 @@ + (RCTManagedPointer *)JS_NativeDialogManagerAndroid_DialogOptions:(id)json } - NativeDialogManagerAndroidSpecJSI::NativeDialogManagerAndroidSpecJSI(id instance, std::shared_ptr jsInvoker) - : ObjCTurboModule("DialogManagerAndroid", instance, jsInvoker) { + NativeDialogManagerAndroidSpecJSI::NativeDialogManagerAndroidSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("DialogManagerAndroid", instance, jsInvoker, nativeInvoker, perfLogger) { methodMap_["showAlert"] = MethodMetadata {3, __hostFunction_NativeDialogManagerAndroidSpecJSI_showAlert}; @@ -1082,8 +1096,8 @@ + (RCTManagedPointer *)JS_NativeExceptionsManager_ExceptionData:(id)json } - NativeExceptionsManagerSpecJSI::NativeExceptionsManagerSpecJSI(id instance, std::shared_ptr jsInvoker) - : ObjCTurboModule("ExceptionsManager", instance, jsInvoker) { + NativeExceptionsManagerSpecJSI::NativeExceptionsManagerSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("ExceptionsManager", instance, jsInvoker, nativeInvoker, perfLogger) { methodMap_["reportFatalException"] = MethodMetadata {3, __hostFunction_NativeExceptionsManagerSpecJSI_reportFatalException}; @@ -1119,8 +1133,8 @@ + (RCTManagedPointer *)JS_NativeExceptionsManager_ExceptionData:(id)json } - NativeFileReaderModuleSpecJSI::NativeFileReaderModuleSpecJSI(id instance, std::shared_ptr jsInvoker) - : ObjCTurboModule("FileReaderModule", instance, jsInvoker) { + NativeFileReaderModuleSpecJSI::NativeFileReaderModuleSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("FileReaderModule", instance, jsInvoker, nativeInvoker, perfLogger) { methodMap_["readAsDataURL"] = MethodMetadata {1, __hostFunction_NativeFileReaderModuleSpecJSI_readAsDataURL}; @@ -1160,8 +1174,8 @@ + (RCTManagedPointer *)JS_NativeFrameRateLogger_SpecSetGlobalOptionsOptions:(id) } - NativeFrameRateLoggerSpecJSI::NativeFrameRateLoggerSpecJSI(id instance, std::shared_ptr jsInvoker) - : ObjCTurboModule("FrameRateLogger", instance, jsInvoker) { + NativeFrameRateLoggerSpecJSI::NativeFrameRateLoggerSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("FrameRateLogger", instance, jsInvoker, nativeInvoker, perfLogger) { methodMap_["setGlobalOptions"] = MethodMetadata {1, __hostFunction_NativeFrameRateLoggerSpecJSI_setGlobalOptions}; @@ -1194,8 +1208,8 @@ + (RCTManagedPointer *)JS_NativeFrameRateLogger_SpecSetGlobalOptionsOptions:(id) } - NativeHeadlessJsTaskSupportSpecJSI::NativeHeadlessJsTaskSupportSpecJSI(id instance, std::shared_ptr jsInvoker) - : ObjCTurboModule("HeadlessJsTaskSupport", instance, jsInvoker) { + NativeHeadlessJsTaskSupportSpecJSI::NativeHeadlessJsTaskSupportSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("HeadlessJsTaskSupport", instance, jsInvoker, nativeInvoker, perfLogger) { methodMap_["notifyTaskFinished"] = MethodMetadata {1, __hostFunction_NativeHeadlessJsTaskSupportSpecJSI_notifyTaskFinished}; @@ -1204,33 +1218,6 @@ + (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 @@ -1256,8 +1243,8 @@ + (RCTManagedPointer *)JS_NativeFrameRateLogger_SpecSetGlobalOptionsOptions:(id) } - NativeI18nManagerSpecJSI::NativeI18nManagerSpecJSI(id instance, std::shared_ptr jsInvoker) - : ObjCTurboModule("I18nManager", instance, jsInvoker) { + NativeI18nManagerSpecJSI::NativeI18nManagerSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("I18nManager", instance, jsInvoker, nativeInvoker, perfLogger) { methodMap_["allowRTL"] = MethodMetadata {1, __hostFunction_NativeI18nManagerSpecJSI_allowRTL}; @@ -1309,8 +1296,8 @@ + (RCTManagedPointer *)JS_NativeImageEditor_Options:(id)json } - NativeImageEditorSpecJSI::NativeImageEditorSpecJSI(id instance, std::shared_ptr jsInvoker) - : ObjCTurboModule("ImageEditor", instance, jsInvoker) { + NativeImageEditorSpecJSI::NativeImageEditorSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("ImageEditor", instance, jsInvoker, nativeInvoker, perfLogger) { methodMap_["cropImage"] = MethodMetadata {4, __hostFunction_NativeImageEditorSpecJSI_cropImage}; @@ -1346,8 +1333,8 @@ + (RCTManagedPointer *)JS_NativeImageEditor_Options:(id)json } - NativeImageLoaderAndroidSpecJSI::NativeImageLoaderAndroidSpecJSI(id instance, std::shared_ptr jsInvoker) - : ObjCTurboModule("ImageLoaderAndroid", instance, jsInvoker) { + NativeImageLoaderAndroidSpecJSI::NativeImageLoaderAndroidSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("ImageLoaderAndroid", instance, jsInvoker, nativeInvoker, perfLogger) { methodMap_["abortRequest"] = MethodMetadata {1, __hostFunction_NativeImageLoaderAndroidSpecJSI_abortRequest}; @@ -1390,8 +1377,8 @@ + (RCTManagedPointer *)JS_NativeImageEditor_Options:(id)json } - NativeImageLoaderIOSSpecJSI::NativeImageLoaderIOSSpecJSI(id instance, std::shared_ptr jsInvoker) - : ObjCTurboModule("ImageLoaderIOS", instance, jsInvoker) { + NativeImageLoaderIOSSpecJSI::NativeImageLoaderIOSSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("ImageLoaderIOS", instance, jsInvoker, nativeInvoker, perfLogger) { methodMap_["getSize"] = MethodMetadata {1, __hostFunction_NativeImageLoaderIOSSpecJSI_getSize}; @@ -1451,8 +1438,8 @@ + (RCTManagedPointer *)JS_NativeImagePickerIOS_SpecOpenSelectDialogConfig:(id)js } - NativeImagePickerIOSSpecJSI::NativeImagePickerIOSSpecJSI(id instance, std::shared_ptr jsInvoker) - : ObjCTurboModule("ImagePickerIOS", instance, jsInvoker) { + NativeImagePickerIOSSpecJSI::NativeImagePickerIOSSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("ImagePickerIOS", instance, jsInvoker, nativeInvoker, perfLogger) { methodMap_["canRecordVideos"] = MethodMetadata {1, __hostFunction_NativeImagePickerIOSSpecJSI_canRecordVideos}; @@ -1506,8 +1493,8 @@ + (RCTManagedPointer *)JS_NativeImageStore_SpecAddImageFromBase64ErrorCallbackEr } - NativeImageStoreSpecJSI::NativeImageStoreSpecJSI(id instance, std::shared_ptr jsInvoker) - : ObjCTurboModule("ImageStore", instance, jsInvoker) { + NativeImageStoreSpecJSI::NativeImageStoreSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("ImageStore", instance, jsInvoker, nativeInvoker, perfLogger) { methodMap_["getBase64ForTag"] = MethodMetadata {3, __hostFunction_NativeImageStoreSpecJSI_getBase64ForTag}; @@ -1522,6 +1509,26 @@ + (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 @@ -1535,8 +1542,8 @@ + (RCTManagedPointer *)JS_NativeImageStore_SpecAddImageFromBase64ErrorCallbackEr } - NativeJSCSamplingProfilerSpecJSI::NativeJSCSamplingProfilerSpecJSI(id instance, std::shared_ptr jsInvoker) - : ObjCTurboModule("JSCSamplingProfiler", instance, jsInvoker) { + NativeJSCSamplingProfilerSpecJSI::NativeJSCSamplingProfilerSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("JSCSamplingProfiler", instance, jsInvoker, nativeInvoker, perfLogger) { methodMap_["operationComplete"] = MethodMetadata {3, __hostFunction_NativeJSCSamplingProfilerSpecJSI_operationComplete}; @@ -1563,8 +1570,8 @@ + (RCTManagedPointer *)JS_NativeImageStore_SpecAddImageFromBase64ErrorCallbackEr } - NativeJSDevSupportSpecJSI::NativeJSDevSupportSpecJSI(id instance, std::shared_ptr jsInvoker) - : ObjCTurboModule("JSDevSupport", instance, jsInvoker) { + NativeJSDevSupportSpecJSI::NativeJSDevSupportSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("JSDevSupport", instance, jsInvoker, nativeInvoker, perfLogger) { methodMap_["onSuccess"] = MethodMetadata {1, __hostFunction_NativeJSDevSupportSpecJSI_onSuccess}; @@ -1593,8 +1600,8 @@ + (RCTManagedPointer *)JS_NativeImageStore_SpecAddImageFromBase64ErrorCallbackEr } - NativeKeyboardObserverSpecJSI::NativeKeyboardObserverSpecJSI(id instance, std::shared_ptr jsInvoker) - : ObjCTurboModule("KeyboardObserver", instance, jsInvoker) { + NativeKeyboardObserverSpecJSI::NativeKeyboardObserverSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("KeyboardObserver", instance, jsInvoker, nativeInvoker, perfLogger) { methodMap_["addListener"] = MethodMetadata {1, __hostFunction_NativeKeyboardObserverSpecJSI_addListener}; @@ -1646,8 +1653,8 @@ + (RCTManagedPointer *)JS_NativeLinking_SpecSendIntentExtrasElement:(id)json } - NativeLinkingSpecJSI::NativeLinkingSpecJSI(id instance, std::shared_ptr jsInvoker) - : ObjCTurboModule("Linking", instance, jsInvoker) { + NativeLinkingSpecJSI::NativeLinkingSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("Linking", instance, jsInvoker, nativeInvoker, perfLogger) { methodMap_["getInitialURL"] = MethodMetadata {0, __hostFunction_NativeLinkingSpecJSI_getInitialURL}; @@ -1688,8 +1695,8 @@ + (RCTManagedPointer *)JS_NativeLinking_SpecSendIntentExtrasElement:(id)json } - NativeLogBoxSpecJSI::NativeLogBoxSpecJSI(id instance, std::shared_ptr jsInvoker) - : ObjCTurboModule("LogBox", instance, jsInvoker) { + NativeLogBoxSpecJSI::NativeLogBoxSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("LogBox", instance, jsInvoker, nativeInvoker, perfLogger) { methodMap_["show"] = MethodMetadata {0, __hostFunction_NativeLogBoxSpecJSI_show}; @@ -1715,8 +1722,8 @@ + (RCTManagedPointer *)JS_NativeLinking_SpecSendIntentExtrasElement:(id)json } - NativeModalManagerSpecJSI::NativeModalManagerSpecJSI(id instance, std::shared_ptr jsInvoker) - : ObjCTurboModule("ModalManager", instance, jsInvoker) { + NativeModalManagerSpecJSI::NativeModalManagerSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("ModalManager", instance, jsInvoker, nativeInvoker, perfLogger) { methodMap_["addListener"] = MethodMetadata {1, __hostFunction_NativeModalManagerSpecJSI_addListener}; @@ -1729,12 +1736,6 @@ + (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 { @@ -1760,8 +1761,8 @@ + (RCTManagedPointer *)JS_NativeNetworkingAndroid_Header:(id)json } - NativeNetworkingAndroidSpecJSI::NativeNetworkingAndroidSpecJSI(id instance, std::shared_ptr jsInvoker) - : ObjCTurboModule("NetworkingAndroid", instance, jsInvoker) { + NativeNetworkingAndroidSpecJSI::NativeNetworkingAndroidSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("NetworkingAndroid", instance, jsInvoker, nativeInvoker, perfLogger) { methodMap_["sendRequest"] = MethodMetadata {9, __hostFunction_NativeNetworkingAndroidSpecJSI_sendRequest}; @@ -1814,8 +1815,8 @@ + (RCTManagedPointer *)JS_NativeNetworkingIOS_SpecSendRequestQuery:(id)json } - NativeNetworkingIOSSpecJSI::NativeNetworkingIOSSpecJSI(id instance, std::shared_ptr jsInvoker) - : ObjCTurboModule("NetworkingIOS", instance, jsInvoker) { + NativeNetworkingIOSSpecJSI::NativeNetworkingIOSSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("NetworkingIOS", instance, jsInvoker, nativeInvoker, perfLogger) { methodMap_["sendRequest"] = MethodMetadata {2, __hostFunction_NativeNetworkingIOSSpecJSI_sendRequest}; @@ -1859,8 +1860,8 @@ + (RCTManagedPointer *)JS_NativeNetworkingIOS_SpecSendRequestQuery:(id)json } - NativePermissionsAndroidSpecJSI::NativePermissionsAndroidSpecJSI(id instance, std::shared_ptr jsInvoker) - : ObjCTurboModule("PermissionsAndroid", instance, jsInvoker) { + NativePermissionsAndroidSpecJSI::NativePermissionsAndroidSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("PermissionsAndroid", instance, jsInvoker, nativeInvoker, perfLogger) { methodMap_["checkPermission"] = MethodMetadata {1, __hostFunction_NativePermissionsAndroidSpecJSI_checkPermission}; @@ -1892,8 +1893,8 @@ + (RCTManagedPointer *)JS_NativeNetworkingIOS_SpecSendRequestQuery:(id)json } - NativePlatformConstantsAndroidSpecJSI::NativePlatformConstantsAndroidSpecJSI(id instance, std::shared_ptr jsInvoker) - : ObjCTurboModule("PlatformConstantsAndroid", instance, jsInvoker) { + NativePlatformConstantsAndroidSpecJSI::NativePlatformConstantsAndroidSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("PlatformConstantsAndroid", instance, jsInvoker, nativeInvoker, perfLogger) { methodMap_["getAndroidID"] = MethodMetadata {0, __hostFunction_NativePlatformConstantsAndroidSpecJSI_getAndroidID}; @@ -1915,8 +1916,8 @@ + (RCTManagedPointer *)JS_NativeNetworkingIOS_SpecSendRequestQuery:(id)json } - NativePlatformConstantsIOSSpecJSI::NativePlatformConstantsIOSSpecJSI(id instance, std::shared_ptr jsInvoker) - : ObjCTurboModule("PlatformConstantsIOS", instance, jsInvoker) { + NativePlatformConstantsIOSSpecJSI::NativePlatformConstantsIOSSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("PlatformConstantsIOS", instance, jsInvoker, nativeInvoker, perfLogger) { methodMap_["getConstants"] = MethodMetadata {0, __hostFunction_NativePlatformConstantsIOSSpecJSI_getConstants}; @@ -2017,8 +2018,8 @@ + (RCTManagedPointer *)JS_NativePushNotificationManagerIOS_Notification:(id)json } - NativePushNotificationManagerIOSSpecJSI::NativePushNotificationManagerIOSSpecJSI(id instance, std::shared_ptr jsInvoker) - : ObjCTurboModule("PushNotificationManagerIOS", instance, jsInvoker) { + NativePushNotificationManagerIOSSpecJSI::NativePushNotificationManagerIOSSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("PushNotificationManagerIOS", instance, jsInvoker, nativeInvoker, perfLogger) { methodMap_["onFinishRemoteNotification"] = MethodMetadata {2, __hostFunction_NativePushNotificationManagerIOSSpecJSI_onFinishRemoteNotification}; @@ -2092,8 +2093,8 @@ + (RCTManagedPointer *)JS_NativePushNotificationManagerIOS_Notification:(id)json } - NativeRedBoxSpecJSI::NativeRedBoxSpecJSI(id instance, std::shared_ptr jsInvoker) - : ObjCTurboModule("RedBox", instance, jsInvoker) { + NativeRedBoxSpecJSI::NativeRedBoxSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("RedBox", instance, jsInvoker, nativeInvoker, perfLogger) { methodMap_["setExtraData"] = MethodMetadata {2, __hostFunction_NativeRedBoxSpecJSI_setExtraData}; @@ -2119,8 +2120,8 @@ + (RCTManagedPointer *)JS_NativePushNotificationManagerIOS_Notification:(id)json } - NativeSegmentFetcherSpecJSI::NativeSegmentFetcherSpecJSI(id instance, std::shared_ptr jsInvoker) - : ObjCTurboModule("SegmentFetcher", instance, jsInvoker) { + NativeSegmentFetcherSpecJSI::NativeSegmentFetcherSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("SegmentFetcher", instance, jsInvoker, nativeInvoker, perfLogger) { methodMap_["fetchSegment"] = MethodMetadata {3, __hostFunction_NativeSegmentFetcherSpecJSI_fetchSegment}; @@ -2150,8 +2151,8 @@ + (RCTManagedPointer *)JS_NativePushNotificationManagerIOS_Notification:(id)json } - NativeSettingsManagerSpecJSI::NativeSettingsManagerSpecJSI(id instance, std::shared_ptr jsInvoker) - : ObjCTurboModule("SettingsManager", instance, jsInvoker) { + NativeSettingsManagerSpecJSI::NativeSettingsManagerSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("SettingsManager", instance, jsInvoker, nativeInvoker, perfLogger) { methodMap_["setValues"] = MethodMetadata {1, __hostFunction_NativeSettingsManagerSpecJSI_setValues}; @@ -2182,8 +2183,8 @@ + (RCTManagedPointer *)JS_NativeShareModule_SpecShareContent:(id)json } - NativeShareModuleSpecJSI::NativeShareModuleSpecJSI(id instance, std::shared_ptr jsInvoker) - : ObjCTurboModule("ShareModule", instance, jsInvoker) { + NativeShareModuleSpecJSI::NativeShareModuleSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("ShareModule", instance, jsInvoker, nativeInvoker, perfLogger) { methodMap_["share"] = MethodMetadata {2, __hostFunction_NativeShareModuleSpecJSI_share}; @@ -2203,8 +2204,8 @@ + (RCTManagedPointer *)JS_NativeShareModule_SpecShareContent:(id)json } - NativeSoundManagerSpecJSI::NativeSoundManagerSpecJSI(id instance, std::shared_ptr jsInvoker) - : ObjCTurboModule("SoundManager", instance, jsInvoker) { + NativeSoundManagerSpecJSI::NativeSoundManagerSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("SoundManager", instance, jsInvoker, nativeInvoker, perfLogger) { methodMap_["playTouchSound"] = MethodMetadata {0, __hostFunction_NativeSoundManagerSpecJSI_playTouchSound}; @@ -2223,8 +2224,8 @@ + (RCTManagedPointer *)JS_NativeShareModule_SpecShareContent:(id)json } - NativeSourceCodeSpecJSI::NativeSourceCodeSpecJSI(id instance, std::shared_ptr jsInvoker) - : ObjCTurboModule("SourceCode", instance, jsInvoker) { + NativeSourceCodeSpecJSI::NativeSourceCodeSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("SourceCode", instance, jsInvoker, nativeInvoker, perfLogger) { methodMap_["getConstants"] = MethodMetadata {0, __hostFunction_NativeSourceCodeSpecJSI_getConstants}; @@ -2259,8 +2260,8 @@ + (RCTManagedPointer *)JS_NativeShareModule_SpecShareContent:(id)json } - NativeStatusBarManagerAndroidSpecJSI::NativeStatusBarManagerAndroidSpecJSI(id instance, std::shared_ptr jsInvoker) - : ObjCTurboModule("StatusBarManagerAndroid", instance, jsInvoker) { + NativeStatusBarManagerAndroidSpecJSI::NativeStatusBarManagerAndroidSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("StatusBarManagerAndroid", instance, jsInvoker, nativeInvoker, perfLogger) { methodMap_["setColor"] = MethodMetadata {2, __hostFunction_NativeStatusBarManagerAndroidSpecJSI_setColor}; @@ -2321,8 +2322,8 @@ + (RCTManagedPointer *)JS_NativeStatusBarManagerIOS_SpecGetHeightCallbackResult: } - NativeStatusBarManagerIOSSpecJSI::NativeStatusBarManagerIOSSpecJSI(id instance, std::shared_ptr jsInvoker) - : ObjCTurboModule("StatusBarManagerIOS", instance, jsInvoker) { + NativeStatusBarManagerIOSSpecJSI::NativeStatusBarManagerIOSSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("StatusBarManagerIOS", instance, jsInvoker, nativeInvoker, perfLogger) { methodMap_["getHeight"] = MethodMetadata {1, __hostFunction_NativeStatusBarManagerIOSSpecJSI_getHeight}; @@ -2363,8 +2364,8 @@ + (RCTManagedPointer *)JS_NativeStatusBarManagerIOS_SpecGetHeightCallbackResult: } - NativeTVNavigationEventEmitterSpecJSI::NativeTVNavigationEventEmitterSpecJSI(id instance, std::shared_ptr jsInvoker) - : ObjCTurboModule("TVNavigationEventEmitter", instance, jsInvoker) { + NativeTVNavigationEventEmitterSpecJSI::NativeTVNavigationEventEmitterSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("TVNavigationEventEmitter", instance, jsInvoker, nativeInvoker, perfLogger) { methodMap_["addListener"] = MethodMetadata {1, __hostFunction_NativeTVNavigationEventEmitterSpecJSI_addListener}; @@ -2392,8 +2393,8 @@ + (RCTManagedPointer *)JS_NativeTimePickerAndroid_TimePickerOptions:(id)json } - NativeTimePickerAndroidSpecJSI::NativeTimePickerAndroidSpecJSI(id instance, std::shared_ptr jsInvoker) - : ObjCTurboModule("TimePickerAndroid", instance, jsInvoker) { + NativeTimePickerAndroidSpecJSI::NativeTimePickerAndroidSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("TimePickerAndroid", instance, jsInvoker, nativeInvoker, perfLogger) { methodMap_["open"] = MethodMetadata {1, __hostFunction_NativeTimePickerAndroidSpecJSI_open}; @@ -2427,8 +2428,8 @@ + (RCTManagedPointer *)JS_NativeTimePickerAndroid_TimePickerResult:(id)json } - NativeTimingSpecJSI::NativeTimingSpecJSI(id instance, std::shared_ptr jsInvoker) - : ObjCTurboModule("Timing", instance, jsInvoker) { + NativeTimingSpecJSI::NativeTimingSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("Timing", instance, jsInvoker, nativeInvoker, perfLogger) { methodMap_["createTimer"] = MethodMetadata {4, __hostFunction_NativeTimingSpecJSI_createTimer}; @@ -2465,8 +2466,8 @@ + (RCTManagedPointer *)JS_NativeTimePickerAndroid_TimePickerResult:(id)json } - NativeToastAndroidSpecJSI::NativeToastAndroidSpecJSI(id instance, std::shared_ptr jsInvoker) - : ObjCTurboModule("ToastAndroid", instance, jsInvoker) { + NativeToastAndroidSpecJSI::NativeToastAndroidSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("ToastAndroid", instance, jsInvoker, nativeInvoker, perfLogger) { methodMap_["show"] = MethodMetadata {2, __hostFunction_NativeToastAndroidSpecJSI_show}; @@ -2598,8 +2599,8 @@ + (RCTManagedPointer *)JS_NativeTimePickerAndroid_TimePickerResult:(id)json } - NativeUIManagerSpecJSI::NativeUIManagerSpecJSI(id instance, std::shared_ptr jsInvoker) - : ObjCTurboModule("UIManager", instance, jsInvoker) { + NativeUIManagerSpecJSI::NativeUIManagerSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("UIManager", instance, jsInvoker, nativeInvoker, perfLogger) { methodMap_["getConstantsForViewManager"] = MethodMetadata {1, __hostFunction_NativeUIManagerSpecJSI_getConstantsForViewManager}; @@ -2704,8 +2705,8 @@ + (RCTManagedPointer *)JS_NativeTimePickerAndroid_TimePickerResult:(id)json } - NativeVibrationSpecJSI::NativeVibrationSpecJSI(id instance, std::shared_ptr jsInvoker) - : ObjCTurboModule("Vibration", instance, jsInvoker) { + NativeVibrationSpecJSI::NativeVibrationSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("Vibration", instance, jsInvoker, nativeInvoker, perfLogger) { methodMap_["vibrate"] = MethodMetadata {1, __hostFunction_NativeVibrationSpecJSI_vibrate}; @@ -2760,8 +2761,8 @@ + (RCTManagedPointer *)JS_NativeWebSocketModule_SpecConnectOptions:(id)json } - NativeWebSocketModuleSpecJSI::NativeWebSocketModuleSpecJSI(id instance, std::shared_ptr jsInvoker) - : ObjCTurboModule("WebSocketModule", instance, jsInvoker) { + NativeWebSocketModuleSpecJSI::NativeWebSocketModuleSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger) + : ObjCTurboModule("WebSocketModule", instance, jsInvoker, nativeInvoker, perfLogger) { methodMap_["connect"] = MethodMetadata {4, __hostFunction_NativeWebSocketModuleSpecJSI_connect}; diff --git a/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec.h b/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec.h index 2bb267d5a7b175..c3a848b06e9354 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); + NativeAccessibilityInfoSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); }; } // namespace react @@ -101,7 +101,7 @@ namespace facebook { class JSI_EXPORT NativeAccessibilityManagerSpecJSI : public ObjCTurboModule { public: - NativeAccessibilityManagerSpecJSI(id instance, std::shared_ptr jsInvoker); + NativeAccessibilityManagerSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); }; } // namespace react @@ -117,6 +117,7 @@ namespace JS { folly::Optional cancelButtonIndex() const; folly::Optional anchor() const; folly::Optional tintColor() const; + NSString *userInterfaceStyle() const; SpecShowActionSheetWithOptionsOptions(NSDictionary *const v) : _v(v) {} private: @@ -138,6 +139,7 @@ namespace JS { folly::Optional anchor() const; folly::Optional tintColor() const; folly::Optional> excludedActivityTypes() const; + NSString *userInterfaceStyle() const; SpecShowShareActionSheetWithOptionsOptions(NSDictionary *const v) : _v(v) {} private: @@ -185,7 +187,7 @@ namespace facebook { class JSI_EXPORT NativeActionSheetManagerSpecJSI : public ObjCTurboModule { public: - NativeActionSheetManagerSpecJSI(id instance, std::shared_ptr jsInvoker); + NativeActionSheetManagerSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); }; } // namespace react @@ -232,7 +234,7 @@ namespace facebook { class JSI_EXPORT NativeAlertManagerSpecJSI : public ObjCTurboModule { public: - NativeAlertManagerSpecJSI(id instance, std::shared_ptr jsInvoker); + NativeAlertManagerSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); }; } // namespace react @@ -315,7 +317,7 @@ namespace facebook { class JSI_EXPORT NativeAnimatedModuleSpecJSI : public ObjCTurboModule { public: - NativeAnimatedModuleSpecJSI(id instance, std::shared_ptr jsInvoker); + NativeAnimatedModuleSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); }; } // namespace react @@ -334,7 +336,7 @@ namespace facebook { class JSI_EXPORT NativeAnimationsDebugModuleSpecJSI : public ObjCTurboModule { public: - NativeAnimationsDebugModuleSpecJSI(id instance, std::shared_ptr jsInvoker); + NativeAnimationsDebugModuleSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); }; } // namespace react @@ -401,7 +403,7 @@ namespace facebook { class JSI_EXPORT NativeAppStateSpecJSI : public ObjCTurboModule { public: - NativeAppStateSpecJSI(id instance, std::shared_ptr jsInvoker); + NativeAppStateSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); }; } // namespace react @@ -421,7 +423,7 @@ namespace facebook { class JSI_EXPORT NativeAppearanceSpecJSI : public ObjCTurboModule { public: - NativeAppearanceSpecJSI(id instance, std::shared_ptr jsInvoker); + NativeAppearanceSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); }; } // namespace react @@ -567,7 +569,7 @@ namespace facebook { class JSI_EXPORT NativeAsyncStorageSpecJSI : public ObjCTurboModule { public: - NativeAsyncStorageSpecJSI(id instance, std::shared_ptr jsInvoker); + NativeAsyncStorageSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); }; } // namespace react @@ -623,7 +625,7 @@ namespace facebook { class JSI_EXPORT NativeBlobModuleSpecJSI : public ObjCTurboModule { public: - NativeBlobModuleSpecJSI(id instance, std::shared_ptr jsInvoker); + NativeBlobModuleSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); }; } // namespace react @@ -644,7 +646,7 @@ namespace facebook { class JSI_EXPORT NativeBugReportingSpecJSI : public ObjCTurboModule { public: - NativeBugReportingSpecJSI(id instance, std::shared_ptr jsInvoker); + NativeBugReportingSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); }; } // namespace react @@ -693,7 +695,7 @@ namespace facebook { class JSI_EXPORT NativeCameraRollManagerSpecJSI : public ObjCTurboModule { public: - NativeCameraRollManagerSpecJSI(id instance, std::shared_ptr jsInvoker); + NativeCameraRollManagerSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); }; } // namespace react @@ -825,7 +827,7 @@ namespace facebook { class JSI_EXPORT NativeClipboardSpecJSI : public ObjCTurboModule { public: - NativeClipboardSpecJSI(id instance, std::shared_ptr jsInvoker); + NativeClipboardSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); }; } // namespace react @@ -845,7 +847,7 @@ namespace facebook { class JSI_EXPORT NativeDatePickerAndroidSpecJSI : public ObjCTurboModule { public: - NativeDatePickerAndroidSpecJSI(id instance, std::shared_ptr jsInvoker); + NativeDatePickerAndroidSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); }; } // namespace react @@ -853,8 +855,8 @@ namespace facebook { @protocol NativeDevLoadingViewSpec - (void)showMessage:(NSString *)message - color:(NSDictionary *)color - backgroundColor:(NSDictionary *)backgroundColor; + withColor:(NSNumber *)withColor +withBackgroundColor:(NSNumber *)withBackgroundColor; - (void)hide; @end @@ -866,7 +868,7 @@ namespace facebook { class JSI_EXPORT NativeDevLoadingViewSpecJSI : public ObjCTurboModule { public: - NativeDevLoadingViewSpecJSI(id instance, std::shared_ptr jsInvoker); + NativeDevLoadingViewSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); }; } // namespace react @@ -888,7 +890,7 @@ namespace facebook { class JSI_EXPORT NativeDevMenuSpecJSI : public ObjCTurboModule { public: - NativeDevMenuSpecJSI(id instance, std::shared_ptr jsInvoker); + NativeDevMenuSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); }; } // namespace react @@ -903,6 +905,8 @@ 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; @@ -915,7 +919,7 @@ namespace facebook { class JSI_EXPORT NativeDevSettingsSpecJSI : public ObjCTurboModule { public: - NativeDevSettingsSpecJSI(id instance, std::shared_ptr jsInvoker); + NativeDevSettingsSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); }; } // namespace react @@ -933,7 +937,7 @@ namespace facebook { class JSI_EXPORT NativeDeviceEventManagerSpecJSI : public ObjCTurboModule { public: - NativeDeviceEventManagerSpecJSI(id instance, std::shared_ptr jsInvoker); + NativeDeviceEventManagerSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); }; } // namespace react @@ -1075,7 +1079,7 @@ namespace facebook { class JSI_EXPORT NativeDeviceInfoSpecJSI : public ObjCTurboModule { public: - NativeDeviceInfoSpecJSI(id instance, std::shared_ptr jsInvoker); + NativeDeviceInfoSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); }; } // namespace react @@ -1151,7 +1155,7 @@ namespace facebook { class JSI_EXPORT NativeDialogManagerAndroidSpecJSI : public ObjCTurboModule { public: - NativeDialogManagerAndroidSpecJSI(id instance, std::shared_ptr jsInvoker); + NativeDialogManagerAndroidSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); }; } // namespace react @@ -1222,7 +1226,7 @@ namespace facebook { class JSI_EXPORT NativeExceptionsManagerSpecJSI : public ObjCTurboModule { public: - NativeExceptionsManagerSpecJSI(id instance, std::shared_ptr jsInvoker); + NativeExceptionsManagerSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); }; } // namespace react @@ -1246,7 +1250,7 @@ namespace facebook { class JSI_EXPORT NativeFileReaderModuleSpecJSI : public ObjCTurboModule { public: - NativeFileReaderModuleSpecJSI(id instance, std::shared_ptr jsInvoker); + NativeFileReaderModuleSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); }; } // namespace react @@ -1284,7 +1288,7 @@ namespace facebook { class JSI_EXPORT NativeFrameRateLoggerSpecJSI : public ObjCTurboModule { public: - NativeFrameRateLoggerSpecJSI(id instance, std::shared_ptr jsInvoker); + NativeFrameRateLoggerSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); }; } // namespace react @@ -1305,27 +1309,7 @@ namespace facebook { class JSI_EXPORT NativeHeadlessJsTaskSupportSpecJSI : public ObjCTurboModule { public: - 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); + NativeHeadlessJsTaskSupportSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); }; } // namespace react @@ -1376,7 +1360,7 @@ namespace facebook { class JSI_EXPORT NativeI18nManagerSpecJSI : public ObjCTurboModule { public: - NativeI18nManagerSpecJSI(id instance, std::shared_ptr jsInvoker); + NativeI18nManagerSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); }; } // namespace react @@ -1440,6 +1424,7 @@ 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: @@ -1467,7 +1452,7 @@ namespace facebook { class JSI_EXPORT NativeImageEditorSpecJSI : public ObjCTurboModule { public: - NativeImageEditorSpecJSI(id instance, std::shared_ptr jsInvoker); + NativeImageEditorSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); }; } // namespace react @@ -1499,7 +1484,7 @@ namespace facebook { class JSI_EXPORT NativeImageLoaderAndroidSpecJSI : public ObjCTurboModule { public: - NativeImageLoaderAndroidSpecJSI(id instance, std::shared_ptr jsInvoker); + NativeImageLoaderAndroidSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); }; } // namespace react @@ -1529,7 +1514,7 @@ namespace facebook { class JSI_EXPORT NativeImageLoaderIOSSpecJSI : public ObjCTurboModule { public: - NativeImageLoaderIOSSpecJSI(id instance, std::shared_ptr jsInvoker); + NativeImageLoaderIOSSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); }; } // namespace react @@ -1590,7 +1575,7 @@ namespace facebook { class JSI_EXPORT NativeImagePickerIOSSpecJSI : public ObjCTurboModule { public: - NativeImagePickerIOSSpecJSI(id instance, std::shared_ptr jsInvoker); + NativeImagePickerIOSSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); }; } // namespace react @@ -1632,7 +1617,26 @@ namespace facebook { class JSI_EXPORT NativeImageStoreSpecJSI : public ObjCTurboModule { public: - NativeImageStoreSpecJSI(id instance, std::shared_ptr jsInvoker); + 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); }; } // namespace react @@ -1652,7 +1656,7 @@ namespace facebook { class JSI_EXPORT NativeJSCSamplingProfilerSpecJSI : public ObjCTurboModule { public: - NativeJSCSamplingProfilerSpecJSI(id instance, std::shared_ptr jsInvoker); + NativeJSCSamplingProfilerSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); }; } // namespace react @@ -1688,7 +1692,7 @@ namespace JS { } @protocol NativeJSDevSupportSpec -- (void)onSuccess:(NSDictionary *)data; +- (void)onSuccess:(NSString *)data; - (void)onFailure:(double)errorCode error:(NSString *)error; - (facebook::react::ModuleConstants)constantsToExport; @@ -1703,7 +1707,7 @@ namespace facebook { class JSI_EXPORT NativeJSDevSupportSpecJSI : public ObjCTurboModule { public: - NativeJSDevSupportSpecJSI(id instance, std::shared_ptr jsInvoker); + NativeJSDevSupportSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); }; } // namespace react @@ -1722,7 +1726,7 @@ namespace facebook { class JSI_EXPORT NativeKeyboardObserverSpecJSI : public ObjCTurboModule { public: - NativeKeyboardObserverSpecJSI(id instance, std::shared_ptr jsInvoker); + NativeKeyboardObserverSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); }; } // namespace react @@ -1772,7 +1776,7 @@ namespace facebook { class JSI_EXPORT NativeLinkingSpecJSI : public ObjCTurboModule { public: - NativeLinkingSpecJSI(id instance, std::shared_ptr jsInvoker); + NativeLinkingSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); }; } // namespace react @@ -1791,7 +1795,7 @@ namespace facebook { class JSI_EXPORT NativeLogBoxSpecJSI : public ObjCTurboModule { public: - NativeLogBoxSpecJSI(id instance, std::shared_ptr jsInvoker); + NativeLogBoxSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); }; } // namespace react @@ -1810,28 +1814,11 @@ namespace facebook { class JSI_EXPORT NativeModalManagerSpecJSI : public ObjCTurboModule { public: - NativeModalManagerSpecJSI(id instance, std::shared_ptr jsInvoker); + NativeModalManagerSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); }; } // 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 @@ -1857,7 +1844,7 @@ namespace facebook { class JSI_EXPORT NativeNetworkingAndroidSpecJSI : public ObjCTurboModule { public: - NativeNetworkingAndroidSpecJSI(id instance, std::shared_ptr jsInvoker); + NativeNetworkingAndroidSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); }; } // namespace react @@ -1903,7 +1890,7 @@ namespace facebook { class JSI_EXPORT NativeNetworkingIOSSpecJSI : public ObjCTurboModule { public: - NativeNetworkingIOSSpecJSI(id instance, std::shared_ptr jsInvoker); + NativeNetworkingIOSSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); }; } // namespace react @@ -1932,7 +1919,7 @@ namespace facebook { class JSI_EXPORT NativePermissionsAndroidSpecJSI : public ObjCTurboModule { public: - NativePermissionsAndroidSpecJSI(id instance, std::shared_ptr jsInvoker); + NativePermissionsAndroidSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); }; } // namespace react @@ -1982,7 +1969,7 @@ namespace JS { RCTRequired Serial; RCTRequired Fingerprint; RCTRequired Model; - RCTRequired ServerHost; + NSString *ServerHost; RCTRequired uiMode; }; @@ -2019,7 +2006,7 @@ namespace facebook { class JSI_EXPORT NativePlatformConstantsAndroidSpecJSI : public ObjCTurboModule { public: - NativePlatformConstantsAndroidSpecJSI(id instance, std::shared_ptr jsInvoker); + NativePlatformConstantsAndroidSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); }; } // namespace react @@ -2102,7 +2089,7 @@ namespace facebook { class JSI_EXPORT NativePlatformConstantsIOSSpecJSI : public ObjCTurboModule { public: - NativePlatformConstantsIOSSpecJSI(id instance, std::shared_ptr jsInvoker); + NativePlatformConstantsIOSSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); }; } // namespace react @@ -2200,7 +2187,7 @@ namespace facebook { class JSI_EXPORT NativePushNotificationManagerIOSSpecJSI : public ObjCTurboModule { public: - NativePushNotificationManagerIOSSpecJSI(id instance, std::shared_ptr jsInvoker); + NativePushNotificationManagerIOSSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); }; } // namespace react @@ -2220,7 +2207,7 @@ namespace facebook { class JSI_EXPORT NativeRedBoxSpecJSI : public ObjCTurboModule { public: - NativeRedBoxSpecJSI(id instance, std::shared_ptr jsInvoker); + NativeRedBoxSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); }; } // namespace react @@ -2243,7 +2230,7 @@ namespace facebook { class JSI_EXPORT NativeSegmentFetcherSpecJSI : public ObjCTurboModule { public: - NativeSegmentFetcherSpecJSI(id instance, std::shared_ptr jsInvoker); + NativeSegmentFetcherSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); }; } // namespace react @@ -2292,7 +2279,7 @@ namespace facebook { class JSI_EXPORT NativeSettingsManagerSpecJSI : public ObjCTurboModule { public: - NativeSettingsManagerSpecJSI(id instance, std::shared_ptr jsInvoker); + NativeSettingsManagerSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); }; } // namespace react @@ -2330,7 +2317,7 @@ namespace facebook { class JSI_EXPORT NativeShareModuleSpecJSI : public ObjCTurboModule { public: - NativeShareModuleSpecJSI(id instance, std::shared_ptr jsInvoker); + NativeShareModuleSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); }; } // namespace react @@ -2348,7 +2335,7 @@ namespace facebook { class JSI_EXPORT NativeSoundManagerSpecJSI : public ObjCTurboModule { public: - NativeSoundManagerSpecJSI(id instance, std::shared_ptr jsInvoker); + NativeSoundManagerSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); }; } // namespace react @@ -2395,7 +2382,7 @@ namespace facebook { class JSI_EXPORT NativeSourceCodeSpecJSI : public ObjCTurboModule { public: - NativeSourceCodeSpecJSI(id instance, std::shared_ptr jsInvoker); + NativeSourceCodeSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); }; } // namespace react @@ -2448,7 +2435,7 @@ namespace facebook { class JSI_EXPORT NativeStatusBarManagerAndroidSpecJSI : public ObjCTurboModule { public: - NativeStatusBarManagerAndroidSpecJSI(id instance, std::shared_ptr jsInvoker); + NativeStatusBarManagerAndroidSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); }; } // namespace react @@ -2520,7 +2507,7 @@ namespace facebook { class JSI_EXPORT NativeStatusBarManagerIOSSpecJSI : public ObjCTurboModule { public: - NativeStatusBarManagerIOSSpecJSI(id instance, std::shared_ptr jsInvoker); + NativeStatusBarManagerIOSSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); }; } // namespace react @@ -2539,7 +2526,7 @@ namespace facebook { class JSI_EXPORT NativeTVNavigationEventEmitterSpecJSI : public ObjCTurboModule { public: - NativeTVNavigationEventEmitterSpecJSI(id instance, std::shared_ptr jsInvoker); + NativeTVNavigationEventEmitterSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); }; } // namespace react @@ -2578,7 +2565,7 @@ namespace facebook { class JSI_EXPORT NativeTimePickerAndroidSpecJSI : public ObjCTurboModule { public: - NativeTimePickerAndroidSpecJSI(id instance, std::shared_ptr jsInvoker); + NativeTimePickerAndroidSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); }; } // namespace react @@ -2619,7 +2606,7 @@ namespace facebook { class JSI_EXPORT NativeTimingSpecJSI : public ObjCTurboModule { public: - NativeTimingSpecJSI(id instance, std::shared_ptr jsInvoker); + NativeTimingSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); }; } // namespace react @@ -2680,7 +2667,7 @@ namespace facebook { class JSI_EXPORT NativeToastAndroidSpecJSI : public ObjCTurboModule { public: - NativeToastAndroidSpecJSI(id instance, std::shared_ptr jsInvoker); + NativeToastAndroidSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); }; } // namespace react @@ -2784,7 +2771,7 @@ namespace facebook { class JSI_EXPORT NativeUIManagerSpecJSI : public ObjCTurboModule { public: - NativeUIManagerSpecJSI(id instance, std::shared_ptr jsInvoker); + NativeUIManagerSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); }; } // namespace react @@ -2805,7 +2792,7 @@ namespace facebook { class JSI_EXPORT NativeVibrationSpecJSI : public ObjCTurboModule { public: - NativeVibrationSpecJSI(id instance, std::shared_ptr jsInvoker); + NativeVibrationSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); }; } // namespace react @@ -2852,7 +2839,7 @@ namespace facebook { class JSI_EXPORT NativeWebSocketModuleSpecJSI : public ObjCTurboModule { public: - NativeWebSocketModuleSpecJSI(id instance, std::shared_ptr jsInvoker); + NativeWebSocketModuleSpecJSI(id instance, std::shared_ptr jsInvoker, std::shared_ptr nativeInvoker, id perfLogger); }; } // namespace react @@ -2956,6 +2943,11 @@ 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"]; @@ -2986,6 +2978,11 @@ 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"]; @@ -3529,6 +3526,11 @@ 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"]; @@ -3575,16 +3577,6 @@ 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"]; @@ -3656,7 +3648,7 @@ inline JS::NativePlatformConstantsAndroid::Constants::Builder::Builder(const Inp d[@"Fingerprint"] = Fingerprint; auto Model = i.Model.get(); d[@"Model"] = Model; - auto ServerHost = i.ServerHost.get(); + auto ServerHost = i.ServerHost; d[@"ServerHost"] = ServerHost; auto uiMode = i.uiMode.get(); d[@"uiMode"] = uiMode; diff --git a/Libraries/HeapCapture/HeapCapture.js b/Libraries/HeapCapture/HeapCapture.js index 9cbabc60417487..903343a05b0601 100644 --- a/Libraries/HeapCapture/HeapCapture.js +++ b/Libraries/HeapCapture/HeapCapture.js @@ -10,7 +10,7 @@ 'use strict'; -import NativeHeapCapture from './NativeHeapCapture'; +import NativeJSCHeapCapture from './NativeJSCHeapCapture'; const HeapCapture = { captureHeap: function(path: string) { @@ -22,8 +22,8 @@ const HeapCapture = { console.log('HeapCapture.captureHeap error: ' + e.toString()); error = e.toString(); } - if (NativeHeapCapture) { - NativeHeapCapture.captureComplete(path, error); + if (NativeJSCHeapCapture) { + NativeJSCHeapCapture.captureComplete(path, error); } }, }; diff --git a/Libraries/HeapCapture/NativeHeapCapture.js b/Libraries/HeapCapture/NativeJSCHeapCapture.js similarity index 76% rename from Libraries/HeapCapture/NativeHeapCapture.js rename to Libraries/HeapCapture/NativeJSCHeapCapture.js index 5d778e44771467..05e941f17e7b83 100644 --- a/Libraries/HeapCapture/NativeHeapCapture.js +++ b/Libraries/HeapCapture/NativeJSCHeapCapture.js @@ -14,11 +14,7 @@ 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('HeapCapture'): ?Spec); +export default (TurboModuleRegistry.get('JSCHeapCapture'): ?Spec); diff --git a/Libraries/Image/AssetSourceResolver.js b/Libraries/Image/AssetSourceResolver.js index 624c6225c2008f..bc671090b25b5f 100644 --- a/Libraries/Image/AssetSourceResolver.js +++ b/Libraries/Image/AssetSourceResolver.js @@ -114,7 +114,12 @@ class AssetSourceResolver { */ scaledAssetURLNearBundle(): ResolvedAssetSource { const path = this.jsbundleUrl || 'file://'; - return this.fromSource(path + getScaledAssetPath(this.asset)); + 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, '_'), + ); } /** diff --git a/Libraries/Image/Image.android.js b/Libraries/Image/Image.android.js index fec14e0487f7ea..5e57732a855424 100644 --- a/Libraries/Image/Image.android.js +++ b/Libraries/Image/Image.android.js @@ -13,13 +13,14 @@ const DeprecatedImageStylePropTypes = require('../DeprecatedPropTypes/DeprecatedImageStylePropTypes'); const DeprecatedStyleSheetPropType = require('../DeprecatedPropTypes/DeprecatedStyleSheetPropType'); const DeprecatedViewPropTypes = require('../DeprecatedPropTypes/DeprecatedViewPropTypes'); -const ImageViewNativeComponent = require('./ImageViewNativeComponent'); +import ImageViewNativeComponent from './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'); @@ -40,7 +41,7 @@ const ImageProps = { DeprecatedImageStylePropTypes, ): ReactPropsCheckType), /** - * See https://facebook.github.io/react-native/docs/image.html#source + * See https://reactnative.dev/docs/image.html#source */ source: (PropTypes.oneOfType([ PropTypes.shape({ @@ -76,15 +77,15 @@ const ImageProps = { /** * blurRadius: the blur radius of the blur filter added to the image * - * See https://facebook.github.io/react-native/docs/image.html#blurradius + * See https://reactnative.dev/docs/image.html#blurradius */ blurRadius: PropTypes.number, /** - * See https://facebook.github.io/react-native/docs/image.html#defaultsource + * See https://reactnative.dev/docs/image.html#defaultsource */ defaultSource: PropTypes.number, /** - * See https://facebook.github.io/react-native/docs/image.html#loadingindicatorsource + * See https://reactnative.dev/docs/image.html#loadingindicatorsource */ loadingIndicatorSource: (PropTypes.oneOfType([ PropTypes.shape({ @@ -95,6 +96,10 @@ 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 */ @@ -119,7 +124,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://facebook.github.io/react-native/docs/image.html#resizemethod + * See https://reactnative.dev/docs/image.html#resizemethod */ resizeMethod: (PropTypes.oneOf([ 'auto', @@ -130,7 +135,7 @@ const ImageProps = { * Determines how to resize the image when the frame doesn't match the raw * image dimensions. * - * See https://facebook.github.io/react-native/docs/image.html#resizemode + * See https://reactnative.dev/docs/image.html#resizemode */ resizeMode: (PropTypes.oneOf([ 'cover', @@ -146,7 +151,7 @@ const ImageProps = { /** * Retrieve the width and height (in pixels) of an image prior to displaying it * - * See https://facebook.github.io/react-native/docs/image.html#getsize + * See https://reactnative.dev/docs/image.html#getsize */ function getSize( url: string, @@ -169,7 +174,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://facebook.github.io/react-native/docs/image.html#getsizewithheaders + * See https://reactnative.dev/docs/image.html#getsizewithheaders */ function getSizeWithHeaders( url: string, @@ -202,7 +207,7 @@ function abortPrefetch(requestId: number) { /** * Perform cache interrogation. * - * See https://facebook.github.io/react-native/docs/image.html#querycache + * See https://reactnative.dev/docs/image.html#querycache */ async function queryCache( urls: Array, @@ -225,7 +230,7 @@ type ImageComponentStatics = $ReadOnly<{| * including network images, static resources, temporary local images, and * images from local disk, such as the camera roll. * - * See https://facebook.github.io/react-native/docs/image.html + * See https://reactnative.dev/docs/image.html */ let Image = (props: ImagePropsType, forwardedRef) => { let source = resolveAssetSource(props.source); @@ -263,12 +268,8 @@ 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]); @@ -292,15 +293,28 @@ let Image = (props: ImagePropsType, forwardedRef) => { }; return ( - - {hasTextAncestor => - hasTextAncestor ? ( - - ) : ( - - ) - } - + + {analyticTag => { + const nativePropsWithAnalytics = + analyticTag !== null + ? { + ...nativeProps, + internal_analyticTag: analyticTag, + } + : nativeProps; + return ( + + {hasTextAncestor => + hasTextAncestor ? ( + + ) : ( + + ) + } + + ); + }} + ); }; @@ -315,7 +329,7 @@ Image.displayName = 'Image'; /** * Retrieve the width and height (in pixels) of an image prior to displaying it * - * See https://facebook.github.io/react-native/docs/image.html#getsize + * See https://reactnative.dev/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 @@ -326,7 +340,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://facebook.github.io/react-native/docs/image.html#getsizewithheaders + * See https://reactnative.dev/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 @@ -337,7 +351,7 @@ Image.getSizeWithHeaders = getSizeWithHeaders; * Prefetches a remote image for later use by downloading it to the disk * cache * - * See https://facebook.github.io/react-native/docs/image.html#prefetch + * See https://reactnative.dev/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 @@ -347,7 +361,7 @@ Image.prefetch = prefetch; /** * Abort prefetch request. * - * See https://facebook.github.io/react-native/docs/image.html#abortprefetch + * See https://reactnative.dev/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 @@ -357,7 +371,7 @@ Image.abortPrefetch = abortPrefetch; /** * Perform cache interrogation. * - * See https://facebook.github.io/react-native/docs/image.html#querycache + * See https://reactnative.dev/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 @@ -367,7 +381,7 @@ Image.queryCache = queryCache; /** * Resolves an asset reference into an object. * - * See https://facebook.github.io/react-native/docs/image.html#resolveassetsource + * See https://reactnative.dev/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 5cd788918f7b40..22b28309076ee1 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'; -const RCTImageView = require('./ImageViewNativeComponent'); +import ImageViewNativeComponent from './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://facebook.github.io/react-native/docs/image.html + * See https://reactnative.dev/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>( - Image, -); +Image = React.forwardRef< + ImagePropsType, + React.ElementRef, +>(Image); Image.displayName = 'Image'; /** * Retrieve the width and height (in pixels) of an image prior to displaying it. * - * See https://facebook.github.io/react-native/docs/image.html#getsize + * See https://reactnative.dev/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 @@ -154,7 +155,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://facebook.github.io/react-native/docs/image.html#getsizewithheaders + * See https://reactnative.dev/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 @@ -165,7 +166,7 @@ Image.getSizeWithHeaders = getSizeWithHeaders; * Prefetches a remote image for later use by downloading it to the disk * cache. * - * See https://facebook.github.io/react-native/docs/image.html#prefetch + * See https://reactnative.dev/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 @@ -175,7 +176,7 @@ Image.prefetch = prefetch; /** * Performs cache interrogation. * - * See https://facebook.github.io/react-native/docs/image.html#querycache + * See https://reactnative.dev/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 @@ -185,7 +186,7 @@ Image.queryCache = queryCache; /** * Resolves an asset reference into an object. * - * See https://facebook.github.io/react-native/docs/image.html#resolveassetsource + * See https://reactnative.dev/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 @@ -205,6 +206,6 @@ const styles = StyleSheet.create({ module.exports = ((Image: any): React.AbstractComponent< ImagePropsType, - React.ElementRef, + React.ElementRef, > & ImageComponentStatics); diff --git a/Libraries/StyleSheet/NativeOrDynamicColorType.js b/Libraries/Image/ImageAnalyticsTagContext.js similarity index 54% rename from Libraries/StyleSheet/NativeOrDynamicColorType.js rename to Libraries/Image/ImageAnalyticsTagContext.js index a3a24dc7585f7d..ea458bf0c28043 100644 --- a/Libraries/StyleSheet/NativeOrDynamicColorType.js +++ b/Libraries/Image/ImageAnalyticsTagContext.js @@ -4,16 +4,18 @@ * 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 + * @format */ 'use strict'; -export type NativeOrDynamicColorType = { - semantic?: string, - dynamic?: { - light: ?(string | number | NativeOrDynamicColorType), - dark: ?(string | number | NativeOrDynamicColorType), - }, -}; +import * as React from 'react'; + +type ContextType = ?string; + +const Context: React.Context = React.createContext( + null, +); + +export default Context; diff --git a/Libraries/Image/ImageBackground.js b/Libraries/Image/ImageBackground.js index d9c849c5270e30..b4b6223b846b61 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 b3098a814debeb..8f8512e06cb861 100644 --- a/Libraries/Image/ImageProps.js +++ b/Libraries/Image/ImageProps.js @@ -14,7 +14,6 @@ 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< @@ -32,19 +31,19 @@ type IOSImageProps = $ReadOnly<{| /** * A static image to display while loading the image source. * - * See https://facebook.github.io/react-native/docs/image.html#defaultsource + * See https://reactnative.dev/docs/image.html#defaultsource */ defaultSource?: ?ImageSource, /** * Invoked when a partial load of the image is complete. * - * See https://facebook.github.io/react-native/docs/image.html#onpartialload + * See https://reactnative.dev/docs/image.html#onpartialload */ onPartialLoad?: ?() => void, /** * Invoked on download progress with `{nativeEvent: {loaded, total}}`. * - * See https://facebook.github.io/react-native/docs/image.html#onprogress + * See https://reactnative.dev/docs/image.html#onprogress */ onProgress?: ?( event: SyntheticEvent<$ReadOnly<{|loaded: number, total: number|}>>, @@ -65,34 +64,39 @@ export type ImageProps = {| /** * When true, indicates the image is an accessibility element. * - * See https://facebook.github.io/react-native/docs/image.html#accessible + * See https://reactnative.dev/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://facebook.github.io/react-native/docs/image.html#accessibilitylabel + * See https://reactnative.dev/docs/image.html#accessibilitylabel */ accessibilityLabel?: ?Stringish, /** * blurRadius: the blur radius of the blur filter added to the image * - * See https://facebook.github.io/react-native/docs/image.html#blurradius + * See https://reactnative.dev/docs/image.html#blurradius */ blurRadius?: ?number, /** - * See https://facebook.github.io/react-native/docs/image.html#capinsets + * See https://reactnative.dev/docs/image.html#capinsets */ capInsets?: ?EdgeInsetsProp, /** * Invoked on load error with `{nativeEvent: {error}}`. * - * See https://facebook.github.io/react-native/docs/image.html#onerror + * See https://reactnative.dev/docs/image.html#onerror */ onError?: ?( event: SyntheticEvent< @@ -106,7 +110,7 @@ export type ImageProps = {| * Invoked on mount and layout changes with * `{nativeEvent: {layout: {x, y, width, height}}}`. * - * See https://facebook.github.io/react-native/docs/image.html#onlayout + * See https://reactnative.dev/docs/image.html#onlayout */ onLayout?: ?(event: LayoutEvent) => mixed, @@ -114,50 +118,46 @@ export type ImageProps = {| /** * Invoked when load completes successfully. * - * See https://facebook.github.io/react-native/docs/image.html#onload + * See https://reactnative.dev/docs/image.html#onload */ onLoad?: ?(event: ImageLoadEvent) => void, /** * Invoked when load either succeeds or fails. * - * See https://facebook.github.io/react-native/docs/image.html#onloadend + * See https://reactnative.dev/docs/image.html#onloadend */ onLoadEnd?: ?() => void, /** * Invoked on load start. * - * See https://facebook.github.io/react-native/docs/image.html#onloadstart + * See https://reactnative.dev/docs/image.html#onloadstart */ onLoadStart?: ?() => void, /** - * See https://facebook.github.io/react-native/docs/image.html#resizemethod + * See https://reactnative.dev/docs/image.html#resizemethod */ resizeMethod?: ?('auto' | 'resize' | 'scale'), /** * The image source (either a remote URL or a local file resource). * - * See https://facebook.github.io/react-native/docs/image.html#source + * See https://reactnative.dev/docs/image.html#source */ source?: ?ImageSource, /** - * See https://facebook.github.io/react-native/docs/image.html#style + * See https://reactnative.dev/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://facebook.github.io/react-native/docs/image.html#resizemode + * See https://reactnative.dev/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://facebook.github.io/react-native/docs/image.html#testid + * See https://reactnative.dev/docs/image.html#testid */ testID?: ?string, diff --git a/Libraries/Image/ImageViewNativeComponent.js b/Libraries/Image/ImageViewNativeComponent.js index a2f9bd587677e3..b5dea64e6f19f7 100644 --- a/Libraries/Image/ImageViewNativeComponent.js +++ b/Libraries/Image/ImageViewNativeComponent.js @@ -12,8 +12,6 @@ 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'; @@ -22,6 +20,9 @@ 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, @@ -40,15 +41,16 @@ type NativeProps = $ReadOnly<{| |}>; let ImageViewNativeComponent; - if (global.RN$Bridgeless) { - ImageViewNativeComponent = codegenNativeComponent( - 'RCTImageView', - ); + ReactNativeViewConfigRegistry.register('RCTImageView', () => { + return ImageViewViewConfig; + }); + ImageViewNativeComponent = 'RCTImageView'; } else { ImageViewNativeComponent = requireNativeComponent( 'RCTImageView', ); } -module.exports = (ImageViewNativeComponent: HostComponent); +// flowlint-next-line unclear-type:off +export default ((ImageViewNativeComponent: any): HostComponent); diff --git a/Libraries/Image/ImageViewViewConfig.js b/Libraries/Image/ImageViewViewConfig.js new file mode 100644 index 00000000000000..5870038e97d584 --- /dev/null +++ b/Libraries/Image/ImageViewViewConfig.js @@ -0,0 +1,68 @@ +/** + * 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 9343787912e9b9..67c206d6ef0187 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) { + if (delayTimeUnclampedProp != nil && [delayTimeUnclampedProp floatValue] != 0.0f) { frameDuration = [delayTimeUnclampedProp floatValue]; } else { NSNumber *delayTimeProp = gifProperties[(NSString *)kCGImagePropertyGIFDelayTime]; diff --git a/Libraries/Image/RCTDisplayWeakRefreshable.h b/Libraries/Image/RCTDisplayWeakRefreshable.h new file mode 100644 index 00000000000000..a6a05059fb7a37 --- /dev/null +++ b/Libraries/Image/RCTDisplayWeakRefreshable.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#import + +#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 new file mode 100644 index 00000000000000..e8d8bfc3b88f76 --- /dev/null +++ b/Libraries/Image/RCTDisplayWeakRefreshable.m @@ -0,0 +1,29 @@ +/* + * 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 f2786873654dd4..3dda1241161715 100644 --- a/Libraries/Image/RCTImageEditingManager.mm +++ b/Libraries/Image/RCTImageEditingManager.mm @@ -92,10 +92,12 @@ @implementation RCTImageEditingManager }]; } -- (std::shared_ptr)getTurboModuleWithJsInvoker: - (std::shared_ptr)jsInvoker +- (std::shared_ptr) + getTurboModuleWithJsInvoker:(std::shared_ptr)jsInvoker + nativeInvoker:(std::shared_ptr)nativeInvoker + perfLogger:(id)perfLogger { - return std::make_shared(self, jsInvoker); + return std::make_shared(self, jsInvoker, nativeInvoker, perfLogger); } @end diff --git a/Libraries/Image/RCTImageLoader.h b/Libraries/Image/RCTImageLoader.h index 000d6ecbe98755..4272fbd13544e4 100644 --- a/Libraries/Image/RCTImageLoader.h +++ b/Libraries/Image/RCTImageLoader.h @@ -16,11 +16,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); - @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 9bb1f3d12666a6..483d46f19db126 100644 --- a/Libraries/Image/RCTImageLoader.mm +++ b/Libraries/Image/RCTImageLoader.mm @@ -7,6 +7,7 @@ #import #import +#import #import @@ -21,29 +22,19 @@ #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; @@ -78,6 +69,18 @@ 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 @@ -121,6 +124,7 @@ @implementation RCTImageLoader @synthesize maxConcurrentLoadingTasks = _maxConcurrentLoadingTasks; @synthesize maxConcurrentDecodingTasks = _maxConcurrentDecodingTasks; @synthesize maxConcurrentDecodingBytes = _maxConcurrentDecodingBytes; +@synthesize turboModuleLookupDelegate = _turboModuleLookupDelegate; RCT_EXPORT_MODULE() @@ -193,11 +197,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)]; } @@ -257,11 +261,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)]; } @@ -338,7 +342,6 @@ - (RCTImageLoaderCancellationBlock) loadImageWithURLRequest:(NSURLRequest *)imag scale:1 clipped:YES resizeMode:RCTResizeModeStretch - attribution:{} progressBlock:nil partialLoadBlock:nil completionBlock:callback]; @@ -353,15 +356,18 @@ - (RCTImageLoaderCancellationBlock)loadImageWithURLRequest:(NSURLRequest *)image partialLoadBlock:(RCTImageLoaderPartialLoadBlock)partialLoadBlock completionBlock:(RCTImageLoaderCompletionBlock)completionBlock { - return [self loadImageWithURLRequest:imageURLRequest - size:size - scale:scale - clipped:clipped - resizeMode:resizeMode - attribution:{} - progressBlock:progressBlock - partialLoadBlock:partialLoadBlock - completionBlock:completionBlock]; + RCTImageURLLoaderRequest *request = [self loadImageWithURLRequest:imageURLRequest + size:size + scale:scale + clipped:clipped + resizeMode:resizeMode + attribution:{} + progressBlock:progressBlock + partialLoadBlock:partialLoadBlock + completionBlock:completionBlock]; + return ^{ + [request cancel]; + }; } - (void)dequeueTasks @@ -436,14 +442,14 @@ - (NSInteger)activeTasks { * path taken. This is useful if you want to skip decoding, e.g. when preloading * the image, or retrieving metadata. */ -- (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 +- (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 { { NSMutableURLRequest *mutableRequest = [request mutableCopy]; @@ -475,6 +481,8 @@ - (RCTImageLoaderCancellationBlock)_loadImageOrDataWithURLRequest:(NSURLRequest 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; @@ -503,6 +511,7 @@ - (RCTImageLoaderCancellationBlock)_loadImageOrDataWithURLRequest:(NSURLRequest size:size scale:scale resizeMode:resizeMode + requestId:requestId attribution:attributionCopy progressHandler:progressHandler partialLoadHandler:partialLoadHandler @@ -510,15 +519,16 @@ - (RCTImageLoaderCancellationBlock)_loadImageOrDataWithURLRequest:(NSURLRequest completionHandler(error, image, nil); }]; } - return [loadHandler loadImageForURL:request.URL - size:size - scale:scale - resizeMode:resizeMode - progressHandler:progressHandler - partialLoadHandler:partialLoadHandler - completionHandler:^(NSError *error, UIImage *image) { - 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]; } // All access to URL cache must be serialized @@ -536,16 +546,18 @@ - (RCTImageLoaderCancellationBlock)_loadImageOrDataWithURLRequest:(NSURLRequest if (loadHandler) { dispatch_block_t cancelLoadLocal; if ([loadHandler conformsToProtocol:@protocol(RCTImageURLLoaderWithAttribution)]) { - 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); - }]; + 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; } else { cancelLoadLocal = [loadHandler loadImageForURL:request.URL size:size @@ -583,7 +595,7 @@ - (RCTImageLoaderCancellationBlock)_loadImageOrDataWithURLRequest:(NSURLRequest } }); - return ^{ + return [[RCTImageURLLoaderRequest alloc] initWithRequestId:requestId imageURL:request.URL cancellationBlock:^{ BOOL alreadyCancelled = atomic_fetch_or(cancelled.get(), 1); if (alreadyCancelled) { return; @@ -595,7 +607,7 @@ - (RCTImageLoaderCancellationBlock)_loadImageOrDataWithURLRequest:(NSURLRequest if (cancelLoadLocal) { cancelLoadLocal(); } - }; + }]; } - (RCTImageLoaderCancellationBlock)_loadURLRequest:(NSURLRequest *)request @@ -603,7 +615,8 @@ - (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)]) { + if (RCT_DEBUG && ![_bridge respondsToSelector:@selector(networking)] + && ![_turboModuleLookupDelegate moduleForName:"RCTNetworking"]) { RCTLogError(@"No suitable image URL loader found for %@. You may need to " " import the RCTNetwork library in order to load images.", request.URL.absoluteString); @@ -611,6 +624,9 @@ - (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]) { @@ -709,15 +725,17 @@ - (RCTImageLoaderCancellationBlock)_loadURLRequest:(NSURLRequest *)request }; } -- (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 +#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 { auto cancelled = std::make_shared>(0); __block dispatch_block_t cancelLoad = nil; @@ -777,15 +795,51 @@ - (RCTImageLoaderCancellationBlock)loadImageWithURLRequest:(NSURLRequest *)image [cancelLoadLock unlock]; }; - cancelLoad = [self _loadImageOrDataWithURLRequest:imageURLRequest - size:size - scale:scale - resizeMode:resizeMode - attribution:attribution - progressBlock:progressBlock - partialLoadBlock:partialLoadBlock - completionBlock:completionHandler]; - return cancellationBlock; + 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]; + } } - (RCTImageLoaderCancellationBlock)decodeImageData:(NSData *)data @@ -943,14 +997,15 @@ - (RCTImageLoaderCancellationBlock)getImageSizeForURLRequest:(NSURLRequest *)ima callback(error, size); }; - return [self _loadImageOrDataWithURLRequest:imageURLRequest - size:CGSizeZero - scale:1 - resizeMode:RCTResizeModeStretch - attribution:{} - progressBlock:NULL - partialLoadBlock:NULL - completionBlock:completion]; + RCTImageURLLoaderRequest *loaderRequest = [self _loadImageOrDataWithURLRequest:imageURLRequest + size:CGSizeZero + scale:1 + resizeMode:RCTResizeModeStretch + attribution:{} + progressBlock:NULL + partialLoadBlock:NULL + completionBlock:completion]; + return loaderRequest.cancellationBlock; } - (NSDictionary *)getImageCacheStatus:(NSArray *)requests @@ -1071,10 +1126,12 @@ - (void)cancelRequest:(id)requestToken } } -- (std::shared_ptr)getTurboModuleWithJsInvoker: - (std::shared_ptr)jsInvoker +- (std::shared_ptr) + getTurboModuleWithJsInvoker:(std::shared_ptr)jsInvoker + nativeInvoker:(std::shared_ptr)nativeInvoker + perfLogger:(id)perfLogger { - return std::make_shared(self, jsInvoker); + return std::make_shared(self, jsInvoker, nativeInvoker, perfLogger); } 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 3bd8604949f85e..1b73db119895b5 100644 --- a/Libraries/Image/RCTImageLoaderWithAttributionProtocol.h +++ b/Libraries/Image/RCTImageLoaderWithAttributionProtocol.h @@ -10,6 +10,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); + @protocol RCTImageLoaderWithAttributionProtocol // TODO (T61325135): Remove C++ checks @@ -18,15 +23,30 @@ * Same as the variant in RCTImageURLLoaderProtocol, but allows passing attribution * information that each image URL loader can process. */ -- (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; +- (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; #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 453590ee26dadb..5fd1691854b24d 100644 --- a/Libraries/Image/RCTImageStoreManager.mm +++ b/Libraries/Image/RCTImageStoreManager.mm @@ -236,10 +236,12 @@ - (void)getImageForTag:(NSString *)imageTag withBlock:(void (^)(UIImage *image)) }); } -- (std::shared_ptr)getTurboModuleWithJsInvoker: - (std::shared_ptr)jsInvoker +- (std::shared_ptr) + getTurboModuleWithJsInvoker:(std::shared_ptr)jsInvoker + nativeInvoker:(std::shared_ptr)nativeInvoker + perfLogger:(id)perfLogger { - return std::make_shared(self, jsInvoker); + return std::make_shared(self, jsInvoker, nativeInvoker, perfLogger); } @end diff --git a/Libraries/Image/RCTImageURLLoaderWithAttribution.h b/Libraries/Image/RCTImageURLLoaderWithAttribution.h index f5ee3e0c4f9e2c..9480b0e113cbb2 100644 --- a/Libraries/Image/RCTImageURLLoaderWithAttribution.h +++ b/Libraries/Image/RCTImageURLLoaderWithAttribution.h @@ -7,6 +7,8 @@ #import +#import // TODO(macOS ISS#2323203) + // TODO (T61325135): Remove C++ checks #ifdef __cplusplus namespace facebook { @@ -21,6 +23,17 @@ 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. @@ -31,15 +44,32 @@ 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. */ -- (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; +- (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; #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 new file mode 100644 index 00000000000000..61baa4aafee979 --- /dev/null +++ b/Libraries/Image/RCTImageURLLoaderWithAttribution.mm @@ -0,0 +1,30 @@ +/* + * 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 656f6196a32dbf..c2b0b1fe53ff22 100644 --- a/Libraries/Image/RCTImageView.mm +++ b/Libraries/Image/RCTImageView.mm @@ -146,7 +146,11 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge #if TARGET_OS_OSX // [TODO(macOS ISS#2323203) self.wantsLayer = YES; #endif -#if !TARGET_OS_OSX +#if !TARGET_OS_OSX // [TODO(macOS ISS#2323203) + _imageView = [[RCTUIImageViewAnimated alloc] init]; + _imageView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + [self addSubview:_imageView]; + NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; [center addObserver:self selector:@selector(clearImageIfDetached) @@ -156,10 +160,16 @@ - (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 - _imageView = [[RCTUIImageViewAnimated alloc] init]; - _imageView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; - [self addSubview:_imageView]; +#endif // ]TODO(macOS ISS#2323203) } return self; } @@ -430,18 +440,19 @@ - (void)reloadImage id imageLoader = [_bridge moduleForName:@"ImageLoader" lazilyLoadIfNecessary:YES]; - _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]; + 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; } else { [self clearImage]; } diff --git a/Libraries/Image/RCTLocalAssetImageLoader.mm b/Libraries/Image/RCTLocalAssetImageLoader.mm index 7a550581c4d3a7..8669ad3615d82c 100644 --- a/Libraries/Image/RCTLocalAssetImageLoader.mm +++ b/Libraries/Image/RCTLocalAssetImageLoader.mm @@ -49,28 +49,19 @@ - (RCTImageLoaderCancellationBlock)loadImageForURL:(NSURL *)imageURL partialLoadHandler:(RCTImageLoaderPartialLoadBlock)partialLoadHandler completionHandler:(RCTImageLoaderCompletionBlock)completionHandler { - __block auto cancelled = std::make_shared>(false); - RCTExecuteOnMainQueue(^{ - if (cancelled->load()) { - return; + UIImage *image = RCTImageFromLocalAssetURL(imageURL); + if (image) { + if (progressHandler) { + progressHandler(1, 1); } - - 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); - }; + completionHandler(nil, image); + } else { + NSString *message = [NSString stringWithFormat:@"Could not find image %@", imageURL]; + RCTLogWarn(@"%@", message); + completionHandler(RCTErrorWithMessage(message), nil); + } + + return nil; } @end diff --git a/Libraries/Image/RCTUIImageViewAnimated.m b/Libraries/Image/RCTUIImageViewAnimated.m index cd74208bdd43dd..0f3bd362c3ebc0 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 = [CADisplayLink displayLinkWithTarget:[RCTWeakProxy weakProxyWithTarget:self] selector:@selector(displayDidRefresh:)]; + _displayLink = [RCTDisplayWeakRefreshable displayLinkWithWeakRefreshable:self]; 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 18270b5379e725..3cfb96ee430476 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 = '2018.10.22.00' +folly_version = '2020.01.13.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 = "http://facebook.github.io/react-native/" - s.documentation_url = "https://facebook.github.io/react-native/docs/image" + s.homepage = "https://reactnative.dev/" + s.documentation_url = "https://reactnative.dev/docs/image" s.license = package["license"] s.author = "Facebook, Inc. and its affiliates" - s.platforms = { :ios => "9.0", :tvos => "9.2", :osx => "10.13" } # TODO(macOS GH#214) + 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.source = source s.source_files = "*.{m,mm}" @@ -43,6 +43,7 @@ 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 287e0657beb5ac..ee752bd7322c4a 100644 --- a/Libraries/Image/__tests__/resolveAssetSource-test.js +++ b/Libraries/Image/__tests__/resolveAssetSource-test.js @@ -143,6 +143,29 @@ 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', () => { @@ -175,6 +198,29 @@ 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 564c77d1c0b2b3..739c9ca4586ab0 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 - // http://facebook.github.io/react-native/docs/images.html#why-not-automatically-size-everything + // https://reactnative.dev/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: * - * http://facebook.github.io/react-native/docs/images.html + * https://reactnative.dev/docs/images.html * */ function nativeImageSource(spec: NativeImageSourceSpec): ImageURISource { diff --git a/Libraries/Inspector/Inspector.js b/Libraries/Inspector/Inspector.js index a68160ad86dfcd..2394a3dded98a1 100644 --- a/Libraries/Inspector/Inspector.js +++ b/Libraries/Inspector/Inspector.js @@ -18,14 +18,27 @@ 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 = { - getInspectorDataForViewTag: (viewTag: number) => Object, - ... + rendererConfig: { + getInspectorDataForViewAtPoint: ( + inspectedView: ?HostRef, + locationX: number, + locationY: number, + callback: Function, + ) => void, + ... + }, }; const hook = window.__REACT_DEVTOOLS_GLOBAL_HOOK__; @@ -34,7 +47,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.js'); +const viewConfig = require('../Components/View/ReactNativeViewViewConfig'); hook.nativeStyleEditorValidAttributes = Object.keys( viewConfig.validAttributes.style, ); @@ -48,27 +61,35 @@ function findRenderers(): $ReadOnlyArray { return allRenderers; } -function getInspectorDataForViewTag(touchedViewTag: number) { +function getInspectorDataForViewAtPoint( + inspectedView: ?HostRef, + locationX: number, + locationY: number, + callback: (viewData: TouchedViewDataAtPoint) => void, +) { + // Check all renderers for inspector data. for (let i = 0; i < renderers.length; i++) { const renderer = renderers[i]; - if ( - Object.prototype.hasOwnProperty.call( - renderer, - 'getInspectorDataForViewTag', - ) - ) { - const inspectorData = renderer.getInspectorDataForViewTag(touchedViewTag); - if (inspectorData.hierarchy.length > 0) { - return inspectorData; - } + 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); + } + }, + ); } } - throw new Error('Expected to find at least one React renderer.'); } + class Inspector extends React.Component< { - inspectedViewTag: ?number, - onRequestRerenderApp: (callback: (tag: ?number) => void) => void, + inspectedView: ?HostRef, + onRequestRerenderApp: (callback: (instance: ?HostRef) => void) => void, ... }, { @@ -79,13 +100,14 @@ class Inspector extends React.Component< selection: ?number, perfing: boolean, inspected: any, - inspectedViewTag: any, + inspectedView: ?HostRef, networking: boolean, ... }, > { _hideTimeoutID: TimeoutID | null = null; _subs: ?Array<() => void>; + _setTouchedViewData: ?(TouchedViewDataAtPoint) => void; constructor(props: Object) { super(props); @@ -98,7 +120,7 @@ class Inspector extends React.Component< perfing: false, inspected: null, selection: null, - inspectedViewTag: this.props.inspectedViewTag, + inspectedView: this.props.inspectedView, networking: false, }; } @@ -116,10 +138,11 @@ 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({inspectedViewTag: newProps.inspectedViewTag}); + this.setState({inspectedView: newProps.inspectedView}); } _attachToDevtools = (agent: Object) => { @@ -147,11 +170,7 @@ class Inspector extends React.Component< _onAgentShowNativeHighlight = node => { clearTimeout(this._hideTimeoutID); - if (typeof node !== 'number') { - node = ReactNative.findNodeHandle(node); - } - - UIManager.measure(node, (x, y, width, height, left, top) => { + node.measure((x, y, width, height, left, top) => { this.setState({ hierarchy: [], inspected: { @@ -197,30 +216,50 @@ class Inspector extends React.Component< }); } - 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, - ); - - 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, + 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), + ); + } + + 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; + } }, - }); + ); } setPerfing(val: boolean) { @@ -241,8 +280,8 @@ class Inspector extends React.Component< setTouchTargeting(val: boolean) { Touchable.TOUCH_TARGET_DEBUG = val; - this.props.onRequestRerenderApp(inspectedViewTag => { - this.setState({inspectedViewTag}); + this.props.onRequestRerenderApp(inspectedView => { + this.setState({inspectedView}); }); } @@ -265,8 +304,7 @@ class Inspector extends React.Component< {this.state.inspecting && ( )} diff --git a/Libraries/Inspector/InspectorOverlay.js b/Libraries/Inspector/InspectorOverlay.js index 878ee5e6ca1591..51a1ce55607cf8 100644 --- a/Libraries/Inspector/InspectorOverlay.js +++ b/Libraries/Inspector/InspectorOverlay.js @@ -14,7 +14,6 @@ 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'; @@ -27,24 +26,14 @@ type Inspected = $ReadOnly<{| type Props = $ReadOnly<{| inspected?: Inspected, - inspectedViewTag?: ?number, - onTouchViewTag: (tag: number, frame: Object, pointerY: number) => mixed, + onTouchPoint: (locationX: number, locationY: number) => void, |}>; class InspectorOverlay extends React.Component { findViewForTouchEvent: (e: PressEvent) => void = (e: PressEvent) => { const {locationX, locationY} = e.nativeEvent.touches[0]; - UIManager.findSubviewIn( - this.props.inspectedViewTag, - [locationX, locationY], - (nativeViewTag, left, top, width, height) => { - this.props.onTouchViewTag( - nativeViewTag, - {left, top, width, height}, - locationY, - ); - }, - ); + + this.props.onTouchPoint(locationX, locationY); }; shouldSetResponser: (e: PressEvent) => boolean = (e: PressEvent): boolean => { diff --git a/Libraries/LayoutAnimation/LayoutAnimation.js b/Libraries/LayoutAnimation/LayoutAnimation.js index 4cf9b0db4c4708..ba4632eb712404 100644 --- a/Libraries/LayoutAnimation/LayoutAnimation.js +++ b/Libraries/LayoutAnimation/LayoutAnimation.js @@ -33,7 +33,7 @@ type AnimationConfig = $ReadOnly<{| property?: Property, |}>; -type LayoutAnimationConfig = $ReadOnly<{| +export type LayoutAnimationConfig = $ReadOnly<{| duration: number, create?: AnimationConfig, update?: AnimationConfig, diff --git a/Libraries/Linking/Linking.js b/Libraries/Linking/Linking.js index 8c7dfa9b0c09d2..dd6fc76f152fe4 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://facebook.github.io/react-native/docs/linking.html + * See https://reactnative.dev/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://facebook.github.io/react-native/docs/linking.html#addeventlistener + * See https://reactnative.dev/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://facebook.github.io/react-native/docs/linking.html#removeeventlistener + * See https://reactnative.dev/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://facebook.github.io/react-native/docs/linking.html#openurl + * See https://reactnative.dev/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://facebook.github.io/react-native/docs/linking.html#canopenurl + * See https://reactnative.dev/docs/linking.html#canopenurl */ canOpenURL(url: string): Promise { this._validateURL(url); @@ -71,7 +71,7 @@ class Linking extends NativeEventEmitter { /** * Open app settings. * - * See https://facebook.github.io/react-native/docs/linking.html#opensettings + * See https://reactnative.dev/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://facebook.github.io/react-native/docs/linking.html#getinitialurl + * See https://reactnative.dev/docs/linking.html#getinitialurl */ getInitialURL(): Promise { return Platform.OS === 'android' @@ -96,7 +96,7 @@ class Linking extends NativeEventEmitter { * * @platform android * - * See https://facebook.github.io/react-native/docs/linking.html#sendintent + * See https://reactnative.dev/docs/linking.html#sendintent */ sendIntent( action: string, diff --git a/Libraries/LinkingIOS/RCTLinkingManager.mm b/Libraries/LinkingIOS/RCTLinkingManager.mm index 85b9aa7a0bd0ec..0f14b40d1b70d3 100644 --- a/Libraries/LinkingIOS/RCTLinkingManager.mm +++ b/Libraries/LinkingIOS/RCTLinkingManager.mm @@ -99,30 +99,8 @@ - (void)handleOpenURLNotification:(NSNotification *)notification resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) { - 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) { + [RCTSharedApplication() openURL:URL options:@{} completionHandler:^(BOOL success) { + if (success) { resolve(@YES); } else { #if TARGET_OS_SIMULATOR @@ -138,9 +116,7 @@ - (void)handleOpenURLNotification:(NSNotification *)notification reject(RCTErrorUnspecified, [NSString stringWithFormat:@"Unable to open URL: %@", URL], nil); #endif } -#endif - } - + }]; } RCT_EXPORT_METHOD(canOpenURL:(NSURL *)URL @@ -193,25 +169,13 @@ - (void)handleOpenURLNotification:(NSNotification *)notification reject:(__unused RCTPromiseRejectBlock)reject) { NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString]; - 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 - } + [RCTSharedApplication() openURL:url options:@{} completionHandler:^(BOOL success) { + if (success) { + resolve(nil); + } else { + reject(RCTErrorUnspecified, @"Unable to open app settings", nil); + } + }]; } RCT_EXPORT_METHOD(sendIntent:(NSString *)action @@ -222,9 +186,12 @@ - (void)handleOpenURLNotification:(NSNotification *)notification RCTLogError(@"Not implemented: %@", NSStringFromSelector(_cmd)); } -- (std::shared_ptr)getTurboModuleWithJsInvoker:(std::shared_ptr)jsInvoker +- (std::shared_ptr) + getTurboModuleWithJsInvoker:(std::shared_ptr)jsInvoker + nativeInvoker:(std::shared_ptr)nativeInvoker + perfLogger:(id)perfLogger { - return std::make_shared(self, jsInvoker); + return std::make_shared(self, jsInvoker, nativeInvoker, perfLogger); } @end diff --git a/Libraries/LinkingIOS/React-RCTLinking.podspec b/Libraries/LinkingIOS/React-RCTLinking.podspec index 73df19b95a1aa2..a7748dc8bb78fd 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 = '2018.10.22.00' +folly_version = '2020.01.13.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 = "http://facebook.github.io/react-native/" - s.documentation_url = "https://facebook.github.io/react-native/docs/linking" + s.homepage = "https://reactnative.dev/" + s.documentation_url = "https://reactnative.dev/docs/linking" s.license = package["license"] s.author = "Facebook, Inc. and its affiliates" - s.platforms = { :ios => "9.0", :tvos => "9.2", :osx => "10.13" } # TODO(macOS GH#214) + 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.source = source s.source_files = "*.{m,mm}" @@ -46,4 +46,5 @@ 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 808738ebd9a666..806c69f210cf2d 100644 --- a/Libraries/Lists/FlatList.js +++ b/Libraries/Lists/FlatList.js @@ -19,9 +19,7 @@ const StyleSheet = require('../StyleSheet/StyleSheet'); const invariant = require('invariant'); -import ScrollView, { - type ScrollResponderType, -} from '../Components/ScrollView/ScrollView'; +import {type ScrollResponderType} from '../Components/ScrollView/ScrollView'; import type {ScrollViewNativeComponentType} from '../Components/ScrollView/ScrollViewNativeComponentType.js'; import type {ViewStyleProp} from '../StyleSheet/StyleSheet'; import type { @@ -376,14 +374,7 @@ class FlatList extends React.PureComponent, void> { | ?React.ElementRef | ?React.ElementRef { if (this._listRef) { - const scrollRef = this._listRef.getScrollRef(); - if (scrollRef != null) { - if (scrollRef instanceof ScrollView) { - return scrollRef.getNativeScrollRef(); - } else { - return scrollRef; - } - } + return this._listRef.getScrollRef(); } } @@ -412,10 +403,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 b6322986902fb9..a20d4af954d9c8 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 [``](/react-native/docs/flatlist.html). + * The actual data to render, akin to the `data` prop in [``](https://reactnative.dev/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 - * [``](/react-native/docs/flatlist.html). + * [``](https://reactnative.dev/docs/flatlist.html). * * Simple Examples: * diff --git a/Libraries/Lists/ViewabilityHelper.js b/Libraries/Lists/ViewabilityHelper.js index 1ea6b880dad9fc..48425b00707776 100644 --- a/Libraries/Lists/ViewabilityHelper.js +++ b/Libraries/Lists/ViewabilityHelper.js @@ -75,9 +75,6 @@ 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(); @@ -92,6 +89,9 @@ 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,6 +227,9 @@ 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, @@ -234,6 +237,9 @@ 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 1b416d5c6158d7..240589ebd22bee 100644 --- a/Libraries/Lists/VirtualizedList.js +++ b/Libraries/Lists/VirtualizedList.js @@ -373,9 +373,21 @@ 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 [``](/react-native/docs/flatlist.html) - * and [``](/react-native/docs/sectionlist.html) components, which are also better + * Base implementation for the more convenient [``](https://reactnative.dev/docs/flatlist.html) + * and [``](https://reactnative.dev/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. * @@ -656,6 +668,10 @@ 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({ @@ -668,6 +684,10 @@ class VirtualizedList extends React.PureComponent { getNestedChildState: PropTypes.func, registerAsNestedChild: PropTypes.func, unregisterAsNestedChild: PropTypes.func, + debugInfo: PropTypes.shape({ + listKey: PropTypes.string, + cellKey: PropTypes.string, + }), }), }; @@ -710,6 +730,7 @@ class VirtualizedList extends React.PureComponent { cellKey: string, key: string, ref: VirtualizedList, + parentDebugInfo: ListDebugInfo, ... }) => ?ChildListState, unregisterAsNestedChild: ({ @@ -717,6 +738,7 @@ class VirtualizedList extends React.PureComponent { state: ChildListState, ... }) => void, + debugInfo: ListDebugInfo, ... }, |} { @@ -728,6 +750,7 @@ class VirtualizedList extends React.PureComponent { getNestedChildState: this._getNestedChildState, registerAsNestedChild: this._registerAsNestedChild, unregisterAsNestedChild: this._unregisterAsNestedChild, + debugInfo: this._getDebugInfo(), }, }; } @@ -739,6 +762,21 @@ 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; }; @@ -764,6 +802,7 @@ 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 @@ -771,13 +810,18 @@ 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.', + '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, + }), ); } this._nestedChildLists.set(childList.key, { @@ -849,7 +893,7 @@ class VirtualizedList extends React.PureComponent { if (this._isNestedWithSameOrientation()) { const storedState = this.context.virtualizedList.getNestedChildState( - this.props.listKey || this._getCellKey(), + this._getListKey(), ); if (storedState) { initialState = storedState; @@ -865,8 +909,13 @@ class VirtualizedList extends React.PureComponent { if (this._isNestedWithSameOrientation()) { this.context.virtualizedList.registerAsNestedChild({ cellKey: this._getCellKey(), - key: this.props.listKey || this._getCellKey(), + key: this._getListKey(), 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, }); } } @@ -874,7 +923,7 @@ class VirtualizedList extends React.PureComponent { componentWillUnmount() { if (this._isNestedWithSameOrientation()) { this.context.virtualizedList.unregisterAsNestedChild({ - key: this.props.listKey || this._getCellKey(), + key: this._getListKey(), state: { first: this.state.first, last: this.state.last, @@ -1173,7 +1222,7 @@ class VirtualizedList extends React.PureComponent { ); cells.push( { this._frames[cellKey].inLayout = true; } - 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._triggerRemeasureForChildListsInCell(cellKey); this._computeBlankness(); this._updateViewableItems(this.props.data); @@ -1439,6 +1480,18 @@ 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 @@ -1449,10 +1502,7 @@ 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() - .getNativeScrollRef(), + this.context.virtualizedList.getOutermostParentListRef().getScrollRef(), (x, y, width, height) => { this._offsetFromParentVirtualizedList = this._selectOffset({x, y}); this._scrollMetrics.contentLength = this._selectLength({ @@ -1499,7 +1549,12 @@ 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); }; @@ -1895,12 +1950,13 @@ 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 (this._scrollMetrics.visibleLength) { + if (visibleLength > 0 && contentLength > 0) { // 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, @@ -1915,7 +1971,6 @@ 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 @@ -1959,6 +2014,13 @@ class VirtualizedList extends React.PureComponent { } } } + if ( + newState != null && + newState.first === state.first && + newState.last === state.last + ) { + newState = null; + } return newState; }); }; @@ -2295,6 +2357,31 @@ 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 5be4c1eebcd22a..912289cbf0043d 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,6 +97,7 @@ module.exports = { />, // EverythingIsFine } data={data} />, diff --git a/Libraries/Lists/__flowtests__/SectionList-flowtest.js b/Libraries/Lists/__flowtests__/SectionList-flowtest.js index 79a92a88a39098..9425bacd5cf8a5 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,9 +94,6 @@ 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: [ @@ -115,7 +112,6 @@ module.exports = { const sections = [ { key: 'a', - // $FlowExpectedError - section has bad meta data `fooNumber` field of type string fooNumber: 'string', data: [ { @@ -129,6 +125,8 @@ module.exports = { ); diff --git a/Libraries/Lists/__tests__/VirtualizedList-test.js b/Libraries/Lists/__tests__/VirtualizedList-test.js index 5cee6bca2cbcdc..e99215a2d867d1 100644 --- a/Libraries/Lists/__tests__/VirtualizedList-test.js +++ b/Libraries/Lists/__tests__/VirtualizedList-test.js @@ -69,11 +69,12 @@ 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; } - console.errorDebug(message); + consoleError(message); }); const componentFactory = () => @@ -299,7 +300,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(Function); + expect(scrollRef.scrollTo).toBeInstanceOf(jest.fn().constructor); }); it('getScrollRef for case where it returns a View', () => { @@ -334,4 +335,125 @@ 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 83e64356facc75..1076d26661f448 100644 --- a/Libraries/LogBox/Data/LogBoxData.js +++ b/Libraries/LogBox/Data/LogBoxData.js @@ -60,6 +60,7 @@ 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 f2f64f5647585e..2d019518306d76 100644 --- a/Libraries/LogBox/Data/LogBoxLog.js +++ b/Libraries/LogBox/Data/LogBoxLog.js @@ -26,6 +26,7 @@ export type LogLevel = 'warn' | 'error' | 'fatal' | 'syntax'; export type LogBoxLogData = $ReadOnly<{| level: LogLevel, + type?: ?string, message: Message, stack: Stack, category: string, @@ -36,6 +37,7 @@ export type LogBoxLogData = $ReadOnly<{| class LogBoxLog { message: Message; + type: ?string; category: Category; componentStack: ComponentStack; stack: Stack; @@ -55,6 +57,7 @@ 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 f4025dcc176d06..30c489a3445a49 100644 --- a/Libraries/LogBox/Data/__tests__/parseLogBoxLog-test.js +++ b/Libraries/LogBox/Data/__tests__/parseLogBoxLog-test.js @@ -143,6 +143,32 @@ 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([ @@ -272,6 +298,74 @@ 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: ` @@ -411,7 +505,7 @@ Please follow the instructions at: fburl.com/rn-remote-assets`, }); }); - it('parses a error log', () => { + it('parses an error log with `error.componentStack`', () => { const error = { id: 0, isFatal: false, @@ -464,6 +558,59 @@ 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 a65bd5d531ee51..0d7c83d3755270 100644 --- a/Libraries/LogBox/Data/parseLogBoxLog.js +++ b/Libraries/LogBox/Data/parseLogBoxLog.js @@ -16,7 +16,8 @@ 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 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; export type ExtendedExceptionData = ExceptionData & { isComponentError: boolean, @@ -46,7 +47,7 @@ export type ComponentStack = $ReadOnlyArray; const SUBSTITUTION = UTFSequence.BOM + '%s'; -export function parseCategory( +export function parseInterpolation( args: $ReadOnlyArray, ): $ReadOnly<{| category: Category, @@ -151,6 +152,38 @@ 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. @@ -206,21 +239,50 @@ export function parseLogBoxException( }; } - const level = message.match(/^TransformError /) - ? 'syntax' - : error.isFatal || error.isComponentError - ? 'fatal' - : 'error'; + 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]), + }; + } + 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: level, + level: 'error', stack: error.stack, isComponentError: error.isComponentError, - componentStack: - error.componentStack != null - ? parseComponentStack(error.componentStack) - : [], - ...parseCategory([message]), + ...parseLogBoxLog([message]), }; } @@ -253,7 +315,13 @@ 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)) { + 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)); + } + componentStack = parseComponentStack(arg); } else { argsWithoutComponentStack.push(arg); @@ -262,7 +330,7 @@ export function parseLogBoxLog( } return { - ...parseCategory(argsWithoutComponentStack), + ...parseInterpolation(argsWithoutComponentStack), componentStack, }; } diff --git a/Libraries/LogBox/LogBox.js b/Libraries/LogBox/LogBox.js index b231b9396ad184..913dfa8daa3e58 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} from './Data/parseLogBoxLog'; +import {parseLogBoxLog, parseInterpolation} from './Data/parseLogBoxLog'; import type {IgnorePattern} from './Data/LogBoxData'; @@ -37,15 +37,14 @@ if (__DEV__) { }; LogBox = { - // TODO: deprecated, replace with ignoreLogs - ignoreWarnings: (patterns: $ReadOnlyArray): void => { - LogBox.ignoreLogs(patterns); - }, - ignoreLogs: (patterns: $ReadOnlyArray): void => { LogBoxData.addIgnorePatterns(patterns); }, + ignoreAllLogs: (value?: ?boolean): void => { + LogBoxData.setDisabled(value == null ? true : value); + }, + uninstall: (): void => { errorImpl = error; warnImpl = warn; @@ -64,18 +63,26 @@ if (__DEV__) { registerWarning(...args); }; - if ((console: any).disableLogBox === true) { + if ((console: any).disableYellowBox === 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, 'disableLogBox', { + (Object.defineProperty: any)(console, 'disableYellowBox', { configurable: true, get: () => LogBoxData.isDisabled(), - set: value => LogBoxData.setDisabled(value), + 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.', + ); + }, }); if (Platform.isTesting) { - (console: any).disableLogBox = true; + LogBoxData.setDisabled(true); } RCTLog.setWarningHandler((...args) => { @@ -95,6 +102,12 @@ 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); @@ -103,14 +116,12 @@ if (__DEV__) { // Be sure to pass LogBox warnings through. warn.call(console, ...args); - if (!LogBoxData.isLogBoxErrorMessage(message.content)) { - LogBoxData.addLog({ - level: 'warn', - category, - message, - componentStack, - }); - } + LogBoxData.addLog({ + level: 'warn', + category, + message, + componentStack, + }); } } } catch (err) { @@ -119,9 +130,21 @@ 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 and skip. + // 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. error.call(console, ...args); return; } @@ -144,17 +167,17 @@ if (__DEV__) { const {category, message, componentStack} = parseLogBoxLog(args); if (!LogBoxData.isMessageIgnored(message.content)) { - // Be sure to pass LogBox errors through. - error.call(console, ...args); - - if (!LogBoxData.isLogBoxErrorMessage(message.content)) { - LogBoxData.addLog({ - level, - category, - message, - componentStack, - }); - } + // 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, + }); } } catch (err) { LogBoxData.reportLogBoxError(err); @@ -162,12 +185,11 @@ if (__DEV__) { }; } else { LogBox = { - // TODO: deprecated, replace with ignoreLogs - ignoreWarnings: (patterns: $ReadOnlyArray): void => { + ignoreLogs: (patterns: $ReadOnlyArray): void => { // Do nothing. }, - ignoreLogs: (patterns: $ReadOnlyArray): void => { + ignoreAllLogs: (value?: ?boolean): void => { // Do nothing. }, @@ -182,9 +204,8 @@ 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 616a88ca47a61e..101b14258264b2 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) || Infinity; + const whitespaceLength = (match && match[0]?.length) || 0; if (whitespaceLength < commonWhitespaceLength) { commonWhitespaceLength = whitespaceLength; } diff --git a/Libraries/LogBox/UI/LogBoxInspector.js b/Libraries/LogBox/UI/LogBoxInspector.js index 62900e5b47ca2d..9c2983264b04b7 100644 --- a/Libraries/LogBox/UI/LogBoxInspector.js +++ b/Libraries/LogBox/UI/LogBoxInspector.js @@ -102,6 +102,7 @@ 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 b9e8f483c1dd31..2c4e1036a17761 100644 --- a/Libraries/LogBox/UI/LogBoxInspectorCodeFrame.js +++ b/Libraries/LogBox/UI/LogBoxInspectorCodeFrame.js @@ -87,9 +87,19 @@ function AppInfo() { } return ( - - {appInfo.appVersion} ({appInfo.engine}) - + + + {appInfo.appVersion} ({appInfo.engine}) + + ); } @@ -98,8 +108,14 @@ 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 88ee3374bde603..3ca8ebfcd9e105 100644 --- a/Libraries/LogBox/UI/LogBoxInspectorSourceMapStatus.js +++ b/Libraries/LogBox/UI/LogBoxInspectorSourceMapStatus.js @@ -47,6 +47,9 @@ 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 bb668d391e63c6..26264ecb5e1cb7 100644 --- a/Libraries/LogBox/UI/LogBoxNotification.js +++ b/Libraries/LogBox/UI/LogBoxNotification.js @@ -59,6 +59,8 @@ 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 3a8b8b933c4d29..8259c01b67d4ff 100644 --- a/Libraries/LogBox/UI/__tests__/__snapshots__/LogBoxInspector-test.js.snap +++ b/Libraries/LogBox/UI/__tests__/__snapshots__/LogBoxInspector-test.js.snap @@ -34,6 +34,7 @@ exports[`LogBoxContainer should render fatal with selectedIndex 2 1`] = ` "stack": null, "status": "NONE", }, + "type": undefined, } } onRetry={[Function]} @@ -82,6 +83,7 @@ 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 6fc9fda0cf8d2c..c847ccd0872e63 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(() => { @@ -44,27 +45,51 @@ describe('LogBox', () => { console.warn = warn; }); - it('can set `disableLogBox` after installing', () => { - expect(console.disableLogBox).toBe(undefined); + it('can call `ignoreAllLogs` after installing', () => { + expect(LogBoxData.isDisabled()).toBe(false); LogBox.install(); - expect(console.disableLogBox).toBe(false); expect(LogBoxData.isDisabled()).toBe(false); - console.disableLogBox = true; + LogBox.ignoreAllLogs(true); - expect(console.disableLogBox).toBe(true); expect(LogBoxData.isDisabled()).toBe(true); }); - it('can set `disableLogBox` before installing', () => { - expect(console.disableLogBox).toBe(undefined); + it('can call `ignoreAllLogs` before installing', () => { + expect(LogBoxData.isDisabled()).toBe(false); + + LogBox.ignoreAllLogs(true); + + expect(LogBoxData.isDisabled()).toBe(true); - console.disableLogBox = true; LogBox.install(); - expect(console.disableLogBox).toBe(true); + 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(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 7182e10482b899..99c5f74e76ad37 100644 --- a/Libraries/LogBox/__tests__/__snapshots__/LogBoxInspectorContainer-test.js.snap +++ b/Libraries/LogBox/__tests__/__snapshots__/LogBoxInspectorContainer-test.js.snap @@ -40,6 +40,7 @@ exports[`LogBoxNotificationContainer should render both an error and warning not "stack": null, "status": "NONE", }, + "type": undefined, } } onPressDismiss={[Function]} @@ -76,6 +77,7 @@ exports[`LogBoxNotificationContainer should render both an error and warning not "stack": null, "status": "NONE", }, + "type": undefined, } } onPressDismiss={[Function]} @@ -134,6 +136,7 @@ exports[`LogBoxNotificationContainer should render the latest error notification "stack": null, "status": "NONE", }, + "type": undefined, } } onPressDismiss={[Function]} @@ -184,6 +187,7 @@ 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 2c2253ad83b26b..c512ee317f257c 100644 --- a/Libraries/LogBox/__tests__/__snapshots__/LogBoxNotificationContainer-test.js.snap +++ b/Libraries/LogBox/__tests__/__snapshots__/LogBoxNotificationContainer-test.js.snap @@ -32,6 +32,7 @@ exports[`LogBoxNotificationContainer should render inspector with logs, even whe "stack": null, "status": "NONE", }, + "type": undefined, }, LogBoxLog { "category": "Some kind of message (latest)", @@ -50,6 +51,7 @@ 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 426988d33b3602..9217732197bfb2 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://facebook.github.io/react-native/docs/modal.html + * See https://reactnative.dev/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://facebook.github.io/react-native/docs/modal.html#animationtype + * See https://reactnative.dev/docs/modal.html#animationtype */ animationType?: ?('none' | 'slide' | 'fade'), /** * The `presentationStyle` prop controls how the modal appears. * - * See https://facebook.github.io/react-native/docs/modal.html#presentationstyle + * See https://reactnative.dev/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://facebook.github.io/react-native/docs/modal.html#transparent + * See https://reactnative.dev/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://facebook.github.io/react-native/docs/modal.html#transparent + * See https://reactnative.dev/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 inly on Android. + * This prop works only on Android. * - * See https://facebook.github.io/react-native/docs/modal.html#hardwareaccelerated + * See https://reactnative.dev/docs/modal.html#hardwareaccelerated */ hardwareAccelerated?: ?boolean, /** * The `visible` prop determines whether your modal is visible. * - * See https://facebook.github.io/react-native/docs/modal.html#visible + * See https://reactnative.dev/docs/modal.html#visible */ visible?: ?boolean, @@ -108,7 +108,7 @@ export type Props = $ReadOnly<{| * * This is required on Apple TV and Android. * - * See https://facebook.github.io/react-native/docs/modal.html#onrequestclose + * See https://reactnative.dev/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://facebook.github.io/react-native/docs/modal.html#onshow + * See https://reactnative.dev/docs/modal.html#onshow */ onShow?: ?DirectEventHandler, @@ -124,19 +124,14 @@ export type Props = $ReadOnly<{| * The `onDismiss` prop allows passing a function that will be called once * the modal has been dismissed. * - * See https://facebook.github.io/react-native/docs/modal.html#ondismiss + * See https://reactnative.dev/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://facebook.github.io/react-native/docs/modal.html#supportedorientations + * See https://reactnative.dev/docs/modal.html#supportedorientations */ supportedOrientations?: ?$ReadOnlyArray< | 'portrait' @@ -149,7 +144,7 @@ export type Props = $ReadOnly<{| /** * The `onOrientationChange` callback is called when the orientation changes while the modal is being displayed. * - * See https://facebook.github.io/react-native/docs/modal.html#onorientationchange + * See https://reactnative.dev/docs/modal.html#onorientationchange */ onOrientationChange?: ?DirectEventHandler, |}>; @@ -233,14 +228,7 @@ class Modal extends React.Component { backgroundColor: this.props.transparent ? 'transparent' : 'white', }; - 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 animationType = this.props.animationType || 'none'; let presentationStyle = this.props.presentationStyle; if (!presentationStyle) { diff --git a/Libraries/Modal/RCTModalHostViewNativeComponent.js b/Libraries/Modal/RCTModalHostViewNativeComponent.js index 907acd07d1a4c2..ebc154146c7f54 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://facebook.github.io/react-native/docs/modal.html#animationtype + * See https://reactnative.dev/docs/modal.html#animationtype */ animationType?: WithDefault<'none' | 'slide' | 'fade', 'none'>, /** * The `presentationStyle` prop controls how the modal appears. * - * See https://facebook.github.io/react-native/docs/modal.html#presentationstyle + * See https://reactnative.dev/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://facebook.github.io/react-native/docs/modal.html#transparent + * See https://reactnative.dev/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://facebook.github.io/react-native/docs/modal.html#statusBarTranslucent + * See https://reactnative.dev/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://facebook.github.io/react-native/docs/modal.html#hardwareaccelerated + * See https://reactnative.dev/docs/modal.html#hardwareaccelerated */ hardwareAccelerated?: WithDefault, @@ -75,7 +75,7 @@ type NativeProps = $ReadOnly<{| * * This is required on Apple TV and Android. * - * See https://facebook.github.io/react-native/docs/modal.html#onrequestclose + * See https://reactnative.dev/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://facebook.github.io/react-native/docs/modal.html#onshow + * See https://reactnative.dev/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://facebook.github.io/react-native/docs/modal.html#supportedorientations + * See https://reactnative.dev/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://facebook.github.io/react-native/docs/modal.html#onorientationchange + * See https://reactnative.dev/docs/modal.html#onorientationchange */ onOrientationChange?: ?DirectEventHandler, diff --git a/Libraries/NativeAnimation/RCTNativeAnimatedModule.mm b/Libraries/NativeAnimation/RCTNativeAnimatedModule.mm index f0677e813fb742..e0316f6fec2729 100644 --- a/Libraries/NativeAnimation/RCTNativeAnimatedModule.mm +++ b/Libraries/NativeAnimation/RCTNativeAnimatedModule.mm @@ -15,6 +15,9 @@ typedef void (^AnimatedOperation)(RCTNativeAnimatedNodesManager *nodesManager); +@interface RCTNativeAnimatedModule() +@end + @implementation RCTNativeAnimatedModule { RCTNativeAnimatedNodesManager *_nodesManager; @@ -332,6 +335,14 @@ - (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 391d520acd0676..f79a098a76fa33 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 = '2018.10.22.00' +folly_version = '2020.01.13.00' Pod::Spec.new do |s| s.name = "React-RCTAnimation" s.version = version s.summary = "A native driver for the Animated API." - s.homepage = "http://facebook.github.io/react-native/" + s.homepage = "https://reactnative.dev/" s.license = package["license"] s.author = "Facebook, Inc. and its affiliates" - s.platforms = { :ios => "9.0", :tvos => "9.2", :osx => "10.13" } # TODO(macOS GH#214) + 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.source = source s.source_files = "{Drivers/*,Nodes/*,*}.{m,mm}" @@ -41,6 +41,7 @@ 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 8f6afeaa39d752..2e092a2d682baa 100644 --- a/Libraries/NativeModules/specs/NativeDevSettings.js +++ b/Libraries/NativeModules/specs/NativeDevSettings.js @@ -23,6 +23,10 @@ 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 36383741fc7ca8..2989276aca93b2 100644 --- a/Libraries/Network/RCTNetworking.mm +++ b/Libraries/Network/RCTNetworking.mm @@ -714,10 +714,12 @@ - (RCTNetworkTask *)networkTaskWithRequest:(NSURLRequest *)request completionBlo responseSender(@[@YES]); } -- (std::shared_ptr)getTurboModuleWithJsInvoker: - (std::shared_ptr)jsInvoker +- (std::shared_ptr) + getTurboModuleWithJsInvoker:(std::shared_ptr)jsInvoker + nativeInvoker:(std::shared_ptr)nativeInvoker + perfLogger:(id)perfLogger { - return std::make_shared(self, jsInvoker); + return std::make_shared(self, jsInvoker, nativeInvoker, perfLogger); } @end diff --git a/Libraries/Network/React-RCTNetwork.podspec b/Libraries/Network/React-RCTNetwork.podspec index d5c99c966531a8..f2275bcb9cd6af 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 = '2018.10.22.00' +folly_version = '2020.01.13.00' Pod::Spec.new do |s| s.name = "React-RCTNetwork" s.version = version s.summary = "The networking library of React Native." - s.homepage = "http://facebook.github.io/react-native/" + s.homepage = "https://reactnative.dev/" s.license = package["license"] s.author = "Facebook, Inc. and its affiliates" - s.platforms = { :ios => "9.0", :tvos => "9.2", :osx => "10.13" } # TODO(macOS GH#214) + 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.source = source s.source_files = "*.{m,mm}" @@ -43,5 +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/RCTNetworkHeaders", version end diff --git a/Libraries/Network/XMLHttpRequest.js b/Libraries/Network/XMLHttpRequest.js index e25e876e814828..7bfb0ffa35830d 100644 --- a/Libraries/Network/XMLHttpRequest.js +++ b/Libraries/Network/XMLHttpRequest.js @@ -12,12 +12,15 @@ 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 = | '' @@ -130,6 +133,7 @@ class XMLHttpRequest extends (EventTarget(...XHR_EVENTS): any) { _headers: Object; _lowerCaseResponseHeaders: Object; _method: ?string = null; + _perfKey: ?string = null; _response: string | ?Object; _responseType: ResponseType; _response: string = ''; @@ -242,7 +246,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 = null; + this._cachedResponse = BlobManager.createFromParts([]); } else { throw new Error(`Invalid response for blob: ${this._response}`); } @@ -299,6 +303,8 @@ 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); @@ -511,22 +517,41 @@ class XMLHttpRequest extends (EventTarget(...XHR_EVENTS): any) { nativeResponseType = 'blob'; } - 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, - ); + 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(); + } } abort(): void { diff --git a/Libraries/NewAppScreen/components/LearnMoreLinks.js b/Libraries/NewAppScreen/components/LearnMoreLinks.js index 6db3a1970fe8de..9effd49e172093 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://facebook.github.io/react-native/docs/tutorial', + link: 'https://reactnative.dev/docs/tutorial', description: 'Explains a Hello World for React Native.', }, { id: 2, title: 'Style', - link: 'https://facebook.github.io/react-native/docs/style', + link: 'https://reactnative.dev/docs/style', description: 'Covers how to use the prop named style which controls the visuals.', }, { id: 3, title: 'Layout', - link: 'https://facebook.github.io/react-native/docs/flexbox', + link: 'https://reactnative.dev/docs/flexbox', description: 'React Native uses flexbox for layout, learn how it works.', }, { id: 4, title: 'Components', - link: 'https://facebook.github.io/react-native/docs/components-and-apis', + link: 'https://reactnative.dev/docs/components-and-apis', description: 'The full list of components and APIs inside React Native.', }, { id: 5, title: 'Navigation', - link: 'https://facebook.github.io/react-native/docs/navigation', + link: 'https://reactnative.dev/docs/navigation', description: 'How to handle moving between screens inside your application.', }, { id: 6, title: 'Networking', - link: 'https://facebook.github.io/react-native/docs/network', + link: 'https://reactnative.dev/docs/network', description: 'How to use the Fetch API in React Native.', }, { id: 7, title: 'Help', - link: 'https://facebook.github.io/react-native/help', + link: 'https://reactnative.dev/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 23ae5b30d25ed4..6dfed3cdbd0328 100644 --- a/Libraries/Performance/QuickPerformanceLogger.js +++ b/Libraries/Performance/QuickPerformanceLogger.js @@ -81,6 +81,15 @@ 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 dcc8555c9a55c2..e1db39bbfc5bbc 100644 --- a/Libraries/Performance/Systrace.js +++ b/Libraries/Performance/Systrace.js @@ -87,11 +87,25 @@ 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__) { - global.performance = userTimingPolyfill; + installPerformanceHooks(userTimingPolyfill); } } _canInstallReactHook = true; @@ -108,8 +122,8 @@ const Systrace = { global.nativeTraceEndLegacy(TRACE_TAG_JS_VM_CALLS); } if (_canInstallReactHook) { - if (enabled && global.performance === undefined) { - global.performance = userTimingPolyfill; + if (enabled) { + installPerformanceHooks(userTimingPolyfill); } } } diff --git a/Libraries/PermissionsAndroid/PermissionsAndroid.js b/Libraries/PermissionsAndroid/PermissionsAndroid.js index 66694c2f320d2f..83124ccc24bd05 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://facebook.github.io/react-native/docs/permissionsandroid.html + * See https://reactnative.dev/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://facebook.github.io/react-native/docs/permissionsandroid.html#check + * See https://reactnative.dev/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://facebook.github.io/react-native/docs/permissionsandroid.html#request + * See https://reactnative.dev/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://facebook.github.io/react-native/docs/permissionsandroid.html#requestmultiple + * See https://reactnative.dev/docs/permissionsandroid.html#requestmultiple */ requestMultiple( permissions: Array, diff --git a/Libraries/Pressability/Pressability.js b/Libraries/Pressability/Pressability.js index 42ee68d23eca0f..37555d5df735ae 100644 --- a/Libraries/Pressability/Pressability.js +++ b/Libraries/Pressability/Pressability.js @@ -10,16 +10,16 @@ 'use strict'; -import {isHoverEnabled} from './HoverState.js'; +import {isHoverEnabled} from './HoverState'; import invariant from 'invariant'; -import SoundManager from '../Components/Sound/SoundManager.js'; -import type {EdgeInsetsProp} from '../StyleSheet/EdgeInsetsPropType.js'; +import SoundManager from '../Components/Sound/SoundManager'; +import {normalizeRect, type RectOrSize} from '../StyleSheet/Rect'; import type { BlurEvent, FocusEvent, PressEvent, MouseEvent, -} from '../Types/CoreEventTypes.js'; +} from '../Types/CoreEventTypes'; import Platform from '../Utilities/Platform'; import UIManager from '../ReactNative/UIManager'; import type {HostComponent} from '../Renderer/shims/ReactNativeTypes'; @@ -27,110 +27,132 @@ import * as React from 'react'; export type PressabilityConfig = $ReadOnly<{| /** - * Returns the amount to extend the `VisualRect` by to create `HitRect`. + * Whether a press gesture can be interrupted by a parent gesture such as a + * scroll event. Defaults to true. */ - getHitSlop?: ?() => ?EdgeInsetsProp, + cancelable?: ?boolean, /** - * Returns the duration to wait after hover in before activation. + * Whether to disable initialization of the press gesture. */ - getHoverInDelayMS?: ?() => ?number, + disabled?: ?boolean, /** - * Returns the duration to wait after hover out before deactivation. + * Amount to extend the `VisualRect` by to create `HitRect`. */ - getHoverOutDelayMS?: ?() => ?number, + hitSlop?: ?RectOrSize, /** - * Returns the duration (in addition to the value from `getPressDelayMS`) - * after which a press gesture becomes a long press gesture. + * Amount to extend the `HitRect` by to create `PressRect`. */ - getLongPressDelayMS?: ?() => ?number, + pressRectOffset?: ?RectOrSize, /** - * Returns the duration to wait after press down before activation. + * Whether to disable the systemm sound when `onPress` fires on Android. + **/ + android_disableSound?: ?boolean, + + /** + * Duration to wait after hover in before calling `onHoverIn`. */ - getPressDelayMS?: ?() => ?number, + delayHoverIn?: ?number, /** - * Returns the duration to wait after letting up before deactivation. + * Duration to wait after hover out before calling `onHoverOut`. */ - getPressOutDelayMS?: ?() => ?number, + delayHoverOut?: ?number, /** - * Returns the amount to extend the `HitRect` by to create `PressRect`. + * Duration (in addition to `delayPressIn`) after which a press gesture is + * considered a long press gesture. Defaults to 500 (milliseconds). */ - getPressRectOffset?: ?() => ?EdgeInsetsProp, + delayLongPress?: ?number, /** - * Returns true to disable playing system sound on touch (Android Only) - **/ - getTouchSoundDisabled?: ?() => ?boolean, + * Duration to wait after press down before calling `onPressIn`. + */ + delayPressIn?: ?number, + + /** + * Duration to wait after letting up before calling `onPressOut`. + */ + delayPressOut?: ?number, + + /** + * Minimum duration to wait between calling `onPressIn` and `onPressOut`. + */ + minPressDuration?: ?number, /** * Called after the element loses focus. */ - onBlur?: ?(event: BlurEvent) => void, + onBlur?: ?(event: BlurEvent) => mixed, /** * Called after the element is focused. */ - onFocus?: ?(event: FocusEvent) => void, + onFocus?: ?(event: FocusEvent) => mixed, /** * Called when the hover is activated to provide visual feedback. */ - onHoverIn?: ?(event: MouseEvent) => void, + onHoverIn?: ?(event: MouseEvent) => mixed, /** * Called when the hover is deactivated to undo visual feedback. */ - onHoverOut?: ?(event: MouseEvent) => void, + onHoverOut?: ?(event: MouseEvent) => mixed, /** * Called when a long press gesture has been triggered. */ - onLongPress?: ?(event: PressEvent) => void, - - /** - * Returns whether a long press gesture should cancel the press gesture. - * Defaults to true. - */ - onLongPressShouldCancelPress?: ?() => boolean, + onLongPress?: ?(event: PressEvent) => mixed, /** * Called when a press gestute has been triggered. */ - onPress?: ?(event: PressEvent) => void, + onPress?: ?(event: PressEvent) => mixed, /** * Called when the press is activated to provide visual feedback. */ - onPressIn?: ?(event: PressEvent) => void, + onPressIn?: ?(event: PressEvent) => mixed, /** * Called when the press location moves. (This should rarely be used.) */ - onPressMove?: ?(event: PressEvent) => void, + onPressMove?: ?(event: PressEvent) => mixed, /** * Called when the press is deactivated to undo visual feedback. */ - onPressOut?: ?(event: PressEvent) => void, + onPressOut?: ?(event: PressEvent) => mixed, /** + * 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?: ?() => boolean, + onResponderTerminationRequest_DEPRECATED?: ?() => boolean, /** + * If `disabled` is set, this will be ignored. + * * Returns whether to start a press gesture. + * + * @deprecated */ - onStartShouldSetResponder?: ?() => boolean, + onStartShouldSetResponder_DEPRECATED?: ?() => boolean, |}>; -type EventHandlers = $ReadOnly<{| +export type EventHandlers = $ReadOnly<{| onBlur: (event: BlurEvent) => void, onClick: (event: PressEvent) => void, onFocus: (event: FocusEvent) => void, @@ -254,14 +276,15 @@ const isPressInSignal = signal => const isTerminalSignal = signal => signal === 'RESPONDER_TERMINATED' || signal === 'RESPONDER_RELEASE'; -const DEFAULT_LONG_PRESS_DELAY_MS = 500; -const DEFAULT_PRESS_DELAY_MS = 0; +const DEFAULT_LONG_PRESS_DELAY_MS = 370; // 500 - 130 +const DEFAULT_PRESS_DELAY_MS = 130; const DEFAULT_PRESS_RECT_OFFSETS = { bottom: 30, left: 20, right: 20, top: 20, }; +const DEFAULT_MIN_PRESS_DURATION = 130; /** * Pressability implements press handling capabilities. @@ -315,7 +338,7 @@ const DEFAULT_PRESS_RECT_OFFSETS = { * * ┌────────────────────────┐ * │ ┌──────────────────┐ │ - Presses start anywhere within `HitRect`, which - * │ │ ┌────────────┐ │ │ is expanded via the prop `getHitSlop`. + * │ │ ┌────────────┐ │ │ is expanded via the prop `hitSlop`. * │ │ │ VisualRect │ │ │ * │ │ └────────────┘ │ │ - When pressed down for sufficient amount of time * │ │ HitRect │ │ before letting up, `VisualRect` activates for @@ -323,7 +346,7 @@ const DEFAULT_PRESS_RECT_OFFSETS = { * │ PressRect o │ * └────────────────────│───┘ * Out Region └────── `PressRect`, which is expanded via the prop - * `getPressRectOffset`, allows presses to move + * `pressRectOffset`, allows presses to move * beyond `HitRect` while maintaining activation * and being eligible for a "press". * @@ -376,9 +399,14 @@ 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; } @@ -420,11 +448,15 @@ export default class Pressability { }; const responderEventHandlers = { - onStartShouldSetResponder: () => { - const {onStartShouldSetResponder} = this._config; - return onStartShouldSetResponder == null - ? true - : onStartShouldSetResponder(); + onStartShouldSetResponder: (): boolean => { + const {disabled} = this._config; + if (disabled == null) { + const {onStartShouldSetResponder_DEPRECATED} = this._config; + return onStartShouldSetResponder_DEPRECATED == null + ? true + : onStartShouldSetResponder_DEPRECATED(); + } + return !disabled; }, onResponderGrant: (event: PressEvent): void => { @@ -436,29 +468,28 @@ export default class Pressability { this._touchState = 'NOT_RESPONDER'; this._receiveSignal('RESPONDER_GRANT', event); - const {getLongPressDelayMS, getPressDelayMS} = this._config; - - const pressDelay = getDelayMS( - getPressDelayMS, + const delayPressIn = normalizeDelay( + this._config.delayPressIn, 0, DEFAULT_PRESS_DELAY_MS, ); - if (pressDelay > 0) { + + if (delayPressIn > 0) { this._pressDelayTimeout = setTimeout(() => { this._receiveSignal('DELAY', event); - }, pressDelay); + }, delayPressIn); } else { this._receiveSignal('DELAY', event); } - const longPressDelay = getDelayMS( - getLongPressDelayMS, + const delayLongPress = normalizeDelay( + this._config.delayLongPress, 10, DEFAULT_LONG_PRESS_DELAY_MS, ); this._longPressDelayTimeout = setTimeout(() => { this._handleLongPress(event); - }, longPressDelay + pressDelay); + }, delayLongPress + delayPressIn); }, onResponderMove: (event: PressEvent): void => { @@ -504,13 +535,17 @@ export default class Pressability { }, onResponderTerminationRequest: (): boolean => { - const {onResponderTerminationRequest} = this._config; - return onResponderTerminationRequest == null - ? true - : onResponderTerminationRequest(); + const {cancelable} = this._config; + if (cancelable == null) { + const {onResponderTerminationRequest_DEPRECATED} = this._config; + return onResponderTerminationRequest_DEPRECATED == null + ? true + : onResponderTerminationRequest_DEPRECATED(); + } + return cancelable; }, - onClick: (event: PressEvent) => { + onClick: (event: PressEvent): void => { const {onPress} = this._config; if (onPress != null) { onPress(event); @@ -518,6 +553,12 @@ 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 @@ -526,13 +567,15 @@ export default class Pressability { if (isHoverEnabled()) { this._isHovered = true; this._cancelHoverOutDelayTimeout(); - const {onHoverIn, getHoverInDelayMS} = this._config; + const {onHoverIn} = this._config; if (onHoverIn != null) { - const delay = getDelayMS(getHoverInDelayMS); - if (delay > 0) { + const delayHoverIn = normalizeDelay( + this._config.delayHoverIn, + ); + if (delayHoverIn > 0) { this._hoverInDelayTimeout = setTimeout(() => { onHoverIn(event); - }, delay); + }, delayHoverIn); } else { onHoverIn(event); } @@ -544,13 +587,15 @@ export default class Pressability { if (this._isHovered) { this._isHovered = false; this._cancelHoverInDelayTimeout(); - const {onHoverOut, getHoverOutDelayMS} = this._config; + const {onHoverOut} = this._config; if (onHoverOut != null) { - const delay = getDelayMS(getHoverOutDelayMS); - if (delay > 0) { + const delayHoverOut = normalizeDelay( + this._config.delayHoverOut, + ); + if (delayHoverOut > 0) { this._hoverInDelayTimeout = setTimeout(() => { onHoverOut(event); - }, delay); + }, delayHoverOut); } else { onHoverOut(event); } @@ -634,7 +679,7 @@ export default class Pressability { } if (isPressInSignal(prevState) && signal === 'RESPONDER_RELEASE') { - const {onLongPress, onPress, getTouchSoundDisabled} = this._config; + const {onLongPress, onPress, android_disableSound} = this._config; if (onPress != null) { const isPressCanceledByLongPress = onLongPress != null && @@ -646,10 +691,7 @@ export default class Pressability { this._activate(event); this._deactivate(event); } - const isTouchSoundDisabled = - (getTouchSoundDisabled == null ? null : getTouchSoundDisabled()) ?? - false; - if (Platform.OS === 'android' && !isTouchSoundDisabled) { + if (Platform.OS === 'android' && android_disableSound !== true) { SoundManager.playTouchSound(); } onPress(event); @@ -667,23 +709,34 @@ 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, getPressOutDelayMS} = this._config; + const {onPressOut} = this._config; if (onPressOut != null) { - const delay = getDelayMS(getPressOutDelayMS); - if (delay > 0) { + 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) { this._pressOutDelayTimeout = setTimeout(() => { onPressOut(event); - }, delay); + }, delayPressOut); } else { onPressOut(event); } } + this._touchActivateTime = null; } _measureResponderRegion(): void { @@ -719,14 +772,14 @@ export default class Pressability { top: number, |}>, ): boolean { - const {getHitSlop, getPressRectOffset} = this._config; + const hitSlop = normalizeRect(this._config.hitSlop); + const pressRectOffset = normalizeRect(this._config.pressRectOffset); 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; @@ -742,23 +795,11 @@ export default class Pressability { } } - const rectOffset = getPressRectOffset == null ? null : getPressRectOffset(); regionBottom += - 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; + 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; return ( touch.pageX > regionLeft && @@ -779,8 +820,8 @@ export default class Pressability { _shouldLongPressCancelPress(): boolean { return ( - this._config.onLongPressShouldCancelPress == null || - this._config.onLongPressShouldCancelPress() + this._config.onLongPressShouldCancelPress_DEPRECATED == null || + this._config.onLongPressShouldCancelPress_DEPRECATED() ); } @@ -820,9 +861,9 @@ export default class Pressability { } } -const getDelayMS = (getDelay: ?() => ?number, min = 0, fallback = 0) => { - return Math.max(min, (getDelay == null ? null : getDelay()) ?? fallback); -}; +function normalizeDelay(delay: ?number, min = 0, fallback = 0): number { + return Math.max(min, delay ?? fallback); +} const getTouchFromPressEvent = (event: PressEvent) => { const {changedTouches, touches} = event.nativeEvent; diff --git a/Libraries/Pressability/PressabilityDebug.js b/Libraries/Pressability/PressabilityDebug.js index d593c58587e96a..168a8c1d110163 100644 --- a/Libraries/Pressability/PressabilityDebug.js +++ b/Libraries/Pressability/PressabilityDebug.js @@ -10,13 +10,15 @@ 'use strict'; -import normalizeColor from '../StyleSheet/normalizeColor.js'; +import normalizeColor from '../StyleSheet/normalizeColor'; +import type {ColorValue} from '../StyleSheet/StyleSheetTypes'; + import Touchable from '../Components/Touchable/Touchable'; import View from '../Components/View/View'; import * as React from 'react'; type Props = $ReadOnly<{| - color: string, + color: ColorValue, hitSlop: ?$ReadOnly<{| bottom?: ?number, left?: ?number, @@ -43,12 +45,12 @@ type Props = $ReadOnly<{| export function PressabilityDebugView({color, hitSlop}: Props): React.Node { if (__DEV__) { if (isEnabled()) { - const processedColor = normalizeColor(color); + const normalizedColor = normalizeColor(color); + if (typeof normalizedColor !== 'number') { + return null; + } const baseColor = - '#' + - (typeof processedColor === 'number' ? processedColor : 0) - .toString(16) - .padStart(8, '0'); + '#' + (normalizedColor ?? 0).toString(16).padStart(8, '0'); return ( , TReturn>( const createMockPressability = overrides => { const config = { - 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(), + cancelable: null, + disabled: null, + hitSlop: null, + pressRectOffset: null, + delayHoverIn: null, + delayHoverOut: null, + delayLongPress: null, + delayPressIn: null, + delayPressOut: null, 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(), - onResponderTerminationRequest: jest.fn(() => true), - onStartShouldSetResponder: jest.fn(() => true), + onLongPressShouldCancelPress_DEPRECATED: jest.fn(), + onResponderTerminationRequest_DEPRECATED: jest.fn(() => true), + onStartShouldSetResponder_DEPRECATED: jest.fn(() => true), ...overrides, }; const touchable = new Pressability(config); @@ -230,6 +232,7 @@ const createMockPressEvent = ( describe('Pressability', () => { beforeEach(() => { jest.resetModules(); + jest.spyOn(Date, 'now'); jest.spyOn(HoverState, 'isHoverEnabled'); }); @@ -282,7 +285,7 @@ describe('Pressability', () => { it('is called after no delay by default', () => { const {config, handlers} = createMockPressability({ - getHoverInDelayMS: () => null, + delayHoverIn: null, }); invariant( typeof handlers.onMouseEnter === 'function', @@ -293,9 +296,9 @@ describe('Pressability', () => { expect(config.onHoverIn).toBeCalled(); }); - it('falls back to no delay if `getHoverInDelayMS` is omitted', () => { + it('falls back to no delay if `delayHoverIn` is omitted', () => { const {config, handlers} = createMockPressability({ - getHoverInDelayMS: null, + delayHoverIn: null, }); invariant( typeof handlers.onMouseEnter === 'function', @@ -308,7 +311,7 @@ describe('Pressability', () => { it('is called after a configured delay', () => { const {config, handlers} = createMockPressability({ - getHoverInDelayMS: () => 500, + delayHoverIn: 500, }); invariant( typeof handlers.onMouseEnter === 'function', @@ -324,7 +327,7 @@ describe('Pressability', () => { it('is called synchronously if delay is 0ms', () => { const {config, handlers} = createMockPressability({ - getHoverInDelayMS: () => 0, + delayHoverIn: 0, }); invariant( typeof handlers.onMouseEnter === 'function', @@ -352,16 +355,16 @@ describe('Pressability', () => { expect(config.onLongPress).toBeCalled(); }); - it('is called if pressed for 500ms after the press delay', () => { + it('is called if pressed for 370ms after the press delay', () => { const {config, handlers} = createMockPressability({ - getPressDelayMS: () => 100, + delayPressIn: 100, }); handlers.onStartShouldSetResponder(); handlers.onResponderGrant(createMockPressEvent('onResponderGrant')); handlers.onResponderMove(createMockPressEvent('onResponderMove')); - jest.advanceTimersByTime(599); + jest.advanceTimersByTime(469); expect(config.onLongPress).not.toBeCalled(); jest.advanceTimersByTime(1); expect(config.onLongPress).toBeCalled(); @@ -383,14 +386,14 @@ describe('Pressability', () => { it('falls back to a minimum of 10ms before calling `onLongPress`', () => { const {config, handlers} = createMockPressability({ - getLongPressDelayMS: () => 0, + delayLongPress: 0, }); handlers.onStartShouldSetResponder(); handlers.onResponderGrant(createMockPressEvent('onResponderGrant')); handlers.onResponderMove(createMockPressEvent('onResponderMove')); - jest.advanceTimersByTime(9); + jest.advanceTimersByTime(139); expect(config.onLongPress).not.toBeCalled(); jest.advanceTimersByTime(1); expect(config.onLongPress).toBeCalled(); @@ -452,8 +455,7 @@ describe('Pressability', () => { expect(config.onLongPress).not.toBeCalled(); }); - // 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', () => { + it('is called independent of preceding long touch gesture', () => { mockUIManagerMeasure(); const {config, handlers} = createMockPressability(); @@ -504,6 +506,7 @@ describe('Pressability', () => { handlers.onResponderRelease(createMockPressEvent('onResponderRelease')); expect(config.onPress).toBeCalled(); + jest.runOnlyPendingTimers(); expect(config.onPressOut).toBeCalled(); }); }); @@ -519,33 +522,39 @@ describe('Pressability', () => { expect(config.onPressIn).toBeCalled(); }); - it('is called after no delay by default', () => { + it('is called after the default delay by default', () => { const {config, handlers} = createMockPressability({ - getPressDelayMS: () => null, + delayPressIn: 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 no delay if `getPressDelayMS` is omitted', () => { + it('falls back to the default delay if `delayPressIn` is omitted', () => { const {config, handlers} = createMockPressability({ - getPressDelayMS: null, + delayPressIn: 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({ - getPressDelayMS: () => 500, + delayPressIn: 500, }); handlers.onStartShouldSetResponder(); @@ -560,7 +569,7 @@ describe('Pressability', () => { it('is called synchronously if delay is 0ms', () => { const {config, handlers} = createMockPressability({ - getPressDelayMS: () => 0, + delayPressIn: 0, }); handlers.onStartShouldSetResponder(); @@ -571,14 +580,125 @@ describe('Pressability', () => { }); }); - // TODO: onPressOut tests + 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(); + }); + }); describe('`onPress*` with movement', () => { describe('within bounds of hit rect', () => { it('`onPress*` are called when no delay', () => { mockUIManagerMeasure(); const {config, handlers} = createMockPressability({ - getHitSlop: () => mockSlop, + hitSlop: mockSlop, }); handlers.onStartShouldSetResponder(); @@ -604,14 +724,15 @@ 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({ - getHitSlop: () => mockSlop, - getPressDelayMS: () => 500, + hitSlop: mockSlop, + delayPressIn: 500, }); handlers.onStartShouldSetResponder(); @@ -641,6 +762,7 @@ describe('Pressability', () => { handlers.onResponderRelease(createMockPressEvent('onResponderRelease')); expect(config.onPress).toBeCalled(); + jest.runOnlyPendingTimers(); expect(config.onPressOut).toBeCalled(); }); }); @@ -648,7 +770,9 @@ describe('Pressability', () => { describe('beyond bounds of hit rect', () => { it('`onPress` only is not called when no delay', () => { mockUIManagerMeasure(); - const {config, handlers} = createMockPressability(); + const {config, handlers} = createMockPressability({ + delayPressIn: 0, + }); handlers.onStartShouldSetResponder(); handlers.onResponderGrant(createMockPressEvent('onResponderGrant')); @@ -667,13 +791,14 @@ 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({ - getPressDelayMS: () => 500, + delayPressIn: 500, }); handlers.onStartShouldSetResponder(); @@ -700,7 +825,7 @@ describe('Pressability', () => { it('`onPress*` are called when press is released before measure completes', () => { mockUIManagerMeasure({delay: 1000}); const {config, handlers} = createMockPressability({ - getPressDelayMS: () => 500, + delayPressIn: 500, }); handlers.onStartShouldSetResponder(); @@ -724,6 +849,7 @@ describe('Pressability', () => { handlers.onResponderRelease(createMockPressEvent('onResponderRelease')); expect(config.onPress).toBeCalled(); + jest.runOnlyPendingTimers(); expect(config.onPressOut).toBeCalled(); }); }); @@ -732,7 +858,7 @@ describe('Pressability', () => { describe('onStartShouldSetResponder', () => { it('if omitted the responder is set by default', () => { const {handlers} = createMockPressability({ - onStartShouldSetResponder: null, + onStartShouldSetResponder_DEPRECATED: null, }); expect(handlers.onStartShouldSetResponder()).toBe(true); @@ -740,11 +866,14 @@ describe('Pressability', () => { it('if supplied it is called', () => { const {config, handlers} = createMockPressability(); + const onStartShouldSetResponder_DEPRECATED = nullthrows( + config.onStartShouldSetResponder_DEPRECATED, + ); - nullthrows(config.onStartShouldSetResponder).mockReturnValue(false); + onStartShouldSetResponder_DEPRECATED.mockReturnValue(false); expect(handlers.onStartShouldSetResponder()).toBe(false); - nullthrows(config.onStartShouldSetResponder).mockReturnValue(true); + onStartShouldSetResponder_DEPRECATED.mockReturnValue(true); expect(handlers.onStartShouldSetResponder()).toBe(true); }); }); diff --git a/Libraries/Pressability/usePressability.js b/Libraries/Pressability/usePressability.js new file mode 100644 index 00000000000000..3538524239387b --- /dev/null +++ b/Libraries/Pressability/usePressability.js @@ -0,0 +1,43 @@ +/** + * 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 922e0173c60495..88f0b0812ff7c8 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://facebook.github.io/react-native/docs/pushnotificationios.html + * See https://reactnative.dev/docs/pushnotificationios.html */ class PushNotificationIOS { _data: Object; @@ -91,7 +91,7 @@ class PushNotificationIOS { /** * Schedules the localNotification for immediate presentation. * - * See https://facebook.github.io/react-native/docs/pushnotificationios.html#presentlocalnotification + * See https://reactnative.dev/docs/pushnotificationios.html#presentlocalnotification */ static presentLocalNotification(details: Object) { invariant( @@ -104,7 +104,7 @@ class PushNotificationIOS { /** * Schedules the localNotification for future presentation. * - * See https://facebook.github.io/react-native/docs/pushnotificationios.html#schedulelocalnotification + * See https://reactnative.dev/docs/pushnotificationios.html#schedulelocalnotification */ static scheduleLocalNotification(details: Object) { invariant( @@ -117,7 +117,7 @@ class PushNotificationIOS { /** * Cancels all scheduled localNotifications. * - * See https://facebook.github.io/react-native/docs/pushnotificationios.html#cancelalllocalnotifications + * See https://reactnative.dev/docs/pushnotificationios.html#cancelalllocalnotifications */ static cancelAllLocalNotifications() { invariant( @@ -130,7 +130,7 @@ class PushNotificationIOS { /** * Remove all delivered notifications from Notification Center. * - * See https://facebook.github.io/react-native/docs/pushnotificationios.html#removealldeliverednotifications + * See https://reactnative.dev/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://facebook.github.io/react-native/docs/pushnotificationios.html#getdeliverednotifications + * See https://reactnative.dev/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://facebook.github.io/react-native/docs/pushnotificationios.html#removedeliverednotifications + * See https://reactnative.dev/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://facebook.github.io/react-native/docs/pushnotificationios.html#setapplicationiconbadgenumber + * See https://reactnative.dev/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://facebook.github.io/react-native/docs/pushnotificationios.html#getapplicationiconbadgenumber + * See https://reactnative.dev/docs/pushnotificationios.html#getapplicationiconbadgenumber */ static getApplicationIconBadgeNumber(callback: Function) { invariant( @@ -197,7 +197,7 @@ class PushNotificationIOS { /** * Cancel local notifications. * - * See https://facebook.github.io/react-native/docs/pushnotificationios.html#cancellocalnotification + * See https://reactnative.dev/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://facebook.github.io/react-native/docs/pushnotificationios.html#getscheduledlocalnotifications + * See https://reactnative.dev/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://facebook.github.io/react-native/docs/pushnotificationios.html#addeventlistener + * See https://reactnative.dev/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://facebook.github.io/react-native/docs/pushnotificationios.html#removeeventlistener + * See https://reactnative.dev/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://facebook.github.io/react-native/docs/pushnotificationios.html#requestpermissions + * See https://reactnative.dev/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://facebook.github.io/react-native/docs/pushnotificationios.html#abandonpermissions + * See https://reactnative.dev/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://facebook.github.io/react-native/docs/pushnotificationios.html#checkpermissions + * See https://reactnative.dev/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://facebook.github.io/react-native/docs/pushnotificationios.html#getinitialnotification + * See https://reactnative.dev/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://facebook.github.io/react-native/docs/pushnotificationios.html#finish + * See https://reactnative.dev/docs/pushnotificationios.html#finish */ finish(fetchResult: string) { if ( @@ -456,7 +456,7 @@ class PushNotificationIOS { /** * Gets the sound string from the `aps` object * - * See https://facebook.github.io/react-native/docs/pushnotificationios.html#getsound + * See https://reactnative.dev/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://facebook.github.io/react-native/docs/pushnotificationios.html#getcategory + * See https://reactnative.dev/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://facebook.github.io/react-native/docs/pushnotificationios.html#getalert + * See https://reactnative.dev/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://facebook.github.io/react-native/docs/pushnotificationios.html#getcontentavailable + * See https://reactnative.dev/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://facebook.github.io/react-native/docs/pushnotificationios.html#getbadgecount + * See https://reactnative.dev/docs/pushnotificationios.html#getbadgecount */ getBadgeCount(): ?number { return this._badgeCount; @@ -501,7 +501,7 @@ class PushNotificationIOS { /** * Gets the data object on the notif * - * See https://facebook.github.io/react-native/docs/pushnotificationios.html#getdata + * See https://reactnative.dev/docs/pushnotificationios.html#getdata */ getData(): ?Object { return this._data; @@ -510,7 +510,7 @@ class PushNotificationIOS { /** * Gets the thread ID on the notif * - * See https://facebook.github.io/react-native/docs/pushnotificationios.html#getthreadid + * See https://reactnative.dev/docs/pushnotificationios.html#getthreadid */ getThreadID(): ?string { return this._threadID; diff --git a/Libraries/PushNotificationIOS/RCTPushNotificationManager.mm b/Libraries/PushNotificationIOS/RCTPushNotificationManager.mm index b699e1880fb413..eca5613721e646 100644 --- a/Libraries/PushNotificationIOS/RCTPushNotificationManager.mm +++ b/Libraries/PushNotificationIOS/RCTPushNotificationManager.mm @@ -23,12 +23,11 @@ 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 && !TARGET_OS_UIKITFORMAC +#if !TARGET_OS_TV @implementation RCTConvert (NSCalendarUnit) RCT_ENUM_CONVERTER(NSCalendarUnit, @@ -124,9 +123,6 @@ @interface RCTPushNotificationManager () #endif //TARGET_OS_TV / TARGET_OS_UIKITFORMAC @implementation RCTPushNotificationManager -{ - RCTPromiseResolveBlock _requestPermissionsResolveBlock; -} #if !TARGET_OS_TV && !TARGET_OS_UIKITFORMAC && !TARGET_OS_OSX @@ -213,10 +209,6 @@ - (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 @@ -243,23 +235,11 @@ - (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); @@ -359,34 +339,6 @@ - (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]; @@ -437,14 +389,8 @@ - (void)handleRegisterUserNotificationSettings:(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; @@ -459,9 +405,18 @@ - (void)handleRegisterUserNotificationSettings:(NSNotification *)notification types |= UIUserNotificationTypeSound; } - UIUserNotificationSettings *notificationSettings = - [UIUserNotificationSettings settingsForTypes:types categories:nil]; - [RCTSharedApplication() registerUserNotificationSettings:notificationSettings]; + [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)); + }]; + } + }]; #else // [TODO(macOS ISS#2323203) NSRemoteNotificationType types = NSRemoteNotificationTypeNone; if (permissions.alert()) { @@ -486,18 +441,15 @@ - (void)handleRegisterUserNotificationSettings:(NSNotification *)notification { #if !TARGET_OS_OSX // TODO(macOS ISS#2323203) if (RCTRunningInAppExtension()) { - callback(@[@{@"alert": @NO, @"badge": @NO, @"sound": @NO}]); + callback(@[RCTSettingsDictForUNNotificationSettings(NO, NO, NO)]); return; } #endif // TODO(macOS ISS#2323203) #if !TARGET_OS_OSX // TODO(macOS ISS#2323203) - NSUInteger types = [RCTSharedApplication() currentUserNotificationSettings].types; - callback(@[@{ - @"alert": @((types & UIUserNotificationTypeAlert) > 0), - @"badge": @((types & UIUserNotificationTypeBadge) > 0), - @"sound": @((types & UIUserNotificationTypeSound) > 0), - }]); + [UNUserNotificationCenter.currentNotificationCenter getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) { + callback(@[RCTPromiseResolveValueForUNNotificationSettings(settings)]); + }]; #else // [TODO(macOS ISS#2323203) NSRemoteNotificationType types = RCTSharedApplication().enabledRemoteNotificationTypes; callback(@[@{ @@ -508,6 +460,18 @@ - (void)handleRegisterUserNotificationSettings:(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) { @@ -655,11 +619,8 @@ - (void)handleRegisterUserNotificationSettings:(NSNotification *)notification RCT_EXPORT_METHOD(removeAllDeliveredNotifications) { #if !TARGET_OS_OSX // TODO(macOS ISS#2323203) - // TODO: T56867629 - if (@available(iOS 10.0, tvOS 10.0, *)) { - UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; - [center removeAllDeliveredNotifications]; - } + UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; + [center removeAllDeliveredNotifications]; #else // [TODO(macOS ISS#2323203) [[NSUserNotificationCenter defaultUserNotificationCenter] removeAllDeliveredNotifications]; #endif // ]TODO(macOS ISS#2323203) @@ -668,11 +629,8 @@ - (void)handleRegisterUserNotificationSettings:(NSNotification *)notification RCT_EXPORT_METHOD(removeDeliveredNotifications:(NSArray *)identifiers) { #if !TARGET_OS_OSX // TODO(macOS ISS#2323203) - // TODO: T56867629 - if (@available(iOS 10.0, tvOS 10.0, *)) { - UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; - [center removeDeliveredNotificationsWithIdentifiers:identifiers]; - } + 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]; @@ -686,18 +644,15 @@ - (void)handleRegisterUserNotificationSettings:(NSNotification *)notification RCT_EXPORT_METHOD(getDeliveredNotifications:(RCTResponseSenderBlock)callback) { #if !TARGET_OS_OSX // TODO(macOS ISS#2323203) - // 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]); - }]; - } + 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) { @@ -794,9 +749,12 @@ - (void)handleRegisterUserNotificationSettings:(NSNotification *)notification #endif //TARGET_OS_TV / TARGET_OS_UIKITFORMAC -- (std::shared_ptr)getTurboModuleWithJsInvoker:(std::shared_ptr)jsInvoker +- (std::shared_ptr) + getTurboModuleWithJsInvoker:(std::shared_ptr)jsInvoker + nativeInvoker:(std::shared_ptr)nativeInvoker + perfLogger:(id)perfLogger { - return std::make_shared(self, jsInvoker); + return std::make_shared(self, jsInvoker, nativeInvoker, perfLogger); } @end diff --git a/Libraries/PushNotificationIOS/React-RCTPushNotification.podspec b/Libraries/PushNotificationIOS/React-RCTPushNotification.podspec index 48bbc07bb438dd..05c056cfea415a 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 = '2018.10.22.00' +folly_version = '2020.01.13.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 = "http://facebook.github.io/react-native/" - s.documentation_url = "https://facebook.github.io/react-native/docs/pushnotificationios" + s.homepage = "https://reactnative.dev/" + s.documentation_url = "https://reactnative.dev/docs/pushnotificationios" s.license = package["license"] s.author = "Facebook, Inc. and its affiliates" - s.platforms = { :ios => "9.0", :tvos => "9.2", :osx => "10.13" } # TODO(macOS GH#214) + 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.source = source s.source_files = "*.{m,mm}" @@ -44,4 +44,5 @@ 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 d061b9e31e92aa..396f41b3f98e50 100644 --- a/Libraries/RCTRequired/BUCK +++ b/Libraries/RCTRequired/BUCK @@ -3,7 +3,9 @@ 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/isolation/infra.react_native"], + labels = ["supermodule:ios/default/public.react_native.infra"], ) diff --git a/Libraries/RCTRequired/RCTRequired.podspec b/Libraries/RCTRequired/RCTRequired.podspec index 0b8335b533f56a..063d4fce0b2f45 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 = "http://facebook.github.io/react-native/" + s.homepage = "https://reactnative.dev/" s.license = package["license"] s.author = "Facebook, Inc. and its affiliates" - s.platforms = { :ios => "9.0", :tvos => "9.2", :osx => "10.13" } # TODO(macOS ISS#2323203) + s.platforms = { :ios => "10.0", :tvos => "10.0", :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 eab3b420958363..22e3bd3bef1883 100644 --- a/Libraries/ReactNative/AppContainer.js +++ b/Libraries/ReactNative/AppContainer.js @@ -14,7 +14,6 @@ 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'); @@ -68,14 +67,11 @@ class AppContainer extends React.Component { const Inspector = require('../Inspector/Inspector'); const inspector = this.state.inspector ? null : ( { + inspectedView={this._mainRef} + onRequestRerenderApp={updateInspectedView => { this.setState( s => ({mainKey: s.mainKey + 1}), - () => - updateInspectedViewTag( - ReactNative.findNodeHandle(this._mainRef), - ), + () => updateInspectedView(this._mainRef), ); }} /> @@ -94,14 +90,15 @@ class AppContainer extends React.Component { } render(): React.Node { - let yellowBox = null; + let logBox = null; if (__DEV__) { if ( !global.__RCTProfileIsProfiling && !this.props.internal_excludeLogBox ) { - const YellowBox = require('../YellowBox/YellowBox'); - yellowBox = ; + const LogBoxNotificationContainer = require('../LogBox/LogBoxNotificationContainer') + .default; + logBox = ; } } @@ -135,7 +132,7 @@ class AppContainer extends React.Component { {!this.state.hasError && innerView} {this.state.inspector} - {yellowBox} + {logBox} ); @@ -150,8 +147,8 @@ const styles = StyleSheet.create({ if (__DEV__) { if (!global.__RCTProfileIsProfiling) { - const YellowBox = require('../YellowBox/YellowBox'); - YellowBox.install(); + const LogBox = require('../LogBox/LogBox'); + LogBox.install(); } } diff --git a/Libraries/ReactNative/AppRegistry.js b/Libraries/ReactNative/AppRegistry.js index 6dc813731327ac..99abee3e0d792e 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 http://facebook.github.io/react-native/docs/appregistry.html + * See https://reactnative.dev/docs/appregistry.html */ const AppRegistry = { setWrapperComponentProvider(provider: WrapperComponentProvider) { @@ -103,7 +103,7 @@ const AppRegistry = { /** * Registers an app's root component. * - * See http://facebook.github.io/react-native/docs/appregistry.html#registercomponent + * See https://reactnative.dev/docs/appregistry.html#registercomponent */ registerComponent( appKey: string, @@ -178,7 +178,7 @@ const AppRegistry = { /** * Loads the JavaScript bundle and runs the app. * - * See http://facebook.github.io/react-native/docs/appregistry.html#runapplication + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/appregistry.html#unmountapplicationcomponentatroottag + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/appregistry.html#registerheadlesstask + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/appregistry.html#registercancellableheadlesstask + * See https://reactnative.dev/docs/appregistry.html#registercancellableheadlesstask */ registerCancellableHeadlessTask( taskKey: string, @@ -244,7 +244,7 @@ const AppRegistry = { /** * Only called from native code. Starts a headless task. * - * See http://facebook.github.io/react-native/docs/appregistry.html#startheadlesstask + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/appregistry.html#cancelheadlesstask + * See https://reactnative.dev/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 a6ae78a9624566..bf918219c79496 100644 --- a/Libraries/ReactNative/DummyUIManager.js +++ b/Libraries/ReactNative/DummyUIManager.js @@ -10,10 +10,13 @@ 'use strict'; module.exports = { - getViewManagerConfig: (viewManagerName: string): null => { + getViewManagerConfig: (viewManagerName: string): mixed => { 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 7424d51d45b308..0aeecb4b8c9948 100644 --- a/Libraries/ReactNative/FabricUIManager.js +++ b/Libraries/ReactNative/FabricUIManager.js @@ -49,7 +49,6 @@ 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 592f4359e44202..4be6f784a2904d 100644 --- a/Libraries/ReactNative/ReactFabricInternals.js +++ b/Libraries/ReactNative/ReactFabricInternals.js @@ -10,16 +10,8 @@ '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 3d2f7b06f789e4..d67720d28fe1a7 100644 --- a/Libraries/ReactPrivate/ReactNativePrivateInterface.js +++ b/Libraries/ReactPrivate/ReactNativePrivateInterface.js @@ -8,7 +8,7 @@ * @flow strict-local */ -import typeof BatchedBridge from '../BatchedBridge/BatchedBridge.js'; +import typeof BatchedBridge from '../BatchedBridge/BatchedBridge'; 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.js'); + return require('../BatchedBridge/BatchedBridge'); }, get ExceptionsManager(): ExceptionsManager { return require('../Core/ExceptionsManager'); diff --git a/Libraries/Renderer/REVISION b/Libraries/Renderer/REVISION index d45d99aeb1adb8..55c9a60f3d6303 100644 --- a/Libraries/Renderer/REVISION +++ b/Libraries/Renderer/REVISION @@ -1 +1 @@ -6cff70a740d1e6ad10070ebf88514bd3a49d0f0d +b5c6dd2de557428974855b5aa88bf9c6595beb2b \ No newline at end of file diff --git a/Libraries/Renderer/implementations/ReactFabric-dev.fb.js b/Libraries/Renderer/implementations/ReactFabric-dev.fb.js index 52d8fc3dbd9e50..2a462f48ee41d0 100644 --- a/Libraries/Renderer/implementations/ReactFabric-dev.fb.js +++ b/Libraries/Renderer/implementations/ReactFabric-dev.fb.js @@ -5,6 +5,7 @@ * LICENSE file in the root directory of this source tree. * * @noflow + * @nolint * @preventMunge * @generated */ @@ -15,253 +16,234 @@ 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"); -/** - * 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. - */ +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. -/** - * Injectable ordering of event plugins. - */ -var eventPluginOrder = null; -/** - * Injectable mapping from names to event plugin modules. - */ +if (!ReactSharedInternals.hasOwnProperty("ReactCurrentDispatcher")) { + ReactSharedInternals.ReactCurrentDispatcher = { + current: 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; - } +if (!ReactSharedInternals.hasOwnProperty("ReactCurrentBatchConfig")) { + ReactSharedInternals.ReactCurrentBatchConfig = { + suspense: null + }; +} - for (var pluginName in namesToPlugins) { - var pluginModule = namesToPlugins[pluginName]; - var pluginIndex = eventPluginOrder.indexOf(pluginName); +// 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. - if (!(pluginIndex > -1)) { - throw Error( - "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + - 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 (plugins[pluginIndex]) { - continue; + 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 (!pluginModule.extractEvents) { - throw Error( - "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + - pluginName + - "` does not." - ); - } + printWarning("error", format, args); + } +} - plugins[pluginIndex] = pluginModule; - var publishedEvents = pluginModule.eventTypes; +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; - for (var eventName in publishedEvents) { - if ( - !publishEventForPlugin( - publishedEvents[eventName], - pluginModule, - eventName - ) - ) { - throw Error( - "EventPluginRegistry: Failed to publish event `" + - eventName + - "` for plugin `" + - pluginName + - "`." - ); + if (!hasExistingStack) { + var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; + var stack = ReactDebugCurrentFrame.getStackAddendum(); + + if (stack !== "") { + format += "%s"; + args = args.concat([stack]); } } + + 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 - */ -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 FunctionComponent = 0; +var ClassComponent = 1; +var IndeterminateComponent = 2; // Before we know whether it is function or class - eventNameDispatchConfigs[eventName] = dispatchConfig; - var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; +var HostRoot = 3; // Root of a host tree. Could be nested inside another node. - 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; +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 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 (inst) { + return inst; } - return false; + return null; } /** - * 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 + * Return the lowest common ancestor of A and B, or null if they are in + * different trees. */ -function publishRegistrationName(registrationName, pluginModule, eventName) { - if (!!registrationNameModules[registrationName]) { - throw Error( - "EventPluginHub: More than one plugin attempted to publish the same registration name, `" + - registrationName + - "`." - ); +function getLowestCommonAncestor(instA, instB) { + var depthA = 0; + + for (var tempA = instA; tempA; tempA = getParent(tempA)) { + depthA++; } - registrationNameModules[registrationName] = pluginModule; - registrationNameDependencies[registrationName] = - pluginModule.eventTypes[eventName].dependencies; + var depthB = 0; - { - var lowerCasedName = registrationName.toLowerCase(); + 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; + } + + instA = getParent(instA); + instB = getParent(instB); } + + return null; } /** - * Registers plugins so that they can extract and dispatch events. - * - * @see {EventPluginHub} + * Return if A is an ancestor of B. */ -/** - * Ordered list of injected plugins. - */ +function isAncestor(instA, instB) { + while (instB) { + if (instA === instB || instA === instB.alternate) { + return true; + } -var plugins = []; + instB = getParent(instB); + } + + return false; +} /** - * Mapping from event name to dispatch config + * Return the parent instance of the passed-in instance. */ -var eventNameDispatchConfigs = {}; +function getParentInstance(inst) { + return getParent(inst); +} /** - * Mapping from registration name to plugin module + * Simulates the traversal of a two-phase, capture/bubble event dispatch. */ -var registrationNameModules = {}; -/** - * Mapping from registration name to event name - */ - -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} - */ - -// Trust the developer to only use possibleRegistrationNames in true - -/** - * 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; - } +function traverseTwoPhase(inst, fn, arg) { + var path = []; - var pluginModule = injectedNamesToPlugins[pluginName]; + while (inst) { + path.push(inst); + inst = getParent(inst); + } - 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 i; - namesToPlugins[pluginName] = pluginModule; - isOrderingDirty = true; - } + for (i = path.length; i-- > 0; ) { + fn(path[i], "captured", arg); } - if (isOrderingDirty) { - recomputePluginOrdering(); + + for (i = 0; i < path.length; i++) { + fn(path[i], "bubbled", arg); } } @@ -277,6 +259,7 @@ var invokeGuardedCallbackImpl = function( f ) { var funcArgs = Array.prototype.slice.call(arguments, 3); + try { func.apply(context, funcArgs); } catch (error) { @@ -485,6 +468,7 @@ 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; @@ -500,6 +484,7 @@ 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, @@ -526,6 +511,7 @@ 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; @@ -552,70 +538,6 @@ 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; @@ -627,14 +549,14 @@ function setComponentTree( getFiberCurrentPropsFromNode = getFiberCurrentPropsFromNodeImpl; getInstanceFromNode = getInstanceFromNodeImpl; getNodeFromInstance = getNodeFromInstanceImpl; + { - !(getNodeFromInstance && getInstanceFromNode) - ? warningWithoutStack$1( - false, - "EventPluginUtils.setComponentTree(...): Injected " + - "module is missing getNodeFromInstance or getInstanceFromNode." - ) - : void 0; + if (!getNodeFromInstance || !getInstanceFromNode) { + error( + "EventPluginUtils.setComponentTree(...): Injected " + + "module is missing getNodeFromInstance or getInstanceFromNode." + ); + } } } var validateEventDispatches; @@ -647,17 +569,18 @@ 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; - !(instancesIsArr === listenersIsArr && instancesLen === listenersLen) - ? warningWithoutStack$1(false, "EventPluginUtils: Invalid `event`.") - : void 0; + ? 1 + : 0; + + if (instancesIsArr !== listenersIsArr || instancesLen !== listenersLen) { + error("EventPluginUtils: Invalid `event`."); + } }; } /** @@ -666,6 +589,7 @@ 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); @@ -752,6 +676,7 @@ function executeDispatchesInOrderStopAtTrue(event) { * * @return {*} The return value of executing the single dispatch. */ + function executeDirectDispatch(event) { { validateEventDispatches(event); @@ -777,10 +702,82 @@ 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 @@ -811,6 +808,7 @@ function accumulateInto(current, next) { current.push.apply(current, next); return current; } + current.push(next); return current; } @@ -841,1107 +839,794 @@ function forEachAccumulated(arr, cb, scope) { } /** - * Internal queue of events that have accumulated their dispatches and are - * waiting to have their dispatches executed. + * 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. */ -var eventQueue = null; /** - * Dispatches an event and releases it back into the pool, unless persistent. - * - * @param {?object} event Synthetic event to be dispatched. - * @private + * 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 executeDispatchesAndRelease = function(event) { - if (event) { - executeDispatchesInOrder(event); - if (!event.isPersistent()) { - event.constructor.release(event); +function accumulateDirectionalDispatches(inst, phase, event) { + { + if (!inst) { + error("Dispatching inst must not be null"); } } -}; -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); + var listener = listenerAtPhase(inst, event, phase); - if (!!eventQueue) { - throw Error( - "processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented." + if (listener) { + event._dispatchListeners = accumulateInto( + event._dispatchListeners, + listener ); - } // This would be a good time to rethrow if any of the event handlers threw. - - rethrowCaughtError(); -} - -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; + event._dispatchInstances = accumulateInto(event._dispatchInstances, inst); } } /** - * 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 + * 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); + } +} /** - * Methods for injecting dependencies. + * Same as `accumulateTwoPhaseDispatchesSingle`, but skips over the targetID. */ -var injection = { - /** - * @param {array} InjectedEventPluginOrder - * @public - */ - injectEventPluginOrder: injectEventPluginOrder, - /** - * @param {object} injectedNamesToPlugins Map from names to plugin modules. - */ - injectEventPluginsByName: injectEventPluginsByName -}; +function accumulateTwoPhaseDispatchesSingleSkipTarget(event) { + if (event && event.dispatchConfig.phasedRegistrationNames) { + var targetInst = event._targetInst; + var parentInst = targetInst ? getParentInstance(targetInst) : null; + traverseTwoPhase(parentInst, accumulateDirectionalDispatches, 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. + * 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 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; +function accumulateDispatches(inst, ignoredDirection, event) { + if (inst && event && event.dispatchConfig.registrationName) { + var registrationName = event.dispatchConfig.registrationName; + var listener = getListener(inst, registrationName); - if (!stateNode) { - // Work in progress (ex: onload events in incremental mode). - return null; + 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 + */ - var props = getFiberCurrentPropsFromNode(stateNode); - - if (!props) { - // Work in progress. - return null; +function accumulateDirectDispatchesSingle(event) { + if (event && event.dispatchConfig.registrationName) { + accumulateDispatches(event._targetInst, null, event); } +} - listener = props[registrationName]; +function accumulateTwoPhaseDispatches(events) { + forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle); +} +function accumulateTwoPhaseDispatchesSkipTarget(events) { + forEachAccumulated(events, accumulateTwoPhaseDispatchesSingleSkipTarget); +} +function accumulateDirectDispatches(events) { + forEachAccumulated(events, accumulateDirectDispatchesSingle); +} - if (shouldPreventMouseEvent(registrationName, inst.type, props)) { +var EVENT_POOL_SIZE = 10; +/** + * @interface Event + * @see http://www.w3.org/TR/DOM-Level-3-Events/ + */ + +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 +}; - if (!(!listener || typeof listener === "function")) { - throw Error( - "Expected `" + - registrationName + - "` listener to be a function, instead got a value of `" + - typeof listener + - "` type." - ); - } +function functionThatReturnsTrue() { + return true; +} - return listener; +function functionThatReturnsFalse() { + return false; } /** - * Allows registered plugins an opportunity to extract events from top-level - * native browser events. + * Synthetic events are dispatched by event plugins, typically in response to a + * top-level event delegation handler. * - * @return {*} An accumulation of synthetic events. - * @internal + * 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 extractPluginEvents( - topLevelType, + +function SyntheticEvent( + dispatchConfig, targetInst, nativeEvent, - nativeEventTarget, - eventSystemFlags + nativeEventTarget ) { - var events = null; + { + // these have a getter/setter for warnings + delete this.nativeEvent; + delete this.preventDefault; + delete this.stopPropagation; + delete this.isDefaultPrevented; + delete this.isPropagationStopped; + } - for (var i = 0; i < plugins.length; i++) { - // Not every plugin in the ordering may be loaded at runtime. - var possiblePlugin = plugins[i]; + this.dispatchConfig = dispatchConfig; + this._targetInst = targetInst; + this.nativeEvent = nativeEvent; + var Interface = this.constructor.Interface; - if (possiblePlugin) { - var extractedEvents = possiblePlugin.extractEvents( - topLevelType, - targetInst, - nativeEvent, - nativeEventTarget, - eventSystemFlags - ); + for (var propName in Interface) { + if (!Interface.hasOwnProperty(propName)) { + continue; + } - if (extractedEvents) { - events = accumulateInto(events, extractedEvents); + { + 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]; } } } - return events; -} -function runExtractedPluginEventsInBatch( - topLevelType, - targetInst, - nativeEvent, - nativeEventTarget, - eventSystemFlags -) { - var events = extractPluginEvents( - topLevelType, - targetInst, - nativeEvent, - nativeEventTarget, - eventSystemFlags - ); - runEventsInBatch(events); -} + var defaultPrevented = + nativeEvent.defaultPrevented != null + ? nativeEvent.defaultPrevented + : nativeEvent.returnValue === false; -var FunctionComponent = 0; -var ClassComponent = 1; -var IndeterminateComponent = 2; // Before we know whether it is function or class + if (defaultPrevented) { + this.isDefaultPrevented = functionThatReturnsTrue; + } else { + this.isDefaultPrevented = functionThatReturnsFalse; + } -var HostRoot = 3; // Root of a host tree. Could be nested inside another node. + this.isPropagationStopped = functionThatReturnsFalse; + return this; +} -var HostPortal = 4; // A subtree. Could be an entry point to a different renderer. +Object.assign(SyntheticEvent.prototype, { + preventDefault: function() { + this.defaultPrevented = true; + 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.preventDefault) { + event.preventDefault(); + } else if (typeof event.returnValue !== "unknown") { + event.returnValue = false; + } - if (inst) { - return inst; - } + this.isDefaultPrevented = functionThatReturnsTrue; + }, + stopPropagation: function() { + var event = this.nativeEvent; - return null; -} -/** - * Return the lowest common ancestor of A and B, or null if they are in - * different trees. - */ + if (!event) { + return; + } -function getLowestCommonAncestor(instA, instB) { - var depthA = 0; + 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; + } - for (var tempA = instA; tempA; tempA = getParent(tempA)) { - depthA++; - } + this.isPropagationStopped = functionThatReturnsTrue; + }, - var depthB = 0; + /** + * 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; + }, - for (var tempB = instB; tempB; tempB = getParent(tempB)) { - depthB++; - } // If A is deeper, crawl up. + /** + * Checks if this event should be released back into the pool. + * + * @return {boolean} True if this should not be released, false otherwise. + */ + isPersistent: functionThatReturnsFalse, - while (depthA - depthB > 0) { - instA = getParent(instA); - depthA--; - } // If B is deeper, crawl up. + /** + * `PooledClass` looks for `destructor` on each instance it releases. + */ + destructor: function() { + var Interface = this.constructor.Interface; - while (depthB - depthA > 0) { - instB = getParent(instB); - depthB--; - } // Walk in lockstep until we find a match. + for (var propName in Interface) { + { + Object.defineProperty( + this, + propName, + getPooledWarningPropertyDefinition(propName, Interface[propName]) + ); + } + } - var depth = depthA; + this.dispatchConfig = null; + this._targetInst = null; + this.nativeEvent = null; + this.isDefaultPrevented = functionThatReturnsFalse; + this.isPropagationStopped = functionThatReturnsFalse; + this._dispatchListeners = null; + this._dispatchInstances = null; - while (depth--) { - if (instA === instB || instA === instB.alternate) { - return instA; + { + 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() {}) + ); } - - instA = getParent(instA); - instB = getParent(instB); } - - return null; -} +}); +SyntheticEvent.Interface = EventInterface; /** - * Return if A is an ancestor of B. + * Helper to reduce boilerplate when creating subclasses. */ -function isAncestor(instA, instB) { - while (instB) { - if (instA === instB || instA === instB.alternate) { - return true; - } +SyntheticEvent.extend = function(Interface) { + var Super = this; - instB = getParent(instB); + var E = function() {}; + + E.prototype = Super.prototype; + var prototype = new E(); + + function Class() { + return Super.apply(this, arguments); } - return false; -} -/** - * Return the parent instance of the passed-in instance. - */ + 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; +}; -function getParentInstance(inst) { - return getParent(inst); -} +addEventPoolingTo(SyntheticEvent); /** - * Simulates the traversal of a two-phase, capture/bubble event dispatch. + * Helper to nullify syntheticEvent instance properties when destructing + * + * @param {String} propName + * @param {?object} getVal + * @return {object} defineProperty object */ -function traverseTwoPhase(inst, fn, arg) { - var path = []; +function getPooledWarningPropertyDefinition(propName, getVal) { + var isFunction = typeof getVal === "function"; + return { + configurable: true, + set: set, + get: get + }; - while (inst) { - path.push(inst); - inst = getParent(inst); + function set(val) { + var action = isFunction ? "setting the method" : "setting the property"; + warn(action, "This is effectively a no-op"); + return val; } - var i; - - for (i = path.length; i-- > 0; ) { - fn(path[i], "captured", arg); + 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; } - for (i = 0; i < path.length; i++) { - fn(path[i], "bubbled", arg); + 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 + ); + } } } -/** - * 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. - */ -/** - * 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. - */ +function getPooledEvent(dispatchConfig, targetInst, nativeEvent, nativeInst) { + var EventConstructor = this; -/** - * 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; + if (EventConstructor.eventPool.length) { + var instance = EventConstructor.eventPool.pop(); + EventConstructor.call( + instance, + dispatchConfig, + targetInst, + nativeEvent, + nativeInst + ); + return instance; } - var listener = listenerAtPhase(inst, event, phase); + return new EventConstructor( + dispatchConfig, + targetInst, + nativeEvent, + nativeInst + ); +} - if (listener) { - event._dispatchListeners = accumulateInto( - event._dispatchListeners, - listener +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._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 accumulateTwoPhaseDispatchesSingle(event) { - if (event && event.dispatchConfig.phasedRegistrationNames) { - traverseTwoPhase(event._targetInst, accumulateDirectionalDispatches, event); } -} -/** - * 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); + event.destructor(); + + if (EventConstructor.eventPool.length < EVENT_POOL_SIZE) { + EventConstructor.eventPool.push(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); - } - } + +function addEventPoolingTo(EventConstructor) { + EventConstructor.eventPool = []; + EventConstructor.getPooled = getPooledEvent; + EventConstructor.release = releasePooledEvent; } + /** - * Accumulates dispatches on an `SyntheticEvent`, but only for the - * `dispatchMarker`. - * @param {SyntheticEvent} 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. */ -function accumulateDirectDispatchesSingle(event) { - if (event && event.dispatchConfig.registrationName) { - accumulateDispatches(event._targetInst, null, event); + +var ResponderSyntheticEvent = SyntheticEvent.extend({ + touchHistory: function(nativeEvent) { + return null; // Actually doesn't even look at the native event. } -} +}); -function accumulateTwoPhaseDispatches(events) { - forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle); +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 accumulateTwoPhaseDispatchesSkipTarget(events) { - forEachAccumulated(events, accumulateTwoPhaseDispatchesSingleSkipTarget); +function isMoveish(topLevelType) { + return topLevelType === TOP_TOUCH_MOVE; } - -function accumulateDirectDispatches(events) { - forEachAccumulated(events, accumulateDirectDispatchesSingle); +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]; -/* eslint valid-typeof: 0 */ -var EVENT_POOL_SIZE = 10; /** - * @interface Event - * @see http://www.w3.org/TR/DOM-Level-3-Events/ + * 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 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 functionThatReturnsTrue() { - return true; -} +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 functionThatReturnsFalse() { - return false; +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; } /** - * 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. + * TODO: Instead of making gestures recompute filtered velocity, we could + * include a built in velocity computation that can be reused globally. */ -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; - } - this.dispatchConfig = dispatchConfig; - this._targetInst = targetInst; - this.nativeEvent = nativeEvent; - var Interface = this.constructor.Interface; +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) + }; +} - for (var propName in Interface) { - if (!Interface.hasOwnProperty(propName)) { - continue; - } +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); +} - { - delete this[propName]; // this has a getter/setter for warnings - } +function getTouchIdentifier(_ref) { + var identifier = _ref.identifier; - var normalize = Interface[propName]; + if (!(identifier != null)) { + throw Error("Touch object is missing identifier."); + } - if (normalize) { - this[propName] = normalize(nativeEvent); - } else { - if (propName === "target") { - this.target = nativeEventTarget; - } else { - this[propName] = nativeEvent[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 + ); } } - var defaultPrevented = - nativeEvent.defaultPrevented != null - ? nativeEvent.defaultPrevented - : nativeEvent.returnValue === false; - if (defaultPrevented) { - this.isDefaultPrevented = functionThatReturnsTrue; - } else { - this.isDefaultPrevented = functionThatReturnsFalse; - } - this.isPropagationStopped = functionThatReturnsFalse; - return this; + return identifier; } -Object.assign(SyntheticEvent.prototype, { - preventDefault: function() { - this.defaultPrevented = true; - var event = this.nativeEvent; - if (!event) { - return; - } +function recordTouchStart(touch) { + var identifier = getTouchIdentifier(touch); + var touchRecord = touchBank[identifier]; - if (event.preventDefault) { - event.preventDefault(); - } else if (typeof event.returnValue !== "unknown") { - event.returnValue = false; - } + if (touchRecord) { + resetTouchRecord(touchRecord, touch); + } else { + touchBank[identifier] = createTouchRecord(touch); + } - this.isDefaultPrevented = functionThatReturnsTrue; - }, - stopPropagation: function() { - var event = this.nativeEvent; + touchHistory.mostRecentTimeStamp = timestampForTouch(touch); +} - if (!event) { - return; - } +function recordTouchMove(touch) { + var touchRecord = touchBank[getTouchIdentifier(touch)]; - 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 (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() + ); } + } +} - this.isPropagationStopped = functionThatReturnsTrue; - }, - - /** - * 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; - }, - - /** - * Checks if this event should be released back into the pool. - * - * @return {boolean} True if this should not be released, false otherwise. - */ - isPersistent: functionThatReturnsFalse, +function recordTouchEnd(touch) { + var touchRecord = touchBank[getTouchIdentifier(touch)]; - /** - * `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]) - ); - } - } - this.dispatchConfig = null; - this._targetInst = null; - this.nativeEvent = null; - this.isDefaultPrevented = functionThatReturnsFalse; - this.isPropagationStopped = functionThatReturnsFalse; - this._dispatchListeners = null; - this._dispatchInstances = null; + 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 { { - 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() {}) + warn( + "Cannot record touch end without a touch start.\n" + + "Touch End: %s\n" + + "Touch Bank: %s", + printTouch(touch), + printTouchBank() ); } } -}); -SyntheticEvent.Interface = EventInterface; -/** - * Helper to reduce boilerplate when creating subclasses. - */ +} -SyntheticEvent.extend = function(Interface) { - var Super = this; +function printTouch(touch) { + return JSON.stringify({ + identifier: touch.identifier, + pageX: touch.pageX, + pageY: touch.pageY, + timestamp: timestampForTouch(touch) + }); +} - var E = function() {}; - E.prototype = Super.prototype; - var prototype = new E(); +function printTouchBank() { + var printed = JSON.stringify(touchBank.slice(0, MAX_TOUCH_BANK)); - function Class() { - return Super.apply(this, arguments); + if (touchBank.length > MAX_TOUCH_BANK) { + printed += " (original size: " + touchBank.length + ")"; } - 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 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]; + + if (activeRecord == null || !activeRecord.touchActive) { + error("Cannot find single active touch."); + } + } + } + } + }, + touchHistory: touchHistory }; -addEventPoolingTo(SyntheticEvent); /** - * Helper to nullify syntheticEvent instance properties when destructing + * Accumulates items that must not be null or undefined. * - * @param {String} propName - * @param {?object} getVal - * @return {object} defineProperty object + * This is used to conserve memory by avoiding array allocations. + * + * @return {*|array<*>} An accumulation of items. */ -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 accumulate(current, next) { + if (!(next != null)) { + throw Error( + "accumulate(...): Accumulated items must not be null or undefined." + ); } - 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 (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 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; + if (Array.isArray(next)) { + return [current].concat(next); } + + 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; -} - -/** - * `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. + * Instance of element that should respond to touch/move types of interactions, + * as indicated explicitly by relevant callbacks. */ -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; -} +var responderInst = null; /** - * TODO: Instead of making gestures recompute filtered velocity, we could - * include a built in velocity computation that can be reused globally. + * Count of current touches. A textInput should become responder iff the + * selection changes while there is a touch on the screen. */ -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; -} -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); -} +var trackedTouchCount = 0; -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 changeResponder = function(nextResponderInst, blockHostResponder) { + var oldResponderInst = responderInst; + responderInst = nextResponderInst; -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() + if (ResponderEventPlugin.GlobalResponderHandler !== null) { + ResponderEventPlugin.GlobalResponderHandler.onChange( + oldResponderInst, + nextResponderInst, + blockHostResponder ); } -} +}; -function printTouch(touch) { - return JSON.stringify({ - identifier: touch.identifier, - pageX: touch.pageX, - pageY: touch.pageY, - timestamp: timestampForTouch(touch) - }); -} +var eventTypes = { + /** + * On a `touchStart`/`mouseDown`, is it desired that this element become the + * responder? + */ + startShouldSetResponder: { + phasedRegistrationNames: { + bubbled: "onStartShouldSetResponder", + captured: "onStartShouldSetResponderCapture" + }, + dependencies: startDependencies + }, -function printTouchBank() { - var printed = JSON.stringify(touchBank.slice(0, MAX_TOUCH_BANK)); + /** + * 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 (touchBank.length > MAX_TOUCH_BANK) { - printed += " (original size: " + touchBank.length + ")"; - } + /** + * 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] + }, - 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 - }, + /** + * 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. @@ -2110,7 +1795,7 @@ to return true:wantsResponderID| | + + */ /** - * A note about event ordering in the `EventPluginHub`. + * A note about event ordering in the `EventPluginRegistry`. * * Suppose plugins are injected in the following order: * @@ -2129,7 +1814,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 `EventPluginHub` (hence the + * 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 @@ -2153,9 +1838,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 `EventPluginHub`) - * - `S`s extracted events (if any) (dispatched by `EventPluginHub`) - * - `C`s extracted events (if any) (dispatched by `EventPluginHub`) + * - `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 @@ -2164,9 +1849,9 @@ to return true:wantsResponderID| | * 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) + * - `touchStartCapture` (`EventPluginRegistry` dispatches as usual) + * - `touchStart` (`EventPluginRegistry` dispatches as usual) + * - `responderGrant/Reject` (`EventPluginRegistry` dispatches as usual) */ function setResponderAndExtractTransfer( @@ -2178,10 +1863,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 @@ -2198,6 +1883,7 @@ function setResponderAndExtractTransfer( nativeEventTarget ); shouldSetEvent.touchHistory = ResponderTouchHistoryStore.touchHistory; + if (skipOverBubbleShouldSetFrom) { accumulateTwoPhaseDispatchesSkipTarget(shouldSetEvent); } else { @@ -2238,6 +1924,7 @@ function setResponderAndExtractTransfer( var shouldSwitch = !hasDispatches(terminationRequestEvent) || executeDirectDispatch(terminationRequestEvent); + if (!terminationRequestEvent.isPersistent()) { terminationRequestEvent.constructor.release(terminationRequestEvent); } @@ -2319,6 +2006,7 @@ function noResponderTouches(nativeEvent) { } } } + return true; } @@ -2347,9 +2035,12 @@ var ResponderEventPlugin = { if (trackedTouchCount >= 0) { trackedTouchCount -= 1; } else { - console.warn( - "Ended a touch event which was not counted in `trackedTouchCount`." - ); + { + warn( + "Ended a touch event which was not counted in `trackedTouchCount`." + ); + } + return null; } } @@ -2372,16 +2063,17 @@ 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( @@ -2405,8 +2097,9 @@ var ResponderEventPlugin = { var finalTouch = isResponderTerminate ? eventTypes.responderTerminate : isResponderRelease - ? eventTypes.responderRelease - : null; + ? eventTypes.responderRelease + : null; + if (finalTouch) { var finalEvent = ResponderSyntheticEvent.getPooled( finalTouch, @@ -2435,333 +2128,461 @@ var ResponderEventPlugin = { } }; -var customBubblingEventTypes = - ReactNativePrivateInterface.ReactNativeViewConfigRegistry - .customBubblingEventTypes; -var customDirectEventTypes = - ReactNativePrivateInterface.ReactNativeViewConfigRegistry - .customDirectEventTypes; -var ReactNativeBridgeEventPlugin = { - eventTypes: {}, - - /** - * @see {EventPluginHub.extractEvents} - */ - 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; - } -}; - -var ReactNativeEventPluginOrder = [ - "ResponderEventPlugin", - "ReactNativeBridgeEventPlugin" -]; - /** - * Make sure essential globals are available and are patched correctly. Please don't remove this - * line. Bundles created by react-packager `require` it before executing any application code. This - * ensures it exists in the dependency graph and can be `require`d. - * TODO: require this in packager, not in React #10932517 + * Injectable ordering of event plugins. */ -// Module provided by RN: +var eventPluginOrder = null; /** - * Inject module for resolving DOM hierarchy and plugin ordering. + * Injectable mapping from names to event plugin modules. */ -injection.injectEventPluginOrder(ReactNativeEventPluginOrder); +var namesToPlugins = {}; /** - * Some important event plugins included by default (without having to require - * them). + * Recomputes the plugin list using the injected plugins and plugin ordering. + * + * @private */ -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 recomputePluginOrdering() { + if (!eventPluginOrder) { + // Wait until an `eventPluginOrder` is injected. + return; + } -function getTagFromInstance(inst) { - if (enableNativeTargetAsInstance) { - var nativeInstance = inst.stateNode.canonical; + for (var pluginName in namesToPlugins) { + var pluginModule = namesToPlugins[pluginName]; + var pluginIndex = eventPluginOrder.indexOf(pluginName); - if (!nativeInstance._nativeTag) { - throw Error("All native instances should have a tag."); + if (!(pluginIndex > -1)) { + throw Error( + "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + + pluginName + + "`." + ); } - return nativeInstance; - } else { - var tag = inst.stateNode.canonical._nativeTag; - - if (!tag) { - throw Error("All native instances should have a tag."); + if (plugins[pluginIndex]) { + continue; } - return tag; - } -} - -function getFiberCurrentPropsFromNode$1(inst) { - return inst.canonical.currentProps; -} - -// Module provided by RN: -var ReactFabricGlobalResponderHandler = { - onChange: function(from, to, blockNativeResponder) { - if (to !== null) { - var tag = to.stateNode.canonical._nativeTag; - ReactNativePrivateInterface.UIManager.setJSResponder( - tag, - blockNativeResponder + if (!pluginModule.extractEvents) { + throw Error( + "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + + pluginName + + "` does not." ); - } else { - ReactNativePrivateInterface.UIManager.clearJSResponder(); } - } -}; -setComponentTree( - getFiberCurrentPropsFromNode$1, - getInstanceFromInstance, - getTagFromInstance -); -ResponderEventPlugin.injection.injectGlobalResponderHandler( - ReactFabricGlobalResponderHandler -); + 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 + + "`." + ); + } + } + } +} /** - * `ReactInstanceMap` maintains a mapping from a public facing stateful - * instance (key) and the internal representation (value). This allows public - * methods to accept the user facing instance as an argument and map them back - * to internal methods. + * Publishes an event so that it can be dispatched by the supplied plugin. * - * Note that this module is currently shared and assumed to be stateless. - * If this becomes an actual Map, that will break. + * @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 */ -/** - * 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 publishEventForPlugin(dispatchConfig, pluginModule, eventName) { + if (!!eventNameDispatchConfigs.hasOwnProperty(eventName)) { + throw Error( + "EventPluginRegistry: More than one plugin attempted to publish the same event name, `" + + eventName + + "`." + ); + } -function get(key) { - return key._reactInternalFiber; -} + eventNameDispatchConfigs[eventName] = dispatchConfig; + var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; -function set(key, value) { - key._reactInternalFiber = value; -} + if (phasedRegistrationNames) { + for (var phaseName in phasedRegistrationNames) { + if (phasedRegistrationNames.hasOwnProperty(phaseName)) { + var phasedRegistrationName = phasedRegistrationNames[phaseName]; + publishRegistrationName( + phasedRegistrationName, + pluginModule, + eventName + ); + } + } -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. + return true; + } else if (dispatchConfig.registrationName) { + publishRegistrationName( + dispatchConfig.registrationName, + pluginModule, + eventName + ); + return true; + } -if (!ReactSharedInternals.hasOwnProperty("ReactCurrentDispatcher")) { - ReactSharedInternals.ReactCurrentDispatcher = { - current: null - }; -} -if (!ReactSharedInternals.hasOwnProperty("ReactCurrentBatchConfig")) { - ReactSharedInternals.ReactCurrentBatchConfig = { - suspense: null - }; + 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 + */ -// 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; -var REACT_FORWARD_REF_TYPE = hasSymbol - ? Symbol.for("react.forward_ref") - : 0xead0; -var REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for("react.suspense") : 0xead1; -var REACT_SUSPENSE_LIST_TYPE = hasSymbol - ? Symbol.for("react.suspense_list") - : 0xead8; -var REACT_MEMO_TYPE = hasSymbol ? Symbol.for("react.memo") : 0xead3; -var REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 0xead4; -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) { - if (maybeIterable === null || typeof maybeIterable !== "object") { - return null; +function publishRegistrationName(registrationName, pluginModule, eventName) { + if (!!registrationNameModules[registrationName]) { + throw Error( + "EventPluginRegistry: More than one plugin attempted to publish the same registration name, `" + + registrationName + + "`." + ); } - var maybeIterator = - (MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL]) || - maybeIterable[FAUX_ITERATOR_SYMBOL]; + registrationNameModules[registrationName] = pluginModule; + registrationNameDependencies[registrationName] = + pluginModule.eventTypes[eventName].dependencies; - if (typeof maybeIterator === "function") { - return maybeIterator; + { + var lowerCasedName = registrationName.toLowerCase(); } - - return null; } +/** + * Registers plugins so that they can extract and dispatch events. + */ /** - * 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. + * Ordered list of injected plugins. */ -var warning = warningWithoutStack$1; +var plugins = []; +/** + * Mapping from event name to dispatch config + */ -{ - warning = function(condition, format) { - if (condition) { - return; - } +var eventNameDispatchConfigs = {}; +/** + * Mapping from registration name to plugin module + */ - var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; - var stack = ReactDebugCurrentFrame.getStackAddendum(); // eslint-disable-next-line react-internal/warning-and-invariant-args +var registrationNameModules = {}; +/** + * Mapping from registration name to event name + */ - for ( - var _len = arguments.length, - args = new Array(_len > 2 ? _len - 2 : 0), - _key = 2; - _key < _len; - _key++ - ) { - args[_key - 2] = arguments[_key]; - } +var registrationNameDependencies = {}; - warningWithoutStack$1.apply( - void 0, - [false, format + "%s"].concat(args, [stack]) - ); - }; -} +/** + * 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 + */ -var warning$1 = warning; +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 Uninitialized = -1; -var Pending = 0; -var Resolved = 1; -var Rejected = 2; -function refineResolvedLazyComponent(lazyComponent) { - return lazyComponent._status === Resolved ? lazyComponent._result : null; + eventPluginOrder = Array.prototype.slice.call(injectedEventPluginOrder); + recomputePluginOrdering(); } -function initializeLazyComponentType(lazyComponent) { - if (lazyComponent._status === Uninitialized) { - lazyComponent._status = Pending; - var ctor = lazyComponent._ctor; - var thenable = ctor(); - lazyComponent._result = thenable; - thenable.then( - function(moduleObject) { - if (lazyComponent._status === Pending) { - var defaultExport = moduleObject.default; +/** + * 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 + */ - { - if (defaultExport === undefined) { - warning$1( - false, - "lazy: Expected the result of a dynamic import() call. " + - "Instead received: %s\n\nYour code should look like: \n " + - "const MyComponent = lazy(() => import('./MyComponent'))", - moduleObject - ); - } - } +function injectEventPluginsByName(injectedNamesToPlugins) { + var isOrderingDirty = false; - lazyComponent._status = Resolved; - lazyComponent._result = defaultExport; - } - }, - function(error) { - if (lazyComponent._status === Pending) { - lazyComponent._status = Rejected; - lazyComponent._result = error; - } - } - ); - } -} + for (var pluginName in injectedNamesToPlugins) { + if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) { + continue; + } -function getWrappedName(outerType, innerType, wrapperName) { + 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; + } +}; + +var ReactNativeEventPluginOrder = [ + "ResponderEventPlugin", + "ReactNativeBridgeEventPlugin" +]; + +/** + * Make sure essential globals are available and are patched correctly. Please don't remove this + * line. Bundles created by react-packager `require` it before executing any application code. This + * ensures it exists in the dependency graph and can be `require`d. + * TODO: require this in packager, not in React #10932517 + */ +/** + * Inject module for resolving DOM hierarchy and plugin ordering. + */ + +injectEventPluginOrder(ReactNativeEventPluginOrder); +/** + * Some important event plugins included by default (without having to require + * them). + */ + +injectEventPluginsByName({ + ResponderEventPlugin: ResponderEventPlugin, + ReactNativeBridgeEventPlugin: ReactNativeBridgeEventPlugin +}); + +function getInstanceFromInstance(instanceHandle) { + return instanceHandle; +} + +function getTagFromInstance(inst) { + var nativeInstance = inst.stateNode.canonical; + + if (!nativeInstance._nativeTag) { + throw Error("All native instances should have a tag."); + } + + return nativeInstance; +} +function getFiberCurrentPropsFromNode$1(inst) { + return inst.canonical.currentProps; +} + +// Module provided by RN: +var ReactFabricGlobalResponderHandler = { + onChange: function(from, to, blockNativeResponder) { + if (to !== null) { + var tag = to.stateNode.canonical._nativeTag; + ReactNativePrivateInterface.UIManager.setJSResponder( + tag, + blockNativeResponder + ); + } else { + ReactNativePrivateInterface.UIManager.clearJSResponder(); + } + } +}; + +setComponentTree( + getFiberCurrentPropsFromNode$1, + getInstanceFromInstance, + getTagFromInstance +); +ResponderEventPlugin.injection.injectGlobalResponderHandler( + ReactFabricGlobalResponderHandler +); + +/** + * `ReactInstanceMap` maintains a mapping from a public facing stateful + * instance (key) and the internal representation (value). This allows public + * methods to accept the user facing instance as an argument and map them back + * to internal methods. + * + * Note that this module is currently shared and assumed to be stateless. + * If this becomes an actual Map, that will break. + */ +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 REACT_CONCURRENT_MODE_TYPE = hasSymbol + ? Symbol.for("react.concurrent_mode") + : 0xeacf; +var REACT_FORWARD_REF_TYPE = hasSymbol + ? Symbol.for("react.forward_ref") + : 0xead0; +var REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for("react.suspense") : 0xead1; +var REACT_SUSPENSE_LIST_TYPE = hasSymbol + ? Symbol.for("react.suspense_list") + : 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 MAYBE_ITERATOR_SYMBOL = typeof Symbol === "function" && Symbol.iterator; +var FAUX_ITERATOR_SYMBOL = "@@iterator"; +function getIteratorFn(maybeIterable) { + if (maybeIterable === null || typeof maybeIterable !== "object") { + return null; + } + + var maybeIterator = + (MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL]) || + maybeIterable[FAUX_ITERATOR_SYMBOL]; + + if (typeof maybeIterator === "function") { + return maybeIterator; + } + + return null; +} + +// TODO: Move this to "react" once we can import from externals. +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; + thenable.then( + function(moduleObject) { + if (lazyComponent._status === Pending) { + var defaultExport = moduleObject.default; + + { + if (defaultExport === undefined) { + error( + "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'))", + moduleObject + ); + } + } // Transition to the next state. + + var resolved = lazyComponent; + resolved._status = Resolved; + resolved._result = defaultExport; + } + }, + function(error) { + if (lazyComponent._status === Pending) { + // Transition to the next state. + var rejected = lazyComponent; + rejected._status = Rejected; + rejected._result = error; + } + } + ); + } +} + +function getWrappedName(outerType, innerType, wrapperName) { var functionName = innerType.displayName || innerType.name || ""; return ( outerType.displayName || @@ -2769,15 +2590,19 @@ 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") { - warningWithoutStack$1( - false, + error( "Received an unexpected object in getComponentName(). " + "This is likely a bug in React. Please file an issue." ); @@ -2815,10 +2640,12 @@ function getComponentName(type) { if (typeof type === "object") { switch (type.$$typeof) { case REACT_CONTEXT_TYPE: - return "Context.Consumer"; + var context = type; + return getContextName(context) + ".Consumer"; case REACT_PROVIDER_TYPE: - return "Context.Provider"; + var provider = type; + return getContextName(provider._context) + ".Provider"; case REACT_FORWARD_REF_TYPE: return getWrappedName(type, type.render, "ForwardRef"); @@ -2826,6 +2653,9 @@ 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); @@ -2838,6 +2668,7 @@ function getComponentName(type) { } } } + return null; } @@ -2900,7 +2731,10 @@ var ShouldCapture = /* */ 4096; -var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner; +var enableProfilerTimer = true; +var warnAboutStringRefs = false; + +var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner; function getNearestMountedFiber(fiber) { var node = fiber; var nearestMounted = fiber; @@ -2937,28 +2771,28 @@ function getNearestMountedFiber(fiber) { return null; } - function isFiberMounted(fiber) { return getNearestMountedFiber(fiber) === fiber; } function isMounted(component) { { - var owner = ReactCurrentOwner$1.current; + var owner = ReactCurrentOwner.current; if (owner !== null && owner.tag === ClassComponent) { var ownerFiber = owner; var instance = ownerFiber.stateNode; - !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; + + 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 = true; } } @@ -3037,6 +2871,7 @@ function findCurrentFiberUsingSlowPath(fiber) { assertIsMounted(parentA); return fiber; } + if (child === b) { // We've determined that B is the current branch. assertIsMounted(parentA); @@ -3067,6 +2902,7 @@ function findCurrentFiberUsingSlowPath(fiber) { // Search parent A's child set var didFindChild = false; var _child = parentA.child; + while (_child) { if (_child === a) { didFindChild = true; @@ -3074,6 +2910,7 @@ function findCurrentFiberUsingSlowPath(fiber) { b = parentB; break; } + if (_child === b) { didFindChild = true; b = parentA; @@ -3095,6 +2932,7 @@ function findCurrentFiberUsingSlowPath(fiber) { b = parentA; break; } + if (_child === b) { didFindChild = true; b = parentB; @@ -3200,41 +3038,6 @@ 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 = {}; @@ -3275,6 +3078,7 @@ function restoreDeletedValuesInNestedArray( ) { if (Array.isArray(node)) { var i = node.length; + while (i-- && removedKeyCount > 0) { restoreDeletedValuesInNestedArray( updatePayload, @@ -3284,6 +3088,7 @@ function restoreDeletedValuesInNestedArray( } } else if (node && removedKeyCount > 0) { var obj = node; + for (var propKey in removedKeys) { if (!removedKeys[propKey]) { continue; @@ -3296,6 +3101,7 @@ function restoreDeletedValuesInNestedArray( } var attributeConfig = validAttributes[propKey]; + if (!attributeConfig) { continue; // not a valid native prop } @@ -3303,6 +3109,7 @@ function restoreDeletedValuesInNestedArray( if (typeof nextProp === "function") { nextProp = true; } + if (typeof nextProp === "undefined") { nextProp = null; } @@ -3321,6 +3128,7 @@ function restoreDeletedValuesInNestedArray( : nextProp; updatePayload[propKey] = nextValue; } + removedKeys[propKey] = false; removedKeyCount--; } @@ -3347,6 +3155,7 @@ function diffNestedArrayProperty( validAttributes ); } + for (; i < prevArray.length; i++) { // Clear out all remaining properties. updatePayload = clearNestedProperty( @@ -3355,6 +3164,7 @@ function diffNestedArrayProperty( validAttributes ); } + for (; i < nextArray.length; i++) { // Add all remaining properties. updatePayload = addNestedProperty( @@ -3363,6 +3173,7 @@ function diffNestedArrayProperty( validAttributes ); } + return updatePayload; } @@ -3426,6 +3237,7 @@ function diffNestedProperty( * attribute configurations. It processes each prop and adds it to the * updatePayload. */ + function addNestedProperty(updatePayload, nextProp, validAttributes) { if (!nextProp) { return updatePayload; @@ -3451,6 +3263,7 @@ 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; @@ -3537,6 +3350,7 @@ function diffProperties(updatePayload, prevProps, nextProps, validAttributes) { : nextProp; updatePayload[propKey] = nextValue; } + continue; } @@ -3560,11 +3374,13 @@ 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 { @@ -3579,6 +3395,7 @@ function diffProperties(updatePayload, prevProps, nextProps, validAttributes) { nextProp, attributeConfig ); + if (removedKeyCount > 0 && updatePayload) { restoreDeletedValuesInNestedArray( updatePayload, @@ -3657,6 +3474,7 @@ 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); @@ -3680,49 +3498,6 @@ 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 @@ -3732,31 +3507,7 @@ function restoreStateIfNeeded() { 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) { @@ -3771,72 +3522,6 @@ 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( @@ -3846,567 +3531,188 @@ function setBatchingImplementation( _batchedEventUpdatesImpl ) { batchedUpdatesImpl = _batchedUpdatesImpl; - discreteUpdatesImpl = _discreteUpdatesImpl; - flushDiscreteUpdatesImpl = _flushDiscreteUpdatesImpl; - batchedEventUpdatesImpl = _batchedEventUpdatesImpl; } -function _inheritsLoose(subClass, superClass) { - subClass.prototype = Object.create(superClass.prototype); - subClass.prototype.constructor = subClass; - subClass.__proto__ = superClass; -} +/** + * Internal queue of events that have accumulated their dispatches and are + * waiting to have their dispatches executed. + */ +var eventQueue = null; /** - * Class only exists for its Flow type. + * Dispatches an event and releases it back into the pool, unless persistent. + * + * @param {?object} event Synthetic event to be dispatched. + * @private */ -var ReactNativeComponent = - /*#__PURE__*/ - (function(_React$Component) { - _inheritsLoose(ReactNativeComponent, _React$Component); - function ReactNativeComponent() { - return _React$Component.apply(this, arguments) || this; - } +var executeDispatchesAndRelease = function(event) { + if (event) { + executeDispatchesInOrder(event); - var _proto = ReactNativeComponent.prototype; + if (!event.isPersistent()) { + event.constructor.release(event); + } + } +}; - _proto.blur = function blur() {}; +var executeDispatchesAndReleaseTopLevel = function(e) { + return executeDispatchesAndRelease(e); +}; - _proto.focus = function focus() {}; +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.measure = function measure(callback) {}; + var processingEventQueue = eventQueue; + eventQueue = null; - _proto.measureInWindow = function measureInWindow(callback) {}; + if (!processingEventQueue) { + return; + } - _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; - } + forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseTopLevel); - case UserBlockingEvent: { - runWithPriority(UserBlockingPriority, function() { - return executeUserEventHandler(eventListener, eventValue); - }); - break; - } + 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. - case ContinuousEvent: { - executeUserEventHandler(eventListener, eventValue); - break; - } - } - }, - isTargetWithinNode: function(childTarget, parentTarget) { - validateResponderContext(); - var childFiber = getFiberFromTarget(childTarget); - var parentFiber = getFiberFromTarget(parentTarget); - var node = childFiber; + rethrowCaughtError(); +} - while (node !== null) { - if (node === parentFiber) { - return true; - } +/** + * Allows registered plugins an opportunity to extract events from top-level + * native browser events. + * + * @return {*} An accumulation of synthetic events. + * @internal + */ - node = node.return; - } +function extractPluginEvents( + topLevelType, + targetInst, + nativeEvent, + nativeEventTarget, + eventSystemFlags +) { + var events = null; - 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 < plugins.length; i++) { + // Not every plugin in the ordering may be loaded at runtime. + var possiblePlugin = plugins[i]; - for (var i = 0; i < rootEventTypes.length; i++) { - var rootEventType = rootEventTypes[i]; - var rootEventResponders = rootEventTypesToEventResponderInstances.get( - rootEventType + if (possiblePlugin) { + var extractedEvents = possiblePlugin.extractEvents( + topLevelType, + targetInst, + nativeEvent, + nativeEventTarget, + eventSystemFlags ); - var rootEventTypesSet = currentInstance.rootEventTypes; - - if (rootEventTypesSet !== null) { - rootEventTypesSet.delete(rootEventType); - } - if (rootEventResponders !== undefined) { - rootEventResponders.delete(currentInstance); + if (extractedEvents) { + events = accumulateInto(events, extractedEvents); } } - }, - getTimeStamp: function() { - validateResponderContext(); - return currentTimeStamp; - }, - getResponderNode: function() { - validateResponderContext(); - var responderFiber = currentInstance.fiber; - - if (responderFiber.tag === ScopeComponent) { - return null; - } - - return responderFiber.stateNode; } -}; -function validateEventValue(eventValue) { - if (typeof eventValue === "object" && eventValue !== null) { - var target = eventValue.target, - type = eventValue.type, - timeStamp = eventValue.timeStamp; - - 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 + return events; +} - Object.defineProperty(eventValue, "nativeEvent", { - get: function() { - { - showWarning("nativeEvent"); - } - } - }); - } +function runExtractedPluginEventsInBatch( + topLevelType, + targetInst, + nativeEvent, + nativeEventTarget, + eventSystemFlags +) { + var events = extractPluginEvents( + topLevelType, + targetInst, + nativeEvent, + nativeEventTarget, + eventSystemFlags + ); + runEventsInBatch(events); } -function getFiberFromTarget(target) { - if (target === null) { - return null; +function dispatchEvent(target, topLevelType, nativeEvent) { + var targetFiber = target; + var eventTarget = null; + + if (targetFiber != null) { + var stateNode = targetFiber.stateNode; // Guard against Fiber being unmounted + + if (stateNode != null) { + eventTarget = stateNode.canonical; + } } - return target.canonical._internalInstanceHandle || null; + batchedUpdates(function() { + // Heritage plugin event system + runExtractedPluginEventsInBatch( + topLevelType, + targetFiber, + nativeEvent, + eventTarget, + PLUGIN_EVENT_SYSTEM + ); + }); // React Native doesn't use ReactControlledComponent but if it did, here's + // where it would do it. } -function createFabricResponderEvent(topLevelType, nativeEvent, target) { - return { - nativeEvent: nativeEvent, - target: target, - type: topLevelType - }; -} +// can re-export everything from this module. -function validateResponderContext() { - if (!currentInstance) { +function shim() { + { throw Error( - "An event responder context was used outside of an event cycle." + "The current renderer does not support mutation. This error is likely caused by a bug in React. Please file an issue." ); } -} // TODO this function is almost an exact copy of the DOM version, we should -// somehow share the logic +} // Mutation (when unsupported) -function responderEventTypesContainType(eventTypes, type) { - for (var i = 0, len = eventTypes.length; i < len; i++) { - if (eventTypes[i] === type) { - return true; - } - } - return false; -} +var supportsMutation = false; +var commitMount = shim; -function validateResponderTargetEventTypes(eventType, responder) { - var targetEventTypes = responder.targetEventTypes; // Validate the target event type exists on the responder +// can re-export everything from this module. - if (targetEventTypes !== null) { - return responderEventTypesContainType(targetEventTypes, eventType); +function shim$1() { + { + throw Error( + "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." + ); } +} // Hydration (when unsupported) +var isSuspenseInstancePending = shim$1; +var isSuspenseInstanceFallback = shim$1; +var hydrateTextInstance = shim$1; - 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, - targetFiber !== null ? targetFiber.stateNode : null - ); - 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; +var _nativeFabricUIManage = nativeFabricUIManager, + createNode = _nativeFabricUIManage.createNode, + cloneNode = _nativeFabricUIManage.cloneNode, + cloneNodeWithNewChildren = _nativeFabricUIManage.cloneNodeWithNewChildren, + cloneNodeWithNewChildrenAndProps = + _nativeFabricUIManage.cloneNodeWithNewChildrenAndProps, + cloneNodeWithNewProps = _nativeFabricUIManage.cloneNodeWithNewProps, + createChildNodeSet = _nativeFabricUIManage.createChildSet, + appendChildNode = _nativeFabricUIManage.appendChild, + appendChildNodeToSet = _nativeFabricUIManage.appendChildToSet, + completeRoot = _nativeFabricUIManage.completeRoot, + registerEventHandler = _nativeFabricUIManage.registerEventHandler, + fabricMeasure = _nativeFabricUIManage.measure, + fabricMeasureInWindow = _nativeFabricUIManage.measureInWindow, + fabricMeasureLayout = _nativeFabricUIManage.measureLayout; +var getViewConfigForType = + ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get; // Counter for uniquely identifying views. +// % 10 === 1 means it is a rootTag. +// % 2 === 0 means it is a Fabric tag. +// This means that they never overlap. - 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; - if (enableFlareAPI) { - // React Flare event system - dispatchEventForResponderEventSystem(topLevelType, target, nativeEvent); - } - - var eventTarget = null; - - if (enableNativeTargetAsInstance) { - if (targetFiber != null) { - eventTarget = targetFiber.stateNode.canonical; - } - } else { - eventTarget = nativeEvent.target; - } - - batchedUpdates(function() { - // Heritage plugin event system - runExtractedPluginEventsInBatch( - topLevelType, - targetFiber, - nativeEvent, - eventTarget, - PLUGIN_EVENT_SYSTEM - ); - }); // React Native doesn't use ReactControlledComponent but if it did, here's - // where it would do it. -} - -// can re-export everything from this module. - -function shim() { - { - throw Error( - "The current renderer does not support mutation. This error is likely caused by a bug in React. Please file an issue." - ); - } -} // Mutation (when unsupported) - -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. - -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 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 _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. -// % 2 === 0 means it is a Fabric tag. -// This means that they never overlap. - -var nextReactTag = 2; +var nextReactTag = 2; // TODO: Remove this conditional once all changes have propagated. if (registerEventHandler) { @@ -4437,13 +3743,11 @@ var ReactFabricHostComponent = var _proto = ReactFabricHostComponent.prototype; _proto.blur = function blur() { - ReactNativePrivateInterface.TextInputState.blurTextInput(this._nativeTag); + ReactNativePrivateInterface.TextInputState.blurTextInput(this); }; _proto.focus = function focus() { - ReactNativePrivateInterface.TextInputState.focusTextInput( - this._nativeTag - ); + ReactNativePrivateInterface.TextInputState.focusTextInput(this); }; _proto.measure = function measure(callback) { @@ -4470,10 +3774,12 @@ var ReactFabricHostComponent = typeof relativeToNativeNode === "number" || !(relativeToNativeNode instanceof ReactFabricHostComponent) ) { - warningWithoutStack$1( - false, - "Warning: ref.measureLayout must be called with a ref to a native component." - ); + { + error( + "Warning: ref.measureLayout must be called with a ref to a native component." + ); + } + return; } @@ -4486,16 +3792,15 @@ var ReactFabricHostComponent = }; _proto.setNativeProps = function setNativeProps(nativeProps) { - warningWithoutStack$1( - false, - "Warning: setNativeProps is not currently supported in Fabric" - ); + { + error("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); } @@ -4564,15 +3869,6 @@ function createTextInstance( node: node }; } -function finalizeInitialChildren( - parentInstance, - type, - props, - rootContainerInstance, - hostContext -) { - return false; -} function getRootHostContext(rootContainerInstance) { return { isInAParentText: false @@ -4632,17 +3928,9 @@ 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, @@ -4669,6 +3957,7 @@ function cloneInstance( clone = cloneNodeWithNewChildren(node); } } + return { node: clone, canonical: instance.canonical @@ -4703,194 +3992,108 @@ function finalizeContainerChildren(container, newChildren) { completeRoot(container, newChildren); } -function mountResponderInstance( - responder, - responderInstance, - props, - state, - instance -) { - if (enableFlareAPI) { - var rootEventTypes = responder.rootEventTypes; - - if (rootEventTypes !== null) { - addRootEventTypesForResponderInstance(responderInstance, rootEventTypes); - } +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); - 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."); -} + for (var typeSpecName in typeSpecs) { + if (has(typeSpecs, typeSpecName)) { + var error$1 = void 0; // Prop type validation may throw. In case they do, we don't want to + // fail the render phase where it didn't fail before. So we log it. + // After these have been cleaned up, we'll let them throw. -var BEFORE_SLASH_RE = /^(.*)[\\\/]/; -var describeComponentFrame = function(name, source, ownerName) { - var sourceInfo = ""; + 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 (source) { - var path = source.fileName; - var fileName = path.replace(BEFORE_SLASH_RE, ""); + error$1 = typeSpecs[typeSpecName]( + values, + typeSpecName, + componentName, + location, + null, + "SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED" + ); + } catch (ex) { + error$1 = ex; + } - { - // 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 (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 (match) { - var pathBeforeSlash = match[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; - if (pathBeforeSlash) { - var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, ""); - fileName = folderName + "/" + fileName; - } + error("Failed %s type: %s", location, error$1.message); } } } - sourceInfo = " (at " + fileName + ":" + source.lineNumber + ")"; - } else if (ownerName) { - sourceInfo = " (created by " + ownerName + ")"; } - return "\n in " + (name || "Unknown") + sourceInfo; -}; +} -var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; +// 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? -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 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). - if (owner) { - ownerName = getComponentName(owner.type); - } +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. - 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. +var isCommitting = false; +var hasScheduledUpdateInCurrentCommit = false; +var hasScheduledUpdateInCurrentPhase = false; +var commitCountInCurrentWorkLoop = 0; +var effectCountInCurrentCommit = 0; +// to avoid stretch the commit phase with measurement overhead. var labelsInCurrentCommit = new Set(); @@ -4991,6 +4194,7 @@ var shouldIgnoreFiber = function(fiber) { case ContextConsumer: case Mode: return true; + default: return false; } @@ -5000,6 +4204,7 @@ var clearPendingPhaseMeasurement = function() { if (currentPhase !== null && currentPhaseFiber !== null) { clearFiberMark(currentPhaseFiber, currentPhase); } + currentPhaseFiber = null; currentPhase = null; hasScheduledUpdateInCurrentPhase = false; @@ -5009,10 +4214,12 @@ 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; } }; @@ -5021,6 +4228,7 @@ var resumeTimersRecursively = function(fiber) { if (fiber.return !== null) { resumeTimersRecursively(fiber.return); } + if (fiber._debugIsCurrentlyTiming) { beginFiberMark(fiber, null); } @@ -5034,15 +4242,16 @@ var resumeTimers = function() { }; function recordEffect() { - if (enableUserTimingAPI) { + { effectCountInCurrentCommit++; } } function recordScheduleUpdate() { - if (enableUserTimingAPI) { + { if (isCommitting) { hasScheduledUpdateInCurrentCommit = true; } + if ( currentPhase !== null && currentPhase !== "componentWillMount" && @@ -5052,9 +4261,8 @@ function recordScheduleUpdate() { } } } - function startWorkTimer(fiber) { - if (enableUserTimingAPI) { + { if (!supportsUserTiming || shouldIgnoreFiber(fiber)) { return; } // If we pause, this is the fiber to unwind from. @@ -5069,7 +4277,7 @@ function startWorkTimer(fiber) { } } function cancelWorkTimer(fiber) { - if (enableUserTimingAPI) { + { if (!supportsUserTiming || shouldIgnoreFiber(fiber)) { return; } // Remember we shouldn't complete measurement for this fiber. @@ -5080,7 +4288,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. @@ -5096,7 +4304,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. @@ -5116,7 +4324,7 @@ function stopFailedWorkTimer(fiber) { } } function startPhaseTimer(fiber, phase) { - if (enableUserTimingAPI) { + { if (!supportsUserTiming) { return; } @@ -5132,22 +4340,24 @@ 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) { @@ -5163,7 +4373,7 @@ function startWorkLoopTimer(nextUnitOfWork) { } } function stopWorkLoopTimer(interruptedBy, didCompleteRoot) { - if (enableUserTimingAPI) { + { if (!supportsUserTiming) { return; } @@ -5192,10 +4402,11 @@ function stopWorkLoopTimer(interruptedBy, didCompleteRoot) { } } function startCommitTimer() { - if (enableUserTimingAPI) { + { if (!supportsUserTiming) { return; } + isCommitting = true; hasScheduledUpdateInCurrentCommit = false; labelsInCurrentCommit.clear(); @@ -5203,17 +4414,19 @@ 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; @@ -5222,19 +4435,21 @@ 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( @@ -5245,19 +4460,21 @@ 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( @@ -5268,19 +4485,21 @@ 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( @@ -5309,14 +4528,15 @@ function createCursor(defaultValue) { function pop(cursor, fiber) { if (index < 0) { { - warningWithoutStack$1(false, "Unexpected pop."); + error("Unexpected pop."); } + return; } { if (fiber !== fiberStack[index]) { - warningWithoutStack$1(false, "Unexpected Fiber popped."); + error("Unexpected Fiber popped."); } } @@ -5366,9 +4586,7 @@ 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 @@ -5376,14 +4594,13 @@ 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; @@ -5391,9 +4608,7 @@ function cacheContext(workInProgress, unmaskedContext, maskedContext) { } function getMaskedContext(workInProgress, unmaskedContext) { - if (disableLegacyContext) { - return emptyContextObject; - } else { + { var type = workInProgress.type; var contextTypes = type.contextTypes; @@ -5413,19 +4628,14 @@ 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, - getCurrentFiberStackInDev - ); + checkPropTypes(contextTypes, context, "context", name); } // Cache unmasked context so we can avoid recreating masked context unless necessary. // Context is created before the class component is instantiated so check for instance. @@ -5438,44 +4648,34 @@ 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." @@ -5488,9 +4688,7 @@ 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. @@ -5501,8 +4699,8 @@ function processChildContext(fiber, type, parentContext) { if (!warnedAboutMissingGetChildContext[componentName]) { warnedAboutMissingGetChildContext[componentName] = true; - warningWithoutStack$1( - false, + + error( "%s.childContextTypes is specified but there is no getChildContext() method " + "on the instance. You can either define getChildContext() on %s or remove " + "childContextTypes from it.", @@ -5516,19 +4714,10 @@ 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( @@ -5542,17 +4731,7 @@ function processChildContext(fiber, type, parentContext) { { var name = getComponentName(type) || "Unknown"; - 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 - ); + checkPropTypes(childContextTypes, childContext, "child context", name); } return Object.assign({}, parentContext, {}, childContext); @@ -5560,9 +4739,7 @@ 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. @@ -5584,9 +4761,7 @@ function pushContextProvider(workInProgress) { } function invalidateContextProvider(workInProgress, type, didChange) { - if (disableLegacyContext) { - return; - } else { + { var instance = workInProgress.stateNode; if (!instance) { @@ -5620,9 +4795,7 @@ 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)) { @@ -5665,22 +4838,21 @@ var BlockingRoot = 1; var ConcurrentRoot = 2; // Intentionally not named imports because Rollup would use dynamic dispatch for -// 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) { +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; + +{ // Provide explicit error message when production+profiling bundle of e.g. // react-dom is used with production (non-profiling) bundle of // scheduler/tracing @@ -5701,7 +4873,7 @@ var fakeCallbackNode = {}; // Except for NoPriority, these correspond to Schedul // avoid clashing with Scheduler's priorities. var ImmediatePriority = 99; -var UserBlockingPriority$1 = 98; +var UserBlockingPriority = 98; var NormalPriority = 97; var LowPriority = 96; var IdlePriority = 95; // NoPriority is the absence of priority. Also React-only. @@ -5720,6 +4892,7 @@ 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 @@ -5732,7 +4905,7 @@ function getCurrentPriorityLevel() { return ImmediatePriority; case Scheduler_UserBlockingPriority: - return UserBlockingPriority$1; + return UserBlockingPriority; case Scheduler_NormalPriority: return NormalPriority; @@ -5754,7 +4927,7 @@ function reactPriorityToSchedulerPriority(reactPriorityLevel) { case ImmediatePriority: return Scheduler_ImmediatePriority; - case UserBlockingPriority$1: + case UserBlockingPriority: return Scheduler_UserBlockingPriority; case NormalPriority: @@ -5772,7 +4945,7 @@ function reactPriorityToSchedulerPriority(reactPriorityLevel) { } } -function runWithPriority$1(reactPriorityLevel, fn) { +function runWithPriority(reactPriorityLevel, fn) { var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); return Scheduler_runWithPriority(priorityLevel, fn); } @@ -5818,12 +4991,14 @@ function flushSyncCallbackQueueImpl() { // Prevent re-entrancy. isFlushingSyncQueue = true; var i = 0; + try { var _isSync = true; var queue = syncQueue; - runWithPriority$1(ImmediatePriority, function() { + runWithPriority(ImmediatePriority, function() { for (; i < queue.length; i++) { var callback = queue[i]; + do { callback = callback(_isSync); } while (callback !== null); @@ -5871,14 +5046,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 a moving priority. It is slightly higher than Idle +var Idle = 2; // Continuous Hydration is slightly higher than Idle and is used to increase 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 add an offset so that we don't clash with the magic number for NoWork. + // Always subtract from the offset so that we don't clash with the magic number for NoWork. return MAGIC_NUMBER_OFFSET - ((ms / UNIT_SIZE) | 0); } function expirationTimeToMs(expirationTime) { @@ -5937,7 +5112,6 @@ function computeInteractiveExpiration(currentTime) { HIGH_PRIORITY_BATCH_SIZE ); } - function inferPriorityFromExpirationTime(currentTime, expirationTime) { if (expirationTime === Sync) { return ImmediatePriority; @@ -5955,7 +5129,7 @@ function inferPriorityFromExpirationTime(currentTime, expirationTime) { } if (msUntil <= HIGH_PRIORITY_EXPIRATION + HIGH_PRIORITY_BATCH_SIZE) { - return UserBlockingPriority$1; + return UserBlockingPriority; } if (msUntil <= LOW_PRIORITY_EXPIRATION + LOW_PRIORITY_BATCH_SIZE) { @@ -5976,7 +5150,7 @@ function is(x, y) { ); } -var is$1 = typeof Object.is === "function" ? Object.is : is; +var objectIs = typeof Object.is === "function" ? Object.is : is; var hasOwnProperty = Object.prototype.hasOwnProperty; /** @@ -5986,7 +5160,7 @@ var hasOwnProperty = Object.prototype.hasOwnProperty; */ function shallowEqual(objA, objB) { - if (is$1(objA, objB)) { + if (objectIs(objA, objB)) { return true; } @@ -6009,7 +5183,7 @@ function shallowEqual(objA, objB) { for (var i = 0; i < keysA.length; i++) { if ( !hasOwnProperty.call(objB, keysA[i]) || - !is$1(objA[keysA[i]], objB[keysA[i]]) + !objectIs(objA[keysA[i]], objB[keysA[i]]) ) { return false; } @@ -6018,95 +5192,141 @@ function shallowEqual(objA, objB) { return true; } -/** - * 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() {}; - -{ - 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]; - } +var BEFORE_SLASH_RE = /^(.*)[\\\/]/; +function describeComponentFrame(name, source, ownerName) { + var sourceInfo = ""; - var argIndex = 0; - var message = - "Warning: " + - format.replace(/%s/g, function() { - return args[argIndex++]; - }); + if (source) { + var path = source.fileName; + var fileName = path.replace(BEFORE_SLASH_RE, ""); - if (typeof console !== "undefined") { - console.warn(message); - } + { + // 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 { - // --- 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 (match) { + var pathBeforeSlash = match[1]; - lowPriorityWarningWithoutStack = function(condition, format) { - if (format === undefined) { - throw new Error( - "`lowPriorityWarningWithoutStack(condition, format, ...args)` requires a warning " + - "message argument" - ); + if (pathBeforeSlash) { + var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, ""); + fileName = folderName + "/" + fileName; + } + } + } } - 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]; - } + sourceInfo = " (at " + fileName + ":" + source.lineNumber + ")"; + } else if (ownerName) { + sourceInfo = " (created by " + ownerName + ")"; + } - printWarning.apply(void 0, [format].concat(args)); - } - }; + return "\n in " + (name || "Unknown") + sourceInfo; } -var lowPriorityWarningWithoutStack$1 = lowPriorityWarningWithoutStack; +var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; -var ReactStrictModeWarnings = { - recordUnsafeLifecycleWarnings: function(fiber, instance) {}, - flushPendingUnsafeLifecycleWarnings: function() {}, - recordLegacyContextWarning: function(fiber, instance) {}, - flushLegacyContextWarning: function() {}, - discardPendingWarnings: function() {} -}; +function describeFiber(fiber) { + switch (fiber.tag) { + case HostRoot: + case HostPortal: + case HostText: + case Fragment: + case ContextProvider: + case ContextConsumer: + return ""; -{ - var findStrictRoot = function(fiber) { - var maybeStrictRoot = null; - var node = fiber; + default: + var owner = fiber._debugOwner; + var source = fiber._debugSource; + var name = getComponentName(fiber.type); + var ownerName = null; - while (node !== null) { - if (node.mode & StrictMode) { - maybeStrictRoot = node; + 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 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 ReactStrictModeWarnings = { + recordUnsafeLifecycleWarnings: function(fiber, instance) {}, + flushPendingUnsafeLifecycleWarnings: function() {}, + recordLegacyContextWarning: function(fiber, instance) {}, + flushLegacyContextWarning: function() {}, + discardPendingWarnings: function() {} +}; + +{ + var findStrictRoot = function(fiber) { + var maybeStrictRoot = null; + var node = fiber; + + while (node !== null) { + if (node.mode & StrictMode) { + maybeStrictRoot = node; + } + node = node.return; } @@ -6185,6 +5405,7 @@ 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( @@ -6196,6 +5417,7 @@ var ReactStrictModeWarnings = { } var UNSAFE_componentWillMountUniqueNames = new Set(); + if (pendingUNSAFE_ComponentWillMountWarnings.length > 0) { pendingUNSAFE_ComponentWillMountWarnings.forEach(function(fiber) { UNSAFE_componentWillMountUniqueNames.add( @@ -6207,6 +5429,7 @@ var ReactStrictModeWarnings = { } var componentWillReceivePropsUniqueNames = new Set(); + if (pendingComponentWillReceivePropsWarnings.length > 0) { pendingComponentWillReceivePropsWarnings.forEach(function(fiber) { componentWillReceivePropsUniqueNames.add( @@ -6218,6 +5441,7 @@ var ReactStrictModeWarnings = { } var UNSAFE_componentWillReceivePropsUniqueNames = new Set(); + if (pendingUNSAFE_ComponentWillReceivePropsWarnings.length > 0) { pendingUNSAFE_ComponentWillReceivePropsWarnings.forEach(function(fiber) { UNSAFE_componentWillReceivePropsUniqueNames.add( @@ -6229,6 +5453,7 @@ var ReactStrictModeWarnings = { } var componentWillUpdateUniqueNames = new Set(); + if (pendingComponentWillUpdateWarnings.length > 0) { pendingComponentWillUpdateWarnings.forEach(function(fiber) { componentWillUpdateUniqueNames.add( @@ -6240,6 +5465,7 @@ var ReactStrictModeWarnings = { } var UNSAFE_componentWillUpdateUniqueNames = new Set(); + if (pendingUNSAFE_ComponentWillUpdateWarnings.length > 0) { pendingUNSAFE_ComponentWillUpdateWarnings.forEach(function(fiber) { UNSAFE_componentWillUpdateUniqueNames.add( @@ -6253,8 +5479,8 @@ var ReactStrictModeWarnings = { if (UNSAFE_componentWillMountUniqueNames.size > 0) { var sortedNames = setToSortedString(UNSAFE_componentWillMountUniqueNames); - warningWithoutStack$1( - false, + + error( "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" + @@ -6267,8 +5493,8 @@ var ReactStrictModeWarnings = { var _sortedNames = setToSortedString( UNSAFE_componentWillReceivePropsUniqueNames ); - warningWithoutStack$1( - false, + + error( "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" + @@ -6285,8 +5511,8 @@ var ReactStrictModeWarnings = { var _sortedNames2 = setToSortedString( UNSAFE_componentWillUpdateUniqueNames ); - warningWithoutStack$1( - false, + + error( "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" + @@ -6299,8 +5525,7 @@ var ReactStrictModeWarnings = { if (componentWillMountUniqueNames.size > 0) { var _sortedNames3 = setToSortedString(componentWillMountUniqueNames); - lowPriorityWarningWithoutStack$1( - false, + warn( "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" + @@ -6318,8 +5543,7 @@ var ReactStrictModeWarnings = { componentWillReceivePropsUniqueNames ); - lowPriorityWarningWithoutStack$1( - false, + warn( "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" + @@ -6338,8 +5562,7 @@ var ReactStrictModeWarnings = { if (componentWillUpdateUniqueNames.size > 0) { var _sortedNames5 = setToSortedString(componentWillUpdateUniqueNames); - lowPriorityWarningWithoutStack$1( - false, + warn( "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" + @@ -6362,12 +5585,13 @@ var ReactStrictModeWarnings = { instance ) { var strictRoot = findStrictRoot(fiber); + if (strictRoot === null) { - warningWithoutStack$1( - false, + error( "Expected to find a StrictMode component in a strict mode tree. " + "This error is likely caused by a bug in React. Please file an issue." ); + return; } // Dedup strategy: Warn once per component. @@ -6386,21 +5610,27 @@ 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 strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot); - warningWithoutStack$1( - false, + var firstComponentStack = getStackByFiberInDevAndProd(firstFiber); + + error( "Legacy context API has been detected within a strict-mode tree." + "\n\nThe old API will be supported in all 16.x releases, but applications " + "using it should migrate to the new version." + @@ -6408,7 +5638,7 @@ var ReactStrictModeWarnings = { "\n\nLearn more about this warning here: https://fb.me/react-legacy-context" + "%s", sortedNames, - strictRootComponentStack + firstComponentStack ); }); }; @@ -6472,6 +5702,7 @@ 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, @@ -6565,6 +5796,7 @@ 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; } @@ -6649,9 +5881,6 @@ function scheduleFibersWithFamiliesRecursively( case ForwardRef: candidateType = type.render; break; - - default: - break; } if (resolveFamily === null) { @@ -6676,6 +5905,7 @@ function scheduleFibersWithFamiliesRecursively( } } } + if (failedBoundaries !== null) { if ( failedBoundaries.has(fiber) || @@ -6700,6 +5930,7 @@ function scheduleFibersWithFamiliesRecursively( staleFamilies ); } + if (sibling !== null) { scheduleFibersWithFamiliesRecursively( sibling, @@ -6749,12 +5980,10 @@ function findHostInstancesForMatchingFibersRecursively( case ForwardRef: candidateType = type.render; break; - - default: - break; } var didMatch = false; + if (candidateType !== null) { if (types.has(candidateType)) { didMatch = true; @@ -6828,6 +6057,7 @@ function findChildHostInstancesForFiberShallowly(fiber, hostInstances) { { var node = fiber; var foundHostInstances = false; + while (true) { if (node.tag === HostComponent) { // We got a match. @@ -6855,6 +6085,7 @@ function findChildHostInstancesForFiberShallowly(fiber, hostInstances) { node = node.sibling; } } + return false; } @@ -6863,6 +6094,7 @@ 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]; @@ -6902,6 +6134,7 @@ function resetContextDependencies() { currentlyRenderingFiber = null; lastContextDependency = null; lastContextWithAllBitsObserved = null; + { isDisallowedContextReadInDEV = false; } @@ -6919,40 +6152,22 @@ 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; { - !( - 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; + if ( + context._currentRenderer2 !== undefined && + context._currentRenderer2 !== null && + context._currentRenderer2 !== rendererSigil + ) { + error( + "Detected multiple renderers concurrently rendering the " + + "same context provider. This is currently unsupported." + ); + } + context._currentRenderer2 = rendererSigil; } } @@ -6962,14 +6177,12 @@ 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 (is$1(oldValue, newValue)) { + if (objectIs(oldValue, newValue)) { // No change return 0; } else { @@ -6979,14 +6192,13 @@ function calculateChangedBits(context, newValue, oldValue) { : MAX_SIGNED_31_BIT_INT; { - !((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; + if ((changedBits & MAX_SIGNED_31_BIT_INT) !== changedBits) { + error( + "calculateChangedBits: Expected the return value to be a " + + "31-bit integer. Instead received: %s", + changedBits + ); + } } return changedBits | 0; @@ -7030,6 +6242,7 @@ 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; @@ -7090,39 +6303,6 @@ 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; @@ -7134,6 +6314,7 @@ 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. @@ -7180,22 +6361,19 @@ 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. - !!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 (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()." + ); + } } - 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 { + if (lastContextWithAllBitsObserved === context); + else if (observedBits === false || observedBits === 0); + else { var resolvedObservedBits; // Avoid deopting on observable arguments or heterogeneous types. if ( @@ -7233,85 +6411,10 @@ function readContext(context, observedBits) { lastContextDependency = lastContextDependency.next = contextItem; } } - return isPrimaryRenderer ? context._currentValue : context._currentValue2; + + return 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; @@ -7328,38 +6431,32 @@ var currentlyProcessingQueue; currentlyProcessingQueue = null; } -function createUpdateQueue(baseState) { - var queue = { - baseState: baseState, - firstUpdate: null, - lastUpdate: null, - firstCapturedUpdate: null, - lastCapturedUpdate: null, - firstEffect: null, - lastEffect: null, - firstCapturedEffect: null, - lastCapturedEffect: null - }; - return queue; -} - -function cloneUpdateQueue(currentQueue) { +function initializeUpdateQueue(fiber) { 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 + baseState: fiber.memoizedState, + baseQueue: null, + shared: { + pending: null + }, + effects: null }; - return queue; + 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; + } } - function createUpdate(expirationTime, suspenseConfig) { var update = { expirationTime: expirationTime, @@ -7367,9 +6464,9 @@ function createUpdate(expirationTime, suspenseConfig) { tag: UpdateState, payload: null, callback: null, - next: null, - nextEffect: null + next: null }; + update.next = update; { update.priority = getCurrentPriorityLevel(); @@ -7377,130 +6474,62 @@ function createUpdate(expirationTime, suspenseConfig) { return update; } +function enqueueUpdate(fiber, update) { + var updateQueue = fiber.updateQueue; -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; + if (updateQueue === null) { + // Only occurs if the fiber has been unmounted. + return; } -} -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 (queue1 === null) { - queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState); - } + if (pending === null) { + // This is the first update. Create a circular list. + update.next = update; } else { - // 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. - } - } + update.next = pending.next; + pending.next = 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; - } - } + sharedQueue.pending = update; { if ( - fiber.tag === ClassComponent && - (currentlyProcessingQueue === queue1 || - (queue2 !== null && currentlyProcessingQueue === queue2)) && + currentlyProcessingQueue === sharedQueue && !didWarnUpdateInsideUpdate ) { - warningWithoutStack$1( - false, + error( "An update (setState, replaceState, or forceUpdate) was scheduled " + "from inside an update function. Update functions should be pure, " + "with zero side-effects. Consider using componentDidUpdate or a " + "callback." ); + didWarnUpdateInsideUpdate = true; } } } function enqueueCapturedUpdate(workInProgress, update) { - // 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 (workInProgressQueue.lastCapturedUpdate === null) { - // This is the first render phase update - workInProgressQueue.firstCapturedUpdate = workInProgressQueue.lastCapturedUpdate = update; - } else { - 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); - } + // 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; + + if (last === null) { + queue.baseQueue = update.next = update; + update.next = update; + } else { + update.next = last.next; + last.next = update; } - return queue; } function getStateFromUpdate( @@ -7520,10 +6549,7 @@ function getStateFromUpdate( { enterDisallowedContextReadInDEV(); - if ( - debugRenderPhaseSideEffectsForStrictMode && - workInProgress.mode & StrictMode - ) { + if (workInProgress.mode & StrictMode) { payload.call(instance, prevState, nextProps); } } @@ -7555,10 +6581,7 @@ function getStateFromUpdate( { enterDisallowedContextReadInDEV(); - if ( - debugRenderPhaseSideEffectsForStrictMode && - workInProgress.mode & StrictMode - ) { + if (workInProgress.mode & StrictMode) { _payload.call(instance, prevState, nextProps); } } @@ -7586,164 +6609,176 @@ 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; - } // These values may change as we process the queue. + currentlyProcessingQueue = queue.shared; + } // The last rebase update that is NOT part of the base state. - var newBaseState = queue.baseState; - var newFirstUpdate = null; - var newExpirationTime = NoWork; // Iterate through the list of updates to compute the result. + var baseQueue = queue.baseQueue; // The last pending update that hasn't been processed yet. - var update = queue.firstUpdate; - var resultState = newBaseState; + var pendingQueue = queue.shared.pending; + + 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; + } - while (update !== null) { - var updateExpirationTime = update.expirationTime; + baseQueue = pendingQueue; + queue.shared.pending = null; // TODO: Pass `current` as argument - 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. + var current = workInProgress.alternate; - newBaseState = resultState; - } // Since this update will remain in the list, update the remaining - // expiration time. + if (current !== null) { + var currentQueue = current.updateQueue; - if (newExpirationTime < updateExpirationTime) { - newExpirationTime = updateExpirationTime; + if (currentQueue !== null) { + currentQueue.baseQueue = pendingQueue; } - } 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; + } + } // These values may change as we process the queue. - if (callback !== null) { - workInProgress.effectTag |= Callback; // Set this to null, in case it was mutated during an aborted render. + if (baseQueue !== null) { + var first = baseQueue.next; // Iterate through the list of updates to compute the result. - update.nextEffect = null; + var newState = queue.baseState; + var newExpirationTime = NoWork; + var newBaseState = null; + var newBaseQueueFirst = null; + var newBaseQueueLast = null; - if (queue.lastEffect === null) { - queue.firstEffect = queue.lastEffect = update; - } else { - queue.lastEffect.nextEffect = update; - queue.lastEffect = update; - } - } - } // Continue to the next update. + if (first !== null) { + var update = first; - update = update.next; - } // Separately, iterate though the list of captured updates. + 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 + }; - var newFirstCapturedUpdate = null; - update = queue.firstCapturedUpdate; + if (newBaseQueueLast === null) { + newBaseQueueFirst = newBaseQueueLast = clone; + newBaseState = newState; + } else { + newBaseQueueLast = newBaseQueueLast.next = clone; + } // Update the remaining priority in the queue. - while (update !== null) { - var _updateExpirationTime = update.expirationTime; + 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; - 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 (callback !== null) { + workInProgress.effectTag |= Callback; + var effects = queue.effects; - if (newFirstUpdate === null) { - newBaseState = resultState; + if (effects === null) { + queue.effects = [update]; + } else { + effects.push(update); + } + } } - } // 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; - if (_callback !== null) { - workInProgress.effectTag |= Callback; // Set this to null, in case it was mutated during an aborted render. + update = update.next; - update.nextEffect = null; + if (update === null || update === first) { + pendingQueue = queue.shared.pending; - if (queue.lastCapturedEffect === null) { - queue.firstCapturedEffect = queue.lastCapturedEffect = update; - } else { - queue.lastCapturedEffect.nextEffect = update; - queue.lastCapturedEffect = update; + 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; + } } - } + } while (true); } - update = update.next; - } - 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; - } + if (newBaseQueueLast === null) { + newBaseState = newState; + } else { + newBaseQueueLast.next = newBaseQueueFirst; + } - 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. + 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. - markUnprocessedUpdateTime(newExpirationTime); - workInProgress.expirationTime = newExpirationTime; - workInProgress.memoizedState = resultState; + markUnprocessedUpdateTime(newExpirationTime); + workInProgress.expirationTime = newExpirationTime; + workInProgress.memoizedState = newState; + } { currentlyProcessingQueue = null; @@ -7767,42 +6802,21 @@ function resetHasForceUpdateBeforeProcessing() { function checkHasForceUpdateAfterProcessing() { return hasForceUpdate; } -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. +function commitUpdateQueue(finishedWork, finishedQueue, instance) { + // Commit the effects + var effects = finishedQueue.effects; + finishedQueue.effects = null; - finishedQueue.firstCapturedUpdate = finishedQueue.lastCapturedUpdate = null; - } // Commit the effects + if (effects !== null) { + for (var i = 0; i < effects.length; i++) { + var effect = effects[i]; + var callback = effect.callback; - 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); + if (callback !== null) { + effect.callback = null; + callCallback(callback, instance); + } } - - effect = effect.nextEffect; } } @@ -7812,7 +6826,7 @@ function requestCurrentSuspenseConfig() { } var fakeInternalInstance = {}; -var isArray$1 = Array.isArray; // React.Component uses a shared frozen object by default. +var isArray = Array.isArray; // React.Component uses a shared frozen object by default. // We'll use it to determine whether we need to initialize legacy refs. var emptyRefsObject = new React.Component().refs; @@ -7847,8 +6861,8 @@ var didWarnAboutInvalidateContextType; if (!didWarnOnInvalidCallback.has(key)) { didWarnOnInvalidCallback.add(key); - warningWithoutStack$1( - false, + + error( "%s(...): Expected the last optional `callback` argument to be a " + "function. Instead received: %s.", callerName, @@ -7860,10 +6874,11 @@ var didWarnAboutInvalidateContextType; warnOnUndefinedDerivedState = function(type, partialState) { if (partialState === undefined) { var componentName = getComponentName(type) || "Component"; + if (!didWarnAboutUndefinedDerivedState.has(componentName)) { didWarnAboutUndefinedDerivedState.add(componentName); - warningWithoutStack$1( - false, + + error( "%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. " + "You have returned undefined.", componentName @@ -7898,10 +6913,7 @@ function applyDerivedStateFromProps( var prevState = workInProgress.memoizedState; { - if ( - debugRenderPhaseSideEffectsForStrictMode && - workInProgress.mode & StrictMode - ) { + if (workInProgress.mode & StrictMode) { // Invoke the function an extra time to help detect side-effects. getDerivedStateFromProps(nextProps, prevState); } @@ -7920,9 +6932,9 @@ function applyDerivedStateFromProps( workInProgress.memoizedState = memoizedState; // Once the update queue is empty, persist the derived state onto the // base state. - var updateQueue = workInProgress.updateQueue; - - if (updateQueue !== null && workInProgress.expirationTime === NoWork) { + if (workInProgress.expirationTime === NoWork) { + // Queue is always non-null for classes + var updateQueue = workInProgress.updateQueue; updateQueue.baseState = memoizedState; } } @@ -8010,7 +7022,15 @@ 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, @@ -8020,14 +7040,13 @@ function checkShouldComponentUpdate( stopPhaseTimer(); { - !(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; + if (shouldUpdate === undefined) { + error( + "%s.shouldComponentUpdate(): Returned undefined instead of a " + + "boolean value. Make sure to return true or false.", + getComponentName(ctor) || "Component" + ); + } } return shouldUpdate; @@ -8044,21 +7063,20 @@ 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") { - warningWithoutStack$1( - false, + error( "%s(...): No `render` method found on the returned component " + "instance: did you accidentally return an object from the constructor?", name ); } else { - warningWithoutStack$1( - false, + error( "%s(...): No `render` method found on the returned component " + "instance: you may have forgotten to define `render`.", name @@ -8066,77 +7084,55 @@ function checkClassInstance(workInProgress, ctor, newProps) { } } - 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.", + if ( + instance.getInitialState && + !instance.getInitialState.isReactClassApproved && + !instance.state + ) { + error( + "getInitialState was defined on %s, a plain JavaScript class. " + + "This is only supported for classes created using React.createClass. " + + "Did you mean to define a state property instead?", + name + ); + } + + if ( + instance.getDefaultProps && + !instance.getDefaultProps.isReactClassApproved + ) { + error( + "getDefaultProps was defined on %s, a plain JavaScript class. " + + "This is only supported for classes created using React.createClass. " + + "Use a static property to define defaultProps instead.", + name + ); + } + + if (instance.propTypes) { + error( + "propTypes was defined as an instance property on %s. Use a static " + + "property to define propTypes instead.", + name + ); + } + + if (instance.contextType) { + error( + "contextType was defined as an instance property on %s. Use a static " + + "property to define contextType instead.", + name + ); + } + + { + if (instance.contextTypes) { + error( + "contextTypes was defined as an instance property on %s. Use a static " + + "property to define contextTypes instead.", name ); } - } 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 && @@ -8144,8 +7140,8 @@ function checkClassInstance(workInProgress, ctor, newProps) { !didWarnAboutContextTypeAndContextTypes.has(ctor) ) { didWarnAboutContextTypeAndContextTypes.add(ctor); - warningWithoutStack$1( - false, + + error( "%s declares both contextTypes and contextType static properties. " + "The legacy contextTypes property will be ignored.", name @@ -8153,95 +7149,84 @@ function checkClassInstance(workInProgress, ctor, newProps) { } } - 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 (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 + ); + } + if ( ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== "undefined" ) { - warningWithoutStack$1( - false, + error( "%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" ); } - 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; + + 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 hasMutatedProps = instance.props !== newProps; - !(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 (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 + ); + } if ( typeof instance.getSnapshotBeforeUpdate === "function" && @@ -8249,61 +7234,53 @@ function checkClassInstance(workInProgress, ctor, newProps) { !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor) ) { didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor); - warningWithoutStack$1( - false, + + error( "%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). " + "This component defines getSnapshotBeforeUpdate() only.", getComponentName(ctor) ); } - 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$1(_state))) { - warningWithoutStack$1( - false, - "%s.state: must be set to an object or null", + 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 ); } - 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; + + 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 + ); } } } @@ -8319,12 +7296,7 @@ function adoptClassInstance(workInProgress, instance) { } } -function constructClassInstance( - workInProgress, - ctor, - props, - renderExpirationTime -) { +function constructClassInstance(workInProgress, ctor, props) { var isLegacyContextConsumer = false; var unmaskedContext = emptyContextObject; var context = emptyContextObject; @@ -8361,8 +7333,8 @@ function constructClassInstance( Object.keys(contextType).join(", ") + "}."; } - warningWithoutStack$1( - false, + + error( "%s defines an invalid contextType. " + "contextType should point to the Context object returned by React.createContext().%s", getComponentName(ctor) || "Component", @@ -8374,7 +7346,7 @@ function constructClassInstance( if (typeof contextType === "object" && contextType !== null) { context = readContext(contextType); - } else if (!disableLegacyContext) { + } else { unmaskedContext = getUnmaskedContext(workInProgress, ctor, true); var contextTypes = ctor.contextTypes; isLegacyContextConsumer = @@ -8385,10 +7357,7 @@ function constructClassInstance( } // Instantiate twice to help detect side-effects. { - if ( - debugRenderPhaseSideEffectsForStrictMode && - workInProgress.mode & StrictMode - ) { + if (workInProgress.mode & StrictMode) { new ctor(props, context); // eslint-disable-line no-new } } @@ -8403,10 +7372,11 @@ function constructClassInstance( { if (typeof ctor.getDerivedStateFromProps === "function" && state === null) { var componentName = getComponentName(ctor) || "Component"; + if (!didWarnAboutUninitializedState.has(componentName)) { didWarnAboutUninitializedState.add(componentName); - warningWithoutStack$1( - false, + + error( "`%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`. " + @@ -8427,6 +7397,7 @@ function constructClassInstance( var foundWillMountName = null; var foundWillReceivePropsName = null; var foundWillUpdateName = null; + if ( typeof instance.componentWillMount === "function" && instance.componentWillMount.__suppressDeprecationWarning !== true @@ -8435,6 +7406,7 @@ function constructClassInstance( } else if (typeof instance.UNSAFE_componentWillMount === "function") { foundWillMountName = "UNSAFE_componentWillMount"; } + if ( typeof instance.componentWillReceiveProps === "function" && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true @@ -8445,6 +7417,7 @@ function constructClassInstance( ) { foundWillReceivePropsName = "UNSAFE_componentWillReceiveProps"; } + if ( typeof instance.componentWillUpdate === "function" && instance.componentWillUpdate.__suppressDeprecationWarning !== true @@ -8453,20 +7426,23 @@ function constructClassInstance( } 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); - warningWithoutStack$1( - false, + + error( "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" + @@ -8499,6 +7475,7 @@ function callComponentWillMount(workInProgress, instance) { if (typeof instance.componentWillMount === "function") { instance.componentWillMount(); } + if (typeof instance.UNSAFE_componentWillMount === "function") { instance.UNSAFE_componentWillMount(); } @@ -8507,14 +7484,14 @@ function callComponentWillMount(workInProgress, instance) { if (oldState !== instance.state) { { - warningWithoutStack$1( - false, + error( "%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); } } @@ -8541,10 +7518,11 @@ function callComponentWillReceiveProps( if (instance.state !== oldState) { { var componentName = getComponentName(workInProgress.type) || "Component"; + if (!didWarnAboutStateAssignmentForComponent.has(componentName)) { didWarnAboutStateAssignmentForComponent.add(componentName); - warningWithoutStack$1( - false, + + error( "%s.componentWillReceiveProps(): Assigning directly to " + "this.state is deprecated (except inside a component's " + "constructor). Use setState instead.", @@ -8571,12 +7549,11 @@ 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); @@ -8585,10 +7562,11 @@ function mountClassInstance( { if (instance.state === newProps) { var componentName = getComponentName(ctor) || "Component"; + if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) { didWarnAboutDirectlyAssigningPropsToState.add(componentName); - warningWithoutStack$1( - false, + + error( "%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.", @@ -8604,7 +7582,7 @@ function mountClassInstance( ); } - if (warnAboutDeprecatedLifecycles) { + { ReactStrictModeWarnings.recordUnsafeLifecycleWarnings( workInProgress, instance @@ -8612,19 +7590,10 @@ function mountClassInstance( } } - var updateQueue = workInProgress.updateQueue; - if (updateQueue !== null) { - processUpdateQueue( - workInProgress, - updateQueue, - newProps, - instance, - renderExpirationTime - ); - instance.state = workInProgress.memoizedState; - } - + processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); + instance.state = workInProgress.memoizedState; var getDerivedStateFromProps = ctor.getDerivedStateFromProps; + if (typeof getDerivedStateFromProps === "function") { applyDerivedStateFromProps( workInProgress, @@ -8645,18 +7614,13 @@ function mountClassInstance( callComponentWillMount(workInProgress, instance); // If we had additional state updates during this life-cycle, let's // process them now. - updateQueue = workInProgress.updateQueue; - - if (updateQueue !== null) { - processUpdateQueue( - workInProgress, - updateQueue, - newProps, - instance, - renderExpirationTime - ); - instance.state = workInProgress.memoizedState; - } + processUpdateQueue( + workInProgress, + newProps, + instance, + renderExpirationTime + ); + instance.state = workInProgress.memoizedState; } if (typeof instance.componentDidMount === "function") { @@ -8679,7 +7643,7 @@ function resumeMountClassInstance( if (typeof contextType === "object" && contextType !== null) { nextContext = readContext(contextType); - } else if (!disableLegacyContext) { + } else { var nextLegacyUnmaskedContext = getUnmaskedContext( workInProgress, ctor, @@ -8715,18 +7679,9 @@ function resumeMountClassInstance( resetHasForceUpdateBeforeProcessing(); var oldState = workInProgress.memoizedState; var newState = (instance.state = oldState); - var updateQueue = workInProgress.updateQueue; + processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); + newState = workInProgress.memoizedState; - if (updateQueue !== null) { - processUpdateQueue( - workInProgress, - updateQueue, - newProps, - instance, - renderExpirationTime - ); - newState = workInProgress.memoizedState; - } if ( oldProps === newProps && oldState === newState && @@ -8738,6 +7693,7 @@ function resumeMountClassInstance( if (typeof instance.componentDidMount === "function") { workInProgress.effectTag |= Update; } + return false; } @@ -8814,6 +7770,7 @@ function updateClassInstance( renderExpirationTime ) { var instance = workInProgress.stateNode; + cloneUpdateQueue(current, workInProgress); var oldProps = workInProgress.memoizedProps; instance.props = workInProgress.type === workInProgress.elementType @@ -8825,7 +7782,7 @@ function updateClassInstance( if (typeof contextType === "object" && contextType !== null) { nextContext = readContext(contextType); - } else if (!disableLegacyContext) { + } else { var nextUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true); nextContext = getMaskedContext(workInProgress, nextUnmaskedContext); } @@ -8857,18 +7814,8 @@ function updateClassInstance( resetHasForceUpdateBeforeProcessing(); var oldState = workInProgress.memoizedState; var newState = (instance.state = oldState); - var updateQueue = workInProgress.updateQueue; - - if (updateQueue !== null) { - processUpdateQueue( - workInProgress, - updateQueue, - newProps, - instance, - renderExpirationTime - ); - newState = workInProgress.memoizedState; - } + processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); + newState = workInProgress.memoizedState; if ( oldProps === newProps && @@ -8886,6 +7833,7 @@ function updateClassInstance( workInProgress.effectTag |= Update; } } + if (typeof instance.getSnapshotBeforeUpdate === "function") { if ( oldProps !== current.memoizedProps || @@ -8894,6 +7842,7 @@ function updateClassInstance( workInProgress.effectTag |= Snapshot; } } + return false; } @@ -8958,6 +7907,7 @@ function updateClassInstance( workInProgress.effectTag |= Update; } } + if (typeof instance.getSnapshotBeforeUpdate === "function") { if ( oldProps !== current.memoizedProps || @@ -8996,6 +7946,7 @@ var warnForMissingKey = function(child) {}; * object keys are not valid. This allows us to keep track of children between * updates. */ + ownerHasKeyUseWarning = {}; ownerHasFunctionTypeWarning = {}; @@ -9026,8 +7977,8 @@ var warnForMissingKey = function(child) {}; } ownerHasKeyUseWarning[currentComponentErrorInfo] = true; - warning$1( - false, + + error( "Each child in a list should have a unique " + '"key" prop. See https://fb.me/react-warning-keys for ' + "more information." @@ -9035,10 +7986,11 @@ var warnForMissingKey = function(child) {}; }; } -var isArray = Array.isArray; +var isArray$1 = Array.isArray; -function coerceRef(returnFiber, current$$1, element) { +function coerceRef(returnFiber, current, element) { var mixedRef = element.ref; + if ( mixedRef !== null && typeof mixedRef !== "function" && @@ -9047,24 +7999,21 @@ function coerceRef(returnFiber, current$$1, 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) { + 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 + ) + ) { var componentName = getComponentName(returnFiber.type) || "Component"; + if (!didWarnAboutStringRefs[componentName]) { - 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, + { + error( '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. " + @@ -9074,6 +8023,7 @@ function coerceRef(returnFiber, current$$1, element) { getStackByFiberInDevAndProd(returnFiber) ); } + didWarnAboutStringRefs[componentName] = true; } } @@ -9088,7 +8038,7 @@ function coerceRef(returnFiber, current$$1, element) { if (!(ownerFiber.tag === ClassComponent)) { throw Error( - "Function components cannot have refs. Did you mean to use React.forwardRef()?" + "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" ); } @@ -9106,12 +8056,12 @@ function coerceRef(returnFiber, current$$1, element) { var stringRef = "" + mixedRef; // Check if previous string ref matches new string ref if ( - current$$1 !== null && - current$$1.ref !== null && - typeof current$$1.ref === "function" && - current$$1.ref._stringRef === stringRef + current !== null && + current.ref !== null && + typeof current.ref === "function" && + current.ref._stringRef === stringRef ) { - return current$$1.ref; + return current.ref; } var ref = function(value) { @@ -9121,6 +8071,7 @@ function coerceRef(returnFiber, current$$1, element) { // This is a lazy pooled frozen object, so we need to initialize. refs = inst.refs = {}; } + if (value === null) { delete refs[stringRef]; } else { @@ -9153,6 +8104,7 @@ function coerceRef(returnFiber, current$$1, element) { function throwOnInvalidObjectType(returnFiber, newChild) { if (returnFiber.type !== "textarea") { var addendum = ""; + { addendum = " If you meant to render a collection of children, use an array " + @@ -9174,23 +8126,25 @@ 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; - } + 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." - ); + 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." + ); + } } // 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 @@ -9215,6 +8169,7 @@ function ChildReconciler(shouldTrackSideEffects) { } else { returnFiber.firstEffect = returnFiber.lastEffect = childToDelete; } + childToDelete.nextEffect = null; childToDelete.effectTag = Deletion; } @@ -9232,6 +8187,7 @@ function ChildReconciler(shouldTrackSideEffects) { deleteChild(returnFiber, childToDelete); childToDelete = childToDelete.sibling; } + return null; } @@ -9255,10 +8211,10 @@ function ChildReconciler(shouldTrackSideEffects) { return existingChildren; } - function useFiber(fiber, pendingProps, expirationTime) { + function useFiber(fiber, pendingProps) { // 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, expirationTime); + var clone = createWorkInProgress(fiber, pendingProps); clone.index = 0; clone.sibling = null; return clone; @@ -9266,15 +8222,16 @@ function ChildReconciler(shouldTrackSideEffects) { function placeChild(newFiber, lastPlacedIndex, newIndex) { newFiber.index = newIndex; + if (!shouldTrackSideEffects) { // Noop. return lastPlacedIndex; } - var current$$1 = newFiber.alternate; + var current = newFiber.alternate; - if (current$$1 !== null) { - var oldIndex = current$$1.index; + if (current !== null) { + var oldIndex = current.index; if (oldIndex < lastPlacedIndex) { // This is a move. @@ -9297,16 +8254,12 @@ function ChildReconciler(shouldTrackSideEffects) { if (shouldTrackSideEffects && newFiber.alternate === null) { newFiber.effectTag = Placement; } + return newFiber; } - function updateTextNode( - returnFiber, - current$$1, - textContent, - expirationTime - ) { - if (current$$1 === null || current$$1.tag !== HostText) { + function updateTextNode(returnFiber, current, textContent, expirationTime) { + if (current === null || current.tag !== HostText) { // Insert var created = createFiberFromText( textContent, @@ -9317,46 +8270,48 @@ function ChildReconciler(shouldTrackSideEffects) { return created; } else { // Update - var existing = useFiber(current$$1, textContent, expirationTime); + var existing = useFiber(current, textContent); existing.return = returnFiber; 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; + 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; } - return existing; - } else { - // Insert - var created = createFiberFromElement( - element, - returnFiber.mode, - expirationTime - ); - created.ref = coerceRef(returnFiber, current$$1, element); - created.return = returnFiber; - return created; - } + } // Insert + + var created = createFiberFromElement( + element, + returnFiber.mode, + expirationTime + ); + created.ref = coerceRef(returnFiber, current, element); + created.return = returnFiber; + return created; } - function updatePortal(returnFiber, current$$1, portal, expirationTime) { + function updatePortal(returnFiber, current, portal, expirationTime) { if ( - current$$1 === null || - current$$1.tag !== HostPortal || - current$$1.stateNode.containerInfo !== portal.containerInfo || - current$$1.stateNode.implementation !== portal.implementation + current === null || + current.tag !== HostPortal || + current.stateNode.containerInfo !== portal.containerInfo || + current.stateNode.implementation !== portal.implementation ) { // Insert var created = createFiberFromPortal( @@ -9368,24 +8323,14 @@ function ChildReconciler(shouldTrackSideEffects) { return created; } else { // Update - var existing = useFiber( - current$$1, - portal.children || [], - expirationTime - ); + var existing = useFiber(current, portal.children || []); existing.return = returnFiber; return existing; } } - function updateFragment( - returnFiber, - current$$1, - fragment, - expirationTime, - key - ) { - if (current$$1 === null || current$$1.tag !== Fragment) { + function updateFragment(returnFiber, current, fragment, expirationTime, key) { + if (current === null || current.tag !== Fragment) { // Insert var created = createFiberFromFragment( fragment, @@ -9397,7 +8342,7 @@ function ChildReconciler(shouldTrackSideEffects) { return created; } else { // Update - var existing = useFiber(current$$1, fragment, expirationTime); + var existing = useFiber(current, fragment); existing.return = returnFiber; return existing; } @@ -9425,28 +8370,32 @@ 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(newChild) || getIteratorFn(newChild)) { + if (isArray$1(newChild) || getIteratorFn(newChild)) { var _created3 = createFiberFromFragment( newChild, returnFiber.mode, expirationTime, null ); + _created3.return = returnFiber; return _created3; } @@ -9474,6 +8423,7 @@ function ChildReconciler(shouldTrackSideEffects) { if (key !== null) { return null; } + return updateTextNode( returnFiber, oldFiber, @@ -9495,6 +8445,7 @@ function ChildReconciler(shouldTrackSideEffects) { key ); } + return updateElement( returnFiber, oldFiber, @@ -9505,6 +8456,7 @@ function ChildReconciler(shouldTrackSideEffects) { return null; } } + case REACT_PORTAL_TYPE: { if (newChild.key === key) { return updatePortal( @@ -9519,7 +8471,7 @@ function ChildReconciler(shouldTrackSideEffects) { } } - if (isArray(newChild) || getIteratorFn(newChild)) { + if (isArray$1(newChild) || getIteratorFn(newChild)) { if (key !== null) { return null; } @@ -9571,6 +8523,7 @@ function ChildReconciler(shouldTrackSideEffects) { existingChildren.get( newChild.key === null ? newIdx : newChild.key ) || null; + if (newChild.type === REACT_FRAGMENT_TYPE) { return updateFragment( returnFiber, @@ -9580,6 +8533,7 @@ function ChildReconciler(shouldTrackSideEffects) { newChild.key ); } + return updateElement( returnFiber, _matchedFiber, @@ -9587,11 +8541,13 @@ function ChildReconciler(shouldTrackSideEffects) { expirationTime ); } + case REACT_PORTAL_TYPE: { var _matchedFiber2 = existingChildren.get( newChild.key === null ? newIdx : newChild.key ) || null; + return updatePortal( returnFiber, _matchedFiber2, @@ -9601,8 +8557,9 @@ function ChildReconciler(shouldTrackSideEffects) { } } - if (isArray(newChild) || getIteratorFn(newChild)) { + if (isArray$1(newChild) || getIteratorFn(newChild)) { var _matchedFiber3 = existingChildren.get(newIdx) || null; + return updateFragment( returnFiber, _matchedFiber3, @@ -9632,6 +8589,7 @@ function ChildReconciler(shouldTrackSideEffects) { if (typeof child !== "object" || child === null) { return knownKeys; } + switch (child.$$typeof) { case REACT_ELEMENT_TYPE: case REACT_PORTAL_TYPE: @@ -9647,12 +8605,13 @@ function ChildReconciler(shouldTrackSideEffects) { knownKeys.add(key); break; } + if (!knownKeys.has(key)) { knownKeys.add(key); break; } - warning$1( - false, + + error( "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 " + @@ -9660,11 +8619,11 @@ function ChildReconciler(shouldTrackSideEffects) { "could change in a future version.", key ); - break; - default: + break; } } + return knownKeys; } @@ -9705,6 +8664,7 @@ 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; @@ -9712,12 +8672,14 @@ 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 @@ -9750,6 +8712,7 @@ function ChildReconciler(shouldTrackSideEffects) { // with the previous one. previousNewFiber.sibling = newFiber; } + previousNewFiber = newFiber; oldFiber = nextOldFiber; } @@ -9799,6 +8762,7 @@ function ChildReconciler(shouldTrackSideEffects) { newChildren[newIdx], expirationTime ); + if (_newFiber2 !== null) { if (shouldTrackSideEffects) { if (_newFiber2.alternate !== null) { @@ -9819,6 +8783,7 @@ function ChildReconciler(shouldTrackSideEffects) { } else { previousNewFiber.sibling = _newFiber2; } + previousNewFiber = _newFiber2; } } @@ -9857,28 +8822,28 @@ function ChildReconciler(shouldTrackSideEffects) { typeof Symbol === "function" && // $FlowFixMe Flow doesn't know about toStringTag newChildrenIterable[Symbol.toStringTag] === "Generator" ) { - !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; + 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 = true; } // Warn about using Maps as children if (newChildrenIterable.entries === iteratorFn) { - !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; + 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 = true; } // First, validate keys. // We'll get a different iterator later for the main pass. @@ -9922,12 +8887,14 @@ 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 @@ -9960,6 +8927,7 @@ function ChildReconciler(shouldTrackSideEffects) { // with the previous one. previousNewFiber.sibling = newFiber; } + previousNewFiber = newFiber; oldFiber = nextOldFiber; } @@ -10005,6 +8973,7 @@ function ChildReconciler(shouldTrackSideEffects) { step.value, expirationTime ); + if (_newFiber4 !== null) { if (shouldTrackSideEffects) { if (_newFiber4.alternate !== null) { @@ -10025,6 +8994,7 @@ function ChildReconciler(shouldTrackSideEffects) { } else { previousNewFiber.sibling = _newFiber4; } + previousNewFiber = _newFiber4; } } @@ -10052,7 +9022,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, expirationTime); + var existing = useFiber(currentFirstChild, textContent); existing.return = returnFiber; return existing; } // The existing first child is not a text node so we need to create one @@ -10076,38 +9046,64 @@ 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) { - 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: + 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: isCompatibleFamilyForHotReloading(child, element) - ) { - 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; + ) { + 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; } - return existing; - } else { - deleteRemainingChildren(returnFiber, child); - break; - } + } // Didn't match. + + deleteRemainingChildren(returnFiber, child); + break; } else { deleteChild(returnFiber, child); } + child = child.sibling; } @@ -10126,6 +9122,7 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime ); + _created4.ref = coerceRef(returnFiber, currentFirstChild, element); _created4.return = returnFiber; return _created4; @@ -10140,6 +9137,7 @@ 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. @@ -10150,7 +9148,7 @@ function ChildReconciler(shouldTrackSideEffects) { child.stateNode.implementation === portal.implementation ) { deleteRemainingChildren(returnFiber, child.sibling); - var existing = useFiber(child, portal.children || [], expirationTime); + var existing = useFiber(child, portal.children || []); existing.return = returnFiber; return existing; } else { @@ -10160,6 +9158,7 @@ function ChildReconciler(shouldTrackSideEffects) { } else { deleteChild(returnFiber, child); } + child = child.sibling; } @@ -10210,6 +9209,7 @@ function ChildReconciler(shouldTrackSideEffects) { expirationTime ) ); + case REACT_PORTAL_TYPE: return placeSingleChild( reconcileSinglePortal( @@ -10233,7 +9233,7 @@ function ChildReconciler(shouldTrackSideEffects) { ); } - if (isArray(newChild)) { + if (isArray$1(newChild)) { return reconcileChildrenArray( returnFiber, currentFirstChild, @@ -10260,6 +9260,7 @@ 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, @@ -10268,6 +9269,7 @@ 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; @@ -10299,8 +9301,8 @@ function ChildReconciler(shouldTrackSideEffects) { var reconcileChildFibers = ChildReconciler(true); var mountChildFibers = ChildReconciler(false); -function cloneChildFibers(current$$1, workInProgress) { - if (!(current$$1 === null || workInProgress.child === current$$1.child)) { +function cloneChildFibers(current, workInProgress) { + if (!(current === null || workInProgress.child === current.child)) { throw Error("Resuming work not yet implemented."); } @@ -10309,11 +9311,7 @@ function cloneChildFibers(current$$1, workInProgress) { } var currentChild = workInProgress.child; - var newChild = createWorkInProgress( - currentChild, - currentChild.pendingProps, - currentChild.expirationTime - ); + var newChild = createWorkInProgress(currentChild, currentChild.pendingProps); workInProgress.child = newChild; newChild.return = workInProgress; @@ -10321,8 +9319,7 @@ function cloneChildFibers(current$$1, workInProgress) { currentChild = currentChild.sibling; newChild = newChild.sibling = createWorkInProgress( currentChild, - currentChild.pendingProps, - currentChild.expirationTime + currentChild.pendingProps ); newChild.return = workInProgress; } @@ -10372,7 +9369,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(nextRootInstance); // Now that we know this function doesn't throw, replace it. + var nextRootContext = getRootHostContext(); // Now that we know this function doesn't throw, replace it. pop(contextStackCursor$1, fiber); push(contextStackCursor$1, nextRootContext, fiber); @@ -10392,7 +9389,7 @@ function getHostContext() { function pushHostContext(fiber) { var rootInstance = requiredContext(rootInstanceStackCursor.current); var context = requiredContext(contextStackCursor$1.current); - var nextContext = getChildHostContext(context, fiber.type, rootInstance); // Don't push this Fiber's context unless it's unique. + var nextContext = getChildHostContext(context, fiber.type); // Don't push this Fiber's context unless it's unique. if (context === nextContext) { return; @@ -10495,8 +9492,8 @@ function findFirstSuspended(row) { if ( dehydrated === null || - isSuspenseInstancePending(dehydrated) || - isSuspenseInstanceFallback(dehydrated) + isSuspenseInstancePending() || + isSuspenseInstanceFallback() ) { return node; } @@ -10507,6 +9504,7 @@ function findFirstSuspended(row) { node.memoizedProps.revealOrder !== undefined ) { var didSuspend = (node.effectTag & DidCapture) !== NoEffect; + if (didSuspend) { return node; } @@ -10535,191 +9533,7 @@ function findFirstSuspended(row) { 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$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) { +function createDeprecatedResponderListener(responder, props) { var eventResponderListener = { responder: responder, props: props @@ -10732,33 +9546,19 @@ function createResponderListener(responder, props) { return eventResponderListener; } -var NoEffect$1 = - /* */ - 0; -var UnmountSnapshot = - /* */ +var HasEffect = + /* */ + 1; // Represents the phase in which the effect (not the clean-up) fires. + +var Layout = + /* */ 2; -var UnmountMutation = - /* */ +var Passive$1 = + /* */ 4; -var MountMutation = - /* */ - 8; -var UnmountLayout = - /* */ - 16; -var MountLayout = - /* */ - 32; -var MountPassive = - /* */ - 64; -var UnmountPassive = - /* */ - 128; -var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher; -var ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig; +var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher, + ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig; var didWarnAboutMismatchedHooksForComponent; { @@ -10766,7 +9566,7 @@ var didWarnAboutMismatchedHooksForComponent; } // These are set right before calling the component. -var renderExpirationTime$1 = NoWork; // The work-in-progress fiber. I've named it differently to distinguish it from +var renderExpirationTime = 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 @@ -10775,26 +9575,12 @@ var currentlyRenderingFiber$1 = null; // Hooks are stored as a linked list on th // work-in-progress fiber. var currentHook = null; -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 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 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. @@ -10826,6 +9612,7 @@ function updateHookTypesDev() { if (hookTypesDev !== null) { hookTypesUpdateIndexDev++; + if (hookTypesDev[hookTypesUpdateIndexDev] !== hookName) { warnOnHookMismatchInDev(hookName); } @@ -10838,8 +9625,7 @@ 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. - warning$1( - false, + error( "%s received a final argument that is not an array (instead, received `%s`). When " + "specified, the final argument must be an array.", currentHookNameInDev, @@ -10852,6 +9638,7 @@ function checkDepsAreArrayDev(deps) { function warnOnHookMismatchInDev(currentHookName) { { var componentName = getComponentName(currentlyRenderingFiber$1.type); + if (!didWarnAboutMismatchedHooksForComponent.has(componentName)) { didWarnAboutMismatchedHooksForComponent.add(componentName); @@ -10874,8 +9661,7 @@ function warnOnHookMismatchInDev(currentHookName) { table += row; } - warning$1( - false, + error( "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" + @@ -10909,14 +9695,14 @@ function areHookInputsEqual(nextDeps, prevDeps) { if (prevDeps === null) { { - warning$1( - false, + error( "%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; } @@ -10924,8 +9710,7 @@ function areHookInputsEqual(nextDeps, prevDeps) { // Don't bother comparing lengths in prod because these arrays should be // passed inline. if (nextDeps.length !== prevDeps.length) { - warning$1( - false, + error( "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" + @@ -10938,7 +9723,7 @@ function areHookInputsEqual(nextDeps, prevDeps) { } for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) { - if (is$1(nextDeps[i], prevDeps[i])) { + if (objectIs(nextDeps[i], prevDeps[i])) { continue; } @@ -10953,12 +9738,11 @@ function renderWithHooks( workInProgress, Component, props, - refOrContext, + secondArg, nextRenderExpirationTime ) { - renderExpirationTime$1 = nextRenderExpirationTime; + renderExpirationTime = nextRenderExpirationTime; currentlyRenderingFiber$1 = workInProgress; - nextCurrentHook = current !== null ? current.memoizedState : null; { hookTypesDev = current !== null ? current._debugHookTypes : null; @@ -10966,89 +9750,87 @@ function renderWithHooks( ignorePreviousDependencies = current !== null && current.type !== workInProgress.type; - } // The following should have already been reset + } + + workInProgress.memoizedState = null; + workInProgress.updateQueue = null; + workInProgress.expirationTime = NoWork; // 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 nextCurrentHook === null. + // Currently we will identify the update render as a mount because memoizedState === null. // This is tricky because it's valid for certain types of components (e.g. React.lazy) - // Using nextCurrentHook to differentiate between mount/update only works if at least one stateful hook is used. + // Using memoizedState 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 nextCurrentHook would be null during updates and mounts. + // so memoizedState would be null during updates and mounts. { - if (nextCurrentHook !== null) { - ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV; + if (current !== null && current.memoizedState !== null) { + ReactCurrentDispatcher.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$1.current = HooksDispatcherOnMountWithHookTypesInDEV; + ReactCurrentDispatcher.current = HooksDispatcherOnMountWithHookTypesInDEV; } else { - ReactCurrentDispatcher$1.current = HooksDispatcherOnMountInDEV; + ReactCurrentDispatcher.current = HooksDispatcherOnMountInDEV; } } - var children = Component(props, refOrContext); + 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; - if (didScheduleRenderPhaseUpdate) { do { - didScheduleRenderPhaseUpdate = false; + 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." + ); + } + 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; - componentUpdateQueue = null; + workInProgress.updateQueue = null; { // Also validate hook order for cascading updates. hookTypesUpdateIndexDev = -1; } - ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV; - children = Component(props, refOrContext); - } while (didScheduleRenderPhaseUpdate); - - renderPhaseUpdates = null; - numberOfReRenders = 0; + ReactCurrentDispatcher.current = HooksDispatcherOnRerenderInDEV; + children = Component(props, secondArg); + } while (workInProgress.expirationTime === renderExpirationTime); } // 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$1.current = ContextOnlyDispatcher; - var renderedWork = currentlyRenderingFiber$1; - renderedWork.memoizedState = firstWorkInProgressHook; - renderedWork.expirationTime = remainingExpirationTime; - renderedWork.updateQueue = componentUpdateQueue; - renderedWork.effectTag |= sideEffectTag; + ReactCurrentDispatcher.current = ContextOnlyDispatcher; { - renderedWork._debugHookTypes = hookTypesDev; + workInProgress._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$1 = NoWork; + renderExpirationTime = NoWork; currentlyRenderingFiber$1 = null; currentHook = null; - nextCurrentHook = null; - firstWorkInProgressHook = null; workInProgressHook = null; - nextWorkInProgressHook = null; { currentHookNameInDev = null; @@ -11056,12 +9838,7 @@ function renderWithHooks( hookTypesUpdateIndexDev = -1; } - remainingExpirationTime = NoWork; - componentUpdateQueue = null; - sideEffectTag = 0; // These were reset above - // didScheduleRenderPhaseUpdate = false; - // renderPhaseUpdates = null; - // numberOfReRenders = 0; + didScheduleRenderPhaseUpdate = false; if (!!didRenderTooFewHooks) { throw Error( @@ -11079,20 +9856,37 @@ function bailoutHooks(current, workInProgress, expirationTime) { current.expirationTime = NoWork; } } -function resetHooks() { +function resetHooksAfterThrow() { // 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$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. + 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; + } - renderExpirationTime$1 = NoWork; + hook = hook.next; + } + } + + renderExpirationTime = NoWork; currentlyRenderingFiber$1 = null; currentHook = null; - nextCurrentHook = null; - firstWorkInProgressHook = null; workInProgressHook = null; - nextWorkInProgressHook = null; { hookTypesDev = null; @@ -11100,30 +9894,26 @@ function resetHooks() { 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 - firstWorkInProgressHook = workInProgressHook = hook; + currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook; } else { // Append to the end of the list workInProgressHook = workInProgressHook.next = hook; } + return workInProgressHook; } @@ -11133,12 +9923,33 @@ 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)) { @@ -11149,20 +9960,18 @@ 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. - workInProgressHook = firstWorkInProgressHook = newHook; + currentlyRenderingFiber$1.memoizedState = workInProgressHook = newHook; } else { // Append to the end of the list. workInProgressHook = workInProgressHook.next = newHook; } - - nextCurrentHook = currentHook.next; } return workInProgressHook; @@ -11175,6 +9984,7 @@ function createFunctionComponentUpdateQueue() { } function basicStateReducer(state, action) { + // $FlowFixMe: Flow doesn't like mixed types return typeof action === "function" ? action(state) : action; } @@ -11187,15 +9997,16 @@ function mountReducer(reducer, initialArg, init) { } else { initialState = initialArg; } + hook.memoizedState = hook.baseState = initialState; var queue = (hook.queue = { - last: null, + pending: null, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialState }); var dispatch = (queue.dispatch = dispatchAction.bind( - null, // Flow doesn't know this is non-null, but we do. + null, currentlyRenderingFiber$1, queue )); @@ -11213,157 +10024,191 @@ function updateReducer(reducer, initialArg, init) { } queue.lastRenderedReducer = reducer; + var current = currentHook; // The last rebase update that is NOT part of the base state. - 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 baseQueue = current.baseQueue; // The last pending update that hasn't been processed yet. - if (hook.baseUpdate === queue.last) { - hook.baseState = newState; - } + var pendingQueue = queue.pending; - queue.lastRenderedState = newState; - return [newState, _dispatch]; - } + 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; } - return [hook.memoizedState, _dispatch]; - } // The last update in the entire queue + current.baseQueue = baseQueue = pendingQueue; + queue.pending = null; + } - var last = queue.last; // The last update that is part of the base state. + if (baseQueue !== null) { + // We have a queue to process. + var first = baseQueue.next; + var newState = current.baseState; + var newBaseState = null; + var newBaseQueueFirst = null; + var newBaseQueueLast = null; + var update = first; - var baseUpdate = hook.baseUpdate; - var baseState = hook.baseState; // Find the first unprocessed update. + do { + var updateExpirationTime = update.expirationTime; - 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 newBaseUpdate = null; - var prevUpdate = baseUpdate; - var _update = first; - var didSkip = false; - - do { - var updateExpirationTime = _update.expirationTime; - - if (updateExpirationTime < renderExpirationTime$1) { + 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. - if (!didSkip) { - didSkip = true; - newBaseUpdate = prevUpdate; - newBaseState = _newState; + 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; } // Update the remaining priority in the queue. - if (updateExpirationTime > remainingExpirationTime) { - remainingExpirationTime = updateExpirationTime; - markUnprocessedUpdateTime(remainingExpirationTime); + if (updateExpirationTime > currentlyRenderingFiber$1.expirationTime) { + currentlyRenderingFiber$1.expirationTime = updateExpirationTime; + markUnprocessedUpdateTime(updateExpirationTime); } } else { // This update does have sufficient priority. - // Mark the event time of this update as relevant to this render pass. + 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. // 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); } } - prevUpdate = _update; - _update = _update.next; - } while (_update !== null && _update !== first); + update = update.next; + } while (update !== null && update !== first); - if (!didSkip) { - newBaseUpdate = prevUpdate; - newBaseState = _newState; + if (newBaseQueueLast === null) { + newBaseState = newState; + } else { + newBaseQueueLast.next = newBaseQueueFirst; } // Mark that the fiber performed work, but only if the new state is // different from the current state. - if (!is$1(_newState, hook.memoizedState)) { + if (!objectIs(newState, hook.memoizedState)) { markWorkInProgressReceivedUpdate(); } - hook.memoizedState = _newState; - hook.baseUpdate = newBaseUpdate; + hook.memoizedState = newState; hook.baseState = newBaseState; - queue.lastRenderedState = _newState; + hook.baseQueue = newBaseQueueLast; + 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 = { - last: null, + pending: null, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState }); var dispatch = (queue.dispatch = dispatchAction.bind( - null, // Flow doesn't know this is non-null, but we do. + null, currentlyRenderingFiber$1, queue )); @@ -11371,7 +10216,11 @@ function mountState(initialState) { } function updateState(initialState) { - return updateReducer(basicStateReducer, initialState); + return updateReducer(basicStateReducer); +} + +function rerenderState(initialState) { + return rerenderReducer(basicStateReducer); } function pushEffect(tag, create, destroy, deps) { @@ -11383,8 +10232,11 @@ 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; @@ -11398,6 +10250,7 @@ function pushEffect(tag, create, destroy, deps) { componentUpdateQueue.lastEffect = effect; } } + return effect; } @@ -11423,8 +10276,13 @@ function updateRef(initialValue) { function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var hook = mountWorkInProgressHook(); var nextDeps = deps === undefined ? null : deps; - sideEffectTag |= fiberEffectTag; - hook.memoizedState = pushEffect(hookEffectTag, create, undefined, nextDeps); + currentlyRenderingFiber$1.effectTag |= fiberEffectTag; + hook.memoizedState = pushEffect( + HasEffect | hookEffectTag, + create, + undefined, + nextDeps + ); } function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { @@ -11440,52 +10298,35 @@ function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var prevDeps = prevEffect.deps; if (areHookInputsEqual(nextDeps, prevDeps)) { - pushEffect(NoEffect$1, create, destroy, nextDeps); + pushEffect(hookEffectTag, create, destroy, nextDeps); return; } } } - sideEffectTag |= fiberEffectTag; - hook.memoizedState = pushEffect(hookEffectTag, create, destroy, nextDeps); + currentlyRenderingFiber$1.effectTag |= fiberEffectTag; + hook.memoizedState = pushEffect( + HasEffect | hookEffectTag, + create, + destroy, + nextDeps + ); } function mountEffect(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 - ); + return mountEffectImpl(Update | Passive, Passive$1, create, deps); } function updateEffect(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 - ); + return updateEffectImpl(Update | Passive, Passive$1, create, deps); } function mountLayoutEffect(create, deps) { - return mountEffectImpl(Update, UnmountMutation | MountLayout, create, deps); + return mountEffectImpl(Update, Layout, create, deps); } function updateLayoutEffect(create, deps) { - return updateEffectImpl(Update, UnmountMutation | MountLayout, create, deps); + return updateEffectImpl(Update, Layout, create, deps); } function imperativeHandleEffect(create, ref) { @@ -11500,15 +10341,15 @@ function imperativeHandleEffect(create, ref) { }; } else if (ref !== null && ref !== undefined) { var refObject = ref; + { - !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; + 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(", ") + "}" + ); + } } var _inst2 = create(); @@ -11522,21 +10363,20 @@ function imperativeHandleEffect(create, ref) { function mountImperativeHandle(ref, create, deps) { { - !(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; + 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" + ); + } } // 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, - UnmountMutation | MountLayout, + Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps ); @@ -11544,21 +10384,20 @@ function mountImperativeHandle(ref, create, deps) { function updateImperativeHandle(ref, create, deps) { { - !(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; + 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" + ); + } } // 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, - UnmountMutation | MountLayout, + Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps ); @@ -11593,6 +10432,7 @@ function updateCallback(callback, deps) { } } } + hook.memoizedState = [callback, nextDeps]; return callback; } @@ -11609,15 +10449,18 @@ 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; @@ -11630,17 +10473,14 @@ function mountDeferredValue(value, config) { mountEffect( function() { - Scheduler.unstable_next(function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - config === undefined ? null : config; + 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] ); @@ -11648,100 +10488,151 @@ function mountDeferredValue(value, config) { } function updateDeferredValue(value, config) { - var _updateState = updateState(value), + var _updateState = updateState(), prevValue = _updateState[0], setValue = _updateState[1]; updateEffect( function() { - Scheduler.unstable_next(function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - config === undefined ? null : config; + 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 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; + + 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 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]; + var start = mountCallback(startTransition.bind(null, setPending, config), [ + setPending, + config + ]); + return [start, isPending]; } function updateTransition(config) { - var _updateState2 = updateState(false), + var _updateState2 = updateState(), isPending = _updateState2[0], setPending = _updateState2[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 rerenderTransition(config) { + var _rerenderState2 = rerenderState(), + isPending = _rerenderState2[0], + setPending = _rerenderState2[1]; + + var start = updateCallback(startTransition.bind(null, setPending, config), [ + setPending, + config + ]); + return [start, isPending]; } function dispatchAction(fiber, queue, action) { - if (!(numberOfReRenders < RE_RENDER_LIMIT)) { - throw Error( - "Too many re-renders. React limits the number of renders to prevent an infinite loop." - ); + { + 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()." + ); + } } + 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 + }; + { - !(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; + 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; } + queue.pending = update; var alternate = fiber.alternate; + if ( fiber === currentlyRenderingFiber$1 || (alternate !== null && alternate === currentlyRenderingFiber$1) @@ -11750,76 +10641,9 @@ 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; - 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; - } + update.expirationTime = renderExpirationTime; + currentlyRenderingFiber$1.expirationTime = renderExpirationTime; } 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) @@ -11833,8 +10657,8 @@ function dispatchAction(fiber, queue, action) { var prevDispatcher; { - prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; } try { @@ -11844,10 +10668,10 @@ function dispatchAction(fiber, queue, action) { // time we enter the render phase, then the eager state can be used // without calling the reducer again. - _update2.eagerReducer = lastRenderedReducer; - _update2.eagerState = eagerState; + update.eagerReducer = lastRenderedReducer; + update.eagerState = eagerState; - if (is$1(eagerState, currentState)) { + if (objectIs(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 @@ -11858,23 +10682,24 @@ function dispatchAction(fiber, queue, action) { // Suppress the error. It will throw again in the render phase. } finally { { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.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, @@ -11889,18 +10714,20 @@ var ContextOnlyDispatcher = { useDebugValue: throwInvalidHookError, useResponder: throwInvalidHookError, useDeferredValue: throwInvalidHookError, - useTransition: throwInvalidHookError + useTransition: throwInvalidHookError, + useEvent: 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() { - warning$1( - false, + 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 " + @@ -11909,8 +10736,7 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; }; var warnInvalidHookAccess = function() { - warning$1( - false, + error( "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 " + @@ -11955,23 +10781,25 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; currentHookNameInDev = "useMemo"; mountHookTypesDev(); checkDepsAreArrayDev(deps); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; + try { return mountMemo(create, deps); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useReducer: function(reducer, initialArg, init) { currentHookNameInDev = "useReducer"; mountHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; + try { return mountReducer(reducer, initialArg, init); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useRef: function(initialValue) { @@ -11982,23 +10810,24 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; useState: function(initialState) { currentHookNameInDev = "useState"; mountHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; + try { return mountState(initialState); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useDebugValue: function(value, formatterFn) { currentHookNameInDev = "useDebugValue"; mountHookTypesDev(); - return mountDebugValue(value, formatterFn); + return mountDebugValue(); }, useResponder: function(responder, props) { currentHookNameInDev = "useResponder"; mountHookTypesDev(); - return createResponderListener(responder, props); + return createDeprecatedResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; @@ -12009,6 +10838,11 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; currentHookNameInDev = "useTransition"; mountHookTypesDev(); return mountTransition(config); + }, + useEvent: function(event) { + currentHookNameInDev = "useEvent"; + mountHookTypesDev(); + return mountEventListener(); } }; HooksDispatcherOnMountWithHookTypesInDEV = { @@ -12043,23 +10877,25 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; useMemo: function(create, deps) { currentHookNameInDev = "useMemo"; updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; + try { return mountMemo(create, deps); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useReducer: function(reducer, initialArg, init) { currentHookNameInDev = "useReducer"; updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; + try { return mountReducer(reducer, initialArg, init); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useRef: function(initialValue) { @@ -12070,23 +10906,24 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; useState: function(initialState) { currentHookNameInDev = "useState"; updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; + try { return mountState(initialState); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useDebugValue: function(value, formatterFn) { currentHookNameInDev = "useDebugValue"; updateHookTypesDev(); - return mountDebugValue(value, formatterFn); + return mountDebugValue(); }, useResponder: function(responder, props) { currentHookNameInDev = "useResponder"; updateHookTypesDev(); - return createResponderListener(responder, props); + return createDeprecatedResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; @@ -12097,6 +10934,11 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; currentHookNameInDev = "useTransition"; updateHookTypesDev(); return mountTransition(config); + }, + useEvent: function(event) { + currentHookNameInDev = "useEvent"; + updateHookTypesDev(); + return mountEventListener(); } }; HooksDispatcherOnUpdateInDEV = { @@ -12131,50 +10973,53 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; useMemo: function(create, deps) { currentHookNameInDev = "useMemo"; updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + try { return updateMemo(create, deps); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useReducer: function(reducer, initialArg, init) { currentHookNameInDev = "useReducer"; updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + try { return updateReducer(reducer, initialArg, init); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useRef: function(initialValue) { currentHookNameInDev = "useRef"; updateHookTypesDev(); - return updateRef(initialValue); + return updateRef(); }, useState: function(initialState) { currentHookNameInDev = "useState"; updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + try { return updateState(initialState); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useDebugValue: function(value, formatterFn) { currentHookNameInDev = "useDebugValue"; updateHookTypesDev(); - return updateDebugValue(value, formatterFn); + return updateDebugValue(); }, useResponder: function(responder, props) { currentHookNameInDev = "useResponder"; updateHookTypesDev(); - return createResponderListener(responder, props); + return createDeprecatedResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; @@ -12185,70 +11030,173 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; currentHookNameInDev = "useTransition"; updateHookTypesDev(); return updateTransition(config); + }, + useEvent: function(event) { + currentHookNameInDev = "useEvent"; + updateHookTypesDev(); + return updateEventListener(); } }; - InvalidNestedHooksDispatcherOnMountInDEV = { + HooksDispatcherOnRerenderInDEV = { readContext: function(context, observedBits) { - warnInvalidContextAccess(); return readContext(context, observedBits); }, useCallback: function(callback, deps) { currentHookNameInDev = "useCallback"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountCallback(callback, deps); + updateHookTypesDev(); + return updateCallback(callback, deps); }, useContext: function(context, observedBits) { currentHookNameInDev = "useContext"; - warnInvalidHookAccess(); - mountHookTypesDev(); + updateHookTypesDev(); return readContext(context, observedBits); }, useEffect: function(create, deps) { currentHookNameInDev = "useEffect"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountEffect(create, deps); + updateHookTypesDev(); + return updateEffect(create, deps); }, useImperativeHandle: function(ref, create, deps) { currentHookNameInDev = "useImperativeHandle"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountImperativeHandle(ref, create, deps); + updateHookTypesDev(); + return updateImperativeHandle(ref, create, deps); }, useLayoutEffect: function(create, deps) { currentHookNameInDev = "useLayoutEffect"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountLayoutEffect(create, deps); + updateHookTypesDev(); + return updateLayoutEffect(create, deps); }, useMemo: function(create, deps) { currentHookNameInDev = "useMemo"; - warnInvalidHookAccess(); - mountHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnRerenderInDEV; + try { - return mountMemo(create, deps); + return updateMemo(create, deps); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useReducer: function(reducer, initialArg, init) { currentHookNameInDev = "useReducer"; - warnInvalidHookAccess(); - mountHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnRerenderInDEV; + try { - return mountReducer(reducer, initialArg, init); + return rerenderReducer(reducer, initialArg, init); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useRef: function(initialValue) { currentHookNameInDev = "useRef"; - warnInvalidHookAccess(); + 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 = { + 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); }, @@ -12256,25 +11204,26 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; currentHookNameInDev = "useState"; warnInvalidHookAccess(); mountHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; + try { return mountState(initialState); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useDebugValue: function(value, formatterFn) { currentHookNameInDev = "useDebugValue"; warnInvalidHookAccess(); mountHookTypesDev(); - return mountDebugValue(value, formatterFn); + return mountDebugValue(); }, useResponder: function(responder, props) { currentHookNameInDev = "useResponder"; warnInvalidHookAccess(); mountHookTypesDev(); - return createResponderListener(responder, props); + return createDeprecatedResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; @@ -12287,6 +11236,12 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; warnInvalidHookAccess(); mountHookTypesDev(); return mountTransition(config); + }, + useEvent: function(event) { + currentHookNameInDev = "useEvent"; + warnInvalidHookAccess(); + mountHookTypesDev(); + return mountEventListener(); } }; InvalidNestedHooksDispatcherOnUpdateInDEV = { @@ -12328,55 +11283,58 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; currentHookNameInDev = "useMemo"; warnInvalidHookAccess(); updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + try { return updateMemo(create, deps); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useReducer: function(reducer, initialArg, init) { currentHookNameInDev = "useReducer"; warnInvalidHookAccess(); updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + try { return updateReducer(reducer, initialArg, init); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useRef: function(initialValue) { currentHookNameInDev = "useRef"; warnInvalidHookAccess(); updateHookTypesDev(); - return updateRef(initialValue); + return updateRef(); }, useState: function(initialState) { currentHookNameInDev = "useState"; warnInvalidHookAccess(); updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + try { return updateState(initialState); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useDebugValue: function(value, formatterFn) { currentHookNameInDev = "useDebugValue"; warnInvalidHookAccess(); updateHookTypesDev(); - return updateDebugValue(value, formatterFn); + return updateDebugValue(); }, useResponder: function(responder, props) { currentHookNameInDev = "useResponder"; warnInvalidHookAccess(); updateHookTypesDev(); - return createResponderListener(responder, props); + return createDeprecatedResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; @@ -12389,2412 +11347,951 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; warnInvalidHookAccess(); updateHookTypesDev(); return updateTransition(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; - -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. - - 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 (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, - shouldUpdate, - hasContext, - renderExpirationTime -) { - // 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 - ); - } - - 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 { - { - 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); - } - - return workInProgress.child; -} - -function pushHostRootContext(workInProgress) { - var root = workInProgress.stateNode; - if (root.pendingContext) { - pushTopLevelContextObject( - workInProgress, - root.pendingContext, - root.pendingContext !== root.context - ); - } else if (root.context) { - // Should always be set - pushTopLevelContextObject(workInProgress, root.context, false); - } - pushHostContainer(workInProgress, root.containerInfo); -} - -function updateHostRoot(current$$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." - ); - } - - 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 - ); - 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 updateHostComponent(current$$1, workInProgress, renderExpirationTime) { - pushHostContext(workInProgress); - - 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, - nextChildren, - renderExpirationTime - ); - return workInProgress.child; -} - -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, - elementType, - updateExpirationTime, - renderExpirationTime -) { - 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 - - 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 - ); - 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; - } - - 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 - ); - } - } - } - - return 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. - - 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, - Component, - true, - hasContext, - renderExpirationTime - ); -} - -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 - - workInProgress.effectTag |= Placement; - } - - var props = workInProgress.pendingProps; - var context; - - if (!disableLegacyContext) { - 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"; + 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; - 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; + try { + return updateMemo(create, deps); + } finally { + ReactCurrentDispatcher.current = prevDispatcher; } - } - - if (workInProgress.mode & StrictMode) { - ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null); - } - - ReactCurrentOwner$3.current = workInProgress; - value = renderWithHooks( - null, - workInProgress, - Component, - props, - context, - renderExpirationTime - ); - } // React DevTools reads this flag. - - workInProgress.effectTag |= PerformedWork; + }, + useReducer: function(reducer, initialArg, init) { + currentHookNameInDev = "useReducer"; + warnInvalidHookAccess(); + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; - 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; + try { + return rerenderReducer(reducer, initialArg, init); + } finally { + ReactCurrentDispatcher.current = prevDispatcher; } - } // Proceed under the assumption that this is a class instance - - workInProgress.tag = ClassComponent; // Throw out any hooks that were used. - - 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 hasContext = false; - - if (isContextProvider(Component)) { - hasContext = true; - pushContextProvider(workInProgress); - } else { - hasContext = false; - } - - workInProgress.memoizedState = - value.state !== null && value.state !== undefined ? value.state : null; - var getDerivedStateFromProps = Component.getDerivedStateFromProps; + }, + useRef: function(initialValue) { + currentHookNameInDev = "useRef"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateRef(); + }, + useState: function(initialState) { + currentHookNameInDev = "useState"; + warnInvalidHookAccess(); + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; - if (typeof getDerivedStateFromProps === "function") { - applyDerivedStateFromProps( - workInProgress, - Component, - getDerivedStateFromProps, - props - ); + 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(); } + }; +} - 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 now$1 = Scheduler.unstable_now; +var commitTime = 0; +var profilerStartTime = -1; - if ( - debugRenderPhaseSideEffectsForStrictMode && - workInProgress.mode & StrictMode - ) { - // Only double-render components with Hooks - if (workInProgress.memoizedState !== null) { - value = renderWithHooks( - null, - workInProgress, - Component, - props, - context, - renderExpirationTime - ); - } - } - } +function getCommitTime() { + return commitTime; +} - reconcileChildren(null, workInProgress, value, renderExpirationTime); +function recordCommitTime() { + commitTime = now$1(); +} - { - validateFunctionComponentInDev(workInProgress, Component); - } +function startProfilerTimer(fiber) { + profilerStartTime = now$1(); - return workInProgress.child; + if (fiber.actualStartTime < 0) { + fiber.actualStartTime = now$1(); } } -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 stopProfilerTimerIfRunning(fiber) { + profilerStartTime = -1; +} - if (workInProgress.ref !== null) { - var info = ""; - var ownerName = getCurrentFiberOwnerNameInDevOrNull(); +function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) { + if (profilerStartTime >= 0) { + var elapsedTime = now$1() - profilerStartTime; + fiber.actualDuration += elapsedTime; - if (ownerName) { - info += "\n\nCheck the render method of `" + ownerName + "`."; + if (overrideBaseTime) { + fiber.selfBaseDuration = elapsedTime; } - var warningKey = ownerName || workInProgress._debugID || ""; - var debugSource = workInProgress._debugSource; + profilerStartTime = -1; + } +} - if (debugSource) { - warningKey = debugSource.fileName + ":" + debugSource.lineNumber; - } +function enterHydrationState(fiber) { + { + return false; + } +} - 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 +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." ); } } +} - 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 +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." ); - didWarnAboutDefaultPropsOnFunctionComponent[componentName] = true; } } + var shouldUpdate = hydrateTextInstance(); +} - 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; - } +function popHydrationState(fiber) { + { + return false; } +} - if ( - typeof Component.contextType === "object" && - Component.contextType !== null - ) { - var _componentName3 = getComponentName(Component) || "Unknown"; +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 (!didWarnAboutContextTypeOnFunctionComponent[_componentName3]) { - warningWithoutStack$1( - false, - "%s: Function components do not support contextType.", - _componentName3 - ); - didWarnAboutContextTypeOnFunctionComponent[_componentName3] = true; - } +{ + didWarnAboutBadClass = {}; + didWarnAboutModulePatternComponent = {}; + didWarnAboutContextTypeOnFunctionComponent = {}; + didWarnAboutGetDerivedStateOnFunctionComponent = {}; + didWarnAboutFunctionRefs = {}; + didWarnAboutReassigningProps = false; + didWarnAboutRevealOrder = {}; + didWarnAboutTailOptions = {}; +} + +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 + ); } } -var SUSPENDED_MARKER = { - dehydrated: null, - retryTime: NoWork -}; +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 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) + workInProgress.child = reconcileChildFibers( + workInProgress, + null, + nextChildren, + renderExpirationTime ); } -function updateSuspenseComponent( - current$$1, +function updateForwardRef( + current, workInProgress, + Component, + nextProps, renderExpirationTime ) { - var mode = workInProgress.mode; - var nextProps = workInProgress.pendingProps; // This is used by DevTools to force a boundary to suspend. - + // 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 (shouldSuspend(workInProgress)) { - workInProgress.effectTag |= DidCapture; - } - } - - var suspenseContext = suspenseStackCursor.current; - var nextDidTimeout = false; - var didSuspend = (workInProgress.effectTag & DidCapture) !== NoEffect; + if (workInProgress.type !== workInProgress.elementType) { + // Lazy component props can't be validated in createElement + // because they're only guaranteed to be resolved here. + var innerPropTypes = Component.propTypes; - if ( - didSuspend || - shouldRemainOnFallback(suspenseContext, current$$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 + if (innerPropTypes) { + checkPropTypes( + innerPropTypes, + nextProps, // Resolved props + "prop", + getComponentName(Component) ); } } } - suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); - 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. - // 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; + var render = Component.render; + var ref = workInProgress.ref; // The rest is a fork of updateFunctionComponent - 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. + var nextChildren; + prepareToReadContext(workInProgress, renderExpirationTime); - if (nextDidTimeout) { - // Mount separate fragments for primary and fallback children. - var nextFallbackChildren = nextProps.fallback; - var primaryChildFragment = createFiberFromFragment( - null, - mode, - NoWork, - null - ); - primaryChildFragment.return = workInProgress; + { + ReactCurrentOwner$1.current = workInProgress; + setIsRendering(true); + nextChildren = renderWithHooks( + current, + workInProgress, + render, + nextProps, + ref, + 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 progressedPrimaryChild = - progressedState !== null - ? workInProgress.child.child - : workInProgress.child; - primaryChildFragment.child = progressedPrimaryChild; - var progressedChild = progressedPrimaryChild; - while (progressedChild !== null) { - progressedChild.return = primaryChildFragment; - progressedChild = progressedChild.sibling; - } + if (workInProgress.mode & StrictMode) { + // Only double-render components with Hooks + if (workInProgress.memoizedState !== null) { + nextChildren = renderWithHooks( + current, + workInProgress, + render, + nextProps, + ref, + renderExpirationTime + ); } - - 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 - )); } - } 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 - ); + setIsRendering(false); + } - _primaryChildFragment.return = workInProgress; // This is always null since we never want the previous child - // that we're not going to hydrate. + if (current !== null && !didReceiveUpdate) { + bailoutHooks(current, workInProgress, renderExpirationTime); + return bailoutOnAlreadyFinishedWork( + current, + workInProgress, + renderExpirationTime + ); + } // React DevTools reads this flag. - _primaryChildFragment.child = null; + workInProgress.effectTag |= PerformedWork; + reconcileChildren( + current, + workInProgress, + nextChildren, + 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 _progressedChild = (_primaryChildFragment.child = - workInProgress.child); +function updateMemoComponent( + current, + workInProgress, + Component, + nextProps, + updateExpirationTime, + renderExpirationTime +) { + if (current === null) { + var type = Component.type; - 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 ( + isSimpleFunctionComponent(type) && + Component.compare === null && // SimpleMemoComponent codepath doesn't resolve outer props either. + Component.defaultProps === undefined + ) { + var resolvedType = type; - if (enableProfilerTimer && workInProgress.mode & ProfileMode) { - // treeBaseDuration is the sum of all the child tree base durations. - var treeBaseDuration = 0; - var hiddenChild = _primaryChildFragment.child; + { + 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. - while (hiddenChild !== null) { - treeBaseDuration += hiddenChild.treeBaseDuration; - hiddenChild = hiddenChild.sibling; - } + workInProgress.tag = SimpleMemoComponent; + workInProgress.type = resolvedType; - _primaryChildFragment.treeBaseDuration = treeBaseDuration; - } // Create a fragment from the fallback children, too. + { + validateFunctionComponentInDev(workInProgress, type); + } - var _fallbackChildFragment = createFiberFromFragment( - _nextFallbackChildren, - mode, - renderExpirationTime, - null - ); + return updateSimpleMemoComponent( + current, + workInProgress, + resolvedType, + nextProps, + updateExpirationTime, + renderExpirationTime + ); + } - _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. + { + var innerPropTypes = type.propTypes; - return _fallbackChildFragment; - } - } - } // The current tree already timed out. That means each child set is - // wrapped in a fragment fiber. + if (innerPropTypes) { + // Inner memo component props aren't currently validated in createElement. + // We could move it there, but we'd still need this for lazy code path. + checkPropTypes( + innerPropTypes, + nextProps, // Resolved props + "prop", + getComponentName(type) + ); + } + } - var currentPrimaryChildFragment = current$$1.child; - var currentFallbackChildFragment = currentPrimaryChildFragment.sibling; + var child = createFiberFromTypeAndProps( + Component.type, + null, + nextProps, + null, + workInProgress.mode, + renderExpirationTime + ); + child.ref = workInProgress.ref; + child.return = workInProgress; + workInProgress.child = child; + return child; + } - 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 _type = Component.type; + var _innerPropTypes = _type.propTypes; - var _primaryChildFragment2 = createWorkInProgress( - currentPrimaryChildFragment, - currentPrimaryChildFragment.pendingProps, - NoWork - ); + 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) + ); + } + } - _primaryChildFragment2.return = workInProgress; + var currentChild = current.child; // This is always exactly one 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; + 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 _progressedPrimaryChild = - _progressedState !== null - ? workInProgress.child.child - : workInProgress.child; + var compare = Component.compare; + compare = compare !== null ? compare : shallowEqual; - if (_progressedPrimaryChild !== currentPrimaryChildFragment.child) { - _primaryChildFragment2.child = _progressedPrimaryChild; - var _progressedChild2 = _progressedPrimaryChild; + if (compare(prevProps, nextProps) && current.ref === workInProgress.ref) { + return bailoutOnAlreadyFinishedWork( + current, + workInProgress, + renderExpirationTime + ); + } + } // React DevTools reads this flag. - 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. + workInProgress.effectTag |= PerformedWork; + var newChild = createWorkInProgress(currentChild, nextProps); + newChild.ref = workInProgress.ref; + newChild.return = workInProgress; + workInProgress.child = newChild; + return newChild; +} - if (enableProfilerTimer && workInProgress.mode & ProfileMode) { - // treeBaseDuration is the sum of all the child tree base durations. - var _treeBaseDuration = 0; - var _hiddenChild = _primaryChildFragment2.child; +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; - while (_hiddenChild !== null) { - _treeBaseDuration += _hiddenChild.treeBaseDuration; - _hiddenChild = _hiddenChild.sibling; - } + 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); + } - _primaryChildFragment2.treeBaseDuration = _treeBaseDuration; - } // Clone the fallback child fragment, too. These we'll continue - // working on. + var outerPropTypes = outerMemoType && outerMemoType.propTypes; - var _fallbackChildFragment2 = createWorkInProgress( - currentFallbackChildFragment, - _nextFallbackChildren2, - currentFallbackChildFragment.expirationTime + if (outerPropTypes) { + checkPropTypes( + outerPropTypes, + nextProps, // Resolved (SimpleMemoComponent has no defaultProps) + "prop", + getComponentName(outerMemoType) ); + } // Inner propTypes will be validated in the function component path. + } + } - _fallbackChildFragment2.return = workInProgress; - _primaryChildFragment2.sibling = _fallbackChildFragment2; - _primaryChildFragment2.childExpirationTime = NoWork; // Skip the primary children, and continue working on the - // fallback children. + if (current !== null) { + var prevProps = current.memoizedProps; - 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( + if ( + shallowEqual(prevProps, nextProps) && + current.ref === workInProgress.ref && // Prevent bailout if the implementation changed due to hot reload. + workInProgress.type === current.type + ) { + didReceiveUpdate = false; + + if (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, - 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.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; + } + } - if (nextDidTimeout) { - // Timed out. Wrap the children in a fragment fiber to keep them - // separate from the fallback children. - var _nextFallbackChildren3 = nextProps.fallback; + return updateFunctionComponent( + current, + workInProgress, + Component, + nextProps, + renderExpirationTime + ); +} - 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 - ); +function updateFragment(current, workInProgress, renderExpirationTime) { + var nextChildren = workInProgress.pendingProps; + reconcileChildren( + current, + workInProgress, + nextChildren, + renderExpirationTime + ); + return workInProgress.child; +} - _primaryChildFragment3.return = workInProgress; - _primaryChildFragment3.child = _currentPrimaryChild; +function updateMode(current, workInProgress, renderExpirationTime) { + var nextChildren = workInProgress.pendingProps.children; + reconcileChildren( + current, + workInProgress, + nextChildren, + renderExpirationTime + ); + 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 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 ((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 stateNode = workInProgress.stateNode; + stateNode.effectDuration = 0; + stateNode.passiveEffectDuration = 0; + } - var _progressedPrimaryChild2 = - _progressedState2 !== null - ? workInProgress.child.child - : workInProgress.child; + var nextProps = workInProgress.pendingProps; + var nextChildren = nextProps.children; + reconcileChildren( + current, + workInProgress, + nextChildren, + renderExpirationTime + ); + return workInProgress.child; +} + +function markRef(current, workInProgress) { + var ref = workInProgress.ref; - _primaryChildFragment3.child = _progressedPrimaryChild2; - var _progressedChild3 = _progressedPrimaryChild2; + if ( + (current === null && ref !== null) || + (current !== null && current.ref !== ref) + ) { + // Schedule a Ref effect + workInProgress.effectTag |= Ref; + } +} - 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 updateFunctionComponent( + 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 (enableProfilerTimer && workInProgress.mode & ProfileMode) { - // treeBaseDuration is the sum of all the child tree base durations. - var _treeBaseDuration2 = 0; - var _hiddenChild2 = _primaryChildFragment3.child; + if (innerPropTypes) { + checkPropTypes( + innerPropTypes, + nextProps, // Resolved props + "prop", + getComponentName(Component) + ); + } + } + } - while (_hiddenChild2 !== null) { - _treeBaseDuration2 += _hiddenChild2.treeBaseDuration; - _hiddenChild2 = _hiddenChild2.sibling; - } + var context; - _primaryChildFragment3.treeBaseDuration = _treeBaseDuration2; - } // Create a fragment from the fallback children, too. + { + var unmaskedContext = getUnmaskedContext(workInProgress, Component, true); + context = getMaskedContext(workInProgress, unmaskedContext); + } - var _fallbackChildFragment3 = createFiberFromFragment( - _nextFallbackChildren3, - mode, - renderExpirationTime, - null - ); + var nextChildren; + prepareToReadContext(workInProgress, renderExpirationTime); - _fallbackChildFragment3.return = workInProgress; - _primaryChildFragment3.sibling = _fallbackChildFragment3; - _fallbackChildFragment3.effectTag |= Placement; - _primaryChildFragment3.childExpirationTime = NoWork; // Skip the primary children, and continue working on the - // fallback children. + { + ReactCurrentOwner$1.current = workInProgress; + setIsRendering(true); + nextChildren = renderWithHooks( + current, + workInProgress, + Component, + nextProps, + context, + renderExpirationTime + ); - 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( + if (workInProgress.mode & StrictMode) { + // Only double-render components with Hooks + if (workInProgress.memoizedState !== null) { + nextChildren = renderWithHooks( + current, workInProgress, - _currentPrimaryChild, - _nextPrimaryChildren2, + Component, + nextProps, + context, renderExpirationTime - )); + ); } } + + setIsRendering(false); } + + if (current !== null && !didReceiveUpdate) { + bailoutHooks(current, workInProgress, renderExpirationTime); + return bailoutOnAlreadyFinishedWork( + current, + workInProgress, + renderExpirationTime + ); + } // React DevTools reads this flag. + + workInProgress.effectTag |= PerformedWork; + reconcileChildren( + current, + workInProgress, + nextChildren, + renderExpirationTime + ); + return workInProgress.child; } -function retrySuspenseComponentWithoutHydrating( - current$$1, +function updateClassComponent( + current, workInProgress, + Component, + nextProps, renderExpirationTime ) { - // We're now not suspended nor dehydrated. - workInProgress.memoizedState = null; // Retry with the full children. + { + if (workInProgress.type !== workInProgress.elementType) { + // Lazy component props can't be validated in createElement + // because they're only guaranteed to be resolved here. + var innerPropTypes = Component.propTypes; - var 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. + 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. - reconcileChildren( - current$$1, + 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 !== 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, workInProgress, - nextChildren, + Component, + shouldUpdate, + hasContext, renderExpirationTime ); - return workInProgress.child; + + { + 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 mountDehydratedSuspenseComponent( +function finishClassComponent( + current, workInProgress, - suspenseInstance, + Component, + shouldUpdate, + hasContext, 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." - ); + // 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); } - 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. + return bailoutOnAlreadyFinishedWork( + current, + workInProgress, + renderExpirationTime + ); + } - var newExpirationTime = computeAsyncExpiration(serverDisplayTime); + var instance = workInProgress.stateNode; // Rerender - if (enableSchedulerTracing) { - markSpawnedWork(newExpirationTime); - } + ReactCurrentOwner$1.current = workInProgress; + var nextChildren; - workInProgress.expirationTime = newExpirationTime; + if ( + didCaptureError && + typeof Component.getDerivedStateFromError !== "function" + ) { + // If we captured an error, but getDerivedStateFromError is not defined, + // unmount all the children. componentDidCatch will schedule an update to + // re-render a fallback. This is temporary until we migrate everyone to + // the new API. + // TODO: Warn in a future release. + nextChildren = null; + + { + stopProfilerTimerIfRunning(); + } } else { - // 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; + { + setIsRendering(true); + nextChildren = instance.render(); - if (enableSchedulerTracing) { - markSpawnedWork(Never); + if (workInProgress.mode & StrictMode) { + instance.render(); + } + + setIsRendering(false); } + } // React DevTools reads this flag. + + workInProgress.effectTag |= PerformedWork; + + if (current !== null && didCaptureError) { + // If we're recovering from an error, reconcile without reusing any of + // the existing children. Conceptually, the normal children and the children + // that are shown on error are two different sets, so we shouldn't reuse + // normal children even if their identities match. + forceUnmountCurrentAndReconcile( + current, + workInProgress, + nextChildren, + 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. + + workInProgress.memoizedState = instance.state; // The context might have changed so we need to recalculate it. + + if (hasContext) { + invalidateContextProvider(workInProgress, Component, true); } - return null; + return workInProgress.child; } -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(); +function pushHostRootContext(workInProgress) { + var root = workInProgress.stateNode; - if ((workInProgress.mode & BlockingMode) === NoMode) { - return retrySuspenseComponentWithoutHydrating( - current$$1, + if (root.pendingContext) { + pushTopLevelContextObject( workInProgress, - renderExpirationTime + root.pendingContext, + root.pendingContext !== root.context ); + } else if (root.context) { + // Should always be set + pushTopLevelContextObject(workInProgress, root.context, false); } - 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 + pushHostContainer(workInProgress, root.containerInfo); +} + +function updateHostRoot(current, workInProgress, renderExpirationTime) { + pushHostRootContext(workInProgress); + var updateQueue = workInProgress.updateQueue; + + if (!(current !== null && updateQueue !== null)) { + throw Error( + "If the root does not have an updateQueue, we should have already bailed out. This error is likely caused by a bug in React. Please file an issue." ); - } // 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, + } + + 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 nextChildren = nextState.element; + + if (nextChildren === prevChildren) { + return bailoutOnAlreadyFinishedWork( + current, 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 root = workInProgress.stateNode; + + 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; while (node) { @@ -14804,4133 +12301,3612 @@ function updateDehydratedSuspenseComponent( // 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; - } - - 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 (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; - } -} - -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; - } - - return lastContentRow; -} - -function validateRevealOrder(revealOrder) { - { - if ( - revealOrder !== undefined && - revealOrder !== "forwards" && - revealOrder !== "backwards" && - revealOrder !== "together" && - !didWarnAboutRevealOrder[revealOrder] - ) { - didWarnAboutRevealOrder[revealOrder] = true; - if (typeof revealOrder === "string") { - switch (revealOrder.toLowerCase()) { - case "together": - case "forwards": - case "backwards": { - 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 - ); - } - } - } -} - -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 - ); - } - } - } -} - -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; -} - -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); + node.effectTag = (node.effectTag & ~Placement) | Hydrating; + node = node.sibling; + } + } else { + // Otherwise reset hydration state in case we aborted and resumed another + // root. + reconcileChildren( + current, + workInProgress, + nextChildren, + renderExpirationTime + ); + } - if (typeof iteratorFn === "function") { - var childrenIterator = iteratorFn.call(children); + return workInProgress.child; +} - if (childrenIterator) { - var step = childrenIterator.next(); - var _i = 0; +function updateHostComponent(current, workInProgress, renderExpirationTime) { + pushHostContext(workInProgress); - 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 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; } -} -function initSuspenseListRenderState( - workInProgress, - isBackwards, - tail, - lastContentRow, - tailMode, - lastEffectBeforeRendering -) { - var renderState = workInProgress.memoizedState; + markRef(current, workInProgress); // Check the host config to see if the children are offscreen/hidden. - 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; + 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; } -} // 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, + current, workInProgress, - newChildren, + nextChildren, 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 updateHostText(current, workInProgress) { + // immediately after. + + return null; +} + +function mountLazyComponent( + _current, + 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 + + workInProgress.effectTag |= Placement; } - pushSuspenseContext(workInProgress, suspenseContext); + 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. - 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; + cancelWorkTimer(workInProgress); + var Component = readLazyComponentType(elementType); // Store the unwrapped component in the type. - 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 + 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 ); - break; } - case "backwards": { - // We're going to find the first row that has existing content. - // At the same time we're going to reverse the list of everything - // we pass in the meantime. That's going to be our tail in reverse - // order. - var _tail = null; - var row = workInProgress.child; - workInProgress.child = null; - - while (row !== null) { - var currentRow = row.alternate; // New rows can't be content rows. - - if (currentRow !== null && findFirstSuspended(currentRow) === null) { - // This is the beginning of the main content. - workInProgress.child = row; - break; - } - var nextRow = row.sibling; - row.sibling = _tail; - _tail = row; - row = nextRow; - } // TODO: If workInProgress.child is null, we can continue on the tail immediately. + child = updateFunctionComponent( + null, + workInProgress, + Component, + resolvedProps, + renderExpirationTime + ); + return child; + } - initSuspenseListRenderState( - workInProgress, - true, // isBackwards - _tail, - null, // last - tailMode, - workInProgress.lastEffect + case ClassComponent: { + { + workInProgress.type = Component = resolveClassForHotReloading( + Component ); - break; } - case "together": { - initSuspenseListRenderState( - workInProgress, - false, // isBackwards - null, // tail - null, // last - undefined, - workInProgress.lastEffect + child = updateClassComponent( + null, + workInProgress, + Component, + resolvedProps, + renderExpirationTime + ); + return child; + } + + case ForwardRef: { + { + workInProgress.type = Component = resolveForwardRefForHotReloading( + Component ); - break; } - default: { - // The default reveal order is the same as not having - // a boundary. - workInProgress.memoizedState = null; + child = updateForwardRef( + null, + workInProgress, + Component, + resolvedProps, + renderExpirationTime + ); + return child; + } + + case MemoComponent: { + { + if (workInProgress.type !== workInProgress.elementType) { + var outerPropTypes = Component.propTypes; + + if (outerPropTypes) { + checkPropTypes( + outerPropTypes, + resolvedProps, // Resolved for outer only + "prop", + getComponentName(Component) + ); + } + } } + + child = updateMemoComponent( + null, + workInProgress, + Component, + resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too + updateExpirationTime, + renderExpirationTime + ); + return child; } } - return workInProgress.child; -} -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 + 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 ); } - return workInProgress.child; } -function updateContextProvider( - current$$1, +function mountIncompleteClassComponent( + _current, workInProgress, + Component, + nextProps, renderExpirationTime ) { - var providerType = workInProgress.type; - var context = providerType._context; - var newProps = workInProgress.pendingProps; - var oldProps = workInProgress.memoizedProps; - var newValue = newProps.value; + if (_current !== null) { + // An incomplete component only mounts if it suspended inside a non- + // concurrent tree, in an inconsistent state. We want to treat it like + // a new mount, even though an empty version of it already committed. + // Disconnect the alternate pointers. + _current.alternate = null; + workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect - { - var providerPropTypes = workInProgress.type.propTypes; + workInProgress.effectTag |= Placement; + } // Promote the fiber to a class and try rendering again. - if (providerPropTypes) { - checkPropTypes( - providerPropTypes, - newProps, - "prop", - "Context.Provider", - getCurrentFiberStackInDev - ); - } - } + 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. - pushProvider(workInProgress, newValue); + var hasContext; - 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 - ); - } + if (isContextProvider(Component)) { + hasContext = true; + pushContextProvider(workInProgress); + } else { + hasContext = false; } - var newChildren = newProps.children; - reconcileChildren( - current$$1, + prepareToReadContext(workInProgress, renderExpirationTime); + constructClassInstance(workInProgress, Component, nextProps); + mountClassInstance( workInProgress, - newChildren, + Component, + nextProps, + renderExpirationTime + ); + return finishClassComponent( + null, + workInProgress, + Component, + true, + hasContext, renderExpirationTime ); - return workInProgress.child; } -var hasWarnedAboutUsingContextAsConsumer = false; - -function updateContextConsumer( - current$$1, +function mountIndeterminateComponent( + _current, workInProgress, + Component, 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 { - context = context._context; - } + 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 newProps = workInProgress.pendingProps; - var render = newProps.children; + + var props = workInProgress.pendingProps; + var context; { - !(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 unmaskedContext = getUnmaskedContext(workInProgress, Component, false); + context = getMaskedContext(workInProgress, unmaskedContext); } prepareToReadContext(workInProgress, renderExpirationTime); - var newValue = readContext(context, newProps.unstable_observedBits); - var newChildren; + var value; { - ReactCurrentOwner$3.current = workInProgress; - setCurrentPhase("render"); - newChildren = render(newValue); - setCurrentPhase(null); + if ( + Component.prototype && + typeof Component.prototype.render === "function" + ) { + var componentName = getComponentName(Component) || "Unknown"; + + if (!didWarnAboutBadClass[componentName]) { + error( + "The <%s /> component appears to have a render method, but doesn't extend React.Component. " + + "This is likely to cause errors. Change %s to extend React.Component instead.", + componentName, + componentName + ); + + didWarnAboutBadClass[componentName] = true; + } + } + + if (workInProgress.mode & StrictMode) { + ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null); + } + + ReactCurrentOwner$1.current = workInProgress; + value = renderWithHooks( + null, + workInProgress, + Component, + props, + context, + renderExpirationTime + ); } // React DevTools reads this flag. workInProgress.effectTag |= PerformedWork; - reconcileChildren( - current$$1, - workInProgress, - newChildren, - renderExpirationTime - ); - return workInProgress.child; -} -function updateFundamentalComponent$1( - current$$1, - workInProgress, - renderExpirationTime -) { - var fundamentalImpl = workInProgress.type.impl; + if ( + typeof value === "object" && + value !== null && + typeof value.render === "function" && + value.$$typeof === undefined + ) { + { + var _componentName = getComponentName(Component) || "Unknown"; - if (fundamentalImpl.reconcileChildren === false) { - return null; - } + if (!didWarnAboutModulePatternComponent[_componentName]) { + error( + "The <%s /> component appears to be a function component that returns a class instance. " + + "Change %s to a class that extends React.Component instead. " + + "If you can't use a class try assigning the prototype on the function as a workaround. " + + "`%s.prototype = React.Component.prototype`. Don't use an arrow function since it " + + "cannot be called with `new` by React.", + _componentName, + _componentName, + _componentName + ); + + didWarnAboutModulePatternComponent[_componentName] = true; + } + } // Proceed under the assumption that this is a class instance - var nextProps = workInProgress.pendingProps; - var nextChildren = nextProps.children; - reconcileChildren( - current$$1, - workInProgress, - nextChildren, - renderExpirationTime - ); - return workInProgress.child; -} + workInProgress.tag = ClassComponent; // Throw out any hooks that were used. -function updateScopeComponent( - current$$1, - workInProgress, - renderExpirationTime -) { - var nextProps = workInProgress.pendingProps; - var nextChildren = nextProps.children; - reconcileChildren( - current$$1, - workInProgress, - nextChildren, - renderExpirationTime - ); - return workInProgress.child; -} + workInProgress.memoizedState = null; + workInProgress.updateQueue = null; // Push context providers early to prevent context stack mismatches. + // During mounting we don't know the child context yet as the instance doesn't exist. + // We will invalidate the child context in finishClassComponent() right after rendering. -function markWorkInProgressReceivedUpdate() { - didReceiveUpdate = true; -} + var hasContext = false; -function bailoutOnAlreadyFinishedWork( - current$$1, - workInProgress, - renderExpirationTime -) { - cancelWorkTimer(workInProgress); + if (isContextProvider(Component)) { + hasContext = true; + pushContextProvider(workInProgress); + } else { + hasContext = false; + } - if (current$$1 !== null) { - // Reuse previous dependencies - workInProgress.dependencies = current$$1.dependencies; - } + workInProgress.memoizedState = + value.state !== null && value.state !== undefined ? value.state : null; + initializeUpdateQueue(workInProgress); + var getDerivedStateFromProps = Component.getDerivedStateFromProps; - if (enableProfilerTimer) { - // Don't update "base" render times for bailouts. - stopProfilerTimerIfRunning(workInProgress); - } + if (typeof getDerivedStateFromProps === "function") { + applyDerivedStateFromProps( + workInProgress, + Component, + getDerivedStateFromProps, + props + ); + } - var updateExpirationTime = workInProgress.expirationTime; + 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 (updateExpirationTime !== NoWork) { - markUnprocessedUpdateTime(updateExpirationTime); - } // Check if the children have any pending work. + { + if (workInProgress.mode & StrictMode) { + // Only double-render components with Hooks + if (workInProgress.memoizedState !== null) { + value = renderWithHooks( + null, + workInProgress, + Component, + props, + context, + renderExpirationTime + ); + } + } + } - var childExpirationTime = workInProgress.childExpirationTime; + reconcileChildren(null, workInProgress, value, renderExpirationTime); + + { + validateFunctionComponentInDev(workInProgress, Component); + } - 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 remountFiber(current$$1, oldWorkInProgress, newWorkInProgress) { +function validateFunctionComponentInDev(workInProgress, Component) { { - var returnFiber = oldWorkInProgress.return; - - if (returnFiber === null) { - throw new Error("Cannot swap the root fiber."); - } // Disconnect from the old current. - // It will get deleted. - - current$$1.alternate = null; - oldWorkInProgress.alternate = null; // Connect to the new tree. - - newWorkInProgress.index = oldWorkInProgress.index; - newWorkInProgress.sibling = oldWorkInProgress.sibling; - newWorkInProgress.return = oldWorkInProgress.return; - newWorkInProgress.ref = oldWorkInProgress.ref; // Replace the child/sibling pointers above it. + if (Component) { + if (Component.childContextTypes) { + error( + "%s(...): childContextTypes cannot be defined on a function component.", + Component.displayName || Component.name || "Component" + ); + } + } - if (oldWorkInProgress === returnFiber.child) { - returnFiber.child = newWorkInProgress; - } else { - var prevSibling = returnFiber.child; + if (workInProgress.ref !== null) { + var info = ""; + var ownerName = getCurrentFiberOwnerNameInDevOrNull(); - if (prevSibling === null) { - throw new Error("Expected parent to have a child."); + if (ownerName) { + info += "\n\nCheck the render method of `" + ownerName + "`."; } - while (prevSibling.sibling !== oldWorkInProgress) { - prevSibling = prevSibling.sibling; + var warningKey = ownerName || workInProgress._debugID || ""; + var debugSource = workInProgress._debugSource; - if (prevSibling === null) { - throw new Error("Expected to find the previous sibling."); - } + if (debugSource) { + warningKey = debugSource.fileName + ":" + debugSource.lineNumber; } - 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 (!didWarnAboutFunctionRefs[warningKey]) { + didWarnAboutFunctionRefs[warningKey] = true; - if (last !== null) { - last.nextEffect = current$$1; - returnFiber.lastEffect = current$$1; - } else { - returnFiber.firstEffect = returnFiber.lastEffect = current$$1; + error( + "Function components cannot be given refs. " + + "Attempts to access this ref will fail. " + + "Did you mean to use React.forwardRef()?%s", + info + ); + } } - current$$1.nextEffect = null; - current$$1.effectTag = Deletion; - newWorkInProgress.effectTag |= Placement; // Restart work from the new fiber. - - return newWorkInProgress; - } -} + if (typeof Component.getDerivedStateFromProps === "function") { + var _componentName2 = getComponentName(Component) || "Unknown"; -function beginWork$1(current$$1, workInProgress, renderExpirationTime) { - var updateExpirationTime = workInProgress.expirationTime; + if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2]) { + error( + "%s: Function components do not support getDerivedStateFromProps.", + _componentName2 + ); - { - 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 - ) - ); + didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2] = true; + } } - } - - 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 + typeof Component.contextType === "object" && + Component.contextType !== null ) { - // 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. - - switch (workInProgress.tag) { - case HostRoot: - pushHostRootContext(workInProgress); - resetHydrationState(); - break; + var _componentName3 = getComponentName(Component) || "Unknown"; - case HostComponent: - pushHostContext(workInProgress); + if (!didWarnAboutContextTypeOnFunctionComponent[_componentName3]) { + error( + "%s: Function components do not support contextType.", + _componentName3 + ); - 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. + didWarnAboutContextTypeOnFunctionComponent[_componentName3] = true; + } + } + } +} - workInProgress.expirationTime = workInProgress.childExpirationTime = Never; - return null; - } +var SUSPENDED_MARKER = { + dehydrated: null, + retryTime: NoWork +}; - break; +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) + ); +} - case ClassComponent: { - var Component = workInProgress.type; +function updateSuspenseComponent( + current, + workInProgress, + renderExpirationTime +) { + var mode = workInProgress.mode; + var nextProps = workInProgress.pendingProps; // This is used by DevTools to force a boundary to suspend. - if (isContextProvider(Component)) { - pushContextProvider(workInProgress); - } + { + if (shouldSuspend(workInProgress)) { + workInProgress.effectTag |= DidCapture; + } + } - break; - } + var suspenseContext = suspenseStackCursor.current; + var nextDidTimeout = false; + var didSuspend = (workInProgress.effectTag & DidCapture) !== NoEffect; - case HostPortal: - pushHostContainer( - workInProgress, - workInProgress.stateNode.containerInfo - ); - break; - case ContextProvider: { - var newValue = workInProgress.memoizedProps.value; - pushProvider(workInProgress, newValue); - break; - } + 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 + ); + } + } + } - case Profiler: - if (enableProfilerTimer) { - // Profiler should only call onRender when one of its descendants actually rendered. - var hasChildWork = - workInProgress.childExpirationTime >= 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 (hasChildWork) { - workInProgress.effectTag |= Update; - } - } + 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. - break; + if (nextDidTimeout) { + // Mount separate fragments for primary and fallback children. + var nextFallbackChildren = nextProps.fallback; + var primaryChildFragment = createFiberFromFragment( + null, + mode, + NoWork, + null + ); + primaryChildFragment.return = workInProgress; - case SuspenseComponent: { - var state = workInProgress.memoizedState; + 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 (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. + while (progressedChild !== null) { + progressedChild.return = primaryChildFragment; + progressedChild = progressedChild.sibling; + } + } - 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 fallbackChildFragment = createFiberFromFragment( + nextFallbackChildren, + mode, + renderExpirationTime, + null + ); + fallbackChildFragment.return = workInProgress; + primaryChildFragment.sibling = fallbackChildFragment; // Skip the primary children, and continue working on the + // fallback children. - var primaryChildFragment = workInProgress.child; - var primaryChildExpirationTime = - primaryChildFragment.childExpirationTime; + 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.memoizedState; - 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. + if (prevState !== null) { + // wrapped in a fragment fiber. - 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) - ); - } + var currentPrimaryChildFragment = current.child; + var currentFallbackChildFragment = currentPrimaryChildFragment.sibling; - break; - } + 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 SuspenseListComponent: { - var didSuspendBefore = - (current$$1.effectTag & DidCapture) !== NoEffect; + var _primaryChildFragment2 = createWorkInProgress( + currentPrimaryChildFragment, + currentPrimaryChildFragment.pendingProps + ); - var _hasChildWork = - workInProgress.childExpirationTime >= renderExpirationTime; + _primaryChildFragment2.return = workInProgress; - if (didSuspendBefore) { - if (_hasChildWork) { - // If something was in fallback state last time, and we have all the - // same children then we're still in progressive loading state. - // Something might get unblocked by state updates or retries in the - // tree which will affect the tail. So we need to use the normal - // path to compute the correct tail. - return updateSuspenseListComponent( - current$$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 ((workInProgress.mode & BlockingMode) === NoMode) { + // Outside of blocking mode, we commit the effects from the + // partially completed, timed-out tree, too. + var _progressedState = workInProgress.memoizedState; - 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. + var _progressedPrimaryChild = + _progressedState !== null + ? workInProgress.child.child + : workInProgress.child; - var renderState = workInProgress.memoizedState; + if (_progressedPrimaryChild !== currentPrimaryChildFragment.child) { + _primaryChildFragment2.child = _progressedPrimaryChild; + var _progressedChild2 = _progressedPrimaryChild; - 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; + 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. - pushSuspenseContext(workInProgress, suspenseStackCursor.current); + if (workInProgress.mode & ProfileMode) { + // treeBaseDuration is the sum of all the child tree base durations. + var _treeBaseDuration = 0; + var _hiddenChild = _primaryChildFragment2.child; - if (_hasChildWork) { - break; - } else { - // If none of the children had any work, that means that none of - // them got retried so they'll still be blocked in the same way - // as before. We can fast bail out. - return null; + while (_hiddenChild !== null) { + _treeBaseDuration += _hiddenChild.treeBaseDuration; + _hiddenChild = _hiddenChild.sibling; } - } - } - 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. - workInProgress.expirationTime = NoWork; + _primaryChildFragment2.treeBaseDuration = _treeBaseDuration; + } // Clone the fallback child fragment, too. These we'll continue + // working on. - 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 - ); - } + var _fallbackChildFragment2 = createWorkInProgress( + currentFallbackChildFragment, + _nextFallbackChildren2 + ); - case ClassComponent: { - var _Component2 = workInProgress.type; - var _unresolvedProps = workInProgress.pendingProps; + _fallbackChildFragment2.return = workInProgress; + _primaryChildFragment2.sibling = _fallbackChildFragment2; + _primaryChildFragment2.childExpirationTime = NoWork; // Skip the primary children, and continue working on the + // fallback children. - var _resolvedProps = - workInProgress.elementType === _Component2 - ? _unresolvedProps - : resolveDefaultProps(_Component2, _unresolvedProps); - return updateClassComponent( - current$$1, - workInProgress, - _Component2, - _resolvedProps, - renderExpirationTime - ); - } + 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. - case HostRoot: - return updateHostRoot(current$$1, workInProgress, renderExpirationTime); + 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; - case HostComponent: - return updateHostComponent( - current$$1, - workInProgress, - renderExpirationTime - ); + if (nextDidTimeout) { + // Timed out. Wrap the children in a fragment fiber to keep them + // separate from the fallback children. + var _nextFallbackChildren3 = nextProps.fallback; - case HostText: - return updateHostText(current$$1, workInProgress); + 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 + ); - case SuspenseComponent: - return updateSuspenseComponent( - current$$1, - workInProgress, - renderExpirationTime - ); - case HostPortal: - return updatePortalComponent( - current$$1, - workInProgress, - renderExpirationTime - ); + _primaryChildFragment3.return = workInProgress; + _primaryChildFragment3.child = _currentPrimaryChild; - case ForwardRef: { - var type = workInProgress.type; - var _unresolvedProps2 = workInProgress.pendingProps; + 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; - var _resolvedProps2 = - workInProgress.elementType === type - ? _unresolvedProps2 - : resolveDefaultProps(type, _unresolvedProps2); - return updateForwardRef( - current$$1, - workInProgress, - type, - _resolvedProps2, - renderExpirationTime - ); - } + 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; - case Fragment: - return updateFragment(current$$1, workInProgress, renderExpirationTime); + var _progressedPrimaryChild2 = + _progressedState2 !== null + ? workInProgress.child.child + : workInProgress.child; - case Mode: - return updateMode(current$$1, workInProgress, renderExpirationTime); + _primaryChildFragment3.child = _progressedPrimaryChild2; + var _progressedChild3 = _progressedPrimaryChild2; - case Profiler: - return updateProfiler(current$$1, workInProgress, renderExpirationTime); + 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. - case ContextProvider: - return updateContextProvider( - current$$1, - workInProgress, - renderExpirationTime - ); - case ContextConsumer: - return updateContextConsumer( - current$$1, - workInProgress, - renderExpirationTime - ); + if (workInProgress.mode & ProfileMode) { + // treeBaseDuration is the sum of all the child tree base durations. + var _treeBaseDuration2 = 0; + var _hiddenChild2 = _primaryChildFragment3.child; - case MemoComponent: { - var _type2 = workInProgress.type; - var _unresolvedProps3 = workInProgress.pendingProps; // Resolve outer props first, then resolve inner props. + while (_hiddenChild2 !== null) { + _treeBaseDuration2 += _hiddenChild2.treeBaseDuration; + _hiddenChild2 = _hiddenChild2.sibling; + } - var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3); + _primaryChildFragment3.treeBaseDuration = _treeBaseDuration2; + } // Create a fragment from the fallback children, too. - { - if (workInProgress.type !== workInProgress.elementType) { - var outerPropTypes = _type2.propTypes; + var _fallbackChildFragment3 = createFiberFromFragment( + _nextFallbackChildren3, + mode, + renderExpirationTime, + null + ); - if (outerPropTypes) { - checkPropTypes( - outerPropTypes, - _resolvedProps3, // Resolved for outer only - "prop", - getComponentName(_type2), - getCurrentFiberStackInDev - ); - } - } + _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 + )); } - _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 - ); } + } +} - case IncompleteClassComponent: { - var _Component3 = workInProgress.type; - var _unresolvedProps4 = workInProgress.pendingProps; +function scheduleWorkOnFiber(fiber, renderExpirationTime) { + if (fiber.expirationTime < renderExpirationTime) { + fiber.expirationTime = renderExpirationTime; + } - 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 - ); + 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; + } - break; + if (node === workInProgress) { + return; } - case ScopeComponent: { - if (enableScopeAPI) { - return updateScopeComponent( - current$$1, - workInProgress, - renderExpirationTime - ); + while (node.sibling === null) { + if (node.return === null || node.return === workInProgress) { + return; } - break; + node = node.return; } - } - { - throw Error( - "Unknown unit of work tag (" + - workInProgress.tag + - "). This error is likely caused by a bug in React. Please file an issue." - ); + node.sibling.return = node.return; + node = node.sibling; } } -function createFundamentalStateInstance(currentFiber, props, impl, state) { - return { - currentFiber: currentFiber, - impl: impl, - instance: null, - prevProps: null, - props: props, - state: state - }; -} +function findLastContentRow(firstChild) { + // This is going to find the last row among these children that is already + // showing content on the screen, as opposed to being in fallback state or + // new. If a row has multiple Suspense boundaries, any of them being in the + // fallback state, counts as the whole row being in a fallback state. + // Note that the "rows" will be workInProgress, but any nested children + // will still be current since we haven't rendered them yet. The mounted + // order may not be the same as the new order. We use the new order. + var row = firstChild; + var lastContentRow = null; -function isFiberSuspenseAndTimedOut(fiber) { - return fiber.tag === SuspenseComponent && fiber.memoizedState !== 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; + } -function getSuspenseFallbackChild(fiber) { - return fiber.child.sibling.child; + return lastContentRow; } -var emptyObject$2 = {}; +function validateRevealOrder(revealOrder) { + { + if ( + revealOrder !== undefined && + revealOrder !== "forwards" && + revealOrder !== "backwards" && + revealOrder !== "together" && + !didWarnAboutRevealOrder[revealOrder] + ) { + didWarnAboutRevealOrder[revealOrder] = true; -function collectScopedNodes(node, fn, scopedNodes) { - if (enableScopeAPI) { - if (node.tag === HostComponent) { - var _type = node.type, - memoizedProps = node.memoizedProps, - stateNode = node.stateNode; + 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 _instance = getPublicInstance(stateNode); + break; + } - if ( - _instance !== null && - fn(_type, memoizedProps || emptyObject$2, _instance) === true - ) { - scopedNodes.push(_instance); - } - } + 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 = node.child; + break; + } - if (isFiberSuspenseAndTimedOut(node)) { - child = getSuspenseFallbackChild(node); - } + default: + error( + '"%s" is not a supported revealOrder on . ' + + 'Did you mean "together", "forwards" or "backwards"?', + revealOrder + ); - if (child !== null) { - collectScopedNodesFromChildren(child, fn, scopedNodes); + break; + } + } else { + error( + "%s is not a supported value for revealOrder on . " + + 'Did you mean "together", "forwards" or "backwards"?', + revealOrder + ); + } } } } -function collectFirstScopedNode(node, fn) { - if (enableScopeAPI) { - if (node.tag === HostComponent) { - var _type2 = node.type, - memoizedProps = node.memoizedProps, - stateNode = node.stateNode; +function validateTailOptions(tailMode, revealOrder) { + { + if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) { + if (tailMode !== "collapsed" && tailMode !== "hidden") { + didWarnAboutTailOptions[tailMode] = true; - var _instance2 = getPublicInstance(stateNode); + error( + '"%s" is not a supported value for tail on . ' + + 'Did you mean "collapsed" or "hidden"?', + tailMode + ); + } else if (revealOrder !== "forwards" && revealOrder !== "backwards") { + didWarnAboutTailOptions[tailMode] = true; - if ( - _instance2 !== null && - fn(_type2, memoizedProps, _instance2) === true - ) { - return _instance2; + error( + ' is only valid if revealOrder is ' + + '"forwards" or "backwards". ' + + 'Did you mean to specify revealOrder="forwards"?', + tailMode + ); } } + } +} + +function validateSuspenseListNestedChild(childSlot, index) { + { + var isArray = Array.isArray(childSlot); + var isIterable = !isArray && typeof getIteratorFn(childSlot) === "function"; - var child = node.child; + if (isArray || isIterable) { + var type = isArray ? "array" : "iterable"; - if (isFiberSuspenseAndTimedOut(node)) { - child = getSuspenseFallbackChild(node); - } + error( + "A nested %s was passed to row #%s in . Wrap it in " + + "an additional SuspenseList to configure its revealOrder: " + + " ... " + + "{%s} ... " + + "", + type, + index, + type + ); - if (child !== null) { - return collectFirstScopedNodeFromChildren(child, fn); + return false; } } - return null; + return true; } -function collectScopedNodesFromChildren(startingChild, fn, scopedNodes) { - var child = startingChild; +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); - while (child !== null) { - collectScopedNodes(child, fn, scopedNodes); - child = child.sibling; - } -} + if (typeof iteratorFn === "function") { + var childrenIterator = iteratorFn.call(children); -function collectFirstScopedNodeFromChildren(startingChild, fn) { - var child = startingChild; + if (childrenIterator) { + var step = childrenIterator.next(); + var _i = 0; - while (child !== null) { - var scopedNode = collectFirstScopedNode(child, fn); + for (; !step.done; step = childrenIterator.next()) { + if (!validateSuspenseListNestedChild(step.value, _i)) { + return; + } - if (scopedNode !== null) { - return scopedNode; + _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 + ); + } + } } - - child = child.sibling; } - - return null; } -function collectNearestScopeMethods(node, scope, childrenScopes) { - if (isValidScopeNode(node, scope)) { - childrenScopes.push(node.stateNode.methods); +function initSuspenseListRenderState( + workInProgress, + isBackwards, + tail, + lastContentRow, + tailMode, + lastEffectBeforeRendering +) { + var renderState = workInProgress.memoizedState; + + if (renderState === null) { + workInProgress.memoizedState = { + isBackwards: isBackwards, + rendering: null, + renderingStartTime: 0, + last: lastContentRow, + tail: tail, + tailExpiration: 0, + tailMode: tailMode, + lastEffect: lastEffectBeforeRendering + }; } else { - var child = node.child; + // 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. - if (isFiberSuspenseAndTimedOut(node)) { - child = getSuspenseFallbackChild(node); - } +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 + ); - if (child !== null) { - collectNearestChildScopeMethods(child, scope, childrenScopes); - } - } -} + if (shouldForceFallback) { + suspenseContext = setShallowSuspenseContext( + suspenseContext, + ForceSuspenseFallback + ); + workInProgress.effectTag |= DidCapture; + } else { + var didSuspendBefore = + current !== null && (current.effectTag & DidCapture) !== NoEffect; -function collectNearestChildScopeMethods(startingChild, scope, childrenScopes) { - var child = startingChild; + 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 + ); + } - while (child !== null) { - collectNearestScopeMethods(child, scope, childrenScopes); - child = child.sibling; + suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); } -} - -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; + pushSuspenseContext(workInProgress, suspenseContext); - while (node !== null) { - var parent = node.return; + 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 (parent === null) { - break; + 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; } - node = parent; - - if (node.tag === ScopeComponent && node.type === scope) { - break; - } + initSuspenseListRenderState( + workInProgress, + false, // isBackwards + tail, + lastContentRow, + tailMode, + workInProgress.lastEffect + ); + break; } - var childrenScopes = []; - collectNearestChildScopeMethods(node.child, scope, childrenScopes); - return childrenScopes.length === 0 ? null : childrenScopes; - }, - getParent: function() { - var node = instance.fiber.return; + case "backwards": { + // We're going to find the first row that has existing content. + // At the same time we're going to reverse the list of everything + // we pass in the meantime. That's going to be our tail in reverse + // order. + var _tail = null; + var row = workInProgress.child; + workInProgress.child = null; - while (node !== null) { - if (node.tag === ScopeComponent && node.type === scope) { - return node.stateNode.methods; - } + while (row !== null) { + var currentRow = row.alternate; // New rows can't be content rows. - node = node.return; - } + if (currentRow !== null && findFirstSuspended(currentRow) === null) { + // This is the beginning of the main content. + workInProgress.child = row; + break; + } - 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 nextRow = row.sibling; + row.sibling = _tail; + _tail = row; + row = nextRow; + } // TODO: If workInProgress.child is null, we can continue on the tail immediately. - if (child !== null) { - collectScopedNodesFromChildren(child, fn, scopedNodes); + initSuspenseListRenderState( + workInProgress, + true, // isBackwards + _tail, + null, // last + tailMode, + workInProgress.lastEffect + ); + break; } - 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 "together": { + initSuspenseListRenderState( + workInProgress, + false, // isBackwards + null, // tail + null, // last + undefined, + workInProgress.lastEffect + ); + break; } - return null; - }, - containsNode: function(node) { - var fiber = getInstanceFromNode$1(node); - - while (fiber !== null) { - if ( - fiber.tag === ScopeComponent && - fiber.type === scope && - fiber.stateNode === instance - ) { - return true; - } - - fiber = fiber.return; + default: { + // The default reveal order is the same as not having + // a boundary. + workInProgress.memoizedState = null; } - - return false; } - }; -} - -function markUpdate(workInProgress) { - // Tag the fiber with an update effect. This turns a Placement into - // a PlacementAndUpdate. - workInProgress.effectTag |= Update; -} + } -function markRef$1(workInProgress) { - workInProgress.effectTag |= Ref; + return workInProgress.child; } -var appendAllChildren; -var updateHostContainer; -var updateHostComponent$1; -var updateHostText$1; - -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 (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; - } - }; +function updatePortalComponent(current, workInProgress, renderExpirationTime) { + pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); + var nextChildren = workInProgress.pendingProps; - 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 (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 + ); + } - 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`. + return workInProgress.child; +} - var updatePayload = prepareUpdate( - instance, - type, - oldProps, - newProps, - rootContainerInstance, - currentHostContext - ); // TODO: Type this specific to this type of component. +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; - 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. + { + var providerPropTypes = workInProgress.type.propTypes; - 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); + if (providerPropTypes) { + checkPropTypes(providerPropTypes, newProps, "prop", "Context.Provider"); } - }; -} 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; + pushProvider(workInProgress, newValue); - if (needsVisibilityToggle && isHidden) { - // This child is inside a timed out tree. Hide it. - var text = node.memoizedProps; - _instance = cloneHiddenTextInstance(_instance, text, node); - } + if (oldProps !== null) { + var oldValue = oldProps.value; + var changedBits = calculateChangedBits(context, newValue, oldValue); - appendInitialChild(parent, _instance); - } else if (enableFundamentalAPI && node.tag === FundamentalComponent) { - var _instance2 = node.stateNode.instance; + 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 (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 newChildren = newProps.children; + reconcileChildren(current, workInProgress, newChildren, renderExpirationTime); + return workInProgress.child; +} - if (newIsHidden) { - var primaryChildParent = node.child; +var hasWarnedAboutUsingContextAsConsumer = false; - if (primaryChildParent !== null) { - if (primaryChildParent.child !== null) { - primaryChildParent.child.return = primaryChildParent; - appendAllChildren( - parent, - primaryChildParent, - true, - newIsHidden - ); - } +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. - var fallbackChildParent = primaryChildParent.sibling; + { + if (context._context === undefined) { + // This may be because it's a Context (rather than a Consumer). + // Or it may be because it's older React where they're the same thing. + // We only want to warn if we're sure it's a new React. + if (context !== context.Consumer) { + if (!hasWarnedAboutUsingContextAsConsumer) { + hasWarnedAboutUsingContextAsConsumer = true; - if (fallbackChildParent !== null) { - fallbackChildParent.return = node; - node = fallbackChildParent; - continue; - } - } - } - } - if (node.child !== null) { - // Continue traversing like normal - node.child.return = node; - node = node.child; - continue; + error( + "Rendering directly is not supported and will be removed in " + + "a future major release. Did you mean to render instead?" + ); } - } 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; } + } else { + context = context._context; + } + } - while (node.sibling === null) { - if (node.return === null || node.return === workInProgress) { - return; - } - - node = node.return; - } + var newProps = workInProgress.pendingProps; + var render = newProps.children; - node.sibling.return = node.return; - node = node.sibling; + { + 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." + ); } - }; // 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); - } + prepareToReadContext(workInProgress, renderExpirationTime); + var newValue = readContext(context, newProps.unstable_observedBits); + var newChildren; - appendChildToContainerChildSet(containerChildSet, instance); - } else if (node.tag === HostText) { - var _instance3 = node.stateNode; + { + ReactCurrentOwner$1.current = workInProgress; + setIsRendering(true); + newChildren = render(newValue); + setIsRendering(false); + } // React DevTools reads this flag. - if (needsVisibilityToggle && isHidden) { - // This child is inside a timed out tree. Hide it. - var text = node.memoizedProps; - _instance3 = cloneHiddenTextInstance(_instance3, text, node); - } + workInProgress.effectTag |= PerformedWork; + reconcileChildren(current, workInProgress, newChildren, renderExpirationTime); + return workInProgress.child; +} - appendChildToContainerChildSet(containerChildSet, _instance3); - } else if (enableFundamentalAPI && node.tag === FundamentalComponent) { - var _instance4 = node.stateNode.instance; +function markWorkInProgressReceivedUpdate() { + didReceiveUpdate = true; +} - 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; +function bailoutOnAlreadyFinishedWork( + current, + workInProgress, + renderExpirationTime +) { + cancelWorkTimer(workInProgress); - if (newIsHidden) { - var primaryChildParent = node.child; + if (current !== null) { + // Reuse previous dependencies + workInProgress.dependencies = current.dependencies; + } - if (primaryChildParent !== null) { - if (primaryChildParent.child !== null) { - primaryChildParent.child.return = primaryChildParent; - appendAllChildrenToContainer( - containerChildSet, - primaryChildParent, - true, - newIsHidden - ); - } + { + // Don't update "base" render times for bailouts. + stopProfilerTimerIfRunning(); + } - var fallbackChildParent = primaryChildParent.sibling; + var updateExpirationTime = workInProgress.expirationTime; - 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. + if (updateExpirationTime !== NoWork) { + markUnprocessedUpdateTime(updateExpirationTime); + } // Check if the children have any pending work. - node = node; + var childExpirationTime = workInProgress.childExpirationTime; - if (node === workInProgress) { - return; - } + 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; + } +} - while (node.sibling === null) { - if (node.return === null || node.return === workInProgress) { - return; - } +function remountFiber(current, oldWorkInProgress, newWorkInProgress) { + { + var returnFiber = oldWorkInProgress.return; - node = node.return; - } + if (returnFiber === null) { + throw new Error("Cannot swap the root fiber."); + } // Disconnect from the old current. + // It will get deleted. - node.sibling.return = node.return; - node = node.sibling; - } - }; + current.alternate = null; + oldWorkInProgress.alternate = null; // Connect to the new tree. - updateHostContainer = function(workInProgress) { - var portalOrRoot = workInProgress.stateNode; - var childrenUnchanged = workInProgress.firstEffect === null; + newWorkInProgress.index = oldWorkInProgress.index; + newWorkInProgress.sibling = oldWorkInProgress.sibling; + newWorkInProgress.return = oldWorkInProgress.return; + newWorkInProgress.ref = oldWorkInProgress.ref; // Replace the child/sibling pointers above it. - if (childrenUnchanged) { - // No changes, just reuse the existing instance. + if (oldWorkInProgress === returnFiber.child) { + returnFiber.child = newWorkInProgress; } else { - var container = portalOrRoot.containerInfo; - var newChildSet = createContainerChildSet(container); // If children might have changed, we have to add them all to the set. + var prevSibling = returnFiber.child; - appendAllChildrenToContainer(newChildSet, workInProgress, false, false); - portalOrRoot.pendingChildren = newChildSet; // Schedule an update on the container to swap out the container. + if (prevSibling === null) { + throw new Error("Expected parent to have a child."); + } - 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. + while (prevSibling.sibling !== oldWorkInProgress) { + prevSibling = prevSibling.sibling; + + if (prevSibling === null) { + throw new Error("Expected to find the previous sibling."); + } + } + + 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 childrenUnchanged = workInProgress.firstEffect === null; + var last = returnFiber.lastEffect; - if (childrenUnchanged && oldProps === newProps) { - // No changes, just reuse the existing instance. - // Note that this might release a previous clone. - workInProgress.stateNode = currentInstance; - return; + if (last !== null) { + last.nextEffect = current; + returnFiber.lastEffect = current; + } else { + returnFiber.firstEffect = returnFiber.lastEffect = current; } - var recyclableInstance = workInProgress.stateNode; - var currentHostContext = getHostContext(); - var updatePayload = null; + current.nextEffect = null; + current.effectTag = Deletion; + newWorkInProgress.effectTag |= Placement; // Restart work from the new fiber. - if (oldProps !== newProps) { - updatePayload = prepareUpdate( - recyclableInstance, - type, - oldProps, - newProps, - rootContainerInstance, - currentHostContext + return newWorkInProgress; + } +} + +function beginWork(current, workInProgress, renderExpirationTime) { + var updateExpirationTime = workInProgress.expirationTime; + + { + 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 (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 (current !== null) { + var oldProps = current.memoizedProps; + var newProps = workInProgress.pendingProps; + if ( - finalizeInitialChildren( - newInstance, - type, - newProps, - rootContainerInstance, - currentHostContext - ) + oldProps !== newProps || + hasContextChanged() || // Force a re-render if the implementation changed due to hot reload: + workInProgress.type !== current.type ) { - markUpdate(workInProgress); - } + // 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. - workInProgress.stateNode = newInstance; + switch (workInProgress.tag) { + case HostRoot: + pushHostRootContext(workInProgress); + break; - 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 HostComponent: + pushHostContext(workInProgress); - 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 - }; -} + if ( + workInProgress.mode & ConcurrentMode && + renderExpirationTime !== Never && + shouldDeprioritizeSubtree(workInProgress.type) + ) { + { + markSpawnedWork(Never); + } // Schedule this fiber to re-render at offscreen priority. Then bailout. -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; - } + workInProgress.expirationTime = workInProgress.childExpirationTime = Never; + return null; + } - tailNode = tailNode.sibling; - } // Next we're simply going to delete all insertions after the - // last rendered item. + break; - if (lastTailNode === null) { - // All remaining items in the tail are insertions. - renderState.tail = null; - } else { - // Detach the insertion after the last node that was already - // inserted. - lastTailNode.sibling = null; - } + case ClassComponent: { + var Component = workInProgress.type; - break; - } + if (isContextProvider(Component)) { + pushContextProvider(workInProgress); + } - 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; + break; } - _tailNode = _tailNode.sibling; - } // Next we're simply going to delete all insertions after the - // last rendered item. + case HostPortal: + pushHostContainer( + workInProgress, + workInProgress.stateNode.containerInfo + ); + break; - if (_lastTailNode === null) { - // All remaining items in the tail are insertions. - if (!hasRenderedATailFallback && renderState.tail !== null) { - // We suspended during the head. We want to show at least one - // row at the tail. So we'll keep on and cut off the rest. - renderState.tail.sibling = null; - } else { - renderState.tail = null; + case ContextProvider: { + var newValue = workInProgress.memoizedProps.value; + pushProvider(workInProgress, newValue); + break; + } + + case Profiler: + { + // 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; + + case SuspenseComponent: { + var state = workInProgress.memoizedState; + + if (state !== null) { + // whether to retry the primary children, or to skip over it and + // go straight to the fallback. Check the priority of the primary + // child fragment. + + var primaryChildFragment = workInProgress.child; + var 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, + workInProgress, + renderExpirationTime + ); + } else { + pushSuspenseContext( + workInProgress, + setDefaultShallowSuspenseContext(suspenseStackCursor.current) + ); // The primary children do not have pending work with sufficient + // priority. Bailout. + + var child = bailoutOnAlreadyFinishedWork( + current, + 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; } - } 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; + case SuspenseListComponent: { + var didSuspendBefore = (current.effectTag & DidCapture) !== NoEffect; - switch (workInProgress.tag) { - case IndeterminateComponent: - break; + var _hasChildWork = + workInProgress.childExpirationTime >= renderExpirationTime; - case LazyComponent: - break; + 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. - case SimpleMemoComponent: - case FunctionComponent: - break; + 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. - case ClassComponent: { - var Component = workInProgress.type; + var renderState = workInProgress.memoizedState; - if (isContextProvider(Component)) { - popContext(workInProgress); + if (renderState !== null) { + // Reset to the "together" mode in case we've started a different + // update in the past but didn't complete it. + renderState.rendering = null; + renderState.tail = null; + } + + pushSuspenseContext(workInProgress, suspenseStackCursor.current); + + if (_hasChildWork) { + break; + } else { + // If none of the children had any work, that means that none of + // them got retried so they'll still be blocked in the same way + // as before. We can fast bail out. + return null; + } + } } - break; + 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. - case HostRoot: { - popHostContainer(workInProgress); - popTopLevelContextObject(workInProgress); - var fiberRoot = workInProgress.stateNode; - if (fiberRoot.pendingContext) { - fiberRoot.context = fiberRoot.pendingContext; - fiberRoot.pendingContext = null; - } + workInProgress.expirationTime = NoWork; - 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); + switch (workInProgress.tag) { + case IndeterminateComponent: { + return mountIndeterminateComponent( + current, + workInProgress, + workInProgress.type, + renderExpirationTime + ); + } - if (wasHydrated) { - // If we hydrated, then we'll need to schedule an update for - // the commit side-effects on the root. - markUpdate(workInProgress); - } - } + case LazyComponent: { + var elementType = workInProgress.elementType; + return mountLazyComponent( + current, + workInProgress, + elementType, + updateExpirationTime, + renderExpirationTime + ); + } - updateHostContainer(workInProgress); - break; + 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 + ); } - case HostComponent: { - popHostContext(workInProgress); - var rootContainerInstance = getRootHostContainer(); - var type = workInProgress.type; - if (current !== null && workInProgress.stateNode != null) { - updateHostComponent$1( - current, - workInProgress, - type, - newProps, - rootContainerInstance - ); + case ClassComponent: { + var _Component2 = workInProgress.type; + var _unresolvedProps = workInProgress.pendingProps; - if (enableFlareAPI) { - var prevListeners = current.memoizedProps.listeners; - var nextListeners = newProps.listeners; + var _resolvedProps = + workInProgress.elementType === _Component2 + ? _unresolvedProps + : resolveDefaultProps(_Component2, _unresolvedProps); - if (prevListeners !== nextListeners) { - markUpdate(workInProgress); - } - } + return updateClassComponent( + current, + workInProgress, + _Component2, + _resolvedProps, + renderExpirationTime + ); + } - if (current.ref !== workInProgress.ref) { - markRef$1(workInProgress); - } - } else { - if (!newProps) { - if (!(workInProgress.stateNode !== null)) { - throw Error( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." - ); - } // This can happen when we abort work. + case HostRoot: + return updateHostRoot(current, workInProgress, renderExpirationTime); - break; - } + case HostComponent: + return updateHostComponent(current, workInProgress, renderExpirationTime); - 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. + case HostText: + return updateHostText(); - var _wasHydrated = popHydrationState(workInProgress); + case SuspenseComponent: + return updateSuspenseComponent( + current, + workInProgress, + renderExpirationTime + ); - 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); - } + case HostPortal: + return updatePortalComponent( + current, + workInProgress, + renderExpirationTime + ); - if (enableFlareAPI) { - var listeners = newProps.listeners; + case ForwardRef: { + var type = workInProgress.type; + var _unresolvedProps2 = workInProgress.pendingProps; - 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 + var _resolvedProps2 = + workInProgress.elementType === type + ? _unresolvedProps2 + : resolveDefaultProps(type, _unresolvedProps2); - workInProgress.stateNode = instance; + return updateForwardRef( + current, + workInProgress, + type, + _resolvedProps2, + renderExpirationTime + ); + } - if (enableFlareAPI) { - var _listeners = newProps.listeners; + case Fragment: + return updateFragment(current, workInProgress, renderExpirationTime); - 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. + case Mode: + return updateMode(current, workInProgress, renderExpirationTime); - if ( - finalizeInitialChildren( - instance, - type, - newProps, - rootContainerInstance, - currentHostContext - ) - ) { - markUpdate(workInProgress); - } - } + case Profiler: + return updateProfiler(current, workInProgress, renderExpirationTime); - if (workInProgress.ref !== null) { - // If there is a ref on a host node we need to schedule a callback - markRef$1(workInProgress); - } - } + case ContextProvider: + return updateContextProvider( + current, + workInProgress, + renderExpirationTime + ); - break; - } + case ContextConsumer: + return updateContextConsumer( + current, + workInProgress, + renderExpirationTime + ); + + case MemoComponent: { + var _type2 = workInProgress.type; + var _unresolvedProps3 = workInProgress.pendingProps; // Resolve outer props first, then resolve inner props. - case HostText: { - var newText = newProps; + var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3); - 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 (workInProgress.type !== workInProgress.elementType) { + var outerPropTypes = _type2.propTypes; - 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." + if (outerPropTypes) { + checkPropTypes( + outerPropTypes, + _resolvedProps3, // Resolved for outer only + "prop", + getComponentName(_type2) ); - } // This can happen when we abort work. + } } + } - var _rootContainerInstance = getRootHostContainer(); + _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3); + return updateMemoComponent( + current, + workInProgress, + _type2, + _resolvedProps3, + updateExpirationTime, + renderExpirationTime + ); + } - var _currentHostContext = getHostContext(); + case SimpleMemoComponent: { + return updateSimpleMemoComponent( + current, + workInProgress, + workInProgress.type, + workInProgress.pendingProps, + updateExpirationTime, + renderExpirationTime + ); + } - var _wasHydrated2 = popHydrationState(workInProgress); + case IncompleteClassComponent: { + var _Component3 = workInProgress.type; + var _unresolvedProps4 = workInProgress.pendingProps; - if (_wasHydrated2) { - if (prepareToHydrateHostTextInstance(workInProgress)) { - markUpdate(workInProgress); - } - } else { - workInProgress.stateNode = createTextInstance( - newText, - _rootContainerInstance, - _currentHostContext, - workInProgress - ); - } - } + var _resolvedProps4 = + workInProgress.elementType === _Component3 + ? _unresolvedProps4 + : resolveDefaultProps(_Component3, _unresolvedProps4); - break; + return mountIncompleteClassComponent( + current, + workInProgress, + _Component3, + _resolvedProps4, + renderExpirationTime + ); } - case ForwardRef: - break; + case SuspenseListComponent: { + return updateSuspenseListComponent( + current, + workInProgress, + renderExpirationTime + ); + } + } - case SuspenseComponent: { - popSuspenseContext(workInProgress); - var nextState = workInProgress.memoizedState; + { + 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) { + // Tag the fiber with an update effect. This turns a Placement into + // a PlacementAndUpdate. + workInProgress.effectTag |= Update; +} - if (enableSuspenseServerRenderer) { - if (nextState !== null && nextState.dehydrated !== null) { - if (current === null) { - var _wasHydrated3 = popHydrationState(workInProgress); +function markRef$1(workInProgress) { + workInProgress.effectTag |= Ref; +} - if (!_wasHydrated3) { - throw Error( - "A dehydrated suspense component was completed without a hydrated node. This is probably a bug in React." - ); - } +var appendAllChildren; +var updateHostContainer; +var updateHostComponent$1; +var updateHostText$1; - prepareToHydrateHostSuspenseInstance(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; - if (enableSchedulerTracing) { - markSpawnedWork(Never); - } + while (node !== null) { + // eslint-disable-next-line no-labels + if (node.tag === HostComponent) { + var instance = node.stateNode; - 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 (needsVisibilityToggle && isHidden) { + // This child is inside a timed out tree. Hide it. + var props = node.memoizedProps; + var type = node.type; + instance = cloneHiddenInstance(instance); } - } - if ((workInProgress.effectTag & DidCapture) !== NoEffect) { - // Something suspended. Re-render with the fallback children. - workInProgress.expirationTime = renderExpirationTime; // Do not reset the effect list. + appendInitialChild(parent, instance); + } else if (node.tag === HostText) { + var _instance = node.stateNode; - return workInProgress; - } + if (needsVisibilityToggle && isHidden) { + // This child is inside a timed out tree. Hide it. + var text = node.memoizedProps; + _instance = cloneHiddenTextInstance(); + } - var nextDidTimeout = nextState !== null; - var prevDidTimeout = false; + 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; - if (current === null) { - if (workInProgress.memoizedProps.fallback !== undefined) { - popHydrationState(workInProgress); - } - } else { - var prevState = current.memoizedState; - prevDidTimeout = prevState !== null; + if (newIsHidden) { + var primaryChildParent = node.child; - 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 (primaryChildParent !== null) { + if (primaryChildParent.child !== null) { + primaryChildParent.child.return = primaryChildParent; + appendAllChildren( + parent, + primaryChildParent, + true, + newIsHidden + ); + } - if (currentFallbackChild !== null) { - // Deletions go at the beginning of the return fiber's effect list - var first = workInProgress.firstEffect; + var fallbackChildParent = primaryChildParent.sibling; - if (first !== null) { - workInProgress.firstEffect = currentFallbackChild; - currentFallbackChild.nextEffect = first; - } else { - workInProgress.firstEffect = workInProgress.lastEffect = currentFallbackChild; - currentFallbackChild.nextEffect = null; + if (fallbackChildParent !== null) { + fallbackChildParent.return = node; + node = fallbackChildParent; + continue; + } } - currentFallbackChild.effectTag = Deletion; } } + + 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; } - 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(); - } + while (node.sibling === null) { + if (node.return === null || node.return === workInProgress) { + return; } + + node = node.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.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 + 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); } - } - 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; + + 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(); } - } - if ( - enableSuspenseCallback && - workInProgress.updateQueue !== null && - workInProgress.memoizedProps.suspenseCallback != null - ) { - // Always notify the callback - workInProgress.effectTag |= Update; - } - break; - } + 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; - case Fragment: - break; + if (newIsHidden) { + var primaryChildParent = node.child; - case Mode: - break; + if (primaryChildParent !== null) { + if (primaryChildParent.child !== null) { + primaryChildParent.child.return = primaryChildParent; + appendAllChildrenToContainer( + containerChildSet, + primaryChildParent, + true, + newIsHidden + ); + } - case Profiler: - break; + var fallbackChildParent = primaryChildParent.sibling; - case HostPortal: - popHostContainer(workInProgress); - updateHostContainer(workInProgress); - break; - case ContextProvider: - // Pop provider fiber - popProvider(workInProgress); - break; + if (fallbackChildParent !== null) { + fallbackChildParent.return = node; + node = fallbackChildParent; + continue; + } + } + } + } - case ContextConsumer: - 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 MemoComponent: - break; + node = node; - 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 (node === workInProgress) { + return; + } - if (isContextProvider(_Component)) { - popContext(workInProgress); + while (node.sibling === null) { + if (node.return === null || node.return === workInProgress) { + return; + } + + node = node.return; } - break; + node.sibling.return = node.return; + node = node.sibling; } + }; - case SuspenseListComponent: { - popSuspenseContext(workInProgress); - var renderState = workInProgress.memoizedState; + updateHostContainer = function(workInProgress) { + var portalOrRoot = workInProgress.stateNode; + var childrenUnchanged = workInProgress.firstEffect === null; - if (renderState === null) { - // We're running in the default, "independent" mode. We don't do anything - // in this mode. - break; - } + 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. - var didSuspendAlready = - (workInProgress.effectTag & DidCapture) !== NoEffect; - var renderedTail = renderState.rendering; + appendAllChildrenToContainer(newChildSet, workInProgress, false, false); + portalOrRoot.pendingChildren = newChildSet; // Schedule an update on the container to swap out the container. - 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); + markUpdate(workInProgress); + finalizeContainerChildren(container, newChildSet); + } + }; - if (!cannotBeSuspended) { - var row = workInProgress.child; + updateHostComponent$1 = function( + current, + workInProgress, + type, + newProps, + rootContainerInstance + ) { + var currentInstance = current.stateNode; + var oldProps = current.memoizedProps; // If there are no effects associated with this node, then none of our children had any updates. + // This guarantees that we can reuse all of them. - while (row !== null) { - var suspended = findFirstSuspended(row); + var childrenUnchanged = workInProgress.firstEffect === 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. + if (childrenUnchanged && oldProps === newProps) { + // No changes, just reuse the existing instance. + // Note that this might release a previous clone. + workInProgress.stateNode = currentInstance; + return; + } - var newThennables = suspended.updateQueue; + var recyclableInstance = workInProgress.stateNode; + var currentHostContext = getHostContext(); + var updatePayload = 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. + if (oldProps !== newProps) { + updatePayload = prepareUpdate( + recyclableInstance, + type, + oldProps, + newProps + ); + } - if (renderState.lastEffect === null) { - workInProgress.firstEffect = null; - } + if (childrenUnchanged && updatePayload === null) { + // No changes, just reuse the existing instance. + // Note that this might release a previous clone. + workInProgress.stateNode = currentInstance; + return; + } - workInProgress.lastEffect = renderState.lastEffect; // Reset the child fibers to their original state. + var newInstance = cloneInstance( + currentInstance, + updatePayload, + type, + oldProps, + newProps, + workInProgress, + childrenUnchanged + ); - resetChildFibers(workInProgress, renderExpirationTime); // Set up the Suspense Context to force suspense and immediately - // rerender the children. + workInProgress.stateNode = newInstance; - pushSuspenseContext( - workInProgress, - setShallowSuspenseContext( - suspenseStackCursor.current, - ForceSuspenseFallback - ) - ); - return workInProgress.child; - } - 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); + 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. - 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. + markUpdate(workInProgress); + } else { + workInProgress.stateNode = current.stateNode; + } + }; +} - var _newThennables = _suspended.updateQueue; +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 (_newThennables !== null) { - workInProgress.updateQueue = _newThennables; - workInProgress.effectTag |= Update; - } + while (tailNode !== null) { + if (tailNode.alternate !== null) { + lastTailNode = tailNode; + } - cutOffTailIfNeeded(renderState, true); // This might have been modified. + tailNode = tailNode.sibling; + } // Next we're simply going to delete all insertions after the + // last rendered item. - 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 (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 (lastEffect !== null) { - lastEffect.nextEffect = null; - } // We're done. + break; + } - 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. + case "collapsed": { + // Any insertions at the end of the tail list after this point + // should be invisible. If there are already mounted boundaries + // anything before them are not considered for collapsing. + // Therefore we need to go through the whole tail to find if + // there are any. + var _tailNode = renderState.tail; + var _lastTailNode = null; - var 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; + while (_tailNode !== null) { + if (_tailNode.alternate !== null) { + _lastTailNode = _tailNode; } - } - - 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. - - 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. - var suspenseContext = suspenseStackCursor.current; + _tailNode = _tailNode.sibling; + } // Next we're simply going to delete all insertions after the + // last rendered item. - if (didSuspendAlready) { - suspenseContext = setShallowSuspenseContext( - suspenseContext, - ForceSuspenseFallback - ); + 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 { - suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); + renderState.tail = null; } - - pushSuspenseContext(workInProgress, suspenseContext); // Do a pass over the next row. - - return next; + } else { + // Detach the insertion after the last node that was already + // inserted. + _lastTailNode.sibling = null; } break; } + } +} - 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 || {} - ); +function completeWork(current, workInProgress, renderExpirationTime) { + var newProps = workInProgress.pendingProps; - var _instance5 = getFundamentalComponentInstance(fundamentalInstance); + 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; - fundamentalInstance.instance = _instance5; + case ClassComponent: { + var Component = workInProgress.type; - if (fundamentalImpl.reconcileChildren === false) { - return null; - } + if (isContextProvider(Component)) { + popContext(workInProgress); + } - 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; + return null; + } - if (supportsPersistence) { - var _instance6 = cloneFundamentalInstance(fundamentalInstance); + case HostRoot: { + popHostContainer(workInProgress); + popTopLevelContextObject(workInProgress); + var fiberRoot = workInProgress.stateNode; - fundamentalInstance.instance = _instance6; - appendAllChildren(_instance6, workInProgress, false, false); - } + if (fiberRoot.pendingContext) { + fiberRoot.context = fiberRoot.pendingContext; + fiberRoot.pendingContext = null; + } - var shouldUpdate = shouldUpdateFundamentalComponent( - fundamentalInstance - ); + if (current === null || current.child === null) { + // If we hydrated, pop so that we can delete any remaining children + // that weren't hydrated. + var wasHydrated = popHydrationState(); - if (shouldUpdate) { - markUpdate(workInProgress); - } + if (wasHydrated) { + // If we hydrated, then we'll need to schedule an update for + // the commit side-effects on the root. + markUpdate(workInProgress); } } - break; + updateHostContainer(workInProgress); + return null; } - 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); + case HostComponent: { + popHostContext(workInProgress); + var rootContainerInstance = getRootHostContainer(); + var type = workInProgress.type; + + if (current !== null && workInProgress.stateNode != null) { + updateHostComponent$1( + current, + workInProgress, + type, + newProps, + rootContainerInstance + ); + + if (current.ref !== workInProgress.ref) { + markRef$1(workInProgress); + } + } else { + if (!newProps) { + if (!(workInProgress.stateNode !== null)) { + throw Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ); + } // This can happen when we abort work. - if (enableFlareAPI) { - var _listeners2 = newProps.listeners; + return null; + } - if (_listeners2 != null) { - var _rootContainerInstance2 = getRootHostContainer(); + 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. - updateEventListeners( - _listeners2, - workInProgress, - _rootContainerInstance2 - ); - } - } + var _wasHydrated = popHydrationState(); - if (workInProgress.ref !== null) { - markRef$1(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 + // commit-phase we mark this as such. 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); - } - } + var instance = createInstance( + type, + newProps, + rootContainerInstance, + currentHostContext, + workInProgress + ); + appendAllChildren(instance, workInProgress, false, false); // This needs to be set before we mount Flare event listeners - if (current.ref !== workInProgress.ref) { - markRef$1(workInProgress); - } + workInProgress.stateNode = instance; + } + + if (workInProgress.ref !== null) { + // If there is a ref on a host node we need to schedule a callback + markRef$1(workInProgress); } } - break; + return null; } - default: { - throw Error( - "Unknown unit of work tag (" + - workInProgress.tag + - "). This error is likely caused by a bug in React. Please file an issue." - ); - } - } + case HostText: { + var newText = newProps; - return null; -} + if (current && workInProgress.stateNode != null) { + var oldText = current.memoizedProps; // If we have an alternate, that means this is an update and we need + // to schedule a side-effect to do the updates. -function unwindWork(workInProgress, renderExpirationTime) { - switch (workInProgress.tag) { - case ClassComponent: { - var Component = workInProgress.type; + 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 (isContextProvider(Component)) { - popContext(workInProgress); - } + var _rootContainerInstance = getRootHostContainer(); - var effectTag = workInProgress.effectTag; + var _currentHostContext = getHostContext(); - if (effectTag & ShouldCapture) { - workInProgress.effectTag = (effectTag & ~ShouldCapture) | DidCapture; - return workInProgress; + var _wasHydrated2 = popHydrationState(); + + if (_wasHydrated2) { + if (prepareToHydrateHostTextInstance()) { + markUpdate(workInProgress); + } + } else { + workInProgress.stateNode = createTextInstance( + newText, + _rootContainerInstance, + _currentHostContext, + workInProgress + ); + } } return null; } - case HostRoot: { - popHostContainer(workInProgress); - popTopLevelContextObject(workInProgress); - var _effectTag = workInProgress.effectTag; + case SuspenseComponent: { + popSuspenseContext(workInProgress); + var nextState = workInProgress.memoizedState; - 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 ((workInProgress.effectTag & DidCapture) !== NoEffect) { + // Something suspended. Re-render with the fallback children. + workInProgress.expirationTime = renderExpirationTime; // Do not reset the effect list. + + return workInProgress; } - workInProgress.effectTag = (_effectTag & ~ShouldCapture) | DidCapture; - return workInProgress; - } + var nextDidTimeout = nextState !== null; + var prevDidTimeout = false; - case HostComponent: { - // TODO: popHydrationState - popHostContext(workInProgress); - return null; - } + if (current === null) { + if (workInProgress.memoizedProps.fallback !== undefined); + } else { + var prevState = current.memoizedState; + prevDidTimeout = prevState !== null; - case SuspenseComponent: { - popSuspenseContext(workInProgress); + 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 (enableSuspenseServerRenderer) { - var suspenseState = workInProgress.memoizedState; + if (currentFallbackChild !== null) { + // Deletions go at the beginning of the return fiber's effect list + var first = workInProgress.firstEffect; - 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." - ); - } + if (first !== null) { + workInProgress.firstEffect = currentFallbackChild; + currentFallbackChild.nextEffect = first; + } else { + workInProgress.firstEffect = workInProgress.lastEffect = currentFallbackChild; + currentFallbackChild.nextEffect = null; + } - resetHydrationState(); + currentFallbackChild.effectTag = Deletion; + } } } - var _effectTag2 = workInProgress.effectTag; - - if (_effectTag2 & ShouldCapture) { - workInProgress.effectTag = (_effectTag2 & ~ShouldCapture) | DidCapture; // Captured a suspense effect. Re-render the boundary. + 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; - return workInProgress; + if ( + hasInvisibleChildContext || + hasSuspenseContext( + suspenseStackCursor.current, + InvisibleParentSuspenseContext + ) + ) { + // If this was in an invisible tree or a new render, then showing + // this boundary is ok. + renderDidSuspend(); + } else { + // Otherwise, we're going to have to hide content so we should + // suspend for longer if possible. + renderDidSuspendDelayIfPossible(); + } + } } - return 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. + { + // 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; + } + } return null; } case HostPortal: popHostContainer(workInProgress); + updateHostContainer(workInProgress); return null; case ContextProvider: + // Pop provider fiber popProvider(workInProgress); return null; - default: + 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); + } + return null; - } -} + } -function unwindInterruptedWork(interruptedWork) { - switch (interruptedWork.tag) { - case ClassComponent: { - var childContextTypes = interruptedWork.type.childContextTypes; + case SuspenseListComponent: { + popSuspenseContext(workInProgress); + var renderState = workInProgress.memoizedState; - if (childContextTypes !== null && childContextTypes !== undefined) { - popContext(interruptedWork); + if (renderState === null) { + // We're running in the default, "independent" mode. + // We don't do anything in this mode. + return null; } - break; - } + var didSuspendAlready = + (workInProgress.effectTag & DidCapture) !== NoEffect; + var renderedTail = renderState.rendering; - case HostRoot: { - popHostContainer(interruptedWork); - popTopLevelContextObject(interruptedWork); - break; - } - case HostComponent: { - popHostContext(interruptedWork); - break; - } + 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); - case HostPortal: - popHostContainer(interruptedWork); - break; + if (!cannotBeSuspended) { + var row = workInProgress.child; - case SuspenseComponent: - popSuspenseContext(interruptedWork); - break; + while (row !== null) { + var suspended = findFirstSuspended(row); - case SuspenseListComponent: - popSuspenseContext(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 ContextProvider: - popProvider(interruptedWork); - break; + var newThennables = suspended.updateQueue; + + 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. - default: - break; - } -} + if (renderState.lastEffect === null) { + workInProgress.firstEffect = null; + } -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) - }; -} + workInProgress.lastEffect = renderState.lastEffect; // Reset the child fibers to their original state. -// Module provided by RN: -if ( - !( - typeof ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog === - "function" - ) -) { - throw Error( - "Expected ReactFiberErrorDialog.showErrorDialog to be a function." - ); -} + resetChildFibers(workInProgress, renderExpirationTime); // Set up the Suspense Context to force suspense and immediately + // rerender the children. -function showErrorDialog(capturedError) { - return ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog( - capturedError - ); -} + pushSuspenseContext( + workInProgress, + setShallowSuspenseContext( + suspenseStackCursor.current, + ForceSuspenseFallback + ) + ); + return workInProgress.child; + } -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. + 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); - if (logError === false) { - return; - } + 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. - 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. + var _newThennables = _suspended.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 (_newThennables !== null) { + workInProgress.updateQueue = _newThennables; + workInProgress.effectTag |= Update; + } - console.error(error); // For a more detailed description of this block, see: - // https://github.com/facebook/react/pull/13384 - } + cutOffTailIfNeeded(renderState, true); // This might have been modified. - 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. + 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 (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. + if (lastEffect !== null) { + lastEffect.nextEffect = null; + } // We're done. - console.error(combinedMessage); - } -} + 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 didWarnAboutUndefinedSnapshotBeforeUpdate = null; -{ - didWarnAboutUndefinedSnapshotBeforeUpdate = new Set(); -} + var nextPriority = renderExpirationTime - 1; + workInProgress.expirationTime = workInProgress.childExpirationTime = nextPriority; -var PossiblyWeakSet = typeof WeakSet === "function" ? WeakSet : Set; -function logError(boundary, errorInfo) { - var source = errorInfo.source; - var stack = errorInfo.stack; + { + markSpawnedWork(nextPriority); + } + } + } - if (stack === null && source !== null) { - stack = getStackByFiberInDevAndProd(source); - } + 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 capturedError = { - componentName: source !== null ? getComponentName(source.type) : null, - componentStack: stack !== null ? stack : "", - error: errorInfo.value, - errorBoundary: null, - errorBoundaryName: null, - errorBoundaryFound: false, - willRetry: false - }; + if (previousSibling !== null) { + previousSibling.sibling = renderedTail; + } else { + workInProgress.child = renderedTail; + } - if (boundary !== null && boundary.tag === ClassComponent) { - capturedError.errorBoundary = boundary.stateNode; - capturedError.errorBoundaryName = getComponentName(boundary.type); - capturedError.errorBoundaryFound = true; - capturedError.willRetry = true; - } + renderState.last = renderedTail; + } + } - 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 (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 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. + 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. -function safelyCallComponentWillUnmount(current$$1, instance) { - { - invokeGuardedCallback( - null, - callComponentWillUnmountWithTimer, - null, - current$$1, - instance - ); - if (hasCaughtError()) { - var unmountError = clearCaughtError(); - captureCommitPhaseError(current$$1, unmountError); - } - } -} + var suspenseContext = suspenseStackCursor.current; -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); + if (didSuspendAlready) { + suspenseContext = setShallowSuspenseContext( + suspenseContext, + ForceSuspenseFallback + ); + } else { + suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); } + + pushSuspenseContext(workInProgress, suspenseContext); // Do a pass over the next row. + + return next; } - } else { - ref.current = null; + + return null; } } -} -function safelyCallDestroy(current$$1, destroy) { { - invokeGuardedCallback(null, destroy, null); - if (hasCaughtError()) { - var error = clearCaughtError(); - captureCommitPhaseError(current$$1, error); - } + throw Error( + "Unknown unit of work tag (" + + workInProgress.tag + + "). This error is likely caused by a bug in React. Please file an issue." + ); } } -function commitBeforeMutationLifeCycles(current$$1, finishedWork) { - switch (finishedWork.tag) { - case FunctionComponent: - case ForwardRef: - case SimpleMemoComponent: { - commitHookEffectList(UnmountSnapshot, NoEffect$1, finishedWork); - return; - } +function unwindWork(workInProgress, renderExpirationTime) { + switch (workInProgress.tag) { case ClassComponent: { - 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. + var Component = workInProgress.type; - { - 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 - ); + if (isContextProvider(Component)) { + popContext(workInProgress); + } - { - var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate; + var effectTag = workInProgress.effectTag; - 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(); - } + if (effectTag & ShouldCapture) { + workInProgress.effectTag = (effectTag & ~ShouldCapture) | DidCapture; + return workInProgress; } - return; + return null; } - case HostRoot: - case HostComponent: - case HostText: - case HostPortal: - case IncompleteClassComponent: - // Nothing to do for these component types - return; + case HostRoot: { + popHostContainer(workInProgress); + popTopLevelContextObject(workInProgress); + var _effectTag = workInProgress.effectTag; - default: { - { + if (!((_effectTag & DidCapture) === NoEffect)) { 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." + "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." ); } - } - } -} - -function commitHookEffectList(unmountTag, mountTag, finishedWork) { - var updateQueue = finishedWork.updateQueue; - var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; - if (lastEffect !== null) { - var firstEffect = lastEffect.next; - var effect = firstEffect; + workInProgress.effectTag = (_effectTag & ~ShouldCapture) | DidCapture; + 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(); + case HostComponent: { + // TODO: popHydrationState + popHostContext(workInProgress); + return null; + } - { - var _destroy = effect.destroy; + case SuspenseComponent: { + popSuspenseContext(workInProgress); - if (_destroy !== undefined && typeof _destroy !== "function") { - var addendum = void 0; + var _effectTag2 = workInProgress.effectTag; - 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); - } -} + if (_effectTag2 & ShouldCapture) { + workInProgress.effectTag = (_effectTag2 & ~ShouldCapture) | DidCapture; // Captured a suspense effect. Re-render the boundary. -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; + return workInProgress; } - default: - break; - } - } -} -function commitLifeCycles( - finishedRoot, - current$$1, - finishedWork, - committedExpirationTime -) { - switch (finishedWork.tag) { - case FunctionComponent: - case ForwardRef: - case SimpleMemoComponent: { - commitHookEffectList(UnmountLayout, MountLayout, finishedWork); - break; + return null; } - case ClassComponent: { - var instance = finishedWork.stateNode; + case SuspenseListComponent: { + popSuspenseContext(workInProgress); // SuspenseList doesn't actually catch anything. It should've been + // caught by a nested boundary. If not, it should bubble through. - if (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. + return null; + } - { - 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. + case HostPortal: + popHostContainer(workInProgress); + return null; - { - 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(); - } - } + case ContextProvider: + popProvider(workInProgress); + return null; - var updateQueue = finishedWork.updateQueue; + default: + return null; + } +} - 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 unwindInterruptedWork(interruptedWork) { + switch (interruptedWork.tag) { + case ClassComponent: { + var childContextTypes = interruptedWork.type.childContextTypes; - commitUpdateQueue( - finishedWork, - updateQueue, - instance, - committedExpirationTime - ); + if (childContextTypes !== null && childContextTypes !== undefined) { + popContext(interruptedWork); } - return; + break; } case HostRoot: { - var _updateQueue = finishedWork.updateQueue; + popHostContainer(interruptedWork); + popTopLevelContextObject(interruptedWork); + break; + } - if (_updateQueue !== null) { - var _instance = null; + case HostComponent: { + popHostContext(interruptedWork); + break; + } - 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 - ); - } + case HostPortal: + popHostContainer(interruptedWork); + break; - return; - } + case SuspenseComponent: + popSuspenseContext(interruptedWork); + break; - case HostComponent: { - var _instance2 = finishedWork.stateNode; // Renderers may schedule work to be done after host components are mounted - // (eg DOM renderer may schedule auto-focus for inputs and form controls). - // These effects should only be committed when components are first mounted, - // aka when there is no current/alternate. + case SuspenseListComponent: + popSuspenseContext(interruptedWork); + break; - if (current$$1 === null && finishedWork.effectTag & Update) { - var type = finishedWork.type; - var props = finishedWork.memoizedProps; - commitMount(_instance2, type, props, finishedWork); - } + case ContextProvider: + popProvider(interruptedWork); + break; + } +} - 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; +function createCapturedValue(value, source) { + // If the value is an error, call this function immediately after it is thrown + // so the stack is accurate. + return { + value: value, + source: source, + stack: getStackByFiberInDevAndProd(source) + }; +} - if (typeof 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() - ); - } - } - } +// Module provided by RN: - return; - } +if ( + !( + typeof ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog === + "function" + ) +) { + throw Error( + "Expected ReactFiberErrorDialog.showErrorDialog to be a function." + ); +} - case SuspenseComponent: { - commitSuspenseHydrationCallbacks(finishedRoot, finishedWork); - return; +function showErrorDialog(capturedError) { + return ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog( + capturedError + ); +} + +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 (logError === false) { + return; + } + + 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 (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. + + console["error"](error); // Don't transform to our wrapper + // For a more detailed description of this block, see: + // https://github.com/facebook/react/pull/13384 } - case SuspenseListComponent: - case IncompleteClassComponent: - case FundamentalComponent: - case ScopeComponent: - 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. - 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 (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. + + console["error"](combinedMessage); // Don't transform to our wrapper } } -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; +var didWarnAboutUndefinedSnapshotBeforeUpdate = null; - while (true) { - if (node.tag === HostComponent) { - var instance = node.stateNode; +{ + didWarnAboutUndefinedSnapshotBeforeUpdate = new Set(); +} - 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; - } +var PossiblyWeakSet = typeof WeakSet === "function" ? WeakSet : Set; +function logError(boundary, errorInfo) { + var source = errorInfo.source; + var stack = errorInfo.stack; - if (node === finishedWork) { - return; - } + if (stack === null && source !== null) { + stack = getStackByFiberInDevAndProd(source); + } - while (node.sibling === null) { - if (node.return === null || node.return === finishedWork) { - 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 + }; - node = node.return; - } + if (boundary !== null && boundary.tag === ClassComponent) { + capturedError.errorBoundary = boundary.stateNode; + capturedError.errorBoundaryName = getComponentName(boundary.type); + capturedError.errorBoundaryFound = true; + capturedError.willRetry = true; + } - node.sibling.return = node.return; - node = node.sibling; - } + 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; + }); } } -function commitAttachRef(finishedWork) { - var ref = finishedWork.ref; +var callComponentWillUnmountWithTimer = function(current, instance) { + startPhaseTimer(current, "componentWillUnmount"); + instance.props = current.memoizedProps; + instance.state = current.memoizedState; - if (ref !== null) { - var instance = finishedWork.stateNode; - var instanceToUse; + { + instance.componentWillUnmount(); + } - switch (finishedWork.tag) { - case HostComponent: - instanceToUse = getPublicInstance(instance); - break; + stopPhaseTimer(); +}; // Capture errors so they don't interrupt unmounting. - default: - instanceToUse = instance; - } // Moved outside to ensure DCE works with this flag +function safelyCallComponentWillUnmount(current, instance) { + { + invokeGuardedCallback( + null, + callComponentWillUnmountWithTimer, + null, + current, + instance + ); - if (enableScopeAPI && finishedWork.tag === ScopeComponent) { - instanceToUse = instance.methods; + if (hasCaughtError()) { + var unmountError = clearCaughtError(); + captureCommitPhaseError(current, unmountError); } + } +} + +function safelyDetachRef(current) { + var ref = current.ref; + if (ref !== null) { if (typeof ref === "function") { - ref(instanceToUse); - } else { { - 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) - ); + invokeGuardedCallback(null, ref, null, null); + + if (hasCaughtError()) { + var refError = clearCaughtError(); + captureCommitPhaseError(current, refError); } } - - ref.current = instanceToUse; + } else { + ref.current = null; } } } -function commitDetachRef(current$$1) { - var currentRef = current$$1.ref; - if (currentRef !== null) { - if (typeof currentRef === "function") { - currentRef(null); - } else { - currentRef.current = null; +function safelyCallDestroy(current, destroy) { + { + invokeGuardedCallback(null, destroy, null); + + if (hasCaughtError()) { + var error = clearCaughtError(); + captureCommitPhaseError(current, error); } } -} // User-originating errors (lifecycles and refs) should not interrupt -// deletion, so don't let them throw. Host-originating errors should -// interrupt deletion, so it's okay - -function commitUnmount(finishedRoot, current$$1, renderPriorityLevel) { - onCommitUnmount(current$$1); +} - switch (current$$1.tag) { +function commitBeforeMutationLifeCycles(current, finishedWork) { + switch (finishedWork.tag) { case FunctionComponent: case ForwardRef: - 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: { - safelyDetachRef(current$$1); - var instance = current$$1.stateNode; - - if (typeof instance.componentWillUnmount === "function") { - safelyCallComponentWillUnmount(current$$1, instance); - } - + case SimpleMemoComponent: + case Block: { return; } - case HostComponent: { - if (enableFlareAPI) { - var dependencies = current$$1.dependencies; - - if (dependencies !== null) { - var respondersMap = dependencies.responders; - - if (respondersMap !== null) { - var responderInstances = Array.from(respondersMap.values()); + 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. - for ( - var i = 0, length = responderInstances.length; - i < length; - i++ + { + if ( + finishedWork.type === finishedWork.elementType && + !didWarnAboutReassigningProps ) { - var responderInstance = responderInstances[i]; - unmountResponderInstance(responderInstance); + 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" + ); + } } - dependencies.responders = null; } - } - } - safelyDetachRef(current$$1); - return; - } + var snapshot = instance.getSnapshotBeforeUpdate( + finishedWork.elementType === finishedWork.type + ? prevProps + : resolveDefaultProps(finishedWork.type, prevProps), + prevState + ); - 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); - } + { + var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate; - return; - } + if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) { + didWarnSet.add(finishedWork.type); - case FundamentalComponent: { - if (enableFundamentalAPI) { - var fundamentalInstance = current$$1.stateNode; + error( + "%s.getSnapshotBeforeUpdate(): A snapshot value (or null) " + + "must be returned. You have returned undefined.", + getComponentName(finishedWork.type) + ); + } + } - if (fundamentalInstance !== null) { - unmountFundamentalComponent(fundamentalInstance); - current$$1.stateNode = null; + instance.__reactInternalSnapshotBeforeUpdate = snapshot; + stopPhaseTimer(); } } return; } - case DehydratedFragment: { - if (enableSuspenseCallback) { - var hydrationCallbacks = finishedRoot.hydrationCallbacks; - - if (hydrationCallbacks !== null) { - var onDeleted = hydrationCallbacks.onDeleted; - - if (onDeleted) { - onDeleted(current$$1.stateNode); - } - } - } - + case HostRoot: + case HostComponent: + case HostText: + case HostPortal: + case IncompleteClassComponent: + // Nothing to do for these component types return; - } + } - case ScopeComponent: { - if (enableScopeAPI) { - safelyDetachRef(current$$1); - } - } + { + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); } } -function commitNestedUnmounts(finishedRoot, root, renderPriorityLevel) { - // While we're inside a removed host node we don't want to call - // removeChild on the inner nodes because they're removed by the top - // call anyway. We also want to call componentWillUnmount on all - // composites before this host node is removed from the tree. Therefore - // we do an inner loop while we're still inside the host node. - var node = root; - - 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. +function commitHookEffectListUnmount(tag, finishedWork) { + var updateQueue = finishedWork.updateQueue; + var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; - 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 (lastEffect !== null) { + var firstEffect = lastEffect.next; + var effect = firstEffect; - if (node === root) { - return; - } + do { + if ((effect.tag & tag) === tag) { + // Unmount + var destroy = effect.destroy; + effect.destroy = undefined; - while (node.sibling === null) { - if (node.return === null || node.return === root) { - return; + if (destroy !== undefined) { + destroy(); + } } - node = node.return; - } - - 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); + effect = effect.next; + } while (effect !== firstEffect); } } -function emptyPortalContainer(current$$1) { - if (!supportsPersistence) { - return; - } +function commitHookEffectListMount(tag, finishedWork) { + var updateQueue = finishedWork.updateQueue; + var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; - var portal = current$$1.stateNode; - var containerInfo = portal.containerInfo; - var emptyChildSet = createContainerChildSet(containerInfo); -} + if (lastEffect !== null) { + var firstEffect = lastEffect.next; + var effect = firstEffect; -function commitContainer(finishedWork) { - if (!supportsPersistence) { - return; - } + do { + if ((effect.tag & tag) === tag) { + // Mount + var create = effect.create; + effect.destroy = create(); - 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; - } + { + var destroy = effect.destroy; - 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 (destroy !== undefined && typeof destroy !== "function") { + var addendum = void 0; -function getHostParentFiber(fiber) { - var parent = fiber.return; - while (parent !== null) { - if (isHostParent(parent)) { - return parent; - } + 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; + } - parent = parent.return; - } + error( + "An effect function must not return anything besides a function, " + + "which is used for clean-up.%s%s", + addendum, + getStackByFiberInDevAndProd(finishedWork) + ); + } + } + } - { - throw Error( - "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." - ); + effect = effect.next; + } while (effect !== firstEffect); } } -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; - } - - node = node.return; - } - - node.sibling.return = node.return; - node = node.sibling; +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); + } - 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; + break; } - } // Check if this host node is stable or about to be placed. - - if (!(node.effectTag & Placement)) { - // Found it! - return node.stateNode; } } } -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; - var isContainer; - var parentStateNode = parentFiber.stateNode; - - switch (parentFiber.tag) { - case HostComponent: - parent = parentStateNode; - isContainer = false; - break; - case HostRoot: - parent = parentStateNode.containerInfo; - isContainer = true; - break; - case HostPortal: - parent = parentStateNode.containerInfo; - isContainer = true; - break; - case FundamentalComponent: - if (enableFundamentalAPI) { - parent = parentStateNode.instance; - isContainer = false; +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); } - // eslint-disable-next-line-no-fallthrough - - default: { - throw Error( - "Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue." - ); + return; } - } - if (parentFiber.effectTag & ContentReset) { - // Reset the text content of the parent before doing any insertions - resetTextContent(parent); // Clear ContentReset from the effect tag - - parentFiber.effectTag &= ~ContentReset; - } + case ClassComponent: { + var instance = finishedWork.stateNode; - var before = getHostSibling(finishedWork); // We only have the top Fiber that was inserted but we need to recurse down its - // children to find all the terminal nodes. + if (finishedWork.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. - var node = finishedWork; + { + 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" + ); + } - while (true) { - var isHost = node.tag === HostComponent || node.tag === HostText; + if (instance.state !== finishedWork.memoizedState) { + error( + "Expected %s state to match memoized state before " + + "componentDidMount. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.state`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } + } + } - if (isHost || (enableFundamentalAPI && node.tag === FundamentalComponent)) { - var stateNode = isHost ? node.stateNode : node.stateNode.instance; + { + instance.componentDidMount(); + } - if (before) { - if (isContainer) { - insertInContainerBefore(parent, stateNode, before); - } else { - insertBefore(parent, stateNode, before); - } - } else { - if (isContainer) { - appendChildToContainer(parent, stateNode); + stopPhaseTimer(); } 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; - } - - while (node.sibling === null) { - if (node.return === null || node.return === finishedWork) { - return; - } - - node = node.return; - } + 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. - node.sibling.return = node.return; - node = node.sibling; - } -} + { + 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" + ); + } -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 (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 currentParentIsValid = false; // Note: these two variables *must* always be updated together. + { + instance.componentDidUpdate( + prevProps, + prevState, + instance.__reactInternalSnapshotBeforeUpdate + ); + } - var currentParent; - var currentParentIsContainer; + stopPhaseTimer(); + } + } - while (true) { - if (!currentParentIsValid) { - var parent = node.return; + var updateQueue = finishedWork.updateQueue; - findParent: while (true) { - if (!(parent !== null)) { - throw Error( - "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." - ); - } + if (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 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 (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. - parent = parent.return; + commitUpdateQueue(finishedWork, updateQueue, instance); } - currentParentIsValid = true; + 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 HostRoot: { + var _updateQueue = finishedWork.updateQueue; - 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; + if (_updateQueue !== null) { + var _instance = null; - if (hydrationCallbacks !== null) { - var onDeleted = hydrationCallbacks.onDeleted; + if (finishedWork.child !== null) { + switch (finishedWork.child.tag) { + case HostComponent: + _instance = getPublicInstance(finishedWork.child.stateNode); + break; - if (onDeleted) { - onDeleted(node.stateNode); + case ClassComponent: + _instance = finishedWork.child.stateNode; + break; } } - } // Delete the dehydrated suspense boundary and all of its content. - if (currentParentIsContainer) { - clearSuspenseBoundaryFromContainer(currentParent, node.stateNode); - } else { - clearSuspenseBoundary(currentParent, node.stateNode); + commitUpdateQueue(finishedWork, _updateQueue, _instance); } - } 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. + return; + } - if (node.child !== null) { - node.child.return = node; - node = node.child; - continue; + 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 (current === null && finishedWork.effectTag & Update) { + var type = finishedWork.type; + var props = finishedWork.memoizedProps; + commitMount(); } + + return; } - if (node === current$$1) { + case HostText: { + // We have no life-cycles associated with text. return; } - while (node.sibling === null) { - if (node.return === null || node.return === current$$1) { - return; - } + case HostPortal: { + // We have no life-cycles associated with portals. + return; + } - node = node.return; + case Profiler: { + { + var _finishedWork$memoize2 = finishedWork.memoizedProps, + onCommit = _finishedWork$memoize2.onCommit, + onRender = _finishedWork$memoize2.onRender; + var effectDuration = finishedWork.stateNode.effectDuration; + var commitTime = getCommitTime(); - if (node.tag === HostPortal) { - // When we go out of the portal, we need to restore the parent. - // Since we don't keep a stack of them, we will search for it. - currentParentIsValid = false; + if (typeof onRender === "function") { + { + onRender( + finishedWork.memoizedProps.id, + current === null ? "mount" : "update", + finishedWork.actualDuration, + finishedWork.treeBaseDuration, + finishedWork.actualStartTime, + commitTime, + finishedRoot.memoizedInteractions + ); + } + } } + + return; } - node.sibling.return = node.return; - node = node.sibling; + + case SuspenseComponent: { + return; + } + + case SuspenseListComponent: + case IncompleteClassComponent: + case FundamentalComponent: + case ScopeComponent: + return; } -} -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); + { + 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." + ); } - - detachFiber(current$$1); } -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; - } +function commitAttachRef(finishedWork) { + var ref = finishedWork.ref; - case Profiler: { - return; - } + if (ref !== null) { + var instance = finishedWork.stateNode; + var instanceToUse; - case SuspenseComponent: { - commitSuspenseComponent(finishedWork); - attachSuspenseRetryListeners(finishedWork); - return; - } - case SuspenseListComponent: { - attachSuspenseRetryListeners(finishedWork); - return; - } + switch (finishedWork.tag) { + case HostComponent: + instanceToUse = getPublicInstance(instance); + break; - case HostRoot: { - if (supportsHydration) { - var root = finishedWork.stateNode; + default: + instanceToUse = instance; + } // Moved outside to ensure DCE works with this flag - if (root.hydrate) { - // We've just hydrated. No need to hydrate again. - root.hydrate = false; - commitHydratedContainer(root.containerInfo); - } + 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) + ); } - - break; } - } - commitContainer(finishedWork); - return; + ref.current = instanceToUse; + } } +} - 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; - } +function commitDetachRef(current) { + var currentRef = current.ref; - case ClassComponent: { - return; + if (currentRef !== null) { + if (typeof currentRef === "function") { + currentRef(null); + } else { + currentRef.current = null; } + } +} // User-originating errors (lifecycles and refs) should not interrupt +// deletion, so don't let them throw. Host-originating errors should +// interrupt deletion, so it's okay - case HostComponent: { - var instance = finishedWork.stateNode; - - if (instance != null) { - // Commit the work prepared earlier. - var newProps = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps - // as the newProps. The updatePayload will contain the real change in - // this case. +function commitUnmount(finishedRoot, current, renderPriorityLevel) { + onCommitUnmount(current); - var oldProps = - current$$1 !== null ? current$$1.memoizedProps : newProps; - var type = finishedWork.type; // TODO: Type the updateQueue to be specific to host components. + switch (current.tag) { + case FunctionComponent: + case ForwardRef: + case MemoComponent: + case SimpleMemoComponent: + case Block: { + var updateQueue = current.updateQueue; - var updatePayload = finishedWork.updateQueue; - finishedWork.updateQueue = null; + if (updateQueue !== null) { + var lastEffect = updateQueue.lastEffect; - if (updatePayload !== null) { - commitUpdate( - instance, - updatePayload, - type, - oldProps, - newProps, - finishedWork - ); - } + if (lastEffect !== null) { + var firstEffect = lastEffect.next; - if (enableFlareAPI) { - var prevListeners = oldProps.listeners; - var nextListeners = newProps.listeners; + { + // 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 (prevListeners !== nextListeners) { - updateEventListeners(nextListeners, finishedWork, null); + effect = effect.next; + } while (effect !== firstEffect); + }); } } } @@ -18938,164 +15914,199 @@ function commitWork(current$$1, finishedWork) { return; } - case HostText: { - if (!(finishedWork.stateNode !== null)) { - throw Error( - "This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue." - ); - } + case ClassComponent: { + safelyDetachRef(current); + var instance = current.stateNode; - var textInstance = finishedWork.stateNode; - var newText = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps - // as the newProps. The updatePayload will contain the real change in - // this case. + if (typeof instance.componentWillUnmount === "function") { + safelyCallComponentWillUnmount(current, instance); + } - var oldText = current$$1 !== null ? current$$1.memoizedProps : newText; - commitTextUpdate(textInstance, oldText, newText); return; } - case HostRoot: { - if (supportsHydration) { - var _root = finishedWork.stateNode; + case HostComponent: { + safelyDetachRef(current); + return; + } - if (_root.hydrate) { - // We've just hydrated. No need to hydrate again. - _root.hydrate = false; - commitHydratedContainer(_root.containerInfo); - } + case HostPortal: { + // TODO: this is recursive. + // We are also not using this parent because + // the portal will get pushed immediately. + { + emptyPortalContainer(current); } return; } - case Profiler: { + case FundamentalComponent: { return; } - case SuspenseComponent: { - commitSuspenseComponent(finishedWork); - attachSuspenseRetryListeners(finishedWork); + case DehydratedFragment: { return; } - case SuspenseListComponent: { - attachSuspenseRetryListeners(finishedWork); + + case ScopeComponent: { return; } + } +} - case IncompleteClassComponent: { +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) { return; } - case FundamentalComponent: { - if (enableFundamentalAPI) { - var fundamentalInstance = finishedWork.stateNode; - updateFundamentalComponent(fundamentalInstance); + while (node.sibling === null) { + if (node.return === null || node.return === root) { + return; } - return; + node = node.return; } - case ScopeComponent: { - if (enableScopeAPI) { - var scopeInstance = finishedWork.stateNode; - scopeInstance.fiber = finishedWork; + node.sibling.return = node.return; + node = node.sibling; + } +} - if (enableFlareAPI) { - var _newProps = finishedWork.memoizedProps; +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. - var _oldProps = - current$$1 !== null ? current$$1.memoizedProps : _newProps; + 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 _prevListeners = _oldProps.listeners; - var _nextListeners = _newProps.listeners; + if (alternate !== null) { + detachFiber(alternate); + } +} - if (_prevListeners !== _nextListeners) { - updateEventListeners(_nextListeners, finishedWork, null); - } - } - } +function emptyPortalContainer(current) { + var portal = current.stateNode; + var containerInfo = portal.containerInfo; + var emptyChildSet = createContainerChildSet(containerInfo); +} +function commitContainer(finishedWork) { + switch (finishedWork.tag) { + case ClassComponent: + case HostComponent: + case HostText: + case FundamentalComponent: { 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." - ); - } + case HostRoot: + case HostPortal: { + var portalOrRoot = finishedWork.stateNode; + var containerInfo = portalOrRoot.containerInfo, + pendingChildren = portalOrRoot.pendingChildren; + return; } } -} - -function commitSuspenseComponent(finishedWork) { - var newState = finishedWork.memoizedState; - var newDidTimeout; - var primaryChildParent = finishedWork; - if (newState === null) { - newDidTimeout = false; - } else { - newDidTimeout = true; - primaryChildParent = finishedWork.child; - markCommitTimeOfFallback(); + { + 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 (supportsMutation && primaryChildParent !== null) { - hideOrUnhideAllChildren(primaryChildParent, newDidTimeout); +function commitDeletion(finishedRoot, current, renderPriorityLevel) { + { + // Detach refs and call componentWillUnmount() on the whole subtree. + commitNestedUnmounts(finishedRoot, current, renderPriorityLevel); } - if (enableSuspenseCallback && newState !== null) { - var suspenseCallback = finishedWork.memoizedProps.suspenseCallback; + detachFiber(current); +} + +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); + } + + return; + } - if (typeof suspenseCallback === "function") { - var thenables = finishedWork.updateQueue; + case Profiler: { + return; + } - if (thenables !== null) { - suspenseCallback(new Set(thenables)); + case SuspenseComponent: { + commitSuspenseComponent(finishedWork); + attachSuspenseRetryListeners(finishedWork); + return; } - } else { - if (suspenseCallback !== undefined) { - warning$1(false, "Unexpected type for suspenseCallback."); + + case SuspenseListComponent: { + attachSuspenseRetryListeners(finishedWork); + return; } } - } -} -function commitSuspenseHydrationCallbacks(finishedRoot, finishedWork) { - if (!supportsHydration) { + commitContainer(finishedWork); return; } +} +function commitSuspenseComponent(finishedWork) { var newState = finishedWork.memoizedState; + var primaryChildParent = finishedWork; - 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); - } - } - } - } - } - } + if (newState === null); + else { + primaryChildParent = finishedWork.child; + markCommitTimeOfFallback(); } } @@ -19118,7 +16129,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); } @@ -19131,14 +16142,6 @@ 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) { @@ -19156,6 +16159,7 @@ function createRootErrorUpdate(fiber, errorInfo, expirationTime) { onUncaughtError(error); logError(fiber, errorInfo); }; + return update; } @@ -19165,20 +16169,22 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { var getDerivedStateFromError = fiber.type.getDerivedStateFromError; if (typeof getDerivedStateFromError === "function") { - var error = errorInfo.value; + var error$1 = errorInfo.value; update.payload = function() { logError(fiber, errorInfo); - return getDerivedStateFromError(error); + return getDerivedStateFromError(error$1); }; } 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. @@ -19190,24 +16196,24 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { logError(fiber, errorInfo); } - var error = errorInfo.value; + var error$1 = errorInfo.value; var stack = errorInfo.stack; - this.componentDidCatch(error, { + this.componentDidCatch(error$1, { componentStack: stack !== null ? stack : "" }); + { if (typeof getDerivedStateFromError !== "function") { // If componentDidCatch is the only error boundary method defined, // then it needs to call setState to recover from errors. // If no state update is scheduled then the boundary will swallow the error. - !(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; + 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" + ); + } } } }; @@ -19216,6 +16222,7 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { markFailedErrorBoundaryForHotReloading(fiber); }; } + return update; } @@ -19232,11 +16239,13 @@ 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); @@ -19269,7 +16278,22 @@ function throwException( ) { // This is a thenable. var thenable = value; - checkForWrongSuspensePriorityInDEV(sourceFiber); + + 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; + } + } + var hasInvisibleParentBoundary = hasSuspenseContext( suspenseStackCursor.current, InvisibleParentSuspenseContext @@ -19311,6 +16335,7 @@ 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 @@ -19404,6 +16429,7 @@ function throwException( var _errorInfo = value; workInProgress.effectTag |= ShouldCapture; workInProgress.expirationTime = renderExpirationTime; + var _update = createRootErrorUpdate( workInProgress, _errorInfo, @@ -19419,6 +16445,7 @@ function throwException( var errorInfo = value; var ctor = workInProgress.type; var instance = workInProgress.stateNode; + if ( (workInProgress.effectTag & DidCapture) === NoEffect && (typeof ctor.getDerivedStateFromError === "function" || @@ -19440,9 +16467,6 @@ function throwException( } break; - - default: - break; } workInProgress = workInProgress.return; @@ -19450,18 +16474,15 @@ function throwException( } var ceil = Math.ceil; -var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher; -var ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner; -var IsSomeRendererActing = ReactSharedInternals.IsSomeRendererActing; +var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, + ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, + IsSomeRendererActing = ReactSharedInternals.IsSomeRendererActing; var NoContext = /* */ 0; var BatchedContext = /* */ 1; -var EventContext = - /* */ - 2; var DiscreteEventContext = /* */ 4; @@ -19487,7 +16508,7 @@ var workInProgressRoot = null; // The fiber we're working on var workInProgress = null; // The expiration time we're rendering -var renderExpirationTime = NoWork; // Whether to root completed, errored, suspended, etc. +var renderExpirationTime$1 = NoWork; // Whether to root completed, errored, suspended, etc. var workInProgressRootExitStatus = RootIncomplete; // A fatal error, if one is thrown @@ -19564,6 +16585,7 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { } var priorityLevel = getCurrentPriorityLevel(); + if ((mode & ConcurrentMode) === NoMode) { return priorityLevel === ImmediatePriority ? Sync : Batched; } @@ -19571,7 +16593,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; + return renderExpirationTime$1; } var expirationTime; @@ -19588,10 +16610,12 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { case ImmediatePriority: expirationTime = Sync; break; - case UserBlockingPriority$1: + + case UserBlockingPriority: // TODO: Rename this to computeUserBlockingExpiration expirationTime = computeInteractiveExpiration(currentTime); break; + case NormalPriority: case LowPriority: // TODO: Handle LowPriority @@ -19612,7 +16636,11 @@ 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) { + + if ( + workInProgressRoot !== null && + expirationTime === renderExpirationTime$1 + ) { // This is a trick to move this update into a separate batch expirationTime -= 1; } @@ -19621,7 +16649,7 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { } function scheduleUpdateOnFiber(fiber, expirationTime) { checkForNestedUpdates(); - warnAboutInvalidUpdatesOnClassComponentsInDEV(fiber); + warnAboutRenderPhaseUpdatesInDEV(fiber); var root = markUpdateTimeFromFiberToRoot(fiber, expirationTime); if (root === null) { @@ -19668,7 +16696,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$1 || + (priorityLevel === UserBlockingPriority || priorityLevel === ImmediatePriority) ) { // This is the result of a discrete event. Track the lowest priority @@ -19677,6 +16705,7 @@ function scheduleUpdateOnFiber(fiber, expirationTime) { rootsWithPendingDiscreteUpdates = new Map([[root, expirationTime]]); } else { var lastDiscreteTime = rootsWithPendingDiscreteUpdates.get(root); + if (lastDiscreteTime === undefined || lastDiscreteTime > expirationTime) { rootsWithPendingDiscreteUpdates.set(root, expirationTime); } @@ -19724,10 +16753,12 @@ function markUpdateTimeFromFiberToRoot(fiber, expirationTime) { ) { alternate.childExpirationTime = expirationTime; } + if (node.return === null && node.tag === HostRoot) { root = node.stateNode; break; } + node = node.return; } } @@ -19752,7 +16783,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); + markRootSuspendedAtTime(root, renderExpirationTime$1); } } // Mark that the root has a pending update. @@ -19784,9 +16815,17 @@ function getNextRootExpirationTimeToWorkOn(root) { var lastPingedTime = root.lastPingedTime; var nextKnownPendingLevel = root.nextKnownPendingLevel; - return lastPingedTime > nextKnownPendingLevel - ? lastPingedTime - : 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; } // 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 @@ -19853,11 +16892,6 @@ 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, @@ -19876,7 +16910,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; + currentEventTime = NoWork; // Check if the render expired. if (didTimeout) { // The render task took too long to complete. Mark the current time as @@ -19891,83 +16925,50 @@ function performConcurrentWorkOnRoot(root, didTimeout) { var expirationTime = getNextRootExpirationTimeToWorkOn(root); - if (expirationTime !== NoWork) { - var originalCallbackNode = root.callbackNode; - - 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 ( - 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 (expirationTime === NoWork) { + return null; + } - if (workInProgress !== null) { - var prevExecutionContext = executionContext; - executionContext |= RenderContext; - var prevDispatcher = pushDispatcher(root); - var prevInteractions = pushInteractions(root); - startWorkLoopTimer(workInProgress); + var originalCallbackNode = root.callbackNode; - do { - try { - workLoopConcurrent(); - break; - } catch (thrownValue) { - handleError(root, thrownValue); - } - } while (true); + if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { + throw Error("Should not already be working."); + } - resetContextDependencies(); - executionContext = prevExecutionContext; - popDispatcher(prevDispatcher); + flushPassiveEffects(); + var exitStatus = renderRootConcurrent(root, expirationTime); - if (enableSchedulerTracing) { - popInteractions(prevInteractions); - } + 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 (workInProgressRootExitStatus === RootFatalErrored) { - var fatalError = workInProgressRootFatalError; - stopInterruptedWorkLoopTimer(); - prepareFreshStack(root, expirationTime); - markRootSuspendedAtTime(root, expirationTime); - ensureRootIsScheduled(root); - throw fatalError; - } + 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. - 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 - ); - } + var finishedWork = (root.finishedWork = root.current.alternate); + root.finishedExpirationTime = expirationTime; + finishConcurrentRender(root, finishedWork, exitStatus, expirationTime); + } - ensureRootIsScheduled(root); + 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; @@ -19979,9 +16980,6 @@ function finishConcurrentRender( exitStatus, expirationTime ) { - // Set this to null to indicate there's no in-progress render. - workInProgressRoot = null; - switch (exitStatus) { case RootIncomplete: case RootFatalErrored: { @@ -19994,19 +16992,9 @@ function finishConcurrentRender( // if I do. eslint-disable-next-line no-fallthrough case RootErrored: { - // 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. - + // We should have already attempted to retry this tree. If we reached + // this point, it errored again. Commit it. + commitRoot(root); break; } @@ -20016,9 +17004,7 @@ function finishConcurrentRender( if (expirationTime === lastSuspendedTime) { root.nextKnownPendingLevel = getRemainingExpirationTime(finishedWork); - } - - flushSuspensePriorityWarningInDEV(); // We have an acceptable loading state. We need to figure out if we + } // 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 @@ -20029,7 +17015,7 @@ function finishConcurrentRender( if ( hasNotProcessedNewUpdates && // do not delay if we're inside an act() scope - !(true && flushSuspenseFallbacksInTests && IsThisRendererActing.current) + !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 @@ -20093,12 +17079,7 @@ 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) { @@ -20153,6 +17134,7 @@ 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; @@ -20187,11 +17169,6 @@ 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 ) { @@ -20229,147 +17206,65 @@ function finishConcurrentRender( // through Scheduler function performSyncWorkOnRoot(root) { - // Check if there's expired work on this root. Otherwise, render at Sync. - var lastExpiredTime = root.lastExpiredTime; - 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."); - } + 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 lastExpiredTime = root.lastExpiredTime; + var expirationTime; + if (lastExpiredTime !== NoWork) { + // There's expired work on this root. Check if we have a partial tree + // that we can reuse. if ( - root !== workInProgressRoot || - expirationTime !== renderExpirationTime + root === workInProgressRoot && + renderExpirationTime$1 >= 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); + // 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; } + } else { + // There's no expired work. This must be a new, synchronous render. + expirationTime = Sync; } - return null; -} - -function finishSyncRender(root, exitStatus, expirationTime) { - // Set this to null to indicate there's no in-progress render. - workInProgressRoot = null; + var exitStatus = renderRootSync(root, expirationTime); - { - if (exitStatus === RootSuspended || exitStatus === RootSuspendedWithDelay) { - flushSuspensePriorityWarningInDEV(); - } + 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); } - 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; - } + 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. - flushPendingDiscreteUpdates(); // If the discrete updates scheduled passive effects, flush them now so that - // they fire before the next serial event. + root.finishedWork = root.current.alternate; + root.finishedExpirationTime = expirationTime; + commitRoot(root); // Before exiting, make sure there's a callback scheduled for the next + // pending level. - flushPassiveEffects(); + ensureRootIsScheduled(root); + return null; } - function syncUpdates(fn, 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(); - } + return runWithPriority(ImmediatePriority, fn.bind(null, a, b, c)); } function batchedUpdates$1(fn, a) { @@ -20387,38 +17282,6 @@ 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) { { @@ -20432,7 +17295,7 @@ function flushSync(fn, a) { executionContext |= BatchedContext; try { - return runWithPriority$1(ImmediatePriority, fn.bind(null, a)); + return runWithPriority(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 @@ -20465,8 +17328,8 @@ function prepareFreshStack(root, expirationTime) { } workInProgressRoot = root; - workInProgress = createWorkInProgress(root.current, null, expirationTime); - renderExpirationTime = expirationTime; + workInProgress = createWorkInProgress(root.current, null); + renderExpirationTime$1 = expirationTime; workInProgressRootExitStatus = RootIncomplete; workInProgressRootFatalError = null; workInProgressRootLatestProcessedExpirationTime = Sync; @@ -20475,13 +17338,12 @@ function prepareFreshStack(root, expirationTime) { workInProgressRootNextUnprocessedUpdateTime = NoWork; workInProgressRootHasPendingPing = false; - if (enableSchedulerTracing) { + { spawnedWorkDuringRender = null; } { ReactStrictModeWarnings.discardPendingWarnings(); - componentsThatTriggeredHighPriSuspend = null; } } @@ -20490,7 +17352,7 @@ function handleError(root, thrownValue) { try { // Reset module-level state that was set during the render phase. resetContextDependencies(); - resetHooks(); + resetHooksAfterThrow(); resetCurrentFiber(); if (workInProgress === null || workInProgress.return === null) { @@ -20499,7 +17361,14 @@ function handleError(root, thrownValue) { // supposed to capture all errors that weren't caught by an error // boundary. workInProgressRootExitStatus = RootFatalErrored; - workInProgressRootFatalError = thrownValue; + 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; return null; } @@ -20515,7 +17384,7 @@ function handleError(root, thrownValue) { workInProgress.return, workInProgress, thrownValue, - renderExpirationTime + renderExpirationTime$1 ); workInProgress = completeUnitOfWork(workInProgress); } catch (yetAnotherThrownValue) { @@ -20529,8 +17398,8 @@ function handleError(root, thrownValue) { } function pushDispatcher(root) { - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = ContextOnlyDispatcher; + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; if (prevDispatcher === null) { // The React isomorphic package does not include a default dispatcher. @@ -20543,21 +17412,19 @@ function pushDispatcher(root) { } function popDispatcher(prevDispatcher) { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.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; } } @@ -20610,7 +17477,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); + markRootSuspendedAtTime(workInProgressRoot, renderExpirationTime$1); markRootUpdatedAtTime( workInProgressRoot, workInProgressRootNextUnprocessedUpdateTime @@ -20649,6 +17516,56 @@ 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 */ @@ -20659,6 +17576,55 @@ 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() { @@ -20672,21 +17638,22 @@ 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$$1 = unitOfWork.alternate; + var current = unitOfWork.alternate; startWorkTimer(unitOfWork); setCurrentFiber(unitOfWork); var next; - if (enableProfilerTimer && (unitOfWork.mode & ProfileMode) !== NoMode) { + if ((unitOfWork.mode & ProfileMode) !== NoMode) { startProfilerTimer(unitOfWork); - next = beginWork$$1(current$$1, unitOfWork, renderExpirationTime); + next = beginWork$1(current, unitOfWork, renderExpirationTime$1); stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true); } else { - next = beginWork$$1(current$$1, unitOfWork, renderExpirationTime); + next = beginWork$1(current, unitOfWork, renderExpirationTime$1); } resetCurrentFiber(); unitOfWork.memoizedProps = unitOfWork.pendingProps; + if (next === null) { // If this doesn't spawn new work, complete the current work. next = completeUnitOfWork(unitOfWork); @@ -20700,25 +17667,23 @@ 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$$1 = workInProgress.alternate; + var current = 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 ( - !enableProfilerTimer || - (workInProgress.mode & ProfileMode) === NoMode - ) { - next = completeWork(current$$1, workInProgress, renderExpirationTime); + if ((workInProgress.mode & ProfileMode) === NoMode) { + next = completeWork(current, workInProgress, renderExpirationTime$1); } else { startProfilerTimer(workInProgress); - next = completeWork(current$$1, workInProgress, renderExpirationTime); // Update render duration assuming we didn't error. + next = completeWork(current, workInProgress, renderExpirationTime$1); // Update render duration assuming we didn't error. stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false); } @@ -20742,6 +17707,7 @@ function completeUnitOfWork(unitOfWork) { if (returnFiber.firstEffect === null) { returnFiber.firstEffect = workInProgress.firstEffect; } + if (workInProgress.lastEffect !== null) { if (returnFiber.lastEffect !== null) { returnFiber.lastEffect.nextEffect = workInProgress.firstEffect; @@ -20765,6 +17731,7 @@ function completeUnitOfWork(unitOfWork) { } else { returnFiber.firstEffect = workInProgress; } + returnFiber.lastEffect = workInProgress; } } @@ -20772,12 +17739,9 @@ 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, renderExpirationTime); // Because this fiber did not complete, don't reset its expiration time. + var _next = unwindWork(workInProgress); // Because this fiber did not complete, don't reset its expiration time. - if ( - enableProfilerTimer && - (workInProgress.mode & ProfileMode) !== NoMode - ) { + if ((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. @@ -20788,6 +17752,7 @@ function completeUnitOfWork(unitOfWork) { actualDuration += child.actualDuration; child = child.sibling; } + workInProgress.actualDuration = actualDuration; } @@ -20802,6 +17767,7 @@ function completeUnitOfWork(unitOfWork) { _next.effectTag &= HostEffectMask; return _next; } + stopWorkTimer(workInProgress); if (returnFiber !== null) { @@ -20838,7 +17804,7 @@ function getRemainingExpirationTime(fiber) { function resetChildExpirationTime(completedWork) { if ( - renderExpirationTime !== Never && + renderExpirationTime$1 !== Never && completedWork.childExpirationTime === Never ) { // The children of this component are hidden. Don't bubble their @@ -20848,7 +17814,7 @@ function resetChildExpirationTime(completedWork) { var newChildExpirationTime = NoWork; // Bubble up the earliest expiration time. - if (enableProfilerTimer && (completedWork.mode & ProfileMode) !== NoMode) { + if ((completedWork.mode & ProfileMode) !== NoMode) { // In profiling mode, resetChildExpirationTime is also used to reset // profiler durations. var actualDuration = completedWork.actualDuration; @@ -20911,7 +17877,7 @@ function resetChildExpirationTime(completedWork) { function commitRoot(root) { var renderPriorityLevel = getCurrentPriorityLevel(); - runWithPriority$1( + runWithPriority( ImmediatePriority, commitRootImpl.bind(null, root, renderPriorityLevel) ); @@ -20919,7 +17885,16 @@ function commitRoot(root) { } function commitRootImpl(root, renderPriorityLevel) { - flushPassiveEffects(); + 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); + flushRenderPhaseStrictModeWarningsInDEV(); if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { @@ -20963,8 +17938,7 @@ function commitRootImpl(root, renderPriorityLevel) { // We can reset these now that they are finished. workInProgressRoot = null; workInProgress = null; - renderExpirationTime = NoWork; - } else { + renderExpirationTime$1 = NoWork; } // 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. @@ -21019,9 +17993,10 @@ 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(); @@ -21095,7 +18070,7 @@ function commitRootImpl(root, renderPriorityLevel) { requestPaint(); - if (enableSchedulerTracing) { + { popInteractions(prevInteractions); } @@ -21109,7 +18084,7 @@ function commitRootImpl(root, renderPriorityLevel) { startCommitSnapshotEffectsTimer(); stopCommitSnapshotEffectsTimer(); - if (enableProfilerTimer) { + { recordCommitTime(); } @@ -21134,6 +18109,7 @@ 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; @@ -21144,10 +18120,11 @@ 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, @@ -21165,7 +18142,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. @@ -21219,8 +18196,8 @@ function commitBeforeMutationEffects() { if ((effectTag & Snapshot) !== NoEffect) { setCurrentFiber(nextEffect); recordEffect(); - var current$$1 = nextEffect.alternate; - commitBeforeMutationLifeCycles(current$$1, nextEffect); + var current = nextEffect.alternate; + commitBeforeMutationLifeCycles(current, nextEffect); resetCurrentFiber(); } @@ -21246,15 +18223,11 @@ function commitMutationEffects(root, renderPriorityLevel) { setCurrentFiber(nextEffect); var effectTag = nextEffect.effectTag; - if (effectTag & ContentReset) { - commitResetTextContent(nextEffect); - } - if (effectTag & Ref) { - var current$$1 = nextEffect.alternate; + var current = nextEffect.alternate; - if (current$$1 !== null) { - commitDetachRef(current$$1); + if (current !== null) { + commitDetachRef(current); } } // The following switch statement is only concerned about placement, // updates, and deletions. To avoid needing to add a case for every possible @@ -21266,7 +18239,6 @@ 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. @@ -21276,8 +18248,6 @@ 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 @@ -21326,8 +18296,8 @@ function commitLayoutEffects(root, committedExpirationTime) { if (effectTag & (Update | Callback)) { recordEffect(); - var current$$1 = nextEffect.alternate; - commitLifeCycles(root, current$$1, nextEffect, committedExpirationTime); + var current = nextEffect.alternate; + commitLifeCycles(root, current, nextEffect); } if (effectTag & Ref) { @@ -21347,7 +18317,7 @@ function flushPassiveEffects() { ? NormalPriority : pendingPassiveEffectsRenderPriority; pendingPassiveEffectsRenderPriority = NoPriority; - return runWithPriority$1(priorityLevel, flushPassiveEffectsImpl); + return runWithPriority(priorityLevel, flushPassiveEffectsImpl); } } @@ -21367,36 +18337,40 @@ 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 prevInteractions = pushInteractions(root); - var effect = root.current.firstEffect; + { + // 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 (effect !== null) { - { - setCurrentFiber(effect); - invokeGuardedCallback(null, commitPassiveHookEffects, null, effect); + while (_effect2 !== null) { + { + setCurrentFiber(_effect2); + invokeGuardedCallback(null, commitPassiveHookEffects, null, _effect2); - if (hasCaughtError()) { - if (!(effect !== null)) { - throw Error("Should be working on an effect."); + if (hasCaughtError()) { + if (!(_effect2 !== null)) { + throw Error("Should be working on an effect."); + } + + var _error5 = clearCaughtError(); + + captureCommitPhaseError(_effect2, _error5); } - var error = clearCaughtError(); - captureCommitPhaseError(effect, error); + resetCurrentFiber(); } - resetCurrentFiber(); - } - - var nextNextEffect = effect.nextEffect; // Remove nextEffect pointer to assist GC + var nextNextEffect = _effect2.nextEffect; // Remove nextEffect pointer to assist GC - effect.nextEffect = null; - effect = nextNextEffect; + _effect2.nextEffect = null; + _effect2 = nextNextEffect; + } } - if (enableSchedulerTracing) { + { popInteractions(prevInteractions); finishPendingInteractions(root, expirationTime); } @@ -21430,6 +18404,7 @@ function prepareToThrowUncaughtError(error) { firstUncaughtError = error; } } + var onUncaughtError = prepareToThrowUncaughtError; function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { @@ -21453,6 +18428,7 @@ function captureCommitPhaseError(sourceFiber, error) { } var fiber = sourceFiber.return; + while (fiber !== null) { if (fiber.tag === HostRoot) { captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error); @@ -21460,6 +18436,7 @@ 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" && @@ -21495,7 +18472,7 @@ function pingSuspendedRoot(root, thenable, suspendedTime) { pingCache.delete(thenable); } - if (workInProgressRoot === root && renderExpirationTime === suspendedTime) { + if (workInProgressRoot === root && renderExpirationTime$1 === 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. @@ -21515,7 +18492,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); + prepareFreshStack(root, renderExpirationTime$1); } else { // Even though we can't restart right now, we might get an // opportunity later. So we mark this render as having a ping. @@ -21538,13 +18515,6 @@ 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); } @@ -21572,45 +18542,12 @@ 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; } @@ -21630,20 +18567,21 @@ 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( @@ -21665,6 +18603,7 @@ 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. @@ -21691,8 +18630,8 @@ function checkForNestedUpdates() { { if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) { nestedPassiveUpdateCount = 0; - warning$1( - false, + + error( "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 " + @@ -21706,7 +18645,7 @@ function flushRenderPhaseStrictModeWarningsInDEV() { { ReactStrictModeWarnings.flushLegacyContextWarning(); - if (warnAboutDeprecatedLifecycles) { + { ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings(); } } @@ -21727,9 +18666,8 @@ function stopInterruptedWorkLoopTimer() { function checkForInterruption(fiberThatReceivedUpdate, updateExpirationTime) { if ( - enableUserTimingAPI && workInProgressRoot !== null && - updateExpirationTime > renderExpirationTime + updateExpirationTime > renderExpirationTime$1 ) { interruptedBy = fiberThatReceivedUpdate; } @@ -21747,11 +18685,12 @@ function warnAboutUpdateOnUnmountedFiberInDEV(fiber) { tag !== FunctionComponent && tag !== ForwardRef && tag !== MemoComponent && - tag !== SimpleMemoComponent + tag !== SimpleMemoComponent && + tag !== Block ) { // 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"; @@ -21760,12 +18699,13 @@ function warnAboutUpdateOnUnmountedFiberInDEV(fiber) { if (didWarnStateUpdateForUnmountedComponent.has(componentName)) { return; } + didWarnStateUpdateForUnmountedComponent.add(componentName); } else { didWarnStateUpdateForUnmountedComponent = new Set([componentName]); } - warningWithoutStack$1( - false, + + error( "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", @@ -21777,12 +18717,12 @@ function warnAboutUpdateOnUnmountedFiberInDEV(fiber) { } } -var beginWork$$1; +var beginWork$1; -if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) { +{ var dummyFiber = null; - beginWork$$1 = function(current$$1, unitOfWork, expirationTime) { + beginWork$1 = function(current, 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. @@ -21792,8 +18732,9 @@ if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) { dummyFiber, unitOfWork ); + try { - return beginWork$1(current$$1, unitOfWork, expirationTime); + return beginWork(current, unitOfWork, expirationTime); } catch (originalError) { if ( originalError !== null && @@ -21806,7 +18747,7 @@ if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) { // corresponding changes there. resetContextDependencies(); - resetHooks(); // Don't reset current debug fiber, since we're about to work on the + resetHooksAfterThrow(); // Don't reset current debug fiber, since we're about to work on the // same fiber again. // Unwind the failed stack frame @@ -21814,16 +18755,16 @@ if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) { assignFiberPropertiesInDEV(unitOfWork, originalWorkInProgressCopy); - if (enableProfilerTimer && unitOfWork.mode & ProfileMode) { + if (unitOfWork.mode & ProfileMode) { // Reset the profiler timer. startProfilerTimer(unitOfWork); } // Run beginWork again. invokeGuardedCallback( null, - beginWork$1, + beginWork, null, - current$$1, + current, unitOfWork, expirationTime ); @@ -21839,38 +18780,37 @@ if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) { } } }; -} else { - beginWork$$1 = beginWork$1; } var didWarnAboutUpdateInRender = false; -var didWarnAboutUpdateInGetChildContext = false; -function warnAboutInvalidUpdatesOnClassComponentsInDEV(fiber) { + +function warnAboutRenderPhaseUpdatesInDEV(fiber) { { - if (fiber.tag === ClassComponent) { - switch (phase) { - case "getChildContext": - if (didWarnAboutUpdateInGetChildContext) { - return; - } - warningWithoutStack$1( - false, - "setState(...): Cannot call setState() inside getChildContext()" + 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." ); - didWarnAboutUpdateInGetChildContext = true; + break; - case "render": - if (didWarnAboutUpdateInRender) { - return; + } + + 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; } - 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; + } } } } @@ -21879,89 +18819,6 @@ function warnAboutInvalidUpdatesOnClassComponentsInDEV(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, @@ -21976,159 +18833,30 @@ function warnIfUnmockedScheduler(fiber) { ) { if (fiber.mode & BlockingMode || fiber.mode & ConcurrentMode) { didWarnAboutUnmockedScheduler = true; - warningWithoutStack$1( - false, + + error( '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" + - "jest.mock('scheduler', () => require('scheduler/unstable_mock'));\n\n" + + "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" + "For more info, visit https://fb.me/react-mock-scheduler" ); - } else if (warnAboutUnmockedScheduler === true) { + } else { didWarnAboutUnmockedScheduler = true; - warningWithoutStack$1( - false, + + error( '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" + + "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" + "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. @@ -22136,9 +18864,6 @@ function computeThreadID(root, expirationTime) { } function markSpawnedWork(expirationTime) { - if (!enableSchedulerTracing) { - return; - } if (spawnedWorkDuringRender === null) { spawnedWorkDuringRender = [expirationTime]; } else { @@ -22147,13 +18872,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); + if (pendingInteractions != null) { interactions.forEach(function(interaction) { if (!pendingInteractions.has(interaction)) { @@ -22172,6 +18894,7 @@ function scheduleInteractions(root, expirationTime, interactions) { } var subscriber = tracing.__subscriberRef.current; + if (subscriber !== null) { var threadID = computeThreadID(root, expirationTime); subscriber.onWorkScheduled(interactions, threadID); @@ -22180,21 +18903,10 @@ 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. @@ -22235,10 +18947,6 @@ function startWorkOnPendingInteractions(root, expirationTime) { } function finishPendingInteractions(root, committedExpirationTime) { - if (!enableSchedulerTracing) { - return; - } - var earliestRemainingTimeAfterCommit = root.firstPendingTime; var subscriber; @@ -22287,6 +18995,7 @@ function finishPendingInteractions(root, committedExpirationTime) { } } +var onScheduleFiberRoot = null; var onCommitFiberRoot = null; var onCommitFiberUnmount = null; var hasLoggedError = false; @@ -22305,10 +19014,10 @@ function injectInternals(internals) { // https://github.com/facebook/react/issues/3877 return true; } + if (!hook.supportsFiber) { { - warningWithoutStack$1( - false, + error( "The installed version of React DevTools is too old and will not work " + "with the current version of React. Please update React DevTools. " + "https://fb.me/react-devtools" @@ -22321,6 +19030,23 @@ 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; @@ -22336,43 +19062,43 @@ function injectInternals(internals) { hook.onCommitFiberRoot(rendererID, root, undefined, didError); } } catch (err) { - if (true && !hasLoggedError) { - hasLoggedError = true; - warningWithoutStack$1( - false, - "React DevTools encountered an error: %s", - err - ); + if (true) { + if (!hasLoggedError) { + hasLoggedError = true; + + error("React instrumentation encountered an error: %s", err); + } } } }; + onCommitFiberUnmount = function(fiber) { try { hook.onCommitFiberUnmount(rendererID, fiber); } catch (err) { - if (true && !hasLoggedError) { - hasLoggedError = true; - warningWithoutStack$1( - false, - "React DevTools encountered an error: %s", - err - ); + if (true) { + if (!hasLoggedError) { + hasLoggedError = true; + + error("React instrumentation encountered an error: %s", err); + } } } }; } catch (err) { // Catch all errors because it is unsafe to throw during initialization. { - warningWithoutStack$1( - false, - "React DevTools encountered an error: %s.", - err - ); + error("React instrumentation 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); @@ -22434,7 +19160,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 @@ -22461,7 +19187,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; } @@ -22489,6 +19215,7 @@ 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); @@ -22524,7 +19251,7 @@ function resolveLazyComponentTag(Component) { return IndeterminateComponent; } // This is used to create an alternate fiber to do work on. -function createWorkInProgress(current, pendingProps, expirationTime) { +function createWorkInProgress(current, pendingProps) { var workInProgress = current.alternate; if (workInProgress === null) { @@ -22545,7 +19272,10 @@ function createWorkInProgress(current, pendingProps, expirationTime) { { // DEV-only fields - workInProgress._debugID = current._debugID; + { + workInProgress._debugID = current._debugID; + } + workInProgress._debugSource = current._debugSource; workInProgress._debugOwner = current._debugOwner; workInProgress._debugHookTypes = current._debugHookTypes; @@ -22563,7 +19293,7 @@ function createWorkInProgress(current, pendingProps, expirationTime) { 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, @@ -22573,6 +19303,19 @@ function createWorkInProgress(current, pendingProps, expirationTime) { } } + { + // 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; @@ -22595,13 +19338,14 @@ function createWorkInProgress(current, pendingProps, expirationTime) { 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: @@ -22616,9 +19360,6 @@ function createWorkInProgress(current, pendingProps, expirationTime) { case ForwardRef: workInProgress.type = resolveForwardRefForHotReloading(current.type); break; - - default: - break; } } @@ -22651,7 +19392,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; @@ -22677,7 +19418,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; @@ -22698,7 +19439,7 @@ function createHostRootFiber(tag) { mode = NoMode; } - if (enableProfilerTimer && isDevToolsPresent) { + if (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. @@ -22767,12 +19508,14 @@ 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; @@ -22795,29 +19538,10 @@ function createFiberFromTypeAndProps( fiberTag = LazyComponent; resolvedType = null; 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 - ); - } + case REACT_BLOCK_TYPE: + fiberTag = Block; + break getTag; } } @@ -22879,6 +19603,7 @@ function createFiberFromElement(element, mode, expirationTime) { mode, expirationTime ); + { fiber._debugSource = element._source; fiber._debugOwner = element._owner; @@ -22891,38 +19616,11 @@ 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" || - typeof pendingProps.onRender !== "function" - ) { - warningWithoutStack$1( - false, - 'Profiler must specify an "id" string and "onRender" function as props' - ); + if (typeof pendingProps.id !== "string") { + error('Profiler must specify an "id" as a prop'); } } @@ -22931,6 +19629,14 @@ 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; } @@ -22953,6 +19659,7 @@ function createFiberFromSuspenseList(pendingProps, mode, expirationTime, key) { // instead. fiber.type = REACT_SUSPENSE_LIST_TYPE; } + fiber.elementType = REACT_SUSPENSE_LIST_TYPE; fiber.expirationTime = expirationTime; return fiber; @@ -22962,18 +19669,6 @@ 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); @@ -23021,16 +19716,21 @@ 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._debugID = source._debugID; + target._debugIsCurrentlyTiming = source._debugIsCurrentlyTiming; + } + target._debugSource = source._debugSource; target._debugOwner = source._debugOwner; - target._debugIsCurrentlyTiming = source._debugIsCurrentlyTiming; target._debugNeedsRemount = source._debugNeedsRemount; target._debugHookTypes = source._debugHookTypes; return target; @@ -23057,28 +19757,21 @@ 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) { @@ -23172,15 +19865,6 @@ 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; @@ -23199,39 +19883,13 @@ function getContextForSubtree(parentComponent) { 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 (hostFiber === null) { - return null; + if (isContextProvider(Component)) { + return processChildContext(fiber, Component, parentContext); + } } - return hostFiber.stateNode; + return parentContext; } function findHostInstanceWithWarning(component, methodName) { @@ -23266,8 +19924,7 @@ function findHostInstanceWithWarning(component, methodName) { didWarnAboutFindNodeInStrictMode[componentName] = true; if (fiber.mode & StrictMode) { - warningWithoutStack$1( - false, + error( "%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. " + @@ -23279,8 +19936,7 @@ function findHostInstanceWithWarning(component, methodName) { getStackByFiberInDevAndProd(hostFiber) ); } else { - warningWithoutStack$1( - false, + error( "%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. " + @@ -23297,43 +19953,32 @@ function findHostInstanceWithWarning(component, methodName) { return hostFiber.stateNode; } - - return findHostInstance(component); } function createContainer(containerInfo, tag, hydrate, hydrationCallbacks) { - return createFiberRoot(containerInfo, tag, hydrate, hydrationCallbacks); + return createFiberRoot(containerInfo, tag, hydrate); } function updateContainer(element, container, parentComponent, callback) { - var current$$1 = container.current; + { + onScheduleRoot(container, element); + } + + 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); } } + 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) { @@ -23343,10 +19988,10 @@ function updateContainer(element, container, parentComponent, callback) { } { - if (phase === "render" && current !== null && !didWarnAboutNestedUpdates) { + if (isRendering && current !== null && !didWarnAboutNestedUpdates) { didWarnAboutNestedUpdates = true; - warningWithoutStack$1( - false, + + error( "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" + @@ -23365,719 +20010,173 @@ function updateContainer(element, container, parentComponent, callback) { callback = callback === undefined ? null : callback; if (callback !== null) { - !(typeof callback === "function") - ? warningWithoutStack$1( - false, + { + if (typeof callback !== "function") { + error( "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); - return expirationTime; -} -function getPublicRootInstance(container) { - var containerFiber = container.current; - - if (!containerFiber.child) { - return null; - } - - switch (containerFiber.child.tag) { - case HostComponent: - return getPublicInstance(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; + update.callback = callback; } - return NativeMethodsMixin; -}; - -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); - - function ReactNativeComponent() { - return _React$Component.apply(this, arguments) || this; - } + enqueueUpdate(current$1, update); + scheduleWork(current$1, expirationTime); + return expirationTime; +} +function getPublicRootInstance(container) { + var containerFiber = container.current; - var _proto = ReactNativeComponent.prototype; + if (!containerFiber.child) { + return null; + } - /** - * Due to bugs in Flow's handling of React.createClass, some fields already - * declared in the base class need to be redeclared below. - */ + switch (containerFiber.child.tag) { + case HostComponent: + return getPublicInstance(containerFiber.child.stateNode); - /** - * 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. - */ + default: + return containerFiber.child.stateNode; + } +} - _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 shouldSuspendImpl = function(fiber) { + return false; +}; - 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. +function shouldSuspend(fiber) { + return shouldSuspendImpl(fiber); +} +var overrideHookState = null; +var overrideProps = null; +var scheduleUpdate = null; +var setSuspenseHandler = null; - if (maybeInstance == null) { - return; - } +{ + var copyWithSetImpl = function(obj, path, idx, value) { + if (idx >= path.length) { + return value; + } - 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. + 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.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. + 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) { - 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; + fiber.memoizedProps = Object.assign({}, fiber.memoizedProps); + scheduleWork(fiber, Sync); + } + }; // Support DevTools props for function components, forwardRef, memo, host components, etc. - if (typeof relativeToNativeNode === "number") { - // Already a node handle - relativeNode = relativeToNativeNode; - } else if (relativeToNativeNode._nativeTag) { - relativeNode = relativeToNativeNode._nativeTag; - } + overrideProps = function(fiber, path, value) { + fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value); - if (relativeNode == null) { - warningWithoutStack$1( - false, - "Warning: ref.measureLayout must be called with a node handle or a ref to a native component." - ); - return; - } + if (fiber.alternate) { + fiber.alternate.pendingProps = fiber.pendingProps; + } - 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. + 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. + scheduleUpdate = function(fiber) { + scheduleWork(fiber, Sync); + }; - if (maybeInstance == null) { - return; - } + setSuspenseHandler = function(newShouldSuspendImpl) { + shouldSuspendImpl = newShouldSuspendImpl; + }; +} - if (maybeInstance.canonical) { - warningWithoutStack$1( - false, - "Warning: setNativeProps is not currently supported in Fabric" - ); - 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; + } - 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 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; + } + }); +} +var IsSomeRendererActing$1 = ReactSharedInternals.IsSomeRendererActing; - return ReactNativeComponent; - })(React.Component); // eslint-disable-next-line no-unused-expressions +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 + }; +} - return ReactNativeComponent; -}; +// TODO: this is special because it gets imported during build. +var ReactVersion = "16.13.0"; var instanceCache = new Map(); @@ -24085,13 +20184,14 @@ function getInstanceFromTag(tag) { return instanceCache.get(tag) || null; } -var emptyObject$3 = {}; +var emptyObject$1 = {}; { - Object.freeze(emptyObject$3); + Object.freeze(emptyObject$1); } var getInspectorDataForViewTag; +var getInspectorDataForViewAtPoint; { var traverseOwnerTreeUp = function(hierarchy, instance) { @@ -24115,6 +20215,7 @@ var getInspectorDataForViewTag; return instance; } } + return hierarchy[0]; }; @@ -24122,10 +20223,10 @@ var getInspectorDataForViewTag; var host = findCurrentHostFiber(fiber); if (host) { - return host.memoizedProps || emptyObject$3; + return host.memoizedProps || emptyObject$1; } - return emptyObject$3; + return emptyObject$1; }; var getHostNode = function(fiber, findNodeHandle) { @@ -24153,28 +20254,65 @@ var getInspectorDataForViewTag; name: getComponentName(fiber.type), getInspectorData: function(findNodeHandle) { return { - measure: function(callback) { - return ReactNativePrivateInterface.UIManager.measure( - getHostNode(fiber, findNodeHandle), - callback - ); - }, props: getHostProps(fiber), - source: fiber._debugSource + 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 + ); + } + } }; } }; }); }; + 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$3, - selection: null, + props: emptyObject$1, + selectedIndex: null, source: null }; } @@ -24185,36 +20323,122 @@ var getInspectorDataForViewTag; var hierarchy = createHierarchy(fiberHierarchy); var props = getHostProps(instance); var source = instance._debugSource; - var selection = fiberHierarchy.indexOf(instance); + var selectedIndex = fiberHierarchy.indexOf(instance); return { hierarchy: hierarchy, props: props, - selection: selection, + selectedIndex: selectedIndex, 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 _nativeFabricUIManage = nativeFabricUIManager; -var fabricDispatchCommand = _nativeFabricUIManage.dispatchCommand; -var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner; +var ReactCurrentOwner$3 = ReactSharedInternals.ReactCurrentOwner; function findHostInstance_DEPRECATED(componentOrHandle) { { - var owner = ReactCurrentOwner.current; + var owner = ReactCurrentOwner$3.current; if (owner !== null && owner.stateNode !== null) { - !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; + 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 = true; } } @@ -24254,20 +20478,20 @@ function findHostInstance_DEPRECATED(componentOrHandle) { function findNodeHandle(componentOrHandle) { { - var owner = ReactCurrentOwner.current; + var owner = ReactCurrentOwner$3.current; if (owner !== null && owner.stateNode !== null) { - !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; + 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 = true; } } @@ -24307,94 +20531,95 @@ function findNodeHandle(componentOrHandle) { // Fabric return hostInstance.canonical._nativeTag; } + return hostInstance._nativeTag; } -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; +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" + ); } - fabricDispatchCommand( + return; + } + + if (handle._internalInstanceHandle) { + nativeFabricUIManager.dispatchCommand( handle._internalInstanceHandle.stateNode.node, command, args ); - }, - render: function(element, containerTag, callback) { - var root = roots.get(containerTag); + } else { + ReactNativePrivateInterface.UIManager.dispatchViewManagerCommand( + handle._nativeTag, + command, + args + ); + } +} - 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); - } +function render(element, containerTag, callback) { + var root = roots.get(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) + 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); +} + +function stopSurface(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 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" -}); - -var ReactFabric$2 = Object.freeze({ - default: ReactFabric + rendererPackageName: "react-native-renderer", + rendererConfig: { + getInspectorDataForViewTag: getInspectorDataForViewTag, + getInspectorDataForViewAtPoint: getInspectorDataForViewAtPoint.bind( + null, + findNodeHandle + ) + } }); -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; +exports.createPortal = createPortal$1; +exports.dispatchCommand = dispatchCommand; +exports.findHostInstance_DEPRECATED = findHostInstance_DEPRECATED; +exports.findNodeHandle = findNodeHandle; +exports.render = render; +exports.stopSurface = stopSurface; +exports.unmountComponentAtNode = unmountComponentAtNode; })(); } diff --git a/Libraries/Renderer/implementations/ReactFabric-dev.js b/Libraries/Renderer/implementations/ReactFabric-dev.js index a4cbef3535b812..8e2baedcc4efc4 100644 --- a/Libraries/Renderer/implementations/ReactFabric-dev.js +++ b/Libraries/Renderer/implementations/ReactFabric-dev.js @@ -5,6 +5,7 @@ * LICENSE file in the root directory of this source tree. * * @noflow + * @nolint * @providesModule ReactFabric-dev * @preventMunge * @generated @@ -16,253 +17,234 @@ 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"); -/** - * 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. - */ +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. -/** - * Injectable ordering of event plugins. - */ -var eventPluginOrder = null; -/** - * Injectable mapping from names to event plugin modules. - */ +if (!ReactSharedInternals.hasOwnProperty("ReactCurrentDispatcher")) { + ReactSharedInternals.ReactCurrentDispatcher = { + current: 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; - } +if (!ReactSharedInternals.hasOwnProperty("ReactCurrentBatchConfig")) { + ReactSharedInternals.ReactCurrentBatchConfig = { + suspense: null + }; +} - for (var pluginName in namesToPlugins) { - var pluginModule = namesToPlugins[pluginName]; - var pluginIndex = eventPluginOrder.indexOf(pluginName); +// 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. - if (!(pluginIndex > -1)) { - throw Error( - "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + - 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 (plugins[pluginIndex]) { - continue; + 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 (!pluginModule.extractEvents) { - throw Error( - "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + - pluginName + - "` does not." - ); - } + printWarning("error", format, args); + } +} - plugins[pluginIndex] = pluginModule; - var publishedEvents = pluginModule.eventTypes; +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; - for (var eventName in publishedEvents) { - if ( - !publishEventForPlugin( - publishedEvents[eventName], - pluginModule, - eventName - ) - ) { - throw Error( - "EventPluginRegistry: Failed to publish event `" + - eventName + - "` for plugin `" + - pluginName + - "`." - ); + if (!hasExistingStack) { + var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; + var stack = ReactDebugCurrentFrame.getStackAddendum(); + + if (stack !== "") { + format += "%s"; + args = args.concat([stack]); } } + + 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 - */ -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 FunctionComponent = 0; +var ClassComponent = 1; +var IndeterminateComponent = 2; // Before we know whether it is function or class - eventNameDispatchConfigs[eventName] = dispatchConfig; - var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; +var HostRoot = 3; // Root of a host tree. Could be nested inside another node. - 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; +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 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 (inst) { + return inst; } - return false; + return null; } /** - * 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 + * Return the lowest common ancestor of A and B, or null if they are in + * different trees. */ -function publishRegistrationName(registrationName, pluginModule, eventName) { - if (!!registrationNameModules[registrationName]) { - throw Error( - "EventPluginHub: More than one plugin attempted to publish the same registration name, `" + - registrationName + - "`." - ); +function getLowestCommonAncestor(instA, instB) { + var depthA = 0; + + for (var tempA = instA; tempA; tempA = getParent(tempA)) { + depthA++; } - registrationNameModules[registrationName] = pluginModule; - registrationNameDependencies[registrationName] = - pluginModule.eventTypes[eventName].dependencies; + var depthB = 0; - { - var lowerCasedName = registrationName.toLowerCase(); + 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; + } + + instA = getParent(instA); + instB = getParent(instB); } + + return null; } /** - * Registers plugins so that they can extract and dispatch events. - * - * @see {EventPluginHub} + * Return if A is an ancestor of B. */ -/** - * Ordered list of injected plugins. - */ +function isAncestor(instA, instB) { + while (instB) { + if (instA === instB || instA === instB.alternate) { + return true; + } -var plugins = []; + instB = getParent(instB); + } + + return false; +} /** - * Mapping from event name to dispatch config + * Return the parent instance of the passed-in instance. */ -var eventNameDispatchConfigs = {}; +function getParentInstance(inst) { + return getParent(inst); +} /** - * Mapping from registration name to plugin module + * Simulates the traversal of a two-phase, capture/bubble event dispatch. */ -var registrationNameModules = {}; -/** - * Mapping from registration name to event name - */ - -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} - */ - -// Trust the developer to only use possibleRegistrationNames in true - -/** - * 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; - } +function traverseTwoPhase(inst, fn, arg) { + var path = []; - var pluginModule = injectedNamesToPlugins[pluginName]; + while (inst) { + path.push(inst); + inst = getParent(inst); + } - 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 i; - namesToPlugins[pluginName] = pluginModule; - isOrderingDirty = true; - } + for (i = path.length; i-- > 0; ) { + fn(path[i], "captured", arg); } - if (isOrderingDirty) { - recomputePluginOrdering(); + + for (i = 0; i < path.length; i++) { + fn(path[i], "bubbled", arg); } } @@ -278,6 +260,7 @@ var invokeGuardedCallbackImpl = function( f ) { var funcArgs = Array.prototype.slice.call(arguments, 3); + try { func.apply(context, funcArgs); } catch (error) { @@ -486,6 +469,7 @@ 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; @@ -501,6 +485,7 @@ 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, @@ -527,6 +512,7 @@ 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; @@ -553,70 +539,6 @@ 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; @@ -628,14 +550,14 @@ function setComponentTree( getFiberCurrentPropsFromNode = getFiberCurrentPropsFromNodeImpl; getInstanceFromNode = getInstanceFromNodeImpl; getNodeFromInstance = getNodeFromInstanceImpl; + { - !(getNodeFromInstance && getInstanceFromNode) - ? warningWithoutStack$1( - false, - "EventPluginUtils.setComponentTree(...): Injected " + - "module is missing getNodeFromInstance or getInstanceFromNode." - ) - : void 0; + if (!getNodeFromInstance || !getInstanceFromNode) { + error( + "EventPluginUtils.setComponentTree(...): Injected " + + "module is missing getNodeFromInstance or getInstanceFromNode." + ); + } } } var validateEventDispatches; @@ -648,17 +570,18 @@ 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; - !(instancesIsArr === listenersIsArr && instancesLen === listenersLen) - ? warningWithoutStack$1(false, "EventPluginUtils: Invalid `event`.") - : void 0; + ? 1 + : 0; + + if (instancesIsArr !== listenersIsArr || instancesLen !== listenersLen) { + error("EventPluginUtils: Invalid `event`."); + } }; } /** @@ -667,6 +590,7 @@ 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); @@ -753,6 +677,7 @@ function executeDispatchesInOrderStopAtTrue(event) { * * @return {*} The return value of executing the single dispatch. */ + function executeDirectDispatch(event) { { validateEventDispatches(event); @@ -778,10 +703,82 @@ 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 @@ -812,6 +809,7 @@ function accumulateInto(current, next) { current.push.apply(current, next); return current; } + current.push(next); return current; } @@ -842,1107 +840,794 @@ function forEachAccumulated(arr, cb, scope) { } /** - * Internal queue of events that have accumulated their dispatches and are - * waiting to have their dispatches executed. + * 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. */ -var eventQueue = null; /** - * Dispatches an event and releases it back into the pool, unless persistent. - * - * @param {?object} event Synthetic event to be dispatched. - * @private + * 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 executeDispatchesAndRelease = function(event) { - if (event) { - executeDispatchesInOrder(event); - if (!event.isPersistent()) { - event.constructor.release(event); +function accumulateDirectionalDispatches(inst, phase, event) { + { + if (!inst) { + error("Dispatching inst must not be null"); } } -}; -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); + var listener = listenerAtPhase(inst, event, phase); - if (!!eventQueue) { - throw Error( - "processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented." + if (listener) { + event._dispatchListeners = accumulateInto( + event._dispatchListeners, + listener ); - } // This would be a good time to rethrow if any of the event handlers threw. - - rethrowCaughtError(); -} - -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; + event._dispatchInstances = accumulateInto(event._dispatchInstances, inst); } } /** - * 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 + * 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); + } +} /** - * Methods for injecting dependencies. + * Same as `accumulateTwoPhaseDispatchesSingle`, but skips over the targetID. */ -var injection = { - /** - * @param {array} InjectedEventPluginOrder - * @public - */ - injectEventPluginOrder: injectEventPluginOrder, - /** - * @param {object} injectedNamesToPlugins Map from names to plugin modules. - */ - injectEventPluginsByName: injectEventPluginsByName -}; +function accumulateTwoPhaseDispatchesSingleSkipTarget(event) { + if (event && event.dispatchConfig.phasedRegistrationNames) { + var targetInst = event._targetInst; + var parentInst = targetInst ? getParentInstance(targetInst) : null; + traverseTwoPhase(parentInst, accumulateDirectionalDispatches, 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. + * 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 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; +function accumulateDispatches(inst, ignoredDirection, event) { + if (inst && event && event.dispatchConfig.registrationName) { + var registrationName = event.dispatchConfig.registrationName; + var listener = getListener(inst, registrationName); - if (!stateNode) { - // Work in progress (ex: onload events in incremental mode). - return null; + 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 + */ - var props = getFiberCurrentPropsFromNode(stateNode); - - if (!props) { - // Work in progress. - return null; +function accumulateDirectDispatchesSingle(event) { + if (event && event.dispatchConfig.registrationName) { + accumulateDispatches(event._targetInst, null, event); } +} - listener = props[registrationName]; +function accumulateTwoPhaseDispatches(events) { + forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle); +} +function accumulateTwoPhaseDispatchesSkipTarget(events) { + forEachAccumulated(events, accumulateTwoPhaseDispatchesSingleSkipTarget); +} +function accumulateDirectDispatches(events) { + forEachAccumulated(events, accumulateDirectDispatchesSingle); +} - if (shouldPreventMouseEvent(registrationName, inst.type, props)) { +var EVENT_POOL_SIZE = 10; +/** + * @interface Event + * @see http://www.w3.org/TR/DOM-Level-3-Events/ + */ + +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 +}; - if (!(!listener || typeof listener === "function")) { - throw Error( - "Expected `" + - registrationName + - "` listener to be a function, instead got a value of `" + - typeof listener + - "` type." - ); - } +function functionThatReturnsTrue() { + return true; +} - return listener; +function functionThatReturnsFalse() { + return false; } /** - * Allows registered plugins an opportunity to extract events from top-level - * native browser events. + * Synthetic events are dispatched by event plugins, typically in response to a + * top-level event delegation handler. * - * @return {*} An accumulation of synthetic events. - * @internal + * 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 extractPluginEvents( - topLevelType, + +function SyntheticEvent( + dispatchConfig, targetInst, nativeEvent, - nativeEventTarget, - eventSystemFlags + nativeEventTarget ) { - var events = null; + { + // these have a getter/setter for warnings + delete this.nativeEvent; + delete this.preventDefault; + delete this.stopPropagation; + delete this.isDefaultPrevented; + delete this.isPropagationStopped; + } - for (var i = 0; i < plugins.length; i++) { - // Not every plugin in the ordering may be loaded at runtime. - var possiblePlugin = plugins[i]; + this.dispatchConfig = dispatchConfig; + this._targetInst = targetInst; + this.nativeEvent = nativeEvent; + var Interface = this.constructor.Interface; - if (possiblePlugin) { - var extractedEvents = possiblePlugin.extractEvents( - topLevelType, - targetInst, - nativeEvent, - nativeEventTarget, - eventSystemFlags - ); + for (var propName in Interface) { + if (!Interface.hasOwnProperty(propName)) { + continue; + } - if (extractedEvents) { - events = accumulateInto(events, extractedEvents); + { + 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]; } } } - return events; -} -function runExtractedPluginEventsInBatch( - topLevelType, - targetInst, - nativeEvent, - nativeEventTarget, - eventSystemFlags -) { - var events = extractPluginEvents( - topLevelType, - targetInst, - nativeEvent, - nativeEventTarget, - eventSystemFlags - ); - runEventsInBatch(events); -} + var defaultPrevented = + nativeEvent.defaultPrevented != null + ? nativeEvent.defaultPrevented + : nativeEvent.returnValue === false; -var FunctionComponent = 0; -var ClassComponent = 1; -var IndeterminateComponent = 2; // Before we know whether it is function or class + if (defaultPrevented) { + this.isDefaultPrevented = functionThatReturnsTrue; + } else { + this.isDefaultPrevented = functionThatReturnsFalse; + } -var HostRoot = 3; // Root of a host tree. Could be nested inside another node. + this.isPropagationStopped = functionThatReturnsFalse; + return this; +} -var HostPortal = 4; // A subtree. Could be an entry point to a different renderer. +Object.assign(SyntheticEvent.prototype, { + preventDefault: function() { + this.defaultPrevented = true; + 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.preventDefault) { + event.preventDefault(); + } else if (typeof event.returnValue !== "unknown") { + event.returnValue = false; + } - if (inst) { - return inst; - } + this.isDefaultPrevented = functionThatReturnsTrue; + }, + stopPropagation: function() { + var event = this.nativeEvent; - return null; -} -/** - * Return the lowest common ancestor of A and B, or null if they are in - * different trees. - */ + if (!event) { + return; + } -function getLowestCommonAncestor(instA, instB) { - var depthA = 0; + 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; + } - for (var tempA = instA; tempA; tempA = getParent(tempA)) { - depthA++; - } + this.isPropagationStopped = functionThatReturnsTrue; + }, - var depthB = 0; + /** + * 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; + }, - for (var tempB = instB; tempB; tempB = getParent(tempB)) { - depthB++; - } // If A is deeper, crawl up. + /** + * Checks if this event should be released back into the pool. + * + * @return {boolean} True if this should not be released, false otherwise. + */ + isPersistent: functionThatReturnsFalse, - while (depthA - depthB > 0) { - instA = getParent(instA); - depthA--; - } // If B is deeper, crawl up. + /** + * `PooledClass` looks for `destructor` on each instance it releases. + */ + destructor: function() { + var Interface = this.constructor.Interface; - while (depthB - depthA > 0) { - instB = getParent(instB); - depthB--; - } // Walk in lockstep until we find a match. + for (var propName in Interface) { + { + Object.defineProperty( + this, + propName, + getPooledWarningPropertyDefinition(propName, Interface[propName]) + ); + } + } - var depth = depthA; + this.dispatchConfig = null; + this._targetInst = null; + this.nativeEvent = null; + this.isDefaultPrevented = functionThatReturnsFalse; + this.isPropagationStopped = functionThatReturnsFalse; + this._dispatchListeners = null; + this._dispatchInstances = null; - while (depth--) { - if (instA === instB || instA === instB.alternate) { - return instA; + { + 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() {}) + ); } - - instA = getParent(instA); - instB = getParent(instB); } - - return null; -} +}); +SyntheticEvent.Interface = EventInterface; /** - * Return if A is an ancestor of B. + * Helper to reduce boilerplate when creating subclasses. */ -function isAncestor(instA, instB) { - while (instB) { - if (instA === instB || instA === instB.alternate) { - return true; - } +SyntheticEvent.extend = function(Interface) { + var Super = this; - instB = getParent(instB); + var E = function() {}; + + E.prototype = Super.prototype; + var prototype = new E(); + + function Class() { + return Super.apply(this, arguments); } - return false; -} -/** - * Return the parent instance of the passed-in instance. - */ + 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; +}; -function getParentInstance(inst) { - return getParent(inst); -} +addEventPoolingTo(SyntheticEvent); /** - * Simulates the traversal of a two-phase, capture/bubble event dispatch. + * Helper to nullify syntheticEvent instance properties when destructing + * + * @param {String} propName + * @param {?object} getVal + * @return {object} defineProperty object */ -function traverseTwoPhase(inst, fn, arg) { - var path = []; +function getPooledWarningPropertyDefinition(propName, getVal) { + var isFunction = typeof getVal === "function"; + return { + configurable: true, + set: set, + get: get + }; - while (inst) { - path.push(inst); - inst = getParent(inst); + function set(val) { + var action = isFunction ? "setting the method" : "setting the property"; + warn(action, "This is effectively a no-op"); + return val; } - var i; - - for (i = path.length; i-- > 0; ) { - fn(path[i], "captured", arg); + 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; } - for (i = 0; i < path.length; i++) { - fn(path[i], "bubbled", arg); + 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 + ); + } } } -/** - * 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. - */ -/** - * 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. - */ +function getPooledEvent(dispatchConfig, targetInst, nativeEvent, nativeInst) { + var EventConstructor = this; -/** - * 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; + if (EventConstructor.eventPool.length) { + var instance = EventConstructor.eventPool.pop(); + EventConstructor.call( + instance, + dispatchConfig, + targetInst, + nativeEvent, + nativeInst + ); + return instance; } - var listener = listenerAtPhase(inst, event, phase); + return new EventConstructor( + dispatchConfig, + targetInst, + nativeEvent, + nativeInst + ); +} - if (listener) { - event._dispatchListeners = accumulateInto( - event._dispatchListeners, - listener +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._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 accumulateTwoPhaseDispatchesSingle(event) { - if (event && event.dispatchConfig.phasedRegistrationNames) { - traverseTwoPhase(event._targetInst, accumulateDirectionalDispatches, event); } -} -/** - * 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); + event.destructor(); + + if (EventConstructor.eventPool.length < EVENT_POOL_SIZE) { + EventConstructor.eventPool.push(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); - } - } + +function addEventPoolingTo(EventConstructor) { + EventConstructor.eventPool = []; + EventConstructor.getPooled = getPooledEvent; + EventConstructor.release = releasePooledEvent; } + /** - * Accumulates dispatches on an `SyntheticEvent`, but only for the - * `dispatchMarker`. - * @param {SyntheticEvent} 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. */ -function accumulateDirectDispatchesSingle(event) { - if (event && event.dispatchConfig.registrationName) { - accumulateDispatches(event._targetInst, null, event); + +var ResponderSyntheticEvent = SyntheticEvent.extend({ + touchHistory: function(nativeEvent) { + return null; // Actually doesn't even look at the native event. } -} +}); -function accumulateTwoPhaseDispatches(events) { - forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle); +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 accumulateTwoPhaseDispatchesSkipTarget(events) { - forEachAccumulated(events, accumulateTwoPhaseDispatchesSingleSkipTarget); +function isMoveish(topLevelType) { + return topLevelType === TOP_TOUCH_MOVE; } - -function accumulateDirectDispatches(events) { - forEachAccumulated(events, accumulateDirectDispatchesSingle); +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]; -/* eslint valid-typeof: 0 */ -var EVENT_POOL_SIZE = 10; /** - * @interface Event - * @see http://www.w3.org/TR/DOM-Level-3-Events/ + * 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 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 functionThatReturnsTrue() { - return true; -} +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 functionThatReturnsFalse() { - return false; +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; } /** - * 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. + * TODO: Instead of making gestures recompute filtered velocity, we could + * include a built in velocity computation that can be reused globally. */ -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; - } - this.dispatchConfig = dispatchConfig; - this._targetInst = targetInst; - this.nativeEvent = nativeEvent; - var Interface = this.constructor.Interface; +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) + }; +} - for (var propName in Interface) { - if (!Interface.hasOwnProperty(propName)) { - continue; - } +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); +} - { - delete this[propName]; // this has a getter/setter for warnings - } +function getTouchIdentifier(_ref) { + var identifier = _ref.identifier; - var normalize = Interface[propName]; + if (!(identifier != null)) { + throw Error("Touch object is missing identifier."); + } - if (normalize) { - this[propName] = normalize(nativeEvent); - } else { - if (propName === "target") { - this.target = nativeEventTarget; - } else { - this[propName] = nativeEvent[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 + ); } } - var defaultPrevented = - nativeEvent.defaultPrevented != null - ? nativeEvent.defaultPrevented - : nativeEvent.returnValue === false; - if (defaultPrevented) { - this.isDefaultPrevented = functionThatReturnsTrue; - } else { - this.isDefaultPrevented = functionThatReturnsFalse; - } - this.isPropagationStopped = functionThatReturnsFalse; - return this; + return identifier; } -Object.assign(SyntheticEvent.prototype, { - preventDefault: function() { - this.defaultPrevented = true; - var event = this.nativeEvent; - if (!event) { - return; - } +function recordTouchStart(touch) { + var identifier = getTouchIdentifier(touch); + var touchRecord = touchBank[identifier]; - if (event.preventDefault) { - event.preventDefault(); - } else if (typeof event.returnValue !== "unknown") { - event.returnValue = false; - } + if (touchRecord) { + resetTouchRecord(touchRecord, touch); + } else { + touchBank[identifier] = createTouchRecord(touch); + } - this.isDefaultPrevented = functionThatReturnsTrue; - }, - stopPropagation: function() { - var event = this.nativeEvent; + touchHistory.mostRecentTimeStamp = timestampForTouch(touch); +} - if (!event) { - return; - } +function recordTouchMove(touch) { + var touchRecord = touchBank[getTouchIdentifier(touch)]; - 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 (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() + ); } + } +} - this.isPropagationStopped = functionThatReturnsTrue; - }, - - /** - * 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; - }, - - /** - * Checks if this event should be released back into the pool. - * - * @return {boolean} True if this should not be released, false otherwise. - */ - isPersistent: functionThatReturnsFalse, +function recordTouchEnd(touch) { + var touchRecord = touchBank[getTouchIdentifier(touch)]; - /** - * `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]) - ); - } - } - this.dispatchConfig = null; - this._targetInst = null; - this.nativeEvent = null; - this.isDefaultPrevented = functionThatReturnsFalse; - this.isPropagationStopped = functionThatReturnsFalse; - this._dispatchListeners = null; - this._dispatchInstances = null; + 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 { { - 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() {}) + warn( + "Cannot record touch end without a touch start.\n" + + "Touch End: %s\n" + + "Touch Bank: %s", + printTouch(touch), + printTouchBank() ); } } -}); -SyntheticEvent.Interface = EventInterface; -/** - * Helper to reduce boilerplate when creating subclasses. - */ +} -SyntheticEvent.extend = function(Interface) { - var Super = this; +function printTouch(touch) { + return JSON.stringify({ + identifier: touch.identifier, + pageX: touch.pageX, + pageY: touch.pageY, + timestamp: timestampForTouch(touch) + }); +} - var E = function() {}; - E.prototype = Super.prototype; - var prototype = new E(); +function printTouchBank() { + var printed = JSON.stringify(touchBank.slice(0, MAX_TOUCH_BANK)); - function Class() { - return Super.apply(this, arguments); + if (touchBank.length > MAX_TOUCH_BANK) { + printed += " (original size: " + touchBank.length + ")"; } - 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 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]; + + if (activeRecord == null || !activeRecord.touchActive) { + error("Cannot find single active touch."); + } + } + } + } + }, + touchHistory: touchHistory }; -addEventPoolingTo(SyntheticEvent); /** - * Helper to nullify syntheticEvent instance properties when destructing + * Accumulates items that must not be null or undefined. * - * @param {String} propName - * @param {?object} getVal - * @return {object} defineProperty object + * This is used to conserve memory by avoiding array allocations. + * + * @return {*|array<*>} An accumulation of items. */ -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 accumulate(current, next) { + if (!(next != null)) { + throw Error( + "accumulate(...): Accumulated items must not be null or undefined." + ); } - 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 (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 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; + if (Array.isArray(next)) { + return [current].concat(next); } + + 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; -} - -/** - * `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. + * Instance of element that should respond to touch/move types of interactions, + * as indicated explicitly by relevant callbacks. */ -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; -} +var responderInst = null; /** - * TODO: Instead of making gestures recompute filtered velocity, we could - * include a built in velocity computation that can be reused globally. + * Count of current touches. A textInput should become responder iff the + * selection changes while there is a touch on the screen. */ -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; -} -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); -} +var trackedTouchCount = 0; -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 changeResponder = function(nextResponderInst, blockHostResponder) { + var oldResponderInst = responderInst; + responderInst = nextResponderInst; -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() + if (ResponderEventPlugin.GlobalResponderHandler !== null) { + ResponderEventPlugin.GlobalResponderHandler.onChange( + oldResponderInst, + nextResponderInst, + blockHostResponder ); } -} +}; -function printTouch(touch) { - return JSON.stringify({ - identifier: touch.identifier, - pageX: touch.pageX, - pageY: touch.pageY, - timestamp: timestampForTouch(touch) - }); -} +var eventTypes = { + /** + * On a `touchStart`/`mouseDown`, is it desired that this element become the + * responder? + */ + startShouldSetResponder: { + phasedRegistrationNames: { + bubbled: "onStartShouldSetResponder", + captured: "onStartShouldSetResponderCapture" + }, + dependencies: startDependencies + }, -function printTouchBank() { - var printed = JSON.stringify(touchBank.slice(0, MAX_TOUCH_BANK)); + /** + * 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 (touchBank.length > MAX_TOUCH_BANK) { - printed += " (original size: " + touchBank.length + ")"; - } + /** + * 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] + }, - 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 - }, + /** + * 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. @@ -2111,7 +1796,7 @@ to return true:wantsResponderID| | + + */ /** - * A note about event ordering in the `EventPluginHub`. + * A note about event ordering in the `EventPluginRegistry`. * * Suppose plugins are injected in the following order: * @@ -2130,7 +1815,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 `EventPluginHub` (hence the + * 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 @@ -2154,9 +1839,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 `EventPluginHub`) - * - `S`s extracted events (if any) (dispatched by `EventPluginHub`) - * - `C`s extracted events (if any) (dispatched by `EventPluginHub`) + * - `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 @@ -2165,9 +1850,9 @@ to return true:wantsResponderID| | * 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) + * - `touchStartCapture` (`EventPluginRegistry` dispatches as usual) + * - `touchStart` (`EventPluginRegistry` dispatches as usual) + * - `responderGrant/Reject` (`EventPluginRegistry` dispatches as usual) */ function setResponderAndExtractTransfer( @@ -2179,10 +1864,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 @@ -2199,6 +1884,7 @@ function setResponderAndExtractTransfer( nativeEventTarget ); shouldSetEvent.touchHistory = ResponderTouchHistoryStore.touchHistory; + if (skipOverBubbleShouldSetFrom) { accumulateTwoPhaseDispatchesSkipTarget(shouldSetEvent); } else { @@ -2239,6 +1925,7 @@ function setResponderAndExtractTransfer( var shouldSwitch = !hasDispatches(terminationRequestEvent) || executeDirectDispatch(terminationRequestEvent); + if (!terminationRequestEvent.isPersistent()) { terminationRequestEvent.constructor.release(terminationRequestEvent); } @@ -2320,6 +2007,7 @@ function noResponderTouches(nativeEvent) { } } } + return true; } @@ -2348,9 +2036,12 @@ var ResponderEventPlugin = { if (trackedTouchCount >= 0) { trackedTouchCount -= 1; } else { - console.warn( - "Ended a touch event which was not counted in `trackedTouchCount`." - ); + { + warn( + "Ended a touch event which was not counted in `trackedTouchCount`." + ); + } + return null; } } @@ -2373,16 +2064,17 @@ 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( @@ -2406,8 +2098,9 @@ var ResponderEventPlugin = { var finalTouch = isResponderTerminate ? eventTypes.responderTerminate : isResponderRelease - ? eventTypes.responderRelease - : null; + ? eventTypes.responderRelease + : null; + if (finalTouch) { var finalEvent = ResponderSyntheticEvent.getPooled( finalTouch, @@ -2436,345 +2129,481 @@ var ResponderEventPlugin = { } }; -var customBubblingEventTypes = - ReactNativePrivateInterface.ReactNativeViewConfigRegistry - .customBubblingEventTypes; -var customDirectEventTypes = - ReactNativePrivateInterface.ReactNativeViewConfigRegistry - .customDirectEventTypes; -var ReactNativeBridgeEventPlugin = { - eventTypes: {}, - - /** - * @see {EventPluginHub.extractEvents} - */ - 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; - } -}; - -var ReactNativeEventPluginOrder = [ - "ResponderEventPlugin", - "ReactNativeBridgeEventPlugin" -]; - /** - * Make sure essential globals are available and are patched correctly. Please don't remove this - * line. Bundles created by react-packager `require` it before executing any application code. This - * ensures it exists in the dependency graph and can be `require`d. - * TODO: require this in packager, not in React #10932517 + * Injectable ordering of event plugins. */ -// Module provided by RN: +var eventPluginOrder = null; /** - * Inject module for resolving DOM hierarchy and plugin ordering. + * Injectable mapping from names to event plugin modules. */ -injection.injectEventPluginOrder(ReactNativeEventPluginOrder); +var namesToPlugins = {}; /** - * Some important event plugins included by default (without having to require - * them). + * Recomputes the plugin list using the injected plugins and plugin ordering. + * + * @private */ -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 recomputePluginOrdering() { + if (!eventPluginOrder) { + // Wait until an `eventPluginOrder` is injected. + return; + } -function getTagFromInstance(inst) { - if (enableNativeTargetAsInstance) { - var nativeInstance = inst.stateNode.canonical; + for (var pluginName in namesToPlugins) { + var pluginModule = namesToPlugins[pluginName]; + var pluginIndex = eventPluginOrder.indexOf(pluginName); - if (!nativeInstance._nativeTag) { - throw Error("All native instances should have a tag."); + if (!(pluginIndex > -1)) { + throw Error( + "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + + pluginName + + "`." + ); } - return nativeInstance; - } else { - var tag = inst.stateNode.canonical._nativeTag; - - if (!tag) { - throw Error("All native instances should have a tag."); + if (plugins[pluginIndex]) { + continue; } - return tag; - } -} - -function getFiberCurrentPropsFromNode$1(inst) { - return inst.canonical.currentProps; -} - -// Module provided by RN: -var ReactFabricGlobalResponderHandler = { - onChange: function(from, to, blockNativeResponder) { - if (to !== null) { - var tag = to.stateNode.canonical._nativeTag; - ReactNativePrivateInterface.UIManager.setJSResponder( - tag, - blockNativeResponder + if (!pluginModule.extractEvents) { + throw Error( + "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + + pluginName + + "` does not." ); - } else { - ReactNativePrivateInterface.UIManager.clearJSResponder(); } - } -}; -setComponentTree( - getFiberCurrentPropsFromNode$1, - getInstanceFromInstance, - getTagFromInstance -); -ResponderEventPlugin.injection.injectGlobalResponderHandler( - ReactFabricGlobalResponderHandler -); + 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 + + "`." + ); + } + } + } +} /** - * `ReactInstanceMap` maintains a mapping from a public facing stateful - * instance (key) and the internal representation (value). This allows public - * methods to accept the user facing instance as an argument and map them back - * to internal methods. + * Publishes an event so that it can be dispatched by the supplied plugin. * - * Note that this module is currently shared and assumed to be stateless. - * If this becomes an actual Map, that will break. + * @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 */ -/** - * 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 publishEventForPlugin(dispatchConfig, pluginModule, eventName) { + if (!!eventNameDispatchConfigs.hasOwnProperty(eventName)) { + throw Error( + "EventPluginRegistry: More than one plugin attempted to publish the same event name, `" + + eventName + + "`." + ); + } -function get(key) { - return key._reactInternalFiber; -} + eventNameDispatchConfigs[eventName] = dispatchConfig; + var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; -function set(key, value) { - key._reactInternalFiber = value; -} + if (phasedRegistrationNames) { + for (var phaseName in phasedRegistrationNames) { + if (phasedRegistrationNames.hasOwnProperty(phaseName)) { + var phasedRegistrationName = phasedRegistrationNames[phaseName]; + publishRegistrationName( + phasedRegistrationName, + pluginModule, + eventName + ); + } + } -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. + return true; + } else if (dispatchConfig.registrationName) { + publishRegistrationName( + dispatchConfig.registrationName, + pluginModule, + eventName + ); + return true; + } -if (!ReactSharedInternals.hasOwnProperty("ReactCurrentDispatcher")) { - ReactSharedInternals.ReactCurrentDispatcher = { - current: null - }; -} -if (!ReactSharedInternals.hasOwnProperty("ReactCurrentBatchConfig")) { - ReactSharedInternals.ReactCurrentBatchConfig = { - suspense: null - }; + 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 + */ -// 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; -var REACT_FORWARD_REF_TYPE = hasSymbol - ? Symbol.for("react.forward_ref") - : 0xead0; -var REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for("react.suspense") : 0xead1; -var REACT_SUSPENSE_LIST_TYPE = hasSymbol - ? Symbol.for("react.suspense_list") - : 0xead8; -var REACT_MEMO_TYPE = hasSymbol ? Symbol.for("react.memo") : 0xead3; -var REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 0xead4; -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) { - if (maybeIterable === null || typeof maybeIterable !== "object") { - return null; +function publishRegistrationName(registrationName, pluginModule, eventName) { + if (!!registrationNameModules[registrationName]) { + throw Error( + "EventPluginRegistry: More than one plugin attempted to publish the same registration name, `" + + registrationName + + "`." + ); } - var maybeIterator = - (MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL]) || - maybeIterable[FAUX_ITERATOR_SYMBOL]; + registrationNameModules[registrationName] = pluginModule; + registrationNameDependencies[registrationName] = + pluginModule.eventTypes[eventName].dependencies; - if (typeof maybeIterator === "function") { - return maybeIterator; + { + var lowerCasedName = registrationName.toLowerCase(); } - - return null; } +/** + * Registers plugins so that they can extract and dispatch events. + */ /** - * 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. + * Ordered list of injected plugins. */ -var warning = warningWithoutStack$1; +var plugins = []; +/** + * Mapping from event name to dispatch config + */ -{ - warning = function(condition, format) { - if (condition) { - return; - } +var eventNameDispatchConfigs = {}; +/** + * Mapping from registration name to plugin module + */ - var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; - var stack = ReactDebugCurrentFrame.getStackAddendum(); // eslint-disable-next-line react-internal/warning-and-invariant-args +var registrationNameModules = {}; +/** + * Mapping from registration name to event name + */ - for ( - var _len = arguments.length, - args = new Array(_len > 2 ? _len - 2 : 0), - _key = 2; - _key < _len; - _key++ - ) { - args[_key - 2] = arguments[_key]; - } +var registrationNameDependencies = {}; - warningWithoutStack$1.apply( - void 0, - [false, format + "%s"].concat(args, [stack]) - ); - }; -} +/** + * 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 + */ -var warning$1 = warning; +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 Uninitialized = -1; -var Pending = 0; -var Resolved = 1; -var Rejected = 2; -function refineResolvedLazyComponent(lazyComponent) { - return lazyComponent._status === Resolved ? lazyComponent._result : null; + eventPluginOrder = Array.prototype.slice.call(injectedEventPluginOrder); + recomputePluginOrdering(); } -function initializeLazyComponentType(lazyComponent) { - if (lazyComponent._status === Uninitialized) { - lazyComponent._status = Pending; - var ctor = lazyComponent._ctor; - var thenable = ctor(); - lazyComponent._result = thenable; - thenable.then( - function(moduleObject) { - if (lazyComponent._status === Pending) { - var defaultExport = moduleObject.default; +/** + * 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 + */ - { - if (defaultExport === undefined) { - warning$1( - false, - "lazy: Expected the result of a dynamic import() call. " + - "Instead received: %s\n\nYour code should look like: \n " + - "const MyComponent = lazy(() => import('./MyComponent'))", - moduleObject - ); - } - } +function injectEventPluginsByName(injectedNamesToPlugins) { + var isOrderingDirty = false; - lazyComponent._status = Resolved; - lazyComponent._result = defaultExport; - } - }, - function(error) { - if (lazyComponent._status === Pending) { - lazyComponent._status = Rejected; - lazyComponent._result = error; - } - } - ); - } -} + for (var pluginName in injectedNamesToPlugins) { + if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) { + continue; + } -function getWrappedName(outerType, innerType, wrapperName) { - var functionName = innerType.displayName || innerType.name || ""; + 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; + } +}; + +var ReactNativeEventPluginOrder = [ + "ResponderEventPlugin", + "ReactNativeBridgeEventPlugin" +]; + +/** + * Make sure essential globals are available and are patched correctly. Please don't remove this + * line. Bundles created by react-packager `require` it before executing any application code. This + * ensures it exists in the dependency graph and can be `require`d. + * TODO: require this in packager, not in React #10932517 + */ +/** + * Inject module for resolving DOM hierarchy and plugin ordering. + */ + +injectEventPluginOrder(ReactNativeEventPluginOrder); +/** + * Some important event plugins included by default (without having to require + * them). + */ + +injectEventPluginsByName({ + ResponderEventPlugin: ResponderEventPlugin, + ReactNativeBridgeEventPlugin: ReactNativeBridgeEventPlugin +}); + +function getInstanceFromInstance(instanceHandle) { + return instanceHandle; +} + +function getTagFromInstance(inst) { + var nativeInstance = inst.stateNode.canonical; + + if (!nativeInstance._nativeTag) { + throw Error("All native instances should have a tag."); + } + + return nativeInstance; +} +function getFiberCurrentPropsFromNode$1(inst) { + return inst.canonical.currentProps; +} + +// Module provided by RN: +var ReactFabricGlobalResponderHandler = { + onChange: function(from, to, blockNativeResponder) { + if (to !== null) { + var tag = to.stateNode.canonical._nativeTag; + ReactNativePrivateInterface.UIManager.setJSResponder( + tag, + blockNativeResponder + ); + } else { + ReactNativePrivateInterface.UIManager.clearJSResponder(); + } + } +}; + +setComponentTree( + getFiberCurrentPropsFromNode$1, + getInstanceFromInstance, + getTagFromInstance +); +ResponderEventPlugin.injection.injectGlobalResponderHandler( + ReactFabricGlobalResponderHandler +); + +/** + * `ReactInstanceMap` maintains a mapping from a public facing stateful + * instance (key) and the internal representation (value). This allows public + * methods to accept the user facing instance as an argument and map them back + * to internal methods. + * + * Note that this module is currently shared and assumed to be stateless. + * If this becomes an actual Map, that will break. + */ +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 REACT_CONCURRENT_MODE_TYPE = hasSymbol + ? Symbol.for("react.concurrent_mode") + : 0xeacf; +var REACT_FORWARD_REF_TYPE = hasSymbol + ? Symbol.for("react.forward_ref") + : 0xead0; +var REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for("react.suspense") : 0xead1; +var REACT_SUSPENSE_LIST_TYPE = hasSymbol + ? Symbol.for("react.suspense_list") + : 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 MAYBE_ITERATOR_SYMBOL = typeof Symbol === "function" && Symbol.iterator; +var FAUX_ITERATOR_SYMBOL = "@@iterator"; +function getIteratorFn(maybeIterable) { + if (maybeIterable === null || typeof maybeIterable !== "object") { + return null; + } + + var maybeIterator = + (MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL]) || + maybeIterable[FAUX_ITERATOR_SYMBOL]; + + if (typeof maybeIterator === "function") { + return maybeIterator; + } + + return null; +} + +// TODO: Move this to "react" once we can import from externals. +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; + thenable.then( + function(moduleObject) { + if (lazyComponent._status === Pending) { + var defaultExport = moduleObject.default; + + { + if (defaultExport === undefined) { + error( + "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'))", + moduleObject + ); + } + } // Transition to the next state. + + var resolved = lazyComponent; + resolved._status = Resolved; + resolved._result = defaultExport; + } + }, + function(error) { + if (lazyComponent._status === Pending) { + // Transition to the next state. + var rejected = lazyComponent; + rejected._status = Rejected; + rejected._result = error; + } + } + ); + } +} + +function getWrappedName(outerType, innerType, wrapperName) { + var functionName = innerType.displayName || innerType.name || ""; return ( outerType.displayName || (functionName !== "" ? wrapperName + "(" + functionName + ")" : 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") { - warningWithoutStack$1( - false, + error( "Received an unexpected object in getComponentName(). " + "This is likely a bug in React. Please file an issue." ); @@ -2812,10 +2641,12 @@ function getComponentName(type) { if (typeof type === "object") { switch (type.$$typeof) { case REACT_CONTEXT_TYPE: - return "Context.Consumer"; + var context = type; + return getContextName(context) + ".Consumer"; case REACT_PROVIDER_TYPE: - return "Context.Provider"; + var provider = type; + return getContextName(provider._context) + ".Provider"; case REACT_FORWARD_REF_TYPE: return getWrappedName(type, type.render, "ForwardRef"); @@ -2823,6 +2654,9 @@ 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); @@ -2835,6 +2669,7 @@ function getComponentName(type) { } } } + return null; } @@ -2897,7 +2732,10 @@ var ShouldCapture = /* */ 4096; -var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner; +var enableProfilerTimer = true; +var warnAboutStringRefs = false; + +var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner; function getNearestMountedFiber(fiber) { var node = fiber; var nearestMounted = fiber; @@ -2934,28 +2772,28 @@ function getNearestMountedFiber(fiber) { return null; } - function isFiberMounted(fiber) { return getNearestMountedFiber(fiber) === fiber; } function isMounted(component) { { - var owner = ReactCurrentOwner$1.current; + var owner = ReactCurrentOwner.current; if (owner !== null && owner.tag === ClassComponent) { var ownerFiber = owner; var instance = ownerFiber.stateNode; - !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; + + 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 = true; } } @@ -3034,6 +2872,7 @@ function findCurrentFiberUsingSlowPath(fiber) { assertIsMounted(parentA); return fiber; } + if (child === b) { // We've determined that B is the current branch. assertIsMounted(parentA); @@ -3064,6 +2903,7 @@ function findCurrentFiberUsingSlowPath(fiber) { // Search parent A's child set var didFindChild = false; var _child = parentA.child; + while (_child) { if (_child === a) { didFindChild = true; @@ -3071,6 +2911,7 @@ function findCurrentFiberUsingSlowPath(fiber) { b = parentB; break; } + if (_child === b) { didFindChild = true; b = parentA; @@ -3092,6 +2933,7 @@ function findCurrentFiberUsingSlowPath(fiber) { b = parentA; break; } + if (_child === b) { didFindChild = true; b = parentB; @@ -3197,41 +3039,6 @@ 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 = {}; @@ -3272,6 +3079,7 @@ function restoreDeletedValuesInNestedArray( ) { if (Array.isArray(node)) { var i = node.length; + while (i-- && removedKeyCount > 0) { restoreDeletedValuesInNestedArray( updatePayload, @@ -3281,6 +3089,7 @@ function restoreDeletedValuesInNestedArray( } } else if (node && removedKeyCount > 0) { var obj = node; + for (var propKey in removedKeys) { if (!removedKeys[propKey]) { continue; @@ -3293,6 +3102,7 @@ function restoreDeletedValuesInNestedArray( } var attributeConfig = validAttributes[propKey]; + if (!attributeConfig) { continue; // not a valid native prop } @@ -3300,6 +3110,7 @@ function restoreDeletedValuesInNestedArray( if (typeof nextProp === "function") { nextProp = true; } + if (typeof nextProp === "undefined") { nextProp = null; } @@ -3318,6 +3129,7 @@ function restoreDeletedValuesInNestedArray( : nextProp; updatePayload[propKey] = nextValue; } + removedKeys[propKey] = false; removedKeyCount--; } @@ -3344,6 +3156,7 @@ function diffNestedArrayProperty( validAttributes ); } + for (; i < prevArray.length; i++) { // Clear out all remaining properties. updatePayload = clearNestedProperty( @@ -3352,6 +3165,7 @@ function diffNestedArrayProperty( validAttributes ); } + for (; i < nextArray.length; i++) { // Add all remaining properties. updatePayload = addNestedProperty( @@ -3360,6 +3174,7 @@ function diffNestedArrayProperty( validAttributes ); } + return updatePayload; } @@ -3423,6 +3238,7 @@ function diffNestedProperty( * attribute configurations. It processes each prop and adds it to the * updatePayload. */ + function addNestedProperty(updatePayload, nextProp, validAttributes) { if (!nextProp) { return updatePayload; @@ -3448,6 +3264,7 @@ 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; @@ -3534,6 +3351,7 @@ function diffProperties(updatePayload, prevProps, nextProps, validAttributes) { : nextProp; updatePayload[propKey] = nextValue; } + continue; } @@ -3557,11 +3375,13 @@ 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 { @@ -3576,6 +3396,7 @@ function diffProperties(updatePayload, prevProps, nextProps, validAttributes) { nextProp, attributeConfig ); + if (removedKeyCount > 0 && updatePayload) { restoreDeletedValuesInNestedArray( updatePayload, @@ -3654,6 +3475,7 @@ 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); @@ -3677,49 +3499,6 @@ 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 @@ -3729,31 +3508,7 @@ function restoreStateIfNeeded() { 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) { @@ -3768,72 +3523,6 @@ 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( @@ -3843,567 +3532,188 @@ function setBatchingImplementation( _batchedEventUpdatesImpl ) { batchedUpdatesImpl = _batchedUpdatesImpl; - discreteUpdatesImpl = _discreteUpdatesImpl; - flushDiscreteUpdatesImpl = _flushDiscreteUpdatesImpl; - batchedEventUpdatesImpl = _batchedEventUpdatesImpl; } -function _inheritsLoose(subClass, superClass) { - subClass.prototype = Object.create(superClass.prototype); - subClass.prototype.constructor = subClass; - subClass.__proto__ = superClass; -} +/** + * Internal queue of events that have accumulated their dispatches and are + * waiting to have their dispatches executed. + */ +var eventQueue = null; /** - * Class only exists for its Flow type. + * Dispatches an event and releases it back into the pool, unless persistent. + * + * @param {?object} event Synthetic event to be dispatched. + * @private */ -var ReactNativeComponent = - /*#__PURE__*/ - (function(_React$Component) { - _inheritsLoose(ReactNativeComponent, _React$Component); - function ReactNativeComponent() { - return _React$Component.apply(this, arguments) || this; - } +var executeDispatchesAndRelease = function(event) { + if (event) { + executeDispatchesInOrder(event); - var _proto = ReactNativeComponent.prototype; + if (!event.isPersistent()) { + event.constructor.release(event); + } + } +}; - _proto.blur = function blur() {}; +var executeDispatchesAndReleaseTopLevel = function(e) { + return executeDispatchesAndRelease(e); +}; - _proto.focus = function focus() {}; +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.measure = function measure(callback) {}; + var processingEventQueue = eventQueue; + eventQueue = null; - _proto.measureInWindow = function measureInWindow(callback) {}; + if (!processingEventQueue) { + return; + } - _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; - } + forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseTopLevel); - case UserBlockingEvent: { - runWithPriority(UserBlockingPriority, function() { - return executeUserEventHandler(eventListener, eventValue); - }); - break; - } + 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. - case ContinuousEvent: { - executeUserEventHandler(eventListener, eventValue); - break; - } - } - }, - isTargetWithinNode: function(childTarget, parentTarget) { - validateResponderContext(); - var childFiber = getFiberFromTarget(childTarget); - var parentFiber = getFiberFromTarget(parentTarget); - var node = childFiber; + rethrowCaughtError(); +} - while (node !== null) { - if (node === parentFiber) { - return true; - } +/** + * Allows registered plugins an opportunity to extract events from top-level + * native browser events. + * + * @return {*} An accumulation of synthetic events. + * @internal + */ - node = node.return; - } +function extractPluginEvents( + topLevelType, + targetInst, + nativeEvent, + nativeEventTarget, + eventSystemFlags +) { + var events = null; - 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 < plugins.length; i++) { + // Not every plugin in the ordering may be loaded at runtime. + var possiblePlugin = plugins[i]; - for (var i = 0; i < rootEventTypes.length; i++) { - var rootEventType = rootEventTypes[i]; - var rootEventResponders = rootEventTypesToEventResponderInstances.get( - rootEventType + if (possiblePlugin) { + var extractedEvents = possiblePlugin.extractEvents( + topLevelType, + targetInst, + nativeEvent, + nativeEventTarget, + eventSystemFlags ); - var rootEventTypesSet = currentInstance.rootEventTypes; - - if (rootEventTypesSet !== null) { - rootEventTypesSet.delete(rootEventType); - } - if (rootEventResponders !== undefined) { - rootEventResponders.delete(currentInstance); + if (extractedEvents) { + events = accumulateInto(events, extractedEvents); } } - }, - getTimeStamp: function() { - validateResponderContext(); - return currentTimeStamp; - }, - getResponderNode: function() { - validateResponderContext(); - var responderFiber = currentInstance.fiber; - - if (responderFiber.tag === ScopeComponent) { - return null; - } - - return responderFiber.stateNode; } -}; - -function validateEventValue(eventValue) { - if (typeof eventValue === "object" && eventValue !== null) { - var target = eventValue.target, - type = eventValue.type, - timeStamp = eventValue.timeStamp; - 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 + return events; +} - Object.defineProperty(eventValue, "nativeEvent", { - get: function() { - { - showWarning("nativeEvent"); - } - } - }); - } +function runExtractedPluginEventsInBatch( + topLevelType, + targetInst, + nativeEvent, + nativeEventTarget, + eventSystemFlags +) { + var events = extractPluginEvents( + topLevelType, + targetInst, + nativeEvent, + nativeEventTarget, + eventSystemFlags + ); + runEventsInBatch(events); } -function getFiberFromTarget(target) { - if (target === null) { - return null; +function dispatchEvent(target, topLevelType, nativeEvent) { + var targetFiber = target; + var eventTarget = null; + + if (targetFiber != null) { + var stateNode = targetFiber.stateNode; // Guard against Fiber being unmounted + + if (stateNode != null) { + eventTarget = stateNode.canonical; + } } - return target.canonical._internalInstanceHandle || null; + batchedUpdates(function() { + // Heritage plugin event system + runExtractedPluginEventsInBatch( + topLevelType, + targetFiber, + nativeEvent, + eventTarget, + PLUGIN_EVENT_SYSTEM + ); + }); // React Native doesn't use ReactControlledComponent but if it did, here's + // where it would do it. } -function createFabricResponderEvent(topLevelType, nativeEvent, target) { - return { - nativeEvent: nativeEvent, - target: target, - type: topLevelType - }; -} +// can re-export everything from this module. -function validateResponderContext() { - if (!currentInstance) { +function shim() { + { throw Error( - "An event responder context was used outside of an event cycle." + "The current renderer does not support mutation. This error is likely caused by a bug in React. Please file an issue." ); } -} // TODO this function is almost an exact copy of the DOM version, we should -// somehow share the logic +} // Mutation (when unsupported) -function responderEventTypesContainType(eventTypes, type) { - for (var i = 0, len = eventTypes.length; i < len; i++) { - if (eventTypes[i] === type) { - return true; - } - } - return false; -} +var supportsMutation = false; +var commitMount = shim; -function validateResponderTargetEventTypes(eventType, responder) { - var targetEventTypes = responder.targetEventTypes; // Validate the target event type exists on the responder +// can re-export everything from this module. - if (targetEventTypes !== null) { - return responderEventTypesContainType(targetEventTypes, eventType); +function shim$1() { + { + throw Error( + "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." + ); } +} // Hydration (when unsupported) +var isSuspenseInstancePending = shim$1; +var isSuspenseInstanceFallback = shim$1; +var hydrateTextInstance = shim$1; - 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, - targetFiber !== null ? targetFiber.stateNode : null - ); - var visitedResponders = new Set(); - var node = targetFiber; - while (node !== null) { - var _node = node, - dependencies = _node.dependencies, - tag = _node.tag; +var _nativeFabricUIManage = nativeFabricUIManager, + createNode = _nativeFabricUIManage.createNode, + cloneNode = _nativeFabricUIManage.cloneNode, + cloneNodeWithNewChildren = _nativeFabricUIManage.cloneNodeWithNewChildren, + cloneNodeWithNewChildrenAndProps = + _nativeFabricUIManage.cloneNodeWithNewChildrenAndProps, + cloneNodeWithNewProps = _nativeFabricUIManage.cloneNodeWithNewProps, + createChildNodeSet = _nativeFabricUIManage.createChildSet, + appendChildNode = _nativeFabricUIManage.appendChild, + appendChildNodeToSet = _nativeFabricUIManage.appendChildToSet, + completeRoot = _nativeFabricUIManage.completeRoot, + registerEventHandler = _nativeFabricUIManage.registerEventHandler, + fabricMeasure = _nativeFabricUIManage.measure, + fabricMeasureInWindow = _nativeFabricUIManage.measureInWindow, + fabricMeasureLayout = _nativeFabricUIManage.measureLayout; +var getViewConfigForType = + ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get; // Counter for uniquely identifying views. +// % 10 === 1 means it is a rootTag. +// % 2 === 0 means it is a Fabric tag. +// This means that they never overlap. - 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; - if (enableFlareAPI) { - // React Flare event system - dispatchEventForResponderEventSystem(topLevelType, target, nativeEvent); - } - - var eventTarget = null; - - if (enableNativeTargetAsInstance) { - if (targetFiber != null) { - eventTarget = targetFiber.stateNode.canonical; - } - } else { - eventTarget = nativeEvent.target; - } - - batchedUpdates(function() { - // Heritage plugin event system - runExtractedPluginEventsInBatch( - topLevelType, - targetFiber, - nativeEvent, - eventTarget, - PLUGIN_EVENT_SYSTEM - ); - }); // React Native doesn't use ReactControlledComponent but if it did, here's - // where it would do it. -} - -// can re-export everything from this module. - -function shim() { - { - throw Error( - "The current renderer does not support mutation. This error is likely caused by a bug in React. Please file an issue." - ); - } -} // Mutation (when unsupported) - -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. - -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 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 _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. -// % 2 === 0 means it is a Fabric tag. -// This means that they never overlap. - -var nextReactTag = 2; +var nextReactTag = 2; // TODO: Remove this conditional once all changes have propagated. if (registerEventHandler) { @@ -4434,13 +3744,11 @@ var ReactFabricHostComponent = var _proto = ReactFabricHostComponent.prototype; _proto.blur = function blur() { - ReactNativePrivateInterface.TextInputState.blurTextInput(this._nativeTag); + ReactNativePrivateInterface.TextInputState.blurTextInput(this); }; _proto.focus = function focus() { - ReactNativePrivateInterface.TextInputState.focusTextInput( - this._nativeTag - ); + ReactNativePrivateInterface.TextInputState.focusTextInput(this); }; _proto.measure = function measure(callback) { @@ -4467,10 +3775,12 @@ var ReactFabricHostComponent = typeof relativeToNativeNode === "number" || !(relativeToNativeNode instanceof ReactFabricHostComponent) ) { - warningWithoutStack$1( - false, - "Warning: ref.measureLayout must be called with a ref to a native component." - ); + { + error( + "Warning: ref.measureLayout must be called with a ref to a native component." + ); + } + return; } @@ -4483,16 +3793,15 @@ var ReactFabricHostComponent = }; _proto.setNativeProps = function setNativeProps(nativeProps) { - warningWithoutStack$1( - false, - "Warning: setNativeProps is not currently supported in Fabric" - ); + { + error("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); } @@ -4561,15 +3870,6 @@ function createTextInstance( node: node }; } -function finalizeInitialChildren( - parentInstance, - type, - props, - rootContainerInstance, - hostContext -) { - return false; -} function getRootHostContext(rootContainerInstance) { return { isInAParentText: false @@ -4629,17 +3929,9 @@ 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, @@ -4666,6 +3958,7 @@ function cloneInstance( clone = cloneNodeWithNewChildren(node); } } + return { node: clone, canonical: instance.canonical @@ -4700,194 +3993,108 @@ function finalizeContainerChildren(container, newChildren) { completeRoot(container, newChildren); } -function mountResponderInstance( - responder, - responderInstance, - props, - state, - instance -) { - if (enableFlareAPI) { - var rootEventTypes = responder.rootEventTypes; - - if (rootEventTypes !== null) { - addRootEventTypesForResponderInstance(responderInstance, rootEventTypes); - } +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); - 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."); -} + for (var typeSpecName in typeSpecs) { + if (has(typeSpecs, typeSpecName)) { + var error$1 = void 0; // Prop type validation may throw. In case they do, we don't want to + // fail the render phase where it didn't fail before. So we log it. + // After these have been cleaned up, we'll let them throw. -var BEFORE_SLASH_RE = /^(.*)[\\\/]/; -var describeComponentFrame = function(name, source, ownerName) { - var sourceInfo = ""; + 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 (source) { - var path = source.fileName; - var fileName = path.replace(BEFORE_SLASH_RE, ""); + error$1 = typeSpecs[typeSpecName]( + values, + typeSpecName, + componentName, + location, + null, + "SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED" + ); + } catch (ex) { + error$1 = ex; + } - { - // 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 (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 (match) { - var pathBeforeSlash = match[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; - if (pathBeforeSlash) { - var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, ""); - fileName = folderName + "/" + fileName; - } + error("Failed %s type: %s", location, error$1.message); } } } - sourceInfo = " (at " + fileName + ":" + source.lineNumber + ")"; - } else if (ownerName) { - sourceInfo = " (created by " + ownerName + ")"; } - return "\n in " + (name || "Unknown") + sourceInfo; -}; +} -var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; +// 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? -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 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). - if (owner) { - ownerName = getComponentName(owner.type); - } +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. - 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. +var isCommitting = false; +var hasScheduledUpdateInCurrentCommit = false; +var hasScheduledUpdateInCurrentPhase = false; +var commitCountInCurrentWorkLoop = 0; +var effectCountInCurrentCommit = 0; +// to avoid stretch the commit phase with measurement overhead. var labelsInCurrentCommit = new Set(); @@ -4988,6 +4195,7 @@ var shouldIgnoreFiber = function(fiber) { case ContextConsumer: case Mode: return true; + default: return false; } @@ -4997,6 +4205,7 @@ var clearPendingPhaseMeasurement = function() { if (currentPhase !== null && currentPhaseFiber !== null) { clearFiberMark(currentPhaseFiber, currentPhase); } + currentPhaseFiber = null; currentPhase = null; hasScheduledUpdateInCurrentPhase = false; @@ -5006,10 +4215,12 @@ 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; } }; @@ -5018,6 +4229,7 @@ var resumeTimersRecursively = function(fiber) { if (fiber.return !== null) { resumeTimersRecursively(fiber.return); } + if (fiber._debugIsCurrentlyTiming) { beginFiberMark(fiber, null); } @@ -5031,15 +4243,16 @@ var resumeTimers = function() { }; function recordEffect() { - if (enableUserTimingAPI) { + { effectCountInCurrentCommit++; } } function recordScheduleUpdate() { - if (enableUserTimingAPI) { + { if (isCommitting) { hasScheduledUpdateInCurrentCommit = true; } + if ( currentPhase !== null && currentPhase !== "componentWillMount" && @@ -5049,9 +4262,8 @@ function recordScheduleUpdate() { } } } - function startWorkTimer(fiber) { - if (enableUserTimingAPI) { + { if (!supportsUserTiming || shouldIgnoreFiber(fiber)) { return; } // If we pause, this is the fiber to unwind from. @@ -5066,7 +4278,7 @@ function startWorkTimer(fiber) { } } function cancelWorkTimer(fiber) { - if (enableUserTimingAPI) { + { if (!supportsUserTiming || shouldIgnoreFiber(fiber)) { return; } // Remember we shouldn't complete measurement for this fiber. @@ -5077,7 +4289,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. @@ -5093,7 +4305,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. @@ -5113,7 +4325,7 @@ function stopFailedWorkTimer(fiber) { } } function startPhaseTimer(fiber, phase) { - if (enableUserTimingAPI) { + { if (!supportsUserTiming) { return; } @@ -5129,22 +4341,24 @@ 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) { @@ -5160,7 +4374,7 @@ function startWorkLoopTimer(nextUnitOfWork) { } } function stopWorkLoopTimer(interruptedBy, didCompleteRoot) { - if (enableUserTimingAPI) { + { if (!supportsUserTiming) { return; } @@ -5189,10 +4403,11 @@ function stopWorkLoopTimer(interruptedBy, didCompleteRoot) { } } function startCommitTimer() { - if (enableUserTimingAPI) { + { if (!supportsUserTiming) { return; } + isCommitting = true; hasScheduledUpdateInCurrentCommit = false; labelsInCurrentCommit.clear(); @@ -5200,17 +4415,19 @@ 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; @@ -5219,19 +4436,21 @@ 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( @@ -5242,19 +4461,21 @@ 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( @@ -5265,19 +4486,21 @@ 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( @@ -5306,14 +4529,15 @@ function createCursor(defaultValue) { function pop(cursor, fiber) { if (index < 0) { { - warningWithoutStack$1(false, "Unexpected pop."); + error("Unexpected pop."); } + return; } { if (fiber !== fiberStack[index]) { - warningWithoutStack$1(false, "Unexpected Fiber popped."); + error("Unexpected Fiber popped."); } } @@ -5363,9 +4587,7 @@ 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 @@ -5373,14 +4595,13 @@ 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; @@ -5388,9 +4609,7 @@ function cacheContext(workInProgress, unmaskedContext, maskedContext) { } function getMaskedContext(workInProgress, unmaskedContext) { - if (disableLegacyContext) { - return emptyContextObject; - } else { + { var type = workInProgress.type; var contextTypes = type.contextTypes; @@ -5410,19 +4629,14 @@ 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, - getCurrentFiberStackInDev - ); + checkPropTypes(contextTypes, context, "context", name); } // Cache unmasked context so we can avoid recreating masked context unless necessary. // Context is created before the class component is instantiated so check for instance. @@ -5435,44 +4649,34 @@ 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." @@ -5485,9 +4689,7 @@ 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. @@ -5498,8 +4700,8 @@ function processChildContext(fiber, type, parentContext) { if (!warnedAboutMissingGetChildContext[componentName]) { warnedAboutMissingGetChildContext[componentName] = true; - warningWithoutStack$1( - false, + + error( "%s.childContextTypes is specified but there is no getChildContext() method " + "on the instance. You can either define getChildContext() on %s or remove " + "childContextTypes from it.", @@ -5513,19 +4715,10 @@ 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( @@ -5539,17 +4732,7 @@ function processChildContext(fiber, type, parentContext) { { var name = getComponentName(type) || "Unknown"; - 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 - ); + checkPropTypes(childContextTypes, childContext, "child context", name); } return Object.assign({}, parentContext, {}, childContext); @@ -5557,9 +4740,7 @@ 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. @@ -5581,9 +4762,7 @@ function pushContextProvider(workInProgress) { } function invalidateContextProvider(workInProgress, type, didChange) { - if (disableLegacyContext) { - return; - } else { + { var instance = workInProgress.stateNode; if (!instance) { @@ -5617,9 +4796,7 @@ 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)) { @@ -5662,22 +4839,21 @@ var BlockingRoot = 1; var ConcurrentRoot = 2; // Intentionally not named imports because Rollup would use dynamic dispatch for -// 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) { +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; + +{ // Provide explicit error message when production+profiling bundle of e.g. // react-dom is used with production (non-profiling) bundle of // scheduler/tracing @@ -5698,7 +4874,7 @@ var fakeCallbackNode = {}; // Except for NoPriority, these correspond to Schedul // avoid clashing with Scheduler's priorities. var ImmediatePriority = 99; -var UserBlockingPriority$1 = 98; +var UserBlockingPriority = 98; var NormalPriority = 97; var LowPriority = 96; var IdlePriority = 95; // NoPriority is the absence of priority. Also React-only. @@ -5717,6 +4893,7 @@ 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 @@ -5729,7 +4906,7 @@ function getCurrentPriorityLevel() { return ImmediatePriority; case Scheduler_UserBlockingPriority: - return UserBlockingPriority$1; + return UserBlockingPriority; case Scheduler_NormalPriority: return NormalPriority; @@ -5751,7 +4928,7 @@ function reactPriorityToSchedulerPriority(reactPriorityLevel) { case ImmediatePriority: return Scheduler_ImmediatePriority; - case UserBlockingPriority$1: + case UserBlockingPriority: return Scheduler_UserBlockingPriority; case NormalPriority: @@ -5769,7 +4946,7 @@ function reactPriorityToSchedulerPriority(reactPriorityLevel) { } } -function runWithPriority$1(reactPriorityLevel, fn) { +function runWithPriority(reactPriorityLevel, fn) { var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); return Scheduler_runWithPriority(priorityLevel, fn); } @@ -5815,12 +4992,14 @@ function flushSyncCallbackQueueImpl() { // Prevent re-entrancy. isFlushingSyncQueue = true; var i = 0; + try { var _isSync = true; var queue = syncQueue; - runWithPriority$1(ImmediatePriority, function() { + runWithPriority(ImmediatePriority, function() { for (; i < queue.length; i++) { var callback = queue[i]; + do { callback = callback(_isSync); } while (callback !== null); @@ -5868,14 +5047,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 a moving priority. It is slightly higher than Idle +var Idle = 2; // Continuous Hydration is slightly higher than Idle and is used to increase 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 add an offset so that we don't clash with the magic number for NoWork. + // Always subtract from the offset so that we don't clash with the magic number for NoWork. return MAGIC_NUMBER_OFFSET - ((ms / UNIT_SIZE) | 0); } function expirationTimeToMs(expirationTime) { @@ -5934,7 +5113,6 @@ function computeInteractiveExpiration(currentTime) { HIGH_PRIORITY_BATCH_SIZE ); } - function inferPriorityFromExpirationTime(currentTime, expirationTime) { if (expirationTime === Sync) { return ImmediatePriority; @@ -5952,7 +5130,7 @@ function inferPriorityFromExpirationTime(currentTime, expirationTime) { } if (msUntil <= HIGH_PRIORITY_EXPIRATION + HIGH_PRIORITY_BATCH_SIZE) { - return UserBlockingPriority$1; + return UserBlockingPriority; } if (msUntil <= LOW_PRIORITY_EXPIRATION + LOW_PRIORITY_BATCH_SIZE) { @@ -5973,7 +5151,7 @@ function is(x, y) { ); } -var is$1 = typeof Object.is === "function" ? Object.is : is; +var objectIs = typeof Object.is === "function" ? Object.is : is; var hasOwnProperty = Object.prototype.hasOwnProperty; /** @@ -5983,7 +5161,7 @@ var hasOwnProperty = Object.prototype.hasOwnProperty; */ function shallowEqual(objA, objB) { - if (is$1(objA, objB)) { + if (objectIs(objA, objB)) { return true; } @@ -6006,7 +5184,7 @@ function shallowEqual(objA, objB) { for (var i = 0; i < keysA.length; i++) { if ( !hasOwnProperty.call(objB, keysA[i]) || - !is$1(objA[keysA[i]], objB[keysA[i]]) + !objectIs(objA[keysA[i]], objB[keysA[i]]) ) { return false; } @@ -6015,95 +5193,141 @@ function shallowEqual(objA, objB) { return true; } -/** - * 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() {}; - -{ - 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]; - } +var BEFORE_SLASH_RE = /^(.*)[\\\/]/; +function describeComponentFrame(name, source, ownerName) { + var sourceInfo = ""; - var argIndex = 0; - var message = - "Warning: " + - format.replace(/%s/g, function() { - return args[argIndex++]; - }); + if (source) { + var path = source.fileName; + var fileName = path.replace(BEFORE_SLASH_RE, ""); - if (typeof console !== "undefined") { - console.warn(message); - } + { + // 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 { - // --- 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 (match) { + var pathBeforeSlash = match[1]; - lowPriorityWarningWithoutStack = function(condition, format) { - if (format === undefined) { - throw new Error( - "`lowPriorityWarningWithoutStack(condition, format, ...args)` requires a warning " + - "message argument" - ); + if (pathBeforeSlash) { + var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, ""); + fileName = folderName + "/" + fileName; + } + } + } } - 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]; - } + sourceInfo = " (at " + fileName + ":" + source.lineNumber + ")"; + } else if (ownerName) { + sourceInfo = " (created by " + ownerName + ")"; + } - printWarning.apply(void 0, [format].concat(args)); - } - }; + return "\n in " + (name || "Unknown") + sourceInfo; } -var lowPriorityWarningWithoutStack$1 = lowPriorityWarningWithoutStack; +var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; -var ReactStrictModeWarnings = { - recordUnsafeLifecycleWarnings: function(fiber, instance) {}, - flushPendingUnsafeLifecycleWarnings: function() {}, - recordLegacyContextWarning: function(fiber, instance) {}, - flushLegacyContextWarning: function() {}, - discardPendingWarnings: function() {} -}; +function describeFiber(fiber) { + switch (fiber.tag) { + case HostRoot: + case HostPortal: + case HostText: + case Fragment: + case ContextProvider: + case ContextConsumer: + return ""; -{ - var findStrictRoot = function(fiber) { - var maybeStrictRoot = null; - var node = fiber; + 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 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 ReactStrictModeWarnings = { + recordUnsafeLifecycleWarnings: function(fiber, instance) {}, + flushPendingUnsafeLifecycleWarnings: function() {}, + recordLegacyContextWarning: function(fiber, instance) {}, + flushLegacyContextWarning: function() {}, + discardPendingWarnings: function() {} +}; + +{ + var findStrictRoot = function(fiber) { + var maybeStrictRoot = null; + var node = fiber; + + while (node !== null) { + if (node.mode & StrictMode) { + maybeStrictRoot = node; + } - while (node !== null) { - if (node.mode & StrictMode) { - maybeStrictRoot = node; - } node = node.return; } @@ -6182,6 +5406,7 @@ 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( @@ -6193,6 +5418,7 @@ var ReactStrictModeWarnings = { } var UNSAFE_componentWillMountUniqueNames = new Set(); + if (pendingUNSAFE_ComponentWillMountWarnings.length > 0) { pendingUNSAFE_ComponentWillMountWarnings.forEach(function(fiber) { UNSAFE_componentWillMountUniqueNames.add( @@ -6204,6 +5430,7 @@ var ReactStrictModeWarnings = { } var componentWillReceivePropsUniqueNames = new Set(); + if (pendingComponentWillReceivePropsWarnings.length > 0) { pendingComponentWillReceivePropsWarnings.forEach(function(fiber) { componentWillReceivePropsUniqueNames.add( @@ -6215,6 +5442,7 @@ var ReactStrictModeWarnings = { } var UNSAFE_componentWillReceivePropsUniqueNames = new Set(); + if (pendingUNSAFE_ComponentWillReceivePropsWarnings.length > 0) { pendingUNSAFE_ComponentWillReceivePropsWarnings.forEach(function(fiber) { UNSAFE_componentWillReceivePropsUniqueNames.add( @@ -6226,6 +5454,7 @@ var ReactStrictModeWarnings = { } var componentWillUpdateUniqueNames = new Set(); + if (pendingComponentWillUpdateWarnings.length > 0) { pendingComponentWillUpdateWarnings.forEach(function(fiber) { componentWillUpdateUniqueNames.add( @@ -6237,6 +5466,7 @@ var ReactStrictModeWarnings = { } var UNSAFE_componentWillUpdateUniqueNames = new Set(); + if (pendingUNSAFE_ComponentWillUpdateWarnings.length > 0) { pendingUNSAFE_ComponentWillUpdateWarnings.forEach(function(fiber) { UNSAFE_componentWillUpdateUniqueNames.add( @@ -6250,8 +5480,8 @@ var ReactStrictModeWarnings = { if (UNSAFE_componentWillMountUniqueNames.size > 0) { var sortedNames = setToSortedString(UNSAFE_componentWillMountUniqueNames); - warningWithoutStack$1( - false, + + error( "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" + @@ -6264,8 +5494,8 @@ var ReactStrictModeWarnings = { var _sortedNames = setToSortedString( UNSAFE_componentWillReceivePropsUniqueNames ); - warningWithoutStack$1( - false, + + error( "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" + @@ -6282,8 +5512,8 @@ var ReactStrictModeWarnings = { var _sortedNames2 = setToSortedString( UNSAFE_componentWillUpdateUniqueNames ); - warningWithoutStack$1( - false, + + error( "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" + @@ -6296,8 +5526,7 @@ var ReactStrictModeWarnings = { if (componentWillMountUniqueNames.size > 0) { var _sortedNames3 = setToSortedString(componentWillMountUniqueNames); - lowPriorityWarningWithoutStack$1( - false, + warn( "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" + @@ -6315,8 +5544,7 @@ var ReactStrictModeWarnings = { componentWillReceivePropsUniqueNames ); - lowPriorityWarningWithoutStack$1( - false, + warn( "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" + @@ -6335,8 +5563,7 @@ var ReactStrictModeWarnings = { if (componentWillUpdateUniqueNames.size > 0) { var _sortedNames5 = setToSortedString(componentWillUpdateUniqueNames); - lowPriorityWarningWithoutStack$1( - false, + warn( "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" + @@ -6359,12 +5586,13 @@ var ReactStrictModeWarnings = { instance ) { var strictRoot = findStrictRoot(fiber); + if (strictRoot === null) { - warningWithoutStack$1( - false, + error( "Expected to find a StrictMode component in a strict mode tree. " + "This error is likely caused by a bug in React. Please file an issue." ); + return; } // Dedup strategy: Warn once per component. @@ -6383,21 +5611,27 @@ 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 strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot); - warningWithoutStack$1( - false, + var firstComponentStack = getStackByFiberInDevAndProd(firstFiber); + + error( "Legacy context API has been detected within a strict-mode tree." + "\n\nThe old API will be supported in all 16.x releases, but applications " + "using it should migrate to the new version." + @@ -6405,7 +5639,7 @@ var ReactStrictModeWarnings = { "\n\nLearn more about this warning here: https://fb.me/react-legacy-context" + "%s", sortedNames, - strictRootComponentStack + firstComponentStack ); }); }; @@ -6469,6 +5703,7 @@ 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, @@ -6562,6 +5797,7 @@ 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; } @@ -6646,9 +5882,6 @@ function scheduleFibersWithFamiliesRecursively( case ForwardRef: candidateType = type.render; break; - - default: - break; } if (resolveFamily === null) { @@ -6673,6 +5906,7 @@ function scheduleFibersWithFamiliesRecursively( } } } + if (failedBoundaries !== null) { if ( failedBoundaries.has(fiber) || @@ -6697,6 +5931,7 @@ function scheduleFibersWithFamiliesRecursively( staleFamilies ); } + if (sibling !== null) { scheduleFibersWithFamiliesRecursively( sibling, @@ -6746,12 +5981,10 @@ function findHostInstancesForMatchingFibersRecursively( case ForwardRef: candidateType = type.render; break; - - default: - break; } var didMatch = false; + if (candidateType !== null) { if (types.has(candidateType)) { didMatch = true; @@ -6825,6 +6058,7 @@ function findChildHostInstancesForFiberShallowly(fiber, hostInstances) { { var node = fiber; var foundHostInstances = false; + while (true) { if (node.tag === HostComponent) { // We got a match. @@ -6852,6 +6086,7 @@ function findChildHostInstancesForFiberShallowly(fiber, hostInstances) { node = node.sibling; } } + return false; } @@ -6860,6 +6095,7 @@ 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]; @@ -6899,6 +6135,7 @@ function resetContextDependencies() { currentlyRenderingFiber = null; lastContextDependency = null; lastContextWithAllBitsObserved = null; + { isDisallowedContextReadInDEV = false; } @@ -6916,40 +6153,22 @@ 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; { - !( - 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; + if ( + context._currentRenderer2 !== undefined && + context._currentRenderer2 !== null && + context._currentRenderer2 !== rendererSigil + ) { + error( + "Detected multiple renderers concurrently rendering the " + + "same context provider. This is currently unsupported." + ); + } + context._currentRenderer2 = rendererSigil; } } @@ -6959,14 +6178,12 @@ 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 (is$1(oldValue, newValue)) { + if (objectIs(oldValue, newValue)) { // No change return 0; } else { @@ -6976,14 +6193,13 @@ function calculateChangedBits(context, newValue, oldValue) { : MAX_SIGNED_31_BIT_INT; { - !((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; + if ((changedBits & MAX_SIGNED_31_BIT_INT) !== changedBits) { + error( + "calculateChangedBits: Expected the return value to be a " + + "31-bit integer. Instead received: %s", + changedBits + ); + } } return changedBits | 0; @@ -7027,6 +6243,7 @@ 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; @@ -7087,39 +6304,6 @@ 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; @@ -7131,6 +6315,7 @@ 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. @@ -7177,22 +6362,19 @@ 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. - !!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 (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()." + ); + } } - 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 { + if (lastContextWithAllBitsObserved === context); + else if (observedBits === false || observedBits === 0); + else { var resolvedObservedBits; // Avoid deopting on observable arguments or heterogeneous types. if ( @@ -7230,85 +6412,10 @@ function readContext(context, observedBits) { lastContextDependency = lastContextDependency.next = contextItem; } } - return isPrimaryRenderer ? context._currentValue : context._currentValue2; + + return 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; @@ -7325,38 +6432,32 @@ var currentlyProcessingQueue; currentlyProcessingQueue = null; } -function createUpdateQueue(baseState) { - var queue = { - baseState: baseState, - firstUpdate: null, - lastUpdate: null, - firstCapturedUpdate: null, - lastCapturedUpdate: null, - firstEffect: null, - lastEffect: null, - firstCapturedEffect: null, - lastCapturedEffect: null - }; - return queue; -} - -function cloneUpdateQueue(currentQueue) { +function initializeUpdateQueue(fiber) { 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 + baseState: fiber.memoizedState, + baseQueue: null, + shared: { + pending: null + }, + effects: null }; - return queue; + 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; + } } - function createUpdate(expirationTime, suspenseConfig) { var update = { expirationTime: expirationTime, @@ -7364,9 +6465,9 @@ function createUpdate(expirationTime, suspenseConfig) { tag: UpdateState, payload: null, callback: null, - next: null, - nextEffect: null + next: null }; + update.next = update; { update.priority = getCurrentPriorityLevel(); @@ -7374,130 +6475,62 @@ function createUpdate(expirationTime, suspenseConfig) { return update; } +function enqueueUpdate(fiber, update) { + var updateQueue = fiber.updateQueue; -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; + if (updateQueue === null) { + // Only occurs if the fiber has been unmounted. + return; } -} -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 (queue1 === null) { - queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState); - } + if (pending === null) { + // This is the first update. Create a circular list. + update.next = update; } else { - // 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. - } - } + update.next = pending.next; + pending.next = 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; - } - } + sharedQueue.pending = update; { if ( - fiber.tag === ClassComponent && - (currentlyProcessingQueue === queue1 || - (queue2 !== null && currentlyProcessingQueue === queue2)) && + currentlyProcessingQueue === sharedQueue && !didWarnUpdateInsideUpdate ) { - warningWithoutStack$1( - false, + error( "An update (setState, replaceState, or forceUpdate) was scheduled " + "from inside an update function. Update functions should be pure, " + "with zero side-effects. Consider using componentDidUpdate or a " + "callback." ); + didWarnUpdateInsideUpdate = true; } } } function enqueueCapturedUpdate(workInProgress, update) { - // 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 (workInProgressQueue.lastCapturedUpdate === null) { - // This is the first render phase update - workInProgressQueue.firstCapturedUpdate = workInProgressQueue.lastCapturedUpdate = update; - } else { - 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); - } + // 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; + + if (last === null) { + queue.baseQueue = update.next = update; + update.next = update; + } else { + update.next = last.next; + last.next = update; } - return queue; } function getStateFromUpdate( @@ -7516,13 +6549,6 @@ function getStateFromUpdate( // Updater function { enterDisallowedContextReadInDEV(); - - if ( - debugRenderPhaseSideEffectsForStrictMode && - workInProgress.mode & StrictMode - ) { - payload.call(instance, prevState, nextProps); - } } var nextState = payload.call(instance, prevState, nextProps); @@ -7551,13 +6577,6 @@ function getStateFromUpdate( // Updater function { enterDisallowedContextReadInDEV(); - - if ( - debugRenderPhaseSideEffectsForStrictMode && - workInProgress.mode & StrictMode - ) { - _payload.call(instance, prevState, nextProps); - } } partialState = _payload.call(instance, prevState, nextProps); @@ -7583,164 +6602,176 @@ 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; - } // These values may change as we process the 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. - var newBaseState = queue.baseState; - var newFirstUpdate = null; - var newExpirationTime = NoWork; // Iterate through the list of updates to compute the result. + var pendingQueue = queue.shared.pending; - var update = queue.firstUpdate; - var resultState = newBaseState; + 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; + } - while (update !== null) { - var updateExpirationTime = update.expirationTime; + baseQueue = pendingQueue; + queue.shared.pending = null; // TODO: Pass `current` as argument - 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. + var current = workInProgress.alternate; - newBaseState = resultState; - } // Since this update will remain in the list, update the remaining - // expiration time. + if (current !== null) { + var currentQueue = current.updateQueue; - if (newExpirationTime < updateExpirationTime) { - newExpirationTime = updateExpirationTime; + if (currentQueue !== null) { + currentQueue.baseQueue = pendingQueue; } - } 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; + } + } // These values may change as we process the queue. - if (callback !== null) { - workInProgress.effectTag |= Callback; // Set this to null, in case it was mutated during an aborted render. + if (baseQueue !== null) { + var first = baseQueue.next; // Iterate through the list of updates to compute the result. - update.nextEffect = null; + var newState = queue.baseState; + var newExpirationTime = NoWork; + var newBaseState = null; + var newBaseQueueFirst = null; + var newBaseQueueLast = null; - if (queue.lastEffect === null) { - queue.firstEffect = queue.lastEffect = update; - } else { - queue.lastEffect.nextEffect = update; - queue.lastEffect = update; - } - } - } // Continue to the next update. + if (first !== null) { + var update = first; - update = update.next; - } // Separately, iterate though the list of captured updates. + 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 + }; - var newFirstCapturedUpdate = null; - update = queue.firstCapturedUpdate; + if (newBaseQueueLast === null) { + newBaseQueueFirst = newBaseQueueLast = clone; + newBaseState = newState; + } else { + newBaseQueueLast = newBaseQueueLast.next = clone; + } // Update the remaining priority in the queue. - while (update !== null) { - var _updateExpirationTime = update.expirationTime; + 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; - 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 (callback !== null) { + workInProgress.effectTag |= Callback; + var effects = queue.effects; - if (newFirstUpdate === null) { - newBaseState = resultState; + if (effects === null) { + queue.effects = [update]; + } else { + effects.push(update); + } + } } - } // 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; - if (_callback !== null) { - workInProgress.effectTag |= Callback; // Set this to null, in case it was mutated during an aborted render. + update = update.next; - update.nextEffect = null; + if (update === null || update === first) { + pendingQueue = queue.shared.pending; - if (queue.lastCapturedEffect === null) { - queue.firstCapturedEffect = queue.lastCapturedEffect = update; - } else { - queue.lastCapturedEffect.nextEffect = update; - queue.lastCapturedEffect = update; + 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; + } } - } + } while (true); } - update = update.next; - } - 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; - } + if (newBaseQueueLast === null) { + newBaseState = newState; + } else { + newBaseQueueLast.next = newBaseQueueFirst; + } - 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. + 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. - markUnprocessedUpdateTime(newExpirationTime); - workInProgress.expirationTime = newExpirationTime; - workInProgress.memoizedState = resultState; + markUnprocessedUpdateTime(newExpirationTime); + workInProgress.expirationTime = newExpirationTime; + workInProgress.memoizedState = newState; + } { currentlyProcessingQueue = null; @@ -7764,42 +6795,21 @@ function resetHasForceUpdateBeforeProcessing() { function checkHasForceUpdateAfterProcessing() { return hasForceUpdate; } -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; -} +function commitUpdateQueue(finishedWork, finishedQueue, instance) { + // Commit the effects + var effects = finishedQueue.effects; + finishedQueue.effects = null; -function commitUpdateEffects(effect, instance) { - while (effect !== null) { - var callback = effect.callback; + if (effects !== null) { + for (var i = 0; i < effects.length; i++) { + var effect = effects[i]; + 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; } } @@ -7809,7 +6819,7 @@ function requestCurrentSuspenseConfig() { } var fakeInternalInstance = {}; -var isArray$1 = Array.isArray; // React.Component uses a shared frozen object by default. +var isArray = Array.isArray; // React.Component uses a shared frozen object by default. // We'll use it to determine whether we need to initialize legacy refs. var emptyRefsObject = new React.Component().refs; @@ -7844,8 +6854,8 @@ var didWarnAboutInvalidateContextType; if (!didWarnOnInvalidCallback.has(key)) { didWarnOnInvalidCallback.add(key); - warningWithoutStack$1( - false, + + error( "%s(...): Expected the last optional `callback` argument to be a " + "function. Instead received: %s.", callerName, @@ -7857,10 +6867,11 @@ var didWarnAboutInvalidateContextType; warnOnUndefinedDerivedState = function(type, partialState) { if (partialState === undefined) { var componentName = getComponentName(type) || "Component"; + if (!didWarnAboutUndefinedDerivedState.has(componentName)) { didWarnAboutUndefinedDerivedState.add(componentName); - warningWithoutStack$1( - false, + + error( "%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. " + "You have returned undefined.", componentName @@ -7894,16 +6905,6 @@ 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); { @@ -7917,9 +6918,9 @@ function applyDerivedStateFromProps( workInProgress.memoizedState = memoizedState; // Once the update queue is empty, persist the derived state onto the // base state. - var updateQueue = workInProgress.updateQueue; - - if (updateQueue !== null && workInProgress.expirationTime === NoWork) { + if (workInProgress.expirationTime === NoWork) { + // Queue is always non-null for classes + var updateQueue = workInProgress.updateQueue; updateQueue.baseState = memoizedState; } } @@ -8007,6 +7008,7 @@ function checkShouldComponentUpdate( nextContext ) { var instance = workInProgress.stateNode; + if (typeof instance.shouldComponentUpdate === "function") { startPhaseTimer(workInProgress, "shouldComponentUpdate"); var shouldUpdate = instance.shouldComponentUpdate( @@ -8017,14 +7019,13 @@ function checkShouldComponentUpdate( stopPhaseTimer(); { - !(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; + if (shouldUpdate === undefined) { + error( + "%s.shouldComponentUpdate(): Returned undefined instead of a " + + "boolean value. Make sure to return true or false.", + getComponentName(ctor) || "Component" + ); + } } return shouldUpdate; @@ -8041,21 +7042,20 @@ 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") { - warningWithoutStack$1( - false, + error( "%s(...): No `render` method found on the returned component " + "instance: did you accidentally return an object from the constructor?", name ); } else { - warningWithoutStack$1( - false, + error( "%s(...): No `render` method found on the returned component " + "instance: you may have forgotten to define `render`.", name @@ -8063,77 +7063,55 @@ function checkClassInstance(workInProgress, ctor, newProps) { } } - 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.", + if ( + instance.getInitialState && + !instance.getInitialState.isReactClassApproved && + !instance.state + ) { + error( + "getInitialState was defined on %s, a plain JavaScript class. " + + "This is only supported for classes created using React.createClass. " + + "Did you mean to define a state property instead?", + name + ); + } + + if ( + instance.getDefaultProps && + !instance.getDefaultProps.isReactClassApproved + ) { + error( + "getDefaultProps was defined on %s, a plain JavaScript class. " + + "This is only supported for classes created using React.createClass. " + + "Use a static property to define defaultProps instead.", + name + ); + } + + if (instance.propTypes) { + error( + "propTypes was defined as an instance property on %s. Use a static " + + "property to define propTypes instead.", + name + ); + } + + if (instance.contextType) { + error( + "contextType was defined as an instance property on %s. Use a static " + + "property to define contextType instead.", + name + ); + } + + { + if (instance.contextTypes) { + error( + "contextTypes was defined as an instance property on %s. Use a static " + + "property to define contextTypes instead.", name ); } - } 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 && @@ -8141,8 +7119,8 @@ function checkClassInstance(workInProgress, ctor, newProps) { !didWarnAboutContextTypeAndContextTypes.has(ctor) ) { didWarnAboutContextTypeAndContextTypes.add(ctor); - warningWithoutStack$1( - false, + + error( "%s declares both contextTypes and contextType static properties. " + "The legacy contextTypes property will be ignored.", name @@ -8150,95 +7128,84 @@ function checkClassInstance(workInProgress, ctor, newProps) { } } - 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 (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 + ); + } + if ( ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== "undefined" ) { - warningWithoutStack$1( - false, + error( "%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" ); } - 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; + + 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 hasMutatedProps = instance.props !== newProps; - !(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 (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 + ); + } if ( typeof instance.getSnapshotBeforeUpdate === "function" && @@ -8246,61 +7213,53 @@ function checkClassInstance(workInProgress, ctor, newProps) { !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor) ) { didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor); - warningWithoutStack$1( - false, + + error( "%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). " + "This component defines getSnapshotBeforeUpdate() only.", getComponentName(ctor) ); } - 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$1(_state))) { - warningWithoutStack$1( - false, - "%s.state: must be set to an object or null", + 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 ); } - 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; + + 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 + ); } } } @@ -8316,12 +7275,7 @@ function adoptClassInstance(workInProgress, instance) { } } -function constructClassInstance( - workInProgress, - ctor, - props, - renderExpirationTime -) { +function constructClassInstance(workInProgress, ctor, props) { var isLegacyContextConsumer = false; var unmaskedContext = emptyContextObject; var context = emptyContextObject; @@ -8358,8 +7312,8 @@ function constructClassInstance( Object.keys(contextType).join(", ") + "}."; } - warningWithoutStack$1( - false, + + error( "%s defines an invalid contextType. " + "contextType should point to the Context object returned by React.createContext().%s", getComponentName(ctor) || "Component", @@ -8371,7 +7325,7 @@ function constructClassInstance( if (typeof contextType === "object" && contextType !== null) { context = readContext(contextType); - } else if (!disableLegacyContext) { + } else { unmaskedContext = getUnmaskedContext(workInProgress, ctor, true); var contextTypes = ctor.contextTypes; isLegacyContextConsumer = @@ -8381,15 +7335,6 @@ function constructClassInstance( : 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 @@ -8400,10 +7345,11 @@ function constructClassInstance( { if (typeof ctor.getDerivedStateFromProps === "function" && state === null) { var componentName = getComponentName(ctor) || "Component"; + if (!didWarnAboutUninitializedState.has(componentName)) { didWarnAboutUninitializedState.add(componentName); - warningWithoutStack$1( - false, + + error( "`%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`. " + @@ -8424,6 +7370,7 @@ function constructClassInstance( var foundWillMountName = null; var foundWillReceivePropsName = null; var foundWillUpdateName = null; + if ( typeof instance.componentWillMount === "function" && instance.componentWillMount.__suppressDeprecationWarning !== true @@ -8432,6 +7379,7 @@ function constructClassInstance( } else if (typeof instance.UNSAFE_componentWillMount === "function") { foundWillMountName = "UNSAFE_componentWillMount"; } + if ( typeof instance.componentWillReceiveProps === "function" && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true @@ -8442,6 +7390,7 @@ function constructClassInstance( ) { foundWillReceivePropsName = "UNSAFE_componentWillReceiveProps"; } + if ( typeof instance.componentWillUpdate === "function" && instance.componentWillUpdate.__suppressDeprecationWarning !== true @@ -8450,20 +7399,23 @@ function constructClassInstance( } 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); - warningWithoutStack$1( - false, + + error( "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" + @@ -8496,6 +7448,7 @@ function callComponentWillMount(workInProgress, instance) { if (typeof instance.componentWillMount === "function") { instance.componentWillMount(); } + if (typeof instance.UNSAFE_componentWillMount === "function") { instance.UNSAFE_componentWillMount(); } @@ -8504,14 +7457,14 @@ function callComponentWillMount(workInProgress, instance) { if (oldState !== instance.state) { { - warningWithoutStack$1( - false, + error( "%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); } } @@ -8538,10 +7491,11 @@ function callComponentWillReceiveProps( if (instance.state !== oldState) { { var componentName = getComponentName(workInProgress.type) || "Component"; + if (!didWarnAboutStateAssignmentForComponent.has(componentName)) { didWarnAboutStateAssignmentForComponent.add(componentName); - warningWithoutStack$1( - false, + + error( "%s.componentWillReceiveProps(): Assigning directly to " + "this.state is deprecated (except inside a component's " + "constructor). Use setState instead.", @@ -8568,12 +7522,11 @@ 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); @@ -8582,10 +7535,11 @@ function mountClassInstance( { if (instance.state === newProps) { var componentName = getComponentName(ctor) || "Component"; + if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) { didWarnAboutDirectlyAssigningPropsToState.add(componentName); - warningWithoutStack$1( - false, + + error( "%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.", @@ -8601,7 +7555,7 @@ function mountClassInstance( ); } - if (warnAboutDeprecatedLifecycles) { + { ReactStrictModeWarnings.recordUnsafeLifecycleWarnings( workInProgress, instance @@ -8609,19 +7563,10 @@ function mountClassInstance( } } - var updateQueue = workInProgress.updateQueue; - if (updateQueue !== null) { - processUpdateQueue( - workInProgress, - updateQueue, - newProps, - instance, - renderExpirationTime - ); - instance.state = workInProgress.memoizedState; - } - + processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); + instance.state = workInProgress.memoizedState; var getDerivedStateFromProps = ctor.getDerivedStateFromProps; + if (typeof getDerivedStateFromProps === "function") { applyDerivedStateFromProps( workInProgress, @@ -8642,18 +7587,13 @@ function mountClassInstance( callComponentWillMount(workInProgress, instance); // If we had additional state updates during this life-cycle, let's // process them now. - updateQueue = workInProgress.updateQueue; - - if (updateQueue !== null) { - processUpdateQueue( - workInProgress, - updateQueue, - newProps, - instance, - renderExpirationTime - ); - instance.state = workInProgress.memoizedState; - } + processUpdateQueue( + workInProgress, + newProps, + instance, + renderExpirationTime + ); + instance.state = workInProgress.memoizedState; } if (typeof instance.componentDidMount === "function") { @@ -8676,7 +7616,7 @@ function resumeMountClassInstance( if (typeof contextType === "object" && contextType !== null) { nextContext = readContext(contextType); - } else if (!disableLegacyContext) { + } else { var nextLegacyUnmaskedContext = getUnmaskedContext( workInProgress, ctor, @@ -8712,18 +7652,9 @@ function resumeMountClassInstance( resetHasForceUpdateBeforeProcessing(); var oldState = workInProgress.memoizedState; var newState = (instance.state = oldState); - var updateQueue = workInProgress.updateQueue; + processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); + newState = workInProgress.memoizedState; - if (updateQueue !== null) { - processUpdateQueue( - workInProgress, - updateQueue, - newProps, - instance, - renderExpirationTime - ); - newState = workInProgress.memoizedState; - } if ( oldProps === newProps && oldState === newState && @@ -8735,6 +7666,7 @@ function resumeMountClassInstance( if (typeof instance.componentDidMount === "function") { workInProgress.effectTag |= Update; } + return false; } @@ -8811,6 +7743,7 @@ function updateClassInstance( renderExpirationTime ) { var instance = workInProgress.stateNode; + cloneUpdateQueue(current, workInProgress); var oldProps = workInProgress.memoizedProps; instance.props = workInProgress.type === workInProgress.elementType @@ -8822,7 +7755,7 @@ function updateClassInstance( if (typeof contextType === "object" && contextType !== null) { nextContext = readContext(contextType); - } else if (!disableLegacyContext) { + } else { var nextUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true); nextContext = getMaskedContext(workInProgress, nextUnmaskedContext); } @@ -8854,18 +7787,8 @@ function updateClassInstance( resetHasForceUpdateBeforeProcessing(); var oldState = workInProgress.memoizedState; var newState = (instance.state = oldState); - var updateQueue = workInProgress.updateQueue; - - if (updateQueue !== null) { - processUpdateQueue( - workInProgress, - updateQueue, - newProps, - instance, - renderExpirationTime - ); - newState = workInProgress.memoizedState; - } + processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); + newState = workInProgress.memoizedState; if ( oldProps === newProps && @@ -8883,6 +7806,7 @@ function updateClassInstance( workInProgress.effectTag |= Update; } } + if (typeof instance.getSnapshotBeforeUpdate === "function") { if ( oldProps !== current.memoizedProps || @@ -8891,6 +7815,7 @@ function updateClassInstance( workInProgress.effectTag |= Snapshot; } } + return false; } @@ -8955,6 +7880,7 @@ function updateClassInstance( workInProgress.effectTag |= Update; } } + if (typeof instance.getSnapshotBeforeUpdate === "function") { if ( oldProps !== current.memoizedProps || @@ -8993,6 +7919,7 @@ var warnForMissingKey = function(child) {}; * object keys are not valid. This allows us to keep track of children between * updates. */ + ownerHasKeyUseWarning = {}; ownerHasFunctionTypeWarning = {}; @@ -9023,8 +7950,8 @@ var warnForMissingKey = function(child) {}; } ownerHasKeyUseWarning[currentComponentErrorInfo] = true; - warning$1( - false, + + error( "Each child in a list should have a unique " + '"key" prop. See https://fb.me/react-warning-keys for ' + "more information." @@ -9032,10 +7959,11 @@ var warnForMissingKey = function(child) {}; }; } -var isArray = Array.isArray; +var isArray$1 = Array.isArray; -function coerceRef(returnFiber, current$$1, element) { +function coerceRef(returnFiber, current, element) { var mixedRef = element.ref; + if ( mixedRef !== null && typeof mixedRef !== "function" && @@ -9044,24 +7972,21 @@ function coerceRef(returnFiber, current$$1, 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) { + 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 + ) + ) { var componentName = getComponentName(returnFiber.type) || "Component"; + if (!didWarnAboutStringRefs[componentName]) { - 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, + { + error( '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. " + @@ -9071,6 +7996,7 @@ function coerceRef(returnFiber, current$$1, element) { getStackByFiberInDevAndProd(returnFiber) ); } + didWarnAboutStringRefs[componentName] = true; } } @@ -9085,7 +8011,7 @@ function coerceRef(returnFiber, current$$1, element) { if (!(ownerFiber.tag === ClassComponent)) { throw Error( - "Function components cannot have refs. Did you mean to use React.forwardRef()?" + "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" ); } @@ -9103,12 +8029,12 @@ function coerceRef(returnFiber, current$$1, element) { var stringRef = "" + mixedRef; // Check if previous string ref matches new string ref if ( - current$$1 !== null && - current$$1.ref !== null && - typeof current$$1.ref === "function" && - current$$1.ref._stringRef === stringRef + current !== null && + current.ref !== null && + typeof current.ref === "function" && + current.ref._stringRef === stringRef ) { - return current$$1.ref; + return current.ref; } var ref = function(value) { @@ -9118,6 +8044,7 @@ function coerceRef(returnFiber, current$$1, element) { // This is a lazy pooled frozen object, so we need to initialize. refs = inst.refs = {}; } + if (value === null) { delete refs[stringRef]; } else { @@ -9150,6 +8077,7 @@ function coerceRef(returnFiber, current$$1, element) { function throwOnInvalidObjectType(returnFiber, newChild) { if (returnFiber.type !== "textarea") { var addendum = ""; + { addendum = " If you meant to render a collection of children, use an array " + @@ -9171,23 +8099,25 @@ 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; - } + 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." - ); + 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." + ); + } } // 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 @@ -9212,6 +8142,7 @@ function ChildReconciler(shouldTrackSideEffects) { } else { returnFiber.firstEffect = returnFiber.lastEffect = childToDelete; } + childToDelete.nextEffect = null; childToDelete.effectTag = Deletion; } @@ -9229,6 +8160,7 @@ function ChildReconciler(shouldTrackSideEffects) { deleteChild(returnFiber, childToDelete); childToDelete = childToDelete.sibling; } + return null; } @@ -9252,10 +8184,10 @@ function ChildReconciler(shouldTrackSideEffects) { return existingChildren; } - function useFiber(fiber, pendingProps, expirationTime) { + function useFiber(fiber, pendingProps) { // 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, expirationTime); + var clone = createWorkInProgress(fiber, pendingProps); clone.index = 0; clone.sibling = null; return clone; @@ -9263,15 +8195,16 @@ function ChildReconciler(shouldTrackSideEffects) { function placeChild(newFiber, lastPlacedIndex, newIndex) { newFiber.index = newIndex; + if (!shouldTrackSideEffects) { // Noop. return lastPlacedIndex; } - var current$$1 = newFiber.alternate; + var current = newFiber.alternate; - if (current$$1 !== null) { - var oldIndex = current$$1.index; + if (current !== null) { + var oldIndex = current.index; if (oldIndex < lastPlacedIndex) { // This is a move. @@ -9294,16 +8227,12 @@ function ChildReconciler(shouldTrackSideEffects) { if (shouldTrackSideEffects && newFiber.alternate === null) { newFiber.effectTag = Placement; } + return newFiber; } - function updateTextNode( - returnFiber, - current$$1, - textContent, - expirationTime - ) { - if (current$$1 === null || current$$1.tag !== HostText) { + function updateTextNode(returnFiber, current, textContent, expirationTime) { + if (current === null || current.tag !== HostText) { // Insert var created = createFiberFromText( textContent, @@ -9314,46 +8243,48 @@ function ChildReconciler(shouldTrackSideEffects) { return created; } else { // Update - var existing = useFiber(current$$1, textContent, expirationTime); + var existing = useFiber(current, textContent); existing.return = returnFiber; 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; - } - return existing; - } else { - // Insert - var created = createFiberFromElement( - element, - returnFiber.mode, - expirationTime - ); - created.ref = coerceRef(returnFiber, current$$1, element); - created.return = returnFiber; - return created; - } + 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; + } + } // Insert + + var created = createFiberFromElement( + element, + returnFiber.mode, + expirationTime + ); + created.ref = coerceRef(returnFiber, current, element); + created.return = returnFiber; + return created; } - function updatePortal(returnFiber, current$$1, portal, expirationTime) { + function updatePortal(returnFiber, current, portal, expirationTime) { if ( - current$$1 === null || - current$$1.tag !== HostPortal || - current$$1.stateNode.containerInfo !== portal.containerInfo || - current$$1.stateNode.implementation !== portal.implementation + current === null || + current.tag !== HostPortal || + current.stateNode.containerInfo !== portal.containerInfo || + current.stateNode.implementation !== portal.implementation ) { // Insert var created = createFiberFromPortal( @@ -9365,24 +8296,14 @@ function ChildReconciler(shouldTrackSideEffects) { return created; } else { // Update - var existing = useFiber( - current$$1, - portal.children || [], - expirationTime - ); + var existing = useFiber(current, portal.children || []); existing.return = returnFiber; return existing; } } - function updateFragment( - returnFiber, - current$$1, - fragment, - expirationTime, - key - ) { - if (current$$1 === null || current$$1.tag !== Fragment) { + function updateFragment(returnFiber, current, fragment, expirationTime, key) { + if (current === null || current.tag !== Fragment) { // Insert var created = createFiberFromFragment( fragment, @@ -9394,7 +8315,7 @@ function ChildReconciler(shouldTrackSideEffects) { return created; } else { // Update - var existing = useFiber(current$$1, fragment, expirationTime); + var existing = useFiber(current, fragment); existing.return = returnFiber; return existing; } @@ -9422,28 +8343,32 @@ 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(newChild) || getIteratorFn(newChild)) { + if (isArray$1(newChild) || getIteratorFn(newChild)) { var _created3 = createFiberFromFragment( newChild, returnFiber.mode, expirationTime, null ); + _created3.return = returnFiber; return _created3; } @@ -9471,6 +8396,7 @@ function ChildReconciler(shouldTrackSideEffects) { if (key !== null) { return null; } + return updateTextNode( returnFiber, oldFiber, @@ -9492,6 +8418,7 @@ function ChildReconciler(shouldTrackSideEffects) { key ); } + return updateElement( returnFiber, oldFiber, @@ -9502,6 +8429,7 @@ function ChildReconciler(shouldTrackSideEffects) { return null; } } + case REACT_PORTAL_TYPE: { if (newChild.key === key) { return updatePortal( @@ -9516,7 +8444,7 @@ function ChildReconciler(shouldTrackSideEffects) { } } - if (isArray(newChild) || getIteratorFn(newChild)) { + if (isArray$1(newChild) || getIteratorFn(newChild)) { if (key !== null) { return null; } @@ -9568,6 +8496,7 @@ function ChildReconciler(shouldTrackSideEffects) { existingChildren.get( newChild.key === null ? newIdx : newChild.key ) || null; + if (newChild.type === REACT_FRAGMENT_TYPE) { return updateFragment( returnFiber, @@ -9577,6 +8506,7 @@ function ChildReconciler(shouldTrackSideEffects) { newChild.key ); } + return updateElement( returnFiber, _matchedFiber, @@ -9584,11 +8514,13 @@ function ChildReconciler(shouldTrackSideEffects) { expirationTime ); } + case REACT_PORTAL_TYPE: { var _matchedFiber2 = existingChildren.get( newChild.key === null ? newIdx : newChild.key ) || null; + return updatePortal( returnFiber, _matchedFiber2, @@ -9598,8 +8530,9 @@ function ChildReconciler(shouldTrackSideEffects) { } } - if (isArray(newChild) || getIteratorFn(newChild)) { + if (isArray$1(newChild) || getIteratorFn(newChild)) { var _matchedFiber3 = existingChildren.get(newIdx) || null; + return updateFragment( returnFiber, _matchedFiber3, @@ -9629,6 +8562,7 @@ function ChildReconciler(shouldTrackSideEffects) { if (typeof child !== "object" || child === null) { return knownKeys; } + switch (child.$$typeof) { case REACT_ELEMENT_TYPE: case REACT_PORTAL_TYPE: @@ -9644,12 +8578,13 @@ function ChildReconciler(shouldTrackSideEffects) { knownKeys.add(key); break; } + if (!knownKeys.has(key)) { knownKeys.add(key); break; } - warning$1( - false, + + error( "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 " + @@ -9657,11 +8592,11 @@ function ChildReconciler(shouldTrackSideEffects) { "could change in a future version.", key ); - break; - default: + break; } } + return knownKeys; } @@ -9702,6 +8637,7 @@ 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; @@ -9709,12 +8645,14 @@ 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 @@ -9747,6 +8685,7 @@ function ChildReconciler(shouldTrackSideEffects) { // with the previous one. previousNewFiber.sibling = newFiber; } + previousNewFiber = newFiber; oldFiber = nextOldFiber; } @@ -9796,6 +8735,7 @@ function ChildReconciler(shouldTrackSideEffects) { newChildren[newIdx], expirationTime ); + if (_newFiber2 !== null) { if (shouldTrackSideEffects) { if (_newFiber2.alternate !== null) { @@ -9816,6 +8756,7 @@ function ChildReconciler(shouldTrackSideEffects) { } else { previousNewFiber.sibling = _newFiber2; } + previousNewFiber = _newFiber2; } } @@ -9854,28 +8795,28 @@ function ChildReconciler(shouldTrackSideEffects) { typeof Symbol === "function" && // $FlowFixMe Flow doesn't know about toStringTag newChildrenIterable[Symbol.toStringTag] === "Generator" ) { - !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; + 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 = true; } // Warn about using Maps as children if (newChildrenIterable.entries === iteratorFn) { - !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; + 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 = true; } // First, validate keys. // We'll get a different iterator later for the main pass. @@ -9919,12 +8860,14 @@ 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 @@ -9957,6 +8900,7 @@ function ChildReconciler(shouldTrackSideEffects) { // with the previous one. previousNewFiber.sibling = newFiber; } + previousNewFiber = newFiber; oldFiber = nextOldFiber; } @@ -10002,6 +8946,7 @@ function ChildReconciler(shouldTrackSideEffects) { step.value, expirationTime ); + if (_newFiber4 !== null) { if (shouldTrackSideEffects) { if (_newFiber4.alternate !== null) { @@ -10022,6 +8967,7 @@ function ChildReconciler(shouldTrackSideEffects) { } else { previousNewFiber.sibling = _newFiber4; } + previousNewFiber = _newFiber4; } } @@ -10049,7 +8995,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, expirationTime); + var existing = useFiber(currentFirstChild, textContent); existing.return = returnFiber; return existing; } // The existing first child is not a text node so we need to create one @@ -10073,38 +9019,64 @@ 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) { - 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: + 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: isCompatibleFamilyForHotReloading(child, element) - ) { - 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; + ) { + 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; } - return existing; - } else { - deleteRemainingChildren(returnFiber, child); - break; - } + } // Didn't match. + + deleteRemainingChildren(returnFiber, child); + break; } else { deleteChild(returnFiber, child); } + child = child.sibling; } @@ -10123,6 +9095,7 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime ); + _created4.ref = coerceRef(returnFiber, currentFirstChild, element); _created4.return = returnFiber; return _created4; @@ -10137,6 +9110,7 @@ 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. @@ -10147,7 +9121,7 @@ function ChildReconciler(shouldTrackSideEffects) { child.stateNode.implementation === portal.implementation ) { deleteRemainingChildren(returnFiber, child.sibling); - var existing = useFiber(child, portal.children || [], expirationTime); + var existing = useFiber(child, portal.children || []); existing.return = returnFiber; return existing; } else { @@ -10157,6 +9131,7 @@ function ChildReconciler(shouldTrackSideEffects) { } else { deleteChild(returnFiber, child); } + child = child.sibling; } @@ -10207,6 +9182,7 @@ function ChildReconciler(shouldTrackSideEffects) { expirationTime ) ); + case REACT_PORTAL_TYPE: return placeSingleChild( reconcileSinglePortal( @@ -10230,7 +9206,7 @@ function ChildReconciler(shouldTrackSideEffects) { ); } - if (isArray(newChild)) { + if (isArray$1(newChild)) { return reconcileChildrenArray( returnFiber, currentFirstChild, @@ -10257,6 +9233,7 @@ 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, @@ -10265,6 +9242,7 @@ 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; @@ -10296,8 +9274,8 @@ function ChildReconciler(shouldTrackSideEffects) { var reconcileChildFibers = ChildReconciler(true); var mountChildFibers = ChildReconciler(false); -function cloneChildFibers(current$$1, workInProgress) { - if (!(current$$1 === null || workInProgress.child === current$$1.child)) { +function cloneChildFibers(current, workInProgress) { + if (!(current === null || workInProgress.child === current.child)) { throw Error("Resuming work not yet implemented."); } @@ -10306,11 +9284,7 @@ function cloneChildFibers(current$$1, workInProgress) { } var currentChild = workInProgress.child; - var newChild = createWorkInProgress( - currentChild, - currentChild.pendingProps, - currentChild.expirationTime - ); + var newChild = createWorkInProgress(currentChild, currentChild.pendingProps); workInProgress.child = newChild; newChild.return = workInProgress; @@ -10318,8 +9292,7 @@ function cloneChildFibers(current$$1, workInProgress) { currentChild = currentChild.sibling; newChild = newChild.sibling = createWorkInProgress( currentChild, - currentChild.pendingProps, - currentChild.expirationTime + currentChild.pendingProps ); newChild.return = workInProgress; } @@ -10369,7 +9342,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(nextRootInstance); // Now that we know this function doesn't throw, replace it. + var nextRootContext = getRootHostContext(); // Now that we know this function doesn't throw, replace it. pop(contextStackCursor$1, fiber); push(contextStackCursor$1, nextRootContext, fiber); @@ -10389,7 +9362,7 @@ function getHostContext() { function pushHostContext(fiber) { var rootInstance = requiredContext(rootInstanceStackCursor.current); var context = requiredContext(contextStackCursor$1.current); - var nextContext = getChildHostContext(context, fiber.type, rootInstance); // Don't push this Fiber's context unless it's unique. + var nextContext = getChildHostContext(context, fiber.type); // Don't push this Fiber's context unless it's unique. if (context === nextContext) { return; @@ -10492,8 +9465,8 @@ function findFirstSuspended(row) { if ( dehydrated === null || - isSuspenseInstancePending(dehydrated) || - isSuspenseInstanceFallback(dehydrated) + isSuspenseInstancePending() || + isSuspenseInstanceFallback() ) { return node; } @@ -10504,6 +9477,7 @@ function findFirstSuspended(row) { node.memoizedProps.revealOrder !== undefined ) { var didSuspend = (node.effectTag & DidCapture) !== NoEffect; + if (didSuspend) { return node; } @@ -10532,191 +9506,7 @@ function findFirstSuspended(row) { 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$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) { +function createDeprecatedResponderListener(responder, props) { var eventResponderListener = { responder: responder, props: props @@ -10729,33 +9519,19 @@ function createResponderListener(responder, props) { return eventResponderListener; } -var NoEffect$1 = - /* */ - 0; -var UnmountSnapshot = - /* */ +var HasEffect = + /* */ + 1; // Represents the phase in which the effect (not the clean-up) fires. + +var Layout = + /* */ 2; -var UnmountMutation = - /* */ +var Passive$1 = + /* */ 4; -var MountMutation = - /* */ - 8; -var UnmountLayout = - /* */ - 16; -var MountLayout = - /* */ - 32; -var MountPassive = - /* */ - 64; -var UnmountPassive = - /* */ - 128; -var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher; -var ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig; +var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher, + ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig; var didWarnAboutMismatchedHooksForComponent; { @@ -10763,7 +9539,7 @@ var didWarnAboutMismatchedHooksForComponent; } // These are set right before calling the component. -var renderExpirationTime$1 = NoWork; // The work-in-progress fiber. I've named it differently to distinguish it from +var renderExpirationTime = 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 @@ -10772,26 +9548,12 @@ var currentlyRenderingFiber$1 = null; // Hooks are stored as a linked list on th // work-in-progress fiber. var currentHook = null; -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 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 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. @@ -10823,6 +9585,7 @@ function updateHookTypesDev() { if (hookTypesDev !== null) { hookTypesUpdateIndexDev++; + if (hookTypesDev[hookTypesUpdateIndexDev] !== hookName) { warnOnHookMismatchInDev(hookName); } @@ -10835,8 +9598,7 @@ 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. - warning$1( - false, + error( "%s received a final argument that is not an array (instead, received `%s`). When " + "specified, the final argument must be an array.", currentHookNameInDev, @@ -10849,6 +9611,7 @@ function checkDepsAreArrayDev(deps) { function warnOnHookMismatchInDev(currentHookName) { { var componentName = getComponentName(currentlyRenderingFiber$1.type); + if (!didWarnAboutMismatchedHooksForComponent.has(componentName)) { didWarnAboutMismatchedHooksForComponent.add(componentName); @@ -10871,8 +9634,7 @@ function warnOnHookMismatchInDev(currentHookName) { table += row; } - warning$1( - false, + error( "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" + @@ -10906,14 +9668,14 @@ function areHookInputsEqual(nextDeps, prevDeps) { if (prevDeps === null) { { - warning$1( - false, + error( "%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; } @@ -10921,8 +9683,7 @@ function areHookInputsEqual(nextDeps, prevDeps) { // Don't bother comparing lengths in prod because these arrays should be // passed inline. if (nextDeps.length !== prevDeps.length) { - warning$1( - false, + error( "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" + @@ -10935,7 +9696,7 @@ function areHookInputsEqual(nextDeps, prevDeps) { } for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) { - if (is$1(nextDeps[i], prevDeps[i])) { + if (objectIs(nextDeps[i], prevDeps[i])) { continue; } @@ -10950,12 +9711,11 @@ function renderWithHooks( workInProgress, Component, props, - refOrContext, + secondArg, nextRenderExpirationTime ) { - renderExpirationTime$1 = nextRenderExpirationTime; + renderExpirationTime = nextRenderExpirationTime; currentlyRenderingFiber$1 = workInProgress; - nextCurrentHook = current !== null ? current.memoizedState : null; { hookTypesDev = current !== null ? current._debugHookTypes : null; @@ -10963,89 +9723,87 @@ function renderWithHooks( ignorePreviousDependencies = current !== null && current.type !== workInProgress.type; - } // The following should have already been reset + } + + workInProgress.memoizedState = null; + workInProgress.updateQueue = null; + workInProgress.expirationTime = NoWork; // 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 nextCurrentHook === null. + // Currently we will identify the update render as a mount because memoizedState === null. // This is tricky because it's valid for certain types of components (e.g. React.lazy) - // Using nextCurrentHook to differentiate between mount/update only works if at least one stateful hook is used. + // Using memoizedState 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 nextCurrentHook would be null during updates and mounts. + // so memoizedState would be null during updates and mounts. { - if (nextCurrentHook !== null) { - ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV; + if (current !== null && current.memoizedState !== null) { + ReactCurrentDispatcher.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$1.current = HooksDispatcherOnMountWithHookTypesInDEV; + ReactCurrentDispatcher.current = HooksDispatcherOnMountWithHookTypesInDEV; } else { - ReactCurrentDispatcher$1.current = HooksDispatcherOnMountInDEV; + ReactCurrentDispatcher.current = HooksDispatcherOnMountInDEV; } } - var children = Component(props, refOrContext); + 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; - if (didScheduleRenderPhaseUpdate) { do { - didScheduleRenderPhaseUpdate = false; + 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." + ); + } + 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; - componentUpdateQueue = null; + workInProgress.updateQueue = null; { // Also validate hook order for cascading updates. hookTypesUpdateIndexDev = -1; } - ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV; - children = Component(props, refOrContext); - } while (didScheduleRenderPhaseUpdate); - - renderPhaseUpdates = null; - numberOfReRenders = 0; + ReactCurrentDispatcher.current = HooksDispatcherOnRerenderInDEV; + children = Component(props, secondArg); + } while (workInProgress.expirationTime === renderExpirationTime); } // 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$1.current = ContextOnlyDispatcher; - var renderedWork = currentlyRenderingFiber$1; - renderedWork.memoizedState = firstWorkInProgressHook; - renderedWork.expirationTime = remainingExpirationTime; - renderedWork.updateQueue = componentUpdateQueue; - renderedWork.effectTag |= sideEffectTag; + ReactCurrentDispatcher.current = ContextOnlyDispatcher; { - renderedWork._debugHookTypes = hookTypesDev; + workInProgress._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$1 = NoWork; + renderExpirationTime = NoWork; currentlyRenderingFiber$1 = null; currentHook = null; - nextCurrentHook = null; - firstWorkInProgressHook = null; workInProgressHook = null; - nextWorkInProgressHook = null; { currentHookNameInDev = null; @@ -11053,12 +9811,7 @@ function renderWithHooks( hookTypesUpdateIndexDev = -1; } - remainingExpirationTime = NoWork; - componentUpdateQueue = null; - sideEffectTag = 0; // These were reset above - // didScheduleRenderPhaseUpdate = false; - // renderPhaseUpdates = null; - // numberOfReRenders = 0; + didScheduleRenderPhaseUpdate = false; if (!!didRenderTooFewHooks) { throw Error( @@ -11076,20 +9829,37 @@ function bailoutHooks(current, workInProgress, expirationTime) { current.expirationTime = NoWork; } } -function resetHooks() { +function resetHooksAfterThrow() { // 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$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. + 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; - renderExpirationTime$1 = NoWork; + while (hook !== null) { + var queue = hook.queue; + + if (queue !== null) { + queue.pending = null; + } + + hook = hook.next; + } + } + + renderExpirationTime = NoWork; currentlyRenderingFiber$1 = null; currentHook = null; - nextCurrentHook = null; - firstWorkInProgressHook = null; workInProgressHook = null; - nextWorkInProgressHook = null; { hookTypesDev = null; @@ -11097,30 +9867,26 @@ function resetHooks() { 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 - firstWorkInProgressHook = workInProgressHook = hook; + currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook; } else { // Append to the end of the list workInProgressHook = workInProgressHook.next = hook; } + return workInProgressHook; } @@ -11130,12 +9896,33 @@ 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)) { @@ -11146,20 +9933,18 @@ 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. - workInProgressHook = firstWorkInProgressHook = newHook; + currentlyRenderingFiber$1.memoizedState = workInProgressHook = newHook; } else { // Append to the end of the list. workInProgressHook = workInProgressHook.next = newHook; } - - nextCurrentHook = currentHook.next; } return workInProgressHook; @@ -11172,6 +9957,7 @@ function createFunctionComponentUpdateQueue() { } function basicStateReducer(state, action) { + // $FlowFixMe: Flow doesn't like mixed types return typeof action === "function" ? action(state) : action; } @@ -11184,15 +9970,16 @@ function mountReducer(reducer, initialArg, init) { } else { initialState = initialArg; } + hook.memoizedState = hook.baseState = initialState; var queue = (hook.queue = { - last: null, + pending: null, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialState }); var dispatch = (queue.dispatch = dispatchAction.bind( - null, // Flow doesn't know this is non-null, but we do. + null, currentlyRenderingFiber$1, queue )); @@ -11210,157 +9997,191 @@ function updateReducer(reducer, initialArg, init) { } queue.lastRenderedReducer = reducer; + var current = currentHook; // The last rebase update that is NOT part of the base state. - 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 baseQueue = current.baseQueue; // The last pending update that hasn't been processed yet. - if (hook.baseUpdate === queue.last) { - hook.baseState = newState; - } + var pendingQueue = queue.pending; - queue.lastRenderedState = newState; - return [newState, _dispatch]; - } + 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; } - 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 (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; + current.baseQueue = baseQueue = pendingQueue; + queue.pending = null; } - if (first !== null) { - var _newState = baseState; + + if (baseQueue !== null) { + // We have a queue to process. + var first = baseQueue.next; + var newState = current.baseState; var newBaseState = null; - var newBaseUpdate = null; - var prevUpdate = baseUpdate; - var _update = first; - var didSkip = false; + var newBaseQueueFirst = null; + var newBaseQueueLast = null; + var update = first; do { - var updateExpirationTime = _update.expirationTime; + var updateExpirationTime = update.expirationTime; - if (updateExpirationTime < renderExpirationTime$1) { + 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. - if (!didSkip) { - didSkip = true; - newBaseUpdate = prevUpdate; - newBaseState = _newState; + 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; } // Update the remaining priority in the queue. - if (updateExpirationTime > remainingExpirationTime) { - remainingExpirationTime = updateExpirationTime; - markUnprocessedUpdateTime(remainingExpirationTime); + if (updateExpirationTime > currentlyRenderingFiber$1.expirationTime) { + currentlyRenderingFiber$1.expirationTime = updateExpirationTime; + markUnprocessedUpdateTime(updateExpirationTime); } } else { // This update does have sufficient priority. - // Mark the event time of this update as relevant to this render pass. + 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. // 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); } } - prevUpdate = _update; - _update = _update.next; - } while (_update !== null && _update !== first); + update = update.next; + } while (update !== null && update !== first); - if (!didSkip) { - newBaseUpdate = prevUpdate; - newBaseState = _newState; + if (newBaseQueueLast === null) { + newBaseState = newState; + } else { + newBaseQueueLast.next = newBaseQueueFirst; } // Mark that the fiber performed work, but only if the new state is // different from the current state. - if (!is$1(_newState, hook.memoizedState)) { + if (!objectIs(newState, hook.memoizedState)) { markWorkInProgressReceivedUpdate(); } - hook.memoizedState = _newState; - hook.baseUpdate = newBaseUpdate; + hook.memoizedState = newState; hook.baseState = newBaseState; - queue.lastRenderedState = _newState; + hook.baseQueue = newBaseQueueLast; + 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 = { - last: null, + pending: null, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState }); var dispatch = (queue.dispatch = dispatchAction.bind( - null, // Flow doesn't know this is non-null, but we do. + null, currentlyRenderingFiber$1, queue )); @@ -11368,7 +10189,11 @@ function mountState(initialState) { } function updateState(initialState) { - return updateReducer(basicStateReducer, initialState); + return updateReducer(basicStateReducer); +} + +function rerenderState(initialState) { + return rerenderReducer(basicStateReducer); } function pushEffect(tag, create, destroy, deps) { @@ -11380,8 +10205,11 @@ 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; @@ -11395,6 +10223,7 @@ function pushEffect(tag, create, destroy, deps) { componentUpdateQueue.lastEffect = effect; } } + return effect; } @@ -11420,8 +10249,13 @@ function updateRef(initialValue) { function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var hook = mountWorkInProgressHook(); var nextDeps = deps === undefined ? null : deps; - sideEffectTag |= fiberEffectTag; - hook.memoizedState = pushEffect(hookEffectTag, create, undefined, nextDeps); + currentlyRenderingFiber$1.effectTag |= fiberEffectTag; + hook.memoizedState = pushEffect( + HasEffect | hookEffectTag, + create, + undefined, + nextDeps + ); } function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { @@ -11437,52 +10271,35 @@ function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var prevDeps = prevEffect.deps; if (areHookInputsEqual(nextDeps, prevDeps)) { - pushEffect(NoEffect$1, create, destroy, nextDeps); + pushEffect(hookEffectTag, create, destroy, nextDeps); return; } } } - sideEffectTag |= fiberEffectTag; - hook.memoizedState = pushEffect(hookEffectTag, create, destroy, nextDeps); + currentlyRenderingFiber$1.effectTag |= fiberEffectTag; + hook.memoizedState = pushEffect( + HasEffect | hookEffectTag, + create, + destroy, + nextDeps + ); } function mountEffect(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 - ); + return mountEffectImpl(Update | Passive, Passive$1, create, deps); } function updateEffect(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 - ); + return updateEffectImpl(Update | Passive, Passive$1, create, deps); } function mountLayoutEffect(create, deps) { - return mountEffectImpl(Update, UnmountMutation | MountLayout, create, deps); + return mountEffectImpl(Update, Layout, create, deps); } function updateLayoutEffect(create, deps) { - return updateEffectImpl(Update, UnmountMutation | MountLayout, create, deps); + return updateEffectImpl(Update, Layout, create, deps); } function imperativeHandleEffect(create, ref) { @@ -11497,15 +10314,15 @@ function imperativeHandleEffect(create, ref) { }; } else if (ref !== null && ref !== undefined) { var refObject = ref; + { - !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; + 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(", ") + "}" + ); + } } var _inst2 = create(); @@ -11519,21 +10336,20 @@ function imperativeHandleEffect(create, ref) { function mountImperativeHandle(ref, create, deps) { { - !(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; + 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" + ); + } } // 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, - UnmountMutation | MountLayout, + Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps ); @@ -11541,21 +10357,20 @@ function mountImperativeHandle(ref, create, deps) { function updateImperativeHandle(ref, create, deps) { { - !(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; + 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" + ); + } } // 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, - UnmountMutation | MountLayout, + Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps ); @@ -11590,6 +10405,7 @@ function updateCallback(callback, deps) { } } } + hook.memoizedState = [callback, nextDeps]; return callback; } @@ -11606,15 +10422,18 @@ 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; @@ -11627,17 +10446,14 @@ function mountDeferredValue(value, config) { mountEffect( function() { - Scheduler.unstable_next(function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - config === undefined ? null : config; + 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] ); @@ -11645,100 +10461,151 @@ function mountDeferredValue(value, config) { } function updateDeferredValue(value, config) { - var _updateState = updateState(value), + var _updateState = updateState(), prevValue = _updateState[0], setValue = _updateState[1]; updateEffect( function() { - Scheduler.unstable_next(function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - config === undefined ? null : config; + 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 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; + + 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 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]; + var start = mountCallback(startTransition.bind(null, setPending, config), [ + setPending, + config + ]); + return [start, isPending]; } function updateTransition(config) { - var _updateState2 = updateState(false), + var _updateState2 = updateState(), isPending = _updateState2[0], setPending = _updateState2[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 rerenderTransition(config) { + var _rerenderState2 = rerenderState(), + isPending = _rerenderState2[0], + setPending = _rerenderState2[1]; + + var start = updateCallback(startTransition.bind(null, setPending, config), [ + setPending, + config + ]); + return [start, isPending]; } function dispatchAction(fiber, queue, action) { - if (!(numberOfReRenders < RE_RENDER_LIMIT)) { - throw Error( - "Too many re-renders. React limits the number of renders to prevent an infinite loop." - ); + { + 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()." + ); + } } + 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 + }; + { - !(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; + 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; } + queue.pending = update; var alternate = fiber.alternate; + if ( fiber === currentlyRenderingFiber$1 || (alternate !== null && alternate === currentlyRenderingFiber$1) @@ -11747,76 +10614,9 @@ 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; - 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; - } + update.expirationTime = renderExpirationTime; + currentlyRenderingFiber$1.expirationTime = renderExpirationTime; } 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) @@ -11830,8 +10630,8 @@ function dispatchAction(fiber, queue, action) { var prevDispatcher; { - prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; } try { @@ -11841,10 +10641,10 @@ function dispatchAction(fiber, queue, action) { // time we enter the render phase, then the eager state can be used // without calling the reducer again. - _update2.eagerReducer = lastRenderedReducer; - _update2.eagerState = eagerState; + update.eagerReducer = lastRenderedReducer; + update.eagerState = eagerState; - if (is$1(eagerState, currentState)) { + if (objectIs(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 @@ -11855,23 +10655,24 @@ function dispatchAction(fiber, queue, action) { // Suppress the error. It will throw again in the render phase. } finally { { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.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, @@ -11886,18 +10687,20 @@ var ContextOnlyDispatcher = { useDebugValue: throwInvalidHookError, useResponder: throwInvalidHookError, useDeferredValue: throwInvalidHookError, - useTransition: throwInvalidHookError + useTransition: throwInvalidHookError, + useEvent: 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() { - warning$1( - false, + 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 " + @@ -11906,8 +10709,7 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; }; var warnInvalidHookAccess = function() { - warning$1( - false, + error( "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 " + @@ -11952,23 +10754,25 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; currentHookNameInDev = "useMemo"; mountHookTypesDev(); checkDepsAreArrayDev(deps); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; + try { return mountMemo(create, deps); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useReducer: function(reducer, initialArg, init) { currentHookNameInDev = "useReducer"; mountHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; + try { return mountReducer(reducer, initialArg, init); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useRef: function(initialValue) { @@ -11979,23 +10783,24 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; useState: function(initialState) { currentHookNameInDev = "useState"; mountHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; + try { return mountState(initialState); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useDebugValue: function(value, formatterFn) { currentHookNameInDev = "useDebugValue"; mountHookTypesDev(); - return mountDebugValue(value, formatterFn); + return mountDebugValue(); }, useResponder: function(responder, props) { currentHookNameInDev = "useResponder"; mountHookTypesDev(); - return createResponderListener(responder, props); + return createDeprecatedResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; @@ -12006,6 +10811,11 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; currentHookNameInDev = "useTransition"; mountHookTypesDev(); return mountTransition(config); + }, + useEvent: function(event) { + currentHookNameInDev = "useEvent"; + mountHookTypesDev(); + return mountEventListener(); } }; HooksDispatcherOnMountWithHookTypesInDEV = { @@ -12040,23 +10850,25 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; useMemo: function(create, deps) { currentHookNameInDev = "useMemo"; updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; + try { return mountMemo(create, deps); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useReducer: function(reducer, initialArg, init) { currentHookNameInDev = "useReducer"; updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; + try { return mountReducer(reducer, initialArg, init); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useRef: function(initialValue) { @@ -12067,23 +10879,24 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; useState: function(initialState) { currentHookNameInDev = "useState"; updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; + try { return mountState(initialState); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useDebugValue: function(value, formatterFn) { currentHookNameInDev = "useDebugValue"; updateHookTypesDev(); - return mountDebugValue(value, formatterFn); + return mountDebugValue(); }, useResponder: function(responder, props) { currentHookNameInDev = "useResponder"; updateHookTypesDev(); - return createResponderListener(responder, props); + return createDeprecatedResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; @@ -12094,6 +10907,11 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; currentHookNameInDev = "useTransition"; updateHookTypesDev(); return mountTransition(config); + }, + useEvent: function(event) { + currentHookNameInDev = "useEvent"; + updateHookTypesDev(); + return mountEventListener(); } }; HooksDispatcherOnUpdateInDEV = { @@ -12128,50 +10946,53 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; useMemo: function(create, deps) { currentHookNameInDev = "useMemo"; updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + try { return updateMemo(create, deps); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useReducer: function(reducer, initialArg, init) { currentHookNameInDev = "useReducer"; updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + try { return updateReducer(reducer, initialArg, init); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useRef: function(initialValue) { currentHookNameInDev = "useRef"; updateHookTypesDev(); - return updateRef(initialValue); + return updateRef(); }, useState: function(initialState) { currentHookNameInDev = "useState"; updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + try { return updateState(initialState); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useDebugValue: function(value, formatterFn) { currentHookNameInDev = "useDebugValue"; updateHookTypesDev(); - return updateDebugValue(value, formatterFn); + return updateDebugValue(); }, useResponder: function(responder, props) { currentHookNameInDev = "useResponder"; updateHookTypesDev(); - return createResponderListener(responder, props); + return createDeprecatedResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; @@ -12182,111 +11003,110 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; currentHookNameInDev = "useTransition"; updateHookTypesDev(); return updateTransition(config); + }, + useEvent: function(event) { + currentHookNameInDev = "useEvent"; + updateHookTypesDev(); + return updateEventListener(); } }; - InvalidNestedHooksDispatcherOnMountInDEV = { + HooksDispatcherOnRerenderInDEV = { readContext: function(context, observedBits) { - warnInvalidContextAccess(); return readContext(context, observedBits); }, useCallback: function(callback, deps) { currentHookNameInDev = "useCallback"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountCallback(callback, deps); + updateHookTypesDev(); + return updateCallback(callback, deps); }, useContext: function(context, observedBits) { currentHookNameInDev = "useContext"; - warnInvalidHookAccess(); - mountHookTypesDev(); + updateHookTypesDev(); return readContext(context, observedBits); }, useEffect: function(create, deps) { currentHookNameInDev = "useEffect"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountEffect(create, deps); + updateHookTypesDev(); + return updateEffect(create, deps); }, useImperativeHandle: function(ref, create, deps) { currentHookNameInDev = "useImperativeHandle"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountImperativeHandle(ref, create, deps); + updateHookTypesDev(); + return updateImperativeHandle(ref, create, deps); }, useLayoutEffect: function(create, deps) { currentHookNameInDev = "useLayoutEffect"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountLayoutEffect(create, deps); + updateHookTypesDev(); + return updateLayoutEffect(create, deps); }, useMemo: function(create, deps) { currentHookNameInDev = "useMemo"; - warnInvalidHookAccess(); - mountHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnRerenderInDEV; + try { - return mountMemo(create, deps); + return updateMemo(create, deps); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useReducer: function(reducer, initialArg, init) { currentHookNameInDev = "useReducer"; - warnInvalidHookAccess(); - mountHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnRerenderInDEV; + try { - return mountReducer(reducer, initialArg, init); + return rerenderReducer(reducer, initialArg, init); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useRef: function(initialValue) { currentHookNameInDev = "useRef"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountRef(initialValue); + updateHookTypesDev(); + return updateRef(); }, useState: function(initialState) { currentHookNameInDev = "useState"; - warnInvalidHookAccess(); - mountHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnRerenderInDEV; + try { - return mountState(initialState); + return rerenderState(initialState); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useDebugValue: function(value, formatterFn) { currentHookNameInDev = "useDebugValue"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountDebugValue(value, formatterFn); + updateHookTypesDev(); + return updateDebugValue(); }, useResponder: function(responder, props) { currentHookNameInDev = "useResponder"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return createResponderListener(responder, props); + updateHookTypesDev(); + return createDeprecatedResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountDeferredValue(value, config); + updateHookTypesDev(); + return rerenderDeferredValue(value, config); }, useTransition: function(config) { currentHookNameInDev = "useTransition"; - warnInvalidHookAccess(); - mountHookTypesDev(); - return mountTransition(config); + updateHookTypesDev(); + return rerenderTransition(config); + }, + useEvent: function(event) { + currentHookNameInDev = "useEvent"; + updateHookTypesDev(); + return updateEventListener(); } }; - InvalidNestedHooksDispatcherOnUpdateInDEV = { + InvalidNestedHooksDispatcherOnMountInDEV = { readContext: function(context, observedBits) { warnInvalidContextAccess(); return readContext(context, observedBits); @@ -12294,2504 +11114,1125 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; useCallback: function(callback, deps) { currentHookNameInDev = "useCallback"; warnInvalidHookAccess(); - updateHookTypesDev(); - return updateCallback(callback, deps); + mountHookTypesDev(); + return mountCallback(callback, deps); }, useContext: function(context, observedBits) { currentHookNameInDev = "useContext"; warnInvalidHookAccess(); - updateHookTypesDev(); + mountHookTypesDev(); return readContext(context, observedBits); }, useEffect: function(create, deps) { currentHookNameInDev = "useEffect"; warnInvalidHookAccess(); - updateHookTypesDev(); - return updateEffect(create, deps); + mountHookTypesDev(); + return mountEffect(create, deps); }, useImperativeHandle: function(ref, create, deps) { currentHookNameInDev = "useImperativeHandle"; warnInvalidHookAccess(); - updateHookTypesDev(); - return updateImperativeHandle(ref, create, deps); + mountHookTypesDev(); + return mountImperativeHandle(ref, create, deps); }, useLayoutEffect: function(create, deps) { currentHookNameInDev = "useLayoutEffect"; warnInvalidHookAccess(); - updateHookTypesDev(); - return updateLayoutEffect(create, deps); + mountHookTypesDev(); + return mountLayoutEffect(create, deps); }, useMemo: function(create, deps) { currentHookNameInDev = "useMemo"; warnInvalidHookAccess(); - updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + mountHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; + try { - return updateMemo(create, deps); + return mountMemo(create, deps); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useReducer: function(reducer, initialArg, init) { currentHookNameInDev = "useReducer"; warnInvalidHookAccess(); - updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + mountHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; + try { - return updateReducer(reducer, initialArg, init); + return mountReducer(reducer, initialArg, init); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useRef: function(initialValue) { currentHookNameInDev = "useRef"; warnInvalidHookAccess(); - updateHookTypesDev(); - return updateRef(initialValue); + mountHookTypesDev(); + return mountRef(initialValue); }, useState: function(initialState) { currentHookNameInDev = "useState"; warnInvalidHookAccess(); - updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + mountHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; + try { - return updateState(initialState); + return mountState(initialState); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useDebugValue: function(value, formatterFn) { currentHookNameInDev = "useDebugValue"; warnInvalidHookAccess(); - updateHookTypesDev(); - return updateDebugValue(value, formatterFn); + mountHookTypesDev(); + return mountDebugValue(); }, useResponder: function(responder, props) { currentHookNameInDev = "useResponder"; warnInvalidHookAccess(); - updateHookTypesDev(); - return createResponderListener(responder, props); + mountHookTypesDev(); + return createDeprecatedResponderListener(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); + mountHookTypesDev(); + return mountTransition(config); + }, + useEvent: function(event) { + currentHookNameInDev = "useEvent"; + warnInvalidHookAccess(); + mountHookTypesDev(); + return mountEventListener(); } }; -} - -// 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. - - 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 (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, - shouldUpdate, - hasContext, - renderExpirationTime -) { - // 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 - ); - } - - 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 { - { - 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); - } - - return workInProgress.child; -} - -function pushHostRootContext(workInProgress) { - var root = workInProgress.stateNode; - if (root.pendingContext) { - pushTopLevelContextObject( - workInProgress, - root.pendingContext, - root.pendingContext !== root.context - ); - } else if (root.context) { - // Should always be set - pushTopLevelContextObject(workInProgress, root.context, false); - } - pushHostContainer(workInProgress, root.containerInfo); -} - -function updateHostRoot(current$$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." - ); - } - - 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 - ); - 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 updateHostComponent(current$$1, workInProgress, renderExpirationTime) { - pushHostContext(workInProgress); - - 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, - nextChildren, - renderExpirationTime - ); - return workInProgress.child; -} - -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, - elementType, - updateExpirationTime, - renderExpirationTime -) { - 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 - - 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 - ); - 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; - } - - 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 - ); - } - } - } - - return 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. - - 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, - Component, - true, - hasContext, - renderExpirationTime - ); -} - -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 - - workInProgress.effectTag |= Placement; - } - - var props = workInProgress.pendingProps; - var context; - - if (!disableLegacyContext) { - 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"; - - 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; - } - } - - if (workInProgress.mode & StrictMode) { - ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null); - } - - ReactCurrentOwner$3.current = workInProgress; - value = renderWithHooks( - null, - workInProgress, - Component, - props, - context, - renderExpirationTime - ); - } // React DevTools reads this flag. - - workInProgress.effectTag |= PerformedWork; - - 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 - - workInProgress.tag = ClassComponent; // Throw out any hooks that were used. + 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; - 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. + 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; - var hasContext = false; + 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; - if (isContextProvider(Component)) { - hasContext = true; - pushContextProvider(workInProgress); - } else { - hasContext = false; + try { + return updateState(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 updateDeferredValue(value, config); + }, + useTransition: function(config) { + currentHookNameInDev = "useTransition"; + 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; - workInProgress.memoizedState = - value.state !== null && value.state !== undefined ? value.state : null; - var getDerivedStateFromProps = Component.getDerivedStateFromProps; - - if (typeof getDerivedStateFromProps === "function") { - applyDerivedStateFromProps( - workInProgress, - Component, - getDerivedStateFromProps, - props - ); - } + 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; - 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" - ); + 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; - if ( - debugRenderPhaseSideEffectsForStrictMode && - workInProgress.mode & StrictMode - ) { - // Only double-render components with Hooks - if (workInProgress.memoizedState !== null) { - value = renderWithHooks( - null, - workInProgress, - Component, - props, - context, - renderExpirationTime - ); - } + 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(); } + }; +} - reconcileChildren(null, workInProgress, value, renderExpirationTime); +var now$1 = Scheduler.unstable_now; +var commitTime = 0; +var profilerStartTime = -1; - { - validateFunctionComponentInDev(workInProgress, Component); - } +function getCommitTime() { + return commitTime; +} - return workInProgress.child; - } +function recordCommitTime() { + commitTime = now$1(); } -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 startProfilerTimer(fiber) { + profilerStartTime = now$1(); + + if (fiber.actualStartTime < 0) { + fiber.actualStartTime = now$1(); } +} + +function stopProfilerTimerIfRunning(fiber) { + profilerStartTime = -1; +} - if (workInProgress.ref !== null) { - var info = ""; - var ownerName = getCurrentFiberOwnerNameInDevOrNull(); +function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) { + if (profilerStartTime >= 0) { + var elapsedTime = now$1() - profilerStartTime; + fiber.actualDuration += elapsedTime; - if (ownerName) { - info += "\n\nCheck the render method of `" + ownerName + "`."; + if (overrideBaseTime) { + fiber.selfBaseDuration = elapsedTime; } - var warningKey = ownerName || workInProgress._debugID || ""; - var debugSource = workInProgress._debugSource; + profilerStartTime = -1; + } +} - if (debugSource) { - warningKey = debugSource.fileName + ":" + debugSource.lineNumber; - } +function enterHydrationState(fiber) { + { + return false; + } +} - 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 +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." ); } } +} - 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 +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." ); - didWarnAboutDefaultPropsOnFunctionComponent[componentName] = true; } } + var shouldUpdate = hydrateTextInstance(); +} - 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; - } +function popHydrationState(fiber) { + { + return false; } +} + +var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner; +var didReceiveUpdate = false; +var didWarnAboutBadClass; +var didWarnAboutModulePatternComponent; +var didWarnAboutContextTypeOnFunctionComponent; +var didWarnAboutGetDerivedStateOnFunctionComponent; +var didWarnAboutFunctionRefs; +var didWarnAboutReassigningProps; +var didWarnAboutRevealOrder; +var didWarnAboutTailOptions; - if ( - typeof Component.contextType === "object" && - Component.contextType !== null - ) { - var _componentName3 = getComponentName(Component) || "Unknown"; +{ + didWarnAboutBadClass = {}; + didWarnAboutModulePatternComponent = {}; + didWarnAboutContextTypeOnFunctionComponent = {}; + didWarnAboutGetDerivedStateOnFunctionComponent = {}; + didWarnAboutFunctionRefs = {}; + didWarnAboutReassigningProps = false; + didWarnAboutRevealOrder = {}; + didWarnAboutTailOptions = {}; +} - if (!didWarnAboutContextTypeOnFunctionComponent[_componentName3]) { - warningWithoutStack$1( - false, - "%s: Function components do not support contextType.", - _componentName3 - ); - didWarnAboutContextTypeOnFunctionComponent[_componentName3] = true; - } +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 + ); } } -var SUSPENDED_MARKER = { - dehydrated: null, - retryTime: NoWork -}; +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 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) + workInProgress.child = reconcileChildFibers( + workInProgress, + null, + nextChildren, + renderExpirationTime ); } -function updateSuspenseComponent( - current$$1, +function updateForwardRef( + current, workInProgress, + Component, + nextProps, renderExpirationTime ) { - var mode = workInProgress.mode; - var nextProps = workInProgress.pendingProps; // This is used by DevTools to force a boundary to suspend. - + // 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 (shouldSuspend(workInProgress)) { - workInProgress.effectTag |= DidCapture; - } - } - - var suspenseContext = suspenseStackCursor.current; - var nextDidTimeout = false; - var didSuspend = (workInProgress.effectTag & DidCapture) !== NoEffect; + if (workInProgress.type !== workInProgress.elementType) { + // Lazy component props can't be validated in createElement + // because they're only guaranteed to be resolved here. + var innerPropTypes = Component.propTypes; - if ( - didSuspend || - shouldRemainOnFallback(suspenseContext, current$$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 + if (innerPropTypes) { + checkPropTypes( + innerPropTypes, + nextProps, // Resolved props + "prop", + getComponentName(Component) ); } } } - suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); - pushSuspenseContext(workInProgress, suspenseContext); + var render = Component.render; + var ref = workInProgress.ref; // The rest is a fork of updateFunctionComponent - { - 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, + render, + nextProps, + ref, + renderExpirationTime + ); - if (enableSuspenseServerRenderer) { - var suspenseState = workInProgress.memoizedState; + setIsRendering(false); + } - if (suspenseState !== null) { - var dehydrated = suspenseState.dehydrated; + if (current !== null && !didReceiveUpdate) { + bailoutHooks(current, workInProgress, renderExpirationTime); + return bailoutOnAlreadyFinishedWork( + current, + workInProgress, + renderExpirationTime + ); + } // React DevTools reads this flag. - 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. + workInProgress.effectTag |= PerformedWork; + reconcileChildren( + current, + workInProgress, + nextChildren, + renderExpirationTime + ); + return workInProgress.child; +} - if (nextDidTimeout) { - // Mount separate fragments for primary and fallback children. - var nextFallbackChildren = nextProps.fallback; - var primaryChildFragment = createFiberFromFragment( - null, - mode, - NoWork, - null - ); - primaryChildFragment.return = workInProgress; +function updateMemoComponent( + current, + workInProgress, + Component, + nextProps, + updateExpirationTime, + renderExpirationTime +) { + if (current === null) { + var type = Component.type; - 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; - } - } + if ( + isSimpleFunctionComponent(type) && + Component.compare === null && // SimpleMemoComponent codepath doesn't resolve outer props either. + Component.defaultProps === undefined + ) { + var resolvedType = type; - var fallbackChildFragment = createFiberFromFragment( - nextFallbackChildren, - mode, - renderExpirationTime, - null - ); - fallbackChildFragment.return = workInProgress; - primaryChildFragment.sibling = fallbackChildFragment; // Skip the primary children, and continue working on the - // fallback children. + { + 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.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.tag = SimpleMemoComponent; + workInProgress.type = resolvedType; + + { + validateFunctionComponentInDev(workInProgress, type); + } + + return updateSimpleMemoComponent( + current, workInProgress, - null, - nextPrimaryChildren, + resolvedType, + nextProps, + updateExpirationTime, 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 - ); + { + var innerPropTypes = type.propTypes; - _primaryChildFragment.return = workInProgress; // This is always null since we never want the previous child - // that we're not going to hydrate. + 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) + ); + } + } - _primaryChildFragment.child = null; + var child = createFiberFromTypeAndProps( + Component.type, + null, + nextProps, + null, + workInProgress.mode, + renderExpirationTime + ); + child.ref = workInProgress.ref; + child.return = workInProgress; + workInProgress.child = child; + return child; + } - 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); + { + var _type = Component.type; + var _innerPropTypes = _type.propTypes; - 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 (_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 (enableProfilerTimer && workInProgress.mode & ProfileMode) { - // treeBaseDuration is the sum of all the child tree base durations. - var treeBaseDuration = 0; - var hiddenChild = _primaryChildFragment.child; + var currentChild = current.child; // This is always exactly one child - while (hiddenChild !== null) { - treeBaseDuration += hiddenChild.treeBaseDuration; - hiddenChild = hiddenChild.sibling; - } + 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 - _primaryChildFragment.treeBaseDuration = treeBaseDuration; - } // Create a fragment from the fallback children, too. + var compare = Component.compare; + compare = compare !== null ? compare : shallowEqual; - var _fallbackChildFragment = createFiberFromFragment( - _nextFallbackChildren, - mode, - renderExpirationTime, - null - ); + if (compare(prevProps, nextProps) && current.ref === workInProgress.ref) { + return bailoutOnAlreadyFinishedWork( + current, + workInProgress, + renderExpirationTime + ); + } + } // React DevTools reads this flag. - _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. + workInProgress.effectTag |= PerformedWork; + var newChild = createWorkInProgress(currentChild, nextProps); + newChild.ref = workInProgress.ref; + newChild.return = workInProgress; + workInProgress.child = newChild; + return newChild; +} - return _fallbackChildFragment; - } - } - } // The current tree already timed out. That means each child set is - // wrapped in a fragment fiber. +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; - var currentPrimaryChildFragment = current$$1.child; - var currentFallbackChildFragment = currentPrimaryChildFragment.sibling; + 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 (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 outerPropTypes = outerMemoType && outerMemoType.propTypes; - var _primaryChildFragment2 = createWorkInProgress( - currentPrimaryChildFragment, - currentPrimaryChildFragment.pendingProps, - NoWork + if (outerPropTypes) { + checkPropTypes( + outerPropTypes, + nextProps, // Resolved (SimpleMemoComponent has no defaultProps) + "prop", + getComponentName(outerMemoType) ); + } // Inner propTypes will be validated in the function component path. + } + } - _primaryChildFragment2.return = workInProgress; + if (current !== null) { + var prevProps = current.memoizedProps; - 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 ( + shallowEqual(prevProps, nextProps) && + current.ref === workInProgress.ref && // Prevent bailout if the implementation changed due to hot reload. + workInProgress.type === current.type + ) { + didReceiveUpdate = false; - var _progressedPrimaryChild = - _progressedState !== null - ? workInProgress.child.child - : workInProgress.child; + 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 + ); + } + } + } - if (_progressedPrimaryChild !== currentPrimaryChildFragment.child) { - _primaryChildFragment2.child = _progressedPrimaryChild; - var _progressedChild2 = _progressedPrimaryChild; + return updateFunctionComponent( + current, + workInProgress, + Component, + nextProps, + renderExpirationTime + ); +} - 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. +function updateFragment(current, workInProgress, renderExpirationTime) { + var nextChildren = workInProgress.pendingProps; + reconcileChildren( + current, + workInProgress, + nextChildren, + renderExpirationTime + ); + return workInProgress.child; +} - if (enableProfilerTimer && workInProgress.mode & ProfileMode) { - // treeBaseDuration is the sum of all the child tree base durations. - var _treeBaseDuration = 0; - var _hiddenChild = _primaryChildFragment2.child; +function updateMode(current, workInProgress, renderExpirationTime) { + var nextChildren = workInProgress.pendingProps.children; + reconcileChildren( + current, + workInProgress, + nextChildren, + renderExpirationTime + ); + return workInProgress.child; +} - while (_hiddenChild !== null) { - _treeBaseDuration += _hiddenChild.treeBaseDuration; - _hiddenChild = _hiddenChild.sibling; - } +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, - _primaryChildFragment2.treeBaseDuration = _treeBaseDuration; - } // Clone the fallback child fragment, too. These we'll continue - // working on. + var stateNode = workInProgress.stateNode; + stateNode.effectDuration = 0; + stateNode.passiveEffectDuration = 0; + } - var _fallbackChildFragment2 = createWorkInProgress( - currentFallbackChildFragment, - _nextFallbackChildren2, - currentFallbackChildFragment.expirationTime - ); + var nextProps = workInProgress.pendingProps; + var nextChildren = nextProps.children; + reconcileChildren( + current, + workInProgress, + nextChildren, + renderExpirationTime + ); + return workInProgress.child; +} - _fallbackChildFragment2.return = workInProgress; - _primaryChildFragment2.sibling = _fallbackChildFragment2; - _primaryChildFragment2.childExpirationTime = NoWork; // Skip the primary children, and continue working on the - // fallback children. +function markRef(current, workInProgress) { + var ref = workInProgress.ref; - 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 ( + (current === null && ref !== null) || + (current !== null && current.ref !== ref) + ) { + // Schedule a Ref effect + workInProgress.effectTag |= Ref; + } +} + +function updateFunctionComponent( + 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 = null; - return (workInProgress.child = primaryChild); + if (innerPropTypes) { + checkPropTypes( + innerPropTypes, + nextProps, // Resolved props + "prop", + getComponentName(Component) + ); } - } 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; + } + } - if (nextDidTimeout) { - // Timed out. Wrap the children in a fragment fiber to keep them - // separate from the fallback children. - var _nextFallbackChildren3 = nextProps.fallback; + var context; - 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 unmaskedContext = getUnmaskedContext(workInProgress, Component, true); + context = getMaskedContext(workInProgress, unmaskedContext); + } - _primaryChildFragment3.return = workInProgress; - _primaryChildFragment3.child = _currentPrimaryChild; + var nextChildren; + prepareToReadContext(workInProgress, renderExpirationTime); - 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; + { + ReactCurrentOwner$1.current = workInProgress; + setIsRendering(true); + nextChildren = renderWithHooks( + current, + workInProgress, + Component, + nextProps, + context, + renderExpirationTime + ); - 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; + setIsRendering(false); + } - var _progressedPrimaryChild2 = - _progressedState2 !== null - ? workInProgress.child.child - : workInProgress.child; + if (current !== null && !didReceiveUpdate) { + bailoutHooks(current, workInProgress, renderExpirationTime); + return bailoutOnAlreadyFinishedWork( + current, + workInProgress, + renderExpirationTime + ); + } // React DevTools reads this flag. - _primaryChildFragment3.child = _progressedPrimaryChild2; - var _progressedChild3 = _progressedPrimaryChild2; + workInProgress.effectTag |= PerformedWork; + reconcileChildren( + current, + 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 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; - if (enableProfilerTimer && workInProgress.mode & ProfileMode) { - // treeBaseDuration is the sum of all the child tree base durations. - var _treeBaseDuration2 = 0; - var _hiddenChild2 = _primaryChildFragment3.child; + 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. - while (_hiddenChild2 !== null) { - _treeBaseDuration2 += _hiddenChild2.treeBaseDuration; - _hiddenChild2 = _hiddenChild2.sibling; - } + var hasContext; - _primaryChildFragment3.treeBaseDuration = _treeBaseDuration2; - } // Create a fragment from the fallback children, too. + if (isContextProvider(Component)) { + hasContext = true; + pushContextProvider(workInProgress); + } else { + hasContext = false; + } - var _fallbackChildFragment3 = createFiberFromFragment( - _nextFallbackChildren3, - mode, - renderExpirationTime, - null - ); + prepareToReadContext(workInProgress, renderExpirationTime); + var instance = workInProgress.stateNode; + var shouldUpdate; - _fallbackChildFragment3.return = workInProgress; - _primaryChildFragment3.sibling = _fallbackChildFragment3; - _fallbackChildFragment3.effectTag |= Placement; - _primaryChildFragment3.childExpirationTime = NoWork; // Skip the primary children, and continue working on the - // fallback children. + 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.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 - )); + 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, + workInProgress, + Component, + shouldUpdate, + 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 retrySuspenseComponentWithoutHydrating( - current$$1, +function finishClassComponent( + current, workInProgress, + Component, + shouldUpdate, + hasContext, renderExpirationTime ) { - // We're now not suspended nor dehydrated. - workInProgress.memoizedState = null; // Retry with the full children. + // 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); + } + + return bailoutOnAlreadyFinishedWork( + current, + workInProgress, + renderExpirationTime + ); + } + + var instance = workInProgress.stateNode; // Rerender + + ReactCurrentOwner$1.current = workInProgress; + var nextChildren; + + if ( + didCaptureError && + typeof Component.getDerivedStateFromError !== "function" + ) { + // If we captured an error, but getDerivedStateFromError is not defined, + // unmount all the children. componentDidCatch will schedule an update to + // re-render a fallback. This is temporary until we migrate everyone to + // the new API. + // TODO: Warn in a future release. + nextChildren = null; + + { + stopProfilerTimerIfRunning(); + } + } else { + { + setIsRendering(true); + nextChildren = instance.render(); + + setIsRendering(false); + } + } // React DevTools reads this flag. + + workInProgress.effectTag |= PerformedWork; + + if (current !== null && didCaptureError) { + // If we're recovering from an error, reconcile without reusing any of + // the existing children. Conceptually, the normal children and the children + // that are shown on error are two different sets, so we shouldn't reuse + // normal children even if their identities match. + forceUnmountCurrentAndReconcile( + current, + workInProgress, + nextChildren, + 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. - 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.memoizedState = instance.state; // The context might have changed so we need to recalculate it. + + if (hasContext) { + invalidateContextProvider(workInProgress, Component, true); + } - 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. +function pushHostRootContext(workInProgress) { + var root = workInProgress.stateNode; - var newExpirationTime = computeAsyncExpiration(serverDisplayTime); + if (root.pendingContext) { + pushTopLevelContextObject( + workInProgress, + root.pendingContext, + root.pendingContext !== root.context + ); + } else if (root.context) { + // Should always be set + pushTopLevelContextObject(workInProgress, root.context, false); + } - if (enableSchedulerTracing) { - markSpawnedWork(newExpirationTime); - } + pushHostContainer(workInProgress, root.containerInfo); +} - 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; +function updateHostRoot(current, workInProgress, renderExpirationTime) { + pushHostRootContext(workInProgress); + var updateQueue = workInProgress.updateQueue; - if (enableSchedulerTracing) { - markSpawnedWork(Never); - } + 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." + ); } - return null; -} + 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". -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(); + var nextChildren = nextState.element; - if ((workInProgress.mode & BlockingMode) === NoMode) { - return retrySuspenseComponentWithoutHydrating( - current$$1, + if (nextChildren === prevChildren) { + return bailoutOnAlreadyFinishedWork( + current, 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 root = workInProgress.stateNode; + + 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; while (node) { @@ -14801,4133 +12242,3596 @@ function updateDehydratedSuspenseComponent( // 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.effectTag = (node.effectTag & ~Placement) | Hydrating; node = node.sibling; } - - workInProgress.child = child; - return workInProgress.child; - } -} - -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 (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; - } -} - -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; - } - - return lastContentRow; -} - -function validateRevealOrder(revealOrder) { - { - if ( - revealOrder !== undefined && - revealOrder !== "forwards" && - revealOrder !== "backwards" && - revealOrder !== "together" && - !didWarnAboutRevealOrder[revealOrder] - ) { - didWarnAboutRevealOrder[revealOrder] = true; - if (typeof revealOrder === "string") { - switch (revealOrder.toLowerCase()) { - case "together": - case "forwards": - case "backwards": { - 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 - ); - } - } - } -} - -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 - ); - } - } - } -} - -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; - } + } else { + // Otherwise reset hydration state in case we aborted and resumed another + // root. + reconcileChildren( + current, + workInProgress, + nextChildren, + renderExpirationTime + ); } - return true; -} -function validateSuspenseListChildren(children, revealOrder) { - { - if ( - (revealOrder === "forwards" || revealOrder === "backwards") && - children !== undefined && - children !== null && - children !== false - ) { - if (Array.isArray(children)) { - for (var i = 0; i < children.length; i++) { - if (!validateSuspenseListNestedChild(children[i], i)) { - return; - } - } - } else { - var iteratorFn = getIteratorFn(children); + return workInProgress.child; +} - if (typeof iteratorFn === "function") { - var childrenIterator = iteratorFn.call(children); +function updateHostComponent(current, workInProgress, renderExpirationTime) { + pushHostContext(workInProgress); - if (childrenIterator) { - var step = childrenIterator.next(); - var _i = 0; + var type = workInProgress.type; + var nextProps = workInProgress.pendingProps; + var prevProps = current !== null ? current.memoizedProps : null; + var nextChildren = nextProps.children; - 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 - ); - } - } - } + 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; } -} -function initSuspenseListRenderState( - workInProgress, - isBackwards, - tail, - lastContentRow, - tailMode, - lastEffectBeforeRendering -) { - var renderState = workInProgress.memoizedState; + markRef(current, workInProgress); // Check the host config to see if the children are offscreen/hidden. - 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; + 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; } -} // 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, + current, workInProgress, - newChildren, + nextChildren, 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 updateHostText(current, workInProgress) { + // immediately after. + + return null; +} + +function mountLazyComponent( + _current, + 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 + + workInProgress.effectTag |= Placement; } - pushSuspenseContext(workInProgress, suspenseContext); + 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. - 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; + cancelWorkTimer(workInProgress); + var Component = readLazyComponentType(elementType); // Store the unwrapped component in the type. - 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 + 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 ); - break; } - case "backwards": { - // We're going to find the first row that has existing content. - // At the same time we're going to reverse the list of everything - // we pass in the meantime. That's going to be our tail in reverse - // order. - var _tail = null; - var row = workInProgress.child; - workInProgress.child = null; - - while (row !== null) { - var currentRow = row.alternate; // New rows can't be content rows. - - if (currentRow !== null && findFirstSuspended(currentRow) === null) { - // This is the beginning of the main content. - workInProgress.child = row; - break; - } - var nextRow = row.sibling; - row.sibling = _tail; - _tail = row; - row = nextRow; - } // TODO: If workInProgress.child is null, we can continue on the tail immediately. + child = updateFunctionComponent( + null, + workInProgress, + Component, + resolvedProps, + renderExpirationTime + ); + return child; + } - initSuspenseListRenderState( - workInProgress, - true, // isBackwards - _tail, - null, // last - tailMode, - workInProgress.lastEffect + case ClassComponent: { + { + workInProgress.type = Component = resolveClassForHotReloading( + Component ); - break; } - case "together": { - initSuspenseListRenderState( - workInProgress, - false, // isBackwards - null, // tail - null, // last - undefined, - workInProgress.lastEffect + child = updateClassComponent( + null, + workInProgress, + Component, + resolvedProps, + renderExpirationTime + ); + return child; + } + + case ForwardRef: { + { + workInProgress.type = Component = resolveForwardRefForHotReloading( + Component ); - break; } - default: { - // The default reveal order is the same as not having - // a boundary. - workInProgress.memoizedState = null; + child = updateForwardRef( + null, + workInProgress, + Component, + resolvedProps, + renderExpirationTime + ); + return child; + } + + case MemoComponent: { + { + if (workInProgress.type !== workInProgress.elementType) { + var outerPropTypes = Component.propTypes; + + if (outerPropTypes) { + checkPropTypes( + outerPropTypes, + resolvedProps, // Resolved for outer only + "prop", + getComponentName(Component) + ); + } + } } + + child = updateMemoComponent( + null, + workInProgress, + Component, + resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too + updateExpirationTime, + renderExpirationTime + ); + return child; } } - return workInProgress.child; -} -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 + 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 ); } - return workInProgress.child; } -function updateContextProvider( - current$$1, +function mountIncompleteClassComponent( + _current, workInProgress, + Component, + nextProps, renderExpirationTime ) { - var providerType = workInProgress.type; - var context = providerType._context; - var newProps = workInProgress.pendingProps; - var oldProps = workInProgress.memoizedProps; - var newValue = newProps.value; + if (_current !== null) { + // An incomplete component only mounts if it suspended inside a non- + // concurrent tree, in an inconsistent state. We want to treat it like + // a new mount, even though an empty version of it already committed. + // Disconnect the alternate pointers. + _current.alternate = null; + workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect - { - var providerPropTypes = workInProgress.type.propTypes; + workInProgress.effectTag |= Placement; + } // Promote the fiber to a class and try rendering again. - if (providerPropTypes) { - checkPropTypes( - providerPropTypes, - newProps, - "prop", - "Context.Provider", - getCurrentFiberStackInDev - ); - } - } + 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. - pushProvider(workInProgress, newValue); + var hasContext; - 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 - ); - } + if (isContextProvider(Component)) { + hasContext = true; + pushContextProvider(workInProgress); + } else { + hasContext = false; } - var newChildren = newProps.children; - reconcileChildren( - current$$1, + prepareToReadContext(workInProgress, renderExpirationTime); + constructClassInstance(workInProgress, Component, nextProps); + mountClassInstance( workInProgress, - newChildren, + Component, + nextProps, + renderExpirationTime + ); + return finishClassComponent( + null, + workInProgress, + Component, + true, + hasContext, renderExpirationTime ); - return workInProgress.child; } -var hasWarnedAboutUsingContextAsConsumer = false; - -function updateContextConsumer( - current$$1, +function mountIndeterminateComponent( + _current, workInProgress, + Component, 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 { - context = context._context; - } + 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 newProps = workInProgress.pendingProps; - var render = newProps.children; + + var props = workInProgress.pendingProps; + var context; { - !(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 unmaskedContext = getUnmaskedContext(workInProgress, Component, false); + context = getMaskedContext(workInProgress, unmaskedContext); } prepareToReadContext(workInProgress, renderExpirationTime); - var newValue = readContext(context, newProps.unstable_observedBits); - var newChildren; + var value; { - ReactCurrentOwner$3.current = workInProgress; - setCurrentPhase("render"); - newChildren = render(newValue); - setCurrentPhase(null); + if ( + Component.prototype && + typeof Component.prototype.render === "function" + ) { + var componentName = getComponentName(Component) || "Unknown"; + + if (!didWarnAboutBadClass[componentName]) { + error( + "The <%s /> component appears to have a render method, but doesn't extend React.Component. " + + "This is likely to cause errors. Change %s to extend React.Component instead.", + componentName, + componentName + ); + + didWarnAboutBadClass[componentName] = true; + } + } + + if (workInProgress.mode & StrictMode) { + ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null); + } + + ReactCurrentOwner$1.current = workInProgress; + value = renderWithHooks( + null, + workInProgress, + Component, + props, + context, + renderExpirationTime + ); } // React DevTools reads this flag. workInProgress.effectTag |= PerformedWork; - reconcileChildren( - current$$1, - workInProgress, - newChildren, - renderExpirationTime - ); - return workInProgress.child; -} -function updateFundamentalComponent$1( - current$$1, - workInProgress, - renderExpirationTime -) { - var fundamentalImpl = workInProgress.type.impl; + if ( + typeof value === "object" && + value !== null && + typeof value.render === "function" && + value.$$typeof === undefined + ) { + { + var _componentName = getComponentName(Component) || "Unknown"; + + if (!didWarnAboutModulePatternComponent[_componentName]) { + error( + "The <%s /> component appears to be a function component that returns a class instance. " + + "Change %s to a class that extends React.Component instead. " + + "If you can't use a class try assigning the prototype on the function as a workaround. " + + "`%s.prototype = React.Component.prototype`. Don't use an arrow function since it " + + "cannot be called with `new` by React.", + _componentName, + _componentName, + _componentName + ); - if (fundamentalImpl.reconcileChildren === false) { - return null; - } + didWarnAboutModulePatternComponent[_componentName] = true; + } + } // Proceed under the assumption that this is a class instance - var nextProps = workInProgress.pendingProps; - var nextChildren = nextProps.children; - reconcileChildren( - current$$1, - workInProgress, - nextChildren, - renderExpirationTime - ); - return workInProgress.child; -} + workInProgress.tag = ClassComponent; // Throw out any hooks that were used. -function updateScopeComponent( - current$$1, - workInProgress, - renderExpirationTime -) { - var nextProps = workInProgress.pendingProps; - var nextChildren = nextProps.children; - reconcileChildren( - current$$1, - workInProgress, - nextChildren, - renderExpirationTime - ); - return workInProgress.child; -} + workInProgress.memoizedState = null; + workInProgress.updateQueue = null; // Push context providers early to prevent context stack mismatches. + // During mounting we don't know the child context yet as the instance doesn't exist. + // We will invalidate the child context in finishClassComponent() right after rendering. -function markWorkInProgressReceivedUpdate() { - didReceiveUpdate = true; -} + var hasContext = false; -function bailoutOnAlreadyFinishedWork( - current$$1, - workInProgress, - renderExpirationTime -) { - cancelWorkTimer(workInProgress); + if (isContextProvider(Component)) { + hasContext = true; + pushContextProvider(workInProgress); + } else { + hasContext = false; + } - if (current$$1 !== null) { - // Reuse previous dependencies - workInProgress.dependencies = current$$1.dependencies; - } + workInProgress.memoizedState = + value.state !== null && value.state !== undefined ? value.state : null; + initializeUpdateQueue(workInProgress); + var getDerivedStateFromProps = Component.getDerivedStateFromProps; - if (enableProfilerTimer) { - // Don't update "base" render times for bailouts. - stopProfilerTimerIfRunning(workInProgress); - } + if (typeof getDerivedStateFromProps === "function") { + applyDerivedStateFromProps( + workInProgress, + Component, + getDerivedStateFromProps, + props + ); + } - var updateExpirationTime = workInProgress.expirationTime; + 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 (updateExpirationTime !== NoWork) { - markUnprocessedUpdateTime(updateExpirationTime); - } // Check if the children have any pending work. + reconcileChildren(null, workInProgress, value, renderExpirationTime); - var childExpirationTime = workInProgress.childExpirationTime; + { + validateFunctionComponentInDev(workInProgress, Component); + } - 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 remountFiber(current$$1, oldWorkInProgress, newWorkInProgress) { +function validateFunctionComponentInDev(workInProgress, Component) { { - var returnFiber = oldWorkInProgress.return; - - if (returnFiber === null) { - throw new Error("Cannot swap the root fiber."); - } // Disconnect from the old current. - // It will get deleted. - - current$$1.alternate = null; - oldWorkInProgress.alternate = null; // Connect to the new tree. - - newWorkInProgress.index = oldWorkInProgress.index; - newWorkInProgress.sibling = oldWorkInProgress.sibling; - newWorkInProgress.return = oldWorkInProgress.return; - newWorkInProgress.ref = oldWorkInProgress.ref; // Replace the child/sibling pointers above it. + if (Component) { + if (Component.childContextTypes) { + error( + "%s(...): childContextTypes cannot be defined on a function component.", + Component.displayName || Component.name || "Component" + ); + } + } - if (oldWorkInProgress === returnFiber.child) { - returnFiber.child = newWorkInProgress; - } else { - var prevSibling = returnFiber.child; + if (workInProgress.ref !== null) { + var info = ""; + var ownerName = getCurrentFiberOwnerNameInDevOrNull(); - if (prevSibling === null) { - throw new Error("Expected parent to have a child."); + if (ownerName) { + info += "\n\nCheck the render method of `" + ownerName + "`."; } - while (prevSibling.sibling !== oldWorkInProgress) { - prevSibling = prevSibling.sibling; + var warningKey = ownerName || workInProgress._debugID || ""; + var debugSource = workInProgress._debugSource; - if (prevSibling === null) { - throw new Error("Expected to find the previous sibling."); - } + if (debugSource) { + warningKey = debugSource.fileName + ":" + debugSource.lineNumber; } - 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 (!didWarnAboutFunctionRefs[warningKey]) { + didWarnAboutFunctionRefs[warningKey] = true; - if (last !== null) { - last.nextEffect = current$$1; - returnFiber.lastEffect = current$$1; - } else { - returnFiber.firstEffect = returnFiber.lastEffect = current$$1; + error( + "Function components cannot be given refs. " + + "Attempts to access this ref will fail. " + + "Did you mean to use React.forwardRef()?%s", + info + ); + } } - current$$1.nextEffect = null; - current$$1.effectTag = Deletion; - newWorkInProgress.effectTag |= Placement; // Restart work from the new fiber. - - return newWorkInProgress; - } -} + if (typeof Component.getDerivedStateFromProps === "function") { + var _componentName2 = getComponentName(Component) || "Unknown"; -function beginWork$1(current$$1, workInProgress, renderExpirationTime) { - var updateExpirationTime = workInProgress.expirationTime; + if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2]) { + error( + "%s: Function components do not support getDerivedStateFromProps.", + _componentName2 + ); - { - 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 - ) - ); + didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2] = true; + } } - } - - 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 + typeof Component.contextType === "object" && + Component.contextType !== null ) { - // 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. - - switch (workInProgress.tag) { - case HostRoot: - pushHostRootContext(workInProgress); - resetHydrationState(); - break; + var _componentName3 = getComponentName(Component) || "Unknown"; - case HostComponent: - pushHostContext(workInProgress); + if (!didWarnAboutContextTypeOnFunctionComponent[_componentName3]) { + error( + "%s: Function components do not support contextType.", + _componentName3 + ); - 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. + didWarnAboutContextTypeOnFunctionComponent[_componentName3] = true; + } + } + } +} - workInProgress.expirationTime = workInProgress.childExpirationTime = Never; - return null; - } +var SUSPENDED_MARKER = { + dehydrated: null, + retryTime: NoWork +}; - break; +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) + ); +} - case ClassComponent: { - var Component = workInProgress.type; +function updateSuspenseComponent( + current, + workInProgress, + renderExpirationTime +) { + var mode = workInProgress.mode; + var nextProps = workInProgress.pendingProps; // This is used by DevTools to force a boundary to suspend. - if (isContextProvider(Component)) { - pushContextProvider(workInProgress); - } + { + if (shouldSuspend(workInProgress)) { + workInProgress.effectTag |= DidCapture; + } + } - break; - } + var suspenseContext = suspenseStackCursor.current; + var nextDidTimeout = false; + var didSuspend = (workInProgress.effectTag & DidCapture) !== NoEffect; - case HostPortal: - pushHostContainer( - workInProgress, - workInProgress.stateNode.containerInfo - ); - break; - case ContextProvider: { - var newValue = workInProgress.memoizedProps.value; - pushProvider(workInProgress, newValue); - break; - } + 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 + ); + } + } + } - case Profiler: - if (enableProfilerTimer) { - // Profiler should only call onRender when one of its descendants actually rendered. - var hasChildWork = - workInProgress.childExpirationTime >= 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 (hasChildWork) { - workInProgress.effectTag |= Update; - } - } + 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. - break; + if (nextDidTimeout) { + // Mount separate fragments for primary and fallback children. + var nextFallbackChildren = nextProps.fallback; + var primaryChildFragment = createFiberFromFragment( + null, + mode, + NoWork, + null + ); + primaryChildFragment.return = workInProgress; - case SuspenseComponent: { - var state = workInProgress.memoizedState; + 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 (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. + while (progressedChild !== null) { + progressedChild.return = primaryChildFragment; + progressedChild = progressedChild.sibling; + } + } - 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 fallbackChildFragment = createFiberFromFragment( + nextFallbackChildren, + mode, + renderExpirationTime, + null + ); + fallbackChildFragment.return = workInProgress; + primaryChildFragment.sibling = fallbackChildFragment; // Skip the primary children, and continue working on the + // fallback children. - var primaryChildFragment = workInProgress.child; - var primaryChildExpirationTime = - primaryChildFragment.childExpirationTime; + 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.memoizedState; - 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. + if (prevState !== null) { + // wrapped in a fragment fiber. - 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) - ); - } + var currentPrimaryChildFragment = current.child; + var currentFallbackChildFragment = currentPrimaryChildFragment.sibling; - break; - } + 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 SuspenseListComponent: { - var didSuspendBefore = - (current$$1.effectTag & DidCapture) !== NoEffect; + var _primaryChildFragment2 = createWorkInProgress( + currentPrimaryChildFragment, + currentPrimaryChildFragment.pendingProps + ); - var _hasChildWork = - workInProgress.childExpirationTime >= renderExpirationTime; + _primaryChildFragment2.return = workInProgress; - if (didSuspendBefore) { - if (_hasChildWork) { - // If something was in fallback state last time, and we have all the - // same children then we're still in progressive loading state. - // Something might get unblocked by state updates or retries in the - // tree which will affect the tail. So we need to use the normal - // path to compute the correct tail. - return updateSuspenseListComponent( - current$$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 ((workInProgress.mode & BlockingMode) === NoMode) { + // Outside of blocking mode, we commit the effects from the + // partially completed, timed-out tree, too. + var _progressedState = workInProgress.memoizedState; - 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. + var _progressedPrimaryChild = + _progressedState !== null + ? workInProgress.child.child + : workInProgress.child; - var renderState = workInProgress.memoizedState; + if (_progressedPrimaryChild !== currentPrimaryChildFragment.child) { + _primaryChildFragment2.child = _progressedPrimaryChild; + var _progressedChild2 = _progressedPrimaryChild; - 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; + 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. - pushSuspenseContext(workInProgress, suspenseStackCursor.current); + if (workInProgress.mode & ProfileMode) { + // treeBaseDuration is the sum of all the child tree base durations. + var _treeBaseDuration = 0; + var _hiddenChild = _primaryChildFragment2.child; - if (_hasChildWork) { - break; - } else { - // If none of the children had any work, that means that none of - // them got retried so they'll still be blocked in the same way - // as before. We can fast bail out. - return null; + while (_hiddenChild !== null) { + _treeBaseDuration += _hiddenChild.treeBaseDuration; + _hiddenChild = _hiddenChild.sibling; } - } - } - 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. - - workInProgress.expirationTime = NoWork; - - 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 - ); - } - - case ClassComponent: { - var _Component2 = workInProgress.type; - var _unresolvedProps = workInProgress.pendingProps; - var _resolvedProps = - workInProgress.elementType === _Component2 - ? _unresolvedProps - : resolveDefaultProps(_Component2, _unresolvedProps); - return updateClassComponent( - current$$1, - workInProgress, - _Component2, - _resolvedProps, - renderExpirationTime - ); - } + _primaryChildFragment2.treeBaseDuration = _treeBaseDuration; + } // Clone the fallback child fragment, too. These we'll continue + // working on. - case HostRoot: - return updateHostRoot(current$$1, workInProgress, renderExpirationTime); + var _fallbackChildFragment2 = createWorkInProgress( + currentFallbackChildFragment, + _nextFallbackChildren2 + ); - case HostComponent: - return updateHostComponent( - current$$1, - workInProgress, - renderExpirationTime - ); + _fallbackChildFragment2.return = workInProgress; + _primaryChildFragment2.sibling = _fallbackChildFragment2; + _primaryChildFragment2.childExpirationTime = NoWork; // Skip the primary children, and continue working on the + // fallback children. - case HostText: - return updateHostText(current$$1, workInProgress); + 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. - case SuspenseComponent: - return updateSuspenseComponent( - current$$1, - workInProgress, - renderExpirationTime - ); - case HostPortal: - return updatePortalComponent( - current$$1, - workInProgress, - renderExpirationTime - ); + 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; - case ForwardRef: { - var type = workInProgress.type; - var _unresolvedProps2 = workInProgress.pendingProps; + if (nextDidTimeout) { + // Timed out. Wrap the children in a fragment fiber to keep them + // separate from the fallback children. + var _nextFallbackChildren3 = nextProps.fallback; - var _resolvedProps2 = - workInProgress.elementType === type - ? _unresolvedProps2 - : resolveDefaultProps(type, _unresolvedProps2); - return updateForwardRef( - current$$1, - workInProgress, - type, - _resolvedProps2, - renderExpirationTime - ); - } + 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 + ); - case Fragment: - return updateFragment(current$$1, workInProgress, renderExpirationTime); + _primaryChildFragment3.return = workInProgress; + _primaryChildFragment3.child = _currentPrimaryChild; - case Mode: - return updateMode(current$$1, workInProgress, renderExpirationTime); + 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; - case Profiler: - return updateProfiler(current$$1, workInProgress, renderExpirationTime); + 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; - case ContextProvider: - return updateContextProvider( - current$$1, - workInProgress, - renderExpirationTime - ); - case ContextConsumer: - return updateContextConsumer( - current$$1, - workInProgress, - renderExpirationTime - ); + var _progressedPrimaryChild2 = + _progressedState2 !== null + ? workInProgress.child.child + : workInProgress.child; - case MemoComponent: { - var _type2 = workInProgress.type; - var _unresolvedProps3 = workInProgress.pendingProps; // Resolve outer props first, then resolve inner props. + _primaryChildFragment3.child = _progressedPrimaryChild2; + var _progressedChild3 = _progressedPrimaryChild2; - var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3); + 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 (workInProgress.type !== workInProgress.elementType) { - var outerPropTypes = _type2.propTypes; + if (workInProgress.mode & ProfileMode) { + // treeBaseDuration is the sum of all the child tree base durations. + var _treeBaseDuration2 = 0; + var _hiddenChild2 = _primaryChildFragment3.child; - if (outerPropTypes) { - checkPropTypes( - outerPropTypes, - _resolvedProps3, // Resolved for outer only - "prop", - getComponentName(_type2), - getCurrentFiberStackInDev - ); + while (_hiddenChild2 !== null) { + _treeBaseDuration2 += _hiddenChild2.treeBaseDuration; + _hiddenChild2 = _hiddenChild2.sibling; } - } - } - _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 - ); - } - case IncompleteClassComponent: { - var _Component3 = workInProgress.type; - var _unresolvedProps4 = workInProgress.pendingProps; + _primaryChildFragment3.treeBaseDuration = _treeBaseDuration2; + } // Create a fragment from the fallback children, too. - 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, + var _fallbackChildFragment3 = createFiberFromFragment( + _nextFallbackChildren3, + mode, + renderExpirationTime, + null + ); + + _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 - ); + )); + } + } + } +} + +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; + } - break; + if (node === workInProgress) { + return; } - case ScopeComponent: { - if (enableScopeAPI) { - return updateScopeComponent( - current$$1, - workInProgress, - renderExpirationTime - ); + while (node.sibling === null) { + if (node.return === null || node.return === workInProgress) { + return; } - break; + node = node.return; } - } - { - throw Error( - "Unknown unit of work tag (" + - workInProgress.tag + - "). This error is likely caused by a bug in React. Please file an issue." - ); + node.sibling.return = node.return; + node = node.sibling; } } -function createFundamentalStateInstance(currentFiber, props, impl, state) { - return { - currentFiber: currentFiber, - impl: impl, - instance: null, - prevProps: null, - props: props, - state: state - }; -} +function findLastContentRow(firstChild) { + // This is going to find the last row among these children that is already + // showing content on the screen, as opposed to being in fallback state or + // new. If a row has multiple Suspense boundaries, any of them being in the + // fallback state, counts as the whole row being in a fallback state. + // Note that the "rows" will be workInProgress, but any nested children + // will still be current since we haven't rendered them yet. The mounted + // order may not be the same as the new order. We use the new order. + var row = firstChild; + var lastContentRow = null; -function isFiberSuspenseAndTimedOut(fiber) { - return fiber.tag === SuspenseComponent && fiber.memoizedState !== null; -} + while (row !== null) { + var currentRow = row.alternate; // New rows can't be content rows. -function getSuspenseFallbackChild(fiber) { - return fiber.child.sibling.child; + if (currentRow !== null && findFirstSuspended(currentRow) === null) { + lastContentRow = row; + } + + row = row.sibling; + } + + return lastContentRow; } -var emptyObject$2 = {}; +function validateRevealOrder(revealOrder) { + { + if ( + revealOrder !== undefined && + revealOrder !== "forwards" && + revealOrder !== "backwards" && + revealOrder !== "together" && + !didWarnAboutRevealOrder[revealOrder] + ) { + didWarnAboutRevealOrder[revealOrder] = true; -function collectScopedNodes(node, fn, scopedNodes) { - if (enableScopeAPI) { - if (node.tag === HostComponent) { - var _type = node.type, - memoizedProps = node.memoizedProps, - stateNode = node.stateNode; + 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 _instance = getPublicInstance(stateNode); + break; + } - if ( - _instance !== null && - fn(_type, memoizedProps || emptyObject$2, _instance) === true - ) { - scopedNodes.push(_instance); - } - } + 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 = node.child; + break; + } - if (isFiberSuspenseAndTimedOut(node)) { - child = getSuspenseFallbackChild(node); - } + default: + error( + '"%s" is not a supported revealOrder on . ' + + 'Did you mean "together", "forwards" or "backwards"?', + revealOrder + ); - if (child !== null) { - collectScopedNodesFromChildren(child, fn, scopedNodes); + break; + } + } else { + error( + "%s is not a supported value for revealOrder on . " + + 'Did you mean "together", "forwards" or "backwards"?', + revealOrder + ); + } } } } -function collectFirstScopedNode(node, fn) { - if (enableScopeAPI) { - if (node.tag === HostComponent) { - var _type2 = node.type, - memoizedProps = node.memoizedProps, - stateNode = node.stateNode; +function validateTailOptions(tailMode, revealOrder) { + { + if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) { + if (tailMode !== "collapsed" && tailMode !== "hidden") { + didWarnAboutTailOptions[tailMode] = true; - var _instance2 = getPublicInstance(stateNode); + error( + '"%s" is not a supported value for tail on . ' + + 'Did you mean "collapsed" or "hidden"?', + tailMode + ); + } else if (revealOrder !== "forwards" && revealOrder !== "backwards") { + didWarnAboutTailOptions[tailMode] = true; - if ( - _instance2 !== null && - fn(_type2, memoizedProps, _instance2) === true - ) { - return _instance2; + error( + ' is only valid if revealOrder is ' + + '"forwards" or "backwards". ' + + 'Did you mean to specify revealOrder="forwards"?', + tailMode + ); } } - - 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 validateSuspenseListNestedChild(childSlot, index) { + { + var isArray = Array.isArray(childSlot); + var isIterable = !isArray && typeof getIteratorFn(childSlot) === "function"; -function collectFirstScopedNodeFromChildren(startingChild, fn) { - var child = startingChild; + if (isArray || isIterable) { + var type = isArray ? "array" : "iterable"; - while (child !== null) { - var scopedNode = collectFirstScopedNode(child, fn); + error( + "A nested %s was passed to row #%s in . Wrap it in " + + "an additional SuspenseList to configure its revealOrder: " + + " ... " + + "{%s} ... " + + "", + type, + index, + type + ); - if (scopedNode !== null) { - return scopedNode; + return false; } - - child = child.sibling; } - return null; + return true; } -function collectNearestScopeMethods(node, scope, childrenScopes) { - if (isValidScopeNode(node, scope)) { - childrenScopes.push(node.stateNode.methods); - } else { - var child = node.child; +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 (isFiberSuspenseAndTimedOut(node)) { - child = getSuspenseFallbackChild(node); - } + 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; + } - if (child !== null) { - collectNearestChildScopeMethods(child, scope, childrenScopes); + _i++; + } + } + } else { + error( + 'A single row was passed to a . ' + + "This is not useful since it needs multiple rows. " + + "Did you mean to pass multiple children or an array?", + revealOrder + ); + } + } } } } -function collectNearestChildScopeMethods(startingChild, scope, childrenScopes) { - var child = startingChild; +function initSuspenseListRenderState( + workInProgress, + isBackwards, + tail, + lastContentRow, + tailMode, + lastEffectBeforeRendering +) { + var renderState = workInProgress.memoizedState; - while (child !== null) { - collectNearestScopeMethods(child, scope, childrenScopes); - child = child.sibling; + 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. -function isValidScopeNode(node, scope) { - return ( - node.tag === ScopeComponent && - node.type === scope && - node.stateNode !== null +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 ); -} -function createScopeMethods(scope, instance) { - return { - getChildren: function() { - var currentFiber = instance.fiber; - var child = currentFiber.child; - var childrenScopes = []; - - if (child !== null) { - collectNearestChildScopeMethods(child, scope, childrenScopes); - } + if (shouldForceFallback) { + suspenseContext = setShallowSuspenseContext( + suspenseContext, + ForceSuspenseFallback + ); + workInProgress.effectTag |= DidCapture; + } else { + var didSuspendBefore = + current !== null && (current.effectTag & DidCapture) !== NoEffect; - return childrenScopes.length === 0 ? null : childrenScopes; - }, - getChildrenFromRoot: function() { - var currentFiber = instance.fiber; - var node = currentFiber; + 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 + ); + } - while (node !== null) { - var parent = node.return; + suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); + } - if (parent === null) { - break; - } + pushSuspenseContext(workInProgress, suspenseContext); - node = parent; + 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 (node.tag === ScopeComponent && node.type === scope) { - break; + 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 childrenScopes = []; - collectNearestChildScopeMethods(node.child, scope, childrenScopes); - return childrenScopes.length === 0 ? null : childrenScopes; - }, - getParent: function() { - var node = instance.fiber.return; + case "backwards": { + // We're going to find the first row that has existing content. + // At the same time we're going to reverse the list of everything + // we pass in the meantime. That's going to be our tail in reverse + // order. + var _tail = null; + var row = workInProgress.child; + workInProgress.child = null; - while (node !== null) { - if (node.tag === ScopeComponent && node.type === scope) { - return node.stateNode.methods; - } + while (row !== null) { + var currentRow = row.alternate; // New rows can't be content rows. - node = node.return; - } + if (currentRow !== null && findFirstSuspended(currentRow) === null) { + // This is the beginning of the main content. + workInProgress.child = row; + break; + } - 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 nextRow = row.sibling; + row.sibling = _tail; + _tail = row; + row = nextRow; + } // TODO: If workInProgress.child is null, we can continue on the tail immediately. - if (child !== null) { - collectScopedNodesFromChildren(child, fn, scopedNodes); + initSuspenseListRenderState( + workInProgress, + true, // isBackwards + _tail, + null, // last + tailMode, + workInProgress.lastEffect + ); + break; } - 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 "together": { + initSuspenseListRenderState( + workInProgress, + false, // isBackwards + null, // tail + null, // last + undefined, + workInProgress.lastEffect + ); + break; } - return null; - }, - containsNode: function(node) { - var fiber = getInstanceFromNode$1(node); - - while (fiber !== null) { - if ( - fiber.tag === ScopeComponent && - fiber.type === scope && - fiber.stateNode === instance - ) { - return true; - } - - fiber = fiber.return; + default: { + // The default reveal order is the same as not having + // a boundary. + workInProgress.memoizedState = null; } - - return false; } - }; -} - -function markUpdate(workInProgress) { - // Tag the fiber with an update effect. This turns a Placement into - // a PlacementAndUpdate. - workInProgress.effectTag |= Update; -} + } -function markRef$1(workInProgress) { - workInProgress.effectTag |= Ref; + return workInProgress.child; } -var appendAllChildren; -var updateHostContainer; -var updateHostComponent$1; -var updateHostText$1; - -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 (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; - } - }; +function updatePortalComponent(current, workInProgress, renderExpirationTime) { + pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); + var nextChildren = workInProgress.pendingProps; - 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 (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 + ); + } - 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`. + return workInProgress.child; +} - var updatePayload = prepareUpdate( - instance, - type, - oldProps, - newProps, - rootContainerInstance, - currentHostContext - ); // TODO: Type this specific to this type of component. +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; - 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. + { + var providerPropTypes = workInProgress.type.propTypes; - 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); + if (providerPropTypes) { + checkPropTypes(providerPropTypes, newProps, "prop", "Context.Provider"); } - }; -} 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; + pushProvider(workInProgress, newValue); - if (needsVisibilityToggle && isHidden) { - // This child is inside a timed out tree. Hide it. - var text = node.memoizedProps; - _instance = cloneHiddenTextInstance(_instance, text, node); - } + if (oldProps !== null) { + var oldValue = oldProps.value; + var changedBits = calculateChangedBits(context, newValue, oldValue); - appendInitialChild(parent, _instance); - } else if (enableFundamentalAPI && node.tag === FundamentalComponent) { - var _instance2 = node.stateNode.instance; + 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 (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 newChildren = newProps.children; + reconcileChildren(current, workInProgress, newChildren, renderExpirationTime); + return workInProgress.child; +} - if (newIsHidden) { - var primaryChildParent = node.child; +var hasWarnedAboutUsingContextAsConsumer = false; - if (primaryChildParent !== null) { - if (primaryChildParent.child !== null) { - primaryChildParent.child.return = primaryChildParent; - appendAllChildren( - parent, - primaryChildParent, - true, - newIsHidden - ); - } +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. - var fallbackChildParent = primaryChildParent.sibling; + { + if (context._context === undefined) { + // This may be because it's a Context (rather than a Consumer). + // Or it may be because it's older React where they're the same thing. + // We only want to warn if we're sure it's a new React. + if (context !== context.Consumer) { + if (!hasWarnedAboutUsingContextAsConsumer) { + hasWarnedAboutUsingContextAsConsumer = true; - if (fallbackChildParent !== null) { - fallbackChildParent.return = node; - node = fallbackChildParent; - continue; - } - } - } - } - if (node.child !== null) { - // Continue traversing like normal - node.child.return = node; - node = node.child; - continue; + error( + "Rendering directly is not supported and will be removed in " + + "a future major release. Did you mean to render instead?" + ); } - } 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; } + } else { + context = context._context; + } + } - while (node.sibling === null) { - if (node.return === null || node.return === workInProgress) { - return; - } - - node = node.return; - } + var newProps = workInProgress.pendingProps; + var render = newProps.children; - node.sibling.return = node.return; - node = node.sibling; + { + 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." + ); } - }; // 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); - } + prepareToReadContext(workInProgress, renderExpirationTime); + var newValue = readContext(context, newProps.unstable_observedBits); + var newChildren; - appendChildToContainerChildSet(containerChildSet, instance); - } else if (node.tag === HostText) { - var _instance3 = node.stateNode; + { + ReactCurrentOwner$1.current = workInProgress; + setIsRendering(true); + newChildren = render(newValue); + setIsRendering(false); + } // React DevTools reads this flag. - if (needsVisibilityToggle && isHidden) { - // This child is inside a timed out tree. Hide it. - var text = node.memoizedProps; - _instance3 = cloneHiddenTextInstance(_instance3, text, node); - } + workInProgress.effectTag |= PerformedWork; + reconcileChildren(current, workInProgress, newChildren, renderExpirationTime); + return workInProgress.child; +} - appendChildToContainerChildSet(containerChildSet, _instance3); - } else if (enableFundamentalAPI && node.tag === FundamentalComponent) { - var _instance4 = node.stateNode.instance; +function markWorkInProgressReceivedUpdate() { + didReceiveUpdate = true; +} - 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; +function bailoutOnAlreadyFinishedWork( + current, + workInProgress, + renderExpirationTime +) { + cancelWorkTimer(workInProgress); - if (newIsHidden) { - var primaryChildParent = node.child; + if (current !== null) { + // Reuse previous dependencies + workInProgress.dependencies = current.dependencies; + } - if (primaryChildParent !== null) { - if (primaryChildParent.child !== null) { - primaryChildParent.child.return = primaryChildParent; - appendAllChildrenToContainer( - containerChildSet, - primaryChildParent, - true, - newIsHidden - ); - } + { + // Don't update "base" render times for bailouts. + stopProfilerTimerIfRunning(); + } - var fallbackChildParent = primaryChildParent.sibling; + var updateExpirationTime = workInProgress.expirationTime; - 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. + if (updateExpirationTime !== NoWork) { + markUnprocessedUpdateTime(updateExpirationTime); + } // Check if the children have any pending work. - node = node; + var childExpirationTime = workInProgress.childExpirationTime; - if (node === workInProgress) { - return; - } + 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; + } +} - while (node.sibling === null) { - if (node.return === null || node.return === workInProgress) { - return; - } +function remountFiber(current, oldWorkInProgress, newWorkInProgress) { + { + var returnFiber = oldWorkInProgress.return; - node = node.return; - } + if (returnFiber === null) { + throw new Error("Cannot swap the root fiber."); + } // Disconnect from the old current. + // It will get deleted. - node.sibling.return = node.return; - node = node.sibling; - } - }; + current.alternate = null; + oldWorkInProgress.alternate = null; // Connect to the new tree. - updateHostContainer = function(workInProgress) { - var portalOrRoot = workInProgress.stateNode; - var childrenUnchanged = workInProgress.firstEffect === null; + newWorkInProgress.index = oldWorkInProgress.index; + newWorkInProgress.sibling = oldWorkInProgress.sibling; + newWorkInProgress.return = oldWorkInProgress.return; + newWorkInProgress.ref = oldWorkInProgress.ref; // Replace the child/sibling pointers above it. - if (childrenUnchanged) { - // No changes, just reuse the existing instance. + if (oldWorkInProgress === returnFiber.child) { + returnFiber.child = newWorkInProgress; } else { - var container = portalOrRoot.containerInfo; - var newChildSet = createContainerChildSet(container); // If children might have changed, we have to add them all to the set. + var prevSibling = returnFiber.child; - appendAllChildrenToContainer(newChildSet, workInProgress, false, false); - portalOrRoot.pendingChildren = newChildSet; // Schedule an update on the container to swap out the container. + if (prevSibling === null) { + throw new Error("Expected parent to have a child."); + } - 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. + while (prevSibling.sibling !== oldWorkInProgress) { + prevSibling = prevSibling.sibling; + + if (prevSibling === null) { + throw new Error("Expected to find the previous sibling."); + } + } + + 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 childrenUnchanged = workInProgress.firstEffect === null; + var last = returnFiber.lastEffect; - if (childrenUnchanged && oldProps === newProps) { - // No changes, just reuse the existing instance. - // Note that this might release a previous clone. - workInProgress.stateNode = currentInstance; - return; + if (last !== null) { + last.nextEffect = current; + returnFiber.lastEffect = current; + } else { + returnFiber.firstEffect = returnFiber.lastEffect = current; } - var recyclableInstance = workInProgress.stateNode; - var currentHostContext = getHostContext(); - var updatePayload = null; + current.nextEffect = null; + current.effectTag = Deletion; + newWorkInProgress.effectTag |= Placement; // Restart work from the new fiber. - if (oldProps !== newProps) { - updatePayload = prepareUpdate( - recyclableInstance, - type, - oldProps, - newProps, - rootContainerInstance, - currentHostContext + return newWorkInProgress; + } +} + +function beginWork(current, workInProgress, renderExpirationTime) { + var updateExpirationTime = workInProgress.expirationTime; + + { + 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 (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 (current !== null) { + var oldProps = current.memoizedProps; + var newProps = workInProgress.pendingProps; + if ( - finalizeInitialChildren( - newInstance, - type, - newProps, - rootContainerInstance, - currentHostContext - ) + oldProps !== newProps || + hasContextChanged() || // Force a re-render if the implementation changed due to hot reload: + workInProgress.type !== current.type ) { - markUpdate(workInProgress); - } + // 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. - workInProgress.stateNode = newInstance; + switch (workInProgress.tag) { + case HostRoot: + pushHostRootContext(workInProgress); + break; - 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 HostComponent: + pushHostContext(workInProgress); - 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 - }; -} + if ( + workInProgress.mode & ConcurrentMode && + renderExpirationTime !== Never && + shouldDeprioritizeSubtree(workInProgress.type) + ) { + { + markSpawnedWork(Never); + } // Schedule this fiber to re-render at offscreen priority. Then bailout. -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; - } + workInProgress.expirationTime = workInProgress.childExpirationTime = Never; + return null; + } - tailNode = tailNode.sibling; - } // Next we're simply going to delete all insertions after the - // last rendered item. + break; - if (lastTailNode === null) { - // All remaining items in the tail are insertions. - renderState.tail = null; - } else { - // Detach the insertion after the last node that was already - // inserted. - lastTailNode.sibling = null; - } + case ClassComponent: { + var Component = workInProgress.type; - break; - } + if (isContextProvider(Component)) { + pushContextProvider(workInProgress); + } - 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; + break; } - _tailNode = _tailNode.sibling; - } // Next we're simply going to delete all insertions after the - // last rendered item. + case HostPortal: + pushHostContainer( + workInProgress, + workInProgress.stateNode.containerInfo + ); + break; - if (_lastTailNode === null) { - // All remaining items in the tail are insertions. - if (!hasRenderedATailFallback && renderState.tail !== null) { - // We suspended during the head. We want to show at least one - // row at the tail. So we'll keep on and cut off the rest. - renderState.tail.sibling = null; - } else { - renderState.tail = null; + case ContextProvider: { + var newValue = workInProgress.memoizedProps.value; + pushProvider(workInProgress, newValue); + break; + } + + case Profiler: + { + // 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; + + case SuspenseComponent: { + var state = workInProgress.memoizedState; + + if (state !== null) { + // whether to retry the primary children, or to skip over it and + // go straight to the fallback. Check the priority of the primary + // child fragment. + + var primaryChildFragment = workInProgress.child; + var 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, + workInProgress, + renderExpirationTime + ); + } else { + pushSuspenseContext( + workInProgress, + setDefaultShallowSuspenseContext(suspenseStackCursor.current) + ); // The primary children do not have pending work with sufficient + // priority. Bailout. + + var child = bailoutOnAlreadyFinishedWork( + current, + 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; } - } 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; + case SuspenseListComponent: { + var didSuspendBefore = (current.effectTag & DidCapture) !== NoEffect; - switch (workInProgress.tag) { - case IndeterminateComponent: - break; + var _hasChildWork = + workInProgress.childExpirationTime >= renderExpirationTime; - case LazyComponent: - break; + 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. - case SimpleMemoComponent: - case FunctionComponent: - break; + 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. - case ClassComponent: { - var Component = workInProgress.type; + var renderState = workInProgress.memoizedState; - if (isContextProvider(Component)) { - popContext(workInProgress); + if (renderState !== null) { + // Reset to the "together" mode in case we've started a different + // update in the past but didn't complete it. + renderState.rendering = null; + renderState.tail = null; + } + + pushSuspenseContext(workInProgress, suspenseStackCursor.current); + + if (_hasChildWork) { + break; + } else { + // If none of the children had any work, that means that none of + // them got retried so they'll still be blocked in the same way + // as before. We can fast bail out. + return null; + } + } } - break; + 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. - case HostRoot: { - popHostContainer(workInProgress); - popTopLevelContextObject(workInProgress); - var fiberRoot = workInProgress.stateNode; - if (fiberRoot.pendingContext) { - fiberRoot.context = fiberRoot.pendingContext; - fiberRoot.pendingContext = null; - } + workInProgress.expirationTime = NoWork; - 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); + switch (workInProgress.tag) { + case IndeterminateComponent: { + return mountIndeterminateComponent( + current, + workInProgress, + workInProgress.type, + renderExpirationTime + ); + } - if (wasHydrated) { - // If we hydrated, then we'll need to schedule an update for - // the commit side-effects on the root. - markUpdate(workInProgress); - } - } + case LazyComponent: { + var elementType = workInProgress.elementType; + return mountLazyComponent( + current, + workInProgress, + elementType, + updateExpirationTime, + renderExpirationTime + ); + } - updateHostContainer(workInProgress); - break; + 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 + ); } - case HostComponent: { - popHostContext(workInProgress); - var rootContainerInstance = getRootHostContainer(); - var type = workInProgress.type; - if (current !== null && workInProgress.stateNode != null) { - updateHostComponent$1( - current, - workInProgress, - type, - newProps, - rootContainerInstance - ); + case ClassComponent: { + var _Component2 = workInProgress.type; + var _unresolvedProps = workInProgress.pendingProps; - if (enableFlareAPI) { - var prevListeners = current.memoizedProps.listeners; - var nextListeners = newProps.listeners; + var _resolvedProps = + workInProgress.elementType === _Component2 + ? _unresolvedProps + : resolveDefaultProps(_Component2, _unresolvedProps); - if (prevListeners !== nextListeners) { - markUpdate(workInProgress); - } - } + return updateClassComponent( + current, + workInProgress, + _Component2, + _resolvedProps, + renderExpirationTime + ); + } - if (current.ref !== workInProgress.ref) { - markRef$1(workInProgress); - } - } else { - if (!newProps) { - if (!(workInProgress.stateNode !== null)) { - throw Error( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." - ); - } // This can happen when we abort work. + case HostRoot: + return updateHostRoot(current, workInProgress, renderExpirationTime); - break; - } + case HostComponent: + return updateHostComponent(current, workInProgress, renderExpirationTime); - 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. + case HostText: + return updateHostText(); - var _wasHydrated = popHydrationState(workInProgress); + case SuspenseComponent: + return updateSuspenseComponent( + current, + workInProgress, + renderExpirationTime + ); - 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); - } + case HostPortal: + return updatePortalComponent( + current, + workInProgress, + renderExpirationTime + ); - if (enableFlareAPI) { - var listeners = newProps.listeners; + case ForwardRef: { + var type = workInProgress.type; + var _unresolvedProps2 = workInProgress.pendingProps; - 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 + var _resolvedProps2 = + workInProgress.elementType === type + ? _unresolvedProps2 + : resolveDefaultProps(type, _unresolvedProps2); - workInProgress.stateNode = instance; + return updateForwardRef( + current, + workInProgress, + type, + _resolvedProps2, + renderExpirationTime + ); + } - if (enableFlareAPI) { - var _listeners = newProps.listeners; + case Fragment: + return updateFragment(current, workInProgress, renderExpirationTime); - 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. + case Mode: + return updateMode(current, workInProgress, renderExpirationTime); - if ( - finalizeInitialChildren( - instance, - type, - newProps, - rootContainerInstance, - currentHostContext - ) - ) { - markUpdate(workInProgress); - } - } + case Profiler: + return updateProfiler(current, workInProgress, renderExpirationTime); - if (workInProgress.ref !== null) { - // If there is a ref on a host node we need to schedule a callback - markRef$1(workInProgress); - } - } + case ContextProvider: + return updateContextProvider( + current, + workInProgress, + renderExpirationTime + ); - break; - } + case ContextConsumer: + return updateContextConsumer( + current, + workInProgress, + renderExpirationTime + ); + + case MemoComponent: { + var _type2 = workInProgress.type; + var _unresolvedProps3 = workInProgress.pendingProps; // Resolve outer props first, then resolve inner props. - case HostText: { - var newText = newProps; + var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3); - 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 (workInProgress.type !== workInProgress.elementType) { + var outerPropTypes = _type2.propTypes; - 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." + if (outerPropTypes) { + checkPropTypes( + outerPropTypes, + _resolvedProps3, // Resolved for outer only + "prop", + getComponentName(_type2) ); - } // This can happen when we abort work. + } } + } - var _rootContainerInstance = getRootHostContainer(); + _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3); + return updateMemoComponent( + current, + workInProgress, + _type2, + _resolvedProps3, + updateExpirationTime, + renderExpirationTime + ); + } - var _currentHostContext = getHostContext(); + case SimpleMemoComponent: { + return updateSimpleMemoComponent( + current, + workInProgress, + workInProgress.type, + workInProgress.pendingProps, + updateExpirationTime, + renderExpirationTime + ); + } - var _wasHydrated2 = popHydrationState(workInProgress); + case IncompleteClassComponent: { + var _Component3 = workInProgress.type; + var _unresolvedProps4 = workInProgress.pendingProps; - if (_wasHydrated2) { - if (prepareToHydrateHostTextInstance(workInProgress)) { - markUpdate(workInProgress); - } - } else { - workInProgress.stateNode = createTextInstance( - newText, - _rootContainerInstance, - _currentHostContext, - workInProgress - ); - } - } + var _resolvedProps4 = + workInProgress.elementType === _Component3 + ? _unresolvedProps4 + : resolveDefaultProps(_Component3, _unresolvedProps4); - break; + return mountIncompleteClassComponent( + current, + workInProgress, + _Component3, + _resolvedProps4, + renderExpirationTime + ); } - case ForwardRef: - break; + case SuspenseListComponent: { + return updateSuspenseListComponent( + current, + workInProgress, + renderExpirationTime + ); + } + } - case SuspenseComponent: { - popSuspenseContext(workInProgress); - var nextState = workInProgress.memoizedState; + { + throw Error( + "Unknown unit of work tag (" + + workInProgress.tag + + "). This error is likely caused by a bug in React. Please file an issue." + ); + } +} - if (enableSuspenseServerRenderer) { - if (nextState !== null && nextState.dehydrated !== null) { - if (current === null) { - var _wasHydrated3 = popHydrationState(workInProgress); +function markUpdate(workInProgress) { + // Tag the fiber with an update effect. This turns a Placement into + // a PlacementAndUpdate. + workInProgress.effectTag |= Update; +} - if (!_wasHydrated3) { - throw Error( - "A dehydrated suspense component was completed without a hydrated node. This is probably a bug in React." - ); - } +function markRef$1(workInProgress) { + workInProgress.effectTag |= Ref; +} - prepareToHydrateHostSuspenseInstance(workInProgress); +var appendAllChildren; +var updateHostContainer; +var updateHostComponent$1; +var updateHostText$1; - if (enableSchedulerTracing) { - markSpawnedWork(Never); - } +{ + // 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; - 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; - } + while (node !== null) { + // eslint-disable-next-line no-labels + if (node.tag === HostComponent) { + var instance = node.stateNode; + + if (needsVisibilityToggle && isHidden) { + // This child is inside a timed out tree. Hide it. + var props = node.memoizedProps; + var type = node.type; + instance = cloneHiddenInstance(instance); } - } - if ((workInProgress.effectTag & DidCapture) !== NoEffect) { - // Something suspended. Re-render with the fallback children. - workInProgress.expirationTime = renderExpirationTime; // Do not reset the effect list. + appendInitialChild(parent, instance); + } else if (node.tag === HostText) { + var _instance = node.stateNode; - return workInProgress; - } + if (needsVisibilityToggle && isHidden) { + // This child is inside a timed out tree. Hide it. + var text = node.memoizedProps; + _instance = cloneHiddenTextInstance(); + } - var nextDidTimeout = nextState !== null; - var prevDidTimeout = false; + 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; - if (current === null) { - if (workInProgress.memoizedProps.fallback !== undefined) { - popHydrationState(workInProgress); - } - } else { - var prevState = current.memoizedState; - prevDidTimeout = prevState !== null; + if (newIsHidden) { + var primaryChildParent = node.child; - 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 (primaryChildParent !== null) { + if (primaryChildParent.child !== null) { + primaryChildParent.child.return = primaryChildParent; + appendAllChildren( + parent, + primaryChildParent, + true, + newIsHidden + ); + } - if (currentFallbackChild !== null) { - // Deletions go at the beginning of the return fiber's effect list - var first = workInProgress.firstEffect; + var fallbackChildParent = primaryChildParent.sibling; - if (first !== null) { - workInProgress.firstEffect = currentFallbackChild; - currentFallbackChild.nextEffect = first; - } else { - workInProgress.firstEffect = workInProgress.lastEffect = currentFallbackChild; - currentFallbackChild.nextEffect = null; + if (fallbackChildParent !== null) { + fallbackChildParent.return = node; + node = fallbackChildParent; + continue; + } } - currentFallbackChild.effectTag = Deletion; } } + + 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; } - 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(); - } + while (node.sibling === null) { + if (node.return === null || node.return === workInProgress) { + return; } + + node = node.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.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 + 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); } - } - 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; + + 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(); } - } - if ( - enableSuspenseCallback && - workInProgress.updateQueue !== null && - workInProgress.memoizedProps.suspenseCallback != null - ) { - // Always notify the callback - workInProgress.effectTag |= Update; - } - break; - } + 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; - case Fragment: - break; + if (newIsHidden) { + var primaryChildParent = node.child; - case Mode: - break; + if (primaryChildParent !== null) { + if (primaryChildParent.child !== null) { + primaryChildParent.child.return = primaryChildParent; + appendAllChildrenToContainer( + containerChildSet, + primaryChildParent, + true, + newIsHidden + ); + } - case Profiler: - break; + var fallbackChildParent = primaryChildParent.sibling; - case HostPortal: - popHostContainer(workInProgress); - updateHostContainer(workInProgress); - break; - case ContextProvider: - // Pop provider fiber - popProvider(workInProgress); - break; + if (fallbackChildParent !== null) { + fallbackChildParent.return = node; + node = fallbackChildParent; + continue; + } + } + } + } - case ContextConsumer: - 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 MemoComponent: - break; + node = node; - 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 (node === workInProgress) { + return; + } - if (isContextProvider(_Component)) { - popContext(workInProgress); + while (node.sibling === null) { + if (node.return === null || node.return === workInProgress) { + return; + } + + node = node.return; } - break; + node.sibling.return = node.return; + node = node.sibling; } + }; - case SuspenseListComponent: { - popSuspenseContext(workInProgress); - var renderState = workInProgress.memoizedState; + updateHostContainer = function(workInProgress) { + var portalOrRoot = workInProgress.stateNode; + var childrenUnchanged = workInProgress.firstEffect === null; - if (renderState === null) { - // We're running in the default, "independent" mode. We don't do anything - // in this mode. - break; - } + 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. - var didSuspendAlready = - (workInProgress.effectTag & DidCapture) !== NoEffect; - var renderedTail = renderState.rendering; + appendAllChildrenToContainer(newChildSet, workInProgress, false, false); + portalOrRoot.pendingChildren = newChildSet; // Schedule an update on the container to swap out the container. - 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); + markUpdate(workInProgress); + finalizeContainerChildren(container, newChildSet); + } + }; - if (!cannotBeSuspended) { - var row = workInProgress.child; + updateHostComponent$1 = function( + current, + workInProgress, + type, + newProps, + rootContainerInstance + ) { + var currentInstance = current.stateNode; + var oldProps = current.memoizedProps; // If there are no effects associated with this node, then none of our children had any updates. + // This guarantees that we can reuse all of them. - while (row !== null) { - var suspended = findFirstSuspended(row); + var childrenUnchanged = workInProgress.firstEffect === 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. + if (childrenUnchanged && oldProps === newProps) { + // No changes, just reuse the existing instance. + // Note that this might release a previous clone. + workInProgress.stateNode = currentInstance; + return; + } - var newThennables = suspended.updateQueue; + var recyclableInstance = workInProgress.stateNode; + var currentHostContext = getHostContext(); + var updatePayload = 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. + if (oldProps !== newProps) { + updatePayload = prepareUpdate( + recyclableInstance, + type, + oldProps, + newProps + ); + } - if (renderState.lastEffect === null) { - workInProgress.firstEffect = null; - } + if (childrenUnchanged && updatePayload === null) { + // No changes, just reuse the existing instance. + // Note that this might release a previous clone. + workInProgress.stateNode = currentInstance; + return; + } - workInProgress.lastEffect = renderState.lastEffect; // Reset the child fibers to their original state. + var newInstance = cloneInstance( + currentInstance, + updatePayload, + type, + oldProps, + newProps, + workInProgress, + childrenUnchanged + ); - resetChildFibers(workInProgress, renderExpirationTime); // Set up the Suspense Context to force suspense and immediately - // rerender the children. + workInProgress.stateNode = newInstance; - pushSuspenseContext( - workInProgress, - setShallowSuspenseContext( - suspenseStackCursor.current, - ForceSuspenseFallback - ) - ); - return workInProgress.child; - } - 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); + 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. - 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. + markUpdate(workInProgress); + } else { + workInProgress.stateNode = current.stateNode; + } + }; +} - var _newThennables = _suspended.updateQueue; +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 (_newThennables !== null) { - workInProgress.updateQueue = _newThennables; - workInProgress.effectTag |= Update; - } + while (tailNode !== null) { + if (tailNode.alternate !== null) { + lastTailNode = tailNode; + } - cutOffTailIfNeeded(renderState, true); // This might have been modified. + tailNode = tailNode.sibling; + } // Next we're simply going to delete all insertions after the + // last rendered item. - 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 (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 (lastEffect !== null) { - lastEffect.nextEffect = null; - } // We're done. + break; + } - 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. + case "collapsed": { + // Any insertions at the end of the tail list after this point + // should be invisible. If there are already mounted boundaries + // anything before them are not considered for collapsing. + // Therefore we need to go through the whole tail to find if + // there are any. + var _tailNode = renderState.tail; + var _lastTailNode = null; - var 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; + while (_tailNode !== null) { + if (_tailNode.alternate !== null) { + _lastTailNode = _tailNode; } - } - - 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. - - 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. - var suspenseContext = suspenseStackCursor.current; + _tailNode = _tailNode.sibling; + } // Next we're simply going to delete all insertions after the + // last rendered item. - if (didSuspendAlready) { - suspenseContext = setShallowSuspenseContext( - suspenseContext, - ForceSuspenseFallback - ); + 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 { - suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); + renderState.tail = null; } - - pushSuspenseContext(workInProgress, suspenseContext); // Do a pass over the next row. - - return next; + } else { + // Detach the insertion after the last node that was already + // inserted. + _lastTailNode.sibling = null; } break; } + } +} - 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 || {} - ); +function completeWork(current, workInProgress, renderExpirationTime) { + var newProps = workInProgress.pendingProps; - var _instance5 = getFundamentalComponentInstance(fundamentalInstance); + 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; - fundamentalInstance.instance = _instance5; + case ClassComponent: { + var Component = workInProgress.type; - if (fundamentalImpl.reconcileChildren === false) { - return null; - } + if (isContextProvider(Component)) { + popContext(workInProgress); + } - 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; + return null; + } - if (supportsPersistence) { - var _instance6 = cloneFundamentalInstance(fundamentalInstance); + case HostRoot: { + popHostContainer(workInProgress); + popTopLevelContextObject(workInProgress); + var fiberRoot = workInProgress.stateNode; - fundamentalInstance.instance = _instance6; - appendAllChildren(_instance6, workInProgress, false, false); - } + if (fiberRoot.pendingContext) { + fiberRoot.context = fiberRoot.pendingContext; + fiberRoot.pendingContext = null; + } - var shouldUpdate = shouldUpdateFundamentalComponent( - fundamentalInstance - ); + if (current === null || current.child === null) { + // If we hydrated, pop so that we can delete any remaining children + // that weren't hydrated. + var wasHydrated = popHydrationState(); - if (shouldUpdate) { - markUpdate(workInProgress); - } + if (wasHydrated) { + // If we hydrated, then we'll need to schedule an update for + // the commit side-effects on the root. + markUpdate(workInProgress); } } - break; + updateHostContainer(workInProgress); + return null; } - 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); + case HostComponent: { + popHostContext(workInProgress); + var rootContainerInstance = getRootHostContainer(); + var type = workInProgress.type; + + if (current !== null && workInProgress.stateNode != null) { + updateHostComponent$1( + current, + workInProgress, + type, + newProps, + rootContainerInstance + ); + + if (current.ref !== workInProgress.ref) { + markRef$1(workInProgress); + } + } else { + if (!newProps) { + if (!(workInProgress.stateNode !== null)) { + throw Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ); + } // This can happen when we abort work. - if (enableFlareAPI) { - var _listeners2 = newProps.listeners; + return null; + } - if (_listeners2 != null) { - var _rootContainerInstance2 = getRootHostContainer(); + 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. - updateEventListeners( - _listeners2, - workInProgress, - _rootContainerInstance2 - ); - } - } + var _wasHydrated = popHydrationState(); - if (workInProgress.ref !== null) { - markRef$1(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 + // commit-phase we mark this as such. 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); - } - } + var instance = createInstance( + type, + newProps, + rootContainerInstance, + currentHostContext, + workInProgress + ); + appendAllChildren(instance, workInProgress, false, false); // This needs to be set before we mount Flare event listeners - if (current.ref !== workInProgress.ref) { - markRef$1(workInProgress); - } + workInProgress.stateNode = instance; + } + + if (workInProgress.ref !== null) { + // If there is a ref on a host node we need to schedule a callback + markRef$1(workInProgress); } } - break; + return null; } - default: { - throw Error( - "Unknown unit of work tag (" + - workInProgress.tag + - "). This error is likely caused by a bug in React. Please file an issue." - ); - } - } + case HostText: { + var newText = newProps; - return null; -} + if (current && workInProgress.stateNode != null) { + var oldText = current.memoizedProps; // If we have an alternate, that means this is an update and we need + // to schedule a side-effect to do the updates. -function unwindWork(workInProgress, renderExpirationTime) { - switch (workInProgress.tag) { - case ClassComponent: { - var Component = workInProgress.type; + 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 (isContextProvider(Component)) { - popContext(workInProgress); - } + var _rootContainerInstance = getRootHostContainer(); - var effectTag = workInProgress.effectTag; + var _currentHostContext = getHostContext(); - if (effectTag & ShouldCapture) { - workInProgress.effectTag = (effectTag & ~ShouldCapture) | DidCapture; - return workInProgress; + var _wasHydrated2 = popHydrationState(); + + if (_wasHydrated2) { + if (prepareToHydrateHostTextInstance()) { + markUpdate(workInProgress); + } + } else { + workInProgress.stateNode = createTextInstance( + newText, + _rootContainerInstance, + _currentHostContext, + workInProgress + ); + } } return null; } - case HostRoot: { - popHostContainer(workInProgress); - popTopLevelContextObject(workInProgress); - var _effectTag = workInProgress.effectTag; + case SuspenseComponent: { + popSuspenseContext(workInProgress); + var nextState = workInProgress.memoizedState; - 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 ((workInProgress.effectTag & DidCapture) !== NoEffect) { + // Something suspended. Re-render with the fallback children. + workInProgress.expirationTime = renderExpirationTime; // Do not reset the effect list. + + return workInProgress; } - workInProgress.effectTag = (_effectTag & ~ShouldCapture) | DidCapture; - return workInProgress; - } + var nextDidTimeout = nextState !== null; + var prevDidTimeout = false; - case HostComponent: { - // TODO: popHydrationState - popHostContext(workInProgress); - return null; - } + if (current === null) { + if (workInProgress.memoizedProps.fallback !== undefined); + } else { + var prevState = current.memoizedState; + prevDidTimeout = prevState !== null; - case SuspenseComponent: { - popSuspenseContext(workInProgress); + 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 (enableSuspenseServerRenderer) { - var suspenseState = workInProgress.memoizedState; + if (first !== null) { + workInProgress.firstEffect = currentFallbackChild; + currentFallbackChild.nextEffect = first; + } else { + workInProgress.firstEffect = workInProgress.lastEffect = currentFallbackChild; + currentFallbackChild.nextEffect = null; + } - 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." - ); + currentFallbackChild.effectTag = Deletion; } - - resetHydrationState(); } } - var _effectTag2 = workInProgress.effectTag; - - if (_effectTag2 & ShouldCapture) { - workInProgress.effectTag = (_effectTag2 & ~ShouldCapture) | DidCapture; // Captured a suspense effect. Re-render the boundary. + 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; - return workInProgress; + if ( + hasInvisibleChildContext || + hasSuspenseContext( + suspenseStackCursor.current, + InvisibleParentSuspenseContext + ) + ) { + // If this was in an invisible tree or a new render, then showing + // this boundary is ok. + renderDidSuspend(); + } else { + // Otherwise, we're going to have to hide content so we should + // suspend for longer if possible. + renderDidSuspendDelayIfPossible(); + } + } } - return 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. + { + // 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; + } + } return null; } case HostPortal: popHostContainer(workInProgress); + updateHostContainer(workInProgress); return null; case ContextProvider: + // Pop provider fiber popProvider(workInProgress); return null; - default: + 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); + } + return null; - } -} + } -function unwindInterruptedWork(interruptedWork) { - switch (interruptedWork.tag) { - case ClassComponent: { - var childContextTypes = interruptedWork.type.childContextTypes; + case SuspenseListComponent: { + popSuspenseContext(workInProgress); + var renderState = workInProgress.memoizedState; - if (childContextTypes !== null && childContextTypes !== undefined) { - popContext(interruptedWork); + if (renderState === null) { + // We're running in the default, "independent" mode. + // We don't do anything in this mode. + return null; } - break; - } + var didSuspendAlready = + (workInProgress.effectTag & DidCapture) !== NoEffect; + var renderedTail = renderState.rendering; - case HostRoot: { - popHostContainer(interruptedWork); - popTopLevelContextObject(interruptedWork); - break; - } - case HostComponent: { - popHostContext(interruptedWork); - break; - } + 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); - case HostPortal: - popHostContainer(interruptedWork); - break; + if (!cannotBeSuspended) { + var row = workInProgress.child; - case SuspenseComponent: - popSuspenseContext(interruptedWork); - break; + while (row !== null) { + var suspended = findFirstSuspended(row); - case SuspenseListComponent: - popSuspenseContext(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 ContextProvider: - popProvider(interruptedWork); - break; + var newThennables = suspended.updateQueue; + + 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. - default: - break; - } -} + if (renderState.lastEffect === null) { + workInProgress.firstEffect = null; + } -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) - }; -} + workInProgress.lastEffect = renderState.lastEffect; // Reset the child fibers to their original state. -// Module provided by RN: -if ( - !( - typeof ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog === - "function" - ) -) { - throw Error( - "Expected ReactFiberErrorDialog.showErrorDialog to be a function." - ); -} + resetChildFibers(workInProgress, renderExpirationTime); // Set up the Suspense Context to force suspense and immediately + // rerender the children. -function showErrorDialog(capturedError) { - return ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog( - capturedError - ); -} + pushSuspenseContext( + workInProgress, + setShallowSuspenseContext( + suspenseStackCursor.current, + ForceSuspenseFallback + ) + ); + return workInProgress.child; + } -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. + 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); - if (logError === false) { - return; - } + 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. - 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. + var _newThennables = _suspended.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 (_newThennables !== null) { + workInProgress.updateQueue = _newThennables; + workInProgress.effectTag |= Update; + } - console.error(error); // For a more detailed description of this block, see: - // https://github.com/facebook/react/pull/13384 - } + cutOffTailIfNeeded(renderState, true); // This might have been modified. - 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. + 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 (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. + if (lastEffect !== null) { + lastEffect.nextEffect = null; + } // We're done. - console.error(combinedMessage); - } -} + 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 didWarnAboutUndefinedSnapshotBeforeUpdate = null; -{ - didWarnAboutUndefinedSnapshotBeforeUpdate = new Set(); -} + var nextPriority = renderExpirationTime - 1; + workInProgress.expirationTime = workInProgress.childExpirationTime = nextPriority; -var PossiblyWeakSet = typeof WeakSet === "function" ? WeakSet : Set; -function logError(boundary, errorInfo) { - var source = errorInfo.source; - var stack = errorInfo.stack; + { + markSpawnedWork(nextPriority); + } + } + } - if (stack === null && source !== null) { - stack = getStackByFiberInDevAndProd(source); - } + 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 capturedError = { - componentName: source !== null ? getComponentName(source.type) : null, - componentStack: stack !== null ? stack : "", - error: errorInfo.value, - errorBoundary: null, - errorBoundaryName: null, - errorBoundaryFound: false, - willRetry: false - }; + if (previousSibling !== null) { + previousSibling.sibling = renderedTail; + } else { + workInProgress.child = renderedTail; + } - if (boundary !== null && boundary.tag === ClassComponent) { - capturedError.errorBoundary = boundary.stateNode; - capturedError.errorBoundaryName = getComponentName(boundary.type); - capturedError.errorBoundaryFound = true; - capturedError.willRetry = true; - } + renderState.last = renderedTail; + } + } - 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 (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 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. + 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. -function safelyCallComponentWillUnmount(current$$1, instance) { - { - invokeGuardedCallback( - null, - callComponentWillUnmountWithTimer, - null, - current$$1, - instance - ); - if (hasCaughtError()) { - var unmountError = clearCaughtError(); - captureCommitPhaseError(current$$1, unmountError); - } - } -} + var suspenseContext = suspenseStackCursor.current; -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); + if (didSuspendAlready) { + suspenseContext = setShallowSuspenseContext( + suspenseContext, + ForceSuspenseFallback + ); + } else { + suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); } + + pushSuspenseContext(workInProgress, suspenseContext); // Do a pass over the next row. + + return next; } - } else { - ref.current = null; + + return null; } } -} -function safelyCallDestroy(current$$1, destroy) { { - invokeGuardedCallback(null, destroy, null); - if (hasCaughtError()) { - var error = clearCaughtError(); - captureCommitPhaseError(current$$1, error); - } + throw Error( + "Unknown unit of work tag (" + + workInProgress.tag + + "). This error is likely caused by a bug in React. Please file an issue." + ); } } -function commitBeforeMutationLifeCycles(current$$1, finishedWork) { - switch (finishedWork.tag) { - case FunctionComponent: - case ForwardRef: - case SimpleMemoComponent: { - commitHookEffectList(UnmountSnapshot, NoEffect$1, finishedWork); - return; - } +function unwindWork(workInProgress, renderExpirationTime) { + switch (workInProgress.tag) { case ClassComponent: { - 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. + var Component = workInProgress.type; - { - 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 - ); + if (isContextProvider(Component)) { + popContext(workInProgress); + } - { - var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate; + var effectTag = workInProgress.effectTag; - 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(); - } + if (effectTag & ShouldCapture) { + workInProgress.effectTag = (effectTag & ~ShouldCapture) | DidCapture; + return workInProgress; } - return; + return null; } - case HostRoot: - case HostComponent: - case HostText: - case HostPortal: - case IncompleteClassComponent: - // Nothing to do for these component types - return; + case HostRoot: { + popHostContainer(workInProgress); + popTopLevelContextObject(workInProgress); + var _effectTag = workInProgress.effectTag; - default: { - { + if (!((_effectTag & DidCapture) === NoEffect)) { 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." + "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." ); } - } - } -} -function commitHookEffectList(unmountTag, mountTag, finishedWork) { - var updateQueue = finishedWork.updateQueue; - var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; + workInProgress.effectTag = (_effectTag & ~ShouldCapture) | DidCapture; + return workInProgress; + } - if (lastEffect !== null) { - var firstEffect = lastEffect.next; - var effect = firstEffect; + case HostComponent: { + // TODO: popHydrationState + popHostContext(workInProgress); + return null; + } - 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(); + case SuspenseComponent: { + popSuspenseContext(workInProgress); - { - var _destroy = effect.destroy; + var _effectTag2 = workInProgress.effectTag; - if (_destroy !== undefined && typeof _destroy !== "function") { - var addendum = void 0; + if (_effectTag2 & ShouldCapture) { + workInProgress.effectTag = (_effectTag2 & ~ShouldCapture) | DidCapture; // Captured a suspense effect. Re-render the boundary. - 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) - ); - } - } + return workInProgress; } - effect = effect.next; - } while (effect !== firstEffect); - } -} -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; - } - default: - break; + return null; } - } -} -function commitLifeCycles( - finishedRoot, - current$$1, - finishedWork, - committedExpirationTime -) { - switch (finishedWork.tag) { - case FunctionComponent: - case ForwardRef: - case SimpleMemoComponent: { - commitHookEffectList(UnmountLayout, MountLayout, finishedWork); - break; + 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 ClassComponent: { - var instance = finishedWork.stateNode; + case HostPortal: + popHostContainer(workInProgress); + return null; - 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. + case ContextProvider: + popProvider(workInProgress); + return null; - { - 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. + default: + return null; + } +} - { - 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(); - } - } +function unwindInterruptedWork(interruptedWork) { + switch (interruptedWork.tag) { + case ClassComponent: { + var childContextTypes = interruptedWork.type.childContextTypes; - var updateQueue = finishedWork.updateQueue; + if (childContextTypes !== null && childContextTypes !== undefined) { + popContext(interruptedWork); + } - 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. + break; + } - commitUpdateQueue( - finishedWork, - updateQueue, - instance, - committedExpirationTime - ); - } + case HostRoot: { + popHostContainer(interruptedWork); + popTopLevelContextObject(interruptedWork); + break; + } - return; + case HostComponent: { + popHostContext(interruptedWork); + break; } - case HostRoot: { - var _updateQueue = finishedWork.updateQueue; + case HostPortal: + popHostContainer(interruptedWork); + break; - if (_updateQueue !== null) { - var _instance = null; + case SuspenseComponent: + popSuspenseContext(interruptedWork); + break; - 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 - ); - } + case SuspenseListComponent: + popSuspenseContext(interruptedWork); + break; - return; - } + case ContextProvider: + popProvider(interruptedWork); + break; + } +} - case HostComponent: { - var _instance2 = finishedWork.stateNode; // Renderers may schedule work to be done after host components are mounted - // (eg DOM renderer may schedule auto-focus for inputs and form controls). - // These effects should only be committed when components are first mounted, - // aka when there is no current/alternate. +function 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 (current$$1 === null && finishedWork.effectTag & Update) { - var type = finishedWork.type; - var props = finishedWork.memoizedProps; - commitMount(_instance2, type, props, finishedWork); - } +// Module provided by RN: - 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; +if ( + !( + typeof ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog === + "function" + ) +) { + throw Error( + "Expected ReactFiberErrorDialog.showErrorDialog to be a function." + ); +} - 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() - ); - } - } - } +function showErrorDialog(capturedError) { + return ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog( + capturedError + ); +} - return; - } +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. - case SuspenseComponent: { - commitSuspenseHydrationCallbacks(finishedRoot, finishedWork); - return; + if (logError === false) { + return; + } + + 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 (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. + + console["error"](error); // Don't transform to our wrapper + // For a more detailed description of this block, see: + // https://github.com/facebook/react/pull/13384 } - case SuspenseListComponent: - case IncompleteClassComponent: - case FundamentalComponent: - case ScopeComponent: - 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. - 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 (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. + + console["error"](combinedMessage); // Don't transform to our wrapper } } -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; +var didWarnAboutUndefinedSnapshotBeforeUpdate = null; - while (true) { - if (node.tag === HostComponent) { - var instance = node.stateNode; +{ + didWarnAboutUndefinedSnapshotBeforeUpdate = new Set(); +} - 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; - } +var PossiblyWeakSet = typeof WeakSet === "function" ? WeakSet : Set; +function logError(boundary, errorInfo) { + var source = errorInfo.source; + var stack = errorInfo.stack; - if (node === finishedWork) { - return; - } + if (stack === null && source !== null) { + stack = getStackByFiberInDevAndProd(source); + } - while (node.sibling === null) { - if (node.return === null || node.return === finishedWork) { - 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 + }; - node = node.return; - } + if (boundary !== null && boundary.tag === ClassComponent) { + capturedError.errorBoundary = boundary.stateNode; + capturedError.errorBoundaryName = getComponentName(boundary.type); + capturedError.errorBoundaryFound = true; + capturedError.willRetry = true; + } - node.sibling.return = node.return; - node = node.sibling; + 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 callComponentWillUnmountWithTimer = function(current, instance) { + startPhaseTimer(current, "componentWillUnmount"); + instance.props = current.memoizedProps; + instance.state = current.memoizedState; + + { + instance.componentWillUnmount(); + } + + stopPhaseTimer(); +}; // Capture errors so they don't interrupt unmounting. + +function safelyCallComponentWillUnmount(current, instance) { + { + invokeGuardedCallback( + null, + callComponentWillUnmountWithTimer, + null, + current, + instance + ); + + if (hasCaughtError()) { + var unmountError = clearCaughtError(); + captureCommitPhaseError(current, unmountError); } } } -function commitAttachRef(finishedWork) { - var ref = finishedWork.ref; +function safelyDetachRef(current) { + var ref = current.ref; if (ref !== null) { - var instance = finishedWork.stateNode; - var instanceToUse; - - switch (finishedWork.tag) { - case HostComponent: - instanceToUse = getPublicInstance(instance); - break; - - default: - instanceToUse = instance; - } // Moved outside to ensure DCE works with this flag - - if (enableScopeAPI && finishedWork.tag === ScopeComponent) { - instanceToUse = instance.methods; - } - if (typeof ref === "function") { - ref(instanceToUse); - } else { { - 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) - ); + invokeGuardedCallback(null, ref, null, null); + + if (hasCaughtError()) { + var refError = clearCaughtError(); + captureCommitPhaseError(current, refError); } } - - ref.current = instanceToUse; + } else { + ref.current = null; } } } -function commitDetachRef(current$$1) { - var currentRef = current$$1.ref; - if (currentRef !== null) { - if (typeof currentRef === "function") { - currentRef(null); - } else { - currentRef.current = null; +function safelyCallDestroy(current, destroy) { + { + invokeGuardedCallback(null, destroy, null); + + if (hasCaughtError()) { + var error = clearCaughtError(); + captureCommitPhaseError(current, error); } } -} // User-originating errors (lifecycles and refs) should not interrupt -// deletion, so don't let them throw. Host-originating errors should -// interrupt deletion, so it's okay - -function commitUnmount(finishedRoot, current$$1, renderPriorityLevel) { - onCommitUnmount(current$$1); +} - switch (current$$1.tag) { +function commitBeforeMutationLifeCycles(current, finishedWork) { + switch (finishedWork.tag) { case FunctionComponent: case ForwardRef: - 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: { - safelyDetachRef(current$$1); - var instance = current$$1.stateNode; - - if (typeof instance.componentWillUnmount === "function") { - safelyCallComponentWillUnmount(current$$1, instance); - } - + case SimpleMemoComponent: + case Block: { return; } - case HostComponent: { - if (enableFlareAPI) { - var dependencies = current$$1.dependencies; - - if (dependencies !== null) { - var respondersMap = dependencies.responders; - - if (respondersMap !== null) { - var responderInstances = Array.from(respondersMap.values()); + 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. - for ( - var i = 0, length = responderInstances.length; - i < length; - i++ + { + if ( + finishedWork.type === finishedWork.elementType && + !didWarnAboutReassigningProps ) { - var responderInstance = responderInstances[i]; - unmountResponderInstance(responderInstance); + 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" + ); + } } - dependencies.responders = null; } - } - } - safelyDetachRef(current$$1); - return; - } + var snapshot = instance.getSnapshotBeforeUpdate( + finishedWork.elementType === finishedWork.type + ? prevProps + : resolveDefaultProps(finishedWork.type, prevProps), + prevState + ); - 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); - } + { + var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate; - return; - } + if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) { + didWarnSet.add(finishedWork.type); - case FundamentalComponent: { - if (enableFundamentalAPI) { - var fundamentalInstance = current$$1.stateNode; + error( + "%s.getSnapshotBeforeUpdate(): A snapshot value (or null) " + + "must be returned. You have returned undefined.", + getComponentName(finishedWork.type) + ); + } + } - if (fundamentalInstance !== null) { - unmountFundamentalComponent(fundamentalInstance); - current$$1.stateNode = null; + instance.__reactInternalSnapshotBeforeUpdate = snapshot; + stopPhaseTimer(); } } return; } - case DehydratedFragment: { - if (enableSuspenseCallback) { - var hydrationCallbacks = finishedRoot.hydrationCallbacks; - - if (hydrationCallbacks !== null) { - var onDeleted = hydrationCallbacks.onDeleted; - - if (onDeleted) { - onDeleted(current$$1.stateNode); - } - } - } - + case HostRoot: + case HostComponent: + case HostText: + case HostPortal: + case IncompleteClassComponent: + // Nothing to do for these component types return; - } + } - case ScopeComponent: { - if (enableScopeAPI) { - safelyDetachRef(current$$1); - } - } + { + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); } } -function commitNestedUnmounts(finishedRoot, root, renderPriorityLevel) { - // While we're inside a removed host node we don't want to call - // removeChild on the inner nodes because they're removed by the top - // call anyway. We also want to call componentWillUnmount on all - // composites before this host node is removed from the tree. Therefore - // we do an inner loop while we're still inside the host node. - var node = root; - - 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. +function commitHookEffectListUnmount(tag, finishedWork) { + var updateQueue = finishedWork.updateQueue; + var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; - 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 (lastEffect !== null) { + var firstEffect = lastEffect.next; + var effect = firstEffect; - if (node === root) { - return; - } + do { + if ((effect.tag & tag) === tag) { + // Unmount + var destroy = effect.destroy; + effect.destroy = undefined; - while (node.sibling === null) { - if (node.return === null || node.return === root) { - return; + if (destroy !== undefined) { + destroy(); + } } - node = node.return; - } - - 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; + effect = effect.next; + } while (effect !== firstEffect); } - - 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 commitHookEffectListMount(tag, finishedWork) { + var updateQueue = finishedWork.updateQueue; + var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; -function getHostParentFiber(fiber) { - var parent = fiber.return; - while (parent !== null) { - if (isHostParent(parent)) { - return parent; - } + if (lastEffect !== null) { + var firstEffect = lastEffect.next; + var effect = firstEffect; - parent = parent.return; - } + do { + if ((effect.tag & tag) === tag) { + // Mount + var create = effect.create; + effect.destroy = create(); - { - throw Error( - "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." - ); - } -} + { + var destroy = effect.destroy; -function isHostParent(fiber) { - return ( - fiber.tag === HostComponent || - fiber.tag === HostRoot || - fiber.tag === HostPortal - ); -} + if (destroy !== undefined && typeof destroy !== "function") { + var addendum = void 0; -function getHostSibling(fiber) { - // We're going to search forward into the tree until we find a sibling host - // node. Unfortunately, if multiple insertions are done in a row we have to - // search past them. This leads to exponential search for the next sibling. - // TODO: Find a more efficient way to do this. - var node = fiber; + if (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; + } - 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; + error( + "An effect function must not return anything besides a function, " + + "which is used for clean-up.%s%s", + addendum, + getStackByFiberInDevAndProd(finishedWork) + ); + } + } } - node = node.return; - } + effect = effect.next; + } while (effect !== firstEffect); + } +} - node.sibling.return = node.return; - node = node.sibling; +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); + } - 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; + break; } - } // Check if this host node is stable or about to be placed. - - if (!(node.effectTag & Placement)) { - // Found it! - return node.stateNode; } } } -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. +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); + } - var parent; - var isContainer; - var parentStateNode = parentFiber.stateNode; + return; + } - 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; - } + case ClassComponent: { + var instance = finishedWork.stateNode; - // eslint-disable-next-line-no-fallthrough + 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. - default: { - throw Error( - "Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue." - ); - } - } + { + if ( + finishedWork.type === finishedWork.elementType && + !didWarnAboutReassigningProps + ) { + if (instance.props !== finishedWork.memoizedProps) { + error( + "Expected %s props to match memoized props before " + + "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 (parentFiber.effectTag & ContentReset) { - // Reset the text content of the parent before doing any insertions - resetTextContent(parent); // Clear ContentReset from the effect tag + 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" + ); + } + } + } - parentFiber.effectTag &= ~ContentReset; - } + { + instance.componentDidMount(); + } - 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. + 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 node = finishedWork; + { + 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" + ); + } - while (true) { - var isHost = node.tag === HostComponent || node.tag === HostText; + if (instance.state !== finishedWork.memoizedState) { + error( + "Expected %s state to match memoized state before " + + "componentDidUpdate. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.state`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } + } + } - if (isHost || (enableFundamentalAPI && node.tag === FundamentalComponent)) { - var stateNode = isHost ? node.stateNode : node.stateNode.instance; + { + instance.componentDidUpdate( + prevProps, + prevState, + instance.__reactInternalSnapshotBeforeUpdate + ); + } - if (before) { - if (isContainer) { - insertInContainerBefore(parent, stateNode, before); - } else { - insertBefore(parent, stateNode, before); - } - } else { - if (isContainer) { - appendChildToContainer(parent, stateNode); - } else { - appendChild(parent, stateNode); + stopPhaseTimer(); } } - } 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; - } + var updateQueue = finishedWork.updateQueue; - while (node.sibling === null) { - if (node.return === null || node.return === finishedWork) { - return; + if (updateQueue !== null) { + { + if ( + finishedWork.type === finishedWork.elementType && + !didWarnAboutReassigningProps + ) { + if (instance.props !== finishedWork.memoizedProps) { + error( + "Expected %s props to match memoized props before " + + "processing the update queue. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } + + if (instance.state !== finishedWork.memoizedState) { + error( + "Expected %s state to match memoized state before " + + "processing the update queue. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.state`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } + } + } // We could update instance props and state here, + // but instead we rely on them being set during last render. + // TODO: revisit this when we implement resuming. + + commitUpdateQueue(finishedWork, updateQueue, instance); } - node = node.return; + return; } - node.sibling.return = node.return; - node = node.sibling; - } -} + case HostRoot: { + var _updateQueue = finishedWork.updateQueue; -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 (_updateQueue !== null) { + var _instance = null; - var currentParentIsValid = false; // Note: these two variables *must* always be updated together. + if (finishedWork.child !== null) { + switch (finishedWork.child.tag) { + case HostComponent: + _instance = getPublicInstance(finishedWork.child.stateNode); + break; - var currentParent; - var currentParentIsContainer; + case ClassComponent: + _instance = finishedWork.child.stateNode; + break; + } + } - while (true) { - if (!currentParentIsValid) { - var parent = node.return; + commitUpdateQueue(finishedWork, _updateQueue, _instance); + } - findParent: while (true) { - if (!(parent !== null)) { - throw Error( - "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." - ); - } + return; + } - var parentStateNode = parent.stateNode; - - 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; - } - } + 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. - parent = parent.return; + if (current === null && finishedWork.effectTag & Update) { + var type = finishedWork.type; + var props = finishedWork.memoizedProps; + commitMount(); } - currentParentIsValid = true; + 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 HostText: { + // We have no life-cycles associated with text. + 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 HostPortal: { + // We have no life-cycles associated with portals. + return; + } - if (hydrationCallbacks !== null) { - var onDeleted = hydrationCallbacks.onDeleted; + case Profiler: { + { + var _finishedWork$memoize2 = finishedWork.memoizedProps, + onCommit = _finishedWork$memoize2.onCommit, + onRender = _finishedWork$memoize2.onRender; + var effectDuration = finishedWork.stateNode.effectDuration; + var commitTime = getCommitTime(); - if (onDeleted) { - onDeleted(node.stateNode); + if (typeof onRender === "function") { + { + onRender( + finishedWork.memoizedProps.id, + current === null ? "mount" : "update", + finishedWork.actualDuration, + finishedWork.treeBaseDuration, + finishedWork.actualStartTime, + commitTime, + finishedRoot.memoizedInteractions + ); } } - } // 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; } - if (node === current$$1) { + case SuspenseComponent: { return; } - while (node.sibling === null) { - if (node.return === null || node.return === current$$1) { - return; - } - - node = node.return; + case SuspenseListComponent: + case IncompleteClassComponent: + case FundamentalComponent: + case ScopeComponent: + 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; + { + 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$$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); - } +function commitAttachRef(finishedWork) { + var ref = finishedWork.ref; - detachFiber(current$$1); -} + if (ref !== null) { + var instance = finishedWork.stateNode; + var instanceToUse; -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 HostComponent: + instanceToUse = getPublicInstance(instance); + break; - case Profiler: { - return; - } + default: + instanceToUse = instance; + } // Moved outside to ensure DCE works with this flag - case SuspenseComponent: { - commitSuspenseComponent(finishedWork); - attachSuspenseRetryListeners(finishedWork); - return; - } - case SuspenseListComponent: { - attachSuspenseRetryListeners(finishedWork); - 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 HostRoot: { - if (supportsHydration) { - var root = finishedWork.stateNode; + ref.current = instanceToUse; + } + } +} - if (root.hydrate) { - // We've just hydrated. No need to hydrate again. - root.hydrate = false; - commitHydratedContainer(root.containerInfo); - } - } +function commitDetachRef(current) { + var currentRef = current.ref; - break; - } + if (currentRef !== null) { + if (typeof currentRef === "function") { + currentRef(null); + } else { + currentRef.current = null; } - - commitContainer(finishedWork); - return; } +} // User-originating errors (lifecycles and refs) should not interrupt +// deletion, so don't let them throw. Host-originating errors should +// interrupt deletion, so it's okay - switch (finishedWork.tag) { +function commitUnmount(finishedRoot, current, renderPriorityLevel) { + onCommitUnmount(current); + + switch (current.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 ClassComponent: { - return; - } - - case HostComponent: { - var instance = finishedWork.stateNode; - - if (instance != null) { - // Commit the work prepared earlier. - var newProps = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps - // as the newProps. The updatePayload will contain the real change in - // this case. - - var oldProps = - current$$1 !== null ? current$$1.memoizedProps : newProps; - var type = finishedWork.type; // TODO: Type the updateQueue to be specific to host components. + case SimpleMemoComponent: + case Block: { + var updateQueue = current.updateQueue; - var updatePayload = finishedWork.updateQueue; - finishedWork.updateQueue = null; + if (updateQueue !== null) { + var lastEffect = updateQueue.lastEffect; - if (updatePayload !== null) { - commitUpdate( - instance, - updatePayload, - type, - oldProps, - newProps, - finishedWork - ); - } + if (lastEffect !== null) { + var firstEffect = lastEffect.next; - if (enableFlareAPI) { - var prevListeners = oldProps.listeners; - var nextListeners = newProps.listeners; + { + // 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 (prevListeners !== nextListeners) { - updateEventListeners(nextListeners, finishedWork, null); + effect = effect.next; + } while (effect !== firstEffect); + }); } } } @@ -18935,164 +15839,199 @@ function commitWork(current$$1, finishedWork) { return; } - case HostText: { - if (!(finishedWork.stateNode !== null)) { - throw Error( - "This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue." - ); - } + case ClassComponent: { + safelyDetachRef(current); + var instance = current.stateNode; - var textInstance = finishedWork.stateNode; - var newText = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps - // as the newProps. The updatePayload will contain the real change in - // this case. + if (typeof instance.componentWillUnmount === "function") { + safelyCallComponentWillUnmount(current, instance); + } - var oldText = current$$1 !== null ? current$$1.memoizedProps : newText; - commitTextUpdate(textInstance, oldText, newText); return; } - case HostRoot: { - if (supportsHydration) { - var _root = finishedWork.stateNode; + case HostComponent: { + safelyDetachRef(current); + return; + } - if (_root.hydrate) { - // We've just hydrated. No need to hydrate again. - _root.hydrate = false; - commitHydratedContainer(_root.containerInfo); - } + case HostPortal: { + // TODO: this is recursive. + // We are also not using this parent because + // the portal will get pushed immediately. + { + emptyPortalContainer(current); } return; } - case Profiler: { + case FundamentalComponent: { return; } - case SuspenseComponent: { - commitSuspenseComponent(finishedWork); - attachSuspenseRetryListeners(finishedWork); + case DehydratedFragment: { return; } - case SuspenseListComponent: { - attachSuspenseRetryListeners(finishedWork); + + case ScopeComponent: { return; } + } +} - case IncompleteClassComponent: { +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) { return; } - case FundamentalComponent: { - if (enableFundamentalAPI) { - var fundamentalInstance = finishedWork.stateNode; - updateFundamentalComponent(fundamentalInstance); + while (node.sibling === null) { + if (node.return === null || node.return === root) { + return; } - return; + node = node.return; } - case ScopeComponent: { - if (enableScopeAPI) { - var scopeInstance = finishedWork.stateNode; - scopeInstance.fiber = finishedWork; + node.sibling.return = node.return; + node = node.sibling; + } +} - if (enableFlareAPI) { - var _newProps = finishedWork.memoizedProps; +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. - var _oldProps = - current$$1 !== null ? current$$1.memoizedProps : _newProps; + 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 _prevListeners = _oldProps.listeners; - var _nextListeners = _newProps.listeners; + if (alternate !== null) { + detachFiber(alternate); + } +} - if (_prevListeners !== _nextListeners) { - updateEventListeners(_nextListeners, finishedWork, null); - } - } - } +function emptyPortalContainer(current) { + var portal = current.stateNode; + var containerInfo = portal.containerInfo; + var emptyChildSet = createContainerChildSet(containerInfo); +} +function commitContainer(finishedWork) { + switch (finishedWork.tag) { + case ClassComponent: + case HostComponent: + case HostText: + case FundamentalComponent: { 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." - ); - } + case HostRoot: + case HostPortal: { + var portalOrRoot = finishedWork.stateNode; + var containerInfo = portalOrRoot.containerInfo, + pendingChildren = portalOrRoot.pendingChildren; + return; } } -} -function commitSuspenseComponent(finishedWork) { - var newState = finishedWork.memoizedState; - var newDidTimeout; - var primaryChildParent = finishedWork; - - if (newState === null) { - newDidTimeout = false; - } else { - newDidTimeout = true; - primaryChildParent = finishedWork.child; - markCommitTimeOfFallback(); + { + 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 (supportsMutation && primaryChildParent !== null) { - hideOrUnhideAllChildren(primaryChildParent, newDidTimeout); +function commitDeletion(finishedRoot, current, renderPriorityLevel) { + { + // Detach refs and call componentWillUnmount() on the whole subtree. + commitNestedUnmounts(finishedRoot, current, renderPriorityLevel); } - if (enableSuspenseCallback && newState !== null) { - var suspenseCallback = finishedWork.memoizedProps.suspenseCallback; + detachFiber(current); +} + +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 (typeof suspenseCallback === "function") { - var thenables = finishedWork.updateQueue; + return; + } - if (thenables !== null) { - suspenseCallback(new Set(thenables)); + case Profiler: { + return; } - } else { - if (suspenseCallback !== undefined) { - warning$1(false, "Unexpected type for suspenseCallback."); + + case SuspenseComponent: { + commitSuspenseComponent(finishedWork); + attachSuspenseRetryListeners(finishedWork); + return; + } + + case SuspenseListComponent: { + attachSuspenseRetryListeners(finishedWork); + return; } } - } -} -function commitSuspenseHydrationCallbacks(finishedRoot, finishedWork) { - if (!supportsHydration) { + commitContainer(finishedWork); return; } +} +function commitSuspenseComponent(finishedWork) { var newState = finishedWork.memoizedState; + var primaryChildParent = finishedWork; - 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); - } - } - } - } - } - } + if (newState === null); + else { + primaryChildParent = finishedWork.child; + markCommitTimeOfFallback(); } } @@ -19115,7 +16054,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); } @@ -19128,14 +16067,6 @@ 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) { @@ -19153,6 +16084,7 @@ function createRootErrorUpdate(fiber, errorInfo, expirationTime) { onUncaughtError(error); logError(fiber, errorInfo); }; + return update; } @@ -19162,20 +16094,22 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { var getDerivedStateFromError = fiber.type.getDerivedStateFromError; if (typeof getDerivedStateFromError === "function") { - var error = errorInfo.value; + var error$1 = errorInfo.value; update.payload = function() { logError(fiber, errorInfo); - return getDerivedStateFromError(error); + return getDerivedStateFromError(error$1); }; } 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. @@ -19187,24 +16121,24 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { logError(fiber, errorInfo); } - var error = errorInfo.value; + var error$1 = errorInfo.value; var stack = errorInfo.stack; - this.componentDidCatch(error, { + this.componentDidCatch(error$1, { componentStack: stack !== null ? stack : "" }); + { if (typeof getDerivedStateFromError !== "function") { // If componentDidCatch is the only error boundary method defined, // then it needs to call setState to recover from errors. // If no state update is scheduled then the boundary will swallow the error. - !(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; + 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" + ); + } } } }; @@ -19213,6 +16147,7 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { markFailedErrorBoundaryForHotReloading(fiber); }; } + return update; } @@ -19229,11 +16164,13 @@ 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); @@ -19266,7 +16203,22 @@ function throwException( ) { // This is a thenable. var thenable = value; - checkForWrongSuspensePriorityInDEV(sourceFiber); + + 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; + } + } + var hasInvisibleParentBoundary = hasSuspenseContext( suspenseStackCursor.current, InvisibleParentSuspenseContext @@ -19308,6 +16260,7 @@ 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 @@ -19401,6 +16354,7 @@ function throwException( var _errorInfo = value; workInProgress.effectTag |= ShouldCapture; workInProgress.expirationTime = renderExpirationTime; + var _update = createRootErrorUpdate( workInProgress, _errorInfo, @@ -19416,6 +16370,7 @@ function throwException( var errorInfo = value; var ctor = workInProgress.type; var instance = workInProgress.stateNode; + if ( (workInProgress.effectTag & DidCapture) === NoEffect && (typeof ctor.getDerivedStateFromError === "function" || @@ -19437,9 +16392,6 @@ function throwException( } break; - - default: - break; } workInProgress = workInProgress.return; @@ -19447,18 +16399,15 @@ function throwException( } var ceil = Math.ceil; -var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher; -var ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner; -var IsSomeRendererActing = ReactSharedInternals.IsSomeRendererActing; +var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, + ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, + IsSomeRendererActing = ReactSharedInternals.IsSomeRendererActing; var NoContext = /* */ 0; var BatchedContext = /* */ 1; -var EventContext = - /* */ - 2; var DiscreteEventContext = /* */ 4; @@ -19484,7 +16433,7 @@ var workInProgressRoot = null; // The fiber we're working on var workInProgress = null; // The expiration time we're rendering -var renderExpirationTime = NoWork; // Whether to root completed, errored, suspended, etc. +var renderExpirationTime$1 = NoWork; // Whether to root completed, errored, suspended, etc. var workInProgressRootExitStatus = RootIncomplete; // A fatal error, if one is thrown @@ -19561,6 +16510,7 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { } var priorityLevel = getCurrentPriorityLevel(); + if ((mode & ConcurrentMode) === NoMode) { return priorityLevel === ImmediatePriority ? Sync : Batched; } @@ -19568,7 +16518,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; + return renderExpirationTime$1; } var expirationTime; @@ -19585,10 +16535,12 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { case ImmediatePriority: expirationTime = Sync; break; - case UserBlockingPriority$1: + + case UserBlockingPriority: // TODO: Rename this to computeUserBlockingExpiration expirationTime = computeInteractiveExpiration(currentTime); break; + case NormalPriority: case LowPriority: // TODO: Handle LowPriority @@ -19609,7 +16561,11 @@ 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) { + + if ( + workInProgressRoot !== null && + expirationTime === renderExpirationTime$1 + ) { // This is a trick to move this update into a separate batch expirationTime -= 1; } @@ -19618,7 +16574,7 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { } function scheduleUpdateOnFiber(fiber, expirationTime) { checkForNestedUpdates(); - warnAboutInvalidUpdatesOnClassComponentsInDEV(fiber); + warnAboutRenderPhaseUpdatesInDEV(fiber); var root = markUpdateTimeFromFiberToRoot(fiber, expirationTime); if (root === null) { @@ -19665,7 +16621,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$1 || + (priorityLevel === UserBlockingPriority || priorityLevel === ImmediatePriority) ) { // This is the result of a discrete event. Track the lowest priority @@ -19674,6 +16630,7 @@ function scheduleUpdateOnFiber(fiber, expirationTime) { rootsWithPendingDiscreteUpdates = new Map([[root, expirationTime]]); } else { var lastDiscreteTime = rootsWithPendingDiscreteUpdates.get(root); + if (lastDiscreteTime === undefined || lastDiscreteTime > expirationTime) { rootsWithPendingDiscreteUpdates.set(root, expirationTime); } @@ -19721,10 +16678,12 @@ function markUpdateTimeFromFiberToRoot(fiber, expirationTime) { ) { alternate.childExpirationTime = expirationTime; } + if (node.return === null && node.tag === HostRoot) { root = node.stateNode; break; } + node = node.return; } } @@ -19749,7 +16708,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); + markRootSuspendedAtTime(root, renderExpirationTime$1); } } // Mark that the root has a pending update. @@ -19781,9 +16740,17 @@ function getNextRootExpirationTimeToWorkOn(root) { var lastPingedTime = root.lastPingedTime; var nextKnownPendingLevel = root.nextKnownPendingLevel; - return lastPingedTime > nextKnownPendingLevel - ? lastPingedTime - : 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; } // 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 @@ -19850,11 +16817,6 @@ 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, @@ -19873,7 +16835,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; + currentEventTime = NoWork; // Check if the render expired. if (didTimeout) { // The render task took too long to complete. Mark the current time as @@ -19888,83 +16850,50 @@ function performConcurrentWorkOnRoot(root, didTimeout) { var expirationTime = getNextRootExpirationTimeToWorkOn(root); - if (expirationTime !== NoWork) { - var originalCallbackNode = root.callbackNode; - - 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 ( - 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 (expirationTime === NoWork) { + return null; + } - if (workInProgress !== null) { - var prevExecutionContext = executionContext; - executionContext |= RenderContext; - var prevDispatcher = pushDispatcher(root); - var prevInteractions = pushInteractions(root); - startWorkLoopTimer(workInProgress); + var originalCallbackNode = root.callbackNode; - do { - try { - workLoopConcurrent(); - break; - } catch (thrownValue) { - handleError(root, thrownValue); - } - } while (true); + if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { + throw Error("Should not already be working."); + } - resetContextDependencies(); - executionContext = prevExecutionContext; - popDispatcher(prevDispatcher); + flushPassiveEffects(); + var exitStatus = renderRootConcurrent(root, expirationTime); - if (enableSchedulerTracing) { - popInteractions(prevInteractions); - } + 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 (workInProgressRootExitStatus === RootFatalErrored) { - var fatalError = workInProgressRootFatalError; - stopInterruptedWorkLoopTimer(); - prepareFreshStack(root, expirationTime); - markRootSuspendedAtTime(root, expirationTime); - ensureRootIsScheduled(root); - throw fatalError; - } + 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. - 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 - ); - } + var finishedWork = (root.finishedWork = root.current.alternate); + root.finishedExpirationTime = expirationTime; + finishConcurrentRender(root, finishedWork, exitStatus, expirationTime); + } - ensureRootIsScheduled(root); + 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; @@ -19976,9 +16905,6 @@ function finishConcurrentRender( exitStatus, expirationTime ) { - // Set this to null to indicate there's no in-progress render. - workInProgressRoot = null; - switch (exitStatus) { case RootIncomplete: case RootFatalErrored: { @@ -19991,19 +16917,9 @@ function finishConcurrentRender( // if I do. eslint-disable-next-line no-fallthrough case RootErrored: { - // 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. - + // We should have already attempted to retry this tree. If we reached + // this point, it errored again. Commit it. + commitRoot(root); break; } @@ -20013,9 +16929,7 @@ function finishConcurrentRender( if (expirationTime === lastSuspendedTime) { root.nextKnownPendingLevel = getRemainingExpirationTime(finishedWork); - } - - flushSuspensePriorityWarningInDEV(); // We have an acceptable loading state. We need to figure out if we + } // 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 @@ -20026,7 +16940,7 @@ function finishConcurrentRender( if ( hasNotProcessedNewUpdates && // do not delay if we're inside an act() scope - !(true && flushSuspenseFallbacksInTests && IsThisRendererActing.current) + !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 @@ -20090,12 +17004,7 @@ 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) { @@ -20150,6 +17059,7 @@ 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; @@ -20184,11 +17094,6 @@ 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 ) { @@ -20226,147 +17131,65 @@ function finishConcurrentRender( // through Scheduler function performSyncWorkOnRoot(root) { - // Check if there's expired work on this root. Otherwise, render at Sync. - var lastExpiredTime = root.lastExpiredTime; - 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."); - } + 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 lastExpiredTime = root.lastExpiredTime; + var expirationTime; + if (lastExpiredTime !== NoWork) { + // There's expired work on this root. Check if we have a partial tree + // that we can reuse. if ( - root !== workInProgressRoot || - expirationTime !== renderExpirationTime + root === workInProgressRoot && + renderExpirationTime$1 >= 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); + // 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; } + } else { + // There's no expired work. This must be a new, synchronous render. + expirationTime = Sync; } - return null; -} - -function finishSyncRender(root, exitStatus, expirationTime) { - // Set this to null to indicate there's no in-progress render. - workInProgressRoot = null; + var exitStatus = renderRootSync(root, expirationTime); - { - if (exitStatus === RootSuspended || exitStatus === RootSuspendedWithDelay) { - flushSuspensePriorityWarningInDEV(); - } + 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); } - 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; - } + 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. - flushPendingDiscreteUpdates(); // If the discrete updates scheduled passive effects, flush them now so that - // they fire before the next serial event. + root.finishedWork = root.current.alternate; + root.finishedExpirationTime = expirationTime; + commitRoot(root); // Before exiting, make sure there's a callback scheduled for the next + // pending level. - flushPassiveEffects(); + ensureRootIsScheduled(root); + return null; } - function syncUpdates(fn, 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(); - } + return runWithPriority(ImmediatePriority, fn.bind(null, a, b, c)); } function batchedUpdates$1(fn, a) { @@ -20384,38 +17207,6 @@ 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) { { @@ -20429,7 +17220,7 @@ function flushSync(fn, a) { executionContext |= BatchedContext; try { - return runWithPriority$1(ImmediatePriority, fn.bind(null, a)); + return runWithPriority(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 @@ -20462,8 +17253,8 @@ function prepareFreshStack(root, expirationTime) { } workInProgressRoot = root; - workInProgress = createWorkInProgress(root.current, null, expirationTime); - renderExpirationTime = expirationTime; + workInProgress = createWorkInProgress(root.current, null); + renderExpirationTime$1 = expirationTime; workInProgressRootExitStatus = RootIncomplete; workInProgressRootFatalError = null; workInProgressRootLatestProcessedExpirationTime = Sync; @@ -20472,13 +17263,12 @@ function prepareFreshStack(root, expirationTime) { workInProgressRootNextUnprocessedUpdateTime = NoWork; workInProgressRootHasPendingPing = false; - if (enableSchedulerTracing) { + { spawnedWorkDuringRender = null; } { ReactStrictModeWarnings.discardPendingWarnings(); - componentsThatTriggeredHighPriSuspend = null; } } @@ -20487,7 +17277,7 @@ function handleError(root, thrownValue) { try { // Reset module-level state that was set during the render phase. resetContextDependencies(); - resetHooks(); + resetHooksAfterThrow(); resetCurrentFiber(); if (workInProgress === null || workInProgress.return === null) { @@ -20496,7 +17286,14 @@ function handleError(root, thrownValue) { // supposed to capture all errors that weren't caught by an error // boundary. workInProgressRootExitStatus = RootFatalErrored; - workInProgressRootFatalError = thrownValue; + 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; return null; } @@ -20512,7 +17309,7 @@ function handleError(root, thrownValue) { workInProgress.return, workInProgress, thrownValue, - renderExpirationTime + renderExpirationTime$1 ); workInProgress = completeUnitOfWork(workInProgress); } catch (yetAnotherThrownValue) { @@ -20526,8 +17323,8 @@ function handleError(root, thrownValue) { } function pushDispatcher(root) { - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = ContextOnlyDispatcher; + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; if (prevDispatcher === null) { // The React isomorphic package does not include a default dispatcher. @@ -20540,21 +17337,19 @@ function pushDispatcher(root) { } function popDispatcher(prevDispatcher) { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.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; } } @@ -20607,7 +17402,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); + markRootSuspendedAtTime(workInProgressRoot, renderExpirationTime$1); markRootUpdatedAtTime( workInProgressRoot, workInProgressRootNextUnprocessedUpdateTime @@ -20646,6 +17441,56 @@ 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 */ @@ -20656,6 +17501,55 @@ 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() { @@ -20669,21 +17563,22 @@ 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$$1 = unitOfWork.alternate; + var current = unitOfWork.alternate; startWorkTimer(unitOfWork); setCurrentFiber(unitOfWork); var next; - if (enableProfilerTimer && (unitOfWork.mode & ProfileMode) !== NoMode) { + if ((unitOfWork.mode & ProfileMode) !== NoMode) { startProfilerTimer(unitOfWork); - next = beginWork$$1(current$$1, unitOfWork, renderExpirationTime); + next = beginWork$1(current, unitOfWork, renderExpirationTime$1); stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true); } else { - next = beginWork$$1(current$$1, unitOfWork, renderExpirationTime); + next = beginWork$1(current, unitOfWork, renderExpirationTime$1); } resetCurrentFiber(); unitOfWork.memoizedProps = unitOfWork.pendingProps; + if (next === null) { // If this doesn't spawn new work, complete the current work. next = completeUnitOfWork(unitOfWork); @@ -20697,25 +17592,23 @@ 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$$1 = workInProgress.alternate; + var current = 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 ( - !enableProfilerTimer || - (workInProgress.mode & ProfileMode) === NoMode - ) { - next = completeWork(current$$1, workInProgress, renderExpirationTime); + if ((workInProgress.mode & ProfileMode) === NoMode) { + next = completeWork(current, workInProgress, renderExpirationTime$1); } else { startProfilerTimer(workInProgress); - next = completeWork(current$$1, workInProgress, renderExpirationTime); // Update render duration assuming we didn't error. + next = completeWork(current, workInProgress, renderExpirationTime$1); // Update render duration assuming we didn't error. stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false); } @@ -20739,6 +17632,7 @@ function completeUnitOfWork(unitOfWork) { if (returnFiber.firstEffect === null) { returnFiber.firstEffect = workInProgress.firstEffect; } + if (workInProgress.lastEffect !== null) { if (returnFiber.lastEffect !== null) { returnFiber.lastEffect.nextEffect = workInProgress.firstEffect; @@ -20762,6 +17656,7 @@ function completeUnitOfWork(unitOfWork) { } else { returnFiber.firstEffect = workInProgress; } + returnFiber.lastEffect = workInProgress; } } @@ -20769,12 +17664,9 @@ 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, renderExpirationTime); // Because this fiber did not complete, don't reset its expiration time. + var _next = unwindWork(workInProgress); // Because this fiber did not complete, don't reset its expiration time. - if ( - enableProfilerTimer && - (workInProgress.mode & ProfileMode) !== NoMode - ) { + if ((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. @@ -20785,6 +17677,7 @@ function completeUnitOfWork(unitOfWork) { actualDuration += child.actualDuration; child = child.sibling; } + workInProgress.actualDuration = actualDuration; } @@ -20799,6 +17692,7 @@ function completeUnitOfWork(unitOfWork) { _next.effectTag &= HostEffectMask; return _next; } + stopWorkTimer(workInProgress); if (returnFiber !== null) { @@ -20835,7 +17729,7 @@ function getRemainingExpirationTime(fiber) { function resetChildExpirationTime(completedWork) { if ( - renderExpirationTime !== Never && + renderExpirationTime$1 !== Never && completedWork.childExpirationTime === Never ) { // The children of this component are hidden. Don't bubble their @@ -20845,7 +17739,7 @@ function resetChildExpirationTime(completedWork) { var newChildExpirationTime = NoWork; // Bubble up the earliest expiration time. - if (enableProfilerTimer && (completedWork.mode & ProfileMode) !== NoMode) { + if ((completedWork.mode & ProfileMode) !== NoMode) { // In profiling mode, resetChildExpirationTime is also used to reset // profiler durations. var actualDuration = completedWork.actualDuration; @@ -20908,7 +17802,7 @@ function resetChildExpirationTime(completedWork) { function commitRoot(root) { var renderPriorityLevel = getCurrentPriorityLevel(); - runWithPriority$1( + runWithPriority( ImmediatePriority, commitRootImpl.bind(null, root, renderPriorityLevel) ); @@ -20916,7 +17810,16 @@ function commitRoot(root) { } function commitRootImpl(root, renderPriorityLevel) { - flushPassiveEffects(); + 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); + flushRenderPhaseStrictModeWarningsInDEV(); if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { @@ -20960,8 +17863,7 @@ function commitRootImpl(root, renderPriorityLevel) { // We can reset these now that they are finished. workInProgressRoot = null; workInProgress = null; - renderExpirationTime = NoWork; - } else { + renderExpirationTime$1 = NoWork; } // 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. @@ -21016,9 +17918,10 @@ 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(); @@ -21092,7 +17995,7 @@ function commitRootImpl(root, renderPriorityLevel) { requestPaint(); - if (enableSchedulerTracing) { + { popInteractions(prevInteractions); } @@ -21106,7 +18009,7 @@ function commitRootImpl(root, renderPriorityLevel) { startCommitSnapshotEffectsTimer(); stopCommitSnapshotEffectsTimer(); - if (enableProfilerTimer) { + { recordCommitTime(); } @@ -21131,6 +18034,7 @@ 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; @@ -21141,10 +18045,11 @@ 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, @@ -21162,7 +18067,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. @@ -21216,8 +18121,8 @@ function commitBeforeMutationEffects() { if ((effectTag & Snapshot) !== NoEffect) { setCurrentFiber(nextEffect); recordEffect(); - var current$$1 = nextEffect.alternate; - commitBeforeMutationLifeCycles(current$$1, nextEffect); + var current = nextEffect.alternate; + commitBeforeMutationLifeCycles(current, nextEffect); resetCurrentFiber(); } @@ -21243,15 +18148,11 @@ function commitMutationEffects(root, renderPriorityLevel) { setCurrentFiber(nextEffect); var effectTag = nextEffect.effectTag; - if (effectTag & ContentReset) { - commitResetTextContent(nextEffect); - } - if (effectTag & Ref) { - var current$$1 = nextEffect.alternate; + var current = nextEffect.alternate; - if (current$$1 !== null) { - commitDetachRef(current$$1); + if (current !== null) { + commitDetachRef(current); } } // The following switch statement is only concerned about placement, // updates, and deletions. To avoid needing to add a case for every possible @@ -21263,7 +18164,6 @@ 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. @@ -21273,8 +18173,6 @@ 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 @@ -21323,8 +18221,8 @@ function commitLayoutEffects(root, committedExpirationTime) { if (effectTag & (Update | Callback)) { recordEffect(); - var current$$1 = nextEffect.alternate; - commitLifeCycles(root, current$$1, nextEffect, committedExpirationTime); + var current = nextEffect.alternate; + commitLifeCycles(root, current, nextEffect); } if (effectTag & Ref) { @@ -21344,7 +18242,7 @@ function flushPassiveEffects() { ? NormalPriority : pendingPassiveEffectsRenderPriority; pendingPassiveEffectsRenderPriority = NoPriority; - return runWithPriority$1(priorityLevel, flushPassiveEffectsImpl); + return runWithPriority(priorityLevel, flushPassiveEffectsImpl); } } @@ -21364,36 +18262,40 @@ 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 prevInteractions = pushInteractions(root); - var effect = root.current.firstEffect; + { + // 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 (effect !== null) { - { - setCurrentFiber(effect); - invokeGuardedCallback(null, commitPassiveHookEffects, null, effect); + while (_effect2 !== null) { + { + setCurrentFiber(_effect2); + invokeGuardedCallback(null, commitPassiveHookEffects, null, _effect2); - if (hasCaughtError()) { - if (!(effect !== null)) { - throw Error("Should be working on an effect."); + if (hasCaughtError()) { + if (!(_effect2 !== null)) { + throw Error("Should be working on an effect."); + } + + var _error5 = clearCaughtError(); + + captureCommitPhaseError(_effect2, _error5); } - var error = clearCaughtError(); - captureCommitPhaseError(effect, error); + resetCurrentFiber(); } - resetCurrentFiber(); - } - - var nextNextEffect = effect.nextEffect; // Remove nextEffect pointer to assist GC + var nextNextEffect = _effect2.nextEffect; // Remove nextEffect pointer to assist GC - effect.nextEffect = null; - effect = nextNextEffect; + _effect2.nextEffect = null; + _effect2 = nextNextEffect; + } } - if (enableSchedulerTracing) { + { popInteractions(prevInteractions); finishPendingInteractions(root, expirationTime); } @@ -21427,6 +18329,7 @@ function prepareToThrowUncaughtError(error) { firstUncaughtError = error; } } + var onUncaughtError = prepareToThrowUncaughtError; function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { @@ -21450,6 +18353,7 @@ function captureCommitPhaseError(sourceFiber, error) { } var fiber = sourceFiber.return; + while (fiber !== null) { if (fiber.tag === HostRoot) { captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error); @@ -21457,6 +18361,7 @@ 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" && @@ -21492,7 +18397,7 @@ function pingSuspendedRoot(root, thenable, suspendedTime) { pingCache.delete(thenable); } - if (workInProgressRoot === root && renderExpirationTime === suspendedTime) { + if (workInProgressRoot === root && renderExpirationTime$1 === 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. @@ -21512,7 +18417,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); + prepareFreshStack(root, renderExpirationTime$1); } else { // Even though we can't restart right now, we might get an // opportunity later. So we mark this render as having a ping. @@ -21535,13 +18440,6 @@ 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); } @@ -21569,45 +18467,12 @@ 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; } @@ -21627,20 +18492,21 @@ 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( @@ -21662,6 +18528,7 @@ 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. @@ -21688,8 +18555,8 @@ function checkForNestedUpdates() { { if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) { nestedPassiveUpdateCount = 0; - warning$1( - false, + + error( "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 " + @@ -21703,7 +18570,7 @@ function flushRenderPhaseStrictModeWarningsInDEV() { { ReactStrictModeWarnings.flushLegacyContextWarning(); - if (warnAboutDeprecatedLifecycles) { + { ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings(); } } @@ -21724,9 +18591,8 @@ function stopInterruptedWorkLoopTimer() { function checkForInterruption(fiberThatReceivedUpdate, updateExpirationTime) { if ( - enableUserTimingAPI && workInProgressRoot !== null && - updateExpirationTime > renderExpirationTime + updateExpirationTime > renderExpirationTime$1 ) { interruptedBy = fiberThatReceivedUpdate; } @@ -21744,11 +18610,12 @@ function warnAboutUpdateOnUnmountedFiberInDEV(fiber) { tag !== FunctionComponent && tag !== ForwardRef && tag !== MemoComponent && - tag !== SimpleMemoComponent + tag !== SimpleMemoComponent && + tag !== Block ) { // 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"; @@ -21757,12 +18624,13 @@ function warnAboutUpdateOnUnmountedFiberInDEV(fiber) { if (didWarnStateUpdateForUnmountedComponent.has(componentName)) { return; } + didWarnStateUpdateForUnmountedComponent.add(componentName); } else { didWarnStateUpdateForUnmountedComponent = new Set([componentName]); } - warningWithoutStack$1( - false, + + error( "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", @@ -21774,12 +18642,12 @@ function warnAboutUpdateOnUnmountedFiberInDEV(fiber) { } } -var beginWork$$1; +var beginWork$1; -if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) { +{ var dummyFiber = null; - beginWork$$1 = function(current$$1, unitOfWork, expirationTime) { + beginWork$1 = function(current, 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. @@ -21789,8 +18657,9 @@ if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) { dummyFiber, unitOfWork ); + try { - return beginWork$1(current$$1, unitOfWork, expirationTime); + return beginWork(current, unitOfWork, expirationTime); } catch (originalError) { if ( originalError !== null && @@ -21803,7 +18672,7 @@ if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) { // corresponding changes there. resetContextDependencies(); - resetHooks(); // Don't reset current debug fiber, since we're about to work on the + resetHooksAfterThrow(); // Don't reset current debug fiber, since we're about to work on the // same fiber again. // Unwind the failed stack frame @@ -21811,16 +18680,16 @@ if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) { assignFiberPropertiesInDEV(unitOfWork, originalWorkInProgressCopy); - if (enableProfilerTimer && unitOfWork.mode & ProfileMode) { + if (unitOfWork.mode & ProfileMode) { // Reset the profiler timer. startProfilerTimer(unitOfWork); } // Run beginWork again. invokeGuardedCallback( null, - beginWork$1, + beginWork, null, - current$$1, + current, unitOfWork, expirationTime ); @@ -21836,38 +18705,37 @@ if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) { } } }; -} else { - beginWork$$1 = beginWork$1; } var didWarnAboutUpdateInRender = false; -var didWarnAboutUpdateInGetChildContext = false; -function warnAboutInvalidUpdatesOnClassComponentsInDEV(fiber) { + +function warnAboutRenderPhaseUpdatesInDEV(fiber) { { - if (fiber.tag === ClassComponent) { - switch (phase) { - case "getChildContext": - if (didWarnAboutUpdateInGetChildContext) { - return; - } - warningWithoutStack$1( - false, - "setState(...): Cannot call setState() inside getChildContext()" + 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." ); - didWarnAboutUpdateInGetChildContext = true; + break; - case "render": - if (didWarnAboutUpdateInRender) { - return; + } + + 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; } - 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; + } } } } @@ -21876,89 +18744,6 @@ function warnAboutInvalidUpdatesOnClassComponentsInDEV(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, @@ -21973,155 +18758,15 @@ function warnIfUnmockedScheduler(fiber) { ) { if (fiber.mode & BlockingMode || fiber.mode & ConcurrentMode) { didWarnAboutUnmockedScheduler = true; - warningWithoutStack$1( - false, + + error( '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" + - "jest.mock('scheduler', () => require('scheduler/unstable_mock'));\n\n" + + "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" + "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(", ") - ); } } } @@ -22133,9 +18778,6 @@ function computeThreadID(root, expirationTime) { } function markSpawnedWork(expirationTime) { - if (!enableSchedulerTracing) { - return; - } if (spawnedWorkDuringRender === null) { spawnedWorkDuringRender = [expirationTime]; } else { @@ -22144,13 +18786,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); + if (pendingInteractions != null) { interactions.forEach(function(interaction) { if (!pendingInteractions.has(interaction)) { @@ -22169,6 +18808,7 @@ function scheduleInteractions(root, expirationTime, interactions) { } var subscriber = tracing.__subscriberRef.current; + if (subscriber !== null) { var threadID = computeThreadID(root, expirationTime); subscriber.onWorkScheduled(interactions, threadID); @@ -22177,21 +18817,10 @@ 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. @@ -22232,10 +18861,6 @@ function startWorkOnPendingInteractions(root, expirationTime) { } function finishPendingInteractions(root, committedExpirationTime) { - if (!enableSchedulerTracing) { - return; - } - var earliestRemainingTimeAfterCommit = root.firstPendingTime; var subscriber; @@ -22284,6 +18909,7 @@ function finishPendingInteractions(root, committedExpirationTime) { } } +var onScheduleFiberRoot = null; var onCommitFiberRoot = null; var onCommitFiberUnmount = null; var hasLoggedError = false; @@ -22302,10 +18928,10 @@ function injectInternals(internals) { // https://github.com/facebook/react/issues/3877 return true; } + if (!hook.supportsFiber) { { - warningWithoutStack$1( - false, + error( "The installed version of React DevTools is too old and will not work " + "with the current version of React. Please update React DevTools. " + "https://fb.me/react-devtools" @@ -22318,6 +18944,23 @@ 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; @@ -22333,43 +18976,43 @@ function injectInternals(internals) { hook.onCommitFiberRoot(rendererID, root, undefined, didError); } } catch (err) { - if (true && !hasLoggedError) { - hasLoggedError = true; - warningWithoutStack$1( - false, - "React DevTools encountered an error: %s", - err - ); + if (true) { + if (!hasLoggedError) { + hasLoggedError = true; + + error("React instrumentation encountered an error: %s", err); + } } } }; + onCommitFiberUnmount = function(fiber) { try { hook.onCommitFiberUnmount(rendererID, fiber); } catch (err) { - if (true && !hasLoggedError) { - hasLoggedError = true; - warningWithoutStack$1( - false, - "React DevTools encountered an error: %s", - err - ); + if (true) { + if (!hasLoggedError) { + hasLoggedError = true; + + error("React instrumentation encountered an error: %s", err); + } } } }; } catch (err) { // Catch all errors because it is unsafe to throw during initialization. { - warningWithoutStack$1( - false, - "React DevTools encountered an error: %s.", - err - ); + error("React instrumentation 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); @@ -22431,7 +19074,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 @@ -22458,7 +19101,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; } @@ -22486,6 +19129,7 @@ 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); @@ -22521,7 +19165,7 @@ function resolveLazyComponentTag(Component) { return IndeterminateComponent; } // This is used to create an alternate fiber to do work on. -function createWorkInProgress(current, pendingProps, expirationTime) { +function createWorkInProgress(current, pendingProps) { var workInProgress = current.alternate; if (workInProgress === null) { @@ -22542,7 +19186,10 @@ function createWorkInProgress(current, pendingProps, expirationTime) { { // DEV-only fields - workInProgress._debugID = current._debugID; + { + workInProgress._debugID = current._debugID; + } + workInProgress._debugSource = current._debugSource; workInProgress._debugOwner = current._debugOwner; workInProgress._debugHookTypes = current._debugHookTypes; @@ -22560,7 +19207,7 @@ function createWorkInProgress(current, pendingProps, expirationTime) { 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, @@ -22592,13 +19239,14 @@ function createWorkInProgress(current, pendingProps, expirationTime) { 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: @@ -22613,9 +19261,6 @@ function createWorkInProgress(current, pendingProps, expirationTime) { case ForwardRef: workInProgress.type = resolveForwardRefForHotReloading(current.type); break; - - default: - break; } } @@ -22648,7 +19293,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; @@ -22674,7 +19319,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; @@ -22695,7 +19340,7 @@ function createHostRootFiber(tag) { mode = NoMode; } - if (enableProfilerTimer && isDevToolsPresent) { + if (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. @@ -22764,12 +19409,14 @@ 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; @@ -22792,29 +19439,10 @@ function createFiberFromTypeAndProps( fiberTag = LazyComponent; resolvedType = null; 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 - ); - } + case REACT_BLOCK_TYPE: + fiberTag = Block; + break getTag; } } @@ -22876,6 +19504,7 @@ function createFiberFromElement(element, mode, expirationTime) { mode, expirationTime ); + { fiber._debugSource = element._source; fiber._debugOwner = element._owner; @@ -22888,38 +19517,11 @@ 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" || - typeof pendingProps.onRender !== "function" - ) { - warningWithoutStack$1( - false, - 'Profiler must specify an "id" string and "onRender" function as props' - ); + if (typeof pendingProps.id !== "string") { + error('Profiler must specify an "id" as a prop'); } } @@ -22928,6 +19530,14 @@ 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; } @@ -22950,6 +19560,7 @@ function createFiberFromSuspenseList(pendingProps, mode, expirationTime, key) { // instead. fiber.type = REACT_SUSPENSE_LIST_TYPE; } + fiber.elementType = REACT_SUSPENSE_LIST_TYPE; fiber.expirationTime = expirationTime; return fiber; @@ -22959,18 +19570,6 @@ 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); @@ -23018,16 +19617,21 @@ 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._debugID = source._debugID; + target._debugIsCurrentlyTiming = source._debugIsCurrentlyTiming; + } + target._debugSource = source._debugSource; target._debugOwner = source._debugOwner; - target._debugIsCurrentlyTiming = source._debugIsCurrentlyTiming; target._debugNeedsRemount = source._debugNeedsRemount; target._debugHookTypes = source._debugHookTypes; return target; @@ -23054,28 +19658,21 @@ 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) { @@ -23169,15 +19766,6 @@ 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; @@ -23196,39 +19784,13 @@ function getContextForSubtree(parentComponent) { 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 (hostFiber === null) { - return null; + if (isContextProvider(Component)) { + return processChildContext(fiber, Component, parentContext); + } } - return hostFiber.stateNode; + return parentContext; } function findHostInstanceWithWarning(component, methodName) { @@ -23263,8 +19825,7 @@ function findHostInstanceWithWarning(component, methodName) { didWarnAboutFindNodeInStrictMode[componentName] = true; if (fiber.mode & StrictMode) { - warningWithoutStack$1( - false, + error( "%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. " + @@ -23276,8 +19837,7 @@ function findHostInstanceWithWarning(component, methodName) { getStackByFiberInDevAndProd(hostFiber) ); } else { - warningWithoutStack$1( - false, + error( "%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. " + @@ -23294,43 +19854,32 @@ function findHostInstanceWithWarning(component, methodName) { return hostFiber.stateNode; } - - return findHostInstance(component); } function createContainer(containerInfo, tag, hydrate, hydrationCallbacks) { - return createFiberRoot(containerInfo, tag, hydrate, hydrationCallbacks); + return createFiberRoot(containerInfo, tag, hydrate); } function updateContainer(element, container, parentComponent, callback) { - var current$$1 = container.current; + { + onScheduleRoot(container, element); + } + + 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); } } + 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) { @@ -23340,10 +19889,10 @@ function updateContainer(element, container, parentComponent, callback) { } { - if (phase === "render" && current !== null && !didWarnAboutNestedUpdates) { + if (isRendering && current !== null && !didWarnAboutNestedUpdates) { didWarnAboutNestedUpdates = true; - warningWithoutStack$1( - false, + + error( "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" + @@ -23362,719 +19911,173 @@ function updateContainer(element, container, parentComponent, callback) { callback = callback === undefined ? null : callback; if (callback !== null) { - !(typeof callback === "function") - ? warningWithoutStack$1( - false, + { + if (typeof callback !== "function") { + error( "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); - return expirationTime; -} -function getPublicRootInstance(container) { - var containerFiber = container.current; - - if (!containerFiber.child) { - return null; - } - - switch (containerFiber.child.tag) { - case HostComponent: - return getPublicInstance(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; + update.callback = callback; } - return NativeMethodsMixin; -}; - -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); - - function ReactNativeComponent() { - return _React$Component.apply(this, arguments) || this; - } + enqueueUpdate(current$1, update); + scheduleWork(current$1, expirationTime); + return expirationTime; +} +function getPublicRootInstance(container) { + var containerFiber = container.current; - var _proto = ReactNativeComponent.prototype; + if (!containerFiber.child) { + return null; + } - /** - * Due to bugs in Flow's handling of React.createClass, some fields already - * declared in the base class need to be redeclared below. - */ + switch (containerFiber.child.tag) { + case HostComponent: + return getPublicInstance(containerFiber.child.stateNode); - /** - * 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. - */ + default: + return containerFiber.child.stateNode; + } +} - _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 shouldSuspendImpl = function(fiber) { + return false; +}; - 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. +function shouldSuspend(fiber) { + return shouldSuspendImpl(fiber); +} +var overrideHookState = null; +var overrideProps = null; +var scheduleUpdate = null; +var setSuspenseHandler = null; - if (maybeInstance == null) { - return; - } +{ + var copyWithSetImpl = function(obj, path, idx, value) { + if (idx >= path.length) { + return value; + } - 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. + 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.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. + 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) { - 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; + fiber.memoizedProps = Object.assign({}, fiber.memoizedProps); + scheduleWork(fiber, Sync); + } + }; // Support DevTools props for function components, forwardRef, memo, host components, etc. - if (typeof relativeToNativeNode === "number") { - // Already a node handle - relativeNode = relativeToNativeNode; - } else if (relativeToNativeNode._nativeTag) { - relativeNode = relativeToNativeNode._nativeTag; - } + overrideProps = function(fiber, path, value) { + fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value); - if (relativeNode == null) { - warningWithoutStack$1( - false, - "Warning: ref.measureLayout must be called with a node handle or a ref to a native component." - ); - return; - } + if (fiber.alternate) { + fiber.alternate.pendingProps = fiber.pendingProps; + } - 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. + 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. + scheduleUpdate = function(fiber) { + scheduleWork(fiber, Sync); + }; - if (maybeInstance == null) { - return; - } + setSuspenseHandler = function(newShouldSuspendImpl) { + shouldSuspendImpl = newShouldSuspendImpl; + }; +} - if (maybeInstance.canonical) { - warningWithoutStack$1( - false, - "Warning: setNativeProps is not currently supported in Fabric" - ); - 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; + } - 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 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; + } + }); +} +var IsSomeRendererActing$1 = ReactSharedInternals.IsSomeRendererActing; - return ReactNativeComponent; - })(React.Component); // eslint-disable-next-line no-unused-expressions +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 + }; +} - return ReactNativeComponent; -}; +// TODO: this is special because it gets imported during build. +var ReactVersion = "16.13.0"; var instanceCache = new Map(); @@ -24082,13 +20085,14 @@ function getInstanceFromTag(tag) { return instanceCache.get(tag) || null; } -var emptyObject$3 = {}; +var emptyObject$1 = {}; { - Object.freeze(emptyObject$3); + Object.freeze(emptyObject$1); } var getInspectorDataForViewTag; +var getInspectorDataForViewAtPoint; { var traverseOwnerTreeUp = function(hierarchy, instance) { @@ -24112,6 +20116,7 @@ var getInspectorDataForViewTag; return instance; } } + return hierarchy[0]; }; @@ -24119,10 +20124,10 @@ var getInspectorDataForViewTag; var host = findCurrentHostFiber(fiber); if (host) { - return host.memoizedProps || emptyObject$3; + return host.memoizedProps || emptyObject$1; } - return emptyObject$3; + return emptyObject$1; }; var getHostNode = function(fiber, findNodeHandle) { @@ -24150,28 +20155,65 @@ var getInspectorDataForViewTag; name: getComponentName(fiber.type), getInspectorData: function(findNodeHandle) { return { - measure: function(callback) { - return ReactNativePrivateInterface.UIManager.measure( - getHostNode(fiber, findNodeHandle), - callback - ); - }, props: getHostProps(fiber), - source: fiber._debugSource + 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 + ); + } + } }; } }; }); }; + 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$3, - selection: null, + props: emptyObject$1, + selectedIndex: null, source: null }; } @@ -24182,36 +20224,122 @@ var getInspectorDataForViewTag; var hierarchy = createHierarchy(fiberHierarchy); var props = getHostProps(instance); var source = instance._debugSource; - var selection = fiberHierarchy.indexOf(instance); + var selectedIndex = fiberHierarchy.indexOf(instance); return { hierarchy: hierarchy, props: props, - selection: selection, + selectedIndex: selectedIndex, 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 _nativeFabricUIManage = nativeFabricUIManager; -var fabricDispatchCommand = _nativeFabricUIManage.dispatchCommand; -var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner; +var ReactCurrentOwner$3 = ReactSharedInternals.ReactCurrentOwner; function findHostInstance_DEPRECATED(componentOrHandle) { { - var owner = ReactCurrentOwner.current; + var owner = ReactCurrentOwner$3.current; if (owner !== null && owner.stateNode !== null) { - !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; + 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 = true; } } @@ -24251,20 +20379,20 @@ function findHostInstance_DEPRECATED(componentOrHandle) { function findNodeHandle(componentOrHandle) { { - var owner = ReactCurrentOwner.current; + var owner = ReactCurrentOwner$3.current; if (owner !== null && owner.stateNode !== null) { - !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; + 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 = true; } } @@ -24304,94 +20432,95 @@ function findNodeHandle(componentOrHandle) { // Fabric return hostInstance.canonical._nativeTag; } + return hostInstance._nativeTag; } -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; +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" + ); } - fabricDispatchCommand( + return; + } + + if (handle._internalInstanceHandle) { + nativeFabricUIManager.dispatchCommand( handle._internalInstanceHandle.stateNode.node, command, args ); - }, - render: function(element, containerTag, callback) { - var root = roots.get(containerTag); + } else { + ReactNativePrivateInterface.UIManager.dispatchViewManagerCommand( + handle._nativeTag, + command, + args + ); + } +} - 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); - } +function render(element, containerTag, callback) { + var root = roots.get(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) + 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); +} + +function stopSurface(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 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" -}); - -var ReactFabric$2 = Object.freeze({ - default: ReactFabric + rendererPackageName: "react-native-renderer", + rendererConfig: { + getInspectorDataForViewTag: getInspectorDataForViewTag, + getInspectorDataForViewAtPoint: getInspectorDataForViewAtPoint.bind( + null, + findNodeHandle + ) + } }); -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; +exports.createPortal = createPortal$1; +exports.dispatchCommand = dispatchCommand; +exports.findHostInstance_DEPRECATED = findHostInstance_DEPRECATED; +exports.findNodeHandle = findNodeHandle; +exports.render = render; +exports.stopSurface = stopSurface; +exports.unmountComponentAtNode = unmountComponentAtNode; })(); } diff --git a/Libraries/Renderer/implementations/ReactFabric-prod.fb.js b/Libraries/Renderer/implementations/ReactFabric-prod.fb.js index 1977c28b91768a..278eba5fa3c464 100644 --- a/Libraries/Renderer/implementations/ReactFabric-prod.fb.js +++ b/Libraries/Renderer/implementations/ReactFabric-prod.fb.js @@ -5,6 +5,7 @@ * LICENSE file in the root directory of this source tree. * * @noflow + * @nolint * @preventMunge * @generated */ @@ -14,85 +15,16 @@ require("react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore"); var ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/ReactNativePrivateInterface"), React = require("react"), Scheduler = require("scheduler"); -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 getParent(inst) { + do inst = inst.return; + while (inst && 5 !== inst.tag); + return inst ? inst : null; } -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; +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); } -var plugins = [], - eventNameDispatchConfigs = {}, - registrationNameModules = {}; function invokeGuardedCallbackImpl(name, func, context, a, b, c, d, e, f) { var funcArgs = Array.prototype.slice.call(arguments, 3); try { @@ -163,74 +95,6 @@ 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; @@ -248,6 +112,7 @@ function getListener(inst, registrationName) { case "onMouseMoveCapture": case "onMouseUp": case "onMouseUpCapture": + case "onMouseEnter": (props = !props.disabled) || ((inst = inst.type), (props = !( @@ -272,15 +137,21 @@ function getListener(inst, registrationName) { ); return listener; } -function getParent(inst) { - do inst = inst.return; - while (inst && 5 !== inst.tag); - return inst ? inst : null; +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 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 forEachAccumulated(arr, cb, scope) { + Array.isArray(arr) ? arr.forEach(cb, scope) : arr && cb.call(scope, arr); } function accumulateDirectionalDispatches(inst, phase, event) { if ( @@ -348,8 +219,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) @@ -502,53 +373,27 @@ 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))) - : console.warn( - "Cannot record touch move without a touch start.\nTouch Move: %s\n", - "Touch Bank: %s", - printTouch(touch), - printTouchBank() - ); + 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))); } 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))) - : 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; + 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))); } var ResponderTouchHistoryStore = { recordTouchTrack: function(topLevelType, nativeEvent) { @@ -588,10 +433,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; @@ -681,13 +526,7 @@ var eventTypes = { "topTouchCancel" === topLevelType ) if (0 <= trackedTouchCount) --trackedTouchCount; - else - return ( - console.warn( - "Ended a touch event which was not counted in `trackedTouchCount`." - ), - null - ); + else return null; ResponderTouchHistoryStore.recordTouchTrack(topLevelType, nativeEvent); if ( targetInst && @@ -699,10 +538,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; @@ -856,10 +695,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, @@ -922,8 +761,8 @@ var eventTypes = { (topLevelType = shouldSetEventType ? eventTypes.responderTerminate : topLevelType - ? eventTypes.responderRelease - : null) + ? eventTypes.responderRelease + : null) ) (nativeEvent = ResponderSyntheticEvent.getPooled( topLevelType, @@ -947,50 +786,160 @@ 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; -injection.injectEventPluginOrder([ +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([ "ResponderEventPlugin", "ReactNativeBridgeEventPlugin" ]); -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, +recomputePluginOrdering(); +var injectedNamesToPlugins$jscomp$inline_92 = { + ResponderEventPlugin: ResponderEventPlugin, + ReactNativeBridgeEventPlugin: { + eventTypes: {}, + extractEvents: function( + topLevelType, targetInst, nativeEvent, nativeEventTarget - ); - if (bubbleDispatchConfig) - forEachAccumulated(topLevelType, accumulateTwoPhaseDispatchesSingle); - else if (directDispatchConfig) - forEachAccumulated(topLevelType, accumulateDirectDispatchesSingle); - else return null; - return topLevelType; + ) { + 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; } } -}); -var enableNativeTargetAsInstance = require("../shims/ReactFeatureFlags") - .enableNativeTargetAsInstance; +isOrderingDirty$jscomp$inline_93 && recomputePluginOrdering(); function getInstanceFromInstance(instanceHandle) { return instanceHandle; } @@ -999,14 +948,8 @@ getFiberCurrentPropsFromNode = function(inst) { }; getInstanceFromNode = getInstanceFromInstance; getNodeFromInstance = function(inst) { - 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."); + inst = inst.stateNode.canonical; + if (!inst._nativeTag) throw Error("All native instances should have a tag."); return inst; }; ResponderEventPlugin.injection.injectGlobalResponderHandler({ @@ -1042,11 +985,9 @@ 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; -hasSymbol && Symbol.for("react.fundamental"); -hasSymbol && Symbol.for("react.responder"); -hasSymbol && Symbol.for("react.scope"); -var MAYBE_ITERATOR_SYMBOL = "function" === typeof Symbol && Symbol.iterator; + 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; function getIteratorFn(maybeIterable) { if (null === maybeIterable || "object" !== typeof maybeIterable) return null; maybeIterable = @@ -1056,9 +997,10 @@ function getIteratorFn(maybeIterable) { } function initializeLazyComponentType(lazyComponent) { if (-1 === lazyComponent._status) { - lazyComponent._status = 0; - var ctor = lazyComponent._ctor; + var ctor = lazyComponent._result; + ctor || (ctor = lazyComponent._ctor); ctor = ctor(); + lazyComponent._status = 0; lazyComponent._result = ctor; ctor.then( function(moduleObject) { @@ -1095,9 +1037,9 @@ function getComponentName(type) { if ("object" === typeof type) switch (type.$$typeof) { case REACT_CONTEXT_TYPE: - return "Context.Consumer"; + return (type.displayName || "Context") + ".Consumer"; case REACT_PROVIDER_TYPE: - return "Context.Provider"; + return (type._context.displayName || "Context") + ".Provider"; case REACT_FORWARD_REF_TYPE: var innerType = type.render; innerType = innerType.displayName || innerType.name || ""; @@ -1107,6 +1049,8 @@ 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); @@ -1296,8 +1240,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)) { @@ -1458,18 +1402,9 @@ 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); @@ -1477,48 +1412,35 @@ function batchedUpdates(fn, bookkeeping) { 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)) - ) - for (bookkeeping = 0; bookkeeping < fn.length; bookkeeping++) - restoreStateOfTarget(fn[bookkeeping]); + isInsideEventHandler = !1; } } -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; +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); } - _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; - enableNativeTargetAsInstance - ? null != target && (eventTarget = target.stateNode.canonical) - : (eventTarget = nativeEvent.target); + if (null != target) { + var stateNode = target.stateNode; + null != stateNode && (eventTarget = stateNode.canonical); + } batchedUpdates(function() { var events = eventTarget; for (var events$jscomp$0 = null, i = 0; i < plugins.length; i++) { @@ -1556,21 +1478,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$1 = nativeFabricUIManager, - createNode = _nativeFabricUIManage$1.createNode, - cloneNode = _nativeFabricUIManage$1.cloneNode, - cloneNodeWithNewChildren = _nativeFabricUIManage$1.cloneNodeWithNewChildren, +var _nativeFabricUIManage = nativeFabricUIManager, + createNode = _nativeFabricUIManage.createNode, + cloneNode = _nativeFabricUIManage.cloneNode, + cloneNodeWithNewChildren = _nativeFabricUIManage.cloneNodeWithNewChildren, cloneNodeWithNewChildrenAndProps = - _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, + _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, getViewConfigForType = ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get, nextReactTag = 2; @@ -1589,10 +1511,10 @@ var ReactFabricHostComponent = (function() { } var _proto = ReactFabricHostComponent.prototype; _proto.blur = function() { - ReactNativePrivateInterface.TextInputState.blurTextInput(this._nativeTag); + ReactNativePrivateInterface.TextInputState.blurTextInput(this); }; _proto.focus = function() { - ReactNativePrivateInterface.TextInputState.focusTextInput(this._nativeTag); + ReactNativePrivateInterface.TextInputState.focusTextInput(this); }; _proto.measure = function(callback) { fabricMeasure( @@ -1654,44 +1576,6 @@ 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) { @@ -1729,21 +1613,17 @@ function isContextProvider(type) { type = type.childContextTypes; return null !== type && void 0 !== type; } -function popContext(fiber) { - pop(didPerformWorkStackCursor, fiber); - pop(contextStackCursor, fiber); -} -function popTopLevelContextObject(fiber) { - pop(didPerformWorkStackCursor, fiber); - pop(contextStackCursor, fiber); +function popContext() { + pop(didPerformWorkStackCursor); + pop(contextStackCursor); } function pushTopLevelContextObject(fiber, context, didChange) { if (contextStackCursor.current !== emptyContextObject) throw Error( "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." ); - push(contextStackCursor, context, fiber); - push(didPerformWorkStackCursor, didChange, fiber); + push(contextStackCursor, context); + push(didPerformWorkStackCursor, didChange); } function processChildContext(fiber, type, parentContext) { var instance = fiber.stateNode; @@ -1761,17 +1641,13 @@ function processChildContext(fiber, type, parentContext) { return Object.assign({}, parentContext, {}, instance); } function pushContextProvider(workInProgress) { - var instance = workInProgress.stateNode; - instance = - (instance && instance.__reactInternalMemoizedMergedChildContext) || + workInProgress = + ((workInProgress = workInProgress.stateNode) && + workInProgress.__reactInternalMemoizedMergedChildContext) || emptyContextObject; previousContext = contextStackCursor.current; - push(contextStackCursor, instance, workInProgress); - push( - didPerformWorkStackCursor, - didPerformWorkStackCursor.current, - workInProgress - ); + push(contextStackCursor, workInProgress); + push(didPerformWorkStackCursor, didPerformWorkStackCursor.current); return !0; } function invalidateContextProvider(workInProgress, type, didChange) { @@ -1781,18 +1657,21 @@ 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 - ? ((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); + ? ((workInProgress = processChildContext( + workInProgress, + type, + previousContext + )), + (instance.__reactInternalMemoizedMergedChildContext = workInProgress), + pop(didPerformWorkStackCursor), + pop(contextStackCursor), + push(contextStackCursor, workInProgress)) + : pop(didPerformWorkStackCursor); + push(didPerformWorkStackCursor, didChange); } 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 = @@ -1803,6 +1682,7 @@ 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, @@ -1847,7 +1727,7 @@ function reactPriorityToSchedulerPriority(reactPriorityLevel) { throw Error("Unknown priority level."); } } -function runWithPriority$1(reactPriorityLevel, fn) { +function runWithPriority(reactPriorityLevel, fn) { reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); return Scheduler_runWithPriority(reactPriorityLevel, fn); } @@ -1879,7 +1759,7 @@ function flushSyncCallbackQueueImpl() { var i = 0; try { var queue = syncQueue; - runWithPriority$1(99, function() { + runWithPriority(99, function() { for (; i < queue.length; i++) { var callback = queue[i]; do callback = callback(!0); @@ -1902,10 +1782,10 @@ function flushSyncCallbackQueueImpl() { function is(x, y) { return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y); } -var is$1 = "function" === typeof Object.is ? Object.is : is, +var objectIs = "function" === typeof Object.is ? Object.is : is, hasOwnProperty = Object.prototype.hasOwnProperty; function shallowEqual(objA, objB) { - if (is$1(objA, objB)) return !0; + if (objectIs(objA, objB)) return !0; if ( "object" !== typeof objA || null === objA || @@ -1919,11 +1799,48 @@ function shallowEqual(objA, objB) { for (keysB = 0; keysB < keysA.length; keysB++) if ( !hasOwnProperty.call(objB, keysA[keysB]) || - !is$1(objA[keysA[keysB]], objB[keysA[keysB]]) + !objectIs(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); @@ -1941,14 +1858,9 @@ 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, providerFiber); + pop(valueCursor); providerFiber.type._context._currentValue2 = currentValue; } function scheduleWorkOnParentPath(parent, renderExpirationTime) { @@ -2003,237 +1915,195 @@ function readContext(context, observedBits) { return context._currentValue2; } var hasForceUpdate = !1; -function createUpdateQueue(baseState) { - return { - baseState: baseState, - firstUpdate: null, - lastUpdate: null, - firstCapturedUpdate: null, - lastCapturedUpdate: null, - firstEffect: null, - lastEffect: null, - firstCapturedEffect: null, - lastCapturedEffect: null +function initializeUpdateQueue(fiber) { + fiber.updateQueue = { + baseState: fiber.memoizedState, + baseQueue: null, + shared: { pending: null }, + effects: null }; } -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 cloneUpdateQueue(current, workInProgress) { + current = current.updateQueue; + workInProgress.updateQueue === current && + (workInProgress.updateQueue = { + baseState: current.baseState, + baseQueue: current.baseQueue, + shared: current.shared, + effects: current.effects + }); } function createUpdate(expirationTime, suspenseConfig) { - return { + expirationTime = { expirationTime: expirationTime, suspenseConfig: suspenseConfig, tag: 0, payload: null, callback: null, - next: null, - nextEffect: null + next: null }; -} -function appendUpdateToQueue(queue, update) { - null === queue.lastUpdate - ? (queue.firstUpdate = queue.lastUpdate = update) - : ((queue.lastUpdate.next = update), (queue.lastUpdate = update)); + return (expirationTime.next = expirationTime); } function enqueueUpdate(fiber, 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)); + 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; + } } 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 && - 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; + 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)); } function processUpdateQueue( - workInProgress, - queue, + workInProgress$jscomp$0, props, instance, renderExpirationTime ) { + var queue = workInProgress$jscomp$0.updateQueue; hasForceUpdate = !1; - queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue); - for ( - var newBaseState = queue.baseState, - newFirstUpdate = null, - newExpirationTime = 0, - 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; + 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)); } - 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; + if (null !== baseQueue) { + baseFirst = baseQueue.next; + var newState = queue.baseState, + 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; } - 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) { - 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); + 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); + } } - effect = effect.nextEffect; - } } var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig, emptyRefsObject = new React.Component().refs; @@ -2250,10 +2120,8 @@ function applyDerivedStateFromProps( ? ctor : Object.assign({}, ctor, getDerivedStateFromProps); workInProgress.memoizedState = getDerivedStateFromProps; - nextProps = workInProgress.updateQueue; - null !== nextProps && - 0 === workInProgress.expirationTime && - (nextProps.baseState = getDerivedStateFromProps); + 0 === workInProgress.expirationTime && + (workInProgress.updateQueue.baseState = getDerivedStateFromProps); } var classComponentUpdater = { isMounted: function(component) { @@ -2272,7 +2140,7 @@ var classComponentUpdater = { null !== callback && (suspenseConfig.callback = callback); enqueueUpdate(inst, suspenseConfig); - scheduleUpdateOnFiber(inst, currentTime); + scheduleWork(inst, currentTime); }, enqueueReplaceState: function(inst, payload, callback) { inst = inst._reactInternalFiber; @@ -2286,7 +2154,7 @@ var classComponentUpdater = { null !== callback && (suspenseConfig.callback = callback); enqueueUpdate(inst, suspenseConfig); - scheduleUpdateOnFiber(inst, currentTime); + scheduleWork(inst, currentTime); }, enqueueForceUpdate: function(inst, callback) { inst = inst._reactInternalFiber; @@ -2299,7 +2167,7 @@ var classComponentUpdater = { null !== callback && (suspenseConfig.callback = callback); enqueueUpdate(inst, suspenseConfig); - scheduleUpdateOnFiber(inst, currentTime); + scheduleWork(inst, currentTime); } }; function checkShouldComponentUpdate( @@ -2315,8 +2183,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, @@ -2368,6 +2236,7 @@ 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)) @@ -2375,16 +2244,8 @@ function mountClassInstance( ? previousContext : contextStackCursor.current), (instance.context = getMaskedContext(workInProgress, contextType))); - contextType = workInProgress.updateQueue; - null !== contextType && - (processUpdateQueue( - workInProgress, - contextType, - newProps, - instance, - renderExpirationTime - ), - (instance.state = workInProgress.memoizedState)); + processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); + instance.state = workInProgress.memoizedState; contextType = ctor.getDerivedStateFromProps; "function" === typeof contextType && (applyDerivedStateFromProps(workInProgress, ctor, contextType, newProps), @@ -2400,21 +2261,18 @@ function mountClassInstance( instance.UNSAFE_componentWillMount(), ctor !== instance.state && classComponentUpdater.enqueueReplaceState(instance, instance.state, null), - (contextType = workInProgress.updateQueue), - null !== contextType && - (processUpdateQueue( - workInProgress, - contextType, - newProps, - instance, - renderExpirationTime - ), - (instance.state = workInProgress.memoizedState))); + processUpdateQueue( + workInProgress, + newProps, + instance, + renderExpirationTime + ), + (instance.state = workInProgress.memoizedState)); "function" === typeof instance.componentDidMount && (workInProgress.effectTag |= 4); } var isArray = Array.isArray; -function coerceRef(returnFiber, current$$1, element) { +function coerceRef(returnFiber, current, element) { returnFiber = element.ref; if ( null !== returnFiber && @@ -2426,7 +2284,7 @@ function coerceRef(returnFiber, current$$1, element) { if (element) { if (1 !== element.tag) throw Error( - "Function components cannot have refs. Did you mean to use React.forwardRef()?" + "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" ); var inst = element.stateNode; } @@ -2438,19 +2296,19 @@ function coerceRef(returnFiber, current$$1, element) { ); var stringRef = "" + returnFiber; if ( - null !== current$$1 && - null !== current$$1.ref && - "function" === typeof current$$1.ref && - current$$1.ref._stringRef === stringRef + null !== current && + null !== current.ref && + "function" === typeof current.ref && + current.ref._stringRef === stringRef ) - return current$$1.ref; - current$$1 = function(value) { + return current.ref; + current = function(value) { var refs = inst.refs; refs === emptyRefsObject && (refs = inst.refs = {}); null === value ? delete refs[stringRef] : (refs[stringRef] = value); }; - current$$1._stringRef = stringRef; - return current$$1; + current._stringRef = stringRef; + return current; } if ("string" !== typeof returnFiber) throw Error( @@ -2502,8 +2360,8 @@ function ChildReconciler(shouldTrackSideEffects) { (currentFirstChild = currentFirstChild.sibling); return returnFiber; } - function useFiber(fiber, pendingProps, expirationTime) { - fiber = createWorkInProgress(fiber, pendingProps, expirationTime); + function useFiber(fiber, pendingProps) { + fiber = createWorkInProgress(fiber, pendingProps); fiber.index = 0; fiber.sibling = null; return fiber; @@ -2528,31 +2386,26 @@ function ChildReconciler(shouldTrackSideEffects) { (newFiber.effectTag = 2); return newFiber; } - function updateTextNode( - returnFiber, - current$$1, - textContent, - expirationTime - ) { - if (null === current$$1 || 6 !== current$$1.tag) + function updateTextNode(returnFiber, current, textContent, expirationTime) { + if (null === current || 6 !== current.tag) return ( - (current$$1 = createFiberFromText( + (current = createFiberFromText( textContent, returnFiber.mode, expirationTime )), - (current$$1.return = returnFiber), - current$$1 + (current.return = returnFiber), + current ); - current$$1 = useFiber(current$$1, textContent, expirationTime); - current$$1.return = returnFiber; - return current$$1; + current = useFiber(current, textContent); + current.return = returnFiber; + return current; } - function updateElement(returnFiber, current$$1, element, expirationTime) { - if (null !== current$$1 && current$$1.elementType === element.type) + function updateElement(returnFiber, current, element, expirationTime) { + if (null !== current && current.elementType === element.type) return ( - (expirationTime = useFiber(current$$1, element.props, expirationTime)), - (expirationTime.ref = coerceRef(returnFiber, current$$1, element)), + (expirationTime = useFiber(current, element.props)), + (expirationTime.ref = coerceRef(returnFiber, current, element)), (expirationTime.return = returnFiber), expirationTime ); @@ -2564,51 +2417,45 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime ); - expirationTime.ref = coerceRef(returnFiber, current$$1, element); + expirationTime.ref = coerceRef(returnFiber, current, element); expirationTime.return = returnFiber; return expirationTime; } - function updatePortal(returnFiber, current$$1, portal, expirationTime) { + function updatePortal(returnFiber, current, portal, expirationTime) { if ( - null === current$$1 || - 4 !== current$$1.tag || - current$$1.stateNode.containerInfo !== portal.containerInfo || - current$$1.stateNode.implementation !== portal.implementation + null === current || + 4 !== current.tag || + current.stateNode.containerInfo !== portal.containerInfo || + current.stateNode.implementation !== portal.implementation ) return ( - (current$$1 = createFiberFromPortal( + (current = createFiberFromPortal( portal, returnFiber.mode, expirationTime )), - (current$$1.return = returnFiber), - current$$1 + (current.return = returnFiber), + current ); - current$$1 = useFiber(current$$1, portal.children || [], expirationTime); - current$$1.return = returnFiber; - return current$$1; + current = useFiber(current, portal.children || []); + current.return = returnFiber; + return current; } - function updateFragment( - returnFiber, - current$$1, - fragment, - expirationTime, - key - ) { - if (null === current$$1 || 7 !== current$$1.tag) + function updateFragment(returnFiber, current, fragment, expirationTime, key) { + if (null === current || 7 !== current.tag) return ( - (current$$1 = createFiberFromFragment( + (current = createFiberFromFragment( fragment, returnFiber.mode, expirationTime, key )), - (current$$1.return = returnFiber), - current$$1 + (current.return = returnFiber), + current ); - current$$1 = useFiber(current$$1, fragment, expirationTime); - current$$1.return = returnFiber; - return current$$1; + current = useFiber(current, fragment); + current.return = returnFiber; + return current; } function createChild(returnFiber, newChild, expirationTime) { if ("string" === typeof newChild || "number" === typeof newChild) @@ -2971,39 +2818,48 @@ function ChildReconciler(shouldTrackSideEffects) { null !== isUnkeyedTopLevelFragment; ) { - 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; + 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; + } } - else deleteChild(returnFiber, isUnkeyedTopLevelFragment); + deleteRemainingChildren(returnFiber, isUnkeyedTopLevelFragment); + break; + } else deleteChild(returnFiber, isUnkeyedTopLevelFragment); isUnkeyedTopLevelFragment = isUnkeyedTopLevelFragment.sibling; } newChild.type === REACT_FRAGMENT_TYPE @@ -3053,8 +2909,7 @@ function ChildReconciler(shouldTrackSideEffects) { ); currentFirstChild = useFiber( currentFirstChild, - newChild.children || [], - expirationTime + newChild.children || [] ); currentFirstChild.return = returnFiber; returnFiber = currentFirstChild; @@ -3081,11 +2936,7 @@ function ChildReconciler(shouldTrackSideEffects) { (newChild = "" + newChild), null !== currentFirstChild && 6 === currentFirstChild.tag ? (deleteRemainingChildren(returnFiber, currentFirstChild.sibling), - (currentFirstChild = useFiber( - currentFirstChild, - newChild, - expirationTime - )), + (currentFirstChild = useFiber(currentFirstChild, newChild)), (currentFirstChild.return = returnFiber), (returnFiber = currentFirstChild)) : (deleteRemainingChildren(returnFiber, currentFirstChild), @@ -3140,16 +2991,16 @@ function requiredContext(c) { return c; } function pushHostContainer(fiber, nextRootInstance) { - push(rootInstanceStackCursor, nextRootInstance, fiber); - push(contextFiberStackCursor, fiber, fiber); - push(contextStackCursor$1, NO_CONTEXT, fiber); - pop(contextStackCursor$1, fiber); - push(contextStackCursor$1, { isInAParentText: !1 }, fiber); + push(rootInstanceStackCursor, nextRootInstance); + push(contextFiberStackCursor, fiber); + push(contextStackCursor$1, NO_CONTEXT); + pop(contextStackCursor$1); + push(contextStackCursor$1, { isInAParentText: !1 }); } -function popHostContainer(fiber) { - pop(contextStackCursor$1, fiber); - pop(contextFiberStackCursor, fiber); - pop(rootInstanceStackCursor, fiber); +function popHostContainer() { + pop(contextStackCursor$1); + pop(contextFiberStackCursor); + pop(rootInstanceStackCursor); } function pushHostContext(fiber) { requiredContext(rootInstanceStackCursor.current); @@ -3166,23 +3017,19 @@ function pushHostContext(fiber) { ? { isInAParentText: nextContext } : context; context !== nextContext && - (push(contextFiberStackCursor, fiber, fiber), - push(contextStackCursor$1, nextContext, fiber)); + (push(contextFiberStackCursor, fiber), + push(contextStackCursor$1, nextContext)); } function popHostContext(fiber) { contextFiberStackCursor.current === fiber && - (pop(contextStackCursor$1, fiber), pop(contextFiberStackCursor, fiber)); + (pop(contextStackCursor$1), pop(contextFiberStackCursor)); } var suspenseStackCursor = { current: 0 }; function findFirstSuspended(row) { for (var node = row; null !== node; ) { if (13 === node.tag) { var state = node.memoizedState; - if ( - null !== state && - ((state = state.dehydrated), - null === state || shim$1(state) || shim$1(state)) - ) + if (null !== state && (null === state.dehydrated || shim$1() || shim$1())) return node; } else if (19 === node.tag && void 0 !== node.memoizedProps.revealOrder) { if (0 !== (node.effectTag & 64)) return node; @@ -3201,24 +3048,16 @@ function findFirstSuspended(row) { } return null; } -function createResponderListener(responder, props) { +function createDeprecatedResponderListener(responder, props) { return { responder: responder, props: props }; } -var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, +var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig, - renderExpirationTime$1 = 0, + renderExpirationTime = 0, currentlyRenderingFiber$1 = null, currentHook = null, - nextCurrentHook = null, - firstWorkInProgressHook = null, workInProgressHook = null, - nextWorkInProgressHook = null, - remainingExpirationTime = 0, - componentUpdateQueue = null, - sideEffectTag = 0, - didScheduleRenderPhaseUpdate = !1, - renderPhaseUpdates = null, - numberOfReRenders = 0; + didScheduleRenderPhaseUpdate = !1; 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." @@ -3227,7 +3066,7 @@ function throwInvalidHookError() { function areHookInputsEqual(nextDeps, prevDeps) { if (null === prevDeps) return !1; for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) - if (!is$1(nextDeps[i], prevDeps[i])) return !1; + if (!objectIs(nextDeps[i], prevDeps[i])) return !1; return !0; } function renderWithHooks( @@ -3235,92 +3074,85 @@ function renderWithHooks( workInProgress, Component, props, - refOrContext, + secondArg, nextRenderExpirationTime ) { - renderExpirationTime$1 = nextRenderExpirationTime; + renderExpirationTime = nextRenderExpirationTime; currentlyRenderingFiber$1 = workInProgress; - 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; + 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); } - 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) + ReactCurrentDispatcher.current = ContextOnlyDispatcher; + workInProgress = null !== currentHook && null !== currentHook.next; + renderExpirationTime = 0; + workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; + didScheduleRenderPhaseUpdate = !1; + if (workInProgress) throw Error( "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." ); - 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; + return current; } function mountWorkInProgressHook() { var hook = { memoizedState: null, baseState: null, + baseQueue: null, queue: null, - baseUpdate: null, next: null }; null === workInProgressHook - ? (firstWorkInProgressHook = workInProgressHook = hook) + ? (currentlyRenderingFiber$1.memoizedState = 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), - (nextWorkInProgressHook = workInProgressHook.next), - (currentHook = nextCurrentHook), - (nextCurrentHook = null !== currentHook ? currentHook.next : null); + (currentHook = nextCurrentHook); else { if (null === nextCurrentHook) throw Error("Rendered more hooks than during the previous render."); currentHook = nextCurrentHook; - var newHook = { + nextCurrentHook = { memoizedState: currentHook.memoizedState, baseState: currentHook.baseState, + baseQueue: currentHook.baseQueue, queue: currentHook.queue, - baseUpdate: currentHook.baseUpdate, next: null }; - workInProgressHook = - null === workInProgressHook - ? (firstWorkInProgressHook = newHook) - : (workInProgressHook.next = newHook); - nextCurrentHook = currentHook.next; + null === workInProgressHook + ? (currentlyRenderingFiber$1.memoizedState = workInProgressHook = nextCurrentHook) + : (workInProgressHook = workInProgressHook.next = nextCurrentHook); } return workInProgressHook; } @@ -3335,74 +3167,100 @@ function updateReducer(reducer) { "Should have a queue. This is likely a bug in React. Please file an issue." ); queue.lastRenderedReducer = reducer; - 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]; - } + 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; } - return [hook.memoizedState, _dispatch]; + current.baseQueue = baseQueue = pendingQueue; + queue.pending = null; } - _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; + if (null !== baseQueue) { + baseQueue = baseQueue.next; + current = current.baseState; + var newBaseQueueLast = (baseFirst = pendingQueue = null), + update = baseQueue; do { - var updateExpirationTime = _update.expirationTime; - updateExpirationTime < renderExpirationTime$1 - ? (didSkip || - ((didSkip = !0), - (newBaseUpdate = baseUpdate), - (firstRenderPhaseUpdate = newState)), - updateExpirationTime > remainingExpirationTime && - ((remainingExpirationTime = updateExpirationTime), - markUnprocessedUpdateTime(remainingExpirationTime))) - : (markRenderEventTimeAndConfig( + 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( updateExpirationTime, - _update.suspenseConfig + update.suspenseConfig ), - (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); + (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); hook.memoizedState = newState; - hook.baseUpdate = newBaseUpdate; - hook.baseState = firstRenderPhaseUpdate; + null === hook.baseQueue && (hook.baseState = newState); queue.lastRenderedState = newState; } - return [hook.memoizedState, queue.dispatch]; + return [newState, dispatch]; } function mountState(initialState) { var hook = mountWorkInProgressHook(); "function" === typeof initialState && (initialState = initialState()); hook.memoizedState = hook.baseState = initialState; initialState = hook.queue = { - last: null, + pending: null, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState @@ -3414,28 +3272,30 @@ 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 }; - 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))); + 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))); return tag; } +function updateRef() { + return updateWorkInProgressHook().memoizedState; +} function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var hook = mountWorkInProgressHook(); - sideEffectTag |= fiberEffectTag; + currentlyRenderingFiber$1.effectTag |= fiberEffectTag; hook.memoizedState = pushEffect( - hookEffectTag, + 1 | hookEffectTag, create, void 0, void 0 === deps ? null : deps @@ -3449,18 +3309,21 @@ function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var prevEffect = currentHook.memoizedState; destroy = prevEffect.destroy; if (null !== deps && areHookInputsEqual(deps, prevEffect.deps)) { - pushEffect(0, create, destroy, deps); + pushEffect(hookEffectTag, create, destroy, deps); return; } } - sideEffectTag |= fiberEffectTag; - hook.memoizedState = pushEffect(hookEffectTag, create, destroy, deps); + currentlyRenderingFiber$1.effectTag |= fiberEffectTag; + hook.memoizedState = pushEffect(1 | hookEffectTag, create, destroy, deps); } function mountEffect(create, deps) { - return mountEffectImpl(516, 192, create, deps); + return mountEffectImpl(516, 4, create, deps); } function updateEffect(create, deps) { - return updateEffectImpl(516, 192, create, deps); + return updateEffectImpl(516, 4, create, deps); +} +function updateLayoutEffect(create, deps) { + return updateEffectImpl(4, 2, create, deps); } function imperativeHandleEffect(create, ref) { if ("function" === typeof ref) @@ -3480,6 +3343,15 @@ 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 = [ @@ -3501,72 +3373,79 @@ 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) { - if (!(25 > numberOfReRenders)) - throw Error( - "Too many re-renders. React limits the number of renders to prevent an infinite loop." - ); - var alternate = fiber.alternate; + 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 ( fiber === currentlyRenderingFiber$1 || - (null !== alternate && alternate === currentlyRenderingFiber$1) + (null !== pending && pending === currentlyRenderingFiber$1) ) - 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; - } + (didScheduleRenderPhaseUpdate = !0), + (suspenseConfig.expirationTime = renderExpirationTime), + (currentlyRenderingFiber$1.expirationTime = renderExpirationTime); 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 === alternate || 0 === alternate.expirationTime) && - ((alternate = queue.lastRenderedReducer), null !== alternate) + (null === pending || 0 === pending.expirationTime) && + ((pending = queue.lastRenderedReducer), null !== pending) ) try { var currentState = queue.lastRenderedState, - eagerState = alternate(currentState, action); - suspenseConfig.eagerReducer = alternate; + eagerState = pending(currentState, action); + suspenseConfig.eagerReducer = pending; suspenseConfig.eagerState = eagerState; - if (is$1(eagerState, currentState)) return; + if (objectIs(eagerState, currentState)) return; } catch (error) { } finally { } - scheduleUpdateOnFiber(fiber, currentTime); + scheduleWork(fiber, currentTime); } } +function updateEventListener() {} var ContextOnlyDispatcher = { readContext: readContext, useCallback: throwInvalidHookError, @@ -3581,7 +3460,8 @@ var ContextOnlyDispatcher = { useDebugValue: throwInvalidHookError, useResponder: throwInvalidHookError, useDeferredValue: throwInvalidHookError, - useTransition: throwInvalidHookError + useTransition: throwInvalidHookError, + useEvent: throwInvalidHookError }, HooksDispatcherOnMount = { readContext: readContext, @@ -3592,13 +3472,13 @@ var ContextOnlyDispatcher = { deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; return mountEffectImpl( 4, - 36, + 2, imperativeHandleEffect.bind(null, create, ref), deps ); }, useLayoutEffect: function(create, deps) { - return mountEffectImpl(4, 36, create, deps); + return mountEffectImpl(4, 2, create, deps); }, useMemo: function(nextCreate, deps) { var hook = mountWorkInProgressHook(); @@ -3612,7 +3492,7 @@ var ContextOnlyDispatcher = { initialArg = void 0 !== init ? init(initialArg) : initialArg; hook.memoizedState = hook.baseState = initialArg; reducer = hook.queue = { - last: null, + pending: null, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialArg @@ -3631,23 +3511,21 @@ var ContextOnlyDispatcher = { }, useState: mountState, useDebugValue: mountDebugValue, - useResponder: createResponderListener, + useResponder: createDeprecatedResponderListener, useDeferredValue: function(value, config) { var _mountState = mountState(value), prevValue = _mountState[0], setValue = _mountState[1]; mountEffect( function() { - 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; - } - }); + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } }, [value, config] ); @@ -3655,177 +3533,124 @@ var ContextOnlyDispatcher = { }, useTransition: function(config) { var _mountState2 = mountState(!1), - isPending = _mountState2[0], - setPending = _mountState2[1]; + isPending = _mountState2[0]; + _mountState2 = _mountState2[1]; return [ - 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] - ), + mountCallback(startTransition.bind(null, _mountState2, config), [ + _mountState2, + config + ]), isPending ]; - } + }, + useEvent: function() {} }, HooksDispatcherOnUpdate = { readContext: readContext, useCallback: updateCallback, useContext: readContext, useEffect: updateEffect, - 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; - }, + useImperativeHandle: updateImperativeHandle, + useLayoutEffect: updateLayoutEffect, + useMemo: updateMemo, useReducer: updateReducer, - useRef: function() { - return updateWorkInProgressHook().memoizedState; + useRef: updateRef, + useState: function() { + return updateReducer(basicStateReducer); }, - useState: updateState, useDebugValue: mountDebugValue, - useResponder: createResponderListener, + useResponder: createDeprecatedResponderListener, useDeferredValue: function(value, config) { - var _updateState = updateState(value), + var _updateState = updateReducer(basicStateReducer), prevValue = _updateState[0], setValue = _updateState[1]; updateEffect( function() { - 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; - } - }); + 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 = updateState(!1), - isPending = _updateState2[0], - setPending = _updateState2[1]; + var _updateState2 = updateReducer(basicStateReducer), + isPending = _updateState2[0]; + _updateState2 = _updateState2[1]; return [ - 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] - ), + updateCallback(startTransition.bind(null, _updateState2, config), [ + _updateState2, + config + ]), isPending ]; - } + }, + useEvent: updateEventListener }, - 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 + 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] ); - 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, + 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, didReceiveUpdate = !1; function reconcileChildren( - current$$1, + current, workInProgress, nextChildren, renderExpirationTime ) { workInProgress.child = - null === current$$1 + null === current ? mountChildFibers( workInProgress, null, @@ -3834,13 +3659,13 @@ function reconcileChildren( ) : reconcileChildFibers( workInProgress, - current$$1.child, + current.child, nextChildren, renderExpirationTime ); } function updateForwardRef( - current$$1, + current, workInProgress, Component, nextProps, @@ -3850,43 +3675,38 @@ function updateForwardRef( var ref = workInProgress.ref; prepareToReadContext(workInProgress, renderExpirationTime); nextProps = renderWithHooks( - current$$1, + current, workInProgress, Component, nextProps, ref, renderExpirationTime ); - if (null !== current$$1 && !didReceiveUpdate) + if (null !== current && !didReceiveUpdate) return ( - (workInProgress.updateQueue = current$$1.updateQueue), + (workInProgress.updateQueue = current.updateQueue), (workInProgress.effectTag &= -517), - current$$1.expirationTime <= renderExpirationTime && - (current$$1.expirationTime = 0), + current.expirationTime <= renderExpirationTime && + (current.expirationTime = 0), bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ) ); workInProgress.effectTag |= 1; - reconcileChildren( - current$$1, - workInProgress, - nextProps, - renderExpirationTime - ); + reconcileChildren(current, workInProgress, nextProps, renderExpirationTime); return workInProgress.child; } function updateMemoComponent( - current$$1, + current, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime ) { - if (null === current$$1) { + if (null === current) { var type = Component.type; if ( "function" === typeof type && @@ -3899,7 +3719,7 @@ function updateMemoComponent( (workInProgress.tag = 15), (workInProgress.type = type), updateSimpleMemoComponent( - current$$1, + current, workInProgress, type, nextProps, @@ -3907,7 +3727,7 @@ function updateMemoComponent( renderExpirationTime ) ); - current$$1 = createFiberFromTypeAndProps( + current = createFiberFromTypeAndProps( Component.type, null, nextProps, @@ -3915,65 +3735,66 @@ function updateMemoComponent( workInProgress.mode, renderExpirationTime ); - current$$1.ref = workInProgress.ref; - current$$1.return = workInProgress; - return (workInProgress.child = current$$1); + current.ref = workInProgress.ref; + current.return = workInProgress; + return (workInProgress.child = current); } - type = current$$1.child; + type = current.child; if ( updateExpirationTime < renderExpirationTime && ((updateExpirationTime = type.memoizedProps), (Component = Component.compare), (Component = null !== Component ? Component : shallowEqual), Component(updateExpirationTime, nextProps) && - current$$1.ref === workInProgress.ref) + current.ref === workInProgress.ref) ) return bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ); workInProgress.effectTag |= 1; - current$$1 = createWorkInProgress(type, nextProps, renderExpirationTime); - current$$1.ref = workInProgress.ref; - current$$1.return = workInProgress; - return (workInProgress.child = current$$1); + current = createWorkInProgress(type, nextProps); + current.ref = workInProgress.ref; + current.return = workInProgress; + return (workInProgress.child = current); } function updateSimpleMemoComponent( - current$$1, + current, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime ) { - return null !== current$$1 && - shallowEqual(current$$1.memoizedProps, nextProps) && - current$$1.ref === workInProgress.ref && + return null !== current && + shallowEqual(current.memoizedProps, nextProps) && + current.ref === workInProgress.ref && ((didReceiveUpdate = !1), updateExpirationTime < renderExpirationTime) - ? bailoutOnAlreadyFinishedWork( - current$$1, + ? ((workInProgress.expirationTime = current.expirationTime), + bailoutOnAlreadyFinishedWork( + current, workInProgress, renderExpirationTime - ) + )) : updateFunctionComponent( - current$$1, + current, workInProgress, Component, nextProps, renderExpirationTime ); } -function markRef(current$$1, workInProgress) { +function markRef(current, workInProgress) { var ref = workInProgress.ref; if ( - (null === current$$1 && null !== ref) || - (null !== current$$1 && current$$1.ref !== ref) + (null === current && null !== ref) || + (null !== current && current.ref !== ref) ) workInProgress.effectTag |= 128; } function updateFunctionComponent( - current$$1, + current, workInProgress, Component, nextProps, @@ -3985,36 +3806,31 @@ function updateFunctionComponent( context = getMaskedContext(workInProgress, context); prepareToReadContext(workInProgress, renderExpirationTime); Component = renderWithHooks( - current$$1, + current, workInProgress, Component, nextProps, context, renderExpirationTime ); - if (null !== current$$1 && !didReceiveUpdate) + if (null !== current && !didReceiveUpdate) return ( - (workInProgress.updateQueue = current$$1.updateQueue), + (workInProgress.updateQueue = current.updateQueue), (workInProgress.effectTag &= -517), - current$$1.expirationTime <= renderExpirationTime && - (current$$1.expirationTime = 0), + current.expirationTime <= renderExpirationTime && + (current.expirationTime = 0), bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ) ); workInProgress.effectTag |= 1; - reconcileChildren( - current$$1, - workInProgress, - Component, - renderExpirationTime - ); + reconcileChildren(current, workInProgress, Component, renderExpirationTime); return workInProgress.child; } function updateClassComponent( - current$$1, + current, workInProgress, Component, nextProps, @@ -4026,16 +3842,11 @@ function updateClassComponent( } else hasContext = !1; prepareToReadContext(workInProgress, renderExpirationTime); if (null === workInProgress.stateNode) - null !== current$$1 && - ((current$$1.alternate = null), + null !== current && + ((current.alternate = null), (workInProgress.alternate = null), (workInProgress.effectTag |= 2)), - constructClassInstance( - workInProgress, - Component, - nextProps, - renderExpirationTime - ), + constructClassInstance(workInProgress, Component, nextProps), mountClassInstance( workInProgress, Component, @@ -4043,7 +3854,7 @@ function updateClassComponent( renderExpirationTime ), (nextProps = !0); - else if (null === current$$1) { + else if (null === current) { var instance = workInProgress.stateNode, oldProps = workInProgress.memoizedProps; instance.props = oldProps; @@ -4071,17 +3882,14 @@ function updateClassComponent( )); hasForceUpdate = !1; var oldState = workInProgress.memoizedState; - oldContext = instance.state = oldState; - var updateQueue = workInProgress.updateQueue; - null !== updateQueue && - (processUpdateQueue( - workInProgress, - updateQueue, - nextProps, - instance, - renderExpirationTime - ), - (oldContext = workInProgress.memoizedState)); + instance.state = oldState; + processUpdateQueue( + workInProgress, + nextProps, + instance, + renderExpirationTime + ); + oldContext = workInProgress.memoizedState; oldProps !== nextProps || oldState !== oldContext || didPerformWorkStackCursor.current || @@ -4127,6 +3935,7 @@ function updateClassComponent( (nextProps = !1)); } else (instance = workInProgress.stateNode), + cloneUpdateQueue(current, workInProgress), (oldProps = workInProgress.memoizedProps), (instance.props = workInProgress.type === workInProgress.elementType @@ -4155,17 +3964,14 @@ function updateClassComponent( )), (hasForceUpdate = !1), (oldContext = workInProgress.memoizedState), - (oldState = instance.state = oldContext), - (updateQueue = workInProgress.updateQueue), - null !== updateQueue && - (processUpdateQueue( - workInProgress, - updateQueue, - nextProps, - instance, - renderExpirationTime - ), - (oldState = workInProgress.memoizedState)), + (instance.state = oldContext), + processUpdateQueue( + workInProgress, + nextProps, + instance, + renderExpirationTime + ), + (oldState = workInProgress.memoizedState), oldProps !== nextProps || oldContext !== oldState || didPerformWorkStackCursor.current || @@ -4209,12 +4015,12 @@ function updateClassComponent( "function" === typeof instance.getSnapshotBeforeUpdate && (workInProgress.effectTag |= 256)) : ("function" !== typeof instance.componentDidUpdate || - (oldProps === current$$1.memoizedProps && - oldContext === current$$1.memoizedState) || + (oldProps === current.memoizedProps && + oldContext === current.memoizedState) || (workInProgress.effectTag |= 4), "function" !== typeof instance.getSnapshotBeforeUpdate || - (oldProps === current$$1.memoizedProps && - oldContext === current$$1.memoizedState) || + (oldProps === current.memoizedProps && + oldContext === current.memoizedState) || (workInProgress.effectTag |= 256), (workInProgress.memoizedProps = nextProps), (workInProgress.memoizedState = oldState)), @@ -4223,16 +4029,16 @@ function updateClassComponent( (instance.context = contextType), (nextProps = getDerivedStateFromProps)) : ("function" !== typeof instance.componentDidUpdate || - (oldProps === current$$1.memoizedProps && - oldContext === current$$1.memoizedState) || + (oldProps === current.memoizedProps && + oldContext === current.memoizedState) || (workInProgress.effectTag |= 4), "function" !== typeof instance.getSnapshotBeforeUpdate || - (oldProps === current$$1.memoizedProps && - oldContext === current$$1.memoizedState) || + (oldProps === current.memoizedProps && + oldContext === current.memoizedState) || (workInProgress.effectTag |= 256), (nextProps = !1)); return finishClassComponent( - current$$1, + current, workInProgress, Component, nextProps, @@ -4241,35 +4047,35 @@ function updateClassComponent( ); } function finishClassComponent( - current$$1, + current, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime ) { - markRef(current$$1, workInProgress); + markRef(current, workInProgress); var didCaptureError = 0 !== (workInProgress.effectTag & 64); if (!shouldUpdate && !didCaptureError) return ( hasContext && invalidateContextProvider(workInProgress, Component, !1), bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ) ); shouldUpdate = workInProgress.stateNode; - ReactCurrentOwner$3.current = workInProgress; + ReactCurrentOwner$1.current = workInProgress; var nextChildren = didCaptureError && "function" !== typeof Component.getDerivedStateFromError ? null : shouldUpdate.render(); workInProgress.effectTag |= 1; - null !== current$$1 && didCaptureError + null !== current && didCaptureError ? ((workInProgress.child = reconcileChildFibers( workInProgress, - current$$1.child, + current.child, null, renderExpirationTime )), @@ -4280,7 +4086,7 @@ function finishClassComponent( renderExpirationTime ))) : reconcileChildren( - current$$1, + current, workInProgress, nextChildren, renderExpirationTime @@ -4303,7 +4109,7 @@ function pushHostRootContext(workInProgress) { } var SUSPENDED_MARKER = { dehydrated: null, retryTime: 0 }; function updateSuspenseComponent( - current$$1, + current, workInProgress, renderExpirationTime ) { @@ -4315,32 +4121,30 @@ function updateSuspenseComponent( (JSCompiler_temp = 0 !== (workInProgress.effectTag & 64)) || (JSCompiler_temp = 0 !== (suspenseContext & 2) && - (null === current$$1 || null !== current$$1.memoizedState)); + (null === current || null !== current.memoizedState)); JSCompiler_temp ? ((nextDidTimeout = !0), (workInProgress.effectTag &= -65)) - : (null !== current$$1 && null === current$$1.memoizedState) || + : (null !== current && null === current.memoizedState) || void 0 === nextProps.fallback || !0 === nextProps.unstable_avoidThisFallback || (suspenseContext |= 1); - push(suspenseStackCursor, suspenseContext & 1, workInProgress); - if (null === current$$1) { - void 0 !== nextProps.fallback && - tryToClaimNextHydratableInstance(workInProgress); + push(suspenseStackCursor, suspenseContext & 1); + if (null === current) { if (nextDidTimeout) { nextDidTimeout = nextProps.fallback; nextProps = createFiberFromFragment(null, mode, 0, null); nextProps.return = workInProgress; if (0 === (workInProgress.mode & 2)) for ( - current$$1 = + current = null !== workInProgress.memoizedState ? workInProgress.child.child : workInProgress.child, - nextProps.child = current$$1; - null !== current$$1; + nextProps.child = current; + null !== current; ) - (current$$1.return = nextProps), (current$$1 = current$$1.sibling); + (current.return = nextProps), (current = current.sibling); renderExpirationTime = createFiberFromFragment( nextDidTimeout, mode, @@ -4362,15 +4166,14 @@ function updateSuspenseComponent( renderExpirationTime )); } - if (null !== current$$1.memoizedState) { - current$$1 = current$$1.child; - mode = current$$1.sibling; + if (null !== current.memoizedState) { + current = current.child; + mode = current.sibling; if (nextDidTimeout) { nextProps = nextProps.fallback; renderExpirationTime = createWorkInProgress( - current$$1, - current$$1.pendingProps, - 0 + current, + current.pendingProps ); renderExpirationTime.return = workInProgress; if ( @@ -4379,7 +4182,7 @@ function updateSuspenseComponent( null !== workInProgress.memoizedState ? workInProgress.child.child : workInProgress.child), - nextDidTimeout !== current$$1.child) + nextDidTimeout !== current.child) ) for ( renderExpirationTime.child = nextDidTimeout; @@ -4388,7 +4191,7 @@ function updateSuspenseComponent( ) (nextDidTimeout.return = renderExpirationTime), (nextDidTimeout = nextDidTimeout.sibling); - mode = createWorkInProgress(mode, nextProps, mode.expirationTime); + mode = createWorkInProgress(mode, nextProps); mode.return = workInProgress; renderExpirationTime.sibling = mode; renderExpirationTime.childExpirationTime = 0; @@ -4398,31 +4201,31 @@ function updateSuspenseComponent( } renderExpirationTime = reconcileChildFibers( workInProgress, - current$$1.child, + current.child, nextProps.children, renderExpirationTime ); workInProgress.memoizedState = null; return (workInProgress.child = renderExpirationTime); } - current$$1 = current$$1.child; + current = current.child; if (nextDidTimeout) { nextDidTimeout = nextProps.fallback; nextProps = createFiberFromFragment(null, mode, 0, null); nextProps.return = workInProgress; - nextProps.child = current$$1; - null !== current$$1 && (current$$1.return = nextProps); + nextProps.child = current; + null !== current && (current.return = nextProps); if (0 === (workInProgress.mode & 2)) for ( - current$$1 = + current = null !== workInProgress.memoizedState ? workInProgress.child.child : workInProgress.child, - nextProps.child = current$$1; - null !== current$$1; + nextProps.child = current; + null !== current; ) - (current$$1.return = nextProps), (current$$1 = current$$1.sibling); + (current.return = nextProps), (current = current.sibling); renderExpirationTime = createFiberFromFragment( nextDidTimeout, mode, @@ -4440,7 +4243,7 @@ function updateSuspenseComponent( workInProgress.memoizedState = null; return (workInProgress.child = reconcileChildFibers( workInProgress, - current$$1, + current, nextProps.children, renderExpirationTime )); @@ -4467,6 +4270,7 @@ function initSuspenseListRenderState( ? (workInProgress.memoizedState = { isBackwards: isBackwards, rendering: null, + renderingStartTime: 0, last: lastContentRow, tail: tail, tailExpiration: 0, @@ -4475,6 +4279,7 @@ function initSuspenseListRenderState( }) : ((renderState.isBackwards = isBackwards), (renderState.rendering = null), + (renderState.renderingStartTime = 0), (renderState.last = lastContentRow), (renderState.tail = tail), (renderState.tailExpiration = 0), @@ -4482,7 +4287,7 @@ function initSuspenseListRenderState( (renderState.lastEffect = lastEffectBeforeRendering)); } function updateSuspenseListComponent( - current$$1, + current, workInProgress, renderExpirationTime ) { @@ -4490,7 +4295,7 @@ function updateSuspenseListComponent( revealOrder = nextProps.revealOrder, tailMode = nextProps.tail; reconcileChildren( - current$$1, + current, workInProgress, nextProps.children, renderExpirationTime @@ -4499,42 +4304,39 @@ function updateSuspenseListComponent( if (0 !== (nextProps & 2)) (nextProps = (nextProps & 1) | 2), (workInProgress.effectTag |= 64); else { - 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; + 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; continue; } - if (current$$1 === workInProgress) break a; - for (; null === current$$1.sibling; ) { - if ( - null === current$$1.return || - current$$1.return === workInProgress - ) + if (current === workInProgress) break a; + for (; null === current.sibling; ) { + if (null === current.return || current.return === workInProgress) break a; - current$$1 = current$$1.return; + current = current.return; } - current$$1.sibling.return = current$$1.return; - current$$1 = current$$1.sibling; + current.sibling.return = current.return; + current = current.sibling; } nextProps &= 1; } - push(suspenseStackCursor, nextProps, workInProgress); + push(suspenseStackCursor, nextProps); if (0 === (workInProgress.mode & 2)) workInProgress.memoizedState = null; else switch (revealOrder) { case "forwards": renderExpirationTime = workInProgress.child; for (revealOrder = null; null !== renderExpirationTime; ) - (current$$1 = renderExpirationTime.alternate), - null !== current$$1 && - null === findFirstSuspended(current$$1) && + (current = renderExpirationTime.alternate), + null !== current && + null === findFirstSuspended(current) && (revealOrder = renderExpirationTime), (renderExpirationTime = renderExpirationTime.sibling); renderExpirationTime = revealOrder; @@ -4556,15 +4358,15 @@ function updateSuspenseListComponent( renderExpirationTime = null; revealOrder = workInProgress.child; for (workInProgress.child = null; null !== revealOrder; ) { - current$$1 = revealOrder.alternate; - if (null !== current$$1 && null === findFirstSuspended(current$$1)) { + current = revealOrder.alternate; + if (null !== current && null === findFirstSuspended(current)) { workInProgress.child = revealOrder; break; } - current$$1 = revealOrder.sibling; + current = revealOrder.sibling; revealOrder.sibling = renderExpirationTime; renderExpirationTime = revealOrder; - revealOrder = current$$1; + revealOrder = current; } initSuspenseListRenderState( workInProgress, @@ -4591,35 +4393,29 @@ function updateSuspenseListComponent( return workInProgress.child; } function bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ) { - null !== current$$1 && - (workInProgress.dependencies = current$$1.dependencies); + null !== current && (workInProgress.dependencies = current.dependencies); var updateExpirationTime = workInProgress.expirationTime; 0 !== updateExpirationTime && markUnprocessedUpdateTime(updateExpirationTime); if (workInProgress.childExpirationTime < renderExpirationTime) return null; - if (null !== current$$1 && workInProgress.child !== current$$1.child) + if (null !== current && workInProgress.child !== current.child) throw Error("Resuming work not yet implemented."); if (null !== workInProgress.child) { - current$$1 = workInProgress.child; - renderExpirationTime = createWorkInProgress( - current$$1, - current$$1.pendingProps, - current$$1.expirationTime - ); + current = workInProgress.child; + renderExpirationTime = createWorkInProgress(current, current.pendingProps); workInProgress.child = renderExpirationTime; for ( renderExpirationTime.return = workInProgress; - null !== current$$1.sibling; + null !== current.sibling; ) - (current$$1 = current$$1.sibling), + (current = current.sibling), (renderExpirationTime = renderExpirationTime.sibling = createWorkInProgress( - current$$1, - current$$1.pendingProps, - current$$1.expirationTime + current, + current.pendingProps )), (renderExpirationTime.return = workInProgress); renderExpirationTime.sibling = null; @@ -4641,12 +4437,7 @@ appendAllChildren = function( var instance = node.stateNode; needsVisibilityToggle && isHidden && - (instance = cloneHiddenInstance( - instance, - node.type, - node.memoizedProps, - node - )); + (instance = cloneHiddenInstance(instance)); appendChildNode(parent.node, instance.node); } else if (6 === node.tag) { instance = node.stateNode; @@ -4699,12 +4490,7 @@ function appendAllChildrenToContainer( var instance = node.stateNode; needsVisibilityToggle && isHidden && - (instance = cloneHiddenInstance( - instance, - node.type, - node.memoizedProps, - node - )); + (instance = cloneHiddenInstance(instance)); appendChildNodeToSet(containerChildSet, instance.node); } else if (6 === node.tag) { instance = node.stateNode; @@ -4790,8 +4576,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), @@ -4801,16 +4587,17 @@ 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)); + 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); }; function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { switch (renderState.tailMode) { @@ -4836,47 +4623,346 @@ function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { : (_lastTailNode.sibling = null); } } -function unwindWork(workInProgress) { +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: - isContextProvider(workInProgress.type) && popContext(workInProgress); - var effectTag = workInProgress.effectTag; - return effectTag & 4096 - ? ((workInProgress.effectTag = (effectTag & -4097) | 64), - workInProgress) - : null; + return isContextProvider(workInProgress.type) && popContext(), null; case 3: - popHostContainer(workInProgress); - popTopLevelContextObject(workInProgress); - effectTag = workInProgress.effectTag; - if (0 !== (effectTag & 64)) - throw Error( - "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." - ); - workInProgress.effectTag = (effectTag & -4097) | 64; - return workInProgress; - case 5: - return popHostContext(workInProgress), null; - case 13: return ( - pop(suspenseStackCursor, workInProgress), - (effectTag = workInProgress.effectTag), - effectTag & 4096 - ? ((workInProgress.effectTag = (effectTag & -4097) | 64), - workInProgress) - : null + popHostContainer(), + pop(didPerformWorkStackCursor), + pop(contextStackCursor), + (current = workInProgress.stateNode), + current.pendingContext && + ((current.context = current.pendingContext), + (current.pendingContext = null)), + updateHostContainer(workInProgress), + null ); - case 19: - return pop(suspenseStackCursor, workInProgress), null; - case 4: - return popHostContainer(workInProgress), null; - case 10: - return popProvider(workInProgress), null; - default: + 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; - } -} -function createCapturedValue(value, source) { + 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(); + var effectTag = workInProgress.effectTag; + return effectTag & 4096 + ? ((workInProgress.effectTag = (effectTag & -4097) | 64), + workInProgress) + : null; + case 3: + popHostContainer(); + pop(didPerformWorkStackCursor); + pop(contextStackCursor); + effectTag = workInProgress.effectTag; + if (0 !== (effectTag & 64)) + throw Error( + "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." + ); + workInProgress.effectTag = (effectTag & -4097) | 64; + return workInProgress; + case 5: + return popHostContext(workInProgress), null; + case 13: + return ( + pop(suspenseStackCursor), + (effectTag = workInProgress.effectTag), + effectTag & 4096 + ? ((workInProgress.effectTag = (effectTag & -4097) | 64), + workInProgress) + : null + ); + case 19: + return pop(suspenseStackCursor), null; + case 4: + return popHostContainer(), null; + case 10: + return popProvider(workInProgress), null; + default: + return null; + } +} +function createCapturedValue(value, source) { return { value: value, source: source, @@ -4926,102 +5012,180 @@ function logError(boundary, errorInfo) { }); } } -function safelyCallComponentWillUnmount(current$$1, instance) { +function safelyCallComponentWillUnmount(current, instance) { try { - (instance.props = current$$1.memoizedProps), - (instance.state = current$$1.memoizedState), + (instance.props = current.memoizedProps), + (instance.state = current.memoizedState), instance.componentWillUnmount(); } catch (unmountError) { - captureCommitPhaseError(current$$1, unmountError); + captureCommitPhaseError(current, unmountError); } } -function safelyDetachRef(current$$1) { - var ref = current$$1.ref; +function safelyDetachRef(current) { + var ref = current.ref; if (null !== ref) if ("function" === typeof ref) try { ref(null); } catch (refError) { - captureCommitPhaseError(current$$1, refError); + captureCommitPhaseError(current, refError); } else ref.current = null; } -function commitBeforeMutationLifeCycles(current$$1, finishedWork) { +function commitBeforeMutationLifeCycles(current, finishedWork) { switch (finishedWork.tag) { case 0: case 11: case 15: - commitHookEffectList(2, 0, finishedWork); - break; + case 22: + return; case 1: - if (finishedWork.effectTag & 256 && null !== current$$1) { - var prevProps = current$$1.memoizedProps, - prevState = current$$1.memoizedState; - current$$1 = finishedWork.stateNode; - finishedWork = current$$1.getSnapshotBeforeUpdate( + if (finishedWork.effectTag & 256 && null !== current) { + var prevProps = current.memoizedProps, + prevState = current.memoizedState; + current = finishedWork.stateNode; + finishedWork = current.getSnapshotBeforeUpdate( finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState ); - current$$1.__reactInternalSnapshotBeforeUpdate = finishedWork; + current.__reactInternalSnapshotBeforeUpdate = finishedWork; } - break; + return; case 3: case 5: case 6: case 4: case 17: - break; - default: - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); + 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 commitHookEffectList(unmountTag, mountTag, finishedWork) { +function commitHookEffectListUnmount(tag, finishedWork) { finishedWork = finishedWork.updateQueue; finishedWork = null !== finishedWork ? finishedWork.lastEffect : null; if (null !== finishedWork) { var effect = (finishedWork = finishedWork.next); do { - if (0 !== (effect.tag & unmountTag)) { + if ((effect.tag & tag) === tag) { 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 commitUnmount(finishedRoot, current$$1$jscomp$0, renderPriorityLevel) { +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" === typeof onCommitFiberUnmount && - onCommitFiberUnmount(current$$1$jscomp$0); - switch (current$$1$jscomp$0.tag) { + onCommitFiberUnmount(current$jscomp$0); + switch (current$jscomp$0.tag) { case 0: case 11: case 14: case 15: - finishedRoot = current$$1$jscomp$0.updateQueue; + case 22: + finishedRoot = current$jscomp$0.updateQueue; if ( null !== finishedRoot && ((finishedRoot = finishedRoot.lastEffect), null !== finishedRoot) ) { var firstEffect = finishedRoot.next; - runWithPriority$1( + runWithPriority( 97 < renderPriorityLevel ? 97 : renderPriorityLevel, function() { var effect = firstEffect; do { - var destroy = effect.destroy; - if (void 0 !== destroy) { - var current$$1 = current$$1$jscomp$0; + var _destroy = effect.destroy; + if (void 0 !== _destroy) { + var current = current$jscomp$0; try { - destroy(); + _destroy(); } catch (error) { - captureCommitPhaseError(current$$1, error); + captureCommitPhaseError(current, error); } } effect = effect.next; @@ -5031,42 +5195,41 @@ function commitUnmount(finishedRoot, current$$1$jscomp$0, renderPriorityLevel) { } break; case 1: - safelyDetachRef(current$$1$jscomp$0); - renderPriorityLevel = current$$1$jscomp$0.stateNode; + safelyDetachRef(current$jscomp$0); + renderPriorityLevel = current$jscomp$0.stateNode; "function" === typeof renderPriorityLevel.componentWillUnmount && - safelyCallComponentWillUnmount( - current$$1$jscomp$0, - renderPriorityLevel - ); + safelyCallComponentWillUnmount(current$jscomp$0, renderPriorityLevel); break; case 5: - safelyDetachRef(current$$1$jscomp$0); + safelyDetachRef(current$jscomp$0); break; case 4: - createChildNodeSet(current$$1$jscomp$0.stateNode.containerInfo); + createChildNodeSet(current$jscomp$0.stateNode.containerInfo); } } -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; +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; null !== alternate && detachFiber(alternate); } -function commitWork(current$$1, finishedWork) { +function commitWork(current, finishedWork) { switch (finishedWork.tag) { case 0: case 11: case 14: case 15: - commitHookEffectList(4, 8, finishedWork); + case 22: + commitHookEffectListUnmount(3, finishedWork); return; case 12: return; @@ -5079,19 +5242,20 @@ function commitWork(current$$1, finishedWork) { attachSuspenseRetryListeners(finishedWork); return; } - 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." - ); + 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." + ); } } function attachSuspenseRetryListeners(finishedWork) { @@ -5148,7 +5312,7 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { return expirationTime; } var ceil = Math.ceil, - ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher, + ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, NoContext = 0, LegacyUnbatchedContext = 8, @@ -5163,7 +5327,7 @@ var ceil = Math.ceil, executionContext = NoContext, workInProgressRoot = null, workInProgress = null, - renderExpirationTime = 0, + renderExpirationTime$1 = 0, workInProgressRootExitStatus = RootIncomplete, workInProgressRootFatalError = null, workInProgressRootLatestProcessedExpirationTime = 1073741823, @@ -5188,8 +5352,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; @@ -5197,7 +5361,7 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { var priorityLevel = getCurrentPriorityLevel(); if (0 === (fiber & 4)) return 99 === priorityLevel ? 1073741823 : 1073741822; if ((executionContext & RenderContext) !== NoContext) - return renderExpirationTime; + return renderExpirationTime$1; if (null !== suspenseConfig) currentTime = 1073741821 - @@ -5229,11 +5393,11 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { throw Error("Expected a valid priority level"); } null !== workInProgressRoot && - currentTime === renderExpirationTime && + currentTime === renderExpirationTime$1 && --currentTime; return currentTime; } -function scheduleUpdateOnFiber(fiber, expirationTime) { +function scheduleWork(fiber, expirationTime) { if (50 < nestedUpdateCount) throw ((nestedUpdateCount = 0), (rootWithNestedUpdates = null), @@ -5287,7 +5451,7 @@ function markUpdateTimeFromFiberToRoot(fiber, expirationTime) { (workInProgressRoot === root && (markUnprocessedUpdateTime(expirationTime), workInProgressRootExitStatus === RootSuspendedWithDelay && - markRootSuspendedAtTime(root, renderExpirationTime)), + markRootSuspendedAtTime(root, renderExpirationTime$1)), markRootUpdatedAtTime(root, expirationTime)); return root; } @@ -5296,9 +5460,10 @@ function getNextRootExpirationTimeToWorkOn(root) { if (0 !== lastExpiredTime) return lastExpiredTime; lastExpiredTime = root.firstPendingTime; if (!isRootSuspendedAtTime(root, lastExpiredTime)) return lastExpiredTime; - lastExpiredTime = root.lastPingedTime; + var lastPingedTime = root.lastPingedTime; root = root.nextKnownPendingLevel; - return lastExpiredTime > root ? lastExpiredTime : root; + root = lastPingedTime > root ? lastPingedTime : root; + return 2 >= root && lastExpiredTime !== root ? 0 : root; } function ensureRootIsScheduled(root) { if (0 !== root.lastExpiredTime) @@ -5320,18 +5485,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 ( @@ -5358,264 +5523,225 @@ function ensureRootIsScheduled(root) { } function performConcurrentWorkOnRoot(root, didTimeout) { currentEventTime = 0; - if (didTimeout) - return ( - (didTimeout = requestCurrentTimeForUpdate()), - markRootExpiredAtTime(root, didTimeout), + 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), ensureRootIsScheduled(root), - 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(); + 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; - } catch (thrownValue) { - handleError(root, thrownValue); } - 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) + 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) ) { - case RootIncomplete: - case RootFatalErrored: - throw Error("Root did not complete. This is a bug in React."); - case RootErrored: - markRootExpiredAtTime( - root, - 2 < expirationTime ? 2 : expirationTime + 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 + ); + break; + } + commitRoot(root); + break; + case RootCompleted: + if ( + 1073741823 !== workInProgressRootLatestProcessedExpirationTime && + null !== workInProgressRootCanSuspendUsingConfig + ) { + 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 ); 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."); + } } - ensureRootIsScheduled(root); - if (root.callbackNode === didTimeout) - return performConcurrentWorkOnRoot.bind(null, root); + commitRoot(root); + break; + default: + throw Error("Unknown root exit status."); } } - return null; + 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 ? 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); - } - } + 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; @@ -5627,26 +5753,27 @@ function prepareFreshStack(root, expirationTime) { var interruptedWork = timeoutHandle; switch (interruptedWork.tag) { case 1: - var childContextTypes = interruptedWork.type.childContextTypes; - null !== childContextTypes && - void 0 !== childContextTypes && - popContext(interruptedWork); + interruptedWork = interruptedWork.type.childContextTypes; + null !== interruptedWork && + void 0 !== interruptedWork && + popContext(); break; case 3: - popHostContainer(interruptedWork); - popTopLevelContextObject(interruptedWork); + popHostContainer(); + pop(didPerformWorkStackCursor); + pop(contextStackCursor); break; case 5: popHostContext(interruptedWork); break; case 4: - popHostContainer(interruptedWork); + popHostContainer(); break; case 13: - pop(suspenseStackCursor, interruptedWork); + pop(suspenseStackCursor); break; case 19: - pop(suspenseStackCursor, interruptedWork); + pop(suspenseStackCursor); break; case 10: popProvider(interruptedWork); @@ -5654,8 +5781,8 @@ function prepareFreshStack(root, expirationTime) { timeoutHandle = timeoutHandle.return; } workInProgressRoot = root; - workInProgress = createWorkInProgress(root.current, null, expirationTime); - renderExpirationTime = expirationTime; + workInProgress = createWorkInProgress(root.current, null); + renderExpirationTime$1 = expirationTime; workInProgressRootExitStatus = RootIncomplete; workInProgressRootFatalError = null; workInProgressRootLatestSuspenseTimeout = workInProgressRootLatestProcessedExpirationTime = 1073741823; @@ -5667,19 +5794,32 @@ function handleError(root$jscomp$0, thrownValue) { do { try { resetContextDependencies(); - resetHooks(); + 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; if (null === workInProgress || null === workInProgress.return) return ( (workInProgressRootExitStatus = RootFatalErrored), (workInProgressRootFatalError = thrownValue), - null + (workInProgress = null) ); a: { var root = root$jscomp$0, returnFiber = workInProgress.return, sourceFiber = workInProgress, value = thrownValue; - thrownValue = renderExpirationTime; + thrownValue = renderExpirationTime$1; sourceFiber.effectTag |= 2048; sourceFiber.firstEffect = sourceFiber.lastEffect = null; if ( @@ -5687,8 +5827,17 @@ function handleError(root$jscomp$0, thrownValue) { "object" === typeof value && "function" === typeof value.then ) { - var thenable = value, - hasInvisibleParentBoundary = + 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 = 0 !== (suspenseStackCursor.current & 1), _workInProgress = returnFiber; do { @@ -5703,10 +5852,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) { @@ -5805,399 +5954,102 @@ function handleError(root$jscomp$0, thrownValue) { } while (null !== _workInProgress); } workInProgress = completeUnitOfWork(workInProgress); - } catch (yetAnotherThrownValue) { - thrownValue = yetAnotherThrownValue; - continue; - } - break; - } while (1); -} -function pushDispatcher() { - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = ContextOnlyDispatcher; - return null === prevDispatcher ? ContextOnlyDispatcher : prevDispatcher; -} -function markRenderEventTimeAndConfig(expirationTime, suspenseConfig) { - expirationTime < workInProgressRootLatestProcessedExpirationTime && - 2 < expirationTime && - (workInProgressRootLatestProcessedExpirationTime = expirationTime); - null !== suspenseConfig && - expirationTime < workInProgressRootLatestSuspenseTimeout && - 2 < expirationTime && - ((workInProgressRootLatestSuspenseTimeout = expirationTime), - (workInProgressRootCanSuspendUsingConfig = suspenseConfig)); -} -function markUnprocessedUpdateTime(expirationTime) { - expirationTime > workInProgressRootNextUnprocessedUpdateTime && - (workInProgressRootNextUnprocessedUpdateTime = expirationTime); -} -function workLoopSync() { - for (; null !== workInProgress; ) - workInProgress = performUnitOfWork(workInProgress); -} -function workLoopConcurrent() { - for (; null !== workInProgress && !Scheduler_shouldYield(); ) - workInProgress = performUnitOfWork(workInProgress); -} -function performUnitOfWork(unitOfWork) { - var next = beginWork$$1( - unitOfWork.alternate, - unitOfWork, - renderExpirationTime - ); - unitOfWork.memoizedProps = unitOfWork.pendingProps; - null === next && (next = completeUnitOfWork(unitOfWork)); - ReactCurrentOwner$2.current = null; - return next; -} -function completeUnitOfWork(unitOfWork) { - workInProgress = unitOfWork; - do { - var current$$1 = workInProgress.alternate; - unitOfWork = workInProgress.return; - if (0 === (workInProgress.effectTag & 2048)) { - 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; + } catch (yetAnotherThrownValue) { + thrownValue = yetAnotherThrownValue; + continue; + } + break; + } while (1); +} +function pushDispatcher() { + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; + return null === prevDispatcher ? ContextOnlyDispatcher : prevDispatcher; +} +function markRenderEventTimeAndConfig(expirationTime, suspenseConfig) { + expirationTime < workInProgressRootLatestProcessedExpirationTime && + 2 < expirationTime && + (workInProgressRootLatestProcessedExpirationTime = expirationTime); + null !== suspenseConfig && + expirationTime < workInProgressRootLatestSuspenseTimeout && + 2 < expirationTime && + ((workInProgressRootLatestSuspenseTimeout = expirationTime), + (workInProgressRootCanSuspendUsingConfig = suspenseConfig)); +} +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(); ) + workInProgress = performUnitOfWork(workInProgress); +} +function performUnitOfWork(unitOfWork) { + var next = beginWork$1( + unitOfWork.alternate, + unitOfWork, + renderExpirationTime$1 + ); + unitOfWork.memoizedProps = unitOfWork.pendingProps; + null === next && (next = completeUnitOfWork(unitOfWork)); + ReactCurrentOwner$2.current = null; + return next; +} +function completeUnitOfWork(unitOfWork) { + workInProgress = unitOfWork; + do { + var current = workInProgress.alternate; + unitOfWork = workInProgress.return; + if (0 === (workInProgress.effectTag & 2048)) { + current = completeWork(current, workInProgress, renderExpirationTime$1); + if ( + 1 === renderExpirationTime$1 || + 1 !== workInProgress.childExpirationTime + ) { for ( - rootContainerInstance = instance.child; - null !== rootContainerInstance; + var newChildExpirationTime = 0, _child = workInProgress.child; + null !== _child; - ) - (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; + ) { + var _childUpdateExpirationTime = _child.expirationTime, + _childChildExpirationTime = _child.childExpirationTime; + _childUpdateExpirationTime > newChildExpirationTime && + (newChildExpirationTime = _childUpdateExpirationTime); + _childChildExpirationTime > newChildExpirationTime && + (newChildExpirationTime = _childChildExpirationTime); + _child = _child.sibling; + } + workInProgress.childExpirationTime = newChildExpirationTime; } - if (null !== current$$1) return current$$1; + if (null !== current) return current; null !== unitOfWork && 0 === (unitOfWork.effectTag & 2048) && (null === unitOfWork.firstEffect && @@ -6212,15 +6064,14 @@ function completeUnitOfWork(unitOfWork) { : (unitOfWork.firstEffect = workInProgress), (unitOfWork.lastEffect = workInProgress))); } else { - current$$1 = unwindWork(workInProgress, renderExpirationTime); - if (null !== current$$1) - return (current$$1.effectTag &= 2047), current$$1; + current = unwindWork(workInProgress); + if (null !== current) return (current.effectTag &= 2047), current; null !== unitOfWork && ((unitOfWork.firstEffect = unitOfWork.lastEffect = null), (unitOfWork.effectTag |= 2048)); } - current$$1 = workInProgress.sibling; - if (null !== current$$1) return current$$1; + current = workInProgress.sibling; + if (null !== current) return current; workInProgress = unitOfWork; } while (null !== workInProgress); workInProgressRootExitStatus === RootIncomplete && @@ -6234,11 +6085,12 @@ function getRemainingExpirationTime(fiber) { } function commitRoot(root) { var renderPriorityLevel = getCurrentPriorityLevel(); - runWithPriority$1(99, commitRootImpl.bind(null, root, renderPriorityLevel)); + runWithPriority(99, commitRootImpl.bind(null, root, renderPriorityLevel)); return null; } function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { - flushPassiveEffects(); + do flushPassiveEffects(); + while (null !== rootWithPendingPassiveEffects); if ((executionContext & (RenderContext | CommitContext)) !== NoContext) throw Error("Should not already be working."); var finishedWork = root$jscomp$1.finishedWork, @@ -6267,7 +6119,8 @@ 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 = 0)); + ((workInProgress = workInProgressRoot = null), + (renderExpirationTime$1 = 0)); 1 < finishedWork.effectTag ? null !== finishedWork.lastEffect ? ((finishedWork.lastEffect.nextEffect = finishedWork), @@ -6299,9 +6152,9 @@ function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { ) { var effectTag = nextEffect.effectTag; if (effectTag & 128) { - var current$$1 = nextEffect.alternate; - if (null !== current$$1) { - var currentRef = current$$1.ref; + var current = nextEffect.alternate; + if (null !== current) { + var currentRef = current.ref; null !== currentRef && ("function" === typeof currentRef ? currentRef(null) @@ -6327,10 +6180,10 @@ function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { commitWork(nextEffect.alternate, nextEffect); break; case 8: - var current$$1$jscomp$0 = nextEffect; + var current$jscomp$0 = nextEffect; a: for ( var finishedRoot = root, - root$jscomp$0 = current$$1$jscomp$0, + root$jscomp$0 = current$jscomp$0, renderPriorityLevel$jscomp$0 = renderPriorityLevel, node = root$jscomp$0; ; @@ -6355,7 +6208,7 @@ function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { node.sibling.return = node.return; node = node.sibling; } - detachFiber(current$$1$jscomp$0); + detachFiber(current$jscomp$0); } nextEffect = nextEffect.nextEffect; } @@ -6369,101 +6222,25 @@ function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { nextEffect = remainingExpirationTimeBeforeCommit; do try { - for (effectTag = expirationTime; null !== nextEffect; ) { + for (effectTag = root$jscomp$1; null !== nextEffect; ) { var effectTag$jscomp$0 = nextEffect.effectTag; - 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." - ); - } - } + effectTag$jscomp$0 & 36 && + commitLifeCycles(effectTag, nextEffect.alternate, nextEffect); if (effectTag$jscomp$0 & 128) { - current$$1 = void 0; + current = void 0; var ref = nextEffect.ref; if (null !== ref) { - var instance$jscomp$0 = nextEffect.stateNode; + var instance = nextEffect.stateNode; switch (nextEffect.tag) { case 5: - current$$1 = instance$jscomp$0.canonical; + current = instance.canonical; break; default: - current$$1 = instance$jscomp$0; + current = instance; } "function" === typeof ref - ? ref(current$$1) - : (ref.current = current$$1); + ? ref(current) + : (ref.current = current); } } nextEffect = nextEffect.nextEffect; @@ -6533,7 +6310,7 @@ function flushPassiveEffects() { ? 97 : pendingPassiveEffectsRenderPriority; pendingPassiveEffectsRenderPriority = 90; - return runWithPriority$1(priorityLevel, flushPassiveEffectsImpl); + return runWithPriority(priorityLevel, flushPassiveEffectsImpl); } } function flushPassiveEffectsImpl() { @@ -6552,8 +6329,9 @@ function flushPassiveEffectsImpl() { case 0: case 11: case 15: - commitHookEffectList(128, 0, finishedWork), - commitHookEffectList(0, 64, finishedWork); + case 22: + commitHookEffectListUnmount(5, finishedWork), + commitHookEffectListMount(5, finishedWork); } } catch (error) { if (null === root) throw Error("Should be working on an effect."); @@ -6604,20 +6382,17 @@ function captureCommitPhaseError(sourceFiber, error) { function pingSuspendedRoot(root, thenable, suspendedTime) { var pingCache = root.pingCache; null !== pingCache && pingCache.delete(thenable); - workInProgressRoot === root && renderExpirationTime === suspendedTime + workInProgressRoot === root && renderExpirationTime$1 === suspendedTime ? workInProgressRootExitStatus === RootSuspendedWithDelay || (workInProgressRootExitStatus === RootSuspended && 1073741823 === workInProgressRootLatestProcessedExpirationTime && now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) - ? prepareFreshStack(root, renderExpirationTime) + ? prepareFreshStack(root, renderExpirationTime$1) : (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))); + ((root.lastPingedTime = suspendedTime), ensureRootIsScheduled(root))); } function resolveRetryThenable(boundaryFiber, thenable) { var retryCache = boundaryFiber.stateNode; @@ -6629,12 +6404,12 @@ function resolveRetryThenable(boundaryFiber, thenable) { boundaryFiber = markUpdateTimeFromFiberToRoot(boundaryFiber, thenable); null !== boundaryFiber && ensureRootIsScheduled(boundaryFiber); } -var beginWork$$1; -beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { +var beginWork$1; +beginWork$1 = function(current, workInProgress, renderExpirationTime) { var updateExpirationTime = workInProgress.expirationTime; - if (null !== current$$1) + if (null !== current) if ( - current$$1.memoizedProps !== workInProgress.pendingProps || + current.memoizedProps !== workInProgress.pendingProps || didPerformWorkStackCursor.current ) didReceiveUpdate = !0; @@ -6659,7 +6434,10 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { ); break; case 10: - pushProvider(workInProgress, workInProgress.memoizedProps.value); + updateExpirationTime = workInProgress.memoizedProps.value; + var context = workInProgress.type._context; + push(valueCursor, context._currentValue2); + context._currentValue2 = updateExpirationTime; break; case 13: if (null !== workInProgress.memoizedState) { @@ -6669,52 +6447,40 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { updateExpirationTime >= renderExpirationTime ) return updateSuspenseComponent( - current$$1, + current, workInProgress, renderExpirationTime ); - push( - suspenseStackCursor, - suspenseStackCursor.current & 1, - workInProgress - ); + push(suspenseStackCursor, suspenseStackCursor.current & 1); workInProgress = bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ); return null !== workInProgress ? workInProgress.sibling : null; } - push( - suspenseStackCursor, - suspenseStackCursor.current & 1, - workInProgress - ); + push(suspenseStackCursor, suspenseStackCursor.current & 1); break; case 19: updateExpirationTime = workInProgress.childExpirationTime >= renderExpirationTime; - if (0 !== (current$$1.effectTag & 64)) { + if (0 !== (current.effectTag & 64)) { if (updateExpirationTime) return updateSuspenseListComponent( - current$$1, + current, workInProgress, renderExpirationTime ); workInProgress.effectTag |= 64; } - var renderState = workInProgress.memoizedState; - null !== renderState && - ((renderState.rendering = null), (renderState.tail = null)); - push( - suspenseStackCursor, - suspenseStackCursor.current, - workInProgress - ); + context = workInProgress.memoizedState; + null !== context && + ((context.rendering = null), (context.tail = null)); + push(suspenseStackCursor, suspenseStackCursor.current); if (!updateExpirationTime) return null; } return bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ); @@ -6726,41 +6492,40 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { switch (workInProgress.tag) { case 2: updateExpirationTime = workInProgress.type; - null !== current$$1 && - ((current$$1.alternate = null), + null !== current && + ((current.alternate = null), (workInProgress.alternate = null), (workInProgress.effectTag |= 2)); - current$$1 = workInProgress.pendingProps; - renderState = getMaskedContext( - workInProgress, - contextStackCursor.current - ); + current = workInProgress.pendingProps; + context = getMaskedContext(workInProgress, contextStackCursor.current); prepareToReadContext(workInProgress, renderExpirationTime); - renderState = renderWithHooks( + context = renderWithHooks( null, workInProgress, updateExpirationTime, - current$$1, - renderState, + current, + context, renderExpirationTime ); workInProgress.effectTag |= 1; if ( - "object" === typeof renderState && - null !== renderState && - "function" === typeof renderState.render && - void 0 === renderState.$$typeof + "object" === typeof context && + null !== context && + "function" === typeof context.render && + void 0 === context.$$typeof ) { workInProgress.tag = 1; - resetHooks(); + workInProgress.memoizedState = null; + workInProgress.updateQueue = null; if (isContextProvider(updateExpirationTime)) { var hasContext = !0; pushContextProvider(workInProgress); } else hasContext = !1; workInProgress.memoizedState = - null !== renderState.state && void 0 !== renderState.state - ? renderState.state + null !== context.state && void 0 !== context.state + ? context.state : null; + initializeUpdateQueue(workInProgress); var getDerivedStateFromProps = updateExpirationTime.getDerivedStateFromProps; "function" === typeof getDerivedStateFromProps && @@ -6768,15 +6533,15 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { workInProgress, updateExpirationTime, getDerivedStateFromProps, - current$$1 + current ); - renderState.updater = classComponentUpdater; - workInProgress.stateNode = renderState; - renderState._reactInternalFiber = workInProgress; + context.updater = classComponentUpdater; + workInProgress.stateNode = context; + context._reactInternalFiber = workInProgress; mountClassInstance( workInProgress, updateExpirationTime, - current$$1, + current, renderExpirationTime ); workInProgress = finishClassComponent( @@ -6792,127 +6557,129 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { reconcileChildren( null, workInProgress, - renderState, + context, renderExpirationTime ), (workInProgress = workInProgress.child); return workInProgress; case 16: - 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." - ); + 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." + ); } return workInProgress; case 0: return ( (updateExpirationTime = workInProgress.type), - (renderState = workInProgress.pendingProps), - (renderState = + (context = workInProgress.pendingProps), + (context = workInProgress.elementType === updateExpirationTime - ? renderState - : resolveDefaultProps(updateExpirationTime, renderState)), + ? context + : resolveDefaultProps(updateExpirationTime, context)), updateFunctionComponent( - current$$1, + current, workInProgress, updateExpirationTime, - renderState, + context, renderExpirationTime ) ); case 1: return ( (updateExpirationTime = workInProgress.type), - (renderState = workInProgress.pendingProps), - (renderState = + (context = workInProgress.pendingProps), + (context = workInProgress.elementType === updateExpirationTime - ? renderState - : resolveDefaultProps(updateExpirationTime, renderState)), + ? context + : resolveDefaultProps(updateExpirationTime, context)), updateClassComponent( - current$$1, + current, workInProgress, updateExpirationTime, - renderState, + context, renderExpirationTime ) ); case 3: pushHostRootContext(workInProgress); updateExpirationTime = workInProgress.updateQueue; - if (null === updateExpirationTime) + if (null === current || 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." ); - renderState = workInProgress.memoizedState; - renderState = null !== renderState ? renderState.element : null; + updateExpirationTime = workInProgress.pendingProps; + context = workInProgress.memoizedState; + context = null !== context ? context.element : null; + cloneUpdateQueue(current, workInProgress); processUpdateQueue( workInProgress, updateExpirationTime, - workInProgress.pendingProps, null, renderExpirationTime ); updateExpirationTime = workInProgress.memoizedState.element; - updateExpirationTime === renderState + updateExpirationTime === context ? (workInProgress = bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime )) : (reconcileChildren( - current$$1, + current, workInProgress, updateExpirationTime, renderExpirationTime @@ -6922,11 +6689,10 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { case 5: return ( pushHostContext(workInProgress), - null === current$$1 && tryToClaimNextHydratableInstance(workInProgress), (updateExpirationTime = workInProgress.pendingProps.children), - markRef(current$$1, workInProgress), + markRef(current, workInProgress), reconcileChildren( - current$$1, + current, workInProgress, updateExpirationTime, renderExpirationTime @@ -6935,13 +6701,10 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { workInProgress ); case 6: - return ( - null === current$$1 && tryToClaimNextHydratableInstance(workInProgress), - null - ); + return null; case 13: return updateSuspenseComponent( - current$$1, + current, workInProgress, renderExpirationTime ); @@ -6952,7 +6715,7 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { workInProgress.stateNode.containerInfo ), (updateExpirationTime = workInProgress.pendingProps), - null === current$$1 + null === current ? (workInProgress.child = reconcileChildFibers( workInProgress, null, @@ -6960,7 +6723,7 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { renderExpirationTime )) : reconcileChildren( - current$$1, + current, workInProgress, updateExpirationTime, renderExpirationTime @@ -6970,23 +6733,23 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { case 11: return ( (updateExpirationTime = workInProgress.type), - (renderState = workInProgress.pendingProps), - (renderState = + (context = workInProgress.pendingProps), + (context = workInProgress.elementType === updateExpirationTime - ? renderState - : resolveDefaultProps(updateExpirationTime, renderState)), + ? context + : resolveDefaultProps(updateExpirationTime, context)), updateForwardRef( - current$$1, + current, workInProgress, updateExpirationTime, - renderState, + context, renderExpirationTime ) ); case 7: return ( reconcileChildren( - current$$1, + current, workInProgress, workInProgress.pendingProps, renderExpirationTime @@ -6996,7 +6759,7 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { case 8: return ( reconcileChildren( - current$$1, + current, workInProgress, workInProgress.pendingProps.children, renderExpirationTime @@ -7006,7 +6769,7 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { case 12: return ( reconcileChildren( - current$$1, + current, workInProgress, workInProgress.pendingProps.children, renderExpirationTime @@ -7016,27 +6779,32 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { case 10: a: { updateExpirationTime = workInProgress.type._context; - renderState = workInProgress.pendingProps; + context = workInProgress.pendingProps; getDerivedStateFromProps = workInProgress.memoizedProps; - 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) { + 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) + ) { if ( - getDerivedStateFromProps.children === renderState.children && + getDerivedStateFromProps.children === context.children && !didPerformWorkStackCursor.current ) { workInProgress = bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ); @@ -7044,14 +6812,15 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { } } else for ( - oldValue = workInProgress.child, - null !== oldValue && (oldValue.return = workInProgress); - null !== oldValue; + context$jscomp$0 = workInProgress.child, + null !== context$jscomp$0 && + (context$jscomp$0.return = workInProgress); + null !== context$jscomp$0; ) { - var list = oldValue.dependencies; + var list = context$jscomp$0.dependencies; if (null !== list) { - getDerivedStateFromProps = oldValue.child; + getDerivedStateFromProps = context$jscomp$0.child; for ( var dependency = list.firstContext; null !== dependency; @@ -7061,18 +6830,18 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { dependency.context === updateExpirationTime && 0 !== (dependency.observedBits & hasContext) ) { - 1 === oldValue.tag && + 1 === context$jscomp$0.tag && ((dependency = createUpdate(renderExpirationTime, null)), (dependency.tag = 2), - enqueueUpdate(oldValue, dependency)); - oldValue.expirationTime < renderExpirationTime && - (oldValue.expirationTime = renderExpirationTime); - dependency = oldValue.alternate; + enqueueUpdate(context$jscomp$0, dependency)); + context$jscomp$0.expirationTime < renderExpirationTime && + (context$jscomp$0.expirationTime = renderExpirationTime); + dependency = context$jscomp$0.alternate; null !== dependency && dependency.expirationTime < renderExpirationTime && (dependency.expirationTime = renderExpirationTime); scheduleWorkOnParentPath( - oldValue.return, + context$jscomp$0.return, renderExpirationTime ); list.expirationTime < renderExpirationTime && @@ -7083,16 +6852,16 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { } } else getDerivedStateFromProps = - 10 === oldValue.tag - ? oldValue.type === workInProgress.type + 10 === context$jscomp$0.tag + ? context$jscomp$0.type === workInProgress.type ? null - : oldValue.child - : oldValue.child; + : context$jscomp$0.child + : context$jscomp$0.child; if (null !== getDerivedStateFromProps) - getDerivedStateFromProps.return = oldValue; + getDerivedStateFromProps.return = context$jscomp$0; else for ( - getDerivedStateFromProps = oldValue; + getDerivedStateFromProps = context$jscomp$0; null !== getDerivedStateFromProps; ) { @@ -7100,21 +6869,20 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { getDerivedStateFromProps = null; break; } - oldValue = getDerivedStateFromProps.sibling; - if (null !== oldValue) { - oldValue.return = getDerivedStateFromProps.return; - getDerivedStateFromProps = oldValue; + context$jscomp$0 = getDerivedStateFromProps.sibling; + if (null !== context$jscomp$0) { + context$jscomp$0.return = getDerivedStateFromProps.return; + getDerivedStateFromProps = context$jscomp$0; break; } getDerivedStateFromProps = getDerivedStateFromProps.return; } - oldValue = getDerivedStateFromProps; + context$jscomp$0 = getDerivedStateFromProps; } - } reconcileChildren( - current$$1, + current, workInProgress, - renderState.children, + context.children, renderExpirationTime ); workInProgress = workInProgress.child; @@ -7122,18 +6890,15 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { return workInProgress; case 9: return ( - (renderState = workInProgress.type), + (context = workInProgress.type), (hasContext = workInProgress.pendingProps), (updateExpirationTime = hasContext.children), prepareToReadContext(workInProgress, renderExpirationTime), - (renderState = readContext( - renderState, - hasContext.unstable_observedBits - )), - (updateExpirationTime = updateExpirationTime(renderState)), + (context = readContext(context, hasContext.unstable_observedBits)), + (updateExpirationTime = updateExpirationTime(context)), (workInProgress.effectTag |= 1), reconcileChildren( - current$$1, + current, workInProgress, updateExpirationTime, renderExpirationTime @@ -7142,16 +6907,16 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { ); case 14: return ( - (renderState = workInProgress.type), + (context = workInProgress.type), (hasContext = resolveDefaultProps( - renderState, + context, workInProgress.pendingProps )), - (hasContext = resolveDefaultProps(renderState.type, hasContext)), + (hasContext = resolveDefaultProps(context.type, hasContext)), updateMemoComponent( - current$$1, + current, workInProgress, - renderState, + context, hasContext, updateExpirationTime, renderExpirationTime @@ -7159,7 +6924,7 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { ); case 15: return updateSimpleMemoComponent( - current$$1, + current, workInProgress, workInProgress.type, workInProgress.pendingProps, @@ -7169,30 +6934,25 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { case 17: return ( (updateExpirationTime = workInProgress.type), - (renderState = workInProgress.pendingProps), - (renderState = + (context = workInProgress.pendingProps), + (context = workInProgress.elementType === updateExpirationTime - ? renderState - : resolveDefaultProps(updateExpirationTime, renderState)), - null !== current$$1 && - ((current$$1.alternate = null), + ? context + : resolveDefaultProps(updateExpirationTime, context)), + null !== current && + ((current.alternate = null), (workInProgress.alternate = null), (workInProgress.effectTag |= 2)), (workInProgress.tag = 1), isContextProvider(updateExpirationTime) - ? ((current$$1 = !0), pushContextProvider(workInProgress)) - : (current$$1 = !1), + ? ((current = !0), pushContextProvider(workInProgress)) + : (current = !1), prepareToReadContext(workInProgress, renderExpirationTime), - constructClassInstance( - workInProgress, - updateExpirationTime, - renderState, - renderExpirationTime - ), + constructClassInstance(workInProgress, updateExpirationTime, context), mountClassInstance( workInProgress, updateExpirationTime, - renderState, + context, renderExpirationTime ), finishClassComponent( @@ -7200,13 +6960,13 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { workInProgress, updateExpirationTime, !0, - current$$1, + current, renderExpirationTime ) ); case 19: return updateSuspenseListComponent( - current$$1, + current, workInProgress, renderExpirationTime ); @@ -7257,9 +7017,6 @@ 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); @@ -7277,7 +7034,7 @@ function resolveLazyComponentTag(Component) { function createWorkInProgress(current, pendingProps) { var workInProgress = current.alternate; null === workInProgress - ? ((workInProgress = createFiber( + ? ((workInProgress = new FiberNode( current.tag, pendingProps, current.key, @@ -7293,6 +7050,10 @@ 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; @@ -7344,7 +7105,7 @@ function createFiberFromTypeAndProps( break; case REACT_PROFILER_TYPE: return ( - (type = createFiber(12, pendingProps, key, mode | 8)), + (type = new FiberNode(12, pendingProps, key, mode | 8)), (type.elementType = REACT_PROFILER_TYPE), (type.type = REACT_PROFILER_TYPE), (type.expirationTime = expirationTime), @@ -7352,7 +7113,7 @@ function createFiberFromTypeAndProps( ); case REACT_SUSPENSE_TYPE: return ( - (type = createFiber(13, pendingProps, key, mode)), + (type = new FiberNode(13, pendingProps, key, mode)), (type.type = REACT_SUSPENSE_TYPE), (type.elementType = REACT_SUSPENSE_TYPE), (type.expirationTime = expirationTime), @@ -7360,7 +7121,7 @@ function createFiberFromTypeAndProps( ); case REACT_SUSPENSE_LIST_TYPE: return ( - (type = createFiber(19, pendingProps, key, mode)), + (type = new FiberNode(19, pendingProps, key, mode)), (type.elementType = REACT_SUSPENSE_LIST_TYPE), (type.expirationTime = expirationTime), type @@ -7384,6 +7145,9 @@ 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: " + @@ -7391,24 +7155,24 @@ function createFiberFromTypeAndProps( "." ); } - key = createFiber(fiberTag, pendingProps, key, mode); + key = new FiberNode(fiberTag, pendingProps, key, mode); key.elementType = type; key.type = owner; key.expirationTime = expirationTime; return key; } function createFiberFromFragment(elements, mode, expirationTime, key) { - elements = createFiber(7, elements, key, mode); + elements = new FiberNode(7, elements, key, mode); elements.expirationTime = expirationTime; return elements; } function createFiberFromText(content, mode, expirationTime) { - content = createFiber(6, content, null, mode); + content = new FiberNode(6, content, null, mode); content.expirationTime = expirationTime; return content; } function createFiberFromPortal(portal, mode, expirationTime) { - mode = createFiber( + mode = new FiberNode( 4, null !== portal.children ? portal.children : [], portal.key, @@ -7467,11 +7231,6 @@ 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) { @@ -7486,14 +7245,10 @@ function findHostInstance(component) { return null === component ? null : component.stateNode; } function updateContainer(element, container, parentComponent, callback) { - var current$$1 = container.current, + var current = container.current, currentTime = requestCurrentTimeForUpdate(), suspenseConfig = ReactCurrentBatchConfig.suspense; - currentTime = computeExpirationForFiber( - currentTime, - current$$1, - suspenseConfig - ); + currentTime = computeExpirationForFiber(currentTime, current, suspenseConfig); a: if (parentComponent) { parentComponent = parentComponent._reactInternalFiber; b: { @@ -7544,8 +7299,8 @@ function updateContainer(element, container, parentComponent, callback) { container.payload = { element: element }; callback = void 0 === callback ? null : callback; null !== callback && (container.callback = callback); - enqueueUpdate(current$$1, container); - scheduleUpdateOnFiber(current$$1, currentTime); + enqueueUpdate(current, container); + scheduleWork(current, currentTime); return currentTime; } function createPortal(children, containerInfo, implementation) { @@ -7559,7 +7314,6 @@ 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; @@ -7570,8 +7324,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; @@ -7583,289 +7337,114 @@ batchedUpdatesImpl = function(fn, a) { executionContext === NoContext && flushSyncCallbackQueue(); } }; -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; - }, - findNodeHandle: findNodeHandle, - dispatchCommand: function(handle, command, args) { - null != handle._nativeTag && - null != handle._internalInstanceHandle && - fabricDispatchCommand( - handle._internalInstanceHandle.stateNode.node, - 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.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) - } - }; +var roots = new Map(); (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 - }) - ); + 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; + }, + 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.11.0", - rendererPackageName: "react-native-renderer" + 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) + } }); -var ReactFabric$2 = { default: ReactFabric }, - ReactFabric$3 = (ReactFabric$2 && ReactFabric) || ReactFabric$2; -module.exports = ReactFabric$3.default || ReactFabric$3; +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); +}; diff --git a/Libraries/Renderer/implementations/ReactFabric-prod.js b/Libraries/Renderer/implementations/ReactFabric-prod.js index 21270fe18669b9..7df0e13f1f7fe1 100644 --- a/Libraries/Renderer/implementations/ReactFabric-prod.js +++ b/Libraries/Renderer/implementations/ReactFabric-prod.js @@ -5,6 +5,7 @@ * LICENSE file in the root directory of this source tree. * * @noflow + * @nolint * @providesModule ReactFabric-prod * @preventMunge * @generated @@ -15,85 +16,16 @@ require("react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore"); var ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/ReactNativePrivateInterface"), React = require("react"), Scheduler = require("scheduler"); -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 getParent(inst) { + do inst = inst.return; + while (inst && 5 !== inst.tag); + return inst ? inst : null; } -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; +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); } -var plugins = [], - eventNameDispatchConfigs = {}, - registrationNameModules = {}; function invokeGuardedCallbackImpl(name, func, context, a, b, c, d, e, f) { var funcArgs = Array.prototype.slice.call(arguments, 3); try { @@ -164,74 +96,6 @@ 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; @@ -249,6 +113,7 @@ function getListener(inst, registrationName) { case "onMouseMoveCapture": case "onMouseUp": case "onMouseUpCapture": + case "onMouseEnter": (props = !props.disabled) || ((inst = inst.type), (props = !( @@ -273,15 +138,21 @@ function getListener(inst, registrationName) { ); return listener; } -function getParent(inst) { - do inst = inst.return; - while (inst && 5 !== inst.tag); - return inst ? inst : null; +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 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 forEachAccumulated(arr, cb, scope) { + Array.isArray(arr) ? arr.forEach(cb, scope) : arr && cb.call(scope, arr); } function accumulateDirectionalDispatches(inst, phase, event) { if ( @@ -349,8 +220,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) @@ -503,53 +374,27 @@ 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))) - : console.warn( - "Cannot record touch move without a touch start.\nTouch Move: %s\n", - "Touch Bank: %s", - printTouch(touch), - printTouchBank() - ); + 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))); } 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))) - : 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; + 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))); } var ResponderTouchHistoryStore = { recordTouchTrack: function(topLevelType, nativeEvent) { @@ -589,10 +434,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; @@ -682,13 +527,7 @@ var eventTypes = { "topTouchCancel" === topLevelType ) if (0 <= trackedTouchCount) --trackedTouchCount; - else - return ( - console.warn( - "Ended a touch event which was not counted in `trackedTouchCount`." - ), - null - ); + else return null; ResponderTouchHistoryStore.recordTouchTrack(topLevelType, nativeEvent); if ( targetInst && @@ -700,10 +539,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; @@ -857,10 +696,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, @@ -923,8 +762,8 @@ var eventTypes = { (topLevelType = shouldSetEventType ? eventTypes.responderTerminate : topLevelType - ? eventTypes.responderRelease - : null) + ? eventTypes.responderRelease + : null) ) (nativeEvent = ResponderSyntheticEvent.getPooled( topLevelType, @@ -948,48 +787,160 @@ 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; -injection.injectEventPluginOrder([ +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([ "ResponderEventPlugin", "ReactNativeBridgeEventPlugin" ]); -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, +recomputePluginOrdering(); +var injectedNamesToPlugins$jscomp$inline_92 = { + ResponderEventPlugin: ResponderEventPlugin, + ReactNativeBridgeEventPlugin: { + eventTypes: {}, + extractEvents: function( + topLevelType, targetInst, nativeEvent, nativeEventTarget - ); - if (bubbleDispatchConfig) - forEachAccumulated(topLevelType, accumulateTwoPhaseDispatchesSingle); - else if (directDispatchConfig) - forEachAccumulated(topLevelType, accumulateDirectDispatchesSingle); - else return null; - return topLevelType; + ) { + 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; } } -}); +isOrderingDirty$jscomp$inline_93 && recomputePluginOrdering(); function getInstanceFromInstance(instanceHandle) { return instanceHandle; } @@ -998,8 +949,8 @@ getFiberCurrentPropsFromNode = function(inst) { }; getInstanceFromNode = getInstanceFromInstance; getNodeFromInstance = function(inst) { - inst = inst.stateNode.canonical._nativeTag; - if (!inst) throw Error("All native instances should have a tag."); + inst = inst.stateNode.canonical; + if (!inst._nativeTag) throw Error("All native instances should have a tag."); return inst; }; ResponderEventPlugin.injection.injectGlobalResponderHandler({ @@ -1035,11 +986,9 @@ 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; -hasSymbol && Symbol.for("react.fundamental"); -hasSymbol && Symbol.for("react.responder"); -hasSymbol && Symbol.for("react.scope"); -var MAYBE_ITERATOR_SYMBOL = "function" === typeof Symbol && Symbol.iterator; + 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; function getIteratorFn(maybeIterable) { if (null === maybeIterable || "object" !== typeof maybeIterable) return null; maybeIterable = @@ -1049,9 +998,10 @@ function getIteratorFn(maybeIterable) { } function initializeLazyComponentType(lazyComponent) { if (-1 === lazyComponent._status) { - lazyComponent._status = 0; - var ctor = lazyComponent._ctor; + var ctor = lazyComponent._result; + ctor || (ctor = lazyComponent._ctor); ctor = ctor(); + lazyComponent._status = 0; lazyComponent._result = ctor; ctor.then( function(moduleObject) { @@ -1088,9 +1038,9 @@ function getComponentName(type) { if ("object" === typeof type) switch (type.$$typeof) { case REACT_CONTEXT_TYPE: - return "Context.Consumer"; + return (type.displayName || "Context") + ".Consumer"; case REACT_PROVIDER_TYPE: - return "Context.Provider"; + return (type._context.displayName || "Context") + ".Provider"; case REACT_FORWARD_REF_TYPE: var innerType = type.render; innerType = innerType.displayName || innerType.name || ""; @@ -1100,6 +1050,8 @@ 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); @@ -1289,8 +1241,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)) { @@ -1451,18 +1403,9 @@ 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); @@ -1470,46 +1413,35 @@ function batchedUpdates(fn, bookkeeping) { 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)) - ) - for (bookkeeping = 0; bookkeeping < fn.length; bookkeeping++) - restoreStateOfTarget(fn[bookkeeping]); + isInsideEventHandler = !1; } } -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; +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); } - _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; - eventTarget = nativeEvent.target; + if (null != target) { + var stateNode = target.stateNode; + null != stateNode && (eventTarget = stateNode.canonical); + } batchedUpdates(function() { var events = eventTarget; for (var events$jscomp$0 = null, i = 0; i < plugins.length; i++) { @@ -1547,21 +1479,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$1 = nativeFabricUIManager, - createNode = _nativeFabricUIManage$1.createNode, - cloneNode = _nativeFabricUIManage$1.cloneNode, - cloneNodeWithNewChildren = _nativeFabricUIManage$1.cloneNodeWithNewChildren, +var _nativeFabricUIManage = nativeFabricUIManager, + createNode = _nativeFabricUIManage.createNode, + cloneNode = _nativeFabricUIManage.cloneNode, + cloneNodeWithNewChildren = _nativeFabricUIManage.cloneNodeWithNewChildren, cloneNodeWithNewChildrenAndProps = - _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, + _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, getViewConfigForType = ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get, nextReactTag = 2; @@ -1580,10 +1512,10 @@ var ReactFabricHostComponent = (function() { } var _proto = ReactFabricHostComponent.prototype; _proto.blur = function() { - ReactNativePrivateInterface.TextInputState.blurTextInput(this._nativeTag); + ReactNativePrivateInterface.TextInputState.blurTextInput(this); }; _proto.focus = function() { - ReactNativePrivateInterface.TextInputState.focusTextInput(this._nativeTag); + ReactNativePrivateInterface.TextInputState.focusTextInput(this); }; _proto.measure = function(callback) { fabricMeasure( @@ -1645,44 +1577,6 @@ 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) { @@ -1720,21 +1614,17 @@ function isContextProvider(type) { type = type.childContextTypes; return null !== type && void 0 !== type; } -function popContext(fiber) { - pop(didPerformWorkStackCursor, fiber); - pop(contextStackCursor, fiber); -} -function popTopLevelContextObject(fiber) { - pop(didPerformWorkStackCursor, fiber); - pop(contextStackCursor, fiber); +function popContext() { + pop(didPerformWorkStackCursor); + pop(contextStackCursor); } function pushTopLevelContextObject(fiber, context, didChange) { if (contextStackCursor.current !== emptyContextObject) throw Error( "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." ); - push(contextStackCursor, context, fiber); - push(didPerformWorkStackCursor, didChange, fiber); + push(contextStackCursor, context); + push(didPerformWorkStackCursor, didChange); } function processChildContext(fiber, type, parentContext) { var instance = fiber.stateNode; @@ -1752,17 +1642,13 @@ function processChildContext(fiber, type, parentContext) { return Object.assign({}, parentContext, {}, instance); } function pushContextProvider(workInProgress) { - var instance = workInProgress.stateNode; - instance = - (instance && instance.__reactInternalMemoizedMergedChildContext) || + workInProgress = + ((workInProgress = workInProgress.stateNode) && + workInProgress.__reactInternalMemoizedMergedChildContext) || emptyContextObject; previousContext = contextStackCursor.current; - push(contextStackCursor, instance, workInProgress); - push( - didPerformWorkStackCursor, - didPerformWorkStackCursor.current, - workInProgress - ); + push(contextStackCursor, workInProgress); + push(didPerformWorkStackCursor, didPerformWorkStackCursor.current); return !0; } function invalidateContextProvider(workInProgress, type, didChange) { @@ -1772,18 +1658,21 @@ 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 - ? ((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); + ? ((workInProgress = processChildContext( + workInProgress, + type, + previousContext + )), + (instance.__reactInternalMemoizedMergedChildContext = workInProgress), + pop(didPerformWorkStackCursor), + pop(contextStackCursor), + push(contextStackCursor, workInProgress)) + : pop(didPerformWorkStackCursor); + push(didPerformWorkStackCursor, didChange); } 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 = @@ -1794,6 +1683,7 @@ 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, @@ -1838,7 +1728,7 @@ function reactPriorityToSchedulerPriority(reactPriorityLevel) { throw Error("Unknown priority level."); } } -function runWithPriority$1(reactPriorityLevel, fn) { +function runWithPriority(reactPriorityLevel, fn) { reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); return Scheduler_runWithPriority(reactPriorityLevel, fn); } @@ -1870,7 +1760,7 @@ function flushSyncCallbackQueueImpl() { var i = 0; try { var queue = syncQueue; - runWithPriority$1(99, function() { + runWithPriority(99, function() { for (; i < queue.length; i++) { var callback = queue[i]; do callback = callback(!0); @@ -1893,10 +1783,10 @@ function flushSyncCallbackQueueImpl() { function is(x, y) { return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y); } -var is$1 = "function" === typeof Object.is ? Object.is : is, +var objectIs = "function" === typeof Object.is ? Object.is : is, hasOwnProperty = Object.prototype.hasOwnProperty; function shallowEqual(objA, objB) { - if (is$1(objA, objB)) return !0; + if (objectIs(objA, objB)) return !0; if ( "object" !== typeof objA || null === objA || @@ -1910,11 +1800,48 @@ function shallowEqual(objA, objB) { for (keysB = 0; keysB < keysA.length; keysB++) if ( !hasOwnProperty.call(objB, keysA[keysB]) || - !is$1(objA[keysA[keysB]], objB[keysA[keysB]]) + !objectIs(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); @@ -1932,14 +1859,9 @@ 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, providerFiber); + pop(valueCursor); providerFiber.type._context._currentValue2 = currentValue; } function scheduleWorkOnParentPath(parent, renderExpirationTime) { @@ -1994,237 +1916,195 @@ function readContext(context, observedBits) { return context._currentValue2; } var hasForceUpdate = !1; -function createUpdateQueue(baseState) { - return { - baseState: baseState, - firstUpdate: null, - lastUpdate: null, - firstCapturedUpdate: null, - lastCapturedUpdate: null, - firstEffect: null, - lastEffect: null, - firstCapturedEffect: null, - lastCapturedEffect: null +function initializeUpdateQueue(fiber) { + fiber.updateQueue = { + baseState: fiber.memoizedState, + baseQueue: null, + shared: { pending: null }, + effects: null }; } -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 cloneUpdateQueue(current, workInProgress) { + current = current.updateQueue; + workInProgress.updateQueue === current && + (workInProgress.updateQueue = { + baseState: current.baseState, + baseQueue: current.baseQueue, + shared: current.shared, + effects: current.effects + }); } function createUpdate(expirationTime, suspenseConfig) { - return { + expirationTime = { expirationTime: expirationTime, suspenseConfig: suspenseConfig, tag: 0, payload: null, callback: null, - next: null, - nextEffect: null + next: null }; -} -function appendUpdateToQueue(queue, update) { - null === queue.lastUpdate - ? (queue.firstUpdate = queue.lastUpdate = update) - : ((queue.lastUpdate.next = update), (queue.lastUpdate = update)); + return (expirationTime.next = expirationTime); } function enqueueUpdate(fiber, 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)); + 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; + } } 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 && - 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; + 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)); } function processUpdateQueue( - workInProgress, - queue, + workInProgress$jscomp$0, props, instance, renderExpirationTime ) { + var queue = workInProgress$jscomp$0.updateQueue; hasForceUpdate = !1; - queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue); - for ( - var newBaseState = queue.baseState, - newFirstUpdate = null, - newExpirationTime = 0, - 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; + 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)); } - 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; + if (null !== baseQueue) { + baseFirst = baseQueue.next; + var newState = queue.baseState, + 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; } - 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) { - 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); + 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); + } } - effect = effect.nextEffect; - } } var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig, emptyRefsObject = new React.Component().refs; @@ -2241,10 +2121,8 @@ function applyDerivedStateFromProps( ? ctor : Object.assign({}, ctor, getDerivedStateFromProps); workInProgress.memoizedState = getDerivedStateFromProps; - nextProps = workInProgress.updateQueue; - null !== nextProps && - 0 === workInProgress.expirationTime && - (nextProps.baseState = getDerivedStateFromProps); + 0 === workInProgress.expirationTime && + (workInProgress.updateQueue.baseState = getDerivedStateFromProps); } var classComponentUpdater = { isMounted: function(component) { @@ -2263,7 +2141,7 @@ var classComponentUpdater = { null !== callback && (suspenseConfig.callback = callback); enqueueUpdate(inst, suspenseConfig); - scheduleUpdateOnFiber(inst, currentTime); + scheduleWork(inst, currentTime); }, enqueueReplaceState: function(inst, payload, callback) { inst = inst._reactInternalFiber; @@ -2277,7 +2155,7 @@ var classComponentUpdater = { null !== callback && (suspenseConfig.callback = callback); enqueueUpdate(inst, suspenseConfig); - scheduleUpdateOnFiber(inst, currentTime); + scheduleWork(inst, currentTime); }, enqueueForceUpdate: function(inst, callback) { inst = inst._reactInternalFiber; @@ -2290,7 +2168,7 @@ var classComponentUpdater = { null !== callback && (suspenseConfig.callback = callback); enqueueUpdate(inst, suspenseConfig); - scheduleUpdateOnFiber(inst, currentTime); + scheduleWork(inst, currentTime); } }; function checkShouldComponentUpdate( @@ -2306,8 +2184,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, @@ -2359,6 +2237,7 @@ 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)) @@ -2366,16 +2245,8 @@ function mountClassInstance( ? previousContext : contextStackCursor.current), (instance.context = getMaskedContext(workInProgress, contextType))); - contextType = workInProgress.updateQueue; - null !== contextType && - (processUpdateQueue( - workInProgress, - contextType, - newProps, - instance, - renderExpirationTime - ), - (instance.state = workInProgress.memoizedState)); + processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); + instance.state = workInProgress.memoizedState; contextType = ctor.getDerivedStateFromProps; "function" === typeof contextType && (applyDerivedStateFromProps(workInProgress, ctor, contextType, newProps), @@ -2391,21 +2262,18 @@ function mountClassInstance( instance.UNSAFE_componentWillMount(), ctor !== instance.state && classComponentUpdater.enqueueReplaceState(instance, instance.state, null), - (contextType = workInProgress.updateQueue), - null !== contextType && - (processUpdateQueue( - workInProgress, - contextType, - newProps, - instance, - renderExpirationTime - ), - (instance.state = workInProgress.memoizedState))); + processUpdateQueue( + workInProgress, + newProps, + instance, + renderExpirationTime + ), + (instance.state = workInProgress.memoizedState)); "function" === typeof instance.componentDidMount && (workInProgress.effectTag |= 4); } var isArray = Array.isArray; -function coerceRef(returnFiber, current$$1, element) { +function coerceRef(returnFiber, current, element) { returnFiber = element.ref; if ( null !== returnFiber && @@ -2417,7 +2285,7 @@ function coerceRef(returnFiber, current$$1, element) { if (element) { if (1 !== element.tag) throw Error( - "Function components cannot have refs. Did you mean to use React.forwardRef()?" + "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" ); var inst = element.stateNode; } @@ -2429,19 +2297,19 @@ function coerceRef(returnFiber, current$$1, element) { ); var stringRef = "" + returnFiber; if ( - null !== current$$1 && - null !== current$$1.ref && - "function" === typeof current$$1.ref && - current$$1.ref._stringRef === stringRef + null !== current && + null !== current.ref && + "function" === typeof current.ref && + current.ref._stringRef === stringRef ) - return current$$1.ref; - current$$1 = function(value) { + return current.ref; + current = function(value) { var refs = inst.refs; refs === emptyRefsObject && (refs = inst.refs = {}); null === value ? delete refs[stringRef] : (refs[stringRef] = value); }; - current$$1._stringRef = stringRef; - return current$$1; + current._stringRef = stringRef; + return current; } if ("string" !== typeof returnFiber) throw Error( @@ -2493,8 +2361,8 @@ function ChildReconciler(shouldTrackSideEffects) { (currentFirstChild = currentFirstChild.sibling); return returnFiber; } - function useFiber(fiber, pendingProps, expirationTime) { - fiber = createWorkInProgress(fiber, pendingProps, expirationTime); + function useFiber(fiber, pendingProps) { + fiber = createWorkInProgress(fiber, pendingProps); fiber.index = 0; fiber.sibling = null; return fiber; @@ -2519,31 +2387,26 @@ function ChildReconciler(shouldTrackSideEffects) { (newFiber.effectTag = 2); return newFiber; } - function updateTextNode( - returnFiber, - current$$1, - textContent, - expirationTime - ) { - if (null === current$$1 || 6 !== current$$1.tag) + function updateTextNode(returnFiber, current, textContent, expirationTime) { + if (null === current || 6 !== current.tag) return ( - (current$$1 = createFiberFromText( + (current = createFiberFromText( textContent, returnFiber.mode, expirationTime )), - (current$$1.return = returnFiber), - current$$1 + (current.return = returnFiber), + current ); - current$$1 = useFiber(current$$1, textContent, expirationTime); - current$$1.return = returnFiber; - return current$$1; + current = useFiber(current, textContent); + current.return = returnFiber; + return current; } - function updateElement(returnFiber, current$$1, element, expirationTime) { - if (null !== current$$1 && current$$1.elementType === element.type) + function updateElement(returnFiber, current, element, expirationTime) { + if (null !== current && current.elementType === element.type) return ( - (expirationTime = useFiber(current$$1, element.props, expirationTime)), - (expirationTime.ref = coerceRef(returnFiber, current$$1, element)), + (expirationTime = useFiber(current, element.props)), + (expirationTime.ref = coerceRef(returnFiber, current, element)), (expirationTime.return = returnFiber), expirationTime ); @@ -2555,51 +2418,45 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime ); - expirationTime.ref = coerceRef(returnFiber, current$$1, element); + expirationTime.ref = coerceRef(returnFiber, current, element); expirationTime.return = returnFiber; return expirationTime; } - function updatePortal(returnFiber, current$$1, portal, expirationTime) { + function updatePortal(returnFiber, current, portal, expirationTime) { if ( - null === current$$1 || - 4 !== current$$1.tag || - current$$1.stateNode.containerInfo !== portal.containerInfo || - current$$1.stateNode.implementation !== portal.implementation + null === current || + 4 !== current.tag || + current.stateNode.containerInfo !== portal.containerInfo || + current.stateNode.implementation !== portal.implementation ) return ( - (current$$1 = createFiberFromPortal( + (current = createFiberFromPortal( portal, returnFiber.mode, expirationTime )), - (current$$1.return = returnFiber), - current$$1 + (current.return = returnFiber), + current ); - current$$1 = useFiber(current$$1, portal.children || [], expirationTime); - current$$1.return = returnFiber; - return current$$1; + current = useFiber(current, portal.children || []); + current.return = returnFiber; + return current; } - function updateFragment( - returnFiber, - current$$1, - fragment, - expirationTime, - key - ) { - if (null === current$$1 || 7 !== current$$1.tag) + function updateFragment(returnFiber, current, fragment, expirationTime, key) { + if (null === current || 7 !== current.tag) return ( - (current$$1 = createFiberFromFragment( + (current = createFiberFromFragment( fragment, returnFiber.mode, expirationTime, key )), - (current$$1.return = returnFiber), - current$$1 + (current.return = returnFiber), + current ); - current$$1 = useFiber(current$$1, fragment, expirationTime); - current$$1.return = returnFiber; - return current$$1; + current = useFiber(current, fragment); + current.return = returnFiber; + return current; } function createChild(returnFiber, newChild, expirationTime) { if ("string" === typeof newChild || "number" === typeof newChild) @@ -2962,39 +2819,48 @@ function ChildReconciler(shouldTrackSideEffects) { null !== isUnkeyedTopLevelFragment; ) { - 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; + 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; + } } - else deleteChild(returnFiber, isUnkeyedTopLevelFragment); + deleteRemainingChildren(returnFiber, isUnkeyedTopLevelFragment); + break; + } else deleteChild(returnFiber, isUnkeyedTopLevelFragment); isUnkeyedTopLevelFragment = isUnkeyedTopLevelFragment.sibling; } newChild.type === REACT_FRAGMENT_TYPE @@ -3044,8 +2910,7 @@ function ChildReconciler(shouldTrackSideEffects) { ); currentFirstChild = useFiber( currentFirstChild, - newChild.children || [], - expirationTime + newChild.children || [] ); currentFirstChild.return = returnFiber; returnFiber = currentFirstChild; @@ -3072,11 +2937,7 @@ function ChildReconciler(shouldTrackSideEffects) { (newChild = "" + newChild), null !== currentFirstChild && 6 === currentFirstChild.tag ? (deleteRemainingChildren(returnFiber, currentFirstChild.sibling), - (currentFirstChild = useFiber( - currentFirstChild, - newChild, - expirationTime - )), + (currentFirstChild = useFiber(currentFirstChild, newChild)), (currentFirstChild.return = returnFiber), (returnFiber = currentFirstChild)) : (deleteRemainingChildren(returnFiber, currentFirstChild), @@ -3131,16 +2992,16 @@ function requiredContext(c) { return c; } function pushHostContainer(fiber, nextRootInstance) { - push(rootInstanceStackCursor, nextRootInstance, fiber); - push(contextFiberStackCursor, fiber, fiber); - push(contextStackCursor$1, NO_CONTEXT, fiber); - pop(contextStackCursor$1, fiber); - push(contextStackCursor$1, { isInAParentText: !1 }, fiber); + push(rootInstanceStackCursor, nextRootInstance); + push(contextFiberStackCursor, fiber); + push(contextStackCursor$1, NO_CONTEXT); + pop(contextStackCursor$1); + push(contextStackCursor$1, { isInAParentText: !1 }); } -function popHostContainer(fiber) { - pop(contextStackCursor$1, fiber); - pop(contextFiberStackCursor, fiber); - pop(rootInstanceStackCursor, fiber); +function popHostContainer() { + pop(contextStackCursor$1); + pop(contextFiberStackCursor); + pop(rootInstanceStackCursor); } function pushHostContext(fiber) { requiredContext(rootInstanceStackCursor.current); @@ -3157,23 +3018,19 @@ function pushHostContext(fiber) { ? { isInAParentText: nextContext } : context; context !== nextContext && - (push(contextFiberStackCursor, fiber, fiber), - push(contextStackCursor$1, nextContext, fiber)); + (push(contextFiberStackCursor, fiber), + push(contextStackCursor$1, nextContext)); } function popHostContext(fiber) { contextFiberStackCursor.current === fiber && - (pop(contextStackCursor$1, fiber), pop(contextFiberStackCursor, fiber)); + (pop(contextStackCursor$1), pop(contextFiberStackCursor)); } var suspenseStackCursor = { current: 0 }; function findFirstSuspended(row) { for (var node = row; null !== node; ) { if (13 === node.tag) { var state = node.memoizedState; - if ( - null !== state && - ((state = state.dehydrated), - null === state || shim$1(state) || shim$1(state)) - ) + if (null !== state && (null === state.dehydrated || shim$1() || shim$1())) return node; } else if (19 === node.tag && void 0 !== node.memoizedProps.revealOrder) { if (0 !== (node.effectTag & 64)) return node; @@ -3192,24 +3049,16 @@ function findFirstSuspended(row) { } return null; } -function createResponderListener(responder, props) { +function createDeprecatedResponderListener(responder, props) { return { responder: responder, props: props }; } -var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, +var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig, - renderExpirationTime$1 = 0, + renderExpirationTime = 0, currentlyRenderingFiber$1 = null, currentHook = null, - nextCurrentHook = null, - firstWorkInProgressHook = null, workInProgressHook = null, - nextWorkInProgressHook = null, - remainingExpirationTime = 0, - componentUpdateQueue = null, - sideEffectTag = 0, - didScheduleRenderPhaseUpdate = !1, - renderPhaseUpdates = null, - numberOfReRenders = 0; + didScheduleRenderPhaseUpdate = !1; 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." @@ -3218,7 +3067,7 @@ function throwInvalidHookError() { function areHookInputsEqual(nextDeps, prevDeps) { if (null === prevDeps) return !1; for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) - if (!is$1(nextDeps[i], prevDeps[i])) return !1; + if (!objectIs(nextDeps[i], prevDeps[i])) return !1; return !0; } function renderWithHooks( @@ -3226,92 +3075,85 @@ function renderWithHooks( workInProgress, Component, props, - refOrContext, + secondArg, nextRenderExpirationTime ) { - renderExpirationTime$1 = nextRenderExpirationTime; + renderExpirationTime = nextRenderExpirationTime; currentlyRenderingFiber$1 = workInProgress; - 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; + 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); } - 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) + ReactCurrentDispatcher.current = ContextOnlyDispatcher; + workInProgress = null !== currentHook && null !== currentHook.next; + renderExpirationTime = 0; + workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; + didScheduleRenderPhaseUpdate = !1; + if (workInProgress) throw Error( "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." ); - 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; + return current; } function mountWorkInProgressHook() { var hook = { memoizedState: null, baseState: null, + baseQueue: null, queue: null, - baseUpdate: null, next: null }; null === workInProgressHook - ? (firstWorkInProgressHook = workInProgressHook = hook) + ? (currentlyRenderingFiber$1.memoizedState = 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), - (nextWorkInProgressHook = workInProgressHook.next), - (currentHook = nextCurrentHook), - (nextCurrentHook = null !== currentHook ? currentHook.next : null); + (currentHook = nextCurrentHook); else { if (null === nextCurrentHook) throw Error("Rendered more hooks than during the previous render."); currentHook = nextCurrentHook; - var newHook = { + nextCurrentHook = { memoizedState: currentHook.memoizedState, baseState: currentHook.baseState, + baseQueue: currentHook.baseQueue, queue: currentHook.queue, - baseUpdate: currentHook.baseUpdate, next: null }; - workInProgressHook = - null === workInProgressHook - ? (firstWorkInProgressHook = newHook) - : (workInProgressHook.next = newHook); - nextCurrentHook = currentHook.next; + null === workInProgressHook + ? (currentlyRenderingFiber$1.memoizedState = workInProgressHook = nextCurrentHook) + : (workInProgressHook = workInProgressHook.next = nextCurrentHook); } return workInProgressHook; } @@ -3326,74 +3168,100 @@ function updateReducer(reducer) { "Should have a queue. This is likely a bug in React. Please file an issue." ); queue.lastRenderedReducer = reducer; - 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]; - } + 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; } - return [hook.memoizedState, _dispatch]; + current.baseQueue = baseQueue = pendingQueue; + queue.pending = null; } - _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; + if (null !== baseQueue) { + baseQueue = baseQueue.next; + current = current.baseState; + var newBaseQueueLast = (baseFirst = pendingQueue = null), + update = baseQueue; do { - var updateExpirationTime = _update.expirationTime; - updateExpirationTime < renderExpirationTime$1 - ? (didSkip || - ((didSkip = !0), - (newBaseUpdate = baseUpdate), - (firstRenderPhaseUpdate = newState)), - updateExpirationTime > remainingExpirationTime && - ((remainingExpirationTime = updateExpirationTime), - markUnprocessedUpdateTime(remainingExpirationTime))) - : (markRenderEventTimeAndConfig( + 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( updateExpirationTime, - _update.suspenseConfig + update.suspenseConfig ), - (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); + (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); hook.memoizedState = newState; - hook.baseUpdate = newBaseUpdate; - hook.baseState = firstRenderPhaseUpdate; + null === hook.baseQueue && (hook.baseState = newState); queue.lastRenderedState = newState; } - return [hook.memoizedState, queue.dispatch]; + return [newState, dispatch]; } function mountState(initialState) { var hook = mountWorkInProgressHook(); "function" === typeof initialState && (initialState = initialState()); hook.memoizedState = hook.baseState = initialState; initialState = hook.queue = { - last: null, + pending: null, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState @@ -3405,28 +3273,30 @@ 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 }; - 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))); + 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))); return tag; } +function updateRef() { + return updateWorkInProgressHook().memoizedState; +} function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var hook = mountWorkInProgressHook(); - sideEffectTag |= fiberEffectTag; + currentlyRenderingFiber$1.effectTag |= fiberEffectTag; hook.memoizedState = pushEffect( - hookEffectTag, + 1 | hookEffectTag, create, void 0, void 0 === deps ? null : deps @@ -3440,18 +3310,21 @@ function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var prevEffect = currentHook.memoizedState; destroy = prevEffect.destroy; if (null !== deps && areHookInputsEqual(deps, prevEffect.deps)) { - pushEffect(0, create, destroy, deps); + pushEffect(hookEffectTag, create, destroy, deps); return; } } - sideEffectTag |= fiberEffectTag; - hook.memoizedState = pushEffect(hookEffectTag, create, destroy, deps); + currentlyRenderingFiber$1.effectTag |= fiberEffectTag; + hook.memoizedState = pushEffect(1 | hookEffectTag, create, destroy, deps); } function mountEffect(create, deps) { - return mountEffectImpl(516, 192, create, deps); + return mountEffectImpl(516, 4, create, deps); } function updateEffect(create, deps) { - return updateEffectImpl(516, 192, create, deps); + return updateEffectImpl(516, 4, create, deps); +} +function updateLayoutEffect(create, deps) { + return updateEffectImpl(4, 2, create, deps); } function imperativeHandleEffect(create, ref) { if ("function" === typeof ref) @@ -3471,6 +3344,15 @@ 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 = [ @@ -3492,72 +3374,79 @@ 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) { - if (!(25 > numberOfReRenders)) - throw Error( - "Too many re-renders. React limits the number of renders to prevent an infinite loop." - ); - var alternate = fiber.alternate; + 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 ( fiber === currentlyRenderingFiber$1 || - (null !== alternate && alternate === currentlyRenderingFiber$1) + (null !== pending && pending === currentlyRenderingFiber$1) ) - 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; - } + (didScheduleRenderPhaseUpdate = !0), + (suspenseConfig.expirationTime = renderExpirationTime), + (currentlyRenderingFiber$1.expirationTime = renderExpirationTime); 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 === alternate || 0 === alternate.expirationTime) && - ((alternate = queue.lastRenderedReducer), null !== alternate) + (null === pending || 0 === pending.expirationTime) && + ((pending = queue.lastRenderedReducer), null !== pending) ) try { var currentState = queue.lastRenderedState, - eagerState = alternate(currentState, action); - suspenseConfig.eagerReducer = alternate; + eagerState = pending(currentState, action); + suspenseConfig.eagerReducer = pending; suspenseConfig.eagerState = eagerState; - if (is$1(eagerState, currentState)) return; + if (objectIs(eagerState, currentState)) return; } catch (error) { } finally { } - scheduleUpdateOnFiber(fiber, currentTime); + scheduleWork(fiber, currentTime); } } +function updateEventListener() {} var ContextOnlyDispatcher = { readContext: readContext, useCallback: throwInvalidHookError, @@ -3572,7 +3461,8 @@ var ContextOnlyDispatcher = { useDebugValue: throwInvalidHookError, useResponder: throwInvalidHookError, useDeferredValue: throwInvalidHookError, - useTransition: throwInvalidHookError + useTransition: throwInvalidHookError, + useEvent: throwInvalidHookError }, HooksDispatcherOnMount = { readContext: readContext, @@ -3583,13 +3473,13 @@ var ContextOnlyDispatcher = { deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; return mountEffectImpl( 4, - 36, + 2, imperativeHandleEffect.bind(null, create, ref), deps ); }, useLayoutEffect: function(create, deps) { - return mountEffectImpl(4, 36, create, deps); + return mountEffectImpl(4, 2, create, deps); }, useMemo: function(nextCreate, deps) { var hook = mountWorkInProgressHook(); @@ -3603,7 +3493,7 @@ var ContextOnlyDispatcher = { initialArg = void 0 !== init ? init(initialArg) : initialArg; hook.memoizedState = hook.baseState = initialArg; reducer = hook.queue = { - last: null, + pending: null, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialArg @@ -3622,23 +3512,21 @@ var ContextOnlyDispatcher = { }, useState: mountState, useDebugValue: mountDebugValue, - useResponder: createResponderListener, + useResponder: createDeprecatedResponderListener, useDeferredValue: function(value, config) { var _mountState = mountState(value), prevValue = _mountState[0], setValue = _mountState[1]; mountEffect( function() { - 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; - } - }); + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } }, [value, config] ); @@ -3646,177 +3534,124 @@ var ContextOnlyDispatcher = { }, useTransition: function(config) { var _mountState2 = mountState(!1), - isPending = _mountState2[0], - setPending = _mountState2[1]; + isPending = _mountState2[0]; + _mountState2 = _mountState2[1]; return [ - 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] - ), + mountCallback(startTransition.bind(null, _mountState2, config), [ + _mountState2, + config + ]), isPending ]; - } + }, + useEvent: function() {} }, HooksDispatcherOnUpdate = { readContext: readContext, useCallback: updateCallback, useContext: readContext, useEffect: updateEffect, - 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; - }, + useImperativeHandle: updateImperativeHandle, + useLayoutEffect: updateLayoutEffect, + useMemo: updateMemo, useReducer: updateReducer, - useRef: function() { - return updateWorkInProgressHook().memoizedState; + useRef: updateRef, + useState: function() { + return updateReducer(basicStateReducer); }, - useState: updateState, useDebugValue: mountDebugValue, - useResponder: createResponderListener, + useResponder: createDeprecatedResponderListener, useDeferredValue: function(value, config) { - var _updateState = updateState(value), + var _updateState = updateReducer(basicStateReducer), prevValue = _updateState[0], setValue = _updateState[1]; updateEffect( function() { - 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; - } - }); + 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 = updateState(!1), - isPending = _updateState2[0], - setPending = _updateState2[1]; + var _updateState2 = updateReducer(basicStateReducer), + isPending = _updateState2[0]; + _updateState2 = _updateState2[1]; return [ - 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] - ), + updateCallback(startTransition.bind(null, _updateState2, config), [ + _updateState2, + config + ]), isPending ]; - } + }, + useEvent: updateEventListener }, - 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 + 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] ); - 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, + 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, didReceiveUpdate = !1; function reconcileChildren( - current$$1, + current, workInProgress, nextChildren, renderExpirationTime ) { workInProgress.child = - null === current$$1 + null === current ? mountChildFibers( workInProgress, null, @@ -3825,13 +3660,13 @@ function reconcileChildren( ) : reconcileChildFibers( workInProgress, - current$$1.child, + current.child, nextChildren, renderExpirationTime ); } function updateForwardRef( - current$$1, + current, workInProgress, Component, nextProps, @@ -3841,43 +3676,38 @@ function updateForwardRef( var ref = workInProgress.ref; prepareToReadContext(workInProgress, renderExpirationTime); nextProps = renderWithHooks( - current$$1, + current, workInProgress, Component, nextProps, ref, renderExpirationTime ); - if (null !== current$$1 && !didReceiveUpdate) + if (null !== current && !didReceiveUpdate) return ( - (workInProgress.updateQueue = current$$1.updateQueue), + (workInProgress.updateQueue = current.updateQueue), (workInProgress.effectTag &= -517), - current$$1.expirationTime <= renderExpirationTime && - (current$$1.expirationTime = 0), + current.expirationTime <= renderExpirationTime && + (current.expirationTime = 0), bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ) ); workInProgress.effectTag |= 1; - reconcileChildren( - current$$1, - workInProgress, - nextProps, - renderExpirationTime - ); + reconcileChildren(current, workInProgress, nextProps, renderExpirationTime); return workInProgress.child; } function updateMemoComponent( - current$$1, + current, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime ) { - if (null === current$$1) { + if (null === current) { var type = Component.type; if ( "function" === typeof type && @@ -3890,7 +3720,7 @@ function updateMemoComponent( (workInProgress.tag = 15), (workInProgress.type = type), updateSimpleMemoComponent( - current$$1, + current, workInProgress, type, nextProps, @@ -3898,7 +3728,7 @@ function updateMemoComponent( renderExpirationTime ) ); - current$$1 = createFiberFromTypeAndProps( + current = createFiberFromTypeAndProps( Component.type, null, nextProps, @@ -3906,65 +3736,66 @@ function updateMemoComponent( workInProgress.mode, renderExpirationTime ); - current$$1.ref = workInProgress.ref; - current$$1.return = workInProgress; - return (workInProgress.child = current$$1); + current.ref = workInProgress.ref; + current.return = workInProgress; + return (workInProgress.child = current); } - type = current$$1.child; + type = current.child; if ( updateExpirationTime < renderExpirationTime && ((updateExpirationTime = type.memoizedProps), (Component = Component.compare), (Component = null !== Component ? Component : shallowEqual), Component(updateExpirationTime, nextProps) && - current$$1.ref === workInProgress.ref) + current.ref === workInProgress.ref) ) return bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ); workInProgress.effectTag |= 1; - current$$1 = createWorkInProgress(type, nextProps, renderExpirationTime); - current$$1.ref = workInProgress.ref; - current$$1.return = workInProgress; - return (workInProgress.child = current$$1); + current = createWorkInProgress(type, nextProps); + current.ref = workInProgress.ref; + current.return = workInProgress; + return (workInProgress.child = current); } function updateSimpleMemoComponent( - current$$1, + current, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime ) { - return null !== current$$1 && - shallowEqual(current$$1.memoizedProps, nextProps) && - current$$1.ref === workInProgress.ref && + return null !== current && + shallowEqual(current.memoizedProps, nextProps) && + current.ref === workInProgress.ref && ((didReceiveUpdate = !1), updateExpirationTime < renderExpirationTime) - ? bailoutOnAlreadyFinishedWork( - current$$1, + ? ((workInProgress.expirationTime = current.expirationTime), + bailoutOnAlreadyFinishedWork( + current, workInProgress, renderExpirationTime - ) + )) : updateFunctionComponent( - current$$1, + current, workInProgress, Component, nextProps, renderExpirationTime ); } -function markRef(current$$1, workInProgress) { +function markRef(current, workInProgress) { var ref = workInProgress.ref; if ( - (null === current$$1 && null !== ref) || - (null !== current$$1 && current$$1.ref !== ref) + (null === current && null !== ref) || + (null !== current && current.ref !== ref) ) workInProgress.effectTag |= 128; } function updateFunctionComponent( - current$$1, + current, workInProgress, Component, nextProps, @@ -3976,36 +3807,31 @@ function updateFunctionComponent( context = getMaskedContext(workInProgress, context); prepareToReadContext(workInProgress, renderExpirationTime); Component = renderWithHooks( - current$$1, + current, workInProgress, Component, nextProps, context, renderExpirationTime ); - if (null !== current$$1 && !didReceiveUpdate) + if (null !== current && !didReceiveUpdate) return ( - (workInProgress.updateQueue = current$$1.updateQueue), + (workInProgress.updateQueue = current.updateQueue), (workInProgress.effectTag &= -517), - current$$1.expirationTime <= renderExpirationTime && - (current$$1.expirationTime = 0), + current.expirationTime <= renderExpirationTime && + (current.expirationTime = 0), bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ) ); workInProgress.effectTag |= 1; - reconcileChildren( - current$$1, - workInProgress, - Component, - renderExpirationTime - ); + reconcileChildren(current, workInProgress, Component, renderExpirationTime); return workInProgress.child; } function updateClassComponent( - current$$1, + current, workInProgress, Component, nextProps, @@ -4017,16 +3843,11 @@ function updateClassComponent( } else hasContext = !1; prepareToReadContext(workInProgress, renderExpirationTime); if (null === workInProgress.stateNode) - null !== current$$1 && - ((current$$1.alternate = null), + null !== current && + ((current.alternate = null), (workInProgress.alternate = null), (workInProgress.effectTag |= 2)), - constructClassInstance( - workInProgress, - Component, - nextProps, - renderExpirationTime - ), + constructClassInstance(workInProgress, Component, nextProps), mountClassInstance( workInProgress, Component, @@ -4034,7 +3855,7 @@ function updateClassComponent( renderExpirationTime ), (nextProps = !0); - else if (null === current$$1) { + else if (null === current) { var instance = workInProgress.stateNode, oldProps = workInProgress.memoizedProps; instance.props = oldProps; @@ -4062,17 +3883,14 @@ function updateClassComponent( )); hasForceUpdate = !1; var oldState = workInProgress.memoizedState; - oldContext = instance.state = oldState; - var updateQueue = workInProgress.updateQueue; - null !== updateQueue && - (processUpdateQueue( - workInProgress, - updateQueue, - nextProps, - instance, - renderExpirationTime - ), - (oldContext = workInProgress.memoizedState)); + instance.state = oldState; + processUpdateQueue( + workInProgress, + nextProps, + instance, + renderExpirationTime + ); + oldContext = workInProgress.memoizedState; oldProps !== nextProps || oldState !== oldContext || didPerformWorkStackCursor.current || @@ -4118,6 +3936,7 @@ function updateClassComponent( (nextProps = !1)); } else (instance = workInProgress.stateNode), + cloneUpdateQueue(current, workInProgress), (oldProps = workInProgress.memoizedProps), (instance.props = workInProgress.type === workInProgress.elementType @@ -4146,17 +3965,14 @@ function updateClassComponent( )), (hasForceUpdate = !1), (oldContext = workInProgress.memoizedState), - (oldState = instance.state = oldContext), - (updateQueue = workInProgress.updateQueue), - null !== updateQueue && - (processUpdateQueue( - workInProgress, - updateQueue, - nextProps, - instance, - renderExpirationTime - ), - (oldState = workInProgress.memoizedState)), + (instance.state = oldContext), + processUpdateQueue( + workInProgress, + nextProps, + instance, + renderExpirationTime + ), + (oldState = workInProgress.memoizedState), oldProps !== nextProps || oldContext !== oldState || didPerformWorkStackCursor.current || @@ -4200,12 +4016,12 @@ function updateClassComponent( "function" === typeof instance.getSnapshotBeforeUpdate && (workInProgress.effectTag |= 256)) : ("function" !== typeof instance.componentDidUpdate || - (oldProps === current$$1.memoizedProps && - oldContext === current$$1.memoizedState) || + (oldProps === current.memoizedProps && + oldContext === current.memoizedState) || (workInProgress.effectTag |= 4), "function" !== typeof instance.getSnapshotBeforeUpdate || - (oldProps === current$$1.memoizedProps && - oldContext === current$$1.memoizedState) || + (oldProps === current.memoizedProps && + oldContext === current.memoizedState) || (workInProgress.effectTag |= 256), (workInProgress.memoizedProps = nextProps), (workInProgress.memoizedState = oldState)), @@ -4214,16 +4030,16 @@ function updateClassComponent( (instance.context = contextType), (nextProps = getDerivedStateFromProps)) : ("function" !== typeof instance.componentDidUpdate || - (oldProps === current$$1.memoizedProps && - oldContext === current$$1.memoizedState) || + (oldProps === current.memoizedProps && + oldContext === current.memoizedState) || (workInProgress.effectTag |= 4), "function" !== typeof instance.getSnapshotBeforeUpdate || - (oldProps === current$$1.memoizedProps && - oldContext === current$$1.memoizedState) || + (oldProps === current.memoizedProps && + oldContext === current.memoizedState) || (workInProgress.effectTag |= 256), (nextProps = !1)); return finishClassComponent( - current$$1, + current, workInProgress, Component, nextProps, @@ -4232,35 +4048,35 @@ function updateClassComponent( ); } function finishClassComponent( - current$$1, + current, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime ) { - markRef(current$$1, workInProgress); + markRef(current, workInProgress); var didCaptureError = 0 !== (workInProgress.effectTag & 64); if (!shouldUpdate && !didCaptureError) return ( hasContext && invalidateContextProvider(workInProgress, Component, !1), bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ) ); shouldUpdate = workInProgress.stateNode; - ReactCurrentOwner$3.current = workInProgress; + ReactCurrentOwner$1.current = workInProgress; var nextChildren = didCaptureError && "function" !== typeof Component.getDerivedStateFromError ? null : shouldUpdate.render(); workInProgress.effectTag |= 1; - null !== current$$1 && didCaptureError + null !== current && didCaptureError ? ((workInProgress.child = reconcileChildFibers( workInProgress, - current$$1.child, + current.child, null, renderExpirationTime )), @@ -4271,7 +4087,7 @@ function finishClassComponent( renderExpirationTime ))) : reconcileChildren( - current$$1, + current, workInProgress, nextChildren, renderExpirationTime @@ -4294,7 +4110,7 @@ function pushHostRootContext(workInProgress) { } var SUSPENDED_MARKER = { dehydrated: null, retryTime: 0 }; function updateSuspenseComponent( - current$$1, + current, workInProgress, renderExpirationTime ) { @@ -4306,32 +4122,30 @@ function updateSuspenseComponent( (JSCompiler_temp = 0 !== (workInProgress.effectTag & 64)) || (JSCompiler_temp = 0 !== (suspenseContext & 2) && - (null === current$$1 || null !== current$$1.memoizedState)); + (null === current || null !== current.memoizedState)); JSCompiler_temp ? ((nextDidTimeout = !0), (workInProgress.effectTag &= -65)) - : (null !== current$$1 && null === current$$1.memoizedState) || + : (null !== current && null === current.memoizedState) || void 0 === nextProps.fallback || !0 === nextProps.unstable_avoidThisFallback || (suspenseContext |= 1); - push(suspenseStackCursor, suspenseContext & 1, workInProgress); - if (null === current$$1) { - void 0 !== nextProps.fallback && - tryToClaimNextHydratableInstance(workInProgress); + push(suspenseStackCursor, suspenseContext & 1); + if (null === current) { if (nextDidTimeout) { nextDidTimeout = nextProps.fallback; nextProps = createFiberFromFragment(null, mode, 0, null); nextProps.return = workInProgress; if (0 === (workInProgress.mode & 2)) for ( - current$$1 = + current = null !== workInProgress.memoizedState ? workInProgress.child.child : workInProgress.child, - nextProps.child = current$$1; - null !== current$$1; + nextProps.child = current; + null !== current; ) - (current$$1.return = nextProps), (current$$1 = current$$1.sibling); + (current.return = nextProps), (current = current.sibling); renderExpirationTime = createFiberFromFragment( nextDidTimeout, mode, @@ -4353,15 +4167,14 @@ function updateSuspenseComponent( renderExpirationTime )); } - if (null !== current$$1.memoizedState) { - current$$1 = current$$1.child; - mode = current$$1.sibling; + if (null !== current.memoizedState) { + current = current.child; + mode = current.sibling; if (nextDidTimeout) { nextProps = nextProps.fallback; renderExpirationTime = createWorkInProgress( - current$$1, - current$$1.pendingProps, - 0 + current, + current.pendingProps ); renderExpirationTime.return = workInProgress; if ( @@ -4370,7 +4183,7 @@ function updateSuspenseComponent( null !== workInProgress.memoizedState ? workInProgress.child.child : workInProgress.child), - nextDidTimeout !== current$$1.child) + nextDidTimeout !== current.child) ) for ( renderExpirationTime.child = nextDidTimeout; @@ -4379,7 +4192,7 @@ function updateSuspenseComponent( ) (nextDidTimeout.return = renderExpirationTime), (nextDidTimeout = nextDidTimeout.sibling); - mode = createWorkInProgress(mode, nextProps, mode.expirationTime); + mode = createWorkInProgress(mode, nextProps); mode.return = workInProgress; renderExpirationTime.sibling = mode; renderExpirationTime.childExpirationTime = 0; @@ -4389,31 +4202,31 @@ function updateSuspenseComponent( } renderExpirationTime = reconcileChildFibers( workInProgress, - current$$1.child, + current.child, nextProps.children, renderExpirationTime ); workInProgress.memoizedState = null; return (workInProgress.child = renderExpirationTime); } - current$$1 = current$$1.child; + current = current.child; if (nextDidTimeout) { nextDidTimeout = nextProps.fallback; nextProps = createFiberFromFragment(null, mode, 0, null); nextProps.return = workInProgress; - nextProps.child = current$$1; - null !== current$$1 && (current$$1.return = nextProps); + nextProps.child = current; + null !== current && (current.return = nextProps); if (0 === (workInProgress.mode & 2)) for ( - current$$1 = + current = null !== workInProgress.memoizedState ? workInProgress.child.child : workInProgress.child, - nextProps.child = current$$1; - null !== current$$1; + nextProps.child = current; + null !== current; ) - (current$$1.return = nextProps), (current$$1 = current$$1.sibling); + (current.return = nextProps), (current = current.sibling); renderExpirationTime = createFiberFromFragment( nextDidTimeout, mode, @@ -4431,7 +4244,7 @@ function updateSuspenseComponent( workInProgress.memoizedState = null; return (workInProgress.child = reconcileChildFibers( workInProgress, - current$$1, + current, nextProps.children, renderExpirationTime )); @@ -4458,6 +4271,7 @@ function initSuspenseListRenderState( ? (workInProgress.memoizedState = { isBackwards: isBackwards, rendering: null, + renderingStartTime: 0, last: lastContentRow, tail: tail, tailExpiration: 0, @@ -4466,6 +4280,7 @@ function initSuspenseListRenderState( }) : ((renderState.isBackwards = isBackwards), (renderState.rendering = null), + (renderState.renderingStartTime = 0), (renderState.last = lastContentRow), (renderState.tail = tail), (renderState.tailExpiration = 0), @@ -4473,7 +4288,7 @@ function initSuspenseListRenderState( (renderState.lastEffect = lastEffectBeforeRendering)); } function updateSuspenseListComponent( - current$$1, + current, workInProgress, renderExpirationTime ) { @@ -4481,7 +4296,7 @@ function updateSuspenseListComponent( revealOrder = nextProps.revealOrder, tailMode = nextProps.tail; reconcileChildren( - current$$1, + current, workInProgress, nextProps.children, renderExpirationTime @@ -4490,42 +4305,39 @@ function updateSuspenseListComponent( if (0 !== (nextProps & 2)) (nextProps = (nextProps & 1) | 2), (workInProgress.effectTag |= 64); else { - 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; + 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; continue; } - if (current$$1 === workInProgress) break a; - for (; null === current$$1.sibling; ) { - if ( - null === current$$1.return || - current$$1.return === workInProgress - ) + if (current === workInProgress) break a; + for (; null === current.sibling; ) { + if (null === current.return || current.return === workInProgress) break a; - current$$1 = current$$1.return; + current = current.return; } - current$$1.sibling.return = current$$1.return; - current$$1 = current$$1.sibling; + current.sibling.return = current.return; + current = current.sibling; } nextProps &= 1; } - push(suspenseStackCursor, nextProps, workInProgress); + push(suspenseStackCursor, nextProps); if (0 === (workInProgress.mode & 2)) workInProgress.memoizedState = null; else switch (revealOrder) { case "forwards": renderExpirationTime = workInProgress.child; for (revealOrder = null; null !== renderExpirationTime; ) - (current$$1 = renderExpirationTime.alternate), - null !== current$$1 && - null === findFirstSuspended(current$$1) && + (current = renderExpirationTime.alternate), + null !== current && + null === findFirstSuspended(current) && (revealOrder = renderExpirationTime), (renderExpirationTime = renderExpirationTime.sibling); renderExpirationTime = revealOrder; @@ -4547,15 +4359,15 @@ function updateSuspenseListComponent( renderExpirationTime = null; revealOrder = workInProgress.child; for (workInProgress.child = null; null !== revealOrder; ) { - current$$1 = revealOrder.alternate; - if (null !== current$$1 && null === findFirstSuspended(current$$1)) { + current = revealOrder.alternate; + if (null !== current && null === findFirstSuspended(current)) { workInProgress.child = revealOrder; break; } - current$$1 = revealOrder.sibling; + current = revealOrder.sibling; revealOrder.sibling = renderExpirationTime; renderExpirationTime = revealOrder; - revealOrder = current$$1; + revealOrder = current; } initSuspenseListRenderState( workInProgress, @@ -4582,35 +4394,29 @@ function updateSuspenseListComponent( return workInProgress.child; } function bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ) { - null !== current$$1 && - (workInProgress.dependencies = current$$1.dependencies); + null !== current && (workInProgress.dependencies = current.dependencies); var updateExpirationTime = workInProgress.expirationTime; 0 !== updateExpirationTime && markUnprocessedUpdateTime(updateExpirationTime); if (workInProgress.childExpirationTime < renderExpirationTime) return null; - if (null !== current$$1 && workInProgress.child !== current$$1.child) + if (null !== current && workInProgress.child !== current.child) throw Error("Resuming work not yet implemented."); if (null !== workInProgress.child) { - current$$1 = workInProgress.child; - renderExpirationTime = createWorkInProgress( - current$$1, - current$$1.pendingProps, - current$$1.expirationTime - ); + current = workInProgress.child; + renderExpirationTime = createWorkInProgress(current, current.pendingProps); workInProgress.child = renderExpirationTime; for ( renderExpirationTime.return = workInProgress; - null !== current$$1.sibling; + null !== current.sibling; ) - (current$$1 = current$$1.sibling), + (current = current.sibling), (renderExpirationTime = renderExpirationTime.sibling = createWorkInProgress( - current$$1, - current$$1.pendingProps, - current$$1.expirationTime + current, + current.pendingProps )), (renderExpirationTime.return = workInProgress); renderExpirationTime.sibling = null; @@ -4632,12 +4438,7 @@ appendAllChildren = function( var instance = node.stateNode; needsVisibilityToggle && isHidden && - (instance = cloneHiddenInstance( - instance, - node.type, - node.memoizedProps, - node - )); + (instance = cloneHiddenInstance(instance)); appendChildNode(parent.node, instance.node); } else if (6 === node.tag) { instance = node.stateNode; @@ -4690,12 +4491,7 @@ function appendAllChildrenToContainer( var instance = node.stateNode; needsVisibilityToggle && isHidden && - (instance = cloneHiddenInstance( - instance, - node.type, - node.memoizedProps, - node - )); + (instance = cloneHiddenInstance(instance)); appendChildNodeToSet(containerChildSet, instance.node); } else if (6 === node.tag) { instance = node.stateNode; @@ -4781,8 +4577,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), @@ -4792,16 +4588,17 @@ 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)); + 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); }; function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { switch (renderState.tailMode) { @@ -4827,48 +4624,347 @@ function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { : (_lastTailNode.sibling = null); } } -function unwindWork(workInProgress) { +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: - isContextProvider(workInProgress.type) && popContext(workInProgress); - var effectTag = workInProgress.effectTag; - return effectTag & 4096 - ? ((workInProgress.effectTag = (effectTag & -4097) | 64), - workInProgress) - : null; + return isContextProvider(workInProgress.type) && popContext(), null; case 3: - popHostContainer(workInProgress); - popTopLevelContextObject(workInProgress); - effectTag = workInProgress.effectTag; - if (0 !== (effectTag & 64)) - throw Error( - "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." - ); - workInProgress.effectTag = (effectTag & -4097) | 64; - return workInProgress; - case 5: - return popHostContext(workInProgress), null; - case 13: return ( - pop(suspenseStackCursor, workInProgress), - (effectTag = workInProgress.effectTag), - effectTag & 4096 - ? ((workInProgress.effectTag = (effectTag & -4097) | 64), - workInProgress) - : null + popHostContainer(), + pop(didPerformWorkStackCursor), + pop(contextStackCursor), + (current = workInProgress.stateNode), + current.pendingContext && + ((current.context = current.pendingContext), + (current.pendingContext = null)), + updateHostContainer(workInProgress), + null ); - case 19: - return pop(suspenseStackCursor, workInProgress), null; - case 4: - return popHostContainer(workInProgress), null; - case 10: - return popProvider(workInProgress), null; - default: + 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; - } -} -function createCapturedValue(value, source) { - return { + 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(); + var effectTag = workInProgress.effectTag; + return effectTag & 4096 + ? ((workInProgress.effectTag = (effectTag & -4097) | 64), + workInProgress) + : null; + case 3: + popHostContainer(); + pop(didPerformWorkStackCursor); + pop(contextStackCursor); + effectTag = workInProgress.effectTag; + if (0 !== (effectTag & 64)) + throw Error( + "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." + ); + workInProgress.effectTag = (effectTag & -4097) | 64; + return workInProgress; + case 5: + return popHostContext(workInProgress), null; + case 13: + return ( + pop(suspenseStackCursor), + (effectTag = workInProgress.effectTag), + effectTag & 4096 + ? ((workInProgress.effectTag = (effectTag & -4097) | 64), + workInProgress) + : null + ); + case 19: + return pop(suspenseStackCursor), null; + case 4: + return popHostContainer(), null; + case 10: + return popProvider(workInProgress), null; + default: + return null; + } +} +function createCapturedValue(value, source) { + return { value: value, source: source, stack: getStackByFiberInDevAndProd(source) @@ -4917,102 +5013,180 @@ function logError(boundary, errorInfo) { }); } } -function safelyCallComponentWillUnmount(current$$1, instance) { +function safelyCallComponentWillUnmount(current, instance) { try { - (instance.props = current$$1.memoizedProps), - (instance.state = current$$1.memoizedState), + (instance.props = current.memoizedProps), + (instance.state = current.memoizedState), instance.componentWillUnmount(); } catch (unmountError) { - captureCommitPhaseError(current$$1, unmountError); + captureCommitPhaseError(current, unmountError); } } -function safelyDetachRef(current$$1) { - var ref = current$$1.ref; +function safelyDetachRef(current) { + var ref = current.ref; if (null !== ref) if ("function" === typeof ref) try { ref(null); } catch (refError) { - captureCommitPhaseError(current$$1, refError); + captureCommitPhaseError(current, refError); } else ref.current = null; } -function commitBeforeMutationLifeCycles(current$$1, finishedWork) { +function commitBeforeMutationLifeCycles(current, finishedWork) { switch (finishedWork.tag) { case 0: case 11: case 15: - commitHookEffectList(2, 0, finishedWork); - break; + case 22: + return; case 1: - if (finishedWork.effectTag & 256 && null !== current$$1) { - var prevProps = current$$1.memoizedProps, - prevState = current$$1.memoizedState; - current$$1 = finishedWork.stateNode; - finishedWork = current$$1.getSnapshotBeforeUpdate( + if (finishedWork.effectTag & 256 && null !== current) { + var prevProps = current.memoizedProps, + prevState = current.memoizedState; + current = finishedWork.stateNode; + finishedWork = current.getSnapshotBeforeUpdate( finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState ); - current$$1.__reactInternalSnapshotBeforeUpdate = finishedWork; + current.__reactInternalSnapshotBeforeUpdate = finishedWork; } - break; + return; case 3: case 5: case 6: case 4: case 17: - break; - default: - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); + 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 commitHookEffectList(unmountTag, mountTag, finishedWork) { +function commitHookEffectListUnmount(tag, finishedWork) { finishedWork = finishedWork.updateQueue; finishedWork = null !== finishedWork ? finishedWork.lastEffect : null; if (null !== finishedWork) { var effect = (finishedWork = finishedWork.next); do { - if (0 !== (effect.tag & unmountTag)) { + if ((effect.tag & tag) === tag) { 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 commitUnmount(finishedRoot, current$$1$jscomp$0, renderPriorityLevel) { +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" === typeof onCommitFiberUnmount && - onCommitFiberUnmount(current$$1$jscomp$0); - switch (current$$1$jscomp$0.tag) { + onCommitFiberUnmount(current$jscomp$0); + switch (current$jscomp$0.tag) { case 0: case 11: case 14: case 15: - finishedRoot = current$$1$jscomp$0.updateQueue; + case 22: + finishedRoot = current$jscomp$0.updateQueue; if ( null !== finishedRoot && ((finishedRoot = finishedRoot.lastEffect), null !== finishedRoot) ) { var firstEffect = finishedRoot.next; - runWithPriority$1( + runWithPriority( 97 < renderPriorityLevel ? 97 : renderPriorityLevel, function() { var effect = firstEffect; do { - var destroy = effect.destroy; - if (void 0 !== destroy) { - var current$$1 = current$$1$jscomp$0; + var _destroy = effect.destroy; + if (void 0 !== _destroy) { + var current = current$jscomp$0; try { - destroy(); + _destroy(); } catch (error) { - captureCommitPhaseError(current$$1, error); + captureCommitPhaseError(current, error); } } effect = effect.next; @@ -5022,42 +5196,41 @@ function commitUnmount(finishedRoot, current$$1$jscomp$0, renderPriorityLevel) { } break; case 1: - safelyDetachRef(current$$1$jscomp$0); - renderPriorityLevel = current$$1$jscomp$0.stateNode; + safelyDetachRef(current$jscomp$0); + renderPriorityLevel = current$jscomp$0.stateNode; "function" === typeof renderPriorityLevel.componentWillUnmount && - safelyCallComponentWillUnmount( - current$$1$jscomp$0, - renderPriorityLevel - ); + safelyCallComponentWillUnmount(current$jscomp$0, renderPriorityLevel); break; case 5: - safelyDetachRef(current$$1$jscomp$0); + safelyDetachRef(current$jscomp$0); break; case 4: - createChildNodeSet(current$$1$jscomp$0.stateNode.containerInfo); + createChildNodeSet(current$jscomp$0.stateNode.containerInfo); } } -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; +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; null !== alternate && detachFiber(alternate); } -function commitWork(current$$1, finishedWork) { +function commitWork(current, finishedWork) { switch (finishedWork.tag) { case 0: case 11: case 14: case 15: - commitHookEffectList(4, 8, finishedWork); + case 22: + commitHookEffectListUnmount(3, finishedWork); return; case 12: return; @@ -5070,19 +5243,20 @@ function commitWork(current$$1, finishedWork) { attachSuspenseRetryListeners(finishedWork); return; } - 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." - ); + 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." + ); } } function attachSuspenseRetryListeners(finishedWork) { @@ -5139,7 +5313,7 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { return expirationTime; } var ceil = Math.ceil, - ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher, + ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, NoContext = 0, LegacyUnbatchedContext = 8, @@ -5154,7 +5328,7 @@ var ceil = Math.ceil, executionContext = NoContext, workInProgressRoot = null, workInProgress = null, - renderExpirationTime = 0, + renderExpirationTime$1 = 0, workInProgressRootExitStatus = RootIncomplete, workInProgressRootFatalError = null, workInProgressRootLatestProcessedExpirationTime = 1073741823, @@ -5179,8 +5353,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; @@ -5188,7 +5362,7 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { var priorityLevel = getCurrentPriorityLevel(); if (0 === (fiber & 4)) return 99 === priorityLevel ? 1073741823 : 1073741822; if ((executionContext & RenderContext) !== NoContext) - return renderExpirationTime; + return renderExpirationTime$1; if (null !== suspenseConfig) currentTime = 1073741821 - @@ -5220,11 +5394,11 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { throw Error("Expected a valid priority level"); } null !== workInProgressRoot && - currentTime === renderExpirationTime && + currentTime === renderExpirationTime$1 && --currentTime; return currentTime; } -function scheduleUpdateOnFiber(fiber, expirationTime) { +function scheduleWork(fiber, expirationTime) { if (50 < nestedUpdateCount) throw ((nestedUpdateCount = 0), (rootWithNestedUpdates = null), @@ -5278,7 +5452,7 @@ function markUpdateTimeFromFiberToRoot(fiber, expirationTime) { (workInProgressRoot === root && (markUnprocessedUpdateTime(expirationTime), workInProgressRootExitStatus === RootSuspendedWithDelay && - markRootSuspendedAtTime(root, renderExpirationTime)), + markRootSuspendedAtTime(root, renderExpirationTime$1)), markRootUpdatedAtTime(root, expirationTime)); return root; } @@ -5287,9 +5461,10 @@ function getNextRootExpirationTimeToWorkOn(root) { if (0 !== lastExpiredTime) return lastExpiredTime; lastExpiredTime = root.firstPendingTime; if (!isRootSuspendedAtTime(root, lastExpiredTime)) return lastExpiredTime; - lastExpiredTime = root.lastPingedTime; + var lastPingedTime = root.lastPingedTime; root = root.nextKnownPendingLevel; - return lastExpiredTime > root ? lastExpiredTime : root; + root = lastPingedTime > root ? lastPingedTime : root; + return 2 >= root && lastExpiredTime !== root ? 0 : root; } function ensureRootIsScheduled(root) { if (0 !== root.lastExpiredTime) @@ -5311,18 +5486,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 ( @@ -5349,264 +5524,225 @@ function ensureRootIsScheduled(root) { } function performConcurrentWorkOnRoot(root, didTimeout) { currentEventTime = 0; - if (didTimeout) - return ( - (didTimeout = requestCurrentTimeForUpdate()), - markRootExpiredAtTime(root, didTimeout), + 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), ensureRootIsScheduled(root), - 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(); + 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; - } catch (thrownValue) { - handleError(root, thrownValue); } - 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) + 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 + ); + break; + } + commitRoot(root); + break; + case RootCompleted: + if ( + 1073741823 !== workInProgressRootLatestProcessedExpirationTime && + null !== workInProgressRootCanSuspendUsingConfig ) { - case RootIncomplete: - case RootFatalErrored: - throw Error("Root did not complete. This is a bug in React."); - case RootErrored: - markRootExpiredAtTime( - root, - 2 < expirationTime ? 2 : expirationTime + 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 ); 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."); + } } - ensureRootIsScheduled(root); - if (root.callbackNode === didTimeout) - return performConcurrentWorkOnRoot.bind(null, root); + commitRoot(root); + break; + default: + throw Error("Unknown root exit status."); } } - return null; + 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 ? 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); - } - } + 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; @@ -5618,26 +5754,27 @@ function prepareFreshStack(root, expirationTime) { var interruptedWork = timeoutHandle; switch (interruptedWork.tag) { case 1: - var childContextTypes = interruptedWork.type.childContextTypes; - null !== childContextTypes && - void 0 !== childContextTypes && - popContext(interruptedWork); + interruptedWork = interruptedWork.type.childContextTypes; + null !== interruptedWork && + void 0 !== interruptedWork && + popContext(); break; case 3: - popHostContainer(interruptedWork); - popTopLevelContextObject(interruptedWork); + popHostContainer(); + pop(didPerformWorkStackCursor); + pop(contextStackCursor); break; case 5: popHostContext(interruptedWork); break; case 4: - popHostContainer(interruptedWork); + popHostContainer(); break; case 13: - pop(suspenseStackCursor, interruptedWork); + pop(suspenseStackCursor); break; case 19: - pop(suspenseStackCursor, interruptedWork); + pop(suspenseStackCursor); break; case 10: popProvider(interruptedWork); @@ -5645,8 +5782,8 @@ function prepareFreshStack(root, expirationTime) { timeoutHandle = timeoutHandle.return; } workInProgressRoot = root; - workInProgress = createWorkInProgress(root.current, null, expirationTime); - renderExpirationTime = expirationTime; + workInProgress = createWorkInProgress(root.current, null); + renderExpirationTime$1 = expirationTime; workInProgressRootExitStatus = RootIncomplete; workInProgressRootFatalError = null; workInProgressRootLatestSuspenseTimeout = workInProgressRootLatestProcessedExpirationTime = 1073741823; @@ -5658,19 +5795,32 @@ function handleError(root$jscomp$0, thrownValue) { do { try { resetContextDependencies(); - resetHooks(); + 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; if (null === workInProgress || null === workInProgress.return) return ( (workInProgressRootExitStatus = RootFatalErrored), (workInProgressRootFatalError = thrownValue), - null + (workInProgress = null) ); a: { var root = root$jscomp$0, returnFiber = workInProgress.return, sourceFiber = workInProgress, value = thrownValue; - thrownValue = renderExpirationTime; + thrownValue = renderExpirationTime$1; sourceFiber.effectTag |= 2048; sourceFiber.firstEffect = sourceFiber.lastEffect = null; if ( @@ -5678,8 +5828,17 @@ function handleError(root$jscomp$0, thrownValue) { "object" === typeof value && "function" === typeof value.then ) { - var thenable = value, - hasInvisibleParentBoundary = + 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 = 0 !== (suspenseStackCursor.current & 1), _workInProgress = returnFiber; do { @@ -5694,10 +5853,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) { @@ -5796,399 +5955,102 @@ function handleError(root$jscomp$0, thrownValue) { } while (null !== _workInProgress); } workInProgress = completeUnitOfWork(workInProgress); - } catch (yetAnotherThrownValue) { - thrownValue = yetAnotherThrownValue; - continue; - } - break; - } while (1); -} -function pushDispatcher() { - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = ContextOnlyDispatcher; - return null === prevDispatcher ? ContextOnlyDispatcher : prevDispatcher; -} -function markRenderEventTimeAndConfig(expirationTime, suspenseConfig) { - expirationTime < workInProgressRootLatestProcessedExpirationTime && - 2 < expirationTime && - (workInProgressRootLatestProcessedExpirationTime = expirationTime); - null !== suspenseConfig && - expirationTime < workInProgressRootLatestSuspenseTimeout && - 2 < expirationTime && - ((workInProgressRootLatestSuspenseTimeout = expirationTime), - (workInProgressRootCanSuspendUsingConfig = suspenseConfig)); -} -function markUnprocessedUpdateTime(expirationTime) { - expirationTime > workInProgressRootNextUnprocessedUpdateTime && - (workInProgressRootNextUnprocessedUpdateTime = expirationTime); -} -function workLoopSync() { - for (; null !== workInProgress; ) - workInProgress = performUnitOfWork(workInProgress); -} -function workLoopConcurrent() { - for (; null !== workInProgress && !Scheduler_shouldYield(); ) - workInProgress = performUnitOfWork(workInProgress); -} -function performUnitOfWork(unitOfWork) { - var next = beginWork$$1( - unitOfWork.alternate, - unitOfWork, - renderExpirationTime - ); - unitOfWork.memoizedProps = unitOfWork.pendingProps; - null === next && (next = completeUnitOfWork(unitOfWork)); - ReactCurrentOwner$2.current = null; - return next; -} -function completeUnitOfWork(unitOfWork) { - workInProgress = unitOfWork; - do { - var current$$1 = workInProgress.alternate; - unitOfWork = workInProgress.return; - if (0 === (workInProgress.effectTag & 2048)) { - 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; + } catch (yetAnotherThrownValue) { + thrownValue = yetAnotherThrownValue; + continue; + } + break; + } while (1); +} +function pushDispatcher() { + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; + return null === prevDispatcher ? ContextOnlyDispatcher : prevDispatcher; +} +function markRenderEventTimeAndConfig(expirationTime, suspenseConfig) { + expirationTime < workInProgressRootLatestProcessedExpirationTime && + 2 < expirationTime && + (workInProgressRootLatestProcessedExpirationTime = expirationTime); + null !== suspenseConfig && + expirationTime < workInProgressRootLatestSuspenseTimeout && + 2 < expirationTime && + ((workInProgressRootLatestSuspenseTimeout = expirationTime), + (workInProgressRootCanSuspendUsingConfig = suspenseConfig)); +} +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(); ) + workInProgress = performUnitOfWork(workInProgress); +} +function performUnitOfWork(unitOfWork) { + var next = beginWork$1( + unitOfWork.alternate, + unitOfWork, + renderExpirationTime$1 + ); + unitOfWork.memoizedProps = unitOfWork.pendingProps; + null === next && (next = completeUnitOfWork(unitOfWork)); + ReactCurrentOwner$2.current = null; + return next; +} +function completeUnitOfWork(unitOfWork) { + workInProgress = unitOfWork; + do { + var current = workInProgress.alternate; + unitOfWork = workInProgress.return; + if (0 === (workInProgress.effectTag & 2048)) { + current = completeWork(current, workInProgress, renderExpirationTime$1); + if ( + 1 === renderExpirationTime$1 || + 1 !== workInProgress.childExpirationTime + ) { for ( - rootContainerInstance = instance.child; - null !== rootContainerInstance; + var newChildExpirationTime = 0, _child = workInProgress.child; + null !== _child; - ) - (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; + ) { + var _childUpdateExpirationTime = _child.expirationTime, + _childChildExpirationTime = _child.childExpirationTime; + _childUpdateExpirationTime > newChildExpirationTime && + (newChildExpirationTime = _childUpdateExpirationTime); + _childChildExpirationTime > newChildExpirationTime && + (newChildExpirationTime = _childChildExpirationTime); + _child = _child.sibling; + } + workInProgress.childExpirationTime = newChildExpirationTime; } - if (null !== current$$1) return current$$1; + if (null !== current) return current; null !== unitOfWork && 0 === (unitOfWork.effectTag & 2048) && (null === unitOfWork.firstEffect && @@ -6203,15 +6065,14 @@ function completeUnitOfWork(unitOfWork) { : (unitOfWork.firstEffect = workInProgress), (unitOfWork.lastEffect = workInProgress))); } else { - current$$1 = unwindWork(workInProgress, renderExpirationTime); - if (null !== current$$1) - return (current$$1.effectTag &= 2047), current$$1; + current = unwindWork(workInProgress); + if (null !== current) return (current.effectTag &= 2047), current; null !== unitOfWork && ((unitOfWork.firstEffect = unitOfWork.lastEffect = null), (unitOfWork.effectTag |= 2048)); } - current$$1 = workInProgress.sibling; - if (null !== current$$1) return current$$1; + current = workInProgress.sibling; + if (null !== current) return current; workInProgress = unitOfWork; } while (null !== workInProgress); workInProgressRootExitStatus === RootIncomplete && @@ -6225,11 +6086,12 @@ function getRemainingExpirationTime(fiber) { } function commitRoot(root) { var renderPriorityLevel = getCurrentPriorityLevel(); - runWithPriority$1(99, commitRootImpl.bind(null, root, renderPriorityLevel)); + runWithPriority(99, commitRootImpl.bind(null, root, renderPriorityLevel)); return null; } function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { - flushPassiveEffects(); + do flushPassiveEffects(); + while (null !== rootWithPendingPassiveEffects); if ((executionContext & (RenderContext | CommitContext)) !== NoContext) throw Error("Should not already be working."); var finishedWork = root$jscomp$1.finishedWork, @@ -6258,7 +6120,8 @@ 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 = 0)); + ((workInProgress = workInProgressRoot = null), + (renderExpirationTime$1 = 0)); 1 < finishedWork.effectTag ? null !== finishedWork.lastEffect ? ((finishedWork.lastEffect.nextEffect = finishedWork), @@ -6290,9 +6153,9 @@ function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { ) { var effectTag = nextEffect.effectTag; if (effectTag & 128) { - var current$$1 = nextEffect.alternate; - if (null !== current$$1) { - var currentRef = current$$1.ref; + var current = nextEffect.alternate; + if (null !== current) { + var currentRef = current.ref; null !== currentRef && ("function" === typeof currentRef ? currentRef(null) @@ -6318,10 +6181,10 @@ function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { commitWork(nextEffect.alternate, nextEffect); break; case 8: - var current$$1$jscomp$0 = nextEffect; + var current$jscomp$0 = nextEffect; a: for ( var finishedRoot = root, - root$jscomp$0 = current$$1$jscomp$0, + root$jscomp$0 = current$jscomp$0, renderPriorityLevel$jscomp$0 = renderPriorityLevel, node = root$jscomp$0; ; @@ -6346,7 +6209,7 @@ function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { node.sibling.return = node.return; node = node.sibling; } - detachFiber(current$$1$jscomp$0); + detachFiber(current$jscomp$0); } nextEffect = nextEffect.nextEffect; } @@ -6360,101 +6223,25 @@ function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { nextEffect = remainingExpirationTimeBeforeCommit; do try { - for (effectTag = expirationTime; null !== nextEffect; ) { + for (effectTag = root$jscomp$1; null !== nextEffect; ) { var effectTag$jscomp$0 = nextEffect.effectTag; - 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." - ); - } - } + effectTag$jscomp$0 & 36 && + commitLifeCycles(effectTag, nextEffect.alternate, nextEffect); if (effectTag$jscomp$0 & 128) { - current$$1 = void 0; + current = void 0; var ref = nextEffect.ref; if (null !== ref) { - var instance$jscomp$0 = nextEffect.stateNode; + var instance = nextEffect.stateNode; switch (nextEffect.tag) { case 5: - current$$1 = instance$jscomp$0.canonical; + current = instance.canonical; break; default: - current$$1 = instance$jscomp$0; + current = instance; } "function" === typeof ref - ? ref(current$$1) - : (ref.current = current$$1); + ? ref(current) + : (ref.current = current); } } nextEffect = nextEffect.nextEffect; @@ -6524,7 +6311,7 @@ function flushPassiveEffects() { ? 97 : pendingPassiveEffectsRenderPriority; pendingPassiveEffectsRenderPriority = 90; - return runWithPriority$1(priorityLevel, flushPassiveEffectsImpl); + return runWithPriority(priorityLevel, flushPassiveEffectsImpl); } } function flushPassiveEffectsImpl() { @@ -6543,8 +6330,9 @@ function flushPassiveEffectsImpl() { case 0: case 11: case 15: - commitHookEffectList(128, 0, finishedWork), - commitHookEffectList(0, 64, finishedWork); + case 22: + commitHookEffectListUnmount(5, finishedWork), + commitHookEffectListMount(5, finishedWork); } } catch (error) { if (null === root) throw Error("Should be working on an effect."); @@ -6595,20 +6383,17 @@ function captureCommitPhaseError(sourceFiber, error) { function pingSuspendedRoot(root, thenable, suspendedTime) { var pingCache = root.pingCache; null !== pingCache && pingCache.delete(thenable); - workInProgressRoot === root && renderExpirationTime === suspendedTime + workInProgressRoot === root && renderExpirationTime$1 === suspendedTime ? workInProgressRootExitStatus === RootSuspendedWithDelay || (workInProgressRootExitStatus === RootSuspended && 1073741823 === workInProgressRootLatestProcessedExpirationTime && now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) - ? prepareFreshStack(root, renderExpirationTime) + ? prepareFreshStack(root, renderExpirationTime$1) : (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))); + ((root.lastPingedTime = suspendedTime), ensureRootIsScheduled(root))); } function resolveRetryThenable(boundaryFiber, thenable) { var retryCache = boundaryFiber.stateNode; @@ -6620,12 +6405,12 @@ function resolveRetryThenable(boundaryFiber, thenable) { boundaryFiber = markUpdateTimeFromFiberToRoot(boundaryFiber, thenable); null !== boundaryFiber && ensureRootIsScheduled(boundaryFiber); } -var beginWork$$1; -beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { +var beginWork$1; +beginWork$1 = function(current, workInProgress, renderExpirationTime) { var updateExpirationTime = workInProgress.expirationTime; - if (null !== current$$1) + if (null !== current) if ( - current$$1.memoizedProps !== workInProgress.pendingProps || + current.memoizedProps !== workInProgress.pendingProps || didPerformWorkStackCursor.current ) didReceiveUpdate = !0; @@ -6650,7 +6435,10 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { ); break; case 10: - pushProvider(workInProgress, workInProgress.memoizedProps.value); + updateExpirationTime = workInProgress.memoizedProps.value; + var context = workInProgress.type._context; + push(valueCursor, context._currentValue2); + context._currentValue2 = updateExpirationTime; break; case 13: if (null !== workInProgress.memoizedState) { @@ -6660,52 +6448,40 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { updateExpirationTime >= renderExpirationTime ) return updateSuspenseComponent( - current$$1, + current, workInProgress, renderExpirationTime ); - push( - suspenseStackCursor, - suspenseStackCursor.current & 1, - workInProgress - ); + push(suspenseStackCursor, suspenseStackCursor.current & 1); workInProgress = bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ); return null !== workInProgress ? workInProgress.sibling : null; } - push( - suspenseStackCursor, - suspenseStackCursor.current & 1, - workInProgress - ); + push(suspenseStackCursor, suspenseStackCursor.current & 1); break; case 19: updateExpirationTime = workInProgress.childExpirationTime >= renderExpirationTime; - if (0 !== (current$$1.effectTag & 64)) { + if (0 !== (current.effectTag & 64)) { if (updateExpirationTime) return updateSuspenseListComponent( - current$$1, + current, workInProgress, renderExpirationTime ); workInProgress.effectTag |= 64; } - var renderState = workInProgress.memoizedState; - null !== renderState && - ((renderState.rendering = null), (renderState.tail = null)); - push( - suspenseStackCursor, - suspenseStackCursor.current, - workInProgress - ); + context = workInProgress.memoizedState; + null !== context && + ((context.rendering = null), (context.tail = null)); + push(suspenseStackCursor, suspenseStackCursor.current); if (!updateExpirationTime) return null; } return bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ); @@ -6717,41 +6493,40 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { switch (workInProgress.tag) { case 2: updateExpirationTime = workInProgress.type; - null !== current$$1 && - ((current$$1.alternate = null), + null !== current && + ((current.alternate = null), (workInProgress.alternate = null), (workInProgress.effectTag |= 2)); - current$$1 = workInProgress.pendingProps; - renderState = getMaskedContext( - workInProgress, - contextStackCursor.current - ); + current = workInProgress.pendingProps; + context = getMaskedContext(workInProgress, contextStackCursor.current); prepareToReadContext(workInProgress, renderExpirationTime); - renderState = renderWithHooks( + context = renderWithHooks( null, workInProgress, updateExpirationTime, - current$$1, - renderState, + current, + context, renderExpirationTime ); workInProgress.effectTag |= 1; if ( - "object" === typeof renderState && - null !== renderState && - "function" === typeof renderState.render && - void 0 === renderState.$$typeof + "object" === typeof context && + null !== context && + "function" === typeof context.render && + void 0 === context.$$typeof ) { workInProgress.tag = 1; - resetHooks(); + workInProgress.memoizedState = null; + workInProgress.updateQueue = null; if (isContextProvider(updateExpirationTime)) { var hasContext = !0; pushContextProvider(workInProgress); } else hasContext = !1; workInProgress.memoizedState = - null !== renderState.state && void 0 !== renderState.state - ? renderState.state + null !== context.state && void 0 !== context.state + ? context.state : null; + initializeUpdateQueue(workInProgress); var getDerivedStateFromProps = updateExpirationTime.getDerivedStateFromProps; "function" === typeof getDerivedStateFromProps && @@ -6759,15 +6534,15 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { workInProgress, updateExpirationTime, getDerivedStateFromProps, - current$$1 + current ); - renderState.updater = classComponentUpdater; - workInProgress.stateNode = renderState; - renderState._reactInternalFiber = workInProgress; + context.updater = classComponentUpdater; + workInProgress.stateNode = context; + context._reactInternalFiber = workInProgress; mountClassInstance( workInProgress, updateExpirationTime, - current$$1, + current, renderExpirationTime ); workInProgress = finishClassComponent( @@ -6783,127 +6558,129 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { reconcileChildren( null, workInProgress, - renderState, + context, renderExpirationTime ), (workInProgress = workInProgress.child); return workInProgress; case 16: - 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." - ); + 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." + ); } return workInProgress; case 0: return ( (updateExpirationTime = workInProgress.type), - (renderState = workInProgress.pendingProps), - (renderState = + (context = workInProgress.pendingProps), + (context = workInProgress.elementType === updateExpirationTime - ? renderState - : resolveDefaultProps(updateExpirationTime, renderState)), + ? context + : resolveDefaultProps(updateExpirationTime, context)), updateFunctionComponent( - current$$1, + current, workInProgress, updateExpirationTime, - renderState, + context, renderExpirationTime ) ); case 1: return ( (updateExpirationTime = workInProgress.type), - (renderState = workInProgress.pendingProps), - (renderState = + (context = workInProgress.pendingProps), + (context = workInProgress.elementType === updateExpirationTime - ? renderState - : resolveDefaultProps(updateExpirationTime, renderState)), + ? context + : resolveDefaultProps(updateExpirationTime, context)), updateClassComponent( - current$$1, + current, workInProgress, updateExpirationTime, - renderState, + context, renderExpirationTime ) ); case 3: pushHostRootContext(workInProgress); updateExpirationTime = workInProgress.updateQueue; - if (null === updateExpirationTime) + if (null === current || 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." ); - renderState = workInProgress.memoizedState; - renderState = null !== renderState ? renderState.element : null; + updateExpirationTime = workInProgress.pendingProps; + context = workInProgress.memoizedState; + context = null !== context ? context.element : null; + cloneUpdateQueue(current, workInProgress); processUpdateQueue( workInProgress, updateExpirationTime, - workInProgress.pendingProps, null, renderExpirationTime ); updateExpirationTime = workInProgress.memoizedState.element; - updateExpirationTime === renderState + updateExpirationTime === context ? (workInProgress = bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime )) : (reconcileChildren( - current$$1, + current, workInProgress, updateExpirationTime, renderExpirationTime @@ -6913,11 +6690,10 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { case 5: return ( pushHostContext(workInProgress), - null === current$$1 && tryToClaimNextHydratableInstance(workInProgress), (updateExpirationTime = workInProgress.pendingProps.children), - markRef(current$$1, workInProgress), + markRef(current, workInProgress), reconcileChildren( - current$$1, + current, workInProgress, updateExpirationTime, renderExpirationTime @@ -6926,13 +6702,10 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { workInProgress ); case 6: - return ( - null === current$$1 && tryToClaimNextHydratableInstance(workInProgress), - null - ); + return null; case 13: return updateSuspenseComponent( - current$$1, + current, workInProgress, renderExpirationTime ); @@ -6943,7 +6716,7 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { workInProgress.stateNode.containerInfo ), (updateExpirationTime = workInProgress.pendingProps), - null === current$$1 + null === current ? (workInProgress.child = reconcileChildFibers( workInProgress, null, @@ -6951,7 +6724,7 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { renderExpirationTime )) : reconcileChildren( - current$$1, + current, workInProgress, updateExpirationTime, renderExpirationTime @@ -6961,23 +6734,23 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { case 11: return ( (updateExpirationTime = workInProgress.type), - (renderState = workInProgress.pendingProps), - (renderState = + (context = workInProgress.pendingProps), + (context = workInProgress.elementType === updateExpirationTime - ? renderState - : resolveDefaultProps(updateExpirationTime, renderState)), + ? context + : resolveDefaultProps(updateExpirationTime, context)), updateForwardRef( - current$$1, + current, workInProgress, updateExpirationTime, - renderState, + context, renderExpirationTime ) ); case 7: return ( reconcileChildren( - current$$1, + current, workInProgress, workInProgress.pendingProps, renderExpirationTime @@ -6987,7 +6760,7 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { case 8: return ( reconcileChildren( - current$$1, + current, workInProgress, workInProgress.pendingProps.children, renderExpirationTime @@ -6997,7 +6770,7 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { case 12: return ( reconcileChildren( - current$$1, + current, workInProgress, workInProgress.pendingProps.children, renderExpirationTime @@ -7007,27 +6780,32 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { case 10: a: { updateExpirationTime = workInProgress.type._context; - renderState = workInProgress.pendingProps; + context = workInProgress.pendingProps; getDerivedStateFromProps = workInProgress.memoizedProps; - 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) { + 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) + ) { if ( - getDerivedStateFromProps.children === renderState.children && + getDerivedStateFromProps.children === context.children && !didPerformWorkStackCursor.current ) { workInProgress = bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ); @@ -7035,14 +6813,15 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { } } else for ( - oldValue = workInProgress.child, - null !== oldValue && (oldValue.return = workInProgress); - null !== oldValue; + context$jscomp$0 = workInProgress.child, + null !== context$jscomp$0 && + (context$jscomp$0.return = workInProgress); + null !== context$jscomp$0; ) { - var list = oldValue.dependencies; + var list = context$jscomp$0.dependencies; if (null !== list) { - getDerivedStateFromProps = oldValue.child; + getDerivedStateFromProps = context$jscomp$0.child; for ( var dependency = list.firstContext; null !== dependency; @@ -7052,18 +6831,18 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { dependency.context === updateExpirationTime && 0 !== (dependency.observedBits & hasContext) ) { - 1 === oldValue.tag && + 1 === context$jscomp$0.tag && ((dependency = createUpdate(renderExpirationTime, null)), (dependency.tag = 2), - enqueueUpdate(oldValue, dependency)); - oldValue.expirationTime < renderExpirationTime && - (oldValue.expirationTime = renderExpirationTime); - dependency = oldValue.alternate; + enqueueUpdate(context$jscomp$0, dependency)); + context$jscomp$0.expirationTime < renderExpirationTime && + (context$jscomp$0.expirationTime = renderExpirationTime); + dependency = context$jscomp$0.alternate; null !== dependency && dependency.expirationTime < renderExpirationTime && (dependency.expirationTime = renderExpirationTime); scheduleWorkOnParentPath( - oldValue.return, + context$jscomp$0.return, renderExpirationTime ); list.expirationTime < renderExpirationTime && @@ -7074,16 +6853,16 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { } } else getDerivedStateFromProps = - 10 === oldValue.tag - ? oldValue.type === workInProgress.type + 10 === context$jscomp$0.tag + ? context$jscomp$0.type === workInProgress.type ? null - : oldValue.child - : oldValue.child; + : context$jscomp$0.child + : context$jscomp$0.child; if (null !== getDerivedStateFromProps) - getDerivedStateFromProps.return = oldValue; + getDerivedStateFromProps.return = context$jscomp$0; else for ( - getDerivedStateFromProps = oldValue; + getDerivedStateFromProps = context$jscomp$0; null !== getDerivedStateFromProps; ) { @@ -7091,21 +6870,20 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { getDerivedStateFromProps = null; break; } - oldValue = getDerivedStateFromProps.sibling; - if (null !== oldValue) { - oldValue.return = getDerivedStateFromProps.return; - getDerivedStateFromProps = oldValue; + context$jscomp$0 = getDerivedStateFromProps.sibling; + if (null !== context$jscomp$0) { + context$jscomp$0.return = getDerivedStateFromProps.return; + getDerivedStateFromProps = context$jscomp$0; break; } getDerivedStateFromProps = getDerivedStateFromProps.return; } - oldValue = getDerivedStateFromProps; + context$jscomp$0 = getDerivedStateFromProps; } - } reconcileChildren( - current$$1, + current, workInProgress, - renderState.children, + context.children, renderExpirationTime ); workInProgress = workInProgress.child; @@ -7113,18 +6891,15 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { return workInProgress; case 9: return ( - (renderState = workInProgress.type), + (context = workInProgress.type), (hasContext = workInProgress.pendingProps), (updateExpirationTime = hasContext.children), prepareToReadContext(workInProgress, renderExpirationTime), - (renderState = readContext( - renderState, - hasContext.unstable_observedBits - )), - (updateExpirationTime = updateExpirationTime(renderState)), + (context = readContext(context, hasContext.unstable_observedBits)), + (updateExpirationTime = updateExpirationTime(context)), (workInProgress.effectTag |= 1), reconcileChildren( - current$$1, + current, workInProgress, updateExpirationTime, renderExpirationTime @@ -7133,16 +6908,16 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { ); case 14: return ( - (renderState = workInProgress.type), + (context = workInProgress.type), (hasContext = resolveDefaultProps( - renderState, + context, workInProgress.pendingProps )), - (hasContext = resolveDefaultProps(renderState.type, hasContext)), + (hasContext = resolveDefaultProps(context.type, hasContext)), updateMemoComponent( - current$$1, + current, workInProgress, - renderState, + context, hasContext, updateExpirationTime, renderExpirationTime @@ -7150,7 +6925,7 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { ); case 15: return updateSimpleMemoComponent( - current$$1, + current, workInProgress, workInProgress.type, workInProgress.pendingProps, @@ -7160,30 +6935,25 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { case 17: return ( (updateExpirationTime = workInProgress.type), - (renderState = workInProgress.pendingProps), - (renderState = + (context = workInProgress.pendingProps), + (context = workInProgress.elementType === updateExpirationTime - ? renderState - : resolveDefaultProps(updateExpirationTime, renderState)), - null !== current$$1 && - ((current$$1.alternate = null), + ? context + : resolveDefaultProps(updateExpirationTime, context)), + null !== current && + ((current.alternate = null), (workInProgress.alternate = null), (workInProgress.effectTag |= 2)), (workInProgress.tag = 1), isContextProvider(updateExpirationTime) - ? ((current$$1 = !0), pushContextProvider(workInProgress)) - : (current$$1 = !1), + ? ((current = !0), pushContextProvider(workInProgress)) + : (current = !1), prepareToReadContext(workInProgress, renderExpirationTime), - constructClassInstance( - workInProgress, - updateExpirationTime, - renderState, - renderExpirationTime - ), + constructClassInstance(workInProgress, updateExpirationTime, context), mountClassInstance( workInProgress, updateExpirationTime, - renderState, + context, renderExpirationTime ), finishClassComponent( @@ -7191,13 +6961,13 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { workInProgress, updateExpirationTime, !0, - current$$1, + current, renderExpirationTime ) ); case 19: return updateSuspenseListComponent( - current$$1, + current, workInProgress, renderExpirationTime ); @@ -7248,9 +7018,6 @@ 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); @@ -7268,7 +7035,7 @@ function resolveLazyComponentTag(Component) { function createWorkInProgress(current, pendingProps) { var workInProgress = current.alternate; null === workInProgress - ? ((workInProgress = createFiber( + ? ((workInProgress = new FiberNode( current.tag, pendingProps, current.key, @@ -7335,7 +7102,7 @@ function createFiberFromTypeAndProps( break; case REACT_PROFILER_TYPE: return ( - (type = createFiber(12, pendingProps, key, mode | 8)), + (type = new FiberNode(12, pendingProps, key, mode | 8)), (type.elementType = REACT_PROFILER_TYPE), (type.type = REACT_PROFILER_TYPE), (type.expirationTime = expirationTime), @@ -7343,7 +7110,7 @@ function createFiberFromTypeAndProps( ); case REACT_SUSPENSE_TYPE: return ( - (type = createFiber(13, pendingProps, key, mode)), + (type = new FiberNode(13, pendingProps, key, mode)), (type.type = REACT_SUSPENSE_TYPE), (type.elementType = REACT_SUSPENSE_TYPE), (type.expirationTime = expirationTime), @@ -7351,7 +7118,7 @@ function createFiberFromTypeAndProps( ); case REACT_SUSPENSE_LIST_TYPE: return ( - (type = createFiber(19, pendingProps, key, mode)), + (type = new FiberNode(19, pendingProps, key, mode)), (type.elementType = REACT_SUSPENSE_LIST_TYPE), (type.expirationTime = expirationTime), type @@ -7375,6 +7142,9 @@ 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: " + @@ -7382,24 +7152,24 @@ function createFiberFromTypeAndProps( "." ); } - key = createFiber(fiberTag, pendingProps, key, mode); + key = new FiberNode(fiberTag, pendingProps, key, mode); key.elementType = type; key.type = owner; key.expirationTime = expirationTime; return key; } function createFiberFromFragment(elements, mode, expirationTime, key) { - elements = createFiber(7, elements, key, mode); + elements = new FiberNode(7, elements, key, mode); elements.expirationTime = expirationTime; return elements; } function createFiberFromText(content, mode, expirationTime) { - content = createFiber(6, content, null, mode); + content = new FiberNode(6, content, null, mode); content.expirationTime = expirationTime; return content; } function createFiberFromPortal(portal, mode, expirationTime) { - mode = createFiber( + mode = new FiberNode( 4, null !== portal.children ? portal.children : [], portal.key, @@ -7458,11 +7228,6 @@ 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) { @@ -7477,14 +7242,10 @@ function findHostInstance(component) { return null === component ? null : component.stateNode; } function updateContainer(element, container, parentComponent, callback) { - var current$$1 = container.current, + var current = container.current, currentTime = requestCurrentTimeForUpdate(), suspenseConfig = ReactCurrentBatchConfig.suspense; - currentTime = computeExpirationForFiber( - currentTime, - current$$1, - suspenseConfig - ); + currentTime = computeExpirationForFiber(currentTime, current, suspenseConfig); a: if (parentComponent) { parentComponent = parentComponent._reactInternalFiber; b: { @@ -7535,8 +7296,8 @@ function updateContainer(element, container, parentComponent, callback) { container.payload = { element: element }; callback = void 0 === callback ? null : callback; null !== callback && (container.callback = callback); - enqueueUpdate(current$$1, container); - scheduleUpdateOnFiber(current$$1, currentTime); + enqueueUpdate(current, container); + scheduleWork(current, currentTime); return currentTime; } function createPortal(children, containerInfo, implementation) { @@ -7550,7 +7311,6 @@ 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; @@ -7561,8 +7321,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; @@ -7574,289 +7334,114 @@ batchedUpdatesImpl = function(fn, a) { executionContext === NoContext && flushSyncCallbackQueue(); } }; -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; - }, - findNodeHandle: findNodeHandle, - dispatchCommand: function(handle, command, args) { - null != handle._nativeTag && - null != handle._internalInstanceHandle && - fabricDispatchCommand( - handle._internalInstanceHandle.stateNode.node, - 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.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) - } - }; +var roots = new Map(); (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 - }) - ); + 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; + }, + 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.11.0", - rendererPackageName: "react-native-renderer" + 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) + } }); -var ReactFabric$2 = { default: ReactFabric }, - ReactFabric$3 = (ReactFabric$2 && ReactFabric) || ReactFabric$2; -module.exports = ReactFabric$3.default || ReactFabric$3; +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); +}; diff --git a/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js b/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js index 90b9fe4a0821c5..be0ac55a7b83dc 100644 --- a/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js +++ b/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js @@ -5,6 +5,7 @@ * LICENSE file in the root directory of this source tree. * * @noflow + * @nolint * @preventMunge * @generated */ @@ -14,86 +15,17 @@ require("react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore"); var ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/ReactNativePrivateInterface"), React = require("react"), Scheduler = require("scheduler"), - 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 + - "`." - ); - } - } - } + tracing = require("scheduler/tracing"); +function getParent(inst) { + do inst = inst.return; + while (inst && 5 !== inst.tag); + return inst ? inst : null; } -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; +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); } -var plugins = [], - eventNameDispatchConfigs = {}, - registrationNameModules = {}; function invokeGuardedCallbackImpl(name, func, context, a, b, c, d, e, f) { var funcArgs = Array.prototype.slice.call(arguments, 3); try { @@ -164,74 +96,6 @@ 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; @@ -249,6 +113,7 @@ function getListener(inst, registrationName) { case "onMouseMoveCapture": case "onMouseUp": case "onMouseUpCapture": + case "onMouseEnter": (props = !props.disabled) || ((inst = inst.type), (props = !( @@ -273,15 +138,21 @@ function getListener(inst, registrationName) { ); return listener; } -function getParent(inst) { - do inst = inst.return; - while (inst && 5 !== inst.tag); - return inst ? inst : null; +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 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 forEachAccumulated(arr, cb, scope) { + Array.isArray(arr) ? arr.forEach(cb, scope) : arr && cb.call(scope, arr); } function accumulateDirectionalDispatches(inst, phase, event) { if ( @@ -349,8 +220,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) @@ -503,53 +374,27 @@ 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))) - : console.warn( - "Cannot record touch move without a touch start.\nTouch Move: %s\n", - "Touch Bank: %s", - printTouch(touch), - printTouchBank() - ); + 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))); } 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))) - : 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; + 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))); } var ResponderTouchHistoryStore = { recordTouchTrack: function(topLevelType, nativeEvent) { @@ -589,10 +434,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; @@ -682,13 +527,7 @@ var eventTypes = { "topTouchCancel" === topLevelType ) if (0 <= trackedTouchCount) --trackedTouchCount; - else - return ( - console.warn( - "Ended a touch event which was not counted in `trackedTouchCount`." - ), - null - ); + else return null; ResponderTouchHistoryStore.recordTouchTrack(topLevelType, nativeEvent); if ( targetInst && @@ -700,10 +539,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; @@ -857,10 +696,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, @@ -923,8 +762,8 @@ var eventTypes = { (topLevelType = shouldSetEventType ? eventTypes.responderTerminate : topLevelType - ? eventTypes.responderRelease - : null) + ? eventTypes.responderRelease + : null) ) (nativeEvent = ResponderSyntheticEvent.getPooled( topLevelType, @@ -948,50 +787,160 @@ 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; -injection.injectEventPluginOrder([ +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([ "ResponderEventPlugin", "ReactNativeBridgeEventPlugin" ]); -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, +recomputePluginOrdering(); +var injectedNamesToPlugins$jscomp$inline_92 = { + ResponderEventPlugin: ResponderEventPlugin, + ReactNativeBridgeEventPlugin: { + eventTypes: {}, + extractEvents: function( + topLevelType, targetInst, nativeEvent, nativeEventTarget - ); - if (bubbleDispatchConfig) - forEachAccumulated(topLevelType, accumulateTwoPhaseDispatchesSingle); - else if (directDispatchConfig) - forEachAccumulated(topLevelType, accumulateDirectDispatchesSingle); - else return null; - return topLevelType; + ) { + 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; } } -}); -var enableNativeTargetAsInstance = require("../shims/ReactFeatureFlags") - .enableNativeTargetAsInstance; +isOrderingDirty$jscomp$inline_93 && recomputePluginOrdering(); function getInstanceFromInstance(instanceHandle) { return instanceHandle; } @@ -1000,14 +949,8 @@ getFiberCurrentPropsFromNode = function(inst) { }; getInstanceFromNode = getInstanceFromInstance; getNodeFromInstance = function(inst) { - 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."); + inst = inst.stateNode.canonical; + if (!inst._nativeTag) throw Error("All native instances should have a tag."); return inst; }; ResponderEventPlugin.injection.injectGlobalResponderHandler({ @@ -1043,11 +986,9 @@ 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; -hasSymbol && Symbol.for("react.fundamental"); -hasSymbol && Symbol.for("react.responder"); -hasSymbol && Symbol.for("react.scope"); -var MAYBE_ITERATOR_SYMBOL = "function" === typeof Symbol && Symbol.iterator; + 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; function getIteratorFn(maybeIterable) { if (null === maybeIterable || "object" !== typeof maybeIterable) return null; maybeIterable = @@ -1057,9 +998,10 @@ function getIteratorFn(maybeIterable) { } function initializeLazyComponentType(lazyComponent) { if (-1 === lazyComponent._status) { - lazyComponent._status = 0; - var ctor = lazyComponent._ctor; + var ctor = lazyComponent._result; + ctor || (ctor = lazyComponent._ctor); ctor = ctor(); + lazyComponent._status = 0; lazyComponent._result = ctor; ctor.then( function(moduleObject) { @@ -1096,9 +1038,9 @@ function getComponentName(type) { if ("object" === typeof type) switch (type.$$typeof) { case REACT_CONTEXT_TYPE: - return "Context.Consumer"; + return (type.displayName || "Context") + ".Consumer"; case REACT_PROVIDER_TYPE: - return "Context.Provider"; + return (type._context.displayName || "Context") + ".Provider"; case REACT_FORWARD_REF_TYPE: var innerType = type.render; innerType = innerType.displayName || innerType.name || ""; @@ -1108,6 +1050,8 @@ 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); @@ -1297,8 +1241,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)) { @@ -1459,18 +1403,9 @@ 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); @@ -1478,48 +1413,35 @@ function batchedUpdates(fn, bookkeeping) { 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)) - ) - for (bookkeeping = 0; bookkeeping < fn.length; bookkeeping++) - restoreStateOfTarget(fn[bookkeeping]); + isInsideEventHandler = !1; } } -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; +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); } - _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; - enableNativeTargetAsInstance - ? null != target && (eventTarget = target.stateNode.canonical) - : (eventTarget = nativeEvent.target); + if (null != target) { + var stateNode = target.stateNode; + null != stateNode && (eventTarget = stateNode.canonical); + } batchedUpdates(function() { var events = eventTarget; for (var events$jscomp$0 = null, i = 0; i < plugins.length; i++) { @@ -1557,21 +1479,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$1 = nativeFabricUIManager, - createNode = _nativeFabricUIManage$1.createNode, - cloneNode = _nativeFabricUIManage$1.cloneNode, - cloneNodeWithNewChildren = _nativeFabricUIManage$1.cloneNodeWithNewChildren, +var _nativeFabricUIManage = nativeFabricUIManager, + createNode = _nativeFabricUIManage.createNode, + cloneNode = _nativeFabricUIManage.cloneNode, + cloneNodeWithNewChildren = _nativeFabricUIManage.cloneNodeWithNewChildren, cloneNodeWithNewChildrenAndProps = - _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, + _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, getViewConfigForType = ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get, nextReactTag = 2; @@ -1590,10 +1512,10 @@ var ReactFabricHostComponent = (function() { } var _proto = ReactFabricHostComponent.prototype; _proto.blur = function() { - ReactNativePrivateInterface.TextInputState.blurTextInput(this._nativeTag); + ReactNativePrivateInterface.TextInputState.blurTextInput(this); }; _proto.focus = function() { - ReactNativePrivateInterface.TextInputState.focusTextInput(this._nativeTag); + ReactNativePrivateInterface.TextInputState.focusTextInput(this); }; _proto.measure = function(callback) { fabricMeasure( @@ -1655,44 +1577,6 @@ 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) { @@ -1730,21 +1614,17 @@ function isContextProvider(type) { type = type.childContextTypes; return null !== type && void 0 !== type; } -function popContext(fiber) { - pop(didPerformWorkStackCursor, fiber); - pop(contextStackCursor, fiber); -} -function popTopLevelContextObject(fiber) { - pop(didPerformWorkStackCursor, fiber); - pop(contextStackCursor, fiber); +function popContext() { + pop(didPerformWorkStackCursor); + pop(contextStackCursor); } function pushTopLevelContextObject(fiber, context, didChange) { if (contextStackCursor.current !== emptyContextObject) throw Error( "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." ); - push(contextStackCursor, context, fiber); - push(didPerformWorkStackCursor, didChange, fiber); + push(contextStackCursor, context); + push(didPerformWorkStackCursor, didChange); } function processChildContext(fiber, type, parentContext) { var instance = fiber.stateNode; @@ -1762,17 +1642,13 @@ function processChildContext(fiber, type, parentContext) { return Object.assign({}, parentContext, {}, instance); } function pushContextProvider(workInProgress) { - var instance = workInProgress.stateNode; - instance = - (instance && instance.__reactInternalMemoizedMergedChildContext) || + workInProgress = + ((workInProgress = workInProgress.stateNode) && + workInProgress.__reactInternalMemoizedMergedChildContext) || emptyContextObject; previousContext = contextStackCursor.current; - push(contextStackCursor, instance, workInProgress); - push( - didPerformWorkStackCursor, - didPerformWorkStackCursor.current, - workInProgress - ); + push(contextStackCursor, workInProgress); + push(didPerformWorkStackCursor, didPerformWorkStackCursor.current); return !0; } function invalidateContextProvider(workInProgress, type, didChange) { @@ -1782,13 +1658,17 @@ 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 - ? ((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); + ? ((workInProgress = processChildContext( + workInProgress, + type, + previousContext + )), + (instance.__reactInternalMemoizedMergedChildContext = workInProgress), + pop(didPerformWorkStackCursor), + pop(contextStackCursor), + push(contextStackCursor, workInProgress)) + : pop(didPerformWorkStackCursor); + push(didPerformWorkStackCursor, didChange); } var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback, @@ -1855,7 +1735,7 @@ function reactPriorityToSchedulerPriority(reactPriorityLevel) { throw Error("Unknown priority level."); } } -function runWithPriority$1(reactPriorityLevel, fn) { +function runWithPriority(reactPriorityLevel, fn) { reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); return Scheduler_runWithPriority(reactPriorityLevel, fn); } @@ -1887,7 +1767,7 @@ function flushSyncCallbackQueueImpl() { var i = 0; try { var queue = syncQueue; - runWithPriority$1(99, function() { + runWithPriority(99, function() { for (; i < queue.length; i++) { var callback = queue[i]; do callback = callback(!0); @@ -1915,18 +1795,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 is$1 = "function" === typeof Object.is ? Object.is : is, +var objectIs = "function" === typeof Object.is ? Object.is : is, hasOwnProperty = Object.prototype.hasOwnProperty; function shallowEqual(objA, objB) { - if (is$1(objA, objB)) return !0; + if (objectIs(objA, objB)) return !0; if ( "object" !== typeof objA || null === objA || @@ -1940,11 +1820,48 @@ function shallowEqual(objA, objB) { for (keysB = 0; keysB < keysA.length; keysB++) if ( !hasOwnProperty.call(objB, keysA[keysB]) || - !is$1(objA[keysA[keysB]], objB[keysA[keysB]]) + !objectIs(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); @@ -1962,14 +1879,9 @@ 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, providerFiber); + pop(valueCursor); providerFiber.type._context._currentValue2 = currentValue; } function scheduleWorkOnParentPath(parent, renderExpirationTime) { @@ -2024,237 +1936,195 @@ function readContext(context, observedBits) { return context._currentValue2; } var hasForceUpdate = !1; -function createUpdateQueue(baseState) { - return { - baseState: baseState, - firstUpdate: null, - lastUpdate: null, - firstCapturedUpdate: null, - lastCapturedUpdate: null, - firstEffect: null, - lastEffect: null, - firstCapturedEffect: null, - lastCapturedEffect: null +function initializeUpdateQueue(fiber) { + fiber.updateQueue = { + baseState: fiber.memoizedState, + baseQueue: null, + shared: { pending: null }, + effects: null }; } -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 cloneUpdateQueue(current, workInProgress) { + current = current.updateQueue; + workInProgress.updateQueue === current && + (workInProgress.updateQueue = { + baseState: current.baseState, + baseQueue: current.baseQueue, + shared: current.shared, + effects: current.effects + }); } function createUpdate(expirationTime, suspenseConfig) { - return { + expirationTime = { expirationTime: expirationTime, suspenseConfig: suspenseConfig, tag: 0, payload: null, callback: null, - next: null, - nextEffect: null + next: null }; -} -function appendUpdateToQueue(queue, update) { - null === queue.lastUpdate - ? (queue.firstUpdate = queue.lastUpdate = update) - : ((queue.lastUpdate.next = update), (queue.lastUpdate = update)); + return (expirationTime.next = expirationTime); } function enqueueUpdate(fiber, 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)); + 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; + } } 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 && - 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; + 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)); } function processUpdateQueue( - workInProgress, - queue, + workInProgress$jscomp$0, props, instance, renderExpirationTime ) { + var queue = workInProgress$jscomp$0.updateQueue; hasForceUpdate = !1; - queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue); - for ( - var newBaseState = queue.baseState, - newFirstUpdate = null, - newExpirationTime = 0, - 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; + 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)); } - 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; + if (null !== baseQueue) { + baseFirst = baseQueue.next; + var newState = queue.baseState, + 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; } - 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) { - 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); + 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); + } } - effect = effect.nextEffect; - } } var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig, emptyRefsObject = new React.Component().refs; @@ -2271,10 +2141,8 @@ function applyDerivedStateFromProps( ? ctor : Object.assign({}, ctor, getDerivedStateFromProps); workInProgress.memoizedState = getDerivedStateFromProps; - nextProps = workInProgress.updateQueue; - null !== nextProps && - 0 === workInProgress.expirationTime && - (nextProps.baseState = getDerivedStateFromProps); + 0 === workInProgress.expirationTime && + (workInProgress.updateQueue.baseState = getDerivedStateFromProps); } var classComponentUpdater = { isMounted: function(component) { @@ -2293,7 +2161,7 @@ var classComponentUpdater = { null !== callback && (suspenseConfig.callback = callback); enqueueUpdate(inst, suspenseConfig); - scheduleUpdateOnFiber(inst, currentTime); + scheduleWork(inst, currentTime); }, enqueueReplaceState: function(inst, payload, callback) { inst = inst._reactInternalFiber; @@ -2307,7 +2175,7 @@ var classComponentUpdater = { null !== callback && (suspenseConfig.callback = callback); enqueueUpdate(inst, suspenseConfig); - scheduleUpdateOnFiber(inst, currentTime); + scheduleWork(inst, currentTime); }, enqueueForceUpdate: function(inst, callback) { inst = inst._reactInternalFiber; @@ -2320,7 +2188,7 @@ var classComponentUpdater = { null !== callback && (suspenseConfig.callback = callback); enqueueUpdate(inst, suspenseConfig); - scheduleUpdateOnFiber(inst, currentTime); + scheduleWork(inst, currentTime); } }; function checkShouldComponentUpdate( @@ -2336,8 +2204,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, @@ -2389,23 +2257,16 @@ 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)) : ((contextType = isContextProvider(ctor) - ? previousContext - : contextStackCursor.current), - (instance.context = getMaskedContext(workInProgress, contextType))); - contextType = workInProgress.updateQueue; - null !== contextType && - (processUpdateQueue( - workInProgress, - contextType, - newProps, - instance, - renderExpirationTime - ), - (instance.state = workInProgress.memoizedState)); + ? previousContext + : contextStackCursor.current), + (instance.context = getMaskedContext(workInProgress, contextType))); + processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); + instance.state = workInProgress.memoizedState; contextType = ctor.getDerivedStateFromProps; "function" === typeof contextType && (applyDerivedStateFromProps(workInProgress, ctor, contextType, newProps), @@ -2421,21 +2282,18 @@ function mountClassInstance( instance.UNSAFE_componentWillMount(), ctor !== instance.state && classComponentUpdater.enqueueReplaceState(instance, instance.state, null), - (contextType = workInProgress.updateQueue), - null !== contextType && - (processUpdateQueue( - workInProgress, - contextType, - newProps, - instance, - renderExpirationTime - ), - (instance.state = workInProgress.memoizedState))); + processUpdateQueue( + workInProgress, + newProps, + instance, + renderExpirationTime + ), + (instance.state = workInProgress.memoizedState)); "function" === typeof instance.componentDidMount && (workInProgress.effectTag |= 4); } var isArray = Array.isArray; -function coerceRef(returnFiber, current$$1, element) { +function coerceRef(returnFiber, current, element) { returnFiber = element.ref; if ( null !== returnFiber && @@ -2447,7 +2305,7 @@ function coerceRef(returnFiber, current$$1, element) { if (element) { if (1 !== element.tag) throw Error( - "Function components cannot have refs. Did you mean to use React.forwardRef()?" + "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" ); var inst = element.stateNode; } @@ -2459,19 +2317,19 @@ function coerceRef(returnFiber, current$$1, element) { ); var stringRef = "" + returnFiber; if ( - null !== current$$1 && - null !== current$$1.ref && - "function" === typeof current$$1.ref && - current$$1.ref._stringRef === stringRef + null !== current && + null !== current.ref && + "function" === typeof current.ref && + current.ref._stringRef === stringRef ) - return current$$1.ref; - current$$1 = function(value) { + return current.ref; + current = function(value) { var refs = inst.refs; refs === emptyRefsObject && (refs = inst.refs = {}); null === value ? delete refs[stringRef] : (refs[stringRef] = value); }; - current$$1._stringRef = stringRef; - return current$$1; + current._stringRef = stringRef; + return current; } if ("string" !== typeof returnFiber) throw Error( @@ -2523,8 +2381,8 @@ function ChildReconciler(shouldTrackSideEffects) { (currentFirstChild = currentFirstChild.sibling); return returnFiber; } - function useFiber(fiber, pendingProps, expirationTime) { - fiber = createWorkInProgress(fiber, pendingProps, expirationTime); + function useFiber(fiber, pendingProps) { + fiber = createWorkInProgress(fiber, pendingProps); fiber.index = 0; fiber.sibling = null; return fiber; @@ -2549,31 +2407,26 @@ function ChildReconciler(shouldTrackSideEffects) { (newFiber.effectTag = 2); return newFiber; } - function updateTextNode( - returnFiber, - current$$1, - textContent, - expirationTime - ) { - if (null === current$$1 || 6 !== current$$1.tag) + function updateTextNode(returnFiber, current, textContent, expirationTime) { + if (null === current || 6 !== current.tag) return ( - (current$$1 = createFiberFromText( + (current = createFiberFromText( textContent, returnFiber.mode, expirationTime )), - (current$$1.return = returnFiber), - current$$1 + (current.return = returnFiber), + current ); - current$$1 = useFiber(current$$1, textContent, expirationTime); - current$$1.return = returnFiber; - return current$$1; + current = useFiber(current, textContent); + current.return = returnFiber; + return current; } - function updateElement(returnFiber, current$$1, element, expirationTime) { - if (null !== current$$1 && current$$1.elementType === element.type) + function updateElement(returnFiber, current, element, expirationTime) { + if (null !== current && current.elementType === element.type) return ( - (expirationTime = useFiber(current$$1, element.props, expirationTime)), - (expirationTime.ref = coerceRef(returnFiber, current$$1, element)), + (expirationTime = useFiber(current, element.props)), + (expirationTime.ref = coerceRef(returnFiber, current, element)), (expirationTime.return = returnFiber), expirationTime ); @@ -2585,51 +2438,45 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime ); - expirationTime.ref = coerceRef(returnFiber, current$$1, element); + expirationTime.ref = coerceRef(returnFiber, current, element); expirationTime.return = returnFiber; return expirationTime; } - function updatePortal(returnFiber, current$$1, portal, expirationTime) { + function updatePortal(returnFiber, current, portal, expirationTime) { if ( - null === current$$1 || - 4 !== current$$1.tag || - current$$1.stateNode.containerInfo !== portal.containerInfo || - current$$1.stateNode.implementation !== portal.implementation + null === current || + 4 !== current.tag || + current.stateNode.containerInfo !== portal.containerInfo || + current.stateNode.implementation !== portal.implementation ) return ( - (current$$1 = createFiberFromPortal( + (current = createFiberFromPortal( portal, returnFiber.mode, expirationTime )), - (current$$1.return = returnFiber), - current$$1 + (current.return = returnFiber), + current ); - current$$1 = useFiber(current$$1, portal.children || [], expirationTime); - current$$1.return = returnFiber; - return current$$1; + current = useFiber(current, portal.children || []); + current.return = returnFiber; + return current; } - function updateFragment( - returnFiber, - current$$1, - fragment, - expirationTime, - key - ) { - if (null === current$$1 || 7 !== current$$1.tag) + function updateFragment(returnFiber, current, fragment, expirationTime, key) { + if (null === current || 7 !== current.tag) return ( - (current$$1 = createFiberFromFragment( + (current = createFiberFromFragment( fragment, returnFiber.mode, expirationTime, key )), - (current$$1.return = returnFiber), - current$$1 + (current.return = returnFiber), + current ); - current$$1 = useFiber(current$$1, fragment, expirationTime); - current$$1.return = returnFiber; - return current$$1; + current = useFiber(current, fragment); + current.return = returnFiber; + return current; } function createChild(returnFiber, newChild, expirationTime) { if ("string" === typeof newChild || "number" === typeof newChild) @@ -2992,39 +2839,48 @@ function ChildReconciler(shouldTrackSideEffects) { null !== isUnkeyedTopLevelFragment; ) { - 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; + 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; + } } - else deleteChild(returnFiber, isUnkeyedTopLevelFragment); + deleteRemainingChildren(returnFiber, isUnkeyedTopLevelFragment); + break; + } else deleteChild(returnFiber, isUnkeyedTopLevelFragment); isUnkeyedTopLevelFragment = isUnkeyedTopLevelFragment.sibling; } newChild.type === REACT_FRAGMENT_TYPE @@ -3074,8 +2930,7 @@ function ChildReconciler(shouldTrackSideEffects) { ); currentFirstChild = useFiber( currentFirstChild, - newChild.children || [], - expirationTime + newChild.children || [] ); currentFirstChild.return = returnFiber; returnFiber = currentFirstChild; @@ -3102,11 +2957,7 @@ function ChildReconciler(shouldTrackSideEffects) { (newChild = "" + newChild), null !== currentFirstChild && 6 === currentFirstChild.tag ? (deleteRemainingChildren(returnFiber, currentFirstChild.sibling), - (currentFirstChild = useFiber( - currentFirstChild, - newChild, - expirationTime - )), + (currentFirstChild = useFiber(currentFirstChild, newChild)), (currentFirstChild.return = returnFiber), (returnFiber = currentFirstChild)) : (deleteRemainingChildren(returnFiber, currentFirstChild), @@ -3161,16 +3012,16 @@ function requiredContext(c) { return c; } function pushHostContainer(fiber, nextRootInstance) { - push(rootInstanceStackCursor, nextRootInstance, fiber); - push(contextFiberStackCursor, fiber, fiber); - push(contextStackCursor$1, NO_CONTEXT, fiber); - pop(contextStackCursor$1, fiber); - push(contextStackCursor$1, { isInAParentText: !1 }, fiber); + push(rootInstanceStackCursor, nextRootInstance); + push(contextFiberStackCursor, fiber); + push(contextStackCursor$1, NO_CONTEXT); + pop(contextStackCursor$1); + push(contextStackCursor$1, { isInAParentText: !1 }); } -function popHostContainer(fiber) { - pop(contextStackCursor$1, fiber); - pop(contextFiberStackCursor, fiber); - pop(rootInstanceStackCursor, fiber); +function popHostContainer() { + pop(contextStackCursor$1); + pop(contextFiberStackCursor); + pop(rootInstanceStackCursor); } function pushHostContext(fiber) { requiredContext(rootInstanceStackCursor.current); @@ -3187,23 +3038,19 @@ function pushHostContext(fiber) { ? { isInAParentText: nextContext } : context; context !== nextContext && - (push(contextFiberStackCursor, fiber, fiber), - push(contextStackCursor$1, nextContext, fiber)); + (push(contextFiberStackCursor, fiber), + push(contextStackCursor$1, nextContext)); } function popHostContext(fiber) { contextFiberStackCursor.current === fiber && - (pop(contextStackCursor$1, fiber), pop(contextFiberStackCursor, fiber)); + (pop(contextStackCursor$1), pop(contextFiberStackCursor)); } var suspenseStackCursor = { current: 0 }; function findFirstSuspended(row) { for (var node = row; null !== node; ) { if (13 === node.tag) { var state = node.memoizedState; - if ( - null !== state && - ((state = state.dehydrated), - null === state || shim$1(state) || shim$1(state)) - ) + if (null !== state && (null === state.dehydrated || shim$1() || shim$1())) return node; } else if (19 === node.tag && void 0 !== node.memoizedProps.revealOrder) { if (0 !== (node.effectTag & 64)) return node; @@ -3222,24 +3069,16 @@ function findFirstSuspended(row) { } return null; } -function createResponderListener(responder, props) { +function createDeprecatedResponderListener(responder, props) { return { responder: responder, props: props }; } -var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, +var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig, - renderExpirationTime$1 = 0, + renderExpirationTime = 0, currentlyRenderingFiber$1 = null, currentHook = null, - nextCurrentHook = null, - firstWorkInProgressHook = null, workInProgressHook = null, - nextWorkInProgressHook = null, - remainingExpirationTime = 0, - componentUpdateQueue = null, - sideEffectTag = 0, - didScheduleRenderPhaseUpdate = !1, - renderPhaseUpdates = null, - numberOfReRenders = 0; + didScheduleRenderPhaseUpdate = !1; 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." @@ -3248,7 +3087,7 @@ function throwInvalidHookError() { function areHookInputsEqual(nextDeps, prevDeps) { if (null === prevDeps) return !1; for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) - if (!is$1(nextDeps[i], prevDeps[i])) return !1; + if (!objectIs(nextDeps[i], prevDeps[i])) return !1; return !0; } function renderWithHooks( @@ -3256,92 +3095,85 @@ function renderWithHooks( workInProgress, Component, props, - refOrContext, + secondArg, nextRenderExpirationTime ) { - renderExpirationTime$1 = nextRenderExpirationTime; + renderExpirationTime = nextRenderExpirationTime; currentlyRenderingFiber$1 = workInProgress; - 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; + 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); } - 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) + ReactCurrentDispatcher.current = ContextOnlyDispatcher; + workInProgress = null !== currentHook && null !== currentHook.next; + renderExpirationTime = 0; + workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; + didScheduleRenderPhaseUpdate = !1; + if (workInProgress) throw Error( "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." ); - 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; + return current; } function mountWorkInProgressHook() { var hook = { memoizedState: null, baseState: null, + baseQueue: null, queue: null, - baseUpdate: null, next: null }; null === workInProgressHook - ? (firstWorkInProgressHook = workInProgressHook = hook) + ? (currentlyRenderingFiber$1.memoizedState = 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), - (nextWorkInProgressHook = workInProgressHook.next), - (currentHook = nextCurrentHook), - (nextCurrentHook = null !== currentHook ? currentHook.next : null); + (currentHook = nextCurrentHook); else { if (null === nextCurrentHook) throw Error("Rendered more hooks than during the previous render."); currentHook = nextCurrentHook; - var newHook = { + nextCurrentHook = { memoizedState: currentHook.memoizedState, baseState: currentHook.baseState, + baseQueue: currentHook.baseQueue, queue: currentHook.queue, - baseUpdate: currentHook.baseUpdate, next: null }; - workInProgressHook = - null === workInProgressHook - ? (firstWorkInProgressHook = newHook) - : (workInProgressHook.next = newHook); - nextCurrentHook = currentHook.next; + null === workInProgressHook + ? (currentlyRenderingFiber$1.memoizedState = workInProgressHook = nextCurrentHook) + : (workInProgressHook = workInProgressHook.next = nextCurrentHook); } return workInProgressHook; } @@ -3356,74 +3188,100 @@ function updateReducer(reducer) { "Should have a queue. This is likely a bug in React. Please file an issue." ); queue.lastRenderedReducer = reducer; - 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]; - } + 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; } - return [hook.memoizedState, _dispatch]; + current.baseQueue = baseQueue = pendingQueue; + queue.pending = null; } - _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; + if (null !== baseQueue) { + baseQueue = baseQueue.next; + current = current.baseState; + var newBaseQueueLast = (baseFirst = pendingQueue = null), + update = baseQueue; do { - var updateExpirationTime = _update.expirationTime; - updateExpirationTime < renderExpirationTime$1 - ? (didSkip || - ((didSkip = !0), - (newBaseUpdate = baseUpdate), - (firstRenderPhaseUpdate = newState)), - updateExpirationTime > remainingExpirationTime && - ((remainingExpirationTime = updateExpirationTime), - markUnprocessedUpdateTime(remainingExpirationTime))) - : (markRenderEventTimeAndConfig( + 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( updateExpirationTime, - _update.suspenseConfig + update.suspenseConfig ), - (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); + (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); hook.memoizedState = newState; - hook.baseUpdate = newBaseUpdate; - hook.baseState = firstRenderPhaseUpdate; + null === hook.baseQueue && (hook.baseState = newState); queue.lastRenderedState = newState; } - return [hook.memoizedState, queue.dispatch]; + return [newState, dispatch]; } function mountState(initialState) { var hook = mountWorkInProgressHook(); "function" === typeof initialState && (initialState = initialState()); hook.memoizedState = hook.baseState = initialState; initialState = hook.queue = { - last: null, + pending: null, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState @@ -3435,28 +3293,30 @@ 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 }; - 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))); + 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))); return tag; } +function updateRef() { + return updateWorkInProgressHook().memoizedState; +} function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var hook = mountWorkInProgressHook(); - sideEffectTag |= fiberEffectTag; + currentlyRenderingFiber$1.effectTag |= fiberEffectTag; hook.memoizedState = pushEffect( - hookEffectTag, + 1 | hookEffectTag, create, void 0, void 0 === deps ? null : deps @@ -3470,18 +3330,21 @@ function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var prevEffect = currentHook.memoizedState; destroy = prevEffect.destroy; if (null !== deps && areHookInputsEqual(deps, prevEffect.deps)) { - pushEffect(0, create, destroy, deps); + pushEffect(hookEffectTag, create, destroy, deps); return; } } - sideEffectTag |= fiberEffectTag; - hook.memoizedState = pushEffect(hookEffectTag, create, destroy, deps); + currentlyRenderingFiber$1.effectTag |= fiberEffectTag; + hook.memoizedState = pushEffect(1 | hookEffectTag, create, destroy, deps); } function mountEffect(create, deps) { - return mountEffectImpl(516, 192, create, deps); + return mountEffectImpl(516, 4, create, deps); } function updateEffect(create, deps) { - return updateEffectImpl(516, 192, create, deps); + return updateEffectImpl(516, 4, create, deps); +} +function updateLayoutEffect(create, deps) { + return updateEffectImpl(4, 2, create, deps); } function imperativeHandleEffect(create, ref) { if ("function" === typeof ref) @@ -3501,6 +3364,15 @@ 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 = [ @@ -3522,72 +3394,79 @@ 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) { - if (!(25 > numberOfReRenders)) - throw Error( - "Too many re-renders. React limits the number of renders to prevent an infinite loop." - ); - var alternate = fiber.alternate; + 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 ( fiber === currentlyRenderingFiber$1 || - (null !== alternate && alternate === currentlyRenderingFiber$1) + (null !== pending && pending === currentlyRenderingFiber$1) ) - 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; - } + (didScheduleRenderPhaseUpdate = !0), + (suspenseConfig.expirationTime = renderExpirationTime), + (currentlyRenderingFiber$1.expirationTime = renderExpirationTime); 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 === alternate || 0 === alternate.expirationTime) && - ((alternate = queue.lastRenderedReducer), null !== alternate) + (null === pending || 0 === pending.expirationTime) && + ((pending = queue.lastRenderedReducer), null !== pending) ) try { var currentState = queue.lastRenderedState, - eagerState = alternate(currentState, action); - suspenseConfig.eagerReducer = alternate; + eagerState = pending(currentState, action); + suspenseConfig.eagerReducer = pending; suspenseConfig.eagerState = eagerState; - if (is$1(eagerState, currentState)) return; + if (objectIs(eagerState, currentState)) return; } catch (error) { } finally { } - scheduleUpdateOnFiber(fiber, currentTime); + scheduleWork(fiber, currentTime); } } +function updateEventListener() {} var ContextOnlyDispatcher = { readContext: readContext, useCallback: throwInvalidHookError, @@ -3602,7 +3481,8 @@ var ContextOnlyDispatcher = { useDebugValue: throwInvalidHookError, useResponder: throwInvalidHookError, useDeferredValue: throwInvalidHookError, - useTransition: throwInvalidHookError + useTransition: throwInvalidHookError, + useEvent: throwInvalidHookError }, HooksDispatcherOnMount = { readContext: readContext, @@ -3613,13 +3493,13 @@ var ContextOnlyDispatcher = { deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; return mountEffectImpl( 4, - 36, + 2, imperativeHandleEffect.bind(null, create, ref), deps ); }, useLayoutEffect: function(create, deps) { - return mountEffectImpl(4, 36, create, deps); + return mountEffectImpl(4, 2, create, deps); }, useMemo: function(nextCreate, deps) { var hook = mountWorkInProgressHook(); @@ -3633,7 +3513,7 @@ var ContextOnlyDispatcher = { initialArg = void 0 !== init ? init(initialArg) : initialArg; hook.memoizedState = hook.baseState = initialArg; reducer = hook.queue = { - last: null, + pending: null, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialArg @@ -3652,23 +3532,21 @@ var ContextOnlyDispatcher = { }, useState: mountState, useDebugValue: mountDebugValue, - useResponder: createResponderListener, + useResponder: createDeprecatedResponderListener, useDeferredValue: function(value, config) { var _mountState = mountState(value), prevValue = _mountState[0], setValue = _mountState[1]; mountEffect( function() { - 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; - } - }); + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } }, [value, config] ); @@ -3676,112 +3554,113 @@ var ContextOnlyDispatcher = { }, useTransition: function(config) { var _mountState2 = mountState(!1), - isPending = _mountState2[0], - setPending = _mountState2[1]; + isPending = _mountState2[0]; + _mountState2 = _mountState2[1]; return [ - 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] - ), + mountCallback(startTransition.bind(null, _mountState2, config), [ + _mountState2, + config + ]), isPending ]; - } + }, + useEvent: function() {} }, HooksDispatcherOnUpdate = { readContext: readContext, useCallback: updateCallback, useContext: readContext, useEffect: updateEffect, - 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; - }, + useImperativeHandle: updateImperativeHandle, + useLayoutEffect: updateLayoutEffect, + useMemo: updateMemo, useReducer: updateReducer, - useRef: function() { - return updateWorkInProgressHook().memoizedState; + useRef: updateRef, + useState: function() { + return updateReducer(basicStateReducer); }, - useState: updateState, useDebugValue: mountDebugValue, - useResponder: createResponderListener, + useResponder: createDeprecatedResponderListener, useDeferredValue: function(value, config) { - var _updateState = updateState(value), + var _updateState = updateReducer(basicStateReducer), prevValue = _updateState[0], setValue = _updateState[1]; updateEffect( function() { - 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; - } - }); + 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 = updateState(!1), - isPending = _updateState2[0], - setPending = _updateState2[1]; + var _updateState2 = updateReducer(basicStateReducer), + isPending = _updateState2[0]; + _updateState2 = _updateState2[1]; return [ - 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] - ), + updateCallback(startTransition.bind(null, _updateState2, config), [ + _updateState2, + config + ]), 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] + ); + 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 }, now$1 = Scheduler.unstable_now, commitTime = 0, @@ -3794,70 +3673,16 @@ function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) { profilerStartTime = -1; } } -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, +var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner, didReceiveUpdate = !1; function reconcileChildren( - current$$1, + current, workInProgress, nextChildren, renderExpirationTime ) { workInProgress.child = - null === current$$1 + null === current ? mountChildFibers( workInProgress, null, @@ -3866,13 +3691,13 @@ function reconcileChildren( ) : reconcileChildFibers( workInProgress, - current$$1.child, + current.child, nextChildren, renderExpirationTime ); } function updateForwardRef( - current$$1, + current, workInProgress, Component, nextProps, @@ -3882,43 +3707,38 @@ function updateForwardRef( var ref = workInProgress.ref; prepareToReadContext(workInProgress, renderExpirationTime); nextProps = renderWithHooks( - current$$1, + current, workInProgress, Component, nextProps, ref, renderExpirationTime ); - if (null !== current$$1 && !didReceiveUpdate) + if (null !== current && !didReceiveUpdate) return ( - (workInProgress.updateQueue = current$$1.updateQueue), + (workInProgress.updateQueue = current.updateQueue), (workInProgress.effectTag &= -517), - current$$1.expirationTime <= renderExpirationTime && - (current$$1.expirationTime = 0), + current.expirationTime <= renderExpirationTime && + (current.expirationTime = 0), bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ) ); workInProgress.effectTag |= 1; - reconcileChildren( - current$$1, - workInProgress, - nextProps, - renderExpirationTime - ); + reconcileChildren(current, workInProgress, nextProps, renderExpirationTime); return workInProgress.child; } function updateMemoComponent( - current$$1, + current, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime ) { - if (null === current$$1) { + if (null === current) { var type = Component.type; if ( "function" === typeof type && @@ -3931,7 +3751,7 @@ function updateMemoComponent( (workInProgress.tag = 15), (workInProgress.type = type), updateSimpleMemoComponent( - current$$1, + current, workInProgress, type, nextProps, @@ -3939,7 +3759,7 @@ function updateMemoComponent( renderExpirationTime ) ); - current$$1 = createFiberFromTypeAndProps( + current = createFiberFromTypeAndProps( Component.type, null, nextProps, @@ -3947,65 +3767,66 @@ function updateMemoComponent( workInProgress.mode, renderExpirationTime ); - current$$1.ref = workInProgress.ref; - current$$1.return = workInProgress; - return (workInProgress.child = current$$1); + current.ref = workInProgress.ref; + current.return = workInProgress; + return (workInProgress.child = current); } - type = current$$1.child; + type = current.child; if ( updateExpirationTime < renderExpirationTime && ((updateExpirationTime = type.memoizedProps), (Component = Component.compare), (Component = null !== Component ? Component : shallowEqual), Component(updateExpirationTime, nextProps) && - current$$1.ref === workInProgress.ref) + current.ref === workInProgress.ref) ) return bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ); workInProgress.effectTag |= 1; - current$$1 = createWorkInProgress(type, nextProps, renderExpirationTime); - current$$1.ref = workInProgress.ref; - current$$1.return = workInProgress; - return (workInProgress.child = current$$1); + current = createWorkInProgress(type, nextProps); + current.ref = workInProgress.ref; + current.return = workInProgress; + return (workInProgress.child = current); } function updateSimpleMemoComponent( - current$$1, + current, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime ) { - return null !== current$$1 && - shallowEqual(current$$1.memoizedProps, nextProps) && - current$$1.ref === workInProgress.ref && + return null !== current && + shallowEqual(current.memoizedProps, nextProps) && + current.ref === workInProgress.ref && ((didReceiveUpdate = !1), updateExpirationTime < renderExpirationTime) - ? bailoutOnAlreadyFinishedWork( - current$$1, + ? ((workInProgress.expirationTime = current.expirationTime), + bailoutOnAlreadyFinishedWork( + current, workInProgress, renderExpirationTime - ) + )) : updateFunctionComponent( - current$$1, + current, workInProgress, Component, nextProps, renderExpirationTime ); } -function markRef(current$$1, workInProgress) { +function markRef(current, workInProgress) { var ref = workInProgress.ref; if ( - (null === current$$1 && null !== ref) || - (null !== current$$1 && current$$1.ref !== ref) + (null === current && null !== ref) || + (null !== current && current.ref !== ref) ) workInProgress.effectTag |= 128; } function updateFunctionComponent( - current$$1, + current, workInProgress, Component, nextProps, @@ -4017,36 +3838,31 @@ function updateFunctionComponent( context = getMaskedContext(workInProgress, context); prepareToReadContext(workInProgress, renderExpirationTime); Component = renderWithHooks( - current$$1, + current, workInProgress, Component, nextProps, context, renderExpirationTime ); - if (null !== current$$1 && !didReceiveUpdate) + if (null !== current && !didReceiveUpdate) return ( - (workInProgress.updateQueue = current$$1.updateQueue), + (workInProgress.updateQueue = current.updateQueue), (workInProgress.effectTag &= -517), - current$$1.expirationTime <= renderExpirationTime && - (current$$1.expirationTime = 0), + current.expirationTime <= renderExpirationTime && + (current.expirationTime = 0), bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ) ); workInProgress.effectTag |= 1; - reconcileChildren( - current$$1, - workInProgress, - Component, - renderExpirationTime - ); + reconcileChildren(current, workInProgress, Component, renderExpirationTime); return workInProgress.child; } function updateClassComponent( - current$$1, + current, workInProgress, Component, nextProps, @@ -4058,16 +3874,11 @@ function updateClassComponent( } else hasContext = !1; prepareToReadContext(workInProgress, renderExpirationTime); if (null === workInProgress.stateNode) - null !== current$$1 && - ((current$$1.alternate = null), + null !== current && + ((current.alternate = null), (workInProgress.alternate = null), (workInProgress.effectTag |= 2)), - constructClassInstance( - workInProgress, - Component, - nextProps, - renderExpirationTime - ), + constructClassInstance(workInProgress, Component, nextProps), mountClassInstance( workInProgress, Component, @@ -4075,7 +3886,7 @@ function updateClassComponent( renderExpirationTime ), (nextProps = !0); - else if (null === current$$1) { + else if (null === current) { var instance = workInProgress.stateNode, oldProps = workInProgress.memoizedProps; instance.props = oldProps; @@ -4103,17 +3914,14 @@ function updateClassComponent( )); hasForceUpdate = !1; var oldState = workInProgress.memoizedState; - oldContext = instance.state = oldState; - var updateQueue = workInProgress.updateQueue; - null !== updateQueue && - (processUpdateQueue( - workInProgress, - updateQueue, - nextProps, - instance, - renderExpirationTime - ), - (oldContext = workInProgress.memoizedState)); + instance.state = oldState; + processUpdateQueue( + workInProgress, + nextProps, + instance, + renderExpirationTime + ); + oldContext = workInProgress.memoizedState; oldProps !== nextProps || oldState !== oldContext || didPerformWorkStackCursor.current || @@ -4159,6 +3967,7 @@ function updateClassComponent( (nextProps = !1)); } else (instance = workInProgress.stateNode), + cloneUpdateQueue(current, workInProgress), (oldProps = workInProgress.memoizedProps), (instance.props = workInProgress.type === workInProgress.elementType @@ -4187,17 +3996,14 @@ function updateClassComponent( )), (hasForceUpdate = !1), (oldContext = workInProgress.memoizedState), - (oldState = instance.state = oldContext), - (updateQueue = workInProgress.updateQueue), - null !== updateQueue && - (processUpdateQueue( - workInProgress, - updateQueue, - nextProps, - instance, - renderExpirationTime - ), - (oldState = workInProgress.memoizedState)), + (instance.state = oldContext), + processUpdateQueue( + workInProgress, + nextProps, + instance, + renderExpirationTime + ), + (oldState = workInProgress.memoizedState), oldProps !== nextProps || oldContext !== oldState || didPerformWorkStackCursor.current || @@ -4241,12 +4047,12 @@ function updateClassComponent( "function" === typeof instance.getSnapshotBeforeUpdate && (workInProgress.effectTag |= 256)) : ("function" !== typeof instance.componentDidUpdate || - (oldProps === current$$1.memoizedProps && - oldContext === current$$1.memoizedState) || + (oldProps === current.memoizedProps && + oldContext === current.memoizedState) || (workInProgress.effectTag |= 4), "function" !== typeof instance.getSnapshotBeforeUpdate || - (oldProps === current$$1.memoizedProps && - oldContext === current$$1.memoizedState) || + (oldProps === current.memoizedProps && + oldContext === current.memoizedState) || (workInProgress.effectTag |= 256), (workInProgress.memoizedProps = nextProps), (workInProgress.memoizedState = oldState)), @@ -4255,16 +4061,16 @@ function updateClassComponent( (instance.context = contextType), (nextProps = getDerivedStateFromProps)) : ("function" !== typeof instance.componentDidUpdate || - (oldProps === current$$1.memoizedProps && - oldContext === current$$1.memoizedState) || + (oldProps === current.memoizedProps && + oldContext === current.memoizedState) || (workInProgress.effectTag |= 4), "function" !== typeof instance.getSnapshotBeforeUpdate || - (oldProps === current$$1.memoizedProps && - oldContext === current$$1.memoizedState) || + (oldProps === current.memoizedProps && + oldContext === current.memoizedState) || (workInProgress.effectTag |= 256), (nextProps = !1)); return finishClassComponent( - current$$1, + current, workInProgress, Component, nextProps, @@ -4273,26 +4079,26 @@ function updateClassComponent( ); } function finishClassComponent( - current$$1, + current, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime ) { - markRef(current$$1, workInProgress); + markRef(current, workInProgress); var didCaptureError = 0 !== (workInProgress.effectTag & 64); if (!shouldUpdate && !didCaptureError) return ( hasContext && invalidateContextProvider(workInProgress, Component, !1), bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ) ); shouldUpdate = workInProgress.stateNode; - ReactCurrentOwner$3.current = workInProgress; + ReactCurrentOwner$1.current = workInProgress; if ( didCaptureError && "function" !== typeof Component.getDerivedStateFromError @@ -4301,11 +4107,11 @@ function finishClassComponent( profilerStartTime = -1; } else nextChildren = shouldUpdate.render(); workInProgress.effectTag |= 1; - null !== current$$1 && didCaptureError + null !== current && didCaptureError ? ((didCaptureError = nextChildren), (workInProgress.child = reconcileChildFibers( workInProgress, - current$$1.child, + current.child, null, renderExpirationTime )), @@ -4316,7 +4122,7 @@ function finishClassComponent( renderExpirationTime ))) : reconcileChildren( - current$$1, + current, workInProgress, nextChildren, renderExpirationTime @@ -4339,7 +4145,7 @@ function pushHostRootContext(workInProgress) { } var SUSPENDED_MARKER = { dehydrated: null, retryTime: 0 }; function updateSuspenseComponent( - current$$1, + current, workInProgress, renderExpirationTime ) { @@ -4351,32 +4157,30 @@ function updateSuspenseComponent( (JSCompiler_temp = 0 !== (workInProgress.effectTag & 64)) || (JSCompiler_temp = 0 !== (suspenseContext & 2) && - (null === current$$1 || null !== current$$1.memoizedState)); + (null === current || null !== current.memoizedState)); JSCompiler_temp ? ((nextDidTimeout = !0), (workInProgress.effectTag &= -65)) - : (null !== current$$1 && null === current$$1.memoizedState) || + : (null !== current && null === current.memoizedState) || void 0 === nextProps.fallback || !0 === nextProps.unstable_avoidThisFallback || (suspenseContext |= 1); - push(suspenseStackCursor, suspenseContext & 1, workInProgress); - if (null === current$$1) { - void 0 !== nextProps.fallback && - tryToClaimNextHydratableInstance(workInProgress); + push(suspenseStackCursor, suspenseContext & 1); + if (null === current) { if (nextDidTimeout) { nextDidTimeout = nextProps.fallback; nextProps = createFiberFromFragment(null, mode, 0, null); nextProps.return = workInProgress; if (0 === (workInProgress.mode & 2)) for ( - current$$1 = + current = null !== workInProgress.memoizedState ? workInProgress.child.child : workInProgress.child, - nextProps.child = current$$1; - null !== current$$1; + nextProps.child = current; + null !== current; ) - (current$$1.return = nextProps), (current$$1 = current$$1.sibling); + (current.return = nextProps), (current = current.sibling); renderExpirationTime = createFiberFromFragment( nextDidTimeout, mode, @@ -4398,15 +4202,14 @@ function updateSuspenseComponent( renderExpirationTime )); } - if (null !== current$$1.memoizedState) { - current$$1 = current$$1.child; - mode = current$$1.sibling; + if (null !== current.memoizedState) { + current = current.child; + mode = current.sibling; if (nextDidTimeout) { nextProps = nextProps.fallback; renderExpirationTime = createWorkInProgress( - current$$1, - current$$1.pendingProps, - 0 + current, + current.pendingProps ); renderExpirationTime.return = workInProgress; if ( @@ -4415,7 +4218,7 @@ function updateSuspenseComponent( null !== workInProgress.memoizedState ? workInProgress.child.child : workInProgress.child), - nextDidTimeout !== current$$1.child) + nextDidTimeout !== current.child) ) for ( renderExpirationTime.child = nextDidTimeout; @@ -4426,12 +4229,12 @@ function updateSuspenseComponent( (nextDidTimeout = nextDidTimeout.sibling); if (workInProgress.mode & 8) { nextDidTimeout = 0; - for (current$$1 = renderExpirationTime.child; null !== current$$1; ) - (nextDidTimeout += current$$1.treeBaseDuration), - (current$$1 = current$$1.sibling); + for (current = renderExpirationTime.child; null !== current; ) + (nextDidTimeout += current.treeBaseDuration), + (current = current.sibling); renderExpirationTime.treeBaseDuration = nextDidTimeout; } - mode = createWorkInProgress(mode, nextProps, mode.expirationTime); + mode = createWorkInProgress(mode, nextProps); mode.return = workInProgress; renderExpirationTime.sibling = mode; renderExpirationTime.childExpirationTime = 0; @@ -4441,37 +4244,37 @@ function updateSuspenseComponent( } renderExpirationTime = reconcileChildFibers( workInProgress, - current$$1.child, + current.child, nextProps.children, renderExpirationTime ); workInProgress.memoizedState = null; return (workInProgress.child = renderExpirationTime); } - current$$1 = current$$1.child; + current = current.child; if (nextDidTimeout) { nextDidTimeout = nextProps.fallback; nextProps = createFiberFromFragment(null, mode, 0, null); nextProps.return = workInProgress; - nextProps.child = current$$1; - null !== current$$1 && (current$$1.return = nextProps); + nextProps.child = current; + null !== current && (current.return = nextProps); if (0 === (workInProgress.mode & 2)) for ( - current$$1 = + current = null !== workInProgress.memoizedState ? workInProgress.child.child : workInProgress.child, - nextProps.child = current$$1; - null !== current$$1; + nextProps.child = current; + null !== current; ) - (current$$1.return = nextProps), (current$$1 = current$$1.sibling); + (current.return = nextProps), (current = current.sibling); if (workInProgress.mode & 8) { - current$$1 = 0; + current = 0; for (suspenseContext = nextProps.child; null !== suspenseContext; ) - (current$$1 += suspenseContext.treeBaseDuration), + (current += suspenseContext.treeBaseDuration), (suspenseContext = suspenseContext.sibling); - nextProps.treeBaseDuration = current$$1; + nextProps.treeBaseDuration = current; } renderExpirationTime = createFiberFromFragment( nextDidTimeout, @@ -4490,7 +4293,7 @@ function updateSuspenseComponent( workInProgress.memoizedState = null; return (workInProgress.child = reconcileChildFibers( workInProgress, - current$$1, + current, nextProps.children, renderExpirationTime )); @@ -4517,6 +4320,7 @@ function initSuspenseListRenderState( ? (workInProgress.memoizedState = { isBackwards: isBackwards, rendering: null, + renderingStartTime: 0, last: lastContentRow, tail: tail, tailExpiration: 0, @@ -4525,6 +4329,7 @@ function initSuspenseListRenderState( }) : ((renderState.isBackwards = isBackwards), (renderState.rendering = null), + (renderState.renderingStartTime = 0), (renderState.last = lastContentRow), (renderState.tail = tail), (renderState.tailExpiration = 0), @@ -4532,7 +4337,7 @@ function initSuspenseListRenderState( (renderState.lastEffect = lastEffectBeforeRendering)); } function updateSuspenseListComponent( - current$$1, + current, workInProgress, renderExpirationTime ) { @@ -4540,7 +4345,7 @@ function updateSuspenseListComponent( revealOrder = nextProps.revealOrder, tailMode = nextProps.tail; reconcileChildren( - current$$1, + current, workInProgress, nextProps.children, renderExpirationTime @@ -4549,42 +4354,39 @@ function updateSuspenseListComponent( if (0 !== (nextProps & 2)) (nextProps = (nextProps & 1) | 2), (workInProgress.effectTag |= 64); else { - 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; + 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; continue; - } - if (current$$1 === workInProgress) break a; - for (; null === current$$1.sibling; ) { - if ( - null === current$$1.return || - current$$1.return === workInProgress - ) + } + if (current === workInProgress) break a; + for (; null === current.sibling; ) { + if (null === current.return || current.return === workInProgress) break a; - current$$1 = current$$1.return; + current = current.return; } - current$$1.sibling.return = current$$1.return; - current$$1 = current$$1.sibling; + current.sibling.return = current.return; + current = current.sibling; } nextProps &= 1; } - push(suspenseStackCursor, nextProps, workInProgress); + push(suspenseStackCursor, nextProps); if (0 === (workInProgress.mode & 2)) workInProgress.memoizedState = null; else switch (revealOrder) { case "forwards": renderExpirationTime = workInProgress.child; for (revealOrder = null; null !== renderExpirationTime; ) - (current$$1 = renderExpirationTime.alternate), - null !== current$$1 && - null === findFirstSuspended(current$$1) && + (current = renderExpirationTime.alternate), + null !== current && + null === findFirstSuspended(current) && (revealOrder = renderExpirationTime), (renderExpirationTime = renderExpirationTime.sibling); renderExpirationTime = revealOrder; @@ -4606,15 +4408,15 @@ function updateSuspenseListComponent( renderExpirationTime = null; revealOrder = workInProgress.child; for (workInProgress.child = null; null !== revealOrder; ) { - current$$1 = revealOrder.alternate; - if (null !== current$$1 && null === findFirstSuspended(current$$1)) { + current = revealOrder.alternate; + if (null !== current && null === findFirstSuspended(current)) { workInProgress.child = revealOrder; break; } - current$$1 = revealOrder.sibling; + current = revealOrder.sibling; revealOrder.sibling = renderExpirationTime; renderExpirationTime = revealOrder; - revealOrder = current$$1; + revealOrder = current; } initSuspenseListRenderState( workInProgress, @@ -4641,36 +4443,30 @@ function updateSuspenseListComponent( return workInProgress.child; } function bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ) { - null !== current$$1 && - (workInProgress.dependencies = current$$1.dependencies); + null !== current && (workInProgress.dependencies = current.dependencies); profilerStartTime = -1; var updateExpirationTime = workInProgress.expirationTime; 0 !== updateExpirationTime && markUnprocessedUpdateTime(updateExpirationTime); if (workInProgress.childExpirationTime < renderExpirationTime) return null; - if (null !== current$$1 && workInProgress.child !== current$$1.child) + if (null !== current && workInProgress.child !== current.child) throw Error("Resuming work not yet implemented."); if (null !== workInProgress.child) { - current$$1 = workInProgress.child; - renderExpirationTime = createWorkInProgress( - current$$1, - current$$1.pendingProps, - current$$1.expirationTime - ); + current = workInProgress.child; + renderExpirationTime = createWorkInProgress(current, current.pendingProps); workInProgress.child = renderExpirationTime; for ( renderExpirationTime.return = workInProgress; - null !== current$$1.sibling; + null !== current.sibling; ) - (current$$1 = current$$1.sibling), + (current = current.sibling), (renderExpirationTime = renderExpirationTime.sibling = createWorkInProgress( - current$$1, - current$$1.pendingProps, - current$$1.expirationTime + current, + current.pendingProps )), (renderExpirationTime.return = workInProgress); renderExpirationTime.sibling = null; @@ -4692,12 +4488,7 @@ appendAllChildren = function( var instance = node.stateNode; needsVisibilityToggle && isHidden && - (instance = cloneHiddenInstance( - instance, - node.type, - node.memoizedProps, - node - )); + (instance = cloneHiddenInstance(instance)); appendChildNode(parent.node, instance.node); } else if (6 === node.tag) { instance = node.stateNode; @@ -4750,12 +4541,7 @@ function appendAllChildrenToContainer( var instance = node.stateNode; needsVisibilityToggle && isHidden && - (instance = cloneHiddenInstance( - instance, - node.type, - node.memoizedProps, - node - )); + (instance = cloneHiddenInstance(instance)); appendChildNodeToSet(containerChildSet, instance.node); } else if (6 === node.tag) { instance = node.stateNode; @@ -4841,8 +4627,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), @@ -4852,16 +4638,17 @@ 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)); + 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); }; function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { switch (renderState.tailMode) { @@ -4887,67 +4674,78 @@ function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { : (_lastTailNode.sibling = null); } } -function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { +function completeWork(current, workInProgress, renderExpirationTime) { var newProps = workInProgress.pendingProps; switch (workInProgress.tag) { case 2: - break; case 16: - break; case 15: case 0: - break; + case 11: + case 7: + case 8: + case 12: + case 9: + case 14: + return null; case 1: - isContextProvider(workInProgress.type) && popContext(workInProgress); - break; + return isContextProvider(workInProgress.type) && popContext(), null; case 3: - popHostContainer(workInProgress); - popTopLevelContextObject(workInProgress); - current = workInProgress.stateNode; - current.pendingContext && - ((current.context = current.pendingContext), - (current.pendingContext = null)); - updateHostContainer(workInProgress); - break; + 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$jscomp$0 = workInProgress.type; + renderExpirationTime = workInProgress.type; if (null !== current && null != workInProgress.stateNode) updateHostComponent$1( current, workInProgress, - renderExpirationTime$jscomp$0, + renderExpirationTime, newProps, rootContainerInstance ), current.ref !== workInProgress.ref && (workInProgress.effectTag |= 128); - else if (newProps) { + 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$jscomp$0 = getViewConfigForType( - renderExpirationTime$jscomp$0 - ); + renderExpirationTime = getViewConfigForType(renderExpirationTime); var updatePayload = diffProperties( null, emptyObject, newProps, - renderExpirationTime$jscomp$0.validAttributes + renderExpirationTime.validAttributes ); rootContainerInstance = createNode( current, - renderExpirationTime$jscomp$0.uiViewClassName, + renderExpirationTime.uiViewClassName, rootContainerInstance, updatePayload, workInProgress ); current = new ReactFabricHostComponent( current, - renderExpirationTime$jscomp$0, + renderExpirationTime, newProps, workInProgress ); @@ -4955,11 +4753,8 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { appendAllChildren(current, workInProgress, !1, !1); workInProgress.stateNode = current; null !== workInProgress.ref && (workInProgress.effectTag |= 128); - } 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; + } + return null; case 6: if (current && null != workInProgress.stateNode) updateHostText$1( @@ -4982,33 +4777,30 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { workInProgress ); } - break; - case 11: - break; + return null; case 13: - pop(suspenseStackCursor, workInProgress); + pop(suspenseStackCursor); newProps = workInProgress.memoizedState; if (0 !== (workInProgress.effectTag & 64)) return ( - (workInProgress.expirationTime = renderExpirationTime$jscomp$0), - workInProgress + (workInProgress.expirationTime = renderExpirationTime), workInProgress ); newProps = null !== newProps; rootContainerInstance = !1; null !== current && - ((renderExpirationTime$jscomp$0 = current.memoizedState), - (rootContainerInstance = null !== renderExpirationTime$jscomp$0), + ((renderExpirationTime = current.memoizedState), + (rootContainerInstance = null !== renderExpirationTime), newProps || - null === renderExpirationTime$jscomp$0 || - ((renderExpirationTime$jscomp$0 = current.child.sibling), - null !== renderExpirationTime$jscomp$0 && + null === renderExpirationTime || + ((renderExpirationTime = current.child.sibling), + null !== renderExpirationTime && ((updatePayload = workInProgress.firstEffect), null !== updatePayload - ? ((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)))); + ? ((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 && @@ -5025,38 +4817,27 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { workInProgressRootExitStatus = RootSuspendedWithDelay; 0 !== workInProgressRootNextUnprocessedUpdateTime && null !== workInProgressRoot && - (markRootSuspendedAtTime(workInProgressRoot, renderExpirationTime), + (markRootSuspendedAtTime( + workInProgressRoot, + renderExpirationTime$1 + ), markRootUpdatedAtTime( workInProgressRoot, workInProgressRootNextUnprocessedUpdateTime )); } newProps && (workInProgress.effectTag |= 4); - break; - case 7: - break; - case 8: - break; - case 12: - break; + return null; case 4: - popHostContainer(workInProgress); - updateHostContainer(workInProgress); - break; + return popHostContainer(), updateHostContainer(workInProgress), null; case 10: - popProvider(workInProgress); - break; - case 9: - break; - case 14: - break; + return popProvider(workInProgress), null; case 17: - isContextProvider(workInProgress.type) && popContext(workInProgress); - break; + return isContextProvider(workInProgress.type) && popContext(), null; case 19: - pop(suspenseStackCursor, workInProgress); + pop(suspenseStackCursor); newProps = workInProgress.memoizedState; - if (null === newProps) break; + if (null === newProps) return null; rootContainerInstance = 0 !== (workInProgress.effectTag & 64); updatePayload = newProps.rendering; if (null === updatePayload) @@ -5078,7 +4859,7 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { null === newProps.lastEffect && (workInProgress.firstEffect = null); workInProgress.lastEffect = newProps.lastEffect; - current = renderExpirationTime$jscomp$0; + current = renderExpirationTime; for (newProps = workInProgress.child; null !== newProps; ) (rootContainerInstance = newProps), (updatePayload = current), @@ -5086,9 +4867,8 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { (rootContainerInstance.nextEffect = null), (rootContainerInstance.firstEffect = null), (rootContainerInstance.lastEffect = null), - (renderExpirationTime$jscomp$0 = - rootContainerInstance.alternate), - null === renderExpirationTime$jscomp$0 + (renderExpirationTime = rootContainerInstance.alternate), + null === renderExpirationTime ? ((rootContainerInstance.childExpirationTime = 0), (rootContainerInstance.expirationTime = updatePayload), (rootContainerInstance.child = null), @@ -5099,19 +4879,18 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { (rootContainerInstance.selfBaseDuration = 0), (rootContainerInstance.treeBaseDuration = 0)) : ((rootContainerInstance.childExpirationTime = - renderExpirationTime$jscomp$0.childExpirationTime), + renderExpirationTime.childExpirationTime), (rootContainerInstance.expirationTime = - renderExpirationTime$jscomp$0.expirationTime), + renderExpirationTime.expirationTime), (rootContainerInstance.child = - renderExpirationTime$jscomp$0.child), + renderExpirationTime.child), (rootContainerInstance.memoizedProps = - renderExpirationTime$jscomp$0.memoizedProps), + renderExpirationTime.memoizedProps), (rootContainerInstance.memoizedState = - renderExpirationTime$jscomp$0.memoizedState), + renderExpirationTime.memoizedState), (rootContainerInstance.updateQueue = - renderExpirationTime$jscomp$0.updateQueue), - (updatePayload = - renderExpirationTime$jscomp$0.dependencies), + renderExpirationTime.updateQueue), + (updatePayload = renderExpirationTime.dependencies), (rootContainerInstance.dependencies = null === updatePayload ? null @@ -5121,14 +4900,13 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { responders: updatePayload.responders }), (rootContainerInstance.selfBaseDuration = - renderExpirationTime$jscomp$0.selfBaseDuration), + renderExpirationTime.selfBaseDuration), (rootContainerInstance.treeBaseDuration = - renderExpirationTime$jscomp$0.treeBaseDuration)), + renderExpirationTime.treeBaseDuration)), (newProps = newProps.sibling); push( suspenseStackCursor, - (suspenseStackCursor.current & 1) | 2, - workInProgress + (suspenseStackCursor.current & 1) | 2 ); return workInProgress.child; } @@ -5151,18 +4929,20 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { null === newProps.tail && "hidden" === newProps.tailMode && !updatePayload.alternate) - ) { - workInProgress = workInProgress.lastEffect = newProps.lastEffect; - null !== workInProgress && (workInProgress.nextEffect = null); - break; - } + ) + return ( + (workInProgress = workInProgress.lastEffect = + newProps.lastEffect), + null !== workInProgress && (workInProgress.nextEffect = null), + null + ); } else - now() > newProps.tailExpiration && - 1 < renderExpirationTime$jscomp$0 && + 2 * now() - newProps.renderingStartTime > newProps.tailExpiration && + 1 < renderExpirationTime && ((workInProgress.effectTag |= 64), (rootContainerInstance = !0), cutOffTailIfNeeded(newProps, !1), - (current = renderExpirationTime$jscomp$0 - 1), + (current = renderExpirationTime - 1), (workInProgress.expirationTime = workInProgress.childExpirationTime = current), null === spawnedWorkDuringRender ? (spawnedWorkDuringRender = [current]) @@ -5176,49 +4956,44 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { : (workInProgress.child = updatePayload), (newProps.last = updatePayload)); } - if (null !== newProps.tail) - return ( - 0 === newProps.tailExpiration && + 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), - (newProps = suspenseStackCursor.current), + (workInProgress = suspenseStackCursor.current), push( suspenseStackCursor, - rootContainerInstance ? (newProps & 1) | 2 : newProps & 1, - workInProgress + rootContainerInstance + ? (workInProgress & 1) | 2 + : workInProgress & 1 ), - 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." - ); + current) + : null; } - return 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(workInProgress); + isContextProvider(workInProgress.type) && popContext(); var effectTag = workInProgress.effectTag; return effectTag & 4096 ? ((workInProgress.effectTag = (effectTag & -4097) | 64), workInProgress) : null; case 3: - popHostContainer(workInProgress); - popTopLevelContextObject(workInProgress); + popHostContainer(); + pop(didPerformWorkStackCursor); + pop(contextStackCursor); effectTag = workInProgress.effectTag; if (0 !== (effectTag & 64)) throw Error( @@ -5230,7 +5005,7 @@ function unwindWork(workInProgress) { return popHostContext(workInProgress), null; case 13: return ( - pop(suspenseStackCursor, workInProgress), + pop(suspenseStackCursor), (effectTag = workInProgress.effectTag), effectTag & 4096 ? ((workInProgress.effectTag = (effectTag & -4097) | 64), @@ -5238,9 +5013,9 @@ function unwindWork(workInProgress) { : null ); case 19: - return pop(suspenseStackCursor, workInProgress), null; + return pop(suspenseStackCursor), null; case 4: - return popHostContainer(workInProgress), null; + return popHostContainer(), null; case 10: return popProvider(workInProgress), null; default: @@ -5297,102 +5072,192 @@ function logError(boundary, errorInfo) { }); } } -function safelyCallComponentWillUnmount(current$$1, instance) { +function safelyCallComponentWillUnmount(current, instance) { try { - (instance.props = current$$1.memoizedProps), - (instance.state = current$$1.memoizedState), + (instance.props = current.memoizedProps), + (instance.state = current.memoizedState), instance.componentWillUnmount(); } catch (unmountError) { - captureCommitPhaseError(current$$1, unmountError); + captureCommitPhaseError(current, unmountError); } } -function safelyDetachRef(current$$1) { - var ref = current$$1.ref; +function safelyDetachRef(current) { + var ref = current.ref; if (null !== ref) if ("function" === typeof ref) try { ref(null); } catch (refError) { - captureCommitPhaseError(current$$1, refError); + captureCommitPhaseError(current, refError); } else ref.current = null; } -function commitBeforeMutationLifeCycles(current$$1, finishedWork) { +function commitBeforeMutationLifeCycles(current, finishedWork) { switch (finishedWork.tag) { case 0: case 11: case 15: - commitHookEffectList(2, 0, finishedWork); - break; + case 22: + return; case 1: - if (finishedWork.effectTag & 256 && null !== current$$1) { - var prevProps = current$$1.memoizedProps, - prevState = current$$1.memoizedState; - current$$1 = finishedWork.stateNode; - finishedWork = current$$1.getSnapshotBeforeUpdate( + if (finishedWork.effectTag & 256 && null !== current) { + var prevProps = current.memoizedProps, + prevState = current.memoizedState; + current = finishedWork.stateNode; + finishedWork = current.getSnapshotBeforeUpdate( finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState ); - current$$1.__reactInternalSnapshotBeforeUpdate = finishedWork; + current.__reactInternalSnapshotBeforeUpdate = finishedWork; } - break; + return; case 3: case 5: case 6: case 4: case 17: - break; - default: - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); + 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 commitHookEffectList(unmountTag, mountTag, finishedWork) { +function commitHookEffectListUnmount(tag, finishedWork) { finishedWork = finishedWork.updateQueue; finishedWork = null !== finishedWork ? finishedWork.lastEffect : null; if (null !== finishedWork) { var effect = (finishedWork = finishedWork.next); do { - if (0 !== (effect.tag & unmountTag)) { + if ((effect.tag & tag) === tag) { 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 commitUnmount(finishedRoot, current$$1$jscomp$0, renderPriorityLevel) { +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" === typeof onCommitFiberUnmount && - onCommitFiberUnmount(current$$1$jscomp$0); - switch (current$$1$jscomp$0.tag) { + onCommitFiberUnmount(current$jscomp$0); + switch (current$jscomp$0.tag) { case 0: case 11: case 14: case 15: - finishedRoot = current$$1$jscomp$0.updateQueue; + case 22: + finishedRoot = current$jscomp$0.updateQueue; if ( null !== finishedRoot && ((finishedRoot = finishedRoot.lastEffect), null !== finishedRoot) ) { var firstEffect = finishedRoot.next; - runWithPriority$1( + runWithPriority( 97 < renderPriorityLevel ? 97 : renderPriorityLevel, function() { var effect = firstEffect; do { - var destroy = effect.destroy; - if (void 0 !== destroy) { - var current$$1 = current$$1$jscomp$0; + var _destroy = effect.destroy; + if (void 0 !== _destroy) { + var current = current$jscomp$0; try { - destroy(); + _destroy(); } catch (error) { - captureCommitPhaseError(current$$1, error); + captureCommitPhaseError(current, error); } } effect = effect.next; @@ -5402,42 +5267,41 @@ function commitUnmount(finishedRoot, current$$1$jscomp$0, renderPriorityLevel) { } break; case 1: - safelyDetachRef(current$$1$jscomp$0); - renderPriorityLevel = current$$1$jscomp$0.stateNode; + safelyDetachRef(current$jscomp$0); + renderPriorityLevel = current$jscomp$0.stateNode; "function" === typeof renderPriorityLevel.componentWillUnmount && - safelyCallComponentWillUnmount( - current$$1$jscomp$0, - renderPriorityLevel - ); + safelyCallComponentWillUnmount(current$jscomp$0, renderPriorityLevel); break; case 5: - safelyDetachRef(current$$1$jscomp$0); + safelyDetachRef(current$jscomp$0); break; case 4: - createChildNodeSet(current$$1$jscomp$0.stateNode.containerInfo); + createChildNodeSet(current$jscomp$0.stateNode.containerInfo); } } -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; +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; null !== alternate && detachFiber(alternate); } -function commitWork(current$$1, finishedWork) { +function commitWork(current, finishedWork) { switch (finishedWork.tag) { case 0: case 11: case 14: case 15: - commitHookEffectList(4, 8, finishedWork); + case 22: + commitHookEffectListUnmount(3, finishedWork); return; case 12: return; @@ -5450,19 +5314,20 @@ function commitWork(current$$1, finishedWork) { attachSuspenseRetryListeners(finishedWork); return; } - 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." - ); + 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." + ); } } function attachSuspenseRetryListeners(finishedWork) { @@ -5522,7 +5387,7 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { return expirationTime; } var ceil = Math.ceil, - ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher, + ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, NoContext = 0, LegacyUnbatchedContext = 8, @@ -5537,7 +5402,7 @@ var ceil = Math.ceil, executionContext = NoContext, workInProgressRoot = null, workInProgress = null, - renderExpirationTime = 0, + renderExpirationTime$1 = 0, workInProgressRootExitStatus = RootIncomplete, workInProgressRootFatalError = null, workInProgressRootLatestProcessedExpirationTime = 1073741823, @@ -5564,8 +5429,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; @@ -5573,7 +5438,7 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { var priorityLevel = getCurrentPriorityLevel(); if (0 === (fiber & 4)) return 99 === priorityLevel ? 1073741823 : 1073741822; if ((executionContext & RenderContext) !== NoContext) - return renderExpirationTime; + return renderExpirationTime$1; if (null !== suspenseConfig) currentTime = 1073741821 - @@ -5605,11 +5470,11 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { throw Error("Expected a valid priority level"); } null !== workInProgressRoot && - currentTime === renderExpirationTime && + currentTime === renderExpirationTime$1 && --currentTime; return currentTime; } -function scheduleUpdateOnFiber(fiber, expirationTime) { +function scheduleWork(fiber, expirationTime) { if (50 < nestedUpdateCount) throw ((nestedUpdateCount = 0), (rootWithNestedUpdates = null), @@ -5666,7 +5531,7 @@ function markUpdateTimeFromFiberToRoot(fiber, expirationTime) { (workInProgressRoot === root && (markUnprocessedUpdateTime(expirationTime), workInProgressRootExitStatus === RootSuspendedWithDelay && - markRootSuspendedAtTime(root, renderExpirationTime)), + markRootSuspendedAtTime(root, renderExpirationTime$1)), markRootUpdatedAtTime(root, expirationTime)); return root; } @@ -5675,9 +5540,10 @@ function getNextRootExpirationTimeToWorkOn(root) { if (0 !== lastExpiredTime) return lastExpiredTime; lastExpiredTime = root.firstPendingTime; if (!isRootSuspendedAtTime(root, lastExpiredTime)) return lastExpiredTime; - lastExpiredTime = root.lastPingedTime; + var lastPingedTime = root.lastPingedTime; root = root.nextKnownPendingLevel; - return lastExpiredTime > root ? lastExpiredTime : root; + root = lastPingedTime > root ? lastPingedTime : root; + return 2 >= root && lastExpiredTime !== root ? 0 : root; } function ensureRootIsScheduled(root) { if (0 !== root.lastExpiredTime) @@ -5726,270 +5592,232 @@ function ensureRootIsScheduled(root) { } function performConcurrentWorkOnRoot(root, didTimeout) { currentEventTime = 0; - if (didTimeout) - return ( - (didTimeout = requestCurrentTimeForUpdate()), - markRootExpiredAtTime(root, didTimeout), + 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), ensureRootIsScheduled(root), - 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); - } - 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) + 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) ) { - 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); + if ( + workInProgressRootHasPendingPing && + ((expirationTime = root.lastPingedTime), + 0 === expirationTime || expirationTime >= lastExpiredTime) + ) { + root.lastPingedTime = lastExpiredTime; + prepareFreshStack(root, lastExpiredTime); 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); + } + expirationTime = getNextRootExpirationTimeToWorkOn(root); + if (0 !== expirationTime && expirationTime !== lastExpiredTime) break; + if (0 !== exitStatus && exitStatus !== lastExpiredTime) { + root.lastPingedTime = exitStatus; break; - default: - throw Error("Unknown root exit status."); + } + root.timeoutHandle = scheduleTimeout( + commitRoot.bind(null, root), + prevExecutionContext + ); + break; } - 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(); + 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; - } 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); + 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 + ); + break; + } + commitRoot(root); + break; + case RootCompleted: + if ( + 1073741823 !== workInProgressRootLatestProcessedExpirationTime && + null !== workInProgressRootCanSuspendUsingConfig + ) { + 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 + ); + break; + } + } + commitRoot(root); + break; + default: + throw Error("Unknown root exit status."); } } - return null; + ensureRootIsScheduled(root); + return root.callbackNode === didTimeout + ? performConcurrentWorkOnRoot.bind(null, root) + : null; } -function flushPendingDiscreteUpdates() { - if (null !== rootsWithPendingDiscreteUpdates) { - var roots = rootsWithPendingDiscreteUpdates; - rootsWithPendingDiscreteUpdates = null; - roots.forEach(function(expirationTime, root) { - markRootExpiredAtTime(root, expirationTime); - ensureRootIsScheduled(root); - }); - flushSyncCallbackQueue(); - } +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 prepareFreshStack(root, expirationTime) { root.finishedWork = null; @@ -6002,26 +5830,27 @@ function prepareFreshStack(root, expirationTime) { var interruptedWork = timeoutHandle; switch (interruptedWork.tag) { case 1: - var childContextTypes = interruptedWork.type.childContextTypes; - null !== childContextTypes && - void 0 !== childContextTypes && - popContext(interruptedWork); + interruptedWork = interruptedWork.type.childContextTypes; + null !== interruptedWork && + void 0 !== interruptedWork && + popContext(); break; case 3: - popHostContainer(interruptedWork); - popTopLevelContextObject(interruptedWork); + popHostContainer(); + pop(didPerformWorkStackCursor); + pop(contextStackCursor); break; case 5: popHostContext(interruptedWork); break; case 4: - popHostContainer(interruptedWork); + popHostContainer(); break; case 13: - pop(suspenseStackCursor, interruptedWork); + pop(suspenseStackCursor); break; case 19: - pop(suspenseStackCursor, interruptedWork); + pop(suspenseStackCursor); break; case 10: popProvider(interruptedWork); @@ -6029,8 +5858,8 @@ function prepareFreshStack(root, expirationTime) { timeoutHandle = timeoutHandle.return; } workInProgressRoot = root; - workInProgress = createWorkInProgress(root.current, null, expirationTime); - renderExpirationTime = expirationTime; + workInProgress = createWorkInProgress(root.current, null); + renderExpirationTime$1 = expirationTime; workInProgressRootExitStatus = RootIncomplete; workInProgressRootFatalError = null; workInProgressRootLatestSuspenseTimeout = workInProgressRootLatestProcessedExpirationTime = 1073741823; @@ -6043,12 +5872,25 @@ function handleError(root$jscomp$0, thrownValue) { do { try { resetContextDependencies(); - resetHooks(); + 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; if (null === workInProgress || null === workInProgress.return) return ( (workInProgressRootExitStatus = RootFatalErrored), (workInProgressRootFatalError = thrownValue), - null + (workInProgress = null) ); workInProgress.mode & 8 && stopProfilerTimerIfRunningAndRecordDelta(workInProgress, !0); @@ -6057,7 +5899,7 @@ function handleError(root$jscomp$0, thrownValue) { returnFiber = workInProgress.return, sourceFiber = workInProgress, value = thrownValue; - thrownValue = renderExpirationTime; + thrownValue = renderExpirationTime$1; sourceFiber.effectTag |= 2048; sourceFiber.firstEffect = sourceFiber.lastEffect = null; if ( @@ -6065,8 +5907,17 @@ function handleError(root$jscomp$0, thrownValue) { "object" === typeof value && "function" === typeof value.then ) { - var thenable = value, - hasInvisibleParentBoundary = + 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 = 0 !== (suspenseStackCursor.current & 1), _workInProgress = returnFiber; do { @@ -6081,10 +5932,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) { @@ -6191,8 +6042,8 @@ function handleError(root$jscomp$0, thrownValue) { } while (1); } function pushDispatcher() { - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = ContextOnlyDispatcher; + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; return null === prevDispatcher ? ContextOnlyDispatcher : prevDispatcher; } function pushInteractions(root) { @@ -6214,6 +6065,33 @@ 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); @@ -6223,43 +6101,35 @@ function workLoopConcurrent() { workInProgress = performUnitOfWork(workInProgress); } function performUnitOfWork(unitOfWork) { - var current$$1 = unitOfWork.alternate; + var current = unitOfWork.alternate; 0 !== (unitOfWork.mode & 8) ? ((profilerStartTime = now$1()), 0 > unitOfWork.actualStartTime && (unitOfWork.actualStartTime = now$1()), - (current$$1 = beginWork$$1(current$$1, unitOfWork, renderExpirationTime)), + (current = beginWork$1(current, unitOfWork, renderExpirationTime$1)), stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, !0)) - : (current$$1 = beginWork$$1(current$$1, unitOfWork, renderExpirationTime)); + : (current = beginWork$1(current, unitOfWork, renderExpirationTime$1)); unitOfWork.memoizedProps = unitOfWork.pendingProps; - null === current$$1 && (current$$1 = completeUnitOfWork(unitOfWork)); + null === current && (current = completeUnitOfWork(unitOfWork)); ReactCurrentOwner$2.current = null; - return current$$1; + return current; } function completeUnitOfWork(unitOfWork) { workInProgress = unitOfWork; do { - var current$$1 = workInProgress.alternate; + var current = workInProgress.alternate; unitOfWork = workInProgress.return; if (0 === (workInProgress.effectTag & 2048)) { if (0 === (workInProgress.mode & 8)) - current$$1 = completeWork( - current$$1, - workInProgress, - renderExpirationTime - ); + current = completeWork(current, workInProgress, renderExpirationTime$1); else { var fiber = workInProgress; profilerStartTime = now$1(); 0 > fiber.actualStartTime && (fiber.actualStartTime = now$1()); - current$$1 = completeWork( - current$$1, - workInProgress, - renderExpirationTime - ); + current = completeWork(current, workInProgress, renderExpirationTime$1); stopProfilerTimerIfRunningAndRecordDelta(workInProgress, !1); } fiber = workInProgress; - if (1 === renderExpirationTime || 1 !== fiber.childExpirationTime) { + if (1 === renderExpirationTime$1 || 1 !== fiber.childExpirationTime) { var newChildExpirationTime = 0; if (0 !== (fiber.mode & 8)) { for ( @@ -6297,7 +6167,7 @@ function completeUnitOfWork(unitOfWork) { (actualDuration = actualDuration.sibling); fiber.childExpirationTime = newChildExpirationTime; } - if (null !== current$$1) return current$$1; + if (null !== current) return current; null !== unitOfWork && 0 === (unitOfWork.effectTag & 2048) && (null === unitOfWork.firstEffect && @@ -6312,7 +6182,7 @@ function completeUnitOfWork(unitOfWork) { : (unitOfWork.firstEffect = workInProgress), (unitOfWork.lastEffect = workInProgress))); } else { - current$$1 = unwindWork(workInProgress, renderExpirationTime); + current = unwindWork(workInProgress); if (0 !== (workInProgress.mode & 8)) { stopProfilerTimerIfRunningAndRecordDelta(workInProgress, !1); fiber = workInProgress.actualDuration; @@ -6325,14 +6195,13 @@ function completeUnitOfWork(unitOfWork) { (newChildExpirationTime = newChildExpirationTime.sibling); workInProgress.actualDuration = fiber; } - if (null !== current$$1) - return (current$$1.effectTag &= 2047), current$$1; + if (null !== current) return (current.effectTag &= 2047), current; null !== unitOfWork && ((unitOfWork.firstEffect = unitOfWork.lastEffect = null), (unitOfWork.effectTag |= 2048)); } - current$$1 = workInProgress.sibling; - if (null !== current$$1) return current$$1; + current = workInProgress.sibling; + if (null !== current) return current; workInProgress = unitOfWork; } while (null !== workInProgress); workInProgressRootExitStatus === RootIncomplete && @@ -6346,11 +6215,12 @@ function getRemainingExpirationTime(fiber) { } function commitRoot(root) { var renderPriorityLevel = getCurrentPriorityLevel(); - runWithPriority$1(99, commitRootImpl.bind(null, root, renderPriorityLevel)); + runWithPriority(99, commitRootImpl.bind(null, root, renderPriorityLevel)); return null; } function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { - flushPassiveEffects(); + do flushPassiveEffects(); + while (null !== rootWithPendingPassiveEffects); if ((executionContext & (RenderContext | CommitContext)) !== NoContext) throw Error("Should not already be working."); var finishedWork = root$jscomp$1.finishedWork, @@ -6379,7 +6249,8 @@ 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 = 0)); + ((workInProgress = workInProgressRoot = null), + (renderExpirationTime$1 = 0)); 1 < finishedWork.effectTag ? null !== finishedWork.lastEffect ? ((finishedWork.lastEffect.nextEffect = finishedWork), @@ -6413,9 +6284,9 @@ function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { ) { var effectTag = nextEffect.effectTag; if (effectTag & 128) { - var current$$1 = nextEffect.alternate; - if (null !== current$$1) { - var currentRef = current$$1.ref; + var current = nextEffect.alternate; + if (null !== current) { + var currentRef = current.ref; null !== currentRef && ("function" === typeof currentRef ? currentRef(null) @@ -6441,10 +6312,10 @@ function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { commitWork(nextEffect.alternate, nextEffect); break; case 8: - var current$$1$jscomp$0 = nextEffect; + var current$jscomp$0 = nextEffect; a: for ( var finishedRoot = root, - root$jscomp$0 = current$$1$jscomp$0, + root$jscomp$0 = current$jscomp$0, renderPriorityLevel$jscomp$0 = renderPriorityLevel, node = root$jscomp$0; ; @@ -6469,7 +6340,7 @@ function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { node.sibling.return = node.return; node = node.sibling; } - detachFiber(current$$1$jscomp$0); + detachFiber(current$jscomp$0); } nextEffect = nextEffect.nextEffect; } @@ -6483,118 +6354,25 @@ function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { nextEffect = remainingExpirationTimeBeforeCommit; do try { - for ( - effectTag = root$jscomp$1, current$$1 = expirationTime; - null !== nextEffect; - - ) { + for (effectTag = root$jscomp$1; null !== nextEffect; ) { var effectTag$jscomp$0 = nextEffect.effectTag; - 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." - ); - } - } + effectTag$jscomp$0 & 36 && + commitLifeCycles(effectTag, nextEffect.alternate, nextEffect); if (effectTag$jscomp$0 & 128) { - currentRef = void 0; + current = void 0; var ref = nextEffect.ref; if (null !== ref) { - var instance$jscomp$0 = nextEffect.stateNode; + var instance = nextEffect.stateNode; switch (nextEffect.tag) { case 5: - currentRef = instance$jscomp$0.canonical; + current = instance.canonical; break; default: - currentRef = instance$jscomp$0; + current = instance; } "function" === typeof ref - ? ref(currentRef) - : (ref.current = currentRef); + ? ref(current) + : (ref.current = current); } } nextEffect = nextEffect.nextEffect; @@ -6630,13 +6408,13 @@ function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { for ( remainingExpirationTimeBeforeCommit = spawnedWorkDuringRender, spawnedWorkDuringRender = null, - current$$1$jscomp$1 = 0; - current$$1$jscomp$1 < remainingExpirationTimeBeforeCommit.length; - current$$1$jscomp$1++ + ref = 0; + ref < remainingExpirationTimeBeforeCommit.length; + ref++ ) scheduleInteractions( root$jscomp$1, - remainingExpirationTimeBeforeCommit[current$$1$jscomp$1], + remainingExpirationTimeBeforeCommit[ref], root$jscomp$1.memoizedInteractions ); schedulePendingInteractions(root$jscomp$1, renderPriorityLevel$jscomp$1); @@ -6682,7 +6460,7 @@ function flushPassiveEffects() { ? 97 : pendingPassiveEffectsRenderPriority; pendingPassiveEffectsRenderPriority = 90; - return runWithPriority$1(priorityLevel, flushPassiveEffectsImpl); + return runWithPriority(priorityLevel, flushPassiveEffectsImpl); } } function flushPassiveEffectsImpl() { @@ -6697,27 +6475,28 @@ function flushPassiveEffectsImpl() { executionContext |= CommitContext; for ( var prevInteractions = pushInteractions(root), - effect = root.current.firstEffect; - null !== effect; + _effect2 = root.current.firstEffect; + null !== _effect2; ) { try { - var finishedWork = effect; + var finishedWork = _effect2; if (0 !== (finishedWork.effectTag & 512)) switch (finishedWork.tag) { case 0: case 11: case 15: - commitHookEffectList(128, 0, finishedWork), - commitHookEffectList(0, 64, finishedWork); + case 22: + commitHookEffectListUnmount(5, finishedWork), + commitHookEffectListMount(5, finishedWork); } } catch (error) { - if (null === effect) throw Error("Should be working on an effect."); - captureCommitPhaseError(effect, error); + if (null === _effect2) throw Error("Should be working on an effect."); + captureCommitPhaseError(_effect2, error); } - finishedWork = effect.nextEffect; - effect.nextEffect = null; - effect = finishedWork; + finishedWork = _effect2.nextEffect; + _effect2.nextEffect = null; + _effect2 = finishedWork; } tracing.__interactionsRef.current = prevInteractions; finishPendingInteractions(root, expirationTime); @@ -6766,19 +6545,17 @@ function captureCommitPhaseError(sourceFiber, error) { function pingSuspendedRoot(root, thenable, suspendedTime) { var pingCache = root.pingCache; null !== pingCache && pingCache.delete(thenable); - workInProgressRoot === root && renderExpirationTime === suspendedTime + workInProgressRoot === root && renderExpirationTime$1 === suspendedTime ? workInProgressRootExitStatus === RootSuspendedWithDelay || (workInProgressRootExitStatus === RootSuspended && 1073741823 === workInProgressRootLatestProcessedExpirationTime && now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) - ? prepareFreshStack(root, renderExpirationTime) + ? prepareFreshStack(root, renderExpirationTime$1) : (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))); } @@ -6794,12 +6571,12 @@ function resolveRetryThenable(boundaryFiber, thenable) { (ensureRootIsScheduled(boundaryFiber), schedulePendingInteractions(boundaryFiber, thenable)); } -var beginWork$$1; -beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { +var beginWork$1; +beginWork$1 = function(current, workInProgress, renderExpirationTime) { var updateExpirationTime = workInProgress.expirationTime; - if (null !== current$$1) + if (null !== current) if ( - current$$1.memoizedProps !== workInProgress.pendingProps || + current.memoizedProps !== workInProgress.pendingProps || didPerformWorkStackCursor.current ) didReceiveUpdate = !0; @@ -6824,11 +6601,17 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { ); break; case 10: - pushProvider(workInProgress, workInProgress.memoizedProps.value); + updateExpirationTime = workInProgress.memoizedProps.value; + var context = workInProgress.type._context; + push(valueCursor, context._currentValue2); + context._currentValue2 = updateExpirationTime; 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) { @@ -6838,52 +6621,40 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { updateExpirationTime >= renderExpirationTime ) return updateSuspenseComponent( - current$$1, + current, workInProgress, renderExpirationTime ); - push( - suspenseStackCursor, - suspenseStackCursor.current & 1, - workInProgress - ); + push(suspenseStackCursor, suspenseStackCursor.current & 1); workInProgress = bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ); return null !== workInProgress ? workInProgress.sibling : null; } - push( - suspenseStackCursor, - suspenseStackCursor.current & 1, - workInProgress - ); + push(suspenseStackCursor, suspenseStackCursor.current & 1); break; case 19: updateExpirationTime = workInProgress.childExpirationTime >= renderExpirationTime; - if (0 !== (current$$1.effectTag & 64)) { + if (0 !== (current.effectTag & 64)) { if (updateExpirationTime) return updateSuspenseListComponent( - current$$1, + current, workInProgress, renderExpirationTime ); workInProgress.effectTag |= 64; } - var renderState = workInProgress.memoizedState; - null !== renderState && - ((renderState.rendering = null), (renderState.tail = null)); - push( - suspenseStackCursor, - suspenseStackCursor.current, - workInProgress - ); + context = workInProgress.memoizedState; + null !== context && + ((context.rendering = null), (context.tail = null)); + push(suspenseStackCursor, suspenseStackCursor.current); if (!updateExpirationTime) return null; } return bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ); @@ -6895,41 +6666,40 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { switch (workInProgress.tag) { case 2: updateExpirationTime = workInProgress.type; - null !== current$$1 && - ((current$$1.alternate = null), + null !== current && + ((current.alternate = null), (workInProgress.alternate = null), (workInProgress.effectTag |= 2)); - current$$1 = workInProgress.pendingProps; - renderState = getMaskedContext( - workInProgress, - contextStackCursor.current - ); + current = workInProgress.pendingProps; + context = getMaskedContext(workInProgress, contextStackCursor.current); prepareToReadContext(workInProgress, renderExpirationTime); - renderState = renderWithHooks( + context = renderWithHooks( null, workInProgress, updateExpirationTime, - current$$1, - renderState, + current, + context, renderExpirationTime ); workInProgress.effectTag |= 1; if ( - "object" === typeof renderState && - null !== renderState && - "function" === typeof renderState.render && - void 0 === renderState.$$typeof + "object" === typeof context && + null !== context && + "function" === typeof context.render && + void 0 === context.$$typeof ) { workInProgress.tag = 1; - resetHooks(); + workInProgress.memoizedState = null; + workInProgress.updateQueue = null; if (isContextProvider(updateExpirationTime)) { var hasContext = !0; pushContextProvider(workInProgress); } else hasContext = !1; workInProgress.memoizedState = - null !== renderState.state && void 0 !== renderState.state - ? renderState.state + null !== context.state && void 0 !== context.state + ? context.state : null; + initializeUpdateQueue(workInProgress); var getDerivedStateFromProps = updateExpirationTime.getDerivedStateFromProps; "function" === typeof getDerivedStateFromProps && @@ -6937,15 +6707,15 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { workInProgress, updateExpirationTime, getDerivedStateFromProps, - current$$1 + current ); - renderState.updater = classComponentUpdater; - workInProgress.stateNode = renderState; - renderState._reactInternalFiber = workInProgress; + context.updater = classComponentUpdater; + workInProgress.stateNode = context; + context._reactInternalFiber = workInProgress; mountClassInstance( workInProgress, updateExpirationTime, - current$$1, + current, renderExpirationTime ); workInProgress = finishClassComponent( @@ -6961,127 +6731,129 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { reconcileChildren( null, workInProgress, - renderState, + context, renderExpirationTime ), (workInProgress = workInProgress.child); return workInProgress; case 16: - 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." - ); + 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." + ); } return workInProgress; case 0: return ( (updateExpirationTime = workInProgress.type), - (renderState = workInProgress.pendingProps), - (renderState = + (context = workInProgress.pendingProps), + (context = workInProgress.elementType === updateExpirationTime - ? renderState - : resolveDefaultProps(updateExpirationTime, renderState)), + ? context + : resolveDefaultProps(updateExpirationTime, context)), updateFunctionComponent( - current$$1, + current, workInProgress, updateExpirationTime, - renderState, + context, renderExpirationTime ) ); case 1: return ( (updateExpirationTime = workInProgress.type), - (renderState = workInProgress.pendingProps), - (renderState = + (context = workInProgress.pendingProps), + (context = workInProgress.elementType === updateExpirationTime - ? renderState - : resolveDefaultProps(updateExpirationTime, renderState)), + ? context + : resolveDefaultProps(updateExpirationTime, context)), updateClassComponent( - current$$1, + current, workInProgress, updateExpirationTime, - renderState, + context, renderExpirationTime ) ); case 3: pushHostRootContext(workInProgress); updateExpirationTime = workInProgress.updateQueue; - if (null === updateExpirationTime) + if (null === current || 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." ); - renderState = workInProgress.memoizedState; - renderState = null !== renderState ? renderState.element : null; + updateExpirationTime = workInProgress.pendingProps; + context = workInProgress.memoizedState; + context = null !== context ? context.element : null; + cloneUpdateQueue(current, workInProgress); processUpdateQueue( workInProgress, updateExpirationTime, - workInProgress.pendingProps, null, renderExpirationTime ); updateExpirationTime = workInProgress.memoizedState.element; - updateExpirationTime === renderState + updateExpirationTime === context ? (workInProgress = bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime )) : (reconcileChildren( - current$$1, + current, workInProgress, updateExpirationTime, renderExpirationTime @@ -7091,11 +6863,10 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { case 5: return ( pushHostContext(workInProgress), - null === current$$1 && tryToClaimNextHydratableInstance(workInProgress), (updateExpirationTime = workInProgress.pendingProps.children), - markRef(current$$1, workInProgress), + markRef(current, workInProgress), reconcileChildren( - current$$1, + current, workInProgress, updateExpirationTime, renderExpirationTime @@ -7104,13 +6875,10 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { workInProgress ); case 6: - return ( - null === current$$1 && tryToClaimNextHydratableInstance(workInProgress), - null - ); + return null; case 13: return updateSuspenseComponent( - current$$1, + current, workInProgress, renderExpirationTime ); @@ -7121,7 +6889,7 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { workInProgress.stateNode.containerInfo ), (updateExpirationTime = workInProgress.pendingProps), - null === current$$1 + null === current ? (workInProgress.child = reconcileChildFibers( workInProgress, null, @@ -7129,7 +6897,7 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { renderExpirationTime )) : reconcileChildren( - current$$1, + current, workInProgress, updateExpirationTime, renderExpirationTime @@ -7139,23 +6907,23 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { case 11: return ( (updateExpirationTime = workInProgress.type), - (renderState = workInProgress.pendingProps), - (renderState = + (context = workInProgress.pendingProps), + (context = workInProgress.elementType === updateExpirationTime - ? renderState - : resolveDefaultProps(updateExpirationTime, renderState)), + ? context + : resolveDefaultProps(updateExpirationTime, context)), updateForwardRef( - current$$1, + current, workInProgress, updateExpirationTime, - renderState, + context, renderExpirationTime ) ); case 7: return ( reconcileChildren( - current$$1, + current, workInProgress, workInProgress.pendingProps, renderExpirationTime @@ -7165,7 +6933,7 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { case 8: return ( reconcileChildren( - current$$1, + current, workInProgress, workInProgress.pendingProps.children, renderExpirationTime @@ -7175,8 +6943,11 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { case 12: return ( (workInProgress.effectTag |= 4), + (updateExpirationTime = workInProgress.stateNode), + (updateExpirationTime.effectDuration = 0), + (updateExpirationTime.passiveEffectDuration = 0), reconcileChildren( - current$$1, + current, workInProgress, workInProgress.pendingProps.children, renderExpirationTime @@ -7186,27 +6957,32 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { case 10: a: { updateExpirationTime = workInProgress.type._context; - renderState = workInProgress.pendingProps; + context = workInProgress.pendingProps; getDerivedStateFromProps = workInProgress.memoizedProps; - 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) { + 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) + ) { if ( - getDerivedStateFromProps.children === renderState.children && + getDerivedStateFromProps.children === context.children && !didPerformWorkStackCursor.current ) { workInProgress = bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ); @@ -7214,14 +6990,15 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { } } else for ( - oldValue = workInProgress.child, - null !== oldValue && (oldValue.return = workInProgress); - null !== oldValue; + context$jscomp$0 = workInProgress.child, + null !== context$jscomp$0 && + (context$jscomp$0.return = workInProgress); + null !== context$jscomp$0; ) { - var list = oldValue.dependencies; + var list = context$jscomp$0.dependencies; if (null !== list) { - getDerivedStateFromProps = oldValue.child; + getDerivedStateFromProps = context$jscomp$0.child; for ( var dependency = list.firstContext; null !== dependency; @@ -7231,18 +7008,18 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { dependency.context === updateExpirationTime && 0 !== (dependency.observedBits & hasContext) ) { - 1 === oldValue.tag && + 1 === context$jscomp$0.tag && ((dependency = createUpdate(renderExpirationTime, null)), (dependency.tag = 2), - enqueueUpdate(oldValue, dependency)); - oldValue.expirationTime < renderExpirationTime && - (oldValue.expirationTime = renderExpirationTime); - dependency = oldValue.alternate; + enqueueUpdate(context$jscomp$0, dependency)); + context$jscomp$0.expirationTime < renderExpirationTime && + (context$jscomp$0.expirationTime = renderExpirationTime); + dependency = context$jscomp$0.alternate; null !== dependency && dependency.expirationTime < renderExpirationTime && (dependency.expirationTime = renderExpirationTime); scheduleWorkOnParentPath( - oldValue.return, + context$jscomp$0.return, renderExpirationTime ); list.expirationTime < renderExpirationTime && @@ -7253,16 +7030,16 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { } } else getDerivedStateFromProps = - 10 === oldValue.tag - ? oldValue.type === workInProgress.type + 10 === context$jscomp$0.tag + ? context$jscomp$0.type === workInProgress.type ? null - : oldValue.child - : oldValue.child; + : context$jscomp$0.child + : context$jscomp$0.child; if (null !== getDerivedStateFromProps) - getDerivedStateFromProps.return = oldValue; + getDerivedStateFromProps.return = context$jscomp$0; else for ( - getDerivedStateFromProps = oldValue; + getDerivedStateFromProps = context$jscomp$0; null !== getDerivedStateFromProps; ) { @@ -7270,21 +7047,20 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { getDerivedStateFromProps = null; break; } - oldValue = getDerivedStateFromProps.sibling; - if (null !== oldValue) { - oldValue.return = getDerivedStateFromProps.return; - getDerivedStateFromProps = oldValue; + context$jscomp$0 = getDerivedStateFromProps.sibling; + if (null !== context$jscomp$0) { + context$jscomp$0.return = getDerivedStateFromProps.return; + getDerivedStateFromProps = context$jscomp$0; break; } getDerivedStateFromProps = getDerivedStateFromProps.return; } - oldValue = getDerivedStateFromProps; + context$jscomp$0 = getDerivedStateFromProps; } - } reconcileChildren( - current$$1, + current, workInProgress, - renderState.children, + context.children, renderExpirationTime ); workInProgress = workInProgress.child; @@ -7292,18 +7068,15 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { return workInProgress; case 9: return ( - (renderState = workInProgress.type), + (context = workInProgress.type), (hasContext = workInProgress.pendingProps), (updateExpirationTime = hasContext.children), prepareToReadContext(workInProgress, renderExpirationTime), - (renderState = readContext( - renderState, - hasContext.unstable_observedBits - )), - (updateExpirationTime = updateExpirationTime(renderState)), + (context = readContext(context, hasContext.unstable_observedBits)), + (updateExpirationTime = updateExpirationTime(context)), (workInProgress.effectTag |= 1), reconcileChildren( - current$$1, + current, workInProgress, updateExpirationTime, renderExpirationTime @@ -7312,16 +7085,16 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { ); case 14: return ( - (renderState = workInProgress.type), + (context = workInProgress.type), (hasContext = resolveDefaultProps( - renderState, + context, workInProgress.pendingProps )), - (hasContext = resolveDefaultProps(renderState.type, hasContext)), + (hasContext = resolveDefaultProps(context.type, hasContext)), updateMemoComponent( - current$$1, + current, workInProgress, - renderState, + context, hasContext, updateExpirationTime, renderExpirationTime @@ -7329,7 +7102,7 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { ); case 15: return updateSimpleMemoComponent( - current$$1, + current, workInProgress, workInProgress.type, workInProgress.pendingProps, @@ -7339,30 +7112,25 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { case 17: return ( (updateExpirationTime = workInProgress.type), - (renderState = workInProgress.pendingProps), - (renderState = + (context = workInProgress.pendingProps), + (context = workInProgress.elementType === updateExpirationTime - ? renderState - : resolveDefaultProps(updateExpirationTime, renderState)), - null !== current$$1 && - ((current$$1.alternate = null), + ? context + : resolveDefaultProps(updateExpirationTime, context)), + null !== current && + ((current.alternate = null), (workInProgress.alternate = null), (workInProgress.effectTag |= 2)), (workInProgress.tag = 1), isContextProvider(updateExpirationTime) - ? ((current$$1 = !0), pushContextProvider(workInProgress)) - : (current$$1 = !1), + ? ((current = !0), pushContextProvider(workInProgress)) + : (current = !1), prepareToReadContext(workInProgress, renderExpirationTime), - constructClassInstance( - workInProgress, - updateExpirationTime, - renderState, - renderExpirationTime - ), + constructClassInstance(workInProgress, updateExpirationTime, context), mountClassInstance( workInProgress, updateExpirationTime, - renderState, + context, renderExpirationTime ), finishClassComponent( @@ -7370,13 +7138,13 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { workInProgress, updateExpirationTime, !0, - current$$1, + current, renderExpirationTime ) ); case 19: return updateSuspenseListComponent( - current$$1, + current, workInProgress, renderExpirationTime ); @@ -7517,9 +7285,6 @@ 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); @@ -7537,7 +7302,7 @@ function resolveLazyComponentTag(Component) { function createWorkInProgress(current, pendingProps) { var workInProgress = current.alternate; null === workInProgress - ? ((workInProgress = createFiber( + ? ((workInProgress = new FiberNode( current.tag, pendingProps, current.key, @@ -7555,6 +7320,10 @@ 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; @@ -7608,15 +7377,16 @@ function createFiberFromTypeAndProps( break; case REACT_PROFILER_TYPE: return ( - (type = createFiber(12, pendingProps, key, mode | 8)), + (type = new FiberNode(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 = createFiber(13, pendingProps, key, mode)), + (type = new FiberNode(13, pendingProps, key, mode)), (type.type = REACT_SUSPENSE_TYPE), (type.elementType = REACT_SUSPENSE_TYPE), (type.expirationTime = expirationTime), @@ -7624,7 +7394,7 @@ function createFiberFromTypeAndProps( ); case REACT_SUSPENSE_LIST_TYPE: return ( - (type = createFiber(19, pendingProps, key, mode)), + (type = new FiberNode(19, pendingProps, key, mode)), (type.elementType = REACT_SUSPENSE_LIST_TYPE), (type.expirationTime = expirationTime), type @@ -7648,6 +7418,9 @@ 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: " + @@ -7655,24 +7428,24 @@ function createFiberFromTypeAndProps( "." ); } - key = createFiber(fiberTag, pendingProps, key, mode); + key = new FiberNode(fiberTag, pendingProps, key, mode); key.elementType = type; key.type = owner; key.expirationTime = expirationTime; return key; } function createFiberFromFragment(elements, mode, expirationTime, key) { - elements = createFiber(7, elements, key, mode); + elements = new FiberNode(7, elements, key, mode); elements.expirationTime = expirationTime; return elements; } function createFiberFromText(content, mode, expirationTime) { - content = createFiber(6, content, null, mode); + content = new FiberNode(6, content, null, mode); content.expirationTime = expirationTime; return content; } function createFiberFromPortal(portal, mode, expirationTime) { - mode = createFiber( + mode = new FiberNode( 4, null !== portal.children ? portal.children : [], portal.key, @@ -7734,11 +7507,6 @@ 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) { @@ -7753,14 +7521,10 @@ function findHostInstance(component) { return null === component ? null : component.stateNode; } function updateContainer(element, container, parentComponent, callback) { - var current$$1 = container.current, + var current = container.current, currentTime = requestCurrentTimeForUpdate(), suspenseConfig = ReactCurrentBatchConfig.suspense; - currentTime = computeExpirationForFiber( - currentTime, - current$$1, - suspenseConfig - ); + currentTime = computeExpirationForFiber(currentTime, current, suspenseConfig); a: if (parentComponent) { parentComponent = parentComponent._reactInternalFiber; b: { @@ -7811,8 +7575,8 @@ function updateContainer(element, container, parentComponent, callback) { container.payload = { element: element }; callback = void 0 === callback ? null : callback; null !== callback && (container.callback = callback); - enqueueUpdate(current$$1, container); - scheduleUpdateOnFiber(current$$1, currentTime); + enqueueUpdate(current, container); + scheduleWork(current, currentTime); return currentTime; } function createPortal(children, containerInfo, implementation) { @@ -7826,7 +7590,6 @@ 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; @@ -7837,8 +7600,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; @@ -7850,291 +7613,116 @@ batchedUpdatesImpl = function(fn, a) { executionContext === NoContext && flushSyncCallbackQueue(); } }; -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; - }, - findNodeHandle: findNodeHandle, - dispatchCommand: function(handle, command, args) { - null != handle._nativeTag && - null != handle._internalInstanceHandle && - fabricDispatchCommand( - handle._internalInstanceHandle.stateNode.node, - command, - args - ); - }, - 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) - } - }; +var roots = new Map(); (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 - }) - ); + 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; + }, + 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.11.0", - rendererPackageName: "react-native-renderer" + 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) + } }); -var ReactFabric$2 = { default: ReactFabric }, - ReactFabric$3 = (ReactFabric$2 && ReactFabric) || ReactFabric$2; -module.exports = ReactFabric$3.default || ReactFabric$3; +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); +}; diff --git a/Libraries/Renderer/implementations/ReactFabric-profiling.js b/Libraries/Renderer/implementations/ReactFabric-profiling.js index d36acbd2303fcf..cc076b1040285b 100644 --- a/Libraries/Renderer/implementations/ReactFabric-profiling.js +++ b/Libraries/Renderer/implementations/ReactFabric-profiling.js @@ -5,6 +5,7 @@ * LICENSE file in the root directory of this source tree. * * @noflow + * @nolint * @providesModule ReactFabric-profiling * @preventMunge * @generated @@ -15,86 +16,17 @@ require("react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore"); var ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/ReactNativePrivateInterface"), React = require("react"), Scheduler = require("scheduler"), - 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 + - "`." - ); - } - } - } + tracing = require("scheduler/tracing"); +function getParent(inst) { + do inst = inst.return; + while (inst && 5 !== inst.tag); + return inst ? inst : null; } -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; +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); } -var plugins = [], - eventNameDispatchConfigs = {}, - registrationNameModules = {}; function invokeGuardedCallbackImpl(name, func, context, a, b, c, d, e, f) { var funcArgs = Array.prototype.slice.call(arguments, 3); try { @@ -165,74 +97,6 @@ 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; @@ -250,6 +114,7 @@ function getListener(inst, registrationName) { case "onMouseMoveCapture": case "onMouseUp": case "onMouseUpCapture": + case "onMouseEnter": (props = !props.disabled) || ((inst = inst.type), (props = !( @@ -274,15 +139,21 @@ function getListener(inst, registrationName) { ); return listener; } -function getParent(inst) { - do inst = inst.return; - while (inst && 5 !== inst.tag); - return inst ? inst : null; +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 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 forEachAccumulated(arr, cb, scope) { + Array.isArray(arr) ? arr.forEach(cb, scope) : arr && cb.call(scope, arr); } function accumulateDirectionalDispatches(inst, phase, event) { if ( @@ -350,8 +221,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) @@ -504,53 +375,27 @@ 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))) - : console.warn( - "Cannot record touch move without a touch start.\nTouch Move: %s\n", - "Touch Bank: %s", - printTouch(touch), - printTouchBank() - ); + 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))); } 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))) - : 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; + 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))); } var ResponderTouchHistoryStore = { recordTouchTrack: function(topLevelType, nativeEvent) { @@ -590,10 +435,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; @@ -683,13 +528,7 @@ var eventTypes = { "topTouchCancel" === topLevelType ) if (0 <= trackedTouchCount) --trackedTouchCount; - else - return ( - console.warn( - "Ended a touch event which was not counted in `trackedTouchCount`." - ), - null - ); + else return null; ResponderTouchHistoryStore.recordTouchTrack(topLevelType, nativeEvent); if ( targetInst && @@ -701,10 +540,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; @@ -858,10 +697,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, @@ -924,8 +763,8 @@ var eventTypes = { (topLevelType = shouldSetEventType ? eventTypes.responderTerminate : topLevelType - ? eventTypes.responderRelease - : null) + ? eventTypes.responderRelease + : null) ) (nativeEvent = ResponderSyntheticEvent.getPooled( topLevelType, @@ -949,48 +788,160 @@ 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; -injection.injectEventPluginOrder([ +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([ "ResponderEventPlugin", "ReactNativeBridgeEventPlugin" ]); -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, +recomputePluginOrdering(); +var injectedNamesToPlugins$jscomp$inline_92 = { + ResponderEventPlugin: ResponderEventPlugin, + ReactNativeBridgeEventPlugin: { + eventTypes: {}, + extractEvents: function( + topLevelType, targetInst, nativeEvent, nativeEventTarget - ); - if (bubbleDispatchConfig) - forEachAccumulated(topLevelType, accumulateTwoPhaseDispatchesSingle); - else if (directDispatchConfig) - forEachAccumulated(topLevelType, accumulateDirectDispatchesSingle); - else return null; - return topLevelType; + ) { + 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; } } -}); +isOrderingDirty$jscomp$inline_93 && recomputePluginOrdering(); function getInstanceFromInstance(instanceHandle) { return instanceHandle; } @@ -999,8 +950,8 @@ getFiberCurrentPropsFromNode = function(inst) { }; getInstanceFromNode = getInstanceFromInstance; getNodeFromInstance = function(inst) { - inst = inst.stateNode.canonical._nativeTag; - if (!inst) throw Error("All native instances should have a tag."); + inst = inst.stateNode.canonical; + if (!inst._nativeTag) throw Error("All native instances should have a tag."); return inst; }; ResponderEventPlugin.injection.injectGlobalResponderHandler({ @@ -1036,11 +987,9 @@ 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; -hasSymbol && Symbol.for("react.fundamental"); -hasSymbol && Symbol.for("react.responder"); -hasSymbol && Symbol.for("react.scope"); -var MAYBE_ITERATOR_SYMBOL = "function" === typeof Symbol && Symbol.iterator; + 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; function getIteratorFn(maybeIterable) { if (null === maybeIterable || "object" !== typeof maybeIterable) return null; maybeIterable = @@ -1050,9 +999,10 @@ function getIteratorFn(maybeIterable) { } function initializeLazyComponentType(lazyComponent) { if (-1 === lazyComponent._status) { - lazyComponent._status = 0; - var ctor = lazyComponent._ctor; + var ctor = lazyComponent._result; + ctor || (ctor = lazyComponent._ctor); ctor = ctor(); + lazyComponent._status = 0; lazyComponent._result = ctor; ctor.then( function(moduleObject) { @@ -1089,9 +1039,9 @@ function getComponentName(type) { if ("object" === typeof type) switch (type.$$typeof) { case REACT_CONTEXT_TYPE: - return "Context.Consumer"; + return (type.displayName || "Context") + ".Consumer"; case REACT_PROVIDER_TYPE: - return "Context.Provider"; + return (type._context.displayName || "Context") + ".Provider"; case REACT_FORWARD_REF_TYPE: var innerType = type.render; innerType = innerType.displayName || innerType.name || ""; @@ -1101,6 +1051,8 @@ 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); @@ -1290,8 +1242,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)) { @@ -1452,18 +1404,9 @@ 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); @@ -1471,46 +1414,35 @@ function batchedUpdates(fn, bookkeeping) { 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)) - ) - for (bookkeeping = 0; bookkeeping < fn.length; bookkeeping++) - restoreStateOfTarget(fn[bookkeeping]); + isInsideEventHandler = !1; } } -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; +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); } - _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; - eventTarget = nativeEvent.target; + if (null != target) { + var stateNode = target.stateNode; + null != stateNode && (eventTarget = stateNode.canonical); + } batchedUpdates(function() { var events = eventTarget; for (var events$jscomp$0 = null, i = 0; i < plugins.length; i++) { @@ -1548,21 +1480,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$1 = nativeFabricUIManager, - createNode = _nativeFabricUIManage$1.createNode, - cloneNode = _nativeFabricUIManage$1.cloneNode, - cloneNodeWithNewChildren = _nativeFabricUIManage$1.cloneNodeWithNewChildren, +var _nativeFabricUIManage = nativeFabricUIManager, + createNode = _nativeFabricUIManage.createNode, + cloneNode = _nativeFabricUIManage.cloneNode, + cloneNodeWithNewChildren = _nativeFabricUIManage.cloneNodeWithNewChildren, cloneNodeWithNewChildrenAndProps = - _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, + _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, getViewConfigForType = ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get, nextReactTag = 2; @@ -1581,10 +1513,10 @@ var ReactFabricHostComponent = (function() { } var _proto = ReactFabricHostComponent.prototype; _proto.blur = function() { - ReactNativePrivateInterface.TextInputState.blurTextInput(this._nativeTag); + ReactNativePrivateInterface.TextInputState.blurTextInput(this); }; _proto.focus = function() { - ReactNativePrivateInterface.TextInputState.focusTextInput(this._nativeTag); + ReactNativePrivateInterface.TextInputState.focusTextInput(this); }; _proto.measure = function(callback) { fabricMeasure( @@ -1646,44 +1578,6 @@ 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) { @@ -1721,21 +1615,17 @@ function isContextProvider(type) { type = type.childContextTypes; return null !== type && void 0 !== type; } -function popContext(fiber) { - pop(didPerformWorkStackCursor, fiber); - pop(contextStackCursor, fiber); -} -function popTopLevelContextObject(fiber) { - pop(didPerformWorkStackCursor, fiber); - pop(contextStackCursor, fiber); +function popContext() { + pop(didPerformWorkStackCursor); + pop(contextStackCursor); } function pushTopLevelContextObject(fiber, context, didChange) { if (contextStackCursor.current !== emptyContextObject) throw Error( "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." ); - push(contextStackCursor, context, fiber); - push(didPerformWorkStackCursor, didChange, fiber); + push(contextStackCursor, context); + push(didPerformWorkStackCursor, didChange); } function processChildContext(fiber, type, parentContext) { var instance = fiber.stateNode; @@ -1753,17 +1643,13 @@ function processChildContext(fiber, type, parentContext) { return Object.assign({}, parentContext, {}, instance); } function pushContextProvider(workInProgress) { - var instance = workInProgress.stateNode; - instance = - (instance && instance.__reactInternalMemoizedMergedChildContext) || + workInProgress = + ((workInProgress = workInProgress.stateNode) && + workInProgress.__reactInternalMemoizedMergedChildContext) || emptyContextObject; previousContext = contextStackCursor.current; - push(contextStackCursor, instance, workInProgress); - push( - didPerformWorkStackCursor, - didPerformWorkStackCursor.current, - workInProgress - ); + push(contextStackCursor, workInProgress); + push(didPerformWorkStackCursor, didPerformWorkStackCursor.current); return !0; } function invalidateContextProvider(workInProgress, type, didChange) { @@ -1773,13 +1659,17 @@ 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 - ? ((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); + ? ((workInProgress = processChildContext( + workInProgress, + type, + previousContext + )), + (instance.__reactInternalMemoizedMergedChildContext = workInProgress), + pop(didPerformWorkStackCursor), + pop(contextStackCursor), + push(contextStackCursor, workInProgress)) + : pop(didPerformWorkStackCursor); + push(didPerformWorkStackCursor, didChange); } var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback, @@ -1846,7 +1736,7 @@ function reactPriorityToSchedulerPriority(reactPriorityLevel) { throw Error("Unknown priority level."); } } -function runWithPriority$1(reactPriorityLevel, fn) { +function runWithPriority(reactPriorityLevel, fn) { reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); return Scheduler_runWithPriority(reactPriorityLevel, fn); } @@ -1878,7 +1768,7 @@ function flushSyncCallbackQueueImpl() { var i = 0; try { var queue = syncQueue; - runWithPriority$1(99, function() { + runWithPriority(99, function() { for (; i < queue.length; i++) { var callback = queue[i]; do callback = callback(!0); @@ -1906,18 +1796,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 is$1 = "function" === typeof Object.is ? Object.is : is, +var objectIs = "function" === typeof Object.is ? Object.is : is, hasOwnProperty = Object.prototype.hasOwnProperty; function shallowEqual(objA, objB) { - if (is$1(objA, objB)) return !0; + if (objectIs(objA, objB)) return !0; if ( "object" !== typeof objA || null === objA || @@ -1931,11 +1821,48 @@ function shallowEqual(objA, objB) { for (keysB = 0; keysB < keysA.length; keysB++) if ( !hasOwnProperty.call(objB, keysA[keysB]) || - !is$1(objA[keysA[keysB]], objB[keysA[keysB]]) + !objectIs(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); @@ -1953,14 +1880,9 @@ 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, providerFiber); + pop(valueCursor); providerFiber.type._context._currentValue2 = currentValue; } function scheduleWorkOnParentPath(parent, renderExpirationTime) { @@ -2015,237 +1937,195 @@ function readContext(context, observedBits) { return context._currentValue2; } var hasForceUpdate = !1; -function createUpdateQueue(baseState) { - return { - baseState: baseState, - firstUpdate: null, - lastUpdate: null, - firstCapturedUpdate: null, - lastCapturedUpdate: null, - firstEffect: null, - lastEffect: null, - firstCapturedEffect: null, - lastCapturedEffect: null +function initializeUpdateQueue(fiber) { + fiber.updateQueue = { + baseState: fiber.memoizedState, + baseQueue: null, + shared: { pending: null }, + effects: null }; } -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 cloneUpdateQueue(current, workInProgress) { + current = current.updateQueue; + workInProgress.updateQueue === current && + (workInProgress.updateQueue = { + baseState: current.baseState, + baseQueue: current.baseQueue, + shared: current.shared, + effects: current.effects + }); } function createUpdate(expirationTime, suspenseConfig) { - return { + expirationTime = { expirationTime: expirationTime, suspenseConfig: suspenseConfig, tag: 0, payload: null, callback: null, - next: null, - nextEffect: null + next: null }; -} -function appendUpdateToQueue(queue, update) { - null === queue.lastUpdate - ? (queue.firstUpdate = queue.lastUpdate = update) - : ((queue.lastUpdate.next = update), (queue.lastUpdate = update)); + return (expirationTime.next = expirationTime); } function enqueueUpdate(fiber, 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)); + 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; + } } 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 && - 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; + 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)); } function processUpdateQueue( - workInProgress, - queue, + workInProgress$jscomp$0, props, instance, renderExpirationTime ) { + var queue = workInProgress$jscomp$0.updateQueue; hasForceUpdate = !1; - queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue); - for ( - var newBaseState = queue.baseState, - newFirstUpdate = null, - newExpirationTime = 0, - 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; + 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)); } - 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; + if (null !== baseQueue) { + baseFirst = baseQueue.next; + var newState = queue.baseState, + 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; } - 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) { - 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); + 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); + } } - effect = effect.nextEffect; - } } var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig, emptyRefsObject = new React.Component().refs; @@ -2262,10 +2142,8 @@ function applyDerivedStateFromProps( ? ctor : Object.assign({}, ctor, getDerivedStateFromProps); workInProgress.memoizedState = getDerivedStateFromProps; - nextProps = workInProgress.updateQueue; - null !== nextProps && - 0 === workInProgress.expirationTime && - (nextProps.baseState = getDerivedStateFromProps); + 0 === workInProgress.expirationTime && + (workInProgress.updateQueue.baseState = getDerivedStateFromProps); } var classComponentUpdater = { isMounted: function(component) { @@ -2284,7 +2162,7 @@ var classComponentUpdater = { null !== callback && (suspenseConfig.callback = callback); enqueueUpdate(inst, suspenseConfig); - scheduleUpdateOnFiber(inst, currentTime); + scheduleWork(inst, currentTime); }, enqueueReplaceState: function(inst, payload, callback) { inst = inst._reactInternalFiber; @@ -2298,7 +2176,7 @@ var classComponentUpdater = { null !== callback && (suspenseConfig.callback = callback); enqueueUpdate(inst, suspenseConfig); - scheduleUpdateOnFiber(inst, currentTime); + scheduleWork(inst, currentTime); }, enqueueForceUpdate: function(inst, callback) { inst = inst._reactInternalFiber; @@ -2311,7 +2189,7 @@ var classComponentUpdater = { null !== callback && (suspenseConfig.callback = callback); enqueueUpdate(inst, suspenseConfig); - scheduleUpdateOnFiber(inst, currentTime); + scheduleWork(inst, currentTime); } }; function checkShouldComponentUpdate( @@ -2327,8 +2205,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, @@ -2380,23 +2258,16 @@ 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)) : ((contextType = isContextProvider(ctor) - ? previousContext - : contextStackCursor.current), - (instance.context = getMaskedContext(workInProgress, contextType))); - contextType = workInProgress.updateQueue; - null !== contextType && - (processUpdateQueue( - workInProgress, - contextType, - newProps, - instance, - renderExpirationTime - ), - (instance.state = workInProgress.memoizedState)); + ? previousContext + : contextStackCursor.current), + (instance.context = getMaskedContext(workInProgress, contextType))); + processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); + instance.state = workInProgress.memoizedState; contextType = ctor.getDerivedStateFromProps; "function" === typeof contextType && (applyDerivedStateFromProps(workInProgress, ctor, contextType, newProps), @@ -2412,21 +2283,18 @@ function mountClassInstance( instance.UNSAFE_componentWillMount(), ctor !== instance.state && classComponentUpdater.enqueueReplaceState(instance, instance.state, null), - (contextType = workInProgress.updateQueue), - null !== contextType && - (processUpdateQueue( - workInProgress, - contextType, - newProps, - instance, - renderExpirationTime - ), - (instance.state = workInProgress.memoizedState))); + processUpdateQueue( + workInProgress, + newProps, + instance, + renderExpirationTime + ), + (instance.state = workInProgress.memoizedState)); "function" === typeof instance.componentDidMount && (workInProgress.effectTag |= 4); } var isArray = Array.isArray; -function coerceRef(returnFiber, current$$1, element) { +function coerceRef(returnFiber, current, element) { returnFiber = element.ref; if ( null !== returnFiber && @@ -2438,7 +2306,7 @@ function coerceRef(returnFiber, current$$1, element) { if (element) { if (1 !== element.tag) throw Error( - "Function components cannot have refs. Did you mean to use React.forwardRef()?" + "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" ); var inst = element.stateNode; } @@ -2450,19 +2318,19 @@ function coerceRef(returnFiber, current$$1, element) { ); var stringRef = "" + returnFiber; if ( - null !== current$$1 && - null !== current$$1.ref && - "function" === typeof current$$1.ref && - current$$1.ref._stringRef === stringRef + null !== current && + null !== current.ref && + "function" === typeof current.ref && + current.ref._stringRef === stringRef ) - return current$$1.ref; - current$$1 = function(value) { + return current.ref; + current = function(value) { var refs = inst.refs; refs === emptyRefsObject && (refs = inst.refs = {}); null === value ? delete refs[stringRef] : (refs[stringRef] = value); }; - current$$1._stringRef = stringRef; - return current$$1; + current._stringRef = stringRef; + return current; } if ("string" !== typeof returnFiber) throw Error( @@ -2514,8 +2382,8 @@ function ChildReconciler(shouldTrackSideEffects) { (currentFirstChild = currentFirstChild.sibling); return returnFiber; } - function useFiber(fiber, pendingProps, expirationTime) { - fiber = createWorkInProgress(fiber, pendingProps, expirationTime); + function useFiber(fiber, pendingProps) { + fiber = createWorkInProgress(fiber, pendingProps); fiber.index = 0; fiber.sibling = null; return fiber; @@ -2540,31 +2408,26 @@ function ChildReconciler(shouldTrackSideEffects) { (newFiber.effectTag = 2); return newFiber; } - function updateTextNode( - returnFiber, - current$$1, - textContent, - expirationTime - ) { - if (null === current$$1 || 6 !== current$$1.tag) + function updateTextNode(returnFiber, current, textContent, expirationTime) { + if (null === current || 6 !== current.tag) return ( - (current$$1 = createFiberFromText( + (current = createFiberFromText( textContent, returnFiber.mode, expirationTime )), - (current$$1.return = returnFiber), - current$$1 + (current.return = returnFiber), + current ); - current$$1 = useFiber(current$$1, textContent, expirationTime); - current$$1.return = returnFiber; - return current$$1; + current = useFiber(current, textContent); + current.return = returnFiber; + return current; } - function updateElement(returnFiber, current$$1, element, expirationTime) { - if (null !== current$$1 && current$$1.elementType === element.type) + function updateElement(returnFiber, current, element, expirationTime) { + if (null !== current && current.elementType === element.type) return ( - (expirationTime = useFiber(current$$1, element.props, expirationTime)), - (expirationTime.ref = coerceRef(returnFiber, current$$1, element)), + (expirationTime = useFiber(current, element.props)), + (expirationTime.ref = coerceRef(returnFiber, current, element)), (expirationTime.return = returnFiber), expirationTime ); @@ -2576,51 +2439,45 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime ); - expirationTime.ref = coerceRef(returnFiber, current$$1, element); + expirationTime.ref = coerceRef(returnFiber, current, element); expirationTime.return = returnFiber; return expirationTime; } - function updatePortal(returnFiber, current$$1, portal, expirationTime) { + function updatePortal(returnFiber, current, portal, expirationTime) { if ( - null === current$$1 || - 4 !== current$$1.tag || - current$$1.stateNode.containerInfo !== portal.containerInfo || - current$$1.stateNode.implementation !== portal.implementation + null === current || + 4 !== current.tag || + current.stateNode.containerInfo !== portal.containerInfo || + current.stateNode.implementation !== portal.implementation ) return ( - (current$$1 = createFiberFromPortal( + (current = createFiberFromPortal( portal, returnFiber.mode, expirationTime )), - (current$$1.return = returnFiber), - current$$1 + (current.return = returnFiber), + current ); - current$$1 = useFiber(current$$1, portal.children || [], expirationTime); - current$$1.return = returnFiber; - return current$$1; + current = useFiber(current, portal.children || []); + current.return = returnFiber; + return current; } - function updateFragment( - returnFiber, - current$$1, - fragment, - expirationTime, - key - ) { - if (null === current$$1 || 7 !== current$$1.tag) + function updateFragment(returnFiber, current, fragment, expirationTime, key) { + if (null === current || 7 !== current.tag) return ( - (current$$1 = createFiberFromFragment( + (current = createFiberFromFragment( fragment, returnFiber.mode, expirationTime, key )), - (current$$1.return = returnFiber), - current$$1 + (current.return = returnFiber), + current ); - current$$1 = useFiber(current$$1, fragment, expirationTime); - current$$1.return = returnFiber; - return current$$1; + current = useFiber(current, fragment); + current.return = returnFiber; + return current; } function createChild(returnFiber, newChild, expirationTime) { if ("string" === typeof newChild || "number" === typeof newChild) @@ -2983,39 +2840,48 @@ function ChildReconciler(shouldTrackSideEffects) { null !== isUnkeyedTopLevelFragment; ) { - 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; + 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; + } } - else deleteChild(returnFiber, isUnkeyedTopLevelFragment); + deleteRemainingChildren(returnFiber, isUnkeyedTopLevelFragment); + break; + } else deleteChild(returnFiber, isUnkeyedTopLevelFragment); isUnkeyedTopLevelFragment = isUnkeyedTopLevelFragment.sibling; } newChild.type === REACT_FRAGMENT_TYPE @@ -3065,8 +2931,7 @@ function ChildReconciler(shouldTrackSideEffects) { ); currentFirstChild = useFiber( currentFirstChild, - newChild.children || [], - expirationTime + newChild.children || [] ); currentFirstChild.return = returnFiber; returnFiber = currentFirstChild; @@ -3093,11 +2958,7 @@ function ChildReconciler(shouldTrackSideEffects) { (newChild = "" + newChild), null !== currentFirstChild && 6 === currentFirstChild.tag ? (deleteRemainingChildren(returnFiber, currentFirstChild.sibling), - (currentFirstChild = useFiber( - currentFirstChild, - newChild, - expirationTime - )), + (currentFirstChild = useFiber(currentFirstChild, newChild)), (currentFirstChild.return = returnFiber), (returnFiber = currentFirstChild)) : (deleteRemainingChildren(returnFiber, currentFirstChild), @@ -3152,16 +3013,16 @@ function requiredContext(c) { return c; } function pushHostContainer(fiber, nextRootInstance) { - push(rootInstanceStackCursor, nextRootInstance, fiber); - push(contextFiberStackCursor, fiber, fiber); - push(contextStackCursor$1, NO_CONTEXT, fiber); - pop(contextStackCursor$1, fiber); - push(contextStackCursor$1, { isInAParentText: !1 }, fiber); + push(rootInstanceStackCursor, nextRootInstance); + push(contextFiberStackCursor, fiber); + push(contextStackCursor$1, NO_CONTEXT); + pop(contextStackCursor$1); + push(contextStackCursor$1, { isInAParentText: !1 }); } -function popHostContainer(fiber) { - pop(contextStackCursor$1, fiber); - pop(contextFiberStackCursor, fiber); - pop(rootInstanceStackCursor, fiber); +function popHostContainer() { + pop(contextStackCursor$1); + pop(contextFiberStackCursor); + pop(rootInstanceStackCursor); } function pushHostContext(fiber) { requiredContext(rootInstanceStackCursor.current); @@ -3178,23 +3039,19 @@ function pushHostContext(fiber) { ? { isInAParentText: nextContext } : context; context !== nextContext && - (push(contextFiberStackCursor, fiber, fiber), - push(contextStackCursor$1, nextContext, fiber)); + (push(contextFiberStackCursor, fiber), + push(contextStackCursor$1, nextContext)); } function popHostContext(fiber) { contextFiberStackCursor.current === fiber && - (pop(contextStackCursor$1, fiber), pop(contextFiberStackCursor, fiber)); + (pop(contextStackCursor$1), pop(contextFiberStackCursor)); } var suspenseStackCursor = { current: 0 }; function findFirstSuspended(row) { for (var node = row; null !== node; ) { if (13 === node.tag) { var state = node.memoizedState; - if ( - null !== state && - ((state = state.dehydrated), - null === state || shim$1(state) || shim$1(state)) - ) + if (null !== state && (null === state.dehydrated || shim$1() || shim$1())) return node; } else if (19 === node.tag && void 0 !== node.memoizedProps.revealOrder) { if (0 !== (node.effectTag & 64)) return node; @@ -3213,24 +3070,16 @@ function findFirstSuspended(row) { } return null; } -function createResponderListener(responder, props) { +function createDeprecatedResponderListener(responder, props) { return { responder: responder, props: props }; } -var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, +var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig, - renderExpirationTime$1 = 0, + renderExpirationTime = 0, currentlyRenderingFiber$1 = null, currentHook = null, - nextCurrentHook = null, - firstWorkInProgressHook = null, workInProgressHook = null, - nextWorkInProgressHook = null, - remainingExpirationTime = 0, - componentUpdateQueue = null, - sideEffectTag = 0, - didScheduleRenderPhaseUpdate = !1, - renderPhaseUpdates = null, - numberOfReRenders = 0; + didScheduleRenderPhaseUpdate = !1; 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." @@ -3239,7 +3088,7 @@ function throwInvalidHookError() { function areHookInputsEqual(nextDeps, prevDeps) { if (null === prevDeps) return !1; for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) - if (!is$1(nextDeps[i], prevDeps[i])) return !1; + if (!objectIs(nextDeps[i], prevDeps[i])) return !1; return !0; } function renderWithHooks( @@ -3247,92 +3096,85 @@ function renderWithHooks( workInProgress, Component, props, - refOrContext, + secondArg, nextRenderExpirationTime ) { - renderExpirationTime$1 = nextRenderExpirationTime; + renderExpirationTime = nextRenderExpirationTime; currentlyRenderingFiber$1 = workInProgress; - 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; + 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); } - 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) + ReactCurrentDispatcher.current = ContextOnlyDispatcher; + workInProgress = null !== currentHook && null !== currentHook.next; + renderExpirationTime = 0; + workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; + didScheduleRenderPhaseUpdate = !1; + if (workInProgress) throw Error( "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." ); - 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; + return current; } function mountWorkInProgressHook() { var hook = { memoizedState: null, baseState: null, + baseQueue: null, queue: null, - baseUpdate: null, next: null }; null === workInProgressHook - ? (firstWorkInProgressHook = workInProgressHook = hook) + ? (currentlyRenderingFiber$1.memoizedState = 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), - (nextWorkInProgressHook = workInProgressHook.next), - (currentHook = nextCurrentHook), - (nextCurrentHook = null !== currentHook ? currentHook.next : null); + (currentHook = nextCurrentHook); else { if (null === nextCurrentHook) throw Error("Rendered more hooks than during the previous render."); currentHook = nextCurrentHook; - var newHook = { + nextCurrentHook = { memoizedState: currentHook.memoizedState, baseState: currentHook.baseState, + baseQueue: currentHook.baseQueue, queue: currentHook.queue, - baseUpdate: currentHook.baseUpdate, next: null }; - workInProgressHook = - null === workInProgressHook - ? (firstWorkInProgressHook = newHook) - : (workInProgressHook.next = newHook); - nextCurrentHook = currentHook.next; + null === workInProgressHook + ? (currentlyRenderingFiber$1.memoizedState = workInProgressHook = nextCurrentHook) + : (workInProgressHook = workInProgressHook.next = nextCurrentHook); } return workInProgressHook; } @@ -3347,74 +3189,100 @@ function updateReducer(reducer) { "Should have a queue. This is likely a bug in React. Please file an issue." ); queue.lastRenderedReducer = reducer; - 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]; - } + 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; } - return [hook.memoizedState, _dispatch]; + current.baseQueue = baseQueue = pendingQueue; + queue.pending = null; } - _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; + if (null !== baseQueue) { + baseQueue = baseQueue.next; + current = current.baseState; + var newBaseQueueLast = (baseFirst = pendingQueue = null), + update = baseQueue; do { - var updateExpirationTime = _update.expirationTime; - updateExpirationTime < renderExpirationTime$1 - ? (didSkip || - ((didSkip = !0), - (newBaseUpdate = baseUpdate), - (firstRenderPhaseUpdate = newState)), - updateExpirationTime > remainingExpirationTime && - ((remainingExpirationTime = updateExpirationTime), - markUnprocessedUpdateTime(remainingExpirationTime))) - : (markRenderEventTimeAndConfig( + 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( updateExpirationTime, - _update.suspenseConfig + update.suspenseConfig ), - (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); + (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); hook.memoizedState = newState; - hook.baseUpdate = newBaseUpdate; - hook.baseState = firstRenderPhaseUpdate; + null === hook.baseQueue && (hook.baseState = newState); queue.lastRenderedState = newState; } - return [hook.memoizedState, queue.dispatch]; + return [newState, dispatch]; } function mountState(initialState) { var hook = mountWorkInProgressHook(); "function" === typeof initialState && (initialState = initialState()); hook.memoizedState = hook.baseState = initialState; initialState = hook.queue = { - last: null, + pending: null, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState @@ -3426,28 +3294,30 @@ 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 }; - 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))); + 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))); return tag; } +function updateRef() { + return updateWorkInProgressHook().memoizedState; +} function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var hook = mountWorkInProgressHook(); - sideEffectTag |= fiberEffectTag; + currentlyRenderingFiber$1.effectTag |= fiberEffectTag; hook.memoizedState = pushEffect( - hookEffectTag, + 1 | hookEffectTag, create, void 0, void 0 === deps ? null : deps @@ -3461,18 +3331,21 @@ function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var prevEffect = currentHook.memoizedState; destroy = prevEffect.destroy; if (null !== deps && areHookInputsEqual(deps, prevEffect.deps)) { - pushEffect(0, create, destroy, deps); + pushEffect(hookEffectTag, create, destroy, deps); return; } } - sideEffectTag |= fiberEffectTag; - hook.memoizedState = pushEffect(hookEffectTag, create, destroy, deps); + currentlyRenderingFiber$1.effectTag |= fiberEffectTag; + hook.memoizedState = pushEffect(1 | hookEffectTag, create, destroy, deps); } function mountEffect(create, deps) { - return mountEffectImpl(516, 192, create, deps); + return mountEffectImpl(516, 4, create, deps); } function updateEffect(create, deps) { - return updateEffectImpl(516, 192, create, deps); + return updateEffectImpl(516, 4, create, deps); +} +function updateLayoutEffect(create, deps) { + return updateEffectImpl(4, 2, create, deps); } function imperativeHandleEffect(create, ref) { if ("function" === typeof ref) @@ -3492,6 +3365,15 @@ 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 = [ @@ -3513,72 +3395,79 @@ 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) { - if (!(25 > numberOfReRenders)) - throw Error( - "Too many re-renders. React limits the number of renders to prevent an infinite loop." - ); - var alternate = fiber.alternate; + 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 ( fiber === currentlyRenderingFiber$1 || - (null !== alternate && alternate === currentlyRenderingFiber$1) + (null !== pending && pending === currentlyRenderingFiber$1) ) - 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; - } + (didScheduleRenderPhaseUpdate = !0), + (suspenseConfig.expirationTime = renderExpirationTime), + (currentlyRenderingFiber$1.expirationTime = renderExpirationTime); 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 === alternate || 0 === alternate.expirationTime) && - ((alternate = queue.lastRenderedReducer), null !== alternate) + (null === pending || 0 === pending.expirationTime) && + ((pending = queue.lastRenderedReducer), null !== pending) ) try { var currentState = queue.lastRenderedState, - eagerState = alternate(currentState, action); - suspenseConfig.eagerReducer = alternate; + eagerState = pending(currentState, action); + suspenseConfig.eagerReducer = pending; suspenseConfig.eagerState = eagerState; - if (is$1(eagerState, currentState)) return; + if (objectIs(eagerState, currentState)) return; } catch (error) { } finally { } - scheduleUpdateOnFiber(fiber, currentTime); + scheduleWork(fiber, currentTime); } } +function updateEventListener() {} var ContextOnlyDispatcher = { readContext: readContext, useCallback: throwInvalidHookError, @@ -3593,7 +3482,8 @@ var ContextOnlyDispatcher = { useDebugValue: throwInvalidHookError, useResponder: throwInvalidHookError, useDeferredValue: throwInvalidHookError, - useTransition: throwInvalidHookError + useTransition: throwInvalidHookError, + useEvent: throwInvalidHookError }, HooksDispatcherOnMount = { readContext: readContext, @@ -3604,13 +3494,13 @@ var ContextOnlyDispatcher = { deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; return mountEffectImpl( 4, - 36, + 2, imperativeHandleEffect.bind(null, create, ref), deps ); }, useLayoutEffect: function(create, deps) { - return mountEffectImpl(4, 36, create, deps); + return mountEffectImpl(4, 2, create, deps); }, useMemo: function(nextCreate, deps) { var hook = mountWorkInProgressHook(); @@ -3624,7 +3514,7 @@ var ContextOnlyDispatcher = { initialArg = void 0 !== init ? init(initialArg) : initialArg; hook.memoizedState = hook.baseState = initialArg; reducer = hook.queue = { - last: null, + pending: null, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialArg @@ -3643,23 +3533,21 @@ var ContextOnlyDispatcher = { }, useState: mountState, useDebugValue: mountDebugValue, - useResponder: createResponderListener, + useResponder: createDeprecatedResponderListener, useDeferredValue: function(value, config) { var _mountState = mountState(value), prevValue = _mountState[0], setValue = _mountState[1]; mountEffect( function() { - 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; - } - }); + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } }, [value, config] ); @@ -3667,112 +3555,113 @@ var ContextOnlyDispatcher = { }, useTransition: function(config) { var _mountState2 = mountState(!1), - isPending = _mountState2[0], - setPending = _mountState2[1]; + isPending = _mountState2[0]; + _mountState2 = _mountState2[1]; return [ - 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] - ), + mountCallback(startTransition.bind(null, _mountState2, config), [ + _mountState2, + config + ]), isPending ]; - } + }, + useEvent: function() {} }, HooksDispatcherOnUpdate = { readContext: readContext, useCallback: updateCallback, useContext: readContext, useEffect: updateEffect, - 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; - }, + useImperativeHandle: updateImperativeHandle, + useLayoutEffect: updateLayoutEffect, + useMemo: updateMemo, useReducer: updateReducer, - useRef: function() { - return updateWorkInProgressHook().memoizedState; + useRef: updateRef, + useState: function() { + return updateReducer(basicStateReducer); }, - useState: updateState, useDebugValue: mountDebugValue, - useResponder: createResponderListener, + useResponder: createDeprecatedResponderListener, useDeferredValue: function(value, config) { - var _updateState = updateState(value), + var _updateState = updateReducer(basicStateReducer), prevValue = _updateState[0], setValue = _updateState[1]; updateEffect( function() { - 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; - } - }); + 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 = updateState(!1), - isPending = _updateState2[0], - setPending = _updateState2[1]; + var _updateState2 = updateReducer(basicStateReducer), + isPending = _updateState2[0]; + _updateState2 = _updateState2[1]; return [ - 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] - ), + updateCallback(startTransition.bind(null, _updateState2, config), [ + _updateState2, + config + ]), 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] + ); + 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 }, now$1 = Scheduler.unstable_now, commitTime = 0, @@ -3785,70 +3674,16 @@ function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) { profilerStartTime = -1; } } -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, +var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner, didReceiveUpdate = !1; function reconcileChildren( - current$$1, + current, workInProgress, nextChildren, renderExpirationTime ) { workInProgress.child = - null === current$$1 + null === current ? mountChildFibers( workInProgress, null, @@ -3857,13 +3692,13 @@ function reconcileChildren( ) : reconcileChildFibers( workInProgress, - current$$1.child, + current.child, nextChildren, renderExpirationTime ); } function updateForwardRef( - current$$1, + current, workInProgress, Component, nextProps, @@ -3873,43 +3708,38 @@ function updateForwardRef( var ref = workInProgress.ref; prepareToReadContext(workInProgress, renderExpirationTime); nextProps = renderWithHooks( - current$$1, + current, workInProgress, Component, nextProps, ref, renderExpirationTime ); - if (null !== current$$1 && !didReceiveUpdate) + if (null !== current && !didReceiveUpdate) return ( - (workInProgress.updateQueue = current$$1.updateQueue), + (workInProgress.updateQueue = current.updateQueue), (workInProgress.effectTag &= -517), - current$$1.expirationTime <= renderExpirationTime && - (current$$1.expirationTime = 0), + current.expirationTime <= renderExpirationTime && + (current.expirationTime = 0), bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ) ); workInProgress.effectTag |= 1; - reconcileChildren( - current$$1, - workInProgress, - nextProps, - renderExpirationTime - ); + reconcileChildren(current, workInProgress, nextProps, renderExpirationTime); return workInProgress.child; } function updateMemoComponent( - current$$1, + current, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime ) { - if (null === current$$1) { + if (null === current) { var type = Component.type; if ( "function" === typeof type && @@ -3922,7 +3752,7 @@ function updateMemoComponent( (workInProgress.tag = 15), (workInProgress.type = type), updateSimpleMemoComponent( - current$$1, + current, workInProgress, type, nextProps, @@ -3930,7 +3760,7 @@ function updateMemoComponent( renderExpirationTime ) ); - current$$1 = createFiberFromTypeAndProps( + current = createFiberFromTypeAndProps( Component.type, null, nextProps, @@ -3938,65 +3768,66 @@ function updateMemoComponent( workInProgress.mode, renderExpirationTime ); - current$$1.ref = workInProgress.ref; - current$$1.return = workInProgress; - return (workInProgress.child = current$$1); + current.ref = workInProgress.ref; + current.return = workInProgress; + return (workInProgress.child = current); } - type = current$$1.child; + type = current.child; if ( updateExpirationTime < renderExpirationTime && ((updateExpirationTime = type.memoizedProps), (Component = Component.compare), (Component = null !== Component ? Component : shallowEqual), Component(updateExpirationTime, nextProps) && - current$$1.ref === workInProgress.ref) + current.ref === workInProgress.ref) ) return bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ); workInProgress.effectTag |= 1; - current$$1 = createWorkInProgress(type, nextProps, renderExpirationTime); - current$$1.ref = workInProgress.ref; - current$$1.return = workInProgress; - return (workInProgress.child = current$$1); + current = createWorkInProgress(type, nextProps); + current.ref = workInProgress.ref; + current.return = workInProgress; + return (workInProgress.child = current); } function updateSimpleMemoComponent( - current$$1, + current, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime ) { - return null !== current$$1 && - shallowEqual(current$$1.memoizedProps, nextProps) && - current$$1.ref === workInProgress.ref && + return null !== current && + shallowEqual(current.memoizedProps, nextProps) && + current.ref === workInProgress.ref && ((didReceiveUpdate = !1), updateExpirationTime < renderExpirationTime) - ? bailoutOnAlreadyFinishedWork( - current$$1, + ? ((workInProgress.expirationTime = current.expirationTime), + bailoutOnAlreadyFinishedWork( + current, workInProgress, renderExpirationTime - ) + )) : updateFunctionComponent( - current$$1, + current, workInProgress, Component, nextProps, renderExpirationTime ); } -function markRef(current$$1, workInProgress) { +function markRef(current, workInProgress) { var ref = workInProgress.ref; if ( - (null === current$$1 && null !== ref) || - (null !== current$$1 && current$$1.ref !== ref) + (null === current && null !== ref) || + (null !== current && current.ref !== ref) ) workInProgress.effectTag |= 128; } function updateFunctionComponent( - current$$1, + current, workInProgress, Component, nextProps, @@ -4008,36 +3839,31 @@ function updateFunctionComponent( context = getMaskedContext(workInProgress, context); prepareToReadContext(workInProgress, renderExpirationTime); Component = renderWithHooks( - current$$1, + current, workInProgress, Component, nextProps, context, renderExpirationTime ); - if (null !== current$$1 && !didReceiveUpdate) + if (null !== current && !didReceiveUpdate) return ( - (workInProgress.updateQueue = current$$1.updateQueue), + (workInProgress.updateQueue = current.updateQueue), (workInProgress.effectTag &= -517), - current$$1.expirationTime <= renderExpirationTime && - (current$$1.expirationTime = 0), + current.expirationTime <= renderExpirationTime && + (current.expirationTime = 0), bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ) ); workInProgress.effectTag |= 1; - reconcileChildren( - current$$1, - workInProgress, - Component, - renderExpirationTime - ); + reconcileChildren(current, workInProgress, Component, renderExpirationTime); return workInProgress.child; } function updateClassComponent( - current$$1, + current, workInProgress, Component, nextProps, @@ -4049,16 +3875,11 @@ function updateClassComponent( } else hasContext = !1; prepareToReadContext(workInProgress, renderExpirationTime); if (null === workInProgress.stateNode) - null !== current$$1 && - ((current$$1.alternate = null), + null !== current && + ((current.alternate = null), (workInProgress.alternate = null), (workInProgress.effectTag |= 2)), - constructClassInstance( - workInProgress, - Component, - nextProps, - renderExpirationTime - ), + constructClassInstance(workInProgress, Component, nextProps), mountClassInstance( workInProgress, Component, @@ -4066,7 +3887,7 @@ function updateClassComponent( renderExpirationTime ), (nextProps = !0); - else if (null === current$$1) { + else if (null === current) { var instance = workInProgress.stateNode, oldProps = workInProgress.memoizedProps; instance.props = oldProps; @@ -4094,17 +3915,14 @@ function updateClassComponent( )); hasForceUpdate = !1; var oldState = workInProgress.memoizedState; - oldContext = instance.state = oldState; - var updateQueue = workInProgress.updateQueue; - null !== updateQueue && - (processUpdateQueue( - workInProgress, - updateQueue, - nextProps, - instance, - renderExpirationTime - ), - (oldContext = workInProgress.memoizedState)); + instance.state = oldState; + processUpdateQueue( + workInProgress, + nextProps, + instance, + renderExpirationTime + ); + oldContext = workInProgress.memoizedState; oldProps !== nextProps || oldState !== oldContext || didPerformWorkStackCursor.current || @@ -4150,6 +3968,7 @@ function updateClassComponent( (nextProps = !1)); } else (instance = workInProgress.stateNode), + cloneUpdateQueue(current, workInProgress), (oldProps = workInProgress.memoizedProps), (instance.props = workInProgress.type === workInProgress.elementType @@ -4178,17 +3997,14 @@ function updateClassComponent( )), (hasForceUpdate = !1), (oldContext = workInProgress.memoizedState), - (oldState = instance.state = oldContext), - (updateQueue = workInProgress.updateQueue), - null !== updateQueue && - (processUpdateQueue( - workInProgress, - updateQueue, - nextProps, - instance, - renderExpirationTime - ), - (oldState = workInProgress.memoizedState)), + (instance.state = oldContext), + processUpdateQueue( + workInProgress, + nextProps, + instance, + renderExpirationTime + ), + (oldState = workInProgress.memoizedState), oldProps !== nextProps || oldContext !== oldState || didPerformWorkStackCursor.current || @@ -4232,12 +4048,12 @@ function updateClassComponent( "function" === typeof instance.getSnapshotBeforeUpdate && (workInProgress.effectTag |= 256)) : ("function" !== typeof instance.componentDidUpdate || - (oldProps === current$$1.memoizedProps && - oldContext === current$$1.memoizedState) || + (oldProps === current.memoizedProps && + oldContext === current.memoizedState) || (workInProgress.effectTag |= 4), "function" !== typeof instance.getSnapshotBeforeUpdate || - (oldProps === current$$1.memoizedProps && - oldContext === current$$1.memoizedState) || + (oldProps === current.memoizedProps && + oldContext === current.memoizedState) || (workInProgress.effectTag |= 256), (workInProgress.memoizedProps = nextProps), (workInProgress.memoizedState = oldState)), @@ -4246,16 +4062,16 @@ function updateClassComponent( (instance.context = contextType), (nextProps = getDerivedStateFromProps)) : ("function" !== typeof instance.componentDidUpdate || - (oldProps === current$$1.memoizedProps && - oldContext === current$$1.memoizedState) || + (oldProps === current.memoizedProps && + oldContext === current.memoizedState) || (workInProgress.effectTag |= 4), "function" !== typeof instance.getSnapshotBeforeUpdate || - (oldProps === current$$1.memoizedProps && - oldContext === current$$1.memoizedState) || + (oldProps === current.memoizedProps && + oldContext === current.memoizedState) || (workInProgress.effectTag |= 256), (nextProps = !1)); return finishClassComponent( - current$$1, + current, workInProgress, Component, nextProps, @@ -4264,26 +4080,26 @@ function updateClassComponent( ); } function finishClassComponent( - current$$1, + current, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime ) { - markRef(current$$1, workInProgress); + markRef(current, workInProgress); var didCaptureError = 0 !== (workInProgress.effectTag & 64); if (!shouldUpdate && !didCaptureError) return ( hasContext && invalidateContextProvider(workInProgress, Component, !1), bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ) ); shouldUpdate = workInProgress.stateNode; - ReactCurrentOwner$3.current = workInProgress; + ReactCurrentOwner$1.current = workInProgress; if ( didCaptureError && "function" !== typeof Component.getDerivedStateFromError @@ -4292,11 +4108,11 @@ function finishClassComponent( profilerStartTime = -1; } else nextChildren = shouldUpdate.render(); workInProgress.effectTag |= 1; - null !== current$$1 && didCaptureError + null !== current && didCaptureError ? ((didCaptureError = nextChildren), (workInProgress.child = reconcileChildFibers( workInProgress, - current$$1.child, + current.child, null, renderExpirationTime )), @@ -4307,7 +4123,7 @@ function finishClassComponent( renderExpirationTime ))) : reconcileChildren( - current$$1, + current, workInProgress, nextChildren, renderExpirationTime @@ -4330,7 +4146,7 @@ function pushHostRootContext(workInProgress) { } var SUSPENDED_MARKER = { dehydrated: null, retryTime: 0 }; function updateSuspenseComponent( - current$$1, + current, workInProgress, renderExpirationTime ) { @@ -4342,32 +4158,30 @@ function updateSuspenseComponent( (JSCompiler_temp = 0 !== (workInProgress.effectTag & 64)) || (JSCompiler_temp = 0 !== (suspenseContext & 2) && - (null === current$$1 || null !== current$$1.memoizedState)); + (null === current || null !== current.memoizedState)); JSCompiler_temp ? ((nextDidTimeout = !0), (workInProgress.effectTag &= -65)) - : (null !== current$$1 && null === current$$1.memoizedState) || + : (null !== current && null === current.memoizedState) || void 0 === nextProps.fallback || !0 === nextProps.unstable_avoidThisFallback || (suspenseContext |= 1); - push(suspenseStackCursor, suspenseContext & 1, workInProgress); - if (null === current$$1) { - void 0 !== nextProps.fallback && - tryToClaimNextHydratableInstance(workInProgress); + push(suspenseStackCursor, suspenseContext & 1); + if (null === current) { if (nextDidTimeout) { nextDidTimeout = nextProps.fallback; nextProps = createFiberFromFragment(null, mode, 0, null); nextProps.return = workInProgress; if (0 === (workInProgress.mode & 2)) for ( - current$$1 = + current = null !== workInProgress.memoizedState ? workInProgress.child.child : workInProgress.child, - nextProps.child = current$$1; - null !== current$$1; + nextProps.child = current; + null !== current; ) - (current$$1.return = nextProps), (current$$1 = current$$1.sibling); + (current.return = nextProps), (current = current.sibling); renderExpirationTime = createFiberFromFragment( nextDidTimeout, mode, @@ -4389,15 +4203,14 @@ function updateSuspenseComponent( renderExpirationTime )); } - if (null !== current$$1.memoizedState) { - current$$1 = current$$1.child; - mode = current$$1.sibling; + if (null !== current.memoizedState) { + current = current.child; + mode = current.sibling; if (nextDidTimeout) { nextProps = nextProps.fallback; renderExpirationTime = createWorkInProgress( - current$$1, - current$$1.pendingProps, - 0 + current, + current.pendingProps ); renderExpirationTime.return = workInProgress; if ( @@ -4406,7 +4219,7 @@ function updateSuspenseComponent( null !== workInProgress.memoizedState ? workInProgress.child.child : workInProgress.child), - nextDidTimeout !== current$$1.child) + nextDidTimeout !== current.child) ) for ( renderExpirationTime.child = nextDidTimeout; @@ -4417,12 +4230,12 @@ function updateSuspenseComponent( (nextDidTimeout = nextDidTimeout.sibling); if (workInProgress.mode & 8) { nextDidTimeout = 0; - for (current$$1 = renderExpirationTime.child; null !== current$$1; ) - (nextDidTimeout += current$$1.treeBaseDuration), - (current$$1 = current$$1.sibling); + for (current = renderExpirationTime.child; null !== current; ) + (nextDidTimeout += current.treeBaseDuration), + (current = current.sibling); renderExpirationTime.treeBaseDuration = nextDidTimeout; } - mode = createWorkInProgress(mode, nextProps, mode.expirationTime); + mode = createWorkInProgress(mode, nextProps); mode.return = workInProgress; renderExpirationTime.sibling = mode; renderExpirationTime.childExpirationTime = 0; @@ -4432,37 +4245,37 @@ function updateSuspenseComponent( } renderExpirationTime = reconcileChildFibers( workInProgress, - current$$1.child, + current.child, nextProps.children, renderExpirationTime ); workInProgress.memoizedState = null; return (workInProgress.child = renderExpirationTime); } - current$$1 = current$$1.child; + current = current.child; if (nextDidTimeout) { nextDidTimeout = nextProps.fallback; nextProps = createFiberFromFragment(null, mode, 0, null); nextProps.return = workInProgress; - nextProps.child = current$$1; - null !== current$$1 && (current$$1.return = nextProps); + nextProps.child = current; + null !== current && (current.return = nextProps); if (0 === (workInProgress.mode & 2)) for ( - current$$1 = + current = null !== workInProgress.memoizedState ? workInProgress.child.child : workInProgress.child, - nextProps.child = current$$1; - null !== current$$1; + nextProps.child = current; + null !== current; ) - (current$$1.return = nextProps), (current$$1 = current$$1.sibling); + (current.return = nextProps), (current = current.sibling); if (workInProgress.mode & 8) { - current$$1 = 0; + current = 0; for (suspenseContext = nextProps.child; null !== suspenseContext; ) - (current$$1 += suspenseContext.treeBaseDuration), + (current += suspenseContext.treeBaseDuration), (suspenseContext = suspenseContext.sibling); - nextProps.treeBaseDuration = current$$1; + nextProps.treeBaseDuration = current; } renderExpirationTime = createFiberFromFragment( nextDidTimeout, @@ -4481,7 +4294,7 @@ function updateSuspenseComponent( workInProgress.memoizedState = null; return (workInProgress.child = reconcileChildFibers( workInProgress, - current$$1, + current, nextProps.children, renderExpirationTime )); @@ -4508,6 +4321,7 @@ function initSuspenseListRenderState( ? (workInProgress.memoizedState = { isBackwards: isBackwards, rendering: null, + renderingStartTime: 0, last: lastContentRow, tail: tail, tailExpiration: 0, @@ -4516,6 +4330,7 @@ function initSuspenseListRenderState( }) : ((renderState.isBackwards = isBackwards), (renderState.rendering = null), + (renderState.renderingStartTime = 0), (renderState.last = lastContentRow), (renderState.tail = tail), (renderState.tailExpiration = 0), @@ -4523,7 +4338,7 @@ function initSuspenseListRenderState( (renderState.lastEffect = lastEffectBeforeRendering)); } function updateSuspenseListComponent( - current$$1, + current, workInProgress, renderExpirationTime ) { @@ -4531,7 +4346,7 @@ function updateSuspenseListComponent( revealOrder = nextProps.revealOrder, tailMode = nextProps.tail; reconcileChildren( - current$$1, + current, workInProgress, nextProps.children, renderExpirationTime @@ -4540,42 +4355,39 @@ function updateSuspenseListComponent( if (0 !== (nextProps & 2)) (nextProps = (nextProps & 1) | 2), (workInProgress.effectTag |= 64); else { - 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; + 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; continue; - } - if (current$$1 === workInProgress) break a; - for (; null === current$$1.sibling; ) { - if ( - null === current$$1.return || - current$$1.return === workInProgress - ) + } + if (current === workInProgress) break a; + for (; null === current.sibling; ) { + if (null === current.return || current.return === workInProgress) break a; - current$$1 = current$$1.return; + current = current.return; } - current$$1.sibling.return = current$$1.return; - current$$1 = current$$1.sibling; + current.sibling.return = current.return; + current = current.sibling; } nextProps &= 1; } - push(suspenseStackCursor, nextProps, workInProgress); + push(suspenseStackCursor, nextProps); if (0 === (workInProgress.mode & 2)) workInProgress.memoizedState = null; else switch (revealOrder) { case "forwards": renderExpirationTime = workInProgress.child; for (revealOrder = null; null !== renderExpirationTime; ) - (current$$1 = renderExpirationTime.alternate), - null !== current$$1 && - null === findFirstSuspended(current$$1) && + (current = renderExpirationTime.alternate), + null !== current && + null === findFirstSuspended(current) && (revealOrder = renderExpirationTime), (renderExpirationTime = renderExpirationTime.sibling); renderExpirationTime = revealOrder; @@ -4597,15 +4409,15 @@ function updateSuspenseListComponent( renderExpirationTime = null; revealOrder = workInProgress.child; for (workInProgress.child = null; null !== revealOrder; ) { - current$$1 = revealOrder.alternate; - if (null !== current$$1 && null === findFirstSuspended(current$$1)) { + current = revealOrder.alternate; + if (null !== current && null === findFirstSuspended(current)) { workInProgress.child = revealOrder; break; } - current$$1 = revealOrder.sibling; + current = revealOrder.sibling; revealOrder.sibling = renderExpirationTime; renderExpirationTime = revealOrder; - revealOrder = current$$1; + revealOrder = current; } initSuspenseListRenderState( workInProgress, @@ -4632,36 +4444,30 @@ function updateSuspenseListComponent( return workInProgress.child; } function bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ) { - null !== current$$1 && - (workInProgress.dependencies = current$$1.dependencies); + null !== current && (workInProgress.dependencies = current.dependencies); profilerStartTime = -1; var updateExpirationTime = workInProgress.expirationTime; 0 !== updateExpirationTime && markUnprocessedUpdateTime(updateExpirationTime); if (workInProgress.childExpirationTime < renderExpirationTime) return null; - if (null !== current$$1 && workInProgress.child !== current$$1.child) + if (null !== current && workInProgress.child !== current.child) throw Error("Resuming work not yet implemented."); if (null !== workInProgress.child) { - current$$1 = workInProgress.child; - renderExpirationTime = createWorkInProgress( - current$$1, - current$$1.pendingProps, - current$$1.expirationTime - ); + current = workInProgress.child; + renderExpirationTime = createWorkInProgress(current, current.pendingProps); workInProgress.child = renderExpirationTime; for ( renderExpirationTime.return = workInProgress; - null !== current$$1.sibling; + null !== current.sibling; ) - (current$$1 = current$$1.sibling), + (current = current.sibling), (renderExpirationTime = renderExpirationTime.sibling = createWorkInProgress( - current$$1, - current$$1.pendingProps, - current$$1.expirationTime + current, + current.pendingProps )), (renderExpirationTime.return = workInProgress); renderExpirationTime.sibling = null; @@ -4683,12 +4489,7 @@ appendAllChildren = function( var instance = node.stateNode; needsVisibilityToggle && isHidden && - (instance = cloneHiddenInstance( - instance, - node.type, - node.memoizedProps, - node - )); + (instance = cloneHiddenInstance(instance)); appendChildNode(parent.node, instance.node); } else if (6 === node.tag) { instance = node.stateNode; @@ -4741,12 +4542,7 @@ function appendAllChildrenToContainer( var instance = node.stateNode; needsVisibilityToggle && isHidden && - (instance = cloneHiddenInstance( - instance, - node.type, - node.memoizedProps, - node - )); + (instance = cloneHiddenInstance(instance)); appendChildNodeToSet(containerChildSet, instance.node); } else if (6 === node.tag) { instance = node.stateNode; @@ -4832,8 +4628,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), @@ -4843,16 +4639,17 @@ 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)); + 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); }; function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { switch (renderState.tailMode) { @@ -4878,67 +4675,78 @@ function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { : (_lastTailNode.sibling = null); } } -function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { +function completeWork(current, workInProgress, renderExpirationTime) { var newProps = workInProgress.pendingProps; switch (workInProgress.tag) { case 2: - break; case 16: - break; case 15: case 0: - break; + case 11: + case 7: + case 8: + case 12: + case 9: + case 14: + return null; case 1: - isContextProvider(workInProgress.type) && popContext(workInProgress); - break; + return isContextProvider(workInProgress.type) && popContext(), null; case 3: - popHostContainer(workInProgress); - popTopLevelContextObject(workInProgress); - current = workInProgress.stateNode; - current.pendingContext && - ((current.context = current.pendingContext), - (current.pendingContext = null)); - updateHostContainer(workInProgress); - break; + 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$jscomp$0 = workInProgress.type; + renderExpirationTime = workInProgress.type; if (null !== current && null != workInProgress.stateNode) updateHostComponent$1( current, workInProgress, - renderExpirationTime$jscomp$0, + renderExpirationTime, newProps, rootContainerInstance ), current.ref !== workInProgress.ref && (workInProgress.effectTag |= 128); - else if (newProps) { + 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$jscomp$0 = getViewConfigForType( - renderExpirationTime$jscomp$0 - ); + renderExpirationTime = getViewConfigForType(renderExpirationTime); var updatePayload = diffProperties( null, emptyObject, newProps, - renderExpirationTime$jscomp$0.validAttributes + renderExpirationTime.validAttributes ); rootContainerInstance = createNode( current, - renderExpirationTime$jscomp$0.uiViewClassName, + renderExpirationTime.uiViewClassName, rootContainerInstance, updatePayload, workInProgress ); current = new ReactFabricHostComponent( current, - renderExpirationTime$jscomp$0, + renderExpirationTime, newProps, workInProgress ); @@ -4946,11 +4754,8 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { appendAllChildren(current, workInProgress, !1, !1); workInProgress.stateNode = current; null !== workInProgress.ref && (workInProgress.effectTag |= 128); - } 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; + } + return null; case 6: if (current && null != workInProgress.stateNode) updateHostText$1( @@ -4973,33 +4778,30 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { workInProgress ); } - break; - case 11: - break; + return null; case 13: - pop(suspenseStackCursor, workInProgress); + pop(suspenseStackCursor); newProps = workInProgress.memoizedState; if (0 !== (workInProgress.effectTag & 64)) return ( - (workInProgress.expirationTime = renderExpirationTime$jscomp$0), - workInProgress + (workInProgress.expirationTime = renderExpirationTime), workInProgress ); newProps = null !== newProps; rootContainerInstance = !1; null !== current && - ((renderExpirationTime$jscomp$0 = current.memoizedState), - (rootContainerInstance = null !== renderExpirationTime$jscomp$0), + ((renderExpirationTime = current.memoizedState), + (rootContainerInstance = null !== renderExpirationTime), newProps || - null === renderExpirationTime$jscomp$0 || - ((renderExpirationTime$jscomp$0 = current.child.sibling), - null !== renderExpirationTime$jscomp$0 && + null === renderExpirationTime || + ((renderExpirationTime = current.child.sibling), + null !== renderExpirationTime && ((updatePayload = workInProgress.firstEffect), null !== updatePayload - ? ((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)))); + ? ((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 && @@ -5016,38 +4818,27 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { workInProgressRootExitStatus = RootSuspendedWithDelay; 0 !== workInProgressRootNextUnprocessedUpdateTime && null !== workInProgressRoot && - (markRootSuspendedAtTime(workInProgressRoot, renderExpirationTime), + (markRootSuspendedAtTime( + workInProgressRoot, + renderExpirationTime$1 + ), markRootUpdatedAtTime( workInProgressRoot, workInProgressRootNextUnprocessedUpdateTime )); } newProps && (workInProgress.effectTag |= 4); - break; - case 7: - break; - case 8: - break; - case 12: - break; + return null; case 4: - popHostContainer(workInProgress); - updateHostContainer(workInProgress); - break; + return popHostContainer(), updateHostContainer(workInProgress), null; case 10: - popProvider(workInProgress); - break; - case 9: - break; - case 14: - break; + return popProvider(workInProgress), null; case 17: - isContextProvider(workInProgress.type) && popContext(workInProgress); - break; + return isContextProvider(workInProgress.type) && popContext(), null; case 19: - pop(suspenseStackCursor, workInProgress); + pop(suspenseStackCursor); newProps = workInProgress.memoizedState; - if (null === newProps) break; + if (null === newProps) return null; rootContainerInstance = 0 !== (workInProgress.effectTag & 64); updatePayload = newProps.rendering; if (null === updatePayload) @@ -5069,7 +4860,7 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { null === newProps.lastEffect && (workInProgress.firstEffect = null); workInProgress.lastEffect = newProps.lastEffect; - current = renderExpirationTime$jscomp$0; + current = renderExpirationTime; for (newProps = workInProgress.child; null !== newProps; ) (rootContainerInstance = newProps), (updatePayload = current), @@ -5077,9 +4868,8 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { (rootContainerInstance.nextEffect = null), (rootContainerInstance.firstEffect = null), (rootContainerInstance.lastEffect = null), - (renderExpirationTime$jscomp$0 = - rootContainerInstance.alternate), - null === renderExpirationTime$jscomp$0 + (renderExpirationTime = rootContainerInstance.alternate), + null === renderExpirationTime ? ((rootContainerInstance.childExpirationTime = 0), (rootContainerInstance.expirationTime = updatePayload), (rootContainerInstance.child = null), @@ -5090,19 +4880,18 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { (rootContainerInstance.selfBaseDuration = 0), (rootContainerInstance.treeBaseDuration = 0)) : ((rootContainerInstance.childExpirationTime = - renderExpirationTime$jscomp$0.childExpirationTime), + renderExpirationTime.childExpirationTime), (rootContainerInstance.expirationTime = - renderExpirationTime$jscomp$0.expirationTime), + renderExpirationTime.expirationTime), (rootContainerInstance.child = - renderExpirationTime$jscomp$0.child), + renderExpirationTime.child), (rootContainerInstance.memoizedProps = - renderExpirationTime$jscomp$0.memoizedProps), + renderExpirationTime.memoizedProps), (rootContainerInstance.memoizedState = - renderExpirationTime$jscomp$0.memoizedState), + renderExpirationTime.memoizedState), (rootContainerInstance.updateQueue = - renderExpirationTime$jscomp$0.updateQueue), - (updatePayload = - renderExpirationTime$jscomp$0.dependencies), + renderExpirationTime.updateQueue), + (updatePayload = renderExpirationTime.dependencies), (rootContainerInstance.dependencies = null === updatePayload ? null @@ -5112,14 +4901,13 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { responders: updatePayload.responders }), (rootContainerInstance.selfBaseDuration = - renderExpirationTime$jscomp$0.selfBaseDuration), + renderExpirationTime.selfBaseDuration), (rootContainerInstance.treeBaseDuration = - renderExpirationTime$jscomp$0.treeBaseDuration)), + renderExpirationTime.treeBaseDuration)), (newProps = newProps.sibling); push( suspenseStackCursor, - (suspenseStackCursor.current & 1) | 2, - workInProgress + (suspenseStackCursor.current & 1) | 2 ); return workInProgress.child; } @@ -5142,18 +4930,20 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { null === newProps.tail && "hidden" === newProps.tailMode && !updatePayload.alternate) - ) { - workInProgress = workInProgress.lastEffect = newProps.lastEffect; - null !== workInProgress && (workInProgress.nextEffect = null); - break; - } + ) + return ( + (workInProgress = workInProgress.lastEffect = + newProps.lastEffect), + null !== workInProgress && (workInProgress.nextEffect = null), + null + ); } else - now() > newProps.tailExpiration && - 1 < renderExpirationTime$jscomp$0 && + 2 * now() - newProps.renderingStartTime > newProps.tailExpiration && + 1 < renderExpirationTime && ((workInProgress.effectTag |= 64), (rootContainerInstance = !0), cutOffTailIfNeeded(newProps, !1), - (current = renderExpirationTime$jscomp$0 - 1), + (current = renderExpirationTime - 1), (workInProgress.expirationTime = workInProgress.childExpirationTime = current), null === spawnedWorkDuringRender ? (spawnedWorkDuringRender = [current]) @@ -5167,49 +4957,44 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { : (workInProgress.child = updatePayload), (newProps.last = updatePayload)); } - if (null !== newProps.tail) - return ( - 0 === newProps.tailExpiration && + 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), - (newProps = suspenseStackCursor.current), + (workInProgress = suspenseStackCursor.current), push( suspenseStackCursor, - rootContainerInstance ? (newProps & 1) | 2 : newProps & 1, - workInProgress + rootContainerInstance + ? (workInProgress & 1) | 2 + : workInProgress & 1 ), - 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." - ); + current) + : null; } - return 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(workInProgress); + isContextProvider(workInProgress.type) && popContext(); var effectTag = workInProgress.effectTag; return effectTag & 4096 ? ((workInProgress.effectTag = (effectTag & -4097) | 64), workInProgress) : null; case 3: - popHostContainer(workInProgress); - popTopLevelContextObject(workInProgress); + popHostContainer(); + pop(didPerformWorkStackCursor); + pop(contextStackCursor); effectTag = workInProgress.effectTag; if (0 !== (effectTag & 64)) throw Error( @@ -5221,7 +5006,7 @@ function unwindWork(workInProgress) { return popHostContext(workInProgress), null; case 13: return ( - pop(suspenseStackCursor, workInProgress), + pop(suspenseStackCursor), (effectTag = workInProgress.effectTag), effectTag & 4096 ? ((workInProgress.effectTag = (effectTag & -4097) | 64), @@ -5229,9 +5014,9 @@ function unwindWork(workInProgress) { : null ); case 19: - return pop(suspenseStackCursor, workInProgress), null; + return pop(suspenseStackCursor), null; case 4: - return popHostContainer(workInProgress), null; + return popHostContainer(), null; case 10: return popProvider(workInProgress), null; default: @@ -5288,102 +5073,192 @@ function logError(boundary, errorInfo) { }); } } -function safelyCallComponentWillUnmount(current$$1, instance) { +function safelyCallComponentWillUnmount(current, instance) { try { - (instance.props = current$$1.memoizedProps), - (instance.state = current$$1.memoizedState), + (instance.props = current.memoizedProps), + (instance.state = current.memoizedState), instance.componentWillUnmount(); } catch (unmountError) { - captureCommitPhaseError(current$$1, unmountError); + captureCommitPhaseError(current, unmountError); } } -function safelyDetachRef(current$$1) { - var ref = current$$1.ref; +function safelyDetachRef(current) { + var ref = current.ref; if (null !== ref) if ("function" === typeof ref) try { ref(null); } catch (refError) { - captureCommitPhaseError(current$$1, refError); + captureCommitPhaseError(current, refError); } else ref.current = null; } -function commitBeforeMutationLifeCycles(current$$1, finishedWork) { +function commitBeforeMutationLifeCycles(current, finishedWork) { switch (finishedWork.tag) { case 0: case 11: case 15: - commitHookEffectList(2, 0, finishedWork); - break; + case 22: + return; case 1: - if (finishedWork.effectTag & 256 && null !== current$$1) { - var prevProps = current$$1.memoizedProps, - prevState = current$$1.memoizedState; - current$$1 = finishedWork.stateNode; - finishedWork = current$$1.getSnapshotBeforeUpdate( + if (finishedWork.effectTag & 256 && null !== current) { + var prevProps = current.memoizedProps, + prevState = current.memoizedState; + current = finishedWork.stateNode; + finishedWork = current.getSnapshotBeforeUpdate( finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState ); - current$$1.__reactInternalSnapshotBeforeUpdate = finishedWork; + current.__reactInternalSnapshotBeforeUpdate = finishedWork; } - break; + return; case 3: case 5: case 6: case 4: case 17: - break; - default: - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); + 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 commitHookEffectList(unmountTag, mountTag, finishedWork) { +function commitHookEffectListUnmount(tag, finishedWork) { finishedWork = finishedWork.updateQueue; finishedWork = null !== finishedWork ? finishedWork.lastEffect : null; if (null !== finishedWork) { var effect = (finishedWork = finishedWork.next); do { - if (0 !== (effect.tag & unmountTag)) { + if ((effect.tag & tag) === tag) { 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 commitUnmount(finishedRoot, current$$1$jscomp$0, renderPriorityLevel) { +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" === typeof onCommitFiberUnmount && - onCommitFiberUnmount(current$$1$jscomp$0); - switch (current$$1$jscomp$0.tag) { + onCommitFiberUnmount(current$jscomp$0); + switch (current$jscomp$0.tag) { case 0: case 11: case 14: case 15: - finishedRoot = current$$1$jscomp$0.updateQueue; + case 22: + finishedRoot = current$jscomp$0.updateQueue; if ( null !== finishedRoot && ((finishedRoot = finishedRoot.lastEffect), null !== finishedRoot) ) { var firstEffect = finishedRoot.next; - runWithPriority$1( + runWithPriority( 97 < renderPriorityLevel ? 97 : renderPriorityLevel, function() { var effect = firstEffect; do { - var destroy = effect.destroy; - if (void 0 !== destroy) { - var current$$1 = current$$1$jscomp$0; + var _destroy = effect.destroy; + if (void 0 !== _destroy) { + var current = current$jscomp$0; try { - destroy(); + _destroy(); } catch (error) { - captureCommitPhaseError(current$$1, error); + captureCommitPhaseError(current, error); } } effect = effect.next; @@ -5393,42 +5268,41 @@ function commitUnmount(finishedRoot, current$$1$jscomp$0, renderPriorityLevel) { } break; case 1: - safelyDetachRef(current$$1$jscomp$0); - renderPriorityLevel = current$$1$jscomp$0.stateNode; + safelyDetachRef(current$jscomp$0); + renderPriorityLevel = current$jscomp$0.stateNode; "function" === typeof renderPriorityLevel.componentWillUnmount && - safelyCallComponentWillUnmount( - current$$1$jscomp$0, - renderPriorityLevel - ); + safelyCallComponentWillUnmount(current$jscomp$0, renderPriorityLevel); break; case 5: - safelyDetachRef(current$$1$jscomp$0); + safelyDetachRef(current$jscomp$0); break; case 4: - createChildNodeSet(current$$1$jscomp$0.stateNode.containerInfo); + createChildNodeSet(current$jscomp$0.stateNode.containerInfo); } } -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; +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; null !== alternate && detachFiber(alternate); } -function commitWork(current$$1, finishedWork) { +function commitWork(current, finishedWork) { switch (finishedWork.tag) { case 0: case 11: case 14: case 15: - commitHookEffectList(4, 8, finishedWork); + case 22: + commitHookEffectListUnmount(3, finishedWork); return; case 12: return; @@ -5441,19 +5315,20 @@ function commitWork(current$$1, finishedWork) { attachSuspenseRetryListeners(finishedWork); return; } - 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." - ); + 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." + ); } } function attachSuspenseRetryListeners(finishedWork) { @@ -5513,7 +5388,7 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { return expirationTime; } var ceil = Math.ceil, - ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher, + ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, NoContext = 0, LegacyUnbatchedContext = 8, @@ -5528,7 +5403,7 @@ var ceil = Math.ceil, executionContext = NoContext, workInProgressRoot = null, workInProgress = null, - renderExpirationTime = 0, + renderExpirationTime$1 = 0, workInProgressRootExitStatus = RootIncomplete, workInProgressRootFatalError = null, workInProgressRootLatestProcessedExpirationTime = 1073741823, @@ -5555,8 +5430,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; @@ -5564,7 +5439,7 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { var priorityLevel = getCurrentPriorityLevel(); if (0 === (fiber & 4)) return 99 === priorityLevel ? 1073741823 : 1073741822; if ((executionContext & RenderContext) !== NoContext) - return renderExpirationTime; + return renderExpirationTime$1; if (null !== suspenseConfig) currentTime = 1073741821 - @@ -5596,11 +5471,11 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { throw Error("Expected a valid priority level"); } null !== workInProgressRoot && - currentTime === renderExpirationTime && + currentTime === renderExpirationTime$1 && --currentTime; return currentTime; } -function scheduleUpdateOnFiber(fiber, expirationTime) { +function scheduleWork(fiber, expirationTime) { if (50 < nestedUpdateCount) throw ((nestedUpdateCount = 0), (rootWithNestedUpdates = null), @@ -5657,7 +5532,7 @@ function markUpdateTimeFromFiberToRoot(fiber, expirationTime) { (workInProgressRoot === root && (markUnprocessedUpdateTime(expirationTime), workInProgressRootExitStatus === RootSuspendedWithDelay && - markRootSuspendedAtTime(root, renderExpirationTime)), + markRootSuspendedAtTime(root, renderExpirationTime$1)), markRootUpdatedAtTime(root, expirationTime)); return root; } @@ -5666,9 +5541,10 @@ function getNextRootExpirationTimeToWorkOn(root) { if (0 !== lastExpiredTime) return lastExpiredTime; lastExpiredTime = root.firstPendingTime; if (!isRootSuspendedAtTime(root, lastExpiredTime)) return lastExpiredTime; - lastExpiredTime = root.lastPingedTime; + var lastPingedTime = root.lastPingedTime; root = root.nextKnownPendingLevel; - return lastExpiredTime > root ? lastExpiredTime : root; + root = lastPingedTime > root ? lastPingedTime : root; + return 2 >= root && lastExpiredTime !== root ? 0 : root; } function ensureRootIsScheduled(root) { if (0 !== root.lastExpiredTime) @@ -5717,270 +5593,232 @@ function ensureRootIsScheduled(root) { } function performConcurrentWorkOnRoot(root, didTimeout) { currentEventTime = 0; - if (didTimeout) - return ( - (didTimeout = requestCurrentTimeForUpdate()), - markRootExpiredAtTime(root, didTimeout), + 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), ensureRootIsScheduled(root), - 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); - } - 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) + 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) ) { - 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); + if ( + workInProgressRootHasPendingPing && + ((expirationTime = root.lastPingedTime), + 0 === expirationTime || expirationTime >= lastExpiredTime) + ) { + root.lastPingedTime = lastExpiredTime; + prepareFreshStack(root, lastExpiredTime); 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); + } + expirationTime = getNextRootExpirationTimeToWorkOn(root); + if (0 !== expirationTime && expirationTime !== lastExpiredTime) break; + if (0 !== exitStatus && exitStatus !== lastExpiredTime) { + root.lastPingedTime = exitStatus; break; - default: - throw Error("Unknown root exit status."); + } + root.timeoutHandle = scheduleTimeout( + commitRoot.bind(null, root), + prevExecutionContext + ); + break; } - 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(); + 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; - } 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); + 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 + ); + break; + } + commitRoot(root); + break; + case RootCompleted: + if ( + 1073741823 !== workInProgressRootLatestProcessedExpirationTime && + null !== workInProgressRootCanSuspendUsingConfig + ) { + 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 + ); + break; + } + } + commitRoot(root); + break; + default: + throw Error("Unknown root exit status."); } } - return null; + ensureRootIsScheduled(root); + return root.callbackNode === didTimeout + ? performConcurrentWorkOnRoot.bind(null, root) + : null; } -function flushPendingDiscreteUpdates() { - if (null !== rootsWithPendingDiscreteUpdates) { - var roots = rootsWithPendingDiscreteUpdates; - rootsWithPendingDiscreteUpdates = null; - roots.forEach(function(expirationTime, root) { - markRootExpiredAtTime(root, expirationTime); - ensureRootIsScheduled(root); - }); - flushSyncCallbackQueue(); - } +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 prepareFreshStack(root, expirationTime) { root.finishedWork = null; @@ -5993,26 +5831,27 @@ function prepareFreshStack(root, expirationTime) { var interruptedWork = timeoutHandle; switch (interruptedWork.tag) { case 1: - var childContextTypes = interruptedWork.type.childContextTypes; - null !== childContextTypes && - void 0 !== childContextTypes && - popContext(interruptedWork); + interruptedWork = interruptedWork.type.childContextTypes; + null !== interruptedWork && + void 0 !== interruptedWork && + popContext(); break; case 3: - popHostContainer(interruptedWork); - popTopLevelContextObject(interruptedWork); + popHostContainer(); + pop(didPerformWorkStackCursor); + pop(contextStackCursor); break; case 5: popHostContext(interruptedWork); break; case 4: - popHostContainer(interruptedWork); + popHostContainer(); break; case 13: - pop(suspenseStackCursor, interruptedWork); + pop(suspenseStackCursor); break; case 19: - pop(suspenseStackCursor, interruptedWork); + pop(suspenseStackCursor); break; case 10: popProvider(interruptedWork); @@ -6020,8 +5859,8 @@ function prepareFreshStack(root, expirationTime) { timeoutHandle = timeoutHandle.return; } workInProgressRoot = root; - workInProgress = createWorkInProgress(root.current, null, expirationTime); - renderExpirationTime = expirationTime; + workInProgress = createWorkInProgress(root.current, null); + renderExpirationTime$1 = expirationTime; workInProgressRootExitStatus = RootIncomplete; workInProgressRootFatalError = null; workInProgressRootLatestSuspenseTimeout = workInProgressRootLatestProcessedExpirationTime = 1073741823; @@ -6034,12 +5873,25 @@ function handleError(root$jscomp$0, thrownValue) { do { try { resetContextDependencies(); - resetHooks(); + 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; if (null === workInProgress || null === workInProgress.return) return ( (workInProgressRootExitStatus = RootFatalErrored), (workInProgressRootFatalError = thrownValue), - null + (workInProgress = null) ); workInProgress.mode & 8 && stopProfilerTimerIfRunningAndRecordDelta(workInProgress, !0); @@ -6048,7 +5900,7 @@ function handleError(root$jscomp$0, thrownValue) { returnFiber = workInProgress.return, sourceFiber = workInProgress, value = thrownValue; - thrownValue = renderExpirationTime; + thrownValue = renderExpirationTime$1; sourceFiber.effectTag |= 2048; sourceFiber.firstEffect = sourceFiber.lastEffect = null; if ( @@ -6056,8 +5908,17 @@ function handleError(root$jscomp$0, thrownValue) { "object" === typeof value && "function" === typeof value.then ) { - var thenable = value, - hasInvisibleParentBoundary = + 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 = 0 !== (suspenseStackCursor.current & 1), _workInProgress = returnFiber; do { @@ -6072,10 +5933,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) { @@ -6182,8 +6043,8 @@ function handleError(root$jscomp$0, thrownValue) { } while (1); } function pushDispatcher() { - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = ContextOnlyDispatcher; + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; return null === prevDispatcher ? ContextOnlyDispatcher : prevDispatcher; } function pushInteractions(root) { @@ -6205,6 +6066,33 @@ 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); @@ -6214,43 +6102,35 @@ function workLoopConcurrent() { workInProgress = performUnitOfWork(workInProgress); } function performUnitOfWork(unitOfWork) { - var current$$1 = unitOfWork.alternate; + var current = unitOfWork.alternate; 0 !== (unitOfWork.mode & 8) ? ((profilerStartTime = now$1()), 0 > unitOfWork.actualStartTime && (unitOfWork.actualStartTime = now$1()), - (current$$1 = beginWork$$1(current$$1, unitOfWork, renderExpirationTime)), + (current = beginWork$1(current, unitOfWork, renderExpirationTime$1)), stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, !0)) - : (current$$1 = beginWork$$1(current$$1, unitOfWork, renderExpirationTime)); + : (current = beginWork$1(current, unitOfWork, renderExpirationTime$1)); unitOfWork.memoizedProps = unitOfWork.pendingProps; - null === current$$1 && (current$$1 = completeUnitOfWork(unitOfWork)); + null === current && (current = completeUnitOfWork(unitOfWork)); ReactCurrentOwner$2.current = null; - return current$$1; + return current; } function completeUnitOfWork(unitOfWork) { workInProgress = unitOfWork; do { - var current$$1 = workInProgress.alternate; + var current = workInProgress.alternate; unitOfWork = workInProgress.return; if (0 === (workInProgress.effectTag & 2048)) { if (0 === (workInProgress.mode & 8)) - current$$1 = completeWork( - current$$1, - workInProgress, - renderExpirationTime - ); + current = completeWork(current, workInProgress, renderExpirationTime$1); else { var fiber = workInProgress; profilerStartTime = now$1(); 0 > fiber.actualStartTime && (fiber.actualStartTime = now$1()); - current$$1 = completeWork( - current$$1, - workInProgress, - renderExpirationTime - ); + current = completeWork(current, workInProgress, renderExpirationTime$1); stopProfilerTimerIfRunningAndRecordDelta(workInProgress, !1); } fiber = workInProgress; - if (1 === renderExpirationTime || 1 !== fiber.childExpirationTime) { + if (1 === renderExpirationTime$1 || 1 !== fiber.childExpirationTime) { var newChildExpirationTime = 0; if (0 !== (fiber.mode & 8)) { for ( @@ -6288,7 +6168,7 @@ function completeUnitOfWork(unitOfWork) { (actualDuration = actualDuration.sibling); fiber.childExpirationTime = newChildExpirationTime; } - if (null !== current$$1) return current$$1; + if (null !== current) return current; null !== unitOfWork && 0 === (unitOfWork.effectTag & 2048) && (null === unitOfWork.firstEffect && @@ -6303,7 +6183,7 @@ function completeUnitOfWork(unitOfWork) { : (unitOfWork.firstEffect = workInProgress), (unitOfWork.lastEffect = workInProgress))); } else { - current$$1 = unwindWork(workInProgress, renderExpirationTime); + current = unwindWork(workInProgress); if (0 !== (workInProgress.mode & 8)) { stopProfilerTimerIfRunningAndRecordDelta(workInProgress, !1); fiber = workInProgress.actualDuration; @@ -6316,14 +6196,13 @@ function completeUnitOfWork(unitOfWork) { (newChildExpirationTime = newChildExpirationTime.sibling); workInProgress.actualDuration = fiber; } - if (null !== current$$1) - return (current$$1.effectTag &= 2047), current$$1; + if (null !== current) return (current.effectTag &= 2047), current; null !== unitOfWork && ((unitOfWork.firstEffect = unitOfWork.lastEffect = null), (unitOfWork.effectTag |= 2048)); } - current$$1 = workInProgress.sibling; - if (null !== current$$1) return current$$1; + current = workInProgress.sibling; + if (null !== current) return current; workInProgress = unitOfWork; } while (null !== workInProgress); workInProgressRootExitStatus === RootIncomplete && @@ -6337,11 +6216,12 @@ function getRemainingExpirationTime(fiber) { } function commitRoot(root) { var renderPriorityLevel = getCurrentPriorityLevel(); - runWithPriority$1(99, commitRootImpl.bind(null, root, renderPriorityLevel)); + runWithPriority(99, commitRootImpl.bind(null, root, renderPriorityLevel)); return null; } function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { - flushPassiveEffects(); + do flushPassiveEffects(); + while (null !== rootWithPendingPassiveEffects); if ((executionContext & (RenderContext | CommitContext)) !== NoContext) throw Error("Should not already be working."); var finishedWork = root$jscomp$1.finishedWork, @@ -6370,7 +6250,8 @@ 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 = 0)); + ((workInProgress = workInProgressRoot = null), + (renderExpirationTime$1 = 0)); 1 < finishedWork.effectTag ? null !== finishedWork.lastEffect ? ((finishedWork.lastEffect.nextEffect = finishedWork), @@ -6404,9 +6285,9 @@ function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { ) { var effectTag = nextEffect.effectTag; if (effectTag & 128) { - var current$$1 = nextEffect.alternate; - if (null !== current$$1) { - var currentRef = current$$1.ref; + var current = nextEffect.alternate; + if (null !== current) { + var currentRef = current.ref; null !== currentRef && ("function" === typeof currentRef ? currentRef(null) @@ -6432,10 +6313,10 @@ function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { commitWork(nextEffect.alternate, nextEffect); break; case 8: - var current$$1$jscomp$0 = nextEffect; + var current$jscomp$0 = nextEffect; a: for ( var finishedRoot = root, - root$jscomp$0 = current$$1$jscomp$0, + root$jscomp$0 = current$jscomp$0, renderPriorityLevel$jscomp$0 = renderPriorityLevel, node = root$jscomp$0; ; @@ -6460,7 +6341,7 @@ function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { node.sibling.return = node.return; node = node.sibling; } - detachFiber(current$$1$jscomp$0); + detachFiber(current$jscomp$0); } nextEffect = nextEffect.nextEffect; } @@ -6474,118 +6355,25 @@ function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { nextEffect = remainingExpirationTimeBeforeCommit; do try { - for ( - effectTag = root$jscomp$1, current$$1 = expirationTime; - null !== nextEffect; - - ) { + for (effectTag = root$jscomp$1; null !== nextEffect; ) { var effectTag$jscomp$0 = nextEffect.effectTag; - 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." - ); - } - } + effectTag$jscomp$0 & 36 && + commitLifeCycles(effectTag, nextEffect.alternate, nextEffect); if (effectTag$jscomp$0 & 128) { - currentRef = void 0; + current = void 0; var ref = nextEffect.ref; if (null !== ref) { - var instance$jscomp$0 = nextEffect.stateNode; + var instance = nextEffect.stateNode; switch (nextEffect.tag) { case 5: - currentRef = instance$jscomp$0.canonical; + current = instance.canonical; break; default: - currentRef = instance$jscomp$0; + current = instance; } "function" === typeof ref - ? ref(currentRef) - : (ref.current = currentRef); + ? ref(current) + : (ref.current = current); } } nextEffect = nextEffect.nextEffect; @@ -6621,13 +6409,13 @@ function commitRootImpl(root$jscomp$1, renderPriorityLevel$jscomp$1) { for ( remainingExpirationTimeBeforeCommit = spawnedWorkDuringRender, spawnedWorkDuringRender = null, - current$$1$jscomp$1 = 0; - current$$1$jscomp$1 < remainingExpirationTimeBeforeCommit.length; - current$$1$jscomp$1++ + ref = 0; + ref < remainingExpirationTimeBeforeCommit.length; + ref++ ) scheduleInteractions( root$jscomp$1, - remainingExpirationTimeBeforeCommit[current$$1$jscomp$1], + remainingExpirationTimeBeforeCommit[ref], root$jscomp$1.memoizedInteractions ); schedulePendingInteractions(root$jscomp$1, renderPriorityLevel$jscomp$1); @@ -6673,7 +6461,7 @@ function flushPassiveEffects() { ? 97 : pendingPassiveEffectsRenderPriority; pendingPassiveEffectsRenderPriority = 90; - return runWithPriority$1(priorityLevel, flushPassiveEffectsImpl); + return runWithPriority(priorityLevel, flushPassiveEffectsImpl); } } function flushPassiveEffectsImpl() { @@ -6688,27 +6476,28 @@ function flushPassiveEffectsImpl() { executionContext |= CommitContext; for ( var prevInteractions = pushInteractions(root), - effect = root.current.firstEffect; - null !== effect; + _effect2 = root.current.firstEffect; + null !== _effect2; ) { try { - var finishedWork = effect; + var finishedWork = _effect2; if (0 !== (finishedWork.effectTag & 512)) switch (finishedWork.tag) { case 0: case 11: case 15: - commitHookEffectList(128, 0, finishedWork), - commitHookEffectList(0, 64, finishedWork); + case 22: + commitHookEffectListUnmount(5, finishedWork), + commitHookEffectListMount(5, finishedWork); } } catch (error) { - if (null === effect) throw Error("Should be working on an effect."); - captureCommitPhaseError(effect, error); + if (null === _effect2) throw Error("Should be working on an effect."); + captureCommitPhaseError(_effect2, error); } - finishedWork = effect.nextEffect; - effect.nextEffect = null; - effect = finishedWork; + finishedWork = _effect2.nextEffect; + _effect2.nextEffect = null; + _effect2 = finishedWork; } tracing.__interactionsRef.current = prevInteractions; finishPendingInteractions(root, expirationTime); @@ -6757,19 +6546,17 @@ function captureCommitPhaseError(sourceFiber, error) { function pingSuspendedRoot(root, thenable, suspendedTime) { var pingCache = root.pingCache; null !== pingCache && pingCache.delete(thenable); - workInProgressRoot === root && renderExpirationTime === suspendedTime + workInProgressRoot === root && renderExpirationTime$1 === suspendedTime ? workInProgressRootExitStatus === RootSuspendedWithDelay || (workInProgressRootExitStatus === RootSuspended && 1073741823 === workInProgressRootLatestProcessedExpirationTime && now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) - ? prepareFreshStack(root, renderExpirationTime) + ? prepareFreshStack(root, renderExpirationTime$1) : (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))); } @@ -6785,12 +6572,12 @@ function resolveRetryThenable(boundaryFiber, thenable) { (ensureRootIsScheduled(boundaryFiber), schedulePendingInteractions(boundaryFiber, thenable)); } -var beginWork$$1; -beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { +var beginWork$1; +beginWork$1 = function(current, workInProgress, renderExpirationTime) { var updateExpirationTime = workInProgress.expirationTime; - if (null !== current$$1) + if (null !== current) if ( - current$$1.memoizedProps !== workInProgress.pendingProps || + current.memoizedProps !== workInProgress.pendingProps || didPerformWorkStackCursor.current ) didReceiveUpdate = !0; @@ -6815,11 +6602,17 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { ); break; case 10: - pushProvider(workInProgress, workInProgress.memoizedProps.value); + updateExpirationTime = workInProgress.memoizedProps.value; + var context = workInProgress.type._context; + push(valueCursor, context._currentValue2); + context._currentValue2 = updateExpirationTime; 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) { @@ -6829,52 +6622,40 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { updateExpirationTime >= renderExpirationTime ) return updateSuspenseComponent( - current$$1, + current, workInProgress, renderExpirationTime ); - push( - suspenseStackCursor, - suspenseStackCursor.current & 1, - workInProgress - ); + push(suspenseStackCursor, suspenseStackCursor.current & 1); workInProgress = bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ); return null !== workInProgress ? workInProgress.sibling : null; } - push( - suspenseStackCursor, - suspenseStackCursor.current & 1, - workInProgress - ); + push(suspenseStackCursor, suspenseStackCursor.current & 1); break; case 19: updateExpirationTime = workInProgress.childExpirationTime >= renderExpirationTime; - if (0 !== (current$$1.effectTag & 64)) { + if (0 !== (current.effectTag & 64)) { if (updateExpirationTime) return updateSuspenseListComponent( - current$$1, + current, workInProgress, renderExpirationTime ); workInProgress.effectTag |= 64; } - var renderState = workInProgress.memoizedState; - null !== renderState && - ((renderState.rendering = null), (renderState.tail = null)); - push( - suspenseStackCursor, - suspenseStackCursor.current, - workInProgress - ); + context = workInProgress.memoizedState; + null !== context && + ((context.rendering = null), (context.tail = null)); + push(suspenseStackCursor, suspenseStackCursor.current); if (!updateExpirationTime) return null; } return bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ); @@ -6886,41 +6667,40 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { switch (workInProgress.tag) { case 2: updateExpirationTime = workInProgress.type; - null !== current$$1 && - ((current$$1.alternate = null), + null !== current && + ((current.alternate = null), (workInProgress.alternate = null), (workInProgress.effectTag |= 2)); - current$$1 = workInProgress.pendingProps; - renderState = getMaskedContext( - workInProgress, - contextStackCursor.current - ); + current = workInProgress.pendingProps; + context = getMaskedContext(workInProgress, contextStackCursor.current); prepareToReadContext(workInProgress, renderExpirationTime); - renderState = renderWithHooks( + context = renderWithHooks( null, workInProgress, updateExpirationTime, - current$$1, - renderState, + current, + context, renderExpirationTime ); workInProgress.effectTag |= 1; if ( - "object" === typeof renderState && - null !== renderState && - "function" === typeof renderState.render && - void 0 === renderState.$$typeof + "object" === typeof context && + null !== context && + "function" === typeof context.render && + void 0 === context.$$typeof ) { workInProgress.tag = 1; - resetHooks(); + workInProgress.memoizedState = null; + workInProgress.updateQueue = null; if (isContextProvider(updateExpirationTime)) { var hasContext = !0; pushContextProvider(workInProgress); } else hasContext = !1; workInProgress.memoizedState = - null !== renderState.state && void 0 !== renderState.state - ? renderState.state + null !== context.state && void 0 !== context.state + ? context.state : null; + initializeUpdateQueue(workInProgress); var getDerivedStateFromProps = updateExpirationTime.getDerivedStateFromProps; "function" === typeof getDerivedStateFromProps && @@ -6928,15 +6708,15 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { workInProgress, updateExpirationTime, getDerivedStateFromProps, - current$$1 + current ); - renderState.updater = classComponentUpdater; - workInProgress.stateNode = renderState; - renderState._reactInternalFiber = workInProgress; + context.updater = classComponentUpdater; + workInProgress.stateNode = context; + context._reactInternalFiber = workInProgress; mountClassInstance( workInProgress, updateExpirationTime, - current$$1, + current, renderExpirationTime ); workInProgress = finishClassComponent( @@ -6952,127 +6732,129 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { reconcileChildren( null, workInProgress, - renderState, + context, renderExpirationTime ), (workInProgress = workInProgress.child); return workInProgress; case 16: - 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." - ); + 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." + ); } return workInProgress; case 0: return ( (updateExpirationTime = workInProgress.type), - (renderState = workInProgress.pendingProps), - (renderState = + (context = workInProgress.pendingProps), + (context = workInProgress.elementType === updateExpirationTime - ? renderState - : resolveDefaultProps(updateExpirationTime, renderState)), + ? context + : resolveDefaultProps(updateExpirationTime, context)), updateFunctionComponent( - current$$1, + current, workInProgress, updateExpirationTime, - renderState, + context, renderExpirationTime ) ); case 1: return ( (updateExpirationTime = workInProgress.type), - (renderState = workInProgress.pendingProps), - (renderState = + (context = workInProgress.pendingProps), + (context = workInProgress.elementType === updateExpirationTime - ? renderState - : resolveDefaultProps(updateExpirationTime, renderState)), + ? context + : resolveDefaultProps(updateExpirationTime, context)), updateClassComponent( - current$$1, + current, workInProgress, updateExpirationTime, - renderState, + context, renderExpirationTime ) ); case 3: pushHostRootContext(workInProgress); updateExpirationTime = workInProgress.updateQueue; - if (null === updateExpirationTime) + if (null === current || 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." ); - renderState = workInProgress.memoizedState; - renderState = null !== renderState ? renderState.element : null; + updateExpirationTime = workInProgress.pendingProps; + context = workInProgress.memoizedState; + context = null !== context ? context.element : null; + cloneUpdateQueue(current, workInProgress); processUpdateQueue( workInProgress, updateExpirationTime, - workInProgress.pendingProps, null, renderExpirationTime ); updateExpirationTime = workInProgress.memoizedState.element; - updateExpirationTime === renderState + updateExpirationTime === context ? (workInProgress = bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime )) : (reconcileChildren( - current$$1, + current, workInProgress, updateExpirationTime, renderExpirationTime @@ -7082,11 +6864,10 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { case 5: return ( pushHostContext(workInProgress), - null === current$$1 && tryToClaimNextHydratableInstance(workInProgress), (updateExpirationTime = workInProgress.pendingProps.children), - markRef(current$$1, workInProgress), + markRef(current, workInProgress), reconcileChildren( - current$$1, + current, workInProgress, updateExpirationTime, renderExpirationTime @@ -7095,13 +6876,10 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { workInProgress ); case 6: - return ( - null === current$$1 && tryToClaimNextHydratableInstance(workInProgress), - null - ); + return null; case 13: return updateSuspenseComponent( - current$$1, + current, workInProgress, renderExpirationTime ); @@ -7112,7 +6890,7 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { workInProgress.stateNode.containerInfo ), (updateExpirationTime = workInProgress.pendingProps), - null === current$$1 + null === current ? (workInProgress.child = reconcileChildFibers( workInProgress, null, @@ -7120,7 +6898,7 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { renderExpirationTime )) : reconcileChildren( - current$$1, + current, workInProgress, updateExpirationTime, renderExpirationTime @@ -7130,23 +6908,23 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { case 11: return ( (updateExpirationTime = workInProgress.type), - (renderState = workInProgress.pendingProps), - (renderState = + (context = workInProgress.pendingProps), + (context = workInProgress.elementType === updateExpirationTime - ? renderState - : resolveDefaultProps(updateExpirationTime, renderState)), + ? context + : resolveDefaultProps(updateExpirationTime, context)), updateForwardRef( - current$$1, + current, workInProgress, updateExpirationTime, - renderState, + context, renderExpirationTime ) ); case 7: return ( reconcileChildren( - current$$1, + current, workInProgress, workInProgress.pendingProps, renderExpirationTime @@ -7156,7 +6934,7 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { case 8: return ( reconcileChildren( - current$$1, + current, workInProgress, workInProgress.pendingProps.children, renderExpirationTime @@ -7166,8 +6944,11 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { case 12: return ( (workInProgress.effectTag |= 4), + (updateExpirationTime = workInProgress.stateNode), + (updateExpirationTime.effectDuration = 0), + (updateExpirationTime.passiveEffectDuration = 0), reconcileChildren( - current$$1, + current, workInProgress, workInProgress.pendingProps.children, renderExpirationTime @@ -7177,27 +6958,32 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { case 10: a: { updateExpirationTime = workInProgress.type._context; - renderState = workInProgress.pendingProps; + context = workInProgress.pendingProps; getDerivedStateFromProps = workInProgress.memoizedProps; - 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) { + 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) + ) { if ( - getDerivedStateFromProps.children === renderState.children && + getDerivedStateFromProps.children === context.children && !didPerformWorkStackCursor.current ) { workInProgress = bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ); @@ -7205,14 +6991,15 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { } } else for ( - oldValue = workInProgress.child, - null !== oldValue && (oldValue.return = workInProgress); - null !== oldValue; + context$jscomp$0 = workInProgress.child, + null !== context$jscomp$0 && + (context$jscomp$0.return = workInProgress); + null !== context$jscomp$0; ) { - var list = oldValue.dependencies; + var list = context$jscomp$0.dependencies; if (null !== list) { - getDerivedStateFromProps = oldValue.child; + getDerivedStateFromProps = context$jscomp$0.child; for ( var dependency = list.firstContext; null !== dependency; @@ -7222,18 +7009,18 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { dependency.context === updateExpirationTime && 0 !== (dependency.observedBits & hasContext) ) { - 1 === oldValue.tag && + 1 === context$jscomp$0.tag && ((dependency = createUpdate(renderExpirationTime, null)), (dependency.tag = 2), - enqueueUpdate(oldValue, dependency)); - oldValue.expirationTime < renderExpirationTime && - (oldValue.expirationTime = renderExpirationTime); - dependency = oldValue.alternate; + enqueueUpdate(context$jscomp$0, dependency)); + context$jscomp$0.expirationTime < renderExpirationTime && + (context$jscomp$0.expirationTime = renderExpirationTime); + dependency = context$jscomp$0.alternate; null !== dependency && dependency.expirationTime < renderExpirationTime && (dependency.expirationTime = renderExpirationTime); scheduleWorkOnParentPath( - oldValue.return, + context$jscomp$0.return, renderExpirationTime ); list.expirationTime < renderExpirationTime && @@ -7244,16 +7031,16 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { } } else getDerivedStateFromProps = - 10 === oldValue.tag - ? oldValue.type === workInProgress.type + 10 === context$jscomp$0.tag + ? context$jscomp$0.type === workInProgress.type ? null - : oldValue.child - : oldValue.child; + : context$jscomp$0.child + : context$jscomp$0.child; if (null !== getDerivedStateFromProps) - getDerivedStateFromProps.return = oldValue; + getDerivedStateFromProps.return = context$jscomp$0; else for ( - getDerivedStateFromProps = oldValue; + getDerivedStateFromProps = context$jscomp$0; null !== getDerivedStateFromProps; ) { @@ -7261,21 +7048,20 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { getDerivedStateFromProps = null; break; } - oldValue = getDerivedStateFromProps.sibling; - if (null !== oldValue) { - oldValue.return = getDerivedStateFromProps.return; - getDerivedStateFromProps = oldValue; + context$jscomp$0 = getDerivedStateFromProps.sibling; + if (null !== context$jscomp$0) { + context$jscomp$0.return = getDerivedStateFromProps.return; + getDerivedStateFromProps = context$jscomp$0; break; } getDerivedStateFromProps = getDerivedStateFromProps.return; } - oldValue = getDerivedStateFromProps; + context$jscomp$0 = getDerivedStateFromProps; } - } reconcileChildren( - current$$1, + current, workInProgress, - renderState.children, + context.children, renderExpirationTime ); workInProgress = workInProgress.child; @@ -7283,18 +7069,15 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { return workInProgress; case 9: return ( - (renderState = workInProgress.type), + (context = workInProgress.type), (hasContext = workInProgress.pendingProps), (updateExpirationTime = hasContext.children), prepareToReadContext(workInProgress, renderExpirationTime), - (renderState = readContext( - renderState, - hasContext.unstable_observedBits - )), - (updateExpirationTime = updateExpirationTime(renderState)), + (context = readContext(context, hasContext.unstable_observedBits)), + (updateExpirationTime = updateExpirationTime(context)), (workInProgress.effectTag |= 1), reconcileChildren( - current$$1, + current, workInProgress, updateExpirationTime, renderExpirationTime @@ -7303,16 +7086,16 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { ); case 14: return ( - (renderState = workInProgress.type), + (context = workInProgress.type), (hasContext = resolveDefaultProps( - renderState, + context, workInProgress.pendingProps )), - (hasContext = resolveDefaultProps(renderState.type, hasContext)), + (hasContext = resolveDefaultProps(context.type, hasContext)), updateMemoComponent( - current$$1, + current, workInProgress, - renderState, + context, hasContext, updateExpirationTime, renderExpirationTime @@ -7320,7 +7103,7 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { ); case 15: return updateSimpleMemoComponent( - current$$1, + current, workInProgress, workInProgress.type, workInProgress.pendingProps, @@ -7330,30 +7113,25 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { case 17: return ( (updateExpirationTime = workInProgress.type), - (renderState = workInProgress.pendingProps), - (renderState = + (context = workInProgress.pendingProps), + (context = workInProgress.elementType === updateExpirationTime - ? renderState - : resolveDefaultProps(updateExpirationTime, renderState)), - null !== current$$1 && - ((current$$1.alternate = null), + ? context + : resolveDefaultProps(updateExpirationTime, context)), + null !== current && + ((current.alternate = null), (workInProgress.alternate = null), (workInProgress.effectTag |= 2)), (workInProgress.tag = 1), isContextProvider(updateExpirationTime) - ? ((current$$1 = !0), pushContextProvider(workInProgress)) - : (current$$1 = !1), + ? ((current = !0), pushContextProvider(workInProgress)) + : (current = !1), prepareToReadContext(workInProgress, renderExpirationTime), - constructClassInstance( - workInProgress, - updateExpirationTime, - renderState, - renderExpirationTime - ), + constructClassInstance(workInProgress, updateExpirationTime, context), mountClassInstance( workInProgress, updateExpirationTime, - renderState, + context, renderExpirationTime ), finishClassComponent( @@ -7361,13 +7139,13 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { workInProgress, updateExpirationTime, !0, - current$$1, + current, renderExpirationTime ) ); case 19: return updateSuspenseListComponent( - current$$1, + current, workInProgress, renderExpirationTime ); @@ -7508,9 +7286,6 @@ 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); @@ -7528,7 +7303,7 @@ function resolveLazyComponentTag(Component) { function createWorkInProgress(current, pendingProps) { var workInProgress = current.alternate; null === workInProgress - ? ((workInProgress = createFiber( + ? ((workInProgress = new FiberNode( current.tag, pendingProps, current.key, @@ -7599,15 +7374,16 @@ function createFiberFromTypeAndProps( break; case REACT_PROFILER_TYPE: return ( - (type = createFiber(12, pendingProps, key, mode | 8)), + (type = new FiberNode(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 = createFiber(13, pendingProps, key, mode)), + (type = new FiberNode(13, pendingProps, key, mode)), (type.type = REACT_SUSPENSE_TYPE), (type.elementType = REACT_SUSPENSE_TYPE), (type.expirationTime = expirationTime), @@ -7615,7 +7391,7 @@ function createFiberFromTypeAndProps( ); case REACT_SUSPENSE_LIST_TYPE: return ( - (type = createFiber(19, pendingProps, key, mode)), + (type = new FiberNode(19, pendingProps, key, mode)), (type.elementType = REACT_SUSPENSE_LIST_TYPE), (type.expirationTime = expirationTime), type @@ -7639,6 +7415,9 @@ 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: " + @@ -7646,24 +7425,24 @@ function createFiberFromTypeAndProps( "." ); } - key = createFiber(fiberTag, pendingProps, key, mode); + key = new FiberNode(fiberTag, pendingProps, key, mode); key.elementType = type; key.type = owner; key.expirationTime = expirationTime; return key; } function createFiberFromFragment(elements, mode, expirationTime, key) { - elements = createFiber(7, elements, key, mode); + elements = new FiberNode(7, elements, key, mode); elements.expirationTime = expirationTime; return elements; } function createFiberFromText(content, mode, expirationTime) { - content = createFiber(6, content, null, mode); + content = new FiberNode(6, content, null, mode); content.expirationTime = expirationTime; return content; } function createFiberFromPortal(portal, mode, expirationTime) { - mode = createFiber( + mode = new FiberNode( 4, null !== portal.children ? portal.children : [], portal.key, @@ -7725,11 +7504,6 @@ 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) { @@ -7744,14 +7518,10 @@ function findHostInstance(component) { return null === component ? null : component.stateNode; } function updateContainer(element, container, parentComponent, callback) { - var current$$1 = container.current, + var current = container.current, currentTime = requestCurrentTimeForUpdate(), suspenseConfig = ReactCurrentBatchConfig.suspense; - currentTime = computeExpirationForFiber( - currentTime, - current$$1, - suspenseConfig - ); + currentTime = computeExpirationForFiber(currentTime, current, suspenseConfig); a: if (parentComponent) { parentComponent = parentComponent._reactInternalFiber; b: { @@ -7802,8 +7572,8 @@ function updateContainer(element, container, parentComponent, callback) { container.payload = { element: element }; callback = void 0 === callback ? null : callback; null !== callback && (container.callback = callback); - enqueueUpdate(current$$1, container); - scheduleUpdateOnFiber(current$$1, currentTime); + enqueueUpdate(current, container); + scheduleWork(current, currentTime); return currentTime; } function createPortal(children, containerInfo, implementation) { @@ -7817,7 +7587,6 @@ 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; @@ -7828,8 +7597,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; @@ -7841,291 +7610,116 @@ batchedUpdatesImpl = function(fn, a) { executionContext === NoContext && flushSyncCallbackQueue(); } }; -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; - }, - findNodeHandle: findNodeHandle, - dispatchCommand: function(handle, command, args) { - null != handle._nativeTag && - null != handle._internalInstanceHandle && - fabricDispatchCommand( - handle._internalInstanceHandle.stateNode.node, - command, - args - ); - }, - 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) - } - }; +var roots = new Map(); (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 - }) - ); + 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; + }, + 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.11.0", - rendererPackageName: "react-native-renderer" + 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) + } }); -var ReactFabric$2 = { default: ReactFabric }, - ReactFabric$3 = (ReactFabric$2 && ReactFabric) || ReactFabric$2; -module.exports = ReactFabric$3.default || ReactFabric$3; +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); +}; diff --git a/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js b/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js index b1ae206b2534e5..8ef9be346094b2 100644 --- a/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js +++ b/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js @@ -5,6 +5,7 @@ * LICENSE file in the root directory of this source tree. * * @noflow + * @nolint * @preventMunge * @generated */ @@ -15,256 +16,234 @@ 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"); -/** - * 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. - */ - -/** - * Injectable ordering of event plugins. - */ -var eventPluginOrder = null; -/** - * Injectable mapping from names to event plugin modules. - */ +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. -var namesToPlugins = {}; -/** - * Recomputes the plugin list using the injected plugins and plugin ordering. - * - * @private - */ +if (!ReactSharedInternals.hasOwnProperty("ReactCurrentDispatcher")) { + ReactSharedInternals.ReactCurrentDispatcher = { + current: null + }; +} -function recomputePluginOrdering() { - if (!eventPluginOrder) { - // Wait until an `eventPluginOrder` is injected. - return; - } +if (!ReactSharedInternals.hasOwnProperty("ReactCurrentBatchConfig")) { + ReactSharedInternals.ReactCurrentBatchConfig = { + suspense: null + }; +} - for (var pluginName in namesToPlugins) { - var pluginModule = namesToPlugins[pluginName]; - var pluginIndex = eventPluginOrder.indexOf(pluginName); +// 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. - if (!(pluginIndex > -1)) { - throw Error( - "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + - 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 (plugins[pluginIndex]) { - continue; + 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 (!pluginModule.extractEvents) { - throw Error( - "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + - pluginName + - "` does not." - ); - } + printWarning("error", format, args); + } +} - plugins[pluginIndex] = pluginModule; - var publishedEvents = pluginModule.eventTypes; +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; - for (var eventName in publishedEvents) { - if ( - !publishEventForPlugin( - publishedEvents[eventName], - pluginModule, - eventName - ) - ) { - throw Error( - "EventPluginRegistry: Failed to publish event `" + - eventName + - "` for plugin `" + - pluginName + - "`." - ); + if (!hasExistingStack) { + var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; + var stack = ReactDebugCurrentFrame.getStackAddendum(); + + if (stack !== "") { + format += "%s"; + args = args.concat([stack]); } } + + 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 - */ -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 FunctionComponent = 0; +var ClassComponent = 1; +var IndeterminateComponent = 2; // Before we know whether it is function or class - eventNameDispatchConfigs[eventName] = dispatchConfig; - var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; +var HostRoot = 3; // Root of a host tree. Could be nested inside another node. - if (phasedRegistrationNames) { - for (var phaseName in phasedRegistrationNames) { - if (phasedRegistrationNames.hasOwnProperty(phaseName)) { - var phasedRegistrationName = phasedRegistrationNames[phaseName]; - publishRegistrationName( - phasedRegistrationName, - pluginModule, - eventName - ); - } - } +var HostPortal = 4; // A subtree. Could be an entry point to a different renderer. - return true; - } else if (dispatchConfig.registrationName) { - publishRegistrationName( - dispatchConfig.registrationName, - pluginModule, - eventName - ); - return true; +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 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 (inst) { + return inst; } - return false; + return null; } /** - * 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 + * Return the lowest common ancestor of A and B, or null if they are in + * different trees. */ -function publishRegistrationName(registrationName, pluginModule, eventName) { - if (!!registrationNameModules[registrationName]) { - throw Error( - "EventPluginHub: More than one plugin attempted to publish the same registration name, `" + - registrationName + - "`." - ); +function getLowestCommonAncestor(instA, instB) { + var depthA = 0; + + for (var tempA = instA; tempA; tempA = getParent(tempA)) { + depthA++; } - registrationNameModules[registrationName] = pluginModule; - registrationNameDependencies[registrationName] = - pluginModule.eventTypes[eventName].dependencies; + var depthB = 0; - { - var lowerCasedName = registrationName.toLowerCase(); + 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; + } + + instA = getParent(instA); + instB = getParent(instB); } + + return null; } /** - * Registers plugins so that they can extract and dispatch events. - * - * @see {EventPluginHub} + * Return if A is an ancestor of B. */ -/** - * Ordered list of injected plugins. - */ +function isAncestor(instA, instB) { + while (instB) { + if (instA === instB || instA === instB.alternate) { + return true; + } -var plugins = []; + instB = getParent(instB); + } + + return false; +} /** - * Mapping from event name to dispatch config + * Return the parent instance of the passed-in instance. */ -var eventNameDispatchConfigs = {}; +function getParentInstance(inst) { + return getParent(inst); +} /** - * Mapping from registration name to plugin module + * Simulates the traversal of a two-phase, capture/bubble event dispatch. */ -var registrationNameModules = {}; -/** - * Mapping from registration name to event name - */ - -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} - */ - -// Trust the developer to only use possibleRegistrationNames in true - -/** - * 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; - } +function traverseTwoPhase(inst, fn, arg) { + var path = []; - var pluginModule = injectedNamesToPlugins[pluginName]; + while (inst) { + path.push(inst); + inst = getParent(inst); + } - 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 i; - namesToPlugins[pluginName] = pluginModule; - isOrderingDirty = true; - } + for (i = path.length; i-- > 0; ) { + fn(path[i], "captured", arg); } - if (isOrderingDirty) { - recomputePluginOrdering(); + for (i = 0; i < path.length; i++) { + fn(path[i], "bubbled", arg); } } @@ -559,71 +538,6 @@ 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; @@ -637,13 +551,12 @@ function setComponentTree( getNodeFromInstance = getNodeFromInstanceImpl; { - !(getNodeFromInstance && getInstanceFromNode) - ? warningWithoutStack$1( - false, - "EventPluginUtils.setComponentTree(...): Injected " + - "module is missing getNodeFromInstance or getInstanceFromNode." - ) - : void 0; + if (!getNodeFromInstance || !getInstanceFromNode) { + error( + "EventPluginUtils.setComponentTree(...): Injected " + + "module is missing getNodeFromInstance or getInstanceFromNode." + ); + } } } var validateEventDispatches; @@ -656,17 +569,18 @@ 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; - !(instancesIsArr === listenersIsArr && instancesLen === listenersLen) - ? warningWithoutStack$1(false, "EventPluginUtils: Invalid `event`.") - : void 0; + ? 1 + : 0; + + if (instancesIsArr !== listenersIsArr || instancesLen !== listenersLen) { + error("EventPluginUtils: Invalid `event`."); + } }; } /** @@ -793,6 +707,77 @@ 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 @@ -854,1651 +839,1526 @@ function forEachAccumulated(arr, cb, scope) { } /** - * Internal queue of events that have accumulated their dispatches and are - * waiting to have their dispatches executed. + * Some event types have a notion of different registration names for different + * "phases" of propagation. This finds listeners by a given phase. */ - -var eventQueue = null; +function listenerAtPhase(inst, event, propagationPhase) { + var registrationName = + event.dispatchConfig.phasedRegistrationNames[propagationPhase]; + return getListener(inst, registrationName); +} /** - * Dispatches an event and releases it back into the pool, unless persistent. - * - * @param {?object} event Synthetic event to be dispatched. - * @private + * 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. */ -var executeDispatchesAndRelease = function(event) { - if (event) { - executeDispatchesInOrder(event); +/** + * 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. + */ - if (!event.isPersistent()) { - event.constructor.release(event); +function accumulateDirectionalDispatches(inst, phase, event) { + { + if (!inst) { + error("Dispatching inst must not be null"); } } -}; - -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); + var listener = listenerAtPhase(inst, event, phase); - if (!!eventQueue) { - throw Error( - "processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented." + if (listener) { + event._dispatchListeners = accumulateInto( + event._dispatchListeners, + listener ); - } // This would be a good time to rethrow if any of the event handlers threw. - - rethrowCaughtError(); + 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 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; +function accumulateTwoPhaseDispatchesSingle(event) { + if (event && event.dispatchConfig.phasedRegistrationNames) { + traverseTwoPhase(event._targetInst, accumulateDirectionalDispatches, 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 + * 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); + } +} /** - * Methods for injecting dependencies. + * 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. */ -var injection = { - /** - * @param {array} InjectedEventPluginOrder - * @public - */ - injectEventPluginOrder: injectEventPluginOrder, +function accumulateDispatches(inst, ignoredDirection, event) { + if (inst && event && event.dispatchConfig.registrationName) { + var registrationName = event.dispatchConfig.registrationName; + var listener = getListener(inst, registrationName); - /** - * @param {object} injectedNamesToPlugins Map from names to plugin modules. - */ - injectEventPluginsByName: injectEventPluginsByName -}; + if (listener) { + event._dispatchListeners = accumulateInto( + event._dispatchListeners, + listener + ); + event._dispatchInstances = accumulateInto(event._dispatchInstances, inst); + } + } +} /** - * @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. + * Accumulates dispatches on an `SyntheticEvent`, but only for the + * `dispatchMarker`. + * @param {SyntheticEvent} 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 accumulateDirectDispatchesSingle(event) { + if (event && event.dispatchConfig.registrationName) { + accumulateDispatches(event._targetInst, null, event); } +} - var props = getFiberCurrentPropsFromNode(stateNode); - - if (!props) { - // Work in progress. - return null; - } +function accumulateTwoPhaseDispatches(events) { + forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle); +} +function accumulateTwoPhaseDispatchesSkipTarget(events) { + forEachAccumulated(events, accumulateTwoPhaseDispatchesSingleSkipTarget); +} +function accumulateDirectDispatches(events) { + forEachAccumulated(events, accumulateDirectDispatchesSingle); +} - listener = props[registrationName]; +var EVENT_POOL_SIZE = 10; +/** + * @interface Event + * @see http://www.w3.org/TR/DOM-Level-3-Events/ + */ - if (shouldPreventMouseEvent(registrationName, inst.type, props)) { +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 +}; - if (!(!listener || typeof listener === "function")) { - throw Error( - "Expected `" + - registrationName + - "` listener to be a function, instead got a value of `" + - typeof listener + - "` type." - ); - } +function functionThatReturnsTrue() { + return true; +} - return listener; +function functionThatReturnsFalse() { + return false; } /** - * Allows registered plugins an opportunity to extract events from top-level - * native browser events. + * Synthetic events are dispatched by event plugins, typically in response to a + * top-level event delegation handler. * - * @return {*} An accumulation of synthetic events. - * @internal + * 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 extractPluginEvents( - topLevelType, +function SyntheticEvent( + dispatchConfig, targetInst, nativeEvent, - nativeEventTarget, - eventSystemFlags + nativeEventTarget ) { - var events = null; + { + // these have a getter/setter for warnings + delete this.nativeEvent; + delete this.preventDefault; + delete this.stopPropagation; + delete this.isDefaultPrevented; + delete this.isPropagationStopped; + } - for (var i = 0; i < plugins.length; i++) { - // Not every plugin in the ordering may be loaded at runtime. - var possiblePlugin = plugins[i]; + this.dispatchConfig = dispatchConfig; + this._targetInst = targetInst; + this.nativeEvent = nativeEvent; + var Interface = this.constructor.Interface; - if (possiblePlugin) { - var extractedEvents = possiblePlugin.extractEvents( - topLevelType, - targetInst, - nativeEvent, - nativeEventTarget, - eventSystemFlags - ); + for (var propName in Interface) { + if (!Interface.hasOwnProperty(propName)) { + continue; + } - if (extractedEvents) { - events = accumulateInto(events, extractedEvents); + { + 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]; } } } - return events; -} + var defaultPrevented = + nativeEvent.defaultPrevented != null + ? nativeEvent.defaultPrevented + : nativeEvent.returnValue === false; -function runExtractedPluginEventsInBatch( - topLevelType, - targetInst, - nativeEvent, - nativeEventTarget, - eventSystemFlags -) { - var events = extractPluginEvents( - topLevelType, - targetInst, - nativeEvent, - nativeEventTarget, - eventSystemFlags - ); - runEventsInBatch(events); + if (defaultPrevented) { + this.isDefaultPrevented = functionThatReturnsTrue; + } else { + this.isDefaultPrevented = functionThatReturnsFalse; + } + + this.isPropagationStopped = functionThatReturnsFalse; + return this; } -var FunctionComponent = 0; -var ClassComponent = 1; -var IndeterminateComponent = 2; // Before we know whether it is function or class +Object.assign(SyntheticEvent.prototype, { + preventDefault: function() { + this.defaultPrevented = true; + var event = this.nativeEvent; -var HostRoot = 3; // Root of a host tree. Could be nested inside another node. + if (!event) { + return; + } -var HostPortal = 4; // A subtree. Could be an entry point to a different renderer. + if (event.preventDefault) { + event.preventDefault(); + } else if (typeof event.returnValue !== "unknown") { + event.returnValue = false; + } -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; + this.isDefaultPrevented = functionThatReturnsTrue; + }, + stopPropagation: function() { + var event = this.nativeEvent; -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) { + return; + } - if (inst) { - return inst; - } + 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; + } - return null; -} -/** - * Return the lowest common ancestor of A and B, or null if they are in - * different trees. - */ + this.isPropagationStopped = functionThatReturnsTrue; + }, -function getLowestCommonAncestor(instA, instB) { - var depthA = 0; + /** + * 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; + }, - for (var tempA = instA; tempA; tempA = getParent(tempA)) { - depthA++; - } + /** + * Checks if this event should be released back into the pool. + * + * @return {boolean} True if this should not be released, false otherwise. + */ + isPersistent: functionThatReturnsFalse, - var depthB = 0; + /** + * `PooledClass` looks for `destructor` on each instance it releases. + */ + destructor: function() { + var Interface = this.constructor.Interface; - for (var tempB = instB; tempB; tempB = getParent(tempB)) { - depthB++; - } // If A is deeper, crawl up. + for (var propName in Interface) { + { + Object.defineProperty( + this, + propName, + getPooledWarningPropertyDefinition(propName, Interface[propName]) + ); + } + } - while (depthA - depthB > 0) { - instA = getParent(instA); - depthA--; - } // If B 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 (depthB - depthA > 0) { - instB = getParent(instB); - depthB--; - } // Walk in lockstep until we find a match. + { + 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. + */ - var depth = depthA; +SyntheticEvent.extend = function(Interface) { + var Super = this; - while (depth--) { - if (instA === instB || instA === instB.alternate) { - return instA; - } + var E = function() {}; - instA = getParent(instA); - instB = getParent(instB); + E.prototype = Super.prototype; + var prototype = new E(); + + function Class() { + return Super.apply(this, arguments); } - return null; -} + 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); /** - * Return if A is an ancestor of B. + * Helper to nullify syntheticEvent instance properties when destructing + * + * @param {String} propName + * @param {?object} getVal + * @return {object} defineProperty object */ -function isAncestor(instA, instB) { - while (instB) { - if (instA === instB || instA === instB.alternate) { - return true; - } +function getPooledWarningPropertyDefinition(propName, getVal) { + var isFunction = typeof getVal === "function"; + return { + configurable: true, + set: set, + get: get + }; - instB = getParent(instB); + function set(val) { + var action = isFunction ? "setting the method" : "setting the property"; + warn(action, "This is effectively a no-op"); + return val; } - return false; -} -/** - * Return the parent instance of the passed-in instance. - */ + 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 getParentInstance(inst) { - return getParent(inst); + 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 + ); + } + } } -/** - * Simulates the traversal of a two-phase, capture/bubble event dispatch. - */ -function traverseTwoPhase(inst, fn, arg) { - var path = []; +function getPooledEvent(dispatchConfig, targetInst, nativeEvent, nativeInst) { + var EventConstructor = this; - while (inst) { - path.push(inst); - inst = getParent(inst); + if (EventConstructor.eventPool.length) { + var instance = EventConstructor.eventPool.pop(); + EventConstructor.call( + instance, + dispatchConfig, + targetInst, + nativeEvent, + nativeInst + ); + return instance; } - var i; + return new EventConstructor( + dispatchConfig, + targetInst, + nativeEvent, + nativeInst + ); +} - for (i = path.length; i-- > 0; ) { - fn(path[i], "captured", arg); +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." + ); } - for (i = 0; i < path.length; i++) { - fn(path[i], "bubbled", arg); + event.destructor(); + + if (EventConstructor.eventPool.length < EVENT_POOL_SIZE) { + EventConstructor.eventPool.push(event); } } -/** - * 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. - */ -/** - * 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); +function addEventPoolingTo(EventConstructor) { + EventConstructor.eventPool = []; + EventConstructor.getPooled = getPooledEvent; + EventConstructor.release = releasePooledEvent; } -/** - * 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. + * `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. */ -function accumulateDirectionalDispatches(inst, phase, event) { - { - !inst - ? warningWithoutStack$1(false, "Dispatching inst must not be null") - : void 0; +var ResponderSyntheticEvent = SyntheticEvent.extend({ + touchHistory: function(nativeEvent) { + return null; // Actually doesn't even look at the native event. } +}); - var listener = listenerAtPhase(inst, event, phase); - - if (listener) { - event._dispatchListeners = accumulateInto( - event._dispatchListeners, - listener - ); - event._dispatchInstances = accumulateInto(event._dispatchInstances, inst); - } +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]; + /** - * 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. + * 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 accumulateTwoPhaseDispatchesSingle(event) { - if (event && event.dispatchConfig.phasedRegistrationNames) { - traverseTwoPhase(event._targetInst, accumulateDirectionalDispatches, event); - } +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; } /** - * Same as `accumulateTwoPhaseDispatchesSingle`, but skips over the targetID. + * TODO: Instead of making gestures recompute filtered velocity, we could + * include a built in velocity computation that can be reused globally. */ -function accumulateTwoPhaseDispatchesSingleSkipTarget(event) { - if (event && event.dispatchConfig.phasedRegistrationNames) { - var targetInst = event._targetInst; - var parentInst = targetInst ? getParentInstance(targetInst) : null; - traverseTwoPhase(parentInst, accumulateDirectionalDispatches, event); - } +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) + }; } -/** - * 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 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); +} - if (listener) { - event._dispatchListeners = accumulateInto( - event._dispatchListeners, - listener +function getTouchIdentifier(_ref) { + var identifier = _ref.identifier; + + if (!(identifier != null)) { + throw Error("Touch object is missing identifier."); + } + + { + 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 ); - event._dispatchInstances = accumulateInto(event._dispatchInstances, inst); } } + + return identifier; } -/** - * 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); +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); } -function accumulateTwoPhaseDispatches(events) { - forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle); +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 accumulateTwoPhaseDispatchesSkipTarget(events) { - forEachAccumulated(events, accumulateTwoPhaseDispatchesSingleSkipTarget); + +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 accumulateDirectDispatches(events) { - forEachAccumulated(events, accumulateDirectDispatchesSingle); +function printTouch(touch) { + return JSON.stringify({ + identifier: touch.identifier, + pageX: touch.pageX, + pageY: touch.pageY, + timestamp: timestampForTouch(touch) + }); } -/* eslint valid-typeof: 0 */ -var EVENT_POOL_SIZE = 10; -/** - * @interface Event - * @see http://www.w3.org/TR/DOM-Level-3-Events/ - */ +function printTouchBank() { + var printed = JSON.stringify(touchBank.slice(0, MAX_TOUCH_BANK)); -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 -}; + if (touchBank.length > MAX_TOUCH_BANK) { + printed += " (original size: " + touchBank.length + ")"; + } -function functionThatReturnsTrue() { - return true; + return printed; } -function functionThatReturnsFalse() { - return false; -} -/** - * 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; - } +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; - this.dispatchConfig = dispatchConfig; - this._targetInst = targetInst; - this.nativeEvent = nativeEvent; - var Interface = this.constructor.Interface; + if (touchHistory.numberActiveTouches === 1) { + touchHistory.indexOfSingleActiveTouch = + nativeEvent.touches[0].identifier; + } + } else if (isEndish(topLevelType)) { + nativeEvent.changedTouches.forEach(recordTouchEnd); + touchHistory.numberActiveTouches = nativeEvent.touches.length; - for (var propName in Interface) { - if (!Interface.hasOwnProperty(propName)) { - continue; - } + if (touchHistory.numberActiveTouches === 1) { + for (var i = 0; i < touchBank.length; i++) { + var touchTrackToCheck = touchBank[i]; - { - delete this[propName]; // this has a getter/setter for warnings - } + if (touchTrackToCheck != null && touchTrackToCheck.touchActive) { + touchHistory.indexOfSingleActiveTouch = i; + break; + } + } - var normalize = Interface[propName]; + { + var activeRecord = touchBank[touchHistory.indexOfSingleActiveTouch]; - if (normalize) { - this[propName] = normalize(nativeEvent); - } else { - if (propName === "target") { - this.target = nativeEventTarget; - } else { - this[propName] = nativeEvent[propName]; + if (activeRecord == null || !activeRecord.touchActive) { + error("Cannot find single active touch."); + } + } } } + }, + 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." + ); } - var defaultPrevented = - nativeEvent.defaultPrevented != null - ? nativeEvent.defaultPrevented - : nativeEvent.returnValue === false; + 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 (defaultPrevented) { - this.isDefaultPrevented = functionThatReturnsTrue; - } else { - this.isDefaultPrevented = functionThatReturnsFalse; + if (Array.isArray(current)) { + return current.concat(next); } - this.isPropagationStopped = functionThatReturnsFalse; - return this; -} + if (Array.isArray(next)) { + return [current].concat(next); + } -Object.assign(SyntheticEvent.prototype, { - preventDefault: function() { - this.defaultPrevented = true; - var event = this.nativeEvent; + return [current, next]; +} - if (!event) { - return; - } +/** + * Instance of element that should respond to touch/move types of interactions, + * as indicated explicitly by relevant callbacks. + */ - if (event.preventDefault) { - event.preventDefault(); - } else if (typeof event.returnValue !== "unknown") { - event.returnValue = false; - } +var responderInst = null; +/** + * Count of current touches. A textInput should become responder iff the + * selection changes while there is a touch on the screen. + */ - this.isDefaultPrevented = functionThatReturnsTrue; - }, - stopPropagation: function() { - var event = this.nativeEvent; +var trackedTouchCount = 0; - if (!event) { - return; - } +var changeResponder = function(nextResponderInst, blockHostResponder) { + var oldResponderInst = responderInst; + responderInst = nextResponderInst; - 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 (ResponderEventPlugin.GlobalResponderHandler !== null) { + ResponderEventPlugin.GlobalResponderHandler.onChange( + oldResponderInst, + nextResponderInst, + blockHostResponder + ); + } +}; - this.isPropagationStopped = functionThatReturnsTrue; +var eventTypes = { + /** + * On a `touchStart`/`mouseDown`, is it desired that this element become the + * responder? + */ + startShouldSetResponder: { + phasedRegistrationNames: { + bubbled: "onStartShouldSetResponder", + captured: "onStartShouldSetResponderCapture" + }, + dependencies: startDependencies }, /** - * 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. + * 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. */ - persist: function() { - this.isPersistent = functionThatReturnsTrue; + scrollShouldSetResponder: { + phasedRegistrationNames: { + bubbled: "onScrollShouldSetResponder", + captured: "onScrollShouldSetResponderCapture" + }, + dependencies: [TOP_SCROLL] }, /** - * Checks if this event should be released back into the pool. + * 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. * - * @return {boolean} True if this should not be released, false otherwise. + * TODO: This shouldn't bubble. */ - isPersistent: functionThatReturnsFalse, + selectionChangeShouldSetResponder: { + phasedRegistrationNames: { + bubbled: "onSelectionChangeShouldSetResponder", + captured: "onSelectionChangeShouldSetResponderCapture" + }, + dependencies: [TOP_SELECTION_CHANGE] + }, /** - * `PooledClass` looks for `destructor` on each instance it releases. + * On a `touchMove`/`mouseMove`, is it desired that this element become the + * responder? */ - destructor: function() { - var Interface = this.constructor.Interface; - - 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; + moveShouldSetResponder: { + phasedRegistrationNames: { + bubbled: "onMoveShouldSetResponder", + captured: "onMoveShouldSetResponderCapture" + }, + dependencies: moveDependencies + }, - { - 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() {}) - ); - } + /** + * 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: [] } -}); -SyntheticEvent.Interface = EventInterface; +}; /** - * Helper to reduce boilerplate when creating subclasses. + * + * 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`. + * */ -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; -}; +/* 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 | | + | +------------------------+ | + | | + + + */ -addEventPoolingTo(SyntheticEvent); /** - * Helper to nullify syntheticEvent instance properties when destructing + * A note about event ordering in the `EventPluginRegistry`. * - * @param {String} propName - * @param {?object} getVal - * @return {object} defineProperty object + * 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) */ -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 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 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 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 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; + var skipOverBubbleShouldSetFrom = bubbleShouldSetFrom === responderInst; + var shouldSetEvent = ResponderSyntheticEvent.getPooled( + shouldSetEventType, + bubbleShouldSetFrom, + nativeEvent, + nativeEventTarget + ); + shouldSetEvent.touchHistory = ResponderTouchHistoryStore.touchHistory; + + if (skipOverBubbleShouldSetFrom) { + accumulateTwoPhaseDispatchesSkipTarget(shouldSetEvent); + } else { + accumulateTwoPhaseDispatches(shouldSetEvent); } -} -function getPooledEvent(dispatchConfig, targetInst, nativeEvent, nativeInst) { - var EventConstructor = this; + var wantsResponderInst = executeDispatchesInOrderStopAtTrue(shouldSetEvent); - if (EventConstructor.eventPool.length) { - var instance = EventConstructor.eventPool.pop(); - EventConstructor.call( - instance, - dispatchConfig, - targetInst, - nativeEvent, - nativeInst - ); - return instance; + if (!shouldSetEvent.isPersistent()) { + shouldSetEvent.constructor.release(shouldSetEvent); } - return new EventConstructor( - dispatchConfig, - targetInst, + if (!wantsResponderInst || wantsResponderInst === responderInst) { + return null; + } + + var extracted; + var grantEvent = ResponderSyntheticEvent.getPooled( + eventTypes.responderGrant, + wantsResponderInst, nativeEvent, - nativeInst + nativeEventTarget ); -} - -function releasePooledEvent(event) { - var EventConstructor = this; + grantEvent.touchHistory = ResponderTouchHistoryStore.touchHistory; + accumulateDirectDispatches(grantEvent); + var blockHostResponder = executeDirectDispatch(grantEvent) === true; - if (!(event instanceof EventConstructor)) { - throw Error( - "Trying to release an event instance into a pool of a different type." + if (responderInst) { + var terminationRequestEvent = ResponderSyntheticEvent.getPooled( + eventTypes.responderTerminationRequest, + responderInst, + nativeEvent, + nativeEventTarget ); - } - - event.destructor(); - - if (EventConstructor.eventPool.length < EVENT_POOL_SIZE) { - EventConstructor.eventPool.push(event); - } -} - -function addEventPoolingTo(EventConstructor) { - EventConstructor.eventPool = []; - EventConstructor.getPooled = getPooledEvent; - EventConstructor.release = releasePooledEvent; -} + terminationRequestEvent.touchHistory = + ResponderTouchHistoryStore.touchHistory; + accumulateDirectDispatches(terminationRequestEvent); + var shouldSwitch = + !hasDispatches(terminationRequestEvent) || + executeDirectDispatch(terminationRequestEvent); -/** - * `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. - */ + if (!terminationRequestEvent.isPersistent()) { + terminationRequestEvent.constructor.release(terminationRequestEvent); + } -var ResponderSyntheticEvent = SyntheticEvent.extend({ - touchHistory: function(nativeEvent) { - return null; // Actually doesn't even look at the native event. + 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); } -}); -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; + return extracted; } -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. + * 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 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 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)) + ); } /** - * TODO: Instead of making gestures recompute filtered velocity, we could - * include a built in velocity computation that can be reused globally. + * 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. */ -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 noResponderTouches(nativeEvent) { + var touches = nativeEvent.touches; -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); -} + if (!touches || touches.length === 0) { + return true; + } -function getTouchIdentifier(_ref) { - var identifier = _ref.identifier; + for (var i = 0; i < touches.length; i++) { + var activeTouch = touches[i]; + var target = activeTouch.target; - if (!(identifier != null)) { - throw Error("Touch object is missing identifier."); - } + if (target !== null && target !== undefined && target !== 0) { + // Is the original touch location inside of the current responder? + var targetInst = getInstanceFromNode(target); - { - !(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 (isAncestor(responderInst, targetInst)) { + return false; + } + } } - return identifier; -} - -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); -} - -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() - ); - } -} - -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() - ); - } -} - -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; + 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; +var ResponderEventPlugin = { + /* For unit testing only */ + _getResponder: function() { + return responderInst; + }, + eventTypes: eventTypes, - if (touchHistory.numberActiveTouches === 1) { - touchHistory.indexOfSingleActiveTouch = - nativeEvent.touches[0].identifier; - } + /** + * 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)) { - 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 (trackedTouchCount >= 0) { + trackedTouchCount -= 1; + } else { { - var activeRecord = touchBank[touchHistory.indexOfSingleActiveTouch]; - !(activeRecord != null && activeRecord.touchActive) - ? warningWithoutStack$1(false, "Cannot find single active touch.") - : void 0; + warn( + "Ended a touch event which was not counted in `trackedTouchCount`." + ); } + + return null; } } - }, - 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] - }, + 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`). - /** - * 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] - }, + 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; - /** - * On a `touchMove`/`mouseMove`, is it desired that this element become the - * responder? - */ - moveShouldSetResponder: { - phasedRegistrationNames: { - bubbled: "onMoveShouldSetResponder", - captured: "onMoveShouldSetResponderCapture" - }, - dependencies: moveDependencies - }, + if (incrementalTouch) { + var gesture = ResponderSyntheticEvent.getPooled( + incrementalTouch, + responderInst, + nativeEvent, + nativeEventTarget + ); + gesture.touchHistory = ResponderTouchHistoryStore.touchHistory; + accumulateDirectDispatches(gesture); + extracted = accumulate(extracted, gesture); + } - /** - * 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: [] - } -}; -/** - * - * 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 isResponderTerminate = + responderInst && topLevelType === TOP_TOUCH_CANCEL; + var isResponderRelease = + responderInst && + !isResponderTerminate && + isEndish(topLevelType) && + noResponderTouches(nativeEvent); + var finalTouch = isResponderTerminate + ? eventTypes.responderTerminate + : isResponderRelease + ? eventTypes.responderRelease + : null; -/* 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 | | - | +------------------------+ | - | | - + + */ + 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; + } + } +}; /** - * A note about event ordering in the `EventPluginHub`. - * - * 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: + * 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. * - * - `startShouldSetResponder` (`ResponderEventPlugin` dispatches on-demand) - * - `touchStartCapture` (`EventPluginHub` dispatches as usual) - * - `touchStart` (`EventPluginHub` dispatches as usual) - * - `responderGrant/Reject` (`EventPluginHub` dispatches as usual) + * @private */ -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 recomputePluginOrdering() { + if (!eventPluginOrder) { + // Wait until an `eventPluginOrder` is injected. + return; + } - 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. + for (var pluginName in namesToPlugins) { + var pluginModule = namesToPlugins[pluginName]; + var pluginIndex = eventPluginOrder.indexOf(pluginName); - var skipOverBubbleShouldSetFrom = bubbleShouldSetFrom === responderInst; - var shouldSetEvent = ResponderSyntheticEvent.getPooled( - shouldSetEventType, - bubbleShouldSetFrom, - nativeEvent, - nativeEventTarget - ); - shouldSetEvent.touchHistory = ResponderTouchHistoryStore.touchHistory; + if (!(pluginIndex > -1)) { + throw Error( + "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + + pluginName + + "`." + ); + } - if (skipOverBubbleShouldSetFrom) { - accumulateTwoPhaseDispatchesSkipTarget(shouldSetEvent); - } else { - accumulateTwoPhaseDispatches(shouldSetEvent); - } + if (plugins[pluginIndex]) { + continue; + } - var wantsResponderInst = executeDispatchesInOrderStopAtTrue(shouldSetEvent); + if (!pluginModule.extractEvents) { + throw Error( + "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + + pluginName + + "` does not." + ); + } - if (!shouldSetEvent.isPersistent()) { - shouldSetEvent.constructor.release(shouldSetEvent); + 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 + */ - if (!wantsResponderInst || wantsResponderInst === responderInst) { - return null; +function publishEventForPlugin(dispatchConfig, pluginModule, eventName) { + if (!!eventNameDispatchConfigs.hasOwnProperty(eventName)) { + throw Error( + "EventPluginRegistry: More than one plugin attempted to publish the same event name, `" + + eventName + + "`." + ); } - var extracted; - var grantEvent = ResponderSyntheticEvent.getPooled( - eventTypes.responderGrant, - wantsResponderInst, - nativeEvent, - nativeEventTarget - ); - grantEvent.touchHistory = ResponderTouchHistoryStore.touchHistory; - accumulateDirectDispatches(grantEvent); - var blockHostResponder = executeDirectDispatch(grantEvent) === true; + eventNameDispatchConfigs[eventName] = dispatchConfig; + var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; - if (responderInst) { - var terminationRequestEvent = ResponderSyntheticEvent.getPooled( - eventTypes.responderTerminationRequest, - responderInst, - nativeEvent, - nativeEventTarget + 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 ); - terminationRequestEvent.touchHistory = - ResponderTouchHistoryStore.touchHistory; - accumulateDirectDispatches(terminationRequestEvent); - var shouldSwitch = - !hasDispatches(terminationRequestEvent) || - executeDirectDispatch(terminationRequestEvent); + return true; + } - if (!terminationRequestEvent.isPersistent()) { - terminationRequestEvent.constructor.release(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 (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 publishRegistrationName(registrationName, pluginModule, eventName) { + if (!!registrationNameModules[registrationName]) { + throw Error( + "EventPluginRegistry: More than one plugin attempted to publish the same registration name, `" + + registrationName + + "`." + ); } - return extracted; + registrationNameModules[registrationName] = pluginModule; + registrationNameDependencies[registrationName] = + pluginModule.eventTypes[eventName].dependencies; + + { + var lowerCasedName = registrationName.toLowerCase(); + } } /** - * 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. + * Registers plugins so that they can extract and dispatch events. */ -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`. - * - * @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. + + 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 + */ -var ResponderEventPlugin = { - /* For unit testing only */ - _getResponder: function() { - return responderInst; - }, - eventTypes: eventTypes, +function injectEventPluginsByName(injectedNamesToPlugins) { + var isOrderingDirty = false; - /** - * 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; - } + for (var pluginName in injectedNamesToPlugins) { + if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) { + continue; } - 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 pluginModule = injectedNamesToPlugins[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; + if ( + !namesToPlugins.hasOwnProperty(pluginName) || + namesToPlugins[pluginName] !== pluginModule + ) { + if (!!namesToPlugins[pluginName]) { + throw Error( + "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + + pluginName + + "`." + ); + } - if (finalTouch) { - var finalEvent = ResponderSyntheticEvent.getPooled( - finalTouch, - responderInst, - nativeEvent, - nativeEventTarget - ); - finalEvent.touchHistory = ResponderTouchHistoryStore.touchHistory; - accumulateDirectDispatches(finalEvent); - extracted = accumulate(extracted, finalEvent); - changeResponder(null); + namesToPlugins[pluginName] = pluginModule; + isOrderingDirty = true; } + } - 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; - } + if (isOrderingDirty) { + recomputePluginOrdering(); } -}; +} var customBubblingEventTypes = - ReactNativePrivateInterface.ReactNativeViewConfigRegistry - .customBubblingEventTypes; -var customDirectEventTypes = - ReactNativePrivateInterface.ReactNativeViewConfigRegistry - .customDirectEventTypes; + ReactNativePrivateInterface.ReactNativeViewConfigRegistry + .customBubblingEventTypes, + customDirectEventTypes = + ReactNativePrivateInterface.ReactNativeViewConfigRegistry + .customDirectEventTypes; var ReactNativeBridgeEventPlugin = { eventTypes: {}, - - /** - * @see {EventPluginHub.extractEvents} - */ extractEvents: function( topLevelType, targetInst, @@ -2550,50 +2410,21 @@ 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. */ -injection.injectEventPluginOrder(ReactNativeEventPluginOrder); +injectEventPluginOrder(ReactNativeEventPluginOrder); /** * Some important event plugins included by default (without having to require * them). */ -injection.injectEventPluginsByName({ +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) { @@ -2609,88 +2440,32 @@ function getInstanceFromTag(tag) { } function getTagFromInstance(inst) { - 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; + var nativeInstance = inst.stateNode; + var tag = nativeInstance._nativeTag; - if (_tag === undefined) { - _tag = inst.stateNode.canonical._nativeTag; - } - - if (!_tag) { - throw Error("All native instances should have a tag."); - } + if (tag === undefined) { + nativeInstance = nativeInstance.canonical; + tag = nativeInstance._nativeTag; + } - return _tag; + if (!tag) { + throw Error("All native instances should have a tag."); } -} + return nativeInstance; +} 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; - -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); +var PLUGIN_EVENT_SYSTEM = 1; - if (queuedTargets) { - for (var i = 0; i < queuedTargets.length; i++) { - restoreStateOfTarget(queuedTargets[i]); - } - } -} +var enableProfilerTimer = true; +var enableFundamentalAPI = false; +var warnAboutStringRefs = false; // 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 @@ -2701,25 +2476,7 @@ function restoreStateIfNeeded() { 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) { @@ -2734,11 +2491,8 @@ function batchedUpdates(fn, bookkeeping) { return batchedUpdatesImpl(fn, bookkeeping); } finally { isInsideEventHandler = false; - finishEventHandler(); } } -// This is for the React Flare event system - function setBatchingImplementation( _batchedUpdatesImpl, _discreteUpdatesImpl, @@ -2746,7 +2500,57 @@ function setBatchingImplementation( _batchedEventUpdatesImpl ) { batchedUpdatesImpl = _batchedUpdatesImpl; - flushDiscreteUpdatesImpl = _flushDiscreteUpdatesImpl; +} + +/** + * 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(); } /** @@ -2826,12 +2630,8 @@ function _receiveRootNodeIDEvent(rootNodeID, topLevelType, nativeEventParam) { var inst = getInstanceFromTag(rootNodeID); var target = null; - if (enableNativeTargetAsInstance) { - if (inst != null) { - target = inst.stateNode; - } - } else { - target = nativeEvent.target; + if (inst != null) { + target = inst.stateNode; } batchedUpdates(function() { @@ -2845,6 +2645,61 @@ 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. @@ -2901,10 +2756,7 @@ function receiveTouches(eventTopLevelType, touches, changedIndices) { if (target !== null && target !== undefined) { if (target < 1) { { - warningWithoutStack$1( - false, - "A view is reporting that a touch occurred on tag zero." - ); + error("A view is reporting that a touch occurred on tag zero."); } } else { rootNodeID = target; @@ -2956,38 +2808,13 @@ 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; @@ -3000,8 +2827,6 @@ 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; @@ -3014,11 +2839,7 @@ 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_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 REACT_BLOCK_TYPE = hasSymbol ? Symbol.for("react.block") : 0xead9; var MAYBE_ITERATOR_SYMBOL = typeof Symbol === "function" && Symbol.iterator; var FAUX_ITERATOR_SYMBOL = "@@iterator"; function getIteratorFn(maybeIterable) { @@ -3037,56 +2858,29 @@ function getIteratorFn(maybeIterable) { return null; } -/** - * 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; - +// TODO: Move this to "react" once we can import from externals. 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) { - lazyComponent._status = Pending; - var ctor = lazyComponent._ctor; - var thenable = ctor(); - lazyComponent._result = thenable; + 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; thenable.then( function(moduleObject) { if (lazyComponent._status === Pending) { @@ -3094,24 +2888,27 @@ function initializeLazyComponentType(lazyComponent) { { if (defaultExport === undefined) { - warning$1( - false, + error( "lazy: Expected the result of a dynamic import() call. " + - "Instead received: %s\n\nYour code should look like: \n " + - "const MyComponent = lazy(() => import('./MyComponent'))", + "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'))", moduleObject ); } - } + } // Transition to the next state. - lazyComponent._status = Resolved; - lazyComponent._result = defaultExport; + var resolved = lazyComponent; + resolved._status = Resolved; + resolved._result = defaultExport; } }, function(error) { if (lazyComponent._status === Pending) { - lazyComponent._status = Rejected; - lazyComponent._result = error; + // Transition to the next state. + var rejected = lazyComponent; + rejected._status = Rejected; + rejected._result = error; } } ); @@ -3126,6 +2923,10 @@ 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. @@ -3134,8 +2935,7 @@ function getComponentName(type) { { if (typeof type.tag === "number") { - warningWithoutStack$1( - false, + error( "Received an unexpected object in getComponentName(). " + "This is likely a bug in React. Please file an issue." ); @@ -3173,10 +2973,12 @@ function getComponentName(type) { if (typeof type === "object") { switch (type.$$typeof) { case REACT_CONTEXT_TYPE: - return "Context.Consumer"; + var context = type; + return getContextName(context) + ".Consumer"; case REACT_PROVIDER_TYPE: - return "Context.Provider"; + var provider = type; + return getContextName(provider._context) + ".Provider"; case REACT_FORWARD_REF_TYPE: return getWrappedName(type, type.render, "ForwardRef"); @@ -3184,6 +2986,9 @@ 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); @@ -3259,7 +3064,7 @@ var ShouldCapture = /* */ 4096; -var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner; +var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner; function getNearestMountedFiber(fiber) { var node = fiber; var nearestMounted = fiber; @@ -3296,28 +3101,28 @@ function getNearestMountedFiber(fiber) { return null; } - function isFiberMounted(fiber) { return getNearestMountedFiber(fiber) === fiber; } function isMounted(component) { { - var owner = ReactCurrentOwner$1.current; + var owner = ReactCurrentOwner.current; if (owner !== null && owner.tag === ClassComponent) { var ownerFiber = owner; var instance = ownerFiber.stateNode; - !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; + + 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 = true; } } @@ -4020,71 +3825,49 @@ 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 + - ": ... } }`" - ); + { + 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 + ); + } } } } -// 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) { + function ReactNativeFiberHostComponent( + tag, + viewConfig, + internalInstanceHandleDEV + ) { this._nativeTag = tag; this._children = []; this.viewConfig = viewConfig; + + { + this._internalFiberInstanceHandleDEV = internalInstanceHandleDEV; + } } var _proto = ReactNativeFiberHostComponent.prototype; _proto.blur = function blur() { - ReactNativePrivateInterface.TextInputState.blurTextInput(this._nativeTag); + ReactNativePrivateInterface.TextInputState.blurTextInput(this); }; _proto.focus = function focus() { - ReactNativePrivateInterface.TextInputState.focusTextInput( - this._nativeTag - ); + ReactNativePrivateInterface.TextInputState.focusTextInput(this); }; _proto.measure = function measure(callback) { @@ -4112,15 +3895,21 @@ var ReactNativeFiberHostComponent = if (typeof relativeToNativeNode === "number") { // Already a node handle relativeNode = relativeToNativeNode; - } else if (relativeToNativeNode._nativeTag) { - relativeNode = relativeToNativeNode._nativeTag; + } else { + var nativeNode = relativeToNativeNode; + + if (nativeNode._nativeTag) { + relativeNode = nativeNode._nativeTag; + } } if (relativeNode == null) { - warningWithoutStack$1( - false, - "Warning: ref.measureLayout must be called with a node handle or a ref to a native component." - ); + { + error( + "Warning: ref.measureLayout must be called with a node handle or a ref to a native component." + ); + } + return; } @@ -4156,60 +3945,15 @@ 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 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 isSuspenseInstancePending = shim; +var isSuspenseInstanceFallback = shim; +var hydrateTextInstance = shim; var getViewConfigForType = ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get; @@ -4244,7 +3988,6 @@ function recursivelyUncacheFiberNode(node) { node._children.forEach(recursivelyUncacheFiberNode); } } - function appendInitialChild(parentInstance, child) { parentInstance._children.push(child); } @@ -4275,7 +4018,11 @@ function createInstance( rootContainerInstance, // rootTag updatePayload // props ); - var component = new ReactNativeFiberHostComponent(tag, viewConfig); + var component = new ReactNativeFiberHostComponent( + tag, + viewConfig, + internalInstanceHandle + ); precacheFiberNode(internalInstanceHandle, tag); updateFiberProps(tag, props); // Not sure how to avoid this cast. Flow is okay if the component is defined // in the same file but if it's external it can't see the types. @@ -4370,8 +4117,6 @@ function prepareUpdate( function resetAfterCommit(containerInfo) { // Noop } -var isPrimaryRenderer = true; -var warnsIfNotActing = true; var scheduleTimeout = setTimeout; var cancelTimeout = clearTimeout; var noTimeout = -1; @@ -4387,10 +4132,6 @@ 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; @@ -4435,7 +4176,6 @@ function commitTextUpdate(textInstance, oldText, newText) { } // props ); } - function commitUpdate( instance, updatePayloadTODO, @@ -4553,169 +4293,94 @@ function unhideInstance(instance, props) { props.style, { display: "none" - } - ] - }), - props, - viewConfig.validAttributes - ); - ReactNativePrivateInterface.UIManager.updateView( - instance._nativeTag, - viewConfig.uiViewClassName, - updatePayload - ); -} -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."); + } + ] + }), + props, + viewConfig.validAttributes + ); + ReactNativePrivateInterface.UIManager.updateView( + instance._nativeTag, + viewConfig.uiViewClassName, + updatePayload + ); } -function getInstanceFromNode$1(node) { +function unhideTextInstance(textInstance, text) { 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); +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 (match) { - var pathBeforeSlash = match[1]; + 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 (pathBeforeSlash) { - var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, ""); - fileName = folderName + "/" + fileName; + 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; } - } - } - } - - sourceInfo = " (at " + fileName + ":" + source.lineNumber + ")"; - } else if (ownerName) { - sourceInfo = " (created by " + ownerName + ")"; - } - return "\n in " + (name || "Unknown") + sourceInfo; -}; - -var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; + error$1 = typeSpecs[typeSpecName]( + values, + typeSpecName, + componentName, + location, + null, + "SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED" + ); + } catch (ex) { + error$1 = ex; + } -function describeFiber(fiber) { - switch (fiber.tag) { - case HostRoot: - case HostPortal: - case HostText: - case Fragment: - case ContextProvider: - case ContextConsumer: - return ""; + 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 + ); + } - default: - var owner = fiber._debugOwner; - var source = fiber._debugSource; - var name = getComponentName(fiber.type); - var ownerName = null; + if ( + error$1 instanceof Error && + !(error$1.message in loggedTypeFailures) + ) { + // Only monitor this failure once because there tends to be a lot of the + // same error. + loggedTypeFailures[error$1.message] = true; - if (owner) { - ownerName = getComponentName(owner.type); + error("Failed %s type: %s", location, error$1.message); + } } - - 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. @@ -4894,12 +4559,12 @@ var resumeTimers = function() { }; function recordEffect() { - if (enableUserTimingAPI) { + { effectCountInCurrentCommit++; } } function recordScheduleUpdate() { - if (enableUserTimingAPI) { + { if (isCommitting) { hasScheduledUpdateInCurrentCommit = true; } @@ -4913,9 +4578,8 @@ function recordScheduleUpdate() { } } } - function startWorkTimer(fiber) { - if (enableUserTimingAPI) { + { if (!supportsUserTiming || shouldIgnoreFiber(fiber)) { return; } // If we pause, this is the fiber to unwind from. @@ -4930,7 +4594,7 @@ function startWorkTimer(fiber) { } } function cancelWorkTimer(fiber) { - if (enableUserTimingAPI) { + { if (!supportsUserTiming || shouldIgnoreFiber(fiber)) { return; } // Remember we shouldn't complete measurement for this fiber. @@ -4941,7 +4605,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. @@ -4957,7 +4621,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. @@ -4977,7 +4641,7 @@ function stopFailedWorkTimer(fiber) { } } function startPhaseTimer(fiber, phase) { - if (enableUserTimingAPI) { + { if (!supportsUserTiming) { return; } @@ -4993,7 +4657,7 @@ function startPhaseTimer(fiber, phase) { } } function stopPhaseTimer() { - if (enableUserTimingAPI) { + { if (!supportsUserTiming) { return; } @@ -5010,7 +4674,7 @@ function stopPhaseTimer() { } } function startWorkLoopTimer(nextUnitOfWork) { - if (enableUserTimingAPI) { + { currentFiber = nextUnitOfWork; if (!supportsUserTiming) { @@ -5026,7 +4690,7 @@ function startWorkLoopTimer(nextUnitOfWork) { } } function stopWorkLoopTimer(interruptedBy, didCompleteRoot) { - if (enableUserTimingAPI) { + { if (!supportsUserTiming) { return; } @@ -5055,7 +4719,7 @@ function stopWorkLoopTimer(interruptedBy, didCompleteRoot) { } } function startCommitTimer() { - if (enableUserTimingAPI) { + { if (!supportsUserTiming) { return; } @@ -5067,7 +4731,7 @@ function startCommitTimer() { } } function stopCommitTimer() { - if (enableUserTimingAPI) { + { if (!supportsUserTiming) { return; } @@ -5088,7 +4752,7 @@ function stopCommitTimer() { } } function startCommitSnapshotEffectsTimer() { - if (enableUserTimingAPI) { + { if (!supportsUserTiming) { return; } @@ -5098,7 +4762,7 @@ function startCommitSnapshotEffectsTimer() { } } function stopCommitSnapshotEffectsTimer() { - if (enableUserTimingAPI) { + { if (!supportsUserTiming) { return; } @@ -5113,7 +4777,7 @@ function stopCommitSnapshotEffectsTimer() { } } function startCommitHostEffectsTimer() { - if (enableUserTimingAPI) { + { if (!supportsUserTiming) { return; } @@ -5123,7 +4787,7 @@ function startCommitHostEffectsTimer() { } } function stopCommitHostEffectsTimer() { - if (enableUserTimingAPI) { + { if (!supportsUserTiming) { return; } @@ -5138,7 +4802,7 @@ function stopCommitHostEffectsTimer() { } } function startCommitLifeCyclesTimer() { - if (enableUserTimingAPI) { + { if (!supportsUserTiming) { return; } @@ -5148,7 +4812,7 @@ function startCommitLifeCyclesTimer() { } } function stopCommitLifeCyclesTimer() { - if (enableUserTimingAPI) { + { if (!supportsUserTiming) { return; } @@ -5181,7 +4845,7 @@ function createCursor(defaultValue) { function pop(cursor, fiber) { if (index < 0) { { - warningWithoutStack$1(false, "Unexpected pop."); + error("Unexpected pop."); } return; @@ -5189,7 +4853,7 @@ function pop(cursor, fiber) { { if (fiber !== fiberStack[index]) { - warningWithoutStack$1(false, "Unexpected Fiber popped."); + error("Unexpected Fiber popped."); } } @@ -5239,9 +4903,7 @@ 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 @@ -5255,9 +4917,7 @@ function getUnmaskedContext( } function cacheContext(workInProgress, unmaskedContext, maskedContext) { - if (disableLegacyContext) { - return; - } else { + { var instance = workInProgress.stateNode; instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext; instance.__reactInternalMemoizedMaskedChildContext = maskedContext; @@ -5265,9 +4925,7 @@ function cacheContext(workInProgress, unmaskedContext, maskedContext) { } function getMaskedContext(workInProgress, unmaskedContext) { - if (disableLegacyContext) { - return emptyContextObject; - } else { + { var type = workInProgress.type; var contextTypes = type.contextTypes; @@ -5294,13 +4952,7 @@ function getMaskedContext(workInProgress, unmaskedContext) { { var name = getComponentName(type) || "Unknown"; - checkPropTypes( - contextTypes, - context, - "context", - name, - getCurrentFiberStackInDev - ); + checkPropTypes(contextTypes, context, "context", name); } // Cache unmasked context so we can avoid recreating masked context unless necessary. // Context is created before the class component is instantiated so check for instance. @@ -5313,44 +4965,34 @@ 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." @@ -5363,9 +5005,7 @@ 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. @@ -5376,8 +5016,8 @@ function processChildContext(fiber, type, parentContext) { if (!warnedAboutMissingGetChildContext[componentName]) { warnedAboutMissingGetChildContext[componentName] = true; - warningWithoutStack$1( - false, + + error( "%s.childContextTypes is specified but there is no getChildContext() method " + "on the instance. You can either define getChildContext() on %s or remove " + "childContextTypes from it.", @@ -5391,19 +5031,10 @@ 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( @@ -5417,17 +5048,7 @@ function processChildContext(fiber, type, parentContext) { { var name = getComponentName(type) || "Unknown"; - 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 - ); + checkPropTypes(childContextTypes, childContext, "child context", name); } return Object.assign({}, parentContext, {}, childContext); @@ -5435,9 +5056,7 @@ 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. @@ -5459,9 +5078,7 @@ function pushContextProvider(workInProgress) { } function invalidateContextProvider(workInProgress, type, didChange) { - if (disableLegacyContext) { - return; - } else { + { var instance = workInProgress.stateNode; if (!instance) { @@ -5495,9 +5112,7 @@ 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)) { @@ -5540,22 +5155,21 @@ var BlockingRoot = 1; var ConcurrentRoot = 2; // Intentionally not named imports because Rollup would use dynamic dispatch for -// 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) { +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; + +{ // Provide explicit error message when production+profiling bundle of e.g. // react-dom is used with production (non-profiling) bundle of // scheduler/tracing @@ -5749,14 +5363,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 a moving priority. It is slightly higher than Idle +var Idle = 2; // Continuous Hydration is slightly higher than Idle and is used to increase 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 add an offset so that we don't clash with the magic number for NoWork. + // Always subtract from the offset so that we don't clash with the magic number for NoWork. return MAGIC_NUMBER_OFFSET - ((ms / UNIT_SIZE) | 0); } function expirationTimeToMs(expirationTime) { @@ -5815,7 +5429,6 @@ function computeInteractiveExpiration(currentTime) { HIGH_PRIORITY_BATCH_SIZE ); } - function inferPriorityFromExpirationTime(currentTime, expirationTime) { if (expirationTime === Sync) { return ImmediatePriority; @@ -5854,7 +5467,7 @@ function is(x, y) { ); } -var is$1 = typeof Object.is === "function" ? Object.is : is; +var objectIs = typeof Object.is === "function" ? Object.is : is; var hasOwnProperty = Object.prototype.hasOwnProperty; /** @@ -5864,7 +5477,7 @@ var hasOwnProperty = Object.prototype.hasOwnProperty; */ function shallowEqual(objA, objB) { - if (is$1(objA, objB)) { + if (objectIs(objA, objB)) { return true; } @@ -5887,7 +5500,7 @@ function shallowEqual(objA, objB) { for (var i = 0; i < keysA.length; i++) { if ( !hasOwnProperty.call(objB, keysA[i]) || - !is$1(objA[keysA[i]], objB[keysA[i]]) + !objectIs(objA[keysA[i]], objB[keysA[i]]) ) { return false; } @@ -5896,77 +5509,122 @@ function shallowEqual(objA, objB) { return true; } -/** - * 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() {}; +var BEFORE_SLASH_RE = /^(.*)[\\\/]/; +function describeComponentFrame(name, source, ownerName) { + var sourceInfo = ""; -{ - 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]; + 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; + } + } + } } - var argIndex = 0; - var message = - "Warning: " + - format.replace(/%s/g, function() { - return args[argIndex++]; - }); + 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); + } +} - if (typeof console !== "undefined") { - console.warn(message); - } +function getStackByFiberInDevAndProd(workInProgress) { + var info = ""; + var node = workInProgress; - 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) {} - }; + do { + info += describeFiber(node); + node = node.return; + } while (node); - lowPriorityWarningWithoutStack = function(condition, format) { - if (format === undefined) { - throw new Error( - "`lowPriorityWarningWithoutStack(condition, format, ...args)` requires a warning " + - "message argument" - ); + return info; +} +var current = null; +var isRendering = false; +function getCurrentFiberOwnerNameInDevOrNull() { + { + if (current === null) { + return null; } - 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]; - } + var owner = current._debugOwner; - printWarning.apply(void 0, [format].concat(args)); + 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. -var lowPriorityWarningWithoutStack$1 = lowPriorityWarningWithoutStack; + 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 ReactStrictModeWarnings = { recordUnsafeLifecycleWarnings: function(fiber, instance) {}, @@ -6138,8 +5796,8 @@ var ReactStrictModeWarnings = { if (UNSAFE_componentWillMountUniqueNames.size > 0) { var sortedNames = setToSortedString(UNSAFE_componentWillMountUniqueNames); - warningWithoutStack$1( - false, + + error( "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" + @@ -6153,8 +5811,7 @@ var ReactStrictModeWarnings = { UNSAFE_componentWillReceivePropsUniqueNames ); - warningWithoutStack$1( - false, + error( "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" + @@ -6172,8 +5829,7 @@ var ReactStrictModeWarnings = { UNSAFE_componentWillUpdateUniqueNames ); - warningWithoutStack$1( - false, + error( "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" + @@ -6186,8 +5842,7 @@ var ReactStrictModeWarnings = { if (componentWillMountUniqueNames.size > 0) { var _sortedNames3 = setToSortedString(componentWillMountUniqueNames); - lowPriorityWarningWithoutStack$1( - false, + warn( "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" + @@ -6205,8 +5860,7 @@ var ReactStrictModeWarnings = { componentWillReceivePropsUniqueNames ); - lowPriorityWarningWithoutStack$1( - false, + warn( "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" + @@ -6225,8 +5879,7 @@ var ReactStrictModeWarnings = { if (componentWillUpdateUniqueNames.size > 0) { var _sortedNames5 = setToSortedString(componentWillUpdateUniqueNames); - lowPriorityWarningWithoutStack$1( - false, + warn( "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" + @@ -6251,11 +5904,11 @@ var ReactStrictModeWarnings = { var strictRoot = findStrictRoot(fiber); if (strictRoot === null) { - warningWithoutStack$1( - false, + error( "Expected to find a StrictMode component in a strict mode tree. " + "This error is likely caused by a bug in React. Please file an issue." ); + return; } // Dedup strategy: Warn once per component. @@ -6281,15 +5934,20 @@ 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 strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot); - warningWithoutStack$1( - false, + var firstComponentStack = getStackByFiberInDevAndProd(firstFiber); + + error( "Legacy context API has been detected within a strict-mode tree." + "\n\nThe old API will be supported in all 16.x releases, but applications " + "using it should migrate to the new version." + @@ -6297,7 +5955,7 @@ var ReactStrictModeWarnings = { "\n\nLearn more about this warning here: https://fb.me/react-legacy-context" + "%s", sortedNames, - strictRootComponentStack + firstComponentStack ); }); }; @@ -6540,9 +6198,6 @@ function scheduleFibersWithFamiliesRecursively( case ForwardRef: candidateType = type.render; break; - - default: - break; } if (resolveFamily === null) { @@ -6642,9 +6297,6 @@ function findHostInstancesForMatchingFibersRecursively( case ForwardRef: candidateType = type.render; break; - - default: - break; } var didMatch = false; @@ -6817,41 +6469,23 @@ 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._currentRenderer !== undefined && + context._currentRenderer !== null && + context._currentRenderer !== 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; + context._currentRenderer = rendererSigil; } } } @@ -6860,14 +6494,12 @@ 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 (is$1(oldValue, newValue)) { + if (objectIs(oldValue, newValue)) { // No change return 0; } else { @@ -6877,14 +6509,13 @@ function calculateChangedBits(context, newValue, oldValue) { : MAX_SIGNED_31_BIT_INT; { - !((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; + if ((changedBits & MAX_SIGNED_31_BIT_INT) !== changedBits) { + error( + "calculateChangedBits: Expected the return value to be a " + + "31-bit integer. Instead received: %s", + changedBits + ); + } } return changedBits | 0; @@ -6989,39 +6620,6 @@ 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; @@ -7080,22 +6678,19 @@ 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. - !!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 (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()." + ); + } } - 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 { + if (lastContextWithAllBitsObserved === context); + else if (observedBits === false || observedBits === 0); + else { var resolvedObservedBits; // Avoid deopting on observable arguments or heterogeneous types. if ( @@ -7134,85 +6729,9 @@ function readContext(context, observedBits) { } } - return isPrimaryRenderer ? context._currentValue : context._currentValue2; + return context._currentValue; } -// 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; @@ -7229,38 +6748,32 @@ var currentlyProcessingQueue; currentlyProcessingQueue = null; } -function createUpdateQueue(baseState) { - var queue = { - baseState: baseState, - firstUpdate: null, - lastUpdate: null, - firstCapturedUpdate: null, - lastCapturedUpdate: null, - firstEffect: null, - lastEffect: null, - firstCapturedEffect: null, - lastCapturedEffect: null - }; - return queue; -} - -function cloneUpdateQueue(currentQueue) { +function initializeUpdateQueue(fiber) { 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 + baseState: fiber.memoizedState, + baseQueue: null, + shared: { + pending: null + }, + effects: null }; - return queue; + 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; + } } - function createUpdate(expirationTime, suspenseConfig) { var update = { expirationTime: expirationTime, @@ -7268,9 +6781,9 @@ function createUpdate(expirationTime, suspenseConfig) { tag: UpdateState, payload: null, callback: null, - next: null, - nextEffect: null + next: null }; + update.next = update; { update.priority = getCurrentPriorityLevel(); @@ -7278,136 +6791,62 @@ function createUpdate(expirationTime, suspenseConfig) { return update; } +function enqueueUpdate(fiber, update) { + var updateQueue = fiber.updateQueue; -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; + if (updateQueue === null) { + // Only occurs if the fiber has been unmounted. + return; } -} -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 (queue1 === null) { - queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState); - } + if (pending === null) { + // This is the first update. Create a circular list. + update.next = update; } else { - // 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. - } - } + update.next = pending.next; + pending.next = 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; - } - } + sharedQueue.pending = update; { if ( - fiber.tag === ClassComponent && - (currentlyProcessingQueue === queue1 || - (queue2 !== null && currentlyProcessingQueue === queue2)) && + currentlyProcessingQueue === sharedQueue && !didWarnUpdateInsideUpdate ) { - warningWithoutStack$1( - false, + error( "An update (setState, replaceState, or forceUpdate) was scheduled " + "from inside an update function. Update functions should be pure, " + "with zero side-effects. Consider using componentDidUpdate or a " + "callback." ); + didWarnUpdateInsideUpdate = true; } } } function enqueueCapturedUpdate(workInProgress, update) { - // Captured updates go into a separate list, and only on the work-in- - // progress queue. - var workInProgressQueue = workInProgress.updateQueue; + var current = workInProgress.alternate; - 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 (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.lastCapturedUpdate === null) { - // This is the first render phase update - workInProgressQueue.firstCapturedUpdate = workInProgressQueue.lastCapturedUpdate = update; - } else { - workInProgressQueue.lastCapturedUpdate.next = update; - workInProgressQueue.lastCapturedUpdate = update; - } -} + var queue = workInProgress.updateQueue; // Append the update to the end of the list. -function ensureWorkInProgressQueueIsAClone(workInProgress, queue) { - var current = workInProgress.alternate; + var last = queue.baseQueue; - 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); - } + if (last === null) { + queue.baseQueue = update.next = update; + update.next = update; + } else { + update.next = last.next; + last.next = update; } - - return queue; } function getStateFromUpdate( @@ -7427,10 +6866,7 @@ function getStateFromUpdate( { enterDisallowedContextReadInDEV(); - if ( - debugRenderPhaseSideEffectsForStrictMode && - workInProgress.mode & StrictMode - ) { + if (workInProgress.mode & StrictMode) { payload.call(instance, prevState, nextProps); } } @@ -7462,10 +6898,7 @@ function getStateFromUpdate( { enterDisallowedContextReadInDEV(); - if ( - debugRenderPhaseSideEffectsForStrictMode && - workInProgress.mode & StrictMode - ) { + if (workInProgress.mode & StrictMode) { _payload.call(instance, prevState, nextProps); } } @@ -7499,163 +6932,171 @@ 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; - } // These values may change as we process the queue. + currentlyProcessingQueue = queue.shared; + } // The last rebase update that is NOT part of the base state. - var newBaseState = queue.baseState; - var newFirstUpdate = null; - var newExpirationTime = NoWork; // Iterate through the list of updates to compute the result. + var baseQueue = queue.baseQueue; // The last pending update that hasn't been processed yet. - var update = queue.firstUpdate; - var resultState = newBaseState; + var pendingQueue = queue.shared.pending; + + 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; + } - while (update !== null) { - var updateExpirationTime = update.expirationTime; + baseQueue = pendingQueue; + queue.shared.pending = null; // TODO: Pass `current` as argument - 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. + var current = workInProgress.alternate; - newBaseState = resultState; - } // Since this update will remain in the list, update the remaining - // expiration time. + if (current !== null) { + var currentQueue = current.updateQueue; - if (newExpirationTime < updateExpirationTime) { - newExpirationTime = updateExpirationTime; + if (currentQueue !== null) { + currentQueue.baseQueue = pendingQueue; } - } 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; + } + } // These values may change as we process the queue. - if (callback !== null) { - workInProgress.effectTag |= Callback; // Set this to null, in case it was mutated during an aborted render. + if (baseQueue !== null) { + var first = baseQueue.next; // Iterate through the list of updates to compute the result. - update.nextEffect = null; + var newState = queue.baseState; + var newExpirationTime = NoWork; + var newBaseState = null; + var newBaseQueueFirst = null; + var newBaseQueueLast = null; - if (queue.lastEffect === null) { - queue.firstEffect = queue.lastEffect = update; - } else { - queue.lastEffect.nextEffect = update; - queue.lastEffect = update; - } - } - } // Continue to the next update. + if (first !== null) { + var update = first; - update = update.next; - } // Separately, iterate though the list of captured updates. + 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 + }; - var newFirstCapturedUpdate = null; - update = queue.firstCapturedUpdate; + if (newBaseQueueLast === null) { + newBaseQueueFirst = newBaseQueueLast = clone; + newBaseState = newState; + } else { + newBaseQueueLast = newBaseQueueLast.next = clone; + } // Update the remaining priority in the queue. - while (update !== null) { - var _updateExpirationTime = update.expirationTime; + 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; - 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 (callback !== null) { + workInProgress.effectTag |= Callback; + var effects = queue.effects; - if (newFirstUpdate === null) { - newBaseState = resultState; + if (effects === null) { + queue.effects = [update]; + } else { + effects.push(update); + } + } } - } // 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; - if (_callback !== null) { - workInProgress.effectTag |= Callback; // Set this to null, in case it was mutated during an aborted render. + update = update.next; - update.nextEffect = null; + if (update === null || update === first) { + pendingQueue = queue.shared.pending; - if (queue.lastCapturedEffect === null) { - queue.firstCapturedEffect = queue.lastCapturedEffect = update; - } else { - queue.lastCapturedEffect.nextEffect = update; - queue.lastCapturedEffect = update; + 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; + } } - } + } while (true); } - update = update.next; - } - - if (newFirstUpdate === null) { - queue.lastUpdate = null; - } + if (newBaseQueueLast === null) { + newBaseState = newState; + } else { + newBaseQueueLast.next = newBaseQueueFirst; + } - if (newFirstCapturedUpdate === null) { - queue.lastCapturedUpdate = null; - } else { - workInProgress.effectTag |= Callback; - } + 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 && newFirstCapturedUpdate === null) { - // We processed every update, without skipping. That means the new base - // state is the same as the result state. - newBaseState = resultState; + markUnprocessedUpdateTime(newExpirationTime); + workInProgress.expirationTime = newExpirationTime; + workInProgress.memoizedState = newState; } - 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; } @@ -7678,42 +7119,21 @@ function resetHasForceUpdateBeforeProcessing() { function checkHasForceUpdateAfterProcessing() { return hasForceUpdate; } -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; -} +function commitUpdateQueue(finishedWork, finishedQueue, instance) { + // Commit the effects + var effects = finishedQueue.effects; + finishedQueue.effects = null; -function commitUpdateEffects(effect, instance) { - while (effect !== null) { - var callback = effect.callback; + if (effects !== null) { + for (var i = 0; i < effects.length; i++) { + var effect = effects[i]; + 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; } } @@ -7723,7 +7143,7 @@ function requestCurrentSuspenseConfig() { } var fakeInternalInstance = {}; -var isArray$1 = Array.isArray; // React.Component uses a shared frozen object by default. +var isArray = Array.isArray; // React.Component uses a shared frozen object by default. // We'll use it to determine whether we need to initialize legacy refs. var emptyRefsObject = new React.Component().refs; @@ -7758,8 +7178,8 @@ var didWarnAboutInvalidateContextType; if (!didWarnOnInvalidCallback.has(key)) { didWarnOnInvalidCallback.add(key); - warningWithoutStack$1( - false, + + error( "%s(...): Expected the last optional `callback` argument to be a " + "function. Instead received: %s.", callerName, @@ -7774,8 +7194,8 @@ var didWarnAboutInvalidateContextType; if (!didWarnAboutUndefinedDerivedState.has(componentName)) { didWarnAboutUndefinedDerivedState.add(componentName); - warningWithoutStack$1( - false, + + error( "%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. " + "You have returned undefined.", componentName @@ -7810,10 +7230,7 @@ function applyDerivedStateFromProps( var prevState = workInProgress.memoizedState; { - if ( - debugRenderPhaseSideEffectsForStrictMode && - workInProgress.mode & StrictMode - ) { + if (workInProgress.mode & StrictMode) { // Invoke the function an extra time to help detect side-effects. getDerivedStateFromProps(nextProps, prevState); } @@ -7832,9 +7249,9 @@ function applyDerivedStateFromProps( workInProgress.memoizedState = memoizedState; // Once the update queue is empty, persist the derived state onto the // base state. - var updateQueue = workInProgress.updateQueue; - - if (updateQueue !== null && workInProgress.expirationTime === NoWork) { + if (workInProgress.expirationTime === NoWork) { + // Queue is always non-null for classes + var updateQueue = workInProgress.updateQueue; updateQueue.baseState = memoizedState; } } @@ -7924,6 +7341,13 @@ 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, @@ -7933,14 +7357,13 @@ function checkShouldComponentUpdate( stopPhaseTimer(); { - !(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; + if (shouldUpdate === undefined) { + error( + "%s.shouldComponentUpdate(): Returned undefined instead of a " + + "boolean value. Make sure to return true or false.", + getComponentName(ctor) || "Component" + ); + } } return shouldUpdate; @@ -7964,94 +7387,69 @@ function checkClassInstance(workInProgress, ctor, newProps) { if (!renderPresent) { if (ctor.prototype && typeof ctor.prototype.render === "function") { - warningWithoutStack$1( - false, + error( "%s(...): No `render` method found on the returned component " + "instance: did you accidentally return an object from the constructor?", name ); - } else { - warningWithoutStack$1( - false, - "%s(...): No `render` method found on the returned component " + - "instance: you may have forgotten to define `render`.", - 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.", + } 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 (ctor.contextTypes) { - warningWithoutStack$1( - false, - "%s uses the legacy contextTypes API which is no longer supported. " + - "Use React.createContext() with static contextType instead.", + if (instance.propTypes) { + error( + "propTypes was defined as an instance property on %s. Use a static " + + "property to define propTypes instead.", + name + ); + } + + if (instance.contextType) { + error( + "contextType was defined as an instance property on %s. Use a static " + + "property to define contextType instead.", + name + ); + } + + { + if (instance.contextTypes) { + error( + "contextTypes was defined as an instance property on %s. Use a static " + + "property to define contextTypes instead.", name ); } - } 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 && @@ -8059,8 +7457,8 @@ function checkClassInstance(workInProgress, ctor, newProps) { !didWarnAboutContextTypeAndContextTypes.has(ctor) ) { didWarnAboutContextTypeAndContextTypes.add(ctor); - warningWithoutStack$1( - false, + + error( "%s declares both contextTypes and contextType static properties. " + "The legacy contextTypes property will be ignored.", name @@ -8068,26 +7466,22 @@ function checkClassInstance(workInProgress, ctor, newProps) { } } - 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 (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 + ); + } if ( ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== "undefined" ) { - warningWithoutStack$1( - false, + error( "%s has a method called shouldComponentUpdate(). " + "shouldComponentUpdate should not be used when extending React.PureComponent. " + "Please extend React.Component if shouldComponentUpdate is used.", @@ -8095,70 +7489,61 @@ function checkClassInstance(workInProgress, ctor, newProps) { ); } - 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; + 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 hasMutatedProps = instance.props !== newProps; - !(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 (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 + ); + } if ( typeof instance.getSnapshotBeforeUpdate === "function" && @@ -8166,63 +7551,53 @@ function checkClassInstance(workInProgress, ctor, newProps) { !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor) ) { didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor); - warningWithoutStack$1( - false, + + error( "%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). " + "This component defines getSnapshotBeforeUpdate() only.", getComponentName(ctor) ); } - 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 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 (_state && (typeof _state !== "object" || isArray$1(_state))) { - warningWithoutStack$1( - false, - "%s.state: must be set to an object or null", + 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 ); } - 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; + 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 + ); } } } @@ -8238,12 +7613,7 @@ function adoptClassInstance(workInProgress, instance) { } } -function constructClassInstance( - workInProgress, - ctor, - props, - renderExpirationTime -) { +function constructClassInstance(workInProgress, ctor, props) { var isLegacyContextConsumer = false; var unmaskedContext = emptyContextObject; var context = emptyContextObject; @@ -8281,8 +7651,7 @@ function constructClassInstance( "}."; } - warningWithoutStack$1( - false, + error( "%s defines an invalid contextType. " + "contextType should point to the Context object returned by React.createContext().%s", getComponentName(ctor) || "Component", @@ -8294,7 +7663,7 @@ function constructClassInstance( if (typeof contextType === "object" && contextType !== null) { context = readContext(contextType); - } else if (!disableLegacyContext) { + } else { unmaskedContext = getUnmaskedContext(workInProgress, ctor, true); var contextTypes = ctor.contextTypes; isLegacyContextConsumer = @@ -8305,10 +7674,7 @@ function constructClassInstance( } // Instantiate twice to help detect side-effects. { - if ( - debugRenderPhaseSideEffectsForStrictMode && - workInProgress.mode & StrictMode - ) { + if (workInProgress.mode & StrictMode) { new ctor(props, context); // eslint-disable-line no-new } } @@ -8326,8 +7692,8 @@ function constructClassInstance( if (!didWarnAboutUninitializedState.has(componentName)) { didWarnAboutUninitializedState.add(componentName); - warningWithoutStack$1( - false, + + error( "`%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`. " + @@ -8392,8 +7758,8 @@ function constructClassInstance( if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName)) { didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName); - warningWithoutStack$1( - false, + + error( "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" + @@ -8435,8 +7801,7 @@ function callComponentWillMount(workInProgress, instance) { if (oldState !== instance.state) { { - warningWithoutStack$1( - false, + error( "%s.componentWillMount(): Assigning directly to this.state is " + "deprecated (except inside a component's " + "constructor). Use setState instead.", @@ -8473,8 +7838,8 @@ function callComponentWillReceiveProps( if (!didWarnAboutStateAssignmentForComponent.has(componentName)) { didWarnAboutStateAssignmentForComponent.add(componentName); - warningWithoutStack$1( - false, + + error( "%s.componentWillReceiveProps(): Assigning directly to " + "this.state is deprecated (except inside a component's " + "constructor). Use setState instead.", @@ -8501,12 +7866,11 @@ 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); @@ -8518,8 +7882,8 @@ function mountClassInstance( if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) { didWarnAboutDirectlyAssigningPropsToState.add(componentName); - warningWithoutStack$1( - false, + + error( "%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.", @@ -8535,7 +7899,7 @@ function mountClassInstance( ); } - if (warnAboutDeprecatedLifecycles) { + { ReactStrictModeWarnings.recordUnsafeLifecycleWarnings( workInProgress, instance @@ -8543,19 +7907,8 @@ function mountClassInstance( } } - var updateQueue = workInProgress.updateQueue; - - if (updateQueue !== null) { - processUpdateQueue( - workInProgress, - updateQueue, - newProps, - instance, - renderExpirationTime - ); - instance.state = workInProgress.memoizedState; - } - + processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); + instance.state = workInProgress.memoizedState; var getDerivedStateFromProps = ctor.getDerivedStateFromProps; if (typeof getDerivedStateFromProps === "function") { @@ -8578,18 +7931,13 @@ function mountClassInstance( callComponentWillMount(workInProgress, instance); // If we had additional state updates during this life-cycle, let's // process them now. - updateQueue = workInProgress.updateQueue; - - if (updateQueue !== null) { - processUpdateQueue( - workInProgress, - updateQueue, - newProps, - instance, - renderExpirationTime - ); - instance.state = workInProgress.memoizedState; - } + processUpdateQueue( + workInProgress, + newProps, + instance, + renderExpirationTime + ); + instance.state = workInProgress.memoizedState; } if (typeof instance.componentDidMount === "function") { @@ -8612,7 +7960,7 @@ function resumeMountClassInstance( if (typeof contextType === "object" && contextType !== null) { nextContext = readContext(contextType); - } else if (!disableLegacyContext) { + } else { var nextLegacyUnmaskedContext = getUnmaskedContext( workInProgress, ctor, @@ -8648,18 +7996,8 @@ function resumeMountClassInstance( resetHasForceUpdateBeforeProcessing(); var oldState = workInProgress.memoizedState; var newState = (instance.state = oldState); - var updateQueue = workInProgress.updateQueue; - - if (updateQueue !== null) { - processUpdateQueue( - workInProgress, - updateQueue, - newProps, - instance, - renderExpirationTime - ); - newState = workInProgress.memoizedState; - } + processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); + newState = workInProgress.memoizedState; if ( oldProps === newProps && @@ -8749,6 +8087,7 @@ function updateClassInstance( renderExpirationTime ) { var instance = workInProgress.stateNode; + cloneUpdateQueue(current, workInProgress); var oldProps = workInProgress.memoizedProps; instance.props = workInProgress.type === workInProgress.elementType @@ -8760,7 +8099,7 @@ function updateClassInstance( if (typeof contextType === "object" && contextType !== null) { nextContext = readContext(contextType); - } else if (!disableLegacyContext) { + } else { var nextUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true); nextContext = getMaskedContext(workInProgress, nextUnmaskedContext); } @@ -8792,18 +8131,8 @@ function updateClassInstance( resetHasForceUpdateBeforeProcessing(); var oldState = workInProgress.memoizedState; var newState = (instance.state = oldState); - var updateQueue = workInProgress.updateQueue; - - if (updateQueue !== null) { - processUpdateQueue( - workInProgress, - updateQueue, - newProps, - instance, - renderExpirationTime - ); - newState = workInProgress.memoizedState; - } + processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); + newState = workInProgress.memoizedState; if ( oldProps === newProps && @@ -8965,8 +8294,8 @@ var warnForMissingKey = function(child) {}; } ownerHasKeyUseWarning[currentComponentErrorInfo] = true; - warning$1( - false, + + error( "Each child in a list should have a unique " + '"key" prop. See https://fb.me/react-warning-keys for ' + "more information." @@ -8974,9 +8303,9 @@ var warnForMissingKey = function(child) {}; }; } -var isArray = Array.isArray; +var isArray$1 = Array.isArray; -function coerceRef(returnFiber, current$$1, element) { +function coerceRef(returnFiber, current, element) { var mixedRef = element.ref; if ( @@ -8987,25 +8316,21 @@ function coerceRef(returnFiber, current$$1, 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) { + 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 + ) + ) { var componentName = getComponentName(returnFiber.type) || "Component"; if (!didWarnAboutStringRefs[componentName]) { - 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, + { + error( '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. " + @@ -9030,7 +8355,7 @@ function coerceRef(returnFiber, current$$1, element) { if (!(ownerFiber.tag === ClassComponent)) { throw Error( - "Function components cannot have refs. Did you mean to use React.forwardRef()?" + "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" ); } @@ -9048,12 +8373,12 @@ function coerceRef(returnFiber, current$$1, element) { var stringRef = "" + mixedRef; // Check if previous string ref matches new string ref if ( - current$$1 !== null && - current$$1.ref !== null && - typeof current$$1.ref === "function" && - current$$1.ref._stringRef === stringRef + current !== null && + current.ref !== null && + typeof current.ref === "function" && + current.ref._stringRef === stringRef ) { - return current$$1.ref; + return current.ref; } var ref = function(value) { @@ -9118,23 +8443,25 @@ 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; - } + 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." - ); + 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." + ); + } } // 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 @@ -9201,10 +8528,10 @@ function ChildReconciler(shouldTrackSideEffects) { return existingChildren; } - function useFiber(fiber, pendingProps, expirationTime) { + function useFiber(fiber, pendingProps) { // 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, expirationTime); + var clone = createWorkInProgress(fiber, pendingProps); clone.index = 0; clone.sibling = null; return clone; @@ -9218,10 +8545,10 @@ function ChildReconciler(shouldTrackSideEffects) { return lastPlacedIndex; } - var current$$1 = newFiber.alternate; + var current = newFiber.alternate; - if (current$$1 !== null) { - var oldIndex = current$$1.index; + if (current !== null) { + var oldIndex = current.index; if (oldIndex < lastPlacedIndex) { // This is a move. @@ -9248,13 +8575,8 @@ function ChildReconciler(shouldTrackSideEffects) { return newFiber; } - function updateTextNode( - returnFiber, - current$$1, - textContent, - expirationTime - ) { - if (current$$1 === null || current$$1.tag !== HostText) { + function updateTextNode(returnFiber, current, textContent, expirationTime) { + if (current === null || current.tag !== HostText) { // Insert var created = createFiberFromText( textContent, @@ -9265,48 +8587,48 @@ function ChildReconciler(shouldTrackSideEffects) { return created; } else { // Update - var existing = useFiber(current$$1, textContent, expirationTime); + var existing = useFiber(current, textContent); existing.return = returnFiber; 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; + 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; + { + existing._debugSource = element._source; + existing._debugOwner = element._owner; + } + + return existing; } + } // Insert - return existing; - } else { - // Insert - var created = createFiberFromElement( - element, - returnFiber.mode, - expirationTime - ); - created.ref = coerceRef(returnFiber, current$$1, element); - created.return = returnFiber; - return created; - } + var created = createFiberFromElement( + element, + returnFiber.mode, + expirationTime + ); + created.ref = coerceRef(returnFiber, current, element); + created.return = returnFiber; + return created; } - function updatePortal(returnFiber, current$$1, portal, expirationTime) { + function updatePortal(returnFiber, current, portal, expirationTime) { if ( - current$$1 === null || - current$$1.tag !== HostPortal || - current$$1.stateNode.containerInfo !== portal.containerInfo || - current$$1.stateNode.implementation !== portal.implementation + current === null || + current.tag !== HostPortal || + current.stateNode.containerInfo !== portal.containerInfo || + current.stateNode.implementation !== portal.implementation ) { // Insert var created = createFiberFromPortal( @@ -9318,24 +8640,14 @@ function ChildReconciler(shouldTrackSideEffects) { return created; } else { // Update - var existing = useFiber( - current$$1, - portal.children || [], - expirationTime - ); + var existing = useFiber(current, portal.children || []); existing.return = returnFiber; return existing; } } - function updateFragment( - returnFiber, - current$$1, - fragment, - expirationTime, - key - ) { - if (current$$1 === null || current$$1.tag !== Fragment) { + function updateFragment(returnFiber, current, fragment, expirationTime, key) { + if (current === null || current.tag !== Fragment) { // Insert var created = createFiberFromFragment( fragment, @@ -9347,7 +8659,7 @@ function ChildReconciler(shouldTrackSideEffects) { return created; } else { // Update - var existing = useFiber(current$$1, fragment, expirationTime); + var existing = useFiber(current, fragment); existing.return = returnFiber; return existing; } @@ -9393,7 +8705,7 @@ function ChildReconciler(shouldTrackSideEffects) { } } - if (isArray(newChild) || getIteratorFn(newChild)) { + if (isArray$1(newChild) || getIteratorFn(newChild)) { var _created3 = createFiberFromFragment( newChild, returnFiber.mode, @@ -9476,7 +8788,7 @@ function ChildReconciler(shouldTrackSideEffects) { } } - if (isArray(newChild) || getIteratorFn(newChild)) { + if (isArray$1(newChild) || getIteratorFn(newChild)) { if (key !== null) { return null; } @@ -9562,7 +8874,7 @@ function ChildReconciler(shouldTrackSideEffects) { } } - if (isArray(newChild) || getIteratorFn(newChild)) { + if (isArray$1(newChild) || getIteratorFn(newChild)) { var _matchedFiber3 = existingChildren.get(newIdx) || null; return updateFragment( @@ -9616,8 +8928,7 @@ function ChildReconciler(shouldTrackSideEffects) { break; } - warning$1( - false, + error( "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 " + @@ -9625,9 +8936,7 @@ function ChildReconciler(shouldTrackSideEffects) { "could change in a future version.", key ); - break; - default: break; } } @@ -9830,28 +9139,28 @@ function ChildReconciler(shouldTrackSideEffects) { typeof Symbol === "function" && // $FlowFixMe Flow doesn't know about toStringTag newChildrenIterable[Symbol.toStringTag] === "Generator" ) { - !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; + 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 = true; } // Warn about using Maps as children if (newChildrenIterable.entries === iteratorFn) { - !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; + 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 = true; } // First, validate keys. // We'll get a different iterator later for the main pass. @@ -10030,7 +9339,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, expirationTime); + var existing = useFiber(currentFirstChild, textContent); existing.return = returnFiber; return existing; } // The existing first child is not a text node so we need to create one @@ -10059,33 +9368,55 @@ 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) { - 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: + 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: isCompatibleFamilyForHotReloading(child, element) - ) { - 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; + ) { + deleteRemainingChildren(returnFiber, child.sibling); - { - existing._debugSource = element._source; - existing._debugOwner = element._owner; + 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; } + } // Didn't match. - return existing; - } else { - deleteRemainingChildren(returnFiber, child); - break; - } + deleteRemainingChildren(returnFiber, child); + break; } else { deleteChild(returnFiber, child); } @@ -10134,7 +9465,7 @@ function ChildReconciler(shouldTrackSideEffects) { child.stateNode.implementation === portal.implementation ) { deleteRemainingChildren(returnFiber, child.sibling); - var existing = useFiber(child, portal.children || [], expirationTime); + var existing = useFiber(child, portal.children || []); existing.return = returnFiber; return existing; } else { @@ -10219,7 +9550,7 @@ function ChildReconciler(shouldTrackSideEffects) { ); } - if (isArray(newChild)) { + if (isArray$1(newChild)) { return reconcileChildrenArray( returnFiber, currentFirstChild, @@ -10287,8 +9618,8 @@ function ChildReconciler(shouldTrackSideEffects) { var reconcileChildFibers = ChildReconciler(true); var mountChildFibers = ChildReconciler(false); -function cloneChildFibers(current$$1, workInProgress) { - if (!(current$$1 === null || workInProgress.child === current$$1.child)) { +function cloneChildFibers(current, workInProgress) { + if (!(current === null || workInProgress.child === current.child)) { throw Error("Resuming work not yet implemented."); } @@ -10297,11 +9628,7 @@ function cloneChildFibers(current$$1, workInProgress) { } var currentChild = workInProgress.child; - var newChild = createWorkInProgress( - currentChild, - currentChild.pendingProps, - currentChild.expirationTime - ); + var newChild = createWorkInProgress(currentChild, currentChild.pendingProps); workInProgress.child = newChild; newChild.return = workInProgress; @@ -10309,8 +9636,7 @@ function cloneChildFibers(current$$1, workInProgress) { currentChild = currentChild.sibling; newChild = newChild.sibling = createWorkInProgress( currentChild, - currentChild.pendingProps, - currentChild.expirationTime + currentChild.pendingProps ); newChild.return = workInProgress; } @@ -10360,7 +9686,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(nextRootInstance); // Now that we know this function doesn't throw, replace it. + var nextRootContext = getRootHostContext(); // Now that we know this function doesn't throw, replace it. pop(contextStackCursor$1, fiber); push(contextStackCursor$1, nextRootContext, fiber); @@ -10380,7 +9706,7 @@ function getHostContext() { function pushHostContext(fiber) { var rootInstance = requiredContext(rootInstanceStackCursor.current); var context = requiredContext(contextStackCursor$1.current); - var nextContext = getChildHostContext(context, fiber.type, rootInstance); // Don't push this Fiber's context unless it's unique. + var nextContext = getChildHostContext(context, fiber.type); // Don't push this Fiber's context unless it's unique. if (context === nextContext) { return; @@ -10483,8 +9809,8 @@ function findFirstSuspended(row) { if ( dehydrated === null || - isSuspenseInstancePending(dehydrated) || - isSuspenseInstanceFallback(dehydrated) + isSuspenseInstancePending() || + isSuspenseInstanceFallback() ) { return node; } @@ -10524,191 +9850,7 @@ function findFirstSuspended(row) { 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 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) { +function createDeprecatedResponderListener(responder, props) { var eventResponderListener = { responder: responder, props: props @@ -10721,33 +9863,19 @@ function createResponderListener(responder, props) { return eventResponderListener; } -var NoEffect$1 = - /* */ - 0; -var UnmountSnapshot = - /* */ +var HasEffect = + /* */ + 1; // Represents the phase in which the effect (not the clean-up) fires. + +var Layout = + /* */ 2; -var UnmountMutation = - /* */ +var Passive$1 = + /* */ 4; -var MountMutation = - /* */ - 8; -var UnmountLayout = - /* */ - 16; -var MountLayout = - /* */ - 32; -var MountPassive = - /* */ - 64; -var UnmountPassive = - /* */ - 128; -var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher; -var ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig; +var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher, + ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig; var didWarnAboutMismatchedHooksForComponent; { @@ -10755,7 +9883,7 @@ var didWarnAboutMismatchedHooksForComponent; } // These are set right before calling the component. -var renderExpirationTime$1 = NoWork; // The work-in-progress fiber. I've named it differently to distinguish it from +var renderExpirationTime = 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 @@ -10764,26 +9892,12 @@ var currentlyRenderingFiber$1 = null; // Hooks are stored as a linked list on th // work-in-progress fiber. var currentHook = null; -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 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 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. @@ -10828,8 +9942,7 @@ 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. - warning$1( - false, + error( "%s received a final argument that is not an array (instead, received `%s`). When " + "specified, the final argument must be an array.", currentHookNameInDev, @@ -10865,8 +9978,7 @@ function warnOnHookMismatchInDev(currentHookName) { table += row; } - warning$1( - false, + error( "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" + @@ -10900,8 +10012,7 @@ function areHookInputsEqual(nextDeps, prevDeps) { if (prevDeps === null) { { - warning$1( - false, + error( "%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.", @@ -10916,8 +10027,7 @@ function areHookInputsEqual(nextDeps, prevDeps) { // Don't bother comparing lengths in prod because these arrays should be // passed inline. if (nextDeps.length !== prevDeps.length) { - warning$1( - false, + error( "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" + @@ -10930,7 +10040,7 @@ function areHookInputsEqual(nextDeps, prevDeps) { } for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) { - if (is$1(nextDeps[i], prevDeps[i])) { + if (objectIs(nextDeps[i], prevDeps[i])) { continue; } @@ -10945,12 +10055,11 @@ function renderWithHooks( workInProgress, Component, props, - refOrContext, + secondArg, nextRenderExpirationTime ) { - renderExpirationTime$1 = nextRenderExpirationTime; + renderExpirationTime = nextRenderExpirationTime; currentlyRenderingFiber$1 = workInProgress; - nextCurrentHook = current !== null ? current.memoizedState : null; { hookTypesDev = current !== null ? current._debugHookTypes : null; @@ -10958,42 +10067,52 @@ function renderWithHooks( ignorePreviousDependencies = current !== null && current.type !== workInProgress.type; - } // The following should have already been reset + } + + workInProgress.memoizedState = null; + workInProgress.updateQueue = null; + workInProgress.expirationTime = NoWork; // 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 nextCurrentHook === null. + // Currently we will identify the update render as a mount because memoizedState === null. // This is tricky because it's valid for certain types of components (e.g. React.lazy) - // Using nextCurrentHook to differentiate between mount/update only works if at least one stateful hook is used. + // Using memoizedState 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 nextCurrentHook would be null during updates and mounts. + // so memoizedState would be null during updates and mounts. { - if (nextCurrentHook !== null) { - ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV; + if (current !== null && current.memoizedState !== null) { + ReactCurrentDispatcher.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$1.current = HooksDispatcherOnMountWithHookTypesInDEV; + ReactCurrentDispatcher.current = HooksDispatcherOnMountWithHookTypesInDEV; } else { - ReactCurrentDispatcher$1.current = HooksDispatcherOnMountInDEV; + ReactCurrentDispatcher.current = HooksDispatcherOnMountInDEV; } } - var children = Component(props, refOrContext); + 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; - if (didScheduleRenderPhaseUpdate) { do { - didScheduleRenderPhaseUpdate = false; + 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." + ); + } + numberOfReRenders += 1; { @@ -11002,46 +10121,33 @@ function renderWithHooks( ignorePreviousDependencies = false; } // Start over from the beginning of the list - nextCurrentHook = current !== null ? current.memoizedState : null; - nextWorkInProgressHook = firstWorkInProgressHook; currentHook = null; workInProgressHook = null; - componentUpdateQueue = null; + workInProgress.updateQueue = null; { // Also validate hook order for cascading updates. hookTypesUpdateIndexDev = -1; } - ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV; - children = Component(props, refOrContext); - } while (didScheduleRenderPhaseUpdate); - - renderPhaseUpdates = null; - numberOfReRenders = 0; + ReactCurrentDispatcher.current = HooksDispatcherOnRerenderInDEV; + children = Component(props, secondArg); + } while (workInProgress.expirationTime === renderExpirationTime); } // 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$1.current = ContextOnlyDispatcher; - var renderedWork = currentlyRenderingFiber$1; - renderedWork.memoizedState = firstWorkInProgressHook; - renderedWork.expirationTime = remainingExpirationTime; - renderedWork.updateQueue = componentUpdateQueue; - renderedWork.effectTag |= sideEffectTag; + ReactCurrentDispatcher.current = ContextOnlyDispatcher; { - renderedWork._debugHookTypes = hookTypesDev; + workInProgress._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$1 = NoWork; + renderExpirationTime = NoWork; currentlyRenderingFiber$1 = null; currentHook = null; - nextCurrentHook = null; - firstWorkInProgressHook = null; workInProgressHook = null; - nextWorkInProgressHook = null; { currentHookNameInDev = null; @@ -11049,12 +10155,7 @@ function renderWithHooks( hookTypesUpdateIndexDev = -1; } - remainingExpirationTime = NoWork; - componentUpdateQueue = null; - sideEffectTag = 0; // These were reset above - // didScheduleRenderPhaseUpdate = false; - // renderPhaseUpdates = null; - // numberOfReRenders = 0; + didScheduleRenderPhaseUpdate = false; if (!!didRenderTooFewHooks) { throw Error( @@ -11072,20 +10173,37 @@ function bailoutHooks(current, workInProgress, expirationTime) { current.expirationTime = NoWork; } } -function resetHooks() { +function resetHooksAfterThrow() { // 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$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. + 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; + } + } - renderExpirationTime$1 = NoWork; + renderExpirationTime = NoWork; currentlyRenderingFiber$1 = null; currentHook = null; - nextCurrentHook = null; - firstWorkInProgressHook = null; workInProgressHook = null; - nextWorkInProgressHook = null; { hookTypesDev = null; @@ -11093,26 +10211,21 @@ function resetHooks() { 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 - firstWorkInProgressHook = workInProgressHook = hook; + currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook; } else { // Append to the end of the list workInProgressHook = workInProgressHook.next = hook; @@ -11127,12 +10240,33 @@ 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)) { @@ -11143,20 +10277,18 @@ 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. - workInProgressHook = firstWorkInProgressHook = newHook; + currentlyRenderingFiber$1.memoizedState = workInProgressHook = newHook; } else { // Append to the end of the list. workInProgressHook = workInProgressHook.next = newHook; } - - nextCurrentHook = currentHook.next; } return workInProgressHook; @@ -11169,6 +10301,7 @@ function createFunctionComponentUpdateQueue() { } function basicStateReducer(state, action) { + // $FlowFixMe: Flow doesn't like mixed types return typeof action === "function" ? action(state) : action; } @@ -11184,13 +10317,13 @@ function mountReducer(reducer, initialArg, init) { hook.memoizedState = hook.baseState = initialState; var queue = (hook.queue = { - last: null, + pending: null, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialState }); var dispatch = (queue.dispatch = dispatchAction.bind( - null, // Flow doesn't know this is non-null, but we do. + null, currentlyRenderingFiber$1, queue )); @@ -11208,160 +10341,191 @@ function updateReducer(reducer, initialArg, init) { } queue.lastRenderedReducer = reducer; + var current = currentHook; // The last rebase update that is NOT part of the base state. - 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 baseQueue = current.baseQueue; // The last pending update that hasn't been processed yet. - var baseUpdate = hook.baseUpdate; - var baseState = hook.baseState; // Find the first unprocessed update. + var pendingQueue = queue.pending; - 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; + 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; } - first = baseUpdate.next; - } else { - first = last !== null ? last.next : null; + current.baseQueue = baseQueue = pendingQueue; + queue.pending = null; } - if (first !== null) { - var _newState = baseState; + if (baseQueue !== null) { + // We have a queue to process. + var first = baseQueue.next; + var newState = current.baseState; var newBaseState = null; - var newBaseUpdate = null; - var prevUpdate = baseUpdate; - var _update = first; - var didSkip = false; + var newBaseQueueFirst = null; + var newBaseQueueLast = null; + var update = first; do { - var updateExpirationTime = _update.expirationTime; + var updateExpirationTime = update.expirationTime; - if (updateExpirationTime < renderExpirationTime$1) { + 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. - if (!didSkip) { - didSkip = true; - newBaseUpdate = prevUpdate; - newBaseState = _newState; + 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; } // Update the remaining priority in the queue. - if (updateExpirationTime > remainingExpirationTime) { - remainingExpirationTime = updateExpirationTime; - markUnprocessedUpdateTime(remainingExpirationTime); + if (updateExpirationTime > currentlyRenderingFiber$1.expirationTime) { + currentlyRenderingFiber$1.expirationTime = updateExpirationTime; + markUnprocessedUpdateTime(updateExpirationTime); } } else { // This update does have sufficient priority. - // Mark the event time of this update as relevant to this render pass. + 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. // 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); } } - prevUpdate = _update; - _update = _update.next; - } while (_update !== null && _update !== first); + update = update.next; + } while (update !== null && update !== first); - if (!didSkip) { - newBaseUpdate = prevUpdate; - newBaseState = _newState; + if (newBaseQueueLast === null) { + newBaseState = newState; + } else { + newBaseQueueLast.next = newBaseQueueFirst; } // Mark that the fiber performed work, but only if the new state is // different from the current state. - if (!is$1(_newState, hook.memoizedState)) { + if (!objectIs(newState, hook.memoizedState)) { markWorkInProgressReceivedUpdate(); } - hook.memoizedState = _newState; - hook.baseUpdate = newBaseUpdate; + hook.memoizedState = newState; hook.baseState = newBaseState; - queue.lastRenderedState = _newState; + hook.baseQueue = newBaseQueueLast; + 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 = { - last: null, + pending: null, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState }); var dispatch = (queue.dispatch = dispatchAction.bind( - null, // Flow doesn't know this is non-null, but we do. + null, currentlyRenderingFiber$1, queue )); @@ -11369,7 +10533,11 @@ function mountState(initialState) { } function updateState(initialState) { - return updateReducer(basicStateReducer, initialState); + return updateReducer(basicStateReducer); +} + +function rerenderState(initialState) { + return rerenderReducer(basicStateReducer); } function pushEffect(tag, create, destroy, deps) { @@ -11381,9 +10549,11 @@ 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; @@ -11423,8 +10593,13 @@ function updateRef(initialValue) { function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var hook = mountWorkInProgressHook(); var nextDeps = deps === undefined ? null : deps; - sideEffectTag |= fiberEffectTag; - hook.memoizedState = pushEffect(hookEffectTag, create, undefined, nextDeps); + currentlyRenderingFiber$1.effectTag |= fiberEffectTag; + hook.memoizedState = pushEffect( + HasEffect | hookEffectTag, + create, + undefined, + nextDeps + ); } function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { @@ -11440,14 +10615,19 @@ function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var prevDeps = prevEffect.deps; if (areHookInputsEqual(nextDeps, prevDeps)) { - pushEffect(NoEffect$1, create, destroy, nextDeps); + pushEffect(hookEffectTag, create, destroy, nextDeps); return; } } } - sideEffectTag |= fiberEffectTag; - hook.memoizedState = pushEffect(hookEffectTag, create, destroy, nextDeps); + currentlyRenderingFiber$1.effectTag |= fiberEffectTag; + hook.memoizedState = pushEffect( + HasEffect | hookEffectTag, + create, + destroy, + nextDeps + ); } function mountEffect(create, deps) { @@ -11458,12 +10638,7 @@ function mountEffect(create, deps) { } } - return mountEffectImpl( - Update | Passive, - UnmountPassive | MountPassive, - create, - deps - ); + return mountEffectImpl(Update | Passive, Passive$1, create, deps); } function updateEffect(create, deps) { @@ -11474,20 +10649,15 @@ function updateEffect(create, deps) { } } - return updateEffectImpl( - Update | Passive, - UnmountPassive | MountPassive, - create, - deps - ); + return updateEffectImpl(Update | Passive, Passive$1, create, deps); } function mountLayoutEffect(create, deps) { - return mountEffectImpl(Update, UnmountMutation | MountLayout, create, deps); + return mountEffectImpl(Update, Layout, create, deps); } function updateLayoutEffect(create, deps) { - return updateEffectImpl(Update, UnmountMutation | MountLayout, create, deps); + return updateEffectImpl(Update, Layout, create, deps); } function imperativeHandleEffect(create, ref) { @@ -11504,14 +10674,13 @@ function imperativeHandleEffect(create, ref) { var refObject = ref; { - !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; + 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(", ") + "}" + ); + } } var _inst2 = create(); @@ -11525,21 +10694,20 @@ function imperativeHandleEffect(create, ref) { function mountImperativeHandle(ref, create, deps) { { - !(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; + 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" + ); + } } // 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, - UnmountMutation | MountLayout, + Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps ); @@ -11547,21 +10715,20 @@ function mountImperativeHandle(ref, create, deps) { function updateImperativeHandle(ref, create, deps) { { - !(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; + 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" + ); + } } // 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, - UnmountMutation | MountLayout, + Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps ); @@ -11637,17 +10804,14 @@ function mountDeferredValue(value, config) { mountEffect( function() { - Scheduler.unstable_next(function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - config === undefined ? null : config; + 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] ); @@ -11655,99 +10819,149 @@ function mountDeferredValue(value, config) { } function updateDeferredValue(value, config) { - var _updateState = updateState(value), + var _updateState = updateState(), prevValue = _updateState[0], setValue = _updateState[1]; updateEffect( function() { - Scheduler.unstable_next(function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - config === undefined ? null : config; + 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 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; + + 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 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]; + var start = mountCallback(startTransition.bind(null, setPending, config), [ + setPending, + config + ]); + return [start, isPending]; } function updateTransition(config) { - var _updateState2 = updateState(false), + var _updateState2 = updateState(), isPending = _updateState2[0], setPending = _updateState2[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 rerenderTransition(config) { + var _rerenderState2 = rerenderState(), + isPending = _rerenderState2[0], + setPending = _rerenderState2[1]; + + var start = updateCallback(startTransition.bind(null, setPending, config), [ + setPending, + config + ]); + return [start, isPending]; } function dispatchAction(fiber, queue, action) { - if (!(numberOfReRenders < RE_RENDER_LIMIT)) { - throw Error( - "Too many re-renders. React limits the number of renders to prevent an infinite loop." - ); + { + 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()." + ); + } } + 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 + }; + { - !(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; + 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; } + queue.pending = update; var alternate = fiber.alternate; if ( @@ -11758,76 +10972,9 @@ 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; - 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; - } + update.expirationTime = renderExpirationTime; + currentlyRenderingFiber$1.expirationTime = renderExpirationTime; } 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) @@ -11841,8 +10988,8 @@ function dispatchAction(fiber, queue, action) { var prevDispatcher; { - prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; } try { @@ -11852,10 +10999,10 @@ function dispatchAction(fiber, queue, action) { // time we enter the render phase, then the eager state can be used // without calling the reducer again. - _update2.eagerReducer = lastRenderedReducer; - _update2.eagerState = eagerState; + update.eagerReducer = lastRenderedReducer; + update.eagerState = eagerState; - if (is$1(eagerState, currentState)) { + if (objectIs(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 @@ -11866,7 +11013,7 @@ function dispatchAction(fiber, queue, action) { // Suppress the error. It will throw again in the render phase. } finally { { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } } } @@ -11884,6 +11031,14 @@ function dispatchAction(fiber, queue, action) { } } +function mountEventListener(event) { + return undefined; +} + +function updateEventListener(event) { + return undefined; +} + var ContextOnlyDispatcher = { readContext: readContext, useCallback: throwInvalidHookError, @@ -11898,18 +11053,20 @@ var ContextOnlyDispatcher = { useDebugValue: throwInvalidHookError, useResponder: throwInvalidHookError, useDeferredValue: throwInvalidHookError, - useTransition: throwInvalidHookError + useTransition: throwInvalidHookError, + useEvent: 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() { - warning$1( - false, + 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 " + @@ -11918,8 +11075,7 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; }; var warnInvalidHookAccess = function() { - warning$1( - false, + error( "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 " + @@ -11964,25 +11120,25 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; currentHookNameInDev = "useMemo"; mountHookTypesDev(); checkDepsAreArrayDev(deps); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; try { return mountMemo(create, deps); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useReducer: function(reducer, initialArg, init) { currentHookNameInDev = "useReducer"; mountHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; try { return mountReducer(reducer, initialArg, init); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useRef: function(initialValue) { @@ -11993,24 +11149,24 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; useState: function(initialState) { currentHookNameInDev = "useState"; mountHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; try { return mountState(initialState); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useDebugValue: function(value, formatterFn) { currentHookNameInDev = "useDebugValue"; mountHookTypesDev(); - return mountDebugValue(value, formatterFn); + return mountDebugValue(); }, useResponder: function(responder, props) { currentHookNameInDev = "useResponder"; mountHookTypesDev(); - return createResponderListener(responder, props); + return createDeprecatedResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; @@ -12021,6 +11177,11 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; currentHookNameInDev = "useTransition"; mountHookTypesDev(); return mountTransition(config); + }, + useEvent: function(event) { + currentHookNameInDev = "useEvent"; + mountHookTypesDev(); + return mountEventListener(); } }; HooksDispatcherOnMountWithHookTypesInDEV = { @@ -12055,25 +11216,25 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; useMemo: function(create, deps) { currentHookNameInDev = "useMemo"; updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; try { return mountMemo(create, deps); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useReducer: function(reducer, initialArg, init) { currentHookNameInDev = "useReducer"; updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; try { return mountReducer(reducer, initialArg, init); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useRef: function(initialValue) { @@ -12084,24 +11245,24 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; useState: function(initialState) { currentHookNameInDev = "useState"; updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; try { return mountState(initialState); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useDebugValue: function(value, formatterFn) { currentHookNameInDev = "useDebugValue"; updateHookTypesDev(); - return mountDebugValue(value, formatterFn); + return mountDebugValue(); }, useResponder: function(responder, props) { currentHookNameInDev = "useResponder"; updateHookTypesDev(); - return createResponderListener(responder, props); + return createDeprecatedResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; @@ -12112,6 +11273,11 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; currentHookNameInDev = "useTransition"; updateHookTypesDev(); return mountTransition(config); + }, + useEvent: function(event) { + currentHookNameInDev = "useEvent"; + updateHookTypesDev(); + return mountEventListener(); } }; HooksDispatcherOnUpdateInDEV = { @@ -12146,53 +11312,53 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; useMemo: function(create, deps) { currentHookNameInDev = "useMemo"; updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; try { return updateMemo(create, deps); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useReducer: function(reducer, initialArg, init) { currentHookNameInDev = "useReducer"; updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; try { return updateReducer(reducer, initialArg, init); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useRef: function(initialValue) { currentHookNameInDev = "useRef"; updateHookTypesDev(); - return updateRef(initialValue); + return updateRef(); }, useState: function(initialState) { currentHookNameInDev = "useState"; updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; try { return updateState(initialState); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useDebugValue: function(value, formatterFn) { currentHookNameInDev = "useDebugValue"; updateHookTypesDev(); - return updateDebugValue(value, formatterFn); + return updateDebugValue(); }, useResponder: function(responder, props) { currentHookNameInDev = "useResponder"; updateHookTypesDev(); - return createResponderListener(responder, props); + return createDeprecatedResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; @@ -12203,6 +11369,107 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = 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 = { @@ -12244,26 +11511,26 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; currentHookNameInDev = "useMemo"; warnInvalidHookAccess(); mountHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; try { return mountMemo(create, deps); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useReducer: function(reducer, initialArg, init) { currentHookNameInDev = "useReducer"; warnInvalidHookAccess(); mountHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; try { return mountReducer(reducer, initialArg, init); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useRef: function(initialValue) { @@ -12276,41 +11543,158 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; currentHookNameInDev = "useState"; warnInvalidHookAccess(); mountHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; try { return mountState(initialState); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + 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; } }, useDebugValue: function(value, formatterFn) { currentHookNameInDev = "useDebugValue"; warnInvalidHookAccess(); - mountHookTypesDev(); - return mountDebugValue(value, formatterFn); + updateHookTypesDev(); + return updateDebugValue(); }, useResponder: function(responder, props) { currentHookNameInDev = "useResponder"; warnInvalidHookAccess(); - mountHookTypesDev(); - return createResponderListener(responder, props); + updateHookTypesDev(); + return createDeprecatedResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; warnInvalidHookAccess(); - mountHookTypesDev(); - return mountDeferredValue(value, config); + updateHookTypesDev(); + return updateDeferredValue(value, config); }, useTransition: function(config) { currentHookNameInDev = "useTransition"; warnInvalidHookAccess(); - mountHookTypesDev(); - return mountTransition(config); + updateHookTypesDev(); + return updateTransition(config); + }, + useEvent: function(event) { + currentHookNameInDev = "useEvent"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateEventListener(); } }; - InvalidNestedHooksDispatcherOnUpdateInDEV = { + InvalidNestedHooksDispatcherOnRerenderInDEV = { readContext: function(context, observedBits) { warnInvalidContextAccess(); return readContext(context, observedBits); @@ -12349,76 +11733,80 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; currentHookNameInDev = "useMemo"; warnInvalidHookAccess(); updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; try { return updateMemo(create, deps); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useReducer: function(reducer, initialArg, init) { currentHookNameInDev = "useReducer"; warnInvalidHookAccess(); updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; try { - return updateReducer(reducer, initialArg, init); + return rerenderReducer(reducer, initialArg, init); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useRef: function(initialValue) { currentHookNameInDev = "useRef"; warnInvalidHookAccess(); updateHookTypesDev(); - return updateRef(initialValue); + return updateRef(); }, useState: function(initialState) { currentHookNameInDev = "useState"; warnInvalidHookAccess(); updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; try { - return updateState(initialState); + return rerenderState(initialState); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useDebugValue: function(value, formatterFn) { currentHookNameInDev = "useDebugValue"; warnInvalidHookAccess(); updateHookTypesDev(); - return updateDebugValue(value, formatterFn); + return updateDebugValue(); }, useResponder: function(responder, props) { currentHookNameInDev = "useResponder"; warnInvalidHookAccess(); updateHookTypesDev(); - return createResponderListener(responder, props); + return createDeprecatedResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; warnInvalidHookAccess(); updateHookTypesDev(); - return updateDeferredValue(value, config); + return rerenderDeferredValue(value, config); }, useTransition: function(config) { currentHookNameInDev = "useTransition"; warnInvalidHookAccess(); updateHookTypesDev(); - return updateTransition(config); + 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; @@ -12428,18 +11816,10 @@ function getCommitTime() { } function recordCommitTime() { - if (!enableProfilerTimer) { - return; - } - commitTime = now$1(); } function startProfilerTimer(fiber) { - if (!enableProfilerTimer) { - return; - } - profilerStartTime = now$1(); if (fiber.actualStartTime < 0) { @@ -12448,18 +11828,10 @@ 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; @@ -12472,258 +11844,10 @@ function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) { } } -// 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); + return false; } - - hydrationParentFiber = fiber; - nextHydratableInstance = getFirstHydratableChild(nextInstance); } function prepareToHydrateHostInstance( @@ -12731,209 +11855,33 @@ 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 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." + "Expected prepareToHydrateHostTextInstance() 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; + var shouldUpdate = hydrateTextInstance(); } 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 ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner; var didReceiveUpdate = false; var didWarnAboutBadClass; var didWarnAboutModulePatternComponent; @@ -12941,10 +11889,8 @@ var didWarnAboutContextTypeOnFunctionComponent; var didWarnAboutGetDerivedStateOnFunctionComponent; var didWarnAboutFunctionRefs; var didWarnAboutReassigningProps; -var didWarnAboutMaxDuration; var didWarnAboutRevealOrder; var didWarnAboutTailOptions; -var didWarnAboutDefaultPropsOnFunctionComponent; { didWarnAboutBadClass = {}; @@ -12953,19 +11899,17 @@ var didWarnAboutDefaultPropsOnFunctionComponent; didWarnAboutGetDerivedStateOnFunctionComponent = {}; didWarnAboutFunctionRefs = {}; didWarnAboutReassigningProps = false; - didWarnAboutMaxDuration = false; didWarnAboutRevealOrder = {}; didWarnAboutTailOptions = {}; - didWarnAboutDefaultPropsOnFunctionComponent = {}; } function reconcileChildren( - current$$1, + current, workInProgress, nextChildren, renderExpirationTime ) { - if (current$$1 === null) { + 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 @@ -12984,7 +11928,7 @@ function reconcileChildren( // let's throw it out. workInProgress.child = reconcileChildFibers( workInProgress, - current$$1.child, + current.child, nextChildren, renderExpirationTime ); @@ -12992,7 +11936,7 @@ function reconcileChildren( } function forceUnmountCurrentAndReconcile( - current$$1, + current, workInProgress, nextChildren, renderExpirationTime @@ -13007,13 +11951,13 @@ function forceUnmountCurrentAndReconcile( // passing null. workInProgress.child = reconcileChildFibers( workInProgress, - current$$1.child, + 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 their - // identity matches. + // the effect of remounting all children regardless of whether their + // identities match. workInProgress.child = reconcileChildFibers( workInProgress, @@ -13024,7 +11968,7 @@ function forceUnmountCurrentAndReconcile( } function updateForwardRef( - current$$1, + current, workInProgress, Component, nextProps, @@ -13044,8 +11988,7 @@ function updateForwardRef( innerPropTypes, nextProps, // Resolved props "prop", - getComponentName(Component), - getCurrentFiberStackInDev + getComponentName(Component) ); } } @@ -13058,10 +12001,10 @@ function updateForwardRef( prepareToReadContext(workInProgress, renderExpirationTime); { - ReactCurrentOwner$3.current = workInProgress; - setCurrentPhase("render"); + ReactCurrentOwner$1.current = workInProgress; + setIsRendering(true); nextChildren = renderWithHooks( - current$$1, + current, workInProgress, render, nextProps, @@ -13069,14 +12012,11 @@ function updateForwardRef( renderExpirationTime ); - if ( - debugRenderPhaseSideEffectsForStrictMode && - workInProgress.mode & StrictMode - ) { + if (workInProgress.mode & StrictMode) { // Only double-render components with Hooks if (workInProgress.memoizedState !== null) { nextChildren = renderWithHooks( - current$$1, + current, workInProgress, render, nextProps, @@ -13086,13 +12026,13 @@ function updateForwardRef( } } - setCurrentPhase(null); + setIsRendering(false); } - if (current$$1 !== null && !didReceiveUpdate) { - bailoutHooks(current$$1, workInProgress, renderExpirationTime); + if (current !== null && !didReceiveUpdate) { + bailoutHooks(current, workInProgress, renderExpirationTime); return bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ); @@ -13100,7 +12040,7 @@ function updateForwardRef( workInProgress.effectTag |= PerformedWork; reconcileChildren( - current$$1, + current, workInProgress, nextChildren, renderExpirationTime @@ -13109,14 +12049,14 @@ function updateForwardRef( } function updateMemoComponent( - current$$1, + current, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime ) { - if (current$$1 === null) { + if (current === null) { var type = Component.type; if ( @@ -13140,7 +12080,7 @@ function updateMemoComponent( } return updateSimpleMemoComponent( - current$$1, + current, workInProgress, resolvedType, nextProps, @@ -13159,8 +12099,7 @@ function updateMemoComponent( innerPropTypes, nextProps, // Resolved props "prop", - getComponentName(type), - getCurrentFiberStackInDev + getComponentName(type) ); } } @@ -13190,13 +12129,12 @@ function updateMemoComponent( _innerPropTypes, nextProps, // Resolved props "prop", - getComponentName(_type), - getCurrentFiberStackInDev + getComponentName(_type) ); } } - var currentChild = current$$1.child; // This is always exactly one child + var currentChild = current.child; // This is always exactly one child if (updateExpirationTime < renderExpirationTime) { // This will be the props with resolved defaultProps, @@ -13206,12 +12144,9 @@ function updateMemoComponent( var compare = Component.compare; compare = compare !== null ? compare : shallowEqual; - if ( - compare(prevProps, nextProps) && - current$$1.ref === workInProgress.ref - ) { + if (compare(prevProps, nextProps) && current.ref === workInProgress.ref) { return bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ); @@ -13219,11 +12154,7 @@ function updateMemoComponent( } // React DevTools reads this flag. workInProgress.effectTag |= PerformedWork; - var newChild = createWorkInProgress( - currentChild, - nextProps, - renderExpirationTime - ); + var newChild = createWorkInProgress(currentChild, nextProps); newChild.ref = workInProgress.ref; newChild.return = workInProgress; workInProgress.child = newChild; @@ -13231,7 +12162,7 @@ function updateMemoComponent( } function updateSimpleMemoComponent( - current$$1, + current, workInProgress, Component, nextProps, @@ -13261,26 +12192,39 @@ function updateSimpleMemoComponent( outerPropTypes, nextProps, // Resolved (SimpleMemoComponent has no defaultProps) "prop", - getComponentName(outerMemoType), - getCurrentFiberStackInDev + getComponentName(outerMemoType) ); } // Inner propTypes will be validated in the function component path. } } - if (current$$1 !== null) { - var prevProps = current$$1.memoizedProps; + if (current !== null) { + var prevProps = current.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 + current.ref === workInProgress.ref && // Prevent bailout if the implementation changed due to hot reload. + workInProgress.type === current.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$$1, + current, workInProgress, renderExpirationTime ); @@ -13289,7 +12233,7 @@ function updateSimpleMemoComponent( } return updateFunctionComponent( - current$$1, + current, workInProgress, Component, nextProps, @@ -13297,10 +12241,10 @@ function updateSimpleMemoComponent( ); } -function updateFragment(current$$1, workInProgress, renderExpirationTime) { +function updateFragment(current, workInProgress, renderExpirationTime) { var nextChildren = workInProgress.pendingProps; reconcileChildren( - current$$1, + current, workInProgress, nextChildren, renderExpirationTime @@ -13308,10 +12252,10 @@ function updateFragment(current$$1, workInProgress, renderExpirationTime) { return workInProgress.child; } -function updateMode(current$$1, workInProgress, renderExpirationTime) { +function updateMode(current, workInProgress, renderExpirationTime) { var nextChildren = workInProgress.pendingProps.children; reconcileChildren( - current$$1, + current, workInProgress, nextChildren, renderExpirationTime @@ -13319,15 +12263,20 @@ function updateMode(current$$1, workInProgress, renderExpirationTime) { return workInProgress.child; } -function updateProfiler(current$$1, workInProgress, renderExpirationTime) { - if (enableProfilerTimer) { - workInProgress.effectTag |= Update; +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; } var nextProps = workInProgress.pendingProps; var nextChildren = nextProps.children; reconcileChildren( - current$$1, + current, workInProgress, nextChildren, renderExpirationTime @@ -13335,12 +12284,12 @@ function updateProfiler(current$$1, workInProgress, renderExpirationTime) { return workInProgress.child; } -function markRef(current$$1, workInProgress) { +function markRef(current, workInProgress) { var ref = workInProgress.ref; if ( - (current$$1 === null && ref !== null) || - (current$$1 !== null && current$$1.ref !== ref) + (current === null && ref !== null) || + (current !== null && current.ref !== ref) ) { // Schedule a Ref effect workInProgress.effectTag |= Ref; @@ -13348,7 +12297,7 @@ function markRef(current$$1, workInProgress) { } function updateFunctionComponent( - current$$1, + current, workInProgress, Component, nextProps, @@ -13365,8 +12314,7 @@ function updateFunctionComponent( innerPropTypes, nextProps, // Resolved props "prop", - getComponentName(Component), - getCurrentFiberStackInDev + getComponentName(Component) ); } } @@ -13374,7 +12322,7 @@ function updateFunctionComponent( var context; - if (!disableLegacyContext) { + { var unmaskedContext = getUnmaskedContext(workInProgress, Component, true); context = getMaskedContext(workInProgress, unmaskedContext); } @@ -13383,10 +12331,10 @@ function updateFunctionComponent( prepareToReadContext(workInProgress, renderExpirationTime); { - ReactCurrentOwner$3.current = workInProgress; - setCurrentPhase("render"); + ReactCurrentOwner$1.current = workInProgress; + setIsRendering(true); nextChildren = renderWithHooks( - current$$1, + current, workInProgress, Component, nextProps, @@ -13394,14 +12342,11 @@ function updateFunctionComponent( renderExpirationTime ); - if ( - debugRenderPhaseSideEffectsForStrictMode && - workInProgress.mode & StrictMode - ) { + if (workInProgress.mode & StrictMode) { // Only double-render components with Hooks if (workInProgress.memoizedState !== null) { nextChildren = renderWithHooks( - current$$1, + current, workInProgress, Component, nextProps, @@ -13411,13 +12356,13 @@ function updateFunctionComponent( } } - setCurrentPhase(null); + setIsRendering(false); } - if (current$$1 !== null && !didReceiveUpdate) { - bailoutHooks(current$$1, workInProgress, renderExpirationTime); + if (current !== null && !didReceiveUpdate) { + bailoutHooks(current, workInProgress, renderExpirationTime); return bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ); @@ -13425,7 +12370,7 @@ function updateFunctionComponent( workInProgress.effectTag |= PerformedWork; reconcileChildren( - current$$1, + current, workInProgress, nextChildren, renderExpirationTime @@ -13434,7 +12379,7 @@ function updateFunctionComponent( } function updateClassComponent( - current$$1, + current, workInProgress, Component, nextProps, @@ -13451,8 +12396,7 @@ function updateClassComponent( innerPropTypes, nextProps, // Resolved props "prop", - getComponentName(Component), - getCurrentFiberStackInDev + getComponentName(Component) ); } } @@ -13474,23 +12418,18 @@ function updateClassComponent( 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 + 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$$1.alternate = null; + 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, - renderExpirationTime - ); + constructClassInstance(workInProgress, Component, nextProps); mountClassInstance( workInProgress, Component, @@ -13498,7 +12437,7 @@ function updateClassComponent( renderExpirationTime ); shouldUpdate = true; - } else if (current$$1 === null) { + } else if (current === null) { // In a resume, we'll already have an instance we can reuse. shouldUpdate = resumeMountClassInstance( workInProgress, @@ -13508,7 +12447,7 @@ function updateClassComponent( ); } else { shouldUpdate = updateClassInstance( - current$$1, + current, workInProgress, Component, nextProps, @@ -13517,7 +12456,7 @@ function updateClassComponent( } var nextUnitOfWork = finishClassComponent( - current$$1, + current, workInProgress, Component, shouldUpdate, @@ -13529,14 +12468,14 @@ function updateClassComponent( 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; + 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; } } @@ -13545,7 +12484,7 @@ function updateClassComponent( } function finishClassComponent( - current$$1, + current, workInProgress, Component, shouldUpdate, @@ -13553,7 +12492,7 @@ function finishClassComponent( renderExpirationTime ) { // Refs should update even if shouldComponentUpdate returns false - markRef(current$$1, workInProgress); + markRef(current, workInProgress); var didCaptureError = (workInProgress.effectTag & DidCapture) !== NoEffect; if (!shouldUpdate && !didCaptureError) { @@ -13563,7 +12502,7 @@ function finishClassComponent( } return bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ); @@ -13571,55 +12510,52 @@ function finishClassComponent( var instance = workInProgress.stateNode; // Rerender - ReactCurrentOwner$3.current = workInProgress; + ReactCurrentOwner$1.current = workInProgress; var nextChildren; if ( didCaptureError && typeof Component.getDerivedStateFromError !== "function" ) { - // If we captured an error, but getDerivedStateFrom catch is not defined, + // If we captured an error, but getDerivedStateFromError is not defined, // unmount all the children. componentDidCatch will schedule an update to // re-render a fallback. This is temporary until we migrate everyone to // the new API. // TODO: Warn in a future release. nextChildren = null; - if (enableProfilerTimer) { - stopProfilerTimerIfRunning(workInProgress); + { + stopProfilerTimerIfRunning(); } } else { { - setCurrentPhase("render"); + setIsRendering(true); nextChildren = instance.render(); - if ( - debugRenderPhaseSideEffectsForStrictMode && - workInProgress.mode & StrictMode - ) { + if (workInProgress.mode & StrictMode) { instance.render(); } - setCurrentPhase(null); + setIsRendering(false); } } // React DevTools reads this flag. workInProgress.effectTag |= PerformedWork; - if (current$$1 !== null && didCaptureError) { + 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$$1, + current, workInProgress, nextChildren, renderExpirationTime ); } else { reconcileChildren( - current$$1, + current, workInProgress, nextChildren, renderExpirationTime @@ -13653,11 +12589,11 @@ function pushHostRootContext(workInProgress) { pushHostContainer(workInProgress, root.containerInfo); } -function updateHostRoot(current$$1, workInProgress, renderExpirationTime) { +function updateHostRoot(current, workInProgress, renderExpirationTime) { pushHostRootContext(workInProgress); var updateQueue = workInProgress.updateQueue; - if (!(updateQueue !== null)) { + 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." ); @@ -13666,24 +12602,16 @@ function updateHostRoot(current$$1, workInProgress, renderExpirationTime) { var nextProps = workInProgress.pendingProps; var prevState = workInProgress.memoizedState; var prevChildren = prevState !== null ? prevState.element : null; - processUpdateQueue( - workInProgress, - updateQueue, - nextProps, - null, - renderExpirationTime - ); + cloneUpdateQueue(current, workInProgress); + processUpdateQueue(workInProgress, 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, + current, workInProgress, renderExpirationTime ); @@ -13691,7 +12619,7 @@ function updateHostRoot(current$$1, workInProgress, renderExpirationTime) { var root = workInProgress.stateNode; - if (root.hydrate && enterHydrationState(workInProgress)) { + 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 @@ -13719,50 +12647,38 @@ function updateHostRoot(current$$1, workInProgress, renderExpirationTime) { // Otherwise reset hydration state in case we aborted and resumed another // root. reconcileChildren( - current$$1, + current, workInProgress, nextChildren, renderExpirationTime ); - resetHydrationState(); } return workInProgress.child; } -function updateHostComponent(current$$1, workInProgress, renderExpirationTime) { +function updateHostComponent(current, workInProgress, renderExpirationTime) { pushHostContext(workInProgress); - if (current$$1 === null) { - tryToClaimNextHydratableInstance(workInProgress); - } - var type = workInProgress.type; var nextProps = workInProgress.pendingProps; - var prevProps = current$$1 !== null ? current$$1.memoizedProps : null; + var prevProps = current !== null ? current.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 (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$$1, workInProgress); // Check the host config to see if the children are offscreen/hidden. + markRef(current, workInProgress); // Check the host config to see if the children are offscreen/hidden. if ( workInProgress.mode & ConcurrentMode && renderExpirationTime !== Never && - shouldDeprioritizeSubtree(type, nextProps) + shouldDeprioritizeSubtree() ) { - if (enableSchedulerTracing) { + { markSpawnedWork(Never); } // Schedule this fiber to re-render at offscreen priority. Then bailout. @@ -13771,7 +12687,7 @@ function updateHostComponent(current$$1, workInProgress, renderExpirationTime) { } reconcileChildren( - current$$1, + current, workInProgress, nextChildren, renderExpirationTime @@ -13779,10 +12695,7 @@ function updateHostComponent(current$$1, workInProgress, renderExpirationTime) { return workInProgress.child; } -function updateHostText(current$$1, workInProgress) { - if (current$$1 === null) { - tryToClaimNextHydratableInstance(workInProgress); - } // Nothing to do here. This is terminal. We'll do the completion step +function updateHostText(current, workInProgress) { // immediately after. return null; @@ -13796,7 +12709,7 @@ function mountLazyComponent( renderExpirationTime ) { if (_current !== null) { - // An lazy component only mounts if it suspended inside a non- + // 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. @@ -13834,7 +12747,7 @@ function mountLazyComponent( resolvedProps, renderExpirationTime ); - break; + return child; } case ClassComponent: { @@ -13851,7 +12764,7 @@ function mountLazyComponent( resolvedProps, renderExpirationTime ); - break; + return child; } case ForwardRef: { @@ -13868,7 +12781,7 @@ function mountLazyComponent( resolvedProps, renderExpirationTime ); - break; + return child; } case MemoComponent: { @@ -13881,8 +12794,7 @@ function mountLazyComponent( outerPropTypes, resolvedProps, // Resolved for outer only "prop", - getComponentName(Component), - getCurrentFiberStackInDev + getComponentName(Component) ); } } @@ -13896,36 +12808,32 @@ function mountLazyComponent( updateExpirationTime, renderExpirationTime ); - break; + return child; } + } - 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. + var 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 - ); - } + { + 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. - return 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 + ); + } } function mountIncompleteClassComponent( @@ -13961,12 +12869,7 @@ function mountIncompleteClassComponent( } prepareToReadContext(workInProgress, renderExpirationTime); - constructClassInstance( - workInProgress, - Component, - nextProps, - renderExpirationTime - ); + constructClassInstance(workInProgress, Component, nextProps); mountClassInstance( workInProgress, Component, @@ -14003,7 +12906,7 @@ function mountIndeterminateComponent( var props = workInProgress.pendingProps; var context; - if (!disableLegacyContext) { + { var unmaskedContext = getUnmaskedContext(workInProgress, Component, false); context = getMaskedContext(workInProgress, unmaskedContext); } @@ -14019,13 +12922,13 @@ function mountIndeterminateComponent( var componentName = getComponentName(Component) || "Unknown"; if (!didWarnAboutBadClass[componentName]) { - warningWithoutStack$1( - false, + error( "The <%s /> component appears to have a render method, but doesn't extend React.Component. " + "This is likely to cause errors. Change %s to extend React.Component instead.", componentName, componentName ); + didWarnAboutBadClass[componentName] = true; } } @@ -14034,7 +12937,7 @@ function mountIndeterminateComponent( ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null); } - ReactCurrentOwner$3.current = workInProgress; + ReactCurrentOwner$1.current = workInProgress; value = renderWithHooks( null, workInProgress, @@ -14057,8 +12960,7 @@ function mountIndeterminateComponent( var _componentName = getComponentName(Component) || "Unknown"; if (!didWarnAboutModulePatternComponent[_componentName]) { - warningWithoutStack$1( - false, + 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. " + @@ -14068,13 +12970,15 @@ 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. - resetHooks(); // Push context providers early to prevent context stack mismatches. + 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. @@ -14089,6 +12993,7 @@ function mountIndeterminateComponent( workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null; + initializeUpdateQueue(workInProgress); var getDerivedStateFromProps = Component.getDerivedStateFromProps; if (typeof getDerivedStateFromProps === "function") { @@ -14115,19 +13020,7 @@ function mountIndeterminateComponent( 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 - ) { + if (workInProgress.mode & StrictMode) { // Only double-render components with Hooks if (workInProgress.memoizedState !== null) { value = renderWithHooks( @@ -14153,86 +13046,70 @@ function mountIndeterminateComponent( } function validateFunctionComponentInDev(workInProgress, Component) { - if (Component) { - !!Component.childContextTypes - ? warningWithoutStack$1( - false, + { + if (Component) { + if (Component.childContextTypes) { + error( "%s(...): childContextTypes cannot be defined on a function component.", Component.displayName || Component.name || "Component" - ) - : void 0; - } + ); + } + } - if (workInProgress.ref !== null) { - var info = ""; - var ownerName = getCurrentFiberOwnerNameInDevOrNull(); + if (workInProgress.ref !== null) { + var info = ""; + var ownerName = getCurrentFiberOwnerNameInDevOrNull(); - if (ownerName) { - info += "\n\nCheck the render method of `" + ownerName + "`."; - } + if (ownerName) { + info += "\n\nCheck the render method of `" + ownerName + "`."; + } - var warningKey = ownerName || workInProgress._debugID || ""; - var debugSource = workInProgress._debugSource; + var warningKey = ownerName || workInProgress._debugID || ""; + var debugSource = workInProgress._debugSource; - if (debugSource) { - warningKey = debugSource.fileName + ":" + debugSource.lineNumber; - } + if (debugSource) { + warningKey = debugSource.fileName + ":" + debugSource.lineNumber; + } - 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 (!didWarnAboutFunctionRefs[warningKey]) { + didWarnAboutFunctionRefs[warningKey] = true; - 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; + error( + "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 (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 (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2]) { + error( + "%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 ( + 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; + if (!didWarnAboutContextTypeOnFunctionComponent[_componentName3]) { + error( + "%s: Function components do not support contextType.", + _componentName3 + ); + + didWarnAboutContextTypeOnFunctionComponent[_componentName3] = true; + } } } } @@ -14242,17 +13119,17 @@ var SUSPENDED_MARKER = { retryTime: NoWork }; -function shouldRemainOnFallback(suspenseContext, current$$1, workInProgress) { +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$$1 === null || current$$1.memoizedState !== null) + (current === null || current.memoizedState !== null) ); } function updateSuspenseComponent( - current$$1, + current, workInProgress, renderExpirationTime ) { @@ -14269,17 +13146,14 @@ function updateSuspenseComponent( var nextDidTimeout = false; var didSuspend = (workInProgress.effectTag & DidCapture) !== NoEffect; - if ( - didSuspend || - shouldRemainOnFallback(suspenseContext, current$$1, workInProgress) - ) { + 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$$1 === null || current$$1.memoizedState !== null) { + 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. @@ -14298,20 +13172,7 @@ function updateSuspenseComponent( } suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); - 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 + 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. @@ -14333,28 +13194,10 @@ 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$$1 === null) { + if (current === 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 + 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) { @@ -14412,107 +13255,12 @@ 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$$1.memoizedState; + var prevState = current.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 currentPrimaryChildFragment = current.child; var currentFallbackChildFragment = currentPrimaryChildFragment.sibling; if (nextDidTimeout) { @@ -14522,8 +13270,7 @@ function updateSuspenseComponent( var _primaryChildFragment2 = createWorkInProgress( currentPrimaryChildFragment, - currentPrimaryChildFragment.pendingProps, - NoWork + currentPrimaryChildFragment.pendingProps ); _primaryChildFragment2.return = workInProgress; @@ -14550,7 +13297,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 (enableProfilerTimer && workInProgress.mode & ProfileMode) { + if (workInProgress.mode & ProfileMode) { // treeBaseDuration is the sum of all the child tree base durations. var _treeBaseDuration = 0; var _hiddenChild = _primaryChildFragment2.child; @@ -14566,8 +13313,7 @@ function updateSuspenseComponent( var _fallbackChildFragment2 = createWorkInProgress( currentFallbackChildFragment, - _nextFallbackChildren2, - currentFallbackChildFragment.expirationTime + _nextFallbackChildren2 ); _fallbackChildFragment2.return = workInProgress; @@ -14601,7 +13347,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$$1.child; + var _currentPrimaryChild = current.child; if (nextDidTimeout) { // Timed out. Wrap the children in a fragment fiber to keep them @@ -14647,7 +13393,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 (enableProfilerTimer && workInProgress.mode & ProfileMode) { + if (workInProgress.mode & ProfileMode) { // treeBaseDuration is the sum of all the child tree base durations. var _treeBaseDuration2 = 0; var _hiddenChild2 = _primaryChildFragment3.child; @@ -14677,7 +13423,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; @@ -14692,197 +13438,6 @@ 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; @@ -14984,40 +13539,39 @@ function validateRevealOrder(revealOrder) { case "together": case "forwards": case "backwards": { - warning$1( - false, + error( '"%s" is not a valid value for revealOrder on . ' + 'Use lowercase "%s" instead.', revealOrder, revealOrder.toLowerCase() ); + break; } case "forward": case "backward": { - warning$1( - false, + 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; } default: - warning$1( - false, + error( '"%s" is not a supported revealOrder on . ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder ); + break; } } else { - warning$1( - false, + error( "%s is not a supported value for revealOrder on . " + 'Did you mean "together", "forwards" or "backwards"?', revealOrder @@ -15032,16 +13586,16 @@ function validateTailOptions(tailMode, revealOrder) { if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) { if (tailMode !== "collapsed" && tailMode !== "hidden") { didWarnAboutTailOptions[tailMode] = true; - warning$1( - false, + + 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; - warning$1( - false, + + error( ' is only valid if revealOrder is ' + '"forwards" or "backwards". ' + 'Did you mean to specify revealOrder="forwards"?', @@ -15059,8 +13613,8 @@ function validateSuspenseListNestedChild(childSlot, index) { if (isArray || isIterable) { var type = isArray ? "array" : "iterable"; - warning$1( - false, + + error( "A nested %s was passed to row #%s in . Wrap it in " + "an additional SuspenseList to configure its revealOrder: " + " ... " + @@ -15070,6 +13624,7 @@ function validateSuspenseListNestedChild(childSlot, index) { index, type ); + return false; } } @@ -15110,8 +13665,7 @@ function validateSuspenseListChildren(children, revealOrder) { } } } else { - warning$1( - false, + 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?", @@ -15137,6 +13691,7 @@ function initSuspenseListRenderState( workInProgress.memoizedState = { isBackwards: isBackwards, rendering: null, + renderingStartTime: 0, last: lastContentRow, tail: tail, tailExpiration: 0, @@ -15147,6 +13702,7 @@ 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; @@ -15162,7 +13718,7 @@ function initSuspenseListRenderState( // That happens in the completeWork phase without going back to beginWork. function updateSuspenseListComponent( - current$$1, + current, workInProgress, renderExpirationTime ) { @@ -15173,12 +13729,7 @@ function updateSuspenseListComponent( validateRevealOrder(revealOrder); validateTailOptions(tailMode, revealOrder); validateSuspenseListChildren(newChildren, revealOrder); - reconcileChildren( - current$$1, - workInProgress, - newChildren, - renderExpirationTime - ); + reconcileChildren(current, workInProgress, newChildren, renderExpirationTime); var suspenseContext = suspenseStackCursor.current; var shouldForceFallback = hasSuspenseContext( suspenseContext, @@ -15193,7 +13744,7 @@ function updateSuspenseListComponent( workInProgress.effectTag |= DidCapture; } else { var didSuspendBefore = - current$$1 !== null && (current$$1.effectTag & DidCapture) !== NoEffect; + current !== null && (current.effectTag & DidCapture) !== NoEffect; if (didSuspendBefore) { // If we previously forced a fallback, we need to schedule work @@ -15302,15 +13853,11 @@ function updateSuspenseListComponent( return workInProgress.child; } -function updatePortalComponent( - current$$1, - workInProgress, - renderExpirationTime -) { +function updatePortalComponent(current, workInProgress, renderExpirationTime) { pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); var nextChildren = workInProgress.pendingProps; - if (current$$1 === null) { + if (current === null) { // Portals are special because we don't append the children during mount // but at commit. Therefore we need to track insertions which the normal // flow doesn't do during mount. This doesn't happen at the root because @@ -15324,7 +13871,7 @@ function updatePortalComponent( ); } else { reconcileChildren( - current$$1, + current, workInProgress, nextChildren, renderExpirationTime @@ -15334,11 +13881,7 @@ function updatePortalComponent( return workInProgress.child; } -function updateContextProvider( - current$$1, - workInProgress, - renderExpirationTime -) { +function updateContextProvider(current, workInProgress, renderExpirationTime) { var providerType = workInProgress.type; var context = providerType._context; var newProps = workInProgress.pendingProps; @@ -15349,13 +13892,7 @@ function updateContextProvider( var providerPropTypes = workInProgress.type.propTypes; if (providerPropTypes) { - checkPropTypes( - providerPropTypes, - newProps, - "prop", - "Context.Provider", - getCurrentFiberStackInDev - ); + checkPropTypes(providerPropTypes, newProps, "prop", "Context.Provider"); } } @@ -15369,7 +13906,7 @@ function updateContextProvider( // No change. Bailout early if children are the same. if (oldProps.children === newProps.children && !hasContextChanged()) { return bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ); @@ -15387,22 +13924,13 @@ function updateContextProvider( } var newChildren = newProps.children; - reconcileChildren( - current$$1, - workInProgress, - newChildren, - renderExpirationTime - ); + reconcileChildren(current, workInProgress, newChildren, renderExpirationTime); return workInProgress.child; } var hasWarnedAboutUsingContextAsConsumer = false; -function updateContextConsumer( - current$$1, - workInProgress, - renderExpirationTime -) { +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 @@ -15419,8 +13947,8 @@ function updateContextConsumer( if (context !== context.Consumer) { if (!hasWarnedAboutUsingContextAsConsumer) { hasWarnedAboutUsingContextAsConsumer = true; - warning$1( - false, + + error( "Rendering directly is not supported and will be removed in " + "a future major release. Did you mean to render instead?" ); @@ -15435,15 +13963,14 @@ function updateContextConsumer( var render = newProps.children; { - !(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; + if (typeof render !== "function") { + error( + "A context consumer was rendered with multiple children, or a child " + + "that isn't a function. A context consumer expects a single child " + + "that is a function. If you did pass a function, make sure there " + + "is no trailing or leading whitespace around it." + ); + } } prepareToReadContext(workInProgress, renderExpirationTime); @@ -15451,57 +13978,14 @@ function updateContextConsumer( var newChildren; { - ReactCurrentOwner$3.current = workInProgress; - setCurrentPhase("render"); + ReactCurrentOwner$1.current = workInProgress; + setIsRendering(true); newChildren = render(newValue); - setCurrentPhase(null); + setIsRendering(false); } // React DevTools reads this flag. workInProgress.effectTag |= PerformedWork; - 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 - ); + reconcileChildren(current, workInProgress, newChildren, renderExpirationTime); return workInProgress.child; } @@ -15510,20 +13994,20 @@ function markWorkInProgressReceivedUpdate() { } function bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ) { cancelWorkTimer(workInProgress); - if (current$$1 !== null) { + if (current !== null) { // Reuse previous dependencies - workInProgress.dependencies = current$$1.dependencies; + workInProgress.dependencies = current.dependencies; } - if (enableProfilerTimer) { + { // Don't update "base" render times for bailouts. - stopProfilerTimerIfRunning(workInProgress); + stopProfilerTimerIfRunning(); } var updateExpirationTime = workInProgress.expirationTime; @@ -15542,12 +14026,12 @@ function bailoutOnAlreadyFinishedWork( } else { // This fiber doesn't have work, but its subtree does. Clone the child // fibers and continue. - cloneChildFibers(current$$1, workInProgress); + cloneChildFibers(current, workInProgress); return workInProgress.child; } } -function remountFiber(current$$1, oldWorkInProgress, newWorkInProgress) { +function remountFiber(current, oldWorkInProgress, newWorkInProgress) { { var returnFiber = oldWorkInProgress.return; @@ -15556,7 +14040,7 @@ function remountFiber(current$$1, oldWorkInProgress, newWorkInProgress) { } // Disconnect from the old current. // It will get deleted. - current$$1.alternate = null; + current.alternate = null; oldWorkInProgress.alternate = null; // Connect to the new tree. newWorkInProgress.index = oldWorkInProgress.index; @@ -15588,28 +14072,28 @@ function remountFiber(current$$1, oldWorkInProgress, newWorkInProgress) { var last = returnFiber.lastEffect; if (last !== null) { - last.nextEffect = current$$1; - returnFiber.lastEffect = current$$1; + last.nextEffect = current; + returnFiber.lastEffect = current; } else { - returnFiber.firstEffect = returnFiber.lastEffect = current$$1; + returnFiber.firstEffect = returnFiber.lastEffect = current; } - current$$1.nextEffect = null; - current$$1.effectTag = Deletion; + current.nextEffect = null; + current.effectTag = Deletion; newWorkInProgress.effectTag |= Placement; // Restart work from the new fiber. return newWorkInProgress; } } -function beginWork$1(current$$1, workInProgress, renderExpirationTime) { +function beginWork(current, workInProgress, renderExpirationTime) { var updateExpirationTime = workInProgress.expirationTime; { - if (workInProgress._debugNeedsRemount && current$$1 !== null) { + if (workInProgress._debugNeedsRemount && current !== null) { // This will restart the begin phase with a new fiber. return remountFiber( - current$$1, + current, workInProgress, createFiberFromTypeAndProps( workInProgress.type, @@ -15623,14 +14107,14 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { } } - if (current$$1 !== null) { - var oldProps = current$$1.memoizedProps; + if (current !== null) { + var oldProps = current.memoizedProps; var newProps = workInProgress.pendingProps; if ( oldProps !== newProps || hasContextChanged() || // Force a re-render if the implementation changed due to hot reload: - workInProgress.type !== current$$1.type + 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). @@ -15643,7 +14127,6 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { switch (workInProgress.tag) { case HostRoot: pushHostRootContext(workInProgress); - resetHydrationState(); break; case HostComponent: @@ -15652,9 +14135,9 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { if ( workInProgress.mode & ConcurrentMode && renderExpirationTime !== Never && - shouldDeprioritizeSubtree(workInProgress.type, newProps) + shouldDeprioritizeSubtree(workInProgress.type) ) { - if (enableSchedulerTracing) { + { markSpawnedWork(Never); } // Schedule this fiber to re-render at offscreen priority. Then bailout. @@ -15688,14 +14171,19 @@ function beginWork$1(current$$1, 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; @@ -15704,19 +14192,6 @@ function beginWork$1(current$$1, 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. @@ -15732,7 +14207,7 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { // The primary children have pending work. Use the normal path // to attempt to render the primary children again. return updateSuspenseComponent( - current$$1, + current, workInProgress, renderExpirationTime ); @@ -15744,7 +14219,7 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { // priority. Bailout. var child = bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ); @@ -15768,8 +14243,7 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { } case SuspenseListComponent: { - var didSuspendBefore = - (current$$1.effectTag & DidCapture) !== NoEffect; + var didSuspendBefore = (current.effectTag & DidCapture) !== NoEffect; var _hasChildWork = workInProgress.childExpirationTime >= renderExpirationTime; @@ -15782,7 +14256,7 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { // tree which will affect the tail. So we need to use the normal // path to compute the correct tail. return updateSuspenseListComponent( - current$$1, + current, workInProgress, renderExpirationTime ); @@ -15818,7 +14292,7 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { } return bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ); @@ -15831,14 +14305,18 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { } } else { didReceiveUpdate = false; - } // Before entering the begin phase, clear the expiration time. + } // Before entering the begin phase, clear pending update priority. + // TODO: This assumes that we're about to evaluate the component and process + // the update queue. However, there's an exception: SimpleMemoComponent + // sometimes bails out later in the begin phase. This indicates that we should + // move this assignment out of the common path and into each branch. workInProgress.expirationTime = NoWork; switch (workInProgress.tag) { case IndeterminateComponent: { return mountIndeterminateComponent( - current$$1, + current, workInProgress, workInProgress.type, renderExpirationTime @@ -15848,7 +14326,7 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { case LazyComponent: { var elementType = workInProgress.elementType; return mountLazyComponent( - current$$1, + current, workInProgress, elementType, updateExpirationTime, @@ -15864,7 +14342,7 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { ? unresolvedProps : resolveDefaultProps(_Component, unresolvedProps); return updateFunctionComponent( - current$$1, + current, workInProgress, _Component, resolvedProps, @@ -15882,7 +14360,7 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { : resolveDefaultProps(_Component2, _unresolvedProps); return updateClassComponent( - current$$1, + current, workInProgress, _Component2, _resolvedProps, @@ -15891,28 +14369,24 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { } case HostRoot: - return updateHostRoot(current$$1, workInProgress, renderExpirationTime); + return updateHostRoot(current, workInProgress, renderExpirationTime); case HostComponent: - return updateHostComponent( - current$$1, - workInProgress, - renderExpirationTime - ); + return updateHostComponent(current, workInProgress, renderExpirationTime); case HostText: - return updateHostText(current$$1, workInProgress); + return updateHostText(); case SuspenseComponent: return updateSuspenseComponent( - current$$1, + current, workInProgress, renderExpirationTime ); case HostPortal: return updatePortalComponent( - current$$1, + current, workInProgress, renderExpirationTime ); @@ -15927,7 +14401,7 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { : resolveDefaultProps(type, _unresolvedProps2); return updateForwardRef( - current$$1, + current, workInProgress, type, _resolvedProps2, @@ -15936,24 +14410,24 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { } case Fragment: - return updateFragment(current$$1, workInProgress, renderExpirationTime); + return updateFragment(current, workInProgress, renderExpirationTime); case Mode: - return updateMode(current$$1, workInProgress, renderExpirationTime); + return updateMode(current, workInProgress, renderExpirationTime); case Profiler: - return updateProfiler(current$$1, workInProgress, renderExpirationTime); + return updateProfiler(current, workInProgress, renderExpirationTime); case ContextProvider: return updateContextProvider( - current$$1, + current, workInProgress, renderExpirationTime ); case ContextConsumer: return updateContextConsumer( - current$$1, + current, workInProgress, renderExpirationTime ); @@ -15973,325 +14447,68 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { outerPropTypes, _resolvedProps3, // Resolved for outer only "prop", - getComponentName(_type2), - getCurrentFiberStackInDev + getComponentName(_type2) ); - } - } - } - - _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 - ); - } - - 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; + _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3); + return updateMemoComponent( + current, + workInProgress, + _type2, + _resolvedProps3, + updateExpirationTime, + renderExpirationTime + ); + } - if (child !== null) { - return collectFirstScopedNodeFromChildren(child, fn); - } + case SimpleMemoComponent: { + return updateSimpleMemoComponent( + current, + workInProgress, + workInProgress.type, + workInProgress.pendingProps, + updateExpirationTime, + renderExpirationTime + ); + } - return null; - }, - containsNode: function(node) { - var fiber = getInstanceFromNode$1(node); + case IncompleteClassComponent: { + var _Component3 = workInProgress.type; + var _unresolvedProps4 = workInProgress.pendingProps; - while (fiber !== null) { - if ( - fiber.tag === ScopeComponent && - fiber.type === scope && - fiber.stateNode === instance - ) { - return true; - } + var _resolvedProps4 = + workInProgress.elementType === _Component3 + ? _unresolvedProps4 + : resolveDefaultProps(_Component3, _unresolvedProps4); - fiber = fiber.return; - } + return mountIncompleteClassComponent( + current, + workInProgress, + _Component3, + _resolvedProps4, + renderExpirationTime + ); + } - return false; + case SuspenseListComponent: { + return updateSuspenseListComponent( + current, + workInProgress, + renderExpirationTime + ); } - }; + } + + { + 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) { @@ -16309,7 +14526,7 @@ var updateHostContainer; var updateHostComponent$1; var updateHostText$1; -if (supportsMutation) { +{ // Mutation mode appendAllChildren = function( parent, @@ -16324,13 +14541,8 @@ if (supportsMutation) { 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) { + } else if (node.tag === HostPortal); + else if (node.child !== null) { node.child.return = node; node = node.child; continue; @@ -16382,379 +14594,21 @@ if (supportsMutation) { // component is hitting the resume path. Figure out why. Possibly // related to `hidden`. - 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. - - 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); - } - - 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 - }; + var updatePayload = prepareUpdate(); // TODO: Type this specific to this type of component. - updateHostComponent$1 = function( - current, - workInProgress, - type, - newProps, - rootContainerInstance - ) { - // Noop + 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 (updatePayload) { + markUpdate(workInProgress); + } }; updateHostText$1 = function(current, workInProgress, oldText, newText) { - // Noop + // If the text differs, mark it as an update. All the work in done in commitWork. + if (oldText !== newText) { + markUpdate(workInProgress); + } }; } @@ -16833,14 +14687,16 @@ function completeWork(current, workInProgress, renderExpirationTime) { switch (workInProgress.tag) { case IndeterminateComponent: - break; - case LazyComponent: - break; - case SimpleMemoComponent: case FunctionComponent: - break; + case ForwardRef: + case Fragment: + case Mode: + case Profiler: + case ContextConsumer: + case MemoComponent: + return null; case ClassComponent: { var Component = workInProgress.type; @@ -16849,7 +14705,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { popContext(workInProgress); } - break; + return null; } case HostRoot: { @@ -16865,7 +14721,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(workInProgress); + var wasHydrated = popHydrationState(); if (wasHydrated) { // If we hydrated, then we'll need to schedule an update for @@ -16875,7 +14731,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { } updateHostContainer(workInProgress); - break; + return null; } case HostComponent: { @@ -16892,15 +14748,6 @@ 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); } @@ -16912,42 +14759,24 @@ function completeWork(current, workInProgress, renderExpirationTime) { ); } // This can happen when we abort work. - break; + return 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 + // or completeWork depending on whether we want to add them top->down or // bottom->up. Top->down is faster in IE11. - var _wasHydrated = popHydrationState(workInProgress); + var _wasHydrated = popHydrationState(); 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 + if (prepareToHydrateHostInstance()) { + // If changes to the hydrated node need 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, @@ -16959,30 +14788,10 @@ 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, - type, - newProps, - rootContainerInstance, - currentHostContext - ) - ) { + if (finalizeInitialChildren(instance)) { markUpdate(workInProgress); } } @@ -16993,7 +14802,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { } } - break; + return null; } case HostText: { @@ -17017,10 +14826,10 @@ function completeWork(current, workInProgress, renderExpirationTime) { var _currentHostContext = getHostContext(); - var _wasHydrated2 = popHydrationState(workInProgress); + var _wasHydrated2 = popHydrationState(); if (_wasHydrated2) { - if (prepareToHydrateHostTextInstance(workInProgress)) { + if (prepareToHydrateHostTextInstance()) { markUpdate(workInProgress); } } else { @@ -17033,56 +14842,13 @@ function completeWork(current, workInProgress, renderExpirationTime) { } } - break; + return null; } - 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. @@ -17094,9 +14860,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { var prevDidTimeout = false; if (current === null) { - if (workInProgress.memoizedProps.fallback !== undefined) { - popHydrationState(workInProgress); - } + if (workInProgress.memoizedProps.fallback !== undefined); } else { var prevState = current.memoizedState; prevDidTimeout = prevState !== null; @@ -17161,64 +14925,30 @@ 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 proimse. This flag is also used to hide the + // retry listener to the promise. This flag is also used to hide the // primary children. In mutation mode, we also need the flag to - // *unhide* children that were previously hidden, so check if the + // *unhide* children that were previously hidden, so check if this // is currently timed out, too. workInProgress.effectTag |= Update; } } - if ( - enableSuspenseCallback && - workInProgress.updateQueue !== null && - workInProgress.memoizedProps.suspenseCallback != null - ) { - // Always notify the callback - workInProgress.effectTag |= Update; - } - - break; + return null; } - case Fragment: - break; - - case Mode: - break; - - case Profiler: - break; - case HostPortal: popHostContainer(workInProgress); updateHostContainer(workInProgress); - break; + return null; case ContextProvider: // Pop provider fiber popProvider(workInProgress); - break; - - case ContextConsumer: - break; - - case MemoComponent: - break; + return null; case IncompleteClassComponent: { // Same as class component case. I put it down here so that the tags are @@ -17229,7 +14959,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { popContext(workInProgress); } - break; + return null; } case SuspenseListComponent: { @@ -17237,9 +14967,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. - break; + // We're running in the default, "independent" mode. + // We don't do anything in this mode. + return null; } var didSuspendAlready = @@ -17355,7 +15085,10 @@ function completeWork(current, workInProgress, renderExpirationTime) { return null; } } else if ( - now() > renderState.tailExpiration && + // 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 @@ -17372,7 +15105,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { var nextPriority = renderExpirationTime - 1; workInProgress.expirationTime = workInProgress.childExpirationTime = nextPriority; - if (enableSchedulerTracing) { + { markSpawnedWork(nextPriority); } } @@ -17405,13 +15138,19 @@ 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; + 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 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. @@ -17432,131 +15171,17 @@ function completeWork(current, workInProgress, renderExpirationTime) { return next; } - break; - } - - 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; } } - return 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, renderExpirationTime) { @@ -17602,20 +15227,6 @@ 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) { @@ -17685,9 +15296,6 @@ function unwindInterruptedWork(interruptedWork) { case ContextProvider: popProvider(interruptedWork); break; - - default: - break; } } @@ -17702,6 +15310,7 @@ function createCapturedValue(value, source) { } // Module provided by RN: + if ( !( typeof ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog === @@ -17749,7 +15358,8 @@ 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); // For a more detailed description of this block, see: + 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 } @@ -17786,7 +15396,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); + console["error"](combinedMessage); // Don't transform to our wrapper } } @@ -17835,33 +15445,37 @@ function logError(boundary, errorInfo) { } } -var callComponentWillUnmountWithTimer = function(current$$1, instance) { - startPhaseTimer(current$$1, "componentWillUnmount"); - instance.props = current$$1.memoizedProps; - instance.state = current$$1.memoizedState; - instance.componentWillUnmount(); +var callComponentWillUnmountWithTimer = function(current, instance) { + startPhaseTimer(current, "componentWillUnmount"); + instance.props = current.memoizedProps; + instance.state = current.memoizedState; + + { + instance.componentWillUnmount(); + } + stopPhaseTimer(); }; // Capture errors so they don't interrupt unmounting. -function safelyCallComponentWillUnmount(current$$1, instance) { +function safelyCallComponentWillUnmount(current, instance) { { invokeGuardedCallback( null, callComponentWillUnmountWithTimer, null, - current$$1, + current, instance ); if (hasCaughtError()) { var unmountError = clearCaughtError(); - captureCommitPhaseError(current$$1, unmountError); + captureCommitPhaseError(current, unmountError); } } } -function safelyDetachRef(current$$1) { - var ref = current$$1.ref; +function safelyDetachRef(current) { + var ref = current.ref; if (ref !== null) { if (typeof ref === "function") { @@ -17870,7 +15484,7 @@ function safelyDetachRef(current$$1) { if (hasCaughtError()) { var refError = clearCaughtError(); - captureCommitPhaseError(current$$1, refError); + captureCommitPhaseError(current, refError); } } } else { @@ -17879,31 +15493,31 @@ function safelyDetachRef(current$$1) { } } -function safelyCallDestroy(current$$1, destroy) { +function safelyCallDestroy(current, destroy) { { invokeGuardedCallback(null, destroy, null); if (hasCaughtError()) { var error = clearCaughtError(); - captureCommitPhaseError(current$$1, error); + captureCommitPhaseError(current, error); } } } -function commitBeforeMutationLifeCycles(current$$1, finishedWork) { +function commitBeforeMutationLifeCycles(current, finishedWork) { switch (finishedWork.tag) { case FunctionComponent: case ForwardRef: - case SimpleMemoComponent: { - commitHookEffectList(UnmountSnapshot, NoEffect$1, finishedWork); + case SimpleMemoComponent: + case Block: { return; } case ClassComponent: { if (finishedWork.effectTag & Snapshot) { - if (current$$1 !== null) { - var prevProps = current$$1.memoizedProps; - var prevState = current$$1.memoizedState; + 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. @@ -17914,28 +15528,27 @@ function commitBeforeMutationLifeCycles(current$$1, finishedWork) { 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; + 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" + ); + } } } @@ -17951,8 +15564,8 @@ function commitBeforeMutationLifeCycles(current$$1, finishedWork) { if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) { didWarnSet.add(finishedWork.type); - warningWithoutStack$1( - false, + + error( "%s.getSnapshotBeforeUpdate(): A snapshot value (or null) " + "must be returned. You have returned undefined.", getComponentName(finishedWork.type) @@ -17975,18 +15588,16 @@ function commitBeforeMutationLifeCycles(current$$1, finishedWork) { case IncompleteClassComponent: // Nothing to do for these component types 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 commitHookEffectList(unmountTag, mountTag, finishedWork) { +function commitHookEffectListUnmount(tag, finishedWork) { var updateQueue = finishedWork.updateQueue; var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; @@ -17995,7 +15606,7 @@ function commitHookEffectList(unmountTag, mountTag, finishedWork) { var effect = firstEffect; do { - if ((effect.tag & unmountTag) !== NoEffect$1) { + if ((effect.tag & tag) === tag) { // Unmount var destroy = effect.destroy; effect.destroy = undefined; @@ -18005,22 +15616,36 @@ function commitHookEffectList(unmountTag, mountTag, finishedWork) { } } - if ((effect.tag & mountTag) !== NoEffect$1) { + 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) { // 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 " + @@ -18035,11 +15660,10 @@ function commitHookEffectList(unmountTag, mountTag, 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; } - warningWithoutStack$1( - false, + error( "An effect function must not return anything besides a function, " + "which is used for clean-up.%s%s", addendum, @@ -18059,37 +15683,49 @@ function commitPassiveHookEffects(finishedWork) { switch (finishedWork.tag) { case FunctionComponent: case ForwardRef: - case SimpleMemoComponent: { - commitHookEffectList(UnmountPassive, NoEffect$1, finishedWork); - commitHookEffectList(NoEffect$1, MountPassive, finishedWork); - break; - } + 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); + } - default: break; + } } } } function commitLifeCycles( finishedRoot, - current$$1, + current, finishedWork, committedExpirationTime ) { switch (finishedWork.tag) { case FunctionComponent: case ForwardRef: - case SimpleMemoComponent: { - commitHookEffectList(UnmountLayout, MountLayout, finishedWork); - break; + 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 ClassComponent: { var instance = finishedWork.stateNode; if (finishedWork.effectTag & Update) { - if (current$$1 === null) { + 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. @@ -18099,42 +15735,41 @@ function commitLifeCycles( 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; + if (instance.props !== finishedWork.memoizedProps) { + error( + "Expected %s props to match memoized props before " + + "componentDidMount. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } + + if (instance.state !== finishedWork.memoizedState) { + error( + "Expected %s state to match memoized state before " + + "componentDidMount. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.state`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } } } - instance.componentDidMount(); + { + instance.componentDidMount(); + } + stopPhaseTimer(); } else { var prevProps = finishedWork.elementType === finishedWork.type - ? current$$1.memoizedProps - : resolveDefaultProps( - finishedWork.type, - current$$1.memoizedProps - ); - var prevState = current$$1.memoizedState; + ? 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. @@ -18144,36 +15779,38 @@ function commitLifeCycles( 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; + if (instance.props !== finishedWork.memoizedProps) { + error( + "Expected %s props to match memoized props before " + + "componentDidUpdate. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } + + if (instance.state !== finishedWork.memoizedState) { + error( + "Expected %s state to match memoized state before " + + "componentDidUpdate. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.state`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } } } - instance.componentDidUpdate( - prevProps, - prevState, - instance.__reactInternalSnapshotBeforeUpdate - ); + { + instance.componentDidUpdate( + prevProps, + prevState, + instance.__reactInternalSnapshotBeforeUpdate + ); + } + stopPhaseTimer(); } } @@ -18186,39 +15823,33 @@ function commitLifeCycles( 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; + if (instance.props !== finishedWork.memoizedProps) { + error( + "Expected %s props to match memoized props before " + + "processing the update queue. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } + + if (instance.state !== finishedWork.memoizedState) { + error( + "Expected %s state to match memoized state before " + + "processing the update queue. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.state`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } } } // We could update instance props and state here, // but instead we rely on them being set during last render. // TODO: revisit this when we implement resuming. - commitUpdateQueue( - finishedWork, - updateQueue, - instance, - committedExpirationTime - ); + commitUpdateQueue(finishedWork, updateQueue, instance); } return; @@ -18242,12 +15873,7 @@ function commitLifeCycles( } } - commitUpdateQueue( - finishedWork, - _updateQueue, - _instance, - committedExpirationTime - ); + commitUpdateQueue(finishedWork, _updateQueue, _instance); } return; @@ -18259,7 +15885,7 @@ function commitLifeCycles( // These effects should only be committed when components are first mounted, // aka when there is no current/alternate. - if (current$$1 === null && finishedWork.effectTag & Update) { + if (current === null && finishedWork.effectTag & Update) { var type = finishedWork.type; var props = finishedWork.memoizedProps; } @@ -18278,29 +15904,24 @@ function commitLifeCycles( } case Profiler: { - if (enableProfilerTimer) { - var onRender = finishedWork.memoizedProps.onRender; + { + var _finishedWork$memoize2 = finishedWork.memoizedProps, + onCommit = _finishedWork$memoize2.onCommit, + onRender = _finishedWork$memoize2.onRender; + var effectDuration = finishedWork.stateNode.effectDuration; + var commitTime = getCommitTime(); if (typeof onRender === "function") { - if (enableSchedulerTracing) { + { onRender( finishedWork.memoizedProps.id, - current$$1 === null ? "mount" : "update", + current === null ? "mount" : "update", finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, - getCommitTime(), + commitTime, finishedRoot.memoizedInteractions ); - } else { - onRender( - finishedWork.memoizedProps.id, - current$$1 === null ? "mount" : "update", - finishedWork.actualDuration, - finishedWork.treeBaseDuration, - finishedWork.actualStartTime, - getCommitTime() - ); } } } @@ -18309,7 +15930,6 @@ function commitLifeCycles( } case SuspenseComponent: { - commitSuspenseHydrationCallbacks(finishedRoot, finishedWork); return; } @@ -18318,19 +15938,17 @@ function commitLifeCycles( case FundamentalComponent: case ScopeComponent: 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 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; @@ -18348,7 +15966,7 @@ function hideOrUnhideAllChildren(finishedWork, isHidden) { var _instance3 = node.stateNode; if (isHidden) { - hideTextInstance(_instance3); + hideTextInstance(); } else { unhideTextInstance(_instance3, node.memoizedProps); } @@ -18403,17 +16021,12 @@ 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")) { - warningWithoutStack$1( - false, + error( "Unexpected ref object provided for %s. " + "Use either a ref-setter function or React.createRef().%s", getComponentName(finishedWork.type), @@ -18427,8 +16040,8 @@ function commitAttachRef(finishedWork) { } } -function commitDetachRef(current$$1) { - var currentRef = current$$1.ref; +function commitDetachRef(current) { + var currentRef = current.ref; if (currentRef !== null) { if (typeof currentRef === "function") { @@ -18441,92 +16054,77 @@ function commitDetachRef(current$$1) { // deletion, so don't let them throw. Host-originating errors should // interrupt deletion, so it's okay -function commitUnmount(finishedRoot, current$$1, renderPriorityLevel) { - onCommitUnmount(current$$1); +function commitUnmount(finishedRoot, current, renderPriorityLevel) { + onCommitUnmount(current); - switch (current$$1.tag) { + switch (current.tag) { case FunctionComponent: case ForwardRef: case MemoComponent: - case SimpleMemoComponent: { - var updateQueue = current$$1.updateQueue; + case SimpleMemoComponent: + case Block: { + var updateQueue = current.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 destroy = effect.destroy; - - if (destroy !== undefined) { - safelyCallDestroy(current$$1, 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 _effect3 = effect, + _destroy = _effect3.destroy, + _tag = _effect3.tag; + + if (_destroy !== undefined) { + { + safelyCallDestroy(current, _destroy); + } + } - effect = effect.next; - } while (effect !== firstEffect); - }); + effect = effect.next; + } while (effect !== firstEffect); + }); + } } } - break; + return; } case ClassComponent: { - safelyDetachRef(current$$1); - var instance = current$$1.stateNode; + safelyDetachRef(current); + var instance = current.stateNode; if (typeof instance.componentWillUnmount === "function") { - safelyCallComponentWillUnmount(current$$1, instance); + safelyCallComponentWillUnmount(current, instance); } return; } case HostComponent: { - 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); + safelyDetachRef(current); return; } @@ -18534,48 +16132,23 @@ function commitUnmount(finishedRoot, current$$1, renderPriorityLevel) { // 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); + { + unmountHostComponents(finishedRoot, current, renderPriorityLevel); } 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: { - if (enableScopeAPI) { - safelyDetachRef(current$$1); - } + return; } } } @@ -18595,7 +16168,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. - (!supportsMutation || node.tag !== HostPortal) + node.tag !== HostPortal ) { node.child.return = node; node = node.child; @@ -18619,72 +16192,30 @@ function commitNestedUnmounts(finishedRoot, root, renderPriorityLevel) { } } -function detachFiber(current$$1) { - var alternate = current$$1.alternate; // Cut off the return pointers to disconnect it from the tree. Ideally, we +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. - 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; + 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; 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; @@ -18762,10 +16293,6 @@ 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; @@ -18789,10 +16316,6 @@ function commitPlacement(finishedWork) { break; case FundamentalComponent: - if (enableFundamentalAPI) { - parent = parentStateNode.instance; - isContainer = false; - } // eslint-disable-next-line-no-fallthrough @@ -18804,65 +16327,79 @@ 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. - var node = finishedWork; + if (isContainer) { + insertOrAppendPlacementNodeIntoContainer(finishedWork, before, parent); + } else { + insertOrAppendPlacementNode(finishedWork, before, parent); + } +} - while (true) { - var isHost = node.tag === HostComponent || node.tag === HostText; +function insertOrAppendPlacementNodeIntoContainer(node, before, parent) { + var tag = node.tag; + var isHost = tag === HostComponent || tag === HostText; - if (isHost || (enableFundamentalAPI && node.tag === FundamentalComponent)) { - var stateNode = isHost ? node.stateNode : node.stateNode.instance; + if (isHost || enableFundamentalAPI) { + 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; + if (before) { + insertInContainerBefore(parent); + } else { + appendChildToContainer(parent, stateNode); } + } else if (tag === HostPortal); + else { + var child = node.child; - if (node === finishedWork) { - return; - } + if (child !== null) { + insertOrAppendPlacementNodeIntoContainer(child, before, parent); + var sibling = child.sibling; - while (node.sibling === null) { - if (node.return === null || node.return === finishedWork) { - return; + while (sibling !== null) { + insertOrAppendPlacementNodeIntoContainer(sibling, before, parent); + sibling = sibling.sibling; } + } + } +} - node = node.return; +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); } + } else if (tag === HostPortal); + else { + var child = node.child; - node.sibling.return = node.return; - node = node.sibling; + if (child !== null) { + insertOrAppendPlacementNode(child, before, parent); + var sibling = child.sibling; + + while (sibling !== null) { + insertOrAppendPlacementNode(sibling, before, parent); + sibling = sibling.sibling; + } + } } } -function unmountHostComponents(finishedRoot, current$$1, renderPriorityLevel) { +function unmountHostComponents(finishedRoot, current, renderPriorityLevel) { // We only have the top Fiber that was deleted but we need to recurse down its // children to find all the terminal nodes. - var node = current$$1; // Each iteration, currentParent is populated with node's host parent if not + var node = current; // Each iteration, currentParent is populated with node's host parent if not // currentParentIsValid. var currentParentIsValid = false; // Note: these two variables *must* always be updated together. @@ -18898,12 +16435,6 @@ function unmountHostComponents(finishedRoot, current$$1, renderPriorityLevel) { currentParent = parentStateNode.containerInfo; currentParentIsContainer = true; break findParent; - - case FundamentalComponent: - if (enableFundamentalAPI) { - currentParent = parentStateNode.instance; - currentParentIsContainer = false; - } } parent = parent.return; @@ -18921,37 +16452,6 @@ function unmountHostComponents(finishedRoot, current$$1, 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. @@ -18973,12 +16473,12 @@ function unmountHostComponents(finishedRoot, current$$1, renderPriorityLevel) { } } - if (node === current$$1) { + if (node === current) { return; } while (node.sibling === null) { - if (node.return === null || node.return === current$$1) { + if (node.return === null || node.return === current) { return; } @@ -18996,74 +16496,32 @@ function unmountHostComponents(finishedRoot, current$$1, renderPriorityLevel) { } } -function commitDeletion(finishedRoot, current$$1, renderPriorityLevel) { - if (supportsMutation) { +function commitDeletion(finishedRoot, current, renderPriorityLevel) { + { // Recursively delete all host nodes from the parent. // Detach refs and call componentWillUnmount() on the whole subtree. - unmountHostComponents(finishedRoot, current$$1, renderPriorityLevel); - } else { - // Detach refs and call componentWillUnmount() on the whole subtree. - commitNestedUnmounts(finishedRoot, current$$1, renderPriorityLevel); + unmountHostComponents(finishedRoot, current, renderPriorityLevel); } - detachFiber(current$$1); + detachFiber(current); } -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; - } - +function commitWork(current, finishedWork) { 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); + 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); + } + return; } @@ -19080,31 +16538,14 @@ function commitWork(current$$1, finishedWork) { // as the newProps. The updatePayload will contain the real change in // this case. - var oldProps = - current$$1 !== null ? current$$1.memoizedProps : newProps; + var oldProps = current !== null ? current.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; - - if (prevListeners !== nextListeners) { - updateEventListeners(nextListeners, finishedWork, null); - } + commitUpdate(instance, updatePayload, type, oldProps, newProps); } } @@ -19123,22 +16564,12 @@ function commitWork(current$$1, finishedWork) { // as the newProps. The updatePayload will contain the real change in // this case. - var oldText = current$$1 !== null ? current$$1.memoizedProps : newText; + var oldText = current !== null ? current.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; + } + case HostRoot: { return; } @@ -19160,46 +16591,12 @@ function commitWork(current$$1, finishedWork) { 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); - } - } - } - - 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." + ); } } @@ -19216,61 +16613,9 @@ function commitSuspenseComponent(finishedWork) { markCommitTimeOfFallback(); } - if (supportsMutation && primaryChildParent !== null) { + if (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) { @@ -19292,7 +16637,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); } @@ -19305,12 +16650,8 @@ function attachSuspenseRetryListeners(finishedWork) { } } -function commitResetTextContent(current$$1) { - if (!supportsMutation) { - return; - } - - resetTextContent(current$$1.stateNode); +function commitResetTextContent(current) { + resetTextContent(current.stateNode); } var PossiblyWeakMap = typeof WeakMap === "function" ? WeakMap : Map; @@ -19340,11 +16681,11 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { var getDerivedStateFromError = fiber.type.getDerivedStateFromError; if (typeof getDerivedStateFromError === "function") { - var error = errorInfo.value; + var error$1 = errorInfo.value; update.payload = function() { logError(fiber, errorInfo); - return getDerivedStateFromError(error); + return getDerivedStateFromError(error$1); }; } @@ -19367,9 +16708,9 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { logError(fiber, errorInfo); } - var error = errorInfo.value; + var error$1 = errorInfo.value; var stack = errorInfo.stack; - this.componentDidCatch(error, { + this.componentDidCatch(error$1, { componentStack: stack !== null ? stack : "" }); @@ -19378,14 +16719,13 @@ 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. - !(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; + 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" + ); + } } } }; @@ -19450,7 +16790,22 @@ function throwException( ) { // This is a thenable. var thenable = value; - checkForWrongSuspensePriorityInDEV(sourceFiber); + + 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; + } + } + var hasInvisibleParentBoundary = hasSuspenseContext( suspenseStackCursor.current, InvisibleParentSuspenseContext @@ -19624,9 +16979,6 @@ function throwException( } break; - - default: - break; } workInProgress = workInProgress.return; @@ -19634,18 +16986,15 @@ function throwException( } var ceil = Math.ceil; -var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher; -var ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner; -var IsSomeRendererActing = ReactSharedInternals.IsSomeRendererActing; +var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, + ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, + IsSomeRendererActing = ReactSharedInternals.IsSomeRendererActing; var NoContext = /* */ 0; var BatchedContext = /* */ 1; -var EventContext = - /* */ - 2; var DiscreteEventContext = /* */ 4; @@ -19671,7 +17020,7 @@ var workInProgressRoot = null; // The fiber we're working on var workInProgress = null; // The expiration time we're rendering -var renderExpirationTime = NoWork; // Whether to root completed, errored, suspended, etc. +var renderExpirationTime$1 = NoWork; // Whether to root completed, errored, suspended, etc. var workInProgressRootExitStatus = RootIncomplete; // A fatal error, if one is thrown @@ -19756,7 +17105,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; + return renderExpirationTime$1; } var expirationTime; @@ -19800,7 +17149,10 @@ 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) { + if ( + workInProgressRoot !== null && + expirationTime === renderExpirationTime$1 + ) { // This is a trick to move this update into a separate batch expirationTime -= 1; } @@ -19809,7 +17161,7 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { } function scheduleUpdateOnFiber(fiber, expirationTime) { checkForNestedUpdates(); - warnAboutInvalidUpdatesOnClassComponentsInDEV(fiber); + warnAboutRenderPhaseUpdatesInDEV(fiber); var root = markUpdateTimeFromFiberToRoot(fiber, expirationTime); if (root === null) { @@ -19943,7 +17295,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); + markRootSuspendedAtTime(root, renderExpirationTime$1); } } // Mark that the root has a pending update. @@ -19975,9 +17327,17 @@ function getNextRootExpirationTimeToWorkOn(root) { var lastPingedTime = root.lastPingedTime; var nextKnownPendingLevel = root.nextKnownPendingLevel; - return lastPingedTime > nextKnownPendingLevel - ? lastPingedTime - : 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; } // 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 @@ -20044,11 +17404,6 @@ 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, @@ -20067,7 +17422,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; + currentEventTime = NoWork; // Check if the render expired. if (didTimeout) { // The render task took too long to complete. Mark the current time as @@ -20082,83 +17437,50 @@ function performConcurrentWorkOnRoot(root, didTimeout) { var expirationTime = getNextRootExpirationTimeToWorkOn(root); - if (expirationTime !== NoWork) { - var originalCallbackNode = root.callbackNode; - - 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 ( - 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 (expirationTime === NoWork) { + return null; + } - if (workInProgress !== null) { - var prevExecutionContext = executionContext; - executionContext |= RenderContext; - var prevDispatcher = pushDispatcher(root); - var prevInteractions = pushInteractions(root); - startWorkLoopTimer(workInProgress); + var originalCallbackNode = root.callbackNode; - do { - try { - workLoopConcurrent(); - break; - } catch (thrownValue) { - handleError(root, thrownValue); - } - } while (true); + if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { + throw Error("Should not already be working."); + } - resetContextDependencies(); - executionContext = prevExecutionContext; - popDispatcher(prevDispatcher); + flushPassiveEffects(); + var exitStatus = renderRootConcurrent(root, expirationTime); - if (enableSchedulerTracing) { - popInteractions(prevInteractions); - } + 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 (workInProgressRootExitStatus === RootFatalErrored) { - var fatalError = workInProgressRootFatalError; - stopInterruptedWorkLoopTimer(); - prepareFreshStack(root, expirationTime); - markRootSuspendedAtTime(root, expirationTime); - ensureRootIsScheduled(root); - throw fatalError; - } + 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. - 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 - ); - } + var finishedWork = (root.finishedWork = root.current.alternate); + root.finishedExpirationTime = expirationTime; + finishConcurrentRender(root, finishedWork, exitStatus, expirationTime); + } - ensureRootIsScheduled(root); + 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; @@ -20170,9 +17492,6 @@ function finishConcurrentRender( exitStatus, expirationTime ) { - // Set this to null to indicate there's no in-progress render. - workInProgressRoot = null; - switch (exitStatus) { case RootIncomplete: case RootFatalErrored: { @@ -20185,19 +17504,9 @@ function finishConcurrentRender( // if I do. eslint-disable-next-line no-fallthrough case RootErrored: { - // 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. - + // We should have already attempted to retry this tree. If we reached + // this point, it errored again. Commit it. + commitRoot(root); break; } @@ -20207,9 +17516,7 @@ function finishConcurrentRender( if (expirationTime === lastSuspendedTime) { root.nextKnownPendingLevel = getRemainingExpirationTime(finishedWork); - } - - flushSuspensePriorityWarningInDEV(); // We have an acceptable loading state. We need to figure out if we + } // 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 @@ -20220,7 +17527,7 @@ function finishConcurrentRender( if ( hasNotProcessedNewUpdates && // do not delay if we're inside an act() scope - !(true && flushSuspenseFallbacksInTests && IsThisRendererActing.current) + !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 @@ -20284,12 +17591,7 @@ 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) { @@ -20379,11 +17681,6 @@ 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 ) { @@ -20421,149 +17718,67 @@ function finishConcurrentRender( // through Scheduler function performSyncWorkOnRoot(root) { - // Check if there's expired work on this root. Otherwise, render at Sync. - var lastExpiredTime = root.lastExpiredTime; - 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."); - } + 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 lastExpiredTime = root.lastExpiredTime; + var expirationTime; + if (lastExpiredTime !== NoWork) { + // There's expired work on this root. Check if we have a partial tree + // that we can reuse. if ( - root !== workInProgressRoot || - expirationTime !== renderExpirationTime + root === workInProgressRoot && + renderExpirationTime$1 >= 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); + // 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; } + } else { + // There's no expired work. This must be a new, synchronous render. + expirationTime = Sync; } - return null; -} - -function finishSyncRender(root, exitStatus, expirationTime) { - // Set this to null to indicate there's no in-progress render. - workInProgressRoot = null; + var exitStatus = renderRootSync(root, expirationTime); - { - if (exitStatus === RootSuspended || exitStatus === RootSuspendedWithDelay) { - flushSuspensePriorityWarningInDEV(); - } + 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); } - 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; - } + 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. - flushPendingDiscreteUpdates(); // If the discrete updates scheduled passive effects, flush them now so that - // they fire before the next serial event. + root.finishedWork = root.current.alternate; + root.finishedExpirationTime = expirationTime; + commitRoot(root); // Before exiting, make sure there's a callback scheduled for the next + // pending level. - flushPassiveEffects(); + ensureRootIsScheduled(root); + return null; } - 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; @@ -20579,38 +17794,6 @@ 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) { { @@ -20657,8 +17840,8 @@ function prepareFreshStack(root, expirationTime) { } workInProgressRoot = root; - workInProgress = createWorkInProgress(root.current, null, expirationTime); - renderExpirationTime = expirationTime; + workInProgress = createWorkInProgress(root.current, null); + renderExpirationTime$1 = expirationTime; workInProgressRootExitStatus = RootIncomplete; workInProgressRootFatalError = null; workInProgressRootLatestProcessedExpirationTime = Sync; @@ -20667,13 +17850,12 @@ function prepareFreshStack(root, expirationTime) { workInProgressRootNextUnprocessedUpdateTime = NoWork; workInProgressRootHasPendingPing = false; - if (enableSchedulerTracing) { + { spawnedWorkDuringRender = null; } { ReactStrictModeWarnings.discardPendingWarnings(); - componentsThatTriggeredHighPriSuspend = null; } } @@ -20682,7 +17864,7 @@ function handleError(root, thrownValue) { try { // Reset module-level state that was set during the render phase. resetContextDependencies(); - resetHooks(); + resetHooksAfterThrow(); resetCurrentFiber(); if (workInProgress === null || workInProgress.return === null) { @@ -20691,7 +17873,14 @@ function handleError(root, thrownValue) { // supposed to capture all errors that weren't caught by an error // boundary. workInProgressRootExitStatus = RootFatalErrored; - workInProgressRootFatalError = thrownValue; + 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; return null; } @@ -20707,7 +17896,7 @@ function handleError(root, thrownValue) { workInProgress.return, workInProgress, thrownValue, - renderExpirationTime + renderExpirationTime$1 ); workInProgress = completeUnitOfWork(workInProgress); } catch (yetAnotherThrownValue) { @@ -20721,8 +17910,8 @@ function handleError(root, thrownValue) { } function pushDispatcher(root) { - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = ContextOnlyDispatcher; + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; if (prevDispatcher === null) { // The React isomorphic package does not include a default dispatcher. @@ -20735,21 +17924,19 @@ function pushDispatcher(root) { } function popDispatcher(prevDispatcher) { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.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; } } @@ -20802,7 +17989,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); + markRootSuspendedAtTime(workInProgressRoot, renderExpirationTime$1); markRootUpdatedAtTime( workInProgressRoot, workInProgressRootNextUnprocessedUpdateTime @@ -20841,6 +18028,56 @@ 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 */ @@ -20851,6 +18088,55 @@ 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() { @@ -20864,17 +18150,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$$1 = unitOfWork.alternate; + var current = unitOfWork.alternate; startWorkTimer(unitOfWork); setCurrentFiber(unitOfWork); var next; - if (enableProfilerTimer && (unitOfWork.mode & ProfileMode) !== NoMode) { + if ((unitOfWork.mode & ProfileMode) !== NoMode) { startProfilerTimer(unitOfWork); - next = beginWork$$1(current$$1, unitOfWork, renderExpirationTime); + next = beginWork$1(current, unitOfWork, renderExpirationTime$1); stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true); } else { - next = beginWork$$1(current$$1, unitOfWork, renderExpirationTime); + next = beginWork$1(current, unitOfWork, renderExpirationTime$1); } resetCurrentFiber(); @@ -20898,21 +18184,18 @@ 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$$1 = workInProgress.alternate; + var current = 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 ( - !enableProfilerTimer || - (workInProgress.mode & ProfileMode) === NoMode - ) { - next = completeWork(current$$1, workInProgress, renderExpirationTime); + if ((workInProgress.mode & ProfileMode) === NoMode) { + next = completeWork(current, workInProgress, renderExpirationTime$1); } else { startProfilerTimer(workInProgress); - next = completeWork(current$$1, workInProgress, renderExpirationTime); // Update render duration assuming we didn't error. + next = completeWork(current, workInProgress, renderExpirationTime$1); // Update render duration assuming we didn't error. stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false); } @@ -20968,12 +18251,9 @@ 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, renderExpirationTime); // Because this fiber did not complete, don't reset its expiration time. + var _next = unwindWork(workInProgress); // Because this fiber did not complete, don't reset its expiration time. - if ( - enableProfilerTimer && - (workInProgress.mode & ProfileMode) !== NoMode - ) { + if ((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. @@ -21036,7 +18316,7 @@ function getRemainingExpirationTime(fiber) { function resetChildExpirationTime(completedWork) { if ( - renderExpirationTime !== Never && + renderExpirationTime$1 !== Never && completedWork.childExpirationTime === Never ) { // The children of this component are hidden. Don't bubble their @@ -21046,7 +18326,7 @@ function resetChildExpirationTime(completedWork) { var newChildExpirationTime = NoWork; // Bubble up the earliest expiration time. - if (enableProfilerTimer && (completedWork.mode & ProfileMode) !== NoMode) { + if ((completedWork.mode & ProfileMode) !== NoMode) { // In profiling mode, resetChildExpirationTime is also used to reset // profiler durations. var actualDuration = completedWork.actualDuration; @@ -21117,7 +18397,16 @@ function commitRoot(root) { } function commitRootImpl(root, renderPriorityLevel) { - flushPassiveEffects(); + 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); + flushRenderPhaseStrictModeWarningsInDEV(); if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { @@ -21161,8 +18450,7 @@ function commitRootImpl(root, renderPriorityLevel) { // We can reset these now that they are finished. workInProgressRoot = null; workInProgress = null; - renderExpirationTime = NoWork; - } else { + renderExpirationTime$1 = NoWork; } // 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. @@ -21220,7 +18508,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(); @@ -21294,7 +18582,7 @@ function commitRootImpl(root, renderPriorityLevel) { requestPaint(); - if (enableSchedulerTracing) { + { popInteractions(prevInteractions); } @@ -21308,7 +18596,7 @@ function commitRootImpl(root, renderPriorityLevel) { startCommitSnapshotEffectsTimer(); stopCommitSnapshotEffectsTimer(); - if (enableProfilerTimer) { + { recordCommitTime(); } @@ -21344,7 +18632,7 @@ function commitRootImpl(root, renderPriorityLevel) { var remainingExpirationTime = root.firstPendingTime; if (remainingExpirationTime !== NoWork) { - if (enableSchedulerTracing) { + { if (spawnedWorkDuringRender !== null) { var expirationTimes = spawnedWorkDuringRender; spawnedWorkDuringRender = null; @@ -21366,7 +18654,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. @@ -21420,8 +18708,8 @@ function commitBeforeMutationEffects() { if ((effectTag & Snapshot) !== NoEffect) { setCurrentFiber(nextEffect); recordEffect(); - var current$$1 = nextEffect.alternate; - commitBeforeMutationLifeCycles(current$$1, nextEffect); + var current = nextEffect.alternate; + commitBeforeMutationLifeCycles(current, nextEffect); resetCurrentFiber(); } @@ -21452,10 +18740,10 @@ function commitMutationEffects(root, renderPriorityLevel) { } if (effectTag & Ref) { - var current$$1 = nextEffect.alternate; + var current = nextEffect.alternate; - if (current$$1 !== null) { - commitDetachRef(current$$1); + if (current !== null) { + commitDetachRef(current); } } // The following switch statement is only concerned about placement, // updates, and deletions. To avoid needing to add a case for every possible @@ -21527,8 +18815,8 @@ function commitLayoutEffects(root, committedExpirationTime) { if (effectTag & (Update | Callback)) { recordEffect(); - var current$$1 = nextEffect.alternate; - commitLifeCycles(root, current$$1, nextEffect, committedExpirationTime); + var current = nextEffect.alternate; + commitLifeCycles(root, current, nextEffect); } if (effectTag & Ref) { @@ -21568,36 +18856,40 @@ 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 prevInteractions = pushInteractions(root); - var effect = root.current.firstEffect; + { + // 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 (effect !== null) { - { - setCurrentFiber(effect); - invokeGuardedCallback(null, commitPassiveHookEffects, null, effect); + while (_effect2 !== null) { + { + setCurrentFiber(_effect2); + invokeGuardedCallback(null, commitPassiveHookEffects, null, _effect2); - if (hasCaughtError()) { - if (!(effect !== null)) { - throw Error("Should be working on an effect."); + if (hasCaughtError()) { + if (!(_effect2 !== null)) { + throw Error("Should be working on an effect."); + } + + var _error5 = clearCaughtError(); + + captureCommitPhaseError(_effect2, _error5); } - var error = clearCaughtError(); - captureCommitPhaseError(effect, error); + resetCurrentFiber(); } - resetCurrentFiber(); - } - - var nextNextEffect = effect.nextEffect; // Remove nextEffect pointer to assist GC + var nextNextEffect = _effect2.nextEffect; // Remove nextEffect pointer to assist GC - effect.nextEffect = null; - effect = nextNextEffect; + _effect2.nextEffect = null; + _effect2 = nextNextEffect; + } } - if (enableSchedulerTracing) { + { popInteractions(prevInteractions); finishPendingInteractions(root, expirationTime); } @@ -21699,7 +18991,7 @@ function pingSuspendedRoot(root, thenable, suspendedTime) { pingCache.delete(thenable); } - if (workInProgressRoot === root && renderExpirationTime === suspendedTime) { + if (workInProgressRoot === root && renderExpirationTime$1 === 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. @@ -21719,7 +19011,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); + prepareFreshStack(root, renderExpirationTime$1); } else { // Even though we can't restart right now, we might get an // opportunity later. So we mark this render as having a ping. @@ -21742,13 +19034,6 @@ 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); } @@ -21776,45 +19061,12 @@ 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; } @@ -21839,16 +19091,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( @@ -21897,8 +19149,8 @@ function checkForNestedUpdates() { { if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) { nestedPassiveUpdateCount = 0; - warning$1( - false, + + error( "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 " + @@ -21912,7 +19164,7 @@ function flushRenderPhaseStrictModeWarningsInDEV() { { ReactStrictModeWarnings.flushLegacyContextWarning(); - if (warnAboutDeprecatedLifecycles) { + { ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings(); } } @@ -21933,9 +19185,8 @@ function stopInterruptedWorkLoopTimer() { function checkForInterruption(fiberThatReceivedUpdate, updateExpirationTime) { if ( - enableUserTimingAPI && workInProgressRoot !== null && - updateExpirationTime > renderExpirationTime + updateExpirationTime > renderExpirationTime$1 ) { interruptedBy = fiberThatReceivedUpdate; } @@ -21953,11 +19204,12 @@ function warnAboutUpdateOnUnmountedFiberInDEV(fiber) { tag !== FunctionComponent && tag !== ForwardRef && tag !== MemoComponent && - tag !== SimpleMemoComponent + tag !== SimpleMemoComponent && + tag !== Block ) { // 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"; @@ -21972,8 +19224,7 @@ function warnAboutUpdateOnUnmountedFiberInDEV(fiber) { didWarnStateUpdateForUnmountedComponent = new Set([componentName]); } - warningWithoutStack$1( - false, + error( "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", @@ -21985,12 +19236,12 @@ function warnAboutUpdateOnUnmountedFiberInDEV(fiber) { } } -var beginWork$$1; +var beginWork$1; -if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) { +{ var dummyFiber = null; - beginWork$$1 = function(current$$1, unitOfWork, expirationTime) { + beginWork$1 = function(current, 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. @@ -22002,7 +19253,7 @@ if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) { ); try { - return beginWork$1(current$$1, unitOfWork, expirationTime); + return beginWork(current, unitOfWork, expirationTime); } catch (originalError) { if ( originalError !== null && @@ -22015,7 +19266,7 @@ if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) { // corresponding changes there. resetContextDependencies(); - resetHooks(); // Don't reset current debug fiber, since we're about to work on the + resetHooksAfterThrow(); // Don't reset current debug fiber, since we're about to work on the // same fiber again. // Unwind the failed stack frame @@ -22023,16 +19274,16 @@ if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) { assignFiberPropertiesInDEV(unitOfWork, originalWorkInProgressCopy); - if (enableProfilerTimer && unitOfWork.mode & ProfileMode) { + if (unitOfWork.mode & ProfileMode) { // Reset the profiler timer. startProfilerTimer(unitOfWork); } // Run beginWork again. invokeGuardedCallback( null, - beginWork$1, + beginWork, null, - current$$1, + current, unitOfWork, expirationTime ); @@ -22048,42 +19299,37 @@ if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) { } } }; -} else { - beginWork$$1 = beginWork$1; } var didWarnAboutUpdateInRender = false; -var didWarnAboutUpdateInGetChildContext = false; -function warnAboutInvalidUpdatesOnClassComponentsInDEV(fiber) { +function warnAboutRenderPhaseUpdatesInDEV(fiber) { { - if (fiber.tag === ClassComponent) { - switch (phase) { - case "getChildContext": - if (didWarnAboutUpdateInGetChildContext) { - return; - } - - warningWithoutStack$1( - false, - "setState(...): Cannot call setState() inside getChildContext()" + 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." ); - didWarnAboutUpdateInGetChildContext = true; + break; + } - case "render": - if (didWarnAboutUpdateInRender) { - return; - } + 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." + ); - 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; + didWarnAboutUpdateInRender = true; + break; + } + } } } } @@ -22095,20 +19341,20 @@ var IsThisRendererActing = { function warnIfNotScopedWithMatchingAct(fiber) { { if ( - warnsIfNotActing === true && IsSomeRendererActing.current === true && IsThisRendererActing.current !== true ) { - warningWithoutStack$1( - false, + error( "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" + + "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" + "const {act} = TestRenderer;\n" + "// ...\n" + "act(() => ...);" + @@ -22121,13 +19367,11 @@ function warnIfNotScopedWithMatchingAct(fiber) { function warnIfNotCurrentlyActingEffectsInDEV(fiber) { { if ( - warnsIfNotActing === true && (fiber.mode & StrictMode) !== NoMode && IsSomeRendererActing.current === false && IsThisRendererActing.current === false ) { - warningWithoutStack$1( - false, + error( "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" + @@ -22149,13 +19393,11 @@ function warnIfNotCurrentlyActingEffectsInDEV(fiber) { function warnIfNotCurrentlyActingUpdatesInDEV(fiber) { { if ( - warnsIfNotActing === true && executionContext === NoContext && IsSomeRendererActing.current === false && IsThisRendererActing.current === false ) { - warningWithoutStack$1( - false, + error( "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" + @@ -22189,161 +19431,30 @@ function warnIfUnmockedScheduler(fiber) { ) { if (fiber.mode & BlockingMode || fiber.mode & ConcurrentMode) { didWarnAboutUnmockedScheduler = true; - warningWithoutStack$1( - false, + + error( '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" + - "jest.mock('scheduler', () => require('scheduler/unstable_mock'));\n\n" + + "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" + "For more info, visit https://fb.me/react-mock-scheduler" ); - } else if (warnAboutUnmockedScheduler === true) { + } else { didWarnAboutUnmockedScheduler = true; - warningWithoutStack$1( - false, + + error( '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" + + "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" + "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. @@ -22351,10 +19462,6 @@ function computeThreadID(root, expirationTime) { } function markSpawnedWork(expirationTime) { - if (!enableSchedulerTracing) { - return; - } - if (spawnedWorkDuringRender === null) { spawnedWorkDuringRender = [expirationTime]; } else { @@ -22363,10 +19470,6 @@ function markSpawnedWork(expirationTime) { } function scheduleInteractions(root, expirationTime, interactions) { - if (!enableSchedulerTracing) { - return; - } - if (interactions.size > 0) { var pendingInteractionMap = root.pendingInteractionMap; var pendingInteractions = pendingInteractionMap.get(expirationTime); @@ -22398,21 +19501,10 @@ 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. @@ -22453,10 +19545,6 @@ function startWorkOnPendingInteractions(root, expirationTime) { } function finishPendingInteractions(root, committedExpirationTime) { - if (!enableSchedulerTracing) { - return; - } - var earliestRemainingTimeAfterCommit = root.firstPendingTime; var subscriber; @@ -22505,6 +19593,7 @@ function finishPendingInteractions(root, committedExpirationTime) { } } +var onScheduleFiberRoot = null; var onCommitFiberRoot = null; var onCommitFiberUnmount = null; var hasLoggedError = false; @@ -22526,8 +19615,7 @@ function injectInternals(internals) { if (!hook.supportsFiber) { { - warningWithoutStack$1( - false, + error( "The installed version of React DevTools is too old and will not work " + "with the current version of React. Please update React DevTools. " + "https://fb.me/react-devtools" @@ -22540,6 +19628,23 @@ 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; @@ -22555,13 +19660,12 @@ function injectInternals(internals) { hook.onCommitFiberRoot(rendererID, root, undefined, didError); } } catch (err) { - if (true && !hasLoggedError) { - hasLoggedError = true; - warningWithoutStack$1( - false, - "React DevTools encountered an error: %s", - err - ); + if (true) { + if (!hasLoggedError) { + hasLoggedError = true; + + error("React instrumentation encountered an error: %s", err); + } } } }; @@ -22570,29 +19674,29 @@ function injectInternals(internals) { try { hook.onCommitFiberUnmount(rendererID, fiber); } catch (err) { - if (true && !hasLoggedError) { - hasLoggedError = true; - warningWithoutStack$1( - false, - "React DevTools encountered an error: %s", - err - ); + if (true) { + if (!hasLoggedError) { + hasLoggedError = true; + + error("React instrumentation encountered an error: %s", err); + } } } }; } catch (err) { // Catch all errors because it is unsafe to throw during initialization. { - warningWithoutStack$1( - false, - "React DevTools encountered an error: %s.", - err - ); + error("React instrumentation 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); @@ -22654,7 +19758,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 @@ -22681,7 +19785,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; } @@ -22745,7 +19849,7 @@ function resolveLazyComponentTag(Component) { return IndeterminateComponent; } // This is used to create an alternate fiber to do work on. -function createWorkInProgress(current, pendingProps, expirationTime) { +function createWorkInProgress(current, pendingProps) { var workInProgress = current.alternate; if (workInProgress === null) { @@ -22766,7 +19870,10 @@ function createWorkInProgress(current, pendingProps, expirationTime) { { // DEV-only fields - workInProgress._debugID = current._debugID; + { + workInProgress._debugID = current._debugID; + } + workInProgress._debugSource = current._debugSource; workInProgress._debugOwner = current._debugOwner; workInProgress._debugHookTypes = current._debugHookTypes; @@ -22784,7 +19891,7 @@ function createWorkInProgress(current, pendingProps, expirationTime) { 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, @@ -22794,6 +19901,19 @@ function createWorkInProgress(current, pendingProps, expirationTime) { } } + { + // 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; @@ -22816,7 +19936,7 @@ function createWorkInProgress(current, pendingProps, expirationTime) { workInProgress.index = current.index; workInProgress.ref = current.ref; - if (enableProfilerTimer) { + { workInProgress.selfBaseDuration = current.selfBaseDuration; workInProgress.treeBaseDuration = current.treeBaseDuration; } @@ -22838,9 +19958,6 @@ function createWorkInProgress(current, pendingProps, expirationTime) { case ForwardRef: workInProgress.type = resolveForwardRefForHotReloading(current.type); break; - - default: - break; } } @@ -22873,7 +19990,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; @@ -22899,7 +20016,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; @@ -22920,7 +20037,7 @@ function createHostRootFiber(tag) { mode = NoMode; } - if (enableProfilerTimer && isDevToolsPresent) { + if (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. @@ -23020,29 +20137,9 @@ function createFiberFromTypeAndProps( resolvedType = null; 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 - ); - } + case REACT_BLOCK_TYPE: + fiberTag = Block; + break getTag; } } @@ -23117,38 +20214,11 @@ 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" || - typeof pendingProps.onRender !== "function" - ) { - warningWithoutStack$1( - false, - 'Profiler must specify an "id" string and "onRender" function as props' - ); + if (typeof pendingProps.id !== "string") { + error('Profiler must specify an "id" as a prop'); } } @@ -23157,6 +20227,14 @@ 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; } @@ -23189,18 +20267,6 @@ 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); @@ -23249,17 +20315,20 @@ 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._debugID = source._debugID; + target._debugIsCurrentlyTiming = source._debugIsCurrentlyTiming; + } + target._debugSource = source._debugSource; target._debugOwner = source._debugOwner; - target._debugIsCurrentlyTiming = source._debugIsCurrentlyTiming; target._debugNeedsRemount = source._debugNeedsRemount; target._debugHookTypes = source._debugHookTypes; return target; @@ -23286,28 +20355,21 @@ 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) { @@ -23401,15 +20463,6 @@ 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; @@ -23430,38 +20483,11 @@ function getContextForSubtree(parentComponent) { 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 (hostFiber === null) { - return null; + return processChildContext(fiber, Component, parentContext); + } } - return hostFiber.stateNode; + return parentContext; } function findHostInstanceWithWarning(component, methodName) { @@ -23496,8 +20522,7 @@ function findHostInstanceWithWarning(component, methodName) { didWarnAboutFindNodeInStrictMode[componentName] = true; if (fiber.mode & StrictMode) { - warningWithoutStack$1( - false, + error( "%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. " + @@ -23509,8 +20534,7 @@ function findHostInstanceWithWarning(component, methodName) { getStackByFiberInDevAndProd(hostFiber) ); } else { - warningWithoutStack$1( - false, + error( "%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. " + @@ -23527,44 +20551,33 @@ function findHostInstanceWithWarning(component, methodName) { return hostFiber.stateNode; } - - return findHostInstance(component); } function createContainer(containerInfo, tag, hydrate, hydrationCallbacks) { - return createFiberRoot(containerInfo, tag, hydrate, hydrationCallbacks); + return createFiberRoot(containerInfo, tag, hydrate); } function updateContainer(element, container, parentComponent, callback) { - var current$$1 = container.current; + { + onScheduleRoot(container, element); + } + + 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) { @@ -23574,10 +20587,10 @@ function updateContainer(element, container, parentComponent, callback) { } { - if (phase === "render" && current !== null && !didWarnAboutNestedUpdates) { + if (isRendering && current !== null && !didWarnAboutNestedUpdates) { didWarnAboutNestedUpdates = true; - warningWithoutStack$1( - false, + + error( "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" + @@ -23596,19 +20609,21 @@ function updateContainer(element, container, parentComponent, callback) { callback = callback === undefined ? null : callback; if (callback !== null) { - !(typeof callback === "function") - ? warningWithoutStack$1( - false, + { + if (typeof callback !== "function") { + error( "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) { @@ -23627,703 +20642,149 @@ function getPublicRootInstance(container) { } } -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; - } - - 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 shouldSuspendImpl = function(fiber) { + return false; +}; - _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. +function shouldSuspend(fiber) { + return shouldSuspendImpl(fiber); +} +var overrideHookState = null; +var overrideProps = null; +var scheduleUpdate = null; +var setSuspenseHandler = 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. +{ + var copyWithSetImpl = function(obj, path, idx, value) { + if (idx >= path.length) { + return value; + } - if (maybeInstance == null) { - return; - } + var key = path[idx]; + var updated = Array.isArray(obj) ? obj.slice() : Object.assign({}, obj); // $FlowFixMe number or string is fine here - 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. + updated[key] = copyWithSetImpl(obj[key], path, idx + 1, value); + return updated; + }; - 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. + var copyWithSet = function(obj, path, value) { + return copyWithSetImpl(obj, path, 0, value); + }; // Support DevTools editable values for useState and useReducer. - if (maybeInstance == null) { - return; - } + 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; - 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. + 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) { - 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; + overrideProps = function(fiber, path, value) { + fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value); - if (typeof relativeToNativeNode === "number") { - // Already a node handle - relativeNode = relativeToNativeNode; - } else if (relativeToNativeNode._nativeTag) { - relativeNode = relativeToNativeNode._nativeTag; - } + if (fiber.alternate) { + fiber.alternate.pendingProps = fiber.pendingProps; + } - if (relativeNode == null) { - warningWithoutStack$1( - false, - "Warning: ref.measureLayout must be called with a node handle or a ref to a native component." - ); - return; - } + scheduleWork(fiber, Sync); + }; - 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. + 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: setNativeProps is not currently supported in Fabric" - ); - return; - } + return hostFiber.stateNode; + }, + findFiberByHostInstance: function(instance) { + if (!findFiberByHostInstance) { + // Might not be implemented by the renderer. + return null; + } - 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 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; - return ReactNativeComponent; - })(React.Component); // eslint-disable-next-line no-unused-expressions +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 + }; +} - return ReactNativeComponent; -}; +// TODO: this is special because it gets imported during build. +var ReactVersion = "16.13.0"; -var emptyObject$3 = {}; +var emptyObject$1 = {}; { - Object.freeze(emptyObject$3); + Object.freeze(emptyObject$1); } var getInspectorDataForViewTag; +var getInspectorDataForViewAtPoint; { var traverseOwnerTreeUp = function(hierarchy, instance) { @@ -24355,10 +20816,10 @@ var getInspectorDataForViewTag; var host = findCurrentHostFiber(fiber); if (host) { - return host.memoizedProps || emptyObject$3; + return host.memoizedProps || emptyObject$1; } - return emptyObject$3; + return emptyObject$1; }; var getHostNode = function(fiber, findNodeHandle) { @@ -24386,28 +20847,65 @@ var getInspectorDataForViewTag; name: getComponentName(fiber.type), getInspectorData: function(findNodeHandle) { return { - measure: function(callback) { - return ReactNativePrivateInterface.UIManager.measure( - getHostNode(fiber, findNodeHandle), - callback - ); - }, props: getHostProps(fiber), - source: fiber._debugSource + 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 + ); + } + } }; } }; }); }; + 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$3, - selection: null, + props: emptyObject$1, + selectedIndex: null, source: null }; } @@ -24418,34 +20916,122 @@ var getInspectorDataForViewTag; var hierarchy = createHierarchy(fiberHierarchy); var props = getHostProps(instance); var source = instance._debugSource; - var selection = fiberHierarchy.indexOf(instance); + var selectedIndex = fiberHierarchy.indexOf(instance); return { hierarchy: hierarchy, props: props, - selection: selection, + selectedIndex: selectedIndex, 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 = ReactSharedInternals.ReactCurrentOwner; +var ReactCurrentOwner$3 = ReactSharedInternals.ReactCurrentOwner; function findHostInstance_DEPRECATED(componentOrHandle) { { - var owner = ReactCurrentOwner.current; + var owner = ReactCurrentOwner$3.current; if (owner !== null && owner.stateNode !== null) { - !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; + 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 = true; } } @@ -24485,20 +21071,20 @@ function findHostInstance_DEPRECATED(componentOrHandle) { function findNodeHandle(componentOrHandle) { { - var owner = ReactCurrentOwner.current; + var owner = ReactCurrentOwner$3.current; if (owner !== null && owner.stateNode !== null) { - !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; + 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 = true; } } @@ -24541,110 +21127,109 @@ function findNodeHandle(componentOrHandle) { return hostInstance._nativeTag; } -setBatchingImplementation( - batchedUpdates$1, - discreteUpdates$1, - flushDiscreteUpdates, - batchedEventUpdates$1 -); - -function computeComponentStackForErrorReporting(reactTag) { - var fiber = getInstanceFromTag(reactTag); +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" + ); + } - if (!fiber) { - return ""; + return; } - 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; - } - + if (handle._internalInstanceHandle) { + nativeFabricUIManager.dispatchCommand( + handle._internalInstanceHandle.stateNode.node, + command, + args + ); + } else { ReactNativePrivateInterface.UIManager.dispatchViewManagerCommand( handle._nativeTag, command, args ); - }, - render: function(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, null); - roots.set(containerTag, root); - } +function render(element, containerTag, callback) { + var root = roots.get(containerTag); - updateContainer(element, root, null, callback); - return getPublicRootInstance(root); - }, - unmountComponentAtNode: function(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); + 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); - }); - } - }, - unmountComponentAtNodeAndRemoveContainer: function(containerTag) { - ReactNativeRenderer.unmountComponentAtNode(containerTag); // Call back into native to remove all of the subviews from this container + updateContainer(element, root, null, callback); + return getPublicRootInstance(root); +} - 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 +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); +} + +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); + +function computeComponentStackForErrorReporting(reactTag) { + var fiber = getInstanceFromTag(reactTag); + + if (!fiber) { + return ""; } + + return getStackByFiberInDevAndProd(fiber); +} + +var roots = new Map(); +var Internals = { + computeComponentStackForErrorReporting: computeComponentStackForErrorReporting }; injectIntoDevTools({ findFiberByHostInstance: getInstanceFromTag, - getInspectorDataForViewTag: getInspectorDataForViewTag, bundleType: 1, version: ReactVersion, - rendererPackageName: "react-native-renderer" -}); - -var ReactNativeRenderer$2 = Object.freeze({ - default: ReactNativeRenderer + rendererPackageName: "react-native-renderer", + rendererConfig: { + getInspectorDataForViewTag: getInspectorDataForViewTag, + getInspectorDataForViewAtPoint: getInspectorDataForViewAtPoint.bind( + null, + findNodeHandle + ) + } }); -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; +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; })(); } diff --git a/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js b/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js index 4aa16ac835491d..d837754c50d25c 100644 --- a/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js +++ b/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js @@ -5,6 +5,7 @@ * LICENSE file in the root directory of this source tree. * * @noflow + * @nolint * @providesModule ReactNativeRenderer-dev * @preventMunge * @generated @@ -16,256 +17,234 @@ 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"); -/** - * 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. - */ - -/** - * Injectable ordering of event plugins. - */ -var eventPluginOrder = null; -/** - * Injectable mapping from names to event plugin modules. - */ +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. -var namesToPlugins = {}; -/** - * Recomputes the plugin list using the injected plugins and plugin ordering. - * - * @private - */ +if (!ReactSharedInternals.hasOwnProperty("ReactCurrentDispatcher")) { + ReactSharedInternals.ReactCurrentDispatcher = { + current: null + }; +} -function recomputePluginOrdering() { - if (!eventPluginOrder) { - // Wait until an `eventPluginOrder` is injected. - return; - } +if (!ReactSharedInternals.hasOwnProperty("ReactCurrentBatchConfig")) { + ReactSharedInternals.ReactCurrentBatchConfig = { + suspense: null + }; +} - for (var pluginName in namesToPlugins) { - var pluginModule = namesToPlugins[pluginName]; - var pluginIndex = eventPluginOrder.indexOf(pluginName); +// 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. - if (!(pluginIndex > -1)) { - throw Error( - "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + - 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 (plugins[pluginIndex]) { - continue; + 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 (!pluginModule.extractEvents) { - throw Error( - "EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + - pluginName + - "` does not." - ); - } + printWarning("error", format, args); + } +} - plugins[pluginIndex] = pluginModule; - var publishedEvents = pluginModule.eventTypes; +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; - for (var eventName in publishedEvents) { - if ( - !publishEventForPlugin( - publishedEvents[eventName], - pluginModule, - eventName - ) - ) { - throw Error( - "EventPluginRegistry: Failed to publish event `" + - eventName + - "` for plugin `" + - pluginName + - "`." - ); + if (!hasExistingStack) { + var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; + var stack = ReactDebugCurrentFrame.getStackAddendum(); + + if (stack !== "") { + format += "%s"; + args = args.concat([stack]); } } + + 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 - */ -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 FunctionComponent = 0; +var ClassComponent = 1; +var IndeterminateComponent = 2; // Before we know whether it is function or class - eventNameDispatchConfigs[eventName] = dispatchConfig; - var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; +var HostRoot = 3; // Root of a host tree. Could be nested inside another node. - if (phasedRegistrationNames) { - for (var phaseName in phasedRegistrationNames) { - if (phasedRegistrationNames.hasOwnProperty(phaseName)) { - var phasedRegistrationName = phasedRegistrationNames[phaseName]; - publishRegistrationName( - phasedRegistrationName, - pluginModule, - eventName - ); - } - } +var HostPortal = 4; // A subtree. Could be an entry point to a different renderer. - return true; - } else if (dispatchConfig.registrationName) { - publishRegistrationName( - dispatchConfig.registrationName, - pluginModule, - eventName - ); - return true; +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 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 (inst) { + return inst; } - return false; + return null; } /** - * 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 + * Return the lowest common ancestor of A and B, or null if they are in + * different trees. */ -function publishRegistrationName(registrationName, pluginModule, eventName) { - if (!!registrationNameModules[registrationName]) { - throw Error( - "EventPluginHub: More than one plugin attempted to publish the same registration name, `" + - registrationName + - "`." - ); +function getLowestCommonAncestor(instA, instB) { + var depthA = 0; + + for (var tempA = instA; tempA; tempA = getParent(tempA)) { + depthA++; } - registrationNameModules[registrationName] = pluginModule; - registrationNameDependencies[registrationName] = - pluginModule.eventTypes[eventName].dependencies; + var depthB = 0; - { - var lowerCasedName = registrationName.toLowerCase(); - } -} -/** - * Registers plugins so that they can extract and dispatch events. - * - * @see {EventPluginHub} - */ + for (var tempB = instB; tempB; tempB = getParent(tempB)) { + depthB++; + } // If A is deeper, crawl up. -/** - * Ordered list of injected plugins. - */ + while (depthA - depthB > 0) { + instA = getParent(instA); + depthA--; + } // If B is deeper, crawl up. -var plugins = []; -/** - * Mapping from event name to dispatch config - */ + while (depthB - depthA > 0) { + instB = getParent(instB); + depthB--; + } // Walk in lockstep until we find a match. -var eventNameDispatchConfigs = {}; -/** - * Mapping from registration name to plugin module - */ + var depth = depthA; -var registrationNameModules = {}; -/** - * Mapping from registration name to event name - */ + while (depth--) { + if (instA === instB || instA === instB.alternate) { + return instA; + } -var registrationNameDependencies = {}; + instA = getParent(instA); + instB = getParent(instB); + } + + return null; +} /** - * 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} + * Return if A is an ancestor of B. */ -// Trust the developer to only use possibleRegistrationNames in true +function isAncestor(instA, instB) { + while (instB) { + if (instA === instB || instA === instB.alternate) { + return true; + } + + instB = getParent(instB); + } + 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 - * @see {EventPluginHub.injection.injectEventPluginOrder} + * Return the parent instance of the passed-in instance. */ -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(); +function getParentInstance(inst) { + return getParent(inst); } /** - * 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} + * Simulates the traversal of a two-phase, capture/bubble event dispatch. */ -function injectEventPluginsByName(injectedNamesToPlugins) { - var isOrderingDirty = false; - - for (var pluginName in injectedNamesToPlugins) { - if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) { - continue; - } +function traverseTwoPhase(inst, fn, arg) { + var path = []; - var pluginModule = injectedNamesToPlugins[pluginName]; + while (inst) { + path.push(inst); + inst = getParent(inst); + } - 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 i; - namesToPlugins[pluginName] = pluginModule; - isOrderingDirty = true; - } + for (i = path.length; i-- > 0; ) { + fn(path[i], "captured", arg); } - if (isOrderingDirty) { - recomputePluginOrdering(); + for (i = 0; i < path.length; i++) { + fn(path[i], "bubbled", arg); } } @@ -560,71 +539,6 @@ 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; @@ -638,13 +552,12 @@ function setComponentTree( getNodeFromInstance = getNodeFromInstanceImpl; { - !(getNodeFromInstance && getInstanceFromNode) - ? warningWithoutStack$1( - false, - "EventPluginUtils.setComponentTree(...): Injected " + - "module is missing getNodeFromInstance or getInstanceFromNode." - ) - : void 0; + if (!getNodeFromInstance || !getInstanceFromNode) { + error( + "EventPluginUtils.setComponentTree(...): Injected " + + "module is missing getNodeFromInstance or getInstanceFromNode." + ); + } } } var validateEventDispatches; @@ -657,17 +570,18 @@ 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; - !(instancesIsArr === listenersIsArr && instancesLen === listenersLen) - ? warningWithoutStack$1(false, "EventPluginUtils: Invalid `event`.") - : void 0; + ? 1 + : 0; + + if (instancesIsArr !== listenersIsArr || instancesLen !== listenersLen) { + error("EventPluginUtils: Invalid `event`."); + } }; } /** @@ -774,135 +688,24 @@ function executeDirectDispatch(event) { if (!!Array.isArray(dispatchListener)) { throw Error("executeDirectDispatch(...): Invalid `event`."); - } - - event.currentTarget = dispatchListener - ? getNodeFromInstance(dispatchInstance) - : null; - var res = dispatchListener ? dispatchListener(event) : null; - event.currentTarget = null; - event._dispatchListeners = null; - event._dispatchInstances = null; - return res; -} -/** - * @param {SyntheticEvent} event - * @return {boolean} True iff number of dispatches accumulated is greater than 0. - */ - -function hasDispatches(event) { - return !!event._dispatchListeners; -} - -/** - * 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 - * API cleanness. Since `current` can be null before being passed in and not - * null after this function, make sure to assign it back to `current`: - * - * `a = accumulateInto(a, b);` - * - * This API should be sparingly used. Try `accumulate` for something cleaner. - * - * @return {*|array<*>} An accumulation of items. - */ - -function accumulateInto(current, next) { - if (!(next != null)) { - throw Error( - "accumulateInto(...): 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)) { - if (Array.isArray(next)) { - current.push.apply(current, next); - return current; - } - - current.push(next); - return current; - } - - if (Array.isArray(next)) { - // A bit too dangerous to mutate `next`. - return [current].concat(next); - } - - return [current, next]; -} - -/** - * @param {array} arr an "accumulation" of items which is either an Array or - * a single item. Useful when paired with the `accumulate` module. This is a - * simple utility that allows us to reason about a collection of items, but - * handling the case when there is exactly one item (and we do not need to - * allocate an array). - * @param {function} cb Callback invoked with each element or a collection. - * @param {?} [scope] Scope used as `this` in a callback. - */ -function forEachAccumulated(arr, cb, scope) { - if (Array.isArray(arr)) { - arr.forEach(cb, scope); - } else if (arr) { - cb.call(scope, arr); - } -} - -/** - * 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(); + event.currentTarget = dispatchListener + ? getNodeFromInstance(dispatchInstance) + : null; + var res = dispatchListener ? dispatchListener(event) : null; + event.currentTarget = null; + event._dispatchListeners = null; + event._dispatchInstances = null; + return res; +} +/** + * @param {SyntheticEvent} event + * @return {boolean} True iff number of dispatches accumulated is greater than 0. + */ + +function hasDispatches(event) { + return !!event._dispatchListeners; } function isInteractive(tag) { @@ -926,51 +729,13 @@ function shouldPreventMouseEvent(name, type, props) { case "onMouseMoveCapture": case "onMouseUp": case "onMouseUpCapture": + case "onMouseEnter": return !!(props.disabled && isInteractive(type)); default: return false; } } -/** - * 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 - */ - -/** - * Methods for injecting dependencies. - */ - -var injection = { - /** - * @param {array} InjectedEventPluginOrder - * @public - */ - injectEventPluginOrder: injectEventPluginOrder, - - /** - * @param {object} injectedNamesToPlugins Map from names to plugin modules. - */ - injectEventPluginsByName: injectEventPluginsByName -}; /** * @param {object} inst The instance, which is the source of events. * @param {string} registrationName Name of listener (e.g. `onClick`). @@ -1013,195 +778,66 @@ function getListener(inst, registrationName) { return listener; } -/** - * 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); -} - -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; - -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 (inst) { - return inst; - } - return null; -} /** - * Return the lowest common ancestor of A and B, or null if they are in - * different trees. + * 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 + * API cleanness. Since `current` can be null before being passed in and not + * null after this function, make sure to assign it back to `current`: + * + * `a = accumulateInto(a, b);` + * + * This API should be sparingly used. Try `accumulate` for something cleaner. + * + * @return {*|array<*>} An accumulation of items. */ -function getLowestCommonAncestor(instA, instB) { - var depthA = 0; - - for (var tempA = instA; tempA; tempA = getParent(tempA)) { - depthA++; +function accumulateInto(current, next) { + if (!(next != null)) { + throw Error( + "accumulateInto(...): Accumulated items must not be null or undefined." + ); } - 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; + 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). - while (depth--) { - if (instA === instB || instA === instB.alternate) { - return instA; + if (Array.isArray(current)) { + if (Array.isArray(next)) { + current.push.apply(current, next); + return current; } - instA = getParent(instA); - instB = getParent(instB); + current.push(next); + return current; } - return null; -} -/** - * Return if A is an ancestor of B. - */ - -function isAncestor(instA, instB) { - while (instB) { - if (instA === instB || instA === instB.alternate) { - return true; - } - - instB = getParent(instB); + if (Array.isArray(next)) { + // A bit too dangerous to mutate `next`. + return [current].concat(next); } - return false; + return [current, next]; } -/** - * Return the parent instance of the passed-in instance. - */ -function getParentInstance(inst) { - return getParent(inst); -} /** - * Simulates the traversal of a two-phase, capture/bubble event dispatch. + * @param {array} arr an "accumulation" of items which is either an Array or + * a single item. Useful when paired with the `accumulate` module. This is a + * simple utility that allows us to reason about a collection of items, but + * handling the case when there is exactly one item (and we do not need to + * allocate an array). + * @param {function} cb Callback invoked with each element or a collection. + * @param {?} [scope] Scope used as `this` in a callback. */ - -function traverseTwoPhase(inst, fn, arg) { - var path = []; - - while (inst) { - path.push(inst); - inst = getParent(inst); - } - - var i; - - for (i = path.length; i-- > 0; ) { - fn(path[i], "captured", arg); - } - - for (i = 0; i < path.length; i++) { - fn(path[i], "bubbled", arg); +function forEachAccumulated(arr, cb, scope) { + if (Array.isArray(arr)) { + arr.forEach(cb, scope); + } else if (arr) { + cb.call(scope, arr); } } -/** - * 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. - */ /** * Some event types have a notion of different registration names for different @@ -1231,9 +867,9 @@ function listenerAtPhase(inst, event, propagationPhase) { function accumulateDirectionalDispatches(inst, phase, event) { { - !inst - ? warningWithoutStack$1(false, "Dispatching inst must not be null") - : void 0; + if (!inst) { + error("Dispatching inst must not be null"); + } } var listener = listenerAtPhase(inst, event, phase); @@ -1308,12 +944,10 @@ function accumulateTwoPhaseDispatches(events) { function accumulateTwoPhaseDispatchesSkipTarget(events) { forEachAccumulated(events, accumulateTwoPhaseDispatchesSingleSkipTarget); } - function accumulateDirectDispatches(events) { forEachAccumulated(events, accumulateDirectDispatchesSingle); } -/* eslint valid-typeof: 0 */ var EVENT_POOL_SIZE = 10; /** * @interface Event @@ -1592,19 +1226,17 @@ function getPooledWarningPropertyDefinition(propName, 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; + { + 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 + ); + } } } @@ -1749,15 +1381,14 @@ function getTouchIdentifier(_ref) { } { - !(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 (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 + ); + } } return identifier; @@ -1789,12 +1420,15 @@ function recordTouchMove(touch) { 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() - ); + { + warn( + "Cannot record touch move without a touch start.\n" + + "Touch Move: %s\n" + + "Touch Bank: %s", + printTouch(touch), + printTouchBank() + ); + } } } @@ -1811,12 +1445,15 @@ function recordTouchEnd(touch) { 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() - ); + { + warn( + "Cannot record touch end without a touch start.\n" + + "Touch End: %s\n" + + "Touch Bank: %s", + printTouch(touch), + printTouchBank() + ); + } } } @@ -1867,9 +1504,10 @@ var ResponderTouchHistoryStore = { { var activeRecord = touchBank[touchHistory.indexOfSingleActiveTouch]; - !(activeRecord != null && activeRecord.touchActive) - ? warningWithoutStack$1(false, "Cannot find single active touch.") - : void 0; + + if (activeRecord == null || !activeRecord.touchActive) { + error("Cannot find single active touch."); + } } } } @@ -2158,7 +1796,7 @@ to return true:wantsResponderID| | + + */ /** - * A note about event ordering in the `EventPluginHub`. + * A note about event ordering in the `EventPluginRegistry`. * * Suppose plugins are injected in the following order: * @@ -2177,7 +1815,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 `EventPluginHub` (hence the + * 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 @@ -2201,9 +1839,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 `EventPluginHub`) - * - `S`s extracted events (if any) (dispatched by `EventPluginHub`) - * - `C`s extracted events (if any) (dispatched by `EventPluginHub`) + * - `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 @@ -2212,9 +1850,9 @@ to return true:wantsResponderID| | * 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) + * - `touchStartCapture` (`EventPluginRegistry` dispatches as usual) + * - `touchStart` (`EventPluginRegistry` dispatches as usual) + * - `responderGrant/Reject` (`EventPluginRegistry` dispatches as usual) */ function setResponderAndExtractTransfer( @@ -2226,10 +1864,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 @@ -2398,108 +2036,330 @@ var ResponderEventPlugin = { if (trackedTouchCount >= 0) { trackedTouchCount -= 1; } else { - console.warn( - "Ended a touch event which was not counted in `trackedTouchCount`." - ); + { + 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`). + 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; + + 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; + } + } +}; + +/** + * 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 + */ + +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); + + if (!(pluginIndex > -1)) { + throw Error( + "EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + + pluginName + + "`." + ); + } + + if (plugins[pluginIndex]) { + continue; + } + + 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. - 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; + 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 + */ - if (incrementalTouch) { - var gesture = ResponderSyntheticEvent.getPooled( - incrementalTouch, - responderInst, - nativeEvent, - nativeEventTarget - ); - gesture.touchHistory = ResponderTouchHistoryStore.touchHistory; - accumulateDirectDispatches(gesture); - extracted = accumulate(extracted, gesture); +function injectEventPluginsByName(injectedNamesToPlugins) { + var isOrderingDirty = false; + + for (var pluginName in injectedNamesToPlugins) { + if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) { + continue; } - var isResponderTerminate = - responderInst && topLevelType === TOP_TOUCH_CANCEL; - var isResponderRelease = - responderInst && - !isResponderTerminate && - isEndish(topLevelType) && - noResponderTouches(nativeEvent); - var finalTouch = isResponderTerminate - ? eventTypes.responderTerminate - : isResponderRelease - ? eventTypes.responderRelease - : null; + var pluginModule = injectedNamesToPlugins[pluginName]; - if (finalTouch) { - var finalEvent = ResponderSyntheticEvent.getPooled( - finalTouch, - responderInst, - nativeEvent, - nativeEventTarget - ); - finalEvent.touchHistory = ResponderTouchHistoryStore.touchHistory; - accumulateDirectDispatches(finalEvent); - extracted = accumulate(extracted, finalEvent); - changeResponder(null); - } + if ( + !namesToPlugins.hasOwnProperty(pluginName) || + namesToPlugins[pluginName] !== pluginModule + ) { + if (!!namesToPlugins[pluginName]) { + throw Error( + "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + + pluginName + + "`." + ); + } - 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; + namesToPlugins[pluginName] = pluginModule; + isOrderingDirty = true; } } -}; + + if (isOrderingDirty) { + recomputePluginOrdering(); + } +} var customBubblingEventTypes = - ReactNativePrivateInterface.ReactNativeViewConfigRegistry - .customBubblingEventTypes; -var customDirectEventTypes = - ReactNativePrivateInterface.ReactNativeViewConfigRegistry - .customDirectEventTypes; + ReactNativePrivateInterface.ReactNativeViewConfigRegistry + .customBubblingEventTypes, + customDirectEventTypes = + ReactNativePrivateInterface.ReactNativeViewConfigRegistry + .customDirectEventTypes; var ReactNativeBridgeEventPlugin = { eventTypes: {}, - - /** - * @see {EventPluginHub.extractEvents} - */ extractEvents: function( topLevelType, targetInst, @@ -2551,46 +2411,21 @@ 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. */ -injection.injectEventPluginOrder(ReactNativeEventPluginOrder); +injectEventPluginOrder(ReactNativeEventPluginOrder); /** * Some important event plugins included by default (without having to require * them). */ -injection.injectEventPluginsByName({ +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) { @@ -2606,35 +2441,20 @@ function getInstanceFromTag(tag) { } function getTagFromInstance(inst) { - 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; - } + var nativeInstance = inst.stateNode; + var tag = nativeInstance._nativeTag; - if (!_tag) { - throw Error("All native instances should have a tag."); - } + if (tag === undefined) { + nativeInstance = nativeInstance.canonical; + tag = nativeInstance._nativeTag; + } - return _tag; + if (!tag) { + throw Error("All native instances should have a tag."); } -} + return nativeInstance; +} function getFiberCurrentPropsFromNode$1(stateNode) { return instanceProps.get(stateNode._nativeTag) || null; } @@ -2644,50 +2464,9 @@ function updateFiberProps(tag, props) { 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]); - } - } -} +var enableProfilerTimer = true; +var enableFundamentalAPI = false; +var warnAboutStringRefs = false; // 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 @@ -2698,25 +2477,7 @@ function restoreStateIfNeeded() { 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) { @@ -2731,11 +2492,8 @@ function batchedUpdates(fn, bookkeeping) { return batchedUpdatesImpl(fn, bookkeeping); } finally { isInsideEventHandler = false; - finishEventHandler(); } } -// This is for the React Flare event system - function setBatchingImplementation( _batchedUpdatesImpl, _discreteUpdatesImpl, @@ -2743,7 +2501,57 @@ function setBatchingImplementation( _batchedEventUpdatesImpl ) { batchedUpdatesImpl = _batchedUpdatesImpl; - flushDiscreteUpdatesImpl = _flushDiscreteUpdatesImpl; +} + +/** + * 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(); } /** @@ -2823,12 +2631,8 @@ function _receiveRootNodeIDEvent(rootNodeID, topLevelType, nativeEventParam) { var inst = getInstanceFromTag(rootNodeID); var target = null; - if (enableNativeTargetAsInstance) { - if (inst != null) { - target = inst.stateNode; - } - } else { - target = nativeEvent.target; + if (inst != null) { + target = inst.stateNode; } batchedUpdates(function() { @@ -2842,6 +2646,61 @@ 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. @@ -2898,10 +2757,7 @@ function receiveTouches(eventTopLevelType, touches, changedIndices) { if (target !== null && target !== undefined) { if (target < 1) { { - warningWithoutStack$1( - false, - "A view is reporting that a touch occurred on tag zero." - ); + error("A view is reporting that a touch occurred on tag zero."); } } else { rootNodeID = target; @@ -2953,38 +2809,13 @@ 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; @@ -2997,8 +2828,6 @@ 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; @@ -3011,11 +2840,7 @@ 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_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 REACT_BLOCK_TYPE = hasSymbol ? Symbol.for("react.block") : 0xead9; var MAYBE_ITERATOR_SYMBOL = typeof Symbol === "function" && Symbol.iterator; var FAUX_ITERATOR_SYMBOL = "@@iterator"; function getIteratorFn(maybeIterable) { @@ -3034,56 +2859,29 @@ function getIteratorFn(maybeIterable) { return null; } -/** - * 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; - +// TODO: Move this to "react" once we can import from externals. 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) { - lazyComponent._status = Pending; - var ctor = lazyComponent._ctor; - var thenable = ctor(); - lazyComponent._result = thenable; + 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; thenable.then( function(moduleObject) { if (lazyComponent._status === Pending) { @@ -3091,24 +2889,27 @@ function initializeLazyComponentType(lazyComponent) { { if (defaultExport === undefined) { - warning$1( - false, + error( "lazy: Expected the result of a dynamic import() call. " + - "Instead received: %s\n\nYour code should look like: \n " + - "const MyComponent = lazy(() => import('./MyComponent'))", + "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'))", moduleObject ); } - } + } // Transition to the next state. - lazyComponent._status = Resolved; - lazyComponent._result = defaultExport; + var resolved = lazyComponent; + resolved._status = Resolved; + resolved._result = defaultExport; } }, function(error) { if (lazyComponent._status === Pending) { - lazyComponent._status = Rejected; - lazyComponent._result = error; + // Transition to the next state. + var rejected = lazyComponent; + rejected._status = Rejected; + rejected._result = error; } } ); @@ -3123,6 +2924,10 @@ 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. @@ -3131,8 +2936,7 @@ function getComponentName(type) { { if (typeof type.tag === "number") { - warningWithoutStack$1( - false, + error( "Received an unexpected object in getComponentName(). " + "This is likely a bug in React. Please file an issue." ); @@ -3170,10 +2974,12 @@ function getComponentName(type) { if (typeof type === "object") { switch (type.$$typeof) { case REACT_CONTEXT_TYPE: - return "Context.Consumer"; + var context = type; + return getContextName(context) + ".Consumer"; case REACT_PROVIDER_TYPE: - return "Context.Provider"; + var provider = type; + return getContextName(provider._context) + ".Provider"; case REACT_FORWARD_REF_TYPE: return getWrappedName(type, type.render, "ForwardRef"); @@ -3181,6 +2987,9 @@ 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); @@ -3256,7 +3065,7 @@ var ShouldCapture = /* */ 4096; -var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner; +var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner; function getNearestMountedFiber(fiber) { var node = fiber; var nearestMounted = fiber; @@ -3293,28 +3102,28 @@ function getNearestMountedFiber(fiber) { return null; } - function isFiberMounted(fiber) { return getNearestMountedFiber(fiber) === fiber; } function isMounted(component) { { - var owner = ReactCurrentOwner$1.current; + var owner = ReactCurrentOwner.current; if (owner !== null && owner.tag === ClassComponent) { var ownerFiber = owner; var instance = ownerFiber.stateNode; - !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; + + 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 = true; } } @@ -4017,71 +3826,49 @@ 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 + - ": ... } }`" - ); + { + 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 + ); + } } } } -// 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) { + function ReactNativeFiberHostComponent( + tag, + viewConfig, + internalInstanceHandleDEV + ) { this._nativeTag = tag; this._children = []; this.viewConfig = viewConfig; + + { + this._internalFiberInstanceHandleDEV = internalInstanceHandleDEV; + } } var _proto = ReactNativeFiberHostComponent.prototype; _proto.blur = function blur() { - ReactNativePrivateInterface.TextInputState.blurTextInput(this._nativeTag); + ReactNativePrivateInterface.TextInputState.blurTextInput(this); }; _proto.focus = function focus() { - ReactNativePrivateInterface.TextInputState.focusTextInput( - this._nativeTag - ); + ReactNativePrivateInterface.TextInputState.focusTextInput(this); }; _proto.measure = function measure(callback) { @@ -4109,15 +3896,21 @@ var ReactNativeFiberHostComponent = if (typeof relativeToNativeNode === "number") { // Already a node handle relativeNode = relativeToNativeNode; - } else if (relativeToNativeNode._nativeTag) { - relativeNode = relativeToNativeNode._nativeTag; + } else { + var nativeNode = relativeToNativeNode; + + if (nativeNode._nativeTag) { + relativeNode = nativeNode._nativeTag; + } } if (relativeNode == null) { - warningWithoutStack$1( - false, - "Warning: ref.measureLayout must be called with a node handle or a ref to a native component." - ); + { + error( + "Warning: ref.measureLayout must be called with a node handle or a ref to a native component." + ); + } + return; } @@ -4153,60 +3946,15 @@ 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 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 isSuspenseInstancePending = shim; +var isSuspenseInstanceFallback = shim; +var hydrateTextInstance = shim; var getViewConfigForType = ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get; @@ -4241,7 +3989,6 @@ function recursivelyUncacheFiberNode(node) { node._children.forEach(recursivelyUncacheFiberNode); } } - function appendInitialChild(parentInstance, child) { parentInstance._children.push(child); } @@ -4272,7 +4019,11 @@ function createInstance( rootContainerInstance, // rootTag updatePayload // props ); - var component = new ReactNativeFiberHostComponent(tag, viewConfig); + var component = new ReactNativeFiberHostComponent( + tag, + viewConfig, + internalInstanceHandle + ); precacheFiberNode(internalInstanceHandle, tag); updateFiberProps(tag, props); // Not sure how to avoid this cast. Flow is okay if the component is defined // in the same file but if it's external it can't see the types. @@ -4367,8 +4118,6 @@ function prepareUpdate( function resetAfterCommit(containerInfo) { // Noop } -var isPrimaryRenderer = true; -var warnsIfNotActing = true; var scheduleTimeout = setTimeout; var cancelTimeout = clearTimeout; var noTimeout = -1; @@ -4384,10 +4133,6 @@ 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; @@ -4432,7 +4177,6 @@ function commitTextUpdate(textInstance, oldText, newText) { } // props ); } - function commitUpdate( instance, updatePayloadTODO, @@ -4565,154 +4309,79 @@ 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 = ""; - 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); +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 (match) { - var pathBeforeSlash = match[1]; + 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 (pathBeforeSlash) { - var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, ""); - fileName = folderName + "/" + fileName; + 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; } - } - } - } - - sourceInfo = " (at " + fileName + ":" + source.lineNumber + ")"; - } else if (ownerName) { - sourceInfo = " (created by " + ownerName + ")"; - } - - return "\n in " + (name || "Unknown") + sourceInfo; -}; -var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; + error$1 = typeSpecs[typeSpecName]( + values, + typeSpecName, + componentName, + location, + null, + "SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED" + ); + } catch (ex) { + error$1 = ex; + } -function describeFiber(fiber) { - switch (fiber.tag) { - case HostRoot: - case HostPortal: - case HostText: - case Fragment: - case ContextProvider: - case ContextConsumer: - return ""; + 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 + ); + } - default: - var owner = fiber._debugOwner; - var source = fiber._debugSource; - var name = getComponentName(fiber.type); - var ownerName = null; + if ( + error$1 instanceof Error && + !(error$1.message in loggedTypeFailures) + ) { + // Only monitor this failure once because there tends to be a lot of the + // same error. + loggedTypeFailures[error$1.message] = true; - if (owner) { - ownerName = getComponentName(owner.type); + error("Failed %s type: %s", location, error$1.message); + } } - - 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. @@ -4891,12 +4560,12 @@ var resumeTimers = function() { }; function recordEffect() { - if (enableUserTimingAPI) { + { effectCountInCurrentCommit++; } } function recordScheduleUpdate() { - if (enableUserTimingAPI) { + { if (isCommitting) { hasScheduledUpdateInCurrentCommit = true; } @@ -4910,9 +4579,8 @@ function recordScheduleUpdate() { } } } - function startWorkTimer(fiber) { - if (enableUserTimingAPI) { + { if (!supportsUserTiming || shouldIgnoreFiber(fiber)) { return; } // If we pause, this is the fiber to unwind from. @@ -4927,7 +4595,7 @@ function startWorkTimer(fiber) { } } function cancelWorkTimer(fiber) { - if (enableUserTimingAPI) { + { if (!supportsUserTiming || shouldIgnoreFiber(fiber)) { return; } // Remember we shouldn't complete measurement for this fiber. @@ -4938,7 +4606,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. @@ -4954,7 +4622,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. @@ -4974,7 +4642,7 @@ function stopFailedWorkTimer(fiber) { } } function startPhaseTimer(fiber, phase) { - if (enableUserTimingAPI) { + { if (!supportsUserTiming) { return; } @@ -4990,7 +4658,7 @@ function startPhaseTimer(fiber, phase) { } } function stopPhaseTimer() { - if (enableUserTimingAPI) { + { if (!supportsUserTiming) { return; } @@ -5007,7 +4675,7 @@ function stopPhaseTimer() { } } function startWorkLoopTimer(nextUnitOfWork) { - if (enableUserTimingAPI) { + { currentFiber = nextUnitOfWork; if (!supportsUserTiming) { @@ -5023,7 +4691,7 @@ function startWorkLoopTimer(nextUnitOfWork) { } } function stopWorkLoopTimer(interruptedBy, didCompleteRoot) { - if (enableUserTimingAPI) { + { if (!supportsUserTiming) { return; } @@ -5052,7 +4720,7 @@ function stopWorkLoopTimer(interruptedBy, didCompleteRoot) { } } function startCommitTimer() { - if (enableUserTimingAPI) { + { if (!supportsUserTiming) { return; } @@ -5064,7 +4732,7 @@ function startCommitTimer() { } } function stopCommitTimer() { - if (enableUserTimingAPI) { + { if (!supportsUserTiming) { return; } @@ -5085,7 +4753,7 @@ function stopCommitTimer() { } } function startCommitSnapshotEffectsTimer() { - if (enableUserTimingAPI) { + { if (!supportsUserTiming) { return; } @@ -5095,7 +4763,7 @@ function startCommitSnapshotEffectsTimer() { } } function stopCommitSnapshotEffectsTimer() { - if (enableUserTimingAPI) { + { if (!supportsUserTiming) { return; } @@ -5110,7 +4778,7 @@ function stopCommitSnapshotEffectsTimer() { } } function startCommitHostEffectsTimer() { - if (enableUserTimingAPI) { + { if (!supportsUserTiming) { return; } @@ -5120,7 +4788,7 @@ function startCommitHostEffectsTimer() { } } function stopCommitHostEffectsTimer() { - if (enableUserTimingAPI) { + { if (!supportsUserTiming) { return; } @@ -5135,7 +4803,7 @@ function stopCommitHostEffectsTimer() { } } function startCommitLifeCyclesTimer() { - if (enableUserTimingAPI) { + { if (!supportsUserTiming) { return; } @@ -5145,7 +4813,7 @@ function startCommitLifeCyclesTimer() { } } function stopCommitLifeCyclesTimer() { - if (enableUserTimingAPI) { + { if (!supportsUserTiming) { return; } @@ -5178,7 +4846,7 @@ function createCursor(defaultValue) { function pop(cursor, fiber) { if (index < 0) { { - warningWithoutStack$1(false, "Unexpected pop."); + error("Unexpected pop."); } return; @@ -5186,7 +4854,7 @@ function pop(cursor, fiber) { { if (fiber !== fiberStack[index]) { - warningWithoutStack$1(false, "Unexpected Fiber popped."); + error("Unexpected Fiber popped."); } } @@ -5236,9 +4904,7 @@ 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 @@ -5252,9 +4918,7 @@ function getUnmaskedContext( } function cacheContext(workInProgress, unmaskedContext, maskedContext) { - if (disableLegacyContext) { - return; - } else { + { var instance = workInProgress.stateNode; instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext; instance.__reactInternalMemoizedMaskedChildContext = maskedContext; @@ -5262,9 +4926,7 @@ function cacheContext(workInProgress, unmaskedContext, maskedContext) { } function getMaskedContext(workInProgress, unmaskedContext) { - if (disableLegacyContext) { - return emptyContextObject; - } else { + { var type = workInProgress.type; var contextTypes = type.contextTypes; @@ -5291,13 +4953,7 @@ function getMaskedContext(workInProgress, unmaskedContext) { { var name = getComponentName(type) || "Unknown"; - checkPropTypes( - contextTypes, - context, - "context", - name, - getCurrentFiberStackInDev - ); + checkPropTypes(contextTypes, context, "context", name); } // Cache unmasked context so we can avoid recreating masked context unless necessary. // Context is created before the class component is instantiated so check for instance. @@ -5310,44 +4966,34 @@ 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." @@ -5360,9 +5006,7 @@ 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. @@ -5373,8 +5017,8 @@ function processChildContext(fiber, type, parentContext) { if (!warnedAboutMissingGetChildContext[componentName]) { warnedAboutMissingGetChildContext[componentName] = true; - warningWithoutStack$1( - false, + + error( "%s.childContextTypes is specified but there is no getChildContext() method " + "on the instance. You can either define getChildContext() on %s or remove " + "childContextTypes from it.", @@ -5388,19 +5032,10 @@ 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( @@ -5414,17 +5049,7 @@ function processChildContext(fiber, type, parentContext) { { var name = getComponentName(type) || "Unknown"; - 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 - ); + checkPropTypes(childContextTypes, childContext, "child context", name); } return Object.assign({}, parentContext, {}, childContext); @@ -5432,9 +5057,7 @@ 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. @@ -5456,9 +5079,7 @@ function pushContextProvider(workInProgress) { } function invalidateContextProvider(workInProgress, type, didChange) { - if (disableLegacyContext) { - return; - } else { + { var instance = workInProgress.stateNode; if (!instance) { @@ -5492,9 +5113,7 @@ 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)) { @@ -5537,22 +5156,21 @@ var BlockingRoot = 1; var ConcurrentRoot = 2; // Intentionally not named imports because Rollup would use dynamic dispatch for -// 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) { +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; + +{ // Provide explicit error message when production+profiling bundle of e.g. // react-dom is used with production (non-profiling) bundle of // scheduler/tracing @@ -5746,14 +5364,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 a moving priority. It is slightly higher than Idle +var Idle = 2; // Continuous Hydration is slightly higher than Idle and is used to increase 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 add an offset so that we don't clash with the magic number for NoWork. + // Always subtract from the offset so that we don't clash with the magic number for NoWork. return MAGIC_NUMBER_OFFSET - ((ms / UNIT_SIZE) | 0); } function expirationTimeToMs(expirationTime) { @@ -5812,7 +5430,6 @@ function computeInteractiveExpiration(currentTime) { HIGH_PRIORITY_BATCH_SIZE ); } - function inferPriorityFromExpirationTime(currentTime, expirationTime) { if (expirationTime === Sync) { return ImmediatePriority; @@ -5851,7 +5468,7 @@ function is(x, y) { ); } -var is$1 = typeof Object.is === "function" ? Object.is : is; +var objectIs = typeof Object.is === "function" ? Object.is : is; var hasOwnProperty = Object.prototype.hasOwnProperty; /** @@ -5861,7 +5478,7 @@ var hasOwnProperty = Object.prototype.hasOwnProperty; */ function shallowEqual(objA, objB) { - if (is$1(objA, objB)) { + if (objectIs(objA, objB)) { return true; } @@ -5884,7 +5501,7 @@ function shallowEqual(objA, objB) { for (var i = 0; i < keysA.length; i++) { if ( !hasOwnProperty.call(objB, keysA[i]) || - !is$1(objA[keysA[i]], objB[keysA[i]]) + !objectIs(objA[keysA[i]], objB[keysA[i]]) ) { return false; } @@ -5893,77 +5510,122 @@ function shallowEqual(objA, objB) { return true; } -/** - * 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() {}; +var BEFORE_SLASH_RE = /^(.*)[\\\/]/; +function describeComponentFrame(name, source, ownerName) { + var sourceInfo = ""; -{ - 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]; - } + if (source) { + var path = source.fileName; + var fileName = path.replace(BEFORE_SLASH_RE, ""); - var argIndex = 0; - var message = - "Warning: " + - format.replace(/%s/g, function() { - return args[argIndex++]; - }); + { + // 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 (typeof console !== "undefined") { - console.warn(message); + if (match) { + var pathBeforeSlash = match[1]; + + if (pathBeforeSlash) { + var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, ""); + fileName = folderName + "/" + fileName; + } + } + } } - 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) {} - }; + sourceInfo = " (at " + fileName + ":" + source.lineNumber + ")"; + } else if (ownerName) { + sourceInfo = " (created by " + ownerName + ")"; + } - lowPriorityWarningWithoutStack = function(condition, format) { - if (format === undefined) { - throw new Error( - "`lowPriorityWarningWithoutStack(condition, format, ...args)` requires a warning " + - "message argument" - ); - } + return "\n in " + (name || "Unknown") + sourceInfo; +} - 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]; +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); } - printWarning.apply(void 0, [format].concat(args)); + 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 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. -var lowPriorityWarningWithoutStack$1 = lowPriorityWarningWithoutStack; + 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 ReactStrictModeWarnings = { recordUnsafeLifecycleWarnings: function(fiber, instance) {}, @@ -6135,8 +5797,8 @@ var ReactStrictModeWarnings = { if (UNSAFE_componentWillMountUniqueNames.size > 0) { var sortedNames = setToSortedString(UNSAFE_componentWillMountUniqueNames); - warningWithoutStack$1( - false, + + error( "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" + @@ -6150,8 +5812,7 @@ var ReactStrictModeWarnings = { UNSAFE_componentWillReceivePropsUniqueNames ); - warningWithoutStack$1( - false, + error( "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" + @@ -6169,8 +5830,7 @@ var ReactStrictModeWarnings = { UNSAFE_componentWillUpdateUniqueNames ); - warningWithoutStack$1( - false, + error( "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" + @@ -6183,8 +5843,7 @@ var ReactStrictModeWarnings = { if (componentWillMountUniqueNames.size > 0) { var _sortedNames3 = setToSortedString(componentWillMountUniqueNames); - lowPriorityWarningWithoutStack$1( - false, + warn( "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" + @@ -6202,8 +5861,7 @@ var ReactStrictModeWarnings = { componentWillReceivePropsUniqueNames ); - lowPriorityWarningWithoutStack$1( - false, + warn( "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" + @@ -6222,8 +5880,7 @@ var ReactStrictModeWarnings = { if (componentWillUpdateUniqueNames.size > 0) { var _sortedNames5 = setToSortedString(componentWillUpdateUniqueNames); - lowPriorityWarningWithoutStack$1( - false, + warn( "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" + @@ -6248,11 +5905,11 @@ var ReactStrictModeWarnings = { var strictRoot = findStrictRoot(fiber); if (strictRoot === null) { - warningWithoutStack$1( - false, + error( "Expected to find a StrictMode component in a strict mode tree. " + "This error is likely caused by a bug in React. Please file an issue." ); + return; } // Dedup strategy: Warn once per component. @@ -6278,15 +5935,20 @@ 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 strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot); - warningWithoutStack$1( - false, + var firstComponentStack = getStackByFiberInDevAndProd(firstFiber); + + error( "Legacy context API has been detected within a strict-mode tree." + "\n\nThe old API will be supported in all 16.x releases, but applications " + "using it should migrate to the new version." + @@ -6294,7 +5956,7 @@ var ReactStrictModeWarnings = { "\n\nLearn more about this warning here: https://fb.me/react-legacy-context" + "%s", sortedNames, - strictRootComponentStack + firstComponentStack ); }); }; @@ -6537,9 +6199,6 @@ function scheduleFibersWithFamiliesRecursively( case ForwardRef: candidateType = type.render; break; - - default: - break; } if (resolveFamily === null) { @@ -6639,9 +6298,6 @@ function findHostInstancesForMatchingFibersRecursively( case ForwardRef: candidateType = type.render; break; - - default: - break; } var didMatch = false; @@ -6814,41 +6470,23 @@ 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._currentRenderer !== undefined && + context._currentRenderer !== null && + context._currentRenderer !== 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; + context._currentRenderer = rendererSigil; } } } @@ -6857,14 +6495,12 @@ 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 (is$1(oldValue, newValue)) { + if (objectIs(oldValue, newValue)) { // No change return 0; } else { @@ -6874,14 +6510,13 @@ function calculateChangedBits(context, newValue, oldValue) { : MAX_SIGNED_31_BIT_INT; { - !((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; + if ((changedBits & MAX_SIGNED_31_BIT_INT) !== changedBits) { + error( + "calculateChangedBits: Expected the return value to be a " + + "31-bit integer. Instead received: %s", + changedBits + ); + } } return changedBits | 0; @@ -6986,39 +6621,6 @@ 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; @@ -7077,22 +6679,19 @@ 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. - !!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 (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()." + ); + } } - 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 { + if (lastContextWithAllBitsObserved === context); + else if (observedBits === false || observedBits === 0); + else { var resolvedObservedBits; // Avoid deopting on observable arguments or heterogeneous types. if ( @@ -7131,85 +6730,9 @@ function readContext(context, observedBits) { } } - return isPrimaryRenderer ? context._currentValue : context._currentValue2; + return context._currentValue; } -// 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; @@ -7226,38 +6749,32 @@ var currentlyProcessingQueue; currentlyProcessingQueue = null; } -function createUpdateQueue(baseState) { +function initializeUpdateQueue(fiber) { var queue = { - baseState: baseState, - firstUpdate: null, - lastUpdate: null, - firstCapturedUpdate: null, - lastCapturedUpdate: null, - firstEffect: null, - lastEffect: null, - firstCapturedEffect: null, - lastCapturedEffect: null - }; - 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 + baseState: fiber.memoizedState, + baseQueue: null, + shared: { + pending: null + }, + effects: null }; - return queue; + 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; + } } - function createUpdate(expirationTime, suspenseConfig) { var update = { expirationTime: expirationTime, @@ -7265,9 +6782,9 @@ function createUpdate(expirationTime, suspenseConfig) { tag: UpdateState, payload: null, callback: null, - next: null, - nextEffect: null + next: null }; + update.next = update; { update.priority = getCurrentPriorityLevel(); @@ -7275,136 +6792,62 @@ function createUpdate(expirationTime, suspenseConfig) { return update; } +function enqueueUpdate(fiber, update) { + var updateQueue = fiber.updateQueue; -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; + if (updateQueue === null) { + // Only occurs if the fiber has been unmounted. + return; } -} - -function enqueueUpdate(fiber, update) { - // Update queues are created lazily. - var alternate = fiber.alternate; - var queue1; - var queue2; - if (alternate === null) { - // There's only one fiber. - queue1 = fiber.updateQueue; - queue2 = null; + var sharedQueue = updateQueue.shared; + var pending = sharedQueue.pending; - if (queue1 === null) { - queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState); - } + if (pending === null) { + // This is the first update. Create a circular list. + update.next = update; } else { - // 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. - } - } + update.next = pending.next; + pending.next = 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; - } - } + sharedQueue.pending = update; { if ( - fiber.tag === ClassComponent && - (currentlyProcessingQueue === queue1 || - (queue2 !== null && currentlyProcessingQueue === queue2)) && + currentlyProcessingQueue === sharedQueue && !didWarnUpdateInsideUpdate ) { - warningWithoutStack$1( - false, + error( "An update (setState, replaceState, or forceUpdate) was scheduled " + "from inside an update function. Update functions should be pure, " + "with zero side-effects. Consider using componentDidUpdate or a " + "callback." ); + didWarnUpdateInsideUpdate = true; } } } function enqueueCapturedUpdate(workInProgress, update) { - // Captured updates go into a separate list, and only on the work-in- - // progress queue. - var workInProgressQueue = workInProgress.updateQueue; + var current = workInProgress.alternate; - 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 (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.lastCapturedUpdate === null) { - // This is the first render phase update - workInProgressQueue.firstCapturedUpdate = workInProgressQueue.lastCapturedUpdate = update; - } else { - workInProgressQueue.lastCapturedUpdate.next = update; - workInProgressQueue.lastCapturedUpdate = update; - } -} + var queue = workInProgress.updateQueue; // Append the update to the end of the list. -function ensureWorkInProgressQueueIsAClone(workInProgress, queue) { - var current = workInProgress.alternate; + var last = queue.baseQueue; - 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); - } + if (last === null) { + queue.baseQueue = update.next = update; + update.next = update; + } else { + update.next = last.next; + last.next = update; } - - return queue; } function getStateFromUpdate( @@ -7423,13 +6866,6 @@ function getStateFromUpdate( // Updater function { enterDisallowedContextReadInDEV(); - - if ( - debugRenderPhaseSideEffectsForStrictMode && - workInProgress.mode & StrictMode - ) { - payload.call(instance, prevState, nextProps); - } } var nextState = payload.call(instance, prevState, nextProps); @@ -7458,13 +6894,6 @@ function getStateFromUpdate( // Updater function { enterDisallowedContextReadInDEV(); - - if ( - debugRenderPhaseSideEffectsForStrictMode && - workInProgress.mode & StrictMode - ) { - _payload.call(instance, prevState, nextProps); - } } partialState = _payload.call(instance, prevState, nextProps); @@ -7496,163 +6925,171 @@ 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; - } // These values may change as we process the 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. - var newBaseState = queue.baseState; - var newFirstUpdate = null; - var newExpirationTime = NoWork; // Iterate through the list of updates to compute the result. + var pendingQueue = queue.shared.pending; - var update = queue.firstUpdate; - var resultState = newBaseState; + 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; + } - while (update !== null) { - var updateExpirationTime = update.expirationTime; + baseQueue = pendingQueue; + queue.shared.pending = null; // TODO: Pass `current` as argument - 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. + var current = workInProgress.alternate; - newBaseState = resultState; - } // Since this update will remain in the list, update the remaining - // expiration time. + if (current !== null) { + var currentQueue = current.updateQueue; - if (newExpirationTime < updateExpirationTime) { - newExpirationTime = updateExpirationTime; + if (currentQueue !== null) { + currentQueue.baseQueue = pendingQueue; } - } 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; + } + } // These values may change as we process the queue. - if (callback !== null) { - workInProgress.effectTag |= Callback; // Set this to null, in case it was mutated during an aborted render. + if (baseQueue !== null) { + var first = baseQueue.next; // Iterate through the list of updates to compute the result. - update.nextEffect = null; + var newState = queue.baseState; + var newExpirationTime = NoWork; + var newBaseState = null; + var newBaseQueueFirst = null; + var newBaseQueueLast = null; - if (queue.lastEffect === null) { - queue.firstEffect = queue.lastEffect = update; - } else { - queue.lastEffect.nextEffect = update; - queue.lastEffect = update; - } - } - } // Continue to the next update. + if (first !== null) { + var update = first; - update = update.next; - } // Separately, iterate though the list of captured updates. + 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 + }; - var newFirstCapturedUpdate = null; - update = queue.firstCapturedUpdate; + if (newBaseQueueLast === null) { + newBaseQueueFirst = newBaseQueueLast = clone; + newBaseState = newState; + } else { + newBaseQueueLast = newBaseQueueLast.next = clone; + } // Update the remaining priority in the queue. - while (update !== null) { - var _updateExpirationTime = update.expirationTime; + 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; - 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 (callback !== null) { + workInProgress.effectTag |= Callback; + var effects = queue.effects; - if (newFirstUpdate === null) { - newBaseState = resultState; + if (effects === null) { + queue.effects = [update]; + } else { + effects.push(update); + } + } } - } // 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; - if (_callback !== null) { - workInProgress.effectTag |= Callback; // Set this to null, in case it was mutated during an aborted render. + update = update.next; - update.nextEffect = null; + if (update === null || update === first) { + pendingQueue = queue.shared.pending; - if (queue.lastCapturedEffect === null) { - queue.firstCapturedEffect = queue.lastCapturedEffect = update; - } else { - queue.lastCapturedEffect.nextEffect = update; - queue.lastCapturedEffect = update; + 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; + } } - } + } while (true); } - update = update.next; - } - - if (newFirstUpdate === null) { - queue.lastUpdate = null; - } + if (newBaseQueueLast === null) { + newBaseState = newState; + } else { + newBaseQueueLast.next = newBaseQueueFirst; + } - if (newFirstCapturedUpdate === null) { - queue.lastCapturedUpdate = null; - } else { - workInProgress.effectTag |= Callback; - } + 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 && newFirstCapturedUpdate === null) { - // We processed every update, without skipping. That means the new base - // state is the same as the result state. - newBaseState = resultState; + markUnprocessedUpdateTime(newExpirationTime); + workInProgress.expirationTime = newExpirationTime; + workInProgress.memoizedState = newState; } - 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; } @@ -7675,42 +7112,21 @@ function resetHasForceUpdateBeforeProcessing() { function checkHasForceUpdateAfterProcessing() { return hasForceUpdate; } -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; -} +function commitUpdateQueue(finishedWork, finishedQueue, instance) { + // Commit the effects + var effects = finishedQueue.effects; + finishedQueue.effects = null; -function commitUpdateEffects(effect, instance) { - while (effect !== null) { - var callback = effect.callback; + if (effects !== null) { + for (var i = 0; i < effects.length; i++) { + var effect = effects[i]; + 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; } } @@ -7720,7 +7136,7 @@ function requestCurrentSuspenseConfig() { } var fakeInternalInstance = {}; -var isArray$1 = Array.isArray; // React.Component uses a shared frozen object by default. +var isArray = Array.isArray; // React.Component uses a shared frozen object by default. // We'll use it to determine whether we need to initialize legacy refs. var emptyRefsObject = new React.Component().refs; @@ -7755,8 +7171,8 @@ var didWarnAboutInvalidateContextType; if (!didWarnOnInvalidCallback.has(key)) { didWarnOnInvalidCallback.add(key); - warningWithoutStack$1( - false, + + error( "%s(...): Expected the last optional `callback` argument to be a " + "function. Instead received: %s.", callerName, @@ -7771,8 +7187,8 @@ var didWarnAboutInvalidateContextType; if (!didWarnAboutUndefinedDerivedState.has(componentName)) { didWarnAboutUndefinedDerivedState.add(componentName); - warningWithoutStack$1( - false, + + error( "%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. " + "You have returned undefined.", componentName @@ -7806,16 +7222,6 @@ 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); { @@ -7829,9 +7235,9 @@ function applyDerivedStateFromProps( workInProgress.memoizedState = memoizedState; // Once the update queue is empty, persist the derived state onto the // base state. - var updateQueue = workInProgress.updateQueue; - - if (updateQueue !== null && workInProgress.expirationTime === NoWork) { + if (workInProgress.expirationTime === NoWork) { + // Queue is always non-null for classes + var updateQueue = workInProgress.updateQueue; updateQueue.baseState = memoizedState; } } @@ -7930,14 +7336,13 @@ function checkShouldComponentUpdate( stopPhaseTimer(); { - !(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; + if (shouldUpdate === undefined) { + error( + "%s.shouldComponentUpdate(): Returned undefined instead of a " + + "boolean value. Make sure to return true or false.", + getComponentName(ctor) || "Component" + ); + } } return shouldUpdate; @@ -7961,15 +7366,13 @@ function checkClassInstance(workInProgress, ctor, newProps) { if (!renderPresent) { if (ctor.prototype && typeof ctor.prototype.render === "function") { - warningWithoutStack$1( - false, + error( "%s(...): No `render` method found on the returned component " + "instance: did you accidentally return an object from the constructor?", name ); } else { - warningWithoutStack$1( - false, + error( "%s(...): No `render` method found on the returned component " + "instance: you may have forgotten to define `render`.", name @@ -7977,78 +7380,55 @@ function checkClassInstance(workInProgress, ctor, newProps) { } } - 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.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 (ctor.contextTypes) { - warningWithoutStack$1( - false, - "%s uses the legacy contextTypes API which is no longer supported. " + - "Use React.createContext() with static contextType instead.", + { + if (instance.contextTypes) { + error( + "contextTypes was defined as an instance property on %s. Use a static " + + "property to define contextTypes 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 && @@ -8056,8 +7436,8 @@ function checkClassInstance(workInProgress, ctor, newProps) { !didWarnAboutContextTypeAndContextTypes.has(ctor) ) { didWarnAboutContextTypeAndContextTypes.add(ctor); - warningWithoutStack$1( - false, + + error( "%s declares both contextTypes and contextType static properties. " + "The legacy contextTypes property will be ignored.", name @@ -8065,26 +7445,22 @@ function checkClassInstance(workInProgress, ctor, newProps) { } } - 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 (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 + ); + } if ( ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== "undefined" ) { - warningWithoutStack$1( - false, + error( "%s has a method called shouldComponentUpdate(). " + "shouldComponentUpdate should not be used when extending React.PureComponent. " + "Please extend React.Component if shouldComponentUpdate is used.", @@ -8092,70 +7468,61 @@ function checkClassInstance(workInProgress, ctor, newProps) { ); } - 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; + 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 hasMutatedProps = instance.props !== newProps; - !(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 (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 + ); + } if ( typeof instance.getSnapshotBeforeUpdate === "function" && @@ -8163,63 +7530,53 @@ function checkClassInstance(workInProgress, ctor, newProps) { !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor) ) { didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor); - warningWithoutStack$1( - false, + + error( "%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). " + "This component defines getSnapshotBeforeUpdate() only.", getComponentName(ctor) ); } - 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 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 (_state && (typeof _state !== "object" || isArray$1(_state))) { - warningWithoutStack$1( - false, - "%s.state: must be set to an object or null", + 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 ); } - 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; + 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 + ); } } } @@ -8235,12 +7592,7 @@ function adoptClassInstance(workInProgress, instance) { } } -function constructClassInstance( - workInProgress, - ctor, - props, - renderExpirationTime -) { +function constructClassInstance(workInProgress, ctor, props) { var isLegacyContextConsumer = false; var unmaskedContext = emptyContextObject; var context = emptyContextObject; @@ -8278,8 +7630,7 @@ function constructClassInstance( "}."; } - warningWithoutStack$1( - false, + error( "%s defines an invalid contextType. " + "contextType should point to the Context object returned by React.createContext().%s", getComponentName(ctor) || "Component", @@ -8291,7 +7642,7 @@ function constructClassInstance( if (typeof contextType === "object" && contextType !== null) { context = readContext(contextType); - } else if (!disableLegacyContext) { + } else { unmaskedContext = getUnmaskedContext(workInProgress, ctor, true); var contextTypes = ctor.contextTypes; isLegacyContextConsumer = @@ -8301,15 +7652,6 @@ function constructClassInstance( : 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 @@ -8323,8 +7665,8 @@ function constructClassInstance( if (!didWarnAboutUninitializedState.has(componentName)) { didWarnAboutUninitializedState.add(componentName); - warningWithoutStack$1( - false, + + error( "`%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`. " + @@ -8389,8 +7731,8 @@ function constructClassInstance( if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName)) { didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName); - warningWithoutStack$1( - false, + + error( "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" + @@ -8432,8 +7774,7 @@ function callComponentWillMount(workInProgress, instance) { if (oldState !== instance.state) { { - warningWithoutStack$1( - false, + error( "%s.componentWillMount(): Assigning directly to this.state is " + "deprecated (except inside a component's " + "constructor). Use setState instead.", @@ -8470,8 +7811,8 @@ function callComponentWillReceiveProps( if (!didWarnAboutStateAssignmentForComponent.has(componentName)) { didWarnAboutStateAssignmentForComponent.add(componentName); - warningWithoutStack$1( - false, + + error( "%s.componentWillReceiveProps(): Assigning directly to " + "this.state is deprecated (except inside a component's " + "constructor). Use setState instead.", @@ -8498,12 +7839,11 @@ 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); @@ -8515,8 +7855,8 @@ function mountClassInstance( if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) { didWarnAboutDirectlyAssigningPropsToState.add(componentName); - warningWithoutStack$1( - false, + + error( "%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.", @@ -8532,7 +7872,7 @@ function mountClassInstance( ); } - if (warnAboutDeprecatedLifecycles) { + { ReactStrictModeWarnings.recordUnsafeLifecycleWarnings( workInProgress, instance @@ -8540,19 +7880,8 @@ function mountClassInstance( } } - var updateQueue = workInProgress.updateQueue; - - if (updateQueue !== null) { - processUpdateQueue( - workInProgress, - updateQueue, - newProps, - instance, - renderExpirationTime - ); - instance.state = workInProgress.memoizedState; - } - + processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); + instance.state = workInProgress.memoizedState; var getDerivedStateFromProps = ctor.getDerivedStateFromProps; if (typeof getDerivedStateFromProps === "function") { @@ -8570,23 +7899,18 @@ function mountClassInstance( typeof ctor.getDerivedStateFromProps !== "function" && typeof instance.getSnapshotBeforeUpdate !== "function" && (typeof instance.UNSAFE_componentWillMount === "function" || - typeof instance.componentWillMount === "function") - ) { - callComponentWillMount(workInProgress, instance); // If we had additional state updates during this life-cycle, let's - // process them now. - - updateQueue = workInProgress.updateQueue; - - if (updateQueue !== null) { - processUpdateQueue( - workInProgress, - updateQueue, - newProps, - instance, - renderExpirationTime - ); - instance.state = workInProgress.memoizedState; - } + typeof instance.componentWillMount === "function") + ) { + 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; } if (typeof instance.componentDidMount === "function") { @@ -8609,7 +7933,7 @@ function resumeMountClassInstance( if (typeof contextType === "object" && contextType !== null) { nextContext = readContext(contextType); - } else if (!disableLegacyContext) { + } else { var nextLegacyUnmaskedContext = getUnmaskedContext( workInProgress, ctor, @@ -8645,18 +7969,8 @@ function resumeMountClassInstance( resetHasForceUpdateBeforeProcessing(); var oldState = workInProgress.memoizedState; var newState = (instance.state = oldState); - var updateQueue = workInProgress.updateQueue; - - if (updateQueue !== null) { - processUpdateQueue( - workInProgress, - updateQueue, - newProps, - instance, - renderExpirationTime - ); - newState = workInProgress.memoizedState; - } + processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); + newState = workInProgress.memoizedState; if ( oldProps === newProps && @@ -8746,6 +8060,7 @@ function updateClassInstance( renderExpirationTime ) { var instance = workInProgress.stateNode; + cloneUpdateQueue(current, workInProgress); var oldProps = workInProgress.memoizedProps; instance.props = workInProgress.type === workInProgress.elementType @@ -8757,7 +8072,7 @@ function updateClassInstance( if (typeof contextType === "object" && contextType !== null) { nextContext = readContext(contextType); - } else if (!disableLegacyContext) { + } else { var nextUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true); nextContext = getMaskedContext(workInProgress, nextUnmaskedContext); } @@ -8789,18 +8104,8 @@ function updateClassInstance( resetHasForceUpdateBeforeProcessing(); var oldState = workInProgress.memoizedState; var newState = (instance.state = oldState); - var updateQueue = workInProgress.updateQueue; - - if (updateQueue !== null) { - processUpdateQueue( - workInProgress, - updateQueue, - newProps, - instance, - renderExpirationTime - ); - newState = workInProgress.memoizedState; - } + processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); + newState = workInProgress.memoizedState; if ( oldProps === newProps && @@ -8962,8 +8267,8 @@ var warnForMissingKey = function(child) {}; } ownerHasKeyUseWarning[currentComponentErrorInfo] = true; - warning$1( - false, + + error( "Each child in a list should have a unique " + '"key" prop. See https://fb.me/react-warning-keys for ' + "more information." @@ -8971,9 +8276,9 @@ var warnForMissingKey = function(child) {}; }; } -var isArray = Array.isArray; +var isArray$1 = Array.isArray; -function coerceRef(returnFiber, current$$1, element) { +function coerceRef(returnFiber, current, element) { var mixedRef = element.ref; if ( @@ -8984,25 +8289,21 @@ function coerceRef(returnFiber, current$$1, 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) { + 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 + ) + ) { var componentName = getComponentName(returnFiber.type) || "Component"; if (!didWarnAboutStringRefs[componentName]) { - 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, + { + error( '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. " + @@ -9027,7 +8328,7 @@ function coerceRef(returnFiber, current$$1, element) { if (!(ownerFiber.tag === ClassComponent)) { throw Error( - "Function components cannot have refs. Did you mean to use React.forwardRef()?" + "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" ); } @@ -9045,12 +8346,12 @@ function coerceRef(returnFiber, current$$1, element) { var stringRef = "" + mixedRef; // Check if previous string ref matches new string ref if ( - current$$1 !== null && - current$$1.ref !== null && - typeof current$$1.ref === "function" && - current$$1.ref._stringRef === stringRef + current !== null && + current.ref !== null && + typeof current.ref === "function" && + current.ref._stringRef === stringRef ) { - return current$$1.ref; + return current.ref; } var ref = function(value) { @@ -9115,23 +8416,25 @@ 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; - } + 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." - ); + 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." + ); + } } // 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 @@ -9198,10 +8501,10 @@ function ChildReconciler(shouldTrackSideEffects) { return existingChildren; } - function useFiber(fiber, pendingProps, expirationTime) { + function useFiber(fiber, pendingProps) { // 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, expirationTime); + var clone = createWorkInProgress(fiber, pendingProps); clone.index = 0; clone.sibling = null; return clone; @@ -9215,10 +8518,10 @@ function ChildReconciler(shouldTrackSideEffects) { return lastPlacedIndex; } - var current$$1 = newFiber.alternate; + var current = newFiber.alternate; - if (current$$1 !== null) { - var oldIndex = current$$1.index; + if (current !== null) { + var oldIndex = current.index; if (oldIndex < lastPlacedIndex) { // This is a move. @@ -9245,13 +8548,8 @@ function ChildReconciler(shouldTrackSideEffects) { return newFiber; } - function updateTextNode( - returnFiber, - current$$1, - textContent, - expirationTime - ) { - if (current$$1 === null || current$$1.tag !== HostText) { + function updateTextNode(returnFiber, current, textContent, expirationTime) { + if (current === null || current.tag !== HostText) { // Insert var created = createFiberFromText( textContent, @@ -9262,48 +8560,48 @@ function ChildReconciler(shouldTrackSideEffects) { return created; } else { // Update - var existing = useFiber(current$$1, textContent, expirationTime); + var existing = useFiber(current, textContent); existing.return = returnFiber; 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; + 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; + { + existing._debugSource = element._source; + existing._debugOwner = element._owner; + } + + return existing; } + } // Insert - return existing; - } else { - // Insert - var created = createFiberFromElement( - element, - returnFiber.mode, - expirationTime - ); - created.ref = coerceRef(returnFiber, current$$1, element); - created.return = returnFiber; - return created; - } + var created = createFiberFromElement( + element, + returnFiber.mode, + expirationTime + ); + created.ref = coerceRef(returnFiber, current, element); + created.return = returnFiber; + return created; } - function updatePortal(returnFiber, current$$1, portal, expirationTime) { + function updatePortal(returnFiber, current, portal, expirationTime) { if ( - current$$1 === null || - current$$1.tag !== HostPortal || - current$$1.stateNode.containerInfo !== portal.containerInfo || - current$$1.stateNode.implementation !== portal.implementation + current === null || + current.tag !== HostPortal || + current.stateNode.containerInfo !== portal.containerInfo || + current.stateNode.implementation !== portal.implementation ) { // Insert var created = createFiberFromPortal( @@ -9315,24 +8613,14 @@ function ChildReconciler(shouldTrackSideEffects) { return created; } else { // Update - var existing = useFiber( - current$$1, - portal.children || [], - expirationTime - ); + var existing = useFiber(current, portal.children || []); existing.return = returnFiber; return existing; } } - function updateFragment( - returnFiber, - current$$1, - fragment, - expirationTime, - key - ) { - if (current$$1 === null || current$$1.tag !== Fragment) { + function updateFragment(returnFiber, current, fragment, expirationTime, key) { + if (current === null || current.tag !== Fragment) { // Insert var created = createFiberFromFragment( fragment, @@ -9344,7 +8632,7 @@ function ChildReconciler(shouldTrackSideEffects) { return created; } else { // Update - var existing = useFiber(current$$1, fragment, expirationTime); + var existing = useFiber(current, fragment); existing.return = returnFiber; return existing; } @@ -9390,7 +8678,7 @@ function ChildReconciler(shouldTrackSideEffects) { } } - if (isArray(newChild) || getIteratorFn(newChild)) { + if (isArray$1(newChild) || getIteratorFn(newChild)) { var _created3 = createFiberFromFragment( newChild, returnFiber.mode, @@ -9473,7 +8761,7 @@ function ChildReconciler(shouldTrackSideEffects) { } } - if (isArray(newChild) || getIteratorFn(newChild)) { + if (isArray$1(newChild) || getIteratorFn(newChild)) { if (key !== null) { return null; } @@ -9559,7 +8847,7 @@ function ChildReconciler(shouldTrackSideEffects) { } } - if (isArray(newChild) || getIteratorFn(newChild)) { + if (isArray$1(newChild) || getIteratorFn(newChild)) { var _matchedFiber3 = existingChildren.get(newIdx) || null; return updateFragment( @@ -9613,8 +8901,7 @@ function ChildReconciler(shouldTrackSideEffects) { break; } - warning$1( - false, + error( "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 " + @@ -9622,9 +8909,7 @@ function ChildReconciler(shouldTrackSideEffects) { "could change in a future version.", key ); - break; - default: break; } } @@ -9827,28 +9112,28 @@ function ChildReconciler(shouldTrackSideEffects) { typeof Symbol === "function" && // $FlowFixMe Flow doesn't know about toStringTag newChildrenIterable[Symbol.toStringTag] === "Generator" ) { - !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; + 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 = true; } // Warn about using Maps as children if (newChildrenIterable.entries === iteratorFn) { - !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; + 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 = true; } // First, validate keys. // We'll get a different iterator later for the main pass. @@ -10027,7 +9312,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, expirationTime); + var existing = useFiber(currentFirstChild, textContent); existing.return = returnFiber; return existing; } // The existing first child is not a text node so we need to create one @@ -10056,33 +9341,55 @@ 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) { - 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: + 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: isCompatibleFamilyForHotReloading(child, element) - ) { - 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; + ) { + deleteRemainingChildren(returnFiber, child.sibling); - { - existing._debugSource = element._source; - existing._debugOwner = element._owner; + 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; } + } // Didn't match. - return existing; - } else { - deleteRemainingChildren(returnFiber, child); - break; - } + deleteRemainingChildren(returnFiber, child); + break; } else { deleteChild(returnFiber, child); } @@ -10131,7 +9438,7 @@ function ChildReconciler(shouldTrackSideEffects) { child.stateNode.implementation === portal.implementation ) { deleteRemainingChildren(returnFiber, child.sibling); - var existing = useFiber(child, portal.children || [], expirationTime); + var existing = useFiber(child, portal.children || []); existing.return = returnFiber; return existing; } else { @@ -10216,7 +9523,7 @@ function ChildReconciler(shouldTrackSideEffects) { ); } - if (isArray(newChild)) { + if (isArray$1(newChild)) { return reconcileChildrenArray( returnFiber, currentFirstChild, @@ -10284,8 +9591,8 @@ function ChildReconciler(shouldTrackSideEffects) { var reconcileChildFibers = ChildReconciler(true); var mountChildFibers = ChildReconciler(false); -function cloneChildFibers(current$$1, workInProgress) { - if (!(current$$1 === null || workInProgress.child === current$$1.child)) { +function cloneChildFibers(current, workInProgress) { + if (!(current === null || workInProgress.child === current.child)) { throw Error("Resuming work not yet implemented."); } @@ -10294,11 +9601,7 @@ function cloneChildFibers(current$$1, workInProgress) { } var currentChild = workInProgress.child; - var newChild = createWorkInProgress( - currentChild, - currentChild.pendingProps, - currentChild.expirationTime - ); + var newChild = createWorkInProgress(currentChild, currentChild.pendingProps); workInProgress.child = newChild; newChild.return = workInProgress; @@ -10306,8 +9609,7 @@ function cloneChildFibers(current$$1, workInProgress) { currentChild = currentChild.sibling; newChild = newChild.sibling = createWorkInProgress( currentChild, - currentChild.pendingProps, - currentChild.expirationTime + currentChild.pendingProps ); newChild.return = workInProgress; } @@ -10357,7 +9659,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(nextRootInstance); // Now that we know this function doesn't throw, replace it. + var nextRootContext = getRootHostContext(); // Now that we know this function doesn't throw, replace it. pop(contextStackCursor$1, fiber); push(contextStackCursor$1, nextRootContext, fiber); @@ -10377,7 +9679,7 @@ function getHostContext() { function pushHostContext(fiber) { var rootInstance = requiredContext(rootInstanceStackCursor.current); var context = requiredContext(contextStackCursor$1.current); - var nextContext = getChildHostContext(context, fiber.type, rootInstance); // Don't push this Fiber's context unless it's unique. + var nextContext = getChildHostContext(context, fiber.type); // Don't push this Fiber's context unless it's unique. if (context === nextContext) { return; @@ -10448,264 +9750,80 @@ function shouldCaptureSuspense(workInProgress, hasInvisibleParent) { return true; } - 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 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; + return false; } -} -function updateEventListeners(listeners, fiber, rootContainerInstance) { - var visistedResponders = new Set(); - var dependencies = fiber.dependencies; + var props = workInProgress.memoizedProps; // In order to capture, the Suspense component must have a fallback prop. - if (listeners != null) { - if (dependencies === null) { - dependencies = fiber.dependencies = { - expirationTime: NoWork, - firstContext: null, - responders: new Map() - }; - } + if (props.fallback === undefined) { + return false; + } // Regular boundaries always capture. - var respondersMap = dependencies.responders; + 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 (respondersMap === null) { - respondersMap = new Map(); - } + if (hasInvisibleParent) { + return false; + } // If the parent is not able to handle it, we must handle it. - 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 - ); - } - } + return true; +} +function findFirstSuspended(row) { + var node = row; - if (dependencies !== null) { - var _respondersMap = dependencies.responders; + while (node !== null) { + if (node.tag === SuspenseComponent) { + var state = node.memoizedState; - if (_respondersMap !== null) { - // Unmount - var mountedResponders = Array.from(_respondersMap.keys()); + if (state !== null) { + var dehydrated = state.dehydrated; - for (var _i = 0, _length = mountedResponders.length; _i < _length; _i++) { - var mountedResponder = mountedResponders[_i]; + 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; - if (!visistedResponders.has(mountedResponder)) { - var responderInstance = _respondersMap.get(mountedResponder); + if (didSuspend) { + return node; + } + } else if (node.child !== null) { + node.child.return = node; + node = node.child; + continue; + } - unmountResponderInstance(responderInstance); + if (node === row) { + return null; + } - _respondersMap.delete(mountedResponder); - } + 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; } -function createResponderListener(responder, props) { + +function createDeprecatedResponderListener(responder, props) { var eventResponderListener = { responder: responder, props: props @@ -10718,33 +9836,19 @@ function createResponderListener(responder, props) { return eventResponderListener; } -var NoEffect$1 = - /* */ - 0; -var UnmountSnapshot = - /* */ +var HasEffect = + /* */ + 1; // Represents the phase in which the effect (not the clean-up) fires. + +var Layout = + /* */ 2; -var UnmountMutation = - /* */ +var Passive$1 = + /* */ 4; -var MountMutation = - /* */ - 8; -var UnmountLayout = - /* */ - 16; -var MountLayout = - /* */ - 32; -var MountPassive = - /* */ - 64; -var UnmountPassive = - /* */ - 128; -var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher; -var ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig; +var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher, + ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig; var didWarnAboutMismatchedHooksForComponent; { @@ -10752,7 +9856,7 @@ var didWarnAboutMismatchedHooksForComponent; } // These are set right before calling the component. -var renderExpirationTime$1 = NoWork; // The work-in-progress fiber. I've named it differently to distinguish it from +var renderExpirationTime = 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 @@ -10761,26 +9865,12 @@ var currentlyRenderingFiber$1 = null; // Hooks are stored as a linked list on th // work-in-progress fiber. var currentHook = null; -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 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 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. @@ -10825,8 +9915,7 @@ 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. - warning$1( - false, + error( "%s received a final argument that is not an array (instead, received `%s`). When " + "specified, the final argument must be an array.", currentHookNameInDev, @@ -10862,8 +9951,7 @@ function warnOnHookMismatchInDev(currentHookName) { table += row; } - warning$1( - false, + error( "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" + @@ -10897,8 +9985,7 @@ function areHookInputsEqual(nextDeps, prevDeps) { if (prevDeps === null) { { - warning$1( - false, + error( "%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.", @@ -10913,8 +10000,7 @@ function areHookInputsEqual(nextDeps, prevDeps) { // Don't bother comparing lengths in prod because these arrays should be // passed inline. if (nextDeps.length !== prevDeps.length) { - warning$1( - false, + error( "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" + @@ -10927,7 +10013,7 @@ function areHookInputsEqual(nextDeps, prevDeps) { } for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) { - if (is$1(nextDeps[i], prevDeps[i])) { + if (objectIs(nextDeps[i], prevDeps[i])) { continue; } @@ -10942,12 +10028,11 @@ function renderWithHooks( workInProgress, Component, props, - refOrContext, + secondArg, nextRenderExpirationTime ) { - renderExpirationTime$1 = nextRenderExpirationTime; + renderExpirationTime = nextRenderExpirationTime; currentlyRenderingFiber$1 = workInProgress; - nextCurrentHook = current !== null ? current.memoizedState : null; { hookTypesDev = current !== null ? current._debugHookTypes : null; @@ -10955,42 +10040,52 @@ function renderWithHooks( ignorePreviousDependencies = current !== null && current.type !== workInProgress.type; - } // The following should have already been reset + } + + workInProgress.memoizedState = null; + workInProgress.updateQueue = null; + workInProgress.expirationTime = NoWork; // 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 nextCurrentHook === null. + // Currently we will identify the update render as a mount because memoizedState === null. // This is tricky because it's valid for certain types of components (e.g. React.lazy) - // Using nextCurrentHook to differentiate between mount/update only works if at least one stateful hook is used. + // Using memoizedState 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 nextCurrentHook would be null during updates and mounts. + // so memoizedState would be null during updates and mounts. { - if (nextCurrentHook !== null) { - ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV; + if (current !== null && current.memoizedState !== null) { + ReactCurrentDispatcher.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$1.current = HooksDispatcherOnMountWithHookTypesInDEV; + ReactCurrentDispatcher.current = HooksDispatcherOnMountWithHookTypesInDEV; } else { - ReactCurrentDispatcher$1.current = HooksDispatcherOnMountInDEV; + ReactCurrentDispatcher.current = HooksDispatcherOnMountInDEV; } } - var children = Component(props, refOrContext); + 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; - if (didScheduleRenderPhaseUpdate) { do { - didScheduleRenderPhaseUpdate = false; + 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." + ); + } + numberOfReRenders += 1; { @@ -10999,46 +10094,33 @@ function renderWithHooks( ignorePreviousDependencies = false; } // Start over from the beginning of the list - nextCurrentHook = current !== null ? current.memoizedState : null; - nextWorkInProgressHook = firstWorkInProgressHook; currentHook = null; workInProgressHook = null; - componentUpdateQueue = null; + workInProgress.updateQueue = null; { // Also validate hook order for cascading updates. hookTypesUpdateIndexDev = -1; } - ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV; - children = Component(props, refOrContext); - } while (didScheduleRenderPhaseUpdate); - - renderPhaseUpdates = null; - numberOfReRenders = 0; + ReactCurrentDispatcher.current = HooksDispatcherOnRerenderInDEV; + children = Component(props, secondArg); + } while (workInProgress.expirationTime === renderExpirationTime); } // 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$1.current = ContextOnlyDispatcher; - var renderedWork = currentlyRenderingFiber$1; - renderedWork.memoizedState = firstWorkInProgressHook; - renderedWork.expirationTime = remainingExpirationTime; - renderedWork.updateQueue = componentUpdateQueue; - renderedWork.effectTag |= sideEffectTag; + ReactCurrentDispatcher.current = ContextOnlyDispatcher; { - renderedWork._debugHookTypes = hookTypesDev; + workInProgress._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$1 = NoWork; + renderExpirationTime = NoWork; currentlyRenderingFiber$1 = null; currentHook = null; - nextCurrentHook = null; - firstWorkInProgressHook = null; workInProgressHook = null; - nextWorkInProgressHook = null; { currentHookNameInDev = null; @@ -11046,12 +10128,7 @@ function renderWithHooks( hookTypesUpdateIndexDev = -1; } - remainingExpirationTime = NoWork; - componentUpdateQueue = null; - sideEffectTag = 0; // These were reset above - // didScheduleRenderPhaseUpdate = false; - // renderPhaseUpdates = null; - // numberOfReRenders = 0; + didScheduleRenderPhaseUpdate = false; if (!!didRenderTooFewHooks) { throw Error( @@ -11069,20 +10146,37 @@ function bailoutHooks(current, workInProgress, expirationTime) { current.expirationTime = NoWork; } } -function resetHooks() { +function resetHooksAfterThrow() { // 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$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. + 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; + } + } - renderExpirationTime$1 = NoWork; + renderExpirationTime = NoWork; currentlyRenderingFiber$1 = null; currentHook = null; - nextCurrentHook = null; - firstWorkInProgressHook = null; workInProgressHook = null; - nextWorkInProgressHook = null; { hookTypesDev = null; @@ -11090,26 +10184,21 @@ function resetHooks() { 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 - firstWorkInProgressHook = workInProgressHook = hook; + currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook; } else { // Append to the end of the list workInProgressHook = workInProgressHook.next = hook; @@ -11124,12 +10213,33 @@ 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)) { @@ -11140,20 +10250,18 @@ 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. - workInProgressHook = firstWorkInProgressHook = newHook; + currentlyRenderingFiber$1.memoizedState = workInProgressHook = newHook; } else { // Append to the end of the list. workInProgressHook = workInProgressHook.next = newHook; } - - nextCurrentHook = currentHook.next; } return workInProgressHook; @@ -11166,6 +10274,7 @@ function createFunctionComponentUpdateQueue() { } function basicStateReducer(state, action) { + // $FlowFixMe: Flow doesn't like mixed types return typeof action === "function" ? action(state) : action; } @@ -11181,13 +10290,13 @@ function mountReducer(reducer, initialArg, init) { hook.memoizedState = hook.baseState = initialState; var queue = (hook.queue = { - last: null, + pending: null, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialState }); var dispatch = (queue.dispatch = dispatchAction.bind( - null, // Flow doesn't know this is non-null, but we do. + null, currentlyRenderingFiber$1, queue )); @@ -11205,160 +10314,191 @@ function updateReducer(reducer, initialArg, init) { } queue.lastRenderedReducer = reducer; + var current = currentHook; // The last rebase update that is NOT part of the base state. - 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 baseQueue = current.baseQueue; // The last pending update that hasn't been processed yet. - 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. - - 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; + 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; } - first = baseUpdate.next; - } else { - first = last !== null ? last.next : null; + current.baseQueue = baseQueue = pendingQueue; + queue.pending = null; } - if (first !== null) { - var _newState = baseState; + if (baseQueue !== null) { + // We have a queue to process. + var first = baseQueue.next; + var newState = current.baseState; var newBaseState = null; - var newBaseUpdate = null; - var prevUpdate = baseUpdate; - var _update = first; - var didSkip = false; + var newBaseQueueFirst = null; + var newBaseQueueLast = null; + var update = first; do { - var updateExpirationTime = _update.expirationTime; + var updateExpirationTime = update.expirationTime; - if (updateExpirationTime < renderExpirationTime$1) { + 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. - if (!didSkip) { - didSkip = true; - newBaseUpdate = prevUpdate; - newBaseState = _newState; + 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; } // Update the remaining priority in the queue. - if (updateExpirationTime > remainingExpirationTime) { - remainingExpirationTime = updateExpirationTime; - markUnprocessedUpdateTime(remainingExpirationTime); + if (updateExpirationTime > currentlyRenderingFiber$1.expirationTime) { + currentlyRenderingFiber$1.expirationTime = updateExpirationTime; + markUnprocessedUpdateTime(updateExpirationTime); } } else { // This update does have sufficient priority. - // Mark the event time of this update as relevant to this render pass. + 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. // 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); } } - prevUpdate = _update; - _update = _update.next; - } while (_update !== null && _update !== first); + update = update.next; + } while (update !== null && update !== first); - if (!didSkip) { - newBaseUpdate = prevUpdate; - newBaseState = _newState; + if (newBaseQueueLast === null) { + newBaseState = newState; + } else { + newBaseQueueLast.next = newBaseQueueFirst; } // Mark that the fiber performed work, but only if the new state is // different from the current state. - if (!is$1(_newState, hook.memoizedState)) { + if (!objectIs(newState, hook.memoizedState)) { markWorkInProgressReceivedUpdate(); } - hook.memoizedState = _newState; - hook.baseUpdate = newBaseUpdate; + hook.memoizedState = newState; hook.baseState = newBaseState; - queue.lastRenderedState = _newState; + hook.baseQueue = newBaseQueueLast; + 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 = { - last: null, + pending: null, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState }); var dispatch = (queue.dispatch = dispatchAction.bind( - null, // Flow doesn't know this is non-null, but we do. + null, currentlyRenderingFiber$1, queue )); @@ -11366,7 +10506,11 @@ function mountState(initialState) { } function updateState(initialState) { - return updateReducer(basicStateReducer, initialState); + return updateReducer(basicStateReducer); +} + +function rerenderState(initialState) { + return rerenderReducer(basicStateReducer); } function pushEffect(tag, create, destroy, deps) { @@ -11378,9 +10522,11 @@ 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; @@ -11420,8 +10566,13 @@ function updateRef(initialValue) { function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var hook = mountWorkInProgressHook(); var nextDeps = deps === undefined ? null : deps; - sideEffectTag |= fiberEffectTag; - hook.memoizedState = pushEffect(hookEffectTag, create, undefined, nextDeps); + currentlyRenderingFiber$1.effectTag |= fiberEffectTag; + hook.memoizedState = pushEffect( + HasEffect | hookEffectTag, + create, + undefined, + nextDeps + ); } function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { @@ -11437,14 +10588,19 @@ function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var prevDeps = prevEffect.deps; if (areHookInputsEqual(nextDeps, prevDeps)) { - pushEffect(NoEffect$1, create, destroy, nextDeps); + pushEffect(hookEffectTag, create, destroy, nextDeps); return; } } } - sideEffectTag |= fiberEffectTag; - hook.memoizedState = pushEffect(hookEffectTag, create, destroy, nextDeps); + currentlyRenderingFiber$1.effectTag |= fiberEffectTag; + hook.memoizedState = pushEffect( + HasEffect | hookEffectTag, + create, + destroy, + nextDeps + ); } function mountEffect(create, deps) { @@ -11455,12 +10611,7 @@ function mountEffect(create, deps) { } } - return mountEffectImpl( - Update | Passive, - UnmountPassive | MountPassive, - create, - deps - ); + return mountEffectImpl(Update | Passive, Passive$1, create, deps); } function updateEffect(create, deps) { @@ -11471,20 +10622,15 @@ function updateEffect(create, deps) { } } - return updateEffectImpl( - Update | Passive, - UnmountPassive | MountPassive, - create, - deps - ); + return updateEffectImpl(Update | Passive, Passive$1, create, deps); } function mountLayoutEffect(create, deps) { - return mountEffectImpl(Update, UnmountMutation | MountLayout, create, deps); + return mountEffectImpl(Update, Layout, create, deps); } function updateLayoutEffect(create, deps) { - return updateEffectImpl(Update, UnmountMutation | MountLayout, create, deps); + return updateEffectImpl(Update, Layout, create, deps); } function imperativeHandleEffect(create, ref) { @@ -11501,14 +10647,13 @@ function imperativeHandleEffect(create, ref) { var refObject = ref; { - !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; + 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(", ") + "}" + ); + } } var _inst2 = create(); @@ -11522,21 +10667,20 @@ function imperativeHandleEffect(create, ref) { function mountImperativeHandle(ref, create, deps) { { - !(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; + 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" + ); + } } // 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, - UnmountMutation | MountLayout, + Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps ); @@ -11544,21 +10688,20 @@ function mountImperativeHandle(ref, create, deps) { function updateImperativeHandle(ref, create, deps) { { - !(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; + 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" + ); + } } // 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, - UnmountMutation | MountLayout, + Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps ); @@ -11634,17 +10777,14 @@ function mountDeferredValue(value, config) { mountEffect( function() { - Scheduler.unstable_next(function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - config === undefined ? null : config; + 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] ); @@ -11652,99 +10792,149 @@ function mountDeferredValue(value, config) { } function updateDeferredValue(value, config) { - var _updateState = updateState(value), + var _updateState = updateState(), prevValue = _updateState[0], setValue = _updateState[1]; updateEffect( function() { - Scheduler.unstable_next(function() { - var previousConfig = ReactCurrentBatchConfig$1.suspense; - ReactCurrentBatchConfig$1.suspense = - config === undefined ? null : config; + 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 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; + + 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 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]; + var start = mountCallback(startTransition.bind(null, setPending, config), [ + setPending, + config + ]); + return [start, isPending]; } function updateTransition(config) { - var _updateState2 = updateState(false), + var _updateState2 = updateState(), isPending = _updateState2[0], setPending = _updateState2[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]; +} + +function rerenderTransition(config) { + var _rerenderState2 = rerenderState(), + isPending = _rerenderState2[0], + setPending = _rerenderState2[1]; - try { - setPending(false); - callback(); - } finally { - ReactCurrentBatchConfig$1.suspense = previousConfig; - } - }); - }, - [config, isPending] - ); - return [startTransition, isPending]; + var start = updateCallback(startTransition.bind(null, setPending, config), [ + setPending, + config + ]); + return [start, isPending]; } function dispatchAction(fiber, queue, action) { - if (!(numberOfReRenders < RE_RENDER_LIMIT)) { - throw Error( - "Too many re-renders. React limits the number of renders to prevent an infinite loop." - ); + { + 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()." + ); + } } + 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 + }; + { - !(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; + 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; } + queue.pending = update; var alternate = fiber.alternate; if ( @@ -11755,76 +10945,9 @@ 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; - 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; - } + update.expirationTime = renderExpirationTime; + currentlyRenderingFiber$1.expirationTime = renderExpirationTime; } 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) @@ -11838,8 +10961,8 @@ function dispatchAction(fiber, queue, action) { var prevDispatcher; { - prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; } try { @@ -11849,10 +10972,10 @@ function dispatchAction(fiber, queue, action) { // time we enter the render phase, then the eager state can be used // without calling the reducer again. - _update2.eagerReducer = lastRenderedReducer; - _update2.eagerState = eagerState; + update.eagerReducer = lastRenderedReducer; + update.eagerState = eagerState; - if (is$1(eagerState, currentState)) { + if (objectIs(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 @@ -11863,7 +10986,7 @@ function dispatchAction(fiber, queue, action) { // Suppress the error. It will throw again in the render phase. } finally { { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } } } @@ -11881,6 +11004,14 @@ function dispatchAction(fiber, queue, action) { } } +function mountEventListener(event) { + return undefined; +} + +function updateEventListener(event) { + return undefined; +} + var ContextOnlyDispatcher = { readContext: readContext, useCallback: throwInvalidHookError, @@ -11895,18 +11026,20 @@ var ContextOnlyDispatcher = { useDebugValue: throwInvalidHookError, useResponder: throwInvalidHookError, useDeferredValue: throwInvalidHookError, - useTransition: throwInvalidHookError + useTransition: throwInvalidHookError, + useEvent: 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() { - warning$1( - false, + 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 " + @@ -11915,8 +11048,7 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; }; var warnInvalidHookAccess = function() { - warning$1( - false, + error( "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 " + @@ -11961,25 +11093,25 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; currentHookNameInDev = "useMemo"; mountHookTypesDev(); checkDepsAreArrayDev(deps); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; try { return mountMemo(create, deps); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useReducer: function(reducer, initialArg, init) { currentHookNameInDev = "useReducer"; mountHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; try { return mountReducer(reducer, initialArg, init); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useRef: function(initialValue) { @@ -11990,24 +11122,24 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; useState: function(initialState) { currentHookNameInDev = "useState"; mountHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; try { return mountState(initialState); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useDebugValue: function(value, formatterFn) { currentHookNameInDev = "useDebugValue"; mountHookTypesDev(); - return mountDebugValue(value, formatterFn); + return mountDebugValue(); }, useResponder: function(responder, props) { currentHookNameInDev = "useResponder"; mountHookTypesDev(); - return createResponderListener(responder, props); + return createDeprecatedResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; @@ -12018,6 +11150,11 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; currentHookNameInDev = "useTransition"; mountHookTypesDev(); return mountTransition(config); + }, + useEvent: function(event) { + currentHookNameInDev = "useEvent"; + mountHookTypesDev(); + return mountEventListener(); } }; HooksDispatcherOnMountWithHookTypesInDEV = { @@ -12052,25 +11189,25 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; useMemo: function(create, deps) { currentHookNameInDev = "useMemo"; updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; try { return mountMemo(create, deps); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useReducer: function(reducer, initialArg, init) { currentHookNameInDev = "useReducer"; updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; try { return mountReducer(reducer, initialArg, init); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useRef: function(initialValue) { @@ -12081,24 +11218,24 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; useState: function(initialState) { currentHookNameInDev = "useState"; updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; try { return mountState(initialState); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useDebugValue: function(value, formatterFn) { currentHookNameInDev = "useDebugValue"; updateHookTypesDev(); - return mountDebugValue(value, formatterFn); + return mountDebugValue(); }, useResponder: function(responder, props) { currentHookNameInDev = "useResponder"; updateHookTypesDev(); - return createResponderListener(responder, props); + return createDeprecatedResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; @@ -12109,6 +11246,11 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; currentHookNameInDev = "useTransition"; updateHookTypesDev(); return mountTransition(config); + }, + useEvent: function(event) { + currentHookNameInDev = "useEvent"; + updateHookTypesDev(); + return mountEventListener(); } }; HooksDispatcherOnUpdateInDEV = { @@ -12143,53 +11285,53 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; useMemo: function(create, deps) { currentHookNameInDev = "useMemo"; updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; try { return updateMemo(create, deps); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useReducer: function(reducer, initialArg, init) { currentHookNameInDev = "useReducer"; updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; try { return updateReducer(reducer, initialArg, init); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useRef: function(initialValue) { currentHookNameInDev = "useRef"; updateHookTypesDev(); - return updateRef(initialValue); + return updateRef(); }, useState: function(initialState) { currentHookNameInDev = "useState"; updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; try { return updateState(initialState); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useDebugValue: function(value, formatterFn) { currentHookNameInDev = "useDebugValue"; updateHookTypesDev(); - return updateDebugValue(value, formatterFn); + return updateDebugValue(); }, useResponder: function(responder, props) { currentHookNameInDev = "useResponder"; updateHookTypesDev(); - return createResponderListener(responder, props); + return createDeprecatedResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; @@ -12200,6 +11342,107 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = 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 = { @@ -12241,26 +11484,26 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; currentHookNameInDev = "useMemo"; warnInvalidHookAccess(); mountHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; try { return mountMemo(create, deps); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useReducer: function(reducer, initialArg, init) { currentHookNameInDev = "useReducer"; warnInvalidHookAccess(); mountHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; try { return mountReducer(reducer, initialArg, init); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useRef: function(initialValue) { @@ -12273,26 +11516,26 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; currentHookNameInDev = "useState"; warnInvalidHookAccess(); mountHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV; try { return mountState(initialState); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useDebugValue: function(value, formatterFn) { currentHookNameInDev = "useDebugValue"; warnInvalidHookAccess(); mountHookTypesDev(); - return mountDebugValue(value, formatterFn); + return mountDebugValue(); }, useResponder: function(responder, props) { currentHookNameInDev = "useResponder"; warnInvalidHookAccess(); mountHookTypesDev(); - return createResponderListener(responder, props); + return createDeprecatedResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; @@ -12305,6 +11548,12 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; warnInvalidHookAccess(); mountHookTypesDev(); return mountTransition(config); + }, + useEvent: function(event) { + currentHookNameInDev = "useEvent"; + warnInvalidHookAccess(); + mountHookTypesDev(); + return mountEventListener(); } }; InvalidNestedHooksDispatcherOnUpdateInDEV = { @@ -12346,58 +11595,58 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = null; currentHookNameInDev = "useMemo"; warnInvalidHookAccess(); updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; try { return updateMemo(create, deps); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useReducer: function(reducer, initialArg, init) { currentHookNameInDev = "useReducer"; warnInvalidHookAccess(); updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; try { return updateReducer(reducer, initialArg, init); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useRef: function(initialValue) { currentHookNameInDev = "useRef"; warnInvalidHookAccess(); updateHookTypesDev(); - return updateRef(initialValue); + return updateRef(); }, useState: function(initialState) { currentHookNameInDev = "useState"; warnInvalidHookAccess(); updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + var prevDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV; try { return updateState(initialState); } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + ReactCurrentDispatcher.current = prevDispatcher; } }, useDebugValue: function(value, formatterFn) { currentHookNameInDev = "useDebugValue"; warnInvalidHookAccess(); updateHookTypesDev(); - return updateDebugValue(value, formatterFn); + return updateDebugValue(); }, useResponder: function(responder, props) { currentHookNameInDev = "useResponder"; warnInvalidHookAccess(); updateHookTypesDev(); - return createResponderListener(responder, props); + return createDeprecatedResponderListener(responder, props); }, useDeferredValue: function(value, config) { currentHookNameInDev = "useDeferredValue"; @@ -12410,11 +11659,126 @@ var InvalidNestedHooksDispatcherOnUpdateInDEV = 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; -// CommonJS interop named imports. + 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(); + } + }; +} var now$1 = Scheduler.unstable_now; var commitTime = 0; @@ -12425,18 +11789,10 @@ function getCommitTime() { } function recordCommitTime() { - if (!enableProfilerTimer) { - return; - } - commitTime = now$1(); -} - -function startProfilerTimer(fiber) { - if (!enableProfilerTimer) { - return; - } +} +function startProfilerTimer(fiber) { profilerStartTime = now$1(); if (fiber.actualStartTime < 0) { @@ -12445,18 +11801,10 @@ 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; @@ -12469,258 +11817,10 @@ function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) { } } -// 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); + return false; } - - hydrationParentFiber = fiber; - nextHydratableInstance = getFirstHydratableChild(nextInstance); } function prepareToHydrateHostInstance( @@ -12728,209 +11828,33 @@ 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 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." + "Expected prepareToHydrateHostTextInstance() 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; + var shouldUpdate = hydrateTextInstance(); } 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 ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner; var didReceiveUpdate = false; var didWarnAboutBadClass; var didWarnAboutModulePatternComponent; @@ -12938,10 +11862,8 @@ var didWarnAboutContextTypeOnFunctionComponent; var didWarnAboutGetDerivedStateOnFunctionComponent; var didWarnAboutFunctionRefs; var didWarnAboutReassigningProps; -var didWarnAboutMaxDuration; var didWarnAboutRevealOrder; var didWarnAboutTailOptions; -var didWarnAboutDefaultPropsOnFunctionComponent; { didWarnAboutBadClass = {}; @@ -12950,19 +11872,17 @@ var didWarnAboutDefaultPropsOnFunctionComponent; didWarnAboutGetDerivedStateOnFunctionComponent = {}; didWarnAboutFunctionRefs = {}; didWarnAboutReassigningProps = false; - didWarnAboutMaxDuration = false; didWarnAboutRevealOrder = {}; didWarnAboutTailOptions = {}; - didWarnAboutDefaultPropsOnFunctionComponent = {}; } function reconcileChildren( - current$$1, + current, workInProgress, nextChildren, renderExpirationTime ) { - if (current$$1 === null) { + 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 @@ -12981,7 +11901,7 @@ function reconcileChildren( // let's throw it out. workInProgress.child = reconcileChildFibers( workInProgress, - current$$1.child, + current.child, nextChildren, renderExpirationTime ); @@ -12989,7 +11909,7 @@ function reconcileChildren( } function forceUnmountCurrentAndReconcile( - current$$1, + current, workInProgress, nextChildren, renderExpirationTime @@ -13004,13 +11924,13 @@ function forceUnmountCurrentAndReconcile( // passing null. workInProgress.child = reconcileChildFibers( workInProgress, - current$$1.child, + 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 their - // identity matches. + // the effect of remounting all children regardless of whether their + // identities match. workInProgress.child = reconcileChildFibers( workInProgress, @@ -13021,7 +11941,7 @@ function forceUnmountCurrentAndReconcile( } function updateForwardRef( - current$$1, + current, workInProgress, Component, nextProps, @@ -13041,8 +11961,7 @@ function updateForwardRef( innerPropTypes, nextProps, // Resolved props "prop", - getComponentName(Component), - getCurrentFiberStackInDev + getComponentName(Component) ); } } @@ -13055,10 +11974,10 @@ function updateForwardRef( prepareToReadContext(workInProgress, renderExpirationTime); { - ReactCurrentOwner$3.current = workInProgress; - setCurrentPhase("render"); + ReactCurrentOwner$1.current = workInProgress; + setIsRendering(true); nextChildren = renderWithHooks( - current$$1, + current, workInProgress, render, nextProps, @@ -13066,30 +11985,13 @@ function updateForwardRef( 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); + setIsRendering(false); } - if (current$$1 !== null && !didReceiveUpdate) { - bailoutHooks(current$$1, workInProgress, renderExpirationTime); + if (current !== null && !didReceiveUpdate) { + bailoutHooks(current, workInProgress, renderExpirationTime); return bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ); @@ -13097,7 +11999,7 @@ function updateForwardRef( workInProgress.effectTag |= PerformedWork; reconcileChildren( - current$$1, + current, workInProgress, nextChildren, renderExpirationTime @@ -13106,14 +12008,14 @@ function updateForwardRef( } function updateMemoComponent( - current$$1, + current, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime ) { - if (current$$1 === null) { + if (current === null) { var type = Component.type; if ( @@ -13137,7 +12039,7 @@ function updateMemoComponent( } return updateSimpleMemoComponent( - current$$1, + current, workInProgress, resolvedType, nextProps, @@ -13156,8 +12058,7 @@ function updateMemoComponent( innerPropTypes, nextProps, // Resolved props "prop", - getComponentName(type), - getCurrentFiberStackInDev + getComponentName(type) ); } } @@ -13187,13 +12088,12 @@ function updateMemoComponent( _innerPropTypes, nextProps, // Resolved props "prop", - getComponentName(_type), - getCurrentFiberStackInDev + getComponentName(_type) ); } } - var currentChild = current$$1.child; // This is always exactly one child + var currentChild = current.child; // This is always exactly one child if (updateExpirationTime < renderExpirationTime) { // This will be the props with resolved defaultProps, @@ -13203,12 +12103,9 @@ function updateMemoComponent( var compare = Component.compare; compare = compare !== null ? compare : shallowEqual; - if ( - compare(prevProps, nextProps) && - current$$1.ref === workInProgress.ref - ) { + if (compare(prevProps, nextProps) && current.ref === workInProgress.ref) { return bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ); @@ -13216,11 +12113,7 @@ function updateMemoComponent( } // React DevTools reads this flag. workInProgress.effectTag |= PerformedWork; - var newChild = createWorkInProgress( - currentChild, - nextProps, - renderExpirationTime - ); + var newChild = createWorkInProgress(currentChild, nextProps); newChild.ref = workInProgress.ref; newChild.return = workInProgress; workInProgress.child = newChild; @@ -13228,7 +12121,7 @@ function updateMemoComponent( } function updateSimpleMemoComponent( - current$$1, + current, workInProgress, Component, nextProps, @@ -13258,26 +12151,39 @@ function updateSimpleMemoComponent( outerPropTypes, nextProps, // Resolved (SimpleMemoComponent has no defaultProps) "prop", - getComponentName(outerMemoType), - getCurrentFiberStackInDev + getComponentName(outerMemoType) ); } // Inner propTypes will be validated in the function component path. } } - if (current$$1 !== null) { - var prevProps = current$$1.memoizedProps; + if (current !== null) { + var prevProps = current.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 + current.ref === workInProgress.ref && // Prevent bailout if the implementation changed due to hot reload. + workInProgress.type === current.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$$1, + current, workInProgress, renderExpirationTime ); @@ -13286,7 +12192,7 @@ function updateSimpleMemoComponent( } return updateFunctionComponent( - current$$1, + current, workInProgress, Component, nextProps, @@ -13294,10 +12200,10 @@ function updateSimpleMemoComponent( ); } -function updateFragment(current$$1, workInProgress, renderExpirationTime) { +function updateFragment(current, workInProgress, renderExpirationTime) { var nextChildren = workInProgress.pendingProps; reconcileChildren( - current$$1, + current, workInProgress, nextChildren, renderExpirationTime @@ -13305,10 +12211,10 @@ function updateFragment(current$$1, workInProgress, renderExpirationTime) { return workInProgress.child; } -function updateMode(current$$1, workInProgress, renderExpirationTime) { +function updateMode(current, workInProgress, renderExpirationTime) { var nextChildren = workInProgress.pendingProps.children; reconcileChildren( - current$$1, + current, workInProgress, nextChildren, renderExpirationTime @@ -13316,15 +12222,20 @@ function updateMode(current$$1, workInProgress, renderExpirationTime) { return workInProgress.child; } -function updateProfiler(current$$1, workInProgress, renderExpirationTime) { - if (enableProfilerTimer) { - workInProgress.effectTag |= Update; +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; } var nextProps = workInProgress.pendingProps; var nextChildren = nextProps.children; reconcileChildren( - current$$1, + current, workInProgress, nextChildren, renderExpirationTime @@ -13332,12 +12243,12 @@ function updateProfiler(current$$1, workInProgress, renderExpirationTime) { return workInProgress.child; } -function markRef(current$$1, workInProgress) { +function markRef(current, workInProgress) { var ref = workInProgress.ref; if ( - (current$$1 === null && ref !== null) || - (current$$1 !== null && current$$1.ref !== ref) + (current === null && ref !== null) || + (current !== null && current.ref !== ref) ) { // Schedule a Ref effect workInProgress.effectTag |= Ref; @@ -13345,7 +12256,7 @@ function markRef(current$$1, workInProgress) { } function updateFunctionComponent( - current$$1, + current, workInProgress, Component, nextProps, @@ -13362,8 +12273,7 @@ function updateFunctionComponent( innerPropTypes, nextProps, // Resolved props "prop", - getComponentName(Component), - getCurrentFiberStackInDev + getComponentName(Component) ); } } @@ -13371,7 +12281,7 @@ function updateFunctionComponent( var context; - if (!disableLegacyContext) { + { var unmaskedContext = getUnmaskedContext(workInProgress, Component, true); context = getMaskedContext(workInProgress, unmaskedContext); } @@ -13380,10 +12290,10 @@ function updateFunctionComponent( prepareToReadContext(workInProgress, renderExpirationTime); { - ReactCurrentOwner$3.current = workInProgress; - setCurrentPhase("render"); + ReactCurrentOwner$1.current = workInProgress; + setIsRendering(true); nextChildren = renderWithHooks( - current$$1, + current, workInProgress, Component, nextProps, @@ -13391,30 +12301,13 @@ function updateFunctionComponent( 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); + setIsRendering(false); } - if (current$$1 !== null && !didReceiveUpdate) { - bailoutHooks(current$$1, workInProgress, renderExpirationTime); + if (current !== null && !didReceiveUpdate) { + bailoutHooks(current, workInProgress, renderExpirationTime); return bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ); @@ -13422,7 +12315,7 @@ function updateFunctionComponent( workInProgress.effectTag |= PerformedWork; reconcileChildren( - current$$1, + current, workInProgress, nextChildren, renderExpirationTime @@ -13431,7 +12324,7 @@ function updateFunctionComponent( } function updateClassComponent( - current$$1, + current, workInProgress, Component, nextProps, @@ -13448,8 +12341,7 @@ function updateClassComponent( innerPropTypes, nextProps, // Resolved props "prop", - getComponentName(Component), - getCurrentFiberStackInDev + getComponentName(Component) ); } } @@ -13471,23 +12363,18 @@ function updateClassComponent( 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 + 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$$1.alternate = null; + 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, - renderExpirationTime - ); + constructClassInstance(workInProgress, Component, nextProps); mountClassInstance( workInProgress, Component, @@ -13495,7 +12382,7 @@ function updateClassComponent( renderExpirationTime ); shouldUpdate = true; - } else if (current$$1 === null) { + } else if (current === null) { // In a resume, we'll already have an instance we can reuse. shouldUpdate = resumeMountClassInstance( workInProgress, @@ -13505,7 +12392,7 @@ function updateClassComponent( ); } else { shouldUpdate = updateClassInstance( - current$$1, + current, workInProgress, Component, nextProps, @@ -13514,7 +12401,7 @@ function updateClassComponent( } var nextUnitOfWork = finishClassComponent( - current$$1, + current, workInProgress, Component, shouldUpdate, @@ -13526,14 +12413,14 @@ function updateClassComponent( 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; + 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; } } @@ -13542,7 +12429,7 @@ function updateClassComponent( } function finishClassComponent( - current$$1, + current, workInProgress, Component, shouldUpdate, @@ -13550,7 +12437,7 @@ function finishClassComponent( renderExpirationTime ) { // Refs should update even if shouldComponentUpdate returns false - markRef(current$$1, workInProgress); + markRef(current, workInProgress); var didCaptureError = (workInProgress.effectTag & DidCapture) !== NoEffect; if (!shouldUpdate && !didCaptureError) { @@ -13560,7 +12447,7 @@ function finishClassComponent( } return bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ); @@ -13568,55 +12455,48 @@ function finishClassComponent( var instance = workInProgress.stateNode; // Rerender - ReactCurrentOwner$3.current = workInProgress; + ReactCurrentOwner$1.current = workInProgress; var nextChildren; if ( didCaptureError && typeof Component.getDerivedStateFromError !== "function" ) { - // If we captured an error, but getDerivedStateFrom catch is not defined, + // If we captured an error, but getDerivedStateFromError is not defined, // unmount all the children. componentDidCatch will schedule an update to // re-render a fallback. This is temporary until we migrate everyone to // the new API. // TODO: Warn in a future release. nextChildren = null; - if (enableProfilerTimer) { - stopProfilerTimerIfRunning(workInProgress); + { + stopProfilerTimerIfRunning(); } } else { { - setCurrentPhase("render"); + setIsRendering(true); nextChildren = instance.render(); - if ( - debugRenderPhaseSideEffectsForStrictMode && - workInProgress.mode & StrictMode - ) { - instance.render(); - } - - setCurrentPhase(null); + setIsRendering(false); } } // React DevTools reads this flag. workInProgress.effectTag |= PerformedWork; - if (current$$1 !== null && didCaptureError) { + 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$$1, + current, workInProgress, nextChildren, renderExpirationTime ); } else { reconcileChildren( - current$$1, + current, workInProgress, nextChildren, renderExpirationTime @@ -13650,11 +12530,11 @@ function pushHostRootContext(workInProgress) { pushHostContainer(workInProgress, root.containerInfo); } -function updateHostRoot(current$$1, workInProgress, renderExpirationTime) { +function updateHostRoot(current, workInProgress, renderExpirationTime) { pushHostRootContext(workInProgress); var updateQueue = workInProgress.updateQueue; - if (!(updateQueue !== null)) { + 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." ); @@ -13663,24 +12543,16 @@ function updateHostRoot(current$$1, workInProgress, renderExpirationTime) { var nextProps = workInProgress.pendingProps; var prevState = workInProgress.memoizedState; var prevChildren = prevState !== null ? prevState.element : null; - processUpdateQueue( - workInProgress, - updateQueue, - nextProps, - null, - renderExpirationTime - ); + cloneUpdateQueue(current, workInProgress); + processUpdateQueue(workInProgress, 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, + current, workInProgress, renderExpirationTime ); @@ -13688,7 +12560,7 @@ function updateHostRoot(current$$1, workInProgress, renderExpirationTime) { var root = workInProgress.stateNode; - if (root.hydrate && enterHydrationState(workInProgress)) { + 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 @@ -13716,50 +12588,38 @@ function updateHostRoot(current$$1, workInProgress, renderExpirationTime) { // Otherwise reset hydration state in case we aborted and resumed another // root. reconcileChildren( - current$$1, + current, workInProgress, nextChildren, renderExpirationTime ); - resetHydrationState(); } return workInProgress.child; } -function updateHostComponent(current$$1, workInProgress, renderExpirationTime) { +function updateHostComponent(current, workInProgress, renderExpirationTime) { pushHostContext(workInProgress); - if (current$$1 === null) { - tryToClaimNextHydratableInstance(workInProgress); - } - var type = workInProgress.type; var nextProps = workInProgress.pendingProps; - var prevProps = current$$1 !== null ? current$$1.memoizedProps : null; + var prevProps = current !== null ? current.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 (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$$1, workInProgress); // Check the host config to see if the children are offscreen/hidden. + markRef(current, workInProgress); // Check the host config to see if the children are offscreen/hidden. if ( workInProgress.mode & ConcurrentMode && renderExpirationTime !== Never && - shouldDeprioritizeSubtree(type, nextProps) + shouldDeprioritizeSubtree() ) { - if (enableSchedulerTracing) { + { markSpawnedWork(Never); } // Schedule this fiber to re-render at offscreen priority. Then bailout. @@ -13768,7 +12628,7 @@ function updateHostComponent(current$$1, workInProgress, renderExpirationTime) { } reconcileChildren( - current$$1, + current, workInProgress, nextChildren, renderExpirationTime @@ -13776,10 +12636,7 @@ function updateHostComponent(current$$1, workInProgress, renderExpirationTime) { return workInProgress.child; } -function updateHostText(current$$1, workInProgress) { - if (current$$1 === null) { - tryToClaimNextHydratableInstance(workInProgress); - } // Nothing to do here. This is terminal. We'll do the completion step +function updateHostText(current, workInProgress) { // immediately after. return null; @@ -13793,7 +12650,7 @@ function mountLazyComponent( renderExpirationTime ) { if (_current !== null) { - // An lazy component only mounts if it suspended inside a non- + // 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. @@ -13831,7 +12688,7 @@ function mountLazyComponent( resolvedProps, renderExpirationTime ); - break; + return child; } case ClassComponent: { @@ -13848,7 +12705,7 @@ function mountLazyComponent( resolvedProps, renderExpirationTime ); - break; + return child; } case ForwardRef: { @@ -13865,7 +12722,7 @@ function mountLazyComponent( resolvedProps, renderExpirationTime ); - break; + return child; } case MemoComponent: { @@ -13878,8 +12735,7 @@ function mountLazyComponent( outerPropTypes, resolvedProps, // Resolved for outer only "prop", - getComponentName(Component), - getCurrentFiberStackInDev + getComponentName(Component) ); } } @@ -13893,36 +12749,32 @@ function mountLazyComponent( updateExpirationTime, renderExpirationTime ); - break; + return child; } + } - 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. + var 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 - ); - } + { + 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. - return 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 + ); + } } function mountIncompleteClassComponent( @@ -13958,12 +12810,7 @@ function mountIncompleteClassComponent( } prepareToReadContext(workInProgress, renderExpirationTime); - constructClassInstance( - workInProgress, - Component, - nextProps, - renderExpirationTime - ); + constructClassInstance(workInProgress, Component, nextProps); mountClassInstance( workInProgress, Component, @@ -14000,7 +12847,7 @@ function mountIndeterminateComponent( var props = workInProgress.pendingProps; var context; - if (!disableLegacyContext) { + { var unmaskedContext = getUnmaskedContext(workInProgress, Component, false); context = getMaskedContext(workInProgress, unmaskedContext); } @@ -14016,13 +12863,13 @@ function mountIndeterminateComponent( var componentName = getComponentName(Component) || "Unknown"; if (!didWarnAboutBadClass[componentName]) { - warningWithoutStack$1( - false, + error( "The <%s /> component appears to have a render method, but doesn't extend React.Component. " + "This is likely to cause errors. Change %s to extend React.Component instead.", componentName, componentName ); + didWarnAboutBadClass[componentName] = true; } } @@ -14031,7 +12878,7 @@ function mountIndeterminateComponent( ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null); } - ReactCurrentOwner$3.current = workInProgress; + ReactCurrentOwner$1.current = workInProgress; value = renderWithHooks( null, workInProgress, @@ -14054,8 +12901,7 @@ function mountIndeterminateComponent( var _componentName = getComponentName(Component) || "Unknown"; if (!didWarnAboutModulePatternComponent[_componentName]) { - warningWithoutStack$1( - false, + 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. " + @@ -14065,13 +12911,15 @@ 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. - resetHooks(); // Push context providers early to prevent context stack mismatches. + 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. @@ -14086,6 +12934,7 @@ function mountIndeterminateComponent( workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null; + initializeUpdateQueue(workInProgress); var getDerivedStateFromProps = Component.getDerivedStateFromProps; if (typeof getDerivedStateFromProps === "function") { @@ -14111,34 +12960,6 @@ 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); { @@ -14150,86 +12971,70 @@ function mountIndeterminateComponent( } function validateFunctionComponentInDev(workInProgress, Component) { - if (Component) { - !!Component.childContextTypes - ? warningWithoutStack$1( - false, + { + if (Component) { + if (Component.childContextTypes) { + error( "%s(...): childContextTypes cannot be defined on a function component.", Component.displayName || Component.name || "Component" - ) - : void 0; - } + ); + } + } - if (workInProgress.ref !== null) { - var info = ""; - var ownerName = getCurrentFiberOwnerNameInDevOrNull(); + if (workInProgress.ref !== null) { + var info = ""; + var ownerName = getCurrentFiberOwnerNameInDevOrNull(); - if (ownerName) { - info += "\n\nCheck the render method of `" + ownerName + "`."; - } + if (ownerName) { + info += "\n\nCheck the render method of `" + ownerName + "`."; + } - var warningKey = ownerName || workInProgress._debugID || ""; - var debugSource = workInProgress._debugSource; + var warningKey = ownerName || workInProgress._debugID || ""; + var debugSource = workInProgress._debugSource; - if (debugSource) { - warningKey = debugSource.fileName + ":" + debugSource.lineNumber; - } + if (debugSource) { + warningKey = debugSource.fileName + ":" + debugSource.lineNumber; + } - 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 (!didWarnAboutFunctionRefs[warningKey]) { + didWarnAboutFunctionRefs[warningKey] = true; - 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; + error( + "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 (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 (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2]) { + error( + "%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 ( + 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; + if (!didWarnAboutContextTypeOnFunctionComponent[_componentName3]) { + error( + "%s: Function components do not support contextType.", + _componentName3 + ); + + didWarnAboutContextTypeOnFunctionComponent[_componentName3] = true; + } } } } @@ -14239,17 +13044,17 @@ var SUSPENDED_MARKER = { retryTime: NoWork }; -function shouldRemainOnFallback(suspenseContext, current$$1, workInProgress) { +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$$1 === null || current$$1.memoizedState !== null) + (current === null || current.memoizedState !== null) ); } function updateSuspenseComponent( - current$$1, + current, workInProgress, renderExpirationTime ) { @@ -14266,17 +13071,14 @@ function updateSuspenseComponent( var nextDidTimeout = false; var didSuspend = (workInProgress.effectTag & DidCapture) !== NoEffect; - if ( - didSuspend || - shouldRemainOnFallback(suspenseContext, current$$1, workInProgress) - ) { + 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$$1 === null || current$$1.memoizedState !== null) { + 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. @@ -14295,20 +13097,7 @@ function updateSuspenseComponent( } suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); - 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 + 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. @@ -14330,28 +13119,10 @@ 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$$1 === null) { + if (current === 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 + 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) { @@ -14409,107 +13180,12 @@ 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$$1.memoizedState; + var prevState = current.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 currentPrimaryChildFragment = current.child; var currentFallbackChildFragment = currentPrimaryChildFragment.sibling; if (nextDidTimeout) { @@ -14519,8 +13195,7 @@ function updateSuspenseComponent( var _primaryChildFragment2 = createWorkInProgress( currentPrimaryChildFragment, - currentPrimaryChildFragment.pendingProps, - NoWork + currentPrimaryChildFragment.pendingProps ); _primaryChildFragment2.return = workInProgress; @@ -14547,7 +13222,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 (enableProfilerTimer && workInProgress.mode & ProfileMode) { + if (workInProgress.mode & ProfileMode) { // treeBaseDuration is the sum of all the child tree base durations. var _treeBaseDuration = 0; var _hiddenChild = _primaryChildFragment2.child; @@ -14563,8 +13238,7 @@ function updateSuspenseComponent( var _fallbackChildFragment2 = createWorkInProgress( currentFallbackChildFragment, - _nextFallbackChildren2, - currentFallbackChildFragment.expirationTime + _nextFallbackChildren2 ); _fallbackChildFragment2.return = workInProgress; @@ -14598,7 +13272,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$$1.child; + var _currentPrimaryChild = current.child; if (nextDidTimeout) { // Timed out. Wrap the children in a fragment fiber to keep them @@ -14644,7 +13318,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 (enableProfilerTimer && workInProgress.mode & ProfileMode) { + if (workInProgress.mode & ProfileMode) { // treeBaseDuration is the sum of all the child tree base durations. var _treeBaseDuration2 = 0; var _hiddenChild2 = _primaryChildFragment3.child; @@ -14674,7 +13348,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; @@ -14689,197 +13363,6 @@ 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; @@ -14981,40 +13464,39 @@ function validateRevealOrder(revealOrder) { case "together": case "forwards": case "backwards": { - warning$1( - false, + error( '"%s" is not a valid value for revealOrder on . ' + 'Use lowercase "%s" instead.', revealOrder, revealOrder.toLowerCase() ); + break; } case "forward": case "backward": { - warning$1( - false, + 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; } default: - warning$1( - false, + error( '"%s" is not a supported revealOrder on . ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder ); + break; } } else { - warning$1( - false, + error( "%s is not a supported value for revealOrder on . " + 'Did you mean "together", "forwards" or "backwards"?', revealOrder @@ -15029,16 +13511,16 @@ function validateTailOptions(tailMode, revealOrder) { if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) { if (tailMode !== "collapsed" && tailMode !== "hidden") { didWarnAboutTailOptions[tailMode] = true; - warning$1( - false, + + 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; - warning$1( - false, + + error( ' is only valid if revealOrder is ' + '"forwards" or "backwards". ' + 'Did you mean to specify revealOrder="forwards"?', @@ -15056,8 +13538,8 @@ function validateSuspenseListNestedChild(childSlot, index) { if (isArray || isIterable) { var type = isArray ? "array" : "iterable"; - warning$1( - false, + + error( "A nested %s was passed to row #%s in . Wrap it in " + "an additional SuspenseList to configure its revealOrder: " + " ... " + @@ -15067,6 +13549,7 @@ function validateSuspenseListNestedChild(childSlot, index) { index, type ); + return false; } } @@ -15107,8 +13590,7 @@ function validateSuspenseListChildren(children, revealOrder) { } } } else { - warning$1( - false, + 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?", @@ -15134,6 +13616,7 @@ function initSuspenseListRenderState( workInProgress.memoizedState = { isBackwards: isBackwards, rendering: null, + renderingStartTime: 0, last: lastContentRow, tail: tail, tailExpiration: 0, @@ -15144,6 +13627,7 @@ 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; @@ -15159,7 +13643,7 @@ function initSuspenseListRenderState( // That happens in the completeWork phase without going back to beginWork. function updateSuspenseListComponent( - current$$1, + current, workInProgress, renderExpirationTime ) { @@ -15170,12 +13654,7 @@ function updateSuspenseListComponent( validateRevealOrder(revealOrder); validateTailOptions(tailMode, revealOrder); validateSuspenseListChildren(newChildren, revealOrder); - reconcileChildren( - current$$1, - workInProgress, - newChildren, - renderExpirationTime - ); + reconcileChildren(current, workInProgress, newChildren, renderExpirationTime); var suspenseContext = suspenseStackCursor.current; var shouldForceFallback = hasSuspenseContext( suspenseContext, @@ -15190,7 +13669,7 @@ function updateSuspenseListComponent( workInProgress.effectTag |= DidCapture; } else { var didSuspendBefore = - current$$1 !== null && (current$$1.effectTag & DidCapture) !== NoEffect; + current !== null && (current.effectTag & DidCapture) !== NoEffect; if (didSuspendBefore) { // If we previously forced a fallback, we need to schedule work @@ -15299,15 +13778,11 @@ function updateSuspenseListComponent( return workInProgress.child; } -function updatePortalComponent( - current$$1, - workInProgress, - renderExpirationTime -) { +function updatePortalComponent(current, workInProgress, renderExpirationTime) { pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); var nextChildren = workInProgress.pendingProps; - if (current$$1 === null) { + if (current === null) { // Portals are special because we don't append the children during mount // but at commit. Therefore we need to track insertions which the normal // flow doesn't do during mount. This doesn't happen at the root because @@ -15321,7 +13796,7 @@ function updatePortalComponent( ); } else { reconcileChildren( - current$$1, + current, workInProgress, nextChildren, renderExpirationTime @@ -15331,11 +13806,7 @@ function updatePortalComponent( return workInProgress.child; } -function updateContextProvider( - current$$1, - workInProgress, - renderExpirationTime -) { +function updateContextProvider(current, workInProgress, renderExpirationTime) { var providerType = workInProgress.type; var context = providerType._context; var newProps = workInProgress.pendingProps; @@ -15346,13 +13817,7 @@ function updateContextProvider( var providerPropTypes = workInProgress.type.propTypes; if (providerPropTypes) { - checkPropTypes( - providerPropTypes, - newProps, - "prop", - "Context.Provider", - getCurrentFiberStackInDev - ); + checkPropTypes(providerPropTypes, newProps, "prop", "Context.Provider"); } } @@ -15366,7 +13831,7 @@ function updateContextProvider( // No change. Bailout early if children are the same. if (oldProps.children === newProps.children && !hasContextChanged()) { return bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ); @@ -15384,22 +13849,13 @@ function updateContextProvider( } var newChildren = newProps.children; - reconcileChildren( - current$$1, - workInProgress, - newChildren, - renderExpirationTime - ); + reconcileChildren(current, workInProgress, newChildren, renderExpirationTime); return workInProgress.child; } var hasWarnedAboutUsingContextAsConsumer = false; -function updateContextConsumer( - current$$1, - workInProgress, - renderExpirationTime -) { +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 @@ -15416,8 +13872,8 @@ function updateContextConsumer( if (context !== context.Consumer) { if (!hasWarnedAboutUsingContextAsConsumer) { hasWarnedAboutUsingContextAsConsumer = true; - warning$1( - false, + + error( "Rendering directly is not supported and will be removed in " + "a future major release. Did you mean to render instead?" ); @@ -15432,15 +13888,14 @@ function updateContextConsumer( var render = newProps.children; { - !(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; + if (typeof render !== "function") { + error( + "A context consumer was rendered with multiple children, or a child " + + "that isn't a function. A context consumer expects a single child " + + "that is a function. If you did pass a function, make sure there " + + "is no trailing or leading whitespace around it." + ); + } } prepareToReadContext(workInProgress, renderExpirationTime); @@ -15448,57 +13903,14 @@ function updateContextConsumer( var newChildren; { - ReactCurrentOwner$3.current = workInProgress; - setCurrentPhase("render"); + ReactCurrentOwner$1.current = workInProgress; + setIsRendering(true); newChildren = render(newValue); - setCurrentPhase(null); + setIsRendering(false); } // React DevTools reads this flag. workInProgress.effectTag |= PerformedWork; - 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 - ); + reconcileChildren(current, workInProgress, newChildren, renderExpirationTime); return workInProgress.child; } @@ -15507,20 +13919,20 @@ function markWorkInProgressReceivedUpdate() { } function bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ) { cancelWorkTimer(workInProgress); - if (current$$1 !== null) { + if (current !== null) { // Reuse previous dependencies - workInProgress.dependencies = current$$1.dependencies; + workInProgress.dependencies = current.dependencies; } - if (enableProfilerTimer) { + { // Don't update "base" render times for bailouts. - stopProfilerTimerIfRunning(workInProgress); + stopProfilerTimerIfRunning(); } var updateExpirationTime = workInProgress.expirationTime; @@ -15539,12 +13951,12 @@ function bailoutOnAlreadyFinishedWork( } else { // This fiber doesn't have work, but its subtree does. Clone the child // fibers and continue. - cloneChildFibers(current$$1, workInProgress); + cloneChildFibers(current, workInProgress); return workInProgress.child; } } -function remountFiber(current$$1, oldWorkInProgress, newWorkInProgress) { +function remountFiber(current, oldWorkInProgress, newWorkInProgress) { { var returnFiber = oldWorkInProgress.return; @@ -15553,7 +13965,7 @@ function remountFiber(current$$1, oldWorkInProgress, newWorkInProgress) { } // Disconnect from the old current. // It will get deleted. - current$$1.alternate = null; + current.alternate = null; oldWorkInProgress.alternate = null; // Connect to the new tree. newWorkInProgress.index = oldWorkInProgress.index; @@ -15585,28 +13997,28 @@ function remountFiber(current$$1, oldWorkInProgress, newWorkInProgress) { var last = returnFiber.lastEffect; if (last !== null) { - last.nextEffect = current$$1; - returnFiber.lastEffect = current$$1; + last.nextEffect = current; + returnFiber.lastEffect = current; } else { - returnFiber.firstEffect = returnFiber.lastEffect = current$$1; + returnFiber.firstEffect = returnFiber.lastEffect = current; } - current$$1.nextEffect = null; - current$$1.effectTag = Deletion; + current.nextEffect = null; + current.effectTag = Deletion; newWorkInProgress.effectTag |= Placement; // Restart work from the new fiber. return newWorkInProgress; } } -function beginWork$1(current$$1, workInProgress, renderExpirationTime) { +function beginWork(current, workInProgress, renderExpirationTime) { var updateExpirationTime = workInProgress.expirationTime; { - if (workInProgress._debugNeedsRemount && current$$1 !== null) { + if (workInProgress._debugNeedsRemount && current !== null) { // This will restart the begin phase with a new fiber. return remountFiber( - current$$1, + current, workInProgress, createFiberFromTypeAndProps( workInProgress.type, @@ -15620,14 +14032,14 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { } } - if (current$$1 !== null) { - var oldProps = current$$1.memoizedProps; + if (current !== null) { + var oldProps = current.memoizedProps; var newProps = workInProgress.pendingProps; if ( oldProps !== newProps || hasContextChanged() || // Force a re-render if the implementation changed due to hot reload: - workInProgress.type !== current$$1.type + 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). @@ -15640,7 +14052,6 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { switch (workInProgress.tag) { case HostRoot: pushHostRootContext(workInProgress); - resetHydrationState(); break; case HostComponent: @@ -15649,9 +14060,9 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { if ( workInProgress.mode & ConcurrentMode && renderExpirationTime !== Never && - shouldDeprioritizeSubtree(workInProgress.type, newProps) + shouldDeprioritizeSubtree(workInProgress.type) ) { - if (enableSchedulerTracing) { + { markSpawnedWork(Never); } // Schedule this fiber to re-render at offscreen priority. Then bailout. @@ -15685,14 +14096,19 @@ function beginWork$1(current$$1, 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; @@ -15701,19 +14117,6 @@ function beginWork$1(current$$1, 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. @@ -15729,7 +14132,7 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { // The primary children have pending work. Use the normal path // to attempt to render the primary children again. return updateSuspenseComponent( - current$$1, + current, workInProgress, renderExpirationTime ); @@ -15741,7 +14144,7 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { // priority. Bailout. var child = bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ); @@ -15765,8 +14168,7 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { } case SuspenseListComponent: { - var didSuspendBefore = - (current$$1.effectTag & DidCapture) !== NoEffect; + var didSuspendBefore = (current.effectTag & DidCapture) !== NoEffect; var _hasChildWork = workInProgress.childExpirationTime >= renderExpirationTime; @@ -15779,7 +14181,7 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { // tree which will affect the tail. So we need to use the normal // path to compute the correct tail. return updateSuspenseListComponent( - current$$1, + current, workInProgress, renderExpirationTime ); @@ -15815,7 +14217,7 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { } return bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ); @@ -15828,14 +14230,18 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { } } else { didReceiveUpdate = false; - } // Before entering the begin phase, clear the expiration time. + } // Before entering the begin phase, clear pending update priority. + // TODO: This assumes that we're about to evaluate the component and process + // the update queue. However, there's an exception: SimpleMemoComponent + // sometimes bails out later in the begin phase. This indicates that we should + // move this assignment out of the common path and into each branch. workInProgress.expirationTime = NoWork; switch (workInProgress.tag) { case IndeterminateComponent: { return mountIndeterminateComponent( - current$$1, + current, workInProgress, workInProgress.type, renderExpirationTime @@ -15845,7 +14251,7 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { case LazyComponent: { var elementType = workInProgress.elementType; return mountLazyComponent( - current$$1, + current, workInProgress, elementType, updateExpirationTime, @@ -15861,7 +14267,7 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { ? unresolvedProps : resolveDefaultProps(_Component, unresolvedProps); return updateFunctionComponent( - current$$1, + current, workInProgress, _Component, resolvedProps, @@ -15879,7 +14285,7 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { : resolveDefaultProps(_Component2, _unresolvedProps); return updateClassComponent( - current$$1, + current, workInProgress, _Component2, _resolvedProps, @@ -15888,28 +14294,24 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { } case HostRoot: - return updateHostRoot(current$$1, workInProgress, renderExpirationTime); + return updateHostRoot(current, workInProgress, renderExpirationTime); case HostComponent: - return updateHostComponent( - current$$1, - workInProgress, - renderExpirationTime - ); + return updateHostComponent(current, workInProgress, renderExpirationTime); case HostText: - return updateHostText(current$$1, workInProgress); + return updateHostText(); case SuspenseComponent: return updateSuspenseComponent( - current$$1, + current, workInProgress, renderExpirationTime ); case HostPortal: return updatePortalComponent( - current$$1, + current, workInProgress, renderExpirationTime ); @@ -15924,7 +14326,7 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { : resolveDefaultProps(type, _unresolvedProps2); return updateForwardRef( - current$$1, + current, workInProgress, type, _resolvedProps2, @@ -15933,24 +14335,24 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { } case Fragment: - return updateFragment(current$$1, workInProgress, renderExpirationTime); + return updateFragment(current, workInProgress, renderExpirationTime); case Mode: - return updateMode(current$$1, workInProgress, renderExpirationTime); + return updateMode(current, workInProgress, renderExpirationTime); case Profiler: - return updateProfiler(current$$1, workInProgress, renderExpirationTime); + return updateProfiler(current, workInProgress, renderExpirationTime); case ContextProvider: return updateContextProvider( - current$$1, + current, workInProgress, renderExpirationTime ); case ContextConsumer: return updateContextConsumer( - current$$1, + current, workInProgress, renderExpirationTime ); @@ -15961,334 +14363,77 @@ function beginWork$1(current$$1, workInProgress, renderExpirationTime) { var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3); - { - if (workInProgress.type !== workInProgress.elementType) { - var outerPropTypes = _type2.propTypes; - - 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 - ); - } - - 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); + { + if (workInProgress.type !== workInProgress.elementType) { + var outerPropTypes = _type2.propTypes; + + if (outerPropTypes) { + checkPropTypes( + outerPropTypes, + _resolvedProps3, // Resolved for outer only + "prop", + getComponentName(_type2) + ); + } + } } - return scopedNodes.length === 0 ? null : scopedNodes; - }, - queryFirstNode: function(fn) { - var currentFiber = instance.fiber; - var child = currentFiber.child; + _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3); + return updateMemoComponent( + current, + workInProgress, + _type2, + _resolvedProps3, + updateExpirationTime, + renderExpirationTime + ); + } - if (child !== null) { - return collectFirstScopedNodeFromChildren(child, fn); - } + case SimpleMemoComponent: { + return updateSimpleMemoComponent( + current, + workInProgress, + workInProgress.type, + workInProgress.pendingProps, + updateExpirationTime, + renderExpirationTime + ); + } - return null; - }, - containsNode: function(node) { - var fiber = getInstanceFromNode$1(node); + case IncompleteClassComponent: { + var _Component3 = workInProgress.type; + var _unresolvedProps4 = workInProgress.pendingProps; - while (fiber !== null) { - if ( - fiber.tag === ScopeComponent && - fiber.type === scope && - fiber.stateNode === instance - ) { - return true; - } + var _resolvedProps4 = + workInProgress.elementType === _Component3 + ? _unresolvedProps4 + : resolveDefaultProps(_Component3, _unresolvedProps4); - fiber = fiber.return; - } + return mountIncompleteClassComponent( + current, + workInProgress, + _Component3, + _resolvedProps4, + renderExpirationTime + ); + } - return false; + case SuspenseListComponent: { + return updateSuspenseListComponent( + current, + workInProgress, + renderExpirationTime + ); } - }; + } + + { + 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) { @@ -16306,7 +14451,7 @@ var updateHostContainer; var updateHostComponent$1; var updateHostText$1; -if (supportsMutation) { +{ // Mutation mode appendAllChildren = function( parent, @@ -16321,13 +14466,8 @@ if (supportsMutation) { 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) { + } else if (node.tag === HostPortal); + else if (node.child !== null) { node.child.return = node; node = node.child; continue; @@ -16379,379 +14519,21 @@ if (supportsMutation) { // component is hitting the resume path. Figure out why. Possibly // related to `hidden`. - var updatePayload = prepareUpdate( - instance, - type, - oldProps, - newProps, - rootContainerInstance, - currentHostContext - ); // TODO: Type this specific to this type of component. + var updatePayload = prepareUpdate(); // 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. - 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); - } - - 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 + if (updatePayload) { + markUpdate(workInProgress); + } }; updateHostText$1 = function(current, workInProgress, oldText, newText) { - // Noop + // If the text differs, mark it as an update. All the work in done in commitWork. + if (oldText !== newText) { + markUpdate(workInProgress); + } }; } @@ -16830,14 +14612,16 @@ function completeWork(current, workInProgress, renderExpirationTime) { switch (workInProgress.tag) { case IndeterminateComponent: - break; - case LazyComponent: - break; - case SimpleMemoComponent: case FunctionComponent: - break; + case ForwardRef: + case Fragment: + case Mode: + case Profiler: + case ContextConsumer: + case MemoComponent: + return null; case ClassComponent: { var Component = workInProgress.type; @@ -16846,7 +14630,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { popContext(workInProgress); } - break; + return null; } case HostRoot: { @@ -16862,7 +14646,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(workInProgress); + var wasHydrated = popHydrationState(); if (wasHydrated) { // If we hydrated, then we'll need to schedule an update for @@ -16872,7 +14656,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { } updateHostContainer(workInProgress); - break; + return null; } case HostComponent: { @@ -16889,15 +14673,6 @@ 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); } @@ -16909,42 +14684,24 @@ function completeWork(current, workInProgress, renderExpirationTime) { ); } // This can happen when we abort work. - break; + return 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 + // or completeWork depending on whether we want to add them top->down or // bottom->up. Top->down is faster in IE11. - var _wasHydrated = popHydrationState(workInProgress); + var _wasHydrated = popHydrationState(); 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 + if (prepareToHydrateHostInstance()) { + // If changes to the hydrated node need 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, @@ -16956,30 +14713,10 @@ 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, - type, - newProps, - rootContainerInstance, - currentHostContext - ) - ) { + if (finalizeInitialChildren(instance)) { markUpdate(workInProgress); } } @@ -16990,7 +14727,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { } } - break; + return null; } case HostText: { @@ -17014,10 +14751,10 @@ function completeWork(current, workInProgress, renderExpirationTime) { var _currentHostContext = getHostContext(); - var _wasHydrated2 = popHydrationState(workInProgress); + var _wasHydrated2 = popHydrationState(); if (_wasHydrated2) { - if (prepareToHydrateHostTextInstance(workInProgress)) { + if (prepareToHydrateHostTextInstance()) { markUpdate(workInProgress); } } else { @@ -17030,56 +14767,13 @@ function completeWork(current, workInProgress, renderExpirationTime) { } } - break; + return null; } - 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. @@ -17091,9 +14785,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { var prevDidTimeout = false; if (current === null) { - if (workInProgress.memoizedProps.fallback !== undefined) { - popHydrationState(workInProgress); - } + if (workInProgress.memoizedProps.fallback !== undefined); } else { var prevState = current.memoizedState; prevDidTimeout = prevState !== null; @@ -17158,64 +14850,30 @@ 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 proimse. This flag is also used to hide the + // retry listener to the promise. This flag is also used to hide the // primary children. In mutation mode, we also need the flag to - // *unhide* children that were previously hidden, so check if the + // *unhide* children that were previously hidden, so check if this // is currently timed out, too. workInProgress.effectTag |= Update; } } - if ( - enableSuspenseCallback && - workInProgress.updateQueue !== null && - workInProgress.memoizedProps.suspenseCallback != null - ) { - // Always notify the callback - workInProgress.effectTag |= Update; - } - - break; + return null; } - case Fragment: - break; - - case Mode: - break; - - case Profiler: - break; - case HostPortal: popHostContainer(workInProgress); updateHostContainer(workInProgress); - break; + return null; case ContextProvider: // Pop provider fiber popProvider(workInProgress); - break; - - case ContextConsumer: - break; - - case MemoComponent: - break; + return null; case IncompleteClassComponent: { // Same as class component case. I put it down here so that the tags are @@ -17226,7 +14884,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { popContext(workInProgress); } - break; + return null; } case SuspenseListComponent: { @@ -17234,9 +14892,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. - break; + // We're running in the default, "independent" mode. + // We don't do anything in this mode. + return null; } var didSuspendAlready = @@ -17352,7 +15010,10 @@ function completeWork(current, workInProgress, renderExpirationTime) { return null; } } else if ( - now() > renderState.tailExpiration && + // 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 @@ -17369,7 +15030,7 @@ function completeWork(current, workInProgress, renderExpirationTime) { var nextPriority = renderExpirationTime - 1; workInProgress.expirationTime = workInProgress.childExpirationTime = nextPriority; - if (enableSchedulerTracing) { + { markSpawnedWork(nextPriority); } } @@ -17402,13 +15063,19 @@ 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; + 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 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. @@ -17429,131 +15096,17 @@ function completeWork(current, workInProgress, renderExpirationTime) { return next; } - break; - } - - 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; } } - return 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, renderExpirationTime) { @@ -17599,20 +15152,6 @@ 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) { @@ -17682,9 +15221,6 @@ function unwindInterruptedWork(interruptedWork) { case ContextProvider: popProvider(interruptedWork); break; - - default: - break; } } @@ -17699,6 +15235,7 @@ function createCapturedValue(value, source) { } // Module provided by RN: + if ( !( typeof ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog === @@ -17746,7 +15283,8 @@ 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); // For a more detailed description of this block, see: + 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 } @@ -17783,7 +15321,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); + console["error"](combinedMessage); // Don't transform to our wrapper } } @@ -17832,33 +15370,37 @@ function logError(boundary, errorInfo) { } } -var callComponentWillUnmountWithTimer = function(current$$1, instance) { - startPhaseTimer(current$$1, "componentWillUnmount"); - instance.props = current$$1.memoizedProps; - instance.state = current$$1.memoizedState; - instance.componentWillUnmount(); +var callComponentWillUnmountWithTimer = function(current, instance) { + startPhaseTimer(current, "componentWillUnmount"); + instance.props = current.memoizedProps; + instance.state = current.memoizedState; + + { + instance.componentWillUnmount(); + } + stopPhaseTimer(); }; // Capture errors so they don't interrupt unmounting. -function safelyCallComponentWillUnmount(current$$1, instance) { +function safelyCallComponentWillUnmount(current, instance) { { invokeGuardedCallback( null, callComponentWillUnmountWithTimer, null, - current$$1, + current, instance ); if (hasCaughtError()) { var unmountError = clearCaughtError(); - captureCommitPhaseError(current$$1, unmountError); + captureCommitPhaseError(current, unmountError); } } } -function safelyDetachRef(current$$1) { - var ref = current$$1.ref; +function safelyDetachRef(current) { + var ref = current.ref; if (ref !== null) { if (typeof ref === "function") { @@ -17867,7 +15409,7 @@ function safelyDetachRef(current$$1) { if (hasCaughtError()) { var refError = clearCaughtError(); - captureCommitPhaseError(current$$1, refError); + captureCommitPhaseError(current, refError); } } } else { @@ -17876,31 +15418,31 @@ function safelyDetachRef(current$$1) { } } -function safelyCallDestroy(current$$1, destroy) { +function safelyCallDestroy(current, destroy) { { invokeGuardedCallback(null, destroy, null); if (hasCaughtError()) { var error = clearCaughtError(); - captureCommitPhaseError(current$$1, error); + captureCommitPhaseError(current, error); } } } -function commitBeforeMutationLifeCycles(current$$1, finishedWork) { +function commitBeforeMutationLifeCycles(current, finishedWork) { switch (finishedWork.tag) { case FunctionComponent: case ForwardRef: - case SimpleMemoComponent: { - commitHookEffectList(UnmountSnapshot, NoEffect$1, finishedWork); + case SimpleMemoComponent: + case Block: { return; } case ClassComponent: { if (finishedWork.effectTag & Snapshot) { - if (current$$1 !== null) { - var prevProps = current$$1.memoizedProps; - var prevState = current$$1.memoizedState; + 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. @@ -17911,28 +15453,27 @@ function commitBeforeMutationLifeCycles(current$$1, finishedWork) { 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; + 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" + ); + } } } @@ -17948,8 +15489,8 @@ function commitBeforeMutationLifeCycles(current$$1, finishedWork) { if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) { didWarnSet.add(finishedWork.type); - warningWithoutStack$1( - false, + + error( "%s.getSnapshotBeforeUpdate(): A snapshot value (or null) " + "must be returned. You have returned undefined.", getComponentName(finishedWork.type) @@ -17972,18 +15513,16 @@ function commitBeforeMutationLifeCycles(current$$1, finishedWork) { case IncompleteClassComponent: // Nothing to do for these component types 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 commitHookEffectList(unmountTag, mountTag, finishedWork) { +function commitHookEffectListUnmount(tag, finishedWork) { var updateQueue = finishedWork.updateQueue; var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; @@ -17992,7 +15531,7 @@ function commitHookEffectList(unmountTag, mountTag, finishedWork) { var effect = firstEffect; do { - if ((effect.tag & unmountTag) !== NoEffect$1) { + if ((effect.tag & tag) === tag) { // Unmount var destroy = effect.destroy; effect.destroy = undefined; @@ -18002,22 +15541,36 @@ function commitHookEffectList(unmountTag, mountTag, finishedWork) { } } - if ((effect.tag & mountTag) !== NoEffect$1) { + 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) { // 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 " + @@ -18032,11 +15585,10 @@ function commitHookEffectList(unmountTag, mountTag, 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; } - warningWithoutStack$1( - false, + error( "An effect function must not return anything besides a function, " + "which is used for clean-up.%s%s", addendum, @@ -18056,37 +15608,49 @@ function commitPassiveHookEffects(finishedWork) { switch (finishedWork.tag) { case FunctionComponent: case ForwardRef: - case SimpleMemoComponent: { - commitHookEffectList(UnmountPassive, NoEffect$1, finishedWork); - commitHookEffectList(NoEffect$1, MountPassive, finishedWork); - break; - } + 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); + } - default: break; + } } } } function commitLifeCycles( finishedRoot, - current$$1, + current, finishedWork, committedExpirationTime ) { switch (finishedWork.tag) { case FunctionComponent: case ForwardRef: - case SimpleMemoComponent: { - commitHookEffectList(UnmountLayout, MountLayout, finishedWork); - break; + 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 ClassComponent: { var instance = finishedWork.stateNode; if (finishedWork.effectTag & Update) { - if (current$$1 === null) { + 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. @@ -18096,42 +15660,41 @@ function commitLifeCycles( 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; + if (instance.props !== finishedWork.memoizedProps) { + error( + "Expected %s props to match memoized props before " + + "componentDidMount. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } + + if (instance.state !== finishedWork.memoizedState) { + error( + "Expected %s state to match memoized state before " + + "componentDidMount. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.state`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } } } - instance.componentDidMount(); + { + instance.componentDidMount(); + } + stopPhaseTimer(); } else { var prevProps = finishedWork.elementType === finishedWork.type - ? current$$1.memoizedProps - : resolveDefaultProps( - finishedWork.type, - current$$1.memoizedProps - ); - var prevState = current$$1.memoizedState; + ? 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. @@ -18141,36 +15704,38 @@ function commitLifeCycles( 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; + if (instance.props !== finishedWork.memoizedProps) { + error( + "Expected %s props to match memoized props before " + + "componentDidUpdate. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } + + if (instance.state !== finishedWork.memoizedState) { + error( + "Expected %s state to match memoized state before " + + "componentDidUpdate. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.state`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } } } - instance.componentDidUpdate( - prevProps, - prevState, - instance.__reactInternalSnapshotBeforeUpdate - ); + { + instance.componentDidUpdate( + prevProps, + prevState, + instance.__reactInternalSnapshotBeforeUpdate + ); + } + stopPhaseTimer(); } } @@ -18183,39 +15748,33 @@ function commitLifeCycles( 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; + if (instance.props !== finishedWork.memoizedProps) { + error( + "Expected %s props to match memoized props before " + + "processing the update queue. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } + + if (instance.state !== finishedWork.memoizedState) { + error( + "Expected %s state to match memoized state before " + + "processing the update queue. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.state`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } } } // We could update instance props and state here, // but instead we rely on them being set during last render. // TODO: revisit this when we implement resuming. - commitUpdateQueue( - finishedWork, - updateQueue, - instance, - committedExpirationTime - ); + commitUpdateQueue(finishedWork, updateQueue, instance); } return; @@ -18239,12 +15798,7 @@ function commitLifeCycles( } } - commitUpdateQueue( - finishedWork, - _updateQueue, - _instance, - committedExpirationTime - ); + commitUpdateQueue(finishedWork, _updateQueue, _instance); } return; @@ -18256,7 +15810,7 @@ function commitLifeCycles( // These effects should only be committed when components are first mounted, // aka when there is no current/alternate. - if (current$$1 === null && finishedWork.effectTag & Update) { + if (current === null && finishedWork.effectTag & Update) { var type = finishedWork.type; var props = finishedWork.memoizedProps; } @@ -18275,29 +15829,24 @@ function commitLifeCycles( } case Profiler: { - if (enableProfilerTimer) { - var onRender = finishedWork.memoizedProps.onRender; + { + var _finishedWork$memoize2 = finishedWork.memoizedProps, + onCommit = _finishedWork$memoize2.onCommit, + onRender = _finishedWork$memoize2.onRender; + var effectDuration = finishedWork.stateNode.effectDuration; + var commitTime = getCommitTime(); if (typeof onRender === "function") { - if (enableSchedulerTracing) { + { onRender( finishedWork.memoizedProps.id, - current$$1 === null ? "mount" : "update", + current === null ? "mount" : "update", finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, - getCommitTime(), + commitTime, finishedRoot.memoizedInteractions ); - } else { - onRender( - finishedWork.memoizedProps.id, - current$$1 === null ? "mount" : "update", - finishedWork.actualDuration, - finishedWork.treeBaseDuration, - finishedWork.actualStartTime, - getCommitTime() - ); } } } @@ -18306,7 +15855,6 @@ function commitLifeCycles( } case SuspenseComponent: { - commitSuspenseHydrationCallbacks(finishedRoot, finishedWork); return; } @@ -18315,19 +15863,17 @@ function commitLifeCycles( case FundamentalComponent: case ScopeComponent: 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 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; @@ -18345,7 +15891,7 @@ function hideOrUnhideAllChildren(finishedWork, isHidden) { var _instance3 = node.stateNode; if (isHidden) { - hideTextInstance(_instance3); + hideTextInstance(); } else { unhideTextInstance(_instance3, node.memoizedProps); } @@ -18400,17 +15946,12 @@ 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")) { - warningWithoutStack$1( - false, + error( "Unexpected ref object provided for %s. " + "Use either a ref-setter function or React.createRef().%s", getComponentName(finishedWork.type), @@ -18424,8 +15965,8 @@ function commitAttachRef(finishedWork) { } } -function commitDetachRef(current$$1) { - var currentRef = current$$1.ref; +function commitDetachRef(current) { + var currentRef = current.ref; if (currentRef !== null) { if (typeof currentRef === "function") { @@ -18438,92 +15979,77 @@ function commitDetachRef(current$$1) { // deletion, so don't let them throw. Host-originating errors should // interrupt deletion, so it's okay -function commitUnmount(finishedRoot, current$$1, renderPriorityLevel) { - onCommitUnmount(current$$1); +function commitUnmount(finishedRoot, current, renderPriorityLevel) { + onCommitUnmount(current); - switch (current$$1.tag) { + switch (current.tag) { case FunctionComponent: case ForwardRef: case MemoComponent: - case SimpleMemoComponent: { - var updateQueue = current$$1.updateQueue; + case SimpleMemoComponent: + case Block: { + var updateQueue = current.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 destroy = effect.destroy; - - if (destroy !== undefined) { - safelyCallDestroy(current$$1, 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 _effect3 = effect, + _destroy = _effect3.destroy, + _tag = _effect3.tag; + + if (_destroy !== undefined) { + { + safelyCallDestroy(current, _destroy); + } + } - effect = effect.next; - } while (effect !== firstEffect); - }); + effect = effect.next; + } while (effect !== firstEffect); + }); + } } } - break; + return; } case ClassComponent: { - safelyDetachRef(current$$1); - var instance = current$$1.stateNode; + safelyDetachRef(current); + var instance = current.stateNode; if (typeof instance.componentWillUnmount === "function") { - safelyCallComponentWillUnmount(current$$1, instance); + safelyCallComponentWillUnmount(current, instance); } return; } case HostComponent: { - 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); + safelyDetachRef(current); return; } @@ -18531,48 +16057,23 @@ function commitUnmount(finishedRoot, current$$1, renderPriorityLevel) { // 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); + { + unmountHostComponents(finishedRoot, current, renderPriorityLevel); } 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: { - if (enableScopeAPI) { - safelyDetachRef(current$$1); - } + return; } } } @@ -18592,7 +16093,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. - (!supportsMutation || node.tag !== HostPortal) + node.tag !== HostPortal ) { node.child.return = node; node = node.child; @@ -18616,72 +16117,30 @@ function commitNestedUnmounts(finishedRoot, root, renderPriorityLevel) { } } -function detachFiber(current$$1) { - var alternate = current$$1.alternate; // Cut off the return pointers to disconnect it from the tree. Ideally, we +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. - 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; + 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; 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; @@ -18759,10 +16218,6 @@ 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; @@ -18786,10 +16241,6 @@ function commitPlacement(finishedWork) { break; case FundamentalComponent: - if (enableFundamentalAPI) { - parent = parentStateNode.instance; - isContainer = false; - } // eslint-disable-next-line-no-fallthrough @@ -18801,65 +16252,79 @@ 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. - var node = finishedWork; + if (isContainer) { + insertOrAppendPlacementNodeIntoContainer(finishedWork, before, parent); + } else { + insertOrAppendPlacementNode(finishedWork, before, parent); + } +} - while (true) { - var isHost = node.tag === HostComponent || node.tag === HostText; +function insertOrAppendPlacementNodeIntoContainer(node, before, parent) { + var tag = node.tag; + var isHost = tag === HostComponent || tag === HostText; - if (isHost || (enableFundamentalAPI && node.tag === FundamentalComponent)) { - var stateNode = isHost ? node.stateNode : node.stateNode.instance; + if (isHost || enableFundamentalAPI) { + 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; + if (before) { + insertInContainerBefore(parent); + } else { + appendChildToContainer(parent, stateNode); } + } else if (tag === HostPortal); + else { + var child = node.child; - if (node === finishedWork) { - return; - } + if (child !== null) { + insertOrAppendPlacementNodeIntoContainer(child, before, parent); + var sibling = child.sibling; - while (node.sibling === null) { - if (node.return === null || node.return === finishedWork) { - return; + while (sibling !== null) { + insertOrAppendPlacementNodeIntoContainer(sibling, before, parent); + sibling = sibling.sibling; } + } + } +} - node = node.return; +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); } + } else if (tag === HostPortal); + else { + var child = node.child; - node.sibling.return = node.return; - node = node.sibling; + if (child !== null) { + insertOrAppendPlacementNode(child, before, parent); + var sibling = child.sibling; + + while (sibling !== null) { + insertOrAppendPlacementNode(sibling, before, parent); + sibling = sibling.sibling; + } + } } } -function unmountHostComponents(finishedRoot, current$$1, renderPriorityLevel) { +function unmountHostComponents(finishedRoot, current, renderPriorityLevel) { // We only have the top Fiber that was deleted but we need to recurse down its // children to find all the terminal nodes. - var node = current$$1; // Each iteration, currentParent is populated with node's host parent if not + var node = current; // Each iteration, currentParent is populated with node's host parent if not // currentParentIsValid. var currentParentIsValid = false; // Note: these two variables *must* always be updated together. @@ -18895,12 +16360,6 @@ function unmountHostComponents(finishedRoot, current$$1, renderPriorityLevel) { currentParent = parentStateNode.containerInfo; currentParentIsContainer = true; break findParent; - - case FundamentalComponent: - if (enableFundamentalAPI) { - currentParent = parentStateNode.instance; - currentParentIsContainer = false; - } } parent = parent.return; @@ -18918,37 +16377,6 @@ function unmountHostComponents(finishedRoot, current$$1, 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. @@ -18970,12 +16398,12 @@ function unmountHostComponents(finishedRoot, current$$1, renderPriorityLevel) { } } - if (node === current$$1) { + if (node === current) { return; } while (node.sibling === null) { - if (node.return === null || node.return === current$$1) { + if (node.return === null || node.return === current) { return; } @@ -18993,74 +16421,32 @@ function unmountHostComponents(finishedRoot, current$$1, renderPriorityLevel) { } } -function commitDeletion(finishedRoot, current$$1, renderPriorityLevel) { - if (supportsMutation) { +function commitDeletion(finishedRoot, current, renderPriorityLevel) { + { // Recursively delete all host nodes from the parent. // Detach refs and call componentWillUnmount() on the whole subtree. - unmountHostComponents(finishedRoot, current$$1, renderPriorityLevel); - } else { - // Detach refs and call componentWillUnmount() on the whole subtree. - commitNestedUnmounts(finishedRoot, current$$1, renderPriorityLevel); + unmountHostComponents(finishedRoot, current, renderPriorityLevel); } - detachFiber(current$$1); + detachFiber(current); } -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; - } - +function commitWork(current, finishedWork) { 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); + 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); + } + return; } @@ -19077,31 +16463,14 @@ function commitWork(current$$1, finishedWork) { // as the newProps. The updatePayload will contain the real change in // this case. - var oldProps = - current$$1 !== null ? current$$1.memoizedProps : newProps; + var oldProps = current !== null ? current.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; + var updatePayload = finishedWork.updateQueue; + finishedWork.updateQueue = null; - if (prevListeners !== nextListeners) { - updateEventListeners(nextListeners, finishedWork, null); - } + if (updatePayload !== null) { + commitUpdate(instance, updatePayload, type, oldProps, newProps); } } @@ -19120,22 +16489,12 @@ function commitWork(current$$1, finishedWork) { // as the newProps. The updatePayload will contain the real change in // this case. - var oldText = current$$1 !== null ? current$$1.memoizedProps : newText; + var oldText = current !== null ? current.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; } @@ -19157,46 +16516,12 @@ function commitWork(current$$1, finishedWork) { 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); - } - } - } - - 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." + ); } } @@ -19213,61 +16538,9 @@ function commitSuspenseComponent(finishedWork) { markCommitTimeOfFallback(); } - if (supportsMutation && primaryChildParent !== null) { + if (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) { @@ -19289,7 +16562,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); } @@ -19302,12 +16575,8 @@ function attachSuspenseRetryListeners(finishedWork) { } } -function commitResetTextContent(current$$1) { - if (!supportsMutation) { - return; - } - - resetTextContent(current$$1.stateNode); +function commitResetTextContent(current) { + resetTextContent(current.stateNode); } var PossiblyWeakMap = typeof WeakMap === "function" ? WeakMap : Map; @@ -19337,11 +16606,11 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { var getDerivedStateFromError = fiber.type.getDerivedStateFromError; if (typeof getDerivedStateFromError === "function") { - var error = errorInfo.value; + var error$1 = errorInfo.value; update.payload = function() { logError(fiber, errorInfo); - return getDerivedStateFromError(error); + return getDerivedStateFromError(error$1); }; } @@ -19364,9 +16633,9 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { logError(fiber, errorInfo); } - var error = errorInfo.value; + var error$1 = errorInfo.value; var stack = errorInfo.stack; - this.componentDidCatch(error, { + this.componentDidCatch(error$1, { componentStack: stack !== null ? stack : "" }); @@ -19375,14 +16644,13 @@ 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. - !(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; + 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" + ); + } } } }; @@ -19447,7 +16715,22 @@ function throwException( ) { // This is a thenable. var thenable = value; - checkForWrongSuspensePriorityInDEV(sourceFiber); + + 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; + } + } + var hasInvisibleParentBoundary = hasSuspenseContext( suspenseStackCursor.current, InvisibleParentSuspenseContext @@ -19621,9 +16904,6 @@ function throwException( } break; - - default: - break; } workInProgress = workInProgress.return; @@ -19631,18 +16911,15 @@ function throwException( } var ceil = Math.ceil; -var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher; -var ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner; -var IsSomeRendererActing = ReactSharedInternals.IsSomeRendererActing; +var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, + ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, + IsSomeRendererActing = ReactSharedInternals.IsSomeRendererActing; var NoContext = /* */ 0; var BatchedContext = /* */ 1; -var EventContext = - /* */ - 2; var DiscreteEventContext = /* */ 4; @@ -19668,7 +16945,7 @@ var workInProgressRoot = null; // The fiber we're working on var workInProgress = null; // The expiration time we're rendering -var renderExpirationTime = NoWork; // Whether to root completed, errored, suspended, etc. +var renderExpirationTime$1 = NoWork; // Whether to root completed, errored, suspended, etc. var workInProgressRootExitStatus = RootIncomplete; // A fatal error, if one is thrown @@ -19753,7 +17030,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; + return renderExpirationTime$1; } var expirationTime; @@ -19797,7 +17074,10 @@ 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) { + if ( + workInProgressRoot !== null && + expirationTime === renderExpirationTime$1 + ) { // This is a trick to move this update into a separate batch expirationTime -= 1; } @@ -19806,7 +17086,7 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { } function scheduleUpdateOnFiber(fiber, expirationTime) { checkForNestedUpdates(); - warnAboutInvalidUpdatesOnClassComponentsInDEV(fiber); + warnAboutRenderPhaseUpdatesInDEV(fiber); var root = markUpdateTimeFromFiberToRoot(fiber, expirationTime); if (root === null) { @@ -19940,7 +17220,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); + markRootSuspendedAtTime(root, renderExpirationTime$1); } } // Mark that the root has a pending update. @@ -19972,9 +17252,17 @@ function getNextRootExpirationTimeToWorkOn(root) { var lastPingedTime = root.lastPingedTime; var nextKnownPendingLevel = root.nextKnownPendingLevel; - return lastPingedTime > nextKnownPendingLevel - ? lastPingedTime - : 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; } // 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 @@ -20041,11 +17329,6 @@ 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, @@ -20064,7 +17347,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; + currentEventTime = NoWork; // Check if the render expired. if (didTimeout) { // The render task took too long to complete. Mark the current time as @@ -20079,83 +17362,50 @@ function performConcurrentWorkOnRoot(root, didTimeout) { var expirationTime = getNextRootExpirationTimeToWorkOn(root); - if (expirationTime !== NoWork) { - var originalCallbackNode = root.callbackNode; - - 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 ( - 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 (expirationTime === NoWork) { + return null; + } - if (workInProgress !== null) { - var prevExecutionContext = executionContext; - executionContext |= RenderContext; - var prevDispatcher = pushDispatcher(root); - var prevInteractions = pushInteractions(root); - startWorkLoopTimer(workInProgress); + var originalCallbackNode = root.callbackNode; - do { - try { - workLoopConcurrent(); - break; - } catch (thrownValue) { - handleError(root, thrownValue); - } - } while (true); + if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { + throw Error("Should not already be working."); + } - resetContextDependencies(); - executionContext = prevExecutionContext; - popDispatcher(prevDispatcher); + flushPassiveEffects(); + var exitStatus = renderRootConcurrent(root, expirationTime); - if (enableSchedulerTracing) { - popInteractions(prevInteractions); - } + 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 (workInProgressRootExitStatus === RootFatalErrored) { - var fatalError = workInProgressRootFatalError; - stopInterruptedWorkLoopTimer(); - prepareFreshStack(root, expirationTime); - markRootSuspendedAtTime(root, expirationTime); - ensureRootIsScheduled(root); - throw fatalError; - } + 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. - 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 - ); - } + var finishedWork = (root.finishedWork = root.current.alternate); + root.finishedExpirationTime = expirationTime; + finishConcurrentRender(root, finishedWork, exitStatus, expirationTime); + } - ensureRootIsScheduled(root); + 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; @@ -20167,9 +17417,6 @@ function finishConcurrentRender( exitStatus, expirationTime ) { - // Set this to null to indicate there's no in-progress render. - workInProgressRoot = null; - switch (exitStatus) { case RootIncomplete: case RootFatalErrored: { @@ -20182,19 +17429,9 @@ function finishConcurrentRender( // if I do. eslint-disable-next-line no-fallthrough case RootErrored: { - // 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. - + // We should have already attempted to retry this tree. If we reached + // this point, it errored again. Commit it. + commitRoot(root); break; } @@ -20204,9 +17441,7 @@ function finishConcurrentRender( if (expirationTime === lastSuspendedTime) { root.nextKnownPendingLevel = getRemainingExpirationTime(finishedWork); - } - - flushSuspensePriorityWarningInDEV(); // We have an acceptable loading state. We need to figure out if we + } // 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 @@ -20217,7 +17452,7 @@ function finishConcurrentRender( if ( hasNotProcessedNewUpdates && // do not delay if we're inside an act() scope - !(true && flushSuspenseFallbacksInTests && IsThisRendererActing.current) + !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 @@ -20281,12 +17516,7 @@ 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) { @@ -20376,11 +17606,6 @@ 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 ) { @@ -20418,149 +17643,67 @@ function finishConcurrentRender( // through Scheduler function performSyncWorkOnRoot(root) { - // Check if there's expired work on this root. Otherwise, render at Sync. - var lastExpiredTime = root.lastExpiredTime; - 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."); - } + 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 lastExpiredTime = root.lastExpiredTime; + var expirationTime; + if (lastExpiredTime !== NoWork) { + // There's expired work on this root. Check if we have a partial tree + // that we can reuse. if ( - root !== workInProgressRoot || - expirationTime !== renderExpirationTime + root === workInProgressRoot && + renderExpirationTime$1 >= 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); + // 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; } + } else { + // There's no expired work. This must be a new, synchronous render. + expirationTime = Sync; } - return null; -} - -function finishSyncRender(root, exitStatus, expirationTime) { - // Set this to null to indicate there's no in-progress render. - workInProgressRoot = null; + var exitStatus = renderRootSync(root, expirationTime); - { - if (exitStatus === RootSuspended || exitStatus === RootSuspendedWithDelay) { - flushSuspensePriorityWarningInDEV(); - } + 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); } - 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; - } + 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. - flushPendingDiscreteUpdates(); // If the discrete updates scheduled passive effects, flush them now so that - // they fire before the next serial event. + root.finishedWork = root.current.alternate; + root.finishedExpirationTime = expirationTime; + commitRoot(root); // Before exiting, make sure there's a callback scheduled for the next + // pending level. - flushPassiveEffects(); + ensureRootIsScheduled(root); + return null; } - 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; @@ -20576,38 +17719,6 @@ 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) { { @@ -20654,8 +17765,8 @@ function prepareFreshStack(root, expirationTime) { } workInProgressRoot = root; - workInProgress = createWorkInProgress(root.current, null, expirationTime); - renderExpirationTime = expirationTime; + workInProgress = createWorkInProgress(root.current, null); + renderExpirationTime$1 = expirationTime; workInProgressRootExitStatus = RootIncomplete; workInProgressRootFatalError = null; workInProgressRootLatestProcessedExpirationTime = Sync; @@ -20664,13 +17775,12 @@ function prepareFreshStack(root, expirationTime) { workInProgressRootNextUnprocessedUpdateTime = NoWork; workInProgressRootHasPendingPing = false; - if (enableSchedulerTracing) { + { spawnedWorkDuringRender = null; } { ReactStrictModeWarnings.discardPendingWarnings(); - componentsThatTriggeredHighPriSuspend = null; } } @@ -20679,7 +17789,7 @@ function handleError(root, thrownValue) { try { // Reset module-level state that was set during the render phase. resetContextDependencies(); - resetHooks(); + resetHooksAfterThrow(); resetCurrentFiber(); if (workInProgress === null || workInProgress.return === null) { @@ -20688,7 +17798,14 @@ function handleError(root, thrownValue) { // supposed to capture all errors that weren't caught by an error // boundary. workInProgressRootExitStatus = RootFatalErrored; - workInProgressRootFatalError = thrownValue; + 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; return null; } @@ -20704,7 +17821,7 @@ function handleError(root, thrownValue) { workInProgress.return, workInProgress, thrownValue, - renderExpirationTime + renderExpirationTime$1 ); workInProgress = completeUnitOfWork(workInProgress); } catch (yetAnotherThrownValue) { @@ -20718,8 +17835,8 @@ function handleError(root, thrownValue) { } function pushDispatcher(root) { - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = ContextOnlyDispatcher; + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; if (prevDispatcher === null) { // The React isomorphic package does not include a default dispatcher. @@ -20732,21 +17849,19 @@ function pushDispatcher(root) { } function popDispatcher(prevDispatcher) { - ReactCurrentDispatcher.current = prevDispatcher; + ReactCurrentDispatcher$1.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; } } @@ -20799,7 +17914,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); + markRootSuspendedAtTime(workInProgressRoot, renderExpirationTime$1); markRootUpdatedAtTime( workInProgressRoot, workInProgressRootNextUnprocessedUpdateTime @@ -20838,6 +17953,56 @@ 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 */ @@ -20848,6 +18013,55 @@ 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() { @@ -20861,17 +18075,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$$1 = unitOfWork.alternate; + var current = unitOfWork.alternate; startWorkTimer(unitOfWork); setCurrentFiber(unitOfWork); var next; - if (enableProfilerTimer && (unitOfWork.mode & ProfileMode) !== NoMode) { + if ((unitOfWork.mode & ProfileMode) !== NoMode) { startProfilerTimer(unitOfWork); - next = beginWork$$1(current$$1, unitOfWork, renderExpirationTime); + next = beginWork$1(current, unitOfWork, renderExpirationTime$1); stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true); } else { - next = beginWork$$1(current$$1, unitOfWork, renderExpirationTime); + next = beginWork$1(current, unitOfWork, renderExpirationTime$1); } resetCurrentFiber(); @@ -20895,21 +18109,18 @@ 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$$1 = workInProgress.alternate; + var current = 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 ( - !enableProfilerTimer || - (workInProgress.mode & ProfileMode) === NoMode - ) { - next = completeWork(current$$1, workInProgress, renderExpirationTime); + if ((workInProgress.mode & ProfileMode) === NoMode) { + next = completeWork(current, workInProgress, renderExpirationTime$1); } else { startProfilerTimer(workInProgress); - next = completeWork(current$$1, workInProgress, renderExpirationTime); // Update render duration assuming we didn't error. + next = completeWork(current, workInProgress, renderExpirationTime$1); // Update render duration assuming we didn't error. stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false); } @@ -20965,12 +18176,9 @@ 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, renderExpirationTime); // Because this fiber did not complete, don't reset its expiration time. + var _next = unwindWork(workInProgress); // Because this fiber did not complete, don't reset its expiration time. - if ( - enableProfilerTimer && - (workInProgress.mode & ProfileMode) !== NoMode - ) { + if ((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. @@ -21033,7 +18241,7 @@ function getRemainingExpirationTime(fiber) { function resetChildExpirationTime(completedWork) { if ( - renderExpirationTime !== Never && + renderExpirationTime$1 !== Never && completedWork.childExpirationTime === Never ) { // The children of this component are hidden. Don't bubble their @@ -21043,7 +18251,7 @@ function resetChildExpirationTime(completedWork) { var newChildExpirationTime = NoWork; // Bubble up the earliest expiration time. - if (enableProfilerTimer && (completedWork.mode & ProfileMode) !== NoMode) { + if ((completedWork.mode & ProfileMode) !== NoMode) { // In profiling mode, resetChildExpirationTime is also used to reset // profiler durations. var actualDuration = completedWork.actualDuration; @@ -21114,7 +18322,16 @@ function commitRoot(root) { } function commitRootImpl(root, renderPriorityLevel) { - flushPassiveEffects(); + 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); + flushRenderPhaseStrictModeWarningsInDEV(); if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { @@ -21158,8 +18375,7 @@ function commitRootImpl(root, renderPriorityLevel) { // We can reset these now that they are finished. workInProgressRoot = null; workInProgress = null; - renderExpirationTime = NoWork; - } else { + renderExpirationTime$1 = NoWork; } // 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. @@ -21217,7 +18433,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(); @@ -21291,7 +18507,7 @@ function commitRootImpl(root, renderPriorityLevel) { requestPaint(); - if (enableSchedulerTracing) { + { popInteractions(prevInteractions); } @@ -21305,7 +18521,7 @@ function commitRootImpl(root, renderPriorityLevel) { startCommitSnapshotEffectsTimer(); stopCommitSnapshotEffectsTimer(); - if (enableProfilerTimer) { + { recordCommitTime(); } @@ -21341,7 +18557,7 @@ function commitRootImpl(root, renderPriorityLevel) { var remainingExpirationTime = root.firstPendingTime; if (remainingExpirationTime !== NoWork) { - if (enableSchedulerTracing) { + { if (spawnedWorkDuringRender !== null) { var expirationTimes = spawnedWorkDuringRender; spawnedWorkDuringRender = null; @@ -21363,7 +18579,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. @@ -21417,8 +18633,8 @@ function commitBeforeMutationEffects() { if ((effectTag & Snapshot) !== NoEffect) { setCurrentFiber(nextEffect); recordEffect(); - var current$$1 = nextEffect.alternate; - commitBeforeMutationLifeCycles(current$$1, nextEffect); + var current = nextEffect.alternate; + commitBeforeMutationLifeCycles(current, nextEffect); resetCurrentFiber(); } @@ -21449,10 +18665,10 @@ function commitMutationEffects(root, renderPriorityLevel) { } if (effectTag & Ref) { - var current$$1 = nextEffect.alternate; + var current = nextEffect.alternate; - if (current$$1 !== null) { - commitDetachRef(current$$1); + if (current !== null) { + commitDetachRef(current); } } // The following switch statement is only concerned about placement, // updates, and deletions. To avoid needing to add a case for every possible @@ -21524,8 +18740,8 @@ function commitLayoutEffects(root, committedExpirationTime) { if (effectTag & (Update | Callback)) { recordEffect(); - var current$$1 = nextEffect.alternate; - commitLifeCycles(root, current$$1, nextEffect, committedExpirationTime); + var current = nextEffect.alternate; + commitLifeCycles(root, current, nextEffect); } if (effectTag & Ref) { @@ -21565,36 +18781,40 @@ 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 prevInteractions = pushInteractions(root); - var effect = root.current.firstEffect; + { + // 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 (effect !== null) { - { - setCurrentFiber(effect); - invokeGuardedCallback(null, commitPassiveHookEffects, null, effect); + while (_effect2 !== null) { + { + setCurrentFiber(_effect2); + invokeGuardedCallback(null, commitPassiveHookEffects, null, _effect2); - if (hasCaughtError()) { - if (!(effect !== null)) { - throw Error("Should be working on an effect."); + if (hasCaughtError()) { + if (!(_effect2 !== null)) { + throw Error("Should be working on an effect."); + } + + var _error5 = clearCaughtError(); + + captureCommitPhaseError(_effect2, _error5); } - var error = clearCaughtError(); - captureCommitPhaseError(effect, error); + resetCurrentFiber(); } - resetCurrentFiber(); - } - - var nextNextEffect = effect.nextEffect; // Remove nextEffect pointer to assist GC + var nextNextEffect = _effect2.nextEffect; // Remove nextEffect pointer to assist GC - effect.nextEffect = null; - effect = nextNextEffect; + _effect2.nextEffect = null; + _effect2 = nextNextEffect; + } } - if (enableSchedulerTracing) { + { popInteractions(prevInteractions); finishPendingInteractions(root, expirationTime); } @@ -21696,7 +18916,7 @@ function pingSuspendedRoot(root, thenable, suspendedTime) { pingCache.delete(thenable); } - if (workInProgressRoot === root && renderExpirationTime === suspendedTime) { + if (workInProgressRoot === root && renderExpirationTime$1 === 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. @@ -21716,7 +18936,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); + prepareFreshStack(root, renderExpirationTime$1); } else { // Even though we can't restart right now, we might get an // opportunity later. So we mark this render as having a ping. @@ -21739,13 +18959,6 @@ 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); } @@ -21773,45 +18986,12 @@ 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; } @@ -21836,16 +19016,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( @@ -21894,8 +19074,8 @@ function checkForNestedUpdates() { { if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) { nestedPassiveUpdateCount = 0; - warning$1( - false, + + error( "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 " + @@ -21909,7 +19089,7 @@ function flushRenderPhaseStrictModeWarningsInDEV() { { ReactStrictModeWarnings.flushLegacyContextWarning(); - if (warnAboutDeprecatedLifecycles) { + { ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings(); } } @@ -21930,9 +19110,8 @@ function stopInterruptedWorkLoopTimer() { function checkForInterruption(fiberThatReceivedUpdate, updateExpirationTime) { if ( - enableUserTimingAPI && workInProgressRoot !== null && - updateExpirationTime > renderExpirationTime + updateExpirationTime > renderExpirationTime$1 ) { interruptedBy = fiberThatReceivedUpdate; } @@ -21950,11 +19129,12 @@ function warnAboutUpdateOnUnmountedFiberInDEV(fiber) { tag !== FunctionComponent && tag !== ForwardRef && tag !== MemoComponent && - tag !== SimpleMemoComponent + tag !== SimpleMemoComponent && + tag !== Block ) { // 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"; @@ -21969,8 +19149,7 @@ function warnAboutUpdateOnUnmountedFiberInDEV(fiber) { didWarnStateUpdateForUnmountedComponent = new Set([componentName]); } - warningWithoutStack$1( - false, + error( "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", @@ -21982,12 +19161,12 @@ function warnAboutUpdateOnUnmountedFiberInDEV(fiber) { } } -var beginWork$$1; +var beginWork$1; -if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) { +{ var dummyFiber = null; - beginWork$$1 = function(current$$1, unitOfWork, expirationTime) { + beginWork$1 = function(current, 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. @@ -21999,7 +19178,7 @@ if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) { ); try { - return beginWork$1(current$$1, unitOfWork, expirationTime); + return beginWork(current, unitOfWork, expirationTime); } catch (originalError) { if ( originalError !== null && @@ -22012,7 +19191,7 @@ if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) { // corresponding changes there. resetContextDependencies(); - resetHooks(); // Don't reset current debug fiber, since we're about to work on the + resetHooksAfterThrow(); // Don't reset current debug fiber, since we're about to work on the // same fiber again. // Unwind the failed stack frame @@ -22020,16 +19199,16 @@ if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) { assignFiberPropertiesInDEV(unitOfWork, originalWorkInProgressCopy); - if (enableProfilerTimer && unitOfWork.mode & ProfileMode) { + if (unitOfWork.mode & ProfileMode) { // Reset the profiler timer. startProfilerTimer(unitOfWork); } // Run beginWork again. invokeGuardedCallback( null, - beginWork$1, + beginWork, null, - current$$1, + current, unitOfWork, expirationTime ); @@ -22045,42 +19224,37 @@ if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) { } } }; -} else { - beginWork$$1 = beginWork$1; } var didWarnAboutUpdateInRender = false; -var didWarnAboutUpdateInGetChildContext = false; -function warnAboutInvalidUpdatesOnClassComponentsInDEV(fiber) { +function warnAboutRenderPhaseUpdatesInDEV(fiber) { { - if (fiber.tag === ClassComponent) { - switch (phase) { - case "getChildContext": - if (didWarnAboutUpdateInGetChildContext) { - return; - } - - warningWithoutStack$1( - false, - "setState(...): Cannot call setState() inside getChildContext()" + 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." ); - didWarnAboutUpdateInGetChildContext = true; + break; + } - case "render": - if (didWarnAboutUpdateInRender) { - return; - } + 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." + ); - 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; + didWarnAboutUpdateInRender = true; + break; + } + } } } } @@ -22092,20 +19266,20 @@ var IsThisRendererActing = { function warnIfNotScopedWithMatchingAct(fiber) { { if ( - warnsIfNotActing === true && IsSomeRendererActing.current === true && IsThisRendererActing.current !== true ) { - warningWithoutStack$1( - false, + error( "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" + + "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" + "const {act} = TestRenderer;\n" + "// ...\n" + "act(() => ...);" + @@ -22118,13 +19292,11 @@ function warnIfNotScopedWithMatchingAct(fiber) { function warnIfNotCurrentlyActingEffectsInDEV(fiber) { { if ( - warnsIfNotActing === true && (fiber.mode & StrictMode) !== NoMode && IsSomeRendererActing.current === false && IsThisRendererActing.current === false ) { - warningWithoutStack$1( - false, + error( "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" + @@ -22146,13 +19318,11 @@ function warnIfNotCurrentlyActingEffectsInDEV(fiber) { function warnIfNotCurrentlyActingUpdatesInDEV(fiber) { { if ( - warnsIfNotActing === true && executionContext === NoContext && IsSomeRendererActing.current === false && IsThisRendererActing.current === false ) { - warningWithoutStack$1( - false, + error( "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" + @@ -22186,161 +19356,19 @@ function warnIfUnmockedScheduler(fiber) { ) { if (fiber.mode & BlockingMode || fiber.mode & ConcurrentMode) { didWarnAboutUnmockedScheduler = true; - warningWithoutStack$1( - false, + + error( '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" + - "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" + + "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" + "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. @@ -22348,10 +19376,6 @@ function computeThreadID(root, expirationTime) { } function markSpawnedWork(expirationTime) { - if (!enableSchedulerTracing) { - return; - } - if (spawnedWorkDuringRender === null) { spawnedWorkDuringRender = [expirationTime]; } else { @@ -22360,10 +19384,6 @@ function markSpawnedWork(expirationTime) { } function scheduleInteractions(root, expirationTime, interactions) { - if (!enableSchedulerTracing) { - return; - } - if (interactions.size > 0) { var pendingInteractionMap = root.pendingInteractionMap; var pendingInteractions = pendingInteractionMap.get(expirationTime); @@ -22395,21 +19415,10 @@ 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. @@ -22450,10 +19459,6 @@ function startWorkOnPendingInteractions(root, expirationTime) { } function finishPendingInteractions(root, committedExpirationTime) { - if (!enableSchedulerTracing) { - return; - } - var earliestRemainingTimeAfterCommit = root.firstPendingTime; var subscriber; @@ -22502,6 +19507,7 @@ function finishPendingInteractions(root, committedExpirationTime) { } } +var onScheduleFiberRoot = null; var onCommitFiberRoot = null; var onCommitFiberUnmount = null; var hasLoggedError = false; @@ -22523,8 +19529,7 @@ function injectInternals(internals) { if (!hook.supportsFiber) { { - warningWithoutStack$1( - false, + error( "The installed version of React DevTools is too old and will not work " + "with the current version of React. Please update React DevTools. " + "https://fb.me/react-devtools" @@ -22537,6 +19542,23 @@ 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; @@ -22552,13 +19574,12 @@ function injectInternals(internals) { hook.onCommitFiberRoot(rendererID, root, undefined, didError); } } catch (err) { - if (true && !hasLoggedError) { - hasLoggedError = true; - warningWithoutStack$1( - false, - "React DevTools encountered an error: %s", - err - ); + if (true) { + if (!hasLoggedError) { + hasLoggedError = true; + + error("React instrumentation encountered an error: %s", err); + } } } }; @@ -22567,29 +19588,29 @@ function injectInternals(internals) { try { hook.onCommitFiberUnmount(rendererID, fiber); } catch (err) { - if (true && !hasLoggedError) { - hasLoggedError = true; - warningWithoutStack$1( - false, - "React DevTools encountered an error: %s", - err - ); + if (true) { + if (!hasLoggedError) { + hasLoggedError = true; + + error("React instrumentation encountered an error: %s", err); + } } } }; } catch (err) { // Catch all errors because it is unsafe to throw during initialization. { - warningWithoutStack$1( - false, - "React DevTools encountered an error: %s.", - err - ); + error("React instrumentation 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); @@ -22651,7 +19672,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 @@ -22678,7 +19699,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; } @@ -22742,7 +19763,7 @@ function resolveLazyComponentTag(Component) { return IndeterminateComponent; } // This is used to create an alternate fiber to do work on. -function createWorkInProgress(current, pendingProps, expirationTime) { +function createWorkInProgress(current, pendingProps) { var workInProgress = current.alternate; if (workInProgress === null) { @@ -22763,7 +19784,10 @@ function createWorkInProgress(current, pendingProps, expirationTime) { { // DEV-only fields - workInProgress._debugID = current._debugID; + { + workInProgress._debugID = current._debugID; + } + workInProgress._debugSource = current._debugSource; workInProgress._debugOwner = current._debugOwner; workInProgress._debugHookTypes = current._debugHookTypes; @@ -22781,7 +19805,7 @@ function createWorkInProgress(current, pendingProps, expirationTime) { 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, @@ -22813,7 +19837,7 @@ function createWorkInProgress(current, pendingProps, expirationTime) { workInProgress.index = current.index; workInProgress.ref = current.ref; - if (enableProfilerTimer) { + { workInProgress.selfBaseDuration = current.selfBaseDuration; workInProgress.treeBaseDuration = current.treeBaseDuration; } @@ -22835,9 +19859,6 @@ function createWorkInProgress(current, pendingProps, expirationTime) { case ForwardRef: workInProgress.type = resolveForwardRefForHotReloading(current.type); break; - - default: - break; } } @@ -22870,7 +19891,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; @@ -22896,7 +19917,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; @@ -22917,7 +19938,7 @@ function createHostRootFiber(tag) { mode = NoMode; } - if (enableProfilerTimer && isDevToolsPresent) { + if (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. @@ -23017,29 +20038,9 @@ function createFiberFromTypeAndProps( resolvedType = null; 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 - ); - } + case REACT_BLOCK_TYPE: + fiberTag = Block; + break getTag; } } @@ -23114,38 +20115,11 @@ 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" || - typeof pendingProps.onRender !== "function" - ) { - warningWithoutStack$1( - false, - 'Profiler must specify an "id" string and "onRender" function as props' - ); + if (typeof pendingProps.id !== "string") { + error('Profiler must specify an "id" as a prop'); } } @@ -23154,6 +20128,14 @@ 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; } @@ -23186,18 +20168,6 @@ 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); @@ -23246,17 +20216,20 @@ 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._debugID = source._debugID; + target._debugIsCurrentlyTiming = source._debugIsCurrentlyTiming; + } + target._debugSource = source._debugSource; target._debugOwner = source._debugOwner; - target._debugIsCurrentlyTiming = source._debugIsCurrentlyTiming; target._debugNeedsRemount = source._debugNeedsRemount; target._debugHookTypes = source._debugHookTypes; return target; @@ -23283,28 +20256,21 @@ 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) { @@ -23398,15 +20364,6 @@ 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; @@ -23427,38 +20384,11 @@ function getContextForSubtree(parentComponent) { 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 (hostFiber === null) { - return null; + return processChildContext(fiber, Component, parentContext); + } } - return hostFiber.stateNode; + return parentContext; } function findHostInstanceWithWarning(component, methodName) { @@ -23493,8 +20423,7 @@ function findHostInstanceWithWarning(component, methodName) { didWarnAboutFindNodeInStrictMode[componentName] = true; if (fiber.mode & StrictMode) { - warningWithoutStack$1( - false, + error( "%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. " + @@ -23506,8 +20435,7 @@ function findHostInstanceWithWarning(component, methodName) { getStackByFiberInDevAndProd(hostFiber) ); } else { - warningWithoutStack$1( - false, + error( "%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. " + @@ -23524,44 +20452,33 @@ function findHostInstanceWithWarning(component, methodName) { return hostFiber.stateNode; } - - return findHostInstance(component); } function createContainer(containerInfo, tag, hydrate, hydrationCallbacks) { - return createFiberRoot(containerInfo, tag, hydrate, hydrationCallbacks); + return createFiberRoot(containerInfo, tag, hydrate); } function updateContainer(element, container, parentComponent, callback) { - var current$$1 = container.current; + { + onScheduleRoot(container, element); + } + + 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) { @@ -23571,10 +20488,10 @@ function updateContainer(element, container, parentComponent, callback) { } { - if (phase === "render" && current !== null && !didWarnAboutNestedUpdates) { + if (isRendering && current !== null && !didWarnAboutNestedUpdates) { didWarnAboutNestedUpdates = true; - warningWithoutStack$1( - false, + + error( "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" + @@ -23593,19 +20510,21 @@ function updateContainer(element, container, parentComponent, callback) { callback = callback === undefined ? null : callback; if (callback !== null) { - !(typeof callback === "function") - ? warningWithoutStack$1( - false, + { + if (typeof callback !== "function") { + error( "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) { @@ -23624,703 +20543,149 @@ function getPublicRootInstance(container) { } } -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; - } - - 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 shouldSuspendImpl = function(fiber) { + return false; +}; - _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. +function shouldSuspend(fiber) { + return shouldSuspendImpl(fiber); +} +var overrideHookState = null; +var overrideProps = null; +var scheduleUpdate = null; +var setSuspenseHandler = 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. +{ + var copyWithSetImpl = function(obj, path, idx, value) { + if (idx >= path.length) { + return value; + } - if (maybeInstance == null) { - return; - } + var key = path[idx]; + var updated = Array.isArray(obj) ? obj.slice() : Object.assign({}, obj); // $FlowFixMe number or string is fine here - 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. + updated[key] = copyWithSetImpl(obj[key], path, idx + 1, value); + return updated; + }; - 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. + var copyWithSet = function(obj, path, value) { + return copyWithSetImpl(obj, path, 0, value); + }; // Support DevTools editable values for useState and useReducer. - if (maybeInstance == null) { - return; - } + 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; - 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. + 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) { - 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; + overrideProps = function(fiber, path, value) { + fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value); - if (typeof relativeToNativeNode === "number") { - // Already a node handle - relativeNode = relativeToNativeNode; - } else if (relativeToNativeNode._nativeTag) { - relativeNode = relativeToNativeNode._nativeTag; - } + if (fiber.alternate) { + fiber.alternate.pendingProps = fiber.pendingProps; + } - if (relativeNode == null) { - warningWithoutStack$1( - false, - "Warning: ref.measureLayout must be called with a node handle or a ref to a native component." - ); - return; - } + scheduleWork(fiber, Sync); + }; - 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. + 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: setNativeProps is not currently supported in Fabric" - ); - return; - } + return hostFiber.stateNode; + }, + findFiberByHostInstance: function(instance) { + if (!findFiberByHostInstance) { + // Might not be implemented by the renderer. + return null; + } - 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 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; - return ReactNativeComponent; - })(React.Component); // eslint-disable-next-line no-unused-expressions +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 + }; +} - return ReactNativeComponent; -}; +// TODO: this is special because it gets imported during build. +var ReactVersion = "16.13.0"; -var emptyObject$3 = {}; +var emptyObject$1 = {}; { - Object.freeze(emptyObject$3); + Object.freeze(emptyObject$1); } var getInspectorDataForViewTag; +var getInspectorDataForViewAtPoint; { var traverseOwnerTreeUp = function(hierarchy, instance) { @@ -24352,10 +20717,10 @@ var getInspectorDataForViewTag; var host = findCurrentHostFiber(fiber); if (host) { - return host.memoizedProps || emptyObject$3; + return host.memoizedProps || emptyObject$1; } - return emptyObject$3; + return emptyObject$1; }; var getHostNode = function(fiber, findNodeHandle) { @@ -24383,28 +20748,65 @@ var getInspectorDataForViewTag; name: getComponentName(fiber.type), getInspectorData: function(findNodeHandle) { return { - measure: function(callback) { - return ReactNativePrivateInterface.UIManager.measure( - getHostNode(fiber, findNodeHandle), - callback - ); - }, props: getHostProps(fiber), - source: fiber._debugSource + 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 + ); + } + } }; } }; }); }; + 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$3, - selection: null, + props: emptyObject$1, + selectedIndex: null, source: null }; } @@ -24415,34 +20817,122 @@ var getInspectorDataForViewTag; var hierarchy = createHierarchy(fiberHierarchy); var props = getHostProps(instance); var source = instance._debugSource; - var selection = fiberHierarchy.indexOf(instance); + var selectedIndex = fiberHierarchy.indexOf(instance); return { hierarchy: hierarchy, props: props, - selection: selection, + selectedIndex: selectedIndex, 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 = ReactSharedInternals.ReactCurrentOwner; +var ReactCurrentOwner$3 = ReactSharedInternals.ReactCurrentOwner; function findHostInstance_DEPRECATED(componentOrHandle) { { - var owner = ReactCurrentOwner.current; + var owner = ReactCurrentOwner$3.current; if (owner !== null && owner.stateNode !== null) { - !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; + 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 = true; } } @@ -24482,20 +20972,20 @@ function findHostInstance_DEPRECATED(componentOrHandle) { function findNodeHandle(componentOrHandle) { { - var owner = ReactCurrentOwner.current; + var owner = ReactCurrentOwner$3.current; if (owner !== null && owner.stateNode !== null) { - !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; + 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 = true; } } @@ -24538,110 +21028,109 @@ function findNodeHandle(componentOrHandle) { return hostInstance._nativeTag; } -setBatchingImplementation( - batchedUpdates$1, - discreteUpdates$1, - flushDiscreteUpdates, - batchedEventUpdates$1 -); - -function computeComponentStackForErrorReporting(reactTag) { - var fiber = getInstanceFromTag(reactTag); +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" + ); + } - if (!fiber) { - return ""; + return; } - 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; - } - + if (handle._internalInstanceHandle) { + nativeFabricUIManager.dispatchCommand( + handle._internalInstanceHandle.stateNode.node, + command, + args + ); + } else { ReactNativePrivateInterface.UIManager.dispatchViewManagerCommand( handle._nativeTag, command, args ); - }, - render: function(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, null); - roots.set(containerTag, root); - } +function render(element, containerTag, callback) { + var root = roots.get(containerTag); - updateContainer(element, root, null, callback); - return getPublicRootInstance(root); - }, - unmountComponentAtNode: function(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); + 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); - }); - } - }, - unmountComponentAtNodeAndRemoveContainer: function(containerTag) { - ReactNativeRenderer.unmountComponentAtNode(containerTag); // Call back into native to remove all of the subviews from this container + updateContainer(element, root, null, callback); + return getPublicRootInstance(root); +} - 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 +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); +} + +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); + +function computeComponentStackForErrorReporting(reactTag) { + var fiber = getInstanceFromTag(reactTag); + + if (!fiber) { + return ""; } + + return getStackByFiberInDevAndProd(fiber); +} + +var roots = new Map(); +var Internals = { + computeComponentStackForErrorReporting: computeComponentStackForErrorReporting }; injectIntoDevTools({ findFiberByHostInstance: getInstanceFromTag, - getInspectorDataForViewTag: getInspectorDataForViewTag, bundleType: 1, version: ReactVersion, - rendererPackageName: "react-native-renderer" -}); - -var ReactNativeRenderer$2 = Object.freeze({ - default: ReactNativeRenderer + rendererPackageName: "react-native-renderer", + rendererConfig: { + getInspectorDataForViewTag: getInspectorDataForViewTag, + getInspectorDataForViewAtPoint: getInspectorDataForViewAtPoint.bind( + null, + findNodeHandle + ) + } }); -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; +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; })(); } diff --git a/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js b/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js index c8107e4934204a..f32dc562752364 100644 --- a/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js +++ b/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js @@ -5,6 +5,7 @@ * LICENSE file in the root directory of this source tree. * * @noflow + * @nolint * @preventMunge * @generated */ @@ -14,85 +15,16 @@ require("react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore"); var ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/ReactNativePrivateInterface"), React = require("react"), Scheduler = require("scheduler"); -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 getParent(inst) { + do inst = inst.return; + while (inst && 5 !== inst.tag); + return inst ? inst : null; } -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; +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); } -var plugins = [], - eventNameDispatchConfigs = {}, - registrationNameModules = {}; function invokeGuardedCallbackImpl(name, func, context, a, b, c, d, e, f) { var funcArgs = Array.prototype.slice.call(arguments, 3); try { @@ -163,74 +95,6 @@ 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; @@ -248,6 +112,7 @@ function getListener(inst, registrationName) { case "onMouseMoveCapture": case "onMouseUp": case "onMouseUpCapture": + case "onMouseEnter": (props = !props.disabled) || ((inst = inst.type), (props = !( @@ -272,15 +137,21 @@ function getListener(inst, registrationName) { ); return listener; } -function getParent(inst) { - do inst = inst.return; - while (inst && 5 !== inst.tag); - return inst ? inst : null; +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 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 forEachAccumulated(arr, cb, scope) { + Array.isArray(arr) ? arr.forEach(cb, scope) : arr && cb.call(scope, arr); } function accumulateDirectionalDispatches(inst, phase, event) { if ( @@ -348,8 +219,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) @@ -502,53 +373,27 @@ 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))) - : console.warn( - "Cannot record touch move without a touch start.\nTouch Move: %s\n", - "Touch Bank: %s", - printTouch(touch), - printTouchBank() - ); + 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))); } 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))) - : 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; + 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))); } var ResponderTouchHistoryStore = { recordTouchTrack: function(topLevelType, nativeEvent) { @@ -588,10 +433,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; @@ -681,13 +526,7 @@ var eventTypes = { "topTouchCancel" === topLevelType ) if (0 <= trackedTouchCount) --trackedTouchCount; - else - return ( - console.warn( - "Ended a touch event which was not counted in `trackedTouchCount`." - ), - null - ); + else return null; ResponderTouchHistoryStore.recordTouchTrack(topLevelType, nativeEvent); if ( targetInst && @@ -699,10 +538,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; @@ -856,10 +695,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, @@ -922,8 +761,8 @@ var eventTypes = { (topLevelType = shouldSetEventType ? eventTypes.responderTerminate : topLevelType - ? eventTypes.responderRelease - : null) + ? eventTypes.responderRelease + : null) ) (nativeEvent = ResponderSyntheticEvent.getPooled( topLevelType, @@ -947,67 +786,168 @@ 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; -injection.injectEventPluginOrder([ +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([ "ResponderEventPlugin", "ReactNativeBridgeEventPlugin" ]); -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, +recomputePluginOrdering(); +var injectedNamesToPlugins$jscomp$inline_94 = { + ResponderEventPlugin: ResponderEventPlugin, + ReactNativeBridgeEventPlugin: { + eventTypes: {}, + extractEvents: function( + topLevelType, targetInst, nativeEvent, nativeEventTarget - ); - if (bubbleDispatchConfig) - forEachAccumulated(topLevelType, accumulateTwoPhaseDispatchesSingle); - else if (directDispatchConfig) - forEachAccumulated(topLevelType, accumulateDirectDispatchesSingle); - else return null; - return topLevelType; + ) { + 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 + ) { + if (namesToPlugins[pluginName$jscomp$inline_96]) + throw Error( + "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + + pluginName$jscomp$inline_96 + + "`." + ); + namesToPlugins[ + pluginName$jscomp$inline_96 + ] = pluginModule$jscomp$inline_97; + isOrderingDirty$jscomp$inline_95 = !0; } } -}); -var enableNativeTargetAsInstance = require("../shims/ReactFeatureFlags") - .enableNativeTargetAsInstance, - instanceCache = new Map(), +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); @@ -1015,21 +955,27 @@ function batchedUpdates(fn, bookkeeping) { 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)) + 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++ ) - for (bookkeeping = 0; bookkeeping < fn.length; bookkeeping++) - restoreStateOfTarget(fn[bookkeeping]); + 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 EMPTY_NATIVE_EVENT = {}; @@ -1037,9 +983,7 @@ function _receiveRootNodeIDEvent(rootNodeID, topLevelType, nativeEventParam) { var nativeEvent = nativeEventParam || EMPTY_NATIVE_EVENT, inst = getInstanceFromTag(rootNodeID), target = null; - enableNativeTargetAsInstance - ? null != inst && (target = inst.stateNode) - : (target = nativeEvent.target); + null != inst && (target = inst.stateNode); batchedUpdates(function() { var events = target; for (var events$jscomp$0 = null, i = 0; i < plugins.length; i++) { @@ -1114,17 +1058,11 @@ getFiberCurrentPropsFromNode = function(stateNode) { }; getInstanceFromNode = getInstanceFromTag; getNodeFromInstance = function(inst) { - 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); + 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 tag; + return inst; }; ResponderEventPlugin.injection.injectGlobalResponderHandler({ onChange: function(from, to, blockNativeResponder) { @@ -1159,11 +1097,9 @@ 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; -hasSymbol && Symbol.for("react.fundamental"); -hasSymbol && Symbol.for("react.responder"); -hasSymbol && Symbol.for("react.scope"); -var MAYBE_ITERATOR_SYMBOL = "function" === typeof Symbol && Symbol.iterator; + 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; function getIteratorFn(maybeIterable) { if (null === maybeIterable || "object" !== typeof maybeIterable) return null; maybeIterable = @@ -1173,9 +1109,10 @@ function getIteratorFn(maybeIterable) { } function initializeLazyComponentType(lazyComponent) { if (-1 === lazyComponent._status) { - lazyComponent._status = 0; - var ctor = lazyComponent._ctor; + var ctor = lazyComponent._result; + ctor || (ctor = lazyComponent._ctor); ctor = ctor(); + lazyComponent._status = 0; lazyComponent._result = ctor; ctor.then( function(moduleObject) { @@ -1212,9 +1149,9 @@ function getComponentName(type) { if ("object" === typeof type) switch (type.$$typeof) { case REACT_CONTEXT_TYPE: - return "Context.Consumer"; + return (type.displayName || "Context") + ".Consumer"; case REACT_PROVIDER_TYPE: - return "Context.Provider"; + return (type._context.displayName || "Context") + ".Provider"; case REACT_FORWARD_REF_TYPE: var innerType = type.render; innerType = innerType.displayName || innerType.name || ""; @@ -1224,6 +1161,8 @@ 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); @@ -1404,8 +1343,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)) { @@ -1583,10 +1522,10 @@ var ReactNativeFiberHostComponent = (function() { } var _proto = ReactNativeFiberHostComponent.prototype; _proto.blur = function() { - ReactNativePrivateInterface.TextInputState.blurTextInput(this._nativeTag); + ReactNativePrivateInterface.TextInputState.blurTextInput(this); }; _proto.focus = function() { - ReactNativePrivateInterface.TextInputState.focusTextInput(this._nativeTag); + ReactNativePrivateInterface.TextInputState.focusTextInput(this); }; _proto.measure = function(callback) { ReactNativePrivateInterface.UIManager.measure( @@ -1630,7 +1569,7 @@ var ReactNativeFiberHostComponent = (function() { }; return ReactNativeFiberHostComponent; })(); -function shim$1() { +function shim() { throw Error( "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." ); @@ -1668,45 +1607,7 @@ function finalizeInitialChildren(parentInstance) { } var scheduleTimeout = setTimeout, cancelTimeout = clearTimeout, - 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 = [], + valueStack = [], index = -1; function pop(cursor) { 0 > index || @@ -1743,21 +1644,17 @@ function isContextProvider(type) { type = type.childContextTypes; return null !== type && void 0 !== type; } -function popContext(fiber) { - pop(didPerformWorkStackCursor, fiber); - pop(contextStackCursor, fiber); -} -function popTopLevelContextObject(fiber) { - pop(didPerformWorkStackCursor, fiber); - pop(contextStackCursor, fiber); +function popContext() { + pop(didPerformWorkStackCursor); + pop(contextStackCursor); } function pushTopLevelContextObject(fiber, context, didChange) { if (contextStackCursor.current !== emptyContextObject) throw Error( "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." ); - push(contextStackCursor, context, fiber); - push(didPerformWorkStackCursor, didChange, fiber); + push(contextStackCursor, context); + push(didPerformWorkStackCursor, didChange); } function processChildContext(fiber, type, parentContext) { var instance = fiber.stateNode; @@ -1775,17 +1672,13 @@ function processChildContext(fiber, type, parentContext) { return Object.assign({}, parentContext, {}, instance); } function pushContextProvider(workInProgress) { - var instance = workInProgress.stateNode; - instance = - (instance && instance.__reactInternalMemoizedMergedChildContext) || + workInProgress = + ((workInProgress = workInProgress.stateNode) && + workInProgress.__reactInternalMemoizedMergedChildContext) || emptyContextObject; previousContext = contextStackCursor.current; - push(contextStackCursor, instance, workInProgress); - push( - didPerformWorkStackCursor, - didPerformWorkStackCursor.current, - workInProgress - ); + push(contextStackCursor, workInProgress); + push(didPerformWorkStackCursor, didPerformWorkStackCursor.current); return !0; } function invalidateContextProvider(workInProgress, type, didChange) { @@ -1795,18 +1688,21 @@ 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 - ? ((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); + ? ((workInProgress = processChildContext( + workInProgress, + type, + previousContext + )), + (instance.__reactInternalMemoizedMergedChildContext = workInProgress), + pop(didPerformWorkStackCursor), + pop(contextStackCursor), + push(contextStackCursor, workInProgress)) + : pop(didPerformWorkStackCursor); + push(didPerformWorkStackCursor, didChange); } 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 = @@ -1817,6 +1713,7 @@ 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, @@ -1916,10 +1813,10 @@ function flushSyncCallbackQueueImpl() { function is(x, y) { return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y); } -var is$1 = "function" === typeof Object.is ? Object.is : is, +var objectIs = "function" === typeof Object.is ? Object.is : is, hasOwnProperty = Object.prototype.hasOwnProperty; function shallowEqual(objA, objB) { - if (is$1(objA, objB)) return !0; + if (objectIs(objA, objB)) return !0; if ( "object" !== typeof objA || null === objA || @@ -1933,11 +1830,48 @@ function shallowEqual(objA, objB) { for (keysB = 0; keysB < keysA.length; keysB++) if ( !hasOwnProperty.call(objB, keysA[keysB]) || - !is$1(objA[keysA[keysB]], objB[keysA[keysB]]) + !objectIs(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); @@ -1955,14 +1889,9 @@ 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, providerFiber); + pop(valueCursor); providerFiber.type._context._currentValue = currentValue; } function scheduleWorkOnParentPath(parent, renderExpirationTime) { @@ -2017,237 +1946,195 @@ function readContext(context, observedBits) { return context._currentValue; } var hasForceUpdate = !1; -function createUpdateQueue(baseState) { - return { - baseState: baseState, - firstUpdate: null, - lastUpdate: null, - firstCapturedUpdate: null, - lastCapturedUpdate: null, - firstEffect: null, - lastEffect: null, - firstCapturedEffect: null, - lastCapturedEffect: null +function initializeUpdateQueue(fiber) { + fiber.updateQueue = { + baseState: fiber.memoizedState, + baseQueue: null, + shared: { pending: null }, + effects: null }; } -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 cloneUpdateQueue(current, workInProgress) { + current = current.updateQueue; + workInProgress.updateQueue === current && + (workInProgress.updateQueue = { + baseState: current.baseState, + baseQueue: current.baseQueue, + shared: current.shared, + effects: current.effects + }); } function createUpdate(expirationTime, suspenseConfig) { - return { + expirationTime = { expirationTime: expirationTime, suspenseConfig: suspenseConfig, tag: 0, payload: null, callback: null, - next: null, - nextEffect: null + next: null }; -} -function appendUpdateToQueue(queue, update) { - null === queue.lastUpdate - ? (queue.firstUpdate = queue.lastUpdate = update) - : ((queue.lastUpdate.next = update), (queue.lastUpdate = update)); + return (expirationTime.next = expirationTime); } function enqueueUpdate(fiber, 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)); + 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; + } } 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 && - 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; + 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)); } function processUpdateQueue( - workInProgress, - queue, + workInProgress$jscomp$0, props, instance, renderExpirationTime ) { + var queue = workInProgress$jscomp$0.updateQueue; hasForceUpdate = !1; - queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue); - for ( - var newBaseState = queue.baseState, - newFirstUpdate = null, - newExpirationTime = 0, - 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; + 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)); } - 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; + if (null !== baseQueue) { + baseFirst = baseQueue.next; + var newState = queue.baseState, + 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; } - 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) { - 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); + 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); + } } - effect = effect.nextEffect; - } } var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig, emptyRefsObject = new React.Component().refs; @@ -2264,10 +2151,8 @@ function applyDerivedStateFromProps( ? ctor : Object.assign({}, ctor, getDerivedStateFromProps); workInProgress.memoizedState = getDerivedStateFromProps; - nextProps = workInProgress.updateQueue; - null !== nextProps && - 0 === workInProgress.expirationTime && - (nextProps.baseState = getDerivedStateFromProps); + 0 === workInProgress.expirationTime && + (workInProgress.updateQueue.baseState = getDerivedStateFromProps); } var classComponentUpdater = { isMounted: function(component) { @@ -2286,7 +2171,7 @@ var classComponentUpdater = { null !== callback && (suspenseConfig.callback = callback); enqueueUpdate(inst, suspenseConfig); - scheduleUpdateOnFiber(inst, currentTime); + scheduleWork(inst, currentTime); }, enqueueReplaceState: function(inst, payload, callback) { inst = inst._reactInternalFiber; @@ -2300,7 +2185,7 @@ var classComponentUpdater = { null !== callback && (suspenseConfig.callback = callback); enqueueUpdate(inst, suspenseConfig); - scheduleUpdateOnFiber(inst, currentTime); + scheduleWork(inst, currentTime); }, enqueueForceUpdate: function(inst, callback) { inst = inst._reactInternalFiber; @@ -2313,7 +2198,7 @@ var classComponentUpdater = { null !== callback && (suspenseConfig.callback = callback); enqueueUpdate(inst, suspenseConfig); - scheduleUpdateOnFiber(inst, currentTime); + scheduleWork(inst, currentTime); } }; function checkShouldComponentUpdate( @@ -2329,8 +2214,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, @@ -2382,6 +2267,7 @@ 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)) @@ -2389,16 +2275,8 @@ function mountClassInstance( ? previousContext : contextStackCursor.current), (instance.context = getMaskedContext(workInProgress, contextType))); - contextType = workInProgress.updateQueue; - null !== contextType && - (processUpdateQueue( - workInProgress, - contextType, - newProps, - instance, - renderExpirationTime - ), - (instance.state = workInProgress.memoizedState)); + processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); + instance.state = workInProgress.memoizedState; contextType = ctor.getDerivedStateFromProps; "function" === typeof contextType && (applyDerivedStateFromProps(workInProgress, ctor, contextType, newProps), @@ -2414,21 +2292,18 @@ function mountClassInstance( instance.UNSAFE_componentWillMount(), ctor !== instance.state && classComponentUpdater.enqueueReplaceState(instance, instance.state, null), - (contextType = workInProgress.updateQueue), - null !== contextType && - (processUpdateQueue( - workInProgress, - contextType, - newProps, - instance, - renderExpirationTime - ), - (instance.state = workInProgress.memoizedState))); + processUpdateQueue( + workInProgress, + newProps, + instance, + renderExpirationTime + ), + (instance.state = workInProgress.memoizedState)); "function" === typeof instance.componentDidMount && (workInProgress.effectTag |= 4); } var isArray = Array.isArray; -function coerceRef(returnFiber, current$$1, element) { +function coerceRef(returnFiber, current, element) { returnFiber = element.ref; if ( null !== returnFiber && @@ -2440,7 +2315,7 @@ function coerceRef(returnFiber, current$$1, element) { if (element) { if (1 !== element.tag) throw Error( - "Function components cannot have refs. Did you mean to use React.forwardRef()?" + "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" ); var inst = element.stateNode; } @@ -2452,19 +2327,19 @@ function coerceRef(returnFiber, current$$1, element) { ); var stringRef = "" + returnFiber; if ( - null !== current$$1 && - null !== current$$1.ref && - "function" === typeof current$$1.ref && - current$$1.ref._stringRef === stringRef + null !== current && + null !== current.ref && + "function" === typeof current.ref && + current.ref._stringRef === stringRef ) - return current$$1.ref; - current$$1 = function(value) { + return current.ref; + current = function(value) { var refs = inst.refs; refs === emptyRefsObject && (refs = inst.refs = {}); null === value ? delete refs[stringRef] : (refs[stringRef] = value); }; - current$$1._stringRef = stringRef; - return current$$1; + current._stringRef = stringRef; + return current; } if ("string" !== typeof returnFiber) throw Error( @@ -2516,8 +2391,8 @@ function ChildReconciler(shouldTrackSideEffects) { (currentFirstChild = currentFirstChild.sibling); return returnFiber; } - function useFiber(fiber, pendingProps, expirationTime) { - fiber = createWorkInProgress(fiber, pendingProps, expirationTime); + function useFiber(fiber, pendingProps) { + fiber = createWorkInProgress(fiber, pendingProps); fiber.index = 0; fiber.sibling = null; return fiber; @@ -2542,31 +2417,26 @@ function ChildReconciler(shouldTrackSideEffects) { (newFiber.effectTag = 2); return newFiber; } - function updateTextNode( - returnFiber, - current$$1, - textContent, - expirationTime - ) { - if (null === current$$1 || 6 !== current$$1.tag) + function updateTextNode(returnFiber, current, textContent, expirationTime) { + if (null === current || 6 !== current.tag) return ( - (current$$1 = createFiberFromText( + (current = createFiberFromText( textContent, returnFiber.mode, expirationTime )), - (current$$1.return = returnFiber), - current$$1 + (current.return = returnFiber), + current ); - current$$1 = useFiber(current$$1, textContent, expirationTime); - current$$1.return = returnFiber; - return current$$1; + current = useFiber(current, textContent); + current.return = returnFiber; + return current; } - function updateElement(returnFiber, current$$1, element, expirationTime) { - if (null !== current$$1 && current$$1.elementType === element.type) + function updateElement(returnFiber, current, element, expirationTime) { + if (null !== current && current.elementType === element.type) return ( - (expirationTime = useFiber(current$$1, element.props, expirationTime)), - (expirationTime.ref = coerceRef(returnFiber, current$$1, element)), + (expirationTime = useFiber(current, element.props)), + (expirationTime.ref = coerceRef(returnFiber, current, element)), (expirationTime.return = returnFiber), expirationTime ); @@ -2578,51 +2448,45 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime ); - expirationTime.ref = coerceRef(returnFiber, current$$1, element); + expirationTime.ref = coerceRef(returnFiber, current, element); expirationTime.return = returnFiber; return expirationTime; } - function updatePortal(returnFiber, current$$1, portal, expirationTime) { + function updatePortal(returnFiber, current, portal, expirationTime) { if ( - null === current$$1 || - 4 !== current$$1.tag || - current$$1.stateNode.containerInfo !== portal.containerInfo || - current$$1.stateNode.implementation !== portal.implementation + null === current || + 4 !== current.tag || + current.stateNode.containerInfo !== portal.containerInfo || + current.stateNode.implementation !== portal.implementation ) return ( - (current$$1 = createFiberFromPortal( + (current = createFiberFromPortal( portal, returnFiber.mode, expirationTime )), - (current$$1.return = returnFiber), - current$$1 + (current.return = returnFiber), + current ); - current$$1 = useFiber(current$$1, portal.children || [], expirationTime); - current$$1.return = returnFiber; - return current$$1; + current = useFiber(current, portal.children || []); + current.return = returnFiber; + return current; } - function updateFragment( - returnFiber, - current$$1, - fragment, - expirationTime, - key - ) { - if (null === current$$1 || 7 !== current$$1.tag) + function updateFragment(returnFiber, current, fragment, expirationTime, key) { + if (null === current || 7 !== current.tag) return ( - (current$$1 = createFiberFromFragment( + (current = createFiberFromFragment( fragment, returnFiber.mode, expirationTime, key )), - (current$$1.return = returnFiber), - current$$1 + (current.return = returnFiber), + current ); - current$$1 = useFiber(current$$1, fragment, expirationTime); - current$$1.return = returnFiber; - return current$$1; + current = useFiber(current, fragment); + current.return = returnFiber; + return current; } function createChild(returnFiber, newChild, expirationTime) { if ("string" === typeof newChild || "number" === typeof newChild) @@ -2985,39 +2849,48 @@ function ChildReconciler(shouldTrackSideEffects) { null !== isUnkeyedTopLevelFragment; ) { - 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; + 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; + } } - else deleteChild(returnFiber, isUnkeyedTopLevelFragment); + deleteRemainingChildren(returnFiber, isUnkeyedTopLevelFragment); + break; + } else deleteChild(returnFiber, isUnkeyedTopLevelFragment); isUnkeyedTopLevelFragment = isUnkeyedTopLevelFragment.sibling; } newChild.type === REACT_FRAGMENT_TYPE @@ -3067,8 +2940,7 @@ function ChildReconciler(shouldTrackSideEffects) { ); currentFirstChild = useFiber( currentFirstChild, - newChild.children || [], - expirationTime + newChild.children || [] ); currentFirstChild.return = returnFiber; returnFiber = currentFirstChild; @@ -3095,11 +2967,7 @@ function ChildReconciler(shouldTrackSideEffects) { (newChild = "" + newChild), null !== currentFirstChild && 6 === currentFirstChild.tag ? (deleteRemainingChildren(returnFiber, currentFirstChild.sibling), - (currentFirstChild = useFiber( - currentFirstChild, - newChild, - expirationTime - )), + (currentFirstChild = useFiber(currentFirstChild, newChild)), (currentFirstChild.return = returnFiber), (returnFiber = currentFirstChild)) : (deleteRemainingChildren(returnFiber, currentFirstChild), @@ -3154,16 +3022,16 @@ function requiredContext(c) { return c; } function pushHostContainer(fiber, nextRootInstance) { - push(rootInstanceStackCursor, nextRootInstance, fiber); - push(contextFiberStackCursor, fiber, fiber); - push(contextStackCursor$1, NO_CONTEXT, fiber); - pop(contextStackCursor$1, fiber); - push(contextStackCursor$1, { isInAParentText: !1 }, fiber); + push(rootInstanceStackCursor, nextRootInstance); + push(contextFiberStackCursor, fiber); + push(contextStackCursor$1, NO_CONTEXT); + pop(contextStackCursor$1); + push(contextStackCursor$1, { isInAParentText: !1 }); } -function popHostContainer(fiber) { - pop(contextStackCursor$1, fiber); - pop(contextFiberStackCursor, fiber); - pop(rootInstanceStackCursor, fiber); +function popHostContainer() { + pop(contextStackCursor$1); + pop(contextFiberStackCursor); + pop(rootInstanceStackCursor); } function pushHostContext(fiber) { requiredContext(rootInstanceStackCursor.current); @@ -3180,23 +3048,19 @@ function pushHostContext(fiber) { ? { isInAParentText: nextContext } : context; context !== nextContext && - (push(contextFiberStackCursor, fiber, fiber), - push(contextStackCursor$1, nextContext, fiber)); + (push(contextFiberStackCursor, fiber), + push(contextStackCursor$1, nextContext)); } function popHostContext(fiber) { contextFiberStackCursor.current === fiber && - (pop(contextStackCursor$1, fiber), pop(contextFiberStackCursor, fiber)); + (pop(contextStackCursor$1), pop(contextFiberStackCursor)); } var suspenseStackCursor = { current: 0 }; function findFirstSuspended(row) { for (var node = row; null !== node; ) { if (13 === node.tag) { var state = node.memoizedState; - if ( - null !== state && - ((state = state.dehydrated), - null === state || shim$1(state) || shim$1(state)) - ) + if (null !== state && (null === state.dehydrated || shim() || shim())) return node; } else if (19 === node.tag && void 0 !== node.memoizedProps.revealOrder) { if (0 !== (node.effectTag & 64)) return node; @@ -3215,24 +3079,16 @@ function findFirstSuspended(row) { } return null; } -function createResponderListener(responder, props) { +function createDeprecatedResponderListener(responder, props) { return { responder: responder, props: props }; } -var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, +var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig, - renderExpirationTime$1 = 0, + renderExpirationTime = 0, currentlyRenderingFiber$1 = null, currentHook = null, - nextCurrentHook = null, - firstWorkInProgressHook = null, workInProgressHook = null, - nextWorkInProgressHook = null, - remainingExpirationTime = 0, - componentUpdateQueue = null, - sideEffectTag = 0, - didScheduleRenderPhaseUpdate = !1, - renderPhaseUpdates = null, - numberOfReRenders = 0; + didScheduleRenderPhaseUpdate = !1; 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." @@ -3241,7 +3097,7 @@ function throwInvalidHookError() { function areHookInputsEqual(nextDeps, prevDeps) { if (null === prevDeps) return !1; for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) - if (!is$1(nextDeps[i], prevDeps[i])) return !1; + if (!objectIs(nextDeps[i], prevDeps[i])) return !1; return !0; } function renderWithHooks( @@ -3249,92 +3105,85 @@ function renderWithHooks( workInProgress, Component, props, - refOrContext, + secondArg, nextRenderExpirationTime ) { - renderExpirationTime$1 = nextRenderExpirationTime; + renderExpirationTime = nextRenderExpirationTime; currentlyRenderingFiber$1 = workInProgress; - 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; + 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); } - 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) + ReactCurrentDispatcher.current = ContextOnlyDispatcher; + workInProgress = null !== currentHook && null !== currentHook.next; + renderExpirationTime = 0; + workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; + didScheduleRenderPhaseUpdate = !1; + if (workInProgress) throw Error( "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." ); - 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; + return current; } function mountWorkInProgressHook() { var hook = { memoizedState: null, baseState: null, + baseQueue: null, queue: null, - baseUpdate: null, next: null }; null === workInProgressHook - ? (firstWorkInProgressHook = workInProgressHook = hook) + ? (currentlyRenderingFiber$1.memoizedState = 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), - (nextWorkInProgressHook = workInProgressHook.next), - (currentHook = nextCurrentHook), - (nextCurrentHook = null !== currentHook ? currentHook.next : null); + (currentHook = nextCurrentHook); else { if (null === nextCurrentHook) throw Error("Rendered more hooks than during the previous render."); currentHook = nextCurrentHook; - var newHook = { + nextCurrentHook = { memoizedState: currentHook.memoizedState, baseState: currentHook.baseState, + baseQueue: currentHook.baseQueue, queue: currentHook.queue, - baseUpdate: currentHook.baseUpdate, next: null }; - workInProgressHook = - null === workInProgressHook - ? (firstWorkInProgressHook = newHook) - : (workInProgressHook.next = newHook); - nextCurrentHook = currentHook.next; + null === workInProgressHook + ? (currentlyRenderingFiber$1.memoizedState = workInProgressHook = nextCurrentHook) + : (workInProgressHook = workInProgressHook.next = nextCurrentHook); } return workInProgressHook; } @@ -3349,74 +3198,100 @@ function updateReducer(reducer) { "Should have a queue. This is likely a bug in React. Please file an issue." ); queue.lastRenderedReducer = reducer; - 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]; - } + 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; } - return [hook.memoizedState, _dispatch]; + current.baseQueue = baseQueue = pendingQueue; + queue.pending = null; } - _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; + if (null !== baseQueue) { + baseQueue = baseQueue.next; + current = current.baseState; + var newBaseQueueLast = (baseFirst = pendingQueue = null), + update = baseQueue; do { - var updateExpirationTime = _update.expirationTime; - updateExpirationTime < renderExpirationTime$1 - ? (didSkip || - ((didSkip = !0), - (newBaseUpdate = baseUpdate), - (firstRenderPhaseUpdate = newState)), - updateExpirationTime > remainingExpirationTime && - ((remainingExpirationTime = updateExpirationTime), - markUnprocessedUpdateTime(remainingExpirationTime))) - : (markRenderEventTimeAndConfig( + 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( updateExpirationTime, - _update.suspenseConfig + update.suspenseConfig ), - (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); + (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); hook.memoizedState = newState; - hook.baseUpdate = newBaseUpdate; - hook.baseState = firstRenderPhaseUpdate; + null === hook.baseQueue && (hook.baseState = newState); queue.lastRenderedState = newState; } - return [hook.memoizedState, queue.dispatch]; + return [newState, dispatch]; } function mountState(initialState) { var hook = mountWorkInProgressHook(); "function" === typeof initialState && (initialState = initialState()); hook.memoizedState = hook.baseState = initialState; initialState = hook.queue = { - last: null, + pending: null, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState @@ -3428,28 +3303,30 @@ 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 }; - 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))); + 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))); return tag; } +function updateRef() { + return updateWorkInProgressHook().memoizedState; +} function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var hook = mountWorkInProgressHook(); - sideEffectTag |= fiberEffectTag; + currentlyRenderingFiber$1.effectTag |= fiberEffectTag; hook.memoizedState = pushEffect( - hookEffectTag, + 1 | hookEffectTag, create, void 0, void 0 === deps ? null : deps @@ -3463,18 +3340,21 @@ function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var prevEffect = currentHook.memoizedState; destroy = prevEffect.destroy; if (null !== deps && areHookInputsEqual(deps, prevEffect.deps)) { - pushEffect(0, create, destroy, deps); + pushEffect(hookEffectTag, create, destroy, deps); return; } } - sideEffectTag |= fiberEffectTag; - hook.memoizedState = pushEffect(hookEffectTag, create, destroy, deps); + currentlyRenderingFiber$1.effectTag |= fiberEffectTag; + hook.memoizedState = pushEffect(1 | hookEffectTag, create, destroy, deps); } function mountEffect(create, deps) { - return mountEffectImpl(516, 192, create, deps); + return mountEffectImpl(516, 4, create, deps); } function updateEffect(create, deps) { - return updateEffectImpl(516, 192, create, deps); + return updateEffectImpl(516, 4, create, deps); +} +function updateLayoutEffect(create, deps) { + return updateEffectImpl(4, 2, create, deps); } function imperativeHandleEffect(create, ref) { if ("function" === typeof ref) @@ -3494,6 +3374,15 @@ 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 = [ @@ -3515,72 +3404,79 @@ 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) { - if (!(25 > numberOfReRenders)) - throw Error( - "Too many re-renders. React limits the number of renders to prevent an infinite loop." - ); - var alternate = fiber.alternate; + 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 ( fiber === currentlyRenderingFiber$1 || - (null !== alternate && alternate === currentlyRenderingFiber$1) + (null !== pending && pending === currentlyRenderingFiber$1) ) - 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; - } + (didScheduleRenderPhaseUpdate = !0), + (suspenseConfig.expirationTime = renderExpirationTime), + (currentlyRenderingFiber$1.expirationTime = renderExpirationTime); 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 === alternate || 0 === alternate.expirationTime) && - ((alternate = queue.lastRenderedReducer), null !== alternate) + (null === pending || 0 === pending.expirationTime) && + ((pending = queue.lastRenderedReducer), null !== pending) ) try { var currentState = queue.lastRenderedState, - eagerState = alternate(currentState, action); - suspenseConfig.eagerReducer = alternate; + eagerState = pending(currentState, action); + suspenseConfig.eagerReducer = pending; suspenseConfig.eagerState = eagerState; - if (is$1(eagerState, currentState)) return; + if (objectIs(eagerState, currentState)) return; } catch (error) { } finally { } - scheduleUpdateOnFiber(fiber, currentTime); + scheduleWork(fiber, currentTime); } } +function updateEventListener() {} var ContextOnlyDispatcher = { readContext: readContext, useCallback: throwInvalidHookError, @@ -3595,7 +3491,8 @@ var ContextOnlyDispatcher = { useDebugValue: throwInvalidHookError, useResponder: throwInvalidHookError, useDeferredValue: throwInvalidHookError, - useTransition: throwInvalidHookError + useTransition: throwInvalidHookError, + useEvent: throwInvalidHookError }, HooksDispatcherOnMount = { readContext: readContext, @@ -3606,13 +3503,13 @@ var ContextOnlyDispatcher = { deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; return mountEffectImpl( 4, - 36, + 2, imperativeHandleEffect.bind(null, create, ref), deps ); }, useLayoutEffect: function(create, deps) { - return mountEffectImpl(4, 36, create, deps); + return mountEffectImpl(4, 2, create, deps); }, useMemo: function(nextCreate, deps) { var hook = mountWorkInProgressHook(); @@ -3626,7 +3523,7 @@ var ContextOnlyDispatcher = { initialArg = void 0 !== init ? init(initialArg) : initialArg; hook.memoizedState = hook.baseState = initialArg; reducer = hook.queue = { - last: null, + pending: null, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialArg @@ -3645,23 +3542,21 @@ var ContextOnlyDispatcher = { }, useState: mountState, useDebugValue: mountDebugValue, - useResponder: createResponderListener, + useResponder: createDeprecatedResponderListener, useDeferredValue: function(value, config) { var _mountState = mountState(value), prevValue = _mountState[0], setValue = _mountState[1]; mountEffect( function() { - 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; - } - }); + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } }, [value, config] ); @@ -3669,177 +3564,124 @@ var ContextOnlyDispatcher = { }, useTransition: function(config) { var _mountState2 = mountState(!1), - isPending = _mountState2[0], - setPending = _mountState2[1]; + isPending = _mountState2[0]; + _mountState2 = _mountState2[1]; return [ - 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] - ), + mountCallback(startTransition.bind(null, _mountState2, config), [ + _mountState2, + config + ]), isPending ]; - } + }, + useEvent: function() {} }, HooksDispatcherOnUpdate = { readContext: readContext, useCallback: updateCallback, useContext: readContext, useEffect: updateEffect, - 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; - }, + useImperativeHandle: updateImperativeHandle, + useLayoutEffect: updateLayoutEffect, + useMemo: updateMemo, useReducer: updateReducer, - useRef: function() { - return updateWorkInProgressHook().memoizedState; + useRef: updateRef, + useState: function() { + return updateReducer(basicStateReducer); }, - useState: updateState, useDebugValue: mountDebugValue, - useResponder: createResponderListener, + useResponder: createDeprecatedResponderListener, useDeferredValue: function(value, config) { - var _updateState = updateState(value), + var _updateState = updateReducer(basicStateReducer), prevValue = _updateState[0], setValue = _updateState[1]; updateEffect( function() { - 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; - } - }); + 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 = updateState(!1), - isPending = _updateState2[0], - setPending = _updateState2[1]; + var _updateState2 = updateReducer(basicStateReducer), + isPending = _updateState2[0]; + _updateState2 = _updateState2[1]; return [ - 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] - ), + updateCallback(startTransition.bind(null, _updateState2, config), [ + _updateState2, + config + ]), isPending ]; - } + }, + useEvent: updateEventListener }, - 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 + 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] ); - 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, + 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, didReceiveUpdate = !1; function reconcileChildren( - current$$1, + current, workInProgress, nextChildren, renderExpirationTime ) { workInProgress.child = - null === current$$1 + null === current ? mountChildFibers( workInProgress, null, @@ -3848,13 +3690,13 @@ function reconcileChildren( ) : reconcileChildFibers( workInProgress, - current$$1.child, + current.child, nextChildren, renderExpirationTime ); } function updateForwardRef( - current$$1, + current, workInProgress, Component, nextProps, @@ -3864,43 +3706,38 @@ function updateForwardRef( var ref = workInProgress.ref; prepareToReadContext(workInProgress, renderExpirationTime); nextProps = renderWithHooks( - current$$1, + current, workInProgress, Component, nextProps, ref, renderExpirationTime ); - if (null !== current$$1 && !didReceiveUpdate) + if (null !== current && !didReceiveUpdate) return ( - (workInProgress.updateQueue = current$$1.updateQueue), + (workInProgress.updateQueue = current.updateQueue), (workInProgress.effectTag &= -517), - current$$1.expirationTime <= renderExpirationTime && - (current$$1.expirationTime = 0), + current.expirationTime <= renderExpirationTime && + (current.expirationTime = 0), bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ) ); workInProgress.effectTag |= 1; - reconcileChildren( - current$$1, - workInProgress, - nextProps, - renderExpirationTime - ); + reconcileChildren(current, workInProgress, nextProps, renderExpirationTime); return workInProgress.child; } function updateMemoComponent( - current$$1, + current, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime ) { - if (null === current$$1) { + if (null === current) { var type = Component.type; if ( "function" === typeof type && @@ -3913,7 +3750,7 @@ function updateMemoComponent( (workInProgress.tag = 15), (workInProgress.type = type), updateSimpleMemoComponent( - current$$1, + current, workInProgress, type, nextProps, @@ -3921,7 +3758,7 @@ function updateMemoComponent( renderExpirationTime ) ); - current$$1 = createFiberFromTypeAndProps( + current = createFiberFromTypeAndProps( Component.type, null, nextProps, @@ -3929,65 +3766,66 @@ function updateMemoComponent( workInProgress.mode, renderExpirationTime ); - current$$1.ref = workInProgress.ref; - current$$1.return = workInProgress; - return (workInProgress.child = current$$1); + current.ref = workInProgress.ref; + current.return = workInProgress; + return (workInProgress.child = current); } - type = current$$1.child; + type = current.child; if ( updateExpirationTime < renderExpirationTime && ((updateExpirationTime = type.memoizedProps), (Component = Component.compare), (Component = null !== Component ? Component : shallowEqual), Component(updateExpirationTime, nextProps) && - current$$1.ref === workInProgress.ref) + current.ref === workInProgress.ref) ) return bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ); workInProgress.effectTag |= 1; - current$$1 = createWorkInProgress(type, nextProps, renderExpirationTime); - current$$1.ref = workInProgress.ref; - current$$1.return = workInProgress; - return (workInProgress.child = current$$1); + current = createWorkInProgress(type, nextProps); + current.ref = workInProgress.ref; + current.return = workInProgress; + return (workInProgress.child = current); } function updateSimpleMemoComponent( - current$$1, + current, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime ) { - return null !== current$$1 && - shallowEqual(current$$1.memoizedProps, nextProps) && - current$$1.ref === workInProgress.ref && + return null !== current && + shallowEqual(current.memoizedProps, nextProps) && + current.ref === workInProgress.ref && ((didReceiveUpdate = !1), updateExpirationTime < renderExpirationTime) - ? bailoutOnAlreadyFinishedWork( - current$$1, + ? ((workInProgress.expirationTime = current.expirationTime), + bailoutOnAlreadyFinishedWork( + current, workInProgress, renderExpirationTime - ) + )) : updateFunctionComponent( - current$$1, + current, workInProgress, Component, nextProps, renderExpirationTime ); } -function markRef(current$$1, workInProgress) { +function markRef(current, workInProgress) { var ref = workInProgress.ref; if ( - (null === current$$1 && null !== ref) || - (null !== current$$1 && current$$1.ref !== ref) + (null === current && null !== ref) || + (null !== current && current.ref !== ref) ) workInProgress.effectTag |= 128; } function updateFunctionComponent( - current$$1, + current, workInProgress, Component, nextProps, @@ -3999,36 +3837,31 @@ function updateFunctionComponent( context = getMaskedContext(workInProgress, context); prepareToReadContext(workInProgress, renderExpirationTime); Component = renderWithHooks( - current$$1, + current, workInProgress, Component, nextProps, context, renderExpirationTime ); - if (null !== current$$1 && !didReceiveUpdate) + if (null !== current && !didReceiveUpdate) return ( - (workInProgress.updateQueue = current$$1.updateQueue), + (workInProgress.updateQueue = current.updateQueue), (workInProgress.effectTag &= -517), - current$$1.expirationTime <= renderExpirationTime && - (current$$1.expirationTime = 0), + current.expirationTime <= renderExpirationTime && + (current.expirationTime = 0), bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ) ); workInProgress.effectTag |= 1; - reconcileChildren( - current$$1, - workInProgress, - Component, - renderExpirationTime - ); + reconcileChildren(current, workInProgress, Component, renderExpirationTime); return workInProgress.child; } function updateClassComponent( - current$$1, + current, workInProgress, Component, nextProps, @@ -4040,16 +3873,11 @@ function updateClassComponent( } else hasContext = !1; prepareToReadContext(workInProgress, renderExpirationTime); if (null === workInProgress.stateNode) - null !== current$$1 && - ((current$$1.alternate = null), + null !== current && + ((current.alternate = null), (workInProgress.alternate = null), (workInProgress.effectTag |= 2)), - constructClassInstance( - workInProgress, - Component, - nextProps, - renderExpirationTime - ), + constructClassInstance(workInProgress, Component, nextProps), mountClassInstance( workInProgress, Component, @@ -4057,7 +3885,7 @@ function updateClassComponent( renderExpirationTime ), (nextProps = !0); - else if (null === current$$1) { + else if (null === current) { var instance = workInProgress.stateNode, oldProps = workInProgress.memoizedProps; instance.props = oldProps; @@ -4085,17 +3913,14 @@ function updateClassComponent( )); hasForceUpdate = !1; var oldState = workInProgress.memoizedState; - oldContext = instance.state = oldState; - var updateQueue = workInProgress.updateQueue; - null !== updateQueue && - (processUpdateQueue( - workInProgress, - updateQueue, - nextProps, - instance, - renderExpirationTime - ), - (oldContext = workInProgress.memoizedState)); + instance.state = oldState; + processUpdateQueue( + workInProgress, + nextProps, + instance, + renderExpirationTime + ); + oldContext = workInProgress.memoizedState; oldProps !== nextProps || oldState !== oldContext || didPerformWorkStackCursor.current || @@ -4141,6 +3966,7 @@ function updateClassComponent( (nextProps = !1)); } else (instance = workInProgress.stateNode), + cloneUpdateQueue(current, workInProgress), (oldProps = workInProgress.memoizedProps), (instance.props = workInProgress.type === workInProgress.elementType @@ -4169,17 +3995,14 @@ function updateClassComponent( )), (hasForceUpdate = !1), (oldContext = workInProgress.memoizedState), - (oldState = instance.state = oldContext), - (updateQueue = workInProgress.updateQueue), - null !== updateQueue && - (processUpdateQueue( - workInProgress, - updateQueue, - nextProps, - instance, - renderExpirationTime - ), - (oldState = workInProgress.memoizedState)), + (instance.state = oldContext), + processUpdateQueue( + workInProgress, + nextProps, + instance, + renderExpirationTime + ), + (oldState = workInProgress.memoizedState), oldProps !== nextProps || oldContext !== oldState || didPerformWorkStackCursor.current || @@ -4223,12 +4046,12 @@ function updateClassComponent( "function" === typeof instance.getSnapshotBeforeUpdate && (workInProgress.effectTag |= 256)) : ("function" !== typeof instance.componentDidUpdate || - (oldProps === current$$1.memoizedProps && - oldContext === current$$1.memoizedState) || + (oldProps === current.memoizedProps && + oldContext === current.memoizedState) || (workInProgress.effectTag |= 4), "function" !== typeof instance.getSnapshotBeforeUpdate || - (oldProps === current$$1.memoizedProps && - oldContext === current$$1.memoizedState) || + (oldProps === current.memoizedProps && + oldContext === current.memoizedState) || (workInProgress.effectTag |= 256), (workInProgress.memoizedProps = nextProps), (workInProgress.memoizedState = oldState)), @@ -4237,16 +4060,16 @@ function updateClassComponent( (instance.context = contextType), (nextProps = getDerivedStateFromProps)) : ("function" !== typeof instance.componentDidUpdate || - (oldProps === current$$1.memoizedProps && - oldContext === current$$1.memoizedState) || + (oldProps === current.memoizedProps && + oldContext === current.memoizedState) || (workInProgress.effectTag |= 4), "function" !== typeof instance.getSnapshotBeforeUpdate || - (oldProps === current$$1.memoizedProps && - oldContext === current$$1.memoizedState) || + (oldProps === current.memoizedProps && + oldContext === current.memoizedState) || (workInProgress.effectTag |= 256), (nextProps = !1)); return finishClassComponent( - current$$1, + current, workInProgress, Component, nextProps, @@ -4255,35 +4078,35 @@ function updateClassComponent( ); } function finishClassComponent( - current$$1, + current, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime ) { - markRef(current$$1, workInProgress); + markRef(current, workInProgress); var didCaptureError = 0 !== (workInProgress.effectTag & 64); if (!shouldUpdate && !didCaptureError) return ( hasContext && invalidateContextProvider(workInProgress, Component, !1), bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ) ); shouldUpdate = workInProgress.stateNode; - ReactCurrentOwner$3.current = workInProgress; + ReactCurrentOwner$1.current = workInProgress; var nextChildren = didCaptureError && "function" !== typeof Component.getDerivedStateFromError ? null : shouldUpdate.render(); workInProgress.effectTag |= 1; - null !== current$$1 && didCaptureError + null !== current && didCaptureError ? ((workInProgress.child = reconcileChildFibers( workInProgress, - current$$1.child, + current.child, null, renderExpirationTime )), @@ -4294,7 +4117,7 @@ function finishClassComponent( renderExpirationTime ))) : reconcileChildren( - current$$1, + current, workInProgress, nextChildren, renderExpirationTime @@ -4317,7 +4140,7 @@ function pushHostRootContext(workInProgress) { } var SUSPENDED_MARKER = { dehydrated: null, retryTime: 0 }; function updateSuspenseComponent( - current$$1, + current, workInProgress, renderExpirationTime ) { @@ -4329,32 +4152,30 @@ function updateSuspenseComponent( (JSCompiler_temp = 0 !== (workInProgress.effectTag & 64)) || (JSCompiler_temp = 0 !== (suspenseContext & 2) && - (null === current$$1 || null !== current$$1.memoizedState)); + (null === current || null !== current.memoizedState)); JSCompiler_temp ? ((nextDidTimeout = !0), (workInProgress.effectTag &= -65)) - : (null !== current$$1 && null === current$$1.memoizedState) || + : (null !== current && null === current.memoizedState) || void 0 === nextProps.fallback || !0 === nextProps.unstable_avoidThisFallback || (suspenseContext |= 1); - push(suspenseStackCursor, suspenseContext & 1, workInProgress); - if (null === current$$1) { - void 0 !== nextProps.fallback && - tryToClaimNextHydratableInstance(workInProgress); + push(suspenseStackCursor, suspenseContext & 1); + if (null === current) { if (nextDidTimeout) { nextDidTimeout = nextProps.fallback; nextProps = createFiberFromFragment(null, mode, 0, null); nextProps.return = workInProgress; if (0 === (workInProgress.mode & 2)) for ( - current$$1 = + current = null !== workInProgress.memoizedState ? workInProgress.child.child : workInProgress.child, - nextProps.child = current$$1; - null !== current$$1; + nextProps.child = current; + null !== current; ) - (current$$1.return = nextProps), (current$$1 = current$$1.sibling); + (current.return = nextProps), (current = current.sibling); renderExpirationTime = createFiberFromFragment( nextDidTimeout, mode, @@ -4376,15 +4197,14 @@ function updateSuspenseComponent( renderExpirationTime )); } - if (null !== current$$1.memoizedState) { - current$$1 = current$$1.child; - mode = current$$1.sibling; + if (null !== current.memoizedState) { + current = current.child; + mode = current.sibling; if (nextDidTimeout) { nextProps = nextProps.fallback; renderExpirationTime = createWorkInProgress( - current$$1, - current$$1.pendingProps, - 0 + current, + current.pendingProps ); renderExpirationTime.return = workInProgress; if ( @@ -4393,7 +4213,7 @@ function updateSuspenseComponent( null !== workInProgress.memoizedState ? workInProgress.child.child : workInProgress.child), - nextDidTimeout !== current$$1.child) + nextDidTimeout !== current.child) ) for ( renderExpirationTime.child = nextDidTimeout; @@ -4402,7 +4222,7 @@ function updateSuspenseComponent( ) (nextDidTimeout.return = renderExpirationTime), (nextDidTimeout = nextDidTimeout.sibling); - mode = createWorkInProgress(mode, nextProps, mode.expirationTime); + mode = createWorkInProgress(mode, nextProps); mode.return = workInProgress; renderExpirationTime.sibling = mode; renderExpirationTime.childExpirationTime = 0; @@ -4412,31 +4232,31 @@ function updateSuspenseComponent( } renderExpirationTime = reconcileChildFibers( workInProgress, - current$$1.child, + current.child, nextProps.children, renderExpirationTime ); workInProgress.memoizedState = null; return (workInProgress.child = renderExpirationTime); } - current$$1 = current$$1.child; + current = current.child; if (nextDidTimeout) { nextDidTimeout = nextProps.fallback; nextProps = createFiberFromFragment(null, mode, 0, null); nextProps.return = workInProgress; - nextProps.child = current$$1; - null !== current$$1 && (current$$1.return = nextProps); + nextProps.child = current; + null !== current && (current.return = nextProps); if (0 === (workInProgress.mode & 2)) for ( - current$$1 = + current = null !== workInProgress.memoizedState ? workInProgress.child.child : workInProgress.child, - nextProps.child = current$$1; - null !== current$$1; + nextProps.child = current; + null !== current; ) - (current$$1.return = nextProps), (current$$1 = current$$1.sibling); + (current.return = nextProps), (current = current.sibling); renderExpirationTime = createFiberFromFragment( nextDidTimeout, mode, @@ -4454,7 +4274,7 @@ function updateSuspenseComponent( workInProgress.memoizedState = null; return (workInProgress.child = reconcileChildFibers( workInProgress, - current$$1, + current, nextProps.children, renderExpirationTime )); @@ -4481,6 +4301,7 @@ function initSuspenseListRenderState( ? (workInProgress.memoizedState = { isBackwards: isBackwards, rendering: null, + renderingStartTime: 0, last: lastContentRow, tail: tail, tailExpiration: 0, @@ -4489,6 +4310,7 @@ function initSuspenseListRenderState( }) : ((renderState.isBackwards = isBackwards), (renderState.rendering = null), + (renderState.renderingStartTime = 0), (renderState.last = lastContentRow), (renderState.tail = tail), (renderState.tailExpiration = 0), @@ -4496,7 +4318,7 @@ function initSuspenseListRenderState( (renderState.lastEffect = lastEffectBeforeRendering)); } function updateSuspenseListComponent( - current$$1, + current, workInProgress, renderExpirationTime ) { @@ -4504,7 +4326,7 @@ function updateSuspenseListComponent( revealOrder = nextProps.revealOrder, tailMode = nextProps.tail; reconcileChildren( - current$$1, + current, workInProgress, nextProps.children, renderExpirationTime @@ -4513,42 +4335,39 @@ function updateSuspenseListComponent( if (0 !== (nextProps & 2)) (nextProps = (nextProps & 1) | 2), (workInProgress.effectTag |= 64); else { - 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; + 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; continue; } - if (current$$1 === workInProgress) break a; - for (; null === current$$1.sibling; ) { - if ( - null === current$$1.return || - current$$1.return === workInProgress - ) + if (current === workInProgress) break a; + for (; null === current.sibling; ) { + if (null === current.return || current.return === workInProgress) break a; - current$$1 = current$$1.return; + current = current.return; } - current$$1.sibling.return = current$$1.return; - current$$1 = current$$1.sibling; + current.sibling.return = current.return; + current = current.sibling; } nextProps &= 1; } - push(suspenseStackCursor, nextProps, workInProgress); + push(suspenseStackCursor, nextProps); if (0 === (workInProgress.mode & 2)) workInProgress.memoizedState = null; else switch (revealOrder) { case "forwards": renderExpirationTime = workInProgress.child; for (revealOrder = null; null !== renderExpirationTime; ) - (current$$1 = renderExpirationTime.alternate), - null !== current$$1 && - null === findFirstSuspended(current$$1) && + (current = renderExpirationTime.alternate), + null !== current && + null === findFirstSuspended(current) && (revealOrder = renderExpirationTime), (renderExpirationTime = renderExpirationTime.sibling); renderExpirationTime = revealOrder; @@ -4570,15 +4389,15 @@ function updateSuspenseListComponent( renderExpirationTime = null; revealOrder = workInProgress.child; for (workInProgress.child = null; null !== revealOrder; ) { - current$$1 = revealOrder.alternate; - if (null !== current$$1 && null === findFirstSuspended(current$$1)) { + current = revealOrder.alternate; + if (null !== current && null === findFirstSuspended(current)) { workInProgress.child = revealOrder; break; } - current$$1 = revealOrder.sibling; + current = revealOrder.sibling; revealOrder.sibling = renderExpirationTime; renderExpirationTime = revealOrder; - revealOrder = current$$1; + revealOrder = current; } initSuspenseListRenderState( workInProgress, @@ -4605,35 +4424,29 @@ function updateSuspenseListComponent( return workInProgress.child; } function bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ) { - null !== current$$1 && - (workInProgress.dependencies = current$$1.dependencies); + null !== current && (workInProgress.dependencies = current.dependencies); var updateExpirationTime = workInProgress.expirationTime; 0 !== updateExpirationTime && markUnprocessedUpdateTime(updateExpirationTime); if (workInProgress.childExpirationTime < renderExpirationTime) return null; - if (null !== current$$1 && workInProgress.child !== current$$1.child) + if (null !== current && workInProgress.child !== current.child) throw Error("Resuming work not yet implemented."); if (null !== workInProgress.child) { - current$$1 = workInProgress.child; - renderExpirationTime = createWorkInProgress( - current$$1, - current$$1.pendingProps, - current$$1.expirationTime - ); + current = workInProgress.child; + renderExpirationTime = createWorkInProgress(current, current.pendingProps); workInProgress.child = renderExpirationTime; for ( renderExpirationTime.return = workInProgress; - null !== current$$1.sibling; + null !== current.sibling; ) - (current$$1 = current$$1.sibling), + (current = current.sibling), (renderExpirationTime = renderExpirationTime.sibling = createWorkInProgress( - current$$1, - current$$1.pendingProps, - current$$1.expirationTime + current, + current.pendingProps )), (renderExpirationTime.return = workInProgress); renderExpirationTime.sibling = null; @@ -4695,62 +4508,367 @@ function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { : (_lastTailNode.sibling = null); } } -function unwindWork(workInProgress) { +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: - isContextProvider(workInProgress.type) && popContext(workInProgress); - var effectTag = workInProgress.effectTag; - return effectTag & 4096 - ? ((workInProgress.effectTag = (effectTag & -4097) | 64), - workInProgress) - : null; + return isContextProvider(workInProgress.type) && popContext(), null; case 3: - popHostContainer(workInProgress); - popTopLevelContextObject(workInProgress); - effectTag = workInProgress.effectTag; - if (0 !== (effectTag & 64)) - throw Error( - "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." - ); - workInProgress.effectTag = (effectTag & -4097) | 64; - return workInProgress; - case 5: - return popHostContext(workInProgress), null; - case 13: return ( - pop(suspenseStackCursor, workInProgress), - (effectTag = workInProgress.effectTag), - effectTag & 4096 - ? ((workInProgress.effectTag = (effectTag & -4097) | 64), - workInProgress) - : null + popHostContainer(), + pop(didPerformWorkStackCursor), + pop(contextStackCursor), + (current = workInProgress.stateNode), + current.pendingContext && + ((current.context = current.pendingContext), + (current.pendingContext = null)), + updateHostContainer(workInProgress), + null ); - case 19: - return pop(suspenseStackCursor, workInProgress), null; - case 4: - return popHostContainer(workInProgress), null; - case 10: - return popProvider(workInProgress), null; - default: + 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; - } -} -function createCapturedValue(value, source) { - return { - value: value, - source: source, - stack: getStackByFiberInDevAndProd(source) - }; -} -if ( - "function" !== - typeof ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog -) - throw Error( - "Expected ReactFiberErrorDialog.showErrorDialog to be a function." - ); -function logCapturedError(capturedError) { - !1 !== + 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(); + var effectTag = workInProgress.effectTag; + return effectTag & 4096 + ? ((workInProgress.effectTag = (effectTag & -4097) | 64), + workInProgress) + : null; + case 3: + popHostContainer(); + pop(didPerformWorkStackCursor); + pop(contextStackCursor); + effectTag = workInProgress.effectTag; + if (0 !== (effectTag & 64)) + throw Error( + "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." + ); + workInProgress.effectTag = (effectTag & -4097) | 64; + return workInProgress; + case 5: + return popHostContext(workInProgress), null; + case 13: + return ( + pop(suspenseStackCursor), + (effectTag = workInProgress.effectTag), + effectTag & 4096 + ? ((workInProgress.effectTag = (effectTag & -4097) | 64), + workInProgress) + : null + ); + case 19: + return pop(suspenseStackCursor), null; + case 4: + return popHostContainer(), null; + case 10: + return popProvider(workInProgress), null; + default: + return null; + } +} +function createCapturedValue(value, source) { + return { + value: value, + source: source, + stack: getStackByFiberInDevAndProd(source) + }; +} +if ( + "function" !== + typeof ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog +) + throw Error( + "Expected ReactFiberErrorDialog.showErrorDialog to be a function." + ); +function logCapturedError(capturedError) { + !1 !== ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog( capturedError ) && console.error(capturedError.error); @@ -4785,85 +4903,159 @@ function logError(boundary, errorInfo) { }); } } -function safelyCallComponentWillUnmount(current$$1, instance) { +function safelyCallComponentWillUnmount(current, instance) { try { - (instance.props = current$$1.memoizedProps), - (instance.state = current$$1.memoizedState), + (instance.props = current.memoizedProps), + (instance.state = current.memoizedState), instance.componentWillUnmount(); } catch (unmountError) { - captureCommitPhaseError(current$$1, unmountError); + captureCommitPhaseError(current, unmountError); } } -function safelyDetachRef(current$$1) { - var ref = current$$1.ref; +function safelyDetachRef(current) { + var ref = current.ref; if (null !== ref) if ("function" === typeof ref) try { ref(null); } catch (refError) { - captureCommitPhaseError(current$$1, refError); + captureCommitPhaseError(current, refError); } else ref.current = null; } -function commitBeforeMutationLifeCycles(current$$1, finishedWork) { +function commitBeforeMutationLifeCycles(current, finishedWork) { switch (finishedWork.tag) { case 0: case 11: case 15: - commitHookEffectList(2, 0, finishedWork); - break; + case 22: + return; case 1: - if (finishedWork.effectTag & 256 && null !== current$$1) { - var prevProps = current$$1.memoizedProps, - prevState = current$$1.memoizedState; - current$$1 = finishedWork.stateNode; - finishedWork = current$$1.getSnapshotBeforeUpdate( + if (finishedWork.effectTag & 256 && null !== current) { + var prevProps = current.memoizedProps, + prevState = current.memoizedState; + current = finishedWork.stateNode; + finishedWork = current.getSnapshotBeforeUpdate( finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState ); - current$$1.__reactInternalSnapshotBeforeUpdate = finishedWork; + current.__reactInternalSnapshotBeforeUpdate = finishedWork; } - break; + return; case 3: case 5: case 6: case 4: case 17: - break; - default: - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); + 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 commitHookEffectList(unmountTag, mountTag, finishedWork) { +function commitHookEffectListUnmount(tag, finishedWork) { finishedWork = finishedWork.updateQueue; finishedWork = null !== finishedWork ? finishedWork.lastEffect : null; if (null !== finishedWork) { var effect = (finishedWork = finishedWork.next); do { - if (0 !== (effect.tag & unmountTag)) { + if ((effect.tag & tag) === tag) { 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 commitUnmount(finishedRoot, current$$1$jscomp$0, renderPriorityLevel) { +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" === typeof onCommitFiberUnmount && - onCommitFiberUnmount(current$$1$jscomp$0); - switch (current$$1$jscomp$0.tag) { + onCommitFiberUnmount(current$jscomp$0); + switch (current$jscomp$0.tag) { case 0: case 11: case 14: case 15: - finishedRoot = current$$1$jscomp$0.updateQueue; + case 22: + finishedRoot = current$jscomp$0.updateQueue; if ( null !== finishedRoot && ((finishedRoot = finishedRoot.lastEffect), null !== finishedRoot) @@ -4874,13 +5066,13 @@ function commitUnmount(finishedRoot, current$$1$jscomp$0, renderPriorityLevel) { function() { var effect = firstEffect; do { - var destroy = effect.destroy; - if (void 0 !== destroy) { - var current$$1 = current$$1$jscomp$0; + var _destroy = effect.destroy; + if (void 0 !== _destroy) { + var current = current$jscomp$0; try { - destroy(); + _destroy(); } catch (error) { - captureCommitPhaseError(current$$1, error); + captureCommitPhaseError(current, error); } } effect = effect.next; @@ -4890,37 +5082,35 @@ function commitUnmount(finishedRoot, current$$1$jscomp$0, renderPriorityLevel) { } break; case 1: - safelyDetachRef(current$$1$jscomp$0); - renderPriorityLevel = current$$1$jscomp$0.stateNode; + safelyDetachRef(current$jscomp$0); + renderPriorityLevel = current$jscomp$0.stateNode; "function" === typeof renderPriorityLevel.componentWillUnmount && - safelyCallComponentWillUnmount( - current$$1$jscomp$0, - renderPriorityLevel - ); + safelyCallComponentWillUnmount(current$jscomp$0, renderPriorityLevel); break; case 5: - safelyDetachRef(current$$1$jscomp$0); + safelyDetachRef(current$jscomp$0); break; case 4: unmountHostComponents( finishedRoot, - current$$1$jscomp$0, + current$jscomp$0, renderPriorityLevel ); } } -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; +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; null !== alternate && detachFiber(alternate); } function isHostParent(fiber) { @@ -4983,97 +5173,103 @@ function commitPlacement(finishedWork) { break a; } } - 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), + 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( - isHost._nativeTag, - [index], - [beforeChild], + parent._nativeTag, + [isHost], + [before], [], [], [] )) - : ((index = children.indexOf(beforeChild)), - children.splice(index, 0, stateNode), + : ((before = tag.indexOf(before)), + tag.splice(before, 0, node), ReactNativePrivateInterface.UIManager.manageChildren( - isHost._nativeTag, + parent._nativeTag, [], [], - [ - "number" === typeof stateNode - ? stateNode - : stateNode._nativeTag - ], - [index], + ["number" === typeof node ? node : node._nativeTag], + [before], [] - )); - } - 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; - } + ))) + : ((before = "number" === typeof node ? node : node._nativeTag), + (tag = parent._children), + (isHost = tag.indexOf(node)), + 0 <= isHost + ? (tag.splice(isHost, 1), + tag.push(node), + ReactNativePrivateInterface.UIManager.manageChildren( + parent._nativeTag, + [isHost], + [tag.length - 1], + [], + [], + [] + )) + : (tag.push(node), + ReactNativePrivateInterface.UIManager.manageChildren( + parent._nativeTag, + [], + [], + [before], + [tag.length - 1], + [] + ))); + 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); } function unmountHostComponents( finishedRoot$jscomp$0, - current$$1, + current, renderPriorityLevel$jscomp$0 ) { for ( - var node = current$$1, + var node = current, currentParentIsValid = !1, currentParent, currentParentIsContainer; @@ -5121,7 +5317,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; + if (node$jscomp$0 === root) break a; for (; null === node$jscomp$0.sibling; ) { if (null === node$jscomp$0.return || node$jscomp$0.return === root) break a; @@ -5171,9 +5367,9 @@ function unmountHostComponents( node = node.child; continue; } - if (node === current$$1) break; + if (node === current) break; for (; null === node.sibling; ) { - if (null === node.return || node.return === current$$1) return; + if (null === node.return || node.return === current) return; node = node.return; 4 === node.tag && (currentParentIsValid = !1); } @@ -5181,21 +5377,22 @@ function unmountHostComponents( node = node.sibling; } } -function commitWork(current$$1, finishedWork) { +function commitWork(current, finishedWork) { switch (finishedWork.tag) { case 0: case 11: case 14: case 15: - commitHookEffectList(4, 8, finishedWork); - break; + case 22: + commitHookEffectListUnmount(3, finishedWork); + return; case 1: - break; + return; case 5: var instance = finishedWork.stateNode; if (null != instance) { var newProps = finishedWork.memoizedProps; - current$$1 = null !== current$$1 ? current$$1.memoizedProps : newProps; + current = null !== current ? current.memoizedProps : newProps; var updatePayload = finishedWork.updateQueue; finishedWork.updateQueue = null; null !== updatePayload && @@ -5203,7 +5400,7 @@ function commitWork(current$$1, finishedWork) { instanceProps.set(instance._nativeTag, newProps), (newProps = diffProperties( null, - current$$1, + current, newProps, finishedWork.validAttributes )), @@ -5214,7 +5411,7 @@ function commitWork(current$$1, finishedWork) { newProps )); } - break; + return; case 6: if (null === finishedWork.stateNode) throw Error( @@ -5225,11 +5422,11 @@ function commitWork(current$$1, finishedWork) { "RCTRawText", { text: finishedWork.memoizedProps } ); - break; + return; case 3: - break; + return; case 12: - break; + return; case 13: instance = finishedWork; null === finishedWork.memoizedState @@ -5238,9 +5435,9 @@ function commitWork(current$$1, finishedWork) { (instance = finishedWork.child), (globalMostRecentFallbackTime = now())); if (null !== instance) - a: for (current$$1 = instance; ; ) { - if (5 === current$$1.tag) - if (((updatePayload = current$$1.stateNode), newProps)) { + a: for (current = instance; ; ) { + if (5 === current.tag) + if (((updatePayload = current.stateNode), newProps)) { var viewConfig = updatePayload.viewConfig; var updatePayload$jscomp$0 = diffProperties( null, @@ -5254,8 +5451,8 @@ function commitWork(current$$1, finishedWork) { updatePayload$jscomp$0 ); } else { - updatePayload = current$$1.stateNode; - updatePayload$jscomp$0 = current$$1.memoizedProps; + updatePayload = current.stateNode; + updatePayload$jscomp$0 = current.memoizedProps; viewConfig = updatePayload.viewConfig; var prevProps = Object.assign({}, updatePayload$jscomp$0, { style: [updatePayload$jscomp$0.style, { display: "none" }] @@ -5273,47 +5470,41 @@ function commitWork(current$$1, finishedWork) { ); } else { - if (6 === current$$1.tag) throw Error("Not yet implemented."); + if (6 === current.tag) throw Error("Not yet implemented."); if ( - 13 === current$$1.tag && - null !== current$$1.memoizedState && - null === current$$1.memoizedState.dehydrated + 13 === current.tag && + null !== current.memoizedState && + null === current.memoizedState.dehydrated ) { - updatePayload = current$$1.child.sibling; - updatePayload.return = current$$1; - current$$1 = updatePayload; + updatePayload = current.child.sibling; + updatePayload.return = current; + current = updatePayload; continue; - } else if (null !== current$$1.child) { - current$$1.child.return = current$$1; - current$$1 = current$$1.child; + } else if (null !== current.child) { + current.child.return = current; + current = current.child; continue; } } - 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; + if (current === instance) break; + for (; null === current.sibling; ) { + if (null === current.return || current.return === instance) break a; + current = current.return; } - current$$1.sibling.return = current$$1.return; - current$$1 = current$$1.sibling; + current.sibling.return = current.return; + current = current.sibling; } attachSuspenseRetryListeners(finishedWork); - break; + return; case 19: attachSuspenseRetryListeners(finishedWork); - break; + return; case 17: - 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." - ); + return; } + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); } function attachSuspenseRetryListeners(finishedWork) { var thenables = finishedWork.updateQueue; @@ -5369,7 +5560,7 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { return expirationTime; } var ceil = Math.ceil, - ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher, + ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, NoContext = 0, LegacyUnbatchedContext = 8, @@ -5384,7 +5575,7 @@ var ceil = Math.ceil, executionContext = NoContext, workInProgressRoot = null, workInProgress = null, - renderExpirationTime = 0, + renderExpirationTime$1 = 0, workInProgressRootExitStatus = RootIncomplete, workInProgressRootFatalError = null, workInProgressRootLatestProcessedExpirationTime = 1073741823, @@ -5409,8 +5600,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; @@ -5418,7 +5609,7 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { var priorityLevel = getCurrentPriorityLevel(); if (0 === (fiber & 4)) return 99 === priorityLevel ? 1073741823 : 1073741822; if ((executionContext & RenderContext) !== NoContext) - return renderExpirationTime; + return renderExpirationTime$1; if (null !== suspenseConfig) currentTime = 1073741821 - @@ -5450,11 +5641,11 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { throw Error("Expected a valid priority level"); } null !== workInProgressRoot && - currentTime === renderExpirationTime && + currentTime === renderExpirationTime$1 && --currentTime; return currentTime; } -function scheduleUpdateOnFiber(fiber, expirationTime) { +function scheduleWork(fiber, expirationTime) { if (50 < nestedUpdateCount) throw ((nestedUpdateCount = 0), (rootWithNestedUpdates = null), @@ -5508,7 +5699,7 @@ function markUpdateTimeFromFiberToRoot(fiber, expirationTime) { (workInProgressRoot === root && (markUnprocessedUpdateTime(expirationTime), workInProgressRootExitStatus === RootSuspendedWithDelay && - markRootSuspendedAtTime(root, renderExpirationTime)), + markRootSuspendedAtTime(root, renderExpirationTime$1)), markRootUpdatedAtTime(root, expirationTime)); return root; } @@ -5517,9 +5708,10 @@ function getNextRootExpirationTimeToWorkOn(root) { if (0 !== lastExpiredTime) return lastExpiredTime; lastExpiredTime = root.firstPendingTime; if (!isRootSuspendedAtTime(root, lastExpiredTime)) return lastExpiredTime; - lastExpiredTime = root.lastPingedTime; + var lastPingedTime = root.lastPingedTime; root = root.nextKnownPendingLevel; - return lastExpiredTime > root ? lastExpiredTime : root; + root = lastPingedTime > root ? lastPingedTime : root; + return 2 >= root && lastExpiredTime !== root ? 0 : root; } function ensureRootIsScheduled(root) { if (0 !== root.lastExpiredTime) @@ -5541,18 +5733,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 ( @@ -5579,264 +5771,225 @@ function ensureRootIsScheduled(root) { } function performConcurrentWorkOnRoot(root, didTimeout) { currentEventTime = 0; - if (didTimeout) - return ( - (didTimeout = requestCurrentTimeForUpdate()), - markRootExpiredAtTime(root, didTimeout), + 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), ensureRootIsScheduled(root), - 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(); + 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; - } catch (thrownValue) { - handleError(root, thrownValue); } - 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) + 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) ) { - case RootIncomplete: - case RootFatalErrored: - throw Error("Root did not complete. This is a bug in React."); - case RootErrored: - markRootExpiredAtTime( - root, - 2 < expirationTime ? 2 : expirationTime + 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 + ); + break; + } + commitRoot(root); + break; + case RootCompleted: + if ( + 1073741823 !== workInProgressRootLatestProcessedExpirationTime && + null !== workInProgressRootCanSuspendUsingConfig + ) { + 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 ); 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."); + } } - ensureRootIsScheduled(root); - if (root.callbackNode === didTimeout) - return performConcurrentWorkOnRoot.bind(null, root); + commitRoot(root); + break; + default: + throw Error("Unknown root exit status."); } } - return null; + 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 ? 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); - } - } + 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; @@ -5848,26 +6001,27 @@ function prepareFreshStack(root, expirationTime) { var interruptedWork = timeoutHandle; switch (interruptedWork.tag) { case 1: - var childContextTypes = interruptedWork.type.childContextTypes; - null !== childContextTypes && - void 0 !== childContextTypes && - popContext(interruptedWork); + interruptedWork = interruptedWork.type.childContextTypes; + null !== interruptedWork && + void 0 !== interruptedWork && + popContext(); break; case 3: - popHostContainer(interruptedWork); - popTopLevelContextObject(interruptedWork); + popHostContainer(); + pop(didPerformWorkStackCursor); + pop(contextStackCursor); break; case 5: popHostContext(interruptedWork); break; case 4: - popHostContainer(interruptedWork); + popHostContainer(); break; case 13: - pop(suspenseStackCursor, interruptedWork); + pop(suspenseStackCursor); break; case 19: - pop(suspenseStackCursor, interruptedWork); + pop(suspenseStackCursor); break; case 10: popProvider(interruptedWork); @@ -5875,8 +6029,8 @@ function prepareFreshStack(root, expirationTime) { timeoutHandle = timeoutHandle.return; } workInProgressRoot = root; - workInProgress = createWorkInProgress(root.current, null, expirationTime); - renderExpirationTime = expirationTime; + workInProgress = createWorkInProgress(root.current, null); + renderExpirationTime$1 = expirationTime; workInProgressRootExitStatus = RootIncomplete; workInProgressRootFatalError = null; workInProgressRootLatestSuspenseTimeout = workInProgressRootLatestProcessedExpirationTime = 1073741823; @@ -5888,19 +6042,32 @@ function handleError(root$jscomp$0, thrownValue) { do { try { resetContextDependencies(); - resetHooks(); + 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; if (null === workInProgress || null === workInProgress.return) return ( (workInProgressRootExitStatus = RootFatalErrored), (workInProgressRootFatalError = thrownValue), - null + (workInProgress = null) ); a: { var root = root$jscomp$0, returnFiber = workInProgress.return, sourceFiber = workInProgress, value = thrownValue; - thrownValue = renderExpirationTime; + thrownValue = renderExpirationTime$1; sourceFiber.effectTag |= 2048; sourceFiber.firstEffect = sourceFiber.lastEffect = null; if ( @@ -5908,8 +6075,17 @@ function handleError(root$jscomp$0, thrownValue) { "object" === typeof value && "function" === typeof value.then ) { - var thenable = value, - hasInvisibleParentBoundary = + 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 = 0 !== (suspenseStackCursor.current & 1), _workInProgress = returnFiber; do { @@ -5924,10 +6100,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) { @@ -6034,406 +6210,94 @@ function handleError(root$jscomp$0, thrownValue) { } while (1); } function pushDispatcher() { - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = ContextOnlyDispatcher; - return null === prevDispatcher ? ContextOnlyDispatcher : prevDispatcher; -} -function markRenderEventTimeAndConfig(expirationTime, suspenseConfig) { - expirationTime < workInProgressRootLatestProcessedExpirationTime && - 2 < expirationTime && - (workInProgressRootLatestProcessedExpirationTime = expirationTime); - null !== suspenseConfig && - expirationTime < workInProgressRootLatestSuspenseTimeout && - 2 < expirationTime && - ((workInProgressRootLatestSuspenseTimeout = expirationTime), - (workInProgressRootCanSuspendUsingConfig = suspenseConfig)); -} -function markUnprocessedUpdateTime(expirationTime) { - expirationTime > workInProgressRootNextUnprocessedUpdateTime && - (workInProgressRootNextUnprocessedUpdateTime = expirationTime); -} -function workLoopSync() { - for (; null !== workInProgress; ) - workInProgress = performUnitOfWork(workInProgress); -} -function workLoopConcurrent() { - for (; null !== workInProgress && !Scheduler_shouldYield(); ) - workInProgress = performUnitOfWork(workInProgress); -} -function performUnitOfWork(unitOfWork) { - var next = beginWork$$1( - unitOfWork.alternate, - unitOfWork, - renderExpirationTime - ); - unitOfWork.memoizedProps = unitOfWork.pendingProps; - null === next && (next = completeUnitOfWork(unitOfWork)); - ReactCurrentOwner$2.current = null; - return next; -} -function completeUnitOfWork(unitOfWork) { - workInProgress = unitOfWork; - do { - var current$$1 = workInProgress.alternate; - unitOfWork = workInProgress.return; - if (0 === (workInProgress.effectTag & 2048)) { - 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; + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; + return null === prevDispatcher ? ContextOnlyDispatcher : prevDispatcher; +} +function markRenderEventTimeAndConfig(expirationTime, suspenseConfig) { + expirationTime < workInProgressRootLatestProcessedExpirationTime && + 2 < expirationTime && + (workInProgressRootLatestProcessedExpirationTime = expirationTime); + null !== suspenseConfig && + expirationTime < workInProgressRootLatestSuspenseTimeout && + 2 < expirationTime && + ((workInProgressRootLatestSuspenseTimeout = expirationTime), + (workInProgressRootCanSuspendUsingConfig = suspenseConfig)); +} +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(); ) + workInProgress = performUnitOfWork(workInProgress); +} +function performUnitOfWork(unitOfWork) { + var next = beginWork$1( + unitOfWork.alternate, + unitOfWork, + renderExpirationTime$1 + ); + unitOfWork.memoizedProps = unitOfWork.pendingProps; + null === next && (next = completeUnitOfWork(unitOfWork)); + ReactCurrentOwner$2.current = null; + return next; +} +function completeUnitOfWork(unitOfWork) { + workInProgress = unitOfWork; + do { + var current = workInProgress.alternate; + unitOfWork = workInProgress.return; + if (0 === (workInProgress.effectTag & 2048)) { + current = completeWork(current, workInProgress, renderExpirationTime$1); + if ( + 1 === renderExpirationTime$1 || + 1 !== workInProgress.childExpirationTime + ) { for ( - rootContainerInstance = current.child; - null !== rootContainerInstance; + var newChildExpirationTime = 0, _child = workInProgress.child; + null !== _child; - ) - (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; + ) { + var _childUpdateExpirationTime = _child.expirationTime, + _childChildExpirationTime = _child.childExpirationTime; + _childUpdateExpirationTime > newChildExpirationTime && + (newChildExpirationTime = _childUpdateExpirationTime); + _childChildExpirationTime > newChildExpirationTime && + (newChildExpirationTime = _childChildExpirationTime); + _child = _child.sibling; + } + workInProgress.childExpirationTime = newChildExpirationTime; } - if (null !== current$$1) return current$$1; + if (null !== current) return current; null !== unitOfWork && 0 === (unitOfWork.effectTag & 2048) && (null === unitOfWork.firstEffect && @@ -6448,15 +6312,14 @@ function completeUnitOfWork(unitOfWork) { : (unitOfWork.firstEffect = workInProgress), (unitOfWork.lastEffect = workInProgress))); } else { - current$$1 = unwindWork(workInProgress, renderExpirationTime); - if (null !== current$$1) - return (current$$1.effectTag &= 2047), current$$1; + current = unwindWork(workInProgress); + if (null !== current) return (current.effectTag &= 2047), current; null !== unitOfWork && ((unitOfWork.firstEffect = unitOfWork.lastEffect = null), (unitOfWork.effectTag |= 2048)); } - current$$1 = workInProgress.sibling; - if (null !== current$$1) return current$$1; + current = workInProgress.sibling; + if (null !== current) return current; workInProgress = unitOfWork; } while (null !== workInProgress); workInProgressRootExitStatus === RootIncomplete && @@ -6474,7 +6337,8 @@ function commitRoot(root) { return null; } function commitRootImpl(root$jscomp$0, renderPriorityLevel$jscomp$0) { - flushPassiveEffects(); + do flushPassiveEffects(); + while (null !== rootWithPendingPassiveEffects); if ((executionContext & (RenderContext | CommitContext)) !== NoContext) throw Error("Should not already be working."); var finishedWork = root$jscomp$0.finishedWork, @@ -6503,7 +6367,8 @@ 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 = 0)); + ((workInProgress = workInProgressRoot = null), + (renderExpirationTime$1 = 0)); 1 < finishedWork.effectTag ? null !== finishedWork.lastEffect ? ((finishedWork.lastEffect.nextEffect = finishedWork), @@ -6535,9 +6400,9 @@ function commitRootImpl(root$jscomp$0, renderPriorityLevel$jscomp$0) { ) { var effectTag = nextEffect.effectTag; if (effectTag & 128) { - var current$$1 = nextEffect.alternate; - if (null !== current$$1) { - var currentRef = current$$1.ref; + var current = nextEffect.alternate; + if (null !== current) { + var currentRef = current.ref; null !== currentRef && ("function" === typeof currentRef ? currentRef(null) @@ -6565,13 +6430,13 @@ function commitRootImpl(root$jscomp$0, renderPriorityLevel$jscomp$0) { commitWork(nextEffect.alternate, nextEffect); break; case 8: - var current$$1$jscomp$0 = nextEffect; + var current$jscomp$0 = nextEffect; unmountHostComponents( root, - current$$1$jscomp$0, + current$jscomp$0, renderPriorityLevel ); - detachFiber(current$$1$jscomp$0); + detachFiber(current$jscomp$0); } nextEffect = nextEffect.nextEffect; } @@ -6585,97 +6450,25 @@ function commitRootImpl(root$jscomp$0, renderPriorityLevel$jscomp$0) { nextEffect = remainingExpirationTimeBeforeCommit; do try { - for (effectTag = expirationTime; null !== nextEffect; ) { + for (effectTag = root$jscomp$0; null !== nextEffect; ) { var effectTag$jscomp$0 = nextEffect.effectTag; - 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." - ); - } - } + effectTag$jscomp$0 & 36 && + commitLifeCycles(effectTag, nextEffect.alternate, nextEffect); if (effectTag$jscomp$0 & 128) { - current$$1 = void 0; + current = void 0; var ref = nextEffect.ref; if (null !== ref) { - var instance$jscomp$0 = nextEffect.stateNode; + var instance = nextEffect.stateNode; switch (nextEffect.tag) { case 5: - current$$1 = instance$jscomp$0; + current = instance; break; default: - current$$1 = instance$jscomp$0; + current = instance; } "function" === typeof ref - ? ref(current$$1) - : (ref.current = current$$1); + ? ref(current) + : (ref.current = current); } } nextEffect = nextEffect.nextEffect; @@ -6764,8 +6557,9 @@ function flushPassiveEffectsImpl() { case 0: case 11: case 15: - commitHookEffectList(128, 0, finishedWork), - commitHookEffectList(0, 64, finishedWork); + case 22: + commitHookEffectListUnmount(5, finishedWork), + commitHookEffectListMount(5, finishedWork); } } catch (error) { if (null === root) throw Error("Should be working on an effect."); @@ -6816,20 +6610,17 @@ function captureCommitPhaseError(sourceFiber, error) { function pingSuspendedRoot(root, thenable, suspendedTime) { var pingCache = root.pingCache; null !== pingCache && pingCache.delete(thenable); - workInProgressRoot === root && renderExpirationTime === suspendedTime + workInProgressRoot === root && renderExpirationTime$1 === suspendedTime ? workInProgressRootExitStatus === RootSuspendedWithDelay || (workInProgressRootExitStatus === RootSuspended && 1073741823 === workInProgressRootLatestProcessedExpirationTime && now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) - ? prepareFreshStack(root, renderExpirationTime) + ? prepareFreshStack(root, renderExpirationTime$1) : (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))); + ((root.lastPingedTime = suspendedTime), ensureRootIsScheduled(root))); } function resolveRetryThenable(boundaryFiber, thenable) { var retryCache = boundaryFiber.stateNode; @@ -6841,12 +6632,12 @@ function resolveRetryThenable(boundaryFiber, thenable) { boundaryFiber = markUpdateTimeFromFiberToRoot(boundaryFiber, thenable); null !== boundaryFiber && ensureRootIsScheduled(boundaryFiber); } -var beginWork$$1; -beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { +var beginWork$1; +beginWork$1 = function(current, workInProgress, renderExpirationTime) { var updateExpirationTime = workInProgress.expirationTime; - if (null !== current$$1) + if (null !== current) if ( - current$$1.memoizedProps !== workInProgress.pendingProps || + current.memoizedProps !== workInProgress.pendingProps || didPerformWorkStackCursor.current ) didReceiveUpdate = !0; @@ -6871,7 +6662,10 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { ); break; case 10: - pushProvider(workInProgress, workInProgress.memoizedProps.value); + updateExpirationTime = workInProgress.memoizedProps.value; + var context = workInProgress.type._context; + push(valueCursor, context._currentValue); + context._currentValue = updateExpirationTime; break; case 13: if (null !== workInProgress.memoizedState) { @@ -6881,52 +6675,40 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { updateExpirationTime >= renderExpirationTime ) return updateSuspenseComponent( - current$$1, + current, workInProgress, renderExpirationTime ); - push( - suspenseStackCursor, - suspenseStackCursor.current & 1, - workInProgress - ); + push(suspenseStackCursor, suspenseStackCursor.current & 1); workInProgress = bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ); return null !== workInProgress ? workInProgress.sibling : null; } - push( - suspenseStackCursor, - suspenseStackCursor.current & 1, - workInProgress - ); + push(suspenseStackCursor, suspenseStackCursor.current & 1); break; case 19: updateExpirationTime = workInProgress.childExpirationTime >= renderExpirationTime; - if (0 !== (current$$1.effectTag & 64)) { + if (0 !== (current.effectTag & 64)) { if (updateExpirationTime) return updateSuspenseListComponent( - current$$1, + current, workInProgress, renderExpirationTime ); workInProgress.effectTag |= 64; } - var renderState = workInProgress.memoizedState; - null !== renderState && - ((renderState.rendering = null), (renderState.tail = null)); - push( - suspenseStackCursor, - suspenseStackCursor.current, - workInProgress - ); + context = workInProgress.memoizedState; + null !== context && + ((context.rendering = null), (context.tail = null)); + push(suspenseStackCursor, suspenseStackCursor.current); if (!updateExpirationTime) return null; } return bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ); @@ -6938,41 +6720,40 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { switch (workInProgress.tag) { case 2: updateExpirationTime = workInProgress.type; - null !== current$$1 && - ((current$$1.alternate = null), + null !== current && + ((current.alternate = null), (workInProgress.alternate = null), (workInProgress.effectTag |= 2)); - current$$1 = workInProgress.pendingProps; - renderState = getMaskedContext( - workInProgress, - contextStackCursor.current - ); + current = workInProgress.pendingProps; + context = getMaskedContext(workInProgress, contextStackCursor.current); prepareToReadContext(workInProgress, renderExpirationTime); - renderState = renderWithHooks( + context = renderWithHooks( null, workInProgress, updateExpirationTime, - current$$1, - renderState, + current, + context, renderExpirationTime ); workInProgress.effectTag |= 1; if ( - "object" === typeof renderState && - null !== renderState && - "function" === typeof renderState.render && - void 0 === renderState.$$typeof + "object" === typeof context && + null !== context && + "function" === typeof context.render && + void 0 === context.$$typeof ) { workInProgress.tag = 1; - resetHooks(); + workInProgress.memoizedState = null; + workInProgress.updateQueue = null; if (isContextProvider(updateExpirationTime)) { var hasContext = !0; pushContextProvider(workInProgress); } else hasContext = !1; workInProgress.memoizedState = - null !== renderState.state && void 0 !== renderState.state - ? renderState.state + null !== context.state && void 0 !== context.state + ? context.state : null; + initializeUpdateQueue(workInProgress); var getDerivedStateFromProps = updateExpirationTime.getDerivedStateFromProps; "function" === typeof getDerivedStateFromProps && @@ -6980,15 +6761,15 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { workInProgress, updateExpirationTime, getDerivedStateFromProps, - current$$1 + current ); - renderState.updater = classComponentUpdater; - workInProgress.stateNode = renderState; - renderState._reactInternalFiber = workInProgress; + context.updater = classComponentUpdater; + workInProgress.stateNode = context; + context._reactInternalFiber = workInProgress; mountClassInstance( workInProgress, updateExpirationTime, - current$$1, + current, renderExpirationTime ); workInProgress = finishClassComponent( @@ -7004,127 +6785,129 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { reconcileChildren( null, workInProgress, - renderState, + context, renderExpirationTime ), (workInProgress = workInProgress.child); return workInProgress; case 16: - 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." - ); + 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." + ); } return workInProgress; case 0: return ( (updateExpirationTime = workInProgress.type), - (renderState = workInProgress.pendingProps), - (renderState = + (context = workInProgress.pendingProps), + (context = workInProgress.elementType === updateExpirationTime - ? renderState - : resolveDefaultProps(updateExpirationTime, renderState)), + ? context + : resolveDefaultProps(updateExpirationTime, context)), updateFunctionComponent( - current$$1, + current, workInProgress, updateExpirationTime, - renderState, + context, renderExpirationTime ) ); case 1: return ( (updateExpirationTime = workInProgress.type), - (renderState = workInProgress.pendingProps), - (renderState = + (context = workInProgress.pendingProps), + (context = workInProgress.elementType === updateExpirationTime - ? renderState - : resolveDefaultProps(updateExpirationTime, renderState)), + ? context + : resolveDefaultProps(updateExpirationTime, context)), updateClassComponent( - current$$1, + current, workInProgress, updateExpirationTime, - renderState, + context, renderExpirationTime ) ); case 3: pushHostRootContext(workInProgress); updateExpirationTime = workInProgress.updateQueue; - if (null === updateExpirationTime) + if (null === current || 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." ); - renderState = workInProgress.memoizedState; - renderState = null !== renderState ? renderState.element : null; + updateExpirationTime = workInProgress.pendingProps; + context = workInProgress.memoizedState; + context = null !== context ? context.element : null; + cloneUpdateQueue(current, workInProgress); processUpdateQueue( workInProgress, updateExpirationTime, - workInProgress.pendingProps, null, renderExpirationTime ); updateExpirationTime = workInProgress.memoizedState.element; - updateExpirationTime === renderState + updateExpirationTime === context ? (workInProgress = bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime )) : (reconcileChildren( - current$$1, + current, workInProgress, updateExpirationTime, renderExpirationTime @@ -7134,11 +6917,10 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { case 5: return ( pushHostContext(workInProgress), - null === current$$1 && tryToClaimNextHydratableInstance(workInProgress), (updateExpirationTime = workInProgress.pendingProps.children), - markRef(current$$1, workInProgress), + markRef(current, workInProgress), reconcileChildren( - current$$1, + current, workInProgress, updateExpirationTime, renderExpirationTime @@ -7147,13 +6929,10 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { workInProgress ); case 6: - return ( - null === current$$1 && tryToClaimNextHydratableInstance(workInProgress), - null - ); + return null; case 13: return updateSuspenseComponent( - current$$1, + current, workInProgress, renderExpirationTime ); @@ -7164,7 +6943,7 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { workInProgress.stateNode.containerInfo ), (updateExpirationTime = workInProgress.pendingProps), - null === current$$1 + null === current ? (workInProgress.child = reconcileChildFibers( workInProgress, null, @@ -7172,7 +6951,7 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { renderExpirationTime )) : reconcileChildren( - current$$1, + current, workInProgress, updateExpirationTime, renderExpirationTime @@ -7182,23 +6961,23 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { case 11: return ( (updateExpirationTime = workInProgress.type), - (renderState = workInProgress.pendingProps), - (renderState = + (context = workInProgress.pendingProps), + (context = workInProgress.elementType === updateExpirationTime - ? renderState - : resolveDefaultProps(updateExpirationTime, renderState)), + ? context + : resolveDefaultProps(updateExpirationTime, context)), updateForwardRef( - current$$1, + current, workInProgress, updateExpirationTime, - renderState, + context, renderExpirationTime ) ); case 7: return ( reconcileChildren( - current$$1, + current, workInProgress, workInProgress.pendingProps, renderExpirationTime @@ -7208,7 +6987,7 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { case 8: return ( reconcileChildren( - current$$1, + current, workInProgress, workInProgress.pendingProps.children, renderExpirationTime @@ -7218,7 +6997,7 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { case 12: return ( reconcileChildren( - current$$1, + current, workInProgress, workInProgress.pendingProps.children, renderExpirationTime @@ -7228,27 +7007,32 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { case 10: a: { updateExpirationTime = workInProgress.type._context; - renderState = workInProgress.pendingProps; + context = workInProgress.pendingProps; getDerivedStateFromProps = workInProgress.memoizedProps; - 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) { + 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) + ) { if ( - getDerivedStateFromProps.children === renderState.children && + getDerivedStateFromProps.children === context.children && !didPerformWorkStackCursor.current ) { workInProgress = bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ); @@ -7256,14 +7040,15 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { } } else for ( - oldValue = workInProgress.child, - null !== oldValue && (oldValue.return = workInProgress); - null !== oldValue; + context$jscomp$0 = workInProgress.child, + null !== context$jscomp$0 && + (context$jscomp$0.return = workInProgress); + null !== context$jscomp$0; ) { - var list = oldValue.dependencies; + var list = context$jscomp$0.dependencies; if (null !== list) { - getDerivedStateFromProps = oldValue.child; + getDerivedStateFromProps = context$jscomp$0.child; for ( var dependency = list.firstContext; null !== dependency; @@ -7273,18 +7058,18 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { dependency.context === updateExpirationTime && 0 !== (dependency.observedBits & hasContext) ) { - 1 === oldValue.tag && + 1 === context$jscomp$0.tag && ((dependency = createUpdate(renderExpirationTime, null)), (dependency.tag = 2), - enqueueUpdate(oldValue, dependency)); - oldValue.expirationTime < renderExpirationTime && - (oldValue.expirationTime = renderExpirationTime); - dependency = oldValue.alternate; + enqueueUpdate(context$jscomp$0, dependency)); + context$jscomp$0.expirationTime < renderExpirationTime && + (context$jscomp$0.expirationTime = renderExpirationTime); + dependency = context$jscomp$0.alternate; null !== dependency && dependency.expirationTime < renderExpirationTime && (dependency.expirationTime = renderExpirationTime); scheduleWorkOnParentPath( - oldValue.return, + context$jscomp$0.return, renderExpirationTime ); list.expirationTime < renderExpirationTime && @@ -7295,16 +7080,16 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { } } else getDerivedStateFromProps = - 10 === oldValue.tag - ? oldValue.type === workInProgress.type + 10 === context$jscomp$0.tag + ? context$jscomp$0.type === workInProgress.type ? null - : oldValue.child - : oldValue.child; + : context$jscomp$0.child + : context$jscomp$0.child; if (null !== getDerivedStateFromProps) - getDerivedStateFromProps.return = oldValue; + getDerivedStateFromProps.return = context$jscomp$0; else for ( - getDerivedStateFromProps = oldValue; + getDerivedStateFromProps = context$jscomp$0; null !== getDerivedStateFromProps; ) { @@ -7312,21 +7097,20 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { getDerivedStateFromProps = null; break; } - oldValue = getDerivedStateFromProps.sibling; - if (null !== oldValue) { - oldValue.return = getDerivedStateFromProps.return; - getDerivedStateFromProps = oldValue; + context$jscomp$0 = getDerivedStateFromProps.sibling; + if (null !== context$jscomp$0) { + context$jscomp$0.return = getDerivedStateFromProps.return; + getDerivedStateFromProps = context$jscomp$0; break; } getDerivedStateFromProps = getDerivedStateFromProps.return; } - oldValue = getDerivedStateFromProps; + context$jscomp$0 = getDerivedStateFromProps; } - } reconcileChildren( - current$$1, + current, workInProgress, - renderState.children, + context.children, renderExpirationTime ); workInProgress = workInProgress.child; @@ -7334,18 +7118,15 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { return workInProgress; case 9: return ( - (renderState = workInProgress.type), + (context = workInProgress.type), (hasContext = workInProgress.pendingProps), (updateExpirationTime = hasContext.children), prepareToReadContext(workInProgress, renderExpirationTime), - (renderState = readContext( - renderState, - hasContext.unstable_observedBits - )), - (updateExpirationTime = updateExpirationTime(renderState)), + (context = readContext(context, hasContext.unstable_observedBits)), + (updateExpirationTime = updateExpirationTime(context)), (workInProgress.effectTag |= 1), reconcileChildren( - current$$1, + current, workInProgress, updateExpirationTime, renderExpirationTime @@ -7354,16 +7135,16 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { ); case 14: return ( - (renderState = workInProgress.type), + (context = workInProgress.type), (hasContext = resolveDefaultProps( - renderState, + context, workInProgress.pendingProps )), - (hasContext = resolveDefaultProps(renderState.type, hasContext)), + (hasContext = resolveDefaultProps(context.type, hasContext)), updateMemoComponent( - current$$1, + current, workInProgress, - renderState, + context, hasContext, updateExpirationTime, renderExpirationTime @@ -7371,7 +7152,7 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { ); case 15: return updateSimpleMemoComponent( - current$$1, + current, workInProgress, workInProgress.type, workInProgress.pendingProps, @@ -7381,30 +7162,25 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { case 17: return ( (updateExpirationTime = workInProgress.type), - (renderState = workInProgress.pendingProps), - (renderState = + (context = workInProgress.pendingProps), + (context = workInProgress.elementType === updateExpirationTime - ? renderState - : resolveDefaultProps(updateExpirationTime, renderState)), - null !== current$$1 && - ((current$$1.alternate = null), + ? context + : resolveDefaultProps(updateExpirationTime, context)), + null !== current && + ((current.alternate = null), (workInProgress.alternate = null), (workInProgress.effectTag |= 2)), (workInProgress.tag = 1), isContextProvider(updateExpirationTime) - ? ((current$$1 = !0), pushContextProvider(workInProgress)) - : (current$$1 = !1), + ? ((current = !0), pushContextProvider(workInProgress)) + : (current = !1), prepareToReadContext(workInProgress, renderExpirationTime), - constructClassInstance( - workInProgress, - updateExpirationTime, - renderState, - renderExpirationTime - ), + constructClassInstance(workInProgress, updateExpirationTime, context), mountClassInstance( workInProgress, updateExpirationTime, - renderState, + context, renderExpirationTime ), finishClassComponent( @@ -7412,13 +7188,13 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { workInProgress, updateExpirationTime, !0, - current$$1, + current, renderExpirationTime ) ); case 19: return updateSuspenseListComponent( - current$$1, + current, workInProgress, renderExpirationTime ); @@ -7469,9 +7245,6 @@ 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); @@ -7489,7 +7262,7 @@ function resolveLazyComponentTag(Component) { function createWorkInProgress(current, pendingProps) { var workInProgress = current.alternate; null === workInProgress - ? ((workInProgress = createFiber( + ? ((workInProgress = new FiberNode( current.tag, pendingProps, current.key, @@ -7505,6 +7278,10 @@ 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; @@ -7556,7 +7333,7 @@ function createFiberFromTypeAndProps( break; case REACT_PROFILER_TYPE: return ( - (type = createFiber(12, pendingProps, key, mode | 8)), + (type = new FiberNode(12, pendingProps, key, mode | 8)), (type.elementType = REACT_PROFILER_TYPE), (type.type = REACT_PROFILER_TYPE), (type.expirationTime = expirationTime), @@ -7564,7 +7341,7 @@ function createFiberFromTypeAndProps( ); case REACT_SUSPENSE_TYPE: return ( - (type = createFiber(13, pendingProps, key, mode)), + (type = new FiberNode(13, pendingProps, key, mode)), (type.type = REACT_SUSPENSE_TYPE), (type.elementType = REACT_SUSPENSE_TYPE), (type.expirationTime = expirationTime), @@ -7572,7 +7349,7 @@ function createFiberFromTypeAndProps( ); case REACT_SUSPENSE_LIST_TYPE: return ( - (type = createFiber(19, pendingProps, key, mode)), + (type = new FiberNode(19, pendingProps, key, mode)), (type.elementType = REACT_SUSPENSE_LIST_TYPE), (type.expirationTime = expirationTime), type @@ -7596,6 +7373,9 @@ 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: " + @@ -7603,24 +7383,24 @@ function createFiberFromTypeAndProps( "." ); } - key = createFiber(fiberTag, pendingProps, key, mode); + key = new FiberNode(fiberTag, pendingProps, key, mode); key.elementType = type; key.type = owner; key.expirationTime = expirationTime; return key; } function createFiberFromFragment(elements, mode, expirationTime, key) { - elements = createFiber(7, elements, key, mode); + elements = new FiberNode(7, elements, key, mode); elements.expirationTime = expirationTime; return elements; } function createFiberFromText(content, mode, expirationTime) { - content = createFiber(6, content, null, mode); + content = new FiberNode(6, content, null, mode); content.expirationTime = expirationTime; return content; } function createFiberFromPortal(portal, mode, expirationTime) { - mode = createFiber( + mode = new FiberNode( 4, null !== portal.children ? portal.children : [], portal.key, @@ -7679,11 +7459,6 @@ 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) { @@ -7698,14 +7473,10 @@ function findHostInstance(component) { return null === component ? null : component.stateNode; } function updateContainer(element, container, parentComponent, callback) { - var current$$1 = container.current, + var current = container.current, currentTime = requestCurrentTimeForUpdate(), suspenseConfig = ReactCurrentBatchConfig.suspense; - currentTime = computeExpirationForFiber( - currentTime, - current$$1, - suspenseConfig - ); + currentTime = computeExpirationForFiber(currentTime, current, suspenseConfig); a: if (parentComponent) { parentComponent = parentComponent._reactInternalFiber; b: { @@ -7756,8 +7527,8 @@ function updateContainer(element, container, parentComponent, callback) { container.payload = { element: element }; callback = void 0 === callback ? null : callback; null !== callback && (container.callback = callback); - enqueueUpdate(current$$1, container); - scheduleUpdateOnFiber(current$$1, currentTime); + enqueueUpdate(current, container); + scheduleWork(current, currentTime); return currentTime; } function createPortal(children, containerInfo, implementation) { @@ -7771,11 +7542,6 @@ 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; @@ -7786,8 +7552,15 @@ function findNodeHandle(componentOrHandle) { return null == componentOrHandle ? componentOrHandle : componentOrHandle.canonical - ? componentOrHandle.canonical._nativeTag - : componentOrHandle._nativeTag; + ? componentOrHandle.canonical._nativeTag + : componentOrHandle._nativeTag; +} +function unmountComponentAtNode(containerTag) { + var root = roots.get(containerTag); + root && + updateContainer(null, root, null, function() { + roots.delete(containerTag); + }); } batchedUpdatesImpl = function(fn, a) { var prevExecutionContext = executionContext; @@ -7799,299 +7572,117 @@ batchedUpdatesImpl = function(fn, a) { executionContext === NoContext && flushSyncCallbackQueue(); } }; -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; - }, - 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) - : ""; - } - } - }; +var roots = new Map(); (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 - }) - ); + 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; + }, + 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.11.0", - rendererPackageName: "react-native-renderer" + 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) + } }); -var ReactNativeRenderer$2 = { default: ReactNativeRenderer }, - ReactNativeRenderer$3 = - (ReactNativeRenderer$2 && ReactNativeRenderer) || ReactNativeRenderer$2; -module.exports = ReactNativeRenderer$3.default || ReactNativeRenderer$3; +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; diff --git a/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js b/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js index 4cc776abd951fd..31b089c41bfee8 100644 --- a/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js +++ b/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js @@ -5,6 +5,7 @@ * LICENSE file in the root directory of this source tree. * * @noflow + * @nolint * @providesModule ReactNativeRenderer-prod * @preventMunge * @generated @@ -15,85 +16,16 @@ require("react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore"); var ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/ReactNativePrivateInterface"), React = require("react"), Scheduler = require("scheduler"); -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 getParent(inst) { + do inst = inst.return; + while (inst && 5 !== inst.tag); + return inst ? inst : null; } -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; +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); } -var plugins = [], - eventNameDispatchConfigs = {}, - registrationNameModules = {}; function invokeGuardedCallbackImpl(name, func, context, a, b, c, d, e, f) { var funcArgs = Array.prototype.slice.call(arguments, 3); try { @@ -164,74 +96,6 @@ 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; @@ -249,6 +113,7 @@ function getListener(inst, registrationName) { case "onMouseMoveCapture": case "onMouseUp": case "onMouseUpCapture": + case "onMouseEnter": (props = !props.disabled) || ((inst = inst.type), (props = !( @@ -273,15 +138,21 @@ function getListener(inst, registrationName) { ); return listener; } -function getParent(inst) { - do inst = inst.return; - while (inst && 5 !== inst.tag); - return inst ? inst : null; +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 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 forEachAccumulated(arr, cb, scope) { + Array.isArray(arr) ? arr.forEach(cb, scope) : arr && cb.call(scope, arr); } function accumulateDirectionalDispatches(inst, phase, event) { if ( @@ -349,8 +220,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) @@ -503,53 +374,27 @@ 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))) - : console.warn( - "Cannot record touch move without a touch start.\nTouch Move: %s\n", - "Touch Bank: %s", - printTouch(touch), - printTouchBank() - ); + 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))); } 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))) - : 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; + 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))); } var ResponderTouchHistoryStore = { recordTouchTrack: function(topLevelType, nativeEvent) { @@ -589,10 +434,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; @@ -682,13 +527,7 @@ var eventTypes = { "topTouchCancel" === topLevelType ) if (0 <= trackedTouchCount) --trackedTouchCount; - else - return ( - console.warn( - "Ended a touch event which was not counted in `trackedTouchCount`." - ), - null - ); + else return null; ResponderTouchHistoryStore.recordTouchTrack(topLevelType, nativeEvent); if ( targetInst && @@ -700,10 +539,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; @@ -857,10 +696,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, @@ -923,8 +762,8 @@ var eventTypes = { (topLevelType = shouldSetEventType ? eventTypes.responderTerminate : topLevelType - ? eventTypes.responderRelease - : null) + ? eventTypes.responderRelease + : null) ) (nativeEvent = ResponderSyntheticEvent.getPooled( topLevelType, @@ -948,65 +787,168 @@ 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; -injection.injectEventPluginOrder([ +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([ "ResponderEventPlugin", "ReactNativeBridgeEventPlugin" ]); -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, +recomputePluginOrdering(); +var injectedNamesToPlugins$jscomp$inline_94 = { + ResponderEventPlugin: ResponderEventPlugin, + ReactNativeBridgeEventPlugin: { + eventTypes: {}, + extractEvents: function( + topLevelType, targetInst, nativeEvent, nativeEventTarget - ); - if (bubbleDispatchConfig) - forEachAccumulated(topLevelType, accumulateTwoPhaseDispatchesSingle); - else if (directDispatchConfig) - forEachAccumulated(topLevelType, accumulateDirectDispatchesSingle); - else return null; - return topLevelType; + ) { + 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 + ) { + if (namesToPlugins[pluginName$jscomp$inline_96]) + throw Error( + "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + + pluginName$jscomp$inline_96 + + "`." + ); + namesToPlugins[ + pluginName$jscomp$inline_96 + ] = pluginModule$jscomp$inline_97; + isOrderingDirty$jscomp$inline_95 = !0; } } -}); +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); @@ -1014,21 +956,27 @@ function batchedUpdates(fn, bookkeeping) { 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)) + 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++ ) - for (bookkeeping = 0; bookkeeping < fn.length; bookkeeping++) - restoreStateOfTarget(fn[bookkeeping]); + 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 EMPTY_NATIVE_EVENT = {}; @@ -1036,7 +984,7 @@ function _receiveRootNodeIDEvent(rootNodeID, topLevelType, nativeEventParam) { var nativeEvent = nativeEventParam || EMPTY_NATIVE_EVENT, inst = getInstanceFromTag(rootNodeID), target = null; - target = nativeEvent.target; + null != inst && (target = inst.stateNode); batchedUpdates(function() { var events = target; for (var events$jscomp$0 = null, i = 0; i < plugins.length; i++) { @@ -1111,10 +1059,11 @@ getFiberCurrentPropsFromNode = function(stateNode) { }; getInstanceFromNode = getInstanceFromTag; getNodeFromInstance = function(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; + 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; }; ResponderEventPlugin.injection.injectGlobalResponderHandler({ onChange: function(from, to, blockNativeResponder) { @@ -1149,11 +1098,9 @@ 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; -hasSymbol && Symbol.for("react.fundamental"); -hasSymbol && Symbol.for("react.responder"); -hasSymbol && Symbol.for("react.scope"); -var MAYBE_ITERATOR_SYMBOL = "function" === typeof Symbol && Symbol.iterator; + 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; function getIteratorFn(maybeIterable) { if (null === maybeIterable || "object" !== typeof maybeIterable) return null; maybeIterable = @@ -1163,9 +1110,10 @@ function getIteratorFn(maybeIterable) { } function initializeLazyComponentType(lazyComponent) { if (-1 === lazyComponent._status) { - lazyComponent._status = 0; - var ctor = lazyComponent._ctor; + var ctor = lazyComponent._result; + ctor || (ctor = lazyComponent._ctor); ctor = ctor(); + lazyComponent._status = 0; lazyComponent._result = ctor; ctor.then( function(moduleObject) { @@ -1202,9 +1150,9 @@ function getComponentName(type) { if ("object" === typeof type) switch (type.$$typeof) { case REACT_CONTEXT_TYPE: - return "Context.Consumer"; + return (type.displayName || "Context") + ".Consumer"; case REACT_PROVIDER_TYPE: - return "Context.Provider"; + return (type._context.displayName || "Context") + ".Provider"; case REACT_FORWARD_REF_TYPE: var innerType = type.render; innerType = innerType.displayName || innerType.name || ""; @@ -1214,6 +1162,8 @@ 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); @@ -1394,8 +1344,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)) { @@ -1573,10 +1523,10 @@ var ReactNativeFiberHostComponent = (function() { } var _proto = ReactNativeFiberHostComponent.prototype; _proto.blur = function() { - ReactNativePrivateInterface.TextInputState.blurTextInput(this._nativeTag); + ReactNativePrivateInterface.TextInputState.blurTextInput(this); }; _proto.focus = function() { - ReactNativePrivateInterface.TextInputState.focusTextInput(this._nativeTag); + ReactNativePrivateInterface.TextInputState.focusTextInput(this); }; _proto.measure = function(callback) { ReactNativePrivateInterface.UIManager.measure( @@ -1620,7 +1570,7 @@ var ReactNativeFiberHostComponent = (function() { }; return ReactNativeFiberHostComponent; })(); -function shim$1() { +function shim() { throw Error( "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." ); @@ -1658,45 +1608,7 @@ function finalizeInitialChildren(parentInstance) { } var scheduleTimeout = setTimeout, cancelTimeout = clearTimeout, - 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 = [], + valueStack = [], index = -1; function pop(cursor) { 0 > index || @@ -1733,21 +1645,17 @@ function isContextProvider(type) { type = type.childContextTypes; return null !== type && void 0 !== type; } -function popContext(fiber) { - pop(didPerformWorkStackCursor, fiber); - pop(contextStackCursor, fiber); -} -function popTopLevelContextObject(fiber) { - pop(didPerformWorkStackCursor, fiber); - pop(contextStackCursor, fiber); +function popContext() { + pop(didPerformWorkStackCursor); + pop(contextStackCursor); } function pushTopLevelContextObject(fiber, context, didChange) { if (contextStackCursor.current !== emptyContextObject) throw Error( "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." ); - push(contextStackCursor, context, fiber); - push(didPerformWorkStackCursor, didChange, fiber); + push(contextStackCursor, context); + push(didPerformWorkStackCursor, didChange); } function processChildContext(fiber, type, parentContext) { var instance = fiber.stateNode; @@ -1765,17 +1673,13 @@ function processChildContext(fiber, type, parentContext) { return Object.assign({}, parentContext, {}, instance); } function pushContextProvider(workInProgress) { - var instance = workInProgress.stateNode; - instance = - (instance && instance.__reactInternalMemoizedMergedChildContext) || + workInProgress = + ((workInProgress = workInProgress.stateNode) && + workInProgress.__reactInternalMemoizedMergedChildContext) || emptyContextObject; previousContext = contextStackCursor.current; - push(contextStackCursor, instance, workInProgress); - push( - didPerformWorkStackCursor, - didPerformWorkStackCursor.current, - workInProgress - ); + push(contextStackCursor, workInProgress); + push(didPerformWorkStackCursor, didPerformWorkStackCursor.current); return !0; } function invalidateContextProvider(workInProgress, type, didChange) { @@ -1785,18 +1689,21 @@ 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 - ? ((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); + ? ((workInProgress = processChildContext( + workInProgress, + type, + previousContext + )), + (instance.__reactInternalMemoizedMergedChildContext = workInProgress), + pop(didPerformWorkStackCursor), + pop(contextStackCursor), + push(contextStackCursor, workInProgress)) + : pop(didPerformWorkStackCursor); + push(didPerformWorkStackCursor, didChange); } 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 = @@ -1807,6 +1714,7 @@ 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, @@ -1906,10 +1814,10 @@ function flushSyncCallbackQueueImpl() { function is(x, y) { return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y); } -var is$1 = "function" === typeof Object.is ? Object.is : is, +var objectIs = "function" === typeof Object.is ? Object.is : is, hasOwnProperty = Object.prototype.hasOwnProperty; function shallowEqual(objA, objB) { - if (is$1(objA, objB)) return !0; + if (objectIs(objA, objB)) return !0; if ( "object" !== typeof objA || null === objA || @@ -1923,11 +1831,48 @@ function shallowEqual(objA, objB) { for (keysB = 0; keysB < keysA.length; keysB++) if ( !hasOwnProperty.call(objB, keysA[keysB]) || - !is$1(objA[keysA[keysB]], objB[keysA[keysB]]) + !objectIs(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); @@ -1945,14 +1890,9 @@ 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, providerFiber); + pop(valueCursor); providerFiber.type._context._currentValue = currentValue; } function scheduleWorkOnParentPath(parent, renderExpirationTime) { @@ -2007,237 +1947,195 @@ function readContext(context, observedBits) { return context._currentValue; } var hasForceUpdate = !1; -function createUpdateQueue(baseState) { - return { - baseState: baseState, - firstUpdate: null, - lastUpdate: null, - firstCapturedUpdate: null, - lastCapturedUpdate: null, - firstEffect: null, - lastEffect: null, - firstCapturedEffect: null, - lastCapturedEffect: null +function initializeUpdateQueue(fiber) { + fiber.updateQueue = { + baseState: fiber.memoizedState, + baseQueue: null, + shared: { pending: null }, + effects: null }; } -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 cloneUpdateQueue(current, workInProgress) { + current = current.updateQueue; + workInProgress.updateQueue === current && + (workInProgress.updateQueue = { + baseState: current.baseState, + baseQueue: current.baseQueue, + shared: current.shared, + effects: current.effects + }); } function createUpdate(expirationTime, suspenseConfig) { - return { + expirationTime = { expirationTime: expirationTime, suspenseConfig: suspenseConfig, tag: 0, payload: null, callback: null, - next: null, - nextEffect: null + next: null }; -} -function appendUpdateToQueue(queue, update) { - null === queue.lastUpdate - ? (queue.firstUpdate = queue.lastUpdate = update) - : ((queue.lastUpdate.next = update), (queue.lastUpdate = update)); + return (expirationTime.next = expirationTime); } function enqueueUpdate(fiber, 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)); + 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; + } } 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 && - 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; + 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)); } function processUpdateQueue( - workInProgress, - queue, + workInProgress$jscomp$0, props, instance, renderExpirationTime ) { + var queue = workInProgress$jscomp$0.updateQueue; hasForceUpdate = !1; - queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue); - for ( - var newBaseState = queue.baseState, - newFirstUpdate = null, - newExpirationTime = 0, - 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; + 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)); } - 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; + if (null !== baseQueue) { + baseFirst = baseQueue.next; + var newState = queue.baseState, + 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; } - 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) { - 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); + 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); + } } - effect = effect.nextEffect; - } } var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig, emptyRefsObject = new React.Component().refs; @@ -2254,10 +2152,8 @@ function applyDerivedStateFromProps( ? ctor : Object.assign({}, ctor, getDerivedStateFromProps); workInProgress.memoizedState = getDerivedStateFromProps; - nextProps = workInProgress.updateQueue; - null !== nextProps && - 0 === workInProgress.expirationTime && - (nextProps.baseState = getDerivedStateFromProps); + 0 === workInProgress.expirationTime && + (workInProgress.updateQueue.baseState = getDerivedStateFromProps); } var classComponentUpdater = { isMounted: function(component) { @@ -2276,7 +2172,7 @@ var classComponentUpdater = { null !== callback && (suspenseConfig.callback = callback); enqueueUpdate(inst, suspenseConfig); - scheduleUpdateOnFiber(inst, currentTime); + scheduleWork(inst, currentTime); }, enqueueReplaceState: function(inst, payload, callback) { inst = inst._reactInternalFiber; @@ -2290,7 +2186,7 @@ var classComponentUpdater = { null !== callback && (suspenseConfig.callback = callback); enqueueUpdate(inst, suspenseConfig); - scheduleUpdateOnFiber(inst, currentTime); + scheduleWork(inst, currentTime); }, enqueueForceUpdate: function(inst, callback) { inst = inst._reactInternalFiber; @@ -2303,7 +2199,7 @@ var classComponentUpdater = { null !== callback && (suspenseConfig.callback = callback); enqueueUpdate(inst, suspenseConfig); - scheduleUpdateOnFiber(inst, currentTime); + scheduleWork(inst, currentTime); } }; function checkShouldComponentUpdate( @@ -2319,8 +2215,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, @@ -2372,6 +2268,7 @@ 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)) @@ -2379,16 +2276,8 @@ function mountClassInstance( ? previousContext : contextStackCursor.current), (instance.context = getMaskedContext(workInProgress, contextType))); - contextType = workInProgress.updateQueue; - null !== contextType && - (processUpdateQueue( - workInProgress, - contextType, - newProps, - instance, - renderExpirationTime - ), - (instance.state = workInProgress.memoizedState)); + processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); + instance.state = workInProgress.memoizedState; contextType = ctor.getDerivedStateFromProps; "function" === typeof contextType && (applyDerivedStateFromProps(workInProgress, ctor, contextType, newProps), @@ -2404,21 +2293,18 @@ function mountClassInstance( instance.UNSAFE_componentWillMount(), ctor !== instance.state && classComponentUpdater.enqueueReplaceState(instance, instance.state, null), - (contextType = workInProgress.updateQueue), - null !== contextType && - (processUpdateQueue( - workInProgress, - contextType, - newProps, - instance, - renderExpirationTime - ), - (instance.state = workInProgress.memoizedState))); + processUpdateQueue( + workInProgress, + newProps, + instance, + renderExpirationTime + ), + (instance.state = workInProgress.memoizedState)); "function" === typeof instance.componentDidMount && (workInProgress.effectTag |= 4); } var isArray = Array.isArray; -function coerceRef(returnFiber, current$$1, element) { +function coerceRef(returnFiber, current, element) { returnFiber = element.ref; if ( null !== returnFiber && @@ -2430,7 +2316,7 @@ function coerceRef(returnFiber, current$$1, element) { if (element) { if (1 !== element.tag) throw Error( - "Function components cannot have refs. Did you mean to use React.forwardRef()?" + "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" ); var inst = element.stateNode; } @@ -2442,19 +2328,19 @@ function coerceRef(returnFiber, current$$1, element) { ); var stringRef = "" + returnFiber; if ( - null !== current$$1 && - null !== current$$1.ref && - "function" === typeof current$$1.ref && - current$$1.ref._stringRef === stringRef + null !== current && + null !== current.ref && + "function" === typeof current.ref && + current.ref._stringRef === stringRef ) - return current$$1.ref; - current$$1 = function(value) { + return current.ref; + current = function(value) { var refs = inst.refs; refs === emptyRefsObject && (refs = inst.refs = {}); null === value ? delete refs[stringRef] : (refs[stringRef] = value); }; - current$$1._stringRef = stringRef; - return current$$1; + current._stringRef = stringRef; + return current; } if ("string" !== typeof returnFiber) throw Error( @@ -2506,8 +2392,8 @@ function ChildReconciler(shouldTrackSideEffects) { (currentFirstChild = currentFirstChild.sibling); return returnFiber; } - function useFiber(fiber, pendingProps, expirationTime) { - fiber = createWorkInProgress(fiber, pendingProps, expirationTime); + function useFiber(fiber, pendingProps) { + fiber = createWorkInProgress(fiber, pendingProps); fiber.index = 0; fiber.sibling = null; return fiber; @@ -2532,31 +2418,26 @@ function ChildReconciler(shouldTrackSideEffects) { (newFiber.effectTag = 2); return newFiber; } - function updateTextNode( - returnFiber, - current$$1, - textContent, - expirationTime - ) { - if (null === current$$1 || 6 !== current$$1.tag) + function updateTextNode(returnFiber, current, textContent, expirationTime) { + if (null === current || 6 !== current.tag) return ( - (current$$1 = createFiberFromText( + (current = createFiberFromText( textContent, returnFiber.mode, expirationTime )), - (current$$1.return = returnFiber), - current$$1 + (current.return = returnFiber), + current ); - current$$1 = useFiber(current$$1, textContent, expirationTime); - current$$1.return = returnFiber; - return current$$1; + current = useFiber(current, textContent); + current.return = returnFiber; + return current; } - function updateElement(returnFiber, current$$1, element, expirationTime) { - if (null !== current$$1 && current$$1.elementType === element.type) + function updateElement(returnFiber, current, element, expirationTime) { + if (null !== current && current.elementType === element.type) return ( - (expirationTime = useFiber(current$$1, element.props, expirationTime)), - (expirationTime.ref = coerceRef(returnFiber, current$$1, element)), + (expirationTime = useFiber(current, element.props)), + (expirationTime.ref = coerceRef(returnFiber, current, element)), (expirationTime.return = returnFiber), expirationTime ); @@ -2568,51 +2449,45 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime ); - expirationTime.ref = coerceRef(returnFiber, current$$1, element); + expirationTime.ref = coerceRef(returnFiber, current, element); expirationTime.return = returnFiber; return expirationTime; } - function updatePortal(returnFiber, current$$1, portal, expirationTime) { + function updatePortal(returnFiber, current, portal, expirationTime) { if ( - null === current$$1 || - 4 !== current$$1.tag || - current$$1.stateNode.containerInfo !== portal.containerInfo || - current$$1.stateNode.implementation !== portal.implementation + null === current || + 4 !== current.tag || + current.stateNode.containerInfo !== portal.containerInfo || + current.stateNode.implementation !== portal.implementation ) return ( - (current$$1 = createFiberFromPortal( + (current = createFiberFromPortal( portal, returnFiber.mode, expirationTime )), - (current$$1.return = returnFiber), - current$$1 + (current.return = returnFiber), + current ); - current$$1 = useFiber(current$$1, portal.children || [], expirationTime); - current$$1.return = returnFiber; - return current$$1; + current = useFiber(current, portal.children || []); + current.return = returnFiber; + return current; } - function updateFragment( - returnFiber, - current$$1, - fragment, - expirationTime, - key - ) { - if (null === current$$1 || 7 !== current$$1.tag) + function updateFragment(returnFiber, current, fragment, expirationTime, key) { + if (null === current || 7 !== current.tag) return ( - (current$$1 = createFiberFromFragment( + (current = createFiberFromFragment( fragment, returnFiber.mode, expirationTime, key )), - (current$$1.return = returnFiber), - current$$1 + (current.return = returnFiber), + current ); - current$$1 = useFiber(current$$1, fragment, expirationTime); - current$$1.return = returnFiber; - return current$$1; + current = useFiber(current, fragment); + current.return = returnFiber; + return current; } function createChild(returnFiber, newChild, expirationTime) { if ("string" === typeof newChild || "number" === typeof newChild) @@ -2975,39 +2850,48 @@ function ChildReconciler(shouldTrackSideEffects) { null !== isUnkeyedTopLevelFragment; ) { - 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; + 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; + } } - else deleteChild(returnFiber, isUnkeyedTopLevelFragment); + deleteRemainingChildren(returnFiber, isUnkeyedTopLevelFragment); + break; + } else deleteChild(returnFiber, isUnkeyedTopLevelFragment); isUnkeyedTopLevelFragment = isUnkeyedTopLevelFragment.sibling; } newChild.type === REACT_FRAGMENT_TYPE @@ -3057,8 +2941,7 @@ function ChildReconciler(shouldTrackSideEffects) { ); currentFirstChild = useFiber( currentFirstChild, - newChild.children || [], - expirationTime + newChild.children || [] ); currentFirstChild.return = returnFiber; returnFiber = currentFirstChild; @@ -3085,11 +2968,7 @@ function ChildReconciler(shouldTrackSideEffects) { (newChild = "" + newChild), null !== currentFirstChild && 6 === currentFirstChild.tag ? (deleteRemainingChildren(returnFiber, currentFirstChild.sibling), - (currentFirstChild = useFiber( - currentFirstChild, - newChild, - expirationTime - )), + (currentFirstChild = useFiber(currentFirstChild, newChild)), (currentFirstChild.return = returnFiber), (returnFiber = currentFirstChild)) : (deleteRemainingChildren(returnFiber, currentFirstChild), @@ -3144,16 +3023,16 @@ function requiredContext(c) { return c; } function pushHostContainer(fiber, nextRootInstance) { - push(rootInstanceStackCursor, nextRootInstance, fiber); - push(contextFiberStackCursor, fiber, fiber); - push(contextStackCursor$1, NO_CONTEXT, fiber); - pop(contextStackCursor$1, fiber); - push(contextStackCursor$1, { isInAParentText: !1 }, fiber); + push(rootInstanceStackCursor, nextRootInstance); + push(contextFiberStackCursor, fiber); + push(contextStackCursor$1, NO_CONTEXT); + pop(contextStackCursor$1); + push(contextStackCursor$1, { isInAParentText: !1 }); } -function popHostContainer(fiber) { - pop(contextStackCursor$1, fiber); - pop(contextFiberStackCursor, fiber); - pop(rootInstanceStackCursor, fiber); +function popHostContainer() { + pop(contextStackCursor$1); + pop(contextFiberStackCursor); + pop(rootInstanceStackCursor); } function pushHostContext(fiber) { requiredContext(rootInstanceStackCursor.current); @@ -3170,23 +3049,19 @@ function pushHostContext(fiber) { ? { isInAParentText: nextContext } : context; context !== nextContext && - (push(contextFiberStackCursor, fiber, fiber), - push(contextStackCursor$1, nextContext, fiber)); + (push(contextFiberStackCursor, fiber), + push(contextStackCursor$1, nextContext)); } function popHostContext(fiber) { contextFiberStackCursor.current === fiber && - (pop(contextStackCursor$1, fiber), pop(contextFiberStackCursor, fiber)); + (pop(contextStackCursor$1), pop(contextFiberStackCursor)); } var suspenseStackCursor = { current: 0 }; function findFirstSuspended(row) { for (var node = row; null !== node; ) { if (13 === node.tag) { var state = node.memoizedState; - if ( - null !== state && - ((state = state.dehydrated), - null === state || shim$1(state) || shim$1(state)) - ) + if (null !== state && (null === state.dehydrated || shim() || shim())) return node; } else if (19 === node.tag && void 0 !== node.memoizedProps.revealOrder) { if (0 !== (node.effectTag & 64)) return node; @@ -3205,24 +3080,16 @@ function findFirstSuspended(row) { } return null; } -function createResponderListener(responder, props) { +function createDeprecatedResponderListener(responder, props) { return { responder: responder, props: props }; } -var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, +var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig, - renderExpirationTime$1 = 0, + renderExpirationTime = 0, currentlyRenderingFiber$1 = null, currentHook = null, - nextCurrentHook = null, - firstWorkInProgressHook = null, workInProgressHook = null, - nextWorkInProgressHook = null, - remainingExpirationTime = 0, - componentUpdateQueue = null, - sideEffectTag = 0, - didScheduleRenderPhaseUpdate = !1, - renderPhaseUpdates = null, - numberOfReRenders = 0; + didScheduleRenderPhaseUpdate = !1; 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." @@ -3231,7 +3098,7 @@ function throwInvalidHookError() { function areHookInputsEqual(nextDeps, prevDeps) { if (null === prevDeps) return !1; for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) - if (!is$1(nextDeps[i], prevDeps[i])) return !1; + if (!objectIs(nextDeps[i], prevDeps[i])) return !1; return !0; } function renderWithHooks( @@ -3239,92 +3106,85 @@ function renderWithHooks( workInProgress, Component, props, - refOrContext, + secondArg, nextRenderExpirationTime ) { - renderExpirationTime$1 = nextRenderExpirationTime; + renderExpirationTime = nextRenderExpirationTime; currentlyRenderingFiber$1 = workInProgress; - 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; + 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); } - 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( + ReactCurrentDispatcher.current = ContextOnlyDispatcher; + workInProgress = null !== currentHook && null !== currentHook.next; + renderExpirationTime = 0; + workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; + didScheduleRenderPhaseUpdate = !1; + if (workInProgress) + throw Error( "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." ); - 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; + return current; } function mountWorkInProgressHook() { var hook = { memoizedState: null, baseState: null, + baseQueue: null, queue: null, - baseUpdate: null, next: null }; null === workInProgressHook - ? (firstWorkInProgressHook = workInProgressHook = hook) + ? (currentlyRenderingFiber$1.memoizedState = 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), - (nextWorkInProgressHook = workInProgressHook.next), - (currentHook = nextCurrentHook), - (nextCurrentHook = null !== currentHook ? currentHook.next : null); + (currentHook = nextCurrentHook); else { if (null === nextCurrentHook) throw Error("Rendered more hooks than during the previous render."); currentHook = nextCurrentHook; - var newHook = { + nextCurrentHook = { memoizedState: currentHook.memoizedState, baseState: currentHook.baseState, + baseQueue: currentHook.baseQueue, queue: currentHook.queue, - baseUpdate: currentHook.baseUpdate, next: null }; - workInProgressHook = - null === workInProgressHook - ? (firstWorkInProgressHook = newHook) - : (workInProgressHook.next = newHook); - nextCurrentHook = currentHook.next; + null === workInProgressHook + ? (currentlyRenderingFiber$1.memoizedState = workInProgressHook = nextCurrentHook) + : (workInProgressHook = workInProgressHook.next = nextCurrentHook); } return workInProgressHook; } @@ -3339,74 +3199,100 @@ function updateReducer(reducer) { "Should have a queue. This is likely a bug in React. Please file an issue." ); queue.lastRenderedReducer = reducer; - 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]; - } + 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; } - return [hook.memoizedState, _dispatch]; + current.baseQueue = baseQueue = pendingQueue; + queue.pending = null; } - _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; + if (null !== baseQueue) { + baseQueue = baseQueue.next; + current = current.baseState; + var newBaseQueueLast = (baseFirst = pendingQueue = null), + update = baseQueue; do { - var updateExpirationTime = _update.expirationTime; - updateExpirationTime < renderExpirationTime$1 - ? (didSkip || - ((didSkip = !0), - (newBaseUpdate = baseUpdate), - (firstRenderPhaseUpdate = newState)), - updateExpirationTime > remainingExpirationTime && - ((remainingExpirationTime = updateExpirationTime), - markUnprocessedUpdateTime(remainingExpirationTime))) - : (markRenderEventTimeAndConfig( + 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( updateExpirationTime, - _update.suspenseConfig + update.suspenseConfig ), - (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); + (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); hook.memoizedState = newState; - hook.baseUpdate = newBaseUpdate; - hook.baseState = firstRenderPhaseUpdate; + null === hook.baseQueue && (hook.baseState = newState); queue.lastRenderedState = newState; } - return [hook.memoizedState, queue.dispatch]; + return [newState, dispatch]; } function mountState(initialState) { var hook = mountWorkInProgressHook(); "function" === typeof initialState && (initialState = initialState()); hook.memoizedState = hook.baseState = initialState; initialState = hook.queue = { - last: null, + pending: null, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState @@ -3418,28 +3304,30 @@ 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 }; - 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))); + 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))); return tag; } +function updateRef() { + return updateWorkInProgressHook().memoizedState; +} function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var hook = mountWorkInProgressHook(); - sideEffectTag |= fiberEffectTag; + currentlyRenderingFiber$1.effectTag |= fiberEffectTag; hook.memoizedState = pushEffect( - hookEffectTag, + 1 | hookEffectTag, create, void 0, void 0 === deps ? null : deps @@ -3453,18 +3341,21 @@ function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var prevEffect = currentHook.memoizedState; destroy = prevEffect.destroy; if (null !== deps && areHookInputsEqual(deps, prevEffect.deps)) { - pushEffect(0, create, destroy, deps); + pushEffect(hookEffectTag, create, destroy, deps); return; } } - sideEffectTag |= fiberEffectTag; - hook.memoizedState = pushEffect(hookEffectTag, create, destroy, deps); + currentlyRenderingFiber$1.effectTag |= fiberEffectTag; + hook.memoizedState = pushEffect(1 | hookEffectTag, create, destroy, deps); } function mountEffect(create, deps) { - return mountEffectImpl(516, 192, create, deps); + return mountEffectImpl(516, 4, create, deps); } function updateEffect(create, deps) { - return updateEffectImpl(516, 192, create, deps); + return updateEffectImpl(516, 4, create, deps); +} +function updateLayoutEffect(create, deps) { + return updateEffectImpl(4, 2, create, deps); } function imperativeHandleEffect(create, ref) { if ("function" === typeof ref) @@ -3484,6 +3375,15 @@ 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 = [ @@ -3505,72 +3405,79 @@ 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) { - if (!(25 > numberOfReRenders)) - throw Error( - "Too many re-renders. React limits the number of renders to prevent an infinite loop." - ); - var alternate = fiber.alternate; + 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 ( fiber === currentlyRenderingFiber$1 || - (null !== alternate && alternate === currentlyRenderingFiber$1) + (null !== pending && pending === currentlyRenderingFiber$1) ) - 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; - } + (didScheduleRenderPhaseUpdate = !0), + (suspenseConfig.expirationTime = renderExpirationTime), + (currentlyRenderingFiber$1.expirationTime = renderExpirationTime); 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 === alternate || 0 === alternate.expirationTime) && - ((alternate = queue.lastRenderedReducer), null !== alternate) + (null === pending || 0 === pending.expirationTime) && + ((pending = queue.lastRenderedReducer), null !== pending) ) try { var currentState = queue.lastRenderedState, - eagerState = alternate(currentState, action); - suspenseConfig.eagerReducer = alternate; + eagerState = pending(currentState, action); + suspenseConfig.eagerReducer = pending; suspenseConfig.eagerState = eagerState; - if (is$1(eagerState, currentState)) return; + if (objectIs(eagerState, currentState)) return; } catch (error) { } finally { } - scheduleUpdateOnFiber(fiber, currentTime); + scheduleWork(fiber, currentTime); } } +function updateEventListener() {} var ContextOnlyDispatcher = { readContext: readContext, useCallback: throwInvalidHookError, @@ -3585,7 +3492,8 @@ var ContextOnlyDispatcher = { useDebugValue: throwInvalidHookError, useResponder: throwInvalidHookError, useDeferredValue: throwInvalidHookError, - useTransition: throwInvalidHookError + useTransition: throwInvalidHookError, + useEvent: throwInvalidHookError }, HooksDispatcherOnMount = { readContext: readContext, @@ -3596,13 +3504,13 @@ var ContextOnlyDispatcher = { deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; return mountEffectImpl( 4, - 36, + 2, imperativeHandleEffect.bind(null, create, ref), deps ); }, useLayoutEffect: function(create, deps) { - return mountEffectImpl(4, 36, create, deps); + return mountEffectImpl(4, 2, create, deps); }, useMemo: function(nextCreate, deps) { var hook = mountWorkInProgressHook(); @@ -3616,7 +3524,7 @@ var ContextOnlyDispatcher = { initialArg = void 0 !== init ? init(initialArg) : initialArg; hook.memoizedState = hook.baseState = initialArg; reducer = hook.queue = { - last: null, + pending: null, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialArg @@ -3635,23 +3543,21 @@ var ContextOnlyDispatcher = { }, useState: mountState, useDebugValue: mountDebugValue, - useResponder: createResponderListener, + useResponder: createDeprecatedResponderListener, useDeferredValue: function(value, config) { var _mountState = mountState(value), prevValue = _mountState[0], setValue = _mountState[1]; mountEffect( function() { - 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; - } - }); + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } }, [value, config] ); @@ -3659,177 +3565,124 @@ var ContextOnlyDispatcher = { }, useTransition: function(config) { var _mountState2 = mountState(!1), - isPending = _mountState2[0], - setPending = _mountState2[1]; + isPending = _mountState2[0]; + _mountState2 = _mountState2[1]; return [ - 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] - ), + mountCallback(startTransition.bind(null, _mountState2, config), [ + _mountState2, + config + ]), isPending ]; - } + }, + useEvent: function() {} }, HooksDispatcherOnUpdate = { readContext: readContext, useCallback: updateCallback, useContext: readContext, useEffect: updateEffect, - 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; - }, + useImperativeHandle: updateImperativeHandle, + useLayoutEffect: updateLayoutEffect, + useMemo: updateMemo, useReducer: updateReducer, - useRef: function() { - return updateWorkInProgressHook().memoizedState; + useRef: updateRef, + useState: function() { + return updateReducer(basicStateReducer); }, - useState: updateState, useDebugValue: mountDebugValue, - useResponder: createResponderListener, + useResponder: createDeprecatedResponderListener, useDeferredValue: function(value, config) { - var _updateState = updateState(value), + var _updateState = updateReducer(basicStateReducer), prevValue = _updateState[0], setValue = _updateState[1]; updateEffect( function() { - 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; - } - }); + 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 = updateState(!1), - isPending = _updateState2[0], - setPending = _updateState2[1]; + var _updateState2 = updateReducer(basicStateReducer), + isPending = _updateState2[0]; + _updateState2 = _updateState2[1]; return [ - 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] - ), + updateCallback(startTransition.bind(null, _updateState2, config), [ + _updateState2, + config + ]), isPending ]; - } + }, + useEvent: updateEventListener }, - 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 + 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] ); - 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, + 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, didReceiveUpdate = !1; function reconcileChildren( - current$$1, + current, workInProgress, nextChildren, renderExpirationTime ) { workInProgress.child = - null === current$$1 + null === current ? mountChildFibers( workInProgress, null, @@ -3838,13 +3691,13 @@ function reconcileChildren( ) : reconcileChildFibers( workInProgress, - current$$1.child, + current.child, nextChildren, renderExpirationTime ); } function updateForwardRef( - current$$1, + current, workInProgress, Component, nextProps, @@ -3854,43 +3707,38 @@ function updateForwardRef( var ref = workInProgress.ref; prepareToReadContext(workInProgress, renderExpirationTime); nextProps = renderWithHooks( - current$$1, + current, workInProgress, Component, nextProps, ref, renderExpirationTime ); - if (null !== current$$1 && !didReceiveUpdate) + if (null !== current && !didReceiveUpdate) return ( - (workInProgress.updateQueue = current$$1.updateQueue), + (workInProgress.updateQueue = current.updateQueue), (workInProgress.effectTag &= -517), - current$$1.expirationTime <= renderExpirationTime && - (current$$1.expirationTime = 0), + current.expirationTime <= renderExpirationTime && + (current.expirationTime = 0), bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ) ); workInProgress.effectTag |= 1; - reconcileChildren( - current$$1, - workInProgress, - nextProps, - renderExpirationTime - ); + reconcileChildren(current, workInProgress, nextProps, renderExpirationTime); return workInProgress.child; } function updateMemoComponent( - current$$1, + current, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime ) { - if (null === current$$1) { + if (null === current) { var type = Component.type; if ( "function" === typeof type && @@ -3903,7 +3751,7 @@ function updateMemoComponent( (workInProgress.tag = 15), (workInProgress.type = type), updateSimpleMemoComponent( - current$$1, + current, workInProgress, type, nextProps, @@ -3911,7 +3759,7 @@ function updateMemoComponent( renderExpirationTime ) ); - current$$1 = createFiberFromTypeAndProps( + current = createFiberFromTypeAndProps( Component.type, null, nextProps, @@ -3919,65 +3767,66 @@ function updateMemoComponent( workInProgress.mode, renderExpirationTime ); - current$$1.ref = workInProgress.ref; - current$$1.return = workInProgress; - return (workInProgress.child = current$$1); + current.ref = workInProgress.ref; + current.return = workInProgress; + return (workInProgress.child = current); } - type = current$$1.child; + type = current.child; if ( updateExpirationTime < renderExpirationTime && ((updateExpirationTime = type.memoizedProps), (Component = Component.compare), (Component = null !== Component ? Component : shallowEqual), Component(updateExpirationTime, nextProps) && - current$$1.ref === workInProgress.ref) + current.ref === workInProgress.ref) ) return bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ); workInProgress.effectTag |= 1; - current$$1 = createWorkInProgress(type, nextProps, renderExpirationTime); - current$$1.ref = workInProgress.ref; - current$$1.return = workInProgress; - return (workInProgress.child = current$$1); + current = createWorkInProgress(type, nextProps); + current.ref = workInProgress.ref; + current.return = workInProgress; + return (workInProgress.child = current); } function updateSimpleMemoComponent( - current$$1, + current, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime ) { - return null !== current$$1 && - shallowEqual(current$$1.memoizedProps, nextProps) && - current$$1.ref === workInProgress.ref && + return null !== current && + shallowEqual(current.memoizedProps, nextProps) && + current.ref === workInProgress.ref && ((didReceiveUpdate = !1), updateExpirationTime < renderExpirationTime) - ? bailoutOnAlreadyFinishedWork( - current$$1, + ? ((workInProgress.expirationTime = current.expirationTime), + bailoutOnAlreadyFinishedWork( + current, workInProgress, renderExpirationTime - ) + )) : updateFunctionComponent( - current$$1, + current, workInProgress, Component, nextProps, renderExpirationTime ); } -function markRef(current$$1, workInProgress) { +function markRef(current, workInProgress) { var ref = workInProgress.ref; if ( - (null === current$$1 && null !== ref) || - (null !== current$$1 && current$$1.ref !== ref) + (null === current && null !== ref) || + (null !== current && current.ref !== ref) ) workInProgress.effectTag |= 128; } function updateFunctionComponent( - current$$1, + current, workInProgress, Component, nextProps, @@ -3989,36 +3838,31 @@ function updateFunctionComponent( context = getMaskedContext(workInProgress, context); prepareToReadContext(workInProgress, renderExpirationTime); Component = renderWithHooks( - current$$1, + current, workInProgress, Component, nextProps, context, renderExpirationTime ); - if (null !== current$$1 && !didReceiveUpdate) + if (null !== current && !didReceiveUpdate) return ( - (workInProgress.updateQueue = current$$1.updateQueue), + (workInProgress.updateQueue = current.updateQueue), (workInProgress.effectTag &= -517), - current$$1.expirationTime <= renderExpirationTime && - (current$$1.expirationTime = 0), + current.expirationTime <= renderExpirationTime && + (current.expirationTime = 0), bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ) ); workInProgress.effectTag |= 1; - reconcileChildren( - current$$1, - workInProgress, - Component, - renderExpirationTime - ); + reconcileChildren(current, workInProgress, Component, renderExpirationTime); return workInProgress.child; } function updateClassComponent( - current$$1, + current, workInProgress, Component, nextProps, @@ -4030,16 +3874,11 @@ function updateClassComponent( } else hasContext = !1; prepareToReadContext(workInProgress, renderExpirationTime); if (null === workInProgress.stateNode) - null !== current$$1 && - ((current$$1.alternate = null), + null !== current && + ((current.alternate = null), (workInProgress.alternate = null), (workInProgress.effectTag |= 2)), - constructClassInstance( - workInProgress, - Component, - nextProps, - renderExpirationTime - ), + constructClassInstance(workInProgress, Component, nextProps), mountClassInstance( workInProgress, Component, @@ -4047,7 +3886,7 @@ function updateClassComponent( renderExpirationTime ), (nextProps = !0); - else if (null === current$$1) { + else if (null === current) { var instance = workInProgress.stateNode, oldProps = workInProgress.memoizedProps; instance.props = oldProps; @@ -4075,17 +3914,14 @@ function updateClassComponent( )); hasForceUpdate = !1; var oldState = workInProgress.memoizedState; - oldContext = instance.state = oldState; - var updateQueue = workInProgress.updateQueue; - null !== updateQueue && - (processUpdateQueue( - workInProgress, - updateQueue, - nextProps, - instance, - renderExpirationTime - ), - (oldContext = workInProgress.memoizedState)); + instance.state = oldState; + processUpdateQueue( + workInProgress, + nextProps, + instance, + renderExpirationTime + ); + oldContext = workInProgress.memoizedState; oldProps !== nextProps || oldState !== oldContext || didPerformWorkStackCursor.current || @@ -4131,6 +3967,7 @@ function updateClassComponent( (nextProps = !1)); } else (instance = workInProgress.stateNode), + cloneUpdateQueue(current, workInProgress), (oldProps = workInProgress.memoizedProps), (instance.props = workInProgress.type === workInProgress.elementType @@ -4159,17 +3996,14 @@ function updateClassComponent( )), (hasForceUpdate = !1), (oldContext = workInProgress.memoizedState), - (oldState = instance.state = oldContext), - (updateQueue = workInProgress.updateQueue), - null !== updateQueue && - (processUpdateQueue( - workInProgress, - updateQueue, - nextProps, - instance, - renderExpirationTime - ), - (oldState = workInProgress.memoizedState)), + (instance.state = oldContext), + processUpdateQueue( + workInProgress, + nextProps, + instance, + renderExpirationTime + ), + (oldState = workInProgress.memoizedState), oldProps !== nextProps || oldContext !== oldState || didPerformWorkStackCursor.current || @@ -4213,12 +4047,12 @@ function updateClassComponent( "function" === typeof instance.getSnapshotBeforeUpdate && (workInProgress.effectTag |= 256)) : ("function" !== typeof instance.componentDidUpdate || - (oldProps === current$$1.memoizedProps && - oldContext === current$$1.memoizedState) || + (oldProps === current.memoizedProps && + oldContext === current.memoizedState) || (workInProgress.effectTag |= 4), "function" !== typeof instance.getSnapshotBeforeUpdate || - (oldProps === current$$1.memoizedProps && - oldContext === current$$1.memoizedState) || + (oldProps === current.memoizedProps && + oldContext === current.memoizedState) || (workInProgress.effectTag |= 256), (workInProgress.memoizedProps = nextProps), (workInProgress.memoizedState = oldState)), @@ -4227,16 +4061,16 @@ function updateClassComponent( (instance.context = contextType), (nextProps = getDerivedStateFromProps)) : ("function" !== typeof instance.componentDidUpdate || - (oldProps === current$$1.memoizedProps && - oldContext === current$$1.memoizedState) || + (oldProps === current.memoizedProps && + oldContext === current.memoizedState) || (workInProgress.effectTag |= 4), "function" !== typeof instance.getSnapshotBeforeUpdate || - (oldProps === current$$1.memoizedProps && - oldContext === current$$1.memoizedState) || + (oldProps === current.memoizedProps && + oldContext === current.memoizedState) || (workInProgress.effectTag |= 256), (nextProps = !1)); return finishClassComponent( - current$$1, + current, workInProgress, Component, nextProps, @@ -4245,35 +4079,35 @@ function updateClassComponent( ); } function finishClassComponent( - current$$1, + current, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime ) { - markRef(current$$1, workInProgress); + markRef(current, workInProgress); var didCaptureError = 0 !== (workInProgress.effectTag & 64); if (!shouldUpdate && !didCaptureError) return ( hasContext && invalidateContextProvider(workInProgress, Component, !1), bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ) ); shouldUpdate = workInProgress.stateNode; - ReactCurrentOwner$3.current = workInProgress; + ReactCurrentOwner$1.current = workInProgress; var nextChildren = didCaptureError && "function" !== typeof Component.getDerivedStateFromError ? null : shouldUpdate.render(); workInProgress.effectTag |= 1; - null !== current$$1 && didCaptureError + null !== current && didCaptureError ? ((workInProgress.child = reconcileChildFibers( workInProgress, - current$$1.child, + current.child, null, renderExpirationTime )), @@ -4284,7 +4118,7 @@ function finishClassComponent( renderExpirationTime ))) : reconcileChildren( - current$$1, + current, workInProgress, nextChildren, renderExpirationTime @@ -4307,7 +4141,7 @@ function pushHostRootContext(workInProgress) { } var SUSPENDED_MARKER = { dehydrated: null, retryTime: 0 }; function updateSuspenseComponent( - current$$1, + current, workInProgress, renderExpirationTime ) { @@ -4319,32 +4153,30 @@ function updateSuspenseComponent( (JSCompiler_temp = 0 !== (workInProgress.effectTag & 64)) || (JSCompiler_temp = 0 !== (suspenseContext & 2) && - (null === current$$1 || null !== current$$1.memoizedState)); + (null === current || null !== current.memoizedState)); JSCompiler_temp ? ((nextDidTimeout = !0), (workInProgress.effectTag &= -65)) - : (null !== current$$1 && null === current$$1.memoizedState) || + : (null !== current && null === current.memoizedState) || void 0 === nextProps.fallback || !0 === nextProps.unstable_avoidThisFallback || (suspenseContext |= 1); - push(suspenseStackCursor, suspenseContext & 1, workInProgress); - if (null === current$$1) { - void 0 !== nextProps.fallback && - tryToClaimNextHydratableInstance(workInProgress); + push(suspenseStackCursor, suspenseContext & 1); + if (null === current) { if (nextDidTimeout) { nextDidTimeout = nextProps.fallback; nextProps = createFiberFromFragment(null, mode, 0, null); nextProps.return = workInProgress; if (0 === (workInProgress.mode & 2)) for ( - current$$1 = + current = null !== workInProgress.memoizedState ? workInProgress.child.child : workInProgress.child, - nextProps.child = current$$1; - null !== current$$1; + nextProps.child = current; + null !== current; ) - (current$$1.return = nextProps), (current$$1 = current$$1.sibling); + (current.return = nextProps), (current = current.sibling); renderExpirationTime = createFiberFromFragment( nextDidTimeout, mode, @@ -4366,15 +4198,14 @@ function updateSuspenseComponent( renderExpirationTime )); } - if (null !== current$$1.memoizedState) { - current$$1 = current$$1.child; - mode = current$$1.sibling; + if (null !== current.memoizedState) { + current = current.child; + mode = current.sibling; if (nextDidTimeout) { nextProps = nextProps.fallback; renderExpirationTime = createWorkInProgress( - current$$1, - current$$1.pendingProps, - 0 + current, + current.pendingProps ); renderExpirationTime.return = workInProgress; if ( @@ -4383,7 +4214,7 @@ function updateSuspenseComponent( null !== workInProgress.memoizedState ? workInProgress.child.child : workInProgress.child), - nextDidTimeout !== current$$1.child) + nextDidTimeout !== current.child) ) for ( renderExpirationTime.child = nextDidTimeout; @@ -4392,7 +4223,7 @@ function updateSuspenseComponent( ) (nextDidTimeout.return = renderExpirationTime), (nextDidTimeout = nextDidTimeout.sibling); - mode = createWorkInProgress(mode, nextProps, mode.expirationTime); + mode = createWorkInProgress(mode, nextProps); mode.return = workInProgress; renderExpirationTime.sibling = mode; renderExpirationTime.childExpirationTime = 0; @@ -4402,31 +4233,31 @@ function updateSuspenseComponent( } renderExpirationTime = reconcileChildFibers( workInProgress, - current$$1.child, + current.child, nextProps.children, renderExpirationTime ); workInProgress.memoizedState = null; return (workInProgress.child = renderExpirationTime); } - current$$1 = current$$1.child; + current = current.child; if (nextDidTimeout) { nextDidTimeout = nextProps.fallback; nextProps = createFiberFromFragment(null, mode, 0, null); nextProps.return = workInProgress; - nextProps.child = current$$1; - null !== current$$1 && (current$$1.return = nextProps); + nextProps.child = current; + null !== current && (current.return = nextProps); if (0 === (workInProgress.mode & 2)) for ( - current$$1 = + current = null !== workInProgress.memoizedState ? workInProgress.child.child : workInProgress.child, - nextProps.child = current$$1; - null !== current$$1; + nextProps.child = current; + null !== current; ) - (current$$1.return = nextProps), (current$$1 = current$$1.sibling); + (current.return = nextProps), (current = current.sibling); renderExpirationTime = createFiberFromFragment( nextDidTimeout, mode, @@ -4444,7 +4275,7 @@ function updateSuspenseComponent( workInProgress.memoizedState = null; return (workInProgress.child = reconcileChildFibers( workInProgress, - current$$1, + current, nextProps.children, renderExpirationTime )); @@ -4471,6 +4302,7 @@ function initSuspenseListRenderState( ? (workInProgress.memoizedState = { isBackwards: isBackwards, rendering: null, + renderingStartTime: 0, last: lastContentRow, tail: tail, tailExpiration: 0, @@ -4479,6 +4311,7 @@ function initSuspenseListRenderState( }) : ((renderState.isBackwards = isBackwards), (renderState.rendering = null), + (renderState.renderingStartTime = 0), (renderState.last = lastContentRow), (renderState.tail = tail), (renderState.tailExpiration = 0), @@ -4486,7 +4319,7 @@ function initSuspenseListRenderState( (renderState.lastEffect = lastEffectBeforeRendering)); } function updateSuspenseListComponent( - current$$1, + current, workInProgress, renderExpirationTime ) { @@ -4494,7 +4327,7 @@ function updateSuspenseListComponent( revealOrder = nextProps.revealOrder, tailMode = nextProps.tail; reconcileChildren( - current$$1, + current, workInProgress, nextProps.children, renderExpirationTime @@ -4503,42 +4336,39 @@ function updateSuspenseListComponent( if (0 !== (nextProps & 2)) (nextProps = (nextProps & 1) | 2), (workInProgress.effectTag |= 64); else { - 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; + 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; continue; } - if (current$$1 === workInProgress) break a; - for (; null === current$$1.sibling; ) { - if ( - null === current$$1.return || - current$$1.return === workInProgress - ) + if (current === workInProgress) break a; + for (; null === current.sibling; ) { + if (null === current.return || current.return === workInProgress) break a; - current$$1 = current$$1.return; + current = current.return; } - current$$1.sibling.return = current$$1.return; - current$$1 = current$$1.sibling; + current.sibling.return = current.return; + current = current.sibling; } nextProps &= 1; } - push(suspenseStackCursor, nextProps, workInProgress); + push(suspenseStackCursor, nextProps); if (0 === (workInProgress.mode & 2)) workInProgress.memoizedState = null; else switch (revealOrder) { case "forwards": renderExpirationTime = workInProgress.child; for (revealOrder = null; null !== renderExpirationTime; ) - (current$$1 = renderExpirationTime.alternate), - null !== current$$1 && - null === findFirstSuspended(current$$1) && + (current = renderExpirationTime.alternate), + null !== current && + null === findFirstSuspended(current) && (revealOrder = renderExpirationTime), (renderExpirationTime = renderExpirationTime.sibling); renderExpirationTime = revealOrder; @@ -4560,15 +4390,15 @@ function updateSuspenseListComponent( renderExpirationTime = null; revealOrder = workInProgress.child; for (workInProgress.child = null; null !== revealOrder; ) { - current$$1 = revealOrder.alternate; - if (null !== current$$1 && null === findFirstSuspended(current$$1)) { + current = revealOrder.alternate; + if (null !== current && null === findFirstSuspended(current)) { workInProgress.child = revealOrder; break; } - current$$1 = revealOrder.sibling; + current = revealOrder.sibling; revealOrder.sibling = renderExpirationTime; renderExpirationTime = revealOrder; - revealOrder = current$$1; + revealOrder = current; } initSuspenseListRenderState( workInProgress, @@ -4595,35 +4425,29 @@ function updateSuspenseListComponent( return workInProgress.child; } function bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ) { - null !== current$$1 && - (workInProgress.dependencies = current$$1.dependencies); + null !== current && (workInProgress.dependencies = current.dependencies); var updateExpirationTime = workInProgress.expirationTime; 0 !== updateExpirationTime && markUnprocessedUpdateTime(updateExpirationTime); if (workInProgress.childExpirationTime < renderExpirationTime) return null; - if (null !== current$$1 && workInProgress.child !== current$$1.child) + if (null !== current && workInProgress.child !== current.child) throw Error("Resuming work not yet implemented."); if (null !== workInProgress.child) { - current$$1 = workInProgress.child; - renderExpirationTime = createWorkInProgress( - current$$1, - current$$1.pendingProps, - current$$1.expirationTime - ); + current = workInProgress.child; + renderExpirationTime = createWorkInProgress(current, current.pendingProps); workInProgress.child = renderExpirationTime; for ( renderExpirationTime.return = workInProgress; - null !== current$$1.sibling; + null !== current.sibling; ) - (current$$1 = current$$1.sibling), + (current = current.sibling), (renderExpirationTime = renderExpirationTime.sibling = createWorkInProgress( - current$$1, - current$$1.pendingProps, - current$$1.expirationTime + current, + current.pendingProps )), (renderExpirationTime.return = workInProgress); renderExpirationTime.sibling = null; @@ -4685,62 +4509,367 @@ function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { : (_lastTailNode.sibling = null); } } -function unwindWork(workInProgress) { +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: - isContextProvider(workInProgress.type) && popContext(workInProgress); - var effectTag = workInProgress.effectTag; - return effectTag & 4096 - ? ((workInProgress.effectTag = (effectTag & -4097) | 64), - workInProgress) - : null; + return isContextProvider(workInProgress.type) && popContext(), null; case 3: - popHostContainer(workInProgress); - popTopLevelContextObject(workInProgress); - effectTag = workInProgress.effectTag; - if (0 !== (effectTag & 64)) - throw Error( - "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." - ); - workInProgress.effectTag = (effectTag & -4097) | 64; - return workInProgress; - case 5: - return popHostContext(workInProgress), null; - case 13: return ( - pop(suspenseStackCursor, workInProgress), - (effectTag = workInProgress.effectTag), - effectTag & 4096 - ? ((workInProgress.effectTag = (effectTag & -4097) | 64), - workInProgress) - : null + popHostContainer(), + pop(didPerformWorkStackCursor), + pop(contextStackCursor), + (current = workInProgress.stateNode), + current.pendingContext && + ((current.context = current.pendingContext), + (current.pendingContext = null)), + updateHostContainer(workInProgress), + null ); - case 19: - return pop(suspenseStackCursor, workInProgress), null; - case 4: - return popHostContainer(workInProgress), null; - case 10: - return popProvider(workInProgress), null; - default: + 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; - } -} -function createCapturedValue(value, source) { - return { - value: value, - source: source, - stack: getStackByFiberInDevAndProd(source) - }; -} -if ( - "function" !== - typeof ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog -) - throw Error( - "Expected ReactFiberErrorDialog.showErrorDialog to be a function." - ); -function logCapturedError(capturedError) { - !1 !== + 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(); + var effectTag = workInProgress.effectTag; + return effectTag & 4096 + ? ((workInProgress.effectTag = (effectTag & -4097) | 64), + workInProgress) + : null; + case 3: + popHostContainer(); + pop(didPerformWorkStackCursor); + pop(contextStackCursor); + effectTag = workInProgress.effectTag; + if (0 !== (effectTag & 64)) + throw Error( + "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." + ); + workInProgress.effectTag = (effectTag & -4097) | 64; + return workInProgress; + case 5: + return popHostContext(workInProgress), null; + case 13: + return ( + pop(suspenseStackCursor), + (effectTag = workInProgress.effectTag), + effectTag & 4096 + ? ((workInProgress.effectTag = (effectTag & -4097) | 64), + workInProgress) + : null + ); + case 19: + return pop(suspenseStackCursor), null; + case 4: + return popHostContainer(), null; + case 10: + return popProvider(workInProgress), null; + default: + return null; + } +} +function createCapturedValue(value, source) { + return { + value: value, + source: source, + stack: getStackByFiberInDevAndProd(source) + }; +} +if ( + "function" !== + typeof ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog +) + throw Error( + "Expected ReactFiberErrorDialog.showErrorDialog to be a function." + ); +function logCapturedError(capturedError) { + !1 !== ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog( capturedError ) && console.error(capturedError.error); @@ -4775,85 +4904,159 @@ function logError(boundary, errorInfo) { }); } } -function safelyCallComponentWillUnmount(current$$1, instance) { +function safelyCallComponentWillUnmount(current, instance) { try { - (instance.props = current$$1.memoizedProps), - (instance.state = current$$1.memoizedState), + (instance.props = current.memoizedProps), + (instance.state = current.memoizedState), instance.componentWillUnmount(); } catch (unmountError) { - captureCommitPhaseError(current$$1, unmountError); + captureCommitPhaseError(current, unmountError); } } -function safelyDetachRef(current$$1) { - var ref = current$$1.ref; +function safelyDetachRef(current) { + var ref = current.ref; if (null !== ref) if ("function" === typeof ref) try { ref(null); } catch (refError) { - captureCommitPhaseError(current$$1, refError); + captureCommitPhaseError(current, refError); } else ref.current = null; } -function commitBeforeMutationLifeCycles(current$$1, finishedWork) { +function commitBeforeMutationLifeCycles(current, finishedWork) { switch (finishedWork.tag) { case 0: case 11: case 15: - commitHookEffectList(2, 0, finishedWork); - break; + case 22: + return; case 1: - if (finishedWork.effectTag & 256 && null !== current$$1) { - var prevProps = current$$1.memoizedProps, - prevState = current$$1.memoizedState; - current$$1 = finishedWork.stateNode; - finishedWork = current$$1.getSnapshotBeforeUpdate( + if (finishedWork.effectTag & 256 && null !== current) { + var prevProps = current.memoizedProps, + prevState = current.memoizedState; + current = finishedWork.stateNode; + finishedWork = current.getSnapshotBeforeUpdate( finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState ); - current$$1.__reactInternalSnapshotBeforeUpdate = finishedWork; + current.__reactInternalSnapshotBeforeUpdate = finishedWork; } - break; + return; case 3: case 5: case 6: case 4: case 17: - break; - default: - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); + 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 commitHookEffectList(unmountTag, mountTag, finishedWork) { +function commitHookEffectListUnmount(tag, finishedWork) { finishedWork = finishedWork.updateQueue; finishedWork = null !== finishedWork ? finishedWork.lastEffect : null; if (null !== finishedWork) { var effect = (finishedWork = finishedWork.next); do { - if (0 !== (effect.tag & unmountTag)) { + if ((effect.tag & tag) === tag) { 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 commitUnmount(finishedRoot, current$$1$jscomp$0, renderPriorityLevel) { +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" === typeof onCommitFiberUnmount && - onCommitFiberUnmount(current$$1$jscomp$0); - switch (current$$1$jscomp$0.tag) { + onCommitFiberUnmount(current$jscomp$0); + switch (current$jscomp$0.tag) { case 0: case 11: case 14: case 15: - finishedRoot = current$$1$jscomp$0.updateQueue; + case 22: + finishedRoot = current$jscomp$0.updateQueue; if ( null !== finishedRoot && ((finishedRoot = finishedRoot.lastEffect), null !== finishedRoot) @@ -4864,13 +5067,13 @@ function commitUnmount(finishedRoot, current$$1$jscomp$0, renderPriorityLevel) { function() { var effect = firstEffect; do { - var destroy = effect.destroy; - if (void 0 !== destroy) { - var current$$1 = current$$1$jscomp$0; + var _destroy = effect.destroy; + if (void 0 !== _destroy) { + var current = current$jscomp$0; try { - destroy(); + _destroy(); } catch (error) { - captureCommitPhaseError(current$$1, error); + captureCommitPhaseError(current, error); } } effect = effect.next; @@ -4880,37 +5083,35 @@ function commitUnmount(finishedRoot, current$$1$jscomp$0, renderPriorityLevel) { } break; case 1: - safelyDetachRef(current$$1$jscomp$0); - renderPriorityLevel = current$$1$jscomp$0.stateNode; + safelyDetachRef(current$jscomp$0); + renderPriorityLevel = current$jscomp$0.stateNode; "function" === typeof renderPriorityLevel.componentWillUnmount && - safelyCallComponentWillUnmount( - current$$1$jscomp$0, - renderPriorityLevel - ); + safelyCallComponentWillUnmount(current$jscomp$0, renderPriorityLevel); break; case 5: - safelyDetachRef(current$$1$jscomp$0); + safelyDetachRef(current$jscomp$0); break; case 4: unmountHostComponents( finishedRoot, - current$$1$jscomp$0, + current$jscomp$0, renderPriorityLevel ); } } -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; +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; null !== alternate && detachFiber(alternate); } function isHostParent(fiber) { @@ -4973,97 +5174,103 @@ function commitPlacement(finishedWork) { break a; } } - 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), + 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( - isHost._nativeTag, - [index], - [beforeChild], + parent._nativeTag, + [isHost], + [before], [], [], [] )) - : ((index = children.indexOf(beforeChild)), - children.splice(index, 0, stateNode), + : ((before = tag.indexOf(before)), + tag.splice(before, 0, node), ReactNativePrivateInterface.UIManager.manageChildren( - isHost._nativeTag, + parent._nativeTag, [], [], - [ - "number" === typeof stateNode - ? stateNode - : stateNode._nativeTag - ], - [index], + ["number" === typeof node ? node : node._nativeTag], + [before], [] - )); - } - 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; - } + ))) + : ((before = "number" === typeof node ? node : node._nativeTag), + (tag = parent._children), + (isHost = tag.indexOf(node)), + 0 <= isHost + ? (tag.splice(isHost, 1), + tag.push(node), + ReactNativePrivateInterface.UIManager.manageChildren( + parent._nativeTag, + [isHost], + [tag.length - 1], + [], + [], + [] + )) + : (tag.push(node), + ReactNativePrivateInterface.UIManager.manageChildren( + parent._nativeTag, + [], + [], + [before], + [tag.length - 1], + [] + ))); + 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); } function unmountHostComponents( finishedRoot$jscomp$0, - current$$1, + current, renderPriorityLevel$jscomp$0 ) { for ( - var node = current$$1, + var node = current, currentParentIsValid = !1, currentParent, currentParentIsContainer; @@ -5111,7 +5318,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; + if (node$jscomp$0 === root) break a; for (; null === node$jscomp$0.sibling; ) { if (null === node$jscomp$0.return || node$jscomp$0.return === root) break a; @@ -5161,9 +5368,9 @@ function unmountHostComponents( node = node.child; continue; } - if (node === current$$1) break; + if (node === current) break; for (; null === node.sibling; ) { - if (null === node.return || node.return === current$$1) return; + if (null === node.return || node.return === current) return; node = node.return; 4 === node.tag && (currentParentIsValid = !1); } @@ -5171,21 +5378,22 @@ function unmountHostComponents( node = node.sibling; } } -function commitWork(current$$1, finishedWork) { +function commitWork(current, finishedWork) { switch (finishedWork.tag) { case 0: case 11: case 14: case 15: - commitHookEffectList(4, 8, finishedWork); - break; + case 22: + commitHookEffectListUnmount(3, finishedWork); + return; case 1: - break; + return; case 5: var instance = finishedWork.stateNode; if (null != instance) { var newProps = finishedWork.memoizedProps; - current$$1 = null !== current$$1 ? current$$1.memoizedProps : newProps; + current = null !== current ? current.memoizedProps : newProps; var updatePayload = finishedWork.updateQueue; finishedWork.updateQueue = null; null !== updatePayload && @@ -5193,7 +5401,7 @@ function commitWork(current$$1, finishedWork) { instanceProps.set(instance._nativeTag, newProps), (newProps = diffProperties( null, - current$$1, + current, newProps, finishedWork.validAttributes )), @@ -5204,7 +5412,7 @@ function commitWork(current$$1, finishedWork) { newProps )); } - break; + return; case 6: if (null === finishedWork.stateNode) throw Error( @@ -5215,11 +5423,11 @@ function commitWork(current$$1, finishedWork) { "RCTRawText", { text: finishedWork.memoizedProps } ); - break; + return; case 3: - break; + return; case 12: - break; + return; case 13: instance = finishedWork; null === finishedWork.memoizedState @@ -5228,9 +5436,9 @@ function commitWork(current$$1, finishedWork) { (instance = finishedWork.child), (globalMostRecentFallbackTime = now())); if (null !== instance) - a: for (current$$1 = instance; ; ) { - if (5 === current$$1.tag) - if (((updatePayload = current$$1.stateNode), newProps)) { + a: for (current = instance; ; ) { + if (5 === current.tag) + if (((updatePayload = current.stateNode), newProps)) { var viewConfig = updatePayload.viewConfig; var updatePayload$jscomp$0 = diffProperties( null, @@ -5244,8 +5452,8 @@ function commitWork(current$$1, finishedWork) { updatePayload$jscomp$0 ); } else { - updatePayload = current$$1.stateNode; - updatePayload$jscomp$0 = current$$1.memoizedProps; + updatePayload = current.stateNode; + updatePayload$jscomp$0 = current.memoizedProps; viewConfig = updatePayload.viewConfig; var prevProps = Object.assign({}, updatePayload$jscomp$0, { style: [updatePayload$jscomp$0.style, { display: "none" }] @@ -5263,47 +5471,41 @@ function commitWork(current$$1, finishedWork) { ); } else { - if (6 === current$$1.tag) throw Error("Not yet implemented."); + if (6 === current.tag) throw Error("Not yet implemented."); if ( - 13 === current$$1.tag && - null !== current$$1.memoizedState && - null === current$$1.memoizedState.dehydrated + 13 === current.tag && + null !== current.memoizedState && + null === current.memoizedState.dehydrated ) { - updatePayload = current$$1.child.sibling; - updatePayload.return = current$$1; - current$$1 = updatePayload; + updatePayload = current.child.sibling; + updatePayload.return = current; + current = updatePayload; continue; - } else if (null !== current$$1.child) { - current$$1.child.return = current$$1; - current$$1 = current$$1.child; + } else if (null !== current.child) { + current.child.return = current; + current = current.child; continue; } } - 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; + if (current === instance) break; + for (; null === current.sibling; ) { + if (null === current.return || current.return === instance) break a; + current = current.return; } - current$$1.sibling.return = current$$1.return; - current$$1 = current$$1.sibling; + current.sibling.return = current.return; + current = current.sibling; } attachSuspenseRetryListeners(finishedWork); - break; + return; case 19: attachSuspenseRetryListeners(finishedWork); - break; + return; case 17: - 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." - ); + return; } + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); } function attachSuspenseRetryListeners(finishedWork) { var thenables = finishedWork.updateQueue; @@ -5359,7 +5561,7 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { return expirationTime; } var ceil = Math.ceil, - ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher, + ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, NoContext = 0, LegacyUnbatchedContext = 8, @@ -5374,7 +5576,7 @@ var ceil = Math.ceil, executionContext = NoContext, workInProgressRoot = null, workInProgress = null, - renderExpirationTime = 0, + renderExpirationTime$1 = 0, workInProgressRootExitStatus = RootIncomplete, workInProgressRootFatalError = null, workInProgressRootLatestProcessedExpirationTime = 1073741823, @@ -5399,8 +5601,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; @@ -5408,7 +5610,7 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { var priorityLevel = getCurrentPriorityLevel(); if (0 === (fiber & 4)) return 99 === priorityLevel ? 1073741823 : 1073741822; if ((executionContext & RenderContext) !== NoContext) - return renderExpirationTime; + return renderExpirationTime$1; if (null !== suspenseConfig) currentTime = 1073741821 - @@ -5440,11 +5642,11 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { throw Error("Expected a valid priority level"); } null !== workInProgressRoot && - currentTime === renderExpirationTime && + currentTime === renderExpirationTime$1 && --currentTime; return currentTime; } -function scheduleUpdateOnFiber(fiber, expirationTime) { +function scheduleWork(fiber, expirationTime) { if (50 < nestedUpdateCount) throw ((nestedUpdateCount = 0), (rootWithNestedUpdates = null), @@ -5498,7 +5700,7 @@ function markUpdateTimeFromFiberToRoot(fiber, expirationTime) { (workInProgressRoot === root && (markUnprocessedUpdateTime(expirationTime), workInProgressRootExitStatus === RootSuspendedWithDelay && - markRootSuspendedAtTime(root, renderExpirationTime)), + markRootSuspendedAtTime(root, renderExpirationTime$1)), markRootUpdatedAtTime(root, expirationTime)); return root; } @@ -5507,9 +5709,10 @@ function getNextRootExpirationTimeToWorkOn(root) { if (0 !== lastExpiredTime) return lastExpiredTime; lastExpiredTime = root.firstPendingTime; if (!isRootSuspendedAtTime(root, lastExpiredTime)) return lastExpiredTime; - lastExpiredTime = root.lastPingedTime; + var lastPingedTime = root.lastPingedTime; root = root.nextKnownPendingLevel; - return lastExpiredTime > root ? lastExpiredTime : root; + root = lastPingedTime > root ? lastPingedTime : root; + return 2 >= root && lastExpiredTime !== root ? 0 : root; } function ensureRootIsScheduled(root) { if (0 !== root.lastExpiredTime) @@ -5531,18 +5734,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 ( @@ -5569,264 +5772,225 @@ function ensureRootIsScheduled(root) { } function performConcurrentWorkOnRoot(root, didTimeout) { currentEventTime = 0; - if (didTimeout) - return ( - (didTimeout = requestCurrentTimeForUpdate()), - markRootExpiredAtTime(root, didTimeout), + 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), ensureRootIsScheduled(root), - 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(); + 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; - } catch (thrownValue) { - handleError(root, thrownValue); } - 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) + 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) ) { - case RootIncomplete: - case RootFatalErrored: - throw Error("Root did not complete. This is a bug in React."); - case RootErrored: - markRootExpiredAtTime( - root, - 2 < expirationTime ? 2 : expirationTime + 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 + ); + break; + } + commitRoot(root); + break; + case RootCompleted: + if ( + 1073741823 !== workInProgressRootLatestProcessedExpirationTime && + null !== workInProgressRootCanSuspendUsingConfig + ) { + 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 ); 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."); + } } - ensureRootIsScheduled(root); - if (root.callbackNode === didTimeout) - return performConcurrentWorkOnRoot.bind(null, root); + commitRoot(root); + break; + default: + throw Error("Unknown root exit status."); } } - return null; + 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 ? 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); - } - } + 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; @@ -5838,26 +6002,27 @@ function prepareFreshStack(root, expirationTime) { var interruptedWork = timeoutHandle; switch (interruptedWork.tag) { case 1: - var childContextTypes = interruptedWork.type.childContextTypes; - null !== childContextTypes && - void 0 !== childContextTypes && - popContext(interruptedWork); + interruptedWork = interruptedWork.type.childContextTypes; + null !== interruptedWork && + void 0 !== interruptedWork && + popContext(); break; case 3: - popHostContainer(interruptedWork); - popTopLevelContextObject(interruptedWork); + popHostContainer(); + pop(didPerformWorkStackCursor); + pop(contextStackCursor); break; case 5: popHostContext(interruptedWork); break; case 4: - popHostContainer(interruptedWork); + popHostContainer(); break; case 13: - pop(suspenseStackCursor, interruptedWork); + pop(suspenseStackCursor); break; case 19: - pop(suspenseStackCursor, interruptedWork); + pop(suspenseStackCursor); break; case 10: popProvider(interruptedWork); @@ -5865,8 +6030,8 @@ function prepareFreshStack(root, expirationTime) { timeoutHandle = timeoutHandle.return; } workInProgressRoot = root; - workInProgress = createWorkInProgress(root.current, null, expirationTime); - renderExpirationTime = expirationTime; + workInProgress = createWorkInProgress(root.current, null); + renderExpirationTime$1 = expirationTime; workInProgressRootExitStatus = RootIncomplete; workInProgressRootFatalError = null; workInProgressRootLatestSuspenseTimeout = workInProgressRootLatestProcessedExpirationTime = 1073741823; @@ -5878,19 +6043,32 @@ function handleError(root$jscomp$0, thrownValue) { do { try { resetContextDependencies(); - resetHooks(); + 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; if (null === workInProgress || null === workInProgress.return) return ( (workInProgressRootExitStatus = RootFatalErrored), (workInProgressRootFatalError = thrownValue), - null + (workInProgress = null) ); a: { var root = root$jscomp$0, returnFiber = workInProgress.return, sourceFiber = workInProgress, value = thrownValue; - thrownValue = renderExpirationTime; + thrownValue = renderExpirationTime$1; sourceFiber.effectTag |= 2048; sourceFiber.firstEffect = sourceFiber.lastEffect = null; if ( @@ -5898,8 +6076,17 @@ function handleError(root$jscomp$0, thrownValue) { "object" === typeof value && "function" === typeof value.then ) { - var thenable = value, - hasInvisibleParentBoundary = + 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 = 0 !== (suspenseStackCursor.current & 1), _workInProgress = returnFiber; do { @@ -5914,10 +6101,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) { @@ -6024,406 +6211,94 @@ function handleError(root$jscomp$0, thrownValue) { } while (1); } function pushDispatcher() { - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = ContextOnlyDispatcher; - return null === prevDispatcher ? ContextOnlyDispatcher : prevDispatcher; -} -function markRenderEventTimeAndConfig(expirationTime, suspenseConfig) { - expirationTime < workInProgressRootLatestProcessedExpirationTime && - 2 < expirationTime && - (workInProgressRootLatestProcessedExpirationTime = expirationTime); - null !== suspenseConfig && - expirationTime < workInProgressRootLatestSuspenseTimeout && - 2 < expirationTime && - ((workInProgressRootLatestSuspenseTimeout = expirationTime), - (workInProgressRootCanSuspendUsingConfig = suspenseConfig)); -} -function markUnprocessedUpdateTime(expirationTime) { - expirationTime > workInProgressRootNextUnprocessedUpdateTime && - (workInProgressRootNextUnprocessedUpdateTime = expirationTime); -} -function workLoopSync() { - for (; null !== workInProgress; ) - workInProgress = performUnitOfWork(workInProgress); -} -function workLoopConcurrent() { - for (; null !== workInProgress && !Scheduler_shouldYield(); ) - workInProgress = performUnitOfWork(workInProgress); -} -function performUnitOfWork(unitOfWork) { - var next = beginWork$$1( - unitOfWork.alternate, - unitOfWork, - renderExpirationTime - ); - unitOfWork.memoizedProps = unitOfWork.pendingProps; - null === next && (next = completeUnitOfWork(unitOfWork)); - ReactCurrentOwner$2.current = null; - return next; -} -function completeUnitOfWork(unitOfWork) { - workInProgress = unitOfWork; - do { - var current$$1 = workInProgress.alternate; - unitOfWork = workInProgress.return; - if (0 === (workInProgress.effectTag & 2048)) { - 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; + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; + return null === prevDispatcher ? ContextOnlyDispatcher : prevDispatcher; +} +function markRenderEventTimeAndConfig(expirationTime, suspenseConfig) { + expirationTime < workInProgressRootLatestProcessedExpirationTime && + 2 < expirationTime && + (workInProgressRootLatestProcessedExpirationTime = expirationTime); + null !== suspenseConfig && + expirationTime < workInProgressRootLatestSuspenseTimeout && + 2 < expirationTime && + ((workInProgressRootLatestSuspenseTimeout = expirationTime), + (workInProgressRootCanSuspendUsingConfig = suspenseConfig)); +} +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(); ) + workInProgress = performUnitOfWork(workInProgress); +} +function performUnitOfWork(unitOfWork) { + var next = beginWork$1( + unitOfWork.alternate, + unitOfWork, + renderExpirationTime$1 + ); + unitOfWork.memoizedProps = unitOfWork.pendingProps; + null === next && (next = completeUnitOfWork(unitOfWork)); + ReactCurrentOwner$2.current = null; + return next; +} +function completeUnitOfWork(unitOfWork) { + workInProgress = unitOfWork; + do { + var current = workInProgress.alternate; + unitOfWork = workInProgress.return; + if (0 === (workInProgress.effectTag & 2048)) { + current = completeWork(current, workInProgress, renderExpirationTime$1); + if ( + 1 === renderExpirationTime$1 || + 1 !== workInProgress.childExpirationTime + ) { for ( - rootContainerInstance = current.child; - null !== rootContainerInstance; + var newChildExpirationTime = 0, _child = workInProgress.child; + null !== _child; - ) - (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; + ) { + var _childUpdateExpirationTime = _child.expirationTime, + _childChildExpirationTime = _child.childExpirationTime; + _childUpdateExpirationTime > newChildExpirationTime && + (newChildExpirationTime = _childUpdateExpirationTime); + _childChildExpirationTime > newChildExpirationTime && + (newChildExpirationTime = _childChildExpirationTime); + _child = _child.sibling; + } + workInProgress.childExpirationTime = newChildExpirationTime; } - if (null !== current$$1) return current$$1; + if (null !== current) return current; null !== unitOfWork && 0 === (unitOfWork.effectTag & 2048) && (null === unitOfWork.firstEffect && @@ -6438,15 +6313,14 @@ function completeUnitOfWork(unitOfWork) { : (unitOfWork.firstEffect = workInProgress), (unitOfWork.lastEffect = workInProgress))); } else { - current$$1 = unwindWork(workInProgress, renderExpirationTime); - if (null !== current$$1) - return (current$$1.effectTag &= 2047), current$$1; + current = unwindWork(workInProgress); + if (null !== current) return (current.effectTag &= 2047), current; null !== unitOfWork && ((unitOfWork.firstEffect = unitOfWork.lastEffect = null), (unitOfWork.effectTag |= 2048)); } - current$$1 = workInProgress.sibling; - if (null !== current$$1) return current$$1; + current = workInProgress.sibling; + if (null !== current) return current; workInProgress = unitOfWork; } while (null !== workInProgress); workInProgressRootExitStatus === RootIncomplete && @@ -6464,7 +6338,8 @@ function commitRoot(root) { return null; } function commitRootImpl(root$jscomp$0, renderPriorityLevel$jscomp$0) { - flushPassiveEffects(); + do flushPassiveEffects(); + while (null !== rootWithPendingPassiveEffects); if ((executionContext & (RenderContext | CommitContext)) !== NoContext) throw Error("Should not already be working."); var finishedWork = root$jscomp$0.finishedWork, @@ -6493,7 +6368,8 @@ 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 = 0)); + ((workInProgress = workInProgressRoot = null), + (renderExpirationTime$1 = 0)); 1 < finishedWork.effectTag ? null !== finishedWork.lastEffect ? ((finishedWork.lastEffect.nextEffect = finishedWork), @@ -6525,9 +6401,9 @@ function commitRootImpl(root$jscomp$0, renderPriorityLevel$jscomp$0) { ) { var effectTag = nextEffect.effectTag; if (effectTag & 128) { - var current$$1 = nextEffect.alternate; - if (null !== current$$1) { - var currentRef = current$$1.ref; + var current = nextEffect.alternate; + if (null !== current) { + var currentRef = current.ref; null !== currentRef && ("function" === typeof currentRef ? currentRef(null) @@ -6555,13 +6431,13 @@ function commitRootImpl(root$jscomp$0, renderPriorityLevel$jscomp$0) { commitWork(nextEffect.alternate, nextEffect); break; case 8: - var current$$1$jscomp$0 = nextEffect; + var current$jscomp$0 = nextEffect; unmountHostComponents( root, - current$$1$jscomp$0, + current$jscomp$0, renderPriorityLevel ); - detachFiber(current$$1$jscomp$0); + detachFiber(current$jscomp$0); } nextEffect = nextEffect.nextEffect; } @@ -6575,97 +6451,25 @@ function commitRootImpl(root$jscomp$0, renderPriorityLevel$jscomp$0) { nextEffect = remainingExpirationTimeBeforeCommit; do try { - for (effectTag = expirationTime; null !== nextEffect; ) { + for (effectTag = root$jscomp$0; null !== nextEffect; ) { var effectTag$jscomp$0 = nextEffect.effectTag; - 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." - ); - } - } + effectTag$jscomp$0 & 36 && + commitLifeCycles(effectTag, nextEffect.alternate, nextEffect); if (effectTag$jscomp$0 & 128) { - current$$1 = void 0; + current = void 0; var ref = nextEffect.ref; if (null !== ref) { - var instance$jscomp$0 = nextEffect.stateNode; + var instance = nextEffect.stateNode; switch (nextEffect.tag) { case 5: - current$$1 = instance$jscomp$0; + current = instance; break; default: - current$$1 = instance$jscomp$0; + current = instance; } "function" === typeof ref - ? ref(current$$1) - : (ref.current = current$$1); + ? ref(current) + : (ref.current = current); } } nextEffect = nextEffect.nextEffect; @@ -6754,8 +6558,9 @@ function flushPassiveEffectsImpl() { case 0: case 11: case 15: - commitHookEffectList(128, 0, finishedWork), - commitHookEffectList(0, 64, finishedWork); + case 22: + commitHookEffectListUnmount(5, finishedWork), + commitHookEffectListMount(5, finishedWork); } } catch (error) { if (null === root) throw Error("Should be working on an effect."); @@ -6806,20 +6611,17 @@ function captureCommitPhaseError(sourceFiber, error) { function pingSuspendedRoot(root, thenable, suspendedTime) { var pingCache = root.pingCache; null !== pingCache && pingCache.delete(thenable); - workInProgressRoot === root && renderExpirationTime === suspendedTime + workInProgressRoot === root && renderExpirationTime$1 === suspendedTime ? workInProgressRootExitStatus === RootSuspendedWithDelay || (workInProgressRootExitStatus === RootSuspended && 1073741823 === workInProgressRootLatestProcessedExpirationTime && now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) - ? prepareFreshStack(root, renderExpirationTime) + ? prepareFreshStack(root, renderExpirationTime$1) : (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))); + ((root.lastPingedTime = suspendedTime), ensureRootIsScheduled(root))); } function resolveRetryThenable(boundaryFiber, thenable) { var retryCache = boundaryFiber.stateNode; @@ -6831,12 +6633,12 @@ function resolveRetryThenable(boundaryFiber, thenable) { boundaryFiber = markUpdateTimeFromFiberToRoot(boundaryFiber, thenable); null !== boundaryFiber && ensureRootIsScheduled(boundaryFiber); } -var beginWork$$1; -beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { +var beginWork$1; +beginWork$1 = function(current, workInProgress, renderExpirationTime) { var updateExpirationTime = workInProgress.expirationTime; - if (null !== current$$1) + if (null !== current) if ( - current$$1.memoizedProps !== workInProgress.pendingProps || + current.memoizedProps !== workInProgress.pendingProps || didPerformWorkStackCursor.current ) didReceiveUpdate = !0; @@ -6861,7 +6663,10 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { ); break; case 10: - pushProvider(workInProgress, workInProgress.memoizedProps.value); + updateExpirationTime = workInProgress.memoizedProps.value; + var context = workInProgress.type._context; + push(valueCursor, context._currentValue); + context._currentValue = updateExpirationTime; break; case 13: if (null !== workInProgress.memoizedState) { @@ -6871,52 +6676,40 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { updateExpirationTime >= renderExpirationTime ) return updateSuspenseComponent( - current$$1, + current, workInProgress, renderExpirationTime ); - push( - suspenseStackCursor, - suspenseStackCursor.current & 1, - workInProgress - ); + push(suspenseStackCursor, suspenseStackCursor.current & 1); workInProgress = bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ); return null !== workInProgress ? workInProgress.sibling : null; } - push( - suspenseStackCursor, - suspenseStackCursor.current & 1, - workInProgress - ); + push(suspenseStackCursor, suspenseStackCursor.current & 1); break; case 19: updateExpirationTime = workInProgress.childExpirationTime >= renderExpirationTime; - if (0 !== (current$$1.effectTag & 64)) { + if (0 !== (current.effectTag & 64)) { if (updateExpirationTime) return updateSuspenseListComponent( - current$$1, + current, workInProgress, renderExpirationTime ); workInProgress.effectTag |= 64; } - var renderState = workInProgress.memoizedState; - null !== renderState && - ((renderState.rendering = null), (renderState.tail = null)); - push( - suspenseStackCursor, - suspenseStackCursor.current, - workInProgress - ); + context = workInProgress.memoizedState; + null !== context && + ((context.rendering = null), (context.tail = null)); + push(suspenseStackCursor, suspenseStackCursor.current); if (!updateExpirationTime) return null; } return bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ); @@ -6928,41 +6721,40 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { switch (workInProgress.tag) { case 2: updateExpirationTime = workInProgress.type; - null !== current$$1 && - ((current$$1.alternate = null), + null !== current && + ((current.alternate = null), (workInProgress.alternate = null), (workInProgress.effectTag |= 2)); - current$$1 = workInProgress.pendingProps; - renderState = getMaskedContext( - workInProgress, - contextStackCursor.current - ); + current = workInProgress.pendingProps; + context = getMaskedContext(workInProgress, contextStackCursor.current); prepareToReadContext(workInProgress, renderExpirationTime); - renderState = renderWithHooks( + context = renderWithHooks( null, workInProgress, updateExpirationTime, - current$$1, - renderState, + current, + context, renderExpirationTime ); workInProgress.effectTag |= 1; if ( - "object" === typeof renderState && - null !== renderState && - "function" === typeof renderState.render && - void 0 === renderState.$$typeof + "object" === typeof context && + null !== context && + "function" === typeof context.render && + void 0 === context.$$typeof ) { workInProgress.tag = 1; - resetHooks(); + workInProgress.memoizedState = null; + workInProgress.updateQueue = null; if (isContextProvider(updateExpirationTime)) { var hasContext = !0; pushContextProvider(workInProgress); } else hasContext = !1; workInProgress.memoizedState = - null !== renderState.state && void 0 !== renderState.state - ? renderState.state + null !== context.state && void 0 !== context.state + ? context.state : null; + initializeUpdateQueue(workInProgress); var getDerivedStateFromProps = updateExpirationTime.getDerivedStateFromProps; "function" === typeof getDerivedStateFromProps && @@ -6970,15 +6762,15 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { workInProgress, updateExpirationTime, getDerivedStateFromProps, - current$$1 + current ); - renderState.updater = classComponentUpdater; - workInProgress.stateNode = renderState; - renderState._reactInternalFiber = workInProgress; + context.updater = classComponentUpdater; + workInProgress.stateNode = context; + context._reactInternalFiber = workInProgress; mountClassInstance( workInProgress, updateExpirationTime, - current$$1, + current, renderExpirationTime ); workInProgress = finishClassComponent( @@ -6994,127 +6786,129 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { reconcileChildren( null, workInProgress, - renderState, + context, renderExpirationTime ), (workInProgress = workInProgress.child); return workInProgress; case 16: - 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." - ); + 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." + ); } return workInProgress; case 0: return ( (updateExpirationTime = workInProgress.type), - (renderState = workInProgress.pendingProps), - (renderState = + (context = workInProgress.pendingProps), + (context = workInProgress.elementType === updateExpirationTime - ? renderState - : resolveDefaultProps(updateExpirationTime, renderState)), + ? context + : resolveDefaultProps(updateExpirationTime, context)), updateFunctionComponent( - current$$1, + current, workInProgress, updateExpirationTime, - renderState, + context, renderExpirationTime ) ); case 1: return ( (updateExpirationTime = workInProgress.type), - (renderState = workInProgress.pendingProps), - (renderState = + (context = workInProgress.pendingProps), + (context = workInProgress.elementType === updateExpirationTime - ? renderState - : resolveDefaultProps(updateExpirationTime, renderState)), + ? context + : resolveDefaultProps(updateExpirationTime, context)), updateClassComponent( - current$$1, + current, workInProgress, updateExpirationTime, - renderState, + context, renderExpirationTime ) ); case 3: pushHostRootContext(workInProgress); updateExpirationTime = workInProgress.updateQueue; - if (null === updateExpirationTime) + if (null === current || 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." ); - renderState = workInProgress.memoizedState; - renderState = null !== renderState ? renderState.element : null; + updateExpirationTime = workInProgress.pendingProps; + context = workInProgress.memoizedState; + context = null !== context ? context.element : null; + cloneUpdateQueue(current, workInProgress); processUpdateQueue( workInProgress, updateExpirationTime, - workInProgress.pendingProps, null, renderExpirationTime ); updateExpirationTime = workInProgress.memoizedState.element; - updateExpirationTime === renderState + updateExpirationTime === context ? (workInProgress = bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime )) : (reconcileChildren( - current$$1, + current, workInProgress, updateExpirationTime, renderExpirationTime @@ -7124,11 +6918,10 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { case 5: return ( pushHostContext(workInProgress), - null === current$$1 && tryToClaimNextHydratableInstance(workInProgress), (updateExpirationTime = workInProgress.pendingProps.children), - markRef(current$$1, workInProgress), + markRef(current, workInProgress), reconcileChildren( - current$$1, + current, workInProgress, updateExpirationTime, renderExpirationTime @@ -7137,13 +6930,10 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { workInProgress ); case 6: - return ( - null === current$$1 && tryToClaimNextHydratableInstance(workInProgress), - null - ); + return null; case 13: return updateSuspenseComponent( - current$$1, + current, workInProgress, renderExpirationTime ); @@ -7154,7 +6944,7 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { workInProgress.stateNode.containerInfo ), (updateExpirationTime = workInProgress.pendingProps), - null === current$$1 + null === current ? (workInProgress.child = reconcileChildFibers( workInProgress, null, @@ -7162,7 +6952,7 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { renderExpirationTime )) : reconcileChildren( - current$$1, + current, workInProgress, updateExpirationTime, renderExpirationTime @@ -7172,23 +6962,23 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { case 11: return ( (updateExpirationTime = workInProgress.type), - (renderState = workInProgress.pendingProps), - (renderState = + (context = workInProgress.pendingProps), + (context = workInProgress.elementType === updateExpirationTime - ? renderState - : resolveDefaultProps(updateExpirationTime, renderState)), + ? context + : resolveDefaultProps(updateExpirationTime, context)), updateForwardRef( - current$$1, + current, workInProgress, updateExpirationTime, - renderState, + context, renderExpirationTime ) ); case 7: return ( reconcileChildren( - current$$1, + current, workInProgress, workInProgress.pendingProps, renderExpirationTime @@ -7198,7 +6988,7 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { case 8: return ( reconcileChildren( - current$$1, + current, workInProgress, workInProgress.pendingProps.children, renderExpirationTime @@ -7208,7 +6998,7 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { case 12: return ( reconcileChildren( - current$$1, + current, workInProgress, workInProgress.pendingProps.children, renderExpirationTime @@ -7218,27 +7008,32 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { case 10: a: { updateExpirationTime = workInProgress.type._context; - renderState = workInProgress.pendingProps; + context = workInProgress.pendingProps; getDerivedStateFromProps = workInProgress.memoizedProps; - 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) { + 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) + ) { if ( - getDerivedStateFromProps.children === renderState.children && + getDerivedStateFromProps.children === context.children && !didPerformWorkStackCursor.current ) { workInProgress = bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ); @@ -7246,14 +7041,15 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { } } else for ( - oldValue = workInProgress.child, - null !== oldValue && (oldValue.return = workInProgress); - null !== oldValue; + context$jscomp$0 = workInProgress.child, + null !== context$jscomp$0 && + (context$jscomp$0.return = workInProgress); + null !== context$jscomp$0; ) { - var list = oldValue.dependencies; + var list = context$jscomp$0.dependencies; if (null !== list) { - getDerivedStateFromProps = oldValue.child; + getDerivedStateFromProps = context$jscomp$0.child; for ( var dependency = list.firstContext; null !== dependency; @@ -7263,18 +7059,18 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { dependency.context === updateExpirationTime && 0 !== (dependency.observedBits & hasContext) ) { - 1 === oldValue.tag && + 1 === context$jscomp$0.tag && ((dependency = createUpdate(renderExpirationTime, null)), (dependency.tag = 2), - enqueueUpdate(oldValue, dependency)); - oldValue.expirationTime < renderExpirationTime && - (oldValue.expirationTime = renderExpirationTime); - dependency = oldValue.alternate; + enqueueUpdate(context$jscomp$0, dependency)); + context$jscomp$0.expirationTime < renderExpirationTime && + (context$jscomp$0.expirationTime = renderExpirationTime); + dependency = context$jscomp$0.alternate; null !== dependency && dependency.expirationTime < renderExpirationTime && (dependency.expirationTime = renderExpirationTime); scheduleWorkOnParentPath( - oldValue.return, + context$jscomp$0.return, renderExpirationTime ); list.expirationTime < renderExpirationTime && @@ -7285,16 +7081,16 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { } } else getDerivedStateFromProps = - 10 === oldValue.tag - ? oldValue.type === workInProgress.type + 10 === context$jscomp$0.tag + ? context$jscomp$0.type === workInProgress.type ? null - : oldValue.child - : oldValue.child; + : context$jscomp$0.child + : context$jscomp$0.child; if (null !== getDerivedStateFromProps) - getDerivedStateFromProps.return = oldValue; + getDerivedStateFromProps.return = context$jscomp$0; else for ( - getDerivedStateFromProps = oldValue; + getDerivedStateFromProps = context$jscomp$0; null !== getDerivedStateFromProps; ) { @@ -7302,21 +7098,20 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { getDerivedStateFromProps = null; break; } - oldValue = getDerivedStateFromProps.sibling; - if (null !== oldValue) { - oldValue.return = getDerivedStateFromProps.return; - getDerivedStateFromProps = oldValue; + context$jscomp$0 = getDerivedStateFromProps.sibling; + if (null !== context$jscomp$0) { + context$jscomp$0.return = getDerivedStateFromProps.return; + getDerivedStateFromProps = context$jscomp$0; break; } getDerivedStateFromProps = getDerivedStateFromProps.return; } - oldValue = getDerivedStateFromProps; + context$jscomp$0 = getDerivedStateFromProps; } - } reconcileChildren( - current$$1, + current, workInProgress, - renderState.children, + context.children, renderExpirationTime ); workInProgress = workInProgress.child; @@ -7324,18 +7119,15 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { return workInProgress; case 9: return ( - (renderState = workInProgress.type), + (context = workInProgress.type), (hasContext = workInProgress.pendingProps), (updateExpirationTime = hasContext.children), prepareToReadContext(workInProgress, renderExpirationTime), - (renderState = readContext( - renderState, - hasContext.unstable_observedBits - )), - (updateExpirationTime = updateExpirationTime(renderState)), + (context = readContext(context, hasContext.unstable_observedBits)), + (updateExpirationTime = updateExpirationTime(context)), (workInProgress.effectTag |= 1), reconcileChildren( - current$$1, + current, workInProgress, updateExpirationTime, renderExpirationTime @@ -7344,16 +7136,16 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { ); case 14: return ( - (renderState = workInProgress.type), + (context = workInProgress.type), (hasContext = resolveDefaultProps( - renderState, + context, workInProgress.pendingProps )), - (hasContext = resolveDefaultProps(renderState.type, hasContext)), + (hasContext = resolveDefaultProps(context.type, hasContext)), updateMemoComponent( - current$$1, + current, workInProgress, - renderState, + context, hasContext, updateExpirationTime, renderExpirationTime @@ -7361,7 +7153,7 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { ); case 15: return updateSimpleMemoComponent( - current$$1, + current, workInProgress, workInProgress.type, workInProgress.pendingProps, @@ -7371,30 +7163,25 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { case 17: return ( (updateExpirationTime = workInProgress.type), - (renderState = workInProgress.pendingProps), - (renderState = + (context = workInProgress.pendingProps), + (context = workInProgress.elementType === updateExpirationTime - ? renderState - : resolveDefaultProps(updateExpirationTime, renderState)), - null !== current$$1 && - ((current$$1.alternate = null), + ? context + : resolveDefaultProps(updateExpirationTime, context)), + null !== current && + ((current.alternate = null), (workInProgress.alternate = null), (workInProgress.effectTag |= 2)), (workInProgress.tag = 1), isContextProvider(updateExpirationTime) - ? ((current$$1 = !0), pushContextProvider(workInProgress)) - : (current$$1 = !1), + ? ((current = !0), pushContextProvider(workInProgress)) + : (current = !1), prepareToReadContext(workInProgress, renderExpirationTime), - constructClassInstance( - workInProgress, - updateExpirationTime, - renderState, - renderExpirationTime - ), + constructClassInstance(workInProgress, updateExpirationTime, context), mountClassInstance( workInProgress, updateExpirationTime, - renderState, + context, renderExpirationTime ), finishClassComponent( @@ -7402,13 +7189,13 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { workInProgress, updateExpirationTime, !0, - current$$1, + current, renderExpirationTime ) ); case 19: return updateSuspenseListComponent( - current$$1, + current, workInProgress, renderExpirationTime ); @@ -7459,9 +7246,6 @@ 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); @@ -7479,7 +7263,7 @@ function resolveLazyComponentTag(Component) { function createWorkInProgress(current, pendingProps) { var workInProgress = current.alternate; null === workInProgress - ? ((workInProgress = createFiber( + ? ((workInProgress = new FiberNode( current.tag, pendingProps, current.key, @@ -7546,7 +7330,7 @@ function createFiberFromTypeAndProps( break; case REACT_PROFILER_TYPE: return ( - (type = createFiber(12, pendingProps, key, mode | 8)), + (type = new FiberNode(12, pendingProps, key, mode | 8)), (type.elementType = REACT_PROFILER_TYPE), (type.type = REACT_PROFILER_TYPE), (type.expirationTime = expirationTime), @@ -7554,7 +7338,7 @@ function createFiberFromTypeAndProps( ); case REACT_SUSPENSE_TYPE: return ( - (type = createFiber(13, pendingProps, key, mode)), + (type = new FiberNode(13, pendingProps, key, mode)), (type.type = REACT_SUSPENSE_TYPE), (type.elementType = REACT_SUSPENSE_TYPE), (type.expirationTime = expirationTime), @@ -7562,7 +7346,7 @@ function createFiberFromTypeAndProps( ); case REACT_SUSPENSE_LIST_TYPE: return ( - (type = createFiber(19, pendingProps, key, mode)), + (type = new FiberNode(19, pendingProps, key, mode)), (type.elementType = REACT_SUSPENSE_LIST_TYPE), (type.expirationTime = expirationTime), type @@ -7586,6 +7370,9 @@ 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: " + @@ -7593,24 +7380,24 @@ function createFiberFromTypeAndProps( "." ); } - key = createFiber(fiberTag, pendingProps, key, mode); + key = new FiberNode(fiberTag, pendingProps, key, mode); key.elementType = type; key.type = owner; key.expirationTime = expirationTime; return key; } function createFiberFromFragment(elements, mode, expirationTime, key) { - elements = createFiber(7, elements, key, mode); + elements = new FiberNode(7, elements, key, mode); elements.expirationTime = expirationTime; return elements; } function createFiberFromText(content, mode, expirationTime) { - content = createFiber(6, content, null, mode); + content = new FiberNode(6, content, null, mode); content.expirationTime = expirationTime; return content; } function createFiberFromPortal(portal, mode, expirationTime) { - mode = createFiber( + mode = new FiberNode( 4, null !== portal.children ? portal.children : [], portal.key, @@ -7669,11 +7456,6 @@ 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) { @@ -7688,14 +7470,10 @@ function findHostInstance(component) { return null === component ? null : component.stateNode; } function updateContainer(element, container, parentComponent, callback) { - var current$$1 = container.current, + var current = container.current, currentTime = requestCurrentTimeForUpdate(), suspenseConfig = ReactCurrentBatchConfig.suspense; - currentTime = computeExpirationForFiber( - currentTime, - current$$1, - suspenseConfig - ); + currentTime = computeExpirationForFiber(currentTime, current, suspenseConfig); a: if (parentComponent) { parentComponent = parentComponent._reactInternalFiber; b: { @@ -7746,8 +7524,8 @@ function updateContainer(element, container, parentComponent, callback) { container.payload = { element: element }; callback = void 0 === callback ? null : callback; null !== callback && (container.callback = callback); - enqueueUpdate(current$$1, container); - scheduleUpdateOnFiber(current$$1, currentTime); + enqueueUpdate(current, container); + scheduleWork(current, currentTime); return currentTime; } function createPortal(children, containerInfo, implementation) { @@ -7761,11 +7539,6 @@ 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; @@ -7776,8 +7549,15 @@ function findNodeHandle(componentOrHandle) { return null == componentOrHandle ? componentOrHandle : componentOrHandle.canonical - ? componentOrHandle.canonical._nativeTag - : componentOrHandle._nativeTag; + ? componentOrHandle.canonical._nativeTag + : componentOrHandle._nativeTag; +} +function unmountComponentAtNode(containerTag) { + var root = roots.get(containerTag); + root && + updateContainer(null, root, null, function() { + roots.delete(containerTag); + }); } batchedUpdatesImpl = function(fn, a) { var prevExecutionContext = executionContext; @@ -7789,299 +7569,117 @@ batchedUpdatesImpl = function(fn, a) { executionContext === NoContext && flushSyncCallbackQueue(); } }; -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; - }, - 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) - : ""; - } - } - }; +var roots = new Map(); (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 - }) - ); + 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; + }, + 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.11.0", - rendererPackageName: "react-native-renderer" + 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) + } }); -var ReactNativeRenderer$2 = { default: ReactNativeRenderer }, - ReactNativeRenderer$3 = - (ReactNativeRenderer$2 && ReactNativeRenderer) || ReactNativeRenderer$2; -module.exports = ReactNativeRenderer$3.default || ReactNativeRenderer$3; +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; diff --git a/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js b/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js index b6719c3c3ecd50..2bac9e25f6cf5d 100644 --- a/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js +++ b/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js @@ -5,6 +5,7 @@ * LICENSE file in the root directory of this source tree. * * @noflow + * @nolint * @preventMunge * @generated */ @@ -14,86 +15,17 @@ require("react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore"); var ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/ReactNativePrivateInterface"), React = require("react"), Scheduler = require("scheduler"), - 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 + - "`." - ); - } - } - } + tracing = require("scheduler/tracing"); +function getParent(inst) { + do inst = inst.return; + while (inst && 5 !== inst.tag); + return inst ? inst : null; } -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; +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); } -var plugins = [], - eventNameDispatchConfigs = {}, - registrationNameModules = {}; function invokeGuardedCallbackImpl(name, func, context, a, b, c, d, e, f) { var funcArgs = Array.prototype.slice.call(arguments, 3); try { @@ -164,74 +96,6 @@ 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; @@ -249,6 +113,7 @@ function getListener(inst, registrationName) { case "onMouseMoveCapture": case "onMouseUp": case "onMouseUpCapture": + case "onMouseEnter": (props = !props.disabled) || ((inst = inst.type), (props = !( @@ -273,15 +138,21 @@ function getListener(inst, registrationName) { ); return listener; } -function getParent(inst) { - do inst = inst.return; - while (inst && 5 !== inst.tag); - return inst ? inst : null; +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 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 forEachAccumulated(arr, cb, scope) { + Array.isArray(arr) ? arr.forEach(cb, scope) : arr && cb.call(scope, arr); } function accumulateDirectionalDispatches(inst, phase, event) { if ( @@ -349,8 +220,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) @@ -503,53 +374,27 @@ 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))) - : console.warn( - "Cannot record touch move without a touch start.\nTouch Move: %s\n", - "Touch Bank: %s", - printTouch(touch), - printTouchBank() - ); + 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))); } 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))) - : 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; + 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))); } var ResponderTouchHistoryStore = { recordTouchTrack: function(topLevelType, nativeEvent) { @@ -589,10 +434,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; @@ -682,13 +527,7 @@ var eventTypes = { "topTouchCancel" === topLevelType ) if (0 <= trackedTouchCount) --trackedTouchCount; - else - return ( - console.warn( - "Ended a touch event which was not counted in `trackedTouchCount`." - ), - null - ); + else return null; ResponderTouchHistoryStore.recordTouchTrack(topLevelType, nativeEvent); if ( targetInst && @@ -700,10 +539,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; @@ -857,10 +696,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, @@ -923,8 +762,8 @@ var eventTypes = { (topLevelType = shouldSetEventType ? eventTypes.responderTerminate : topLevelType - ? eventTypes.responderRelease - : null) + ? eventTypes.responderRelease + : null) ) (nativeEvent = ResponderSyntheticEvent.getPooled( topLevelType, @@ -948,67 +787,168 @@ 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; -injection.injectEventPluginOrder([ +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([ "ResponderEventPlugin", "ReactNativeBridgeEventPlugin" ]); -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, +recomputePluginOrdering(); +var injectedNamesToPlugins$jscomp$inline_94 = { + ResponderEventPlugin: ResponderEventPlugin, + ReactNativeBridgeEventPlugin: { + eventTypes: {}, + extractEvents: function( + topLevelType, targetInst, nativeEvent, nativeEventTarget - ); - if (bubbleDispatchConfig) - forEachAccumulated(topLevelType, accumulateTwoPhaseDispatchesSingle); - else if (directDispatchConfig) - forEachAccumulated(topLevelType, accumulateDirectDispatchesSingle); - else return null; - return topLevelType; + ) { + 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 + ) { + if (namesToPlugins[pluginName$jscomp$inline_96]) + throw Error( + "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + + pluginName$jscomp$inline_96 + + "`." + ); + namesToPlugins[ + pluginName$jscomp$inline_96 + ] = pluginModule$jscomp$inline_97; + isOrderingDirty$jscomp$inline_95 = !0; } } -}); -var enableNativeTargetAsInstance = require("../shims/ReactFeatureFlags") - .enableNativeTargetAsInstance, - instanceCache = new Map(), +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); @@ -1016,21 +956,27 @@ function batchedUpdates(fn, bookkeeping) { 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)) + 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++ ) - for (bookkeeping = 0; bookkeeping < fn.length; bookkeeping++) - restoreStateOfTarget(fn[bookkeeping]); + 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 EMPTY_NATIVE_EVENT = {}; @@ -1038,9 +984,7 @@ function _receiveRootNodeIDEvent(rootNodeID, topLevelType, nativeEventParam) { var nativeEvent = nativeEventParam || EMPTY_NATIVE_EVENT, inst = getInstanceFromTag(rootNodeID), target = null; - enableNativeTargetAsInstance - ? null != inst && (target = inst.stateNode) - : (target = nativeEvent.target); + null != inst && (target = inst.stateNode); batchedUpdates(function() { var events = target; for (var events$jscomp$0 = null, i = 0; i < plugins.length; i++) { @@ -1115,17 +1059,11 @@ getFiberCurrentPropsFromNode = function(stateNode) { }; getInstanceFromNode = getInstanceFromTag; getNodeFromInstance = function(inst) { - 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); + 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 tag; + return inst; }; ResponderEventPlugin.injection.injectGlobalResponderHandler({ onChange: function(from, to, blockNativeResponder) { @@ -1160,11 +1098,9 @@ 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; -hasSymbol && Symbol.for("react.fundamental"); -hasSymbol && Symbol.for("react.responder"); -hasSymbol && Symbol.for("react.scope"); -var MAYBE_ITERATOR_SYMBOL = "function" === typeof Symbol && Symbol.iterator; + 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; function getIteratorFn(maybeIterable) { if (null === maybeIterable || "object" !== typeof maybeIterable) return null; maybeIterable = @@ -1174,9 +1110,10 @@ function getIteratorFn(maybeIterable) { } function initializeLazyComponentType(lazyComponent) { if (-1 === lazyComponent._status) { - lazyComponent._status = 0; - var ctor = lazyComponent._ctor; + var ctor = lazyComponent._result; + ctor || (ctor = lazyComponent._ctor); ctor = ctor(); + lazyComponent._status = 0; lazyComponent._result = ctor; ctor.then( function(moduleObject) { @@ -1213,9 +1150,9 @@ function getComponentName(type) { if ("object" === typeof type) switch (type.$$typeof) { case REACT_CONTEXT_TYPE: - return "Context.Consumer"; + return (type.displayName || "Context") + ".Consumer"; case REACT_PROVIDER_TYPE: - return "Context.Provider"; + return (type._context.displayName || "Context") + ".Provider"; case REACT_FORWARD_REF_TYPE: var innerType = type.render; innerType = innerType.displayName || innerType.name || ""; @@ -1225,6 +1162,8 @@ 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); @@ -1405,8 +1344,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)) { @@ -1584,10 +1523,10 @@ var ReactNativeFiberHostComponent = (function() { } var _proto = ReactNativeFiberHostComponent.prototype; _proto.blur = function() { - ReactNativePrivateInterface.TextInputState.blurTextInput(this._nativeTag); + ReactNativePrivateInterface.TextInputState.blurTextInput(this); }; _proto.focus = function() { - ReactNativePrivateInterface.TextInputState.focusTextInput(this._nativeTag); + ReactNativePrivateInterface.TextInputState.focusTextInput(this); }; _proto.measure = function(callback) { ReactNativePrivateInterface.UIManager.measure( @@ -1631,7 +1570,7 @@ var ReactNativeFiberHostComponent = (function() { }; return ReactNativeFiberHostComponent; })(); -function shim$1() { +function shim() { throw Error( "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." ); @@ -1669,45 +1608,7 @@ function finalizeInitialChildren(parentInstance) { } var scheduleTimeout = setTimeout, cancelTimeout = clearTimeout, - 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 = [], + valueStack = [], index = -1; function pop(cursor) { 0 > index || @@ -1744,21 +1645,17 @@ function isContextProvider(type) { type = type.childContextTypes; return null !== type && void 0 !== type; } -function popContext(fiber) { - pop(didPerformWorkStackCursor, fiber); - pop(contextStackCursor, fiber); -} -function popTopLevelContextObject(fiber) { - pop(didPerformWorkStackCursor, fiber); - pop(contextStackCursor, fiber); +function popContext() { + pop(didPerformWorkStackCursor); + pop(contextStackCursor); } function pushTopLevelContextObject(fiber, context, didChange) { if (contextStackCursor.current !== emptyContextObject) throw Error( "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." ); - push(contextStackCursor, context, fiber); - push(didPerformWorkStackCursor, didChange, fiber); + push(contextStackCursor, context); + push(didPerformWorkStackCursor, didChange); } function processChildContext(fiber, type, parentContext) { var instance = fiber.stateNode; @@ -1776,17 +1673,13 @@ function processChildContext(fiber, type, parentContext) { return Object.assign({}, parentContext, {}, instance); } function pushContextProvider(workInProgress) { - var instance = workInProgress.stateNode; - instance = - (instance && instance.__reactInternalMemoizedMergedChildContext) || + workInProgress = + ((workInProgress = workInProgress.stateNode) && + workInProgress.__reactInternalMemoizedMergedChildContext) || emptyContextObject; previousContext = contextStackCursor.current; - push(contextStackCursor, instance, workInProgress); - push( - didPerformWorkStackCursor, - didPerformWorkStackCursor.current, - workInProgress - ); + push(contextStackCursor, workInProgress); + push(didPerformWorkStackCursor, didPerformWorkStackCursor.current); return !0; } function invalidateContextProvider(workInProgress, type, didChange) { @@ -1796,13 +1689,17 @@ 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 - ? ((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); + ? ((workInProgress = processChildContext( + workInProgress, + type, + previousContext + )), + (instance.__reactInternalMemoizedMergedChildContext = workInProgress), + pop(didPerformWorkStackCursor), + pop(contextStackCursor), + push(contextStackCursor, workInProgress)) + : pop(didPerformWorkStackCursor); + push(didPerformWorkStackCursor, didChange); } var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback, @@ -1929,18 +1826,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 is$1 = "function" === typeof Object.is ? Object.is : is, +var objectIs = "function" === typeof Object.is ? Object.is : is, hasOwnProperty = Object.prototype.hasOwnProperty; function shallowEqual(objA, objB) { - if (is$1(objA, objB)) return !0; + if (objectIs(objA, objB)) return !0; if ( "object" !== typeof objA || null === objA || @@ -1954,11 +1851,48 @@ function shallowEqual(objA, objB) { for (keysB = 0; keysB < keysA.length; keysB++) if ( !hasOwnProperty.call(objB, keysA[keysB]) || - !is$1(objA[keysA[keysB]], objB[keysA[keysB]]) + !objectIs(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); @@ -1976,14 +1910,9 @@ 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, providerFiber); + pop(valueCursor); providerFiber.type._context._currentValue = currentValue; } function scheduleWorkOnParentPath(parent, renderExpirationTime) { @@ -2038,237 +1967,195 @@ function readContext(context, observedBits) { return context._currentValue; } var hasForceUpdate = !1; -function createUpdateQueue(baseState) { - return { - baseState: baseState, - firstUpdate: null, - lastUpdate: null, - firstCapturedUpdate: null, - lastCapturedUpdate: null, - firstEffect: null, - lastEffect: null, - firstCapturedEffect: null, - lastCapturedEffect: null +function initializeUpdateQueue(fiber) { + fiber.updateQueue = { + baseState: fiber.memoizedState, + baseQueue: null, + shared: { pending: null }, + effects: null }; } -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 cloneUpdateQueue(current, workInProgress) { + current = current.updateQueue; + workInProgress.updateQueue === current && + (workInProgress.updateQueue = { + baseState: current.baseState, + baseQueue: current.baseQueue, + shared: current.shared, + effects: current.effects + }); } function createUpdate(expirationTime, suspenseConfig) { - return { + expirationTime = { expirationTime: expirationTime, suspenseConfig: suspenseConfig, tag: 0, payload: null, callback: null, - next: null, - nextEffect: null + next: null }; -} -function appendUpdateToQueue(queue, update) { - null === queue.lastUpdate - ? (queue.firstUpdate = queue.lastUpdate = update) - : ((queue.lastUpdate.next = update), (queue.lastUpdate = update)); + return (expirationTime.next = expirationTime); } function enqueueUpdate(fiber, 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)); + 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; + } } 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 && - 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; + 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)); } function processUpdateQueue( - workInProgress, - queue, + workInProgress$jscomp$0, props, instance, renderExpirationTime ) { + var queue = workInProgress$jscomp$0.updateQueue; hasForceUpdate = !1; - queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue); - for ( - var newBaseState = queue.baseState, - newFirstUpdate = null, - newExpirationTime = 0, - 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; + 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)); } - 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; + if (null !== baseQueue) { + baseFirst = baseQueue.next; + var newState = queue.baseState, + 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; } - 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) { - 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); + 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); + } } - effect = effect.nextEffect; - } } var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig, emptyRefsObject = new React.Component().refs; @@ -2285,10 +2172,8 @@ function applyDerivedStateFromProps( ? ctor : Object.assign({}, ctor, getDerivedStateFromProps); workInProgress.memoizedState = getDerivedStateFromProps; - nextProps = workInProgress.updateQueue; - null !== nextProps && - 0 === workInProgress.expirationTime && - (nextProps.baseState = getDerivedStateFromProps); + 0 === workInProgress.expirationTime && + (workInProgress.updateQueue.baseState = getDerivedStateFromProps); } var classComponentUpdater = { isMounted: function(component) { @@ -2307,7 +2192,7 @@ var classComponentUpdater = { null !== callback && (suspenseConfig.callback = callback); enqueueUpdate(inst, suspenseConfig); - scheduleUpdateOnFiber(inst, currentTime); + scheduleWork(inst, currentTime); }, enqueueReplaceState: function(inst, payload, callback) { inst = inst._reactInternalFiber; @@ -2321,7 +2206,7 @@ var classComponentUpdater = { null !== callback && (suspenseConfig.callback = callback); enqueueUpdate(inst, suspenseConfig); - scheduleUpdateOnFiber(inst, currentTime); + scheduleWork(inst, currentTime); }, enqueueForceUpdate: function(inst, callback) { inst = inst._reactInternalFiber; @@ -2334,7 +2219,7 @@ var classComponentUpdater = { null !== callback && (suspenseConfig.callback = callback); enqueueUpdate(inst, suspenseConfig); - scheduleUpdateOnFiber(inst, currentTime); + scheduleWork(inst, currentTime); } }; function checkShouldComponentUpdate( @@ -2350,8 +2235,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, @@ -2403,6 +2288,7 @@ 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)) @@ -2410,16 +2296,8 @@ function mountClassInstance( ? previousContext : contextStackCursor.current), (instance.context = getMaskedContext(workInProgress, contextType))); - contextType = workInProgress.updateQueue; - null !== contextType && - (processUpdateQueue( - workInProgress, - contextType, - newProps, - instance, - renderExpirationTime - ), - (instance.state = workInProgress.memoizedState)); + processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); + instance.state = workInProgress.memoizedState; contextType = ctor.getDerivedStateFromProps; "function" === typeof contextType && (applyDerivedStateFromProps(workInProgress, ctor, contextType, newProps), @@ -2435,21 +2313,18 @@ function mountClassInstance( instance.UNSAFE_componentWillMount(), ctor !== instance.state && classComponentUpdater.enqueueReplaceState(instance, instance.state, null), - (contextType = workInProgress.updateQueue), - null !== contextType && - (processUpdateQueue( - workInProgress, - contextType, - newProps, - instance, - renderExpirationTime - ), - (instance.state = workInProgress.memoizedState))); + processUpdateQueue( + workInProgress, + newProps, + instance, + renderExpirationTime + ), + (instance.state = workInProgress.memoizedState)); "function" === typeof instance.componentDidMount && (workInProgress.effectTag |= 4); } var isArray = Array.isArray; -function coerceRef(returnFiber, current$$1, element) { +function coerceRef(returnFiber, current, element) { returnFiber = element.ref; if ( null !== returnFiber && @@ -2461,7 +2336,7 @@ function coerceRef(returnFiber, current$$1, element) { if (element) { if (1 !== element.tag) throw Error( - "Function components cannot have refs. Did you mean to use React.forwardRef()?" + "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" ); var inst = element.stateNode; } @@ -2473,19 +2348,19 @@ function coerceRef(returnFiber, current$$1, element) { ); var stringRef = "" + returnFiber; if ( - null !== current$$1 && - null !== current$$1.ref && - "function" === typeof current$$1.ref && - current$$1.ref._stringRef === stringRef + null !== current && + null !== current.ref && + "function" === typeof current.ref && + current.ref._stringRef === stringRef ) - return current$$1.ref; - current$$1 = function(value) { + return current.ref; + current = function(value) { var refs = inst.refs; refs === emptyRefsObject && (refs = inst.refs = {}); null === value ? delete refs[stringRef] : (refs[stringRef] = value); }; - current$$1._stringRef = stringRef; - return current$$1; + current._stringRef = stringRef; + return current; } if ("string" !== typeof returnFiber) throw Error( @@ -2537,8 +2412,8 @@ function ChildReconciler(shouldTrackSideEffects) { (currentFirstChild = currentFirstChild.sibling); return returnFiber; } - function useFiber(fiber, pendingProps, expirationTime) { - fiber = createWorkInProgress(fiber, pendingProps, expirationTime); + function useFiber(fiber, pendingProps) { + fiber = createWorkInProgress(fiber, pendingProps); fiber.index = 0; fiber.sibling = null; return fiber; @@ -2563,31 +2438,26 @@ function ChildReconciler(shouldTrackSideEffects) { (newFiber.effectTag = 2); return newFiber; } - function updateTextNode( - returnFiber, - current$$1, - textContent, - expirationTime - ) { - if (null === current$$1 || 6 !== current$$1.tag) + function updateTextNode(returnFiber, current, textContent, expirationTime) { + if (null === current || 6 !== current.tag) return ( - (current$$1 = createFiberFromText( + (current = createFiberFromText( textContent, returnFiber.mode, expirationTime )), - (current$$1.return = returnFiber), - current$$1 + (current.return = returnFiber), + current ); - current$$1 = useFiber(current$$1, textContent, expirationTime); - current$$1.return = returnFiber; - return current$$1; + current = useFiber(current, textContent); + current.return = returnFiber; + return current; } - function updateElement(returnFiber, current$$1, element, expirationTime) { - if (null !== current$$1 && current$$1.elementType === element.type) + function updateElement(returnFiber, current, element, expirationTime) { + if (null !== current && current.elementType === element.type) return ( - (expirationTime = useFiber(current$$1, element.props, expirationTime)), - (expirationTime.ref = coerceRef(returnFiber, current$$1, element)), + (expirationTime = useFiber(current, element.props)), + (expirationTime.ref = coerceRef(returnFiber, current, element)), (expirationTime.return = returnFiber), expirationTime ); @@ -2599,51 +2469,45 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime ); - expirationTime.ref = coerceRef(returnFiber, current$$1, element); + expirationTime.ref = coerceRef(returnFiber, current, element); expirationTime.return = returnFiber; return expirationTime; } - function updatePortal(returnFiber, current$$1, portal, expirationTime) { + function updatePortal(returnFiber, current, portal, expirationTime) { if ( - null === current$$1 || - 4 !== current$$1.tag || - current$$1.stateNode.containerInfo !== portal.containerInfo || - current$$1.stateNode.implementation !== portal.implementation + null === current || + 4 !== current.tag || + current.stateNode.containerInfo !== portal.containerInfo || + current.stateNode.implementation !== portal.implementation ) return ( - (current$$1 = createFiberFromPortal( + (current = createFiberFromPortal( portal, returnFiber.mode, expirationTime )), - (current$$1.return = returnFiber), - current$$1 + (current.return = returnFiber), + current ); - current$$1 = useFiber(current$$1, portal.children || [], expirationTime); - current$$1.return = returnFiber; - return current$$1; + current = useFiber(current, portal.children || []); + current.return = returnFiber; + return current; } - function updateFragment( - returnFiber, - current$$1, - fragment, - expirationTime, - key - ) { - if (null === current$$1 || 7 !== current$$1.tag) + function updateFragment(returnFiber, current, fragment, expirationTime, key) { + if (null === current || 7 !== current.tag) return ( - (current$$1 = createFiberFromFragment( + (current = createFiberFromFragment( fragment, returnFiber.mode, expirationTime, key )), - (current$$1.return = returnFiber), - current$$1 + (current.return = returnFiber), + current ); - current$$1 = useFiber(current$$1, fragment, expirationTime); - current$$1.return = returnFiber; - return current$$1; + current = useFiber(current, fragment); + current.return = returnFiber; + return current; } function createChild(returnFiber, newChild, expirationTime) { if ("string" === typeof newChild || "number" === typeof newChild) @@ -3006,39 +2870,48 @@ function ChildReconciler(shouldTrackSideEffects) { null !== isUnkeyedTopLevelFragment; ) { - 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; + 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; + } } - else deleteChild(returnFiber, isUnkeyedTopLevelFragment); + deleteRemainingChildren(returnFiber, isUnkeyedTopLevelFragment); + break; + } else deleteChild(returnFiber, isUnkeyedTopLevelFragment); isUnkeyedTopLevelFragment = isUnkeyedTopLevelFragment.sibling; } newChild.type === REACT_FRAGMENT_TYPE @@ -3088,8 +2961,7 @@ function ChildReconciler(shouldTrackSideEffects) { ); currentFirstChild = useFiber( currentFirstChild, - newChild.children || [], - expirationTime + newChild.children || [] ); currentFirstChild.return = returnFiber; returnFiber = currentFirstChild; @@ -3116,11 +2988,7 @@ function ChildReconciler(shouldTrackSideEffects) { (newChild = "" + newChild), null !== currentFirstChild && 6 === currentFirstChild.tag ? (deleteRemainingChildren(returnFiber, currentFirstChild.sibling), - (currentFirstChild = useFiber( - currentFirstChild, - newChild, - expirationTime - )), + (currentFirstChild = useFiber(currentFirstChild, newChild)), (currentFirstChild.return = returnFiber), (returnFiber = currentFirstChild)) : (deleteRemainingChildren(returnFiber, currentFirstChild), @@ -3175,16 +3043,16 @@ function requiredContext(c) { return c; } function pushHostContainer(fiber, nextRootInstance) { - push(rootInstanceStackCursor, nextRootInstance, fiber); - push(contextFiberStackCursor, fiber, fiber); - push(contextStackCursor$1, NO_CONTEXT, fiber); - pop(contextStackCursor$1, fiber); - push(contextStackCursor$1, { isInAParentText: !1 }, fiber); + push(rootInstanceStackCursor, nextRootInstance); + push(contextFiberStackCursor, fiber); + push(contextStackCursor$1, NO_CONTEXT); + pop(contextStackCursor$1); + push(contextStackCursor$1, { isInAParentText: !1 }); } -function popHostContainer(fiber) { - pop(contextStackCursor$1, fiber); - pop(contextFiberStackCursor, fiber); - pop(rootInstanceStackCursor, fiber); +function popHostContainer() { + pop(contextStackCursor$1); + pop(contextFiberStackCursor); + pop(rootInstanceStackCursor); } function pushHostContext(fiber) { requiredContext(rootInstanceStackCursor.current); @@ -3201,23 +3069,19 @@ function pushHostContext(fiber) { ? { isInAParentText: nextContext } : context; context !== nextContext && - (push(contextFiberStackCursor, fiber, fiber), - push(contextStackCursor$1, nextContext, fiber)); + (push(contextFiberStackCursor, fiber), + push(contextStackCursor$1, nextContext)); } function popHostContext(fiber) { contextFiberStackCursor.current === fiber && - (pop(contextStackCursor$1, fiber), pop(contextFiberStackCursor, fiber)); + (pop(contextStackCursor$1), pop(contextFiberStackCursor)); } var suspenseStackCursor = { current: 0 }; function findFirstSuspended(row) { for (var node = row; null !== node; ) { if (13 === node.tag) { var state = node.memoizedState; - if ( - null !== state && - ((state = state.dehydrated), - null === state || shim$1(state) || shim$1(state)) - ) + if (null !== state && (null === state.dehydrated || shim() || shim())) return node; } else if (19 === node.tag && void 0 !== node.memoizedProps.revealOrder) { if (0 !== (node.effectTag & 64)) return node; @@ -3236,24 +3100,16 @@ function findFirstSuspended(row) { } return null; } -function createResponderListener(responder, props) { +function createDeprecatedResponderListener(responder, props) { return { responder: responder, props: props }; } -var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, +var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig, - renderExpirationTime$1 = 0, + renderExpirationTime = 0, currentlyRenderingFiber$1 = null, currentHook = null, - nextCurrentHook = null, - firstWorkInProgressHook = null, workInProgressHook = null, - nextWorkInProgressHook = null, - remainingExpirationTime = 0, - componentUpdateQueue = null, - sideEffectTag = 0, - didScheduleRenderPhaseUpdate = !1, - renderPhaseUpdates = null, - numberOfReRenders = 0; + didScheduleRenderPhaseUpdate = !1; 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." @@ -3262,7 +3118,7 @@ function throwInvalidHookError() { function areHookInputsEqual(nextDeps, prevDeps) { if (null === prevDeps) return !1; for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) - if (!is$1(nextDeps[i], prevDeps[i])) return !1; + if (!objectIs(nextDeps[i], prevDeps[i])) return !1; return !0; } function renderWithHooks( @@ -3270,92 +3126,85 @@ function renderWithHooks( workInProgress, Component, props, - refOrContext, + secondArg, nextRenderExpirationTime ) { - renderExpirationTime$1 = nextRenderExpirationTime; + renderExpirationTime = nextRenderExpirationTime; currentlyRenderingFiber$1 = workInProgress; - 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; + 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); } - 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) + ReactCurrentDispatcher.current = ContextOnlyDispatcher; + workInProgress = null !== currentHook && null !== currentHook.next; + renderExpirationTime = 0; + workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; + didScheduleRenderPhaseUpdate = !1; + if (workInProgress) throw Error( "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." ); - 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; + return current; } function mountWorkInProgressHook() { var hook = { memoizedState: null, baseState: null, + baseQueue: null, queue: null, - baseUpdate: null, next: null }; null === workInProgressHook - ? (firstWorkInProgressHook = workInProgressHook = hook) + ? (currentlyRenderingFiber$1.memoizedState = 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), - (nextWorkInProgressHook = workInProgressHook.next), - (currentHook = nextCurrentHook), - (nextCurrentHook = null !== currentHook ? currentHook.next : null); + (currentHook = nextCurrentHook); else { if (null === nextCurrentHook) throw Error("Rendered more hooks than during the previous render."); currentHook = nextCurrentHook; - var newHook = { + nextCurrentHook = { memoizedState: currentHook.memoizedState, baseState: currentHook.baseState, + baseQueue: currentHook.baseQueue, queue: currentHook.queue, - baseUpdate: currentHook.baseUpdate, next: null }; - workInProgressHook = - null === workInProgressHook - ? (firstWorkInProgressHook = newHook) - : (workInProgressHook.next = newHook); - nextCurrentHook = currentHook.next; + null === workInProgressHook + ? (currentlyRenderingFiber$1.memoizedState = workInProgressHook = nextCurrentHook) + : (workInProgressHook = workInProgressHook.next = nextCurrentHook); } return workInProgressHook; } @@ -3370,74 +3219,100 @@ function updateReducer(reducer) { "Should have a queue. This is likely a bug in React. Please file an issue." ); queue.lastRenderedReducer = reducer; - 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]; - } + 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; } - return [hook.memoizedState, _dispatch]; + current.baseQueue = baseQueue = pendingQueue; + queue.pending = null; } - _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; + if (null !== baseQueue) { + baseQueue = baseQueue.next; + current = current.baseState; + var newBaseQueueLast = (baseFirst = pendingQueue = null), + update = baseQueue; do { - var updateExpirationTime = _update.expirationTime; - updateExpirationTime < renderExpirationTime$1 - ? (didSkip || - ((didSkip = !0), - (newBaseUpdate = baseUpdate), - (firstRenderPhaseUpdate = newState)), - updateExpirationTime > remainingExpirationTime && - ((remainingExpirationTime = updateExpirationTime), - markUnprocessedUpdateTime(remainingExpirationTime))) - : (markRenderEventTimeAndConfig( + 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( updateExpirationTime, - _update.suspenseConfig + update.suspenseConfig ), - (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); + (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); hook.memoizedState = newState; - hook.baseUpdate = newBaseUpdate; - hook.baseState = firstRenderPhaseUpdate; + null === hook.baseQueue && (hook.baseState = newState); queue.lastRenderedState = newState; } - return [hook.memoizedState, queue.dispatch]; + return [newState, dispatch]; } function mountState(initialState) { var hook = mountWorkInProgressHook(); "function" === typeof initialState && (initialState = initialState()); hook.memoizedState = hook.baseState = initialState; initialState = hook.queue = { - last: null, + pending: null, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState @@ -3449,28 +3324,30 @@ 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 }; - 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))); + 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))); return tag; } +function updateRef() { + return updateWorkInProgressHook().memoizedState; +} function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var hook = mountWorkInProgressHook(); - sideEffectTag |= fiberEffectTag; + currentlyRenderingFiber$1.effectTag |= fiberEffectTag; hook.memoizedState = pushEffect( - hookEffectTag, + 1 | hookEffectTag, create, void 0, void 0 === deps ? null : deps @@ -3484,18 +3361,21 @@ function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var prevEffect = currentHook.memoizedState; destroy = prevEffect.destroy; if (null !== deps && areHookInputsEqual(deps, prevEffect.deps)) { - pushEffect(0, create, destroy, deps); + pushEffect(hookEffectTag, create, destroy, deps); return; } } - sideEffectTag |= fiberEffectTag; - hook.memoizedState = pushEffect(hookEffectTag, create, destroy, deps); + currentlyRenderingFiber$1.effectTag |= fiberEffectTag; + hook.memoizedState = pushEffect(1 | hookEffectTag, create, destroy, deps); } function mountEffect(create, deps) { - return mountEffectImpl(516, 192, create, deps); + return mountEffectImpl(516, 4, create, deps); } function updateEffect(create, deps) { - return updateEffectImpl(516, 192, create, deps); + return updateEffectImpl(516, 4, create, deps); +} +function updateLayoutEffect(create, deps) { + return updateEffectImpl(4, 2, create, deps); } function imperativeHandleEffect(create, ref) { if ("function" === typeof ref) @@ -3515,6 +3395,15 @@ 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 = [ @@ -3536,72 +3425,79 @@ 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) { - if (!(25 > numberOfReRenders)) - throw Error( - "Too many re-renders. React limits the number of renders to prevent an infinite loop." - ); - var alternate = fiber.alternate; + 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 ( fiber === currentlyRenderingFiber$1 || - (null !== alternate && alternate === currentlyRenderingFiber$1) + (null !== pending && pending === currentlyRenderingFiber$1) ) - 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; - } + (didScheduleRenderPhaseUpdate = !0), + (suspenseConfig.expirationTime = renderExpirationTime), + (currentlyRenderingFiber$1.expirationTime = renderExpirationTime); 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 === alternate || 0 === alternate.expirationTime) && - ((alternate = queue.lastRenderedReducer), null !== alternate) + (null === pending || 0 === pending.expirationTime) && + ((pending = queue.lastRenderedReducer), null !== pending) ) try { var currentState = queue.lastRenderedState, - eagerState = alternate(currentState, action); - suspenseConfig.eagerReducer = alternate; + eagerState = pending(currentState, action); + suspenseConfig.eagerReducer = pending; suspenseConfig.eagerState = eagerState; - if (is$1(eagerState, currentState)) return; + if (objectIs(eagerState, currentState)) return; } catch (error) { } finally { } - scheduleUpdateOnFiber(fiber, currentTime); + scheduleWork(fiber, currentTime); } } +function updateEventListener() {} var ContextOnlyDispatcher = { readContext: readContext, useCallback: throwInvalidHookError, @@ -3616,7 +3512,8 @@ var ContextOnlyDispatcher = { useDebugValue: throwInvalidHookError, useResponder: throwInvalidHookError, useDeferredValue: throwInvalidHookError, - useTransition: throwInvalidHookError + useTransition: throwInvalidHookError, + useEvent: throwInvalidHookError }, HooksDispatcherOnMount = { readContext: readContext, @@ -3627,13 +3524,13 @@ var ContextOnlyDispatcher = { deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; return mountEffectImpl( 4, - 36, + 2, imperativeHandleEffect.bind(null, create, ref), deps ); }, useLayoutEffect: function(create, deps) { - return mountEffectImpl(4, 36, create, deps); + return mountEffectImpl(4, 2, create, deps); }, useMemo: function(nextCreate, deps) { var hook = mountWorkInProgressHook(); @@ -3647,7 +3544,7 @@ var ContextOnlyDispatcher = { initialArg = void 0 !== init ? init(initialArg) : initialArg; hook.memoizedState = hook.baseState = initialArg; reducer = hook.queue = { - last: null, + pending: null, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialArg @@ -3666,23 +3563,21 @@ var ContextOnlyDispatcher = { }, useState: mountState, useDebugValue: mountDebugValue, - useResponder: createResponderListener, + useResponder: createDeprecatedResponderListener, useDeferredValue: function(value, config) { var _mountState = mountState(value), prevValue = _mountState[0], setValue = _mountState[1]; mountEffect( function() { - 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; - } - }); + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } }, [value, config] ); @@ -3690,112 +3585,113 @@ var ContextOnlyDispatcher = { }, useTransition: function(config) { var _mountState2 = mountState(!1), - isPending = _mountState2[0], - setPending = _mountState2[1]; + isPending = _mountState2[0]; + _mountState2 = _mountState2[1]; return [ - 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] - ), + mountCallback(startTransition.bind(null, _mountState2, config), [ + _mountState2, + config + ]), isPending ]; - } + }, + useEvent: function() {} }, HooksDispatcherOnUpdate = { readContext: readContext, useCallback: updateCallback, useContext: readContext, useEffect: updateEffect, - 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; - }, + useImperativeHandle: updateImperativeHandle, + useLayoutEffect: updateLayoutEffect, + useMemo: updateMemo, useReducer: updateReducer, - useRef: function() { - return updateWorkInProgressHook().memoizedState; + useRef: updateRef, + useState: function() { + return updateReducer(basicStateReducer); }, - useState: updateState, useDebugValue: mountDebugValue, - useResponder: createResponderListener, + useResponder: createDeprecatedResponderListener, useDeferredValue: function(value, config) { - var _updateState = updateState(value), + var _updateState = updateReducer(basicStateReducer), prevValue = _updateState[0], setValue = _updateState[1]; updateEffect( function() { - 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; - } - }); + 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 = updateState(!1), - isPending = _updateState2[0], - setPending = _updateState2[1]; + var _updateState2 = updateReducer(basicStateReducer), + isPending = _updateState2[0]; + _updateState2 = _updateState2[1]; return [ - 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] - ), + updateCallback(startTransition.bind(null, _updateState2, config), [ + _updateState2, + config + ]), 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] + ); + 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 }, now$1 = Scheduler.unstable_now, commitTime = 0, @@ -3808,70 +3704,16 @@ function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) { profilerStartTime = -1; } } -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, +var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner, didReceiveUpdate = !1; function reconcileChildren( - current$$1, + current, workInProgress, nextChildren, renderExpirationTime ) { workInProgress.child = - null === current$$1 + null === current ? mountChildFibers( workInProgress, null, @@ -3880,13 +3722,13 @@ function reconcileChildren( ) : reconcileChildFibers( workInProgress, - current$$1.child, + current.child, nextChildren, renderExpirationTime ); } function updateForwardRef( - current$$1, + current, workInProgress, Component, nextProps, @@ -3896,43 +3738,38 @@ function updateForwardRef( var ref = workInProgress.ref; prepareToReadContext(workInProgress, renderExpirationTime); nextProps = renderWithHooks( - current$$1, + current, workInProgress, Component, nextProps, ref, renderExpirationTime ); - if (null !== current$$1 && !didReceiveUpdate) + if (null !== current && !didReceiveUpdate) return ( - (workInProgress.updateQueue = current$$1.updateQueue), + (workInProgress.updateQueue = current.updateQueue), (workInProgress.effectTag &= -517), - current$$1.expirationTime <= renderExpirationTime && - (current$$1.expirationTime = 0), + current.expirationTime <= renderExpirationTime && + (current.expirationTime = 0), bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ) ); workInProgress.effectTag |= 1; - reconcileChildren( - current$$1, - workInProgress, - nextProps, - renderExpirationTime - ); + reconcileChildren(current, workInProgress, nextProps, renderExpirationTime); return workInProgress.child; } function updateMemoComponent( - current$$1, + current, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime ) { - if (null === current$$1) { + if (null === current) { var type = Component.type; if ( "function" === typeof type && @@ -3945,7 +3782,7 @@ function updateMemoComponent( (workInProgress.tag = 15), (workInProgress.type = type), updateSimpleMemoComponent( - current$$1, + current, workInProgress, type, nextProps, @@ -3953,7 +3790,7 @@ function updateMemoComponent( renderExpirationTime ) ); - current$$1 = createFiberFromTypeAndProps( + current = createFiberFromTypeAndProps( Component.type, null, nextProps, @@ -3961,65 +3798,66 @@ function updateMemoComponent( workInProgress.mode, renderExpirationTime ); - current$$1.ref = workInProgress.ref; - current$$1.return = workInProgress; - return (workInProgress.child = current$$1); + current.ref = workInProgress.ref; + current.return = workInProgress; + return (workInProgress.child = current); } - type = current$$1.child; + type = current.child; if ( updateExpirationTime < renderExpirationTime && ((updateExpirationTime = type.memoizedProps), (Component = Component.compare), (Component = null !== Component ? Component : shallowEqual), Component(updateExpirationTime, nextProps) && - current$$1.ref === workInProgress.ref) + current.ref === workInProgress.ref) ) return bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ); workInProgress.effectTag |= 1; - current$$1 = createWorkInProgress(type, nextProps, renderExpirationTime); - current$$1.ref = workInProgress.ref; - current$$1.return = workInProgress; - return (workInProgress.child = current$$1); + current = createWorkInProgress(type, nextProps); + current.ref = workInProgress.ref; + current.return = workInProgress; + return (workInProgress.child = current); } function updateSimpleMemoComponent( - current$$1, + current, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime ) { - return null !== current$$1 && - shallowEqual(current$$1.memoizedProps, nextProps) && - current$$1.ref === workInProgress.ref && + return null !== current && + shallowEqual(current.memoizedProps, nextProps) && + current.ref === workInProgress.ref && ((didReceiveUpdate = !1), updateExpirationTime < renderExpirationTime) - ? bailoutOnAlreadyFinishedWork( - current$$1, + ? ((workInProgress.expirationTime = current.expirationTime), + bailoutOnAlreadyFinishedWork( + current, workInProgress, renderExpirationTime - ) + )) : updateFunctionComponent( - current$$1, + current, workInProgress, Component, nextProps, renderExpirationTime ); } -function markRef(current$$1, workInProgress) { +function markRef(current, workInProgress) { var ref = workInProgress.ref; if ( - (null === current$$1 && null !== ref) || - (null !== current$$1 && current$$1.ref !== ref) + (null === current && null !== ref) || + (null !== current && current.ref !== ref) ) workInProgress.effectTag |= 128; } function updateFunctionComponent( - current$$1, + current, workInProgress, Component, nextProps, @@ -4031,36 +3869,31 @@ function updateFunctionComponent( context = getMaskedContext(workInProgress, context); prepareToReadContext(workInProgress, renderExpirationTime); Component = renderWithHooks( - current$$1, + current, workInProgress, Component, nextProps, context, renderExpirationTime ); - if (null !== current$$1 && !didReceiveUpdate) + if (null !== current && !didReceiveUpdate) return ( - (workInProgress.updateQueue = current$$1.updateQueue), + (workInProgress.updateQueue = current.updateQueue), (workInProgress.effectTag &= -517), - current$$1.expirationTime <= renderExpirationTime && - (current$$1.expirationTime = 0), + current.expirationTime <= renderExpirationTime && + (current.expirationTime = 0), bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ) ); workInProgress.effectTag |= 1; - reconcileChildren( - current$$1, - workInProgress, - Component, - renderExpirationTime - ); + reconcileChildren(current, workInProgress, Component, renderExpirationTime); return workInProgress.child; } function updateClassComponent( - current$$1, + current, workInProgress, Component, nextProps, @@ -4072,16 +3905,11 @@ function updateClassComponent( } else hasContext = !1; prepareToReadContext(workInProgress, renderExpirationTime); if (null === workInProgress.stateNode) - null !== current$$1 && - ((current$$1.alternate = null), + null !== current && + ((current.alternate = null), (workInProgress.alternate = null), (workInProgress.effectTag |= 2)), - constructClassInstance( - workInProgress, - Component, - nextProps, - renderExpirationTime - ), + constructClassInstance(workInProgress, Component, nextProps), mountClassInstance( workInProgress, Component, @@ -4089,7 +3917,7 @@ function updateClassComponent( renderExpirationTime ), (nextProps = !0); - else if (null === current$$1) { + else if (null === current) { var instance = workInProgress.stateNode, oldProps = workInProgress.memoizedProps; instance.props = oldProps; @@ -4117,17 +3945,14 @@ function updateClassComponent( )); hasForceUpdate = !1; var oldState = workInProgress.memoizedState; - oldContext = instance.state = oldState; - var updateQueue = workInProgress.updateQueue; - null !== updateQueue && - (processUpdateQueue( - workInProgress, - updateQueue, - nextProps, - instance, - renderExpirationTime - ), - (oldContext = workInProgress.memoizedState)); + instance.state = oldState; + processUpdateQueue( + workInProgress, + nextProps, + instance, + renderExpirationTime + ); + oldContext = workInProgress.memoizedState; oldProps !== nextProps || oldState !== oldContext || didPerformWorkStackCursor.current || @@ -4173,6 +3998,7 @@ function updateClassComponent( (nextProps = !1)); } else (instance = workInProgress.stateNode), + cloneUpdateQueue(current, workInProgress), (oldProps = workInProgress.memoizedProps), (instance.props = workInProgress.type === workInProgress.elementType @@ -4201,17 +4027,14 @@ function updateClassComponent( )), (hasForceUpdate = !1), (oldContext = workInProgress.memoizedState), - (oldState = instance.state = oldContext), - (updateQueue = workInProgress.updateQueue), - null !== updateQueue && - (processUpdateQueue( - workInProgress, - updateQueue, - nextProps, - instance, - renderExpirationTime - ), - (oldState = workInProgress.memoizedState)), + (instance.state = oldContext), + processUpdateQueue( + workInProgress, + nextProps, + instance, + renderExpirationTime + ), + (oldState = workInProgress.memoizedState), oldProps !== nextProps || oldContext !== oldState || didPerformWorkStackCursor.current || @@ -4255,12 +4078,12 @@ function updateClassComponent( "function" === typeof instance.getSnapshotBeforeUpdate && (workInProgress.effectTag |= 256)) : ("function" !== typeof instance.componentDidUpdate || - (oldProps === current$$1.memoizedProps && - oldContext === current$$1.memoizedState) || + (oldProps === current.memoizedProps && + oldContext === current.memoizedState) || (workInProgress.effectTag |= 4), "function" !== typeof instance.getSnapshotBeforeUpdate || - (oldProps === current$$1.memoizedProps && - oldContext === current$$1.memoizedState) || + (oldProps === current.memoizedProps && + oldContext === current.memoizedState) || (workInProgress.effectTag |= 256), (workInProgress.memoizedProps = nextProps), (workInProgress.memoizedState = oldState)), @@ -4269,16 +4092,16 @@ function updateClassComponent( (instance.context = contextType), (nextProps = getDerivedStateFromProps)) : ("function" !== typeof instance.componentDidUpdate || - (oldProps === current$$1.memoizedProps && - oldContext === current$$1.memoizedState) || + (oldProps === current.memoizedProps && + oldContext === current.memoizedState) || (workInProgress.effectTag |= 4), "function" !== typeof instance.getSnapshotBeforeUpdate || - (oldProps === current$$1.memoizedProps && - oldContext === current$$1.memoizedState) || + (oldProps === current.memoizedProps && + oldContext === current.memoizedState) || (workInProgress.effectTag |= 256), (nextProps = !1)); return finishClassComponent( - current$$1, + current, workInProgress, Component, nextProps, @@ -4287,26 +4110,26 @@ function updateClassComponent( ); } function finishClassComponent( - current$$1, + current, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime ) { - markRef(current$$1, workInProgress); + markRef(current, workInProgress); var didCaptureError = 0 !== (workInProgress.effectTag & 64); if (!shouldUpdate && !didCaptureError) return ( hasContext && invalidateContextProvider(workInProgress, Component, !1), bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ) ); shouldUpdate = workInProgress.stateNode; - ReactCurrentOwner$3.current = workInProgress; + ReactCurrentOwner$1.current = workInProgress; if ( didCaptureError && "function" !== typeof Component.getDerivedStateFromError @@ -4315,11 +4138,11 @@ function finishClassComponent( profilerStartTime = -1; } else nextChildren = shouldUpdate.render(); workInProgress.effectTag |= 1; - null !== current$$1 && didCaptureError + null !== current && didCaptureError ? ((didCaptureError = nextChildren), (workInProgress.child = reconcileChildFibers( workInProgress, - current$$1.child, + current.child, null, renderExpirationTime )), @@ -4330,7 +4153,7 @@ function finishClassComponent( renderExpirationTime ))) : reconcileChildren( - current$$1, + current, workInProgress, nextChildren, renderExpirationTime @@ -4353,7 +4176,7 @@ function pushHostRootContext(workInProgress) { } var SUSPENDED_MARKER = { dehydrated: null, retryTime: 0 }; function updateSuspenseComponent( - current$$1, + current, workInProgress, renderExpirationTime ) { @@ -4365,32 +4188,30 @@ function updateSuspenseComponent( (JSCompiler_temp = 0 !== (workInProgress.effectTag & 64)) || (JSCompiler_temp = 0 !== (suspenseContext & 2) && - (null === current$$1 || null !== current$$1.memoizedState)); + (null === current || null !== current.memoizedState)); JSCompiler_temp ? ((nextDidTimeout = !0), (workInProgress.effectTag &= -65)) - : (null !== current$$1 && null === current$$1.memoizedState) || + : (null !== current && null === current.memoizedState) || void 0 === nextProps.fallback || !0 === nextProps.unstable_avoidThisFallback || (suspenseContext |= 1); - push(suspenseStackCursor, suspenseContext & 1, workInProgress); - if (null === current$$1) { - void 0 !== nextProps.fallback && - tryToClaimNextHydratableInstance(workInProgress); + push(suspenseStackCursor, suspenseContext & 1); + if (null === current) { if (nextDidTimeout) { nextDidTimeout = nextProps.fallback; nextProps = createFiberFromFragment(null, mode, 0, null); nextProps.return = workInProgress; if (0 === (workInProgress.mode & 2)) for ( - current$$1 = + current = null !== workInProgress.memoizedState ? workInProgress.child.child : workInProgress.child, - nextProps.child = current$$1; - null !== current$$1; + nextProps.child = current; + null !== current; ) - (current$$1.return = nextProps), (current$$1 = current$$1.sibling); + (current.return = nextProps), (current = current.sibling); renderExpirationTime = createFiberFromFragment( nextDidTimeout, mode, @@ -4412,15 +4233,14 @@ function updateSuspenseComponent( renderExpirationTime )); } - if (null !== current$$1.memoizedState) { - current$$1 = current$$1.child; - mode = current$$1.sibling; + if (null !== current.memoizedState) { + current = current.child; + mode = current.sibling; if (nextDidTimeout) { nextProps = nextProps.fallback; renderExpirationTime = createWorkInProgress( - current$$1, - current$$1.pendingProps, - 0 + current, + current.pendingProps ); renderExpirationTime.return = workInProgress; if ( @@ -4429,7 +4249,7 @@ function updateSuspenseComponent( null !== workInProgress.memoizedState ? workInProgress.child.child : workInProgress.child), - nextDidTimeout !== current$$1.child) + nextDidTimeout !== current.child) ) for ( renderExpirationTime.child = nextDidTimeout; @@ -4440,12 +4260,12 @@ function updateSuspenseComponent( (nextDidTimeout = nextDidTimeout.sibling); if (workInProgress.mode & 8) { nextDidTimeout = 0; - for (current$$1 = renderExpirationTime.child; null !== current$$1; ) - (nextDidTimeout += current$$1.treeBaseDuration), - (current$$1 = current$$1.sibling); + for (current = renderExpirationTime.child; null !== current; ) + (nextDidTimeout += current.treeBaseDuration), + (current = current.sibling); renderExpirationTime.treeBaseDuration = nextDidTimeout; } - mode = createWorkInProgress(mode, nextProps, mode.expirationTime); + mode = createWorkInProgress(mode, nextProps); mode.return = workInProgress; renderExpirationTime.sibling = mode; renderExpirationTime.childExpirationTime = 0; @@ -4455,37 +4275,37 @@ function updateSuspenseComponent( } renderExpirationTime = reconcileChildFibers( workInProgress, - current$$1.child, + current.child, nextProps.children, renderExpirationTime ); workInProgress.memoizedState = null; return (workInProgress.child = renderExpirationTime); } - current$$1 = current$$1.child; + current = current.child; if (nextDidTimeout) { nextDidTimeout = nextProps.fallback; nextProps = createFiberFromFragment(null, mode, 0, null); nextProps.return = workInProgress; - nextProps.child = current$$1; - null !== current$$1 && (current$$1.return = nextProps); + nextProps.child = current; + null !== current && (current.return = nextProps); if (0 === (workInProgress.mode & 2)) for ( - current$$1 = + current = null !== workInProgress.memoizedState ? workInProgress.child.child : workInProgress.child, - nextProps.child = current$$1; - null !== current$$1; + nextProps.child = current; + null !== current; ) - (current$$1.return = nextProps), (current$$1 = current$$1.sibling); + (current.return = nextProps), (current = current.sibling); if (workInProgress.mode & 8) { - current$$1 = 0; + current = 0; for (suspenseContext = nextProps.child; null !== suspenseContext; ) - (current$$1 += suspenseContext.treeBaseDuration), + (current += suspenseContext.treeBaseDuration), (suspenseContext = suspenseContext.sibling); - nextProps.treeBaseDuration = current$$1; + nextProps.treeBaseDuration = current; } renderExpirationTime = createFiberFromFragment( nextDidTimeout, @@ -4504,7 +4324,7 @@ function updateSuspenseComponent( workInProgress.memoizedState = null; return (workInProgress.child = reconcileChildFibers( workInProgress, - current$$1, + current, nextProps.children, renderExpirationTime )); @@ -4531,6 +4351,7 @@ function initSuspenseListRenderState( ? (workInProgress.memoizedState = { isBackwards: isBackwards, rendering: null, + renderingStartTime: 0, last: lastContentRow, tail: tail, tailExpiration: 0, @@ -4539,6 +4360,7 @@ function initSuspenseListRenderState( }) : ((renderState.isBackwards = isBackwards), (renderState.rendering = null), + (renderState.renderingStartTime = 0), (renderState.last = lastContentRow), (renderState.tail = tail), (renderState.tailExpiration = 0), @@ -4546,7 +4368,7 @@ function initSuspenseListRenderState( (renderState.lastEffect = lastEffectBeforeRendering)); } function updateSuspenseListComponent( - current$$1, + current, workInProgress, renderExpirationTime ) { @@ -4554,7 +4376,7 @@ function updateSuspenseListComponent( revealOrder = nextProps.revealOrder, tailMode = nextProps.tail; reconcileChildren( - current$$1, + current, workInProgress, nextProps.children, renderExpirationTime @@ -4563,42 +4385,39 @@ function updateSuspenseListComponent( if (0 !== (nextProps & 2)) (nextProps = (nextProps & 1) | 2), (workInProgress.effectTag |= 64); else { - 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; + 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; continue; } - if (current$$1 === workInProgress) break a; - for (; null === current$$1.sibling; ) { - if ( - null === current$$1.return || - current$$1.return === workInProgress - ) + if (current === workInProgress) break a; + for (; null === current.sibling; ) { + if (null === current.return || current.return === workInProgress) break a; - current$$1 = current$$1.return; + current = current.return; } - current$$1.sibling.return = current$$1.return; - current$$1 = current$$1.sibling; + current.sibling.return = current.return; + current = current.sibling; } nextProps &= 1; } - push(suspenseStackCursor, nextProps, workInProgress); + push(suspenseStackCursor, nextProps); if (0 === (workInProgress.mode & 2)) workInProgress.memoizedState = null; else switch (revealOrder) { case "forwards": renderExpirationTime = workInProgress.child; for (revealOrder = null; null !== renderExpirationTime; ) - (current$$1 = renderExpirationTime.alternate), - null !== current$$1 && - null === findFirstSuspended(current$$1) && + (current = renderExpirationTime.alternate), + null !== current && + null === findFirstSuspended(current) && (revealOrder = renderExpirationTime), (renderExpirationTime = renderExpirationTime.sibling); renderExpirationTime = revealOrder; @@ -4620,15 +4439,15 @@ function updateSuspenseListComponent( renderExpirationTime = null; revealOrder = workInProgress.child; for (workInProgress.child = null; null !== revealOrder; ) { - current$$1 = revealOrder.alternate; - if (null !== current$$1 && null === findFirstSuspended(current$$1)) { + current = revealOrder.alternate; + if (null !== current && null === findFirstSuspended(current)) { workInProgress.child = revealOrder; break; } - current$$1 = revealOrder.sibling; + current = revealOrder.sibling; revealOrder.sibling = renderExpirationTime; renderExpirationTime = revealOrder; - revealOrder = current$$1; + revealOrder = current; } initSuspenseListRenderState( workInProgress, @@ -4655,36 +4474,30 @@ function updateSuspenseListComponent( return workInProgress.child; } function bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ) { - null !== current$$1 && - (workInProgress.dependencies = current$$1.dependencies); + null !== current && (workInProgress.dependencies = current.dependencies); profilerStartTime = -1; var updateExpirationTime = workInProgress.expirationTime; 0 !== updateExpirationTime && markUnprocessedUpdateTime(updateExpirationTime); if (workInProgress.childExpirationTime < renderExpirationTime) return null; - if (null !== current$$1 && workInProgress.child !== current$$1.child) + if (null !== current && workInProgress.child !== current.child) throw Error("Resuming work not yet implemented."); if (null !== workInProgress.child) { - current$$1 = workInProgress.child; - renderExpirationTime = createWorkInProgress( - current$$1, - current$$1.pendingProps, - current$$1.expirationTime - ); + current = workInProgress.child; + renderExpirationTime = createWorkInProgress(current, current.pendingProps); workInProgress.child = renderExpirationTime; for ( renderExpirationTime.return = workInProgress; - null !== current$$1.sibling; + null !== current.sibling; ) - (current$$1 = current$$1.sibling), + (current = current.sibling), (renderExpirationTime = renderExpirationTime.sibling = createWorkInProgress( - current$$1, - current$$1.pendingProps, - current$$1.expirationTime + current, + current.pendingProps )), (renderExpirationTime.return = workInProgress); renderExpirationTime.sibling = null; @@ -4746,78 +4559,87 @@ function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { : (_lastTailNode.sibling = null); } } -function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { +function completeWork(current, workInProgress, renderExpirationTime) { var newProps = workInProgress.pendingProps; switch (workInProgress.tag) { case 2: - break; case 16: - break; case 15: case 0: - break; + case 11: + case 7: + case 8: + case 12: + case 9: + case 14: + return null; case 1: - isContextProvider(workInProgress.type) && popContext(workInProgress); - break; + return isContextProvider(workInProgress.type) && popContext(), null; case 3: - popHostContainer(workInProgress); - popTopLevelContextObject(workInProgress); - current = workInProgress.stateNode; - current.pendingContext && - ((current.context = current.pendingContext), - (current.pendingContext = null)); - updateHostContainer(workInProgress); - break; + 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$jscomp$0 = workInProgress.type; + renderExpirationTime = workInProgress.type; if (null !== current && null != workInProgress.stateNode) updateHostComponent$1( current, workInProgress, - renderExpirationTime$jscomp$0, + renderExpirationTime, newProps, rootContainerInstance ), current.ref !== workInProgress.ref && (workInProgress.effectTag |= 128); - else if (newProps) { - current = requiredContext(contextStackCursor$1.current); - var tag = allocateTag(), - viewConfig = getViewConfigForType(renderExpirationTime$jscomp$0), - updatePayload = diffProperties( - null, - emptyObject, - newProps, - viewConfig.validAttributes - ); + 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( - tag, - viewConfig.uiViewClassName, + current, + renderExpirationTime.uiViewClassName, rootContainerInstance, updatePayload ); - 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); - } 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." + rootContainerInstance = new ReactNativeFiberHostComponent( + current, + renderExpirationTime, + workInProgress ); - break; + 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( @@ -4846,33 +4668,30 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { instanceCache.set(rootContainerInstance, workInProgress); workInProgress.stateNode = rootContainerInstance; } - break; - case 11: - break; + return null; case 13: - pop(suspenseStackCursor, workInProgress); + pop(suspenseStackCursor); newProps = workInProgress.memoizedState; if (0 !== (workInProgress.effectTag & 64)) return ( - (workInProgress.expirationTime = renderExpirationTime$jscomp$0), - workInProgress + (workInProgress.expirationTime = renderExpirationTime), workInProgress ); newProps = null !== newProps; rootContainerInstance = !1; null !== current && - ((renderExpirationTime$jscomp$0 = current.memoizedState), - (rootContainerInstance = null !== renderExpirationTime$jscomp$0), + ((renderExpirationTime = current.memoizedState), + (rootContainerInstance = null !== renderExpirationTime), newProps || - 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)))); + 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 && @@ -4889,41 +4708,30 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { workInProgressRootExitStatus = RootSuspendedWithDelay; 0 !== workInProgressRootNextUnprocessedUpdateTime && null !== workInProgressRoot && - (markRootSuspendedAtTime(workInProgressRoot, renderExpirationTime), + (markRootSuspendedAtTime( + workInProgressRoot, + renderExpirationTime$1 + ), markRootUpdatedAtTime( workInProgressRoot, workInProgressRootNextUnprocessedUpdateTime - )); - } - if (newProps || rootContainerInstance) workInProgress.effectTag |= 4; - break; - case 7: - break; - case 8: - break; - case 12: - break; + )); + } + if (newProps || rootContainerInstance) workInProgress.effectTag |= 4; + return null; case 4: - popHostContainer(workInProgress); - updateHostContainer(workInProgress); - break; + return popHostContainer(), updateHostContainer(workInProgress), null; case 10: - popProvider(workInProgress); - break; - case 9: - break; - case 14: - break; + return popProvider(workInProgress), null; case 17: - isContextProvider(workInProgress.type) && popContext(workInProgress); - break; + return isContextProvider(workInProgress.type) && popContext(), null; case 19: - pop(suspenseStackCursor, workInProgress); + pop(suspenseStackCursor); newProps = workInProgress.memoizedState; - if (null === newProps) break; + if (null === newProps) return null; rootContainerInstance = 0 !== (workInProgress.effectTag & 64); - tag = newProps.rendering; - if (null === tag) + updatePayload = newProps.rendering; + if (null === updatePayload) if (rootContainerInstance) cutOffTailIfNeeded(newProps, !1); else { if ( @@ -4931,30 +4739,29 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { (null !== current && 0 !== (current.effectTag & 64)) ) for (current = workInProgress.child; null !== current; ) { - tag = findFirstSuspended(current); - if (null !== tag) { + updatePayload = findFirstSuspended(current); + if (null !== updatePayload) { workInProgress.effectTag |= 64; cutOffTailIfNeeded(newProps, !1); - current = tag.updateQueue; + current = updatePayload.updateQueue; null !== current && ((workInProgress.updateQueue = current), (workInProgress.effectTag |= 4)); null === newProps.lastEffect && (workInProgress.firstEffect = null); workInProgress.lastEffect = newProps.lastEffect; - current = renderExpirationTime$jscomp$0; + current = renderExpirationTime; for (newProps = workInProgress.child; null !== newProps; ) (rootContainerInstance = newProps), - (tag = current), + (updatePayload = current), (rootContainerInstance.effectTag &= 2), (rootContainerInstance.nextEffect = null), (rootContainerInstance.firstEffect = null), (rootContainerInstance.lastEffect = null), - (renderExpirationTime$jscomp$0 = - rootContainerInstance.alternate), - null === renderExpirationTime$jscomp$0 + (renderExpirationTime = rootContainerInstance.alternate), + null === renderExpirationTime ? ((rootContainerInstance.childExpirationTime = 0), - (rootContainerInstance.expirationTime = tag), + (rootContainerInstance.expirationTime = updatePayload), (rootContainerInstance.child = null), (rootContainerInstance.memoizedProps = null), (rootContainerInstance.memoizedState = null), @@ -4963,35 +4770,34 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { (rootContainerInstance.selfBaseDuration = 0), (rootContainerInstance.treeBaseDuration = 0)) : ((rootContainerInstance.childExpirationTime = - renderExpirationTime$jscomp$0.childExpirationTime), + renderExpirationTime.childExpirationTime), (rootContainerInstance.expirationTime = - renderExpirationTime$jscomp$0.expirationTime), + renderExpirationTime.expirationTime), (rootContainerInstance.child = - renderExpirationTime$jscomp$0.child), + renderExpirationTime.child), (rootContainerInstance.memoizedProps = - renderExpirationTime$jscomp$0.memoizedProps), + renderExpirationTime.memoizedProps), (rootContainerInstance.memoizedState = - renderExpirationTime$jscomp$0.memoizedState), + renderExpirationTime.memoizedState), (rootContainerInstance.updateQueue = - renderExpirationTime$jscomp$0.updateQueue), - (tag = renderExpirationTime$jscomp$0.dependencies), + renderExpirationTime.updateQueue), + (updatePayload = renderExpirationTime.dependencies), (rootContainerInstance.dependencies = - null === tag + null === updatePayload ? null : { - expirationTime: tag.expirationTime, - firstContext: tag.firstContext, - responders: tag.responders + expirationTime: updatePayload.expirationTime, + firstContext: updatePayload.firstContext, + responders: updatePayload.responders }), (rootContainerInstance.selfBaseDuration = - renderExpirationTime$jscomp$0.selfBaseDuration), + renderExpirationTime.selfBaseDuration), (rootContainerInstance.treeBaseDuration = - renderExpirationTime$jscomp$0.treeBaseDuration)), + renderExpirationTime.treeBaseDuration)), (newProps = newProps.sibling); push( suspenseStackCursor, - (suspenseStackCursor.current & 1) | 2, - workInProgress + (suspenseStackCursor.current & 1) | 2 ); return workInProgress.child; } @@ -5000,7 +4806,9 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { } else { if (!rootContainerInstance) - if (((current = findFirstSuspended(tag)), null !== current)) { + if ( + ((current = findFirstSuspended(updatePayload)), null !== current) + ) { if ( ((workInProgress.effectTag |= 64), (rootContainerInstance = !0), @@ -5011,74 +4819,72 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { cutOffTailIfNeeded(newProps, !0), null === newProps.tail && "hidden" === newProps.tailMode && - !tag.alternate) - ) { - workInProgress = workInProgress.lastEffect = newProps.lastEffect; - null !== workInProgress && (workInProgress.nextEffect = null); - break; - } + !updatePayload.alternate) + ) + return ( + (workInProgress = workInProgress.lastEffect = + newProps.lastEffect), + null !== workInProgress && (workInProgress.nextEffect = null), + null + ); } else - now() > newProps.tailExpiration && - 1 < renderExpirationTime$jscomp$0 && + 2 * now() - newProps.renderingStartTime > newProps.tailExpiration && + 1 < renderExpirationTime && ((workInProgress.effectTag |= 64), (rootContainerInstance = !0), cutOffTailIfNeeded(newProps, !1), - (current = renderExpirationTime$jscomp$0 - 1), + (current = renderExpirationTime - 1), (workInProgress.expirationTime = workInProgress.childExpirationTime = current), null === spawnedWorkDuringRender ? (spawnedWorkDuringRender = [current]) : spawnedWorkDuringRender.push(current)); newProps.isBackwards - ? ((tag.sibling = workInProgress.child), (workInProgress.child = tag)) + ? ((updatePayload.sibling = workInProgress.child), + (workInProgress.child = updatePayload)) : ((current = newProps.last), null !== current - ? (current.sibling = tag) - : (workInProgress.child = tag), - (newProps.last = tag)); + ? (current.sibling = updatePayload) + : (workInProgress.child = updatePayload), + (newProps.last = updatePayload)); } - if (null !== newProps.tail) - return ( - 0 === newProps.tailExpiration && + 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), - (newProps = suspenseStackCursor.current), + (workInProgress = suspenseStackCursor.current), push( suspenseStackCursor, - rootContainerInstance ? (newProps & 1) | 2 : newProps & 1, - workInProgress + rootContainerInstance + ? (workInProgress & 1) | 2 + : workInProgress & 1 ), - 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." - ); + current) + : null; } - return 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(workInProgress); + isContextProvider(workInProgress.type) && popContext(); var effectTag = workInProgress.effectTag; return effectTag & 4096 ? ((workInProgress.effectTag = (effectTag & -4097) | 64), workInProgress) : null; case 3: - popHostContainer(workInProgress); - popTopLevelContextObject(workInProgress); + popHostContainer(); + pop(didPerformWorkStackCursor); + pop(contextStackCursor); effectTag = workInProgress.effectTag; if (0 !== (effectTag & 64)) throw Error( @@ -5090,7 +4896,7 @@ function unwindWork(workInProgress) { return popHostContext(workInProgress), null; case 13: return ( - pop(suspenseStackCursor, workInProgress), + pop(suspenseStackCursor), (effectTag = workInProgress.effectTag), effectTag & 4096 ? ((workInProgress.effectTag = (effectTag & -4097) | 64), @@ -5098,9 +4904,9 @@ function unwindWork(workInProgress) { : null ); case 19: - return pop(suspenseStackCursor, workInProgress), null; + return pop(suspenseStackCursor), null; case 4: - return popHostContainer(workInProgress), null; + return popHostContainer(), null; case 10: return popProvider(workInProgress), null; default: @@ -5157,85 +4963,171 @@ function logError(boundary, errorInfo) { }); } } -function safelyCallComponentWillUnmount(current$$1, instance) { +function safelyCallComponentWillUnmount(current, instance) { try { - (instance.props = current$$1.memoizedProps), - (instance.state = current$$1.memoizedState), + (instance.props = current.memoizedProps), + (instance.state = current.memoizedState), instance.componentWillUnmount(); } catch (unmountError) { - captureCommitPhaseError(current$$1, unmountError); + captureCommitPhaseError(current, unmountError); } } -function safelyDetachRef(current$$1) { - var ref = current$$1.ref; +function safelyDetachRef(current) { + var ref = current.ref; if (null !== ref) if ("function" === typeof ref) try { ref(null); } catch (refError) { - captureCommitPhaseError(current$$1, refError); + captureCommitPhaseError(current, refError); } else ref.current = null; } -function commitBeforeMutationLifeCycles(current$$1, finishedWork) { +function commitBeforeMutationLifeCycles(current, finishedWork) { switch (finishedWork.tag) { case 0: case 11: case 15: - commitHookEffectList(2, 0, finishedWork); - break; + case 22: + return; case 1: - if (finishedWork.effectTag & 256 && null !== current$$1) { - var prevProps = current$$1.memoizedProps, - prevState = current$$1.memoizedState; - current$$1 = finishedWork.stateNode; - finishedWork = current$$1.getSnapshotBeforeUpdate( + if (finishedWork.effectTag & 256 && null !== current) { + var prevProps = current.memoizedProps, + prevState = current.memoizedState; + current = finishedWork.stateNode; + finishedWork = current.getSnapshotBeforeUpdate( finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState ); - current$$1.__reactInternalSnapshotBeforeUpdate = finishedWork; + current.__reactInternalSnapshotBeforeUpdate = finishedWork; } - break; + return; case 3: case 5: case 6: case 4: case 17: - break; - default: - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); + 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 commitHookEffectList(unmountTag, mountTag, finishedWork) { +function commitHookEffectListUnmount(tag, finishedWork) { finishedWork = finishedWork.updateQueue; finishedWork = null !== finishedWork ? finishedWork.lastEffect : null; if (null !== finishedWork) { var effect = (finishedWork = finishedWork.next); do { - if (0 !== (effect.tag & unmountTag)) { + if ((effect.tag & tag) === tag) { 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 commitUnmount(finishedRoot, current$$1$jscomp$0, renderPriorityLevel) { +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" === typeof onCommitFiberUnmount && - onCommitFiberUnmount(current$$1$jscomp$0); - switch (current$$1$jscomp$0.tag) { + onCommitFiberUnmount(current$jscomp$0); + switch (current$jscomp$0.tag) { case 0: case 11: case 14: case 15: - finishedRoot = current$$1$jscomp$0.updateQueue; + case 22: + finishedRoot = current$jscomp$0.updateQueue; if ( null !== finishedRoot && ((finishedRoot = finishedRoot.lastEffect), null !== finishedRoot) @@ -5246,13 +5138,13 @@ function commitUnmount(finishedRoot, current$$1$jscomp$0, renderPriorityLevel) { function() { var effect = firstEffect; do { - var destroy = effect.destroy; - if (void 0 !== destroy) { - var current$$1 = current$$1$jscomp$0; + var _destroy = effect.destroy; + if (void 0 !== _destroy) { + var current = current$jscomp$0; try { - destroy(); + _destroy(); } catch (error) { - captureCommitPhaseError(current$$1, error); + captureCommitPhaseError(current, error); } } effect = effect.next; @@ -5262,37 +5154,35 @@ function commitUnmount(finishedRoot, current$$1$jscomp$0, renderPriorityLevel) { } break; case 1: - safelyDetachRef(current$$1$jscomp$0); - renderPriorityLevel = current$$1$jscomp$0.stateNode; + safelyDetachRef(current$jscomp$0); + renderPriorityLevel = current$jscomp$0.stateNode; "function" === typeof renderPriorityLevel.componentWillUnmount && - safelyCallComponentWillUnmount( - current$$1$jscomp$0, - renderPriorityLevel - ); + safelyCallComponentWillUnmount(current$jscomp$0, renderPriorityLevel); break; case 5: - safelyDetachRef(current$$1$jscomp$0); + safelyDetachRef(current$jscomp$0); break; case 4: unmountHostComponents( finishedRoot, - current$$1$jscomp$0, + current$jscomp$0, renderPriorityLevel ); } } -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; +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; null !== alternate && detachFiber(alternate); } function isHostParent(fiber) { @@ -5355,97 +5245,103 @@ function commitPlacement(finishedWork) { break a; } } - 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), + 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( - isHost._nativeTag, - [index], - [beforeChild], + parent._nativeTag, + [isHost], + [before], [], [], [] )) - : ((index = children.indexOf(beforeChild)), - children.splice(index, 0, stateNode), + : ((before = tag.indexOf(before)), + tag.splice(before, 0, node), ReactNativePrivateInterface.UIManager.manageChildren( - isHost._nativeTag, + parent._nativeTag, [], [], - [ - "number" === typeof stateNode - ? stateNode - : stateNode._nativeTag - ], - [index], + ["number" === typeof node ? node : node._nativeTag], + [before], [] - )); - } - 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; - } + ))) + : ((before = "number" === typeof node ? node : node._nativeTag), + (tag = parent._children), + (isHost = tag.indexOf(node)), + 0 <= isHost + ? (tag.splice(isHost, 1), + tag.push(node), + ReactNativePrivateInterface.UIManager.manageChildren( + parent._nativeTag, + [isHost], + [tag.length - 1], + [], + [], + [] + )) + : (tag.push(node), + ReactNativePrivateInterface.UIManager.manageChildren( + parent._nativeTag, + [], + [], + [before], + [tag.length - 1], + [] + ))); + 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); } function unmountHostComponents( finishedRoot$jscomp$0, - current$$1, + current, renderPriorityLevel$jscomp$0 ) { for ( - var node = current$$1, + var node = current, currentParentIsValid = !1, currentParent, currentParentIsContainer; @@ -5493,7 +5389,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; + if (node$jscomp$0 === root) break a; for (; null === node$jscomp$0.sibling; ) { if (null === node$jscomp$0.return || node$jscomp$0.return === root) break a; @@ -5543,9 +5439,9 @@ function unmountHostComponents( node = node.child; continue; } - if (node === current$$1) break; + if (node === current) break; for (; null === node.sibling; ) { - if (null === node.return || node.return === current$$1) return; + if (null === node.return || node.return === current) return; node = node.return; 4 === node.tag && (currentParentIsValid = !1); } @@ -5553,21 +5449,22 @@ function unmountHostComponents( node = node.sibling; } } -function commitWork(current$$1, finishedWork) { +function commitWork(current, finishedWork) { switch (finishedWork.tag) { case 0: case 11: case 14: case 15: - commitHookEffectList(4, 8, finishedWork); - break; + case 22: + commitHookEffectListUnmount(3, finishedWork); + return; case 1: - break; + return; case 5: var instance = finishedWork.stateNode; if (null != instance) { var newProps = finishedWork.memoizedProps; - current$$1 = null !== current$$1 ? current$$1.memoizedProps : newProps; + current = null !== current ? current.memoizedProps : newProps; var updatePayload = finishedWork.updateQueue; finishedWork.updateQueue = null; null !== updatePayload && @@ -5575,7 +5472,7 @@ function commitWork(current$$1, finishedWork) { instanceProps.set(instance._nativeTag, newProps), (newProps = diffProperties( null, - current$$1, + current, newProps, finishedWork.validAttributes )), @@ -5586,7 +5483,7 @@ function commitWork(current$$1, finishedWork) { newProps )); } - break; + return; case 6: if (null === finishedWork.stateNode) throw Error( @@ -5597,11 +5494,11 @@ function commitWork(current$$1, finishedWork) { "RCTRawText", { text: finishedWork.memoizedProps } ); - break; + return; case 3: - break; + return; case 12: - break; + return; case 13: instance = finishedWork; null === finishedWork.memoizedState @@ -5610,9 +5507,9 @@ function commitWork(current$$1, finishedWork) { (instance = finishedWork.child), (globalMostRecentFallbackTime = now())); if (null !== instance) - a: for (current$$1 = instance; ; ) { - if (5 === current$$1.tag) - if (((updatePayload = current$$1.stateNode), newProps)) { + a: for (current = instance; ; ) { + if (5 === current.tag) + if (((updatePayload = current.stateNode), newProps)) { var viewConfig = updatePayload.viewConfig; var updatePayload$jscomp$0 = diffProperties( null, @@ -5626,8 +5523,8 @@ function commitWork(current$$1, finishedWork) { updatePayload$jscomp$0 ); } else { - updatePayload = current$$1.stateNode; - updatePayload$jscomp$0 = current$$1.memoizedProps; + updatePayload = current.stateNode; + updatePayload$jscomp$0 = current.memoizedProps; viewConfig = updatePayload.viewConfig; var prevProps = Object.assign({}, updatePayload$jscomp$0, { style: [updatePayload$jscomp$0.style, { display: "none" }] @@ -5645,47 +5542,41 @@ function commitWork(current$$1, finishedWork) { ); } else { - if (6 === current$$1.tag) throw Error("Not yet implemented."); + if (6 === current.tag) throw Error("Not yet implemented."); if ( - 13 === current$$1.tag && - null !== current$$1.memoizedState && - null === current$$1.memoizedState.dehydrated + 13 === current.tag && + null !== current.memoizedState && + null === current.memoizedState.dehydrated ) { - updatePayload = current$$1.child.sibling; - updatePayload.return = current$$1; - current$$1 = updatePayload; + updatePayload = current.child.sibling; + updatePayload.return = current; + current = updatePayload; continue; - } else if (null !== current$$1.child) { - current$$1.child.return = current$$1; - current$$1 = current$$1.child; + } else if (null !== current.child) { + current.child.return = current; + current = current.child; continue; } } - 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; + if (current === instance) break; + for (; null === current.sibling; ) { + if (null === current.return || current.return === instance) break a; + current = current.return; } - current$$1.sibling.return = current$$1.return; - current$$1 = current$$1.sibling; + current.sibling.return = current.return; + current = current.sibling; } attachSuspenseRetryListeners(finishedWork); - break; + return; case 19: attachSuspenseRetryListeners(finishedWork); - break; + return; case 17: - 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." - ); + return; } + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); } function attachSuspenseRetryListeners(finishedWork) { var thenables = finishedWork.updateQueue; @@ -5744,7 +5635,7 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { return expirationTime; } var ceil = Math.ceil, - ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher, + ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, NoContext = 0, LegacyUnbatchedContext = 8, @@ -5759,7 +5650,7 @@ var ceil = Math.ceil, executionContext = NoContext, workInProgressRoot = null, workInProgress = null, - renderExpirationTime = 0, + renderExpirationTime$1 = 0, workInProgressRootExitStatus = RootIncomplete, workInProgressRootFatalError = null, workInProgressRootLatestProcessedExpirationTime = 1073741823, @@ -5786,8 +5677,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; @@ -5795,7 +5686,7 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { var priorityLevel = getCurrentPriorityLevel(); if (0 === (fiber & 4)) return 99 === priorityLevel ? 1073741823 : 1073741822; if ((executionContext & RenderContext) !== NoContext) - return renderExpirationTime; + return renderExpirationTime$1; if (null !== suspenseConfig) currentTime = 1073741821 - @@ -5827,11 +5718,11 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { throw Error("Expected a valid priority level"); } null !== workInProgressRoot && - currentTime === renderExpirationTime && + currentTime === renderExpirationTime$1 && --currentTime; return currentTime; } -function scheduleUpdateOnFiber(fiber, expirationTime) { +function scheduleWork(fiber, expirationTime) { if (50 < nestedUpdateCount) throw ((nestedUpdateCount = 0), (rootWithNestedUpdates = null), @@ -5888,7 +5779,7 @@ function markUpdateTimeFromFiberToRoot(fiber, expirationTime) { (workInProgressRoot === root && (markUnprocessedUpdateTime(expirationTime), workInProgressRootExitStatus === RootSuspendedWithDelay && - markRootSuspendedAtTime(root, renderExpirationTime)), + markRootSuspendedAtTime(root, renderExpirationTime$1)), markRootUpdatedAtTime(root, expirationTime)); return root; } @@ -5897,9 +5788,10 @@ function getNextRootExpirationTimeToWorkOn(root) { if (0 !== lastExpiredTime) return lastExpiredTime; lastExpiredTime = root.firstPendingTime; if (!isRootSuspendedAtTime(root, lastExpiredTime)) return lastExpiredTime; - lastExpiredTime = root.lastPingedTime; + var lastPingedTime = root.lastPingedTime; root = root.nextKnownPendingLevel; - return lastExpiredTime > root ? lastExpiredTime : root; + root = lastPingedTime > root ? lastPingedTime : root; + return 2 >= root && lastExpiredTime !== root ? 0 : root; } function ensureRootIsScheduled(root) { if (0 !== root.lastExpiredTime) @@ -5948,270 +5840,232 @@ function ensureRootIsScheduled(root) { } function performConcurrentWorkOnRoot(root, didTimeout) { currentEventTime = 0; - if (didTimeout) - return ( - (didTimeout = requestCurrentTimeForUpdate()), - markRootExpiredAtTime(root, didTimeout), + 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), ensureRootIsScheduled(root), - 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); - } - 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) + 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) ) { - 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); + if ( + workInProgressRootHasPendingPing && + ((expirationTime = root.lastPingedTime), + 0 === expirationTime || expirationTime >= lastExpiredTime) + ) { + root.lastPingedTime = lastExpiredTime; + prepareFreshStack(root, lastExpiredTime); 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); + } + expirationTime = getNextRootExpirationTimeToWorkOn(root); + if (0 !== expirationTime && expirationTime !== lastExpiredTime) break; + if (0 !== exitStatus && exitStatus !== lastExpiredTime) { + root.lastPingedTime = exitStatus; break; - default: - throw Error("Unknown root exit status."); + } + root.timeoutHandle = scheduleTimeout( + commitRoot.bind(null, root), + prevExecutionContext + ); + break; } - 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(); + 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; - } 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(); + 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 + ); + break; + } + commitRoot(root); + break; + case RootCompleted: + if ( + 1073741823 !== workInProgressRootLatestProcessedExpirationTime && + null !== workInProgressRootCanSuspendUsingConfig + ) { + 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 + ); + break; + } + } + commitRoot(root); + break; + default: + throw Error("Unknown root exit status."); + } } + 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 prepareFreshStack(root, expirationTime) { root.finishedWork = null; @@ -6224,26 +6078,27 @@ function prepareFreshStack(root, expirationTime) { var interruptedWork = timeoutHandle; switch (interruptedWork.tag) { case 1: - var childContextTypes = interruptedWork.type.childContextTypes; - null !== childContextTypes && - void 0 !== childContextTypes && - popContext(interruptedWork); + interruptedWork = interruptedWork.type.childContextTypes; + null !== interruptedWork && + void 0 !== interruptedWork && + popContext(); break; case 3: - popHostContainer(interruptedWork); - popTopLevelContextObject(interruptedWork); + popHostContainer(); + pop(didPerformWorkStackCursor); + pop(contextStackCursor); break; case 5: popHostContext(interruptedWork); break; case 4: - popHostContainer(interruptedWork); + popHostContainer(); break; case 13: - pop(suspenseStackCursor, interruptedWork); + pop(suspenseStackCursor); break; case 19: - pop(suspenseStackCursor, interruptedWork); + pop(suspenseStackCursor); break; case 10: popProvider(interruptedWork); @@ -6251,8 +6106,8 @@ function prepareFreshStack(root, expirationTime) { timeoutHandle = timeoutHandle.return; } workInProgressRoot = root; - workInProgress = createWorkInProgress(root.current, null, expirationTime); - renderExpirationTime = expirationTime; + workInProgress = createWorkInProgress(root.current, null); + renderExpirationTime$1 = expirationTime; workInProgressRootExitStatus = RootIncomplete; workInProgressRootFatalError = null; workInProgressRootLatestSuspenseTimeout = workInProgressRootLatestProcessedExpirationTime = 1073741823; @@ -6265,12 +6120,25 @@ function handleError(root$jscomp$0, thrownValue) { do { try { resetContextDependencies(); - resetHooks(); + 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; if (null === workInProgress || null === workInProgress.return) return ( (workInProgressRootExitStatus = RootFatalErrored), (workInProgressRootFatalError = thrownValue), - null + (workInProgress = null) ); workInProgress.mode & 8 && stopProfilerTimerIfRunningAndRecordDelta(workInProgress, !0); @@ -6279,7 +6147,7 @@ function handleError(root$jscomp$0, thrownValue) { returnFiber = workInProgress.return, sourceFiber = workInProgress, value = thrownValue; - thrownValue = renderExpirationTime; + thrownValue = renderExpirationTime$1; sourceFiber.effectTag |= 2048; sourceFiber.firstEffect = sourceFiber.lastEffect = null; if ( @@ -6287,8 +6155,17 @@ function handleError(root$jscomp$0, thrownValue) { "object" === typeof value && "function" === typeof value.then ) { - var thenable = value, - hasInvisibleParentBoundary = + 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 = 0 !== (suspenseStackCursor.current & 1), _workInProgress = returnFiber; do { @@ -6303,10 +6180,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) { @@ -6413,8 +6290,8 @@ function handleError(root$jscomp$0, thrownValue) { } while (1); } function pushDispatcher() { - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = ContextOnlyDispatcher; + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; return null === prevDispatcher ? ContextOnlyDispatcher : prevDispatcher; } function pushInteractions(root) { @@ -6436,6 +6313,33 @@ 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); @@ -6445,43 +6349,35 @@ function workLoopConcurrent() { workInProgress = performUnitOfWork(workInProgress); } function performUnitOfWork(unitOfWork) { - var current$$1 = unitOfWork.alternate; + var current = unitOfWork.alternate; 0 !== (unitOfWork.mode & 8) ? ((profilerStartTime = now$1()), 0 > unitOfWork.actualStartTime && (unitOfWork.actualStartTime = now$1()), - (current$$1 = beginWork$$1(current$$1, unitOfWork, renderExpirationTime)), + (current = beginWork$1(current, unitOfWork, renderExpirationTime$1)), stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, !0)) - : (current$$1 = beginWork$$1(current$$1, unitOfWork, renderExpirationTime)); + : (current = beginWork$1(current, unitOfWork, renderExpirationTime$1)); unitOfWork.memoizedProps = unitOfWork.pendingProps; - null === current$$1 && (current$$1 = completeUnitOfWork(unitOfWork)); + null === current && (current = completeUnitOfWork(unitOfWork)); ReactCurrentOwner$2.current = null; - return current$$1; + return current; } function completeUnitOfWork(unitOfWork) { workInProgress = unitOfWork; do { - var current$$1 = workInProgress.alternate; + var current = workInProgress.alternate; unitOfWork = workInProgress.return; if (0 === (workInProgress.effectTag & 2048)) { if (0 === (workInProgress.mode & 8)) - current$$1 = completeWork( - current$$1, - workInProgress, - renderExpirationTime - ); + current = completeWork(current, workInProgress, renderExpirationTime$1); else { var fiber = workInProgress; profilerStartTime = now$1(); 0 > fiber.actualStartTime && (fiber.actualStartTime = now$1()); - current$$1 = completeWork( - current$$1, - workInProgress, - renderExpirationTime - ); + current = completeWork(current, workInProgress, renderExpirationTime$1); stopProfilerTimerIfRunningAndRecordDelta(workInProgress, !1); } fiber = workInProgress; - if (1 === renderExpirationTime || 1 !== fiber.childExpirationTime) { + if (1 === renderExpirationTime$1 || 1 !== fiber.childExpirationTime) { var newChildExpirationTime = 0; if (0 !== (fiber.mode & 8)) { for ( @@ -6519,7 +6415,7 @@ function completeUnitOfWork(unitOfWork) { (actualDuration = actualDuration.sibling); fiber.childExpirationTime = newChildExpirationTime; } - if (null !== current$$1) return current$$1; + if (null !== current) return current; null !== unitOfWork && 0 === (unitOfWork.effectTag & 2048) && (null === unitOfWork.firstEffect && @@ -6534,7 +6430,7 @@ function completeUnitOfWork(unitOfWork) { : (unitOfWork.firstEffect = workInProgress), (unitOfWork.lastEffect = workInProgress))); } else { - current$$1 = unwindWork(workInProgress, renderExpirationTime); + current = unwindWork(workInProgress); if (0 !== (workInProgress.mode & 8)) { stopProfilerTimerIfRunningAndRecordDelta(workInProgress, !1); fiber = workInProgress.actualDuration; @@ -6547,14 +6443,13 @@ function completeUnitOfWork(unitOfWork) { (newChildExpirationTime = newChildExpirationTime.sibling); workInProgress.actualDuration = fiber; } - if (null !== current$$1) - return (current$$1.effectTag &= 2047), current$$1; + if (null !== current) return (current.effectTag &= 2047), current; null !== unitOfWork && ((unitOfWork.firstEffect = unitOfWork.lastEffect = null), (unitOfWork.effectTag |= 2048)); } - current$$1 = workInProgress.sibling; - if (null !== current$$1) return current$$1; + current = workInProgress.sibling; + if (null !== current) return current; workInProgress = unitOfWork; } while (null !== workInProgress); workInProgressRootExitStatus === RootIncomplete && @@ -6572,7 +6467,8 @@ function commitRoot(root) { return null; } function commitRootImpl(root$jscomp$0, renderPriorityLevel$jscomp$0) { - flushPassiveEffects(); + do flushPassiveEffects(); + while (null !== rootWithPendingPassiveEffects); if ((executionContext & (RenderContext | CommitContext)) !== NoContext) throw Error("Should not already be working."); var finishedWork = root$jscomp$0.finishedWork, @@ -6601,7 +6497,8 @@ 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 = 0)); + ((workInProgress = workInProgressRoot = null), + (renderExpirationTime$1 = 0)); 1 < finishedWork.effectTag ? null !== finishedWork.lastEffect ? ((finishedWork.lastEffect.nextEffect = finishedWork), @@ -6635,9 +6532,9 @@ function commitRootImpl(root$jscomp$0, renderPriorityLevel$jscomp$0) { ) { var effectTag = nextEffect.effectTag; if (effectTag & 128) { - var current$$1 = nextEffect.alternate; - if (null !== current$$1) { - var currentRef = current$$1.ref; + var current = nextEffect.alternate; + if (null !== current) { + var currentRef = current.ref; null !== currentRef && ("function" === typeof currentRef ? currentRef(null) @@ -6665,13 +6562,13 @@ function commitRootImpl(root$jscomp$0, renderPriorityLevel$jscomp$0) { commitWork(nextEffect.alternate, nextEffect); break; case 8: - var current$$1$jscomp$0 = nextEffect; + var current$jscomp$0 = nextEffect; unmountHostComponents( root, - current$$1$jscomp$0, + current$jscomp$0, renderPriorityLevel ); - detachFiber(current$$1$jscomp$0); + detachFiber(current$jscomp$0); } nextEffect = nextEffect.nextEffect; } @@ -6685,113 +6582,25 @@ function commitRootImpl(root$jscomp$0, renderPriorityLevel$jscomp$0) { nextEffect = remainingExpirationTimeBeforeCommit; do try { - for ( - effectTag = root$jscomp$0, current$$1 = expirationTime; - null !== nextEffect; - - ) { + for (effectTag = root$jscomp$0; null !== nextEffect; ) { var effectTag$jscomp$0 = nextEffect.effectTag; - 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." - ); - } - } + effectTag$jscomp$0 & 36 && + commitLifeCycles(effectTag, nextEffect.alternate, nextEffect); if (effectTag$jscomp$0 & 128) { - currentRef = void 0; + current = void 0; var ref = nextEffect.ref; if (null !== ref) { - var instance$jscomp$0 = nextEffect.stateNode; + var instance = nextEffect.stateNode; switch (nextEffect.tag) { case 5: - currentRef = instance$jscomp$0; + current = instance; break; default: - currentRef = instance$jscomp$0; + current = instance; } "function" === typeof ref - ? ref(currentRef) - : (ref.current = currentRef); + ? ref(current) + : (ref.current = current); } } nextEffect = nextEffect.nextEffect; @@ -6827,13 +6636,13 @@ function commitRootImpl(root$jscomp$0, renderPriorityLevel$jscomp$0) { for ( remainingExpirationTimeBeforeCommit = spawnedWorkDuringRender, spawnedWorkDuringRender = null, - current$$1$jscomp$1 = 0; - current$$1$jscomp$1 < remainingExpirationTimeBeforeCommit.length; - current$$1$jscomp$1++ + ref = 0; + ref < remainingExpirationTimeBeforeCommit.length; + ref++ ) scheduleInteractions( root$jscomp$0, - remainingExpirationTimeBeforeCommit[current$$1$jscomp$1], + remainingExpirationTimeBeforeCommit[ref], root$jscomp$0.memoizedInteractions ); schedulePendingInteractions(root$jscomp$0, renderPriorityLevel$jscomp$0); @@ -6894,27 +6703,28 @@ function flushPassiveEffectsImpl() { executionContext |= CommitContext; for ( var prevInteractions = pushInteractions(root), - effect = root.current.firstEffect; - null !== effect; + _effect2 = root.current.firstEffect; + null !== _effect2; ) { try { - var finishedWork = effect; + var finishedWork = _effect2; if (0 !== (finishedWork.effectTag & 512)) switch (finishedWork.tag) { case 0: case 11: case 15: - commitHookEffectList(128, 0, finishedWork), - commitHookEffectList(0, 64, finishedWork); + case 22: + commitHookEffectListUnmount(5, finishedWork), + commitHookEffectListMount(5, finishedWork); } } catch (error) { - if (null === effect) throw Error("Should be working on an effect."); - captureCommitPhaseError(effect, error); + if (null === _effect2) throw Error("Should be working on an effect."); + captureCommitPhaseError(_effect2, error); } - finishedWork = effect.nextEffect; - effect.nextEffect = null; - effect = finishedWork; + finishedWork = _effect2.nextEffect; + _effect2.nextEffect = null; + _effect2 = finishedWork; } tracing.__interactionsRef.current = prevInteractions; finishPendingInteractions(root, expirationTime); @@ -6963,19 +6773,17 @@ function captureCommitPhaseError(sourceFiber, error) { function pingSuspendedRoot(root, thenable, suspendedTime) { var pingCache = root.pingCache; null !== pingCache && pingCache.delete(thenable); - workInProgressRoot === root && renderExpirationTime === suspendedTime + workInProgressRoot === root && renderExpirationTime$1 === suspendedTime ? workInProgressRootExitStatus === RootSuspendedWithDelay || (workInProgressRootExitStatus === RootSuspended && 1073741823 === workInProgressRootLatestProcessedExpirationTime && now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) - ? prepareFreshStack(root, renderExpirationTime) + ? prepareFreshStack(root, renderExpirationTime$1) : (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))); } @@ -6991,12 +6799,12 @@ function resolveRetryThenable(boundaryFiber, thenable) { (ensureRootIsScheduled(boundaryFiber), schedulePendingInteractions(boundaryFiber, thenable)); } -var beginWork$$1; -beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { +var beginWork$1; +beginWork$1 = function(current, workInProgress, renderExpirationTime) { var updateExpirationTime = workInProgress.expirationTime; - if (null !== current$$1) + if (null !== current) if ( - current$$1.memoizedProps !== workInProgress.pendingProps || + current.memoizedProps !== workInProgress.pendingProps || didPerformWorkStackCursor.current ) didReceiveUpdate = !0; @@ -7021,11 +6829,17 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { ); break; case 10: - pushProvider(workInProgress, workInProgress.memoizedProps.value); + updateExpirationTime = workInProgress.memoizedProps.value; + var context = workInProgress.type._context; + push(valueCursor, context._currentValue); + context._currentValue = updateExpirationTime; 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) { @@ -7035,52 +6849,40 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { updateExpirationTime >= renderExpirationTime ) return updateSuspenseComponent( - current$$1, + current, workInProgress, renderExpirationTime ); - push( - suspenseStackCursor, - suspenseStackCursor.current & 1, - workInProgress - ); + push(suspenseStackCursor, suspenseStackCursor.current & 1); workInProgress = bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ); return null !== workInProgress ? workInProgress.sibling : null; } - push( - suspenseStackCursor, - suspenseStackCursor.current & 1, - workInProgress - ); + push(suspenseStackCursor, suspenseStackCursor.current & 1); break; case 19: updateExpirationTime = workInProgress.childExpirationTime >= renderExpirationTime; - if (0 !== (current$$1.effectTag & 64)) { + if (0 !== (current.effectTag & 64)) { if (updateExpirationTime) return updateSuspenseListComponent( - current$$1, + current, workInProgress, renderExpirationTime ); workInProgress.effectTag |= 64; } - var renderState = workInProgress.memoizedState; - null !== renderState && - ((renderState.rendering = null), (renderState.tail = null)); - push( - suspenseStackCursor, - suspenseStackCursor.current, - workInProgress - ); + context = workInProgress.memoizedState; + null !== context && + ((context.rendering = null), (context.tail = null)); + push(suspenseStackCursor, suspenseStackCursor.current); if (!updateExpirationTime) return null; } return bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ); @@ -7092,41 +6894,40 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { switch (workInProgress.tag) { case 2: updateExpirationTime = workInProgress.type; - null !== current$$1 && - ((current$$1.alternate = null), + null !== current && + ((current.alternate = null), (workInProgress.alternate = null), (workInProgress.effectTag |= 2)); - current$$1 = workInProgress.pendingProps; - renderState = getMaskedContext( - workInProgress, - contextStackCursor.current - ); + current = workInProgress.pendingProps; + context = getMaskedContext(workInProgress, contextStackCursor.current); prepareToReadContext(workInProgress, renderExpirationTime); - renderState = renderWithHooks( + context = renderWithHooks( null, workInProgress, updateExpirationTime, - current$$1, - renderState, + current, + context, renderExpirationTime ); workInProgress.effectTag |= 1; if ( - "object" === typeof renderState && - null !== renderState && - "function" === typeof renderState.render && - void 0 === renderState.$$typeof + "object" === typeof context && + null !== context && + "function" === typeof context.render && + void 0 === context.$$typeof ) { workInProgress.tag = 1; - resetHooks(); + workInProgress.memoizedState = null; + workInProgress.updateQueue = null; if (isContextProvider(updateExpirationTime)) { var hasContext = !0; pushContextProvider(workInProgress); } else hasContext = !1; workInProgress.memoizedState = - null !== renderState.state && void 0 !== renderState.state - ? renderState.state + null !== context.state && void 0 !== context.state + ? context.state : null; + initializeUpdateQueue(workInProgress); var getDerivedStateFromProps = updateExpirationTime.getDerivedStateFromProps; "function" === typeof getDerivedStateFromProps && @@ -7134,15 +6935,15 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { workInProgress, updateExpirationTime, getDerivedStateFromProps, - current$$1 + current ); - renderState.updater = classComponentUpdater; - workInProgress.stateNode = renderState; - renderState._reactInternalFiber = workInProgress; + context.updater = classComponentUpdater; + workInProgress.stateNode = context; + context._reactInternalFiber = workInProgress; mountClassInstance( workInProgress, updateExpirationTime, - current$$1, + current, renderExpirationTime ); workInProgress = finishClassComponent( @@ -7158,127 +6959,129 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { reconcileChildren( null, workInProgress, - renderState, + context, renderExpirationTime ), (workInProgress = workInProgress.child); return workInProgress; case 16: - 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." - ); + 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." + ); } return workInProgress; case 0: return ( (updateExpirationTime = workInProgress.type), - (renderState = workInProgress.pendingProps), - (renderState = + (context = workInProgress.pendingProps), + (context = workInProgress.elementType === updateExpirationTime - ? renderState - : resolveDefaultProps(updateExpirationTime, renderState)), + ? context + : resolveDefaultProps(updateExpirationTime, context)), updateFunctionComponent( - current$$1, + current, workInProgress, updateExpirationTime, - renderState, + context, renderExpirationTime ) ); case 1: return ( (updateExpirationTime = workInProgress.type), - (renderState = workInProgress.pendingProps), - (renderState = + (context = workInProgress.pendingProps), + (context = workInProgress.elementType === updateExpirationTime - ? renderState - : resolveDefaultProps(updateExpirationTime, renderState)), + ? context + : resolveDefaultProps(updateExpirationTime, context)), updateClassComponent( - current$$1, + current, workInProgress, updateExpirationTime, - renderState, + context, renderExpirationTime ) ); case 3: pushHostRootContext(workInProgress); updateExpirationTime = workInProgress.updateQueue; - if (null === updateExpirationTime) + if (null === current || 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." ); - renderState = workInProgress.memoizedState; - renderState = null !== renderState ? renderState.element : null; + updateExpirationTime = workInProgress.pendingProps; + context = workInProgress.memoizedState; + context = null !== context ? context.element : null; + cloneUpdateQueue(current, workInProgress); processUpdateQueue( workInProgress, updateExpirationTime, - workInProgress.pendingProps, null, renderExpirationTime ); updateExpirationTime = workInProgress.memoizedState.element; - updateExpirationTime === renderState + updateExpirationTime === context ? (workInProgress = bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime )) : (reconcileChildren( - current$$1, + current, workInProgress, updateExpirationTime, renderExpirationTime @@ -7288,11 +7091,10 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { case 5: return ( pushHostContext(workInProgress), - null === current$$1 && tryToClaimNextHydratableInstance(workInProgress), (updateExpirationTime = workInProgress.pendingProps.children), - markRef(current$$1, workInProgress), + markRef(current, workInProgress), reconcileChildren( - current$$1, + current, workInProgress, updateExpirationTime, renderExpirationTime @@ -7301,13 +7103,10 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { workInProgress ); case 6: - return ( - null === current$$1 && tryToClaimNextHydratableInstance(workInProgress), - null - ); + return null; case 13: return updateSuspenseComponent( - current$$1, + current, workInProgress, renderExpirationTime ); @@ -7318,7 +7117,7 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { workInProgress.stateNode.containerInfo ), (updateExpirationTime = workInProgress.pendingProps), - null === current$$1 + null === current ? (workInProgress.child = reconcileChildFibers( workInProgress, null, @@ -7326,7 +7125,7 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { renderExpirationTime )) : reconcileChildren( - current$$1, + current, workInProgress, updateExpirationTime, renderExpirationTime @@ -7336,23 +7135,23 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { case 11: return ( (updateExpirationTime = workInProgress.type), - (renderState = workInProgress.pendingProps), - (renderState = + (context = workInProgress.pendingProps), + (context = workInProgress.elementType === updateExpirationTime - ? renderState - : resolveDefaultProps(updateExpirationTime, renderState)), + ? context + : resolveDefaultProps(updateExpirationTime, context)), updateForwardRef( - current$$1, + current, workInProgress, updateExpirationTime, - renderState, + context, renderExpirationTime ) ); case 7: return ( reconcileChildren( - current$$1, + current, workInProgress, workInProgress.pendingProps, renderExpirationTime @@ -7362,7 +7161,7 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { case 8: return ( reconcileChildren( - current$$1, + current, workInProgress, workInProgress.pendingProps.children, renderExpirationTime @@ -7372,8 +7171,11 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { case 12: return ( (workInProgress.effectTag |= 4), + (updateExpirationTime = workInProgress.stateNode), + (updateExpirationTime.effectDuration = 0), + (updateExpirationTime.passiveEffectDuration = 0), reconcileChildren( - current$$1, + current, workInProgress, workInProgress.pendingProps.children, renderExpirationTime @@ -7383,27 +7185,32 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { case 10: a: { updateExpirationTime = workInProgress.type._context; - renderState = workInProgress.pendingProps; + context = workInProgress.pendingProps; getDerivedStateFromProps = workInProgress.memoizedProps; - 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) { + 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) + ) { if ( - getDerivedStateFromProps.children === renderState.children && + getDerivedStateFromProps.children === context.children && !didPerformWorkStackCursor.current ) { workInProgress = bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ); @@ -7411,14 +7218,15 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { } } else for ( - oldValue = workInProgress.child, - null !== oldValue && (oldValue.return = workInProgress); - null !== oldValue; + context$jscomp$0 = workInProgress.child, + null !== context$jscomp$0 && + (context$jscomp$0.return = workInProgress); + null !== context$jscomp$0; ) { - var list = oldValue.dependencies; + var list = context$jscomp$0.dependencies; if (null !== list) { - getDerivedStateFromProps = oldValue.child; + getDerivedStateFromProps = context$jscomp$0.child; for ( var dependency = list.firstContext; null !== dependency; @@ -7428,18 +7236,18 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { dependency.context === updateExpirationTime && 0 !== (dependency.observedBits & hasContext) ) { - 1 === oldValue.tag && + 1 === context$jscomp$0.tag && ((dependency = createUpdate(renderExpirationTime, null)), (dependency.tag = 2), - enqueueUpdate(oldValue, dependency)); - oldValue.expirationTime < renderExpirationTime && - (oldValue.expirationTime = renderExpirationTime); - dependency = oldValue.alternate; + enqueueUpdate(context$jscomp$0, dependency)); + context$jscomp$0.expirationTime < renderExpirationTime && + (context$jscomp$0.expirationTime = renderExpirationTime); + dependency = context$jscomp$0.alternate; null !== dependency && dependency.expirationTime < renderExpirationTime && (dependency.expirationTime = renderExpirationTime); scheduleWorkOnParentPath( - oldValue.return, + context$jscomp$0.return, renderExpirationTime ); list.expirationTime < renderExpirationTime && @@ -7450,16 +7258,16 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { } } else getDerivedStateFromProps = - 10 === oldValue.tag - ? oldValue.type === workInProgress.type + 10 === context$jscomp$0.tag + ? context$jscomp$0.type === workInProgress.type ? null - : oldValue.child - : oldValue.child; + : context$jscomp$0.child + : context$jscomp$0.child; if (null !== getDerivedStateFromProps) - getDerivedStateFromProps.return = oldValue; + getDerivedStateFromProps.return = context$jscomp$0; else for ( - getDerivedStateFromProps = oldValue; + getDerivedStateFromProps = context$jscomp$0; null !== getDerivedStateFromProps; ) { @@ -7467,21 +7275,20 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { getDerivedStateFromProps = null; break; } - oldValue = getDerivedStateFromProps.sibling; - if (null !== oldValue) { - oldValue.return = getDerivedStateFromProps.return; - getDerivedStateFromProps = oldValue; + context$jscomp$0 = getDerivedStateFromProps.sibling; + if (null !== context$jscomp$0) { + context$jscomp$0.return = getDerivedStateFromProps.return; + getDerivedStateFromProps = context$jscomp$0; break; } getDerivedStateFromProps = getDerivedStateFromProps.return; } - oldValue = getDerivedStateFromProps; + context$jscomp$0 = getDerivedStateFromProps; } - } reconcileChildren( - current$$1, + current, workInProgress, - renderState.children, + context.children, renderExpirationTime ); workInProgress = workInProgress.child; @@ -7489,18 +7296,15 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { return workInProgress; case 9: return ( - (renderState = workInProgress.type), + (context = workInProgress.type), (hasContext = workInProgress.pendingProps), (updateExpirationTime = hasContext.children), prepareToReadContext(workInProgress, renderExpirationTime), - (renderState = readContext( - renderState, - hasContext.unstable_observedBits - )), - (updateExpirationTime = updateExpirationTime(renderState)), + (context = readContext(context, hasContext.unstable_observedBits)), + (updateExpirationTime = updateExpirationTime(context)), (workInProgress.effectTag |= 1), reconcileChildren( - current$$1, + current, workInProgress, updateExpirationTime, renderExpirationTime @@ -7509,16 +7313,16 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { ); case 14: return ( - (renderState = workInProgress.type), + (context = workInProgress.type), (hasContext = resolveDefaultProps( - renderState, + context, workInProgress.pendingProps )), - (hasContext = resolveDefaultProps(renderState.type, hasContext)), + (hasContext = resolveDefaultProps(context.type, hasContext)), updateMemoComponent( - current$$1, + current, workInProgress, - renderState, + context, hasContext, updateExpirationTime, renderExpirationTime @@ -7526,7 +7330,7 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { ); case 15: return updateSimpleMemoComponent( - current$$1, + current, workInProgress, workInProgress.type, workInProgress.pendingProps, @@ -7536,30 +7340,25 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { case 17: return ( (updateExpirationTime = workInProgress.type), - (renderState = workInProgress.pendingProps), - (renderState = + (context = workInProgress.pendingProps), + (context = workInProgress.elementType === updateExpirationTime - ? renderState - : resolveDefaultProps(updateExpirationTime, renderState)), - null !== current$$1 && - ((current$$1.alternate = null), + ? context + : resolveDefaultProps(updateExpirationTime, context)), + null !== current && + ((current.alternate = null), (workInProgress.alternate = null), (workInProgress.effectTag |= 2)), (workInProgress.tag = 1), isContextProvider(updateExpirationTime) - ? ((current$$1 = !0), pushContextProvider(workInProgress)) - : (current$$1 = !1), + ? ((current = !0), pushContextProvider(workInProgress)) + : (current = !1), prepareToReadContext(workInProgress, renderExpirationTime), - constructClassInstance( - workInProgress, - updateExpirationTime, - renderState, - renderExpirationTime - ), + constructClassInstance(workInProgress, updateExpirationTime, context), mountClassInstance( workInProgress, updateExpirationTime, - renderState, + context, renderExpirationTime ), finishClassComponent( @@ -7567,13 +7366,13 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { workInProgress, updateExpirationTime, !0, - current$$1, + current, renderExpirationTime ) ); case 19: return updateSuspenseListComponent( - current$$1, + current, workInProgress, renderExpirationTime ); @@ -7714,9 +7513,6 @@ 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); @@ -7734,7 +7530,7 @@ function resolveLazyComponentTag(Component) { function createWorkInProgress(current, pendingProps) { var workInProgress = current.alternate; null === workInProgress - ? ((workInProgress = createFiber( + ? ((workInProgress = new FiberNode( current.tag, pendingProps, current.key, @@ -7752,6 +7548,10 @@ 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; @@ -7805,15 +7605,16 @@ function createFiberFromTypeAndProps( break; case REACT_PROFILER_TYPE: return ( - (type = createFiber(12, pendingProps, key, mode | 8)), + (type = new FiberNode(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 = createFiber(13, pendingProps, key, mode)), + (type = new FiberNode(13, pendingProps, key, mode)), (type.type = REACT_SUSPENSE_TYPE), (type.elementType = REACT_SUSPENSE_TYPE), (type.expirationTime = expirationTime), @@ -7821,7 +7622,7 @@ function createFiberFromTypeAndProps( ); case REACT_SUSPENSE_LIST_TYPE: return ( - (type = createFiber(19, pendingProps, key, mode)), + (type = new FiberNode(19, pendingProps, key, mode)), (type.elementType = REACT_SUSPENSE_LIST_TYPE), (type.expirationTime = expirationTime), type @@ -7845,6 +7646,9 @@ 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: " + @@ -7852,24 +7656,24 @@ function createFiberFromTypeAndProps( "." ); } - key = createFiber(fiberTag, pendingProps, key, mode); + key = new FiberNode(fiberTag, pendingProps, key, mode); key.elementType = type; key.type = owner; key.expirationTime = expirationTime; return key; } function createFiberFromFragment(elements, mode, expirationTime, key) { - elements = createFiber(7, elements, key, mode); + elements = new FiberNode(7, elements, key, mode); elements.expirationTime = expirationTime; return elements; } function createFiberFromText(content, mode, expirationTime) { - content = createFiber(6, content, null, mode); + content = new FiberNode(6, content, null, mode); content.expirationTime = expirationTime; return content; } function createFiberFromPortal(portal, mode, expirationTime) { - mode = createFiber( + mode = new FiberNode( 4, null !== portal.children ? portal.children : [], portal.key, @@ -7931,11 +7735,6 @@ 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) { @@ -7950,14 +7749,10 @@ function findHostInstance(component) { return null === component ? null : component.stateNode; } function updateContainer(element, container, parentComponent, callback) { - var current$$1 = container.current, + var current = container.current, currentTime = requestCurrentTimeForUpdate(), suspenseConfig = ReactCurrentBatchConfig.suspense; - currentTime = computeExpirationForFiber( - currentTime, - current$$1, - suspenseConfig - ); + currentTime = computeExpirationForFiber(currentTime, current, suspenseConfig); a: if (parentComponent) { parentComponent = parentComponent._reactInternalFiber; b: { @@ -8008,8 +7803,8 @@ function updateContainer(element, container, parentComponent, callback) { container.payload = { element: element }; callback = void 0 === callback ? null : callback; null !== callback && (container.callback = callback); - enqueueUpdate(current$$1, container); - scheduleUpdateOnFiber(current$$1, currentTime); + enqueueUpdate(current, container); + scheduleWork(current, currentTime); return currentTime; } function createPortal(children, containerInfo, implementation) { @@ -8023,11 +7818,6 @@ 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; @@ -8038,8 +7828,15 @@ function findNodeHandle(componentOrHandle) { return null == componentOrHandle ? componentOrHandle : componentOrHandle.canonical - ? componentOrHandle.canonical._nativeTag - : componentOrHandle._nativeTag; + ? componentOrHandle.canonical._nativeTag + : componentOrHandle._nativeTag; +} +function unmountComponentAtNode(containerTag) { + var root = roots.get(containerTag); + root && + updateContainer(null, root, null, function() { + roots.delete(containerTag); + }); } batchedUpdatesImpl = function(fn, a) { var prevExecutionContext = executionContext; @@ -8051,301 +7848,119 @@ batchedUpdatesImpl = function(fn, a) { executionContext === NoContext && flushSyncCallbackQueue(); } }; -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 = 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) - : ""; - } - } - }; +var roots = new Map(); (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 - }) - ); + 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; + }, + 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.11.0", - rendererPackageName: "react-native-renderer" + 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) + } }); -var ReactNativeRenderer$2 = { default: ReactNativeRenderer }, - ReactNativeRenderer$3 = - (ReactNativeRenderer$2 && ReactNativeRenderer) || ReactNativeRenderer$2; -module.exports = ReactNativeRenderer$3.default || ReactNativeRenderer$3; +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; diff --git a/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.js b/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.js index f6ef2ae04e6e38..c81740113065d3 100644 --- a/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.js +++ b/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.js @@ -5,6 +5,7 @@ * LICENSE file in the root directory of this source tree. * * @noflow + * @nolint * @providesModule ReactNativeRenderer-profiling * @preventMunge * @generated @@ -15,86 +16,17 @@ require("react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore"); var ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/ReactNativePrivateInterface"), React = require("react"), Scheduler = require("scheduler"), - 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 + - "`." - ); - } - } - } + tracing = require("scheduler/tracing"); +function getParent(inst) { + do inst = inst.return; + while (inst && 5 !== inst.tag); + return inst ? inst : null; } -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; +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); } -var plugins = [], - eventNameDispatchConfigs = {}, - registrationNameModules = {}; function invokeGuardedCallbackImpl(name, func, context, a, b, c, d, e, f) { var funcArgs = Array.prototype.slice.call(arguments, 3); try { @@ -165,74 +97,6 @@ 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; @@ -250,6 +114,7 @@ function getListener(inst, registrationName) { case "onMouseMoveCapture": case "onMouseUp": case "onMouseUpCapture": + case "onMouseEnter": (props = !props.disabled) || ((inst = inst.type), (props = !( @@ -274,15 +139,21 @@ function getListener(inst, registrationName) { ); return listener; } -function getParent(inst) { - do inst = inst.return; - while (inst && 5 !== inst.tag); - return inst ? inst : null; +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 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 forEachAccumulated(arr, cb, scope) { + Array.isArray(arr) ? arr.forEach(cb, scope) : arr && cb.call(scope, arr); } function accumulateDirectionalDispatches(inst, phase, event) { if ( @@ -350,8 +221,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) @@ -504,53 +375,27 @@ 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))) - : console.warn( - "Cannot record touch move without a touch start.\nTouch Move: %s\n", - "Touch Bank: %s", - printTouch(touch), - printTouchBank() - ); + 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))); } 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))) - : 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; + 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))); } var ResponderTouchHistoryStore = { recordTouchTrack: function(topLevelType, nativeEvent) { @@ -590,10 +435,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; @@ -683,13 +528,7 @@ var eventTypes = { "topTouchCancel" === topLevelType ) if (0 <= trackedTouchCount) --trackedTouchCount; - else - return ( - console.warn( - "Ended a touch event which was not counted in `trackedTouchCount`." - ), - null - ); + else return null; ResponderTouchHistoryStore.recordTouchTrack(topLevelType, nativeEvent); if ( targetInst && @@ -701,10 +540,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; @@ -858,10 +697,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, @@ -924,8 +763,8 @@ var eventTypes = { (topLevelType = shouldSetEventType ? eventTypes.responderTerminate : topLevelType - ? eventTypes.responderRelease - : null) + ? eventTypes.responderRelease + : null) ) (nativeEvent = ResponderSyntheticEvent.getPooled( topLevelType, @@ -949,65 +788,168 @@ 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; -injection.injectEventPluginOrder([ +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([ "ResponderEventPlugin", "ReactNativeBridgeEventPlugin" ]); -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, +recomputePluginOrdering(); +var injectedNamesToPlugins$jscomp$inline_94 = { + ResponderEventPlugin: ResponderEventPlugin, + ReactNativeBridgeEventPlugin: { + eventTypes: {}, + extractEvents: function( + topLevelType, targetInst, nativeEvent, nativeEventTarget - ); - if (bubbleDispatchConfig) - forEachAccumulated(topLevelType, accumulateTwoPhaseDispatchesSingle); - else if (directDispatchConfig) - forEachAccumulated(topLevelType, accumulateDirectDispatchesSingle); - else return null; - return topLevelType; + ) { + 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 + ) { + if (namesToPlugins[pluginName$jscomp$inline_96]) + throw Error( + "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + + pluginName$jscomp$inline_96 + + "`." + ); + namesToPlugins[ + pluginName$jscomp$inline_96 + ] = pluginModule$jscomp$inline_97; + isOrderingDirty$jscomp$inline_95 = !0; } } -}); +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); @@ -1015,21 +957,27 @@ function batchedUpdates(fn, bookkeeping) { 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)) + 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++ ) - for (bookkeeping = 0; bookkeeping < fn.length; bookkeeping++) - restoreStateOfTarget(fn[bookkeeping]); + 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 EMPTY_NATIVE_EVENT = {}; @@ -1037,7 +985,7 @@ function _receiveRootNodeIDEvent(rootNodeID, topLevelType, nativeEventParam) { var nativeEvent = nativeEventParam || EMPTY_NATIVE_EVENT, inst = getInstanceFromTag(rootNodeID), target = null; - target = nativeEvent.target; + null != inst && (target = inst.stateNode); batchedUpdates(function() { var events = target; for (var events$jscomp$0 = null, i = 0; i < plugins.length; i++) { @@ -1112,10 +1060,11 @@ getFiberCurrentPropsFromNode = function(stateNode) { }; getInstanceFromNode = getInstanceFromTag; getNodeFromInstance = function(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; + 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; }; ResponderEventPlugin.injection.injectGlobalResponderHandler({ onChange: function(from, to, blockNativeResponder) { @@ -1150,11 +1099,9 @@ 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; -hasSymbol && Symbol.for("react.fundamental"); -hasSymbol && Symbol.for("react.responder"); -hasSymbol && Symbol.for("react.scope"); -var MAYBE_ITERATOR_SYMBOL = "function" === typeof Symbol && Symbol.iterator; + 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; function getIteratorFn(maybeIterable) { if (null === maybeIterable || "object" !== typeof maybeIterable) return null; maybeIterable = @@ -1164,9 +1111,10 @@ function getIteratorFn(maybeIterable) { } function initializeLazyComponentType(lazyComponent) { if (-1 === lazyComponent._status) { - lazyComponent._status = 0; - var ctor = lazyComponent._ctor; + var ctor = lazyComponent._result; + ctor || (ctor = lazyComponent._ctor); ctor = ctor(); + lazyComponent._status = 0; lazyComponent._result = ctor; ctor.then( function(moduleObject) { @@ -1203,9 +1151,9 @@ function getComponentName(type) { if ("object" === typeof type) switch (type.$$typeof) { case REACT_CONTEXT_TYPE: - return "Context.Consumer"; + return (type.displayName || "Context") + ".Consumer"; case REACT_PROVIDER_TYPE: - return "Context.Provider"; + return (type._context.displayName || "Context") + ".Provider"; case REACT_FORWARD_REF_TYPE: var innerType = type.render; innerType = innerType.displayName || innerType.name || ""; @@ -1215,6 +1163,8 @@ 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); @@ -1395,8 +1345,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)) { @@ -1574,10 +1524,10 @@ var ReactNativeFiberHostComponent = (function() { } var _proto = ReactNativeFiberHostComponent.prototype; _proto.blur = function() { - ReactNativePrivateInterface.TextInputState.blurTextInput(this._nativeTag); + ReactNativePrivateInterface.TextInputState.blurTextInput(this); }; _proto.focus = function() { - ReactNativePrivateInterface.TextInputState.focusTextInput(this._nativeTag); + ReactNativePrivateInterface.TextInputState.focusTextInput(this); }; _proto.measure = function(callback) { ReactNativePrivateInterface.UIManager.measure( @@ -1621,7 +1571,7 @@ var ReactNativeFiberHostComponent = (function() { }; return ReactNativeFiberHostComponent; })(); -function shim$1() { +function shim() { throw Error( "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." ); @@ -1659,45 +1609,7 @@ function finalizeInitialChildren(parentInstance) { } var scheduleTimeout = setTimeout, cancelTimeout = clearTimeout, - 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 = [], + valueStack = [], index = -1; function pop(cursor) { 0 > index || @@ -1734,21 +1646,17 @@ function isContextProvider(type) { type = type.childContextTypes; return null !== type && void 0 !== type; } -function popContext(fiber) { - pop(didPerformWorkStackCursor, fiber); - pop(contextStackCursor, fiber); -} -function popTopLevelContextObject(fiber) { - pop(didPerformWorkStackCursor, fiber); - pop(contextStackCursor, fiber); +function popContext() { + pop(didPerformWorkStackCursor); + pop(contextStackCursor); } function pushTopLevelContextObject(fiber, context, didChange) { if (contextStackCursor.current !== emptyContextObject) throw Error( "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." ); - push(contextStackCursor, context, fiber); - push(didPerformWorkStackCursor, didChange, fiber); + push(contextStackCursor, context); + push(didPerformWorkStackCursor, didChange); } function processChildContext(fiber, type, parentContext) { var instance = fiber.stateNode; @@ -1766,17 +1674,13 @@ function processChildContext(fiber, type, parentContext) { return Object.assign({}, parentContext, {}, instance); } function pushContextProvider(workInProgress) { - var instance = workInProgress.stateNode; - instance = - (instance && instance.__reactInternalMemoizedMergedChildContext) || + workInProgress = + ((workInProgress = workInProgress.stateNode) && + workInProgress.__reactInternalMemoizedMergedChildContext) || emptyContextObject; previousContext = contextStackCursor.current; - push(contextStackCursor, instance, workInProgress); - push( - didPerformWorkStackCursor, - didPerformWorkStackCursor.current, - workInProgress - ); + push(contextStackCursor, workInProgress); + push(didPerformWorkStackCursor, didPerformWorkStackCursor.current); return !0; } function invalidateContextProvider(workInProgress, type, didChange) { @@ -1786,13 +1690,17 @@ 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 - ? ((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); + ? ((workInProgress = processChildContext( + workInProgress, + type, + previousContext + )), + (instance.__reactInternalMemoizedMergedChildContext = workInProgress), + pop(didPerformWorkStackCursor), + pop(contextStackCursor), + push(contextStackCursor, workInProgress)) + : pop(didPerformWorkStackCursor); + push(didPerformWorkStackCursor, didChange); } var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback, @@ -1919,18 +1827,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 is$1 = "function" === typeof Object.is ? Object.is : is, +var objectIs = "function" === typeof Object.is ? Object.is : is, hasOwnProperty = Object.prototype.hasOwnProperty; function shallowEqual(objA, objB) { - if (is$1(objA, objB)) return !0; + if (objectIs(objA, objB)) return !0; if ( "object" !== typeof objA || null === objA || @@ -1944,11 +1852,48 @@ function shallowEqual(objA, objB) { for (keysB = 0; keysB < keysA.length; keysB++) if ( !hasOwnProperty.call(objB, keysA[keysB]) || - !is$1(objA[keysA[keysB]], objB[keysA[keysB]]) + !objectIs(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); @@ -1966,14 +1911,9 @@ 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, providerFiber); + pop(valueCursor); providerFiber.type._context._currentValue = currentValue; } function scheduleWorkOnParentPath(parent, renderExpirationTime) { @@ -2028,237 +1968,195 @@ function readContext(context, observedBits) { return context._currentValue; } var hasForceUpdate = !1; -function createUpdateQueue(baseState) { - return { - baseState: baseState, - firstUpdate: null, - lastUpdate: null, - firstCapturedUpdate: null, - lastCapturedUpdate: null, - firstEffect: null, - lastEffect: null, - firstCapturedEffect: null, - lastCapturedEffect: null +function initializeUpdateQueue(fiber) { + fiber.updateQueue = { + baseState: fiber.memoizedState, + baseQueue: null, + shared: { pending: null }, + effects: null }; } -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 cloneUpdateQueue(current, workInProgress) { + current = current.updateQueue; + workInProgress.updateQueue === current && + (workInProgress.updateQueue = { + baseState: current.baseState, + baseQueue: current.baseQueue, + shared: current.shared, + effects: current.effects + }); } function createUpdate(expirationTime, suspenseConfig) { - return { + expirationTime = { expirationTime: expirationTime, suspenseConfig: suspenseConfig, tag: 0, payload: null, callback: null, - next: null, - nextEffect: null + next: null }; -} -function appendUpdateToQueue(queue, update) { - null === queue.lastUpdate - ? (queue.firstUpdate = queue.lastUpdate = update) - : ((queue.lastUpdate.next = update), (queue.lastUpdate = update)); + return (expirationTime.next = expirationTime); } function enqueueUpdate(fiber, 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)); + 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; + } } 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 && - 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; + 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)); } function processUpdateQueue( - workInProgress, - queue, + workInProgress$jscomp$0, props, instance, renderExpirationTime ) { + var queue = workInProgress$jscomp$0.updateQueue; hasForceUpdate = !1; - queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue); - for ( - var newBaseState = queue.baseState, - newFirstUpdate = null, - newExpirationTime = 0, - 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; + 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)); } - 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; + if (null !== baseQueue) { + baseFirst = baseQueue.next; + var newState = queue.baseState, + 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; } - 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) { - 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); + 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); + } } - effect = effect.nextEffect; - } } var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig, emptyRefsObject = new React.Component().refs; @@ -2275,10 +2173,8 @@ function applyDerivedStateFromProps( ? ctor : Object.assign({}, ctor, getDerivedStateFromProps); workInProgress.memoizedState = getDerivedStateFromProps; - nextProps = workInProgress.updateQueue; - null !== nextProps && - 0 === workInProgress.expirationTime && - (nextProps.baseState = getDerivedStateFromProps); + 0 === workInProgress.expirationTime && + (workInProgress.updateQueue.baseState = getDerivedStateFromProps); } var classComponentUpdater = { isMounted: function(component) { @@ -2297,7 +2193,7 @@ var classComponentUpdater = { null !== callback && (suspenseConfig.callback = callback); enqueueUpdate(inst, suspenseConfig); - scheduleUpdateOnFiber(inst, currentTime); + scheduleWork(inst, currentTime); }, enqueueReplaceState: function(inst, payload, callback) { inst = inst._reactInternalFiber; @@ -2311,7 +2207,7 @@ var classComponentUpdater = { null !== callback && (suspenseConfig.callback = callback); enqueueUpdate(inst, suspenseConfig); - scheduleUpdateOnFiber(inst, currentTime); + scheduleWork(inst, currentTime); }, enqueueForceUpdate: function(inst, callback) { inst = inst._reactInternalFiber; @@ -2324,7 +2220,7 @@ var classComponentUpdater = { null !== callback && (suspenseConfig.callback = callback); enqueueUpdate(inst, suspenseConfig); - scheduleUpdateOnFiber(inst, currentTime); + scheduleWork(inst, currentTime); } }; function checkShouldComponentUpdate( @@ -2340,8 +2236,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, @@ -2393,6 +2289,7 @@ 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)) @@ -2400,16 +2297,8 @@ function mountClassInstance( ? previousContext : contextStackCursor.current), (instance.context = getMaskedContext(workInProgress, contextType))); - contextType = workInProgress.updateQueue; - null !== contextType && - (processUpdateQueue( - workInProgress, - contextType, - newProps, - instance, - renderExpirationTime - ), - (instance.state = workInProgress.memoizedState)); + processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime); + instance.state = workInProgress.memoizedState; contextType = ctor.getDerivedStateFromProps; "function" === typeof contextType && (applyDerivedStateFromProps(workInProgress, ctor, contextType, newProps), @@ -2425,21 +2314,18 @@ function mountClassInstance( instance.UNSAFE_componentWillMount(), ctor !== instance.state && classComponentUpdater.enqueueReplaceState(instance, instance.state, null), - (contextType = workInProgress.updateQueue), - null !== contextType && - (processUpdateQueue( - workInProgress, - contextType, - newProps, - instance, - renderExpirationTime - ), - (instance.state = workInProgress.memoizedState))); + processUpdateQueue( + workInProgress, + newProps, + instance, + renderExpirationTime + ), + (instance.state = workInProgress.memoizedState)); "function" === typeof instance.componentDidMount && (workInProgress.effectTag |= 4); } var isArray = Array.isArray; -function coerceRef(returnFiber, current$$1, element) { +function coerceRef(returnFiber, current, element) { returnFiber = element.ref; if ( null !== returnFiber && @@ -2451,7 +2337,7 @@ function coerceRef(returnFiber, current$$1, element) { if (element) { if (1 !== element.tag) throw Error( - "Function components cannot have refs. Did you mean to use React.forwardRef()?" + "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" ); var inst = element.stateNode; } @@ -2463,19 +2349,19 @@ function coerceRef(returnFiber, current$$1, element) { ); var stringRef = "" + returnFiber; if ( - null !== current$$1 && - null !== current$$1.ref && - "function" === typeof current$$1.ref && - current$$1.ref._stringRef === stringRef + null !== current && + null !== current.ref && + "function" === typeof current.ref && + current.ref._stringRef === stringRef ) - return current$$1.ref; - current$$1 = function(value) { + return current.ref; + current = function(value) { var refs = inst.refs; refs === emptyRefsObject && (refs = inst.refs = {}); null === value ? delete refs[stringRef] : (refs[stringRef] = value); }; - current$$1._stringRef = stringRef; - return current$$1; + current._stringRef = stringRef; + return current; } if ("string" !== typeof returnFiber) throw Error( @@ -2527,8 +2413,8 @@ function ChildReconciler(shouldTrackSideEffects) { (currentFirstChild = currentFirstChild.sibling); return returnFiber; } - function useFiber(fiber, pendingProps, expirationTime) { - fiber = createWorkInProgress(fiber, pendingProps, expirationTime); + function useFiber(fiber, pendingProps) { + fiber = createWorkInProgress(fiber, pendingProps); fiber.index = 0; fiber.sibling = null; return fiber; @@ -2553,31 +2439,26 @@ function ChildReconciler(shouldTrackSideEffects) { (newFiber.effectTag = 2); return newFiber; } - function updateTextNode( - returnFiber, - current$$1, - textContent, - expirationTime - ) { - if (null === current$$1 || 6 !== current$$1.tag) + function updateTextNode(returnFiber, current, textContent, expirationTime) { + if (null === current || 6 !== current.tag) return ( - (current$$1 = createFiberFromText( + (current = createFiberFromText( textContent, returnFiber.mode, expirationTime )), - (current$$1.return = returnFiber), - current$$1 + (current.return = returnFiber), + current ); - current$$1 = useFiber(current$$1, textContent, expirationTime); - current$$1.return = returnFiber; - return current$$1; + current = useFiber(current, textContent); + current.return = returnFiber; + return current; } - function updateElement(returnFiber, current$$1, element, expirationTime) { - if (null !== current$$1 && current$$1.elementType === element.type) + function updateElement(returnFiber, current, element, expirationTime) { + if (null !== current && current.elementType === element.type) return ( - (expirationTime = useFiber(current$$1, element.props, expirationTime)), - (expirationTime.ref = coerceRef(returnFiber, current$$1, element)), + (expirationTime = useFiber(current, element.props)), + (expirationTime.ref = coerceRef(returnFiber, current, element)), (expirationTime.return = returnFiber), expirationTime ); @@ -2589,51 +2470,45 @@ function ChildReconciler(shouldTrackSideEffects) { returnFiber.mode, expirationTime ); - expirationTime.ref = coerceRef(returnFiber, current$$1, element); + expirationTime.ref = coerceRef(returnFiber, current, element); expirationTime.return = returnFiber; return expirationTime; } - function updatePortal(returnFiber, current$$1, portal, expirationTime) { + function updatePortal(returnFiber, current, portal, expirationTime) { if ( - null === current$$1 || - 4 !== current$$1.tag || - current$$1.stateNode.containerInfo !== portal.containerInfo || - current$$1.stateNode.implementation !== portal.implementation + null === current || + 4 !== current.tag || + current.stateNode.containerInfo !== portal.containerInfo || + current.stateNode.implementation !== portal.implementation ) return ( - (current$$1 = createFiberFromPortal( + (current = createFiberFromPortal( portal, returnFiber.mode, expirationTime )), - (current$$1.return = returnFiber), - current$$1 + (current.return = returnFiber), + current ); - current$$1 = useFiber(current$$1, portal.children || [], expirationTime); - current$$1.return = returnFiber; - return current$$1; + current = useFiber(current, portal.children || []); + current.return = returnFiber; + return current; } - function updateFragment( - returnFiber, - current$$1, - fragment, - expirationTime, - key - ) { - if (null === current$$1 || 7 !== current$$1.tag) + function updateFragment(returnFiber, current, fragment, expirationTime, key) { + if (null === current || 7 !== current.tag) return ( - (current$$1 = createFiberFromFragment( + (current = createFiberFromFragment( fragment, returnFiber.mode, expirationTime, key )), - (current$$1.return = returnFiber), - current$$1 + (current.return = returnFiber), + current ); - current$$1 = useFiber(current$$1, fragment, expirationTime); - current$$1.return = returnFiber; - return current$$1; + current = useFiber(current, fragment); + current.return = returnFiber; + return current; } function createChild(returnFiber, newChild, expirationTime) { if ("string" === typeof newChild || "number" === typeof newChild) @@ -2996,39 +2871,48 @@ function ChildReconciler(shouldTrackSideEffects) { null !== isUnkeyedTopLevelFragment; ) { - 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; + 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; + } } - else deleteChild(returnFiber, isUnkeyedTopLevelFragment); + deleteRemainingChildren(returnFiber, isUnkeyedTopLevelFragment); + break; + } else deleteChild(returnFiber, isUnkeyedTopLevelFragment); isUnkeyedTopLevelFragment = isUnkeyedTopLevelFragment.sibling; } newChild.type === REACT_FRAGMENT_TYPE @@ -3078,8 +2962,7 @@ function ChildReconciler(shouldTrackSideEffects) { ); currentFirstChild = useFiber( currentFirstChild, - newChild.children || [], - expirationTime + newChild.children || [] ); currentFirstChild.return = returnFiber; returnFiber = currentFirstChild; @@ -3106,11 +2989,7 @@ function ChildReconciler(shouldTrackSideEffects) { (newChild = "" + newChild), null !== currentFirstChild && 6 === currentFirstChild.tag ? (deleteRemainingChildren(returnFiber, currentFirstChild.sibling), - (currentFirstChild = useFiber( - currentFirstChild, - newChild, - expirationTime - )), + (currentFirstChild = useFiber(currentFirstChild, newChild)), (currentFirstChild.return = returnFiber), (returnFiber = currentFirstChild)) : (deleteRemainingChildren(returnFiber, currentFirstChild), @@ -3165,16 +3044,16 @@ function requiredContext(c) { return c; } function pushHostContainer(fiber, nextRootInstance) { - push(rootInstanceStackCursor, nextRootInstance, fiber); - push(contextFiberStackCursor, fiber, fiber); - push(contextStackCursor$1, NO_CONTEXT, fiber); - pop(contextStackCursor$1, fiber); - push(contextStackCursor$1, { isInAParentText: !1 }, fiber); + push(rootInstanceStackCursor, nextRootInstance); + push(contextFiberStackCursor, fiber); + push(contextStackCursor$1, NO_CONTEXT); + pop(contextStackCursor$1); + push(contextStackCursor$1, { isInAParentText: !1 }); } -function popHostContainer(fiber) { - pop(contextStackCursor$1, fiber); - pop(contextFiberStackCursor, fiber); - pop(rootInstanceStackCursor, fiber); +function popHostContainer() { + pop(contextStackCursor$1); + pop(contextFiberStackCursor); + pop(rootInstanceStackCursor); } function pushHostContext(fiber) { requiredContext(rootInstanceStackCursor.current); @@ -3191,23 +3070,19 @@ function pushHostContext(fiber) { ? { isInAParentText: nextContext } : context; context !== nextContext && - (push(contextFiberStackCursor, fiber, fiber), - push(contextStackCursor$1, nextContext, fiber)); + (push(contextFiberStackCursor, fiber), + push(contextStackCursor$1, nextContext)); } function popHostContext(fiber) { contextFiberStackCursor.current === fiber && - (pop(contextStackCursor$1, fiber), pop(contextFiberStackCursor, fiber)); + (pop(contextStackCursor$1), pop(contextFiberStackCursor)); } var suspenseStackCursor = { current: 0 }; function findFirstSuspended(row) { for (var node = row; null !== node; ) { if (13 === node.tag) { var state = node.memoizedState; - if ( - null !== state && - ((state = state.dehydrated), - null === state || shim$1(state) || shim$1(state)) - ) + if (null !== state && (null === state.dehydrated || shim() || shim())) return node; } else if (19 === node.tag && void 0 !== node.memoizedProps.revealOrder) { if (0 !== (node.effectTag & 64)) return node; @@ -3226,24 +3101,16 @@ function findFirstSuspended(row) { } return null; } -function createResponderListener(responder, props) { +function createDeprecatedResponderListener(responder, props) { return { responder: responder, props: props }; } -var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, +var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig, - renderExpirationTime$1 = 0, + renderExpirationTime = 0, currentlyRenderingFiber$1 = null, currentHook = null, - nextCurrentHook = null, - firstWorkInProgressHook = null, workInProgressHook = null, - nextWorkInProgressHook = null, - remainingExpirationTime = 0, - componentUpdateQueue = null, - sideEffectTag = 0, - didScheduleRenderPhaseUpdate = !1, - renderPhaseUpdates = null, - numberOfReRenders = 0; + didScheduleRenderPhaseUpdate = !1; 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." @@ -3252,7 +3119,7 @@ function throwInvalidHookError() { function areHookInputsEqual(nextDeps, prevDeps) { if (null === prevDeps) return !1; for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) - if (!is$1(nextDeps[i], prevDeps[i])) return !1; + if (!objectIs(nextDeps[i], prevDeps[i])) return !1; return !0; } function renderWithHooks( @@ -3260,92 +3127,85 @@ function renderWithHooks( workInProgress, Component, props, - refOrContext, + secondArg, nextRenderExpirationTime ) { - renderExpirationTime$1 = nextRenderExpirationTime; + renderExpirationTime = nextRenderExpirationTime; currentlyRenderingFiber$1 = workInProgress; - 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; + 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); } - 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) + ReactCurrentDispatcher.current = ContextOnlyDispatcher; + workInProgress = null !== currentHook && null !== currentHook.next; + renderExpirationTime = 0; + workInProgressHook = currentHook = currentlyRenderingFiber$1 = null; + didScheduleRenderPhaseUpdate = !1; + if (workInProgress) throw Error( "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." ); - 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; + return current; } function mountWorkInProgressHook() { var hook = { memoizedState: null, baseState: null, + baseQueue: null, queue: null, - baseUpdate: null, next: null }; null === workInProgressHook - ? (firstWorkInProgressHook = workInProgressHook = hook) + ? (currentlyRenderingFiber$1.memoizedState = 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), - (nextWorkInProgressHook = workInProgressHook.next), - (currentHook = nextCurrentHook), - (nextCurrentHook = null !== currentHook ? currentHook.next : null); + (currentHook = nextCurrentHook); else { if (null === nextCurrentHook) throw Error("Rendered more hooks than during the previous render."); currentHook = nextCurrentHook; - var newHook = { + nextCurrentHook = { memoizedState: currentHook.memoizedState, baseState: currentHook.baseState, + baseQueue: currentHook.baseQueue, queue: currentHook.queue, - baseUpdate: currentHook.baseUpdate, next: null }; - workInProgressHook = - null === workInProgressHook - ? (firstWorkInProgressHook = newHook) - : (workInProgressHook.next = newHook); - nextCurrentHook = currentHook.next; + null === workInProgressHook + ? (currentlyRenderingFiber$1.memoizedState = workInProgressHook = nextCurrentHook) + : (workInProgressHook = workInProgressHook.next = nextCurrentHook); } return workInProgressHook; } @@ -3360,74 +3220,100 @@ function updateReducer(reducer) { "Should have a queue. This is likely a bug in React. Please file an issue." ); queue.lastRenderedReducer = reducer; - 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]; - } + 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; } - return [hook.memoizedState, _dispatch]; + current.baseQueue = baseQueue = pendingQueue; + queue.pending = null; } - _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; + if (null !== baseQueue) { + baseQueue = baseQueue.next; + current = current.baseState; + var newBaseQueueLast = (baseFirst = pendingQueue = null), + update = baseQueue; do { - var updateExpirationTime = _update.expirationTime; - updateExpirationTime < renderExpirationTime$1 - ? (didSkip || - ((didSkip = !0), - (newBaseUpdate = baseUpdate), - (firstRenderPhaseUpdate = newState)), - updateExpirationTime > remainingExpirationTime && - ((remainingExpirationTime = updateExpirationTime), - markUnprocessedUpdateTime(remainingExpirationTime))) - : (markRenderEventTimeAndConfig( + 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( updateExpirationTime, - _update.suspenseConfig + update.suspenseConfig ), - (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); + (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); hook.memoizedState = newState; - hook.baseUpdate = newBaseUpdate; - hook.baseState = firstRenderPhaseUpdate; + null === hook.baseQueue && (hook.baseState = newState); queue.lastRenderedState = newState; } - return [hook.memoizedState, queue.dispatch]; + return [newState, dispatch]; } function mountState(initialState) { var hook = mountWorkInProgressHook(); "function" === typeof initialState && (initialState = initialState()); hook.memoizedState = hook.baseState = initialState; initialState = hook.queue = { - last: null, + pending: null, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState @@ -3439,28 +3325,30 @@ 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 }; - 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))); + 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))); return tag; } +function updateRef() { + return updateWorkInProgressHook().memoizedState; +} function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var hook = mountWorkInProgressHook(); - sideEffectTag |= fiberEffectTag; + currentlyRenderingFiber$1.effectTag |= fiberEffectTag; hook.memoizedState = pushEffect( - hookEffectTag, + 1 | hookEffectTag, create, void 0, void 0 === deps ? null : deps @@ -3474,18 +3362,21 @@ function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) { var prevEffect = currentHook.memoizedState; destroy = prevEffect.destroy; if (null !== deps && areHookInputsEqual(deps, prevEffect.deps)) { - pushEffect(0, create, destroy, deps); + pushEffect(hookEffectTag, create, destroy, deps); return; } } - sideEffectTag |= fiberEffectTag; - hook.memoizedState = pushEffect(hookEffectTag, create, destroy, deps); + currentlyRenderingFiber$1.effectTag |= fiberEffectTag; + hook.memoizedState = pushEffect(1 | hookEffectTag, create, destroy, deps); } function mountEffect(create, deps) { - return mountEffectImpl(516, 192, create, deps); + return mountEffectImpl(516, 4, create, deps); } function updateEffect(create, deps) { - return updateEffectImpl(516, 192, create, deps); + return updateEffectImpl(516, 4, create, deps); +} +function updateLayoutEffect(create, deps) { + return updateEffectImpl(4, 2, create, deps); } function imperativeHandleEffect(create, ref) { if ("function" === typeof ref) @@ -3505,6 +3396,15 @@ 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 = [ @@ -3526,72 +3426,79 @@ 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) { - if (!(25 > numberOfReRenders)) - throw Error( - "Too many re-renders. React limits the number of renders to prevent an infinite loop." - ); - var alternate = fiber.alternate; + 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 ( fiber === currentlyRenderingFiber$1 || - (null !== alternate && alternate === currentlyRenderingFiber$1) + (null !== pending && pending === currentlyRenderingFiber$1) ) - 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; - } + (didScheduleRenderPhaseUpdate = !0), + (suspenseConfig.expirationTime = renderExpirationTime), + (currentlyRenderingFiber$1.expirationTime = renderExpirationTime); 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 === alternate || 0 === alternate.expirationTime) && - ((alternate = queue.lastRenderedReducer), null !== alternate) + (null === pending || 0 === pending.expirationTime) && + ((pending = queue.lastRenderedReducer), null !== pending) ) try { var currentState = queue.lastRenderedState, - eagerState = alternate(currentState, action); - suspenseConfig.eagerReducer = alternate; + eagerState = pending(currentState, action); + suspenseConfig.eagerReducer = pending; suspenseConfig.eagerState = eagerState; - if (is$1(eagerState, currentState)) return; + if (objectIs(eagerState, currentState)) return; } catch (error) { } finally { } - scheduleUpdateOnFiber(fiber, currentTime); + scheduleWork(fiber, currentTime); } } +function updateEventListener() {} var ContextOnlyDispatcher = { readContext: readContext, useCallback: throwInvalidHookError, @@ -3606,7 +3513,8 @@ var ContextOnlyDispatcher = { useDebugValue: throwInvalidHookError, useResponder: throwInvalidHookError, useDeferredValue: throwInvalidHookError, - useTransition: throwInvalidHookError + useTransition: throwInvalidHookError, + useEvent: throwInvalidHookError }, HooksDispatcherOnMount = { readContext: readContext, @@ -3617,13 +3525,13 @@ var ContextOnlyDispatcher = { deps = null !== deps && void 0 !== deps ? deps.concat([ref]) : null; return mountEffectImpl( 4, - 36, + 2, imperativeHandleEffect.bind(null, create, ref), deps ); }, useLayoutEffect: function(create, deps) { - return mountEffectImpl(4, 36, create, deps); + return mountEffectImpl(4, 2, create, deps); }, useMemo: function(nextCreate, deps) { var hook = mountWorkInProgressHook(); @@ -3637,7 +3545,7 @@ var ContextOnlyDispatcher = { initialArg = void 0 !== init ? init(initialArg) : initialArg; hook.memoizedState = hook.baseState = initialArg; reducer = hook.queue = { - last: null, + pending: null, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialArg @@ -3656,23 +3564,21 @@ var ContextOnlyDispatcher = { }, useState: mountState, useDebugValue: mountDebugValue, - useResponder: createResponderListener, + useResponder: createDeprecatedResponderListener, useDeferredValue: function(value, config) { var _mountState = mountState(value), prevValue = _mountState[0], setValue = _mountState[1]; mountEffect( function() { - 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; - } - }); + var previousConfig = ReactCurrentBatchConfig$1.suspense; + ReactCurrentBatchConfig$1.suspense = + void 0 === config ? null : config; + try { + setValue(value); + } finally { + ReactCurrentBatchConfig$1.suspense = previousConfig; + } }, [value, config] ); @@ -3680,112 +3586,113 @@ var ContextOnlyDispatcher = { }, useTransition: function(config) { var _mountState2 = mountState(!1), - isPending = _mountState2[0], - setPending = _mountState2[1]; + isPending = _mountState2[0]; + _mountState2 = _mountState2[1]; return [ - 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] - ), + mountCallback(startTransition.bind(null, _mountState2, config), [ + _mountState2, + config + ]), isPending ]; - } + }, + useEvent: function() {} }, HooksDispatcherOnUpdate = { readContext: readContext, useCallback: updateCallback, useContext: readContext, useEffect: updateEffect, - 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; - }, + useImperativeHandle: updateImperativeHandle, + useLayoutEffect: updateLayoutEffect, + useMemo: updateMemo, useReducer: updateReducer, - useRef: function() { - return updateWorkInProgressHook().memoizedState; + useRef: updateRef, + useState: function() { + return updateReducer(basicStateReducer); }, - useState: updateState, useDebugValue: mountDebugValue, - useResponder: createResponderListener, + useResponder: createDeprecatedResponderListener, useDeferredValue: function(value, config) { - var _updateState = updateState(value), + var _updateState = updateReducer(basicStateReducer), prevValue = _updateState[0], setValue = _updateState[1]; updateEffect( function() { - 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; - } - }); + 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 = updateState(!1), - isPending = _updateState2[0], - setPending = _updateState2[1]; + var _updateState2 = updateReducer(basicStateReducer), + isPending = _updateState2[0]; + _updateState2 = _updateState2[1]; return [ - 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] - ), + updateCallback(startTransition.bind(null, _updateState2, config), [ + _updateState2, + config + ]), 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] + ); + 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 }, now$1 = Scheduler.unstable_now, commitTime = 0, @@ -3798,70 +3705,16 @@ function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) { profilerStartTime = -1; } } -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, +var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner, didReceiveUpdate = !1; function reconcileChildren( - current$$1, + current, workInProgress, nextChildren, renderExpirationTime ) { workInProgress.child = - null === current$$1 + null === current ? mountChildFibers( workInProgress, null, @@ -3870,13 +3723,13 @@ function reconcileChildren( ) : reconcileChildFibers( workInProgress, - current$$1.child, + current.child, nextChildren, renderExpirationTime ); } function updateForwardRef( - current$$1, + current, workInProgress, Component, nextProps, @@ -3886,43 +3739,38 @@ function updateForwardRef( var ref = workInProgress.ref; prepareToReadContext(workInProgress, renderExpirationTime); nextProps = renderWithHooks( - current$$1, + current, workInProgress, Component, nextProps, ref, renderExpirationTime ); - if (null !== current$$1 && !didReceiveUpdate) + if (null !== current && !didReceiveUpdate) return ( - (workInProgress.updateQueue = current$$1.updateQueue), + (workInProgress.updateQueue = current.updateQueue), (workInProgress.effectTag &= -517), - current$$1.expirationTime <= renderExpirationTime && - (current$$1.expirationTime = 0), + current.expirationTime <= renderExpirationTime && + (current.expirationTime = 0), bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ) ); workInProgress.effectTag |= 1; - reconcileChildren( - current$$1, - workInProgress, - nextProps, - renderExpirationTime - ); + reconcileChildren(current, workInProgress, nextProps, renderExpirationTime); return workInProgress.child; } function updateMemoComponent( - current$$1, + current, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime ) { - if (null === current$$1) { + if (null === current) { var type = Component.type; if ( "function" === typeof type && @@ -3935,7 +3783,7 @@ function updateMemoComponent( (workInProgress.tag = 15), (workInProgress.type = type), updateSimpleMemoComponent( - current$$1, + current, workInProgress, type, nextProps, @@ -3943,7 +3791,7 @@ function updateMemoComponent( renderExpirationTime ) ); - current$$1 = createFiberFromTypeAndProps( + current = createFiberFromTypeAndProps( Component.type, null, nextProps, @@ -3951,65 +3799,66 @@ function updateMemoComponent( workInProgress.mode, renderExpirationTime ); - current$$1.ref = workInProgress.ref; - current$$1.return = workInProgress; - return (workInProgress.child = current$$1); + current.ref = workInProgress.ref; + current.return = workInProgress; + return (workInProgress.child = current); } - type = current$$1.child; + type = current.child; if ( updateExpirationTime < renderExpirationTime && ((updateExpirationTime = type.memoizedProps), (Component = Component.compare), (Component = null !== Component ? Component : shallowEqual), Component(updateExpirationTime, nextProps) && - current$$1.ref === workInProgress.ref) + current.ref === workInProgress.ref) ) return bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ); workInProgress.effectTag |= 1; - current$$1 = createWorkInProgress(type, nextProps, renderExpirationTime); - current$$1.ref = workInProgress.ref; - current$$1.return = workInProgress; - return (workInProgress.child = current$$1); + current = createWorkInProgress(type, nextProps); + current.ref = workInProgress.ref; + current.return = workInProgress; + return (workInProgress.child = current); } function updateSimpleMemoComponent( - current$$1, + current, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime ) { - return null !== current$$1 && - shallowEqual(current$$1.memoizedProps, nextProps) && - current$$1.ref === workInProgress.ref && + return null !== current && + shallowEqual(current.memoizedProps, nextProps) && + current.ref === workInProgress.ref && ((didReceiveUpdate = !1), updateExpirationTime < renderExpirationTime) - ? bailoutOnAlreadyFinishedWork( - current$$1, + ? ((workInProgress.expirationTime = current.expirationTime), + bailoutOnAlreadyFinishedWork( + current, workInProgress, renderExpirationTime - ) + )) : updateFunctionComponent( - current$$1, + current, workInProgress, Component, nextProps, renderExpirationTime ); } -function markRef(current$$1, workInProgress) { +function markRef(current, workInProgress) { var ref = workInProgress.ref; if ( - (null === current$$1 && null !== ref) || - (null !== current$$1 && current$$1.ref !== ref) + (null === current && null !== ref) || + (null !== current && current.ref !== ref) ) workInProgress.effectTag |= 128; } function updateFunctionComponent( - current$$1, + current, workInProgress, Component, nextProps, @@ -4021,36 +3870,31 @@ function updateFunctionComponent( context = getMaskedContext(workInProgress, context); prepareToReadContext(workInProgress, renderExpirationTime); Component = renderWithHooks( - current$$1, + current, workInProgress, Component, nextProps, context, renderExpirationTime ); - if (null !== current$$1 && !didReceiveUpdate) + if (null !== current && !didReceiveUpdate) return ( - (workInProgress.updateQueue = current$$1.updateQueue), + (workInProgress.updateQueue = current.updateQueue), (workInProgress.effectTag &= -517), - current$$1.expirationTime <= renderExpirationTime && - (current$$1.expirationTime = 0), + current.expirationTime <= renderExpirationTime && + (current.expirationTime = 0), bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ) ); workInProgress.effectTag |= 1; - reconcileChildren( - current$$1, - workInProgress, - Component, - renderExpirationTime - ); + reconcileChildren(current, workInProgress, Component, renderExpirationTime); return workInProgress.child; } function updateClassComponent( - current$$1, + current, workInProgress, Component, nextProps, @@ -4062,16 +3906,11 @@ function updateClassComponent( } else hasContext = !1; prepareToReadContext(workInProgress, renderExpirationTime); if (null === workInProgress.stateNode) - null !== current$$1 && - ((current$$1.alternate = null), + null !== current && + ((current.alternate = null), (workInProgress.alternate = null), (workInProgress.effectTag |= 2)), - constructClassInstance( - workInProgress, - Component, - nextProps, - renderExpirationTime - ), + constructClassInstance(workInProgress, Component, nextProps), mountClassInstance( workInProgress, Component, @@ -4079,7 +3918,7 @@ function updateClassComponent( renderExpirationTime ), (nextProps = !0); - else if (null === current$$1) { + else if (null === current) { var instance = workInProgress.stateNode, oldProps = workInProgress.memoizedProps; instance.props = oldProps; @@ -4107,17 +3946,14 @@ function updateClassComponent( )); hasForceUpdate = !1; var oldState = workInProgress.memoizedState; - oldContext = instance.state = oldState; - var updateQueue = workInProgress.updateQueue; - null !== updateQueue && - (processUpdateQueue( - workInProgress, - updateQueue, - nextProps, - instance, - renderExpirationTime - ), - (oldContext = workInProgress.memoizedState)); + instance.state = oldState; + processUpdateQueue( + workInProgress, + nextProps, + instance, + renderExpirationTime + ); + oldContext = workInProgress.memoizedState; oldProps !== nextProps || oldState !== oldContext || didPerformWorkStackCursor.current || @@ -4163,6 +3999,7 @@ function updateClassComponent( (nextProps = !1)); } else (instance = workInProgress.stateNode), + cloneUpdateQueue(current, workInProgress), (oldProps = workInProgress.memoizedProps), (instance.props = workInProgress.type === workInProgress.elementType @@ -4191,17 +4028,14 @@ function updateClassComponent( )), (hasForceUpdate = !1), (oldContext = workInProgress.memoizedState), - (oldState = instance.state = oldContext), - (updateQueue = workInProgress.updateQueue), - null !== updateQueue && - (processUpdateQueue( - workInProgress, - updateQueue, - nextProps, - instance, - renderExpirationTime - ), - (oldState = workInProgress.memoizedState)), + (instance.state = oldContext), + processUpdateQueue( + workInProgress, + nextProps, + instance, + renderExpirationTime + ), + (oldState = workInProgress.memoizedState), oldProps !== nextProps || oldContext !== oldState || didPerformWorkStackCursor.current || @@ -4245,12 +4079,12 @@ function updateClassComponent( "function" === typeof instance.getSnapshotBeforeUpdate && (workInProgress.effectTag |= 256)) : ("function" !== typeof instance.componentDidUpdate || - (oldProps === current$$1.memoizedProps && - oldContext === current$$1.memoizedState) || + (oldProps === current.memoizedProps && + oldContext === current.memoizedState) || (workInProgress.effectTag |= 4), "function" !== typeof instance.getSnapshotBeforeUpdate || - (oldProps === current$$1.memoizedProps && - oldContext === current$$1.memoizedState) || + (oldProps === current.memoizedProps && + oldContext === current.memoizedState) || (workInProgress.effectTag |= 256), (workInProgress.memoizedProps = nextProps), (workInProgress.memoizedState = oldState)), @@ -4259,16 +4093,16 @@ function updateClassComponent( (instance.context = contextType), (nextProps = getDerivedStateFromProps)) : ("function" !== typeof instance.componentDidUpdate || - (oldProps === current$$1.memoizedProps && - oldContext === current$$1.memoizedState) || + (oldProps === current.memoizedProps && + oldContext === current.memoizedState) || (workInProgress.effectTag |= 4), "function" !== typeof instance.getSnapshotBeforeUpdate || - (oldProps === current$$1.memoizedProps && - oldContext === current$$1.memoizedState) || + (oldProps === current.memoizedProps && + oldContext === current.memoizedState) || (workInProgress.effectTag |= 256), (nextProps = !1)); return finishClassComponent( - current$$1, + current, workInProgress, Component, nextProps, @@ -4277,26 +4111,26 @@ function updateClassComponent( ); } function finishClassComponent( - current$$1, + current, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime ) { - markRef(current$$1, workInProgress); + markRef(current, workInProgress); var didCaptureError = 0 !== (workInProgress.effectTag & 64); if (!shouldUpdate && !didCaptureError) return ( hasContext && invalidateContextProvider(workInProgress, Component, !1), bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ) ); shouldUpdate = workInProgress.stateNode; - ReactCurrentOwner$3.current = workInProgress; + ReactCurrentOwner$1.current = workInProgress; if ( didCaptureError && "function" !== typeof Component.getDerivedStateFromError @@ -4305,11 +4139,11 @@ function finishClassComponent( profilerStartTime = -1; } else nextChildren = shouldUpdate.render(); workInProgress.effectTag |= 1; - null !== current$$1 && didCaptureError + null !== current && didCaptureError ? ((didCaptureError = nextChildren), (workInProgress.child = reconcileChildFibers( workInProgress, - current$$1.child, + current.child, null, renderExpirationTime )), @@ -4320,7 +4154,7 @@ function finishClassComponent( renderExpirationTime ))) : reconcileChildren( - current$$1, + current, workInProgress, nextChildren, renderExpirationTime @@ -4343,7 +4177,7 @@ function pushHostRootContext(workInProgress) { } var SUSPENDED_MARKER = { dehydrated: null, retryTime: 0 }; function updateSuspenseComponent( - current$$1, + current, workInProgress, renderExpirationTime ) { @@ -4355,32 +4189,30 @@ function updateSuspenseComponent( (JSCompiler_temp = 0 !== (workInProgress.effectTag & 64)) || (JSCompiler_temp = 0 !== (suspenseContext & 2) && - (null === current$$1 || null !== current$$1.memoizedState)); + (null === current || null !== current.memoizedState)); JSCompiler_temp ? ((nextDidTimeout = !0), (workInProgress.effectTag &= -65)) - : (null !== current$$1 && null === current$$1.memoizedState) || + : (null !== current && null === current.memoizedState) || void 0 === nextProps.fallback || !0 === nextProps.unstable_avoidThisFallback || (suspenseContext |= 1); - push(suspenseStackCursor, suspenseContext & 1, workInProgress); - if (null === current$$1) { - void 0 !== nextProps.fallback && - tryToClaimNextHydratableInstance(workInProgress); + push(suspenseStackCursor, suspenseContext & 1); + if (null === current) { if (nextDidTimeout) { nextDidTimeout = nextProps.fallback; nextProps = createFiberFromFragment(null, mode, 0, null); nextProps.return = workInProgress; if (0 === (workInProgress.mode & 2)) for ( - current$$1 = + current = null !== workInProgress.memoizedState ? workInProgress.child.child : workInProgress.child, - nextProps.child = current$$1; - null !== current$$1; + nextProps.child = current; + null !== current; ) - (current$$1.return = nextProps), (current$$1 = current$$1.sibling); + (current.return = nextProps), (current = current.sibling); renderExpirationTime = createFiberFromFragment( nextDidTimeout, mode, @@ -4402,15 +4234,14 @@ function updateSuspenseComponent( renderExpirationTime )); } - if (null !== current$$1.memoizedState) { - current$$1 = current$$1.child; - mode = current$$1.sibling; + if (null !== current.memoizedState) { + current = current.child; + mode = current.sibling; if (nextDidTimeout) { nextProps = nextProps.fallback; renderExpirationTime = createWorkInProgress( - current$$1, - current$$1.pendingProps, - 0 + current, + current.pendingProps ); renderExpirationTime.return = workInProgress; if ( @@ -4419,7 +4250,7 @@ function updateSuspenseComponent( null !== workInProgress.memoizedState ? workInProgress.child.child : workInProgress.child), - nextDidTimeout !== current$$1.child) + nextDidTimeout !== current.child) ) for ( renderExpirationTime.child = nextDidTimeout; @@ -4430,12 +4261,12 @@ function updateSuspenseComponent( (nextDidTimeout = nextDidTimeout.sibling); if (workInProgress.mode & 8) { nextDidTimeout = 0; - for (current$$1 = renderExpirationTime.child; null !== current$$1; ) - (nextDidTimeout += current$$1.treeBaseDuration), - (current$$1 = current$$1.sibling); + for (current = renderExpirationTime.child; null !== current; ) + (nextDidTimeout += current.treeBaseDuration), + (current = current.sibling); renderExpirationTime.treeBaseDuration = nextDidTimeout; } - mode = createWorkInProgress(mode, nextProps, mode.expirationTime); + mode = createWorkInProgress(mode, nextProps); mode.return = workInProgress; renderExpirationTime.sibling = mode; renderExpirationTime.childExpirationTime = 0; @@ -4445,37 +4276,37 @@ function updateSuspenseComponent( } renderExpirationTime = reconcileChildFibers( workInProgress, - current$$1.child, + current.child, nextProps.children, renderExpirationTime ); workInProgress.memoizedState = null; return (workInProgress.child = renderExpirationTime); } - current$$1 = current$$1.child; + current = current.child; if (nextDidTimeout) { nextDidTimeout = nextProps.fallback; nextProps = createFiberFromFragment(null, mode, 0, null); nextProps.return = workInProgress; - nextProps.child = current$$1; - null !== current$$1 && (current$$1.return = nextProps); + nextProps.child = current; + null !== current && (current.return = nextProps); if (0 === (workInProgress.mode & 2)) for ( - current$$1 = + current = null !== workInProgress.memoizedState ? workInProgress.child.child : workInProgress.child, - nextProps.child = current$$1; - null !== current$$1; + nextProps.child = current; + null !== current; ) - (current$$1.return = nextProps), (current$$1 = current$$1.sibling); + (current.return = nextProps), (current = current.sibling); if (workInProgress.mode & 8) { - current$$1 = 0; + current = 0; for (suspenseContext = nextProps.child; null !== suspenseContext; ) - (current$$1 += suspenseContext.treeBaseDuration), + (current += suspenseContext.treeBaseDuration), (suspenseContext = suspenseContext.sibling); - nextProps.treeBaseDuration = current$$1; + nextProps.treeBaseDuration = current; } renderExpirationTime = createFiberFromFragment( nextDidTimeout, @@ -4494,7 +4325,7 @@ function updateSuspenseComponent( workInProgress.memoizedState = null; return (workInProgress.child = reconcileChildFibers( workInProgress, - current$$1, + current, nextProps.children, renderExpirationTime )); @@ -4521,6 +4352,7 @@ function initSuspenseListRenderState( ? (workInProgress.memoizedState = { isBackwards: isBackwards, rendering: null, + renderingStartTime: 0, last: lastContentRow, tail: tail, tailExpiration: 0, @@ -4529,6 +4361,7 @@ function initSuspenseListRenderState( }) : ((renderState.isBackwards = isBackwards), (renderState.rendering = null), + (renderState.renderingStartTime = 0), (renderState.last = lastContentRow), (renderState.tail = tail), (renderState.tailExpiration = 0), @@ -4536,7 +4369,7 @@ function initSuspenseListRenderState( (renderState.lastEffect = lastEffectBeforeRendering)); } function updateSuspenseListComponent( - current$$1, + current, workInProgress, renderExpirationTime ) { @@ -4544,7 +4377,7 @@ function updateSuspenseListComponent( revealOrder = nextProps.revealOrder, tailMode = nextProps.tail; reconcileChildren( - current$$1, + current, workInProgress, nextProps.children, renderExpirationTime @@ -4553,42 +4386,39 @@ function updateSuspenseListComponent( if (0 !== (nextProps & 2)) (nextProps = (nextProps & 1) | 2), (workInProgress.effectTag |= 64); else { - 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; + 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; continue; } - if (current$$1 === workInProgress) break a; - for (; null === current$$1.sibling; ) { - if ( - null === current$$1.return || - current$$1.return === workInProgress - ) + if (current === workInProgress) break a; + for (; null === current.sibling; ) { + if (null === current.return || current.return === workInProgress) break a; - current$$1 = current$$1.return; + current = current.return; } - current$$1.sibling.return = current$$1.return; - current$$1 = current$$1.sibling; + current.sibling.return = current.return; + current = current.sibling; } nextProps &= 1; } - push(suspenseStackCursor, nextProps, workInProgress); + push(suspenseStackCursor, nextProps); if (0 === (workInProgress.mode & 2)) workInProgress.memoizedState = null; else switch (revealOrder) { case "forwards": renderExpirationTime = workInProgress.child; for (revealOrder = null; null !== renderExpirationTime; ) - (current$$1 = renderExpirationTime.alternate), - null !== current$$1 && - null === findFirstSuspended(current$$1) && + (current = renderExpirationTime.alternate), + null !== current && + null === findFirstSuspended(current) && (revealOrder = renderExpirationTime), (renderExpirationTime = renderExpirationTime.sibling); renderExpirationTime = revealOrder; @@ -4610,15 +4440,15 @@ function updateSuspenseListComponent( renderExpirationTime = null; revealOrder = workInProgress.child; for (workInProgress.child = null; null !== revealOrder; ) { - current$$1 = revealOrder.alternate; - if (null !== current$$1 && null === findFirstSuspended(current$$1)) { + current = revealOrder.alternate; + if (null !== current && null === findFirstSuspended(current)) { workInProgress.child = revealOrder; break; } - current$$1 = revealOrder.sibling; + current = revealOrder.sibling; revealOrder.sibling = renderExpirationTime; renderExpirationTime = revealOrder; - revealOrder = current$$1; + revealOrder = current; } initSuspenseListRenderState( workInProgress, @@ -4645,36 +4475,30 @@ function updateSuspenseListComponent( return workInProgress.child; } function bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ) { - null !== current$$1 && - (workInProgress.dependencies = current$$1.dependencies); + null !== current && (workInProgress.dependencies = current.dependencies); profilerStartTime = -1; var updateExpirationTime = workInProgress.expirationTime; 0 !== updateExpirationTime && markUnprocessedUpdateTime(updateExpirationTime); if (workInProgress.childExpirationTime < renderExpirationTime) return null; - if (null !== current$$1 && workInProgress.child !== current$$1.child) + if (null !== current && workInProgress.child !== current.child) throw Error("Resuming work not yet implemented."); if (null !== workInProgress.child) { - current$$1 = workInProgress.child; - renderExpirationTime = createWorkInProgress( - current$$1, - current$$1.pendingProps, - current$$1.expirationTime - ); + current = workInProgress.child; + renderExpirationTime = createWorkInProgress(current, current.pendingProps); workInProgress.child = renderExpirationTime; for ( renderExpirationTime.return = workInProgress; - null !== current$$1.sibling; + null !== current.sibling; ) - (current$$1 = current$$1.sibling), + (current = current.sibling), (renderExpirationTime = renderExpirationTime.sibling = createWorkInProgress( - current$$1, - current$$1.pendingProps, - current$$1.expirationTime + current, + current.pendingProps )), (renderExpirationTime.return = workInProgress); renderExpirationTime.sibling = null; @@ -4736,78 +4560,87 @@ function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { : (_lastTailNode.sibling = null); } } -function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { +function completeWork(current, workInProgress, renderExpirationTime) { var newProps = workInProgress.pendingProps; switch (workInProgress.tag) { case 2: - break; case 16: - break; case 15: case 0: - break; + case 11: + case 7: + case 8: + case 12: + case 9: + case 14: + return null; case 1: - isContextProvider(workInProgress.type) && popContext(workInProgress); - break; + return isContextProvider(workInProgress.type) && popContext(), null; case 3: - popHostContainer(workInProgress); - popTopLevelContextObject(workInProgress); - current = workInProgress.stateNode; - current.pendingContext && - ((current.context = current.pendingContext), - (current.pendingContext = null)); - updateHostContainer(workInProgress); - break; + 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$jscomp$0 = workInProgress.type; + renderExpirationTime = workInProgress.type; if (null !== current && null != workInProgress.stateNode) updateHostComponent$1( current, workInProgress, - renderExpirationTime$jscomp$0, + renderExpirationTime, newProps, rootContainerInstance ), current.ref !== workInProgress.ref && (workInProgress.effectTag |= 128); - else if (newProps) { - current = requiredContext(contextStackCursor$1.current); - var tag = allocateTag(), - viewConfig = getViewConfigForType(renderExpirationTime$jscomp$0), - updatePayload = diffProperties( - null, - emptyObject, - newProps, - viewConfig.validAttributes - ); + 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( - tag, - viewConfig.uiViewClassName, + current, + renderExpirationTime.uiViewClassName, rootContainerInstance, updatePayload ); - 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); - } 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." + rootContainerInstance = new ReactNativeFiberHostComponent( + current, + renderExpirationTime, + workInProgress ); - break; + 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( @@ -4836,33 +4669,30 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { instanceCache.set(rootContainerInstance, workInProgress); workInProgress.stateNode = rootContainerInstance; } - break; - case 11: - break; + return null; case 13: - pop(suspenseStackCursor, workInProgress); + pop(suspenseStackCursor); newProps = workInProgress.memoizedState; if (0 !== (workInProgress.effectTag & 64)) return ( - (workInProgress.expirationTime = renderExpirationTime$jscomp$0), - workInProgress + (workInProgress.expirationTime = renderExpirationTime), workInProgress ); newProps = null !== newProps; rootContainerInstance = !1; null !== current && - ((renderExpirationTime$jscomp$0 = current.memoizedState), - (rootContainerInstance = null !== renderExpirationTime$jscomp$0), + ((renderExpirationTime = current.memoizedState), + (rootContainerInstance = null !== renderExpirationTime), newProps || - 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)))); + 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 && @@ -4879,41 +4709,30 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { workInProgressRootExitStatus = RootSuspendedWithDelay; 0 !== workInProgressRootNextUnprocessedUpdateTime && null !== workInProgressRoot && - (markRootSuspendedAtTime(workInProgressRoot, renderExpirationTime), + (markRootSuspendedAtTime( + workInProgressRoot, + renderExpirationTime$1 + ), markRootUpdatedAtTime( workInProgressRoot, workInProgressRootNextUnprocessedUpdateTime - )); - } - if (newProps || rootContainerInstance) workInProgress.effectTag |= 4; - break; - case 7: - break; - case 8: - break; - case 12: - break; + )); + } + if (newProps || rootContainerInstance) workInProgress.effectTag |= 4; + return null; case 4: - popHostContainer(workInProgress); - updateHostContainer(workInProgress); - break; + return popHostContainer(), updateHostContainer(workInProgress), null; case 10: - popProvider(workInProgress); - break; - case 9: - break; - case 14: - break; + return popProvider(workInProgress), null; case 17: - isContextProvider(workInProgress.type) && popContext(workInProgress); - break; + return isContextProvider(workInProgress.type) && popContext(), null; case 19: - pop(suspenseStackCursor, workInProgress); + pop(suspenseStackCursor); newProps = workInProgress.memoizedState; - if (null === newProps) break; + if (null === newProps) return null; rootContainerInstance = 0 !== (workInProgress.effectTag & 64); - tag = newProps.rendering; - if (null === tag) + updatePayload = newProps.rendering; + if (null === updatePayload) if (rootContainerInstance) cutOffTailIfNeeded(newProps, !1); else { if ( @@ -4921,30 +4740,29 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { (null !== current && 0 !== (current.effectTag & 64)) ) for (current = workInProgress.child; null !== current; ) { - tag = findFirstSuspended(current); - if (null !== tag) { + updatePayload = findFirstSuspended(current); + if (null !== updatePayload) { workInProgress.effectTag |= 64; cutOffTailIfNeeded(newProps, !1); - current = tag.updateQueue; + current = updatePayload.updateQueue; null !== current && ((workInProgress.updateQueue = current), (workInProgress.effectTag |= 4)); null === newProps.lastEffect && (workInProgress.firstEffect = null); workInProgress.lastEffect = newProps.lastEffect; - current = renderExpirationTime$jscomp$0; + current = renderExpirationTime; for (newProps = workInProgress.child; null !== newProps; ) (rootContainerInstance = newProps), - (tag = current), + (updatePayload = current), (rootContainerInstance.effectTag &= 2), (rootContainerInstance.nextEffect = null), (rootContainerInstance.firstEffect = null), (rootContainerInstance.lastEffect = null), - (renderExpirationTime$jscomp$0 = - rootContainerInstance.alternate), - null === renderExpirationTime$jscomp$0 + (renderExpirationTime = rootContainerInstance.alternate), + null === renderExpirationTime ? ((rootContainerInstance.childExpirationTime = 0), - (rootContainerInstance.expirationTime = tag), + (rootContainerInstance.expirationTime = updatePayload), (rootContainerInstance.child = null), (rootContainerInstance.memoizedProps = null), (rootContainerInstance.memoizedState = null), @@ -4953,35 +4771,34 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { (rootContainerInstance.selfBaseDuration = 0), (rootContainerInstance.treeBaseDuration = 0)) : ((rootContainerInstance.childExpirationTime = - renderExpirationTime$jscomp$0.childExpirationTime), + renderExpirationTime.childExpirationTime), (rootContainerInstance.expirationTime = - renderExpirationTime$jscomp$0.expirationTime), + renderExpirationTime.expirationTime), (rootContainerInstance.child = - renderExpirationTime$jscomp$0.child), + renderExpirationTime.child), (rootContainerInstance.memoizedProps = - renderExpirationTime$jscomp$0.memoizedProps), + renderExpirationTime.memoizedProps), (rootContainerInstance.memoizedState = - renderExpirationTime$jscomp$0.memoizedState), + renderExpirationTime.memoizedState), (rootContainerInstance.updateQueue = - renderExpirationTime$jscomp$0.updateQueue), - (tag = renderExpirationTime$jscomp$0.dependencies), + renderExpirationTime.updateQueue), + (updatePayload = renderExpirationTime.dependencies), (rootContainerInstance.dependencies = - null === tag + null === updatePayload ? null : { - expirationTime: tag.expirationTime, - firstContext: tag.firstContext, - responders: tag.responders + expirationTime: updatePayload.expirationTime, + firstContext: updatePayload.firstContext, + responders: updatePayload.responders }), (rootContainerInstance.selfBaseDuration = - renderExpirationTime$jscomp$0.selfBaseDuration), + renderExpirationTime.selfBaseDuration), (rootContainerInstance.treeBaseDuration = - renderExpirationTime$jscomp$0.treeBaseDuration)), + renderExpirationTime.treeBaseDuration)), (newProps = newProps.sibling); push( suspenseStackCursor, - (suspenseStackCursor.current & 1) | 2, - workInProgress + (suspenseStackCursor.current & 1) | 2 ); return workInProgress.child; } @@ -4990,7 +4807,9 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { } else { if (!rootContainerInstance) - if (((current = findFirstSuspended(tag)), null !== current)) { + if ( + ((current = findFirstSuspended(updatePayload)), null !== current) + ) { if ( ((workInProgress.effectTag |= 64), (rootContainerInstance = !0), @@ -5001,74 +4820,72 @@ function completeWork(current, workInProgress, renderExpirationTime$jscomp$0) { cutOffTailIfNeeded(newProps, !0), null === newProps.tail && "hidden" === newProps.tailMode && - !tag.alternate) - ) { - workInProgress = workInProgress.lastEffect = newProps.lastEffect; - null !== workInProgress && (workInProgress.nextEffect = null); - break; - } + !updatePayload.alternate) + ) + return ( + (workInProgress = workInProgress.lastEffect = + newProps.lastEffect), + null !== workInProgress && (workInProgress.nextEffect = null), + null + ); } else - now() > newProps.tailExpiration && - 1 < renderExpirationTime$jscomp$0 && + 2 * now() - newProps.renderingStartTime > newProps.tailExpiration && + 1 < renderExpirationTime && ((workInProgress.effectTag |= 64), (rootContainerInstance = !0), cutOffTailIfNeeded(newProps, !1), - (current = renderExpirationTime$jscomp$0 - 1), + (current = renderExpirationTime - 1), (workInProgress.expirationTime = workInProgress.childExpirationTime = current), null === spawnedWorkDuringRender ? (spawnedWorkDuringRender = [current]) : spawnedWorkDuringRender.push(current)); newProps.isBackwards - ? ((tag.sibling = workInProgress.child), (workInProgress.child = tag)) + ? ((updatePayload.sibling = workInProgress.child), + (workInProgress.child = updatePayload)) : ((current = newProps.last), null !== current - ? (current.sibling = tag) - : (workInProgress.child = tag), - (newProps.last = tag)); + ? (current.sibling = updatePayload) + : (workInProgress.child = updatePayload), + (newProps.last = updatePayload)); } - if (null !== newProps.tail) - return ( - 0 === newProps.tailExpiration && + 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), - (newProps = suspenseStackCursor.current), + (workInProgress = suspenseStackCursor.current), push( suspenseStackCursor, - rootContainerInstance ? (newProps & 1) | 2 : newProps & 1, - workInProgress + rootContainerInstance + ? (workInProgress & 1) | 2 + : workInProgress & 1 ), - 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." - ); + current) + : null; } - return 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(workInProgress); + isContextProvider(workInProgress.type) && popContext(); var effectTag = workInProgress.effectTag; return effectTag & 4096 ? ((workInProgress.effectTag = (effectTag & -4097) | 64), workInProgress) : null; case 3: - popHostContainer(workInProgress); - popTopLevelContextObject(workInProgress); + popHostContainer(); + pop(didPerformWorkStackCursor); + pop(contextStackCursor); effectTag = workInProgress.effectTag; if (0 !== (effectTag & 64)) throw Error( @@ -5080,7 +4897,7 @@ function unwindWork(workInProgress) { return popHostContext(workInProgress), null; case 13: return ( - pop(suspenseStackCursor, workInProgress), + pop(suspenseStackCursor), (effectTag = workInProgress.effectTag), effectTag & 4096 ? ((workInProgress.effectTag = (effectTag & -4097) | 64), @@ -5088,9 +4905,9 @@ function unwindWork(workInProgress) { : null ); case 19: - return pop(suspenseStackCursor, workInProgress), null; + return pop(suspenseStackCursor), null; case 4: - return popHostContainer(workInProgress), null; + return popHostContainer(), null; case 10: return popProvider(workInProgress), null; default: @@ -5147,85 +4964,171 @@ function logError(boundary, errorInfo) { }); } } -function safelyCallComponentWillUnmount(current$$1, instance) { +function safelyCallComponentWillUnmount(current, instance) { try { - (instance.props = current$$1.memoizedProps), - (instance.state = current$$1.memoizedState), + (instance.props = current.memoizedProps), + (instance.state = current.memoizedState), instance.componentWillUnmount(); } catch (unmountError) { - captureCommitPhaseError(current$$1, unmountError); + captureCommitPhaseError(current, unmountError); } } -function safelyDetachRef(current$$1) { - var ref = current$$1.ref; +function safelyDetachRef(current) { + var ref = current.ref; if (null !== ref) if ("function" === typeof ref) try { ref(null); } catch (refError) { - captureCommitPhaseError(current$$1, refError); + captureCommitPhaseError(current, refError); } else ref.current = null; } -function commitBeforeMutationLifeCycles(current$$1, finishedWork) { +function commitBeforeMutationLifeCycles(current, finishedWork) { switch (finishedWork.tag) { case 0: case 11: case 15: - commitHookEffectList(2, 0, finishedWork); - break; + case 22: + return; case 1: - if (finishedWork.effectTag & 256 && null !== current$$1) { - var prevProps = current$$1.memoizedProps, - prevState = current$$1.memoizedState; - current$$1 = finishedWork.stateNode; - finishedWork = current$$1.getSnapshotBeforeUpdate( + if (finishedWork.effectTag & 256 && null !== current) { + var prevProps = current.memoizedProps, + prevState = current.memoizedState; + current = finishedWork.stateNode; + finishedWork = current.getSnapshotBeforeUpdate( finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState ); - current$$1.__reactInternalSnapshotBeforeUpdate = finishedWork; + current.__reactInternalSnapshotBeforeUpdate = finishedWork; } - break; + return; case 3: case 5: case 6: case 4: case 17: - break; - default: - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); + 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 commitHookEffectList(unmountTag, mountTag, finishedWork) { +function commitHookEffectListUnmount(tag, finishedWork) { finishedWork = finishedWork.updateQueue; finishedWork = null !== finishedWork ? finishedWork.lastEffect : null; if (null !== finishedWork) { var effect = (finishedWork = finishedWork.next); do { - if (0 !== (effect.tag & unmountTag)) { + if ((effect.tag & tag) === tag) { 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 commitUnmount(finishedRoot, current$$1$jscomp$0, renderPriorityLevel) { +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" === typeof onCommitFiberUnmount && - onCommitFiberUnmount(current$$1$jscomp$0); - switch (current$$1$jscomp$0.tag) { + onCommitFiberUnmount(current$jscomp$0); + switch (current$jscomp$0.tag) { case 0: case 11: case 14: case 15: - finishedRoot = current$$1$jscomp$0.updateQueue; + case 22: + finishedRoot = current$jscomp$0.updateQueue; if ( null !== finishedRoot && ((finishedRoot = finishedRoot.lastEffect), null !== finishedRoot) @@ -5236,13 +5139,13 @@ function commitUnmount(finishedRoot, current$$1$jscomp$0, renderPriorityLevel) { function() { var effect = firstEffect; do { - var destroy = effect.destroy; - if (void 0 !== destroy) { - var current$$1 = current$$1$jscomp$0; + var _destroy = effect.destroy; + if (void 0 !== _destroy) { + var current = current$jscomp$0; try { - destroy(); + _destroy(); } catch (error) { - captureCommitPhaseError(current$$1, error); + captureCommitPhaseError(current, error); } } effect = effect.next; @@ -5252,37 +5155,35 @@ function commitUnmount(finishedRoot, current$$1$jscomp$0, renderPriorityLevel) { } break; case 1: - safelyDetachRef(current$$1$jscomp$0); - renderPriorityLevel = current$$1$jscomp$0.stateNode; + safelyDetachRef(current$jscomp$0); + renderPriorityLevel = current$jscomp$0.stateNode; "function" === typeof renderPriorityLevel.componentWillUnmount && - safelyCallComponentWillUnmount( - current$$1$jscomp$0, - renderPriorityLevel - ); + safelyCallComponentWillUnmount(current$jscomp$0, renderPriorityLevel); break; case 5: - safelyDetachRef(current$$1$jscomp$0); + safelyDetachRef(current$jscomp$0); break; case 4: unmountHostComponents( finishedRoot, - current$$1$jscomp$0, + current$jscomp$0, renderPriorityLevel ); } } -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; +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; null !== alternate && detachFiber(alternate); } function isHostParent(fiber) { @@ -5345,97 +5246,103 @@ function commitPlacement(finishedWork) { break a; } } - 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), + 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( - isHost._nativeTag, - [index], - [beforeChild], + parent._nativeTag, + [isHost], + [before], [], [], [] )) - : ((index = children.indexOf(beforeChild)), - children.splice(index, 0, stateNode), + : ((before = tag.indexOf(before)), + tag.splice(before, 0, node), ReactNativePrivateInterface.UIManager.manageChildren( - isHost._nativeTag, + parent._nativeTag, [], [], - [ - "number" === typeof stateNode - ? stateNode - : stateNode._nativeTag - ], - [index], + ["number" === typeof node ? node : node._nativeTag], + [before], [] - )); - } - 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; - } + ))) + : ((before = "number" === typeof node ? node : node._nativeTag), + (tag = parent._children), + (isHost = tag.indexOf(node)), + 0 <= isHost + ? (tag.splice(isHost, 1), + tag.push(node), + ReactNativePrivateInterface.UIManager.manageChildren( + parent._nativeTag, + [isHost], + [tag.length - 1], + [], + [], + [] + )) + : (tag.push(node), + ReactNativePrivateInterface.UIManager.manageChildren( + parent._nativeTag, + [], + [], + [before], + [tag.length - 1], + [] + ))); + 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); } function unmountHostComponents( finishedRoot$jscomp$0, - current$$1, + current, renderPriorityLevel$jscomp$0 ) { for ( - var node = current$$1, + var node = current, currentParentIsValid = !1, currentParent, currentParentIsContainer; @@ -5483,7 +5390,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; + if (node$jscomp$0 === root) break a; for (; null === node$jscomp$0.sibling; ) { if (null === node$jscomp$0.return || node$jscomp$0.return === root) break a; @@ -5533,9 +5440,9 @@ function unmountHostComponents( node = node.child; continue; } - if (node === current$$1) break; + if (node === current) break; for (; null === node.sibling; ) { - if (null === node.return || node.return === current$$1) return; + if (null === node.return || node.return === current) return; node = node.return; 4 === node.tag && (currentParentIsValid = !1); } @@ -5543,21 +5450,22 @@ function unmountHostComponents( node = node.sibling; } } -function commitWork(current$$1, finishedWork) { +function commitWork(current, finishedWork) { switch (finishedWork.tag) { case 0: case 11: case 14: case 15: - commitHookEffectList(4, 8, finishedWork); - break; + case 22: + commitHookEffectListUnmount(3, finishedWork); + return; case 1: - break; + return; case 5: var instance = finishedWork.stateNode; if (null != instance) { var newProps = finishedWork.memoizedProps; - current$$1 = null !== current$$1 ? current$$1.memoizedProps : newProps; + current = null !== current ? current.memoizedProps : newProps; var updatePayload = finishedWork.updateQueue; finishedWork.updateQueue = null; null !== updatePayload && @@ -5565,7 +5473,7 @@ function commitWork(current$$1, finishedWork) { instanceProps.set(instance._nativeTag, newProps), (newProps = diffProperties( null, - current$$1, + current, newProps, finishedWork.validAttributes )), @@ -5576,7 +5484,7 @@ function commitWork(current$$1, finishedWork) { newProps )); } - break; + return; case 6: if (null === finishedWork.stateNode) throw Error( @@ -5587,11 +5495,11 @@ function commitWork(current$$1, finishedWork) { "RCTRawText", { text: finishedWork.memoizedProps } ); - break; + return; case 3: - break; + return; case 12: - break; + return; case 13: instance = finishedWork; null === finishedWork.memoizedState @@ -5600,9 +5508,9 @@ function commitWork(current$$1, finishedWork) { (instance = finishedWork.child), (globalMostRecentFallbackTime = now())); if (null !== instance) - a: for (current$$1 = instance; ; ) { - if (5 === current$$1.tag) - if (((updatePayload = current$$1.stateNode), newProps)) { + a: for (current = instance; ; ) { + if (5 === current.tag) + if (((updatePayload = current.stateNode), newProps)) { var viewConfig = updatePayload.viewConfig; var updatePayload$jscomp$0 = diffProperties( null, @@ -5616,8 +5524,8 @@ function commitWork(current$$1, finishedWork) { updatePayload$jscomp$0 ); } else { - updatePayload = current$$1.stateNode; - updatePayload$jscomp$0 = current$$1.memoizedProps; + updatePayload = current.stateNode; + updatePayload$jscomp$0 = current.memoizedProps; viewConfig = updatePayload.viewConfig; var prevProps = Object.assign({}, updatePayload$jscomp$0, { style: [updatePayload$jscomp$0.style, { display: "none" }] @@ -5635,47 +5543,41 @@ function commitWork(current$$1, finishedWork) { ); } else { - if (6 === current$$1.tag) throw Error("Not yet implemented."); + if (6 === current.tag) throw Error("Not yet implemented."); if ( - 13 === current$$1.tag && - null !== current$$1.memoizedState && - null === current$$1.memoizedState.dehydrated + 13 === current.tag && + null !== current.memoizedState && + null === current.memoizedState.dehydrated ) { - updatePayload = current$$1.child.sibling; - updatePayload.return = current$$1; - current$$1 = updatePayload; + updatePayload = current.child.sibling; + updatePayload.return = current; + current = updatePayload; continue; - } else if (null !== current$$1.child) { - current$$1.child.return = current$$1; - current$$1 = current$$1.child; + } else if (null !== current.child) { + current.child.return = current; + current = current.child; continue; } } - 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; + if (current === instance) break; + for (; null === current.sibling; ) { + if (null === current.return || current.return === instance) break a; + current = current.return; } - current$$1.sibling.return = current$$1.return; - current$$1 = current$$1.sibling; + current.sibling.return = current.return; + current = current.sibling; } attachSuspenseRetryListeners(finishedWork); - break; + return; case 19: attachSuspenseRetryListeners(finishedWork); - break; + return; case 17: - 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." - ); + return; } + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); } function attachSuspenseRetryListeners(finishedWork) { var thenables = finishedWork.updateQueue; @@ -5734,7 +5636,7 @@ function createClassErrorUpdate(fiber, errorInfo, expirationTime) { return expirationTime; } var ceil = Math.ceil, - ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher, + ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, NoContext = 0, LegacyUnbatchedContext = 8, @@ -5749,7 +5651,7 @@ var ceil = Math.ceil, executionContext = NoContext, workInProgressRoot = null, workInProgress = null, - renderExpirationTime = 0, + renderExpirationTime$1 = 0, workInProgressRootExitStatus = RootIncomplete, workInProgressRootFatalError = null, workInProgressRootLatestProcessedExpirationTime = 1073741823, @@ -5776,8 +5678,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; @@ -5785,7 +5687,7 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { var priorityLevel = getCurrentPriorityLevel(); if (0 === (fiber & 4)) return 99 === priorityLevel ? 1073741823 : 1073741822; if ((executionContext & RenderContext) !== NoContext) - return renderExpirationTime; + return renderExpirationTime$1; if (null !== suspenseConfig) currentTime = 1073741821 - @@ -5817,11 +5719,11 @@ function computeExpirationForFiber(currentTime, fiber, suspenseConfig) { throw Error("Expected a valid priority level"); } null !== workInProgressRoot && - currentTime === renderExpirationTime && + currentTime === renderExpirationTime$1 && --currentTime; return currentTime; } -function scheduleUpdateOnFiber(fiber, expirationTime) { +function scheduleWork(fiber, expirationTime) { if (50 < nestedUpdateCount) throw ((nestedUpdateCount = 0), (rootWithNestedUpdates = null), @@ -5878,7 +5780,7 @@ function markUpdateTimeFromFiberToRoot(fiber, expirationTime) { (workInProgressRoot === root && (markUnprocessedUpdateTime(expirationTime), workInProgressRootExitStatus === RootSuspendedWithDelay && - markRootSuspendedAtTime(root, renderExpirationTime)), + markRootSuspendedAtTime(root, renderExpirationTime$1)), markRootUpdatedAtTime(root, expirationTime)); return root; } @@ -5887,9 +5789,10 @@ function getNextRootExpirationTimeToWorkOn(root) { if (0 !== lastExpiredTime) return lastExpiredTime; lastExpiredTime = root.firstPendingTime; if (!isRootSuspendedAtTime(root, lastExpiredTime)) return lastExpiredTime; - lastExpiredTime = root.lastPingedTime; + var lastPingedTime = root.lastPingedTime; root = root.nextKnownPendingLevel; - return lastExpiredTime > root ? lastExpiredTime : root; + root = lastPingedTime > root ? lastPingedTime : root; + return 2 >= root && lastExpiredTime !== root ? 0 : root; } function ensureRootIsScheduled(root) { if (0 !== root.lastExpiredTime) @@ -5938,270 +5841,232 @@ function ensureRootIsScheduled(root) { } function performConcurrentWorkOnRoot(root, didTimeout) { currentEventTime = 0; - if (didTimeout) - return ( - (didTimeout = requestCurrentTimeForUpdate()), - markRootExpiredAtTime(root, didTimeout), + 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), ensureRootIsScheduled(root), - 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); - } - 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) + 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) ) { - 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); + if ( + workInProgressRootHasPendingPing && + ((expirationTime = root.lastPingedTime), + 0 === expirationTime || expirationTime >= lastExpiredTime) + ) { + root.lastPingedTime = lastExpiredTime; + prepareFreshStack(root, lastExpiredTime); 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); + } + expirationTime = getNextRootExpirationTimeToWorkOn(root); + if (0 !== expirationTime && expirationTime !== lastExpiredTime) break; + if (0 !== exitStatus && exitStatus !== lastExpiredTime) { + root.lastPingedTime = exitStatus; break; - default: - throw Error("Unknown root exit status."); + } + root.timeoutHandle = scheduleTimeout( + commitRoot.bind(null, root), + prevExecutionContext + ); + break; } - 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(); + 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; - } 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(); + 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 + ); + break; + } + commitRoot(root); + break; + case RootCompleted: + if ( + 1073741823 !== workInProgressRootLatestProcessedExpirationTime && + null !== workInProgressRootCanSuspendUsingConfig + ) { + 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 + ); + break; + } + } + commitRoot(root); + break; + default: + throw Error("Unknown root exit status."); + } } + 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 prepareFreshStack(root, expirationTime) { root.finishedWork = null; @@ -6214,26 +6079,27 @@ function prepareFreshStack(root, expirationTime) { var interruptedWork = timeoutHandle; switch (interruptedWork.tag) { case 1: - var childContextTypes = interruptedWork.type.childContextTypes; - null !== childContextTypes && - void 0 !== childContextTypes && - popContext(interruptedWork); + interruptedWork = interruptedWork.type.childContextTypes; + null !== interruptedWork && + void 0 !== interruptedWork && + popContext(); break; case 3: - popHostContainer(interruptedWork); - popTopLevelContextObject(interruptedWork); + popHostContainer(); + pop(didPerformWorkStackCursor); + pop(contextStackCursor); break; case 5: popHostContext(interruptedWork); break; case 4: - popHostContainer(interruptedWork); + popHostContainer(); break; case 13: - pop(suspenseStackCursor, interruptedWork); + pop(suspenseStackCursor); break; case 19: - pop(suspenseStackCursor, interruptedWork); + pop(suspenseStackCursor); break; case 10: popProvider(interruptedWork); @@ -6241,8 +6107,8 @@ function prepareFreshStack(root, expirationTime) { timeoutHandle = timeoutHandle.return; } workInProgressRoot = root; - workInProgress = createWorkInProgress(root.current, null, expirationTime); - renderExpirationTime = expirationTime; + workInProgress = createWorkInProgress(root.current, null); + renderExpirationTime$1 = expirationTime; workInProgressRootExitStatus = RootIncomplete; workInProgressRootFatalError = null; workInProgressRootLatestSuspenseTimeout = workInProgressRootLatestProcessedExpirationTime = 1073741823; @@ -6255,12 +6121,25 @@ function handleError(root$jscomp$0, thrownValue) { do { try { resetContextDependencies(); - resetHooks(); + 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; if (null === workInProgress || null === workInProgress.return) return ( (workInProgressRootExitStatus = RootFatalErrored), (workInProgressRootFatalError = thrownValue), - null + (workInProgress = null) ); workInProgress.mode & 8 && stopProfilerTimerIfRunningAndRecordDelta(workInProgress, !0); @@ -6269,7 +6148,7 @@ function handleError(root$jscomp$0, thrownValue) { returnFiber = workInProgress.return, sourceFiber = workInProgress, value = thrownValue; - thrownValue = renderExpirationTime; + thrownValue = renderExpirationTime$1; sourceFiber.effectTag |= 2048; sourceFiber.firstEffect = sourceFiber.lastEffect = null; if ( @@ -6277,8 +6156,17 @@ function handleError(root$jscomp$0, thrownValue) { "object" === typeof value && "function" === typeof value.then ) { - var thenable = value, - hasInvisibleParentBoundary = + 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 = 0 !== (suspenseStackCursor.current & 1), _workInProgress = returnFiber; do { @@ -6293,10 +6181,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) { @@ -6403,8 +6291,8 @@ function handleError(root$jscomp$0, thrownValue) { } while (1); } function pushDispatcher() { - var prevDispatcher = ReactCurrentDispatcher.current; - ReactCurrentDispatcher.current = ContextOnlyDispatcher; + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; return null === prevDispatcher ? ContextOnlyDispatcher : prevDispatcher; } function pushInteractions(root) { @@ -6426,6 +6314,33 @@ 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); @@ -6435,43 +6350,35 @@ function workLoopConcurrent() { workInProgress = performUnitOfWork(workInProgress); } function performUnitOfWork(unitOfWork) { - var current$$1 = unitOfWork.alternate; + var current = unitOfWork.alternate; 0 !== (unitOfWork.mode & 8) ? ((profilerStartTime = now$1()), 0 > unitOfWork.actualStartTime && (unitOfWork.actualStartTime = now$1()), - (current$$1 = beginWork$$1(current$$1, unitOfWork, renderExpirationTime)), + (current = beginWork$1(current, unitOfWork, renderExpirationTime$1)), stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, !0)) - : (current$$1 = beginWork$$1(current$$1, unitOfWork, renderExpirationTime)); + : (current = beginWork$1(current, unitOfWork, renderExpirationTime$1)); unitOfWork.memoizedProps = unitOfWork.pendingProps; - null === current$$1 && (current$$1 = completeUnitOfWork(unitOfWork)); + null === current && (current = completeUnitOfWork(unitOfWork)); ReactCurrentOwner$2.current = null; - return current$$1; + return current; } function completeUnitOfWork(unitOfWork) { workInProgress = unitOfWork; do { - var current$$1 = workInProgress.alternate; + var current = workInProgress.alternate; unitOfWork = workInProgress.return; if (0 === (workInProgress.effectTag & 2048)) { if (0 === (workInProgress.mode & 8)) - current$$1 = completeWork( - current$$1, - workInProgress, - renderExpirationTime - ); + current = completeWork(current, workInProgress, renderExpirationTime$1); else { var fiber = workInProgress; profilerStartTime = now$1(); 0 > fiber.actualStartTime && (fiber.actualStartTime = now$1()); - current$$1 = completeWork( - current$$1, - workInProgress, - renderExpirationTime - ); + current = completeWork(current, workInProgress, renderExpirationTime$1); stopProfilerTimerIfRunningAndRecordDelta(workInProgress, !1); } fiber = workInProgress; - if (1 === renderExpirationTime || 1 !== fiber.childExpirationTime) { + if (1 === renderExpirationTime$1 || 1 !== fiber.childExpirationTime) { var newChildExpirationTime = 0; if (0 !== (fiber.mode & 8)) { for ( @@ -6509,7 +6416,7 @@ function completeUnitOfWork(unitOfWork) { (actualDuration = actualDuration.sibling); fiber.childExpirationTime = newChildExpirationTime; } - if (null !== current$$1) return current$$1; + if (null !== current) return current; null !== unitOfWork && 0 === (unitOfWork.effectTag & 2048) && (null === unitOfWork.firstEffect && @@ -6524,7 +6431,7 @@ function completeUnitOfWork(unitOfWork) { : (unitOfWork.firstEffect = workInProgress), (unitOfWork.lastEffect = workInProgress))); } else { - current$$1 = unwindWork(workInProgress, renderExpirationTime); + current = unwindWork(workInProgress); if (0 !== (workInProgress.mode & 8)) { stopProfilerTimerIfRunningAndRecordDelta(workInProgress, !1); fiber = workInProgress.actualDuration; @@ -6537,14 +6444,13 @@ function completeUnitOfWork(unitOfWork) { (newChildExpirationTime = newChildExpirationTime.sibling); workInProgress.actualDuration = fiber; } - if (null !== current$$1) - return (current$$1.effectTag &= 2047), current$$1; + if (null !== current) return (current.effectTag &= 2047), current; null !== unitOfWork && ((unitOfWork.firstEffect = unitOfWork.lastEffect = null), (unitOfWork.effectTag |= 2048)); } - current$$1 = workInProgress.sibling; - if (null !== current$$1) return current$$1; + current = workInProgress.sibling; + if (null !== current) return current; workInProgress = unitOfWork; } while (null !== workInProgress); workInProgressRootExitStatus === RootIncomplete && @@ -6562,7 +6468,8 @@ function commitRoot(root) { return null; } function commitRootImpl(root$jscomp$0, renderPriorityLevel$jscomp$0) { - flushPassiveEffects(); + do flushPassiveEffects(); + while (null !== rootWithPendingPassiveEffects); if ((executionContext & (RenderContext | CommitContext)) !== NoContext) throw Error("Should not already be working."); var finishedWork = root$jscomp$0.finishedWork, @@ -6591,7 +6498,8 @@ 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 = 0)); + ((workInProgress = workInProgressRoot = null), + (renderExpirationTime$1 = 0)); 1 < finishedWork.effectTag ? null !== finishedWork.lastEffect ? ((finishedWork.lastEffect.nextEffect = finishedWork), @@ -6625,9 +6533,9 @@ function commitRootImpl(root$jscomp$0, renderPriorityLevel$jscomp$0) { ) { var effectTag = nextEffect.effectTag; if (effectTag & 128) { - var current$$1 = nextEffect.alternate; - if (null !== current$$1) { - var currentRef = current$$1.ref; + var current = nextEffect.alternate; + if (null !== current) { + var currentRef = current.ref; null !== currentRef && ("function" === typeof currentRef ? currentRef(null) @@ -6655,13 +6563,13 @@ function commitRootImpl(root$jscomp$0, renderPriorityLevel$jscomp$0) { commitWork(nextEffect.alternate, nextEffect); break; case 8: - var current$$1$jscomp$0 = nextEffect; + var current$jscomp$0 = nextEffect; unmountHostComponents( root, - current$$1$jscomp$0, + current$jscomp$0, renderPriorityLevel ); - detachFiber(current$$1$jscomp$0); + detachFiber(current$jscomp$0); } nextEffect = nextEffect.nextEffect; } @@ -6675,113 +6583,25 @@ function commitRootImpl(root$jscomp$0, renderPriorityLevel$jscomp$0) { nextEffect = remainingExpirationTimeBeforeCommit; do try { - for ( - effectTag = root$jscomp$0, current$$1 = expirationTime; - null !== nextEffect; - - ) { + for (effectTag = root$jscomp$0; null !== nextEffect; ) { var effectTag$jscomp$0 = nextEffect.effectTag; - 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." - ); - } - } + effectTag$jscomp$0 & 36 && + commitLifeCycles(effectTag, nextEffect.alternate, nextEffect); if (effectTag$jscomp$0 & 128) { - currentRef = void 0; + current = void 0; var ref = nextEffect.ref; if (null !== ref) { - var instance$jscomp$0 = nextEffect.stateNode; + var instance = nextEffect.stateNode; switch (nextEffect.tag) { case 5: - currentRef = instance$jscomp$0; + current = instance; break; default: - currentRef = instance$jscomp$0; + current = instance; } "function" === typeof ref - ? ref(currentRef) - : (ref.current = currentRef); + ? ref(current) + : (ref.current = current); } } nextEffect = nextEffect.nextEffect; @@ -6817,13 +6637,13 @@ function commitRootImpl(root$jscomp$0, renderPriorityLevel$jscomp$0) { for ( remainingExpirationTimeBeforeCommit = spawnedWorkDuringRender, spawnedWorkDuringRender = null, - current$$1$jscomp$1 = 0; - current$$1$jscomp$1 < remainingExpirationTimeBeforeCommit.length; - current$$1$jscomp$1++ + ref = 0; + ref < remainingExpirationTimeBeforeCommit.length; + ref++ ) scheduleInteractions( root$jscomp$0, - remainingExpirationTimeBeforeCommit[current$$1$jscomp$1], + remainingExpirationTimeBeforeCommit[ref], root$jscomp$0.memoizedInteractions ); schedulePendingInteractions(root$jscomp$0, renderPriorityLevel$jscomp$0); @@ -6884,27 +6704,28 @@ function flushPassiveEffectsImpl() { executionContext |= CommitContext; for ( var prevInteractions = pushInteractions(root), - effect = root.current.firstEffect; - null !== effect; + _effect2 = root.current.firstEffect; + null !== _effect2; ) { try { - var finishedWork = effect; + var finishedWork = _effect2; if (0 !== (finishedWork.effectTag & 512)) switch (finishedWork.tag) { case 0: case 11: case 15: - commitHookEffectList(128, 0, finishedWork), - commitHookEffectList(0, 64, finishedWork); + case 22: + commitHookEffectListUnmount(5, finishedWork), + commitHookEffectListMount(5, finishedWork); } } catch (error) { - if (null === effect) throw Error("Should be working on an effect."); - captureCommitPhaseError(effect, error); + if (null === _effect2) throw Error("Should be working on an effect."); + captureCommitPhaseError(_effect2, error); } - finishedWork = effect.nextEffect; - effect.nextEffect = null; - effect = finishedWork; + finishedWork = _effect2.nextEffect; + _effect2.nextEffect = null; + _effect2 = finishedWork; } tracing.__interactionsRef.current = prevInteractions; finishPendingInteractions(root, expirationTime); @@ -6953,19 +6774,17 @@ function captureCommitPhaseError(sourceFiber, error) { function pingSuspendedRoot(root, thenable, suspendedTime) { var pingCache = root.pingCache; null !== pingCache && pingCache.delete(thenable); - workInProgressRoot === root && renderExpirationTime === suspendedTime + workInProgressRoot === root && renderExpirationTime$1 === suspendedTime ? workInProgressRootExitStatus === RootSuspendedWithDelay || (workInProgressRootExitStatus === RootSuspended && 1073741823 === workInProgressRootLatestProcessedExpirationTime && now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) - ? prepareFreshStack(root, renderExpirationTime) + ? prepareFreshStack(root, renderExpirationTime$1) : (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))); } @@ -6981,12 +6800,12 @@ function resolveRetryThenable(boundaryFiber, thenable) { (ensureRootIsScheduled(boundaryFiber), schedulePendingInteractions(boundaryFiber, thenable)); } -var beginWork$$1; -beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { +var beginWork$1; +beginWork$1 = function(current, workInProgress, renderExpirationTime) { var updateExpirationTime = workInProgress.expirationTime; - if (null !== current$$1) + if (null !== current) if ( - current$$1.memoizedProps !== workInProgress.pendingProps || + current.memoizedProps !== workInProgress.pendingProps || didPerformWorkStackCursor.current ) didReceiveUpdate = !0; @@ -7011,11 +6830,17 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { ); break; case 10: - pushProvider(workInProgress, workInProgress.memoizedProps.value); + updateExpirationTime = workInProgress.memoizedProps.value; + var context = workInProgress.type._context; + push(valueCursor, context._currentValue); + context._currentValue = updateExpirationTime; 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) { @@ -7025,52 +6850,40 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { updateExpirationTime >= renderExpirationTime ) return updateSuspenseComponent( - current$$1, + current, workInProgress, renderExpirationTime ); - push( - suspenseStackCursor, - suspenseStackCursor.current & 1, - workInProgress - ); + push(suspenseStackCursor, suspenseStackCursor.current & 1); workInProgress = bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ); return null !== workInProgress ? workInProgress.sibling : null; } - push( - suspenseStackCursor, - suspenseStackCursor.current & 1, - workInProgress - ); + push(suspenseStackCursor, suspenseStackCursor.current & 1); break; case 19: updateExpirationTime = workInProgress.childExpirationTime >= renderExpirationTime; - if (0 !== (current$$1.effectTag & 64)) { + if (0 !== (current.effectTag & 64)) { if (updateExpirationTime) return updateSuspenseListComponent( - current$$1, + current, workInProgress, renderExpirationTime ); workInProgress.effectTag |= 64; } - var renderState = workInProgress.memoizedState; - null !== renderState && - ((renderState.rendering = null), (renderState.tail = null)); - push( - suspenseStackCursor, - suspenseStackCursor.current, - workInProgress - ); + context = workInProgress.memoizedState; + null !== context && + ((context.rendering = null), (context.tail = null)); + push(suspenseStackCursor, suspenseStackCursor.current); if (!updateExpirationTime) return null; } return bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ); @@ -7082,41 +6895,40 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { switch (workInProgress.tag) { case 2: updateExpirationTime = workInProgress.type; - null !== current$$1 && - ((current$$1.alternate = null), + null !== current && + ((current.alternate = null), (workInProgress.alternate = null), (workInProgress.effectTag |= 2)); - current$$1 = workInProgress.pendingProps; - renderState = getMaskedContext( - workInProgress, - contextStackCursor.current - ); + current = workInProgress.pendingProps; + context = getMaskedContext(workInProgress, contextStackCursor.current); prepareToReadContext(workInProgress, renderExpirationTime); - renderState = renderWithHooks( + context = renderWithHooks( null, workInProgress, updateExpirationTime, - current$$1, - renderState, + current, + context, renderExpirationTime ); workInProgress.effectTag |= 1; if ( - "object" === typeof renderState && - null !== renderState && - "function" === typeof renderState.render && - void 0 === renderState.$$typeof + "object" === typeof context && + null !== context && + "function" === typeof context.render && + void 0 === context.$$typeof ) { workInProgress.tag = 1; - resetHooks(); + workInProgress.memoizedState = null; + workInProgress.updateQueue = null; if (isContextProvider(updateExpirationTime)) { var hasContext = !0; pushContextProvider(workInProgress); } else hasContext = !1; workInProgress.memoizedState = - null !== renderState.state && void 0 !== renderState.state - ? renderState.state + null !== context.state && void 0 !== context.state + ? context.state : null; + initializeUpdateQueue(workInProgress); var getDerivedStateFromProps = updateExpirationTime.getDerivedStateFromProps; "function" === typeof getDerivedStateFromProps && @@ -7124,15 +6936,15 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { workInProgress, updateExpirationTime, getDerivedStateFromProps, - current$$1 + current ); - renderState.updater = classComponentUpdater; - workInProgress.stateNode = renderState; - renderState._reactInternalFiber = workInProgress; + context.updater = classComponentUpdater; + workInProgress.stateNode = context; + context._reactInternalFiber = workInProgress; mountClassInstance( workInProgress, updateExpirationTime, - current$$1, + current, renderExpirationTime ); workInProgress = finishClassComponent( @@ -7148,127 +6960,129 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { reconcileChildren( null, workInProgress, - renderState, + context, renderExpirationTime ), (workInProgress = workInProgress.child); return workInProgress; case 16: - 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." - ); + 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." + ); } return workInProgress; case 0: return ( (updateExpirationTime = workInProgress.type), - (renderState = workInProgress.pendingProps), - (renderState = + (context = workInProgress.pendingProps), + (context = workInProgress.elementType === updateExpirationTime - ? renderState - : resolveDefaultProps(updateExpirationTime, renderState)), + ? context + : resolveDefaultProps(updateExpirationTime, context)), updateFunctionComponent( - current$$1, + current, workInProgress, updateExpirationTime, - renderState, + context, renderExpirationTime ) ); case 1: return ( (updateExpirationTime = workInProgress.type), - (renderState = workInProgress.pendingProps), - (renderState = + (context = workInProgress.pendingProps), + (context = workInProgress.elementType === updateExpirationTime - ? renderState - : resolveDefaultProps(updateExpirationTime, renderState)), + ? context + : resolveDefaultProps(updateExpirationTime, context)), updateClassComponent( - current$$1, + current, workInProgress, updateExpirationTime, - renderState, + context, renderExpirationTime ) ); case 3: pushHostRootContext(workInProgress); updateExpirationTime = workInProgress.updateQueue; - if (null === updateExpirationTime) + if (null === current || 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." ); - renderState = workInProgress.memoizedState; - renderState = null !== renderState ? renderState.element : null; + updateExpirationTime = workInProgress.pendingProps; + context = workInProgress.memoizedState; + context = null !== context ? context.element : null; + cloneUpdateQueue(current, workInProgress); processUpdateQueue( workInProgress, updateExpirationTime, - workInProgress.pendingProps, null, renderExpirationTime ); updateExpirationTime = workInProgress.memoizedState.element; - updateExpirationTime === renderState + updateExpirationTime === context ? (workInProgress = bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime )) : (reconcileChildren( - current$$1, + current, workInProgress, updateExpirationTime, renderExpirationTime @@ -7278,11 +7092,10 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { case 5: return ( pushHostContext(workInProgress), - null === current$$1 && tryToClaimNextHydratableInstance(workInProgress), (updateExpirationTime = workInProgress.pendingProps.children), - markRef(current$$1, workInProgress), + markRef(current, workInProgress), reconcileChildren( - current$$1, + current, workInProgress, updateExpirationTime, renderExpirationTime @@ -7291,13 +7104,10 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { workInProgress ); case 6: - return ( - null === current$$1 && tryToClaimNextHydratableInstance(workInProgress), - null - ); + return null; case 13: return updateSuspenseComponent( - current$$1, + current, workInProgress, renderExpirationTime ); @@ -7308,7 +7118,7 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { workInProgress.stateNode.containerInfo ), (updateExpirationTime = workInProgress.pendingProps), - null === current$$1 + null === current ? (workInProgress.child = reconcileChildFibers( workInProgress, null, @@ -7316,7 +7126,7 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { renderExpirationTime )) : reconcileChildren( - current$$1, + current, workInProgress, updateExpirationTime, renderExpirationTime @@ -7326,23 +7136,23 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { case 11: return ( (updateExpirationTime = workInProgress.type), - (renderState = workInProgress.pendingProps), - (renderState = + (context = workInProgress.pendingProps), + (context = workInProgress.elementType === updateExpirationTime - ? renderState - : resolveDefaultProps(updateExpirationTime, renderState)), + ? context + : resolveDefaultProps(updateExpirationTime, context)), updateForwardRef( - current$$1, + current, workInProgress, updateExpirationTime, - renderState, + context, renderExpirationTime ) ); case 7: return ( reconcileChildren( - current$$1, + current, workInProgress, workInProgress.pendingProps, renderExpirationTime @@ -7352,7 +7162,7 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { case 8: return ( reconcileChildren( - current$$1, + current, workInProgress, workInProgress.pendingProps.children, renderExpirationTime @@ -7362,8 +7172,11 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { case 12: return ( (workInProgress.effectTag |= 4), + (updateExpirationTime = workInProgress.stateNode), + (updateExpirationTime.effectDuration = 0), + (updateExpirationTime.passiveEffectDuration = 0), reconcileChildren( - current$$1, + current, workInProgress, workInProgress.pendingProps.children, renderExpirationTime @@ -7373,27 +7186,32 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { case 10: a: { updateExpirationTime = workInProgress.type._context; - renderState = workInProgress.pendingProps; + context = workInProgress.pendingProps; getDerivedStateFromProps = workInProgress.memoizedProps; - 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) { + 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) + ) { if ( - getDerivedStateFromProps.children === renderState.children && + getDerivedStateFromProps.children === context.children && !didPerformWorkStackCursor.current ) { workInProgress = bailoutOnAlreadyFinishedWork( - current$$1, + current, workInProgress, renderExpirationTime ); @@ -7401,14 +7219,15 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { } } else for ( - oldValue = workInProgress.child, - null !== oldValue && (oldValue.return = workInProgress); - null !== oldValue; + context$jscomp$0 = workInProgress.child, + null !== context$jscomp$0 && + (context$jscomp$0.return = workInProgress); + null !== context$jscomp$0; ) { - var list = oldValue.dependencies; + var list = context$jscomp$0.dependencies; if (null !== list) { - getDerivedStateFromProps = oldValue.child; + getDerivedStateFromProps = context$jscomp$0.child; for ( var dependency = list.firstContext; null !== dependency; @@ -7418,18 +7237,18 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { dependency.context === updateExpirationTime && 0 !== (dependency.observedBits & hasContext) ) { - 1 === oldValue.tag && + 1 === context$jscomp$0.tag && ((dependency = createUpdate(renderExpirationTime, null)), (dependency.tag = 2), - enqueueUpdate(oldValue, dependency)); - oldValue.expirationTime < renderExpirationTime && - (oldValue.expirationTime = renderExpirationTime); - dependency = oldValue.alternate; + enqueueUpdate(context$jscomp$0, dependency)); + context$jscomp$0.expirationTime < renderExpirationTime && + (context$jscomp$0.expirationTime = renderExpirationTime); + dependency = context$jscomp$0.alternate; null !== dependency && dependency.expirationTime < renderExpirationTime && (dependency.expirationTime = renderExpirationTime); scheduleWorkOnParentPath( - oldValue.return, + context$jscomp$0.return, renderExpirationTime ); list.expirationTime < renderExpirationTime && @@ -7440,16 +7259,16 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { } } else getDerivedStateFromProps = - 10 === oldValue.tag - ? oldValue.type === workInProgress.type + 10 === context$jscomp$0.tag + ? context$jscomp$0.type === workInProgress.type ? null - : oldValue.child - : oldValue.child; + : context$jscomp$0.child + : context$jscomp$0.child; if (null !== getDerivedStateFromProps) - getDerivedStateFromProps.return = oldValue; + getDerivedStateFromProps.return = context$jscomp$0; else for ( - getDerivedStateFromProps = oldValue; + getDerivedStateFromProps = context$jscomp$0; null !== getDerivedStateFromProps; ) { @@ -7457,21 +7276,20 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { getDerivedStateFromProps = null; break; } - oldValue = getDerivedStateFromProps.sibling; - if (null !== oldValue) { - oldValue.return = getDerivedStateFromProps.return; - getDerivedStateFromProps = oldValue; + context$jscomp$0 = getDerivedStateFromProps.sibling; + if (null !== context$jscomp$0) { + context$jscomp$0.return = getDerivedStateFromProps.return; + getDerivedStateFromProps = context$jscomp$0; break; } getDerivedStateFromProps = getDerivedStateFromProps.return; } - oldValue = getDerivedStateFromProps; + context$jscomp$0 = getDerivedStateFromProps; } - } reconcileChildren( - current$$1, + current, workInProgress, - renderState.children, + context.children, renderExpirationTime ); workInProgress = workInProgress.child; @@ -7479,18 +7297,15 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { return workInProgress; case 9: return ( - (renderState = workInProgress.type), + (context = workInProgress.type), (hasContext = workInProgress.pendingProps), (updateExpirationTime = hasContext.children), prepareToReadContext(workInProgress, renderExpirationTime), - (renderState = readContext( - renderState, - hasContext.unstable_observedBits - )), - (updateExpirationTime = updateExpirationTime(renderState)), + (context = readContext(context, hasContext.unstable_observedBits)), + (updateExpirationTime = updateExpirationTime(context)), (workInProgress.effectTag |= 1), reconcileChildren( - current$$1, + current, workInProgress, updateExpirationTime, renderExpirationTime @@ -7499,16 +7314,16 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { ); case 14: return ( - (renderState = workInProgress.type), + (context = workInProgress.type), (hasContext = resolveDefaultProps( - renderState, + context, workInProgress.pendingProps )), - (hasContext = resolveDefaultProps(renderState.type, hasContext)), + (hasContext = resolveDefaultProps(context.type, hasContext)), updateMemoComponent( - current$$1, + current, workInProgress, - renderState, + context, hasContext, updateExpirationTime, renderExpirationTime @@ -7516,7 +7331,7 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { ); case 15: return updateSimpleMemoComponent( - current$$1, + current, workInProgress, workInProgress.type, workInProgress.pendingProps, @@ -7526,30 +7341,25 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { case 17: return ( (updateExpirationTime = workInProgress.type), - (renderState = workInProgress.pendingProps), - (renderState = + (context = workInProgress.pendingProps), + (context = workInProgress.elementType === updateExpirationTime - ? renderState - : resolveDefaultProps(updateExpirationTime, renderState)), - null !== current$$1 && - ((current$$1.alternate = null), + ? context + : resolveDefaultProps(updateExpirationTime, context)), + null !== current && + ((current.alternate = null), (workInProgress.alternate = null), (workInProgress.effectTag |= 2)), (workInProgress.tag = 1), isContextProvider(updateExpirationTime) - ? ((current$$1 = !0), pushContextProvider(workInProgress)) - : (current$$1 = !1), + ? ((current = !0), pushContextProvider(workInProgress)) + : (current = !1), prepareToReadContext(workInProgress, renderExpirationTime), - constructClassInstance( - workInProgress, - updateExpirationTime, - renderState, - renderExpirationTime - ), + constructClassInstance(workInProgress, updateExpirationTime, context), mountClassInstance( workInProgress, updateExpirationTime, - renderState, + context, renderExpirationTime ), finishClassComponent( @@ -7557,13 +7367,13 @@ beginWork$$1 = function(current$$1, workInProgress, renderExpirationTime) { workInProgress, updateExpirationTime, !0, - current$$1, + current, renderExpirationTime ) ); case 19: return updateSuspenseListComponent( - current$$1, + current, workInProgress, renderExpirationTime ); @@ -7704,9 +7514,6 @@ 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); @@ -7724,7 +7531,7 @@ function resolveLazyComponentTag(Component) { function createWorkInProgress(current, pendingProps) { var workInProgress = current.alternate; null === workInProgress - ? ((workInProgress = createFiber( + ? ((workInProgress = new FiberNode( current.tag, pendingProps, current.key, @@ -7795,15 +7602,16 @@ function createFiberFromTypeAndProps( break; case REACT_PROFILER_TYPE: return ( - (type = createFiber(12, pendingProps, key, mode | 8)), + (type = new FiberNode(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 = createFiber(13, pendingProps, key, mode)), + (type = new FiberNode(13, pendingProps, key, mode)), (type.type = REACT_SUSPENSE_TYPE), (type.elementType = REACT_SUSPENSE_TYPE), (type.expirationTime = expirationTime), @@ -7811,7 +7619,7 @@ function createFiberFromTypeAndProps( ); case REACT_SUSPENSE_LIST_TYPE: return ( - (type = createFiber(19, pendingProps, key, mode)), + (type = new FiberNode(19, pendingProps, key, mode)), (type.elementType = REACT_SUSPENSE_LIST_TYPE), (type.expirationTime = expirationTime), type @@ -7835,6 +7643,9 @@ 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: " + @@ -7842,24 +7653,24 @@ function createFiberFromTypeAndProps( "." ); } - key = createFiber(fiberTag, pendingProps, key, mode); + key = new FiberNode(fiberTag, pendingProps, key, mode); key.elementType = type; key.type = owner; key.expirationTime = expirationTime; return key; } function createFiberFromFragment(elements, mode, expirationTime, key) { - elements = createFiber(7, elements, key, mode); + elements = new FiberNode(7, elements, key, mode); elements.expirationTime = expirationTime; return elements; } function createFiberFromText(content, mode, expirationTime) { - content = createFiber(6, content, null, mode); + content = new FiberNode(6, content, null, mode); content.expirationTime = expirationTime; return content; } function createFiberFromPortal(portal, mode, expirationTime) { - mode = createFiber( + mode = new FiberNode( 4, null !== portal.children ? portal.children : [], portal.key, @@ -7921,11 +7732,6 @@ 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) { @@ -7940,14 +7746,10 @@ function findHostInstance(component) { return null === component ? null : component.stateNode; } function updateContainer(element, container, parentComponent, callback) { - var current$$1 = container.current, + var current = container.current, currentTime = requestCurrentTimeForUpdate(), suspenseConfig = ReactCurrentBatchConfig.suspense; - currentTime = computeExpirationForFiber( - currentTime, - current$$1, - suspenseConfig - ); + currentTime = computeExpirationForFiber(currentTime, current, suspenseConfig); a: if (parentComponent) { parentComponent = parentComponent._reactInternalFiber; b: { @@ -7998,8 +7800,8 @@ function updateContainer(element, container, parentComponent, callback) { container.payload = { element: element }; callback = void 0 === callback ? null : callback; null !== callback && (container.callback = callback); - enqueueUpdate(current$$1, container); - scheduleUpdateOnFiber(current$$1, currentTime); + enqueueUpdate(current, container); + scheduleWork(current, currentTime); return currentTime; } function createPortal(children, containerInfo, implementation) { @@ -8013,11 +7815,6 @@ 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; @@ -8028,8 +7825,15 @@ function findNodeHandle(componentOrHandle) { return null == componentOrHandle ? componentOrHandle : componentOrHandle.canonical - ? componentOrHandle.canonical._nativeTag - : componentOrHandle._nativeTag; + ? componentOrHandle.canonical._nativeTag + : componentOrHandle._nativeTag; +} +function unmountComponentAtNode(containerTag) { + var root = roots.get(containerTag); + root && + updateContainer(null, root, null, function() { + roots.delete(containerTag); + }); } batchedUpdatesImpl = function(fn, a) { var prevExecutionContext = executionContext; @@ -8041,301 +7845,119 @@ batchedUpdatesImpl = function(fn, a) { executionContext === NoContext && flushSyncCallbackQueue(); } }; -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 = 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) - : ""; - } - } - }; +var roots = new Map(); (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 - }) - ); + 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; + }, + 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.11.0", - rendererPackageName: "react-native-renderer" + 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) + } }); -var ReactNativeRenderer$2 = { default: ReactNativeRenderer }, - ReactNativeRenderer$3 = - (ReactNativeRenderer$2 && ReactNativeRenderer) || ReactNativeRenderer$2; -module.exports = ReactNativeRenderer$3.default || ReactNativeRenderer$3; +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; diff --git a/Libraries/Renderer/shims/NativeMethodsMixin.js b/Libraries/Renderer/shims/NativeMethodsMixin.js deleted file mode 100644 index c50f379fde06cc..00000000000000 --- a/Libraries/Renderer/shims/NativeMethodsMixin.js +++ /dev/null @@ -1,21 +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 { - __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 8f6a708fd20579..536ce9a6f30b65 100644 --- a/Libraries/Renderer/shims/ReactFabric.js +++ b/Libraries/Renderer/shims/ReactFabric.js @@ -23,6 +23,10 @@ if (__DEV__) { ReactFabric = require('../implementations/ReactFabric-prod'); } -BatchedBridge.registerCallableModule('ReactFabric', ReactFabric); +if (global.RN$Bridgeless) { + global.RN$stopSurface = ReactFabric.stopSurface; +} else { + BatchedBridge.registerCallableModule('ReactFabric', ReactFabric); +} module.exports = (ReactFabric: ReactNativeType); diff --git a/Libraries/Renderer/shims/ReactFeatureFlags.js b/Libraries/Renderer/shims/ReactFeatureFlags.js index 9b6ec97a6234c7..13c548b4bb1e82 100644 --- a/Libraries/Renderer/shims/ReactFeatureFlags.js +++ b/Libraries/Renderer/shims/ReactFeatureFlags.js @@ -12,7 +12,6 @@ const ReactFeatureFlags = { debugRenderPhaseSideEffects: false, - enableNativeTargetAsInstance: false, }; module.exports = ReactFeatureFlags; diff --git a/Libraries/Renderer/shims/ReactNativeTypes.js b/Libraries/Renderer/shims/ReactNativeTypes.js index cf20ce938c2760..10244570b65354 100644 --- a/Libraries/Renderer/shims/ReactNativeTypes.js +++ b/Libraries/Renderer/shims/ReactNativeTypes.js @@ -8,7 +8,7 @@ * @flow */ -import React, {type ElementRef, type AbstractComponent} from 'react'; +import type {ElementRef, AbstractComponent} from 'react'; export type MeasureOnSuccessCallback = ( x: number, @@ -77,31 +77,6 @@ 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, @@ -116,28 +91,60 @@ 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 SecretInternalsFabricType = { - NativeMethodsMixin: NativeMethodsMixinType, - ... -}; +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, +|}>; /** * 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>, @@ -157,8 +164,9 @@ export type ReactNativeType = { }; export type ReactFabricType = { - NativeComponent: typeof ReactNativeComponent, - findHostInstance_DEPRECATED(componentOrHandle: any): ?HostComponent, + findHostInstance_DEPRECATED( + componentOrHandle: any, + ): ?ElementRef>, findNodeHandle(componentOrHandle: any): ?number, dispatchCommand(handle: any, command: string, args: Array): void, render( @@ -167,7 +175,6 @@ export type ReactFabricType = { callback: ?Function, ): any, unmountComponentAtNode(containerTag: number): any, - __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: SecretInternalsFabricType, ... }; @@ -204,51 +211,3 @@ 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 e6e3b13b8e859c..2c09ddf3caab10 100644 --- a/Libraries/Renderer/shims/ReactNativeViewConfigRegistry.js +++ b/Libraries/Renderer/shims/ReactNativeViewConfigRegistry.js @@ -8,7 +8,7 @@ * @flow strict-local */ -/* eslint-disable react-internal/warning-and-invariant-args */ +/* eslint-disable react-internal/invariant-args */ 'use strict'; diff --git a/Libraries/Renderer/shims/ReactTypes.js b/Libraries/Renderer/shims/ReactTypes.js deleted file mode 100644 index e97e5823393490..00000000000000 --- a/Libraries/Renderer/shims/ReactTypes.js +++ /dev/null @@ -1,190 +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 - */ - -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 2ac7d0d12f66e4..bc553e46343f24 100644 --- a/Libraries/Settings/RCTSettingsManager.mm +++ b/Libraries/Settings/RCTSettingsManager.mm @@ -141,10 +141,13 @@ - (void)userDefaultsDidChange:(NSNotification *)note } } #endif // ]TODO(macOS ISS#2323203) -- (std::shared_ptr)getTurboModuleWithJsInvoker: - (std::shared_ptr)jsInvoker + +- (std::shared_ptr) + getTurboModuleWithJsInvoker:(std::shared_ptr)jsInvoker + nativeInvoker:(std::shared_ptr)nativeInvoker + perfLogger:(id)perfLogger { - return std::make_shared(self, jsInvoker); + return std::make_shared(self, jsInvoker, nativeInvoker, perfLogger); } @end diff --git a/Libraries/Settings/React-RCTSettings.podspec b/Libraries/Settings/React-RCTSettings.podspec index f9013df94c94ff..dc8d449d345ca0 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 = '2018.10.22.00' +folly_version = '2020.01.13.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 = "http://facebook.github.io/react-native/" - s.documentation_url = "https://facebook.github.io/react-native/docs/settings" + s.homepage = "https://reactnative.dev/" + s.documentation_url = "https://reactnative.dev/docs/settings" s.license = package["license"] s.author = "Facebook, Inc. and its affiliates" - s.platforms = { :ios => "9.0", :tvos => "9.2", :osx => "10.13" } # TODO(macOS GH#214) + 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.source = source s.source_files = "*.{m,mm}" @@ -43,5 +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/RCTSettingsHeaders", version end diff --git a/Libraries/Share/Share.js b/Libraries/Share/Share.js index 5b61f2919ddb34..aed341e56d04b5 100644 --- a/Libraries/Share/Share.js +++ b/Libraries/Share/Share.js @@ -109,6 +109,11 @@ 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.', @@ -120,7 +125,7 @@ class Share { typeof content.message === 'string' ? content.message : undefined, url: typeof content.url === 'string' ? content.url : undefined, subject: options.subject, - tintColor: tintColor != null ? tintColor : undefined, + tintColor: typeof tintColor === 'number' ? tintColor : undefined, excludedActivityTypes: options.excludedActivityTypes, }, error => reject(error), diff --git a/Libraries/Storage/AsyncStorage.js b/Libraries/Storage/AsyncStorage.js index 5c749a93805d3d..67f365a0e03896 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 http://facebook.github.io/react-native/docs/asyncstorage.html + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/asyncstorage.html#getitem + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/asyncstorage.html#setitem + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/asyncstorage.html#removeitem + * See https://reactnative.dev/docs/asyncstorage.html#removeitem */ removeItem: function( key: string, @@ -108,7 +108,7 @@ const AsyncStorage = { * * **NOTE:** This is not supported by all native implementations. * - * See http://facebook.github.io/react-native/docs/asyncstorage.html#mergeitem + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/asyncstorage.html#clear + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/asyncstorage.html#getallkeys + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/asyncstorage.html#flushgetrequests + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/asyncstorage.html#multiget + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/asyncstorage.html#multiset + * See https://reactnative.dev/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 http://facebook.github.io/react-native/docs/asyncstorage.html#multiremove + * See https://reactnative.dev/docs/asyncstorage.html#multiremove */ multiRemove: function( keys: Array, @@ -314,7 +314,7 @@ const AsyncStorage = { * * **NOTE**: This is not supported by all native implementations. * - * See http://facebook.github.io/react-native/docs/asyncstorage.html#multimerge + * See https://reactnative.dev/docs/asyncstorage.html#multimerge */ multiMerge: function( keyValuePairs: Array>, diff --git a/Libraries/StyleSheet/EdgeInsetsPropType.js b/Libraries/StyleSheet/EdgeInsetsPropType.js index 779bca391da9d3..56a51e5481061e 100644 --- a/Libraries/StyleSheet/EdgeInsetsPropType.js +++ b/Libraries/StyleSheet/EdgeInsetsPropType.js @@ -10,9 +10,6 @@ 'use strict'; -export type EdgeInsetsProp = $ReadOnly<{| - top?: ?number, - left?: ?number, - bottom?: ?number, - right?: ?number, -|}>; +import type {Rect} from './Rect'; + +export type EdgeInsetsProp = Rect; diff --git a/Libraries/StyleSheet/PlatformColorValueTypes.android.js b/Libraries/StyleSheet/PlatformColorValueTypes.android.js new file mode 100644 index 00000000000000..1458a9b4396d54 --- /dev/null +++ b/Libraries/StyleSheet/PlatformColorValueTypes.android.js @@ -0,0 +1,41 @@ +/** + * 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 new file mode 100644 index 00000000000000..d329db9316f2d1 --- /dev/null +++ b/Libraries/StyleSheet/PlatformColorValueTypes.ios.js @@ -0,0 +1,77 @@ +/** + * 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 new file mode 100644 index 00000000000000..29c62f7c93c33f --- /dev/null +++ b/Libraries/StyleSheet/PlatformColorValueTypes.macos.js @@ -0,0 +1,78 @@ +/** + * 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 new file mode 100644 index 00000000000000..58f551098fb5db --- /dev/null +++ b/Libraries/StyleSheet/PlatformColorValueTypesAndroid.android.js @@ -0,0 +1,18 @@ +/** + * 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 new file mode 100644 index 00000000000000..647000b3b1e9d0 --- /dev/null +++ b/Libraries/StyleSheet/PlatformColorValueTypesAndroid.js @@ -0,0 +1,17 @@ +/** + * 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 new file mode 100644 index 00000000000000..2b21c61f3df19e --- /dev/null +++ b/Libraries/StyleSheet/PlatformColorValueTypesIOS.ios.js @@ -0,0 +1,23 @@ +/** + * 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 new file mode 100644 index 00000000000000..cc9aa69e80f96b --- /dev/null +++ b/Libraries/StyleSheet/PlatformColorValueTypesIOS.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 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 new file mode 100644 index 00000000000000..12fee85a5070d8 --- /dev/null +++ b/Libraries/StyleSheet/PlatformColorValueTypesIOS.macos.js @@ -0,0 +1,24 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @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 new file mode 100644 index 00000000000000..164909c74d28b2 --- /dev/null +++ b/Libraries/StyleSheet/Rect.js @@ -0,0 +1,28 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @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 1a1fea49e4fd3e..54094d8bd4929e 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): $ObjMap any> { + create<+S: ____Styles_Internal>(obj: S): $ReadOnly { // 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 d39b6541587c4f..39ee7da194c656 100644 --- a/Libraries/StyleSheet/StyleSheetTypes.js +++ b/Libraries/StyleSheet/StyleSheetTypes.js @@ -11,9 +11,10 @@ 'use strict'; const AnimatedNode = require('../Animated/src/nodes/AnimatedNode'); -import type {NativeOrDynamicColorType} from '../StyleSheet/NativeOrDynamicColorType'; // TODO(macOS ISS#2323203) -export type ColorValue = null | string | NativeOrDynamicColorType; // TODO(macOS ISS#2323203) +import type {NativeColorValue} from './PlatformColorValueTypes'; + +export type ColorValue = null | string | NativeColorValue; export type ColorArrayValue = null | $ReadOnlyArray; export type PointValue = {| @@ -466,7 +467,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://facebook.github.io/yoga/docs/rtl/ + * See https://yogalayout.com/docs/layout-direction * for more details. * @platform ios */ diff --git a/Libraries/StyleSheet/StyleSheetValidation.js b/Libraries/StyleSheet/StyleSheetValidation.js index 6871751eb0dad0..456953f7a064f8 100644 --- a/Libraries/StyleSheet/StyleSheetValidation.js +++ b/Libraries/StyleSheet/StyleSheetValidation.js @@ -51,7 +51,11 @@ class StyleSheetValidation { if (!__DEV__ || global.__RCTProfileIsProfiling) { return; } - for (const prop in styles[name]) { + if (!styles[name]) { + return; + } + const styleProps = Object.keys(styles[name]); + for (const prop of styleProps) { StyleSheetValidation.validateStyleProp( prop, styles[name], diff --git a/Libraries/StyleSheet/__flowtests__/StyleSheet-flowtest.js b/Libraries/StyleSheet/__flowtests__/StyleSheet-flowtest.js index 561cb144978b96..c93c8de63cd9d8 100644 --- a/Libraries/StyleSheet/__flowtests__/StyleSheet-flowtest.js +++ b/Libraries/StyleSheet/__flowtests__/StyleSheet-flowtest.js @@ -66,6 +66,7 @@ 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 35e8cfd03e8b1c..12eac4cfbf8d6d 100644 --- a/Libraries/StyleSheet/__tests__/normalizeColor-test.js +++ b/Libraries/StyleSheet/__tests__/normalizeColor-test.js @@ -10,6 +10,7 @@ 'use strict'; +const {OS} = require('../../Utilities/Platform'); const normalizeColor = require('../normalizeColor'); describe('normalizeColor', function() { @@ -128,4 +129,56 @@ 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 0b60130e26ebf3..d428b854e8f50e 100644 --- a/Libraries/StyleSheet/__tests__/processColor-test.js +++ b/Libraries/StyleSheet/__tests__/processColor-test.js @@ -13,6 +13,13 @@ 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 @@ -84,4 +91,33 @@ 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 acd45cdd72a761..1be389cdb92421 100644 --- a/Libraries/StyleSheet/__tests__/processColorArray-test.js +++ b/Libraries/StyleSheet/__tests__/processColorArray-test.js @@ -13,6 +13,13 @@ 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 @@ -57,4 +64,48 @@ 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 667222329d1584..eaee5813b177e1 100755 --- a/Libraries/StyleSheet/normalizeColor.js +++ b/Libraries/StyleSheet/normalizeColor.js @@ -12,15 +12,12 @@ 'use strict'; -import type {NativeOrDynamicColorType} from './NativeOrDynamicColorType'; // TODO(macOS ISS#2323203) +import type {ColorValue} from './StyleSheetTypes'; +import type {ProcessedColorValue} from './processColor'; function normalizeColor( - color: ?( - | string - | number - | NativeOrDynamicColorType - ) /* TODO(macOS ISS#2323203) */, -): ?(number | NativeOrDynamicColorType) /* TODO(macOS ISS#2323203) */ { + color: ?(ColorValue | ProcessedColorValue), +): ?ProcessedColorValue { const matchers = getMatchers(); let match; @@ -31,20 +28,20 @@ function normalizeColor( return null; } - // [TODO(macOS ISS#2323203) - if (typeof color === 'object' && color !== null) { - const normalizeColorObject = require('./normalizeColorObject'); // TODO(macOS ISS#2323203) + if (typeof color === 'object' && color != null) { + const normalizeColorObject = require('./PlatformColorValueTypes') + .normalizeColorObject; 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 deleted file mode 100644 index bbd5acc0384444..00000000000000 --- a/Libraries/StyleSheet/normalizeColorObject.android.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 - */ -// [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 deleted file mode 100644 index d3f77888dd4d87..00000000000000 --- a/Libraries/StyleSheet/normalizeColorObject.ios.js +++ /dev/null @@ -1,39 +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 - */ -// [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 deleted file mode 100644 index d3f77888dd4d87..00000000000000 --- a/Libraries/StyleSheet/normalizeColorObject.macos.js +++ /dev/null @@ -1,39 +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 - */ -// [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 d9df1d427c11ae..3bfa9679e00a79 100644 --- a/Libraries/StyleSheet/processColor.js +++ b/Libraries/StyleSheet/processColor.js @@ -13,46 +13,49 @@ const Platform = require('../Utilities/Platform'); const normalizeColor = require('./normalizeColor'); -import type {NativeOrDynamicColorType} from '../StyleSheet/NativeOrDynamicColorType'; // TODO(macOS ISS#2323203) + +import type {ColorValue} from './StyleSheetTypes'; +import type {NativeColorValue} from './PlatformColorValueTypes'; + +export type ProcessedColorValue = number | NativeColorValue; /* eslint no-bitwise: 0 */ -function processColor( - color?: ?(string | number | NativeOrDynamicColorType), -): ?(number | NativeOrDynamicColorType) /* TODO(macOS ISS#2323203) */ { +function processColor(color?: ?(number | ColorValue)): ?ProcessedColorValue { if (color === undefined || color === null) { return color; } - let int32Color = normalizeColor(color); - if (int32Color === null || int32Color === undefined) { + let normalizedColor = normalizeColor(color); + if (normalizedColor === null || normalizedColor === undefined) { return undefined; } - if (typeof int32Color === 'object') { - const processColorObject = require('../StyleSheet/processColorObject'); // [TODO(macOS ISS#2323203) + if (typeof normalizedColor === 'object') { + const processColorObject = require('./PlatformColorValueTypes') + .processColorObject; - const processedColorObj = processColorObject(int32Color); + const processedColorObj = processColorObject(normalizedColor); - if (processedColorObj !== null) { + if (processedColorObj != null) { return processedColorObj; } } - if (typeof int32Color !== 'number') { + if (typeof normalizedColor !== 'number') { return null; - } // ]TODO(macOS ISS#2323203) + } // Converts 0xrrggbbaa into 0xaarrggbb - int32Color = ((int32Color << 24) | (int32Color >>> 8)) >>> 0; + normalizedColor = ((normalizedColor << 24) | (normalizedColor >>> 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. - int32Color = int32Color | 0x0; + normalizedColor = normalizedColor | 0x0; } - return int32Color; + return normalizedColor; } module.exports = processColor; diff --git a/Libraries/StyleSheet/processColorArray.js b/Libraries/StyleSheet/processColorArray.js index 4d2490fb0ac9a0..9bdb026b5bc0c3 100644 --- a/Libraries/StyleSheet/processColorArray.js +++ b/Libraries/StyleSheet/processColorArray.js @@ -11,11 +11,13 @@ 'use strict'; const processColor = require('./processColor'); -import type {NativeOrDynamicColorType} from '../StyleSheet/NativeOrDynamicColorType'; // TODO(macOS ISS#2323203) + +import type {ColorValue} from './StyleSheetTypes'; +import type {ProcessedColorValue} from './processColor'; function processColorArray( - colors: ?Array, -): ?Array /* TODO(macOS ISS#2323203) */ { + colors: ?Array, +): ?Array { return colors == null ? null : colors.map(processColor); } diff --git a/Libraries/StyleSheet/processColorObject.android.js b/Libraries/StyleSheet/processColorObject.android.js deleted file mode 100644 index 21a5ade0df425b..00000000000000 --- a/Libraries/StyleSheet/processColorObject.android.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 - */ -// [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 deleted file mode 100644 index d6a7f85ff2d068..00000000000000 --- a/Libraries/StyleSheet/processColorObject.ios.js +++ /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. - * - * @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 deleted file mode 100644 index d6a7f85ff2d068..00000000000000 --- a/Libraries/StyleSheet/processColorObject.macos.js +++ /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. - * - * @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 1ec96929d667b0..9f7ccefbbda8a9 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'); +const stringifySafe = require('../Utilities/stringifySafe').default; /** * Generate a transform matrix based on the provided transforms, and use that @@ -174,9 +174,6 @@ 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', @@ -189,9 +186,6 @@ 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 b98edce8607f87..276ee8ba25787c 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 = "http://facebook.github.io/react-native/" - s.documentation_url = "https://facebook.github.io/react-native/docs/text" + s.homepage = "https://reactnative.dev/" + s.documentation_url = "https://reactnative.dev/docs/text" s.license = package["license"] s.author = "Facebook, Inc. and its affiliates" - s.platforms = { :ios => "9.0", :tvos => "9.2", :osx => "10.13" } # TODO(macOS GH#214) + s.platforms = { :ios => "10.0", :tvos => "10.0", :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 92da79d44901fc..660dd87976121f 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 {NativeComponent} from '../Renderer/shims/ReactNative'; +import type {HostComponent} from '../Renderer/shims/ReactNativeTypes'; import type {PressRetentionOffset, TextProps} from './TextProps'; type ResponseHandlers = $ReadOnly<{| @@ -83,7 +83,7 @@ const viewConfig = { /** * A React component for displaying text. * - * See https://facebook.github.io/react-native/docs/text.html + * See https://reactnative.dev/docs/text.html */ class TouchableText extends React.Component { static defaultProps = { @@ -291,6 +291,12 @@ TextToExport.displayName = 'Text'; * and run Flow. */ TextToExport.propTypes = DeprecatedTextPropTypes; -module.exports = ((TextToExport: $FlowFixMe): Class< - NativeComponent, ->); +type TextStatics = $ReadOnly<{| + propTypes: typeof DeprecatedTextPropTypes, +|}>; + +module.exports = ((TextToExport: any): React.AbstractComponent< + TextProps, + React.ElementRef>, +> & + TextStatics); diff --git a/Libraries/Text/Text/RCTTextShadowView.m b/Libraries/Text/Text/RCTTextShadowView.m index b30a9994a7b8de..28bf15b4a13b21 100644 --- a/Libraries/Text/Text/RCTTextShadowView.m +++ b/Libraries/Text/Text/RCTTextShadowView.m @@ -230,6 +230,7 @@ - (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 25b31f4ad29c95..b2b46747821a86 100644 --- a/Libraries/Text/Text/RCTTextView.m +++ b/Libraries/Text/Text/RCTTextView.m @@ -173,6 +173,7 @@ - (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 000b81fd2bbd74..7b5790e5321891 100644 --- a/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputViewManager.m +++ b/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputViewManager.m @@ -6,7 +6,6 @@ */ #import - #import @implementation RCTMultilineTextInputViewManager diff --git a/Libraries/Text/TextInput/Multiline/RCTUITextView.h b/Libraries/Text/TextInput/Multiline/RCTUITextView.h index 6f15f97a1d9ee2..f77d8b5011c988 100644 --- a/Libraries/Text/TextInput/Multiline/RCTUITextView.h +++ b/Libraries/Text/TextInput/Multiline/RCTUITextView.h @@ -9,9 +9,8 @@ #import "RCTTextUIKit.h" // TODO(macOS ISS#2323203) -#import "RCTBackedTextInputViewProtocol.h" - -#import "RCTBackedTextInputDelegate.h" +#import +#import NS_ASSUME_NONNULL_BEGIN diff --git a/Libraries/Text/TextInput/Multiline/RCTUITextView.m b/Libraries/Text/TextInput/Multiline/RCTUITextView.m index 188e36c828da07..522fc5c794ba7e 100644 --- a/Libraries/Text/TextInput/Multiline/RCTUITextView.m +++ b/Libraries/Text/TextInput/Multiline/RCTUITextView.m @@ -165,6 +165,10 @@ - (BOOL)becomeFirstResponder - (void)setDefaultTextAttributes:(NSDictionary *)defaultTextAttributes { + if ([_defaultTextAttributes isEqualToDictionary:defaultTextAttributes]) { + return; + } + _defaultTextAttributes = defaultTextAttributes; self.typingAttributes = defaultTextAttributes; [self _updatePlaceholder]; @@ -332,6 +336,19 @@ - (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 c4c5844c0e6db3..a9388f1c77b6b3 100644 --- a/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h +++ b/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h @@ -31,12 +31,9 @@ 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) @@ -49,6 +46,14 @@ 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 98aaff61200c24..7345ff02528a6d 100644 --- a/Libraries/Text/TextInput/RCTBaseTextInputView.h +++ b/Libraries/Text/TextInput/RCTBaseTextInputView.h @@ -44,6 +44,7 @@ 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; @@ -58,6 +59,12 @@ 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 6bf2741349bf67..1a63addbdc0a76 100644 --- a/Libraries/Text/TextInput/RCTBaseTextInputView.m +++ b/Libraries/Text/TextInput/RCTBaseTextInputView.m @@ -24,8 +24,7 @@ @implementation RCTBaseTextInputView { __weak RCTBridge *_bridge; __weak RCTEventDispatcher *_eventDispatcher; BOOL _hasInputAccesoryView; - // TODO(OSS Candidate ISS#2710739): remove _predictedText ivar - NSInteger _nativeEventCount; + // TODO(OSS Candidate ISS#2710739): remove explicit _predictedText ivar declaration BOOL _didMoveToWindow; } @@ -70,7 +69,13 @@ - (void)enforceTextAttributesIfNeeded { if (![self ignoresTextAttributes]) { // TODO(OSS Candidate ISS#2710739) id backedTextInputView = self.backedTextInputView; - backedTextInputView.defaultTextAttributes = [_textAttributes effectiveTextAttributes]; + + NSDictionary *textAttributes = [[_textAttributes effectiveTextAttributes] mutableCopy]; + if ([textAttributes valueForKey:NSForegroundColorAttributeName] == nil) { + [textAttributes setValue:[RCTUIColor blackColor] forKey:NSForegroundColorAttributeName]; // TODO(macOS ISS#2323203) + } + + backedTextInputView.defaultTextAttributes = textAttributes; } // TODO(OSS Candidate ISS#2710739) } @@ -233,70 +238,82 @@ - (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) && __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; - } + #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; #endif } diff --git a/Libraries/Text/TextInput/RCTBaseTextInputViewManager.m b/Libraries/Text/TextInput/RCTBaseTextInputViewManager.m index fa8763678ddfd6..2072f10629cdc2 100644 --- a/Libraries/Text/TextInput/RCTBaseTextInputViewManager.m +++ b/Libraries/Text/TextInput/RCTBaseTextInputViewManager.m @@ -21,6 +21,7 @@ #if !TARGET_OS_OSX // TODO(macOS ISS#2323203) #import #endif // TODO(macOS ISS#2323203) +#import // TODO(macOS ISS#2323203) @interface RCTBaseTextInputViewManager () @@ -45,7 +46,6 @@ @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,6 +53,7 @@ @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) @@ -75,6 +76,11 @@ @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 { @@ -105,6 +111,45 @@ - (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 d48d3b96bf8398..ae767255a9dda1 100644 --- a/Libraries/Text/TextInput/Singleline/RCTUITextField.h +++ b/Libraries/Text/TextInput/Singleline/RCTUITextField.h @@ -9,7 +9,8 @@ #import "RCTTextUIKit.h" // TODO(macOS ISS#2323203) -#import "RCTBackedTextInputViewProtocol.h" +#import +#import NS_ASSUME_NONNULL_BEGIN @@ -39,8 +40,10 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, assign, getter=isEditable) BOOL editable; #else // [TODO(macOS ISS#2323203) @property (assign, getter=isEditable) BOOL editable; -#endif -#if TARGET_OS_OSX +#endif // ]TODO(macOS ISS#2323203) +@property (nonatomic, getter=isScrollEnabled) BOOL scrollEnabled; + +#if TARGET_OS_OSX // [TODO(macOS ISS#2323203) @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 b36546f97f4e04..420e7fea252fe4 100644 --- a/Libraries/Text/TextInput/Singleline/RCTUITextField.m +++ b/Libraries/Text/TextInput/Singleline/RCTUITextField.m @@ -9,7 +9,6 @@ #import #import - #import #import // TODO(OSS Candidate ISS#2710739) #import @@ -117,6 +116,7 @@ - (instancetype)initWithFrame:(CGRect)frame #endif // ]TODO(macOS ISS#2323203) _textInputDelegateAdapter = [[RCTBackedTextFieldDelegateAdapter alloc] initWithTextField:self]; + _scrollEnabled = YES; } return self; @@ -248,6 +248,10 @@ - (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]; @@ -292,16 +296,6 @@ - (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 b14dfbfa88cdfc..009929e8ff7076 100644 --- a/Libraries/Text/TextProps.js +++ b/Libraries/Text/TextProps.js @@ -30,13 +30,13 @@ export type PressRetentionOffset = $ReadOnly<{| |}>; /** - * @see https://facebook.github.io/react-native/docs/text.html#reference + * @see https://reactnative.dev/docs/text.html#reference */ export type TextProps = $ReadOnly<{| /** * Indicates whether the view is an accessibility element. * - * See https://facebook.github.io/react-native/docs/text.html#accessible + * See https://reactnative.dev/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://facebook.github.io/react-native/docs/text.html#adjustsfontsizetofit + * See https://reactnative.dev/docs/text.html#adjustsfontsizetofit */ adjustsFontSizeToFit?: ?boolean, /** * Whether fonts should scale to respect Text Size accessibility settings. * - * See https://facebook.github.io/react-native/docs/text.html#allowfontscaling + * See https://reactnative.dev/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://facebook.github.io/react-native/docs/text.html#ellipsizemode + * See https://reactnative.dev/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://facebook.github.io/react-native/docs/text.html#nativeid + * See https://reactnative.dev/docs/text.html#nativeid */ nativeID?: ?string, /** * Used to truncate the text with an ellipsis. * - * See https://facebook.github.io/react-native/docs/text.html#numberoflines + * See https://reactnative.dev/docs/text.html#numberoflines */ numberOfLines?: ?number, /** * Invoked on mount and layout changes. * - * See https://facebook.github.io/react-native/docs/text.html#onlayout + * See https://reactnative.dev/docs/text.html#onlayout */ onLayout?: ?(event: LayoutEvent) => mixed, /** * This function is called on long press. * - * See https://facebook.github.io/react-native/docs/text.html#onlongpress + * See https://reactnative.dev/docs/text.html#onlongpress */ onLongPress?: ?(event: PressEvent) => mixed, /** * This function is called on press. * - * See https://facebook.github.io/react-native/docs/text.html#onpress + * See https://reactnative.dev/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://facebook.github.io/react-native/docs/text.html#pressretentionoffset + * See https://reactnative.dev/docs/text.html#pressretentionoffset */ pressRetentionOffset?: ?PressRetentionOffset, /** * Lets the user select text. * - * See https://facebook.github.io/react-native/docs/text.html#selectable + * See https://reactnative.dev/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://facebook.github.io/react-native/docs/text.html#testid + * See https://reactnative.dev/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://facebook.github.io/react-native/docs/text.html#disabled + * See https://reactnative.dev/docs/text.html#disabled */ disabled?: ?boolean, /** * The highlight color of the text. * - * See https://facebook.github.io/react-native/docs/text.html#selectioncolor + * See https://reactnative.dev/docs/text.html#selectioncolor */ selectionColor?: ?string, @@ -165,7 +165,7 @@ export type TextProps = $ReadOnly<{| /** * Set text break strategy on Android. * - * See https://facebook.github.io/react-native/docs/text.html#textbreakstrategy + * See https://reactnative.dev/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://facebook.github.io/react-native/docs/text.html#minimumfontscale + * See https://reactnative.dev/docs/text.html#minimumfontscale */ minimumFontScale?: ?number, /** * When `true`, no visual change is made when text is pressed down. * - * See https://facebook.github.io/react-native/docs/text.html#supperhighlighting + * See https://reactnative.dev/docs/text.html#supperhighlighting */ suppressHighlighting?: ?boolean, |}>; diff --git a/Libraries/TurboModule/RCTExport.js b/Libraries/TurboModule/RCTExport.js index a0fc78fc96c746..f90568d0e5bfc0 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 us TurboModule. + * NOTE: This export is deprecated. Please use TurboModule. */ // eslint-disable-next-line no-unused-vars @@ -33,5 +33,4 @@ 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 116cf566e51b1d..69fb3e4a3de4f4 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:value]; + return [RCTConvert NSString:RCTNilIfNull(value)]; } folly::Optional RCTBridgingToOptionalDouble(id value) diff --git a/Libraries/TypeSafety/RCTTypeSafety.podspec b/Libraries/TypeSafety/RCTTypeSafety.podspec index ecd296099fdadc..5cd02a9f8119ca 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 = '2018.10.22.00' +folly_version = '2020.01.13.00' Pod::Spec.new do |s| s.name = "RCTTypeSafety" s.version = version s.summary = "-" # TODO - s.homepage = "http://facebook.github.io/react-native/" + s.homepage = "https://reactnative.dev/" s.license = package["license"] s.author = "Facebook, Inc. and its affiliates" - s.platforms = { :ios => "9.0", :tvos => "9.2", :osx => "10.13" } # TODO(macOS ISS#2323203) + s.platforms = { :ios => "10.0", :tvos => "10.0", :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 3cc28bc0ff6195..b3e5822c401bb3 100644 --- a/Libraries/Utilities/Dimensions.js +++ b/Libraries/Utilities/Dimensions.js @@ -134,8 +134,6 @@ 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 a5c3ebfd1fc14d..80e60b0da7c21a 100644 --- a/Libraries/Utilities/HMRClient.js +++ b/Libraries/Utilities/HMRClient.js @@ -10,10 +10,11 @@ 'use strict'; -const Platform = require('./Platform'); +const DevSettings = require('./DevSettings'); 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'; @@ -30,6 +31,7 @@ type LogLevel = | 'trace' | 'info' | 'warn' + | 'error' | 'log' | 'group' | 'groupCollapsed' @@ -113,36 +115,23 @@ const HMRClient: HMRClientNativeInterface = { return; } try { - let message; - if (global.Symbol) { - message = JSON.stringify({ + hmrClient.send( + JSON.stringify({ type: 'log', level, data: data.map(item => typeof item === 'string' ? item - : require('pretty-format')(item, { + : prettyFormat(item, { escapeString: true, highlight: true, maxDepth: 3, min: true, - plugins: [require('pretty-format').plugins.ReactElement], + plugins: [prettyFormat.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. @@ -159,8 +148,8 @@ const HMRClient: HMRClientNativeInterface = { isEnabled: boolean, ) { invariant(platform, 'Missing required parameter `platform`'); - invariant(bundleEntry, 'Missing required paramenter `bundleEntry`'); - invariant(host, 'Missing required paramenter `host`'); + invariant(bundleEntry, 'Missing required parameter `bundleEntry`'); + invariant(host, 'Missing required parameter `host`'); invariant(!hmrClient, 'Cannot initialize hmrClient twice'); // Moving to top gives errors due to NativeModules not being initialized @@ -277,6 +266,11 @@ 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 782bedfbbb69c0..e8f7d133f5caf3 100644 --- a/Libraries/Utilities/LoadingView.ios.js +++ b/Libraries/Utilities/LoadingView.ios.js @@ -16,13 +16,21 @@ 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. - processColor('#ffffff'), + typeof white === 'number' ? white : null, type && type === 'load' - ? processColor('#275714') - : processColor('#2584e8'), + ? typeof green === 'number' + ? green + : null + : typeof blue === 'number' + ? blue + : null, ); } }, diff --git a/Libraries/Utilities/MatrixMath.js b/Libraries/Utilities/MatrixMath.js index 85d2bb7c1e5b94..2a943a8961ac03 100755 --- a/Libraries/Utilities/MatrixMath.js +++ b/Libraries/Utilities/MatrixMath.js @@ -8,8 +8,6 @@ * @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 e672771778b8a1..8938fb6df5ccbf 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, - color: Object, - backgroundColor: Object, + withColor: ?number, + withBackgroundColor: ?number, ) => void; +hide: () => void; } diff --git a/Libraries/Utilities/NativeJSDevSupport.js b/Libraries/Utilities/NativeJSDevSupport.js index 3128d3d83bd214..0c140f0f9621f3 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: Object) => void; + +onSuccess: (data: string) => void; +onFailure: (errorCode: number, error: string) => void; } diff --git a/Libraries/Utilities/NativePlatformConstantsAndroid.js b/Libraries/Utilities/NativePlatformConstantsAndroid.js index dcf276ae2ac3f4..39aa25d8c49055 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 99521348a578ab..06813b3a6d4967 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. * - * 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 + * This reflects the user preference set in: + * - Settings > Display > Font size on Android, + * - Settings > Display & Brightness > Text Size on iOS. */ 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 13b0586701eac5..3785bc8790a5b0 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 b6a368907b0cdf..def04d6c3b2d73 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 YellowBox + // Report native warnings to LogBox if (warningHandler && level === 'warn') { warningHandler(...args); } diff --git a/Libraries/Utilities/ReactNativeTestTools.js b/Libraries/Utilities/ReactNativeTestTools.js index fbe4e094ca4aa4..cd018a6fc5e3cc 100644 --- a/Libraries/Utilities/ReactNativeTestTools.js +++ b/Libraries/Utilities/ReactNativeTestTools.js @@ -16,15 +16,30 @@ 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(); -const {Switch, Text, TextInput, VirtualizedList} = require('react-native'); +import type {ReactTestRenderer as ReactTestRendererType} from 'react-test-renderer'; -import type { - ReactTestInstance, - ReactTestRendererNode, - Predicate, -} from 'react-test-renderer'; +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'); function byClickable(): Predicate { return withMessage( @@ -36,10 +51,18 @@ 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', ); @@ -54,6 +77,9 @@ 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()}`, ); @@ -67,7 +93,7 @@ function enter(instance: ReactTestInstance, text: string) { // Returns null if there is no error, otherwise returns an error message string. function maximumDepthError( - tree: {toJSON: () => ReactTestRendererNode, ...}, + tree: ReactTestRendererType, maxDepthLimit: number, ): ?string { const maxDepth = maximumDepthOfJSON(tree.toJSON()); @@ -139,7 +165,7 @@ function expectRendersMatchingSnapshot( } // Takes a node from toJSON() -function maximumDepthOfJSON(node: ReactTestRendererNode): number { +function maximumDepthOfJSON(node: ?ReactTestRendererJSON): number { if (node == null) { return 0; } else if (typeof node === 'string' || node.children == null) { @@ -158,7 +184,7 @@ function renderAndEnforceStrictMode(element: React.Node): any { return renderWithStrictMode(element); } -function renderWithStrictMode(element: React.Node): any { +function renderWithStrictMode(element: React.Node): ReactTestRendererType { const WorkAroundBugWithStrictModeInTestRenderer = prps => prps.children; const StrictMode = (React: $FlowFixMe).StrictMode; return ReactTestRenderer.create( @@ -177,6 +203,16 @@ 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 ff3bbe07c62f68..23b0c7dcae39ea 100644 --- a/Libraries/Utilities/SceneTracker.js +++ b/Libraries/Utilities/SceneTracker.js @@ -10,7 +10,7 @@ 'use strict'; -type Scene = {name: string, ...}; +export 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 c259caf20a7fd6..9ab85e566cbda3 100644 --- a/Libraries/Utilities/__tests__/stringifySafe-test.js +++ b/Libraries/Utilities/__tests__/stringifySafe-test.js @@ -5,14 +5,15 @@ * LICENSE file in the root directory of this source tree. * * @format + * @flow strict-local * @emails oncall+react_native */ 'use strict'; -describe('stringifySafe', () => { - const stringifySafe = require('../stringifySafe'); +import stringifySafe, {createStringifySafeWithLimits} from '../stringifySafe'; +describe('stringifySafe', () => { it('stringifySafe stringifies undefined values', () => { expect(stringifySafe(undefined)).toEqual('undefined'); }); @@ -41,9 +42,8 @@ describe('stringifySafe', () => { }); it('stringifySafe stringifies circular objects without toString', () => { - const arg = {}; - arg.arg = arg; - arg.toString = undefined; + const arg = {x: {}, toString: undefined}; + arg.x = arg; const result = stringifySafe(arg); expect(result).toEqual('["object" failed to stringify]'); }); @@ -53,4 +53,38 @@ 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 fdd5ca9e3cfc27..2bfdb34258169e 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): void, + stopTimespan(string, options?: {update?: boolean}): void, clear(): void, clearCompleted(): void, clearExceptTimespans(Array): void, @@ -107,7 +107,7 @@ function createPerformanceLogger(): IPerformanceLogger { } }, - stopTimespan(key: string) { + stopTimespan(key: string, options?: {update?: boolean}) { 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) { + if (timespan.endTime && !options?.update) { if (PRINT_TO_CONSOLE && __DEV__) { infoLog( 'PerformanceLogger: Attempting to end a timespan that has already ended ', @@ -134,8 +134,10 @@ function createPerformanceLogger(): IPerformanceLogger { infoLog('PerformanceLogger.js', 'end: ' + key); } - Systrace.endAsyncEvent(key, _cookies[key]); - delete _cookies[key]; + if (_cookies[key] != null) { + Systrace.endAsyncEvent(key, _cookies[key]); + delete _cookies[key]; + } }, clear() { diff --git a/Libraries/Utilities/deprecatedPropType.js b/Libraries/Utilities/deprecatedPropType.js index a147ec9b9f8fc1..480cf4cbeda6f6 100644 --- a/Libraries/Utilities/deprecatedPropType.js +++ b/Libraries/Utilities/deprecatedPropType.js @@ -22,6 +22,7 @@ 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 new file mode 100644 index 00000000000000..26cc35ce3f5b24 --- /dev/null +++ b/Libraries/Utilities/differ/__tests__/matricesDiffer-test.js @@ -0,0 +1,45 @@ +/** + * 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 ade2a5fc3f9246..1726ad361e37d2 100644 --- a/Libraries/Utilities/differ/matricesDiffer.js +++ b/Libraries/Utilities/differ/matricesDiffer.js @@ -30,6 +30,7 @@ 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 98a5cda003ab63..16625a98894d65 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.currentlyFocusedField()); + TextInputState.blurTextInput(TextInputState.currentlyFocusedInput()); } module.exports = dismissKeyboard; diff --git a/Libraries/Utilities/infoLog.js b/Libraries/Utilities/infoLog.js index fd90c86b97038b..6cac4bd149bc67 100644 --- a/Libraries/Utilities/infoLog.js +++ b/Libraries/Utilities/infoLog.js @@ -5,6 +5,7 @@ * LICENSE file in the root directory of this source tree. * * @format + * @flow strict */ 'use strict'; @@ -12,7 +13,7 @@ /** * Intentional info-level logging for clear separation from ad-hoc console debug logging. */ -function infoLog(...args) { +function infoLog(...args: Array): void { return console.log(...args); } diff --git a/Libraries/Utilities/registerGeneratedViewConfig.js b/Libraries/Utilities/registerGeneratedViewConfig.js index 7ce2c2f01f39de..947b3b06642b72 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 d562a911e976ca..effeedcd2994dc 100644 --- a/Libraries/Utilities/stringifySafe.js +++ b/Libraries/Utilities/stringifySafe.js @@ -5,46 +5,117 @@ * LICENSE file in the root directory of this source tree. * * @format - * @flow + * @flow strict-local */ '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. */ -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]'; +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; } - } 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) {} + + 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; } } + stack.unshift(retval); + return retval; } - return ret || '["' + type + '" failed to stringify]'; + + 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]'; + }; } -module.exports = stringifySafe; +const stringifySafe: mixed => string = createStringifySafeWithLimits({ + maxDepth: 10, + maxStringLimit: 100, + maxArrayLimit: 50, + maxObjectKeysLimit: 50, +}); + +export default stringifySafe; diff --git a/Libraries/Utilities/useWindowDimensions.js b/Libraries/Utilities/useWindowDimensions.js index 3de619a5eab877..f298649c943ccc 100644 --- a/Libraries/Utilities/useWindowDimensions.js +++ b/Libraries/Utilities/useWindowDimensions.js @@ -15,19 +15,26 @@ import {type DisplayMetrics} from './NativeDeviceInfo'; import {useEffect, useState} from 'react'; export default function useWindowDimensions(): DisplayMetrics { - const [dims, setDims] = useState(() => Dimensions.get('window')); + const [dimensions, setDimensions] = useState(() => Dimensions.get('window')); useEffect(() => { function handleChange({window}) { - setDims(window); + if ( + dimensions.width !== window.width || + dimensions.height !== window.height || + dimensions.scale !== window.scale || + dimensions.fontScale !== window.fontScale + ) { + setDimensions(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. - setDims(Dimensions.get('window')); + handleChange({window: Dimensions.get('window')}); return () => { Dimensions.removeEventListener('change', handleChange); }; - }, []); - return dims; + }, [dimensions]); + return dimensions; } diff --git a/Libraries/Vibration/RCTVibration.mm b/Libraries/Vibration/RCTVibration.mm index f78599df385774..2bbf168acd0d9e 100644 --- a/Libraries/Vibration/RCTVibration.mm +++ b/Libraries/Vibration/RCTVibration.mm @@ -30,10 +30,12 @@ - (void)vibrate [self vibrate]; } -- (std::shared_ptr)getTurboModuleWithJsInvoker: - (std::shared_ptr)jsInvoker +- (std::shared_ptr) + getTurboModuleWithJsInvoker:(std::shared_ptr)jsInvoker + nativeInvoker:(std::shared_ptr)nativeInvoker + perfLogger:(id)perfLogger { - return std::make_shared(self, jsInvoker); + return std::make_shared(self, jsInvoker, nativeInvoker, perfLogger); } RCT_EXPORT_METHOD(vibrateByPattern:(NSArray *)pattern diff --git a/Libraries/Vibration/React-RCTVibration.podspec b/Libraries/Vibration/React-RCTVibration.podspec index 92cc50e2770445..4b4bb0512eae0e 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 = '2018.10.22.00' +folly_version = '2020.01.13.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 = "http://facebook.github.io/react-native/" - s.documentation_url = "https://facebook.github.io/react-native/docs/vibration" + s.homepage = "https://reactnative.dev/" + s.documentation_url = "https://reactnative.dev/docs/vibration" s.license = package["license"] s.author = "Facebook, Inc. and its affiliates" - s.platforms = { :ios => "9.0", :tvos => "9.2", :osx => "10.13" } # TODO(macOS GH#214) + 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.source = source s.source_files = "*.{m,mm}" @@ -43,5 +43,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/RCTVibrationHeaders", version end diff --git a/Libraries/Vibration/Vibration.js b/Libraries/Vibration/Vibration.js index 6165258ddfffa6..4a2d8444ea702b 100644 --- a/Libraries/Vibration/Vibration.js +++ b/Libraries/Vibration/Vibration.js @@ -17,7 +17,7 @@ const Platform = require('../Utilities/Platform'); /** * Vibration API * - * See https://facebook.github.io/react-native/docs/vibration.html + * See https://reactnative.dev/docs/vibration.html */ let _vibrating: boolean = false; @@ -68,7 +68,7 @@ const Vibration = { /** * Trigger a vibration with specified `pattern`. * - * See https://facebook.github.io/react-native/docs/vibration.html#vibrate + * See https://reactnative.dev/docs/vibration.html#vibrate */ vibrate: function( pattern: number | Array = _default_vibration_length, @@ -98,7 +98,7 @@ const Vibration = { /** * Stop vibration * - * See https://facebook.github.io/react-native/docs/vibration.html#cancel + * See https://reactnative.dev/docs/vibration.html#cancel */ cancel: function() { if (Platform.OS === 'ios') { diff --git a/Libraries/WebSocket/RCTReconnectingWebSocket.m b/Libraries/WebSocket/RCTReconnectingWebSocket.m index 6c6401ee91f6d2..cd85e9b81ea654 100644 --- a/Libraries/WebSocket/RCTReconnectingWebSocket.m +++ b/Libraries/WebSocket/RCTReconnectingWebSocket.m @@ -20,6 +20,7 @@ @interface RCTReconnectingWebSocket () @implementation RCTReconnectingWebSocket { NSURL *_url; RCTSRWebSocket *_socket; + BOOL _stopped; } - (instancetype)initWithURL:(NSURL *)url queue:(dispatch_queue_t)queue @@ -44,6 +45,7 @@ - (void)send:(id)data - (void)start { [self stop]; + _stopped = NO; _socket = [[RCTSRWebSocket alloc] initWithURL:_url]; _socket.delegate = self; [_socket setDelegateDispatchQueue:_delegateDispatchQueue]; @@ -52,6 +54,7 @@ - (void)start - (void)stop { + _stopped = YES; _socket.delegate = nil; [_socket closeWithCode:1000 reason:@"Invalidated"]; _socket = nil; @@ -64,11 +67,17 @@ - (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(), ^{ - [self start]; + [weakSelf start]; if (!socket) { - [self reconnect]; + [weakSelf reconnect]; } }); } diff --git a/Libraries/WebSocket/WebSocket.js b/Libraries/WebSocket/WebSocket.js index a1679bd50accd1..0b051c48e4cd9b 100644 --- a/Libraries/WebSocket/WebSocket.js +++ b/Libraries/WebSocket/WebSocket.js @@ -14,7 +14,6 @@ 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 deleted file mode 100644 index e4ad9234123b41..00000000000000 --- a/Libraries/YellowBox/Data/YellowBoxCategory.js +++ /dev/null @@ -1,155 +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'; - -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 deleted file mode 100644 index d430d3fbed792f..00000000000000 --- a/Libraries/YellowBox/Data/YellowBoxRegistry.js +++ /dev/null @@ -1,154 +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'; - -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 deleted file mode 100644 index a33c3501e9bbb8..00000000000000 --- a/Libraries/YellowBox/Data/YellowBoxSymbolication.js +++ /dev/null @@ -1,89 +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'; - -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 deleted file mode 100644 index 7b86eb4a1e94c4..00000000000000 --- a/Libraries/YellowBox/Data/YellowBoxWarning.js +++ /dev/null @@ -1,126 +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'; - -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 deleted file mode 100644 index 5a325dc92e7c79..00000000000000 --- a/Libraries/YellowBox/Data/__tests__/YellowBoxCategory-test.js +++ /dev/null @@ -1,185 +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 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 deleted file mode 100644 index a93f96befd90e4..00000000000000 --- a/Libraries/YellowBox/Data/__tests__/YellowBoxRegistry-test.js +++ /dev/null @@ -1,281 +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 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 deleted file mode 100644 index f125ff380f040a..00000000000000 --- a/Libraries/YellowBox/Data/__tests__/YellowBoxSymbolication-test.js +++ /dev/null @@ -1,52 +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'; - -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 deleted file mode 100644 index 3bbca34dd569e7..00000000000000 --- a/Libraries/YellowBox/Data/__tests__/YellowBoxWarning-test.js +++ /dev/null @@ -1,126 +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'; - -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 deleted file mode 100644 index b72d36d98181c5..00000000000000 --- a/Libraries/YellowBox/Data/__tests__/__snapshots__/YellowBoxCategory-test.js.snap +++ /dev/null @@ -1,95 +0,0 @@ -// 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 deleted file mode 100644 index 67885298f6c56c..00000000000000 --- a/Libraries/YellowBox/UI/YellowBoxButton.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. - * - * @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 deleted file mode 100644 index d70134612d52a6..00000000000000 --- a/Libraries/YellowBox/UI/YellowBoxInspector.js +++ /dev/null @@ -1,213 +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'; - -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 deleted file mode 100644 index 5dda52a848f99a..00000000000000 --- a/Libraries/YellowBox/UI/YellowBoxInspectorFooter.js +++ /dev/null @@ -1,76 +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'; - -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 deleted file mode 100644 index b415481e30c976..00000000000000 --- a/Libraries/YellowBox/UI/YellowBoxInspectorHeader.js +++ /dev/null @@ -1,116 +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'; - -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 deleted file mode 100644 index 2da3efbe784199..00000000000000 --- a/Libraries/YellowBox/UI/YellowBoxInspectorSourceMapStatus.js +++ /dev/null @@ -1,155 +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'; - -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 deleted file mode 100644 index 01c6f03c5aa7df..00000000000000 --- a/Libraries/YellowBox/UI/YellowBoxInspectorStackFrame.js +++ /dev/null @@ -1,93 +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'; - -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 deleted file mode 100644 index c7fa200d1d7052..00000000000000 --- a/Libraries/YellowBox/UI/YellowBoxList.js +++ /dev/null @@ -1,142 +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'; - -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 deleted file mode 100644 index 367a40e9c6835d..00000000000000 --- a/Libraries/YellowBox/UI/YellowBoxListRow.js +++ /dev/null @@ -1,100 +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'; - -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 deleted file mode 100644 index 766ed2600dd94d..00000000000000 --- a/Libraries/YellowBox/UI/YellowBoxPressable.js +++ /dev/null @@ -1,88 +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'; - -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 deleted file mode 100644 index d984514abd7000..00000000000000 --- a/Libraries/YellowBox/UI/YellowBoxStyle.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 - * @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 deleted file mode 100644 index c77aba67d79fd1..00000000000000 --- a/Libraries/YellowBox/YellowBox.js +++ /dev/null @@ -1,234 +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'); - -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 deleted file mode 100644 index b66bdd2d274119..00000000000000 --- a/Libraries/YellowBox/YellowBoxContainer.js +++ /dev/null @@ -1,65 +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'); - -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 new file mode 100644 index 00000000000000..46ba16eeeda5a3 --- /dev/null +++ b/Libraries/YellowBox/YellowBoxDeprecated.js @@ -0,0 +1,75 @@ +/** + * 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 deleted file mode 100644 index e9a89f3fcdbd0c..00000000000000 --- a/Libraries/YellowBox/__tests__/YellowBox-test.js +++ /dev/null @@ -1,270 +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'; - -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 new file mode 100644 index 00000000000000..4adadb6e87f227 --- /dev/null +++ b/Libraries/YellowBox/__tests__/YellowBoxDeprecated-test.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. + * + * @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 deleted file mode 100644 index 974f032a963f2e..00000000000000 --- a/Libraries/YellowBox/__tests__/__snapshots__/YellowBox-test.js.snap +++ /dev/null @@ -1,5 +0,0 @@ -// 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 cb21b05ab4582c..e6c0bb124d5902 100644 --- a/Libraries/__flowtests__/ReactNativeTypes-flowtest.js +++ b/Libraries/__flowtests__/ReactNativeTypes-flowtest.js @@ -11,13 +11,10 @@ 'use strict'; import * as React from 'react'; -import type { - HostComponent, - _InternalReactNativeComponentClass, -} from '../Renderer/shims/ReactNativeTypes'; +import type {HostComponent} from '../Renderer/shims/ReactNativeTypes'; function takesHostComponentInstance( - instance: React$ElementRef> | null, + instance: React.ElementRef> | null, ): void {} const MyHostComponent = (('Host': any): HostComponent); @@ -33,20 +30,3 @@ 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 0c0f140280a4ba..2d60c4fc378371 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.js'; +import type {ErrorUtilsT} from '../../polyfills/error-guard'; /** * The particular require runtime that we are using looks for a global diff --git a/RNTester/Podfile b/RNTester/Podfile index 04f0b4304c0803..7dce319e13851e 100644 --- a/RNTester/Podfile +++ b/RNTester/Podfile @@ -1,6 +1,6 @@ +require_relative '../scripts/react_native_pods' source 'https://cdn.cocoapods.org/' - -require_relative '../scripts/autolink-ios' +platform :ios, '10.0' # 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_framework = ['FlipperKit', 'Flipper', 'Flipper-Folly', + static_frameworks = ['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_framework.include?(pod.name) - def pod.build_type; + if static_frameworks.include?(pod.name) + def pod.build_type Pod::Target::BuildType.static_library end end @@ -74,53 +74,54 @@ def flipper_post_install(installer) end target 'RNTester' do - platform :ios, '9.0' + platform :ios, '10.0' pods() flipper_pods() + # use_flipper! end target 'RNTester-macOS' do - platform :osx, '10.13' + platform :osx, '10.14' pods(:hermes_enabled => true) end target 'RNTesterUnitTests' do - platform :ios, '9.0' + platform :ios, '10.0' pods() - pod 'React-RCTTest', :path => "RCTTest" + pod 'React-RCTTest', :path => "./RCTTest" end target 'RNTester-macOSUnitTests' do - platform :osx, '10.13' + platform :osx, '10.14' pods() - pod 'React-RCTTest', :path => "RCTTest" + pod 'React-RCTTest', :path => "./RCTTest" end target 'RNTesterIntegrationTests' do - platform :ios, '9.0' + platform :ios, '10.0' pods() - pod 'React-RCTTest', :path => "RCTTest" + pod 'React-RCTTest', :path => "./RCTTest" end target 'RNTester-macOSIntegrationTests' do - platform :osx, '10.13' + platform :osx, '10.14' 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, '9.0' + platform :ios, '10.0' pods() end target 'iosSimulatorBuild' do - platform :ios, '9.0' + platform :ios, '10.0' pods() end target 'macOSBuild' do - platform :osx, '10.13' + platform :osx, '10.14' pods() end # ]TODO(macOS ISS#2323203) diff --git a/RNTester/Podfile.lock b/RNTester/Podfile.lock index 5227fa2cdce4c1..fa2df22bf04c5f 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 (= 2018.10.22.00) + - RCT-Folly (= 2020.01.13.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.4.3) + - hermes (0.5.1) - 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 (2018.10.22.00): + - RCT-Folly (2020.01.13.00): - boost-for-react-native - DoubleConversion - glog - - RCT-Folly/Default (= 2018.10.22.00) - - RCT-Folly/Default (2018.10.22.00): + - RCT-Folly/Default (= 2020.01.13.00) + - RCT-Folly/Default (2020.01.13.00): - boost-for-react-native - DoubleConversion - glog - - RCT-Folly/Futures (2018.10.22.00): + - RCT-Folly/Futures (2020.01.13.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 (= 2018.10.22.00) + - RCT-Folly (= 2020.01.13.00) - RCTRequired (= 1000.0.0) - React-Core (= 1000.0.0) - React (1000.0.0): @@ -102,9 +102,10 @@ 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 (= 2018.10.22.00) + - RCT-Folly (= 2020.01.13.00) - React-Core/Default (= 1000.0.0) - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) @@ -112,7 +113,7 @@ PODS: - Yoga - React-Core/ARTHeaders (1000.0.0): - glog - - RCT-Folly (= 2018.10.22.00) + - RCT-Folly (= 2020.01.13.00) - React-Core/Default - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) @@ -120,7 +121,7 @@ PODS: - Yoga - React-Core/CoreModulesHeaders (1000.0.0): - glog - - RCT-Folly (= 2018.10.22.00) + - RCT-Folly (= 2020.01.13.00) - React-Core/Default - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) @@ -128,14 +129,14 @@ PODS: - Yoga - React-Core/Default (1000.0.0): - glog - - RCT-Folly (= 2018.10.22.00) + - RCT-Folly (= 2020.01.13.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 (= 2018.10.22.00) + - RCT-Folly (= 2020.01.13.00) - React-Core/Default (= 1000.0.0) - React-Core/RCTWebSocket (= 1000.0.0) - React-cxxreact (= 1000.0.0) @@ -145,8 +146,8 @@ PODS: - Yoga - React-Core/Hermes (1000.0.0): - glog - - hermes (~> 0.4.1) - - RCT-Folly (= 2018.10.22.00) + - hermes (~> 0.5.0) + - RCT-Folly (= 2020.01.13.00) - RCT-Folly/Futures - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) @@ -154,7 +155,7 @@ PODS: - Yoga - React-Core/RCTActionSheetHeaders (1000.0.0): - glog - - RCT-Folly (= 2018.10.22.00) + - RCT-Folly (= 2020.01.13.00) - React-Core/Default - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) @@ -162,7 +163,7 @@ PODS: - Yoga - React-Core/RCTAnimationHeaders (1000.0.0): - glog - - RCT-Folly (= 2018.10.22.00) + - RCT-Folly (= 2020.01.13.00) - React-Core/Default - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) @@ -170,7 +171,7 @@ PODS: - Yoga - React-Core/RCTBlobHeaders (1000.0.0): - glog - - RCT-Folly (= 2018.10.22.00) + - RCT-Folly (= 2020.01.13.00) - React-Core/Default - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) @@ -178,7 +179,7 @@ PODS: - Yoga - React-Core/RCTImageHeaders (1000.0.0): - glog - - RCT-Folly (= 2018.10.22.00) + - RCT-Folly (= 2020.01.13.00) - React-Core/Default - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) @@ -186,7 +187,7 @@ PODS: - Yoga - React-Core/RCTLinkingHeaders (1000.0.0): - glog - - RCT-Folly (= 2018.10.22.00) + - RCT-Folly (= 2020.01.13.00) - React-Core/Default - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) @@ -194,7 +195,7 @@ PODS: - Yoga - React-Core/RCTNetworkHeaders (1000.0.0): - glog - - RCT-Folly (= 2018.10.22.00) + - RCT-Folly (= 2020.01.13.00) - React-Core/Default - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) @@ -202,7 +203,7 @@ PODS: - Yoga - React-Core/RCTPushNotificationHeaders (1000.0.0): - glog - - RCT-Folly (= 2018.10.22.00) + - RCT-Folly (= 2020.01.13.00) - React-Core/Default - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) @@ -210,7 +211,7 @@ PODS: - Yoga - React-Core/RCTSettingsHeaders (1000.0.0): - glog - - RCT-Folly (= 2018.10.22.00) + - RCT-Folly (= 2020.01.13.00) - React-Core/Default - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) @@ -218,7 +219,7 @@ PODS: - Yoga - React-Core/RCTTextHeaders (1000.0.0): - glog - - RCT-Folly (= 2018.10.22.00) + - RCT-Folly (= 2020.01.13.00) - React-Core/Default - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) @@ -226,7 +227,7 @@ PODS: - Yoga - React-Core/RCTVibrationHeaders (1000.0.0): - glog - - RCT-Folly (= 2018.10.22.00) + - RCT-Folly (= 2020.01.13.00) - React-Core/Default - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) @@ -234,7 +235,7 @@ PODS: - Yoga - React-Core/RCTWebSocket (1000.0.0): - glog - - RCT-Folly (= 2018.10.22.00) + - RCT-Folly (= 2020.01.13.00) - React-Core/Default (= 1000.0.0) - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) @@ -242,32 +243,34 @@ PODS: - Yoga - React-CoreModules (1000.0.0): - FBReactNativeSpec (= 1000.0.0) - - RCT-Folly (= 2018.10.22.00) + - RCT-Folly (= 2020.01.13.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 (= 2018.10.22.00) + - RCT-Folly (= 2020.01.13.00) + - React-callinvoker (= 1000.0.0) - React-jsinspector (= 1000.0.0) - React-jsi (1000.0.0): - boost-for-react-native (= 1.63.0) - DoubleConversion - glog - - RCT-Folly (= 2018.10.22.00) + - RCT-Folly (= 2020.01.13.00) - React-jsi/Default (= 1000.0.0) - React-jsi/Default (1000.0.0): - boost-for-react-native (= 1.63.0) - DoubleConversion - glog - - RCT-Folly (= 2018.10.22.00) + - RCT-Folly (= 2020.01.13.00) - React-jsiexecutor (1000.0.0): - DoubleConversion - glog - - RCT-Folly (= 2018.10.22.00) + - RCT-Folly (= 2020.01.13.00) - React-cxxreact (= 1000.0.0) - React-jsi (= 1000.0.0) - React-jsinspector (1000.0.0) @@ -275,13 +278,14 @@ PODS: - React-Core/RCTActionSheetHeaders (= 1000.0.0) - React-RCTAnimation (1000.0.0): - FBReactNativeSpec (= 1000.0.0) - - RCT-Folly (= 2018.10.22.00) + - RCT-Folly (= 2020.01.13.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 (= 2018.10.22.00) + - RCT-Folly (= 2020.01.13.00) - React-Core/RCTBlobHeaders (= 1000.0.0) - React-Core/RCTWebSocket (= 1000.0.0) - React-jsi (= 1000.0.0) @@ -289,63 +293,67 @@ PODS: - ReactCommon/turbomodule/core (= 1000.0.0) - React-RCTImage (1000.0.0): - FBReactNativeSpec (= 1000.0.0) - - RCT-Folly (= 2018.10.22.00) + - RCT-Folly (= 2020.01.13.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 (= 2018.10.22.00) + - RCT-Folly (= 2020.01.13.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 (= 2018.10.22.00) + - RCT-Folly (= 2020.01.13.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 (= 2018.10.22.00) + - RCT-Folly (= 2020.01.13.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 (= 2018.10.22.00) + - RCT-Folly (= 2020.01.13.00) + - React-callinvoker (= 1000.0.0) - 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 (= 2018.10.22.00) + - RCT-Folly (= 2020.01.13.00) + - React-callinvoker (= 1000.0.0) - 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): @@ -369,6 +377,7 @@ 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 `../`) @@ -386,16 +395,15 @@ 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: - trunk: + https://cdn.cocoapods.org/: - CocoaAsyncSocket - CocoaLibEvent - Flipper @@ -433,6 +441,8 @@ EXTERNAL SOURCES: :path: "../" React-ART: :path: "../Libraries/ART" + React-callinvoker: + :path: "../ReactCommon/callinvoker" React-Core: :path: "../" React-CoreModules: @@ -462,7 +472,7 @@ EXTERNAL SOURCES: React-RCTSettings: :path: "../Libraries/Settings" React-RCTTest: - :path: RCTTest + :path: "./RCTTest" React-RCTText: :path: "../Libraries/Text" React-RCTVibration: @@ -473,12 +483,12 @@ EXTERNAL SOURCES: :path: "../ReactCommon/yoga" SPEC CHECKSUMS: - boost-for-react-native: dabda8622e76020607c2ae1e65cc0cda8b61479d + boost-for-react-native: a110407d9db2642fd2e1bcd7c5a51c81f2521dc9 CocoaAsyncSocket: eafaa68a7e0ec99ead0a7b35015e0bf25d2c8987 CocoaLibEvent: 2fab71b8bd46dd33ddb959f7928ec5909f838e3f - DoubleConversion: 681b789128e5512811c81706e9b361209f40d21e - FBLazyVector: 400431a0922224a5497bc50a6be9b1bdef19c23b - FBReactNativeSpec: afd0b576c189e459fb30a609a3f9d830dcee69e1 + DoubleConversion: a1bc12a74baa397a2609e0f10e19b8062d864053 + FBLazyVector: 013c754530acf200c794982a91221cae2d73186a + FBReactNativeSpec: 205d67e3c1809fe430adc7be677d28a32e4000ac Flipper: 10b225e352595f521be0e5badddd90e241336e89 Flipper-DoubleConversion: 38631e41ef4f9b12861c67d17cb5518d06badc41 Flipper-Folly: c12092ea368353b58e992843a990a3225d4533c3 @@ -486,36 +496,37 @@ SPEC CHECKSUMS: Flipper-PeerTalk: 116d8f857dc6ef55c7a5a75ea3ceaafe878aadc9 Flipper-RSocket: 64e7431a55835eb953b0bf984ef3b90ae9fdddd7 FlipperKit: 88b7f0d0cf907ddc2137b85eeb7f3d4d8d9395c8 - glog: d86cb3634e15ec6d8cd9a1c7c1b9d6fa295beb37 - hermes: e6c81c75290bb87d1d62d594c269fba09b84e216 - libevent: ee9265726a1fc599dea382964fa304378affaa5f + glog: b3f6d74f3e2d33396addc0ee724d2b2b79fc3e00 + hermes: 12d049af0d8e8379c5b3b54ffb1919d670045bdc + libevent: c2d56c8554ac18101d9c5f4c66ef762798209682 OpenSSL-Universal: 8b48cc0d10c1b2923617dfe5c178aa9ed2689355 - 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 + 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 YogaKit: f782866e155069a2cca2517aafea43200b01fd5a -PODFILE CHECKSUM: 8a50297c26ad9d948d1614b33e20d755094cb377 +PODFILE CHECKSUM: f92cb3c61bb71bceed9b9afe3944fbd8451be8b9 -COCOAPODS: 1.9.3 +COCOAPODS: 1.8.4 diff --git a/RNTester/RCTTest/RCTTestModule.m b/RNTester/RCTTest/RCTTestModule.m deleted file mode 100644 index 7f894b636513a4..00000000000000 --- a/RNTester/RCTTest/RCTTestModule.m +++ /dev/null @@ -1,89 +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 "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 new file mode 100644 index 00000000000000..d5aa9ba1dc1f6e --- /dev/null +++ b/RNTester/RCTTest/RCTTestModule.mm @@ -0,0 +1,161 @@ +/* + * 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 new file mode 100644 index 00000000000000..1572f3a603a1a4 --- /dev/null +++ b/RNTester/RCTTest/RCTTestPlugins.h @@ -0,0 +1,40 @@ +/** + * 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 new file mode 100644 index 00000000000000..a057177b619d66 --- /dev/null +++ b/RNTester/RCTTest/RCTTestPlugins.mm @@ -0,0 +1,32 @@ +/** + * 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 f69065f8368280..fa90f9eed2ebc2 100644 --- a/RNTester/RCTTest/React-RCTTest.podspec +++ b/RNTester/RCTTest/React-RCTTest.podspec @@ -16,20 +16,32 @@ 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 = "http://facebook.github.io/react-native/" + s.homepage = "https://reactnative.dev/" s.license = package["license"] s.author = "Facebook, Inc. and its affiliates" - s.platforms = { :ios => "9.0", :tvos => "9.2", :osx => "10.13" } # TODO(macOS GH#214) + 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.source = source - s.source_files = "**/*.{h,m}" + s.source_files = "**/*.{h,m,mm}" 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 a85e0845709857..4efa9b297ab165 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 - npm install + yarn 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://facebook.github.io/react-native/docs/running-on-device.html) for additional instructions on using a physical device. +See [Running on Device](https://reactnative.dev/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 ec2081a88475d8..54c1b1945712c9 100644 --- a/RNTester/RNTester-macOS/AppDelegate.mm +++ b/RNTester/RNTester-macOS/AppDelegate.mm @@ -18,6 +18,8 @@ #import #import "../NativeModuleExample/ScreenshotMacOS.h" +#import + NSString *kBundleNameJS = @"RNTesterApp"; @interface AppDelegate () @@ -91,7 +93,8 @@ - (NSURL *)sourceURLForBridge:(__unused RCTBridge *)bridge if (strongSelf) { strongSelf->_turboModuleManagerDelegate = [ScreenshotManagerTurboModuleManagerDelegate new]; strongSelf->_turboModuleManager = [[RCTTurboModuleManager alloc] initWithBridge:bridge - delegate:strongSelf->_turboModuleManagerDelegate]; + delegate:strongSelf->_turboModuleManagerDelegate + jsInvoker:bridge.jsCallInvoker]; [strongSelf->_turboModuleManager installJSBindingWithRuntime:&runtime]; } }); diff --git a/RNTester/RNTester/AppDelegate.mm b/RNTester/RNTester/AppDelegate.mm index 8d1ac2aa4c4f30..ac15022b495250 100644 --- a/RNTester/RNTester/AppDelegate.mm +++ b/RNTester/RNTester/AppDelegate.mm @@ -8,6 +8,7 @@ #import "AppDelegate.h" #import +#import #import #import #import @@ -151,17 +152,21 @@ - (void)loadSourceForBridge:(RCTBridge *)bridge - (std::unique_ptr)jsExecutorFactoryForBridge:(RCTBridge *)bridge { - _turboModuleManager = [[RCTTurboModuleManager alloc] initWithBridge:bridge delegate:self]; + _turboModuleManager = [[RCTTurboModuleManager alloc] initWithBridge:bridge + delegate:self + jsInvoker:bridge.jsCallInvoker]; __weak __typeof(self) weakSelf = self; - return std::make_unique([weakSelf, bridge](facebook::jsi::Runtime &runtime) { - if (!bridge) { - return; - } - __typeof(self) strongSelf = weakSelf; - if (strongSelf) { - [strongSelf->_turboModuleManager installJSBindingWithRuntime:&runtime]; - } - }); + 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]; + } + }) + ); } #pragma mark RCTTurboModuleManagerDelegate @@ -180,8 +185,10 @@ - (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); + return facebook::react::RNTesterTurboModuleProvider(name, instance, jsInvoker, nativeInvoker, perfLogger); } - (id)getModuleInstanceFromClass:(Class)moduleClass diff --git a/RNTester/RNTester/Base.lproj/LaunchScreen.xib b/RNTester/RNTester/Base.lproj/LaunchScreen.xib deleted file mode 100644 index f7722dde9ba78c..00000000000000 --- a/RNTester/RNTester/Base.lproj/LaunchScreen.xib +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/RNTester/RNTester/LaunchScreen.storyboard b/RNTester/RNTester/LaunchScreen.storyboard new file mode 100644 index 00000000000000..373f89ee18c77e --- /dev/null +++ b/RNTester/RNTester/LaunchScreen.storyboard @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/RNTester/RNTester/RNTesterTurboModuleProvider.h b/RNTester/RNTester/RNTesterTurboModuleProvider.h index 1d684d3ee4c725..4c61336a6df343 100644 --- a/RNTester/RNTester/RNTesterTurboModuleProvider.h +++ b/RNTester/RNTester/RNTesterTurboModuleProvider.h @@ -25,7 +25,9 @@ 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 jsInvoker, + std::shared_ptr nativeInvoker, + id perfLogger); } // namespace react } // namespace facebook diff --git a/RNTester/RNTester/RNTesterTurboModuleProvider.mm b/RNTester/RNTester/RNTesterTurboModuleProvider.mm index 70dca8cf2505aa..9c2707654fd76a 100644 --- a/RNTester/RNTester/RNTesterTurboModuleProvider.mm +++ b/RNTester/RNTester/RNTesterTurboModuleProvider.mm @@ -30,9 +30,11 @@ Class RNTesterTurboModuleClassProvider(const char *name) { std::shared_ptr RNTesterTurboModuleProvider(const std::string &name, id instance, - std::shared_ptr jsInvoker) { + std::shared_ptr jsInvoker, + std::shared_ptr nativeInvoker, + id perfLogger) { if (name == "SampleTurboModule") { - return std::make_shared(instance, jsInvoker); + return std::make_shared(instance, jsInvoker, nativeInvoker, perfLogger); } 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 dc942bca73cc23..271e80d3f6b487 100644 Binary files a/RNTester/RNTesterIntegrationTests/ReferenceImages/RNTester-js-RNTesterApp.ios/testLayoutExample_1-iOS13@2x.png and b/RNTester/RNTesterIntegrationTests/ReferenceImages/RNTester-js-RNTesterApp.ios/testLayoutExample_1-iOS13@2x.png differ diff --git a/RNTester/RNTesterPods.xcodeproj/project.pbxproj b/RNTester/RNTesterPods.xcodeproj/project.pbxproj index 43690a406335ed..ba6e0afe25a133 100644 --- a/RNTester/RNTesterPods.xcodeproj/project.pbxproj +++ b/RNTester/RNTesterPods.xcodeproj/project.pbxproj @@ -8,7 +8,6 @@ /* 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 */; }; @@ -48,6 +47,7 @@ 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,8 +64,11 @@ 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 */; }; @@ -182,9 +185,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; }; @@ -198,6 +201,7 @@ 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; }; @@ -216,9 +220,11 @@ 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 = ""; }; @@ -277,6 +283,7 @@ 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; }; @@ -422,6 +429,7 @@ 383838C1244BC3D9005FAC75 /* JavaScriptCore.framework in Frameworks */, 38A9383C244532470025DABB /* libOCMock.a in Frameworks */, E59A0FBD0170A092274A6207 /* libPods-RNTesterUnitTests.a in Frameworks */, + 85C7978AB28C149170A56955 /* libPods-RNTesterUnitTests.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -432,6 +440,7 @@ E7DB218C22B41FCD005AC45F /* XCTest.framework in Frameworks */, E7DB216722B2F69F005AC45F /* JavaScriptCore.framework in Frameworks */, 8BBFF9F061783A02D50DD2EC /* libPods-RNTesterIntegrationTests.a in Frameworks */, + 6766440649168A1FAD1DB4A4 /* libPods-RNTesterIntegrationTests.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -458,7 +467,7 @@ 5CB07C99226467E60039471C /* RNTesterTurboModuleProvider.mm */, 13B07FB71A68108700A75B9A /* main.m */, 2DDEF00F1F84BF7B00DBDF73 /* Images.xcassets */, - 13B07FB11A68108700A75B9A /* LaunchScreen.xib */, + 8145AE05241172D900A3F8DA /* LaunchScreen.storyboard */, 272E6B3A1BEA846C001FCF37 /* NativeExampleViews */, 1323F18D1C04ABAC0091BED0 /* Supporting Files */, ); @@ -512,6 +521,9 @@ 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 = ""; @@ -673,6 +685,7 @@ E7DB20CC22B2BAA5005AC45F /* RCTComponentPropsTests.m */, E7DB20CA22B2BAA5005AC45F /* RCTConvert_NSURLTests.m */, E7DB20CE22B2BAA5005AC45F /* RCTConvert_YGValueTests.m */, + 383889D923A7398900D06C3E /* RCTConvert_UIColorTests.m */, E7DB20C822B2BAA5005AC45F /* RCTDevMenuTests.m */, E7DB20C022B2BAA4005AC45F /* RCTEventDispatcherTests.m */, E7DB20AF22B2BAA4005AC45F /* RCTFontTests.m */, @@ -750,12 +763,13 @@ isa = PBXNativeTarget; buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "RNTester" */; buildPhases = ( - F9CB97B0D9633939D43E75E0 /* [CP] Check Pods Manifest.lock */, + D9BE43355C8C29497EED268E /* [CP] Check Pods Manifest.lock */, 13B07F871A680F5B00A75B9A /* Sources */, 13B07F8C1A680F5B00A75B9A /* Frameworks */, 13B07F8E1A680F5B00A75B9A /* Resources */, 68CD48B71D2BCB2C007E06A9 /* Build JS Bundle */, 5CF0FD27207FC6EC00C13D65 /* Start Metro */, + 8BA2D8960038381F0B753726 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -770,7 +784,7 @@ isa = PBXNativeTarget; buildConfigurationList = 387847D7245631D80035033A /* Build configuration list for PBXNativeTarget "iosDeviceBuild" */; buildPhases = ( - F45233491ACAD25C16E8F1CA /* [CP] Check Pods Manifest.lock */, + 79A2B74F37E4F8AF8B3D0A7A /* [CP] Check Pods Manifest.lock */, 387847CD245631D80035033A /* Sources */, 387847CE245631D80035033A /* Frameworks */, 387847CF245631D80035033A /* CopyFiles */, @@ -788,7 +802,7 @@ isa = PBXNativeTarget; buildConfigurationList = 387847E4245631F50035033A /* Build configuration list for PBXNativeTarget "iosSimulatorBuild" */; buildPhases = ( - 258A8D3EFB14581FF1CA788D /* [CP] Check Pods Manifest.lock */, + DBAEBACAAEA09D5E7591E051 /* [CP] Check Pods Manifest.lock */, 387847DA245631F50035033A /* Sources */, 387847DB245631F50035033A /* Frameworks */, 387847DC245631F50035033A /* CopyFiles */, @@ -806,7 +820,7 @@ isa = PBXNativeTarget; buildConfigurationList = 387847F12456320C0035033A /* Build configuration list for PBXNativeTarget "macOSBuild" */; buildPhases = ( - DFD62DE759BFAB8AABFA4179 /* [CP] Check Pods Manifest.lock */, + 26905525A793EABD06A4E9DD /* [CP] Check Pods Manifest.lock */, 387847E72456320C0035033A /* Headers */, 387847E82456320C0035033A /* Sources */, 387847E92456320C0035033A /* Frameworks */, @@ -824,13 +838,14 @@ isa = PBXNativeTarget; buildConfigurationList = 9F153485233AB2C7006DFE44 /* Build configuration list for PBXNativeTarget "RNTester-macOS" */; buildPhases = ( - 26ED73F8C59C75926FA607C9 /* [CP] Check Pods Manifest.lock */, + 840572194E08440DE712816E /* [CP] Check Pods Manifest.lock */, 9F153457233AB2C4006DFE44 /* Sources */, 9F153458233AB2C4006DFE44 /* Frameworks */, 9F153459233AB2C4006DFE44 /* Resources */, 38C8132424577FB500BFFA62 /* Build JS Bundle */, 51B9D81723C4D5A4002B30E1 /* Start Metro */, - 4733C3A4FBA299F6E1E956BA /* [CP] Embed Pods Frameworks */, + 912CCA057E7BE90E9EC53D33 /* [CP] Embed Pods Frameworks */, + 33B976C36DF90C0A044DC053 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -845,11 +860,12 @@ isa = PBXNativeTarget; buildConfigurationList = 9F153486233AB2C7006DFE44 /* Build configuration list for PBXNativeTarget "RNTester-macOSUnitTests" */; buildPhases = ( - 0DDB94B4378380EBD190814A /* [CP] Check Pods Manifest.lock */, + 8BEE9E647FF71296D5EFD137 /* [CP] Check Pods Manifest.lock */, 9F153469233AB2C7006DFE44 /* Sources */, 9F15346A233AB2C7006DFE44 /* Frameworks */, 9F15346B233AB2C7006DFE44 /* Resources */, 3882C0E12445655100E92FB9 /* Copy Files (1 item) */, + DCF7F2DA774E70B7DE02783C /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -865,10 +881,11 @@ isa = PBXNativeTarget; buildConfigurationList = 9F153487233AB2C7006DFE44 /* Build configuration list for PBXNativeTarget "RNTester-macOSIntegrationTests" */; buildPhases = ( - 599A88804E613F1AA7525CB9 /* [CP] Check Pods Manifest.lock */, + B8BFFD6300CD470A1DF043B6 /* [CP] Check Pods Manifest.lock */, 9F153474233AB2C7006DFE44 /* Sources */, 9F153475233AB2C7006DFE44 /* Frameworks */, 9F153476233AB2C7006DFE44 /* Resources */, + 4BDC0C5271A785332898B818 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -884,10 +901,11 @@ isa = PBXNativeTarget; buildConfigurationList = E7DB20A622B2BA84005AC45F /* Build configuration list for PBXNativeTarget "RNTesterUnitTests" */; buildPhases = ( - 64C8C8D2305EEDFDE304A0E6 /* [CP] Check Pods Manifest.lock */, + 1FD7CC5A44DCEE15C8D13E0A /* [CP] Check Pods Manifest.lock */, E7DB209B22B2BA84005AC45F /* Sources */, E7DB209C22B2BA84005AC45F /* Frameworks */, E7DB209D22B2BA84005AC45F /* Resources */, + D3E745B9771EC6F02AC52196 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -902,10 +920,11 @@ isa = PBXNativeTarget; buildConfigurationList = E7DB215A22B2F332005AC45F /* Build configuration list for PBXNativeTarget "RNTesterIntegrationTests" */; buildPhases = ( - 56D84768A7BBB2750D674CF3 /* [CP] Check Pods Manifest.lock */, + A7D95A9E84DEB30F42E4B186 /* [CP] Check Pods Manifest.lock */, E7DB214F22B2F332005AC45F /* Sources */, E7DB215022B2F332005AC45F /* Frameworks */, E7DB215122B2F332005AC45F /* Resources */, + 186E435C9BE5B7CC0656A19C /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -923,7 +942,7 @@ 83CBB9F71A601CBA00E9B192 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0940; + LastUpgradeCheck = 1130; ORGANIZATIONNAME = Facebook; TargetAttributes = { 387847D0245631D80035033A = { @@ -960,10 +979,9 @@ }; buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "RNTesterPods" */; compatibilityVersion = "Xcode 9.3"; - developmentRegion = English; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( - English, en, Base, ); @@ -991,8 +1009,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; }; @@ -1039,29 +1057,24 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 0DDB94B4378380EBD190814A /* [CP] Check Pods Manifest.lock */ = { + 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", ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; + name = "[CP] Copy Pods Resources"; outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-RNTester-macOSUnitTests-checkManifestLockResult.txt", + "${PODS_ROOT}/Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests-resources-${CONFIGURATION}-output-files.xcfilelist", ); 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"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTesterIntegrationTests/Pods-RNTesterIntegrationTests-resources.sh\"\n"; showEnvVarsInLog = 0; }; - 258A8D3EFB14581FF1CA788D /* [CP] Check Pods Manifest.lock */ = { + 1FD7CC5A44DCEE15C8D13E0A /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -1076,14 +1089,14 @@ outputFileListPaths = ( ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-iosSimulatorBuild-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; }; - 26ED73F8C59C75926FA607C9 /* [CP] Check Pods Manifest.lock */ = { + 26905525A793EABD06A4E9DD /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -1098,13 +1111,30 @@ outputFileListPaths = ( ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-RNTester-macOS-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; }; + 33B976C36DF90C0A044DC053 /* [CP] Copy Pods Resources */ = { + 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"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-RNTester-macOS/Pods-RNTester-macOS-resources-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTester-macOS/Pods-RNTester-macOS-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; 38C8132424577FB500BFFA62 /* Build JS Bundle */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -1123,21 +1153,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"; }; - 4733C3A4FBA299F6E1E956BA /* [CP] Embed Pods Frameworks */ = { + 4BDC0C5271A785332898B818 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-RNTester-macOS/Pods-RNTester-macOS-frameworks-${CONFIGURATION}-input-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-RNTester-macOSIntegrationTests/Pods-RNTester-macOSIntegrationTests-resources-${CONFIGURATION}-input-files.xcfilelist", ); - name = "[CP] Embed Pods Frameworks"; + name = "[CP] Copy Pods Resources"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-RNTester-macOS/Pods-RNTester-macOS-frameworks-${CONFIGURATION}-output-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-RNTester-macOSIntegrationTests/Pods-RNTester-macOSIntegrationTests-resources-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTester-macOS/Pods-RNTester-macOS-frameworks.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTester-macOSIntegrationTests/Pods-RNTester-macOSIntegrationTests-resources.sh\"\n"; showEnvVarsInLog = 0; }; 51B9D81723C4D5A4002B30E1 /* Start Metro */ = { @@ -1159,7 +1189,36 @@ 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; }; - 56D84768A7BBB2750D674CF3 /* [CP] Check Pods Manifest.lock */ = { + 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 */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -1174,14 +1233,14 @@ outputFileListPaths = ( ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-RNTesterIntegrationTests-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; }; - 599A88804E613F1AA7525CB9 /* [CP] Check Pods Manifest.lock */ = { + 840572194E08440DE712816E /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -1196,29 +1255,31 @@ outputFileListPaths = ( ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-RNTester-macOSIntegrationTests-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-RNTester-macOS-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; }; - 5CF0FD27207FC6EC00C13D65 /* Start Metro */ = { + 8BA2D8960038381F0B753726 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); - inputPaths = ( + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-RNTester/Pods-RNTester-resources-${CONFIGURATION}-input-files.xcfilelist", ); - name = "Start Metro"; - outputPaths = ( + name = "[CP] Copy Pods Resources"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-RNTester/Pods-RNTester-resources-${CONFIGURATION}-output-files.xcfilelist", ); 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"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTester/Pods-RNTester-resources.sh\"\n"; showEnvVarsInLog = 0; }; - 64C8C8D2305EEDFDE304A0E6 /* [CP] Check Pods Manifest.lock */ = { + 8BEE9E647FF71296D5EFD137 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -1233,28 +1294,53 @@ 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; }; - 68CD48B71D2BCB2C007E06A9 /* Build JS Bundle */ = { + 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 */ = { 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 = "export NODE_BINARY=node\nPROJECT_ROOT=$SRCROOT/.. $SRCROOT/../scripts/react-native-xcode.sh RNTester/js/RNTesterApp.ios.js\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; }; - DFD62DE759BFAB8AABFA4179 /* [CP] Check Pods Manifest.lock */ = { + B8BFFD6300CD470A1DF043B6 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -1269,14 +1355,31 @@ outputFileListPaths = ( ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-macOSBuild-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; }; - F45233491ACAD25C16E8F1CA /* [CP] Check Pods Manifest.lock */ = { + 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 */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -1291,31 +1394,52 @@ outputFileListPaths = ( ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-iosDeviceBuild-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; }; - F9CB97B0D9633939D43E75E0 /* [CP] Check Pods Manifest.lock */ = { + DBAEBACAAEA09D5E7591E051 /* [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-RNTester-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; }; + 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 */ @@ -1441,6 +1565,7 @@ 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 */, @@ -1493,15 +1618,6 @@ /* 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 = ( @@ -1521,47 +1637,22 @@ CLANG_CXX_LANGUAGE_STANDARD = "c++14"; CODE_SIGN_ENTITLEMENTS = RNTester/RNTester.entitlements; DEVELOPMENT_TEAM = ""; - HEADER_SEARCH_PATHS = ( + GCC_PREPROCESSOR_DEFINITIONS = ( "$(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\"", + "FB_SONARKIT_ENABLED=1", ); INFOPLIST_FILE = "$(SRCROOT)/RNTester/Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; LD_RUNPATH_SEARCH_PATHS = ( /usr/lib/swift, - "@executable_path/Frameworks", + "$(inherited)", ); 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", @@ -1573,6 +1664,7 @@ "-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"; @@ -1587,41 +1679,11 @@ 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 = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; LD_RUNPATH_SEARCH_PATHS = ( /usr/lib/swift, - "@executable_path/Frameworks", + "$(inherited)", ); LIBRARY_SEARCH_PATHS = ( "$(inherited)", @@ -1639,6 +1701,7 @@ "-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"; @@ -1789,6 +1852,7 @@ 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; @@ -1844,7 +1908,7 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_LABEL = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; OTHER_CPLUSPLUSFLAGS = ( @@ -1870,6 +1934,7 @@ 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; @@ -1918,7 +1983,7 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_LABEL = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; MTL_ENABLE_DEBUG_INFO = NO; OTHER_CPLUSPLUSFLAGS = ( "$(OTHER_CFLAGS)", @@ -2228,6 +2293,7 @@ "$(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"; @@ -2263,6 +2329,7 @@ "$(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"; @@ -2299,6 +2366,7 @@ "$(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"; @@ -2332,6 +2400,7 @@ "$(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 500b06c03557b1..aa5eb07b7a0e40 100644 --- a/RNTester/RNTesterPods.xcodeproj/xcshareddata/xcschemes/RNTester.xcscheme +++ b/RNTester/RNTesterPods.xcodeproj/xcshareddata/xcschemes/RNTester.xcscheme @@ -1,6 +1,6 @@ + + + + + + + + @@ -49,24 +65,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + - - + + + + + + + + @@ -68,17 +84,6 @@ - - - - - - - - = 130000 if (@available(iOS 13.0, *)) { id savedTraitCollection = [UITraitCollection currentTraitCollection]; - [UITraitCollection setCurrentTraitCollection:[UITraitCollection traitCollectionWithUserInterfaceStyle:UIUserInterfaceStyleLight]]; CGFloat rgba[4]; RCTGetRGBAColorComponents([value CGColor], rgba); @@ -69,14 +80,12 @@ - (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 @@ -91,27 +100,15 @@ - (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]]; - - 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]); - + + XCTAssertTrue(CGColorsAreEqual([value CGColor], [[UIColor systemRedColor] CGColor])); + [UITraitCollection setCurrentTraitCollection:[UITraitCollection traitCollectionWithUserInterfaceStyle:UIUserInterfaceStyleDark]]; - - 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]); - + + XCTAssertTrue(CGColorsAreEqual([value CGColor], [[UIColor systemBlueColor] CGColor])); + [UITraitCollection setCurrentTraitCollection:savedTraitCollection]; } #endif @@ -157,12 +154,10 @@ - (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 @@ -191,7 +186,6 @@ - (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 5e17c5056cfe0e..7a791930591e42 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://facebook.github.io/react-native/img/opengraph.png"]]; + NSURLRequest *urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:@"https://reactnative.dev/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://facebook.github.io/react-native/img/opengraph.png"]]; + NSURLRequest *urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:@"https://reactnative.dev/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 d27f7d9804e8f9..0a36475ade519b 100644 --- a/RNTester/android/app/build.gradle +++ b/RNTester/android/app/build.gradle @@ -65,12 +65,13 @@ 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%/hermes", + hermesCommand: "../../../node_modules/hermes-engine/%OS-BIN%/hermesc", enableHermesForVariant: { def v -> v.name.contains("hermes") } ] @@ -103,13 +104,6 @@ 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 @@ -127,10 +121,12 @@ android { defaultConfig { applicationId "com.facebook.react.uiapp" - minSdkVersion 16 + minSdkVersion 18 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 { @@ -156,10 +152,17 @@ 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']) @@ -169,8 +172,8 @@ dependencies { implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0" def hermesPath = '$projectDir/../../../../node_modules/hermes-engine/android/' - debugImplementation files(hermesPath + "hermes-debug.aar") - releaseImplementation files(hermesPath + "hermes-release.aar") + hermesDebugImplementation files(hermesPath + "hermes-debug.aar") + hermesReleaseImplementation files(hermesPath + "hermes-release.aar") debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") { exclude group:'com.facebook.fbjni' @@ -185,8 +188,12 @@ dependencies { } if (useIntlJsc) { - implementation 'org.webkit:android-jsc-intl:+' + jscImplementation 'org.webkit:android-jsc-intl:+' } else { - implementation 'org.webkit:android-jsc:+' + jscImplementation '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 3d9a626c164f38..4ff9751aab7d8b 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.33.1 +FLIPPER_VERSION=0.37.0 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 new file mode 100644 index 00000000000000..f9febfa3b3845f --- /dev/null +++ b/RNTester/android/app/src/androidTest/java/com/facebook/react/uiapp/DetoxTest.java @@ -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. + */ + +// 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 6a7c961991aecf..11c73fcb2d5f4b 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('4:10 AM'); + await expect(timeIndicator).toHaveText('04: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 new file mode 100644 index 00000000000000..db1933ab6262f6 --- /dev/null +++ b/RNTester/e2e/__tests__/TextInput-test.js @@ -0,0 +1,62 @@ +/** + * 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 5c70397a520b79..4e95bbe7c3e8ab 100644 --- a/RNTester/e2e/test-init.js +++ b/RNTester/e2e/test-init.js @@ -3,19 +3,36 @@ * * 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(480000); +jest.setTimeout(120000); jasmine.getEnv().addReporter(adapter); beforeAll(async () => { - await detox.init(config); + 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', + }, + }); }); beforeEach(async function() { diff --git a/RNTester/js/RNTesterApp.android.js b/RNTester/js/RNTesterApp.android.js index fd3655deec2d86..d7371b4ee6a79c 100644 --- a/RNTester/js/RNTesterApp.android.js +++ b/RNTester/js/RNTesterApp.android.js @@ -316,6 +316,8 @@ 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 9526a00f33a3c6..1786d4ddc8133b 100644 --- a/RNTester/js/RNTesterApp.ios.js +++ b/RNTester/js/RNTesterApp.ios.js @@ -27,12 +27,14 @@ 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, - YellowBox, + LogBox, } = require('react-native'); const {TestModule} = NativeModules; // TODO(OSS Candidate ISS#2710739) @@ -46,9 +48,7 @@ import type {ColorSchemeName} from '../../Libraries/Utilities/NativeAppearance'; type Props = {exampleFromAppetizeParams?: ?string, ...}; -YellowBox.ignoreWarnings([ - 'Module RCTImagePickerManager requires main queue setup', -]); +LogBox.ignoreLogs(['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: {semantic: 'separatorColor'}, // TODO(OSS Candidate ISS#2710739) + borderBottomColor: PlatformColor('separatorColor'), // TODO(OSS Candidate ISS#2710739) ...Platform.select({ // [TODO(macOS ISS#2323203) ios: { - backgroundColor: {semantic: 'tertiarySystemBackgroundColor'}, + backgroundColor: PlatformColor('tertiarySystemBackgroundColor'), }, macos: { - backgroundColor: {semantic: 'windowBackgroundColor'}, + backgroundColor: PlatformColor('windowBackgroundColor'), }, }), // ]TODO(macOS ISS#2323203) @@ -249,7 +249,7 @@ const styles = StyleSheet.create({ fontSize: 19, fontWeight: '600', textAlign: 'center', - color: {dynamic: {light: 'black', dark: 'white'}}, // TODO(OSS Candidate ISS#2710739) + color: DynamicColorIOS({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 2bf61daf7b4756..9af3d0b61e3de2 100644 --- a/RNTester/js/components/RNTesterBlock.js +++ b/RNTester/js/components/RNTesterBlock.js @@ -12,7 +12,7 @@ const React = require('react'); -const {StyleSheet, Text, View} = require('react-native'); +const {PlatformColor, 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: {semantic: 'separatorColor'}, - backgroundColor: {semantic: 'windowBackgroundColor'}, + borderColor: PlatformColor('separatorColor'), + backgroundColor: PlatformColor('windowBackgroundColor'), }, ios: { - borderColor: {semantic: 'separatorColor'}, - backgroundColor: {semantic: 'tertiarySystemBackgroundColor'}, + borderColor: PlatformColor('separatorColor'), + backgroundColor: PlatformColor('tertiarySystemBackgroundColor'), }, default: { borderColor: '#d6d7da', @@ -104,12 +104,12 @@ const styles = StyleSheet.create({ borderTopRightRadius: 2.5, ...Platform.select({ macos: { - borderBottomColor: {semantic: 'separatorColor'}, - backgroundColor: {semantic: 'controlBackgroundColor'}, + borderBottomColor: PlatformColor('separatorColor'), + backgroundColor: PlatformColor('controlBackgroundColor'), }, ios: { - borderBottomColor: {semantic: 'separatorColor'}, - backgroundColor: {semantic: 'tertiarySystemBackgroundColor'}, + borderBottomColor: PlatformColor('separatorColor'), + backgroundColor: PlatformColor('tertiarySystemBackgroundColor'), }, default: { borderBottomColor: '#d6d7da', @@ -122,10 +122,10 @@ const styles = StyleSheet.create({ titleText: { ...Platform.select({ macos: { - color: {semantic: 'labelColor'}, + color: PlatformColor('labelColor'), }, ios: { - color: {semantic: 'labelColor'}, + color: PlatformColor('labelColor'), }, default: undefined, }), @@ -136,10 +136,10 @@ const styles = StyleSheet.create({ fontSize: 14, ...Platform.select({ macos: { - color: {semantic: 'secondaryLabelColor'}, + color: PlatformColor('secondaryLabelColor'), }, ios: { - color: {semantic: 'secondaryLabelColor'}, + color: PlatformColor('secondaryLabelColor'), }, default: undefined, }), diff --git a/RNTester/js/components/RNTesterExampleList.js b/RNTester/js/components/RNTesterExampleList.js index ae598b8ca3693d..ee30dcde1359ea 100644 --- a/RNTester/js/components/RNTesterExampleList.js +++ b/RNTester/js/components/RNTesterExampleList.js @@ -16,6 +16,7 @@ const React = require('react'); const { Platform, + PlatformColor, SectionList, StyleSheet, Text, @@ -252,10 +253,10 @@ const styles = StyleSheet.create({ ...Platform.select({ // [TODO(macOS ISS#2323203) macos: { - backgroundColor: {semantic: 'controlBackgroundColor'}, + backgroundColor: PlatformColor('controlBackgroundColor'), }, ios: { - backgroundColor: {semantic: 'systemBackgroundColor'}, + backgroundColor: PlatformColor('systemBackgroundColor'), }, default: { // ]TODO(macOS ISS#2323203) @@ -270,13 +271,13 @@ const styles = StyleSheet.create({ backgroundColor: { semantic: 'unemphasizedSelectedContentBackgroundColor', }, - color: {semantic: 'headerTextColor'}, + color: PlatformColor('headerTextColor'), }, ios: { backgroundColor: { semantic: 'systemGroupedBackgroundColor', }, - color: {semantic: 'secondaryLabelColor'}, + color: PlatformColor('secondaryLabelColor'), }, default: { // ]TODO(macOS ISS#2323203) @@ -292,10 +293,10 @@ const styles = StyleSheet.create({ ...Platform.select({ // [TODO(macOS ISS#2323203) macos: { - backgroundColor: {semantic: 'controlBackgroundColor'}, + backgroundColor: PlatformColor('controlBackgroundColor'), }, ios: { - backgroundColor: {semantic: 'secondarySystemGroupedBackgroundColor'}, + backgroundColor: PlatformColor('secondarySystemGroupedBackgroundColor'), }, default: { // ]TODO(macOS ISS#2323203) @@ -319,10 +320,10 @@ const styles = StyleSheet.create({ ...Platform.select({ // [TODO(macOS ISS#2323203) macos: { - backgroundColor: {semantic: 'separatorColor'}, + backgroundColor: PlatformColor('separatorColor'), }, ios: { - backgroundColor: {semantic: 'separatorColor'}, + backgroundColor: PlatformColor('separatorColor'), }, default: { // ]TODO(macOS ISS#2323203) @@ -336,8 +337,8 @@ const styles = StyleSheet.create({ }, sectionListContentContainer: Platform.select({ // [TODO(macOS ISS#2323203) - macos: {backgroundColor: {semantic: 'separatorColor'}}, - ios: {backgroundColor: {semantic: 'separatorColor'}}, + macos: {backgroundColor: PlatformColor('separatorColor')}, + ios: {backgroundColor: PlatformColor('separatorColor')}, default: {backgroundColor: 'white'}, }), // ]TODO(macOS ISS#2323203) rowTitleText: { @@ -346,10 +347,10 @@ const styles = StyleSheet.create({ ...Platform.select({ // [TODO(macOS ISS#2323203) macos: { - color: {semantic: 'controlTextColor'}, + color: PlatformColor('controlTextColor'), }, ios: { - color: {semantic: 'labelColor'}, + color: PlatformColor('labelColor'), }, default: { // ]TODO(macOS ISS#2323203) diff --git a/RNTester/js/components/RNTesterTheme.js b/RNTester/js/components/RNTesterTheme.js index b78a8344fe29be..7bc14ea3ebd99d 100644 --- a/RNTester/js/components/RNTesterTheme.js +++ b/RNTester/js/components/RNTesterTheme.js @@ -12,28 +12,29 @@ import * as React from 'react'; import {Appearance} from 'react-native'; +import type {ColorValue} from '../../../Libraries/StyleSheet/StyleSheetTypes'; export type RNTesterTheme = { - 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, + 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, ... }; diff --git a/RNTester/js/examples/Alert/AlertMacOSExample.js b/RNTester/js/examples/Alert/AlertMacOSExample.js index a57a84671d3e5d..07fcb334f18d0b 100644 --- a/RNTester/js/examples/Alert/AlertMacOSExample.js +++ b/RNTester/js/examples/Alert/AlertMacOSExample.js @@ -10,11 +10,11 @@ 'use strict'; -var React = require('react'); -var ReactNative = require('react-native'); -var {StyleSheet, View, Text, TouchableHighlight, AlertMacOS} = ReactNative; +const React = require('react'); +const ReactNative = require('react-native'); +const {StyleSheet, View, Text, TouchableHighlight, AlertMacOS} = ReactNative; -var {SimpleAlertExampleBlock} = require('./AlertExample'); +const {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 ab99e9213bf256..bc2d074b2be75e 100644 --- a/RNTester/js/examples/Appearance/AppearanceExample.js +++ b/RNTester/js/examples/Appearance/AppearanceExample.js @@ -191,7 +191,9 @@ exports.examples = [ paddingVertical: 2, color: theme.LabelColor, }}> - {theme[key]} + {typeof theme[key] === 'string' + ? theme[key] + : JSON.stringify(theme[key])} diff --git a/RNTester/js/examples/DarkModeExample/DarkModeExample.js b/RNTester/js/examples/DarkModeExample/DarkModeExample.js index 7e178ea9ec9b49..5ca95686088aeb 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 {Text, View} = ReactNative; +const {PlatformColor, Text, View} = ReactNative; class SemanticColorsExample extends React.Component<{}> { createTable() { @@ -45,8 +45,8 @@ class SemanticColorsExample extends React.Component<{}> { // Table Colors 'gridColor', 'headerTextColor', - 'alternatingContentBackgroundColorEven', - 'alternatingContentBackgroundColorOdd', + 'alternatingEvenContentBackgroundColor', + 'alternatingOddContentBackgroundColor', // Control Colors 'controlAccentColor', 'controlColor', @@ -138,7 +138,7 @@ class SemanticColorsExample extends React.Component<{}> { style={{ flex: 1, alignItems: 'stretch', - color: {semantic: 'labelColor'}, + color: PlatformColor('labelColor'), }}> {color} @@ -146,7 +146,7 @@ class SemanticColorsExample extends React.Component<{}> { style={{ flex: 0.25, alignItems: 'stretch', - backgroundColor: {semantic: `${color}`}, + backgroundColor: PlatformColor(color), }} /> , diff --git a/RNTester/js/examples/DatePicker/DatePickerMacOSExample.js b/RNTester/js/examples/DatePicker/DatePickerMacOSExample.js index 759b56df251b2f..5f058554d3ab50 100644 --- a/RNTester/js/examples/DatePicker/DatePickerMacOSExample.js +++ b/RNTester/js/examples/DatePicker/DatePickerMacOSExample.js @@ -8,9 +8,9 @@ */ 'use strict'; -var React = require('react'); -var ReactNative = require('react-native'); -var { +const React = require('react'); +const ReactNative = require('react-native'); +const { DatePickerMacOS, StyleSheet, Text, diff --git a/RNTester/js/examples/FocusEventsExample/FocusEventsExample.js b/RNTester/js/examples/FocusEventsExample/FocusEventsExample.js index 65be0afd2cb575..9c60a0bbeaba7d 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) -var React = require('react'); -var ReactNative = require('react-native'); +const React = require('react'); +const ReactNative = require('react-native'); import {Platform} from 'react-native'; -var {Button, StyleSheet, Text, View, TextInput} = ReactNative; +const {Button, PlatformColor, 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' ? {semantic: 'textColor'} : 'black' + Platform.OS === 'macos' ? PlatformColor('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' ? {semantic: 'textColor'} : 'black' + Platform.OS === 'macos' ? PlatformColor('textColor') : 'black' } /> @@ -244,7 +244,7 @@ class FocusEventExample extends React.Component<{}, State> { multiline={true} placeholder={'Nested Multiline TextInput'} placeholderTextColor={ - Platform.OS === 'macos' ? {semantic: 'textColor'} : 'black' + Platform.OS === 'macos' ? PlatformColor('textColor') : 'black' } /> @@ -260,9 +260,9 @@ var styles = StyleSheet.create({ textInput: { ...Platform.select({ macos: { - color: {semantic: 'textColor'}, - backgroundColor: {semantic: 'textBackgroundColor'}, - borderColor: {semantic: 'gridColor'}, + color: PlatformColor('textColor'), + backgroundColor: PlatformColor('textBackgroundColor'), + borderColor: PlatformColor('gridColor'), }, default: { borderColor: '#0f0f0f', diff --git a/RNTester/js/examples/Image/ImageExample.js b/RNTester/js/examples/Image/ImageExample.js index b0d95ac5fdfce2..7a2173f590d094 100644 --- a/RNTester/js/examples/Image/ImageExample.js +++ b/RNTester/js/examples/Image/ImageExample.js @@ -781,6 +781,9 @@ 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 4791cba84a9312..5abb07d95e7dc4 100644 --- a/RNTester/js/examples/Layout/LayoutEventsExample.js +++ b/RNTester/js/examples/Layout/LayoutEventsExample.js @@ -102,8 +102,7 @@ class LayoutEventExample extends React.Component { onLayout={this.onImageLayout} style={styles.image} source={{ - uri: - 'https://fbcdn-dragon-a.akamaihd.net/hphotos-ak-prn1/t39.1997/p128x128/851561_767334496626293_1958532586_n.png', + uri: 'https://www.facebook.com/favicon.ico', }} /> diff --git a/RNTester/js/examples/MaskedView/MaskedViewExample.js b/RNTester/js/examples/MaskedView/MaskedViewExample.js index 2b9f99c19a0aa6..7ad01c6e41cda1 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, - timing: 750, + duration: 750, useNativeDriver: true, }), Animated.timing(this._maskScaleAnimatedValue, { toValue: 1, - timing: 750, + duration: 750, useNativeDriver: true, }), ]), @@ -49,7 +49,7 @@ class AnimatedMaskExample extends React.Component { Animated.loop( Animated.timing(this._maskRotateAnimatedValue, { toValue: 360, - timing: 2000, + duration: 2000, useNativeDriver: true, }), ).start(); @@ -76,6 +76,9 @@ 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 cd20cb7ca504bd..e6c4fcb591c631 100644 --- a/RNTester/js/examples/NativeAnimation/NativeAnimationsExample.js +++ b/RNTester/js/examples/NativeAnimation/NativeAnimationsExample.js @@ -145,6 +145,9 @@ 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], }), }, @@ -240,6 +243,9 @@ 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 7672b9ea420a8d..c4d1e2bfcf4902 100644 --- a/RNTester/js/examples/Picker/PickerExample.js +++ b/RNTester/js/examples/Picker/PickerExample.js @@ -125,6 +125,25 @@ 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: { @@ -160,6 +179,12 @@ exports.examples = [ return ; }, }, + { + title: 'Accessibility Label pickers', + render: function(): React.Element { + return ; + }, + }, { title: 'Picker with no listener', render: function(): React.Element { @@ -186,4 +211,10 @@ 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 new file mode 100644 index 00000000000000..c440808d2123e1 --- /dev/null +++ b/RNTester/js/examples/PlatformColor/PlatformColorExample.js @@ -0,0 +1,358 @@ +/** + * 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 new file mode 100644 index 00000000000000..1dadac6b1c4c13 --- /dev/null +++ b/RNTester/js/examples/Pressable/PressableExample.js @@ -0,0 +1,469 @@ +/** + * 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 c291a7a6e5ef07..93127afb755999 100644 --- a/RNTester/js/examples/PushNotificationIOS/PushNotificationIOSExample.js +++ b/RNTester/js/examples/PushNotificationIOS/PushNotificationIOSExample.js @@ -49,8 +49,6 @@ class NotificationExample extends React.Component<{...}> { 'localNotification', this._onLocalNotification, ); - - PushNotificationIOS.requestPermissions(); } componentWillUnmount() { @@ -173,18 +171,51 @@ class NotificationPermissionExample extends React.Component< return (