diff --git a/.buckconfig b/.buckconfig index a4c6d696ba66b7..963190d2b61a10 100644 --- a/.buckconfig +++ b/.buckconfig @@ -1,13 +1,13 @@ [android] - target = android-26 + target = android-27 [download] max_number_of_retries = 3 [maven_repositories] central = https://repo1.maven.org/maven2 - google = https://maven.google.com + google = https://dl.google.com/dl/android/maven2/ [alias] rntester = //RNTester/android/app:app diff --git a/.circleci/config.yml b/.circleci/config.yml index 336b4dbf200818..7f94a6138c860f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -28,51 +28,42 @@ aliases: - &restore-cache-android-packages keys: - - v1-android-sdkmanager-packages-api-26-alpha-{{ checksum "scripts/.tests.env" }} + - v1-android-sdkmanager-packages-api-27-alpha-{{ checksum "scripts/.tests.env" }} - &save-cache-android-packages paths: - /opt/android/sdk - key: v1-android-sdkmanager-packages-api-26-alpha-{{ checksum "scripts/.tests.env" }} + key: v1-android-sdkmanager-packages-api-27-alpha-{{ checksum "scripts/.tests.env" }} - &restore-cache-gradle keys: - - v1-gradle-{{ arch }}-{{ .Branch }}-{{ checksum "build.gradle" }}-{{ checksum "ReactAndroid/build.gradle" }} + - v1-gradle-{{ .Branch }}-{{ checksum "build.gradle" }}-{{ checksum "ReactAndroid/build.gradle" }} # Fallback in case checksum fails - - v1-gradle-{{ arch }}-{{ .Branch }}-{{ checksum "build.gradle" }}- - - v1-gradle-{{ arch }}-{{ .Branch }}- + - v1-gradle-{{ .Branch }}-{{ checksum "build.gradle" }}- + - v1-gradle-{{ .Branch }}- # Fallback in case this is a first-time run on a fork - - v1-gradle-{{ arch }}-master- + - v1-gradle-master- - &save-cache-gradle paths: - ~/.gradle - key: v1-gradle-{{ arch }}-{{ .Branch }}-{{ checksum "build.gradle" }}-{{ checksum "ReactAndroid/build.gradle" }} - - - &restore-cache-apt - keys: - - v1-apt-{{ .Branch }}-{{ checksum "scripts/circleci/apt-get-android-deps.sh" }} - # Fallback in case this is a first-time run on a fork - - v1-apt-master-{{ checksum "scripts/circleci/apt-get-android-deps.sh" }} - - &save-cache-apt - paths: - - ~/vendor/apt - key: v1-apt-{{ .Branch }}-{{ checksum "scripts/circleci/apt-get-android-deps.sh" }} + key: v1-gradle-{{ .Branch }}-{{ checksum "build.gradle" }}-{{ checksum "ReactAndroid/build.gradle" }} - &restore-cache-ndk keys: - - v3-android-ndk-{{ arch }}-r10e-{{ checksum "scripts/android-setup.sh" }} + - v3-android-ndk-r17c-{{ checksum "scripts/android-setup.sh" }} - &save-cache-ndk paths: - /opt/ndk - key: v3-android-ndk-{{ arch }}-r10e-{{ checksum "scripts/android-setup.sh" }} + key: v3-android-ndk-r17c-{{ checksum "scripts/android-setup.sh" }} - - &restore-cache-buck + - &restore-cache-downloads-buck keys: - - v3-buck-{{ arch }}-v2018.06.25.01 - - &save-cache-buck + - v3-buck-v2018.07.23.01-{{ checksum "scripts/circleci/buck_fetch.sh" }}} + - v3-buck-v2018.07.23.01- + - &save-cache-downloads-buck paths: - ~/buck - ~/okbuck - key: v3-buck-{{ arch }}-v2018.06.25.01 + key: v3-buck-v2018.07.23.01-{{ checksum "scripts/circleci/buck_fetch.sh" }} - &restore-cache-watchman keys: @@ -82,16 +73,16 @@ aliases: - ~/watchman key: v1-watchman-{{ arch }}-v4.9.0 - - &restore-cache-gradle-downloads + - &restore-cache-downloads-gradle keys: - - v1-gradle-{{ arch }}-{{ checksum "ReactAndroid/build.gradle" }}-{{ checksum "scripts/circleci/gradle_download_deps.sh" }} - - v1-gradle-{{ arch }}- - - &save-cache-gradle-downloads + - v1-gradle-{{ checksum "ReactAndroid/build.gradle" }}-{{ checksum "scripts/circleci/gradle_download_deps.sh" }} + - v1-gradle- + - &save-cache-downloads-gradle paths: - ~/.gradle - ReactAndroid/build/downloads - ReactAndroid/build/third-party-ndk - key: v1-gradle-{{ arch }}-{{ checksum "ReactAndroid/build.gradle" }}-{{ checksum "scripts/circleci/gradle_download_deps.sh" }} + key: v1-gradle-{{ checksum "ReactAndroid/build.gradle" }}-{{ checksum "scripts/circleci/gradle_download_deps.sh" }} # Branch Filtering - &filter-only-master-stable @@ -137,15 +128,11 @@ aliases: echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list sudo apt-get update && sudo apt-get install yarn - - &install-node-dependencies - | - npm install --no-package-lock --no-spin --no-progress - - &install-buck name: Install BUCK command: | if [[ ! -e ~/buck ]]; then - git clone https://github.com/facebook/buck.git ~/buck --branch v2018.06.25.01 --depth=1 + git clone https://github.com/facebook/buck.git ~/buck --branch v2018.07.23.01 --depth=1 fi cd ~/buck && ant buck --version @@ -156,13 +143,6 @@ aliases: mkdir -p ~/react-native/tooling/junit cp -R ~/okbuck/tooling/junit/* ~/react-native/tooling/junit/. - - - &install-node - name: Install Node - command: | - curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash - - sudo apt-get install -y nodejs - - &create-ndk-directory name: Create Android NDK Directory command: | @@ -203,29 +183,32 @@ aliases: # eslint sometimes runs into trouble generating the reports - &run-lint-checks name: Lint code - command: | - if [ $((0 % CIRCLE_NODE_TOTAL)) -eq "$CIRCLE_NODE_INDEX" ]; then - scripts/circleci/exec_swallow_error.sh yarn lint --format junit -o ~/react-native/reports/junit/eslint/results.xml - fi + command: scripts/circleci/exec_swallow_error.sh yarn lint --format junit -o ~/react-native/reports/junit/eslint/results.xml - - &run-flow-checks - name: Check for errors in code using Flow - command: | - if [ $((0 % CIRCLE_NODE_TOTAL)) -eq "$CIRCLE_NODE_INDEX" ]; then - yarn flow check - fi + - &run-flow-checks-ios + name: Check for errors in code using Flow (iOS) + command: yarn flow-check-ios + + - &run-flow-checks-android + name: Check for errors in code using Flow (Android) + command: yarn flow-check-android - &run-sanity-checks name: Sanity checks command: | ./scripts/circleci/check_license.sh ./scripts/circleci/check_cache.sh + ./scripts/circleci/validate_yarn_lockfile.sh when: always - - &gradle-download-deps - name: Download C++ Dependencies + - &download-dependencies-gradle + name: Download Dependencies Using Gradle command: ./scripts/circleci/gradle_download_deps.sh + - &download-dependencies-buck + name: Download Dependencies Using Buck + command: ./scripts/circleci/buck_fetch.sh + - &build-android-app name: Build Android App command: | @@ -266,6 +249,10 @@ aliases: 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 + - &build-android-rntester-app + name: Build Android RNTester App + command: ./gradlew RNTester:android:app:assembleRelease -Pjobs=$BUILD_THREADS + - &collect-android-test-results name: Collect Test Results command: | @@ -283,62 +270,54 @@ aliases: mkdir -p ~/react-native/reports/junit/ mkdir -p ~/react-native/reports/outputs/ + - &brew-install-watchman + name: Install Watchman + command: | + brew install watchman + touch .watchmanconfig + - &boot-simulator-iphone name: Boot iPhone Simulator - command: | - if [ $((0 % CIRCLE_NODE_TOTAL)) -eq "$CIRCLE_NODE_INDEX" ]; then - xcrun simctl boot "iPhone 5s" || true - fi + command: xcrun simctl boot "iPhone 5s" || true - &boot-simulator-appletv name: Boot Apple TV Simulator - command: | - if [ $((1 % CIRCLE_NODE_TOTAL)) -eq "$CIRCLE_NODE_INDEX" ]; then - xcrun simctl boot "Apple TV" || true - fi + command: xcrun simctl boot "Apple TV" || true - &run-objc-ios-tests name: iOS Test Suite - command: | - if [ $((0 % CIRCLE_NODE_TOTAL)) -eq "$CIRCLE_NODE_INDEX" ]; then - ./scripts/objc-test-ios.sh test - fi + command: ./scripts/objc-test-ios.sh test - &run-objc-tvos-tests name: tvOS Test Suite + command: ./scripts/objc-test-tvos.sh test + + - &display-broken-tests-warning + name: Running broken tests (Ignore any failures past this point) command: | - if [ $((1 % CIRCLE_NODE_TOTAL)) -eq "$CIRCLE_NODE_INDEX" ]; then - ./scripts/objc-test-tvos.sh test - fi + echo 'The following steps are known to be failing on master.' + echo 'They will no-op for most users.' + echo 'PRs that bring these back to green are appreciated.' - &run-podspec-tests - name: Test CocoaPods - command: | - if [ $((2 % CIRCLE_NODE_TOTAL)) -eq "$CIRCLE_NODE_INDEX" ]; then - ./scripts/process-podspecs.sh - fi + name: Test CocoaPods (Disabled) + command: ./scripts/circleci/exec_author_check.sh ./scripts/process-podspecs.sh - &run-e2e-tests - name: End-to-End Test Suite - command: node ./scripts/run-ci-e2e-tests.js --android --ios --tvos --js --retries 3; + name: End-to-End Test Suite (Disabled) + command: ./scripts/circleci/exec_author_check.sh node ./scripts/run-ci-e2e-tests.js --android --ios --tvos --js --retries 3; - &run-objc-ios-e2e-tests - name: iOS End-to-End Test Suite - command: | - if [ $((0 % CIRCLE_NODE_TOTAL)) -eq "$CIRCLE_NODE_INDEX" ]; then - node ./scripts/run-ci-e2e-tests.js --ios --retries 3; - fi + name: iOS End-to-End Test Suite (Disabled) + command: ./scripts/circleci/exec_author_check.sh node ./scripts/run-ci-e2e-tests.js --ios --retries 3; - &run-objc-tvos-e2e-tests - name: tvOS End-to-End Test Suite - command: | - if [ $((1 % CIRCLE_NODE_TOTAL)) -eq "$CIRCLE_NODE_INDEX" ]; then - node ./scripts/run-ci-e2e-tests.js --tvos --js --retries 3; - fi + name: tvOS End-to-End Test Suite (Disabled) + command: ./scripts/circleci/exec_author_check.sh node ./scripts/run-ci-e2e-tests.js --tvos --js --retries 3; - &run-android-e2e-tests - name: Android End-to-End Test Suite - command: node ./scripts/run-ci-e2e-tests.js --android --retries 3; + name: Android End-to-End Test Suite (Disabled) + command: ./scripts/circleci/exec_author_check.sh node ./scripts/run-ci-e2e-tests.js --android --retries 3; - &run-js-e2e-tests name: JavaScript End-to-End Test Suite @@ -359,14 +338,14 @@ js_defaults: &js_defaults android_defaults: &android_defaults <<: *defaults docker: - - image: circleci/android:api-26-node8-alpha + - image: circleci/android:api-27-node8-alpha resource_class: "large" environment: - TERM: "dumb" - ADB_INSTALL_TIMEOUT: 10 - _JAVA_OPTIONS: "-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap" - GRADLE_OPTS: '-Dorg.gradle.daemon=false -Dorg.gradle.jvmargs="-XX:+HeapDumpOnOutOfMemoryError"' - - ANDROID_NDK: '/opt/ndk/android-ndk-r10e' + - ANDROID_NDK: '/opt/ndk/android-ndk-r17c' - BUILD_THREADS: 2 macos_defaults: &macos_defaults @@ -403,7 +382,8 @@ jobs: at: ~/react-native - run: *run-lint-checks - - run: *run-flow-checks + - run: *run-flow-checks-ios + - run: *run-flow-checks-android - store_test_results: path: ~/react-native/reports/junit @@ -422,108 +402,98 @@ jobs: - store_test_results: path: ~/react-native/reports/junit + # Run JavaScript tests on Node 10 + test_node10: + <<: *defaults + docker: + - image: circleci/node:10 + environment: + - PATH: "/opt/yarn/yarn-v1.5.1/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" + steps: + - checkout + - run: *setup-artifacts + - run: *yarn + - run: *run-js-tests + - store_test_results: + path: ~/react-native/reports/junit + # Runs unit tests on iOS and Apple TV devices test_objc: <<: *macos_defaults - parallelism: 3 steps: - attach_workspace: at: ~/react-native - run: *boot-simulator-iphone - run: *boot-simulator-appletv - - run: brew install watchman + - run: *brew-install-watchman - run: *run-objc-ios-tests - run: *run-objc-tvos-tests + + # TODO: Fix these failing tests. + - run: *display-broken-tests-warning - run: *run-podspec-tests + - run: *run-objc-ios-e2e-tests + - run: *run-objc-tvos-e2e-tests - store_test_results: path: ~/react-native/reports/junit - # Runs end to end tests - test_end_to_end: - <<: *macos_defaults - parallelism: 2 + # Xcode 10: Runs unit tests on iOS and Apple TV devices + test_objc_xcode10: + <<: *defaults + macos: + xcode: "10.0.0" steps: - - attach_workspace: - at: ~/react-native + - checkout + - run: *setup-artifacts + - run: *yarn - run: *boot-simulator-iphone - run: *boot-simulator-appletv + - run: *brew-install-watchman + + - run: *run-objc-ios-tests + - run: *run-objc-tvos-tests + + # TODO: Fix these failing tests. + - run: *display-broken-tests-warning + - run: *run-podspec-tests + - run: *run-objc-ios-e2e-tests + - run: *run-objc-tvos-e2e-tests + + - store_test_results: + path: ~/react-native/reports/junit + # Runs end to end tests (Detox) + test_detox_end_to_end: + <<: *macos_defaults + steps: + - attach_workspace: + at: ~/react-native + - run: xcrun simctl boot "iPhone 5s" || true - run: name: Configure Environment Variables command: | echo 'export PATH=/usr/local/opt/node@8/bin:$PATH' >> $BASH_ENV source $BASH_ENV - - run: name: Install Node 8 command: | brew install node@8 brew link node@8 + brew tap wix/brew + brew install applesimutils node -v - - - run: *run-objc-ios-e2e-tests - # Disabled for now - # - run: *run-objc-tvos-e2e-tests - - - store_test_results: - path: ~/react-native/reports/junit - - # Publishes new version onto npm - publish_npm_package: - <<: *android_defaults - steps: - # Checkout code so that we can work with `git` in publish.js - - checkout - - # Configure Android SDK and related dependencies - - run: *configure-android-path - - run: *install-android-build-dependencies - - - restore-cache: *restore-cache-android-packages - - run: *install-android-packages - - save-cache: *save-cache-android-packages - - # Install Android NDK - - run: *create-ndk-directory - - restore-cache: *restore-cache-ndk - - run: *install-ndk - - save-cache: *save-cache-ndk - - # Fetch dependencies using BUCK - - restore-cache: *restore-cache-buck - - run: *install-buck - - save-cache: *save-cache-buck - - - run: buck fetch ReactAndroid/src/test/java/com/facebook/react/modules - - run: buck fetch ReactAndroid/src/main/java/com/facebook/react - - run: buck fetch ReactAndroid/src/main/java/com/facebook/react/shell - - run: buck fetch ReactAndroid/src/test/... - - run: buck fetch ReactAndroid/src/androidTest/... - - - restore-cache: *restore-cache-gradle-downloads - - run: *gradle-download-deps - - save-cache: *save-cache-gradle-downloads - - - restore-cache: *restore-yarn-cache - run: *yarn - - save-cache: *save-yarn-cache - run: - name: Publish React Native Package - command: | - if [ -z "$CIRCLE_PULL_REQUEST" ]; then - echo "//registry.npmjs.org/:_authToken=${CIRCLE_NPM_TOKEN}" > ~/.npmrc - git config --global user.email "reactjs-bot@users.noreply.github.com" - git config --global user.name "npm Deployment Script" - echo "machine github.com login reactjs-bot password $GITHUB_TOKEN" > ~/.netrc - node ./scripts/publish-npm.js - else - echo "Skipping deploy." - fi + name: Build iOS app for simulator + command: yarn run build-ios-e2e + - run: + name: Run Detox Tests + command: yarn run test-ios-e2e # Set up an Android environment for downstream jobs test_android: @@ -534,14 +504,14 @@ jobs: # Configure Android SDK and related dependencies - run: *configure-android-path - - restore-cache: *restore-cache-apt + # Android build deps install from the network faster than cache - run: *install-android-build-dependencies - - save-cache: *save-cache-apt - restore-cache: *restore-cache-android-packages - run: *install-android-packages - save-cache: *save-cache-android-packages + # Validate Android SDK installation and packages - run: *validate-android-sdk # Starting emulator in advance as it takes some time to boot. @@ -556,22 +526,21 @@ jobs: - run: *install-ndk - save-cache: *save-cache-ndk - # Fetch dependencies using BUCK - - restore-cache: *restore-cache-buck + # Install Buck + - restore-cache: *restore-cache-downloads-buck - run: *install-buck - - save-cache: *save-cache-buck + - save-cache: *save-cache-downloads-buck + # Validate Android test environment (including Buck) - run: *validate-android-test-env - - run: buck fetch ReactAndroid/src/test/java/com/facebook/react/modules - - run: buck fetch ReactAndroid/src/main/java/com/facebook/react - - run: buck fetch ReactAndroid/src/main/java/com/facebook/react/shell - - run: buck fetch ReactAndroid/src/test/... - - run: buck fetch ReactAndroid/src/androidTest/... + # Download dependencies using Buck + - run: *download-dependencies-buck - - restore-cache: *restore-cache-gradle-downloads - - run: *gradle-download-deps - - save-cache: *save-cache-gradle-downloads + # Download dependencies using Gradle + - restore-cache: *restore-cache-downloads-gradle + - run: *download-dependencies-gradle + - save-cache: *save-cache-downloads-gradle # Build and compile - run: *build-android-app @@ -586,16 +555,12 @@ jobs: # Test Suite - run: *run-android-unit-tests - run: *run-android-instrumentation-tests - - # Build Android RNTester - - run: - name: Build Android RNTester - command: | - ./gradlew RNTester:android:app:assembleRelease -Pjobs=$BUILD_THREADS + - run: *build-android-rntester-app # Run Android end-to-end tests - # Disabled - # - run: *run-android-e2e-tests + # TODO: Fix these failing tests. + - run: *display-broken-tests-warning + - run: *run-android-e2e-tests # Collect Results - run: *collect-android-test-results @@ -605,46 +570,111 @@ jobs: # Analyze pull request and raise any lint/flow issues. # Issues will be posted to the PR itself via GitHub bots. # This workflow should only fail if the bots fail to run. + # The public github tokens are publicly visible by design analyze_pr: - <<: *js_defaults + <<: *defaults + docker: + - image: circleci/node:10 + environment: + - PATH: "/opt/yarn/yarn-v1.5.1/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" + - 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: - - attach_workspace: - at: ~/react-native + - checkout + - run: *setup-artifacts - restore-cache: *restore-cache-analysis - run: *yarn + - run: - name: Install Additional Dependencies + name: Analyze Shell Scripts command: | - if [ -n "$CIRCLE_PR_NUMBER" ]; then - yarn add github@0.2.4 - cd bots - yarn install --non-interactive --cache-folder ~/.cache/yarn - else - echo "Skipping dependency installation." - fi - - save-cache: *save-cache-analysis + echo -e "\\x1B[36mInstalling additional dependencies\\x1B[0m" + sudo apt-get install -y shellcheck + yarn add @octokit/rest@15.10.0 + echo -e "\\x1B[36mAnalyzing shell scripts\\x1B[0m"; \ + GITHUB_TOKEN="$PUBLIC_ANALYSISBOT_GITHUB_TOKEN_A""$PUBLIC_ANALYSISBOT_GITHUB_TOKEN_B" \ + GITHUB_OWNER="$CIRCLE_PROJECT_USERNAME" \ + GITHUB_REPO="$CIRCLE_PROJECT_REPONAME" \ + GITHUB_PR_NUMBER="$CIRCLE_PR_NUMBER" \ + ./scripts/circleci/analyze_scripts.sh + when: always - run: - name: Analyze Pull Request + name: Analyze Code command: | - # DANGER_GITHUB_API_TOKEN=React-Linter public_repo access token - if [ -n "$CIRCLE_PR_NUMBER" ]; then - cd bots && DANGER_GITHUB_API_TOKEN="80aa64c50f38a267e9ba""575d41d528f9c234edb8" yarn danger - else - echo "Skipping pull request analysis." - fi + echo -e "\\x1B[36mInstalling additional dependencies\\x1B[0m"; yarn add @octokit/rest@15.10.0 + echo -e "\\x1B[36mAnalyzing code\\x1B[0m"; \ + GITHUB_TOKEN="$PUBLIC_ANALYSISBOT_GITHUB_TOKEN_A""$PUBLIC_ANALYSISBOT_GITHUB_TOKEN_B" \ + GITHUB_OWNER="$CIRCLE_PROJECT_USERNAME" \ + GITHUB_REPO="$CIRCLE_PROJECT_REPONAME" \ + GITHUB_PR_NUMBER="$CIRCLE_PR_NUMBER" \ + ./scripts/circleci/analyze_code.sh when: always + - run: - name: Analyze Code + name: Analyze Pull Request command: | - # GITHUB_TOKEN=eslint-bot public_repo access token - if [ -n "$CIRCLE_PR_NUMBER" ]; then - GITHUB_TOKEN="af6ef0d15709bc91d""06a6217a5a826a226fb57b7" CI_USER=$CIRCLE_PROJECT_USERNAME CI_REPO=$CIRCLE_PROJECT_REPONAME PULL_REQUEST_NUMBER=$CIRCLE_PR_NUMBER scripts/circleci/analyze_code.sh - else - echo "Skipping code analysis." - fi + echo -e "\\x1B[36mInstalling additional dependencies\\x1B[0m" + cd bots + yarn install --non-interactive --cache-folder ~/.cache/yarn + echo -e "\\x1B[36mAnalyzing pull request\\x1B[0m"; \ + DANGER_GITHUB_API_TOKEN="$PUBLIC_PULLBOT_GITHUB_TOKEN_A""$PUBLIC_PULLBOT_GITHUB_TOKEN_B" \ + yarn danger when: always + - save-cache: *save-cache-analysis + + # Publishes new version onto npm + # Only works on stable branches when a properly tagged commit is pushed + publish_npm_package: + <<: *android_defaults + steps: + - checkout + + - restore-cache: *restore-yarn-cache + - run: *yarn + + # Configure Android SDK and related dependencies + - run: *configure-android-path + - run: *install-android-build-dependencies + + - restore-cache: *restore-cache-android-packages + - run: *install-android-packages + + # Install Android NDK + - run: *create-ndk-directory + - restore-cache: *restore-cache-ndk + - run: *install-ndk + + # Fetch dependencies using Buck + - restore-cache: *restore-cache-downloads-buck + - run: *install-buck + - run: *download-dependencies-buck + + # Fetch dependencies using Gradle + - restore-cache: *restore-cache-downloads-gradle + - run: *download-dependencies-gradle + + - restore-cache: *restore-yarn-cache + - run: *yarn + + - run: + name: Authenticate with npm + command: echo "//registry.npmjs.org/:_authToken=${CIRCLE_NPM_TOKEN}" > ~/.npmrc + + - run: + name: Authenticate git user + command: | + 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: + name: Publish React Native Package + command: node ./scripts/publish-npm.js # Workflows enables us to run multiple jobs in parallel workflows: @@ -680,35 +710,29 @@ workflows: requires: - checkout_code - # End-to-end tests - - test_end_to_end: + - test_detox_end_to_end: filters: *filter-ignore-gh-pages requires: - checkout_code + # Tooling Compatibility Checks + - test_objc_xcode10: + filters: *filter-ignore-gh-pages + - test_node10: + filters: *filter-ignore-gh-pages + # Only runs on vX.X.X tags if all tests are green - publish_npm_package: filters: + # ignore any commit on any branch by default branches: ignore: /.*/ + # only act on version tags tags: only: /v[0-9]+(\.[0-9]+)*(\-rc(\.[0-9]+)?)?/ - requires: - - test_javascript - - test_objc - - test_android - - test_end_to_end - - analyze - - # Only runs on PRs - analyze: - jobs: - # Checkout repo and run Yarn - - checkout_code: - filters: *filter-ignore-master-stable - # Run code checks + # Run code checks on PRs from forks - analyze_pr: - filters: *filter-ignore-master-stable - requires: - - checkout_code + filters: + branches: + only: /^pull\/.*$/ diff --git a/.editorconfig b/.editorconfig index 4cde30709106fc..dadac3a2b6d50b 100644 --- a/.editorconfig +++ b/.editorconfig @@ -12,3 +12,6 @@ indent_size = 2 [*.gradle] indent_size = 4 + +[BUCK] +indent_size = 4 diff --git a/.eslintrc b/.eslintrc index 395f7d8243492b..01842b1bcd0e5f 100644 --- a/.eslintrc +++ b/.eslintrc @@ -52,7 +52,8 @@ "setTimeout": false, "window": false, "XMLHttpRequest": false, - "pit": false + "pit": false, + "jasmine": true }, "rules": { @@ -143,7 +144,7 @@ "no-undef": 2, // disallow use of undeclared variables unless mentioned in a /*global */ block "no-undefined": 0, // disallow use of undefined variable (off by default) "no-undef-init": 1, // disallow use of undefined when initializing variables - "no-unused-vars": [1, {"vars": "all", "args": "none"}], // disallow declaration of variables that are not used in the code + "no-unused-vars": [1, {"vars": "all", "args": "none", ignoreRestSiblings: true}], // disallow declaration of variables that are not used in the code "no-use-before-define": 0, // disallow use of variables before they are defined // Node.js diff --git a/.flowconfig b/.flowconfig index 7ba7b7ccf41d93..1915005d9c20e2 100644 --- a/.flowconfig +++ b/.flowconfig @@ -40,6 +40,9 @@ flow-github/ [options] emoji=true +esproposal.optional_chaining=enable +esproposal.nullish_coalescing=enable + module.system=haste module.system.haste.use_name_reducers=true # keep the following in sync with server/haste/hasteImpl.js @@ -53,10 +56,10 @@ module.system.haste.name_reducers='^\(.*\)\.android$' -> '\1' module.system.haste.name_reducers='^\(.*\)\.native$' -> '\1' module.system.haste.paths.blacklist=.*/__tests__/.* module.system.haste.paths.blacklist=.*/__mocks__/.* -module.system.haste.paths.blacklist=/Libraries/Animated/src/polyfills/.* module.system.haste.paths.whitelist=/Libraries/.* module.system.haste.paths.whitelist=/RNTester/.* module.system.haste.paths.whitelist=/IntegrationTests/.* +module.system.haste.paths.blacklist=/Libraries/react-native/react-native-implementation.js module.system.haste.paths.blacklist=/Libraries/Animated/src/polyfills/.* munge_underscores=true @@ -68,13 +71,14 @@ suppress_type=$FlowFixMe suppress_type=$FlowFixMeProps suppress_type=$FlowFixMeState -suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(\\)? *\\(site=[a-z,_]*[react_native_oss|react_native_fb][a-z,_]*\\)?)\\) -suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(\\)? *\\(site=[a-z,_]*[react_native_oss|react_native_fb][a-z,_]*\\)?)\\)?:? #[0-9]+ +suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(\\)? *\\(site=[a-z,_]*react_native\\(_ios\\)?_\\(oss\\|fb\\)[a-z,_]*\\)?)\\) +suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(\\)? *\\(site=[a-z,_]*react_native\\(_ios\\)?_\\(oss\\|fb\\)[a-z,_]*\\)?)\\)?:? #[0-9]+ suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError [lints] all=warn +unnecessary-optional-chain=off # There is an ESLint rule for this unclear-type=off @@ -97,4 +101,4 @@ untyped-import untyped-type-import [version] -^0.76.0 +^0.83.0 diff --git a/.flowconfig.android b/.flowconfig.android new file mode 100644 index 00000000000000..2a37cfe29f58ee --- /dev/null +++ b/.flowconfig.android @@ -0,0 +1,104 @@ +[ignore] +; We fork some components by platform +.*/*[.]ios.js + +; Ignore templates for 'react-native init' +.*/local-cli/templates/.* + +; Ignore the Dangerfile +/bots/dangerfile.js + +; Ignore "BUCK" generated dirs +/\.buckd/ + +; Ignore unexpected extra "@providesModule" +.*/node_modules/.*/node_modules/fbjs/.* + +; Ignore duplicate module providers +; For RN Apps installed via npm, "Libraries" folder is inside +; "node_modules/react-native" but in the source repo it is in the root +.*/Libraries/react-native/React.js + +; Ignore polyfills +.*/Libraries/polyfills/.* + +; Ignore metro +.*/node_modules/metro/.* + +; These should not be required directly +; require from fbjs/lib instead: require('fbjs/lib/invariant') +.*/node_modules/invariant/.* +.*/node_modules/warning/.* + +[include] + +[libs] +Libraries/react-native/react-native-interface.js +flow/ +flow-github/ + +[options] +emoji=true + +esproposal.optional_chaining=enable +esproposal.nullish_coalescing=enable + +module.system=haste +module.system.haste.use_name_reducers=true +# keep the following in sync with server/haste/hasteImpl.js +# get basename +module.system.haste.name_reducers='^.*/\([a-zA-Z0-9$_.-]+\.js\(\.flow\)?\)$' -> '\1' +# strip .js or .js.flow suffix +module.system.haste.name_reducers='^\(.*\)\.js\(\.flow\)?$' -> '\1' +# strip .android suffix +module.system.haste.name_reducers='^\(.*\)\.android$' -> '\1' +module.system.haste.name_reducers='^\(.*\)\.ios$' -> '\1' +module.system.haste.name_reducers='^\(.*\)\.native$' -> '\1' +module.system.haste.paths.blacklist=.*/__tests__/.* +module.system.haste.paths.blacklist=.*/__mocks__/.* +module.system.haste.paths.whitelist=/Libraries/.* +module.system.haste.paths.whitelist=/RNTester/.* +module.system.haste.paths.whitelist=/IntegrationTests/.* +module.system.haste.paths.blacklist=/Libraries/react-native/react-native-implementation.js +module.system.haste.paths.blacklist=/Libraries/Animated/src/polyfills/.* + +munge_underscores=true + +module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> 'RelativeImageStub' + +suppress_type=$FlowIssue +suppress_type=$FlowFixMe +suppress_type=$FlowFixMeProps +suppress_type=$FlowFixMeState + +suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(\\)? *\\(site=[a-z,_]*react_native\\(_android\\)?_\\(oss\\|fb\\)[a-z,_]*\\)?)\\) +suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(\\)? *\\(site=[a-z,_]*react_native\\(_android\\)?_\\(oss\\|fb\\)[a-z,_]*\\)?)\\)?:? #[0-9]+ +suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy +suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError + +[lints] +all=warn +unnecessary-optional-chain=off + +# There is an ESLint rule for this +unclear-type=off + +sketchy-null=off +sketchy-null-number=warn +sketchy-null-mixed=warn + +# This is noisy for now. We *do* still want to warn on importing types +# from untyped files, which is covered by untyped-type-import +untyped-import=off + +[strict] +deprecated-type +nonstrict-import +sketchy-null +unclear-type +unsafe-getters-setters +untyped-import +untyped-type-import + +[version] +^0.83.0 diff --git a/.github/ISSUE_TEMPLATE/discussion.md b/.github/ISSUE_TEMPLATE/discussion.md index a576b0de5c7539..b83e727da0a269 100644 --- a/.github/ISSUE_TEMPLATE/discussion.md +++ b/.github/ISSUE_TEMPLATE/discussion.md @@ -1,19 +1,18 @@ --- name: 🗣 Start a Discussion -about: Use https://discuss.reactjs.org/ to propose changes or discuss feature requests. +about: Use https://github.com/react-native-community/discussions-and-proposals to propose changes or discuss feature requests. --- -Please use https://discuss.reactjs.org/ to propose changes or discuss feature requests. +Use https://github.com/react-native-community/discussions-and-proposals to propose changes or discuss feature requests. This helps us ensure bug reports and regressions are given the priority they require. -If you feel strongly about starting a discussion as a GitHub Issue instead of using the discussion forum, you may follow this template. - -We kindly ask that issues of this type are kept to a minimum to ensure bug reports and regressions are given the priority they require. - -Maintainers may flag an issue for Stack Overflow or kindly ask you to move the discussion to https://discuss.reactjs.org at their own discretion. +You may also use https://discuss.reactjs.org/ for discussions on topics that are not necessarily served by the Bug Report template. --- # For Discussion - + diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 2ae837de23e7e3..d399a3f94c71cc 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,8 +1,10 @@ -Thank you for sending the PR! We appreciate you spending the time to work on these changes. +Thank you for sending the PR! We appreciate you spending the time to work on these changes. Help us understand your motivation by explaining why you decided to make this change. If this PR fixes an issue, type "Fixes #issueNumber" to automatically close the issue when the PR is merged. +_Pull requests that expand test coverage are more likely to get reviewed. Add a test case whenever possible!_ + Test Plan: ---------- Write your test plan here. If you changed any code, please provide us with clear instructions on how you verified your changes work. Bonus points for screenshots and videos! diff --git a/.github/stale.yml b/.github/stale.yml index 538514d6469695..4e334d27a425b0 100644 --- a/.github/stale.yml +++ b/.github/stale.yml @@ -2,7 +2,7 @@ # Number of days of inactivity before an issue becomes stale daysUntilStale: 90 # Number of days of inactivity before a stale issue is closed -daysUntilClose: 30 +daysUntilClose: 7 # Issues with these labels will never be considered stale exemptLabels: - Good first issue @@ -10,6 +10,7 @@ exemptLabels: - Core Team - "Help Wanted :octocat:" - ":warning:Regression" + - ":clock1:PR Pending" # Label to use when marking an issue as stale staleLabel: Stale # Comment to post when marking an issue as stale. Set to `false` to disable diff --git a/.gitignore b/.gitignore index 7705dae8ffa43f..4fb4a25d15f722 100644 --- a/.gitignore +++ b/.gitignore @@ -51,10 +51,6 @@ node_modules *.log .nvm /bots/node_modules/ - -# TODO: Check in yarn.lock in open source. Right now we need to keep it out -# from the GitHub repo as importing it might conflict with internal workspaces -yarn.lock package-lock.json # OS X @@ -72,3 +68,4 @@ package-lock.json # ReactCommon subdir shouldn't have Xcode project /ReactCommon/**/*.xcodeproj +RNTester/build diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 00000000000000..dba04c1e1786b2 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +8.11.3 diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 062c7ca1df5c2d..0f7ad8bfc173ea 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -1,43 +1,5 @@ -# [Open Source Code of Conduct](https://code.facebook.com/codeofconduct) +# Code of Conduct -This code of conduct outlines our expectations for participants within the **Facebook Open Source** community, as well as steps to reporting unacceptable behavior. We are committed to providing a welcoming and inspiring community for all and expect our code of conduct to be honored. Anyone who violates this code of conduct may be banned from the community. - -Our open source community strives to: - -* **Be friendly and patient.** -* **Be welcoming:** We strive to be a community that welcomes and supports people of all backgrounds and identities. This includes, but is not limited to members of any race, ethnicity, culture, national origin, colour, immigration status, social and economic class, educational level, sex, sexual orientation, gender identity and expression, age, size, family status, political belief, religion, and mental and physical ability. -* **Be considerate:** Your work will be used by other people, and you in turn will depend on the work of others. Any decision you take will affect users and colleagues, and you should take those consequences into account when making decisions. Remember that we’re a world-wide community, so you might not be communicating in someone else’s primary language. -* **Be respectful:** Not all of us will agree all the time, but disagreement is no excuse for poor behavior and poor manners. We might all experience some frustration now and then, but we cannot allow that frustration to turn into a personal attack. It’s important to remember that a community where people feel uncomfortable or threatened is not a productive one. -* **Be careful in the words that you choose:** we are a community of professionals, and we conduct ourselves professionally. Be kind to others. Do not insult or put down other participants. Harassment and other exclusionary behavior aren’t acceptable. This includes, but is not limited to: - * Violent threats or language directed against another person. - * Discriminatory jokes and language. - * Posting sexually explicit or violent material. - * Posting (or threatening to post) other people’s personally identifying information (“doxing”). - * Personal insults, especially those using racist or sexist terms. - * Unwelcome sexual attention. - * Advocating for, or encouraging, any of the above behavior. - * Repeated harassment of others. In general, if someone asks you to stop, then stop. -* **When we disagree, try to understand why:** Disagreements, both social and technical, happen all the time. It is important that we resolve disagreements and differing views constructively. -* **Remember that we’re different.** The strength of our community comes from its diversity, people from a wide range of backgrounds. Different people have different perspectives on issues. Being unable to understand why someone holds a viewpoint doesn’t mean that they’re wrong. Don’t forget that it is human to err and blaming each other doesn’t get us anywhere. Instead, focus on helping to resolve issues and learning from mistakes. - -This code is not exhaustive or complete. It serves to distill our common understanding of a collaborative, shared environment, and goals. We expect it to be followed in spirit as much as in the letter. - -## Diversity Statement - -We encourage everyone to participate and are committed to building a community for all. Although we may not be able to satisfy everyone, we all agree that everyone is equal. Whenever a participant has made a mistake, we expect them to take responsibility for it. If someone has been harmed or offended, it is our responsibility to listen carefully and respectfully, and do our best to right the wrong. - -Although this list cannot be exhaustive, we explicitly honor diversity in age, gender, gender identity or expression, culture, ethnicity, language, national origin, political beliefs, profession, race, religion, sexual orientation, socioeconomic status, and technical ability. We will not tolerate discrimination based on any of the protected characteristics above, including participants with disabilities. - -## Reporting Issues - -If you experience or witness unacceptable behavior—or have any other concerns—please report it by contacting us via opensource@fb.com. All reports will be handled with discretion. In your report please include: - -* Your contact information. -* Names (real, nicknames, or pseudonyms) of any individuals involved. If there are additional witnesses, please include them as well. Your account of what occurred, and if you believe the incident is ongoing. If there is a publicly available record (e.g. a mailing list archive or a public IRC logger), please include a link. -* Any additional information that may be helpful. - -After filing a report, a representative will contact you personally. If the person who is harassing you is part of the response team, they will recuse themselves from handling your incident. A representative will then review the incident, follow up with any additional questions, and make a decision as to how to respond. We will respect confidentiality requests for the purpose of protecting victims of abuse. - -Anyone asked to stop unacceptable behavior is expected to comply immediately. If an individual engages in unacceptable behavior, the representative may take any action they deem appropriate, up to and including a permanent ban from our community without warning. - -_This Code Of Conduct follows the [template](http://todogroup.org/opencodeofconduct/) established by the [TODO Group](http://todogroup.org/)._ +Facebook has adopted a Code of Conduct that we expect project participants to adhere to. +Please read the [full text](https://code.fb.com/codeofconduct/) +so that you can understand what actions will and will not be tolerated. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 25ba2d5c1e1d51..743a6db7f3cecc 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,192 +1,41 @@ # Contributing to React Native - -React Native is one of Facebook's first open source projects that is both under very active development and is also being used to ship code to everybody using Facebook's mobile apps. If you're interested in contributing to React Native, hopefully this document makes the process for contributing clear. +We want to make contributing to this project as easy and transparent as possible. Read on to learn more about our development process and how to propose bug fixes and improvements. The [How to Contribute](https://facebook.github.io/react-native/docs/contributing.html) guide on the website goes into more detail for each of these areas. -## [Code of Conduct](https://code.facebook.com/codeofconduct) +## Our Development Process -Facebook has adopted a Code of Conduct that we expect project participants to adhere to. Please read [the full text](https://code.facebook.com/codeofconduct) so that you can understand what actions will and will not be tolerated. +Most changes from engineers at Facebook will sync to [GitHub](https://github.com/facebook/react-native) through a bridge with Facebook's internal source control. Changes from the community are handled through GitHub pull requests. Once a change made on GitHub is approved, it will first be imported into Facebook's internal source control. The change will eventually sync back to GitHub as a single commit once it has passed Facebook's internal tests. -## Get involved - -There are many ways to contribute to React Native, and many of them do not involve writing any code. Here's a few ideas to get started: - -* Simply start using React Native. Go through the [Getting Started](https://facebook.github.io/react-native/docs/getting-started.html) guide. Does everything work as expected? If not, we're always looking for improvements. Let us know by [opening an issue](https://facebook.github.io/react-native/docs/contributing.html#reporting-new-issues). -* Look through the [open issues](https://github.com/facebook/react-native/issues). Provide workarounds, ask for clarification, or suggest labels. Help [triage issues](https://facebook.github.io/react-native/docs/contributing.html#triaging-issues-and-pull-requests). -* If you find an issue you would like to fix, [open a pull request](https://facebook.github.io/react-native/docs/contributing.html#your-first-pull-request). Issues tagged as [_Good first issue_](https://github.com/facebook/react-native/labels/Good%20first%20issue) are a good place to get started. -* Read through the [React Native docs](https://facebook.github.io/react-native/docs/getting-started.html). If you find anything that is confusing or can be improved, you can make edits by clicking the "EDIT" button in the top-right corner of most docs. -* Browse [Stack Overflow](https://stackoverflow.com/questions/tagged/react-native) and answer questions. This will help you get familiarized with common pitfalls or misunderstandings, which can be useful when contributing updates to the documentation. -* Take a look at the [features requested](https://react-native.canny.io/feature-requests) by others in the community and consider opening a pull request if you see something you want to work on. - -Contributions are very welcome. If you think you need help planning your contribution, please hop into [#react-native](https://discord.gg/0ZcbPKXt5bZjGY5n) and let people know you're looking for a mentor. - -Core contributors to React Native meet monthly and post their meeting notes on the [React Native blog](https://facebook.github.io/react-native/blog). You can also find ad hoc discussions in the [React Native Core Contributors](https://www.facebook.com/groups/reactnativeoss/) Facebook group. - -### Triaging issues and pull requests - -One great way you can contribute to the project without writing any code is to help triage issues and pull requests as they come in. - -* Ask for more information if the issue does not provide all the details required by the template. -* Suggest [labels](https://github.com/facebook/react-native/labels) that can help categorize issues. -* Flag issues that are stale or that should be closed. -* Ask for test plans and review code. - -You can learn more about handling issues in the [maintainer's guide](docs/maintainers.html#handling-issues). - -## Our development process - -Some of the core team will be working directly on [GitHub](https://github.com/facebook/react-native). These changes will be public from the beginning. Other changesets will come via a bridge with Facebook's internal source control. This is a necessity as it allows engineers at Facebook outside of the core team to move fast and contribute from an environment they are comfortable in. - -When a change made on GitHub is approved, it will first be imported into Facebook's internal source control. The change will eventually sync back to GitHub as a single commit once it has passed all internal tests. - -### Branch organization - -We will do our best to keep `master` in good shape, with tests passing at all times. But in order to move fast, we will make API changes that your application might not be compatible with. We will do our best to [communicate these changes](https://github.com/facebook/react-native/releases) and version appropriately so you can lock into a specific version if need be. - -To see what changes are coming and provide better feedback to React Native contributors, use the [latest release candidate](https://facebook.github.io/react-native/versions.html) when possible. By the time a release candidate is released, the changes it contains will have been shipped in production Facebook apps for over two weeks. - -## Bugs - -We use [GitHub Issues](https://github.com/facebook/react-native/issues) for our public bugs. If you would like to report a problem, take a look around and see if someone already opened an issue about it. If you a are certain this is a new, unreported bug, you can submit a [bug report](https://facebook.github.io/react-native/docs/contributing.html#reporting-new-issues). - -If you have questions about using React Native, the [Community page](https://facebook.github.io/react-native/help.html) list various resources that should help you get started. - -We also have a [place where you can request features or enhancements](https://react-native.canny.io/feature-requests). If you see anything you'd like to be implemented, vote it up and explain your use case. - -## Reporting new issues - -When [opening a new issue](https://github.com/facebook/react-native/issues/new), always make sure to fill out the [issue template](https://raw.githubusercontent.com/facebook/react-native/master/.github/ISSUE_TEMPLATE.md). **This step is very important!** Not doing so may result in your issue getting closed. Don't take this personally if this happens, and feel free to open a new issue once you've gathered all the information required by the template. - -* **One issue, one bug:** Please report a single bug per issue. -* **Provide a Snack:** The best way to get attention on your issue is to provide a reduced test case. You can use [Snack](https://snack.expo.io/) to demonstrate the issue. -* **Provide reproduction steps:** List all the steps necessary to reproduce the issue. Provide a Snack or upload a sample project to GitHub. The person reading your bug report should be able to follow these steps to reproduce your issue with minimal effort. -* **Try out the latest version:** Verify that the issue can be reproduced locally by updating your project to use [React Native from `master`](https://facebook.github.io/react-native/versions.html). The bug may have already been fixed! - -We're not able to provide support through GitHub Issues. If you're looking for help with your code, consider asking on [Stack Overflow](https://stackoverflow.com/questions/tagged/react-native) or reaching out to the community through [other channels](https://facebook.github.io/react-native/support.html). - -### Security bugs - -Facebook has a [bounty program](https://www.facebook.com/whitehat/) for the safe disclosure of security bugs. With that in mind, please do not file public issues; go through the process outlined on that page. - -## Pull requests - -### Your first pull request - -So you have decided to contribute code back to upstream by opening a pull request. You've invested a good chunk of time, and we appreciate it. We will do our best to work with you and get the PR looked at. - -Working on your first Pull Request? You can learn how from this free video series: - -[**How to Contribute to an Open Source Project on GitHub**](https://egghead.io/courses/how-to-contribute-to-an-open-source-project-on-github) - -We have a list of [beginner friendly issues](https://github.com/facebook/react-native/labels/Good%20first%20issue) to help you get your feet wet in the React Native codebase and familiar with our contribution process. This is a great place to get started. - -### Proposing a change - -If you would like to request a new feature or enhancement but are not yet thinking about opening a pull request, we have a [place to track feature requests](https://react-native.canny.io/feature-requests). - -If you intend to change the public API, or make any non-trivial changes to the implementation, we recommend [filing an issue](https://github.com/facebook/react-native/issues/new?title=%5BProposal%5D) that includes `[Proposal]` in the title. This lets us reach an agreement on your proposal before you put significant effort into it. These types of issues should be rare. If you have been contributing to the project long enough, you will probably already have access to the [React Native Core Contributors](https://www.facebook.com/groups/reactnativeoss/) Facebook Group, where this sort of discussion is usually held. - -If you're only fixing a bug, it's fine to submit a pull request right away but we still recommend to file an issue detailing what you're fixing. This is helpful in case we don't accept that specific fix but want to keep track of the issue. - -### Sending a pull request - -Small pull requests are much easier to review and more likely to get merged. Make sure the PR does only one thing, otherwise please split it. +## Pull Requests Please make sure the following is done when submitting a pull request: -1. Fork [the repository](https://github.com/facebook/react-native) and create your branch from `master`. -2. Add the copyright notice to the top of any new files you've added. -3. Describe your [**test plan**](https://facebook.github.io/react-native/docs/contributing.html#test-plan) in your pull request description. Make sure to [test your changes](https://facebook.github.io/react-native/docs/testing.html)! -4. Make sure your code lints (`npm run lint`). -5. If you haven't already, [sign the CLA](https://code.facebook.com/cla). - -All pull requests should be opened against the `master` branch. After opening your pull request, ensure [**all tests pass**](https://facebook.github.io/react-native/docs/contributing.html#contrinuous-integration-tests) on Circle CI. If a test fails and you believe it is unrelated to your change, leave a comment on the pull request explaining why. - -> **Note:** It is not necessary to keep clicking `Merge master to your branch` on the PR page. You would want to merge master if there are conflicts or tests are failing. The Facebook-GitHub-Bot ultimately squashes all commits to a single one before merging your PR. - -#### Test plan - -A good test plan has the exact commands you ran and their output, provides screenshots or videos if the pull request changes UI. - -* If you've added code that should be tested, add tests! -* If you've changed APIs, update the documentation. - -See [What is a Test Plan?](https://medium.com/@martinkonicek/what-is-a-test-plan-8bfc840ec171#.y9lcuqqi9) to learn more. - -#### Continuous integration tests - -Make sure all **tests pass** on [Circle CI][circle]. PRs that break tests are unlikely to be merged. Learn more about [testing your changes here](https://facebook.github.io/react-native/docs/testing.html). - -[circle]: https://circleci.com/gh/facebook/react-native +1. Fork the repo and create your branch from `master`. +2. If you've added code that should be tested, add tests. +3. If you've changed APIs, update the documentation. +4. Ensure the test suite passes. +5. Make sure your code lints. +6. If you haven't already, complete the Contributor License Agreement ("CLA"). -#### Breaking changes +## Contributor License Agreement ("CLA") -When adding a new breaking change, follow this template in your pull request: +In order to accept your pull request, we need you to submit a CLA. You only need to do this once to work on any of Facebook's open source projects. -``` -### New breaking change here +Complete your CLA here: -* **Who does this affect**: -* **How to migrate**: -* **Why make this breaking change**: -* **Severity (number of people affected x effort)**: -``` +## Issues -If your pull request is merged, a core contributor will update the [list of breaking changes](https://github.com/facebook/react-native/wiki/Breaking-Changes) which is then used to populate the release notes. +We use GitHub issues to track public bugs. Please ensure your description is clear and has sufficient instructions to be able to reproduce the issue. -#### Copyright Notice for files +Facebook has a [bounty program](https://www.facebook.com/whitehat/) for the safe disclosure of security bugs. In those cases, please go through the process outlined on that page and do not file a public issue. -Copy and paste this to the top of your new file(s): +## Coding Style -```JS -/** - * Copyright (c) 2015-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ -``` +We use Prettier to format our JavaScript code. This saves you time and energy as you can let Prettier fix up any formatting issues automatically through its editor integrations, or by manually running `npm run prettier`. We also use a linter to catch styling issues that may exist in your code. You can check the status of your code styling by simply running `npm run lint`. -#### Contributor License Agreement (CLA) +However, there are still some styles that the linter cannot pick up, notably in Java or Objective-C code. -In order to accept your pull request, we need you to submit a CLA. You only need to do this once, so if you've done this for another Facebook open source project, you're good to go. If you are submitting a pull request for the first time, the Facebook GitHub Bot will reply with a link to the CLA form. You may also [complete your CLA here](https://code.facebook.com/cla). - -### What happens next? - -The core team will be monitoring for pull requests. Read [what to expect from maintainers](https://facebook.github.io/react-native/docs/maintainers.html#handling-pull-requests) to understand what may happen after you open a pull request. - -## Style Guide - -Our linter will catch most styling issues that may exist in your code. You can check the status of your code styling by simply running `npm run lint`. - -However, there are still some styles that the linter cannot pick up. - -### Code Conventions - -#### General - -* **Most important: Look around.** Match the style you see used in the rest of the project. This includes formatting, naming things in code, naming things in documentation. -* Add trailing commas, -* 2 spaces for indentation (no tabs) -* "Attractive" - -#### JavaScript - -* Use semicolons; -* ES6 standards -* Prefer `'` over `"` -* Do not use the optional parameters of `setTimeout` and `setInterval` -* 80 character line length - -#### JSX - -* Prefer `"` over `'` for string literal props -* When wrapping opening tags over multiple lines, place one prop per line -* `{}` of props should hug their values (no spaces) -* Place the closing `>` of opening tags on the same line as the last prop -* Place the closing `/>` of self-closing tags on their own line and left-align them with the opening `<` - -#### Objective-C +**Objective-C:** * Space after `@property` declarations * Brackets on *every* `if`, on the *same* line @@ -194,17 +43,13 @@ However, there are still some styles that the linter cannot pick up. * *Try* to keep it around 80 characters line length (sometimes it's just not possible...) * `*` operator goes with the variable name (e.g. `NSObject *variableName;`) -#### Java +**Java:** * If a method call spans multiple lines closing bracket is on the same line as the last argument. * If a method header doesn't fit on one line each argument goes on a separate line. * 100 character line length -### Documentation - -* Do not wrap lines at 80 characters - configure your editor to soft-wrap when editing documentation. - ## License -By contributing to React Native, you agree that your contributions will be licensed under its MIT license. - +By contributing to React Native, you agree that your contributions will be licensed +under the LICENSE file in the root directory of this source tree. diff --git a/ContainerShip/Dockerfile.android-base b/ContainerShip/Dockerfile.android-base index 78cb4dc22ca478..433adf5470e122 100644 --- a/ContainerShip/Dockerfile.android-base +++ b/ContainerShip/Dockerfile.android-base @@ -18,10 +18,10 @@ LABEL maintainer="Héctor Ramos " # set default build arguments ARG SDK_VERSION=sdk-tools-linux-3859397.zip -ARG ANDROID_BUILD_VERSION=26 -ARG ANDROID_TOOLS_VERSION=26.0.3 -ARG BUCK_VERSION=v2018.06.25.01 -ARG NDK_VERSION=10e +ARG ANDROID_BUILD_VERSION=27 +ARG ANDROID_TOOLS_VERSION=27.0.3 +ARG BUCK_VERSION=v2018.07.23.01 +ARG NDK_VERSION=17c ARG NODE_VERSION=8.10.0 ARG WATCHMAN_VERSION=4.9.0 diff --git a/ContainerShip/scripts/run-android-ci-instrumentation-tests.js b/ContainerShip/scripts/run-android-ci-instrumentation-tests.js index c16c7990ed317d..e538be7a6a9318 100644 --- a/ContainerShip/scripts/run-android-ci-instrumentation-tests.js +++ b/ContainerShip/scripts/run-android-ci-instrumentation-tests.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/ContainerShip/scripts/run-android-docker-instrumentation-tests.sh b/ContainerShip/scripts/run-android-docker-instrumentation-tests.sh index ed7183dec9d5fc..e2c320d7e61afe 100644 --- a/ContainerShip/scripts/run-android-docker-instrumentation-tests.sh +++ b/ContainerShip/scripts/run-android-docker-instrumentation-tests.sh @@ -6,7 +6,7 @@ mount -o remount,exec /dev/shm AVD_UUID=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 8 | head -n 1) # create virtual device -echo no | android create avd -n $AVD_UUID -f -t android-19 --abi default/armeabi-v7a +echo no | android create avd -n "$AVD_UUID" -f -t android-19 --abi default/armeabi-v7a # emulator setup emulator64-arm -avd $AVD_UUID -no-skin -no-audio -no-window -no-boot-anim & @@ -28,8 +28,9 @@ watchman shutdown-server node local-cli/cli.js bundle --platform android --dev true --entry-file ReactAndroid/src/androidTest/js/TestBundle.js --bundle-output ReactAndroid/src/androidTest/assets/AndroidTestBundle.js # build test APK +# shellcheck disable=SC1091 source ./scripts/android-setup.sh && NO_BUCKD=1 retry3 buck install ReactAndroid/src/androidTest/buck-runner:instrumentation-tests --config build.threads=1 # run installed apk with tests -node ./ContainerShip/scripts/run-android-ci-instrumentation-tests.js $* +node ./ContainerShip/scripts/run-android-ci-instrumentation-tests.js "$*" exit $? diff --git a/ContainerShip/scripts/run-android-docker-unit-tests.sh b/ContainerShip/scripts/run-android-docker-unit-tests.sh index 5a58bb352e5421..1a422c25bf1b17 100644 --- a/ContainerShip/scripts/run-android-docker-unit-tests.sh +++ b/ContainerShip/scripts/run-android-docker-unit-tests.sh @@ -9,4 +9,4 @@ mount -o remount,exec /dev/shm set -x # run unit tests -buck test ReactAndroid/src/test/... --config build.threads=$UNIT_TESTS_BUILD_THREADS +buck test ReactAndroid/src/test/... --config build.threads="$UNIT_TESTS_BUILD_THREADS" diff --git a/ContainerShip/scripts/run-ci-e2e-tests.sh b/ContainerShip/scripts/run-ci-e2e-tests.sh index de2b97edb5bb7a..be916439735dfd 100755 --- a/ContainerShip/scripts/run-ci-e2e-tests.sh +++ b/ContainerShip/scripts/run-ci-e2e-tests.sh @@ -12,11 +12,12 @@ RUN_IOS=0 RUN_JS=0 RETRY_COUNT=${RETRY_COUNT:-2} -AVD_UUID=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 8 | head -n 1) - +AVD_UUID=$(< /dev/urandom tr -dc 'a-zA-Z0-9' | fold -w 8 | head -n 1) ANDROID_NPM_DEPS="appium@1.5.1 mocha@2.4.5 wd@0.3.11 colors@1.0.3 pretty-data2@0.40.1" -CLI_PACKAGE=$ROOT/react-native-cli/react-native-cli-*.tgz -PACKAGE=$ROOT/react-native-*.tgz +CLI_PACKAGE="$ROOT/react-native-cli/react-native-cli-*.tgz" +PACKAGE="$ROOT/react-native-*.tgz" +# Version of react-native-dummy to test against +REACT_DUMMY_PLATFORM=react-native-dummy@0.1.0 # solve issue with max user watches limit echo 65536 | tee -a /proc/sys/fs/inotify/max_user_watches @@ -27,7 +28,7 @@ watchman shutdown-server # $2 -- command to run function retry() { local -r -i max_attempts="$1"; shift - local -r cmd="$@" + local -r cmd="$*" local -i attempt_num=1 until $cmd; do @@ -75,7 +76,7 @@ while :; do done function e2e_suite() { - cd $ROOT + cd "$ROOT" if [ $RUN_ANDROID -eq 0 ] && [ $RUN_IOS -eq 0 ] && [ $RUN_JS -eq 0 ]; then echo "No e2e tests specified!" @@ -88,8 +89,8 @@ function e2e_suite() { # To make sure we actually installed the local version # of react-native, we will create a temp file inside the template # and check that it exists after `react-native init - IOS_MARKER=$(mktemp $ROOT/local-cli/templates/HelloWorld/ios/HelloWorld/XXXXXXXX) - ANDROID_MARKER=$(mktemp ${ROOT}/local-cli/templates/HelloWorld/android/XXXXXXXX) + IOS_MARKER="$(mktemp "$ROOT"/local-cli/templates/HelloWorld/ios/HelloWorld/XXXXXXXX)" + ANDROID_MARKER="$(mktemp "$ROOT"/local-cli/templates/HelloWorld/android/XXXXXXXX)" # install CLI cd react-native-cli @@ -98,8 +99,8 @@ function e2e_suite() { # can skip cli install for non sudo mode if [ $RUN_CLI_INSTALL -ne 0 ]; then - npm install -g $CLI_PACKAGE - if [ $? -ne 0 ]; then + if ! npm install -g "$CLI_PACKAGE" + then echo "Could not install react-native-cli globally, please run in su mode" echo "Or with --skip-cli-install to skip this step" return 1 @@ -111,7 +112,7 @@ function e2e_suite() { # create virtual device if ! android list avd | grep "$AVD_UUID" > /dev/null; then - echo no | android create avd -n $AVD_UUID -f -t android-19 --abi default/armeabi-v7a + echo no | android create avd -n "$AVD_UUID" -f -t android-19 --abi default/armeabi-v7a fi # newline at end of adb devices call and first line is headers @@ -124,9 +125,10 @@ function e2e_suite() { fi # emulator setup - emulator64-arm -avd $AVD_UUID -no-skin -no-audio -no-window -no-boot-anim & + emulator64-arm -avd "$AVD_UUID" -no-skin -no-audio -no-window -no-boot-anim & bootanim="" + # shellcheck disable=SC2076 until [[ "$bootanim" =~ "stopped" ]]; do sleep 5 bootanim=$(adb -e shell getprop init.svc.bootanim 2>&1) @@ -135,23 +137,23 @@ function e2e_suite() { set -ex - ./gradlew :ReactAndroid:installArchives -Pjobs=1 -Dorg.gradle.jvmargs="-Xmx512m -XX:+HeapDumpOnOutOfMemoryError" - if [ $? -ne 0 ]; then + if ! ./gradlew :ReactAndroid:installArchives -Pjobs=1 -Dorg.gradle.jvmargs="-Xmx512m -XX:+HeapDumpOnOutOfMemoryError" + then echo "Failed to compile Android binaries" return 1 fi fi - npm pack - if [ $? -ne 0 ]; then + if ! npm pack + then echo "Failed to pack react-native" return 1 fi - cd $TEMP_DIR + cd "$TEMP_DIR" - retry $RETRY_COUNT react-native init EndToEndTest --version $PACKAGE --npm - if [ $? -ne 0 ]; then + if ! retry "$RETRY_COUNT" react-native init EndToEndTest --version "$PACKAGE" --npm + then echo "Failed to execute react-native init" echo "Most common reason is npm registry connectivity, try again" return 1 @@ -164,20 +166,21 @@ function e2e_suite() { echo "Running an Android e2e test" echo "Installing e2e framework" - retry $RETRY_COUNT npm install --save-dev $ANDROID_NPM_DEPS --silent >> /dev/null - if [ $? -ne 0 ]; then + if ! retry "$RETRY_COUNT" npm install --save-dev "$ANDROID_NPM_DEPS" --silent >> /dev/null + then echo "Failed to install appium" echo "Most common reason is npm registry connectivity, try again" return 1 fi - cp $SCRIPTS/android-e2e-test.js android-e2e-test.js + cp "$SCRIPTS/android-e2e-test.js" android-e2e-test.js - cd android + ( + cd android || exit echo "Downloading Maven deps" ./gradlew :app:copyDownloadableDepsToLibs + ) - cd .. keytool -genkey -v -keystore android/keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US" node ./node_modules/.bin/appium >> /dev/null & @@ -188,9 +191,8 @@ function e2e_suite() { buck build android/app # hack to get node unhung (kill buckd) - kill -9 $(pgrep java) - - if [ $? -ne 0 ]; then + if ! kill -9 "$(pgrep java)" + then echo "could not execute Buck build, is it installed and in PATH?" return 1 fi @@ -201,23 +203,23 @@ function e2e_suite() { sleep 15 echo "Executing android e2e test" - retry $RETRY_COUNT node node_modules/.bin/_mocha android-e2e-test.js - if [ $? -ne 0 ]; then + if ! retry "$RETRY_COUNT" node node_modules/.bin/_mocha android-e2e-test.js + then echo "Failed to run Android e2e tests" echo "Most likely the code is broken" return 1 fi # kill packager process - if kill -0 $SERVER_PID; then + if kill -0 "$SERVER_PID"; then echo "Killing packager $SERVER_PID" - kill -9 $SERVER_PID + kill -9 "$SERVER_PID" fi # kill appium process - if kill -0 $APPIUM_PID; then + if kill -0 "$APPIUM_PID"; then echo "Killing appium $APPIUM_PID" - kill -9 $APPIUM_PID + kill -9 "$APPIUM_PID" fi fi @@ -230,24 +232,37 @@ function e2e_suite() { # js tests if [ $RUN_JS -ne 0 ]; then # Check the packager produces a bundle (doesn't throw an error) - react-native bundle --max-workers 1 --platform android --dev true --entry-file index.js --bundle-output android-bundle.js - if [ $? -ne 0 ]; then + if ! react-native bundle --max-workers 1 --platform android --dev true --entry-file index.js --bundle-output android-bundle.js + then echo "Could not build android bundle" return 1 fi - react-native bundle --max-workers 1 --platform ios --dev true --entry-file index.js --bundle-output ios-bundle.js - if [ $? -ne 0 ]; then + if ! react-native bundle --max-workers 1 --platform ios --dev true --entry-file index.js --bundle-output ios-bundle.js + then echo "Could not build iOS bundle" return 1 fi + + if ! retry "$RETRY_COUNT" npm install --save "$REACT_DUMMY_PLATFORM" --silent >> /dev/null + then + echo "Failed to install react-native-dummy" + echo "Most common reason is npm registry connectivity, try again" + return 1 + fi + + if ! react-native bundle --max-workers 1 --platform dummy --dev true --entry-file index.js --bundle-output dummy-bundle.js + then + echo "Could not build dummy bundle" + return 1 + fi fi # directory cleanup - rm $IOS_MARKER - rm $ANDROID_MARKER + rm "$IOS_MARKER" + rm "$ANDROID_MARKER" return 0 } -retry $RETRY_COUNT e2e_suite +retry "$RETRY_COUNT" e2e_suite diff --git a/ContainerShip/scripts/run-instrumentation-tests-via-adb-shell.sh b/ContainerShip/scripts/run-instrumentation-tests-via-adb-shell.sh index 5a9a976a97da4e..72b011ca9c3c8b 100755 --- a/ContainerShip/scripts/run-instrumentation-tests-via-adb-shell.sh +++ b/ContainerShip/scripts/run-instrumentation-tests-via-adb-shell.sh @@ -1,5 +1,5 @@ #!/bin/bash - +# shellcheck disable=SC1117 # Python script to run instrumentation tests, copied from https://github.com/circleci/circle-dummy-android # Example: ./scripts/run-android-instrumentation-tests.sh com.facebook.react.tests com.facebook.react.tests.ReactPickerTestCase # @@ -9,7 +9,7 @@ export PATH="$ANDROID_HOME/platform-tools:$ANDROID_HOME/tools:$PATH" adb logcat -c # run tests and check output -python - $1 $2 << END +python - "$1" "$2" << END import re import subprocess as sp @@ -24,7 +24,7 @@ test_class = None if len(sys.argv) > 2: test_class = sys.argv[2] - + def update(): # prevent CircleCI from killing the process for inactivity while not done: @@ -38,10 +38,10 @@ t.start() def run(): sp.Popen(['adb', 'wait-for-device']).communicate() if (test_class != None): - p = sp.Popen('adb shell am instrument -w -e class %s %s/android.support.test.runner.AndroidJUnitRunner' + p = sp.Popen('adb shell am instrument -w -e class %s %s/android.support.test.runner.AndroidJUnitRunner' % (test_class, test_app), shell=True, stdout=sp.PIPE, stderr=sp.PIPE, stdin=sp.PIPE) else : - p = sp.Popen('adb shell am instrument -w %s/android.support.test.runner.AndroidJUnitRunner' + p = sp.Popen('adb shell am instrument -w %s/android.support.test.runner.AndroidJUnitRunner' % (test_app), shell=True, stdout=sp.PIPE, stderr=sp.PIPE, stdin=sp.PIPE) return p.communicate() diff --git a/DockerTests.md b/DockerTests.md index f1714db87a0a05..429e312ceb31be 100644 --- a/DockerTests.md +++ b/DockerTests.md @@ -12,9 +12,9 @@ See for more information on how t We have added a number of default run scripts to the `package.json` file to simplify building and running your tests. -`npm run test-android-setup` - Pulls down the base android docker image used for running the tests +`npm run docker-setup-android` - Pulls down the base android docker image used for running the tests -`npm run test-android-build` - Builds the docker image used to run the tests +`npm run docker-build-android` - Builds the docker image used to run the tests `npm run test-android-run-unit` - Runs all the unit tests that have been built in the latest react/android docker image (note: you need to run test-android-build before executing this, if the image does not exist it will fail) diff --git a/IntegrationTests/AccessibilityManagerTest.js b/IntegrationTests/AccessibilityManagerTest.js index 41710be91e14c0..0a059d99c27c24 100644 --- a/IntegrationTests/AccessibilityManagerTest.js +++ b/IntegrationTests/AccessibilityManagerTest.js @@ -1,11 +1,11 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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 + * @flow strict-local */ 'use strict'; diff --git a/IntegrationTests/AppEventsTest.js b/IntegrationTests/AppEventsTest.js index 90da0bd87c1ac2..e88e97909d35e9 100644 --- a/IntegrationTests/AppEventsTest.js +++ b/IntegrationTests/AppEventsTest.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/IntegrationTests/AsyncStorageTest.js b/IntegrationTests/AsyncStorageTest.js index 150aa2aed511cf..da762ea01ced87 100644 --- a/IntegrationTests/AsyncStorageTest.js +++ b/IntegrationTests/AsyncStorageTest.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/IntegrationTests/ImageCachePolicyTest.js b/IntegrationTests/ImageCachePolicyTest.js index 1dc5d5fb61a9b5..61909b6b0414e2 100644 --- a/IntegrationTests/ImageCachePolicyTest.js +++ b/IntegrationTests/ImageCachePolicyTest.js @@ -1,11 +1,11 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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 + * @flow strict-local */ 'use strict'; diff --git a/IntegrationTests/ImageSnapshotTest.js b/IntegrationTests/ImageSnapshotTest.js index c20406c641ecb5..255db4090d9f71 100644 --- a/IntegrationTests/ImageSnapshotTest.js +++ b/IntegrationTests/ImageSnapshotTest.js @@ -1,11 +1,11 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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 + * @flow strict-local */ 'use strict'; diff --git a/IntegrationTests/IntegrationTestHarnessTest.js b/IntegrationTests/IntegrationTestHarnessTest.js index 045d2e7e1eae1e..e1469dda1b418a 100644 --- a/IntegrationTests/IntegrationTestHarnessTest.js +++ b/IntegrationTests/IntegrationTestHarnessTest.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -10,28 +10,22 @@ 'use strict'; -/* $FlowFixMe(>=0.54.0 site=react_native_oss) This comment suppresses an error - * found when Flow v0.54 was deployed. To see the error delete this comment and - * run Flow. */ const requestAnimationFrame = require('fbjs/lib/requestAnimationFrame'); const React = require('react'); -const PropTypes = require('prop-types'); const ReactNative = require('react-native'); const {Text, View} = ReactNative; const {TestModule} = ReactNative.NativeModules; -class IntegrationTestHarnessTest extends React.Component< - { - shouldThrow?: boolean, - waitOneFrame?: boolean, - }, - $FlowFixMeState, -> { - static propTypes = { - shouldThrow: PropTypes.bool, - waitOneFrame: PropTypes.bool, - }; +type Props = $ReadOnly<{| + shouldThrow?: boolean, + waitOneFrame?: boolean, +|}>; + +type State = {| + done: boolean, +|}; +class IntegrationTestHarnessTest extends React.Component { state = { done: false, }; diff --git a/IntegrationTests/IntegrationTestsApp.js b/IntegrationTests/IntegrationTestsApp.js index 421b4f6abe2b19..348d0867e73e97 100644 --- a/IntegrationTests/IntegrationTestsApp.js +++ b/IntegrationTests/IntegrationTestsApp.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/IntegrationTests/LayoutEventsTest.js b/IntegrationTests/LayoutEventsTest.js index 5d2676bc1550b3..b51544b94e7f29 100644 --- a/IntegrationTests/LayoutEventsTest.js +++ b/IntegrationTests/LayoutEventsTest.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -11,11 +11,12 @@ 'use strict'; const React = require('react'); -const createReactClass = require('create-react-class'); const ReactNative = require('react-native'); const {Image, LayoutAnimation, StyleSheet, Text, View} = ReactNative; const {TestModule} = ReactNative.NativeModules; +import type {ViewStyleProp} from 'StyleSheet'; + const deepDiffer = require('deepDiffer'); function debug(...args) { @@ -23,14 +24,8 @@ function debug(...args) { } import type {Layout, LayoutEvent} from 'CoreEventTypes'; -type Style = { - margin?: number, - padding?: number, - borderColor?: string, - borderWidth?: number, - backgroundColor?: string, - width?: number, -}; + +type Props = $ReadOnly<{||}>; type State = { didAnimation: boolean, @@ -38,44 +33,58 @@ type State = { imageLayout?: Layout, textLayout?: Layout, viewLayout?: Layout, - viewStyle?: Style, - containerStyle?: Style, + viewStyle?: ViewStyleProp, + containerStyle?: ViewStyleProp, }; -const LayoutEventsTest = createReactClass({ - displayName: 'LayoutEventsTest', - getInitialState(): State { - return { - didAnimation: false, - }; - }, - animateViewLayout: function() { +class LayoutEventsTest extends React.Component { + _view: ?React.ElementRef; + _img: ?React.ElementRef; + _txt: ?React.ElementRef; + + state: State = { + didAnimation: false, + }; + + animateViewLayout() { debug('animateViewLayout invoked'); LayoutAnimation.configureNext(LayoutAnimation.Presets.spring, () => { debug('animateViewLayout done'); this.checkLayout(this.addWrapText); }); this.setState({viewStyle: {margin: 60}}); - }, - addWrapText: function() { + } + + addWrapText = () => { debug('addWrapText invoked'); this.setState( {extraText: ' And a bunch more text to wrap around a few lines.'}, () => this.checkLayout(this.changeContainer), ); - }, - changeContainer: function() { + }; + + changeContainer = () => { debug('changeContainer invoked'); this.setState({containerStyle: {width: 280}}, () => this.checkLayout(TestModule.markTestCompleted), ); - }, - checkLayout: function(next?: ?Function) { - if (!this.isMounted()) { + }; + + checkLayout = (next?: ?() => void) => { + const view = this._view; + const txt = this._txt; + const img = this._img; + + if (view == null || txt == null || img == null) { return; } - this.refs.view.measure((x, y, width, height) => { - this.compare('view', {x, y, width, height}, this.state.viewLayout); + + view.measure((x, y, width, height) => { + this.compare( + 'view', + {x, y, width, height}, + this.state.viewLayout || null, + ); if (typeof next === 'function') { next(); } else if (!this.state.didAnimation) { @@ -84,14 +93,17 @@ const LayoutEventsTest = createReactClass({ this.state.didAnimation = true; } }); - this.refs.txt.measure((x, y, width, height) => { + + txt.measure((x, y, width, height) => { this.compare('txt', {x, y, width, height}, this.state.textLayout); }); - this.refs.img.measure((x, y, width, height) => { + + img.measure((x, y, width, height) => { this.compare('img', {x, y, width, height}, this.state.imageLayout); }); - }, - compare: function(node: string, measured: any, onLayout: any): void { + }; + + compare(node: string, measured: Layout, onLayout?: ?Layout): void { if (deepDiffer(measured, onLayout)) { const data = {measured, onLayout}; throw new Error( @@ -100,34 +112,50 @@ const LayoutEventsTest = createReactClass({ JSON.stringify(data, null, ' '), ); } - }, - onViewLayout: function(e: LayoutEvent) { + } + + onViewLayout = (e: LayoutEvent) => { debug('received view layout event\n', e.nativeEvent); this.setState({viewLayout: e.nativeEvent.layout}, this.checkLayout); - }, - onTextLayout: function(e: LayoutEvent) { + }; + + onTextLayout = (e: LayoutEvent) => { debug('received text layout event\n', e.nativeEvent); this.setState({textLayout: e.nativeEvent.layout}, this.checkLayout); - }, - onImageLayout: function(e: LayoutEvent) { + }; + + onImageLayout = (e: LayoutEvent) => { debug('received image layout event\n', e.nativeEvent); this.setState({imageLayout: e.nativeEvent.layout}, this.checkLayout); - }, - render: function() { + }; + + render() { const viewStyle = [styles.view, this.state.viewStyle]; const textLayout = this.state.textLayout || {width: '?', height: '?'}; const imageLayout = this.state.imageLayout || {x: '?', y: '?'}; debug('viewLayout', this.state.viewLayout); return ( - + { + this._view = ref; + }} + onLayout={this.onViewLayout} + style={viewStyle}> { + this._img = ref; + }} onLayout={this.onImageLayout} style={styles.image} source={{uri: 'uie_thumb_big.png'}} /> - + { + this._txt = ref; + }} + onLayout={this.onTextLayout} + style={styles.text}> A simple piece of text.{this.state.extraText} @@ -138,8 +166,8 @@ const LayoutEventsTest = createReactClass({ ); - }, -}); + } +} const styles = StyleSheet.create({ container: { @@ -165,6 +193,4 @@ const styles = StyleSheet.create({ }, }); -LayoutEventsTest.displayName = 'LayoutEventsTest'; - module.exports = LayoutEventsTest; diff --git a/IntegrationTests/LoggingTestModule.js b/IntegrationTests/LoggingTestModule.js index 905abee400828d..32a049f8866265 100644 --- a/IntegrationTests/LoggingTestModule.js +++ b/IntegrationTests/LoggingTestModule.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/IntegrationTests/PromiseTest.js b/IntegrationTests/PromiseTest.js index facf8b45cdc746..c36d3beb017b69 100644 --- a/IntegrationTests/PromiseTest.js +++ b/IntegrationTests/PromiseTest.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/IntegrationTests/PropertiesUpdateTest.js b/IntegrationTests/PropertiesUpdateTest.js index 33d17da5e5c442..8c61685bf8848e 100644 --- a/IntegrationTests/PropertiesUpdateTest.js +++ b/IntegrationTests/PropertiesUpdateTest.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/IntegrationTests/RCTRootViewIntegrationTestApp.js b/IntegrationTests/RCTRootViewIntegrationTestApp.js index 6afda59cd688c1..2466b6378586eb 100644 --- a/IntegrationTests/RCTRootViewIntegrationTestApp.js +++ b/IntegrationTests/RCTRootViewIntegrationTestApp.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -9,8 +9,6 @@ 'use strict'; -require('regenerator-runtime/runtime'); - const React = require('react'); const ReactNative = require('react-native'); diff --git a/IntegrationTests/ReactContentSizeUpdateTest.js b/IntegrationTests/ReactContentSizeUpdateTest.js index be0b06b6abf56b..707abc6cb727e3 100644 --- a/IntegrationTests/ReactContentSizeUpdateTest.js +++ b/IntegrationTests/ReactContentSizeUpdateTest.js @@ -1,78 +1,89 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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 createReactClass = require('create-react-class'); const ReactNative = require('react-native'); const RCTNativeAppEventEmitter = require('RCTNativeAppEventEmitter'); -const Subscribable = require('Subscribable'); -const TimerMixin = require('react-timer-mixin'); const {View} = ReactNative; const {TestModule} = ReactNative.NativeModules; +import type EmitterSubscription from 'EmitterSubscription'; const reactViewWidth = 101; const reactViewHeight = 102; const newReactViewWidth = 201; const newReactViewHeight = 202; -const ReactContentSizeUpdateTest = createReactClass({ - displayName: 'ReactContentSizeUpdateTest', - mixins: [Subscribable.Mixin, TimerMixin], +type Props = {||}; - UNSAFE_componentWillMount: function() { - this.addListenerOn( - RCTNativeAppEventEmitter, +type State = {| + height: number, + width: number, +|}; + +class ReactContentSizeUpdateTest extends React.Component { + _timeoutID: ?TimeoutID = null; + _subscription: ?EmitterSubscription = null; + + state = { + height: reactViewHeight, + width: reactViewWidth, + }; + + UNSAFE_componentWillMount() { + this._subscription = RCTNativeAppEventEmitter.addListener( 'rootViewDidChangeIntrinsicSize', this.rootViewDidChangeIntrinsicSize, ); - }, + } - getInitialState: function() { - return { - height: reactViewHeight, - width: reactViewWidth, - }; - }, + componentDidMount() { + this._timeoutID = setTimeout(() => { + this.updateViewSize(); + }, 1000); + } + + componentWillUnmount() { + if (this._timeoutID != null) { + clearTimeout(this._timeoutID); + } - updateViewSize: function() { + if (this._subscription != null) { + this._subscription.remove(); + } + } + + updateViewSize() { this.setState({ height: newReactViewHeight, width: newReactViewWidth, }); - }, - - componentDidMount: function() { - this.setTimeout(() => { - this.updateViewSize(); - }, 1000); - }, + } - rootViewDidChangeIntrinsicSize: function(intrinsicSize) { + rootViewDidChangeIntrinsicSize = (intrinsicSize: State) => { if ( intrinsicSize.height === newReactViewHeight && intrinsicSize.width === newReactViewWidth ) { TestModule.markTestPassed(true); } - }, + }; render() { return ( ); - }, -}); - -ReactContentSizeUpdateTest.displayName = 'ReactContentSizeUpdateTest'; + } +} module.exports = ReactContentSizeUpdateTest; diff --git a/IntegrationTests/SimpleSnapshotTest.js b/IntegrationTests/SimpleSnapshotTest.js index 2857f3f41b492a..e8f530311b3794 100644 --- a/IntegrationTests/SimpleSnapshotTest.js +++ b/IntegrationTests/SimpleSnapshotTest.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/IntegrationTests/SizeFlexibilityUpdateTest.js b/IntegrationTests/SizeFlexibilityUpdateTest.js index 0d0ebd4bfc20f3..42ce5bf5fb8173 100644 --- a/IntegrationTests/SizeFlexibilityUpdateTest.js +++ b/IntegrationTests/SizeFlexibilityUpdateTest.js @@ -1,46 +1,60 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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 createReactClass = require('create-react-class'); const ReactNative = require('react-native'); const RCTNativeAppEventEmitter = require('RCTNativeAppEventEmitter'); -const Subscribable = require('Subscribable'); const {View} = ReactNative; const {TestModule} = ReactNative.NativeModules; +import type EmitterSubscription from 'EmitterSubscription'; const reactViewWidth = 111; const reactViewHeight = 222; let finalState = false; -const SizeFlexibilityUpdateTest = createReactClass({ - displayName: 'SizeFlexibilityUpdateTest', - mixins: [Subscribable.Mixin], +type Props = $ReadOnly<{| + width: boolean, + height: boolean, + both: boolean, + none: boolean, +|}>; - UNSAFE_componentWillMount: function() { - this.addListenerOn( - RCTNativeAppEventEmitter, +class SizeFlexibilityUpdateTest extends React.Component { + _subscription: ?EmitterSubscription = null; + + UNSAFE_componentWillMount() { + this._subscription = RCTNativeAppEventEmitter.addListener( 'rootViewDidChangeIntrinsicSize', this.rootViewDidChangeIntrinsicSize, ); - }, + } + + componentWillUnmount() { + if (this._subscription != null) { + this._subscription.remove(); + } + } - markPassed: function() { + markPassed = () => { TestModule.markTestPassed(true); finalState = true; - }, + }; - rootViewDidChangeIntrinsicSize: function(intrinsicSize) { + rootViewDidChangeIntrinsicSize = (intrinsicSize: { + width: number, + height: number, + }) => { if (finalState) { // If a test reaches its final state, it is not expected to do anything more TestModule.markTestPassed(false); @@ -83,13 +97,11 @@ const SizeFlexibilityUpdateTest = createReactClass({ return; } } - }, + }; render() { return ; - }, -}); - -SizeFlexibilityUpdateTest.displayName = 'SizeFlexibilityUpdateTest'; + } +} module.exports = SizeFlexibilityUpdateTest; diff --git a/IntegrationTests/SyncMethodTest.js b/IntegrationTests/SyncMethodTest.js index 6efef977d81194..d618ced4761585 100644 --- a/IntegrationTests/SyncMethodTest.js +++ b/IntegrationTests/SyncMethodTest.js @@ -1,11 +1,11 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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 + * @flow strict-local */ 'use strict'; diff --git a/IntegrationTests/TimersTest.js b/IntegrationTests/TimersTest.js index 15d42c4c852a1c..c7eefb915333c3 100644 --- a/IntegrationTests/TimersTest.js +++ b/IntegrationTests/TimersTest.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -11,75 +11,136 @@ 'use strict'; const React = require('react'); -const createReactClass = require('create-react-class'); const ReactNative = require('react-native'); -/* $FlowFixMe(>=0.54.0 site=react_native_oss) This comment suppresses an error - * found when Flow v0.54 was deployed. To see the error delete this comment and - * run Flow. */ -const TimerMixin = require('react-timer-mixin'); - const {StyleSheet, Text, View} = ReactNative; const {TestModule} = ReactNative.NativeModules; -const TimersTest = createReactClass({ - displayName: 'TimersTest', - mixins: [TimerMixin], +type Props = $ReadOnly<{||}>; - _nextTest: () => {}, - _interval: -1, +type State = {| + count: number, + done: boolean, +|}; - getInitialState() { - return { - count: 0, - done: false, - }; - }, +type ImmediateID = Object; + +class TimersTest extends React.Component { + _nextTest = () => {}; + _interval: ?IntervalID = null; + + _timeoutIDs: Set = new Set(); + _intervalIDs: Set = new Set(); + _immediateIDs: Set = new Set(); + _animationFrameIDs: Set = new Set(); + + state = { + count: 0, + done: false, + }; + + setTimeout(fn: () => void, time: number): TimeoutID { + const id = setTimeout(() => { + this._timeoutIDs.delete(id); + fn(); + }, time); + + this._timeoutIDs.add(id); + + return id; + } + + clearTimeout(id: TimeoutID) { + this._timeoutIDs.delete(id); + clearTimeout(id); + } + + setInterval(fn: () => void, time: number): IntervalID { + const id = setInterval(() => { + fn(); + }, time); + + this._intervalIDs.add(id); + + return id; + } + + clearInterval(id: IntervalID) { + this._intervalIDs.delete(id); + clearInterval(id); + } + + setImmediate(fn: () => void): ImmediateID { + const id = setImmediate(() => { + this._immediateIDs.delete(id); + fn(); + }); + + this._immediateIDs.add(id); + + return id; + } + + requestAnimationFrame(fn: () => void): AnimationFrameID { + const id = requestAnimationFrame(() => { + this._animationFrameIDs.delete(id); + fn(); + }); + + this._animationFrameIDs.add(id); + + return id; + } + + cancelAnimationFrame(id: AnimationFrameID): void { + this._animationFrameIDs.delete(id); + cancelAnimationFrame(id); + } componentDidMount() { this.setTimeout(this.testSetTimeout0, 1000); - }, + } testSetTimeout0() { this.setTimeout(this.testSetTimeout1, 0); - }, + } testSetTimeout1() { this.setTimeout(this.testSetTimeout50, 1); - }, + } testSetTimeout50() { this.setTimeout(this.testRequestAnimationFrame, 50); - }, + } testRequestAnimationFrame() { this.requestAnimationFrame(this.testSetInterval0); - }, + } testSetInterval0() { this._nextTest = this.testSetInterval20; this._interval = this.setInterval(this._incrementInterval, 0); - }, + } testSetInterval20() { this._nextTest = this.testSetImmediate; this._interval = this.setInterval(this._incrementInterval, 20); - }, + } testSetImmediate() { this.setImmediate(this.testClearTimeout0); - }, + } testClearTimeout0() { const timeout = this.setTimeout(() => this._fail('testClearTimeout0'), 0); this.clearTimeout(timeout); this.testClearTimeout30(); - }, + } testClearTimeout30() { const timeout = this.setTimeout(() => this._fail('testClearTimeout30'), 30); this.clearTimeout(timeout); this.setTimeout(this.testClearMulti, 50); - }, + } testClearMulti() { const fails = []; @@ -96,7 +157,7 @@ const TimersTest = createReactClass({ this.setTimeout(() => this.clearTimeout(delayClear), 20); this.setTimeout(this.testOrdering, 50); - }, + } testOrdering() { // Clear timers are set first because it's more likely to uncover bugs. @@ -131,42 +192,73 @@ const TimersTest = createReactClass({ 25, ); this.setTimeout(this.done, 50); - }, + } done() { this.setState({done: true}, () => { TestModule.markTestCompleted(); }); - }, + } + + componentWillUnmount() { + for (const timeoutID of this._timeoutIDs) { + clearTimeout(timeoutID); + } + + for (const intervalID of this._intervalIDs) { + clearInterval(intervalID); + } + + for (const requestAnimationFrameID of this._animationFrameIDs) { + cancelAnimationFrame(requestAnimationFrameID); + } + + for (const immediateID of this._immediateIDs) { + clearImmediate(immediateID); + } + + this._timeoutIDs = new Set(); + this._intervalIDs = new Set(); + this._animationFrameIDs = new Set(); + this._immediateIDs = new Set(); + + if (this._interval != null) { + clearInterval(this._interval); + this._interval = null; + } + } render() { return ( - {this.constructor.displayName + ': \n'} + {this.constructor.name + ': \n'} Intervals: {this.state.count + '\n'} {this.state.done ? 'Done' : 'Testing...'} ); - }, + } _incrementInterval() { if (this.state.count > 3) { throw new Error('interval incremented past end.'); } if (this.state.count === 3) { - this.clearInterval(this._interval); + if (this._interval != null) { + this.clearInterval(this._interval); + this._interval = null; + } this.setState({count: 0}, this._nextTest); return; } this.setState({count: this.state.count + 1}); - }, + } _fail(caller: string): void { throw new Error('_fail called by ' + caller); - }, -}); + } +} const styles = StyleSheet.create({ container: { @@ -175,6 +267,4 @@ const styles = StyleSheet.create({ }, }); -TimersTest.displayName = 'TimersTest'; - module.exports = TimersTest; diff --git a/IntegrationTests/WebSocketTest.js b/IntegrationTests/WebSocketTest.js index f2478cbcb68539..d1ccb68cc74a01 100644 --- a/IntegrationTests/WebSocketTest.js +++ b/IntegrationTests/WebSocketTest.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/IntegrationTests/WebViewTest.js b/IntegrationTests/WebViewTest.js index 74dbeddec6b5ce..269b9d24bdee81 100644 --- a/IntegrationTests/WebViewTest.js +++ b/IntegrationTests/WebViewTest.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/IntegrationTests/launchWebSocketServer.command b/IntegrationTests/launchWebSocketServer.command index a6531c5f8d78b2..1ce2cf5317c010 100755 --- a/IntegrationTests/launchWebSocketServer.command +++ b/IntegrationTests/launchWebSocketServer.command @@ -1,6 +1,6 @@ -#!/usr/bin/env bash +#!/bin/bash -# Copyright (c) 2015-present, Facebook, Inc. +# 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. @@ -9,7 +9,7 @@ echo -en "\033]0;Web Socket Test Server\a" clear -THIS_DIR=$(dirname "$0") +THIS_DIR=$(cd -P "$(dirname "$(readlink "${BASH_SOURCE[0]}" || echo "${BASH_SOURCE[0]}")")" && pwd) pushd "$THIS_DIR" ./websocket_integration_test_server.js popd diff --git a/IntegrationTests/websocket_integration_test_server.js b/IntegrationTests/websocket_integration_test_server.js index 50a6568710a2b8..67b358d70b09dd 100755 --- a/IntegrationTests/websocket_integration_test_server.js +++ b/IntegrationTests/websocket_integration_test_server.js @@ -1,7 +1,7 @@ #!/usr/bin/env node /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/LICENSE b/LICENSE index 9e051010d82dc6..b96dcb0480a0b0 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2015-present, Facebook, Inc. +Copyright (c) Facebook, Inc. and its affiliates. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/Libraries/ART/ARTCGFloatArray.h b/Libraries/ART/ARTCGFloatArray.h index 72286a50527e84..a607904e0be1ed 100644 --- a/Libraries/ART/ARTCGFloatArray.h +++ b/Libraries/ART/ARTCGFloatArray.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/ART/ARTContainer.h b/Libraries/ART/ARTContainer.h index 532145825bd74b..5439d9fb1d2176 100644 --- a/Libraries/ART/ARTContainer.h +++ b/Libraries/ART/ARTContainer.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/ART/ARTGroup.h b/Libraries/ART/ARTGroup.h index d9dcb48c87b180..31edddde7b664f 100644 --- a/Libraries/ART/ARTGroup.h +++ b/Libraries/ART/ARTGroup.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/ART/ARTGroup.m b/Libraries/ART/ARTGroup.m index 1bc70725c030e8..56699114f4a3f2 100644 --- a/Libraries/ART/ARTGroup.m +++ b/Libraries/ART/ARTGroup.m @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/ART/ARTNode.h b/Libraries/ART/ARTNode.h index 8b66c205ef2440..9f381115a7646e 100644 --- a/Libraries/ART/ARTNode.h +++ b/Libraries/ART/ARTNode.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/ART/ARTNode.m b/Libraries/ART/ARTNode.m index b27b014b9e7d0e..ae1a152a7d7626 100644 --- a/Libraries/ART/ARTNode.m +++ b/Libraries/ART/ARTNode.m @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/ART/ARTRenderable.h b/Libraries/ART/ARTRenderable.h index e5735a1fbd81ef..077d47ec2c6c32 100644 --- a/Libraries/ART/ARTRenderable.h +++ b/Libraries/ART/ARTRenderable.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/ART/ARTRenderable.m b/Libraries/ART/ARTRenderable.m index d7a3115586f3dd..88349f8296e7b0 100644 --- a/Libraries/ART/ARTRenderable.m +++ b/Libraries/ART/ARTRenderable.m @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/ART/ARTSerializablePath.js b/Libraries/ART/ARTSerializablePath.js index 9c2d98e033fcc3..aafb74c45d065c 100644 --- a/Libraries/ART/ARTSerializablePath.js +++ b/Libraries/ART/ARTSerializablePath.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/ART/ARTShape.h b/Libraries/ART/ARTShape.h index ce685c564b06be..1a1fd429a8bf1a 100644 --- a/Libraries/ART/ARTShape.h +++ b/Libraries/ART/ARTShape.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/ART/ARTShape.m b/Libraries/ART/ARTShape.m index 935c8894994a2b..8a1a7d6979f3e9 100644 --- a/Libraries/ART/ARTShape.m +++ b/Libraries/ART/ARTShape.m @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/ART/ARTSurfaceView.h b/Libraries/ART/ARTSurfaceView.h index cb42928cedbe12..34016b9ea7f8ef 100644 --- a/Libraries/ART/ARTSurfaceView.h +++ b/Libraries/ART/ARTSurfaceView.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/ART/ARTSurfaceView.m b/Libraries/ART/ARTSurfaceView.m index c8f46069038603..7e033690d1dc99 100644 --- a/Libraries/ART/ARTSurfaceView.m +++ b/Libraries/ART/ARTSurfaceView.m @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/ART/ARTText.h b/Libraries/ART/ARTText.h index cdf8393a137629..1431fc5e181c5e 100644 --- a/Libraries/ART/ARTText.h +++ b/Libraries/ART/ARTText.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/ART/ARTText.m b/Libraries/ART/ARTText.m index 0953c850dc293e..5bcebdf5559942 100644 --- a/Libraries/ART/ARTText.m +++ b/Libraries/ART/ARTText.m @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/ART/ARTTextFrame.h b/Libraries/ART/ARTTextFrame.h index 8ad06e0a01baed..1c02d3e04260b0 100644 --- a/Libraries/ART/ARTTextFrame.h +++ b/Libraries/ART/ARTTextFrame.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/ART/Brushes/ARTBrush.h b/Libraries/ART/Brushes/ARTBrush.h index 95709e65f19bc9..f6e39e861f737c 100644 --- a/Libraries/ART/Brushes/ARTBrush.h +++ b/Libraries/ART/Brushes/ARTBrush.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/ART/Brushes/ARTBrush.m b/Libraries/ART/Brushes/ARTBrush.m index 4ade2c221143f7..969ad5d7edb363 100644 --- a/Libraries/ART/Brushes/ARTBrush.m +++ b/Libraries/ART/Brushes/ARTBrush.m @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/ART/Brushes/ARTLinearGradient.h b/Libraries/ART/Brushes/ARTLinearGradient.h index 8e6abbc5fbbfde..d289b192a51b1e 100644 --- a/Libraries/ART/Brushes/ARTLinearGradient.h +++ b/Libraries/ART/Brushes/ARTLinearGradient.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/ART/Brushes/ARTLinearGradient.m b/Libraries/ART/Brushes/ARTLinearGradient.m index 1415a6ffcbc80f..20bd1af6233b4e 100644 --- a/Libraries/ART/Brushes/ARTLinearGradient.m +++ b/Libraries/ART/Brushes/ARTLinearGradient.m @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/ART/Brushes/ARTPattern.h b/Libraries/ART/Brushes/ARTPattern.h index ce1767cc9b0bc8..11fa9354de29d0 100644 --- a/Libraries/ART/Brushes/ARTPattern.h +++ b/Libraries/ART/Brushes/ARTPattern.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/ART/Brushes/ARTPattern.m b/Libraries/ART/Brushes/ARTPattern.m index 5c43586452d198..70e0bd25f367b7 100644 --- a/Libraries/ART/Brushes/ARTPattern.m +++ b/Libraries/ART/Brushes/ARTPattern.m @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/ART/Brushes/ARTRadialGradient.h b/Libraries/ART/Brushes/ARTRadialGradient.h index d7895f8b74d084..98bec026385014 100644 --- a/Libraries/ART/Brushes/ARTRadialGradient.h +++ b/Libraries/ART/Brushes/ARTRadialGradient.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/ART/Brushes/ARTRadialGradient.m b/Libraries/ART/Brushes/ARTRadialGradient.m index 19db9cb97b567a..c36f6ce57fc1fc 100644 --- a/Libraries/ART/Brushes/ARTRadialGradient.m +++ b/Libraries/ART/Brushes/ARTRadialGradient.m @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/ART/Brushes/ARTSolidColor.h b/Libraries/ART/Brushes/ARTSolidColor.h index a16c2b915c72f8..9880cfd61675ff 100644 --- a/Libraries/ART/Brushes/ARTSolidColor.h +++ b/Libraries/ART/Brushes/ARTSolidColor.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/ART/Brushes/ARTSolidColor.m b/Libraries/ART/Brushes/ARTSolidColor.m index 096c4e043ed429..2ef02d43d98592 100644 --- a/Libraries/ART/Brushes/ARTSolidColor.m +++ b/Libraries/ART/Brushes/ARTSolidColor.m @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/ART/RCTConvert+ART.h b/Libraries/ART/RCTConvert+ART.h index 1deb3c600176ab..ffc1deafe4e6e7 100644 --- a/Libraries/ART/RCTConvert+ART.h +++ b/Libraries/ART/RCTConvert+ART.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/ART/RCTConvert+ART.m b/Libraries/ART/RCTConvert+ART.m index ea22d5426f18f9..3312e319436369 100644 --- a/Libraries/ART/RCTConvert+ART.m +++ b/Libraries/ART/RCTConvert+ART.m @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/ART/ReactNativeART.js b/Libraries/ART/ReactNativeART.js index cf56028b102cab..12af4f0b2edc08 100644 --- a/Libraries/ART/ReactNativeART.js +++ b/Libraries/ART/ReactNativeART.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -11,7 +11,6 @@ const Color = require('art/core/color'); const Path = require('ARTSerializablePath'); -const Platform = require('Platform'); const Transform = require('art/core/transform'); const React = require('React'); @@ -154,11 +153,8 @@ class Surface extends React.Component { const height = extractNumber(this.props.height, 0); const width = extractNumber(this.props.width, 0); - // WORKAROUND: Android bug in which canvas does not reflect size changes. - const key = Platform.OS === 'android' ? height + ',' + width : null; - return ( - + {this.props.children} ); diff --git a/Libraries/ART/ViewManagers/ARTGroupManager.h b/Libraries/ART/ViewManagers/ARTGroupManager.h index a35e09481be639..f518cf0efbdbb3 100644 --- a/Libraries/ART/ViewManagers/ARTGroupManager.h +++ b/Libraries/ART/ViewManagers/ARTGroupManager.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/ART/ViewManagers/ARTGroupManager.m b/Libraries/ART/ViewManagers/ARTGroupManager.m index 2de0d0e5688739..9fb45d71bbdf4d 100644 --- a/Libraries/ART/ViewManagers/ARTGroupManager.m +++ b/Libraries/ART/ViewManagers/ARTGroupManager.m @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/ART/ViewManagers/ARTNodeManager.h b/Libraries/ART/ViewManagers/ARTNodeManager.h index 3a8f99e7abdc7a..84ef8fb01cf3d4 100644 --- a/Libraries/ART/ViewManagers/ARTNodeManager.h +++ b/Libraries/ART/ViewManagers/ARTNodeManager.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/ART/ViewManagers/ARTNodeManager.m b/Libraries/ART/ViewManagers/ARTNodeManager.m index 8e568ce6d8efd4..62680975ba1033 100644 --- a/Libraries/ART/ViewManagers/ARTNodeManager.m +++ b/Libraries/ART/ViewManagers/ARTNodeManager.m @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/ART/ViewManagers/ARTRenderableManager.h b/Libraries/ART/ViewManagers/ARTRenderableManager.h index 1e4b554f0f79f7..781ed32f8f574d 100644 --- a/Libraries/ART/ViewManagers/ARTRenderableManager.h +++ b/Libraries/ART/ViewManagers/ARTRenderableManager.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/ART/ViewManagers/ARTRenderableManager.m b/Libraries/ART/ViewManagers/ARTRenderableManager.m index a30841b50c1046..ad0264965391e5 100644 --- a/Libraries/ART/ViewManagers/ARTRenderableManager.m +++ b/Libraries/ART/ViewManagers/ARTRenderableManager.m @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/ART/ViewManagers/ARTShapeManager.h b/Libraries/ART/ViewManagers/ARTShapeManager.h index 2f31b23a0eab10..cc514b159ee192 100644 --- a/Libraries/ART/ViewManagers/ARTShapeManager.h +++ b/Libraries/ART/ViewManagers/ARTShapeManager.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/ART/ViewManagers/ARTShapeManager.m b/Libraries/ART/ViewManagers/ARTShapeManager.m index 57b603ca1a16b6..cb056e5d268877 100644 --- a/Libraries/ART/ViewManagers/ARTShapeManager.m +++ b/Libraries/ART/ViewManagers/ARTShapeManager.m @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/ART/ViewManagers/ARTSurfaceViewManager.h b/Libraries/ART/ViewManagers/ARTSurfaceViewManager.h index 5915536bd6f917..36d5949a90ab4d 100644 --- a/Libraries/ART/ViewManagers/ARTSurfaceViewManager.h +++ b/Libraries/ART/ViewManagers/ARTSurfaceViewManager.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/ART/ViewManagers/ARTSurfaceViewManager.m b/Libraries/ART/ViewManagers/ARTSurfaceViewManager.m index 54052a331d4585..1a03897937e860 100644 --- a/Libraries/ART/ViewManagers/ARTSurfaceViewManager.m +++ b/Libraries/ART/ViewManagers/ARTSurfaceViewManager.m @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/ART/ViewManagers/ARTTextManager.h b/Libraries/ART/ViewManagers/ARTTextManager.h index c7d5304da3a3eb..343e669af7553c 100644 --- a/Libraries/ART/ViewManagers/ARTTextManager.h +++ b/Libraries/ART/ViewManagers/ARTTextManager.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/ART/ViewManagers/ARTTextManager.m b/Libraries/ART/ViewManagers/ARTTextManager.m index ac6688c3d925b9..35c53811fd9509 100644 --- a/Libraries/ART/ViewManagers/ARTTextManager.m +++ b/Libraries/ART/ViewManagers/ARTTextManager.m @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/ActionSheetIOS/ActionSheetIOS.js b/Libraries/ActionSheetIOS/ActionSheetIOS.js index b135a23e5fc998..ea2e01f9dd9b8a 100644 --- a/Libraries/ActionSheetIOS/ActionSheetIOS.js +++ b/Libraries/ActionSheetIOS/ActionSheetIOS.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/ActionSheetIOS/RCTActionSheetManager.h b/Libraries/ActionSheetIOS/RCTActionSheetManager.h index b9a5b2df7329a1..53184041393cd4 100644 --- a/Libraries/ActionSheetIOS/RCTActionSheetManager.h +++ b/Libraries/ActionSheetIOS/RCTActionSheetManager.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/ActionSheetIOS/RCTActionSheetManager.m b/Libraries/ActionSheetIOS/RCTActionSheetManager.m index cd5d5719ff769c..af1e202c962409 100644 --- a/Libraries/ActionSheetIOS/RCTActionSheetManager.m +++ b/Libraries/ActionSheetIOS/RCTActionSheetManager.m @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Alert/Alert.js b/Libraries/Alert/Alert.js index a424f5026d5a8c..ceab6763680b8e 100644 --- a/Libraries/Alert/Alert.js +++ b/Libraries/Alert/Alert.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Alert/AlertIOS.js b/Libraries/Alert/AlertIOS.js index 1998865b2d597c..b7e1a0d73b7b59 100644 --- a/Libraries/Alert/AlertIOS.js +++ b/Libraries/Alert/AlertIOS.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Alert/RCTAlertManager.android.js b/Libraries/Alert/RCTAlertManager.android.js index 2e510add8ddaca..b16298f01ff3f2 100644 --- a/Libraries/Alert/RCTAlertManager.android.js +++ b/Libraries/Alert/RCTAlertManager.android.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2013-present, Facebook, Inc. + * 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. diff --git a/Libraries/Alert/RCTAlertManager.ios.js b/Libraries/Alert/RCTAlertManager.ios.js index 529bb5da0e55f2..a300de65521d97 100644 --- a/Libraries/Alert/RCTAlertManager.ios.js +++ b/Libraries/Alert/RCTAlertManager.ios.js @@ -1,11 +1,11 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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 + * @flow strict-local */ 'use strict'; diff --git a/Libraries/Animated/release/.gitignore b/Libraries/Animated/release/.gitignore new file mode 100644 index 00000000000000..4c422f3bc92283 --- /dev/null +++ b/Libraries/Animated/release/.gitignore @@ -0,0 +1,3 @@ +/lib/ +/dist/ +/node_modules/ diff --git a/Libraries/Animated/release/gulpfile.js b/Libraries/Animated/release/gulpfile.js index b5599e9365fef3..291f3236303d87 100644 --- a/Libraries/Animated/release/gulpfile.js +++ b/Libraries/Animated/release/gulpfile.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2013-present, Facebook, Inc. + * 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. diff --git a/Libraries/Animated/release/package.json b/Libraries/Animated/release/package.json index 49f6a2081ffd14..4873f784a5ffad 100644 --- a/Libraries/Animated/release/package.json +++ b/Libraries/Animated/release/package.json @@ -10,7 +10,7 @@ "license": "MIT", "main": "Animated.js", "dependencies": { - "fbjs": "0.8.17" + "fbjs": "^1.0.0" }, "scripts": { "build": "gulp" diff --git a/Libraries/Animated/src/Animated.js b/Libraries/Animated/src/Animated.js index 8678b21f14b889..f04de4a7aff3f1 100644 --- a/Libraries/Animated/src/Animated.js +++ b/Libraries/Animated/src/Animated.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -11,15 +11,25 @@ 'use strict'; const AnimatedImplementation = require('AnimatedImplementation'); -const Image = require('Image'); -const ScrollView = require('ScrollView'); -const Text = require('Text'); -const View = require('View'); module.exports = { + get FlatList() { + return require('AnimatedFlatList'); + }, + get Image() { + return require('AnimatedImage'); + }, + get ScrollView() { + return require('AnimatedScrollView'); + }, + get SectionList() { + return require('AnimatedSectionList'); + }, + get Text() { + return require('AnimatedText'); + }, + get View() { + return require('AnimatedView'); + }, ...AnimatedImplementation, - View: AnimatedImplementation.createAnimatedComponent(View), - Text: AnimatedImplementation.createAnimatedComponent(Text), - Image: AnimatedImplementation.createAnimatedComponent(Image), - ScrollView: AnimatedImplementation.createAnimatedComponent(ScrollView), }; diff --git a/Libraries/Animated/src/AnimatedEvent.js b/Libraries/Animated/src/AnimatedEvent.js index 084632737c661d..c4d1b88290e5cb 100644 --- a/Libraries/Animated/src/AnimatedEvent.js +++ b/Libraries/Animated/src/AnimatedEvent.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Animated/src/AnimatedImplementation.js b/Libraries/Animated/src/AnimatedImplementation.js index 2c1ce431d10686..57e34ce6e9eee3 100644 --- a/Libraries/Animated/src/AnimatedImplementation.js +++ b/Libraries/Animated/src/AnimatedImplementation.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Animated/src/AnimatedWeb.js b/Libraries/Animated/src/AnimatedWeb.js index e80023d73687a4..cf105d4af58a6c 100644 --- a/Libraries/Animated/src/AnimatedWeb.js +++ b/Libraries/Animated/src/AnimatedWeb.js @@ -1,11 +1,11 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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 + * @flow strict-local */ 'use strict'; diff --git a/Libraries/Animated/src/Easing.js b/Libraries/Animated/src/Easing.js index 94fb865882c040..8f38322a873df1 100644 --- a/Libraries/Animated/src/Easing.js +++ b/Libraries/Animated/src/Easing.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Animated/src/NativeAnimatedHelper.js b/Libraries/Animated/src/NativeAnimatedHelper.js index 3142ea24c084d1..f60a2de0c3b4c4 100644 --- a/Libraries/Animated/src/NativeAnimatedHelper.js +++ b/Libraries/Animated/src/NativeAnimatedHelper.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -153,6 +153,7 @@ const STYLES_WHITELIST = { borderTopLeftRadius: true, borderTopRightRadius: true, borderTopStartRadius: true, + elevation: true, /* ios styles */ shadowOpacity: true, shadowRadius: true, diff --git a/Libraries/Animated/src/SpringConfig.js b/Libraries/Animated/src/SpringConfig.js index 456af9c40ec1ae..e226a3173a1902 100644 --- a/Libraries/Animated/src/SpringConfig.js +++ b/Libraries/Animated/src/SpringConfig.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Animated/src/__tests__/Animated-test.js b/Libraries/Animated/src/__tests__/Animated-test.js index 6c5ef66b14a170..930d8a020f2bff 100644 --- a/Libraries/Animated/src/__tests__/Animated-test.js +++ b/Libraries/Animated/src/__tests__/Animated-test.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -134,7 +134,9 @@ describe('Animated tests', () => { expect(callback).toBeCalled(); }); - it('send toValue when an underdamped spring stops', () => { + // This test is flaky and we are asking open source to fix it + // https://github.com/facebook/react-native/issues/21517 + it.skip('send toValue when an underdamped spring stops', () => { const anim = new Animated.Value(0); const listener = jest.fn(); anim.addListener(listener); diff --git a/Libraries/Animated/src/__tests__/AnimatedNative-test.js b/Libraries/Animated/src/__tests__/AnimatedNative-test.js index d3ff6665cbc81f..fb6257f15d8183 100644 --- a/Libraries/Animated/src/__tests__/AnimatedNative-test.js +++ b/Libraries/Animated/src/__tests__/AnimatedNative-test.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -19,6 +19,8 @@ jest .setMock('View', ClassComponentMock) .setMock('Image', ClassComponentMock) .setMock('ScrollView', ClassComponentMock) + .setMock('FlatList', ClassComponentMock) + .setMock('SectionList', ClassComponentMock) .setMock('React', {Component: class {}}) .setMock('NativeModules', { NativeAnimatedModule: {}, diff --git a/Libraries/Animated/src/__tests__/Easing-test.js b/Libraries/Animated/src/__tests__/Easing-test.js index 0284f3f0b697ef..1cb6152538fec2 100644 --- a/Libraries/Animated/src/__tests__/Easing-test.js +++ b/Libraries/Animated/src/__tests__/Easing-test.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Animated/src/__tests__/Interpolation-test.js b/Libraries/Animated/src/__tests__/Interpolation-test.js index 5515f09bacd0bc..6b77584b00d8ab 100644 --- a/Libraries/Animated/src/__tests__/Interpolation-test.js +++ b/Libraries/Animated/src/__tests__/Interpolation-test.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Animated/src/animations/Animation.js b/Libraries/Animated/src/animations/Animation.js index b4e38016dba557..b34ac9555a1eca 100644 --- a/Libraries/Animated/src/animations/Animation.js +++ b/Libraries/Animated/src/animations/Animation.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Animated/src/animations/DecayAnimation.js b/Libraries/Animated/src/animations/DecayAnimation.js index a6fe05bb3f6343..0e09b6144d30e1 100644 --- a/Libraries/Animated/src/animations/DecayAnimation.js +++ b/Libraries/Animated/src/animations/DecayAnimation.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Animated/src/animations/SpringAnimation.js b/Libraries/Animated/src/animations/SpringAnimation.js index a0f38d3b024e5c..a44c181eb25dfe 100644 --- a/Libraries/Animated/src/animations/SpringAnimation.js +++ b/Libraries/Animated/src/animations/SpringAnimation.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Animated/src/animations/TimingAnimation.js b/Libraries/Animated/src/animations/TimingAnimation.js index 694a52c0a39f7b..61ad74e9e1f5f0 100644 --- a/Libraries/Animated/src/animations/TimingAnimation.js +++ b/Libraries/Animated/src/animations/TimingAnimation.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Animated/src/components/AnimatedFlatList.js b/Libraries/Animated/src/components/AnimatedFlatList.js new file mode 100644 index 00000000000000..af69ff3674769e --- /dev/null +++ b/Libraries/Animated/src/components/AnimatedFlatList.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. + * + * @flow strict-local + * @format + */ + +'use strict'; + +const FlatList = require('FlatList'); + +const createAnimatedComponent = require('createAnimatedComponent'); + +module.exports = createAnimatedComponent(FlatList); diff --git a/Libraries/Animated/src/components/AnimatedImage.js b/Libraries/Animated/src/components/AnimatedImage.js new file mode 100644 index 00000000000000..e7d0bc4429513a --- /dev/null +++ b/Libraries/Animated/src/components/AnimatedImage.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. + * + * @flow strict-local + * @format + */ + +'use strict'; + +const Image = require('Image'); + +const createAnimatedComponent = require('createAnimatedComponent'); + +module.exports = createAnimatedComponent(Image); diff --git a/Libraries/Animated/src/components/AnimatedScrollView.js b/Libraries/Animated/src/components/AnimatedScrollView.js new file mode 100644 index 00000000000000..195f17b7005ad7 --- /dev/null +++ b/Libraries/Animated/src/components/AnimatedScrollView.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. + * + * @flow strict-local + * @format + */ + +'use strict'; + +const ScrollView = require('ScrollView'); + +const createAnimatedComponent = require('createAnimatedComponent'); + +module.exports = createAnimatedComponent(ScrollView); diff --git a/Libraries/Animated/src/components/AnimatedSectionList.js b/Libraries/Animated/src/components/AnimatedSectionList.js new file mode 100644 index 00000000000000..482e203abac637 --- /dev/null +++ b/Libraries/Animated/src/components/AnimatedSectionList.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. + * + * @flow strict-local + * @format + */ + +'use strict'; + +const SectionList = require('SectionList'); + +const createAnimatedComponent = require('createAnimatedComponent'); + +module.exports = createAnimatedComponent(SectionList); diff --git a/Libraries/Animated/src/components/AnimatedText.js b/Libraries/Animated/src/components/AnimatedText.js new file mode 100644 index 00000000000000..870ba144b10207 --- /dev/null +++ b/Libraries/Animated/src/components/AnimatedText.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. + * + * @flow strict-local + * @format + */ + +'use strict'; + +const Text = require('Text'); + +const createAnimatedComponent = require('createAnimatedComponent'); + +module.exports = createAnimatedComponent(Text); diff --git a/Libraries/Animated/src/components/AnimatedView.js b/Libraries/Animated/src/components/AnimatedView.js new file mode 100644 index 00000000000000..396760d999485f --- /dev/null +++ b/Libraries/Animated/src/components/AnimatedView.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. + * + * @flow strict-local + * @format + */ + +'use strict'; + +const View = require('View'); + +const createAnimatedComponent = require('createAnimatedComponent'); + +module.exports = createAnimatedComponent(View); diff --git a/Libraries/Animated/src/createAnimatedComponent.js b/Libraries/Animated/src/createAnimatedComponent.js index a4177d65be0e40..d705d6eebaa8be 100644 --- a/Libraries/Animated/src/createAnimatedComponent.js +++ b/Libraries/Animated/src/createAnimatedComponent.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -12,7 +12,7 @@ const {AnimatedEvent} = require('./AnimatedEvent'); const AnimatedProps = require('./nodes/AnimatedProps'); const React = require('React'); -const ViewStylePropTypes = require('ViewStylePropTypes'); +const DeprecatedViewStylePropTypes = require('DeprecatedViewStylePropTypes'); const invariant = require('fbjs/lib/invariant'); @@ -184,7 +184,7 @@ function createAnimatedComponent(Component: any): any { return; } - for (const key in ViewStylePropTypes) { + for (const key in DeprecatedViewStylePropTypes) { if (!propTypes[key] && props[key] !== undefined) { console.warn( 'You are setting the style `{ ' + diff --git a/Libraries/Animated/src/nodes/AnimatedAddition.js b/Libraries/Animated/src/nodes/AnimatedAddition.js index 60713da500213c..f3d6b55167f404 100644 --- a/Libraries/Animated/src/nodes/AnimatedAddition.js +++ b/Libraries/Animated/src/nodes/AnimatedAddition.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Animated/src/nodes/AnimatedDiffClamp.js b/Libraries/Animated/src/nodes/AnimatedDiffClamp.js index 4219eccfb377ff..3b657ef75ee23f 100644 --- a/Libraries/Animated/src/nodes/AnimatedDiffClamp.js +++ b/Libraries/Animated/src/nodes/AnimatedDiffClamp.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Animated/src/nodes/AnimatedDivision.js b/Libraries/Animated/src/nodes/AnimatedDivision.js index 3498d322211f64..9efb4214dfa41f 100644 --- a/Libraries/Animated/src/nodes/AnimatedDivision.js +++ b/Libraries/Animated/src/nodes/AnimatedDivision.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Animated/src/nodes/AnimatedInterpolation.js b/Libraries/Animated/src/nodes/AnimatedInterpolation.js index 8ee7cbba8a7fc0..d314e078063ec3 100644 --- a/Libraries/Animated/src/nodes/AnimatedInterpolation.js +++ b/Libraries/Animated/src/nodes/AnimatedInterpolation.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Animated/src/nodes/AnimatedModulo.js b/Libraries/Animated/src/nodes/AnimatedModulo.js index a3968566e9a2c4..a0cad545101ccb 100644 --- a/Libraries/Animated/src/nodes/AnimatedModulo.js +++ b/Libraries/Animated/src/nodes/AnimatedModulo.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Animated/src/nodes/AnimatedMultiplication.js b/Libraries/Animated/src/nodes/AnimatedMultiplication.js index 889f530c76baee..b031ba613dc805 100644 --- a/Libraries/Animated/src/nodes/AnimatedMultiplication.js +++ b/Libraries/Animated/src/nodes/AnimatedMultiplication.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Animated/src/nodes/AnimatedNode.js b/Libraries/Animated/src/nodes/AnimatedNode.js index 34e010a62f8c45..94532087d201eb 100644 --- a/Libraries/Animated/src/nodes/AnimatedNode.js +++ b/Libraries/Animated/src/nodes/AnimatedNode.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Animated/src/nodes/AnimatedProps.js b/Libraries/Animated/src/nodes/AnimatedProps.js index 75c9c25487135a..92c5012075fc85 100644 --- a/Libraries/Animated/src/nodes/AnimatedProps.js +++ b/Libraries/Animated/src/nodes/AnimatedProps.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Animated/src/nodes/AnimatedStyle.js b/Libraries/Animated/src/nodes/AnimatedStyle.js index 990b960a336805..e1f3d332a2280f 100644 --- a/Libraries/Animated/src/nodes/AnimatedStyle.js +++ b/Libraries/Animated/src/nodes/AnimatedStyle.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -95,13 +95,13 @@ class AnimatedStyle extends AnimatedWithChildren { } __makeNative() { - super.__makeNative(); for (const key in this._style) { const value = this._style[key]; if (value instanceof AnimatedNode) { value.__makeNative(); } } + super.__makeNative(); } __getNativeConfig(): Object { diff --git a/Libraries/Animated/src/nodes/AnimatedSubtraction.js b/Libraries/Animated/src/nodes/AnimatedSubtraction.js index 3fe8bbb6920703..c79860a4095074 100644 --- a/Libraries/Animated/src/nodes/AnimatedSubtraction.js +++ b/Libraries/Animated/src/nodes/AnimatedSubtraction.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Animated/src/nodes/AnimatedTracking.js b/Libraries/Animated/src/nodes/AnimatedTracking.js index 699da167c7b2c7..284d5b39af7a0b 100644 --- a/Libraries/Animated/src/nodes/AnimatedTracking.js +++ b/Libraries/Animated/src/nodes/AnimatedTracking.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Animated/src/nodes/AnimatedTransform.js b/Libraries/Animated/src/nodes/AnimatedTransform.js index 1706923394ec96..703fa51ceb4e1b 100644 --- a/Libraries/Animated/src/nodes/AnimatedTransform.js +++ b/Libraries/Animated/src/nodes/AnimatedTransform.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -22,7 +22,6 @@ class AnimatedTransform extends AnimatedWithChildren { } __makeNative() { - super.__makeNative(); this._transforms.forEach(transform => { for (const key in transform) { const value = transform[key]; @@ -31,6 +30,7 @@ class AnimatedTransform extends AnimatedWithChildren { } } }); + super.__makeNative(); } __getValue(): $ReadOnlyArray { diff --git a/Libraries/Animated/src/nodes/AnimatedValue.js b/Libraries/Animated/src/nodes/AnimatedValue.js index a3fb3a325b838e..7c4fe9817f98dd 100644 --- a/Libraries/Animated/src/nodes/AnimatedValue.js +++ b/Libraries/Animated/src/nodes/AnimatedValue.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Animated/src/nodes/AnimatedValueXY.js b/Libraries/Animated/src/nodes/AnimatedValueXY.js index 3de5bbaf9d3a04..a8168c591039ad 100644 --- a/Libraries/Animated/src/nodes/AnimatedValueXY.js +++ b/Libraries/Animated/src/nodes/AnimatedValueXY.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Animated/src/nodes/AnimatedWithChildren.js b/Libraries/Animated/src/nodes/AnimatedWithChildren.js index 9cd5fb49e14070..3940c4ae206082 100644 --- a/Libraries/Animated/src/nodes/AnimatedWithChildren.js +++ b/Libraries/Animated/src/nodes/AnimatedWithChildren.js @@ -1,10 +1,10 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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 + * @flow strict-local * @format */ 'use strict'; diff --git a/Libraries/Animated/src/polyfills/InteractionManager.js b/Libraries/Animated/src/polyfills/InteractionManager.js index 5e82aaaa544cdb..c2247c762a3da0 100644 --- a/Libraries/Animated/src/polyfills/InteractionManager.js +++ b/Libraries/Animated/src/polyfills/InteractionManager.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Animated/src/polyfills/Set.js b/Libraries/Animated/src/polyfills/Set.js index c88278bda1cb38..39205b8f9f9920 100644 --- a/Libraries/Animated/src/polyfills/Set.js +++ b/Libraries/Animated/src/polyfills/Set.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Animated/src/polyfills/flattenStyle.js b/Libraries/Animated/src/polyfills/flattenStyle.js index 21907b235f97f5..b50057af28435f 100644 --- a/Libraries/Animated/src/polyfills/flattenStyle.js +++ b/Libraries/Animated/src/polyfills/flattenStyle.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/AppState/AppState.js b/Libraries/AppState/AppState.js index 554689f11ad680..8918225ec92365 100644 --- a/Libraries/AppState/AppState.js +++ b/Libraries/AppState/AppState.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/BatchedBridge/BatchedBridge.js b/Libraries/BatchedBridge/BatchedBridge.js index 0b1aae766493e6..663b0051457e24 100644 --- a/Libraries/BatchedBridge/BatchedBridge.js +++ b/Libraries/BatchedBridge/BatchedBridge.js @@ -1,11 +1,11 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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 + * @flow strict-local */ 'use strict'; diff --git a/Libraries/BatchedBridge/MessageQueue.js b/Libraries/BatchedBridge/MessageQueue.js index c9b750df9efdc8..a7f1f5a3a5aacd 100644 --- a/Libraries/BatchedBridge/MessageQueue.js +++ b/Libraries/BatchedBridge/MessageQueue.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -60,7 +60,7 @@ class MessageQueue { this._failureCallbacks = {}; this._callID = 0; this._lastFlush = 0; - this._eventLoopStartTime = new Date().getTime(); + this._eventLoopStartTime = Date.now(); this._immediatesCallback = null; if (__DEV__) { @@ -141,7 +141,7 @@ class MessageQueue { } getEventLoopRunningTime() { - return new Date().getTime() - this._eventLoopStartTime; + return Date.now() - this._eventLoopStartTime; } registerCallableModule(name: string, module: Object) { @@ -213,11 +213,13 @@ class MessageQueue { t === 'undefined' || t === 'null' || t === 'boolean' || - t === 'number' || t === 'string' ) { return true; } + if (t === 'number') { + return isFinite(val); + } if (t === 'function' || t !== 'object') { return false; } @@ -232,10 +234,25 @@ class MessageQueue { return true; }; + // Replacement allows normally non-JSON-convertible values to be + // seen. There is ambiguity with string values, but in context, + // it should at least be a strong hint. + const replacer = (key, val) => { + const t = typeof val; + if (t === 'function') { + return '<>'; + } else if (t === 'number' && !isFinite(val)) { + return '<<' + val.toString() + '>>'; + } else { + return val; + } + }; + + // Note that JSON.stringify invariant( isValidArgument(params), '%s is not usable as a native method argument', - params, + JSON.stringify(params, replacer), ); // The params object should not be mutated after being queued @@ -243,7 +260,7 @@ class MessageQueue { } this._queue[PARAMS].push(params); - const now = new Date().getTime(); + const now = Date.now(); if ( global.nativeFlushQueueImmediate && now - this._lastFlush >= MIN_TIME_BETWEEN_FLUSHES_MS @@ -323,7 +340,7 @@ class MessageQueue { } __callFunction(module: string, method: string, args: any[]): any { - this._lastFlush = new Date().getTime(); + this._lastFlush = Date.now(); this._eventLoopStartTime = this._lastFlush; if (__DEV__ || this.__spy) { Systrace.beginEvent(`${module}.${method}(${stringifySafe(args)})`); @@ -352,7 +369,7 @@ class MessageQueue { } __invokeCallback(cbID: number, args: any[]) { - this._lastFlush = new Date().getTime(); + this._lastFlush = Date.now(); this._eventLoopStartTime = this._lastFlush; // The rightmost bit of cbID indicates fail (0) or success (1), the other bits are the callID shifted left. diff --git a/Libraries/BatchedBridge/NativeModules.js b/Libraries/BatchedBridge/NativeModules.js index 61dd5bff1e61df..203cce932e0bae 100644 --- a/Libraries/BatchedBridge/NativeModules.js +++ b/Libraries/BatchedBridge/NativeModules.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/BatchedBridge/__mocks__/MessageQueueTestConfig.js b/Libraries/BatchedBridge/__mocks__/MessageQueueTestConfig.js index 3f9ae5f0a4855c..bb50f5d2fa7b50 100644 --- a/Libraries/BatchedBridge/__mocks__/MessageQueueTestConfig.js +++ b/Libraries/BatchedBridge/__mocks__/MessageQueueTestConfig.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2013-present, Facebook, Inc. + * 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. diff --git a/Libraries/BatchedBridge/__mocks__/MessageQueueTestModule.js b/Libraries/BatchedBridge/__mocks__/MessageQueueTestModule.js index 05168a6b570094..37425cd7652706 100644 --- a/Libraries/BatchedBridge/__mocks__/MessageQueueTestModule.js +++ b/Libraries/BatchedBridge/__mocks__/MessageQueueTestModule.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2013-present, Facebook, Inc. + * 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. diff --git a/Libraries/BatchedBridge/__tests__/MessageQueue-test.js b/Libraries/BatchedBridge/__tests__/MessageQueue-test.js index 555a9e2053be33..77cd6948124487 100644 --- a/Libraries/BatchedBridge/__tests__/MessageQueue-test.js +++ b/Libraries/BatchedBridge/__tests__/MessageQueue-test.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2013-present, Facebook, Inc. + * 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. diff --git a/Libraries/BatchedBridge/__tests__/NativeModules-test.js b/Libraries/BatchedBridge/__tests__/NativeModules-test.js index 9702146b719090..821c3261a4169a 100644 --- a/Libraries/BatchedBridge/__tests__/NativeModules-test.js +++ b/Libraries/BatchedBridge/__tests__/NativeModules-test.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2013-present, Facebook, Inc. + * 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. @@ -10,12 +10,7 @@ 'use strict'; -jest - .enableAutomock() - .unmock('BatchedBridge') - .unmock('defineLazyObjectProperty') - .unmock('MessageQueue') - .unmock('NativeModules'); +jest.unmock('NativeModules'); let BatchedBridge; let NativeModules; diff --git a/Libraries/Blob/Blob.js b/Libraries/Blob/Blob.js index 0e36b07f7f4e5a..c7e013dfa0b530 100644 --- a/Libraries/Blob/Blob.js +++ b/Libraries/Blob/Blob.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2013-present, Facebook, Inc. + * 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. diff --git a/Libraries/Blob/BlobManager.js b/Libraries/Blob/BlobManager.js index b08082e35e1580..460980bb5b21ef 100644 --- a/Libraries/Blob/BlobManager.js +++ b/Libraries/Blob/BlobManager.js @@ -1,10 +1,10 @@ /** - * Copyright (c) 2013-present, Facebook, Inc. + * 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 + * @flow strict-local * @format */ diff --git a/Libraries/Blob/BlobRegistry.js b/Libraries/Blob/BlobRegistry.js index 445fe6bb855835..cfd0475a53ea07 100644 --- a/Libraries/Blob/BlobRegistry.js +++ b/Libraries/Blob/BlobRegistry.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2013-present, Facebook, Inc. + * 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. diff --git a/Libraries/Blob/BlobTypes.js b/Libraries/Blob/BlobTypes.js index 2e5be53e19615f..de105d2a6904d3 100644 --- a/Libraries/Blob/BlobTypes.js +++ b/Libraries/Blob/BlobTypes.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2013-present, Facebook, Inc. + * 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. diff --git a/Libraries/Blob/File.js b/Libraries/Blob/File.js index 2f57183cdb3f19..fcad0d0bc1415c 100644 --- a/Libraries/Blob/File.js +++ b/Libraries/Blob/File.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2013-present, Facebook, Inc. + * 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. diff --git a/Libraries/Blob/FileReader.js b/Libraries/Blob/FileReader.js index 309e4577a455f8..b9181ed9aaa34b 100644 --- a/Libraries/Blob/FileReader.js +++ b/Libraries/Blob/FileReader.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Blob/RCTBlobManager.h b/Libraries/Blob/RCTBlobManager.h index 24b589ef987ae5..1d5750799e3d29 100755 --- a/Libraries/Blob/RCTBlobManager.h +++ b/Libraries/Blob/RCTBlobManager.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Blob/RCTBlobManager.mm b/Libraries/Blob/RCTBlobManager.mm index 7c0cbb8673f064..99084d9aba3b53 100755 --- a/Libraries/Blob/RCTBlobManager.mm +++ b/Libraries/Blob/RCTBlobManager.mm @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Blob/RCTFileReaderModule.h b/Libraries/Blob/RCTFileReaderModule.h index 72d224b0d968cb..89c018381bcd32 100644 --- a/Libraries/Blob/RCTFileReaderModule.h +++ b/Libraries/Blob/RCTFileReaderModule.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Blob/RCTFileReaderModule.m b/Libraries/Blob/RCTFileReaderModule.m index 5059e0b84180ee..26b33f63e471a9 100644 --- a/Libraries/Blob/RCTFileReaderModule.m +++ b/Libraries/Blob/RCTFileReaderModule.m @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Blob/URL.js b/Libraries/Blob/URL.js index de73affac2af1b..36dbe0ffa02b50 100644 --- a/Libraries/Blob/URL.js +++ b/Libraries/Blob/URL.js @@ -1,11 +1,11 @@ /** - * Copyright (c) 2013-present, Facebook, Inc. + * 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 + * @flow strict-local */ 'use strict'; diff --git a/Libraries/Blob/__mocks__/BlobModule.js b/Libraries/Blob/__mocks__/BlobModule.js index e904d2929dd74b..3a1cb8eda6174b 100644 --- a/Libraries/Blob/__mocks__/BlobModule.js +++ b/Libraries/Blob/__mocks__/BlobModule.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Blob/__mocks__/FileReaderModule.js b/Libraries/Blob/__mocks__/FileReaderModule.js index 0f35aa89ace07e..da687eca470b1d 100644 --- a/Libraries/Blob/__mocks__/FileReaderModule.js +++ b/Libraries/Blob/__mocks__/FileReaderModule.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Blob/__tests__/Blob-test.js b/Libraries/Blob/__tests__/Blob-test.js index 47bf5fee7c1361..7600c0c967825c 100644 --- a/Libraries/Blob/__tests__/Blob-test.js +++ b/Libraries/Blob/__tests__/Blob-test.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Blob/__tests__/BlobManager-test.js b/Libraries/Blob/__tests__/BlobManager-test.js index c141d42f16334c..73ad2a9de1103f 100644 --- a/Libraries/Blob/__tests__/BlobManager-test.js +++ b/Libraries/Blob/__tests__/BlobManager-test.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Blob/__tests__/File-test.js b/Libraries/Blob/__tests__/File-test.js index c10f90c18766ae..11b25116809a5d 100644 --- a/Libraries/Blob/__tests__/File-test.js +++ b/Libraries/Blob/__tests__/File-test.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Blob/__tests__/FileReader-test.js b/Libraries/Blob/__tests__/FileReader-test.js index b2237550bf7184..a375c3ef374710 100644 --- a/Libraries/Blob/__tests__/FileReader-test.js +++ b/Libraries/Blob/__tests__/FileReader-test.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/BugReporting/BugReporting.js b/Libraries/BugReporting/BugReporting.js index 6c63b6a1eebf98..9e0adabfe3f19f 100644 --- a/Libraries/BugReporting/BugReporting.js +++ b/Libraries/BugReporting/BugReporting.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2013-present, Facebook, Inc. + * 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. diff --git a/Libraries/BugReporting/dumpReactTree.js b/Libraries/BugReporting/dumpReactTree.js index ead8f4bdd76c32..2ef17ecf034784 100644 --- a/Libraries/BugReporting/dumpReactTree.js +++ b/Libraries/BugReporting/dumpReactTree.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2013-present, Facebook, Inc. + * 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. diff --git a/Libraries/BugReporting/getReactData.js b/Libraries/BugReporting/getReactData.js index b4d1c4a32fd557..cc9bc55f0cc394 100644 --- a/Libraries/BugReporting/getReactData.js +++ b/Libraries/BugReporting/getReactData.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/CameraRoll/CameraRoll.js b/Libraries/CameraRoll/CameraRoll.js index f2a4f65aa80933..ad8db27937aa46 100644 --- a/Libraries/CameraRoll/CameraRoll.js +++ b/Libraries/CameraRoll/CameraRoll.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -13,7 +13,7 @@ const PropTypes = require('prop-types'); const {checkPropTypes} = PropTypes; const RCTCameraRollManager = require('NativeModules').CameraRollManager; -const createStrictShapeTypeChecker = require('createStrictShapeTypeChecker'); +const deprecatedCreateStrictShapeTypeChecker = require('deprecatedCreateStrictShapeTypeChecker'); const invariant = require('fbjs/lib/invariant'); const GROUP_TYPES_OPTIONS = { @@ -32,10 +32,12 @@ const ASSET_TYPE_OPTIONS = { Photos: 'Photos', }; -type GetPhotosParams = { +export type GroupTypes = $Keys; + +export type GetPhotosParams = { first: number, after?: string, - groupTypes?: $Keys, + groupTypes?: GroupTypes, groupName?: string, assetType?: $Keys, mimeTypes?: Array, @@ -44,7 +46,7 @@ type GetPhotosParams = { /** * Shape of the param arg for the `getPhotos` function. */ -const getPhotosParamChecker = createStrictShapeTypeChecker({ +const getPhotosParamChecker = deprecatedCreateStrictShapeTypeChecker({ /** * The number of photos wanted in reverse order of the photo application * (i.e. most recent first for SavedPhotos). @@ -79,48 +81,51 @@ const getPhotosParamChecker = createStrictShapeTypeChecker({ mimeTypes: PropTypes.arrayOf(PropTypes.string), }); -type GetPhotosReturn = Promise<{ - edges: Array<{ - node: { - type: string, - group_name: string, - image: { - uri: string, - height: number, - width: number, - isStored?: boolean, - playableDuration: number, - }, - timestamp: number, - location?: { - latitude?: number, - longitude?: number, - altitude?: number, - heading?: number, - speed?: number, - }, +export type PhotoIdentifier = { + node: { + type: string, + group_name: string, + image: { + filename: string, + uri: string, + height: number, + width: number, + isStored?: boolean, + playableDuration: number, + }, + timestamp: number, + location?: { + latitude?: number, + longitude?: number, + altitude?: number, + heading?: number, + speed?: number, }, - }>, + }, +}; + +export type PhotoIdentifiersPage = { + edges: Array, page_info: { has_next_page: boolean, start_cursor?: string, end_cursor?: string, }, -}>; +}; /** * Shape of the return value of the `getPhotos` function. */ -const getPhotosReturnChecker = createStrictShapeTypeChecker({ +const getPhotosReturnChecker = deprecatedCreateStrictShapeTypeChecker({ edges: PropTypes.arrayOf( /* $FlowFixMe(>=0.66.0 site=react_native_fb) This comment suppresses an * error found when Flow v0.66 was deployed. To see the error delete this * comment and run Flow. */ - createStrictShapeTypeChecker({ - node: createStrictShapeTypeChecker({ + deprecatedCreateStrictShapeTypeChecker({ + node: deprecatedCreateStrictShapeTypeChecker({ type: PropTypes.string.isRequired, group_name: PropTypes.string.isRequired, - image: createStrictShapeTypeChecker({ + image: deprecatedCreateStrictShapeTypeChecker({ uri: PropTypes.string.isRequired, height: PropTypes.number.isRequired, width: PropTypes.number.isRequired, @@ -128,7 +133,7 @@ const getPhotosReturnChecker = createStrictShapeTypeChecker({ playableDuration: PropTypes.number.isRequired, }).isRequired, timestamp: PropTypes.number.isRequired, - location: createStrictShapeTypeChecker({ + location: deprecatedCreateStrictShapeTypeChecker({ latitude: PropTypes.number, longitude: PropTypes.number, altitude: PropTypes.number, @@ -138,7 +143,7 @@ const getPhotosReturnChecker = createStrictShapeTypeChecker({ }).isRequired, }), ).isRequired, - page_info: createStrictShapeTypeChecker({ + page_info: deprecatedCreateStrictShapeTypeChecker({ has_next_page: PropTypes.bool.isRequired, start_cursor: PropTypes.string, end_cursor: PropTypes.string, @@ -151,8 +156,8 @@ const getPhotosReturnChecker = createStrictShapeTypeChecker({ * See https://facebook.github.io/react-native/docs/cameraroll.html */ class CameraRoll { - static GroupTypesOptions: Object = GROUP_TYPES_OPTIONS; - static AssetTypeOptions: Object = ASSET_TYPE_OPTIONS; + static GroupTypesOptions = GROUP_TYPES_OPTIONS; + static AssetTypeOptions = ASSET_TYPE_OPTIONS; /** * `CameraRoll.saveImageWithTag()` is deprecated. Use `CameraRoll.saveToCameraRoll()` instead. @@ -204,7 +209,7 @@ class CameraRoll { * * See https://facebook.github.io/react-native/docs/cameraroll.html#getphotos */ - static getPhotos(params: GetPhotosParams): GetPhotosReturn { + static getPhotos(params: GetPhotosParams): Promise { if (__DEV__) { checkPropTypes( {params: getPhotosParamChecker}, diff --git a/Libraries/CameraRoll/ImagePickerIOS.js b/Libraries/CameraRoll/ImagePickerIOS.js index 785f4b57cb6b56..9c783339835f88 100644 --- a/Libraries/CameraRoll/ImagePickerIOS.js +++ b/Libraries/CameraRoll/ImagePickerIOS.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/CameraRoll/RCTAssetsLibraryRequestHandler.h b/Libraries/CameraRoll/RCTAssetsLibraryRequestHandler.h index 8189bb56e4ea8c..7ccba500f59f0b 100644 --- a/Libraries/CameraRoll/RCTAssetsLibraryRequestHandler.h +++ b/Libraries/CameraRoll/RCTAssetsLibraryRequestHandler.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/CameraRoll/RCTAssetsLibraryRequestHandler.m b/Libraries/CameraRoll/RCTAssetsLibraryRequestHandler.m index 9721b392b80f78..663598ceaea0b7 100644 --- a/Libraries/CameraRoll/RCTAssetsLibraryRequestHandler.m +++ b/Libraries/CameraRoll/RCTAssetsLibraryRequestHandler.m @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/CameraRoll/RCTCameraRollManager.h b/Libraries/CameraRoll/RCTCameraRollManager.h index b8b2c7d2ad63c7..3341c539b0e9dc 100644 --- a/Libraries/CameraRoll/RCTCameraRollManager.h +++ b/Libraries/CameraRoll/RCTCameraRollManager.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/CameraRoll/RCTCameraRollManager.m b/Libraries/CameraRoll/RCTCameraRollManager.m index e6e397392bd159..96e117c16a3783 100644 --- a/Libraries/CameraRoll/RCTCameraRollManager.m +++ b/Libraries/CameraRoll/RCTCameraRollManager.m @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/CameraRoll/RCTImagePickerManager.h b/Libraries/CameraRoll/RCTImagePickerManager.h index 825e7721a46c01..5f489191c3ffc2 100644 --- a/Libraries/CameraRoll/RCTImagePickerManager.h +++ b/Libraries/CameraRoll/RCTImagePickerManager.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-present, Facebook, Inc. + * 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. diff --git a/Libraries/CameraRoll/RCTImagePickerManager.m b/Libraries/CameraRoll/RCTImagePickerManager.m index 4da2a6490b9504..96932c473f3446 100644 --- a/Libraries/CameraRoll/RCTImagePickerManager.m +++ b/Libraries/CameraRoll/RCTImagePickerManager.m @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-present, Facebook, Inc. + * 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. @@ -123,7 +123,7 @@ - (void)imagePickerController:(UIImagePickerController *)picker // WARNING: Using ImageStoreManager may cause a memory leak because the // image isn't automatically removed from store once we're done using it. [_bridge.imageStoreManager storeImage:originalImage withBlock:^(NSString *tempImageTag) { - [self _dismissPicker:picker args:tempImageTag ? @[tempImageTag, height, width] : nil]; + [self _dismissPicker:picker args:tempImageTag ? @[tempImageTag, RCTNullIfNil(height), RCTNullIfNil(width)] : nil]; }]; } diff --git a/Libraries/CameraRoll/RCTPhotoLibraryImageLoader.h b/Libraries/CameraRoll/RCTPhotoLibraryImageLoader.h index 0a45f184dab73c..d3b8dc646b3c6b 100644 --- a/Libraries/CameraRoll/RCTPhotoLibraryImageLoader.h +++ b/Libraries/CameraRoll/RCTPhotoLibraryImageLoader.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/CameraRoll/RCTPhotoLibraryImageLoader.m b/Libraries/CameraRoll/RCTPhotoLibraryImageLoader.m index ac27231adc9e9a..e6c191e93b5099 100644 --- a/Libraries/CameraRoll/RCTPhotoLibraryImageLoader.m +++ b/Libraries/CameraRoll/RCTPhotoLibraryImageLoader.m @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Color/normalizeColor.js b/Libraries/Color/normalizeColor.js index edede79ee6e267..811b5535f8de5f 100755 --- a/Libraries/Color/normalizeColor.js +++ b/Libraries/Color/normalizeColor.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Components/AccessibilityInfo/AccessibilityInfo.android.js b/Libraries/Components/AccessibilityInfo/AccessibilityInfo.android.js index dfa09b53a466aa..6cd0193eb42eca 100644 --- a/Libraries/Components/AccessibilityInfo/AccessibilityInfo.android.js +++ b/Libraries/Components/AccessibilityInfo/AccessibilityInfo.android.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -12,6 +12,7 @@ const NativeModules = require('NativeModules'); const RCTDeviceEventEmitter = require('RCTDeviceEventEmitter'); +const UIManager = require('UIManager'); const RCTAccessibilityInfo = NativeModules.AccessibilityInfo; @@ -34,6 +35,8 @@ const _subscriptions = new Map(); */ const AccessibilityInfo = { + /* $FlowFixMe(>=0.78.0 site=react_native_android_fb) This issue was found + * when making Flow check .android.js files. */ fetch: function(): Promise { return new Promise((resolve, reject) => { RCTAccessibilityInfo.isTouchExplorationEnabled(function(resp) { @@ -66,6 +69,18 @@ const AccessibilityInfo = { listener.remove(); _subscriptions.delete(handler); }, + + /** + * Set accessibility focus to a react component. + * + * See http://facebook.github.io/react-native/docs/accessibilityinfo.html#setaccessibilityfocus + */ + setAccessibilityFocus: function(reactTag: number): void { + UIManager.sendAccessibilityEvent( + reactTag, + UIManager.AccessibilityEventTypes.typeViewFocused, + ); + }, }; module.exports = AccessibilityInfo; diff --git a/Libraries/Components/AccessibilityInfo/AccessibilityInfo.ios.js b/Libraries/Components/AccessibilityInfo/AccessibilityInfo.ios.js index 8f2b0aa78dc064..5a1d64e9595e83 100644 --- a/Libraries/Components/AccessibilityInfo/AccessibilityInfo.ios.js +++ b/Libraries/Components/AccessibilityInfo/AccessibilityInfo.ios.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -93,8 +93,6 @@ const AccessibilityInfo = { /** * Set accessibility focus to a react component. * - * @platform ios - * * See http://facebook.github.io/react-native/docs/accessibilityinfo.html#setaccessibilityfocus */ setAccessibilityFocus: function(reactTag: number): void { diff --git a/Libraries/Components/ActivityIndicator/ActivityIndicator.js b/Libraries/Components/ActivityIndicator/ActivityIndicator.js index abe6a75af9478e..62df9c5783ded2 100644 --- a/Libraries/Components/ActivityIndicator/ActivityIndicator.js +++ b/Libraries/Components/ActivityIndicator/ActivityIndicator.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -103,6 +103,8 @@ const ActivityIndicator = ( styles.container, style, )}> + {/* $FlowFixMe(>=0.78.0 site=react_native_android_fb) This issue was + * found when making Flow check .android.js files. */} ); diff --git a/Libraries/Components/AppleTV/TVEventHandler.js b/Libraries/Components/AppleTV/TVEventHandler.js index 567776b5d9bfa9..9b584de6bec581 100644 --- a/Libraries/Components/AppleTV/TVEventHandler.js +++ b/Libraries/Components/AppleTV/TVEventHandler.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Components/AppleTV/TVViewPropTypes.js b/Libraries/Components/AppleTV/TVViewPropTypes.js index 5bda1f618c5440..ce3651d5f490da 100644 --- a/Libraries/Components/AppleTV/TVViewPropTypes.js +++ b/Libraries/Components/AppleTV/TVViewPropTypes.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -9,76 +9,85 @@ */ 'use strict'; -const PropTypes = require('prop-types'); + +type TVParallaxPropertiesType = $ReadOnly<{| + /** + * If true, parallax effects are enabled. Defaults to true. + */ + enabled: boolean, + + /** + * Defaults to 2.0. + */ + shiftDistanceX: number, + + /** + * Defaults to 2.0. + */ + shiftDistanceY: number, + + /** + * Defaults to 0.05. + */ + tiltAngle: number, + + /** + * Defaults to 1.0 + */ + magnification: number, +|}>; /** * Additional View properties for Apple TV */ -const TVViewPropTypes = { +export type TVViewProps = $ReadOnly<{| /** - * When set to true, this view will be focusable - * and navigable using the TV remote. + * *(Apple TV only)* When set to true, this view will be focusable + * and navigable using the Apple TV remote. + * + * @platform ios */ - isTVSelectable: PropTypes.bool, + isTVSelectable?: boolean, /** - * May be set to true to force the TV focus engine to move focus to this view. + * *(Apple TV only)* May be set to true to force the Apple TV focus engine to move focus to this view. + * + * @platform ios */ - hasTVPreferredFocus: PropTypes.bool, + hasTVPreferredFocus?: boolean, /** * *(Apple TV only)* Object with properties to control Apple TV parallax effects. * - * enabled: If true, parallax effects are enabled. Defaults to true. - * shiftDistanceX: Defaults to 2.0. - * shiftDistanceY: Defaults to 2.0. - * tiltAngle: Defaults to 0.05. - * magnification: Defaults to 1.0. - * pressMagnification: Defaults to 1.0. - * pressDuration: Defaults to 0.3. - * pressDelay: Defaults to 0.0. - * * @platform ios */ - tvParallaxProperties: PropTypes.object, + tvParallaxProperties?: TVParallaxPropertiesType, /** * *(Apple TV only)* May be used to change the appearance of the Apple TV parallax effect when this view goes in or out of focus. Defaults to 2.0. * * @platform ios */ - tvParallaxShiftDistanceX: PropTypes.number, + tvParallaxShiftDistanceX?: number, /** * *(Apple TV only)* May be used to change the appearance of the Apple TV parallax effect when this view goes in or out of focus. Defaults to 2.0. * * @platform ios */ - tvParallaxShiftDistanceY: PropTypes.number, + tvParallaxShiftDistanceY?: number, /** * *(Apple TV only)* May be used to change the appearance of the Apple TV parallax effect when this view goes in or out of focus. Defaults to 0.05. * * @platform ios */ - tvParallaxTiltAngle: PropTypes.number, + tvParallaxTiltAngle?: number, /** * *(Apple TV only)* May be used to change the appearance of the Apple TV parallax effect when this view goes in or out of focus. Defaults to 1.0. * * @platform ios */ - tvParallaxMagnification: PropTypes.number, -}; - -export type TVViewProps = $ReadOnly<{| - isTVSelectable?: boolean, - hasTVPreferredFocus?: boolean, - tvParallaxProperties?: Object, - tvParallaxShiftDistanceX?: number, - tvParallaxShiftDistanceY?: number, - tvParallaxTiltAngle?: number, tvParallaxMagnification?: number, |}>; - -module.exports = TVViewPropTypes; diff --git a/Libraries/Components/Button.js b/Libraries/Components/Button.js index 22c376467ea9bc..93ee79035915f6 100644 --- a/Libraries/Components/Button.js +++ b/Libraries/Components/Button.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -10,10 +10,8 @@ 'use strict'; -const ColorPropType = require('ColorPropType'); const Platform = require('Platform'); const React = require('React'); -const PropTypes = require('prop-types'); const StyleSheet = require('StyleSheet'); const Text = require('Text'); const TouchableNativeFeedback = require('TouchableNativeFeedback'); @@ -22,6 +20,45 @@ const View = require('View'); const invariant = require('fbjs/lib/invariant'); +import type {PressEvent} from 'CoreEventTypes'; + +type ButtonProps = $ReadOnly<{| + /** + * Text to display inside the button + */ + title: string, + + /** + * Handler to be called when the user taps the button + */ + onPress: (event?: PressEvent) => mixed, + + /** + * Color of the text (iOS), or background color of the button (Android) + */ + color?: ?string, + + /** + * TV preferred focus (see documentation for the View component). + */ + hasTVPreferredFocus?: ?boolean, + + /** + * Text to display for blindness accessibility features + */ + accessibilityLabel?: ?string, + + /** + * If true, disable all interactions for this component. + */ + disabled?: ?boolean, + + /** + * Used to locate this view in end-to-end tests. + */ + testID?: ?string, +|}>; + /** * A basic button component that should render nicely on any platform. Supports * a minimal level of customization. @@ -50,46 +87,7 @@ const invariant = require('fbjs/lib/invariant'); * */ -class Button extends React.Component<{ - title: string, - onPress: () => any, - color?: ?string, - hasTVPreferredFocus?: ?boolean, - accessibilityLabel?: ?string, - disabled?: ?boolean, - testID?: ?string, -}> { - static propTypes = { - /** - * Text to display inside the button - */ - title: PropTypes.string.isRequired, - /** - * Text to display for blindness accessibility features - */ - accessibilityLabel: PropTypes.string, - /** - * Color of the text (iOS), or background color of the button (Android) - */ - color: ColorPropType, - /** - * If true, disable all interactions for this component. - */ - disabled: PropTypes.bool, - /** - * TV preferred focus (see documentation for the View component). - */ - hasTVPreferredFocus: PropTypes.bool, - /** - * Handler to be called when the user taps the button - */ - onPress: PropTypes.func.isRequired, - /** - * Used to locate this view in end-to-end tests. - */ - testID: PropTypes.string, - }; - +class Button extends React.Component { render() { const { accessibilityLabel, @@ -109,11 +107,11 @@ class Button extends React.Component<{ buttonStyles.push({backgroundColor: color}); } } - const accessibilityTraits = ['button']; + const accessibilityStates = []; if (disabled) { buttonStyles.push(styles.buttonDisabled); textStyles.push(styles.textDisabled); - accessibilityTraits.push('disabled'); + accessibilityStates.push('disabled'); } invariant( typeof title === 'string', @@ -125,9 +123,9 @@ class Button extends React.Component<{ Platform.OS === 'android' ? TouchableNativeFeedback : TouchableOpacity; return ( true; props.onResponderTerminationRequest = () => false; + /* $FlowFixMe(>=0.78.0 site=react_native_android_fb) This issue was found + * when making Flow check .android.js files. */ props.enabled = !this.props.disabled; + /* $FlowFixMe(>=0.78.0 site=react_native_android_fb) This issue was found + * when making Flow check .android.js files. */ props.on = this.props.value; props.style = [styles.rctCheckBox, this.props.style]; diff --git a/Libraries/Components/CheckBox/CheckBox.ios.js b/Libraries/Components/CheckBox/CheckBox.ios.js index 5fda2cd5ec2bce..8bc431d610e066 100644 --- a/Libraries/Components/CheckBox/CheckBox.ios.js +++ b/Libraries/Components/CheckBox/CheckBox.ios.js @@ -1,10 +1,10 @@ /** - * Copyright (c) 2017-present, Facebook, Inc. + * 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 + * @flow strict-local * @format */ 'use strict'; diff --git a/Libraries/Components/Clipboard/Clipboard.js b/Libraries/Components/Clipboard/Clipboard.js index 706bc0fba8c9b7..d9eddb6cd0548e 100644 --- a/Libraries/Components/Clipboard/Clipboard.js +++ b/Libraries/Components/Clipboard/Clipboard.js @@ -1,11 +1,11 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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 + * @flow strict-local */ 'use strict'; diff --git a/Libraries/Components/DatePicker/DatePickerIOS.android.js b/Libraries/Components/DatePicker/DatePickerIOS.android.js index 585be6e297673d..c532f212d6080b 100644 --- a/Libraries/Components/DatePicker/DatePickerIOS.android.js +++ b/Libraries/Components/DatePicker/DatePickerIOS.android.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Components/DatePicker/DatePickerIOS.ios.js b/Libraries/Components/DatePicker/DatePickerIOS.ios.js index 1202364665fc94..8df54ec3169b93 100644 --- a/Libraries/Components/DatePicker/DatePickerIOS.ios.js +++ b/Libraries/Components/DatePicker/DatePickerIOS.ios.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Components/DatePickerAndroid/DatePickerAndroid.android.js b/Libraries/Components/DatePickerAndroid/DatePickerAndroid.android.js index bd91263a8f9b49..734a59abf72cf4 100644 --- a/Libraries/Components/DatePickerAndroid/DatePickerAndroid.android.js +++ b/Libraries/Components/DatePickerAndroid/DatePickerAndroid.android.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Components/DatePickerAndroid/DatePickerAndroid.ios.js b/Libraries/Components/DatePickerAndroid/DatePickerAndroid.ios.js index a158f035c303d3..bb6442b5262c79 100644 --- a/Libraries/Components/DatePickerAndroid/DatePickerAndroid.ios.js +++ b/Libraries/Components/DatePickerAndroid/DatePickerAndroid.ios.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Components/DrawerAndroid/DrawerLayoutAndroid.android.js b/Libraries/Components/DrawerAndroid/DrawerLayoutAndroid.android.js index d4b3fa9f7f63d0..b58385ef941911 100644 --- a/Libraries/Components/DrawerAndroid/DrawerLayoutAndroid.android.js +++ b/Libraries/Components/DrawerAndroid/DrawerLayoutAndroid.android.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -9,19 +9,20 @@ 'use strict'; -const ColorPropType = require('ColorPropType'); +const DeprecatedColorPropType = require('DeprecatedColorPropType'); +const DeprecatedViewPropTypes = require('DeprecatedViewPropTypes'); const NativeMethodsMixin = require('NativeMethodsMixin'); const Platform = require('Platform'); -const React = require('React'); const PropTypes = require('prop-types'); +const React = require('React'); const ReactNative = require('ReactNative'); const StatusBar = require('StatusBar'); const StyleSheet = require('StyleSheet'); const UIManager = require('UIManager'); const View = require('View'); -const ViewPropTypes = require('ViewPropTypes'); -const DrawerConsts = UIManager.AndroidDrawerLayout.Constants; +const DrawerConsts = UIManager.getViewManagerConfig('AndroidDrawerLayout') + .Constants; const createReactClass = require('create-react-class'); const dismissKeyboard = require('dismissKeyboard'); @@ -70,7 +71,7 @@ const DrawerLayoutAndroid = createReactClass({ }, propTypes: { - ...ViewPropTypes, + ...DeprecatedViewPropTypes, /** * Determines whether the keyboard gets dismissed in response to a drag. * - 'none' (the default), drags do not dismiss the keyboard. @@ -91,7 +92,7 @@ const DrawerLayoutAndroid = createReactClass({ * ); * ``` */ - drawerBackgroundColor: ColorPropType, + drawerBackgroundColor: DeprecatedColorPropType, /** * Specifies the side of the screen from which the drawer will slide in. */ @@ -146,7 +147,7 @@ const DrawerLayoutAndroid = createReactClass({ * status bar to allow it to open over the status bar. It will only have an * effect on API 21+. */ - statusBarBackgroundColor: ColorPropType, + statusBarBackgroundColor: DeprecatedColorPropType, }, mixins: [NativeMethodsMixin], @@ -254,7 +255,7 @@ const DrawerLayoutAndroid = createReactClass({ openDrawer: function() { UIManager.dispatchViewManagerCommand( this._getDrawerLayoutHandle(), - UIManager.AndroidDrawerLayout.Commands.openDrawer, + UIManager.getViewManagerConfig('AndroidDrawerLayout').Commands.openDrawer, null, ); }, @@ -265,7 +266,8 @@ const DrawerLayoutAndroid = createReactClass({ closeDrawer: function() { UIManager.dispatchViewManagerCommand( this._getDrawerLayoutHandle(), - UIManager.AndroidDrawerLayout.Commands.closeDrawer, + UIManager.getViewManagerConfig('AndroidDrawerLayout').Commands + .closeDrawer, null, ); }, diff --git a/Libraries/Components/DrawerAndroid/DrawerLayoutAndroid.ios.js b/Libraries/Components/DrawerAndroid/DrawerLayoutAndroid.ios.js index 260d559929796f..7a00b6636cf664 100644 --- a/Libraries/Components/DrawerAndroid/DrawerLayoutAndroid.ios.js +++ b/Libraries/Components/DrawerAndroid/DrawerLayoutAndroid.ios.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Components/Keyboard/Keyboard.js b/Libraries/Components/Keyboard/Keyboard.js index feeb4a4ec2ce70..a2389fe9198c5a 100644 --- a/Libraries/Components/Keyboard/Keyboard.js +++ b/Libraries/Components/Keyboard/Keyboard.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Components/Keyboard/KeyboardAvoidingView.js b/Libraries/Components/Keyboard/KeyboardAvoidingView.js index 4973fd4a0a3805..46e5c2e889e883 100644 --- a/Libraries/Components/Keyboard/KeyboardAvoidingView.js +++ b/Libraries/Components/Keyboard/KeyboardAvoidingView.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Components/MaskedView/MaskedViewIOS.android.js b/Libraries/Components/MaskedView/MaskedViewIOS.android.js index 49d44e1541dcd5..95d93f156b29cd 100644 --- a/Libraries/Components/MaskedView/MaskedViewIOS.android.js +++ b/Libraries/Components/MaskedView/MaskedViewIOS.android.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Components/MaskedView/MaskedViewIOS.ios.js b/Libraries/Components/MaskedView/MaskedViewIOS.ios.js index c65822a64b2d30..ce860ac2eeab40 100644 --- a/Libraries/Components/MaskedView/MaskedViewIOS.ios.js +++ b/Libraries/Components/MaskedView/MaskedViewIOS.ios.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -8,27 +8,26 @@ * @flow */ -const PropTypes = require('prop-types'); const React = require('React'); const StyleSheet = require('StyleSheet'); const View = require('View'); -const ViewPropTypes = require('ViewPropTypes'); + const requireNativeComponent = require('requireNativeComponent'); import type {ViewProps} from 'ViewPropTypes'; const RCTMaskedView = requireNativeComponent('RCTMaskedView'); -type Props = { +type Props = $ReadOnly<{| ...ViewProps, - children: any, + children: React.Node, /** * Should be a React element to be rendered and applied as the * mask for the child element. */ maskElement: React.Element, -}; +|}>; /** * Renders the child view with a mask specified in the `maskElement` prop. @@ -67,11 +66,6 @@ type Props = { * */ class MaskedViewIOS extends React.Component { - static propTypes = { - ...ViewPropTypes, - maskElement: PropTypes.element.isRequired, - }; - _hasWarnedInvalidRenderMask = false; render() { diff --git a/Libraries/Components/Navigation/NavigatorIOS.android.js b/Libraries/Components/Navigation/NavigatorIOS.android.js deleted file mode 100644 index 260d559929796f..00000000000000 --- a/Libraries/Components/Navigation/NavigatorIOS.android.js +++ /dev/null @@ -1,12 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @format - */ - -'use strict'; - -module.exports = require('UnimplementedView'); diff --git a/Libraries/Components/Navigation/NavigatorIOS.ios.js b/Libraries/Components/Navigation/NavigatorIOS.ios.js deleted file mode 100644 index 8f28d79147fe77..00000000000000 --- a/Libraries/Components/Navigation/NavigatorIOS.ios.js +++ /dev/null @@ -1,932 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * - * 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 EventEmitter = require('EventEmitter'); -const Image = require('Image'); -const RCTNavigatorManager = require('NativeModules').NavigatorManager; -const React = require('React'); -const PropTypes = require('prop-types'); -const ReactNative = require('ReactNative'); -const StaticContainer = require('StaticContainer.react'); -const StyleSheet = require('StyleSheet'); -const TVEventHandler = require('TVEventHandler'); -const View = require('View'); -const ViewPropTypes = require('ViewPropTypes'); - -const createReactClass = require('create-react-class'); -const invariant = require('fbjs/lib/invariant'); -const requireNativeComponent = require('requireNativeComponent'); - -/* $FlowFixMe(>=0.54.0 site=react_native_oss) This comment suppresses an error - * found when Flow v0.54 was deployed. To see the error delete this comment and - * run Flow. */ -const keyMirror = require('fbjs/lib/keyMirror'); - -const TRANSITIONER_REF = 'transitionerRef'; - -let __uid = 0; -function getuid() { - return __uid++; -} - -class NavigatorTransitionerIOS extends React.Component<$FlowFixMeProps> { - requestSchedulingNavigation(cb) { - RCTNavigatorManager.requestSchedulingJavaScriptNavigation( - ReactNative.findNodeHandle(this), - cb, - ); - } - - render() { - return ; - } -} - -const SystemIconLabels = { - done: true, - cancel: true, - edit: true, - save: true, - add: true, - compose: true, - reply: true, - action: true, - organize: true, - bookmarks: true, - search: true, - refresh: true, - stop: true, - camera: true, - trash: true, - play: true, - pause: true, - rewind: true, - 'fast-forward': true, - undo: true, - redo: true, - 'page-curl': true, -}; -const SystemIcons = keyMirror(SystemIconLabels); - -type SystemButtonType = $Enum; - -type Route = { - component: Function, - title: string, - titleImage?: Object, - passProps?: Object, - backButtonTitle?: string, - backButtonIcon?: Object, - leftButtonTitle?: string, - leftButtonIcon?: Object, - leftButtonSystemIcon?: SystemButtonType, - onLeftButtonPress?: Function, - rightButtonTitle?: string, - rightButtonIcon?: Object, - rightButtonSystemIcon?: SystemButtonType, - onRightButtonPress?: Function, - wrapperStyle?: any, -}; - -type State = { - idStack: Array, - routeStack: Array, - requestedTopOfStack: number, - observedTopOfStack: number, - progress: number, - fromIndex: number, - toIndex: number, - makingNavigatorRequest: boolean, - updatingAllIndicesAtOrBeyond: ?number, -}; - -type Event = Object; - -/** - * Think of `` as simply a component that renders an - * `RCTNavigator`, and moves the `RCTNavigator`'s `requestedTopOfStack` pointer - * forward and backward. The `RCTNavigator` interprets changes in - * `requestedTopOfStack` to be pushes and pops of children that are rendered. - * `` always ensures that whenever the `requestedTopOfStack` - * pointer is moved, that we've also rendered enough children so that the - * `RCTNavigator` can carry out the push/pop with those children. - * `` also removes children that will no longer be needed - * (after the pop of a child has been fully completed/animated out). - */ - -/** - * `NavigatorIOS` is a wrapper around - * [`UINavigationController`](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UINavigationController_Class/), - * enabling you to implement a navigation stack. It works exactly the same as it - * would on a native app using `UINavigationController`, providing the same - * animations and behavior from UIKit. - * - * As the name implies, it is only available on iOS. Take a look at - * [`React Navigation`](https://reactnavigation.org/) for a cross-platform - * solution in JavaScript, or check out either of these components for native - * solutions: [native-navigation](http://airbnb.io/native-navigation/), - * [react-native-navigation](https://github.com/wix/react-native-navigation). - * - * To set up the navigator, provide the `initialRoute` prop with a route - * object. A route object is used to describe each scene that your app - * navigates to. `initialRoute` represents the first route in your navigator. - * - * ``` - * import PropTypes from 'prop-types'; - * import React, { Component } from 'react'; - * import { NavigatorIOS, Text } from 'react-native'; - * - * export default class NavigatorIOSApp extends Component { - * render() { - * return ( - * - * ); - * } - * } - * - * class MyScene extends Component { - * static propTypes = { - * title: PropTypes.string.isRequired, - * navigator: PropTypes.object.isRequired, - * } - * - * _onForward = () => { - * this.props.navigator.push({ - * title: 'Scene ' + nextIndex, - * }); - * } - * - * render() { - * return ( - * - * Current Scene: { this.props.title } - * - * Tap me to load the next scene - * - * - * ) - * } - * } - * ``` - * - * In this code, the navigator renders the component specified in initialRoute, - * which in this case is `MyScene`. This component will receive a `route` prop - * and a `navigator` prop representing the navigator. The navigator's navigation - * bar will render the title for the current scene, "My Initial Scene". - * - * You can optionally pass in a `passProps` property to your `initialRoute`. - * `NavigatorIOS` passes this in as props to the rendered component: - * - * ``` - * initialRoute={{ - * component: MyScene, - * title: 'My Initial Scene', - * passProps: { myProp: 'foo' } - * }} - * ``` - * - * You can then access the props passed in via `{this.props.myProp}`. - * - * #### Handling Navigation - * - * To trigger navigation functionality such as pushing or popping a view, you - * have access to a `navigator` object. The object is passed in as a prop to any - * component that is rendered by `NavigatorIOS`. You can then call the - * relevant methods to perform the navigation action you need: - * - * ``` - * class MyView extends Component { - * _handleBackPress() { - * this.props.navigator.pop(); - * } - * - * _handleNextPress(nextRoute) { - * this.props.navigator.push(nextRoute); - * } - * - * render() { - * const nextRoute = { - * component: MyView, - * title: 'Bar That', - * passProps: { myProp: 'bar' } - * }; - * return( - * this._handleNextPress(nextRoute)}> - * - * See you on the other nav {this.props.myProp}! - * - * - * ); - * } - * } - * ``` - * - * You can also trigger navigator functionality from the `NavigatorIOS` - * component: - * - * ``` - * class NavvyIOS extends Component { - * _handleNavigationRequest() { - * this.refs.nav.push({ - * component: MyView, - * title: 'Genius', - * passProps: { myProp: 'genius' }, - * }); - * } - * - * render() { - * return ( - * this._handleNavigationRequest(), - * }} - * style={{flex: 1}} - * /> - * ); - * } - * } - * ``` - * - * The code above adds a `_handleNavigationRequest` private method that is - * invoked from the `NavigatorIOS` component when the right navigation bar item - * is pressed. To get access to the navigator functionality, a reference to it - * is saved in the `ref` prop and later referenced to push a new scene into the - * navigation stack. - * - * #### Navigation Bar Configuration - * - * Props passed to `NavigatorIOS` will set the default configuration - * for the navigation bar. Props passed as properties to a route object will set - * the configuration for that route's navigation bar, overriding any props - * passed to the `NavigatorIOS` component. - * - * ``` - * _handleNavigationRequest() { - * this.refs.nav.push({ - * //... - * passProps: { myProp: 'genius' }, - * barTintColor: '#996699', - * }); - * } - * - * render() { - * return ( - * - * ); - * } - * ``` - * - * In the example above the navigation bar color is changed when the new route - * is pushed. - * - */ -const NavigatorIOS = createReactClass({ - displayName: 'NavigatorIOS', - - propTypes: { - /** - * NavigatorIOS uses `route` objects to identify child views, their props, - * and navigation bar configuration. Navigation operations such as push - * operations expect routes to look like this the `initialRoute`. - */ - initialRoute: PropTypes.shape({ - /** - * The React Class to render for this route - */ - component: PropTypes.func.isRequired, - - /** - * The title displayed in the navigation bar and the back button for this - * route. - */ - title: PropTypes.string.isRequired, - - /** - * If set, a title image will appear instead of the text title. - */ - titleImage: Image.propTypes.source, - - /** - * Use this to specify additional props to pass to the rendered - * component. `NavigatorIOS` will automatically pass in `route` and - * `navigator` props to the component. - */ - passProps: PropTypes.object, - - /** - * If set, the left navigation button image will be displayed using this - * source. Note that this doesn't apply to the header of the current - * view, but to those views that are subsequently pushed. - */ - backButtonIcon: Image.propTypes.source, - - /** - * If set, the left navigation button text will be set to this. Note that - * this doesn't apply to the left button of the current view, but to - * those views that are subsequently pushed - */ - backButtonTitle: PropTypes.string, - - /** - * If set, the left navigation button image will be displayed using - * this source. - */ - leftButtonIcon: Image.propTypes.source, - - /** - * If set, the left navigation button will display this text. - */ - leftButtonTitle: PropTypes.string, - - /** - * If set, the left header button will appear with this system icon - * - * Supported icons are `done`, `cancel`, `edit`, `save`, `add`, - * `compose`, `reply`, `action`, `organize`, `bookmarks`, `search`, - * `refresh`, `stop`, `camera`, `trash`, `play`, `pause`, `rewind`, - * `fast-forward`, `undo`, `redo`, and `page-curl` - */ - leftButtonSystemIcon: PropTypes.oneOf(Object.keys(SystemIcons)), - - /** - * This function will be invoked when the left navigation bar item is - * pressed. - */ - onLeftButtonPress: PropTypes.func, - - /** - * If set, the right navigation button image will be displayed using - * this source. - */ - rightButtonIcon: Image.propTypes.source, - - /** - * If set, the right navigation button will display this text. - */ - rightButtonTitle: PropTypes.string, - - /** - * If set, the right header button will appear with this system icon - * - * See leftButtonSystemIcon for supported icons - */ - rightButtonSystemIcon: PropTypes.oneOf(Object.keys(SystemIcons)), - - /** - * This function will be invoked when the right navigation bar item is - * pressed. - */ - onRightButtonPress: PropTypes.func, - - /** - * Styles for the navigation item containing the component. - */ - wrapperStyle: ViewPropTypes.style, - - /** - * Boolean value that indicates whether the navigation bar is hidden. - */ - navigationBarHidden: PropTypes.bool, - - /** - * Boolean value that indicates whether to hide the 1px hairline - * shadow. - */ - shadowHidden: PropTypes.bool, - - /** - * The color used for the buttons in the navigation bar. - */ - tintColor: PropTypes.string, - - /** - * The background color of the navigation bar. - */ - barTintColor: PropTypes.string, - - /** - * The style of the navigation bar. Supported values are 'default', 'black'. - * Use 'black' instead of setting `barTintColor` to black. This produces - * a navigation bar with the native iOS style with higher translucency. - */ - barStyle: PropTypes.oneOf(['default', 'black']), - - /** - * The text color of the navigation bar title. - */ - titleTextColor: PropTypes.string, - - /** - * Boolean value that indicates whether the navigation bar is - * translucent. - */ - translucent: PropTypes.bool, - }).isRequired, - - /** - * Boolean value that indicates whether the navigation bar is hidden - * by default. - */ - navigationBarHidden: PropTypes.bool, - - /** - * Boolean value that indicates whether to hide the 1px hairline shadow - * by default. - */ - shadowHidden: PropTypes.bool, - - /** - * The default wrapper style for components in the navigator. - * A common use case is to set the `backgroundColor` for every scene. - */ - itemWrapperStyle: ViewPropTypes.style, - - /** - * The default color used for the buttons in the navigation bar. - */ - tintColor: PropTypes.string, - - /** - * The default background color of the navigation bar. - */ - barTintColor: PropTypes.string, - - /** - * The style of the navigation bar. Supported values are 'default', 'black'. - * Use 'black' instead of setting `barTintColor` to black. This produces - * a navigation bar with the native iOS style with higher translucency. - */ - barStyle: PropTypes.oneOf(['default', 'black']), - - /** - * The default text color of the navigation bar title. - */ - titleTextColor: PropTypes.string, - - /** - * Boolean value that indicates whether the navigation bar is - * translucent by default - */ - translucent: PropTypes.bool, - - /** - * Boolean value that indicates whether the interactive pop gesture is - * enabled. This is useful for enabling/disabling the back swipe navigation - * gesture. - * - * If this prop is not provided, the default behavior is for the back swipe - * gesture to be enabled when the navigation bar is shown and disabled when - * the navigation bar is hidden. Once you've provided the - * `interactivePopGestureEnabled` prop, you can never restore the default - * behavior. - */ - interactivePopGestureEnabled: PropTypes.bool, - }, - - navigator: (undefined: ?Object), - - UNSAFE_componentWillMount: function() { - // Precompute a pack of callbacks that's frequently generated and passed to - // instances. - this.navigator = { - push: this.push, - pop: this.pop, - popN: this.popN, - replace: this.replace, - replaceAtIndex: this.replaceAtIndex, - replacePrevious: this.replacePrevious, - replacePreviousAndPop: this.replacePreviousAndPop, - resetTo: this.resetTo, - popToRoute: this.popToRoute, - popToTop: this.popToTop, - }; - }, - - componentDidMount: function() { - this._enableTVEventHandler(); - }, - - componentWillUnmount: function() { - this._disableTVEventHandler(); - }, - - getDefaultProps: function(): Object { - return { - translucent: true, - }; - }, - - getInitialState: function(): State { - return { - idStack: [getuid()], - routeStack: [this.props.initialRoute], - // The navigation index that we wish to push/pop to. - requestedTopOfStack: 0, - // The last index that native has sent confirmation of completed push/pop - // for. At this point, we can discard any views that are beyond the - // `requestedTopOfStack`. A value of `null` means we have not received - // any confirmation, ever. We may receive an `observedTopOfStack` without - // ever requesting it - native can instigate pops of its own with the - // backswipe gesture. - observedTopOfStack: 0, - progress: 1, - fromIndex: 0, - toIndex: 0, - // Whether or not we are making a navigator request to push/pop. (Used - // for performance optimization). - makingNavigatorRequest: false, - // Whether or not we are updating children of navigator and if so (not - // `null`) which index marks the beginning of all updates. Used for - // performance optimization. - updatingAllIndicesAtOrBeyond: 0, - }; - }, - - _toFocusOnNavigationComplete: (undefined: any), - - _handleFocusRequest: function(item: any) { - if (this.state.makingNavigatorRequest) { - this._toFocusOnNavigationComplete = item; - } else { - this._getFocusEmitter().emit('focus', item); - } - }, - - _focusEmitter: (undefined: ?EventEmitter), - - _getFocusEmitter: function(): EventEmitter { - // Flow not yet tracking assignments to instance fields. - let focusEmitter = this._focusEmitter; - if (!focusEmitter) { - focusEmitter = new EventEmitter(); - this._focusEmitter = focusEmitter; - } - return focusEmitter; - }, - - getChildContext: function(): { - onFocusRequested: Function, - focusEmitter: EventEmitter, - } { - return { - onFocusRequested: this._handleFocusRequest, - focusEmitter: this._getFocusEmitter(), - }; - }, - - childContextTypes: { - onFocusRequested: PropTypes.func, - focusEmitter: PropTypes.instanceOf(EventEmitter), - }, - - _tryLockNavigator: function(cb: () => void) { - this.refs[TRANSITIONER_REF].requestSchedulingNavigation( - acquiredLock => acquiredLock && cb(), - ); - }, - - _handleNavigatorStackChanged: function(e: Event) { - const newObservedTopOfStack = e.nativeEvent.stackLength - 1; - - invariant( - newObservedTopOfStack <= this.state.requestedTopOfStack, - 'No navigator item should be pushed without JS knowing about it %s %s', - newObservedTopOfStack, - this.state.requestedTopOfStack, - ); - const wasWaitingForConfirmation = - this.state.requestedTopOfStack !== this.state.observedTopOfStack; - if (wasWaitingForConfirmation) { - invariant( - newObservedTopOfStack === this.state.requestedTopOfStack, - 'If waiting for observedTopOfStack to reach requestedTopOfStack, ' + - 'the only valid observedTopOfStack should be requestedTopOfStack.', - ); - } - // Mark the most recent observation regardless of if we can lock the - // navigator. `observedTopOfStack` merely represents what we've observed - // and this first `setState` is only executed to update debugging - // overlays/navigation bar. - // Also reset progress, toIndex, and fromIndex as they might not end - // in the correct states for a two possible reasons: - // Progress isn't always 0 or 1 at the end, the system rounds - // If the Navigator is offscreen these values won't be updated - // TOOD: Revisit this decision when no longer relying on native navigator. - const nextState = { - observedTopOfStack: newObservedTopOfStack, - makingNavigatorRequest: false, - updatingAllIndicesAtOrBeyond: null, - progress: 1, - toIndex: newObservedTopOfStack, - fromIndex: newObservedTopOfStack, - }; - this.setState(nextState, this._eliminateUnneededChildren); - }, - - _eliminateUnneededChildren: function() { - // Updating the indices that we're deleting and that's all. (Truth: Nothing - // even uses the indices in this case, but let's make this describe the - // truth anyways). - const updatingAllIndicesAtOrBeyond = - this.state.routeStack.length > this.state.observedTopOfStack + 1 - ? this.state.observedTopOfStack + 1 - : null; - this.setState({ - idStack: this.state.idStack.slice(0, this.state.observedTopOfStack + 1), - routeStack: this.state.routeStack.slice( - 0, - this.state.observedTopOfStack + 1, - ), - // Now we rerequest the top of stack that we observed. - requestedTopOfStack: this.state.observedTopOfStack, - makingNavigatorRequest: true, - updatingAllIndicesAtOrBeyond: updatingAllIndicesAtOrBeyond, - }); - }, - - /** - * Navigate forward to a new route. - * @param route The new route to navigate to. - */ - push: function(route: Route) { - invariant(!!route, 'Must supply route to push'); - // Make sure all previous requests are caught up first. Otherwise reject. - if (this.state.requestedTopOfStack === this.state.observedTopOfStack) { - this._tryLockNavigator(() => { - const nextStack = this.state.routeStack.concat([route]); - const nextIDStack = this.state.idStack.concat([getuid()]); - this.setState({ - // We have to make sure that we've also supplied enough views to - // satisfy our request to adjust the `requestedTopOfStack`. - idStack: nextIDStack, - routeStack: nextStack, - requestedTopOfStack: nextStack.length - 1, - makingNavigatorRequest: true, - updatingAllIndicesAtOrBeyond: nextStack.length - 1, - }); - }); - } - }, - - /** - * Go back N scenes at once. When N=1, behavior matches `pop()`. - * @param n The number of scenes to pop. - */ - popN: function(n: number) { - if (n === 0) { - return; - } - // Make sure all previous requests are caught up first. Otherwise reject. - if (this.state.requestedTopOfStack === this.state.observedTopOfStack) { - if (this.state.requestedTopOfStack > 0) { - this._tryLockNavigator(() => { - const newRequestedTopOfStack = this.state.requestedTopOfStack - n; - invariant(newRequestedTopOfStack >= 0, 'Cannot pop below 0'); - this.setState({ - requestedTopOfStack: newRequestedTopOfStack, - makingNavigatorRequest: true, - updatingAllIndicesAtOrBeyond: this.state.requestedTopOfStack - n, - }); - }); - } - } - }, - - /** - * Pop back to the previous scene. - */ - pop: function() { - this.popN(1); - }, - - /** - * Replace a route in the navigation stack. - * - * @param route The new route that will replace the specified one. - * @param index The route into the stack that should be replaced. - * If it is negative, it counts from the back of the stack. - */ - replaceAtIndex: function(route: Route, index: number) { - invariant(!!route, 'Must supply route to replace'); - if (index < 0) { - index += this.state.routeStack.length; - } - - if (this.state.routeStack.length <= index) { - return; - } - - // I don't believe we need to lock for a replace since there's no - // navigation actually happening - const nextIDStack = this.state.idStack.slice(); - const nextRouteStack = this.state.routeStack.slice(); - nextIDStack[index] = getuid(); - nextRouteStack[index] = route; - - this.setState({ - idStack: nextIDStack, - routeStack: nextRouteStack, - makingNavigatorRequest: false, - updatingAllIndicesAtOrBeyond: index, - }); - }, - - /** - * Replace the route for the current scene and immediately - * load the view for the new route. - * @param route The new route to navigate to. - */ - replace: function(route: Route) { - this.replaceAtIndex(route, -1); - }, - - /** - * Replace the route/view for the previous scene. - * @param route The new route to will replace the previous scene. - */ - replacePrevious: function(route: Route) { - this.replaceAtIndex(route, -2); - }, - - /** - * Go back to the topmost item in the navigation stack. - */ - popToTop: function() { - this.popToRoute(this.state.routeStack[0]); - }, - - /** - * Go back to the item for a particular route object. - * @param route The new route to navigate to. - */ - popToRoute: function(route: Route) { - const indexOfRoute = this.state.routeStack.indexOf(route); - invariant( - indexOfRoute !== -1, - "Calling pop to route for a route that doesn't exist!", - ); - const numToPop = this.state.routeStack.length - indexOfRoute - 1; - this.popN(numToPop); - }, - - /** - * Replaces the previous route/view and transitions back to it. - * @param route The new route that replaces the previous scene. - */ - replacePreviousAndPop: function(route: Route) { - // Make sure all previous requests are caught up first. Otherwise reject. - if (this.state.requestedTopOfStack !== this.state.observedTopOfStack) { - return; - } - if (this.state.routeStack.length < 2) { - return; - } - this._tryLockNavigator(() => { - this.replacePrevious(route); - this.setState({ - requestedTopOfStack: this.state.requestedTopOfStack - 1, - makingNavigatorRequest: true, - }); - }); - }, - - /** - * Replaces the top item and pop to it. - * @param route The new route that will replace the topmost item. - */ - resetTo: function(route: Route) { - invariant(!!route, 'Must supply route to push'); - // Make sure all previous requests are caught up first. Otherwise reject. - if (this.state.requestedTopOfStack !== this.state.observedTopOfStack) { - return; - } - this.replaceAtIndex(route, 0); - this.popToRoute(route); - }, - - _handleNavigationComplete: function(e: Event) { - // Don't propagate to other NavigatorIOS instances this is nested in: - e.stopPropagation(); - - if (this._toFocusOnNavigationComplete) { - this._getFocusEmitter().emit('focus', this._toFocusOnNavigationComplete); - this._toFocusOnNavigationComplete = null; - } - this._handleNavigatorStackChanged(e); - }, - - _routeToStackItem: function(routeArg: Route, i: number) { - const {component, wrapperStyle, passProps, ...route} = routeArg; - const {itemWrapperStyle, ...props} = this.props; - const shouldUpdateChild = - this.state.updatingAllIndicesAtOrBeyond != null && - this.state.updatingAllIndicesAtOrBeyond >= i; - const Component = component; - return ( - - - - - - ); - }, - - _renderNavigationStackItems: function() { - const shouldRecurseToNavigator = - this.state.makingNavigatorRequest || - this.state.updatingAllIndicesAtOrBeyond !== null; - // If not recursing update to navigator at all, may as well avoid - // computation of navigator children. - const items = shouldRecurseToNavigator - ? this.state.routeStack.map(this._routeToStackItem) - : null; - return ( - - =0.41.0) - vertical={this.props.vertical} - requestedTopOfStack={this.state.requestedTopOfStack} - onNavigationComplete={this._handleNavigationComplete} - interactivePopGestureEnabled={ - this.props.interactivePopGestureEnabled - }> - {items} - - - ); - }, - - _tvEventHandler: (undefined: ?TVEventHandler), - - _enableTVEventHandler: function() { - this._tvEventHandler = new TVEventHandler(); - this._tvEventHandler.enable(this, function(cmp, evt) { - if (evt && evt.eventType === 'menu') { - cmp.pop(); - } - }); - }, - - _disableTVEventHandler: function() { - if (this._tvEventHandler) { - this._tvEventHandler.disable(); - delete this._tvEventHandler; - } - }, - - render: function() { - return ( - // $FlowFixMe(>=0.41.0) - {this._renderNavigationStackItems()} - ); - }, -}); - -const styles = StyleSheet.create({ - stackItem: { - backgroundColor: 'white', - overflow: 'hidden', - position: 'absolute', - top: 0, - left: 0, - right: 0, - bottom: 0, - }, - transitioner: { - flex: 1, - }, -}); - -const RCTNavigator = requireNativeComponent('RCTNavigator'); -const RCTNavigatorItem = requireNativeComponent('RCTNavItem'); - -module.exports = NavigatorIOS; diff --git a/Libraries/Components/Picker/Picker.js b/Libraries/Components/Picker/Picker.js index 1e3e96579e21cb..88a70a59f6d05f 100644 --- a/Libraries/Components/Picker/Picker.js +++ b/Libraries/Components/Picker/Picker.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -10,64 +10,103 @@ 'use strict'; -const ColorPropType = require('ColorPropType'); -const PickerIOS = require('PickerIOS'); const PickerAndroid = require('PickerAndroid'); +const PickerIOS = require('PickerIOS'); const Platform = require('Platform'); const React = require('React'); -const PropTypes = require('prop-types'); -const StyleSheetPropType = require('StyleSheetPropType'); -const TextStylePropTypes = require('TextStylePropTypes'); const UnimplementedView = require('UnimplementedView'); -const ViewPropTypes = require('ViewPropTypes'); -const ViewStylePropTypes = require('ViewStylePropTypes'); - -const itemStylePropType = StyleSheetPropType(TextStylePropTypes); -const pickerStyleType = StyleSheetPropType({ - ...ViewStylePropTypes, - color: ColorPropType, -}); +import type {TextStyleProp} from 'StyleSheet'; +import type {ColorValue} from 'StyleSheetTypes'; const MODE_DIALOG = 'dialog'; const MODE_DROPDOWN = 'dropdown'; -/** - * Individual selectable item in a Picker. - */ -class PickerItem extends React.Component<{ +type PickerItemProps = $ReadOnly<{| + /** + * Text to display for this item. + */ label: string, + + /** + * The value to be passed to picker's `onValueChange` callback when + * this item is selected. Can be a string or an integer. + */ value?: any, - color?: ColorPropType, + + /** + * Color of this item's text. + * @platform android + */ + color?: ColorValue, + + /** + * Used to locate the item in end-to-end tests. + */ testID?: string, -}> { - static propTypes = { - /** - * Text to display for this item. - */ - label: PropTypes.string.isRequired, - /** - * The value to be passed to picker's `onValueChange` callback when - * this item is selected. Can be a string or an integer. - */ - value: PropTypes.any, - /** - * Color of this item's text. - * @platform android - */ - color: ColorPropType, - /** - * Used to locate the item in end-to-end tests. - */ - testID: PropTypes.string, - }; +|}>; +/** + * Individual selectable item in a Picker. + */ +class PickerItem extends React.Component { render() { // The items are not rendered directly throw null; } } +type PickerProps = $ReadOnly<{| + children?: React.Node, + style?: ?TextStyleProp, + + /** + * Value matching value of one of the items. Can be a string or an integer. + */ + selectedValue?: any, + + /** + * Callback for when an item is selected. This is called with the following parameters: + * - `itemValue`: the `value` prop of the item that was selected + * - `itemPosition`: the index of the selected item in this picker + */ + onValueChange?: ?(newValue: any, newIndex: number) => mixed, + + /** + * If set to false, the picker will be disabled, i.e. the user will not be able to make a + * selection. + * @platform android + */ + enabled?: ?boolean, + + /** + * On Android, specifies how to display the selection items when the user taps on the picker: + * + * - 'dialog': Show a modal dialog. This is the default. + * - 'dropdown': Shows a dropdown anchored to the picker view + * + * @platform android + */ + mode?: ?('dialog' | 'dropdown'), + + /** + * Style to apply to each of the item labels. + * @platform ios + */ + itemStyle?: ?TextStyleProp, + + /** + * Prompt string for this picker, used on Android in dialog mode as the title of the dialog. + * @platform android + */ + prompt?: ?string, + + /** + * Used to locate this view in end-to-end tests. + */ + testID?: ?string, +|}>; + /** * Renders the native picker component on iOS and Android. Example: * @@ -78,16 +117,7 @@ class PickerItem extends React.Component<{ * * */ -class Picker extends React.Component<{ - style?: $FlowFixMe, - selectedValue?: any, - onValueChange?: Function, - enabled?: boolean, - mode?: 'dialog' | 'dropdown', - itemStyle?: $FlowFixMe, - prompt?: string, - testID?: string, -}> { +class Picker extends React.Component { /** * On Android, display the options in a dialog. */ @@ -104,58 +134,15 @@ class Picker extends React.Component<{ mode: MODE_DIALOG, }; - // $FlowFixMe(>=0.41.0) - static propTypes = { - ...ViewPropTypes, - style: pickerStyleType, - /** - * Value matching value of one of the items. Can be a string or an integer. - */ - selectedValue: PropTypes.any, - /** - * Callback for when an item is selected. This is called with the following parameters: - * - `itemValue`: the `value` prop of the item that was selected - * - `itemPosition`: the index of the selected item in this picker - */ - onValueChange: PropTypes.func, - /** - * If set to false, the picker will be disabled, i.e. the user will not be able to make a - * selection. - * @platform android - */ - enabled: PropTypes.bool, - /** - * On Android, specifies how to display the selection items when the user taps on the picker: - * - * - 'dialog': Show a modal dialog. This is the default. - * - 'dropdown': Shows a dropdown anchored to the picker view - * - * @platform android - */ - mode: PropTypes.oneOf(['dialog', 'dropdown']), - /** - * Style to apply to each of the item labels. - * @platform ios - */ - itemStyle: itemStylePropType, - /** - * Prompt string for this picker, used on Android in dialog mode as the title of the dialog. - * @platform android - */ - prompt: PropTypes.string, - /** - * Used to locate this view in end-to-end tests. - */ - testID: PropTypes.string, - }; - render() { if (Platform.OS === 'ios') { - // $FlowFixMe found when converting React.createClass to ES6 + /* $FlowFixMe(>=0.81.0 site=react_native_ios_fb) This suppression was + * added when renaming suppression sites. */ return {this.props.children}; } else if (Platform.OS === 'android') { return ( - // $FlowFixMe found when converting React.createClass to ES6 + /* $FlowFixMe(>=0.81.0 site=react_native_android_fb) This suppression + * was added when renaming suppression sites. */ {this.props.children} ); } else { diff --git a/Libraries/Components/Picker/PickerAndroid.android.js b/Libraries/Components/Picker/PickerAndroid.android.js index 1f80aa3928d05c..2fb010506853e0 100644 --- a/Libraries/Components/Picker/PickerAndroid.android.js +++ b/Libraries/Components/Picker/PickerAndroid.android.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -10,13 +10,8 @@ 'use strict'; -const ColorPropType = require('ColorPropType'); const React = require('React'); -const ReactPropTypes = require('prop-types'); const StyleSheet = require('StyleSheet'); -const StyleSheetPropType = require('StyleSheetPropType'); -const ViewPropTypes = require('ViewPropTypes'); -const ViewStylePropTypes = require('ViewStylePropTypes'); const processColor = require('processColor'); const requireNativeComponent = require('requireNativeComponent'); @@ -27,39 +22,32 @@ const DialogPicker = requireNativeComponent('AndroidDialogPicker'); const REF_PICKER = 'picker'; const MODE_DROPDOWN = 'dropdown'; -const pickerStyleType = StyleSheetPropType({ - ...ViewStylePropTypes, - color: ColorPropType, -}); - -type Event = Object; +import type {SyntheticEvent} from 'CoreEventTypes'; +import type {TextStyleProp} from 'StyleSheet'; + +type PickerAndroidChangeEvent = SyntheticEvent< + $ReadOnly<{| + position: number, + |}>, +>; + +type PickerAndroidProps = $ReadOnly<{| + children?: React.Node, + style?: ?TextStyleProp, + selectedValue?: any, + enabled?: ?boolean, + mode?: ?('dialog' | 'dropdown'), + onValueChange?: ?(newValue: any, newIndex: number) => mixed, + prompt?: ?string, + testID?: string, +|}>; /** * Not exposed as a public API - use instead. */ -class PickerAndroid extends React.Component< - { - style?: $FlowFixMe, - selectedValue?: any, - enabled?: boolean, - mode?: 'dialog' | 'dropdown', - onValueChange?: Function, - prompt?: string, - testID?: string, - }, - *, -> { - static propTypes = { - ...ViewPropTypes, - style: pickerStyleType, - selectedValue: ReactPropTypes.any, - enabled: ReactPropTypes.bool, - mode: ReactPropTypes.oneOf(['dialog', 'dropdown']), - onValueChange: ReactPropTypes.func, - prompt: ReactPropTypes.string, - testID: ReactPropTypes.string, - }; - +class PickerAndroid extends React.Component { + /* $FlowFixMe(>=0.78.0 site=react_native_android_fb) This issue was found + * when making Flow check .android.js files. */ constructor(props, context) { super(props, context); const state = this._stateFromProps(props); @@ -70,6 +58,8 @@ class PickerAndroid extends React.Component< }; } + /* $FlowFixMe(>=0.78.0 site=react_native_android_fb) This issue was found + * when making Flow check .android.js files. */ UNSAFE_componentWillReceiveProps(nextProps) { this.setState(this._stateFromProps(nextProps)); } @@ -86,6 +76,8 @@ class PickerAndroid extends React.Component< label: child.props.label, }; if (child.props.color) { + /* $FlowFixMe(>=0.78.0 site=react_native_android_fb) This issue was + * found when making Flow check .android.js files. */ childProps.color = processColor(child.props.color); } return childProps; @@ -106,28 +98,36 @@ class PickerAndroid extends React.Component< selected: this.state.initialSelectedIndex, testID: this.props.testID, style: [styles.pickerAndroid, this.props.style], + /* $FlowFixMe(>=0.78.0 site=react_native_android_fb) This issue was found + * when making Flow check .android.js files. */ accessibilityLabel: this.props.accessibilityLabel, }; return ; } - _onChange = (event: Event) => { + _onChange = (event: PickerAndroidChangeEvent) => { if (this.props.onValueChange) { const position = event.nativeEvent.position; if (position >= 0) { const children = React.Children.toArray(this.props.children); const value = children[position].props.value; + /* $FlowFixMe(>=0.78.0 site=react_native_android_fb) This issue was + * found when making Flow check .android.js files. */ this.props.onValueChange(value, position); } else { this.props.onValueChange(null, position); } } + /* $FlowFixMe(>=0.78.0 site=react_native_android_fb) This issue was found + * when making Flow check .android.js files. */ this._lastNativePosition = event.nativeEvent.position; this.forceUpdate(); }; componentDidMount() { + /* $FlowFixMe(>=0.78.0 site=react_native_android_fb) This issue was found + * when making Flow check .android.js files. */ this._lastNativePosition = this.state.initialSelectedIndex; } @@ -140,11 +140,15 @@ class PickerAndroid extends React.Component< // truth, not the native component. if ( this.refs[REF_PICKER] && + /* $FlowFixMe(>=0.78.0 site=react_native_android_fb) This issue was found + * when making Flow check .android.js files. */ this.state.selectedIndex !== this._lastNativePosition ) { this.refs[REF_PICKER].setNativeProps({ selected: this.state.selectedIndex, }); + /* $FlowFixMe(>=0.78.0 site=react_native_android_fb) This issue was found + * when making Flow check .android.js files. */ this._lastNativePosition = this.state.selectedIndex; } } diff --git a/Libraries/Components/Picker/PickerAndroid.ios.js b/Libraries/Components/Picker/PickerAndroid.ios.js index 260d559929796f..7a00b6636cf664 100644 --- a/Libraries/Components/Picker/PickerAndroid.ios.js +++ b/Libraries/Components/Picker/PickerAndroid.ios.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Components/Picker/PickerIOS.android.js b/Libraries/Components/Picker/PickerIOS.android.js index 36acfe18342b6f..006c5b4d1ae82f 100644 --- a/Libraries/Components/Picker/PickerIOS.android.js +++ b/Libraries/Components/Picker/PickerIOS.android.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Components/Picker/PickerIOS.ios.js b/Libraries/Components/Picker/PickerIOS.ios.js index 62ebe53e89a3ea..fa2fabc09404e2 100644 --- a/Libraries/Components/Picker/PickerIOS.ios.js +++ b/Libraries/Components/Picker/PickerIOS.ios.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Components/ProgressBarAndroid/ProgressBarAndroid.android.js b/Libraries/Components/ProgressBarAndroid/ProgressBarAndroid.android.js index f343e2e5452044..a6f64f011ef074 100644 --- a/Libraries/Components/ProgressBarAndroid/ProgressBarAndroid.android.js +++ b/Libraries/Components/ProgressBarAndroid/ProgressBarAndroid.android.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Components/ProgressBarAndroid/ProgressBarAndroid.ios.js b/Libraries/Components/ProgressBarAndroid/ProgressBarAndroid.ios.js index 260d559929796f..7a00b6636cf664 100644 --- a/Libraries/Components/ProgressBarAndroid/ProgressBarAndroid.ios.js +++ b/Libraries/Components/ProgressBarAndroid/ProgressBarAndroid.ios.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Components/ProgressViewIOS/ProgressViewIOS.android.js b/Libraries/Components/ProgressViewIOS/ProgressViewIOS.android.js index 8caa73db33e494..1b5a1436e4f1ba 100644 --- a/Libraries/Components/ProgressViewIOS/ProgressViewIOS.android.js +++ b/Libraries/Components/ProgressViewIOS/ProgressViewIOS.android.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Components/ProgressViewIOS/ProgressViewIOS.ios.js b/Libraries/Components/ProgressViewIOS/ProgressViewIOS.ios.js index ea92fccb980583..7b0bff3a248f8a 100644 --- a/Libraries/Components/ProgressViewIOS/ProgressViewIOS.ios.js +++ b/Libraries/Components/ProgressViewIOS/ProgressViewIOS.ios.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -10,82 +10,70 @@ 'use strict'; -const Image = require('Image'); -const NativeMethodsMixin = require('NativeMethodsMixin'); const React = require('React'); -const ReactNative = require('ReactNative'); -const PropTypes = require('prop-types'); const StyleSheet = require('StyleSheet'); -const ViewPropTypes = require('ViewPropTypes'); const createReactClass = require('create-react-class'); const requireNativeComponent = require('requireNativeComponent'); +import type {NativeComponent} from 'ReactNative'; import type {ImageSource} from 'ImageSource'; import type {ColorValue} from 'StyleSheetTypes'; import type {ViewProps} from 'ViewPropTypes'; -const RCTProgressView = requireNativeComponent('RCTProgressView'); - type Props = $ReadOnly<{| ...ViewProps, + + /** + * The progress bar style. + */ progressViewStyle?: ?('default' | 'bar'), + + /** + * The progress value (between 0 and 1). + */ progress?: ?number, + + /** + * The tint color of the progress bar itself. + */ progressTintColor?: ?ColorValue, - trackTintColor?: ?string, + + /** + * The tint color of the progress bar track. + */ + trackTintColor?: ?ColorValue, + + /** + * A stretchable image to display as the progress bar. + */ progressImage?: ?ImageSource, + + /** + * A stretchable image to display behind the progress bar. + */ trackImage?: ?ImageSource, |}>; +type NativeProgressViewIOS = Class>; + +const RCTProgressView = ((requireNativeComponent( + 'RCTProgressView', +): any): NativeProgressViewIOS); + /** * Use `ProgressViewIOS` to render a UIProgressView on iOS. */ -const ProgressViewIOS = createReactClass({ - displayName: 'ProgressViewIOS', - mixins: [NativeMethodsMixin], - - propTypes: { - ...ViewPropTypes, - /** - * The progress bar style. - */ - progressViewStyle: PropTypes.oneOf(['default', 'bar']), - - /** - * The progress value (between 0 and 1). - */ - progress: PropTypes.number, - - /** - * The tint color of the progress bar itself. - */ - progressTintColor: PropTypes.string, - - /** - * The tint color of the progress bar track. - */ - trackTintColor: PropTypes.string, - - /** - * A stretchable image to display as the progress bar. - */ - progressImage: Image.propTypes.source, - - /** - * A stretchable image to display behind the progress bar. - */ - trackImage: Image.propTypes.source, - }, - - render: function() { - return ( - - ); - }, -}); +const ProgressViewIOS = ( + props: Props, + forwardedRef?: ?React.Ref, +) => ( + +); const styles = StyleSheet.create({ progressView: { @@ -93,6 +81,7 @@ const styles = StyleSheet.create({ }, }); -module.exports = ((ProgressViewIOS: any): Class< - ReactNative.NativeComponent, ->); +// $FlowFixMe - TODO T29156721 `React.forwardRef` is not defined in Flow, yet. +const ProgressViewIOSWithRef = React.forwardRef(ProgressViewIOS); + +module.exports = (ProgressViewIOSWithRef: NativeProgressViewIOS); diff --git a/Libraries/Components/RefreshControl/RefreshControl.js b/Libraries/Components/RefreshControl/RefreshControl.js index 9b287cc4a180b9..0f3f4c857557df 100644 --- a/Libraries/Components/RefreshControl/RefreshControl.js +++ b/Libraries/Components/RefreshControl/RefreshControl.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -15,21 +15,22 @@ const React = require('React'); const {NativeComponent} = require('ReactNative'); const requireNativeComponent = require('requireNativeComponent'); -const nullthrows = require('fbjs/lib/nullthrows'); +const nullthrows = require('nullthrows'); import type {ColorValue} from 'StyleSheetTypes'; import type {ViewProps} from 'ViewPropTypes'; if (Platform.OS === 'android') { - const AndroidSwipeRefreshLayout = require('UIManager') - .AndroidSwipeRefreshLayout; + const AndroidSwipeRefreshLayout = require('UIManager').getViewManagerConfig( + 'AndroidSwipeRefreshLayout', + ); var RefreshLayoutConsts = AndroidSwipeRefreshLayout ? AndroidSwipeRefreshLayout.Constants : {SIZE: {}}; } else { var RefreshLayoutConsts = {SIZE: {}}; } -type NativeRefreshControlType = Class>; +type NativeRefreshControlType = Class>; const NativeRefreshControl: NativeRefreshControlType = Platform.OS === 'ios' @@ -77,7 +78,7 @@ type AndroidProps = $ReadOnly<{| progressViewOffset?: ?number, |}>; -type Props = $ReadOnly<{| +export type RefreshControlProps = $ReadOnly<{| ...ViewProps, ...IOSProps, ...AndroidProps, @@ -138,7 +139,7 @@ type Props = $ReadOnly<{| * __Note:__ `refreshing` is a controlled prop, this is why it needs to be set to true * in the `onRefresh` function otherwise the refresh indicator will stop immediately. */ -class RefreshControl extends React.Component { +class RefreshControl extends React.Component { static SIZE = RefreshLayoutConsts.SIZE; _nativeRef: ?React.ElementRef = null; @@ -148,7 +149,7 @@ class RefreshControl extends React.Component { this._lastNativeRefreshing = this.props.refreshing; } - componentDidUpdate(prevProps: Props) { + componentDidUpdate(prevProps: RefreshControlProps) { // RefreshControl is a controlled component so if the native refreshing // value doesn't match the current js refreshing prop update it to // the js value. diff --git a/Libraries/Components/RefreshControl/__mocks__/RefreshControlMock.js b/Libraries/Components/RefreshControl/__mocks__/RefreshControlMock.js index bc03b7afa87878..daa576350aa120 100644 --- a/Libraries/Components/RefreshControl/__mocks__/RefreshControlMock.js +++ b/Libraries/Components/RefreshControl/__mocks__/RefreshControlMock.js @@ -1,11 +1,11 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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 + * @flow strict-local */ 'use strict'; diff --git a/Libraries/Components/SafeAreaView/SafeAreaView.ios.js b/Libraries/Components/SafeAreaView/SafeAreaView.ios.js deleted file mode 100644 index 5fb0406b8d5125..00000000000000 --- a/Libraries/Components/SafeAreaView/SafeAreaView.ios.js +++ /dev/null @@ -1,39 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @flow - * @format - */ - -const React = require('React'); -const ViewPropTypes = require('ViewPropTypes'); -const requireNativeComponent = require('requireNativeComponent'); - -import type {ViewProps} from 'ViewPropTypes'; - -const RCTSafeAreaView = requireNativeComponent('RCTSafeAreaView'); - -type Props = ViewProps & { - children: any, -}; - -/** - * Renders nested content and automatically applies paddings reflect the portion of the view - * that is not covered by navigation bars, tab bars, toolbars, and other ancestor views. - * Moreover, and most importantly, Safe Area's paddings reflect physical limitation of the screen, - * such as rounded corners or camera notches (aka sensor housing area on iPhone X). - */ -class SafeAreaView extends React.Component { - static propTypes = { - ...ViewPropTypes, - }; - - render() { - return ; - } -} - -module.exports = SafeAreaView; diff --git a/Libraries/Components/SafeAreaView/SafeAreaView.js b/Libraries/Components/SafeAreaView/SafeAreaView.js new file mode 100644 index 00000000000000..6f4ecf3ac867b4 --- /dev/null +++ b/Libraries/Components/SafeAreaView/SafeAreaView.js @@ -0,0 +1,50 @@ +/** + * 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 + */ + +const Platform = require('Platform'); +const React = require('React'); +const View = require('View'); +const requireNativeComponent = require('requireNativeComponent'); + +import type {ViewProps} from 'ViewPropTypes'; + +type Props = $ReadOnly<{| + ...ViewProps, + emulateUnlessSupported?: boolean, +|}>; + +let exported; + +/** + * Renders nested content and automatically applies paddings reflect the portion + * of the view that is not covered by navigation bars, tab bars, toolbars, and + * other ancestor views. + * + * Moreover, and most importantly, Safe Area's paddings reflect physical + * limitation of the screen, such as rounded corners or camera notches (aka + * sensor housing area on iPhone X). + */ +if (Platform.OS === 'android') { + exported = class SafeAreaView extends React.Component { + render(): React.Node { + const {emulateUnlessSupported, ...props} = this.props; + return ; + } + }; +} else { + const RCTSafeAreaView = requireNativeComponent('RCTSafeAreaView'); + exported = class SafeAreaView extends React.Component { + render(): React.Node { + return ; + } + }; +} + +module.exports = exported; diff --git a/Libraries/Components/ScrollResponder.js b/Libraries/Components/ScrollResponder.js index 548efba80da48c..42079dec32abfa 100644 --- a/Libraries/Components/ScrollResponder.js +++ b/Libraries/Components/ScrollResponder.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -14,17 +14,18 @@ const Dimensions = require('Dimensions'); const FrameRateLogger = require('FrameRateLogger'); const Keyboard = require('Keyboard'); const ReactNative = require('ReactNative'); -const Subscribable = require('Subscribable'); const TextInputState = require('TextInputState'); const UIManager = require('UIManager'); const invariant = require('fbjs/lib/invariant'); -const nullthrows = require('fbjs/lib/nullthrows'); +const nullthrows = require('nullthrows'); const performanceNow = require('fbjs/lib/performanceNow'); const warning = require('fbjs/lib/warning'); const {ScrollViewManager} = require('NativeModules'); +import type EmitterSubscription from 'EmitterSubscription'; + /** * Mixin that can be integrated in order to handle scrolling that plays well * with `ResponderEventPlugin`. Integrate with your platform specific scroll @@ -115,7 +116,10 @@ type State = { type Event = Object; const ScrollResponderMixin = { - mixins: [Subscribable.Mixin], + _subscriptionKeyboardWillShow: (null: ?EmitterSubscription), + _subscriptionKeyboardWillHide: (null: ?EmitterSubscription), + _subscriptionKeyboardDidShow: (null: ?EmitterSubscription), + _subscriptionKeyboardDidHide: (null: ?EmitterSubscription), scrollResponderMixinGetInitialState: function(): State { return { isTouching: false, @@ -436,7 +440,7 @@ const ScrollResponderMixin = { } UIManager.dispatchViewManagerCommand( nullthrows(this.scrollResponderGetScrollableNode()), - UIManager.RCTScrollView.Commands.scrollTo, + UIManager.getViewManagerConfig('RCTScrollView').Commands.scrollTo, [x || 0, y || 0, animated !== false], ); }, @@ -454,7 +458,7 @@ const ScrollResponderMixin = { const animated = (options && options.animated) !== false; UIManager.dispatchViewManagerCommand( this.scrollResponderGetScrollableNode(), - UIManager.RCTScrollView.Commands.scrollToEnd, + UIManager.getViewManagerConfig('RCTScrollView').Commands.scrollToEnd, [animated], ); }, @@ -513,7 +517,8 @@ const ScrollResponderMixin = { scrollResponderFlashScrollIndicators: function() { UIManager.dispatchViewManagerCommand( this.scrollResponderGetScrollableNode(), - UIManager.RCTScrollView.Commands.flashScrollIndicators, + UIManager.getViewManagerConfig('RCTScrollView').Commands + .flashScrollIndicators, [], ); }, @@ -601,28 +606,39 @@ const ScrollResponderMixin = { this.keyboardWillOpenTo = null; this.additionalScrollOffset = 0; - this.addListenerOn( - Keyboard, + this._subscriptionKeyboardWillShow = Keyboard.addListener( 'keyboardWillShow', this.scrollResponderKeyboardWillShow, ); - this.addListenerOn( - Keyboard, + this._subscriptionKeyboardWillHide = Keyboard.addListener( 'keyboardWillHide', this.scrollResponderKeyboardWillHide, ); - this.addListenerOn( - Keyboard, + this._subscriptionKeyboardDidShow = Keyboard.addListener( 'keyboardDidShow', this.scrollResponderKeyboardDidShow, ); - this.addListenerOn( - Keyboard, + this._subscriptionKeyboardDidHide = Keyboard.addListener( 'keyboardDidHide', this.scrollResponderKeyboardDidHide, ); }, + componentWillUnmount: function() { + if (this._subscriptionKeyboardWillShow != null) { + this._subscriptionKeyboardWillShow.remove(); + } + if (this._subscriptionKeyboardWillHide != null) { + this._subscriptionKeyboardWillHide.remove(); + } + if (this._subscriptionKeyboardDidShow != null) { + this._subscriptionKeyboardDidShow.remove(); + } + if (this._subscriptionKeyboardDidHide != null) { + this._subscriptionKeyboardDidHide.remove(); + } + }, + /** * Warning, this may be called several times for a single keyboard opening. * It's best to store the information in this method and then take any action diff --git a/Libraries/Components/ScrollView/InternalScrollViewType.js b/Libraries/Components/ScrollView/InternalScrollViewType.js index 471e25d9a5dab9..a13db7dee6a65b 100644 --- a/Libraries/Components/ScrollView/InternalScrollViewType.js +++ b/Libraries/Components/ScrollView/InternalScrollViewType.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Components/ScrollView/ScrollView.js b/Libraries/Components/ScrollView/ScrollView.js index 9f0688e87489f3..a8b46291190083 100644 --- a/Libraries/Components/ScrollView/ScrollView.js +++ b/Libraries/Components/ScrollView/ScrollView.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -125,19 +125,6 @@ type IOSProps = $ReadOnly<{| * @platform ios */ centerContent?: ?boolean, - /** - * A floating-point number that determines how quickly the scroll view - * decelerates after the user lifts their finger. You may also use string - * shortcuts `"normal"` and `"fast"` which match the underlying iOS settings - * for `UIScrollViewDecelerationRateNormal` and - * `UIScrollViewDecelerationRateFast` respectively. - * - * - `'normal'`: 0.998 (the default) - * - `'fast'`: 0.99 - * - * @platform ios - */ - decelerationRate?: ?('fast' | 'normal' | number), /** * The style of the scroll indicators. * @@ -230,6 +217,11 @@ type IOSProps = $ReadOnly<{| * @platform ios */ scrollsToTop?: ?boolean, + /** + * Fires when the scroll view scrolls to top after the status bar has been tapped + * @platform ios + */ + onScrollToTop?: ?Function, /** * When true, shows a horizontal scroll indicator. * The default value is true. @@ -353,6 +345,17 @@ export type Props = $ReadOnly<{| * ``` */ contentContainerStyle?: ?ViewStyleProp, + /** + * A floating-point number that determines how quickly the scroll view + * decelerates after the user lifts their finger. You may also use string + * shortcuts `"normal"` and `"fast"` which match the underlying iOS settings + * for `UIScrollViewDecelerationRateNormal` and + * `UIScrollViewDecelerationRateFast` respectively. + * + * - `'normal'`: 0.998 on iOS, 0.985 on Android (the default) + * - `'fast'`: 0.99 on iOS, 0.9 on Android + */ + decelerationRate?: ?('fast' | 'normal' | number), /** * When true, the scroll view's children are arranged horizontally in a row * instead of vertically in a column. The default value is false. @@ -462,12 +465,36 @@ export type Props = $ReadOnly<{| * When set, causes the scroll view to stop at multiples of the value of * `snapToInterval`. This can be used for paginating through children * that have lengths smaller than the scroll view. Typically used in - * combination with `snapToAlignment` and `decelerationRate="fast"` on ios. - * Overrides less configurable `pagingEnabled` prop. + * combination with `snapToAlignment` and `decelerationRate="fast"`. * - * Supported for horizontal scrollview on android. + * Overrides less configurable `pagingEnabled` prop. */ snapToInterval?: ?number, + /** + * When set, causes the scroll view to stop at the defined offsets. + * This can be used for paginating through variously sized children + * that have lengths smaller than the scroll view. Typically used in + * combination with `decelerationRate="fast"`. + * + * Overrides less configurable `pagingEnabled` and `snapToInterval` props. + */ + snapToOffsets?: ?$ReadOnlyArray, + /** + * Use in conjuction with `snapToOffsets`. By default, the beginning + * of the list counts as a snap offset. Set `snapToStart` to false to disable + * this behavior and allow the list to scroll freely between its start and + * the first `snapToOffsets` offset. + * The default value is true. + */ + snapToStart?: ?boolean, + /** + * Use in conjuction with `snapToOffsets`. By default, the end + * of the list counts as a snap offset. Set `snapToEnd` to false to disable + * this behavior and allow the list to scroll freely between its end and + * the last `snapToOffsets` offset. + * The default value is true. + */ + snapToEnd?: ?boolean, /** * Experimental: When true, offscreen child views (whose `overflow` value is * `hidden`) are removed from their native backing superview when offscreen. @@ -483,7 +510,6 @@ export type Props = $ReadOnly<{| * See [RefreshControl](docs/refreshcontrol.html). */ refreshControl?: ?React.Element, - style?: ?ViewStyleProp, children?: React.Node, |}>; @@ -773,10 +799,6 @@ const ScrollView = createReactClass({ } else { ScrollViewClass = RCTScrollView; ScrollContentContainerViewClass = RCTScrollContentView; - warning( - this.props.snapToInterval == null || !this.props.pagingEnabled, - 'snapToInterval is currently ignored when pagingEnabled is true.', - ); } invariant( @@ -920,6 +942,23 @@ const ScrollView = createReactClass({ ? true : false, DEPRECATED_sendUpdatedChildFrames, + // default to true + snapToStart: this.props.snapToStart !== false, + // default to true + snapToEnd: this.props.snapToEnd !== false, + // pagingEnabled is overridden by snapToInterval / snapToOffsets + pagingEnabled: Platform.select({ + // on iOS, pagingEnabled must be set to false to have snapToInterval / snapToOffsets work + ios: + this.props.pagingEnabled && + this.props.snapToInterval == null && + this.props.snapToOffsets == null, + // on Android, pagingEnabled must be set to true to have snapToInterval / snapToOffsets work + android: + this.props.pagingEnabled || + this.props.snapToInterval != null || + this.props.snapToOffsets != null, + }), }; const {decelerationRate} = this.props; diff --git a/Libraries/Components/ScrollView/ScrollViewStickyHeader.js b/Libraries/Components/ScrollView/ScrollViewStickyHeader.js index e17467b264cd98..5ad409c783e96f 100644 --- a/Libraries/Components/ScrollView/ScrollViewStickyHeader.js +++ b/Libraries/Components/ScrollView/ScrollViewStickyHeader.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Components/ScrollView/__mocks__/ScrollViewMock.js b/Libraries/Components/ScrollView/__mocks__/ScrollViewMock.js index 46f691382d2f6e..17e55550f35aea 100644 --- a/Libraries/Components/ScrollView/__mocks__/ScrollViewMock.js +++ b/Libraries/Components/ScrollView/__mocks__/ScrollViewMock.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2013-present, Facebook, Inc. + * 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. diff --git a/Libraries/Components/ScrollView/processDecelerationRate.js b/Libraries/Components/ScrollView/processDecelerationRate.js index 18b903ffa3831c..a685381715d835 100644 --- a/Libraries/Components/ScrollView/processDecelerationRate.js +++ b/Libraries/Components/ScrollView/processDecelerationRate.js @@ -1,19 +1,30 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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'; -function processDecelerationRate(decelerationRate) { +const Platform = require('Platform'); + +function processDecelerationRate( + decelerationRate: number | 'normal' | 'fast', +): number { if (decelerationRate === 'normal') { - decelerationRate = 0.998; + return Platform.select({ + ios: 0.998, + android: 0.985, + }); } else if (decelerationRate === 'fast') { - decelerationRate = 0.99; + return Platform.select({ + ios: 0.99, + android: 0.9, + }); } return decelerationRate; } diff --git a/Libraries/Components/SegmentedControlIOS/SegmentedControlIOS.android.js b/Libraries/Components/SegmentedControlIOS/SegmentedControlIOS.android.js index 7a988960ceca96..581e77cf6ff8d4 100644 --- a/Libraries/Components/SegmentedControlIOS/SegmentedControlIOS.android.js +++ b/Libraries/Components/SegmentedControlIOS/SegmentedControlIOS.android.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Components/SegmentedControlIOS/SegmentedControlIOS.ios.js b/Libraries/Components/SegmentedControlIOS/SegmentedControlIOS.ios.js index b4635f13f8e4d5..e8e6d3d57ab65c 100644 --- a/Libraries/Components/SegmentedControlIOS/SegmentedControlIOS.ios.js +++ b/Libraries/Components/SegmentedControlIOS/SegmentedControlIOS.ios.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -10,12 +10,12 @@ 'use strict'; +const DeprecatedViewPropTypes = require('DeprecatedViewPropTypes'); const NativeMethodsMixin = require('NativeMethodsMixin'); +const PropTypes = require('prop-types'); const React = require('React'); const ReactNative = require('ReactNative'); -const PropTypes = require('prop-types'); const StyleSheet = require('StyleSheet'); -const ViewPropTypes = require('ViewPropTypes'); const createReactClass = require('create-react-class'); const requireNativeComponent = require('requireNativeComponent'); @@ -69,7 +69,7 @@ const SegmentedControlIOS = createReactClass({ mixins: [NativeMethodsMixin], propTypes: { - ...ViewPropTypes, + ...DeprecatedViewPropTypes, /** * The labels for the control's segment buttons, in order. */ diff --git a/Libraries/Components/Slider/Slider.js b/Libraries/Components/Slider/Slider.js index 7f18a2d3b35ef0..fdde5f17ea6eec 100644 --- a/Libraries/Components/Slider/Slider.js +++ b/Libraries/Components/Slider/Slider.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -66,7 +66,7 @@ type Props = $ReadOnly<{| /** * Used to style and layout the `Slider`. See `StyleSheet.js` and - * `ViewStylePropTypes.js` for more info. + * `DeprecatedViewStylePropTypes.js` for more info. */ style?: ?ViewStyleProp, diff --git a/Libraries/Components/StaticContainer.react.js b/Libraries/Components/StaticContainer.react.js index ffba809a46ab72..dc852849c1d61f 100644 --- a/Libraries/Components/StaticContainer.react.js +++ b/Libraries/Components/StaticContainer.react.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Components/StaticRenderer.js b/Libraries/Components/StaticRenderer.js index 4f8cfbd0989fa8..f4d630d6a98ab0 100644 --- a/Libraries/Components/StaticRenderer.js +++ b/Libraries/Components/StaticRenderer.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -12,18 +12,20 @@ const React = require('React'); -const PropTypes = require('prop-types'); - -class StaticRenderer extends React.Component<{ +type Props = $ReadOnly<{| + /** + * Indicates whether the render function needs to be called again + */ shouldUpdate: boolean, - render: Function, -}> { - static propTypes = { - shouldUpdate: PropTypes.bool.isRequired, - render: PropTypes.func.isRequired, - }; + /** + * () => renderable + * A function that returns a renderable component + */ + render: () => React.Node, +|}>; - shouldComponentUpdate(nextProps: {shouldUpdate: boolean}): boolean { +class StaticRenderer extends React.Component { + shouldComponentUpdate(nextProps: Props): boolean { return nextProps.shouldUpdate; } diff --git a/Libraries/Components/StatusBar/StatusBar.js b/Libraries/Components/StatusBar/StatusBar.js index 97db49fdd10283..52e6a764d2ca74 100644 --- a/Libraries/Components/StatusBar/StatusBar.js +++ b/Libraries/Components/StatusBar/StatusBar.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -11,8 +11,6 @@ 'use strict'; const React = require('React'); -const PropTypes = require('prop-types'); -const ColorPropType = require('ColorPropType'); const Platform = require('Platform'); const processColor = require('processColor'); @@ -55,9 +53,55 @@ export type StatusBarAnimation = $Enum<{ slide: string, }>; -type DefaultProps = { - animated: boolean, -}; +type AndroidProps = $ReadOnly<{| + /** + * The background color of the status bar. + * @platform android + */ + backgroundColor?: ?string, + /** + * If the status bar is translucent. + * When translucent is set to true, the app will draw under the status bar. + * This is useful when using a semi transparent status bar color. + * + * @platform android + */ + translucent?: ?boolean, +|}>; + +type IOSProps = $ReadOnly<{| + /** + * If the network activity indicator should be visible. + * + * @platform ios + */ + networkActivityIndicatorVisible?: ?boolean, + /** + * The transition effect when showing and hiding the status bar using the `hidden` + * prop. Defaults to 'fade'. + * + * @platform ios + */ + showHideTransition?: ?('fade' | 'slide'), +|}>; + +type Props = $ReadOnly<{| + ...AndroidProps, + ...IOSProps, + /** + * If the status bar is hidden. + */ + hidden?: ?boolean, + /** + * If the transition between status bar property changes should be animated. + * Supported for backgroundColor, barStyle and hidden. + */ + animated?: ?boolean, + /** + * Sets the color of the status bar text. + */ + barStyle?: ?('default' | 'light-content' | 'dark-content'), +|}>; /** * Merges the prop stack with the default values. @@ -148,15 +192,7 @@ function createStackEntry(props: any): any { * * `currentHeight` (Android only) The height of the status bar. */ -class StatusBar extends React.Component<{ - hidden?: boolean, - animated?: boolean, - backgroundColor?: string, - translucent?: boolean, - barStyle?: 'default' | 'light-content' | 'dark-content', - networkActivityIndicatorVisible?: boolean, - showHideTransition?: 'fade' | 'slide', -}> { +class StatusBar extends React.Component { static _propsStack = []; static _defaultProps = createStackEntry({ @@ -261,48 +297,6 @@ class StatusBar extends React.Component<{ StatusBarManager.setTranslucent(translucent); } - static propTypes = { - /** - * If the status bar is hidden. - */ - hidden: PropTypes.bool, - /** - * If the transition between status bar property changes should be animated. - * Supported for backgroundColor, barStyle and hidden. - */ - animated: PropTypes.bool, - /** - * The background color of the status bar. - * @platform android - */ - backgroundColor: ColorPropType, - /** - * If the status bar is translucent. - * When translucent is set to true, the app will draw under the status bar. - * This is useful when using a semi transparent status bar color. - * - * @platform android - */ - translucent: PropTypes.bool, - /** - * Sets the color of the status bar text. - */ - barStyle: PropTypes.oneOf(['default', 'light-content', 'dark-content']), - /** - * If the network activity indicator should be visible. - * - * @platform ios - */ - networkActivityIndicatorVisible: PropTypes.bool, - /** - * The transition effect when showing and hiding the status bar using the `hidden` - * prop. Defaults to 'fade'. - * - * @platform ios - */ - showHideTransition: PropTypes.oneOf(['fade', 'slide']), - }; - static defaultProps = { animated: false, showHideTransition: 'fade', diff --git a/Libraries/Components/StatusBar/StatusBarIOS.android.js b/Libraries/Components/StatusBar/StatusBarIOS.android.js index 96f77d7868fbff..4e9f97309b29b0 100644 --- a/Libraries/Components/StatusBar/StatusBarIOS.android.js +++ b/Libraries/Components/StatusBar/StatusBarIOS.android.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -12,4 +12,6 @@ const NativeEventEmitter = require('NativeEventEmitter'); +/* $FlowFixMe(>=0.78.0 site=react_native_android_fb) This issue was found when + * making Flow check .android.js files. */ module.exports = new NativeEventEmitter('StatusBarManager'); diff --git a/Libraries/Components/StatusBar/StatusBarIOS.ios.js b/Libraries/Components/StatusBar/StatusBarIOS.ios.js index 529e01b308fd88..ea558eafa9ba94 100644 --- a/Libraries/Components/StatusBar/StatusBarIOS.ios.js +++ b/Libraries/Components/StatusBar/StatusBarIOS.ios.js @@ -1,11 +1,11 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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 + * @flow strict-local */ 'use strict'; diff --git a/Libraries/Components/Subscribable.js b/Libraries/Components/Subscribable.js deleted file mode 100644 index a56d42ed864c8d..00000000000000 --- a/Libraries/Components/Subscribable.js +++ /dev/null @@ -1,65 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * - * 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'; - -import type EventEmitter from 'EventEmitter'; - -/** - * Subscribable provides a mixin for safely subscribing a component to an - * eventEmitter - * - * This will be replaced with the observe interface that will be coming soon to - * React Core - */ - -const Subscribable = {}; - -Subscribable.Mixin = { - UNSAFE_componentWillMount: function() { - this._subscribableSubscriptions = []; - }, - - componentWillUnmount: function() { - // This null check is a fix for a broken version of uglify-es. Should be deleted eventually - // https://github.com/facebook/react-native/issues/17348 - this._subscribableSubscriptions && - this._subscribableSubscriptions.forEach(subscription => - subscription.remove(), - ); - this._subscribableSubscriptions = null; - }, - - /** - * Special form of calling `addListener` that *guarantees* that a - * subscription *must* be tied to a component instance, and therefore will - * be cleaned up when the component is unmounted. It is impossible to create - * the subscription and pass it in - this method must be the one to create - * the subscription and therefore can guarantee it is retained in a way that - * will be cleaned up. - * - * @param {EventEmitter} eventEmitter emitter to subscribe to. - * @param {string} eventType Type of event to listen to. - * @param {function} listener Function to invoke when event occurs. - * @param {object} context Object to use as listener context. - */ - addListenerOn: function( - eventEmitter: EventEmitter, - eventType: string, - listener: Function, - context: Object, - ) { - this._subscribableSubscriptions.push( - eventEmitter.addListener(eventType, listener, context), - ); - }, -}; - -module.exports = Subscribable; diff --git a/Libraries/Components/Switch/Switch.js b/Libraries/Components/Switch/Switch.js index 39ccd9a1de16e2..80fe6306d7228c 100644 --- a/Libraries/Components/Switch/Switch.js +++ b/Libraries/Components/Switch/Switch.js @@ -1,163 +1,207 @@ /** - * Copyright (c) 2013-present, Facebook, Inc. + * 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 + * @format */ 'use strict'; +const SwitchNativeComponent = require('SwitchNativeComponent'); const Platform = require('Platform'); const React = require('React'); -const ReactNative = require('ReactNative'); const StyleSheet = require('StyleSheet'); -const nullthrows = require('fbjs/lib/nullthrows'); -const requireNativeComponent = require('requireNativeComponent'); - +import type {SwitchChangeEvent} from 'CoreEventTypes'; import type {ColorValue} from 'StyleSheetTypes'; import type {ViewProps} from 'ViewPropTypes'; +import type {NativeAndroidProps, NativeIOSProps} from 'SwitchNativeComponent'; -type Props = $ReadOnly<{| +export type Props = $ReadOnly<{| ...ViewProps, - /** - * The value of the switch. If true the switch will be turned on. - * Default value is false. - */ - value?: ?boolean, /** - * If true the user won't be able to toggle the switch. - * Default value is false. + * Whether the switch is disabled. Defaults to false. */ disabled?: ?boolean, /** - * Switch change handler. - * - * Invoked with the event when the value changes. For getting the value - * the switch was changed to use onValueChange instead. + * Boolean value of the switch. Defaults to false. */ - onChange?: ?Function, + value?: ?boolean, /** - * Invoked with the new value when the value changes. + * Custom color for the switch thumb. */ - onValueChange?: ?Function, + thumbColor?: ?ColorValue, /** - * Used to locate this view in end-to-end tests. + * Custom colors for the switch track. + * + * NOTE: On iOS when the switch value is false, the track shrinks into the + * border. If you want to change the color of the background exposed by the + * shrunken track, use `ios_backgroundColor`. */ - testID?: ?string, + trackColor?: ?$ReadOnly<{| + false?: ?ColorValue, + true?: ?ColorValue, + |}>, /** - * Border color on iOS and background color on Android when the switch is turned off. + * On iOS, custom color for the background. This background color can be seen + * either when the switch value is false or when the switch is disabled (and + * the switch is translucent). */ - tintColor?: ?ColorValue, + ios_backgroundColor?: ?ColorValue, /** - * Background color when the switch is turned on. + * Called when the user tries to change the value of the switch. + * + * Receives the change event as an argument. If you want to only receive the + * new value, use `onValueChange` instead. */ - onTintColor?: ?ColorValue, + onChange?: ?(event: SwitchChangeEvent) => Promise | void, /** - * Color of the foreground switch grip. + * Called when the user tries to change the value of the switch. + * + * Receives the new value as an argument. If you want to instead receive an + * event, use `onChange`. */ - thumbTintColor?: ?ColorValue, + onValueChange?: ?(value: boolean) => Promise | void, |}>; -type NativeSwitchType = Class< - ReactNative.NativeComponent< - $ReadOnly<{| - ...Props, - enabled?: ?boolean, - on?: ?boolean, - trackTintColor?: ?ColorValue, - |}>, - >, ->; - -const RCTSwitch: NativeSwitchType = - Platform.OS === 'android' - ? (requireNativeComponent('AndroidSwitch'): any) - : (requireNativeComponent('RCTSwitch'): any); - /** - * Renders a boolean input. + * A visual toggle between two mutually exclusive states. * * This is a controlled component that requires an `onValueChange` callback that * updates the `value` prop in order for the component to reflect user actions. - * If the `value` prop is not updated, the component will continue to render - * the supplied `value` prop instead of the expected result of any user actions. - * - * @keyword checkbox - * @keyword toggle + * If the `value` prop is not updated, the component will continue to render the + * supplied `value` prop instead of the expected result of any user actions. */ class Switch extends React.Component { - static defaultProps = { - value: false, - disabled: false, - }; - - _rctSwitch: ?React.ElementRef = null; - - _onChange = (event: Object) => { - if (Platform.OS === 'android') { - nullthrows(this._rctSwitch).setNativeProps({on: this.props.value}); - } else { - nullthrows(this._rctSwitch).setNativeProps({value: this.props.value}); - } - - this.props.onChange && this.props.onChange(event); - this.props.onValueChange && - this.props.onValueChange(event.nativeEvent.value); - }; + _nativeSwitchRef: ?React.ElementRef; render() { - const props = { - ...this.props, - onStartShouldSetResponder: () => true, - onResponderTerminationRequest: () => false, - }; + const { + disabled, + ios_backgroundColor, + onChange, + onValueChange, + style, + thumbColor, + trackColor, + value, + ...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 platformProps = Platform.OS === 'android' - ? { - enabled: !this.props.disabled, - on: this.props.value, - style: this.props.style, - trackTintColor: this.props.value - ? this.props.onTintColor - : this.props.tintColor, - } - : { + ? ({ + enabled: disabled !== true, + on: value === true, + style, + thumbTintColor: _thumbColor, + trackTintColor: + value === true ? _trackColorForTrue : _trackColorForFalse, + }: NativeAndroidProps) + : ({ + disabled, + onTintColor: _trackColorForTrue, style: StyleSheet.compose( - styles.rctSwitchIOS, - this.props.style, + {height: 31, width: 51}, + StyleSheet.compose( + style, + ios_backgroundColor == null + ? null + : { + backgroundColor: ios_backgroundColor, + borderRadius: 16, + }, + ), ), - }; + thumbTintColor: _thumbColor, + tintColor: _trackColorForFalse, + value: value === true, + }: NativeIOSProps); return ( - { - this._rctSwitch = ref; - }} - onChange={this._onChange} + onChange={this._handleChange} + onResponderTerminationRequest={returnsFalse} + onStartShouldSetResponder={returnsTrue} + ref={this._handleSwitchNativeComponentRef} /> ); } + + _handleChange = (event: SwitchChangeEvent) => { + if (this._nativeSwitchRef == null) { + return; + } + + // Force value of native switch in order to control it. + const value = this.props.value === true; + if (Platform.OS === 'android') { + this._nativeSwitchRef.setNativeProps({on: value}); + } else { + this._nativeSwitchRef.setNativeProps({value}); + } + + if (this.props.onChange != null) { + this.props.onChange(event); + } + + if (this.props.onValueChange != null) { + this.props.onValueChange(event.nativeEvent.value); + } + }; + + _handleSwitchNativeComponentRef = ( + ref: ?React.ElementRef, + ) => { + this._nativeSwitchRef = ref; + }; } -const styles = StyleSheet.create({ - rctSwitchIOS: { - height: 31, - width: 51, - }, -}); +const returnsFalse = () => false; +const returnsTrue = () => true; module.exports = Switch; diff --git a/Libraries/Components/Switch/SwitchNativeComponent.js b/Libraries/Components/Switch/SwitchNativeComponent.js new file mode 100644 index 00000000000000..4b43fc3e96cea1 --- /dev/null +++ b/Libraries/Components/Switch/SwitchNativeComponent.js @@ -0,0 +1,56 @@ +/** + * 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 Platform = require('Platform'); +const ReactNative = require('ReactNative'); + +const requireNativeComponent = require('requireNativeComponent'); + +import type {SwitchChangeEvent} from 'CoreEventTypes'; +import type {ViewProps} from 'ViewPropTypes'; + +// @see ReactSwitchManager.java +export type NativeAndroidProps = $ReadOnly<{| + ...ViewProps, + enabled?: ?boolean, + on?: ?boolean, + onChange?: ?(event: SwitchChangeEvent) => mixed, + thumbTintColor?: ?string, + trackTintColor?: ?string, +|}>; + +// @see RCTSwitchManager.m +export type NativeIOSProps = $ReadOnly<{| + ...ViewProps, + disabled?: ?boolean, + onChange?: ?(event: SwitchChangeEvent) => mixed, + onTintColor?: ?string, + thumbTintColor?: ?string, + tintColor?: ?string, + value?: ?boolean, +|}>; + +type SwitchNativeComponentType = Class< + ReactNative.NativeComponent< + $ReadOnly<{| + ...NativeAndroidProps, + ...NativeIOSProps, + |}>, + >, +>; + +const SwitchNativeComponent: SwitchNativeComponentType = + Platform.OS === 'android' + ? (requireNativeComponent('AndroidSwitch'): any) + : (requireNativeComponent('RCTSwitch'): any); + +module.exports = SwitchNativeComponent; diff --git a/Libraries/Components/TabBarIOS/TabBarIOS.android.js b/Libraries/Components/TabBarIOS/TabBarIOS.android.js index e8e376f8a9eb7e..58da238b4b7019 100644 --- a/Libraries/Components/TabBarIOS/TabBarIOS.android.js +++ b/Libraries/Components/TabBarIOS/TabBarIOS.android.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Components/TabBarIOS/TabBarIOS.ios.js b/Libraries/Components/TabBarIOS/TabBarIOS.ios.js index 6cbe213f7fc36d..7b19a1487081e3 100644 --- a/Libraries/Components/TabBarIOS/TabBarIOS.ios.js +++ b/Libraries/Components/TabBarIOS/TabBarIOS.ios.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -10,77 +10,67 @@ 'use strict'; -const ColorPropType = require('ColorPropType'); const React = require('React'); -const PropTypes = require('prop-types'); const StyleSheet = require('StyleSheet'); const TabBarItemIOS = require('TabBarItemIOS'); -const ViewPropTypes = require('ViewPropTypes'); const requireNativeComponent = require('requireNativeComponent'); -import type {DangerouslyImpreciseStyleProp} from 'StyleSheet'; import type {ViewProps} from 'ViewPropTypes'; +import type {ColorValue} from 'StyleSheetTypes'; const RCTTabBar = requireNativeComponent('RCTTabBar'); type Props = $ReadOnly<{| ...ViewProps, - style?: DangerouslyImpreciseStyleProp, - unselectedTintColor?: string, - tintColor?: string, - unselectedItemTintColor?: string, - barTintColor?: string, - barStyle?: 'default' | 'black', - translucent?: boolean, - itemPositioning?: 'fill' | 'center' | 'auto', - children: React.Node, + + /** + * Color of text on unselected tabs + */ + unselectedTintColor?: ColorValue, + + /** + * Color of the currently selected tab icon + */ + tintColor?: ColorValue, + + /** + * Color of unselected tab icons. Available since iOS 10. + */ + unselectedItemTintColor?: ColorValue, + + /** + * Background color of the tab bar + */ + barTintColor?: ColorValue, + + /** + * The style of the tab bar. Supported values are 'default', 'black'. + * Use 'black' instead of setting `barTintColor` to black. This produces + * a tab bar with the native iOS style with higher translucency. + */ + barStyle?: ?('default' | 'black'), + + /** + * A Boolean value that indicates whether the tab bar is translucent + */ + translucent?: ?boolean, + + /** + * Specifies tab bar item positioning. Available values are: + * - fill - distributes items across the entire width of the tab bar + * - center - centers item in the available tab bar space + * - auto (default) - distributes items dynamically according to the + * user interface idiom. In a horizontally compact environment (e.g. iPhone 5) + * this value defaults to `fill`, in a horizontally regular one (e.g. iPad) + * it defaults to center. + */ + itemPositioning?: ?('fill' | 'center' | 'auto'), |}>; class TabBarIOS extends React.Component { static Item = TabBarItemIOS; - static propTypes = { - ...ViewPropTypes, - style: ViewPropTypes.style, - /** - * Color of text on unselected tabs - */ - unselectedTintColor: ColorPropType, - /** - * Color of the currently selected tab icon - */ - tintColor: ColorPropType, - /** - * Color of unselected tab icons. Available since iOS 10. - */ - unselectedItemTintColor: ColorPropType, - /** - * Background color of the tab bar - */ - barTintColor: ColorPropType, - /** - * The style of the tab bar. Supported values are 'default', 'black'. - * Use 'black' instead of setting `barTintColor` to black. This produces - * a tab bar with the native iOS style with higher translucency. - */ - barStyle: PropTypes.oneOf(['default', 'black']), - /** - * A Boolean value that indicates whether the tab bar is translucent - */ - translucent: PropTypes.bool, - /** - * Specifies tab bar item positioning. Available values are: - * - fill - distributes items across the entire width of the tab bar - * - center - centers item in the available tab bar space - * - auto (default) - distributes items dynamically according to the - * user interface idiom. In a horizontally compact environment (e.g. iPhone 5) - * this value defaults to `fill`, in a horizontally regular one (e.g. iPad) - * it defaults to center. - */ - itemPositioning: PropTypes.oneOf(['fill', 'center', 'auto']), - }; - render() { return ( ) => mixed, + + /** + * If set to true it renders the image as original, + * it defaults to being displayed as a template + */ + renderAsOriginal?: ?boolean, + + /** + * It specifies whether the children are visible or not. If you see a + * blank content, you probably forgot to add a selected one. + */ + selected?: ?boolean, + + /** + * Text that appears under the icon. It is ignored when a system icon + * is defined. + */ + title?: ?string, + + /** + * *(Apple TV only)* When set to true, this view will be focusable + * and navigable using the Apple TV remote. + * + * @platform ios + */ + isTVSelectable?: ?boolean, +|}>; + +type State = {| + hasBeenSelected: boolean, +|}; +class TabBarItemIOS extends React.Component { state = { hasBeenSelected: false, }; @@ -104,7 +115,7 @@ class TabBarItemIOS extends React.Component { } } - UNSAFE_componentWillReceiveProps(nextProps: {selected?: boolean}) { + UNSAFE_componentWillReceiveProps(nextProps: Props) { if (this.state.hasBeenSelected || nextProps.selected) { this.setState({hasBeenSelected: true}); } diff --git a/Libraries/Components/TextInput/InputAccessoryView.js b/Libraries/Components/TextInput/InputAccessoryView.js index 731476bc7138b7..2e7f906096c3b0 100644 --- a/Libraries/Components/TextInput/InputAccessoryView.js +++ b/Libraries/Components/TextInput/InputAccessoryView.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2013-present, Facebook, Inc. + * 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. @@ -9,15 +9,17 @@ */ 'use strict'; -const ColorPropType = require('ColorPropType'); +const DeprecatedColorPropType = require('DeprecatedColorPropType'); +const Platform = require('Platform'); const React = require('React'); const StyleSheet = require('StyleSheet'); -const ViewPropTypes = require('ViewPropTypes'); const requireNativeComponent = require('requireNativeComponent'); const RCTInputAccessoryView = requireNativeComponent('RCTInputAccessoryView'); +import type {ViewStyleProp} from 'StyleSheet'; + /** * Note: iOS only * @@ -76,20 +78,22 @@ const RCTInputAccessoryView = requireNativeComponent('RCTInputAccessoryView'); * For an example, look at InputAccessoryViewExample.js in RNTester. */ -type Props = { +type Props = $ReadOnly<{| +children: React.Node, /** * An ID which is used to associate this `InputAccessoryView` to * specified TextInput(s). */ - nativeID?: string, - style?: ViewPropTypes.style, - backgroundColor?: ColorPropType, -}; + nativeID?: ?string, + style?: ?ViewStyleProp, + backgroundColor?: ?DeprecatedColorPropType, +|}>; class InputAccessoryView extends React.Component { render(): React.Node { - console.warn(' is not supported on Android yet.'); + if (Platform.OS !== 'ios') { + console.warn(' is only supported on iOS.'); + } if (React.Children.count(this.props.children) === 0) { return null; diff --git a/Libraries/Components/TextInput/TextInput.js b/Libraries/Components/TextInput/TextInput.js index ef8d6a81f12383..cd71083cc08ebf 100644 --- a/Libraries/Components/TextInput/TextInput.js +++ b/Libraries/Components/TextInput/TextInput.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -9,31 +9,30 @@ */ 'use strict'; -const ColorPropType = require('ColorPropType'); +const DeprecatedColorPropType = require('DeprecatedColorPropType'); +const DeprecatedViewPropTypes = require('DeprecatedViewPropTypes'); const DocumentSelectionState = require('DocumentSelectionState'); const EventEmitter = require('EventEmitter'); const NativeMethodsMixin = require('NativeMethodsMixin'); const Platform = require('Platform'); -const React = require('React'); -const createReactClass = require('create-react-class'); const PropTypes = require('prop-types'); +const React = require('React'); const ReactNative = require('ReactNative'); const StyleSheet = require('StyleSheet'); const Text = require('Text'); const TextAncestor = require('TextAncestor'); const TextInputState = require('TextInputState'); -const TimerMixin = require('react-timer-mixin'); const TouchableWithoutFeedback = require('TouchableWithoutFeedback'); const UIManager = require('UIManager'); -const ViewPropTypes = require('ViewPropTypes'); +const createReactClass = require('create-react-class'); const emptyFunction = require('fbjs/lib/emptyFunction'); const invariant = require('fbjs/lib/invariant'); const requireNativeComponent = require('requireNativeComponent'); const warning = require('fbjs/lib/warning'); +import type {TextStyleProp, ViewStyleProp} from 'StyleSheet'; import type {ColorValue} from 'StyleSheetTypes'; -import type {TextStyleProp} from 'StyleSheet'; import type {ViewProps} from 'ViewPropTypes'; let AndroidTextInput; @@ -155,7 +154,10 @@ type IOSProps = $ReadOnly<{| | 'telephoneNumber' | 'username' | 'password' + | 'newPassword' + | 'oneTimeCode' ), + scrollEnabled?: ?boolean, |}>; type AndroidProps = $ReadOnly<{| @@ -169,13 +171,14 @@ type AndroidProps = $ReadOnly<{| |}>; type Props = $ReadOnly<{| - ...ViewProps, + ...$Diff>, ...IOSProps, ...AndroidProps, autoCapitalize?: ?AutoCapitalize, autoCorrect?: ?boolean, autoFocus?: ?boolean, allowFontScaling?: ?boolean, + maxFontSizeMultiplier?: ?number, editable?: ?boolean, keyboardType?: ?KeyboardType, returnKeyType?: ?ReturnKeyType, @@ -326,22 +329,12 @@ const TextInput = createReactClass({ statics: { State: { currentlyFocusedField: TextInputState.currentlyFocusedField, - focusTextInput: (textFieldID: ?number) => { - console.warn( - '`focusTextInput` is deprecated, use the `focus` method of the `TextInput` ref instead.', - ); - TextInputState.focusTextInput(textFieldID); - }, - blurTextInput: (textFieldID: ?number) => { - console.warn( - '`blurTextInput` is deprecated, use `Keyboard.dismiss` or the `blur` method of the `TextInput` ref.', - ); - TextInputState.blurTextInput(textFieldID); - }, + focusTextInput: TextInputState.focusTextInput, + blurTextInput: TextInputState.blurTextInput, }, }, propTypes: { - ...ViewPropTypes, + ...DeprecatedViewPropTypes, /** * Can tell `TextInput` to automatically capitalize certain characters. * @@ -376,6 +369,14 @@ const TextInput = createReactClass({ * default is `true`. */ allowFontScaling: PropTypes.bool, + /** + * Specifies largest possible scale a font can reach when `allowFontScaling` is enabled. + * Possible values: + * `null/undefined` (default): inherit from the parent node or the global default (0) + * `0`: no max, ignore parent/global default + * `>= 1`: sets the maxFontSizeMultiplier of this node to this value + */ + maxFontSizeMultiplier: PropTypes.number, /** * If `false`, text is not editable. The default value is `true`. */ @@ -590,7 +591,13 @@ const TextInput = createReactClass({ /** * The text color of the placeholder string. */ - placeholderTextColor: ColorPropType, + placeholderTextColor: DeprecatedColorPropType, + /** + * If `false`, scrolling of the text view will be disabled. + * The default value is `true`. Does only work with 'multiline={true}'. + * @platform ios + */ + scrollEnabled: PropTypes.bool, /** * If `true`, the text input obscures the text entered so that sensitive text * like passwords stay secure. The default value is `false`. Does not work with 'multiline={true}'. @@ -599,7 +606,7 @@ const TextInput = createReactClass({ /** * The highlight and cursor color of the text input. */ - selectionColor: ColorPropType, + selectionColor: DeprecatedColorPropType, /** * An instance of `DocumentSelectionState`, this is some state that is responsible for * maintaining selection information for a document. @@ -690,7 +697,7 @@ const TextInput = createReactClass({ * The color of the `TextInput` underline. * @platform android */ - underlineColorAndroid: ColorPropType, + underlineColorAndroid: DeprecatedColorPropType, /** * If defined, the provided image resource will be rendered on the left. @@ -781,6 +788,8 @@ const TextInput = createReactClass({ 'telephoneNumber', 'username', 'password', + 'newPassword', + 'oneTimeCode', ]), }, getDefaultProps(): Object { @@ -793,7 +802,7 @@ const TextInput = createReactClass({ * `NativeMethodsMixin` will look for this when invoking `setNativeProps`. We * make `this` look like an actual native component class. */ - mixins: [NativeMethodsMixin, TimerMixin], + mixins: [NativeMethodsMixin], /** * Returns `true` if the input is currently focused; `false` otherwise. @@ -809,6 +818,7 @@ const TextInput = createReactClass({ _focusSubscription: (undefined: ?Function), _lastNativeText: (undefined: ?string), _lastNativeSelection: (undefined: ?Selection), + _rafId: (null: ?AnimationFrameID), componentDidMount: function() { this._lastNativeText = this.props.value; @@ -823,7 +833,7 @@ const TextInput = createReactClass({ 'focus', el => { if (this === el) { - this.requestAnimationFrame(this.focus); + this._rafId = requestAnimationFrame(this.focus); } else if (this.isFocused()) { this.blur(); } @@ -834,7 +844,7 @@ const TextInput = createReactClass({ } } else { if (this.props.autoFocus) { - this.requestAnimationFrame(this.focus); + this._rafId = requestAnimationFrame(this.focus); } } }, @@ -848,6 +858,9 @@ const TextInput = createReactClass({ if (tag != null) { TextInputState.unregisterInput(tag); } + if (this._rafId != null) { + cancelAnimationFrame(this._rafId); + } }, contextTypes: { @@ -865,7 +878,7 @@ const TextInput = createReactClass({ render: function() { let textInput; if (Platform.OS === 'ios') { - textInput = UIManager.RCTVirtualText + textInput = UIManager.getViewManagerConfig('RCTVirtualText') ? this._renderIOS() : this._renderIOSLegacy(); } else if (Platform.OS === 'android') { @@ -936,7 +949,10 @@ const TextInput = createReactClass({ ); if (childCount >= 1) { children = ( - + {children} ); @@ -971,7 +987,8 @@ const TextInput = createReactClass({ rejectResponderTermination={true} accessible={props.accessible} accessibilityLabel={props.accessibilityLabel} - accessibilityTraits={props.accessibilityTraits} + accessibilityRole={props.accessibilityRole} + accessibilityStates={props.accessibilityStates} nativeID={this.props.nativeID} testID={props.testID}> {textContainer} @@ -1022,7 +1039,8 @@ const TextInput = createReactClass({ rejectResponderTermination={true} accessible={props.accessible} accessibilityLabel={props.accessibilityLabel} - accessibilityTraits={props.accessibilityTraits} + accessibilityRole={props.accessibilityRole} + accessibilityStates={props.accessibilityStates} nativeID={this.props.nativeID} testID={props.testID}> {textContainer} @@ -1033,10 +1051,9 @@ const TextInput = createReactClass({ _renderAndroid: function() { const props = Object.assign({}, this.props); props.style = [this.props.style]; - props.autoCapitalize = - UIManager.AndroidTextInput.Constants.AutoCapitalizationType[ - props.autoCapitalize || 'sentences' - ]; + props.autoCapitalize = UIManager.getViewManagerConfig( + 'AndroidTextInput', + ).Constants.AutoCapitalizationType[props.autoCapitalize || 'sentences']; /* $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. */ @@ -1082,7 +1099,8 @@ const TextInput = createReactClass({ onPress={this._onPress} accessible={this.props.accessible} accessibilityLabel={this.props.accessibilityLabel} - accessibilityComponentType={this.props.accessibilityComponentType} + accessibilityRole={this.props.accessibilityRole} + accessibilityStates={this.props.accessibilityStates} nativeID={this.props.nativeID} testID={this.props.testID}> {textContainer} diff --git a/Libraries/Components/TextInput/TextInputState.js b/Libraries/Components/TextInput/TextInputState.js index 95cd24fbe8d2dc..19acafe2642855 100644 --- a/Libraries/Components/TextInput/TextInputState.js +++ b/Libraries/Components/TextInput/TextInputState.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -10,7 +10,7 @@ * should be funneled through here * * @format - * @flow + * @flow strict-local */ 'use strict'; @@ -18,73 +18,76 @@ const Platform = require('Platform'); const UIManager = require('UIManager'); +let currentlyFocusedID: ?number = null; const inputs = new Set(); -const TextInputState = { - /** - * Internal state - */ - _currentlyFocusedID: (null: ?number), - - /** - * Returns the ID of the currently focused text field, if one exists - * If no text field is focused it returns null - */ - currentlyFocusedField: function(): ?number { - return this._currentlyFocusedID; - }, +/** + * 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; +} - /** - * @param {number} TextInputID id of the text field to focus - * Focuses the specified text field - * noop if the text field was already focused - */ - focusTextInput: function(textFieldID: ?number) { - if (this._currentlyFocusedID !== textFieldID && textFieldID !== null) { - this._currentlyFocusedID = textFieldID; - if (Platform.OS === 'ios') { - UIManager.focus(textFieldID); - } else if (Platform.OS === 'android') { - UIManager.dispatchViewManagerCommand( - textFieldID, - UIManager.AndroidTextInput.Commands.focusTextInput, - null, - ); - } +/** + * @param {number} TextInputID id of the text field to focus + * Focuses the specified text field + * noop if the text field was already focused + */ +function focusTextInput(textFieldID: ?number) { + if (currentlyFocusedID !== textFieldID && textFieldID !== null) { + currentlyFocusedID = textFieldID; + if (Platform.OS === 'ios') { + UIManager.focus(textFieldID); + } else if (Platform.OS === 'android') { + UIManager.dispatchViewManagerCommand( + textFieldID, + UIManager.getViewManagerConfig('AndroidTextInput').Commands + .focusTextInput, + null, + ); } - }, + } +} - /** - * @param {number} textFieldID id of the text field to unfocus - * Unfocuses the specified text field - * noop if it wasn't focused - */ - blurTextInput: function(textFieldID: ?number) { - if (this._currentlyFocusedID === textFieldID && textFieldID !== null) { - this._currentlyFocusedID = null; - if (Platform.OS === 'ios') { - UIManager.blur(textFieldID); - } else if (Platform.OS === 'android') { - UIManager.dispatchViewManagerCommand( - textFieldID, - UIManager.AndroidTextInput.Commands.blurTextInput, - null, - ); - } +/** + * @param {number} textFieldID id of the text field to unfocus + * Unfocuses the specified text field + * noop if it wasn't focused + */ +function blurTextInput(textFieldID: ?number) { + if (currentlyFocusedID === textFieldID && textFieldID !== null) { + currentlyFocusedID = null; + if (Platform.OS === 'ios') { + UIManager.blur(textFieldID); + } else if (Platform.OS === 'android') { + UIManager.dispatchViewManagerCommand( + textFieldID, + UIManager.getViewManagerConfig('AndroidTextInput').Commands + .blurTextInput, + null, + ); } - }, + } +} - registerInput: function(textFieldID: number) { - inputs.add(textFieldID); - }, +function registerInput(textFieldID: number) { + inputs.add(textFieldID); +} - unregisterInput: function(textFieldID: number) { - inputs.delete(textFieldID); - }, +function unregisterInput(textFieldID: number) { + inputs.delete(textFieldID); +} - isTextInput: function(textFieldID: number) { - return inputs.has(textFieldID); - }, -}; +function isTextInput(textFieldID: number) { + return inputs.has(textFieldID); +} -module.exports = TextInputState; +module.exports = { + currentlyFocusedField, + focusTextInput, + blurTextInput, + registerInput, + unregisterInput, + isTextInput, +}; diff --git a/Libraries/Components/TimePickerAndroid/TimePickerAndroid.android.js b/Libraries/Components/TimePickerAndroid/TimePickerAndroid.android.js index 6cdd964cc8cea2..bdb29421f89d0e 100644 --- a/Libraries/Components/TimePickerAndroid/TimePickerAndroid.android.js +++ b/Libraries/Components/TimePickerAndroid/TimePickerAndroid.android.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Components/TimePickerAndroid/TimePickerAndroid.ios.js b/Libraries/Components/TimePickerAndroid/TimePickerAndroid.ios.js index 6a0ecfa656313c..59ec50eb27260c 100644 --- a/Libraries/Components/TimePickerAndroid/TimePickerAndroid.ios.js +++ b/Libraries/Components/TimePickerAndroid/TimePickerAndroid.ios.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Components/ToastAndroid/ToastAndroid.android.js b/Libraries/Components/ToastAndroid/ToastAndroid.android.js index c661adf503565d..832887453c3fc0 100644 --- a/Libraries/Components/ToastAndroid/ToastAndroid.android.js +++ b/Libraries/Components/ToastAndroid/ToastAndroid.android.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Components/ToastAndroid/ToastAndroid.ios.js b/Libraries/Components/ToastAndroid/ToastAndroid.ios.js index adb6032ef6731b..ed5fcf02f40116 100644 --- a/Libraries/Components/ToastAndroid/ToastAndroid.ios.js +++ b/Libraries/Components/ToastAndroid/ToastAndroid.ios.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Components/ToolbarAndroid/ToolbarAndroid.android.js b/Libraries/Components/ToolbarAndroid/ToolbarAndroid.android.js index 44bcfc03d8046e..23d9f22b8b45a0 100644 --- a/Libraries/Components/ToolbarAndroid/ToolbarAndroid.android.js +++ b/Libraries/Components/ToolbarAndroid/ToolbarAndroid.android.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -9,13 +9,13 @@ 'use strict'; +const DeprecatedColorPropType = require('DeprecatedColorPropType'); +const DeprecatedViewPropTypes = require('DeprecatedViewPropTypes'); const Image = require('Image'); const NativeMethodsMixin = require('NativeMethodsMixin'); -const React = require('React'); const PropTypes = require('prop-types'); +const React = require('React'); const UIManager = require('UIManager'); -const ViewPropTypes = require('ViewPropTypes'); -const ColorPropType = require('ColorPropType'); const createReactClass = require('create-react-class'); const requireNativeComponent = require('requireNativeComponent'); @@ -68,7 +68,7 @@ const ToolbarAndroid = createReactClass({ mixins: [NativeMethodsMixin], propTypes: { - ...ViewPropTypes, + ...DeprecatedViewPropTypes, /** * Sets possible actions on the toolbar as part of the action menu. These are displayed as icons * or text on the right side of the widget. If they don't fit they are placed in an 'overflow' @@ -118,7 +118,7 @@ const ToolbarAndroid = createReactClass({ /** * Sets the toolbar subtitle color. */ - subtitleColor: ColorPropType, + subtitleColor: DeprecatedColorPropType, /** * Sets the toolbar title. */ @@ -126,7 +126,7 @@ const ToolbarAndroid = createReactClass({ /** * Sets the toolbar title color. */ - titleColor: ColorPropType, + titleColor: DeprecatedColorPropType, /** * Sets the content inset for the toolbar starting edge. * @@ -185,8 +185,9 @@ const ToolbarAndroid = createReactClass({ action.icon = resolveAssetSource(action.icon); } if (action.show) { - action.show = - UIManager.ToolbarAndroid.Constants.ShowAsAction[action.show]; + action.show = UIManager.getViewManagerConfig( + 'ToolbarAndroid', + ).Constants.ShowAsAction[action.show]; } nativeActions.push(action); } diff --git a/Libraries/Components/ToolbarAndroid/ToolbarAndroid.ios.js b/Libraries/Components/ToolbarAndroid/ToolbarAndroid.ios.js index 260d559929796f..7a00b6636cf664 100644 --- a/Libraries/Components/ToolbarAndroid/ToolbarAndroid.ios.js +++ b/Libraries/Components/ToolbarAndroid/ToolbarAndroid.ios.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Components/Touchable/BoundingDimensions.js b/Libraries/Components/Touchable/BoundingDimensions.js index 755da5ab8937aa..28622a5b2da7f1 100644 --- a/Libraries/Components/Touchable/BoundingDimensions.js +++ b/Libraries/Components/Touchable/BoundingDimensions.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Components/Touchable/PooledClass.js b/Libraries/Components/Touchable/PooledClass.js index a6934facae7049..0d6168a3fa51cf 100644 --- a/Libraries/Components/Touchable/PooledClass.js +++ b/Libraries/Components/Touchable/PooledClass.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2013-present, Facebook, Inc. + * 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. diff --git a/Libraries/Components/Touchable/Position.js b/Libraries/Components/Touchable/Position.js index 19899d74c49820..bc6a45cc6c6a1f 100644 --- a/Libraries/Components/Touchable/Position.js +++ b/Libraries/Components/Touchable/Position.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Components/Touchable/Touchable.js b/Libraries/Components/Touchable/Touchable.js index 3f1874c8aac4a4..8fc27be8882e63 100644 --- a/Libraries/Components/Touchable/Touchable.js +++ b/Libraries/Components/Touchable/Touchable.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2013-present, Facebook, Inc. + * 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. diff --git a/Libraries/Components/Touchable/TouchableBounce.js b/Libraries/Components/Touchable/TouchableBounce.js index c899748b44fd1c..c1e3a731fec294 100644 --- a/Libraries/Components/Touchable/TouchableBounce.js +++ b/Libraries/Components/Touchable/TouchableBounce.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -10,18 +10,19 @@ 'use strict'; const Animated = require('Animated'); -const EdgeInsetsPropType = require('EdgeInsetsPropType'); +const DeprecatedViewPropTypes = require('DeprecatedViewPropTypes'); +const DeprecatedEdgeInsetsPropType = require('DeprecatedEdgeInsetsPropType'); const NativeMethodsMixin = require('NativeMethodsMixin'); -const React = require('React'); -const createReactClass = require('create-react-class'); const PropTypes = require('prop-types'); +const React = require('React'); const Touchable = require('Touchable'); const TouchableWithoutFeedback = require('TouchableWithoutFeedback'); -const ViewPropTypes = require('ViewPropTypes'); + +const createReactClass = require('create-react-class'); import type {EdgeInsetsProp} from 'EdgeInsetsPropType'; -import type {Props as TouchableWithoutFeedbackProps} from 'TouchableWithoutFeedback'; import type {ViewStyleProp} from 'StyleSheet'; +import type {Props as TouchableWithoutFeedbackProps} from 'TouchableWithoutFeedback'; type Event = Object; @@ -69,14 +70,14 @@ const TouchableBounce = ((createReactClass({ * reactivated! Move it back and forth several times while the scroll view * is disabled. Ensure you pass in a constant to reduce memory allocations. */ - pressRetentionOffset: EdgeInsetsPropType, + pressRetentionOffset: DeprecatedEdgeInsetsPropType, releaseVelocity: PropTypes.number.isRequired, releaseBounciness: PropTypes.number.isRequired, /** * Style to apply to the container/underlay. Most commonly used to make sure * rounded corners match the wrapped component. */ - style: ViewPropTypes.style, + style: DeprecatedViewPropTypes.style, }, getDefaultProps: function() { @@ -160,8 +161,9 @@ const TouchableBounce = ((createReactClass({ style={[{transform: [{scale: this.state.scale}]}, this.props.style]} accessible={this.props.accessible !== false} accessibilityLabel={this.props.accessibilityLabel} - accessibilityComponentType={this.props.accessibilityComponentType} - accessibilityTraits={this.props.accessibilityTraits} + accessibilityHint={this.props.accessibilityHint} + accessibilityRole={this.props.accessibilityRole} + accessibilityStates={this.props.accessibilityStates} nativeID={this.props.nativeID} testID={this.props.testID} hitSlop={this.props.hitSlop} diff --git a/Libraries/Components/Touchable/TouchableHighlight.js b/Libraries/Components/Touchable/TouchableHighlight.js index 5a681c099125ac..f4e81f37485e10 100644 --- a/Libraries/Components/Touchable/TouchableHighlight.js +++ b/Libraries/Components/Touchable/TouchableHighlight.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -9,25 +9,25 @@ */ 'use strict'; -const ColorPropType = require('ColorPropType'); +const DeprecatedColorPropType = require('DeprecatedColorPropType'); +const DeprecatedViewPropTypes = require('DeprecatedViewPropTypes'); const NativeMethodsMixin = require('NativeMethodsMixin'); -const PropTypes = require('prop-types'); const Platform = require('Platform'); +const PropTypes = require('prop-types'); const React = require('React'); const ReactNativeViewAttributes = require('ReactNativeViewAttributes'); const StyleSheet = require('StyleSheet'); const Touchable = require('Touchable'); const TouchableWithoutFeedback = require('TouchableWithoutFeedback'); const View = require('View'); -const ViewPropTypes = require('ViewPropTypes'); const createReactClass = require('create-react-class'); const ensurePositiveDelayProps = require('ensurePositiveDelayProps'); import type {PressEvent} from 'CoreEventTypes'; -import type {Props as TouchableWithoutFeedbackProps} from 'TouchableWithoutFeedback'; import type {ViewStyleProp} from 'StyleSheet'; import type {ColorValue} from 'StyleSheetTypes'; +import type {Props as TouchableWithoutFeedbackProps} from 'TouchableWithoutFeedback'; const DEFAULT_PROPS = { activeOpacity: 0.85, @@ -164,12 +164,12 @@ const TouchableHighlight = ((createReactClass({ * The color of the underlay that will show through when the touch is * active. */ - underlayColor: ColorPropType, + underlayColor: DeprecatedColorPropType, /** * Style to apply to the container/underlay. Most commonly used to make sure * rounded corners match the wrapped component. */ - style: ViewPropTypes.style, + style: DeprecatedViewPropTypes.style, /** * Called immediately after the underlay is shown */ @@ -348,8 +348,9 @@ const TouchableHighlight = ((createReactClass({ | any, - accessibilityTraits?: ?AccessibilityTraitsFlow, + accessibilityHint?: ?Stringish, + accessibilityIgnoresInvertColors?: ?boolean, + accessibilityRole?: ?AccessibilityRole, + accessibilityStates?: ?AccessibilityStates, + accessibilityTraits?: ?AccessibilityTraits, children?: ?React.Node, delayLongPress?: ?number, delayPressIn?: ?number, @@ -51,6 +58,8 @@ export type Props = $ReadOnly<{| disabled?: ?boolean, hitSlop?: ?EdgeInsetsProp, nativeID?: ?string, + onBlur?: ?Function, + onFocus?: ?Function, onLayout?: ?Function, onLongPress?: ?Function, onPress?: ?Function, @@ -70,15 +79,22 @@ export type Props = $ReadOnly<{| */ const TouchableWithoutFeedback = ((createReactClass({ displayName: 'TouchableWithoutFeedback', - mixins: [TimerMixin, Touchable.Mixin], + mixins: [Touchable.Mixin], propTypes: { accessible: PropTypes.bool, accessibilityLabel: PropTypes.node, - accessibilityComponentType: PropTypes.oneOf(AccessibilityComponentTypes), + accessibilityHint: PropTypes.string, + accessibilityComponentType: PropTypes.oneOf( + DeprecatedAccessibilityComponentTypes, + ), + accessibilityRole: PropTypes.oneOf(DeprecatedAccessibilityRoles), + accessibilityStates: PropTypes.arrayOf( + PropTypes.oneOf(DeprecatedAccessibilityStates), + ), accessibilityTraits: PropTypes.oneOfType([ - PropTypes.oneOf(AccessibilityTraits), - PropTypes.arrayOf(PropTypes.oneOf(AccessibilityTraits)), + PropTypes.oneOf(DeprecatedAccessibilityTraits), + PropTypes.arrayOf(PropTypes.oneOf(DeprecatedAccessibilityTraits)), ]), /** * When `accessible` is true (which is the default) this may be called when @@ -141,7 +157,7 @@ const TouchableWithoutFeedback = ((createReactClass({ * reactivated! Move it back and forth several times while the scroll view * is disabled. Ensure you pass in a constant to reduce memory allocations. */ - pressRetentionOffset: EdgeInsetsPropType, + pressRetentionOffset: DeprecatedEdgeInsetsPropType, /** * This defines how far your touch can start away from the button. This is * added to `pressRetentionOffset` when moving off of the button. @@ -150,7 +166,7 @@ const TouchableWithoutFeedback = ((createReactClass({ * of sibling views always takes precedence if a touch hits two overlapping * views. */ - hitSlop: EdgeInsetsPropType, + hitSlop: DeprecatedEdgeInsetsPropType, }, getInitialState: function() { @@ -213,32 +229,19 @@ const TouchableWithoutFeedback = ((createReactClass({ // $FlowFixMe(>=0.41.0) const child = React.Children.only(this.props.children); let children = child.props.children; - warning( - !child.type || child.type.displayName !== 'Text', - 'TouchableWithoutFeedback does not work well with Text children. Wrap children in a View instead. See ' + - ((child._owner && child._owner.getName && child._owner.getName()) || - ''), - ); - if ( - Touchable.TOUCH_TARGET_DEBUG && - child.type && - child.type.displayName === 'View' - ) { + if (Touchable.TOUCH_TARGET_DEBUG && child.type === View) { children = React.Children.toArray(children); children.push( Touchable.renderDebugView({color: 'red', hitSlop: this.props.hitSlop}), ); } - const style = - Touchable.TOUCH_TARGET_DEBUG && - child.type && - child.type.displayName === 'Text' - ? [child.props.style, {color: 'red'}] - : child.props.style; return (React: any).cloneElement(child, { accessible: this.props.accessible !== false, accessibilityLabel: this.props.accessibilityLabel, + accessibilityHint: this.props.accessibilityHint, accessibilityComponentType: this.props.accessibilityComponentType, + accessibilityRole: this.props.accessibilityRole, + accessibilityStates: this.props.accessibilityStates, accessibilityTraits: this.props.accessibilityTraits, nativeID: this.props.nativeID, testID: this.props.testID, @@ -251,7 +254,6 @@ const TouchableWithoutFeedback = ((createReactClass({ onResponderMove: this.touchableHandleResponderMove, onResponderRelease: this.touchableHandleResponderRelease, onResponderTerminate: this.touchableHandleResponderTerminate, - style, children, }); }, diff --git a/Libraries/Components/Touchable/__mocks__/ensureComponentIsNative.js b/Libraries/Components/Touchable/__mocks__/ensureComponentIsNative.js index f152b68bba74a4..234c178afddd94 100644 --- a/Libraries/Components/Touchable/__mocks__/ensureComponentIsNative.js +++ b/Libraries/Components/Touchable/__mocks__/ensureComponentIsNative.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Components/Touchable/__tests__/TouchableHighlight-test.js b/Libraries/Components/Touchable/__tests__/TouchableHighlight-test.js index f40cc0b7ad1be9..8f299d8a360103 100644 --- a/Libraries/Components/Touchable/__tests__/TouchableHighlight-test.js +++ b/Libraries/Components/Touchable/__tests__/TouchableHighlight-test.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Components/Touchable/ensureComponentIsNative.js b/Libraries/Components/Touchable/ensureComponentIsNative.js index 5ce5a39d9baaf0..911a8ffbb67bcb 100644 --- a/Libraries/Components/Touchable/ensureComponentIsNative.js +++ b/Libraries/Components/Touchable/ensureComponentIsNative.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Components/Touchable/ensurePositiveDelayProps.js b/Libraries/Components/Touchable/ensurePositiveDelayProps.js index 01c001ad4b6a7e..f4f23aec035641 100644 --- a/Libraries/Components/Touchable/ensurePositiveDelayProps.js +++ b/Libraries/Components/Touchable/ensurePositiveDelayProps.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Components/UnimplementedViews/UnimplementedView.js b/Libraries/Components/UnimplementedViews/UnimplementedView.js index 7be6f1ac77f759..30e64eb83d01fd 100644 --- a/Libraries/Components/UnimplementedViews/UnimplementedView.js +++ b/Libraries/Components/UnimplementedViews/UnimplementedView.js @@ -1,10 +1,10 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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 + * @flow strict-local * @format */ 'use strict'; diff --git a/Libraries/Components/SafeAreaView/SafeAreaView.android.js b/Libraries/Components/View/PlatformViewPropTypes.android.js similarity index 56% rename from Libraries/Components/SafeAreaView/SafeAreaView.android.js rename to Libraries/Components/View/PlatformViewPropTypes.android.js index a581258a57832f..f96fe3a62d8149 100644 --- a/Libraries/Components/SafeAreaView/SafeAreaView.android.js +++ b/Libraries/Components/View/PlatformViewPropTypes.android.js @@ -1,13 +1,14 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. * + * @providesModule PlatformViewPropTypes * @format * @flow */ 'use strict'; -module.exports = require('View'); +export type PlatformViewPropTypes = {}; diff --git a/Libraries/Components/View/PlatformViewPropTypes.ios.js b/Libraries/Components/View/PlatformViewPropTypes.ios.js new file mode 100644 index 00000000000000..fc842750601026 --- /dev/null +++ b/Libraries/Components/View/PlatformViewPropTypes.ios.js @@ -0,0 +1,16 @@ +/** + * 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. + * + * @providesModule PlatformViewPropTypes + * @format + * @flow + */ + +'use strict'; + +import type {TVViewProps} from 'TVViewPropTypes'; + +export type PlatformViewPropTypes = TVViewProps; diff --git a/Libraries/Components/View/PlatformViewPropTypes.js b/Libraries/Components/View/PlatformViewPropTypes.js deleted file mode 100644 index 4c6105893cc6eb..00000000000000 --- a/Libraries/Components/View/PlatformViewPropTypes.js +++ /dev/null @@ -1,21 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @format - * @flow - */ - -const Platform = require('Platform'); - -let TVViewPropTypes = {}; -// We need to always include TVViewPropTypes on Android -// as unlike on iOS we can't detect TV devices at build time -// and hence make view manager export a different list of native properties. -if (Platform.isTV || Platform.OS === 'android') { - TVViewPropTypes = require('TVViewPropTypes'); -} - -module.exports = TVViewPropTypes; diff --git a/Libraries/Components/View/ReactNativeStyleAttributes.js b/Libraries/Components/View/ReactNativeStyleAttributes.js index 7a75dda8b7f41b..240e6a4f0a4e4a 100644 --- a/Libraries/Components/View/ReactNativeStyleAttributes.js +++ b/Libraries/Components/View/ReactNativeStyleAttributes.js @@ -1,32 +1,32 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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 + * @format strict-local * @flow */ 'use strict'; -const ImageStylePropTypes = require('ImageStylePropTypes'); +const DeprecatedImageStylePropTypes = require('DeprecatedImageStylePropTypes'); const TextStylePropTypes = require('TextStylePropTypes'); -const ViewStylePropTypes = require('ViewStylePropTypes'); +const DeprecatedViewStylePropTypes = require('DeprecatedViewStylePropTypes'); -/* $FlowFixMe(>=0.54.0 site=react_native_oss) This comment suppresses an error - * found when Flow v0.54 was deployed. To see the error delete this comment and - * run Flow. */ -const keyMirror = require('fbjs/lib/keyMirror'); const processColor = require('processColor'); const processTransform = require('processTransform'); const sizesDiffer = require('sizesDiffer'); -const ReactNativeStyleAttributes = { - ...keyMirror(ViewStylePropTypes), - ...keyMirror(TextStylePropTypes), - ...keyMirror(ImageStylePropTypes), -}; +const ReactNativeStyleAttributes = {}; + +for (const attributeName of Object.keys({ + ...DeprecatedViewStylePropTypes, + ...TextStylePropTypes, + ...DeprecatedImageStylePropTypes, +})) { + ReactNativeStyleAttributes[attributeName] = true; +} ReactNativeStyleAttributes.transform = {process: processTransform}; ReactNativeStyleAttributes.shadowOffset = {diff: sizesDiffer}; diff --git a/Libraries/Components/View/ReactNativeViewAttributes.js b/Libraries/Components/View/ReactNativeViewAttributes.js index bc4ca6b3d229fc..5b4ab1c6c2c5fa 100644 --- a/Libraries/Components/View/ReactNativeViewAttributes.js +++ b/Libraries/Components/View/ReactNativeViewAttributes.js @@ -1,11 +1,11 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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 - * @flow strict */ 'use strict'; @@ -21,7 +21,10 @@ ReactNativeViewAttributes.UIView = { accessibilityLabel: true, accessibilityComponentType: true, accessibilityLiveRegion: true, + accessibilityRole: true, + accessibilityStates: true, accessibilityTraits: true, + accessibilityHint: true, importantForAccessibility: true, nativeID: true, testID: true, diff --git a/Libraries/Components/View/ShadowPropTypesIOS.js b/Libraries/Components/View/ShadowPropTypesIOS.js deleted file mode 100644 index 2dfc021735ad9e..00000000000000 --- a/Libraries/Components/View/ShadowPropTypesIOS.js +++ /dev/null @@ -1,50 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * - * 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 ColorPropType = require('ColorPropType'); -const ReactPropTypes = require('prop-types'); - -/** - * These props can be used to dynamically generate shadows on views, images, text, etc. - * - * Because they are dynamically generated, they may cause performance regressions. Static - * shadow image asset may be a better way to go for optimal performance. - * - * These properties are iOS only - for similar functionality on Android, use the [`elevation` - * property](docs/viewstyleproptypes.html#elevation). - */ -const ShadowPropTypesIOS = { - /** - * Sets the drop shadow color - * @platform ios - */ - shadowColor: ColorPropType, - /** - * Sets the drop shadow offset - * @platform ios - */ - shadowOffset: ReactPropTypes.shape({ - width: ReactPropTypes.number, - height: ReactPropTypes.number, - }), - /** - * Sets the drop shadow opacity (multiplied by the color's alpha component) - * @platform ios - */ - shadowOpacity: ReactPropTypes.number, - /** - * Sets the drop shadow blur radius - * @platform ios - */ - shadowRadius: ReactPropTypes.number, -}; - -module.exports = ShadowPropTypesIOS; diff --git a/Libraries/Components/View/View.js b/Libraries/Components/View/View.js index 2cfa05a8c118b2..46e55feb8be3f8 100644 --- a/Libraries/Components/View/View.js +++ b/Libraries/Components/View/View.js @@ -1,22 +1,21 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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 + * @flow strict-local */ 'use strict'; const React = require('React'); const TextAncestor = require('TextAncestor'); +const ViewNativeComponent = require('ViewNativeComponent'); const invariant = require('fbjs/lib/invariant'); -const requireNativeComponent = require('requireNativeComponent'); -import type {NativeComponent} from 'ReactNative'; import type {ViewProps} from 'ViewPropTypes'; export type Props = ViewProps; @@ -28,27 +27,29 @@ export type Props = ViewProps; * * @see http://facebook.github.io/react-native/docs/view.html */ -const RCTView = requireNativeComponent('RCTView'); -let ViewToExport = RCTView; +let ViewToExport = ViewNativeComponent; if (__DEV__) { - const View = (props: Props, forwardedRef: ?React.Ref<'RCTView'>) => { - return ( - - {hasTextAncestor => { - invariant( - !hasTextAncestor, - 'Nesting of within is not currently supported.', - ); - return ; - }} - - ); - }; - // $FlowFixMe - TODO T29156721 `React.forwardRef` is not defined in Flow, yet. - ViewToExport = React.forwardRef(View); + if (!global.__RCTProfileIsProfiling) { + const View = ( + props: Props, + forwardedRef: React.Ref, + ) => { + return ( + + {hasTextAncestor => { + invariant( + !hasTextAncestor, + 'Nesting of within is not currently supported.', + ); + return ; + }} + + ); + }; + // $FlowFixMe - TODO T29156721 `React.forwardRef` is not defined in Flow, yet. + ViewToExport = React.forwardRef(View); + } } -module.exports = ((ViewToExport: $FlowFixMe): Class< - NativeComponent, ->); +module.exports = ((ViewToExport: $FlowFixMe): typeof ViewNativeComponent); diff --git a/Libraries/Components/View/ViewAccessibility.js b/Libraries/Components/View/ViewAccessibility.js index 17ed43140e46c6..ed7eb4d68e50b8 100644 --- a/Libraries/Components/View/ViewAccessibility.js +++ b/Libraries/Components/View/ViewAccessibility.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -39,44 +39,19 @@ export type AccessibilityComponentType = | 'radiobutton_checked' | 'radiobutton_unchecked'; +// This must be kept in sync with the AccessibilityRolesMask in RCTViewManager.m export type AccessibilityRole = | 'none' | 'button' + | 'link' + | 'search' | 'image' | 'keyboardkey' - | 'text'; + | 'text' + | 'adjustable' + | 'imagebutton' + | 'header' + | 'summary'; -module.exports = { - AccessibilityTraits: [ - 'none', - 'button', - 'link', - 'header', - 'search', - 'image', - 'selected', - 'plays', - 'key', - 'text', - 'summary', - 'disabled', - 'frequentUpdates', - 'startsMedia', - 'adjustable', - 'allowsDirectInteraction', - 'pageTurn', - ], - AccessibilityComponentTypes: [ - 'none', - 'button', - 'radiobutton_checked', - 'radiobutton_unchecked', - ], - AccessibilityRoles: [ - 'none', - 'button', - 'image', - 'keyboardkey', - 'text', - ], -}; +// This must be kept in sync with the AccessibilityStatesMask in RCTViewManager.m +export type AccessibilityStates = $ReadOnlyArray<'disabled' | 'selected'>; diff --git a/Libraries/Components/View/ViewNativeComponent.js b/Libraries/Components/View/ViewNativeComponent.js new file mode 100644 index 00000000000000..432040ad3c3a4c --- /dev/null +++ b/Libraries/Components/View/ViewNativeComponent.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 + */ + +'use strict'; + +const ReactNative = require('ReactNative'); + +const requireNativeComponent = require('requireNativeComponent'); + +import type {ViewProps} from 'ViewPropTypes'; + +type ViewNativeComponentType = Class>; + +const NativeViewComponent = requireNativeComponent('RCTView'); + +module.exports = ((NativeViewComponent: any): ViewNativeComponentType); diff --git a/Libraries/Components/View/ViewPropTypes.js b/Libraries/Components/View/ViewPropTypes.js index 73a39cf255fcbf..d2907278c34d08 100644 --- a/Libraries/Components/View/ViewPropTypes.js +++ b/Libraries/Components/View/ViewPropTypes.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -10,221 +10,50 @@ 'use strict'; -const React = require('React'); -const EdgeInsetsPropType = require('EdgeInsetsPropType'); -const PlatformViewPropTypes = require('PlatformViewPropTypes'); -const PropTypes = require('prop-types'); -const StyleSheetPropType = require('StyleSheetPropType'); -const ViewStylePropTypes = require('ViewStylePropTypes'); - -const { - AccessibilityComponentTypes, - AccessibilityTraits, - AccessibilityRoles, -} = require('ViewAccessibility'); - +import type {Layout, LayoutEvent} from 'CoreEventTypes'; +import type {EdgeInsetsProp} from 'EdgeInsetsPropType'; +import type React from 'React'; +import type {ViewStyleProp} from 'StyleSheet'; +import type {TVViewProps} from 'TVViewPropTypes'; import type { AccessibilityComponentType, AccessibilityTrait, AccessibilityRole, + AccessibilityStates, } from 'ViewAccessibility'; -import type {EdgeInsetsProp} from 'EdgeInsetsPropType'; -import type {TVViewProps} from 'TVViewPropTypes'; -import type {Layout, LayoutEvent} from 'CoreEventTypes'; - -const stylePropType = StyleSheetPropType(ViewStylePropTypes); export type ViewLayout = Layout; export type ViewLayoutEvent = LayoutEvent; type DirectEventProps = $ReadOnly<{| - onAccessibilityAction?: Function, - onAccessibilityTap?: Function, - onLayout?: ?(event: LayoutEvent) => void, - onMagicTap?: Function, -|}>; - -type TouchEventProps = $ReadOnly<{| - onTouchCancel?: ?Function, - onTouchCancelCapture?: ?Function, - onTouchEnd?: ?Function, - onTouchEndCapture?: ?Function, - onTouchMove?: ?Function, - onTouchMoveCapture?: ?Function, - onTouchStart?: ?Function, - onTouchStartCapture?: ?Function, -|}>; - -type GestureResponderEventProps = $ReadOnly<{| - onMoveShouldSetResponder?: ?Function, - onMoveShouldSetResponderCapture?: ?Function, - onResponderGrant?: ?Function, - onResponderMove?: ?Function, - onResponderReject?: ?Function, - onResponderRelease?: ?Function, - onResponderStart?: ?Function, - onResponderTerminate?: ?Function, - onResponderTerminationRequest?: ?Function, - onStartShouldSetResponder?: ?Function, - onStartShouldSetResponderCapture?: ?Function, -|}>; - -export type ViewProps = $ReadOnly<{| - ...DirectEventProps, - ...GestureResponderEventProps, - ...TouchEventProps, - - // There's no easy way to create a different type if (Platform.isTV): - // so we must include TVViewProps - ...TVViewProps, - - accessible?: boolean, - accessibilityLabel?: - | null - | React$PropType$Primitive - | string - | Array - | any, - accessibilityActions?: Array, - accessibilityComponentType?: AccessibilityComponentType, - accessibilityLiveRegion?: 'none' | 'polite' | 'assertive', - importantForAccessibility?: 'auto' | 'yes' | 'no' | 'no-hide-descendants', - accessibilityIgnoresInvertColors?: boolean, - accessibilityTraits?: AccessibilityTrait | Array, - accessibilityRole?: AccessibilityRole, - accessibilityViewIsModal?: boolean, - accessibilityElementsHidden?: boolean, - children?: ?React.Node, - testID?: ?string, - nativeID?: string, - hitSlop?: ?EdgeInsetsProp, - pointerEvents?: null | 'box-none' | 'none' | 'box-only' | 'auto', - style?: stylePropType, - removeClippedSubviews?: boolean, - renderToHardwareTextureAndroid?: boolean, - shouldRasterizeIOS?: boolean, - collapsable?: boolean, - needsOffscreenAlphaCompositing?: boolean, -|}>; - -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 - */ - accessible: PropTypes.bool, - - /** - * Overrides the text that's read by the screen reader when the user interacts - * 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 - */ - accessibilityLabel: PropTypes.node, - - /** - * Provides an array of custom actions available for accessibility. - * - * @platform ios - */ - accessibilityActions: PropTypes.arrayOf(PropTypes.string), - /** - * Indicates to accessibility services to treat UI component like a - * native one. Works for Android only. - * - * @platform android - * - * See http://facebook.github.io/react-native/docs/view.html#accessibilitycomponenttype - */ - accessibilityComponentType: PropTypes.oneOf(AccessibilityComponentTypes), - - /** - * Indicates to accessibility services to treat UI component like a - * native one. Merging accessibilityComponentType and accessibilityTraits. - */ - accessibilityRole: PropTypes.oneOf(AccessibilityRoles), - - /** - * Indicates to accessibility services whether the user should be notified - * when this view changes. Works for Android API >= 19 only. - * - * @platform android - * - * See http://facebook.github.io/react-native/docs/view.html#accessibilityliveregion - */ - accessibilityLiveRegion: PropTypes.oneOf(['none', 'polite', 'assertive']), - - /** - * Controls how view is important for accessibility which is if it - * fires accessibility events and if it is reported to accessibility services - * that query the screen. Works for Android only. - * - * @platform android - * - * See http://facebook.github.io/react-native/docs/view.html#importantforaccessibility - */ - importantForAccessibility: PropTypes.oneOf([ - 'auto', - 'yes', - 'no', - 'no-hide-descendants', - ]), - - /** - * Provides additional traits to screen reader. By default no traits are - * provided unless specified otherwise in element. - * - * You can provide one trait or an array of many traits. + * When `accessible` is true, the system will try to invoke this function + * when the user performs an accessibility custom action. * * @platform ios - * - * See http://facebook.github.io/react-native/docs/view.html#accessibilitytraits */ - accessibilityTraits: PropTypes.oneOfType([ - PropTypes.oneOf(AccessibilityTraits), - PropTypes.arrayOf(PropTypes.oneOf(AccessibilityTraits)), - ]), + onAccessibilityAction?: ?Function, /** - * A value indicating whether VoiceOver should ignore the elements - * within views that are siblings of the receiver. - * Default is `false`. - * - * @platform ios + * 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#accessibilityviewismodal + * See http://facebook.github.io/react-native/docs/view.html#onaccessibilitytap */ - accessibilityViewIsModal: PropTypes.bool, + onAccessibilityTap?: ?Function, /** - * A value indicating whether the accessibility elements contained within - * this accessibility element are hidden. - * - * @platform ios + * Invoked on mount and layout changes with: * - * See http://facebook.github.io/react-native/docs/view.html#accessibilityElementsHidden - */ - accessibilityElementsHidden: PropTypes.bool, - - /** - * When `accessible` is true, the system will try to invoke this function - * when the user performs an accessibility custom action. + * `{nativeEvent: { layout: {x, y, width, height}}}` * - * @platform ios - */ - onAccessibilityAction: PropTypes.func, - - /** - * When `accessible` is true, the system will try to invoke this function - * when the user performs accessibility tap gesture. + * This event is fired immediately once the layout has been calculated, but + * 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#onaccessibilitytap + * See http://facebook.github.io/react-native/docs/view.html#onlayout */ - onAccessibilityTap: PropTypes.func, + onLayout?: ?(event: LayoutEvent) => mixed, /** * When `accessible` is `true`, the system will invoke this function when the @@ -232,31 +61,47 @@ module.exports = { * * See http://facebook.github.io/react-native/docs/view.html#onmagictap */ - onMagicTap: PropTypes.func, + onMagicTap?: ?Function, +|}>; +type TouchEventProps = $ReadOnly<{| + onTouchCancel?: ?Function, + onTouchCancelCapture?: ?Function, + onTouchEnd?: ?Function, + onTouchEndCapture?: ?Function, + onTouchMove?: ?Function, + onTouchMoveCapture?: ?Function, + onTouchStart?: ?Function, + onTouchStartCapture?: ?Function, +|}>; + +/** + * For most touch interactions, you'll simply want to wrap your component in + * `TouchableHighlight` or `TouchableOpacity`. Check out `Touchable.js`, + * `ScrollResponder.js` and `ResponderEventPlugin.js` for more discussion. + */ +type GestureResponderEventProps = $ReadOnly<{| /** - * Used to locate this view in end-to-end tests. + * Does this view want to "claim" touch responsiveness? This is called for + * every touch move on the `View` when it is not the responder. * - * > This disables the 'layout-only view removal' optimization for this view! + * `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#testid + * See http://facebook.github.io/react-native/docs/view.html#onmoveshouldsetresponder */ - testID: PropTypes.string, + onMoveShouldSetResponder?: ?Function, /** - * Used to locate this view from native classes. + * If a parent `View` wants to prevent a child `View` from becoming responder + * on a move, it should have this handler which returns `true`. * - * > This disables the 'layout-only view removal' optimization for this view! + * `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#nativeid - */ - nativeID: PropTypes.string, - - /** - * For most touch interactions, you'll simply want to wrap your component in - * `TouchableHighlight` or `TouchableOpacity`. Check out `Touchable.js`, - * `ScrollResponder.js` and `ResponderEventPlugin.js` for more discussion. + * See http://facebook.github.io/react-native/docs/view.html#onMoveShouldsetrespondercapture */ + onMoveShouldSetResponderCapture?: ?Function, /** * The View is now responding for touch events. This is the time to highlight @@ -267,7 +112,7 @@ module.exports = { * * See http://facebook.github.io/react-native/docs/view.html#onrespondergrant */ - onResponderGrant: PropTypes.func, + onResponderGrant?: ?Function, /** * The user is moving their finger. @@ -277,7 +122,7 @@ module.exports = { * * See http://facebook.github.io/react-native/docs/view.html#onrespondermove */ - onResponderMove: PropTypes.func, + onResponderMove?: ?Function, /** * Another responder is already active and will not release it to that `View` @@ -288,7 +133,7 @@ module.exports = { * * See http://facebook.github.io/react-native/docs/view.html#onresponderreject */ - onResponderReject: PropTypes.func, + onResponderReject?: ?Function, /** * Fired at the end of the touch. @@ -298,7 +143,10 @@ module.exports = { * * See http://facebook.github.io/react-native/docs/view.html#onresponderrelease */ - onResponderRelease: PropTypes.func, + onResponderRelease?: ?Function, + + onResponderStart?: ?Function, + onResponderEnd?: ?Function, /** * The responder has been taken from the `View`. Might be taken by other @@ -311,7 +159,7 @@ module.exports = { * * See http://facebook.github.io/react-native/docs/view.html#onresponderterminate */ - onResponderTerminate: PropTypes.func, + onResponderTerminate?: ?Function, /** * Some other `View` wants to become responder and is asking this `View` to @@ -322,7 +170,7 @@ module.exports = { * * See http://facebook.github.io/react-native/docs/view.html#onresponderterminationrequest */ - onResponderTerminationRequest: PropTypes.func, + onResponderTerminationRequest?: ?Function, /** * Does this view want to become responder on the start of a touch? @@ -332,7 +180,7 @@ module.exports = { * * See http://facebook.github.io/react-native/docs/view.html#onstartshouldsetresponder */ - onStartShouldSetResponder: PropTypes.func, + onStartShouldSetResponder?: ?Function, /** * If a parent `View` wants to prevent a child `View` from becoming responder @@ -343,89 +191,127 @@ module.exports = { * * See http://facebook.github.io/react-native/docs/view.html#onstartshouldsetrespondercapture */ - onStartShouldSetResponderCapture: PropTypes.func, + onStartShouldSetResponderCapture?: ?Function, +|}>; + +type AndroidViewProps = $ReadOnly<{| + nativeBackgroundAndroid?: ?Object, + nativeForegroundAndroid?: ?Object, /** - * Does this view want to "claim" touch responsiveness? This is called for - * every touch move on the `View` when it is not the responder. + * Whether this `View` should render itself (and all of its children) into a + * single hardware texture on the GPU. * - * `View.props.onMoveShouldSetResponder: (event) => [true | false]`, where - * `event` is a synthetic touch event as described above. + * @platform android * - * See http://facebook.github.io/react-native/docs/view.html#onmoveshouldsetresponder + * See http://facebook.github.io/react-native/docs/view.html#rendertohardwaretextureandroid */ - onMoveShouldSetResponder: PropTypes.func, + renderToHardwareTextureAndroid?: ?boolean, /** - * If a parent `View` wants to prevent a child `View` from becoming responder - * on a move, it should have this handler which returns `true`. + * Views that are only used to layout their children or otherwise don't draw + * anything may be automatically removed from the native hierarchy as an + * optimization. Set this property to `false` to disable this optimization and + * ensure that this `View` exists in the native view hierarchy. * - * `View.props.onMoveShouldSetResponderCapture: (event) => [true | false]`, - * where `event` is a synthetic touch event as described above. + * @platform android * - * See http://facebook.github.io/react-native/docs/view.html#onMoveShouldsetrespondercapture + * See http://facebook.github.io/react-native/docs/view.html#collapsable */ - onMoveShouldSetResponderCapture: PropTypes.func, + collapsable?: ?boolean, /** - * This defines how far a touch event can start away from the view. - * Typical interface guidelines recommend touch targets that are at least - * 30 - 40 points/density-independent pixels. + * Whether this `View` needs to rendered offscreen and composited with an + * alpha in order to preserve 100% correct colors and blending behavior. * - * > The touch area never extends past the parent view bounds and the Z-index - * > of sibling views always takes precedence if a touch hits two overlapping - * > views. + * @platform android * - * See http://facebook.github.io/react-native/docs/view.html#hitslop + * See http://facebook.github.io/react-native/docs/view.html#needsoffscreenalphacompositing */ - hitSlop: EdgeInsetsPropType, + needsOffscreenAlphaCompositing?: ?boolean, /** - * Invoked on mount and layout changes with: + * Indicates to accessibility services to treat UI component like a + * native one. Works for Android only. * - * `{nativeEvent: { layout: {x, y, width, height}}}` + * @platform android * - * This event is fired immediately once the layout has been calculated, but - * 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#accessibilitycomponenttype + */ + accessibilityComponentType?: ?AccessibilityComponentType, + + /** + * Indicates to accessibility services whether the user should be notified + * when this view changes. Works for Android API >= 19 only. * - * See http://facebook.github.io/react-native/docs/view.html#onlayout + * @platform android + * + * See http://facebook.github.io/react-native/docs/view.html#accessibilityliveregion */ - onLayout: PropTypes.func, + accessibilityLiveRegion?: ?('none' | 'polite' | 'assertive'), /** - * Controls whether the `View` can be the target of touch events. + * Controls how view is important for accessibility which is if it + * fires accessibility events and if it is reported to accessibility services + * that query the screen. Works for Android only. * - * See http://facebook.github.io/react-native/docs/view.html#pointerevents + * @platform android + * + * See http://facebook.github.io/react-native/docs/view.html#importantforaccessibility */ - pointerEvents: PropTypes.oneOf(['box-none', 'none', 'box-only', 'auto']), + importantForAccessibility?: ?('auto' | 'yes' | 'no' | 'no-hide-descendants'), +|}>; +type IOSViewProps = $ReadOnly<{| /** - * See http://facebook.github.io/react-native/docs/style.html + * Provides an array of custom actions available for accessibility. + * + * @platform ios */ - style: stylePropType, + accessibilityActions?: ?$ReadOnlyArray, /** - * This is a special performance property exposed by `RCTView` and is useful - * for scrolling content when there are many subviews, most of which are - * offscreen. For this property to be effective, it must be applied to a - * view that contains many subviews that extend outside its bound. The - * subviews must also have `overflow: hidden`, as should the containing view - * (or one of its superviews). + * Prevents view from being inverted if set to true and color inversion is turned on. * - * See http://facebook.github.io/react-native/docs/view.html#removeclippedsubviews + * @platform ios */ - removeClippedSubviews: PropTypes.bool, + accessibilityIgnoresInvertColors?: ?boolean, /** - * Whether this `View` should render itself (and all of its children) into a - * single hardware texture on the GPU. + * Provides additional traits to screen reader. By default no traits are + * provided unless specified otherwise in element. * - * @platform android + * You can provide one trait or an array of many traits. * - * See http://facebook.github.io/react-native/docs/view.html#rendertohardwaretextureandroid + * @platform ios + * + * See http://facebook.github.io/react-native/docs/view.html#accessibilitytraits */ - renderToHardwareTextureAndroid: PropTypes.bool, + accessibilityTraits?: ?( + | AccessibilityTrait + | $ReadOnlyArray + ), + + /** + * A value indicating whether VoiceOver should ignore the elements + * within views that are siblings of the receiver. + * Default is `false`. + * + * @platform ios + * + * See http://facebook.github.io/react-native/docs/view.html#accessibilityviewismodal + */ + accessibilityViewIsModal?: ?boolean, + + /** + * A value indicating whether the accessibility elements contained within + * this accessibility element are hidden. + * + * @platform ios + * + * See http://facebook.github.io/react-native/docs/view.html#accessibilityElementsHidden + */ + accessibilityElementsHidden?: ?boolean, /** * Whether this `View` should be rendered as a bitmap before compositing. @@ -434,32 +320,107 @@ module.exports = { * * See http://facebook.github.io/react-native/docs/view.html#shouldrasterizeios */ - shouldRasterizeIOS: PropTypes.bool, + shouldRasterizeIOS?: ?boolean, +|}>; + +export type ViewProps = $ReadOnly<{| + ...DirectEventProps, + ...GestureResponderEventProps, + ...TouchEventProps, + ...AndroidViewProps, + ...IOSViewProps, + + // There's no easy way to create a different type if (Platform.isTV): + // so we must include TVViewProps + ...TVViewProps, + + children?: React.Node, + style?: ?ViewStyleProp, /** - * Views that are only used to layout their children or otherwise don't draw - * anything may be automatically removed from the native hierarchy as an - * optimization. Set this property to `false` to disable this optimization and - * ensure that this `View` exists in the native view hierarchy. + * When `true`, indicates that the view is an accessibility element. + * By default, all the touchable elements are accessible. * - * @platform android + * See http://facebook.github.io/react-native/docs/view.html#accessible + */ + accessible?: ?boolean, + + /** + * Overrides the text that's read by the screen reader when the user interacts + * 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#collapsable + * See http://facebook.github.io/react-native/docs/view.html#accessibilitylabel */ - collapsable: PropTypes.bool, + accessibilityLabel?: ?Stringish, /** - * Whether this `View` needs to rendered offscreen and composited with an - * alpha in order to preserve 100% correct colors and blending behavior. + * An accessibility hint helps users understand what will happen when they perform + * an action on the accessibility element when that result is not obvious from the + * accessibility label. * - * @platform android * - * See http://facebook.github.io/react-native/docs/view.html#needsoffscreenalphacompositing + * See http://facebook.github.io/react-native/docs/view.html#accessibilityHint + */ + accessibilityHint?: ?Stringish, + + /** + * Indicates to accessibility services to treat UI component like a specific role. + */ + accessibilityRole?: ?AccessibilityRole, + + /** + * Indicates to accessibility services that UI Component is in a specific State. + */ + accessibilityStates?: ?AccessibilityStates, + + /** + * Used to locate this view in end-to-end tests. + * + * > This disables the 'layout-only view removal' optimization for this view! + * + * See http://facebook.github.io/react-native/docs/view.html#testid + */ + testID?: ?string, + + /** + * Used to locate this view from native classes. + * + * > This disables the 'layout-only view removal' optimization for this view! + * + * See http://facebook.github.io/react-native/docs/view.html#nativeid + */ + nativeID?: ?string, + + /** + * This defines how far a touch event can start away from the view. + * Typical interface guidelines recommend touch targets that are at least + * 30 - 40 points/density-independent pixels. + * + * > The touch area never extends past the parent view bounds and the Z-index + * > of sibling views always takes precedence if a touch hits two overlapping + * > views. + * + * See http://facebook.github.io/react-native/docs/view.html#hitslop */ - needsOffscreenAlphaCompositing: PropTypes.bool, + hitSlop?: ?EdgeInsetsProp, /** - * Any additional platform-specific view prop types, or prop type overrides. + * Controls whether the `View` can be the target of touch events. + * + * See http://facebook.github.io/react-native/docs/view.html#pointerevents */ - ...PlatformViewPropTypes, -}; + pointerEvents?: ?('auto' | 'box-none' | 'box-only' | 'none'), + + /** + * This is a special performance property exposed by `RCTView` and is useful + * for scrolling content when there are many subviews, most of which are + * offscreen. For this property to be effective, it must be applied to a + * view that contains many subviews that extend outside its bound. The + * 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 + */ + removeClippedSubviews?: ?boolean, +|}>; diff --git a/Libraries/Components/ViewPager/ViewPagerAndroid.android.js b/Libraries/Components/ViewPager/ViewPagerAndroid.android.js index 2ccdd31b56365d..3b98308b026589 100644 --- a/Libraries/Components/ViewPager/ViewPagerAndroid.android.js +++ b/Libraries/Components/ViewPager/ViewPagerAndroid.android.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2013-present, Facebook, Inc. + * 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. @@ -11,16 +11,16 @@ 'use strict'; const React = require('React'); -const PropTypes = require('prop-types'); const ReactNative = require('ReactNative'); const UIManager = require('UIManager'); -const ViewPropTypes = require('ViewPropTypes'); const dismissKeyboard = require('dismissKeyboard'); const requireNativeComponent = require('requireNativeComponent'); const NativeAndroidViewPager = requireNativeComponent('AndroidViewPager'); +import type {ViewStyleProp} from 'StyleSheet'; + const VIEWPAGER_REF = 'viewPager'; type Event = Object; @@ -31,6 +31,73 @@ export type ViewPagerScrollState = $Enum<{ settling: string, }>; +type Props = $ReadOnly<{| + /** + * Index of initial page that should be selected. Use `setPage` method to + * update the page, and `onPageSelected` to monitor page changes + */ + initialPage?: ?number, + + /** + * Executed when transitioning between pages (ether because of animation for + * the requested page change or when user is swiping/dragging between pages) + * The `event.nativeEvent` object for this callback will carry following data: + * - position - index of first page from the left that is currently visible + * - offset - value from range [0,1) describing stage between page transitions. + * Value x means that (1 - x) fraction of the page at "position" index is + * visible, and x fraction of the next page is visible. + */ + onPageScroll?: ?Function, + + /** + * Function called when the page scrolling state has changed. + * The page scrolling state can be in 3 states: + * - idle, meaning there is no interaction with the page scroller happening at the time + * - dragging, meaning there is currently an interaction with the page scroller + * - settling, meaning that there was an interaction with the page scroller, and the + * page scroller is now finishing it's closing or opening animation + */ + onPageScrollStateChanged?: ?Function, + + /** + * This callback will be called once ViewPager finish navigating to selected page + * (when user swipes between pages). The `event.nativeEvent` object passed to this + * callback will have following fields: + * - position - index of page that has been selected + */ + onPageSelected?: ?Function, + + /** + * Blank space to show between pages. This is only visible while scrolling, pages are still + * edge-to-edge. + */ + pageMargin?: ?number, + + /** + * Whether enable showing peekFraction or not. If this is true, the preview of + * last and next page will show in current screen. Defaults to false. + */ + + peekEnabled?: ?boolean, + + /** + * Determines whether the keyboard gets dismissed in response to a drag. + * - 'none' (the default), drags do not dismiss the keyboard. + * - 'on-drag', the keyboard is dismissed when a drag begins. + */ + keyboardDismissMode?: ?('none' | 'on-drag'), + + /** + * When false, the content does not scroll. + * The default value is true. + */ + scrollEnabled?: ?boolean, + + children?: React.Node, + + style?: ?ViewStyleProp, +|}>; + /** * Container that allows to flip left and right between child views. Each * child view of the `ViewPagerAndroid` will be treated as a separate page @@ -72,92 +139,22 @@ export type ViewPagerScrollState = $Enum<{ * } * ``` */ -class ViewPagerAndroid extends React.Component<{ - initialPage?: number, - onPageScroll?: Function, - onPageScrollStateChanged?: Function, - onPageSelected?: Function, - pageMargin?: number, - peekEnabled?: boolean, - keyboardDismissMode?: 'none' | 'on-drag', - scrollEnabled?: boolean, -}> { - static propTypes = { - ...ViewPropTypes, - /** - * Index of initial page that should be selected. Use `setPage` method to - * update the page, and `onPageSelected` to monitor page changes - */ - initialPage: PropTypes.number, - - /** - * Executed when transitioning between pages (ether because of animation for - * the requested page change or when user is swiping/dragging between pages) - * The `event.nativeEvent` object for this callback will carry following data: - * - position - index of first page from the left that is currently visible - * - offset - value from range [0,1) describing stage between page transitions. - * Value x means that (1 - x) fraction of the page at "position" index is - * visible, and x fraction of the next page is visible. - */ - onPageScroll: PropTypes.func, - - /** - * Function called when the page scrolling state has changed. - * The page scrolling state can be in 3 states: - * - idle, meaning there is no interaction with the page scroller happening at the time - * - dragging, meaning there is currently an interaction with the page scroller - * - settling, meaning that there was an interaction with the page scroller, and the - * page scroller is now finishing it's closing or opening animation - */ - onPageScrollStateChanged: PropTypes.func, - - /** - * This callback will be called once ViewPager finish navigating to selected page - * (when user swipes between pages). The `event.nativeEvent` object passed to this - * callback will have following fields: - * - position - index of page that has been selected - */ - onPageSelected: PropTypes.func, - - /** - * Blank space to show between pages. This is only visible while scrolling, pages are still - * edge-to-edge. - */ - pageMargin: PropTypes.number, - - /** - * Determines whether the keyboard gets dismissed in response to a drag. - * - 'none' (the default), drags do not dismiss the keyboard. - * - 'on-drag', the keyboard is dismissed when a drag begins. - */ - keyboardDismissMode: PropTypes.oneOf([ - 'none', // default - 'on-drag', - ]), - - /** - * When false, the content does not scroll. - * The default value is true. - */ - scrollEnabled: PropTypes.bool, - - /** - * Whether enable showing peekFraction or not. If this is true, the preview of - * last and next page will show in current screen. Defaults to false. - */ - peekEnabled: PropTypes.bool, - }; +class ViewPagerAndroid extends React.Component { componentDidMount() { if (this.props.initialPage != null) { this.setPageWithoutAnimation(this.props.initialPage); } } + /* $FlowFixMe(>=0.78.0 site=react_native_android_fb) This issue was found + * when making Flow check .android.js files. */ getInnerViewNode = (): ReactComponent => { return this.refs[VIEWPAGER_REF].getInnerViewNode(); }; + /* $FlowFixMe(>=0.78.0 site=react_native_android_fb) This issue was found + * when making Flow check .android.js files. */ _childrenWithOverridenStyle = (): Array => { // Override styles so that each page will fill the parent. Native component // will handle positioning of elements, so it's not important to offset @@ -225,7 +222,7 @@ class ViewPagerAndroid extends React.Component<{ setPage = (selectedPage: number) => { UIManager.dispatchViewManagerCommand( ReactNative.findNodeHandle(this), - UIManager.AndroidViewPager.Commands.setPage, + UIManager.getViewManagerConfig('AndroidViewPager').Commands.setPage, [selectedPage], ); }; @@ -237,7 +234,8 @@ class ViewPagerAndroid extends React.Component<{ setPageWithoutAnimation = (selectedPage: number) => { UIManager.dispatchViewManagerCommand( ReactNative.findNodeHandle(this), - UIManager.AndroidViewPager.Commands.setPageWithoutAnimation, + UIManager.getViewManagerConfig('AndroidViewPager').Commands + .setPageWithoutAnimation, [selectedPage], ); }; diff --git a/Libraries/Components/ViewPager/ViewPagerAndroid.ios.js b/Libraries/Components/ViewPager/ViewPagerAndroid.ios.js index 260d559929796f..7a00b6636cf664 100644 --- a/Libraries/Components/ViewPager/ViewPagerAndroid.ios.js +++ b/Libraries/Components/ViewPager/ViewPagerAndroid.ios.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Components/WebView/WebView.android.js b/Libraries/Components/WebView/WebView.android.js index 4d4b65fb11fdc8..83991432b57c83 100644 --- a/Libraries/Components/WebView/WebView.android.js +++ b/Libraries/Components/WebView/WebView.android.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -9,15 +9,15 @@ 'use strict'; -const EdgeInsetsPropType = require('EdgeInsetsPropType'); const ActivityIndicator = require('ActivityIndicator'); -const React = require('React'); +const DeprecatedViewPropTypes = require('DeprecatedViewPropTypes'); +const DeprecatedEdgeInsetsPropType = require('DeprecatedEdgeInsetsPropType'); const PropTypes = require('prop-types'); +const React = require('React'); const ReactNative = require('ReactNative'); const StyleSheet = require('StyleSheet'); const UIManager = require('UIManager'); const View = require('View'); -const ViewPropTypes = require('ViewPropTypes'); const WebViewShared = require('WebViewShared'); const deprecatedPropType = require('deprecatedPropType'); @@ -44,7 +44,7 @@ const defaultRenderLoading = () => ( */ class WebView extends React.Component { static propTypes = { - ...ViewPropTypes, + ...DeprecatedViewPropTypes, renderError: PropTypes.func, renderLoading: PropTypes.func, onLoad: PropTypes.func, @@ -52,12 +52,12 @@ class WebView extends React.Component { onLoadStart: PropTypes.func, onError: PropTypes.func, automaticallyAdjustContentInsets: PropTypes.bool, - contentInset: EdgeInsetsPropType, + contentInset: DeprecatedEdgeInsetsPropType, onNavigationStateChange: PropTypes.func, onMessage: PropTypes.func, onContentSizeChange: PropTypes.func, startInLoadingState: PropTypes.bool, // force WebView to show loadingView on first load - style: ViewPropTypes.style, + style: DeprecatedViewPropTypes.style, html: deprecatedPropType( PropTypes.string, @@ -109,6 +109,12 @@ class WebView extends React.Component { PropTypes.number, ]), + /** + * If true, use WKWebView instead of UIWebView. + * @platform ios + */ + useWebKit: PropTypes.bool, + /** * Used on Android only, JS is enabled by default for WebView on iOS * @platform android @@ -144,6 +150,12 @@ class WebView extends React.Component { */ scalesPageToFit: PropTypes.bool, + /** + * Sets whether the webview allow access to file system. + * @platform android + */ + allowFileAccess: PropTypes.bool, + /** * Sets the user-agent for this WebView. The user-agent can also be set in native using * WebViewConfig. This prop will overwrite that config. @@ -311,6 +323,7 @@ class WebView extends React.Component { style={webViewStyles} source={resolveAssetSource(source)} scalesPageToFit={this.props.scalesPageToFit} + allowFileAccess={this.props.allowFileAccess} injectedJavaScript={this.props.injectedJavaScript} userAgent={this.props.userAgent} javaScriptEnabled={this.props.javaScriptEnabled} @@ -353,7 +366,7 @@ class WebView extends React.Component { goForward = () => { UIManager.dispatchViewManagerCommand( this.getWebViewHandle(), - UIManager.RCTWebView.Commands.goForward, + UIManager.getViewManagerConfig('RCTWebView').Commands.goForward, null, ); }; @@ -361,7 +374,7 @@ class WebView extends React.Component { goBack = () => { UIManager.dispatchViewManagerCommand( this.getWebViewHandle(), - UIManager.RCTWebView.Commands.goBack, + UIManager.getViewManagerConfig('RCTWebView').Commands.goBack, null, ); }; @@ -372,7 +385,7 @@ class WebView extends React.Component { }); UIManager.dispatchViewManagerCommand( this.getWebViewHandle(), - UIManager.RCTWebView.Commands.reload, + UIManager.getViewManagerConfig('RCTWebView').Commands.reload, null, ); }; @@ -380,7 +393,7 @@ class WebView extends React.Component { stopLoading = () => { UIManager.dispatchViewManagerCommand( this.getWebViewHandle(), - UIManager.RCTWebView.Commands.stopLoading, + UIManager.getViewManagerConfig('RCTWebView').Commands.stopLoading, null, ); }; @@ -388,7 +401,7 @@ class WebView extends React.Component { postMessage = data => { UIManager.dispatchViewManagerCommand( this.getWebViewHandle(), - UIManager.RCTWebView.Commands.postMessage, + UIManager.getViewManagerConfig('RCTWebView').Commands.postMessage, [String(data)], ); }; @@ -402,7 +415,7 @@ class WebView extends React.Component { injectJavaScript = data => { UIManager.dispatchViewManagerCommand( this.getWebViewHandle(), - UIManager.RCTWebView.Commands.injectJavaScript, + UIManager.getViewManagerConfig('RCTWebView').Commands.injectJavaScript, [data], ); }; diff --git a/Libraries/Components/WebView/WebView.ios.js b/Libraries/Components/WebView/WebView.ios.js index 56290df97bcf94..f6c9295baba802 100644 --- a/Libraries/Components/WebView/WebView.ios.js +++ b/Libraries/Components/WebView/WebView.ios.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -11,7 +11,8 @@ 'use strict'; const ActivityIndicator = require('ActivityIndicator'); -const EdgeInsetsPropType = require('EdgeInsetsPropType'); +const DeprecatedViewPropTypes = require('DeprecatedViewPropTypes'); +const DeprecatedEdgeInsetsPropType = require('DeprecatedEdgeInsetsPropType'); const Linking = require('Linking'); const PropTypes = require('prop-types'); const React = require('React'); @@ -21,7 +22,6 @@ const StyleSheet = require('StyleSheet'); const Text = require('Text'); const UIManager = require('UIManager'); const View = require('View'); -const ViewPropTypes = require('ViewPropTypes'); const WebViewShared = require('WebViewShared'); const deprecatedPropType = require('deprecatedPropType'); @@ -32,6 +32,7 @@ const requireNativeComponent = require('requireNativeComponent'); const resolveAssetSource = require('resolveAssetSource'); const RCTWebViewManager = require('NativeModules').WebViewManager; +const RCTWKWebViewManager = require('NativeModules').WKWebViewManager; const BGWASH = 'rgba(255,255,255,0.8)'; const RCT_WEBVIEW_REF = 'webview'; @@ -66,6 +67,9 @@ const DataDetectorTypes = [ 'link', 'address', 'calendarEvent', + 'trackingNumber', + 'flightNumber', + 'lookupSuggestion', 'none', 'all', ]; @@ -110,7 +114,7 @@ class WebView extends React.Component { static JSNavigationScheme = JSNavigationScheme; static NavigationType = NavigationType; static propTypes = { - ...ViewPropTypes, + ...DeprecatedViewPropTypes, html: deprecatedPropType( PropTypes.string, @@ -162,6 +166,12 @@ class WebView extends React.Component { PropTypes.number, ]), + /** + * If true, use WKWebView instead of UIWebView. + * @platform ios + */ + useWebKit: PropTypes.bool, + /** * Function that returns a view to show if there's an error. */ @@ -224,7 +234,7 @@ class WebView extends React.Component { * the scroll view. Defaults to {top: 0, left: 0, bottom: 0, right: 0}. * @platform ios */ - contentInset: EdgeInsetsPropType, + contentInset: DeprecatedEdgeInsetsPropType, /** * Function that is invoked when the `WebView` loading starts or ends. */ @@ -247,7 +257,7 @@ class WebView extends React.Component { /** * The style to apply to the `WebView`. */ - style: ViewPropTypes.style, + style: DeprecatedViewPropTypes.style, /** * Determines the types of data converted to clickable URLs in the web view's content. @@ -264,6 +274,11 @@ class WebView extends React.Component { * - `'none'` * - `'all'` * + * With the new WebKit implementation, we have three new values: + * - `'trackingNumber'`, + * - `'flightNumber'`, + * - `'lookupSuggestion'`, + * * @platform ios */ dataDetectorTypes: PropTypes.oneOfType([ @@ -309,6 +324,8 @@ class WebView extends React.Component { * Boolean that controls whether the web content is scaled to fit * the view and enables the user to change the scale. The default value * is `true`. + * + * On iOS, when `useWebKit=true`, this prop will not work. */ scalesPageToFit: PropTypes.bool, @@ -388,7 +405,6 @@ class WebView extends React.Component { static defaultProps = { originWhitelist: WebViewShared.defaultOriginWhitelist, - scalesPageToFit: true, }; state = { @@ -401,11 +417,28 @@ class WebView extends React.Component { if (this.props.startInLoadingState) { this.setState({viewState: WebViewState.LOADING}); } + + if ( + this.props.useWebKit === true && + this.props.scalesPageToFit !== undefined + ) { + console.warn( + 'The scalesPageToFit property is not supported when useWebKit = true', + ); + } } render() { let otherView = null; + let scalesPageToFit; + + if (this.props.useWebKit) { + ({scalesPageToFit} = this.props); + } else { + ({scalesPageToFit = true} = this.props); + } + if (this.state.viewState === WebViewState.LOADING) { otherView = (this.props.renderLoading || defaultRenderLoading)(); } else if (this.state.viewState === WebViewState.ERROR) { @@ -433,11 +466,18 @@ class WebView extends React.Component { const nativeConfig = this.props.nativeConfig || {}; - const viewManager = nativeConfig.viewManager || RCTWebViewManager; + let viewManager = nativeConfig.viewManager; - const compiledWhitelist = (this.props.originWhitelist || []).map( - WebViewShared.originWhitelistToRegex, - ); + if (this.props.useWebKit) { + viewManager = viewManager || RCTWKWebViewManager; + } else { + viewManager = viewManager || RCTWebViewManager; + } + + const compiledWhitelist = [ + 'about:blank', + ...(this.props.originWhitelist || []), + ].map(WebViewShared.originWhitelistToRegex); const onShouldStartLoadWithRequest = (event: Event) => { let shouldStart = true; const {url} = event.nativeEvent; @@ -473,7 +513,13 @@ class WebView extends React.Component { const messagingEnabled = typeof this.props.onMessage === 'function'; - const NativeWebView = nativeConfig.component || RCTWebView; + let NativeWebView = nativeConfig.component; + + if (this.props.useWebKit) { + NativeWebView = NativeWebView || RCTWKWebView; + } else { + NativeWebView = NativeWebView || RCTWebView; + } const webView = ( { UIManager.dispatchViewManagerCommand( this.getWebViewHandle(), - UIManager.RCTWebView.Commands.goForward, + this._getCommands().goForward, null, ); }; @@ -530,7 +584,7 @@ class WebView extends React.Component { goBack = () => { UIManager.dispatchViewManagerCommand( this.getWebViewHandle(), - UIManager.RCTWebView.Commands.goBack, + this._getCommands().goBack, null, ); }; @@ -542,7 +596,7 @@ class WebView extends React.Component { this.setState({viewState: WebViewState.LOADING}); UIManager.dispatchViewManagerCommand( this.getWebViewHandle(), - UIManager.RCTWebView.Commands.reload, + this._getCommands().reload, null, ); }; @@ -553,7 +607,7 @@ class WebView extends React.Component { stopLoading = () => { UIManager.dispatchViewManagerCommand( this.getWebViewHandle(), - UIManager.RCTWebView.Commands.stopLoading, + this._getCommands().stopLoading, null, ); }; @@ -571,7 +625,7 @@ class WebView extends React.Component { postMessage = data => { UIManager.dispatchViewManagerCommand( this.getWebViewHandle(), - UIManager.RCTWebView.Commands.postMessage, + this._getCommands().postMessage, [String(data)], ); }; @@ -585,7 +639,7 @@ class WebView extends React.Component { injectJavaScript = data => { UIManager.dispatchViewManagerCommand( this.getWebViewHandle(), - UIManager.RCTWebView.Commands.injectJavaScript, + this._getCommands().injectJavaScript, [data], ); }; @@ -640,9 +694,42 @@ class WebView extends React.Component { const {onMessage} = this.props; onMessage && onMessage(event); }; + + componentDidUpdate(prevProps) { + if (!(prevProps.useWebKit && this.props.useWebKit)) { + return; + } + + this._showRedboxOnPropChanges(prevProps, 'allowsInlineMediaPlayback'); + this._showRedboxOnPropChanges(prevProps, 'mediaPlaybackRequiresUserAction'); + this._showRedboxOnPropChanges(prevProps, 'dataDetectorTypes'); + + if (this.props.scalesPageToFit !== undefined) { + console.warn( + 'The scalesPageToFit property is not supported when useWebKit = true', + ); + } + } + + _showRedboxOnPropChanges(prevProps, propName: string) { + if (this.props[propName] !== prevProps[propName]) { + console.error( + `Changes to property ${propName} do nothing after the initial render.`, + ); + } + } } -const RCTWebView = requireNativeComponent('RCTWebView'); +const RCTWebView = requireNativeComponent( + 'RCTWebView', + WebView, + WebView.extraNativeComponentConfig, +); +const RCTWKWebView = requireNativeComponent( + 'RCTWKWebView', + WebView, + WebView.extraNativeComponentConfig, +); const styles = StyleSheet.create({ container: { diff --git a/Libraries/Components/WebView/WebViewShared.js b/Libraries/Components/WebView/WebViewShared.js index 5a3006e845b0cc..af2f7e9a80baaa 100644 --- a/Libraries/Components/WebView/WebViewShared.js +++ b/Libraries/Components/WebView/WebViewShared.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Components/WebView/__tests__/WebViewShared-test.js b/Libraries/Components/WebView/__tests__/WebViewShared-test.js index b7456638fedb71..2a6dee2e2758de 100644 --- a/Libraries/Components/WebView/__tests__/WebViewShared-test.js +++ b/Libraries/Components/WebView/__tests__/WebViewShared-test.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2013-present, Facebook, Inc. + * 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. diff --git a/Libraries/Core/Devtools/__tests__/parseErrorStack-test.js b/Libraries/Core/Devtools/__tests__/parseErrorStack-test.js index 79d677e217e71c..14aafede381848 100644 --- a/Libraries/Core/Devtools/__tests__/parseErrorStack-test.js +++ b/Libraries/Core/Devtools/__tests__/parseErrorStack-test.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Core/Devtools/getDevServer.js b/Libraries/Core/Devtools/getDevServer.js index adcc28c2d067e1..3eae2fbc404baf 100644 --- a/Libraries/Core/Devtools/getDevServer.js +++ b/Libraries/Core/Devtools/getDevServer.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Core/Devtools/openFileInEditor.js b/Libraries/Core/Devtools/openFileInEditor.js index c085883920aeda..00074b91eefedf 100644 --- a/Libraries/Core/Devtools/openFileInEditor.js +++ b/Libraries/Core/Devtools/openFileInEditor.js @@ -1,11 +1,11 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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 + * @flow strict-local */ 'use strict'; diff --git a/Libraries/Core/Devtools/parseErrorStack.js b/Libraries/Core/Devtools/parseErrorStack.js index ec85260d7eaa35..ff308d1dd243cf 100644 --- a/Libraries/Core/Devtools/parseErrorStack.js +++ b/Libraries/Core/Devtools/parseErrorStack.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -19,6 +19,7 @@ export type StackFrame = { export type ExtendedError = Error & { framesToPop?: number, + jsEngine?: string, }; function parseErrorStack(e: ExtendedError): Array { diff --git a/Libraries/Core/Devtools/setupDevtools.js b/Libraries/Core/Devtools/setupDevtools.js index ddca7d04003025..232301629e021b 100644 --- a/Libraries/Core/Devtools/setupDevtools.js +++ b/Libraries/Core/Devtools/setupDevtools.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Core/Devtools/symbolicateStackTrace.js b/Libraries/Core/Devtools/symbolicateStackTrace.js index b5d7d4e9754ff0..93d643cdb3380d 100644 --- a/Libraries/Core/Devtools/symbolicateStackTrace.js +++ b/Libraries/Core/Devtools/symbolicateStackTrace.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Core/ExceptionsManager.js b/Libraries/Core/ExceptionsManager.js index bc32f5d0d23890..08fe06f72b6c47 100644 --- a/Libraries/Core/ExceptionsManager.js +++ b/Libraries/Core/ExceptionsManager.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -22,18 +22,16 @@ function reportException(e: ExtendedError, isFatal: boolean) { const parseErrorStack = require('parseErrorStack'); const stack = parseErrorStack(e); const currentExceptionID = ++exceptionID; + const message = + e.jsEngine == null ? e.message : `${e.message}, js engine: ${e.jsEngine}`; if (isFatal) { ExceptionsManager.reportFatalException( - e.message, + message, stack, currentExceptionID, ); } else { - ExceptionsManager.reportSoftException( - e.message, - stack, - currentExceptionID, - ); + ExceptionsManager.reportSoftException(message, stack, currentExceptionID); } if (__DEV__) { const symbolicateStackTrace = require('symbolicateStackTrace'); diff --git a/Libraries/Core/InitializeCore.js b/Libraries/Core/InitializeCore.js index 119deb92b2b0bc..c55163981c8e4b 100644 --- a/Libraries/Core/InitializeCore.js +++ b/Libraries/Core/InitializeCore.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -91,9 +91,6 @@ polyfillGlobal('regeneratorRuntime', () => { // The require just sets up the global, so make sure when we first // invoke it the global does not exist delete global.regeneratorRuntime; - /* $FlowFixMe(>=0.54.0 site=react_native_oss) This comment suppresses an - * error found when Flow v0.54 was deployed. To see the error delete this - * comment and run Flow. */ require('regenerator-runtime/runtime'); return global.regeneratorRuntime; }); @@ -214,9 +211,6 @@ if (__DEV__) { // Set up inspector const JSInspector = require('JSInspector'); - /* $FlowFixMe(>=0.56.0 site=react_native_fb,react_native_oss) This comment - * suppresses an error found when Flow v0.56 was deployed. To see the error - * delete this comment and run Flow. */ JSInspector.registerAgent(require('NetworkAgent')); } } diff --git a/Libraries/Core/ReactNativeVersion.js b/Libraries/Core/ReactNativeVersion.js index 320b26ac84db6b..1fcb2e9eb61be9 100644 --- a/Libraries/Core/ReactNativeVersion.js +++ b/Libraries/Core/ReactNativeVersion.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Core/ReactNativeVersionCheck.js b/Libraries/Core/ReactNativeVersionCheck.js index 8a937c769d9979..578b205645a487 100644 --- a/Libraries/Core/ReactNativeVersionCheck.js +++ b/Libraries/Core/ReactNativeVersionCheck.js @@ -1,10 +1,10 @@ /** - * Copyright (c) 2017-present, Facebook, Inc. + * 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 + * @flow strict-local * @format */ 'use strict'; diff --git a/Libraries/Core/Timers/JSTimers.js b/Libraries/Core/Timers/JSTimers.js index 7cffb4e3d06d82..36a56fd8cf97cd 100644 --- a/Libraries/Core/Timers/JSTimers.js +++ b/Libraries/Core/Timers/JSTimers.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -290,6 +290,9 @@ const JSTimers = { * @param {function} func Callback to be invoked before the end of the * current JavaScript execution loop. */ + /* $FlowFixMe(>=0.79.1 site=react_native_fb) This comment suppresses an + * error found when Flow v0.79 was deployed. To see the error delete this + * comment and run Flow. */ setImmediate: function(func: Function, ...args: any) { const id = _allocateCallback( () => func.apply(undefined, args), @@ -302,6 +305,9 @@ const JSTimers = { /** * @param {function} func Callback to be invoked every frame. */ + /* $FlowFixMe(>=0.79.1 site=react_native_fb) This comment suppresses an + * error found when Flow v0.79 was deployed. To see the error delete this + * comment and run Flow. */ requestAnimationFrame: function(func: Function) { const id = _allocateCallback(func, 'requestAnimationFrame'); Timing.createTimer(id, 1, Date.now(), /* recurring */ false); @@ -313,6 +319,9 @@ const JSTimers = { * with time remaining in frame. * @param {?object} options */ + /* $FlowFixMe(>=0.79.1 site=react_native_fb) This comment suppresses an + * error found when Flow v0.79 was deployed. To see the error delete this + * comment and run Flow. */ requestIdleCallback: function(func: Function, options: ?Object) { if (requestIdleCallbacks.length === 0) { Timing.setSendIdleEvents(true); diff --git a/Libraries/Core/__mocks__/ErrorUtils.js b/Libraries/Core/__mocks__/ErrorUtils.js index 2719c138c4549d..8505e23dc562fc 100644 --- a/Libraries/Core/__mocks__/ErrorUtils.js +++ b/Libraries/Core/__mocks__/ErrorUtils.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2013-present, Facebook, Inc. + * 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. diff --git a/Libraries/Core/__tests__/ReactNativeVersionCheck-test.js b/Libraries/Core/__tests__/ReactNativeVersionCheck-test.js index e5c8cefddf15bb..6f4da360362e9f 100644 --- a/Libraries/Core/__tests__/ReactNativeVersionCheck-test.js +++ b/Libraries/Core/__tests__/ReactNativeVersionCheck-test.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2017-present, Facebook, Inc. + * 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. diff --git a/Libraries/StyleSheet/ColorPropType.js b/Libraries/DeprecatedPropTypes/DeprecatedColorPropType.js similarity index 96% rename from Libraries/StyleSheet/ColorPropType.js rename to Libraries/DeprecatedPropTypes/DeprecatedColorPropType.js index 93474c47ae234e..84d3b225a45f33 100644 --- a/Libraries/StyleSheet/ColorPropType.js +++ b/Libraries/DeprecatedPropTypes/DeprecatedColorPropType.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/DeprecatedPropTypes/DeprecatedEdgeInsetsPropType.js b/Libraries/DeprecatedPropTypes/DeprecatedEdgeInsetsPropType.js new file mode 100644 index 00000000000000..67a016fffc8d24 --- /dev/null +++ b/Libraries/DeprecatedPropTypes/DeprecatedEdgeInsetsPropType.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 + */ + +'use strict'; + +const PropTypes = require('prop-types'); + +const DeprecatedEdgeInsetsPropType = PropTypes.shape({ + top: PropTypes.number, + left: PropTypes.number, + bottom: PropTypes.number, + right: PropTypes.number, +}); + +module.exports = DeprecatedEdgeInsetsPropType; diff --git a/Libraries/DeprecatedPropTypes/DeprecatedImagePropType.js b/Libraries/DeprecatedPropTypes/DeprecatedImagePropType.js new file mode 100644 index 00000000000000..6b8c16b579d23e --- /dev/null +++ b/Libraries/DeprecatedPropTypes/DeprecatedImagePropType.js @@ -0,0 +1,65 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow + * @format + */ + +'use strict'; + +const DeprecatedEdgeInsetsPropType = require('DeprecatedEdgeInsetsPropType'); +const DeprecatedImageSourcePropType = require('DeprecatedImageSourcePropType'); +const DeprecatedImageStylePropTypes = require('DeprecatedImageStylePropTypes'); +const DeprecatedStyleSheetPropType = require('DeprecatedStyleSheetPropType'); +const PropTypes = require('prop-types'); + +module.exports = { + style: DeprecatedStyleSheetPropType(DeprecatedImageStylePropTypes), + source: DeprecatedImageSourcePropType, + defaultSource: PropTypes.oneOfType([ + PropTypes.shape({ + uri: PropTypes.string, + width: PropTypes.number, + height: PropTypes.number, + scale: PropTypes.number, + }), + PropTypes.number, + ]), + + accessible: PropTypes.bool, + + accessibilityLabel: PropTypes.node, + + blurRadius: PropTypes.number, + + capInsets: DeprecatedEdgeInsetsPropType, + + resizeMethod: PropTypes.oneOf(['auto', 'resize', 'scale']), + + resizeMode: PropTypes.oneOf([ + 'cover', + 'contain', + 'stretch', + 'repeat', + 'center', + ]), + + testID: PropTypes.string, + + onLayout: PropTypes.func, + + onLoadStart: PropTypes.func, + + onProgress: PropTypes.func, + + onError: PropTypes.func, + + onPartialLoad: PropTypes.func, + + onLoad: PropTypes.func, + + onLoadEnd: PropTypes.func, +}; diff --git a/Libraries/DeprecatedPropTypes/DeprecatedImageSourcePropType.js b/Libraries/DeprecatedPropTypes/DeprecatedImageSourcePropType.js new file mode 100644 index 00000000000000..0670023ae73ba2 --- /dev/null +++ b/Libraries/DeprecatedPropTypes/DeprecatedImageSourcePropType.js @@ -0,0 +1,39 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @no-flow + * @format + */ +'use strict'; + +const PropTypes = require('prop-types'); + +const ImageURISourcePropType = PropTypes.shape({ + uri: PropTypes.string, + bundle: PropTypes.string, + method: PropTypes.string, + headers: PropTypes.objectOf(PropTypes.string), + body: PropTypes.string, + cache: PropTypes.oneOf([ + 'default', + 'reload', + 'force-cache', + 'only-if-cached', + ]), + width: PropTypes.number, + height: PropTypes.number, + scale: PropTypes.number, +}); + +const ImageSourcePropType = PropTypes.oneOfType([ + ImageURISourcePropType, + // Opaque type returned by require('./image.jpg') + PropTypes.number, + // Multiple sources + PropTypes.arrayOf(ImageURISourcePropType), +]); + +module.exports = ImageSourcePropType; diff --git a/Libraries/Image/ImageStylePropTypes.js b/Libraries/DeprecatedPropTypes/DeprecatedImageStylePropTypes.js similarity index 69% rename from Libraries/Image/ImageStylePropTypes.js rename to Libraries/DeprecatedPropTypes/DeprecatedImageStylePropTypes.js index 54e500994227db..3fbed21da30fe0 100644 --- a/Libraries/Image/ImageStylePropTypes.js +++ b/Libraries/DeprecatedPropTypes/DeprecatedImageStylePropTypes.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -9,21 +9,26 @@ */ 'use strict'; -const ColorPropType = require('ColorPropType'); -const ImageResizeMode = require('ImageResizeMode'); -const LayoutPropTypes = require('LayoutPropTypes'); +const DeprecatedColorPropType = require('DeprecatedColorPropType'); +const DeprecatedLayoutPropTypes = require('DeprecatedLayoutPropTypes'); const ReactPropTypes = require('prop-types'); -const ShadowPropTypesIOS = require('ShadowPropTypesIOS'); -const TransformPropTypes = require('TransformPropTypes'); +const DeprecatedShadowPropTypesIOS = require('DeprecatedShadowPropTypesIOS'); +const DeprecatedTransformPropTypes = require('DeprecatedTransformPropTypes'); const ImageStylePropTypes = { - ...LayoutPropTypes, - ...ShadowPropTypesIOS, - ...TransformPropTypes, - resizeMode: ReactPropTypes.oneOf(Object.keys(ImageResizeMode)), + ...DeprecatedLayoutPropTypes, + ...DeprecatedShadowPropTypesIOS, + ...DeprecatedTransformPropTypes, + resizeMode: ReactPropTypes.oneOf([ + 'center', + 'contain', + 'cover', + 'repeat', + 'stretch', + ]), backfaceVisibility: ReactPropTypes.oneOf(['visible', 'hidden']), - backgroundColor: ColorPropType, - borderColor: ColorPropType, + backgroundColor: DeprecatedColorPropType, + borderColor: DeprecatedColorPropType, borderWidth: ReactPropTypes.number, borderRadius: ReactPropTypes.number, overflow: ReactPropTypes.oneOf(['visible', 'hidden']), @@ -31,7 +36,7 @@ const ImageStylePropTypes = { /** * Changes the color of all the non-transparent pixels to the tintColor. */ - tintColor: ColorPropType, + tintColor: DeprecatedColorPropType, opacity: ReactPropTypes.number, /** * When the image has rounded corners, specifying an overlayColor will diff --git a/Libraries/DeprecatedPropTypes/DeprecatedLayoutPropTypes.js b/Libraries/DeprecatedPropTypes/DeprecatedLayoutPropTypes.js new file mode 100644 index 00000000000000..0ebccaa8d07083 --- /dev/null +++ b/Libraries/DeprecatedPropTypes/DeprecatedLayoutPropTypes.js @@ -0,0 +1,190 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @format + * @flow strict + */ + +'use strict'; + +const ReactPropTypes = require('prop-types'); + +const LayoutPropTypes = { + display: ReactPropTypes.oneOf(['none', 'flex']), + width: ReactPropTypes.oneOfType([ + ReactPropTypes.number, + ReactPropTypes.string, + ]), + height: ReactPropTypes.oneOfType([ + ReactPropTypes.number, + ReactPropTypes.string, + ]), + start: ReactPropTypes.oneOfType([ + ReactPropTypes.number, + ReactPropTypes.string, + ]), + end: ReactPropTypes.oneOfType([ReactPropTypes.number, ReactPropTypes.string]), + top: ReactPropTypes.oneOfType([ReactPropTypes.number, ReactPropTypes.string]), + left: ReactPropTypes.oneOfType([ + ReactPropTypes.number, + ReactPropTypes.string, + ]), + right: ReactPropTypes.oneOfType([ + ReactPropTypes.number, + ReactPropTypes.string, + ]), + bottom: ReactPropTypes.oneOfType([ + ReactPropTypes.number, + ReactPropTypes.string, + ]), + minWidth: ReactPropTypes.oneOfType([ + ReactPropTypes.number, + ReactPropTypes.string, + ]), + maxWidth: ReactPropTypes.oneOfType([ + ReactPropTypes.number, + ReactPropTypes.string, + ]), + minHeight: ReactPropTypes.oneOfType([ + ReactPropTypes.number, + ReactPropTypes.string, + ]), + maxHeight: ReactPropTypes.oneOfType([ + ReactPropTypes.number, + ReactPropTypes.string, + ]), + margin: ReactPropTypes.oneOfType([ + ReactPropTypes.number, + ReactPropTypes.string, + ]), + marginVertical: ReactPropTypes.oneOfType([ + ReactPropTypes.number, + ReactPropTypes.string, + ]), + marginHorizontal: ReactPropTypes.oneOfType([ + ReactPropTypes.number, + ReactPropTypes.string, + ]), + marginTop: ReactPropTypes.oneOfType([ + ReactPropTypes.number, + ReactPropTypes.string, + ]), + marginBottom: ReactPropTypes.oneOfType([ + ReactPropTypes.number, + ReactPropTypes.string, + ]), + marginLeft: ReactPropTypes.oneOfType([ + ReactPropTypes.number, + ReactPropTypes.string, + ]), + marginRight: ReactPropTypes.oneOfType([ + ReactPropTypes.number, + ReactPropTypes.string, + ]), + marginStart: ReactPropTypes.oneOfType([ + ReactPropTypes.number, + ReactPropTypes.string, + ]), + marginEnd: ReactPropTypes.oneOfType([ + ReactPropTypes.number, + ReactPropTypes.string, + ]), + padding: ReactPropTypes.oneOfType([ + ReactPropTypes.number, + ReactPropTypes.string, + ]), + paddingVertical: ReactPropTypes.oneOfType([ + ReactPropTypes.number, + ReactPropTypes.string, + ]), + paddingHorizontal: ReactPropTypes.oneOfType([ + ReactPropTypes.number, + ReactPropTypes.string, + ]), + paddingTop: ReactPropTypes.oneOfType([ + ReactPropTypes.number, + ReactPropTypes.string, + ]), + paddingBottom: ReactPropTypes.oneOfType([ + ReactPropTypes.number, + ReactPropTypes.string, + ]), + paddingLeft: ReactPropTypes.oneOfType([ + ReactPropTypes.number, + ReactPropTypes.string, + ]), + paddingRight: ReactPropTypes.oneOfType([ + ReactPropTypes.number, + ReactPropTypes.string, + ]), + paddingStart: ReactPropTypes.oneOfType([ + ReactPropTypes.number, + ReactPropTypes.string, + ]), + paddingEnd: ReactPropTypes.oneOfType([ + ReactPropTypes.number, + ReactPropTypes.string, + ]), + borderWidth: ReactPropTypes.number, + borderTopWidth: ReactPropTypes.number, + borderStartWidth: ReactPropTypes.number, + borderEndWidth: ReactPropTypes.number, + borderRightWidth: ReactPropTypes.number, + borderBottomWidth: ReactPropTypes.number, + borderLeftWidth: ReactPropTypes.number, + position: ReactPropTypes.oneOf(['absolute', 'relative']), + flexDirection: ReactPropTypes.oneOf([ + 'row', + 'row-reverse', + 'column', + 'column-reverse', + ]), + flexWrap: ReactPropTypes.oneOf(['wrap', 'nowrap', 'wrap-reverse']), + justifyContent: ReactPropTypes.oneOf([ + 'flex-start', + 'flex-end', + 'center', + 'space-between', + 'space-around', + 'space-evenly', + ]), + alignItems: ReactPropTypes.oneOf([ + 'flex-start', + 'flex-end', + 'center', + 'stretch', + 'baseline', + ]), + alignSelf: ReactPropTypes.oneOf([ + 'auto', + 'flex-start', + 'flex-end', + 'center', + 'stretch', + 'baseline', + ]), + alignContent: ReactPropTypes.oneOf([ + 'flex-start', + 'flex-end', + 'center', + 'stretch', + 'space-between', + 'space-around', + ]), + overflow: ReactPropTypes.oneOf(['visible', 'hidden', 'scroll']), + flex: ReactPropTypes.number, + flexGrow: ReactPropTypes.number, + flexShrink: ReactPropTypes.number, + flexBasis: ReactPropTypes.oneOfType([ + ReactPropTypes.number, + ReactPropTypes.string, + ]), + aspectRatio: ReactPropTypes.number, + zIndex: ReactPropTypes.number, + direction: ReactPropTypes.oneOf(['inherit', 'ltr', 'rtl']), +}; + +module.exports = LayoutPropTypes; diff --git a/Libraries/DeprecatedPropTypes/DeprecatedPointPropType.js b/Libraries/DeprecatedPropTypes/DeprecatedPointPropType.js new file mode 100644 index 00000000000000..9ae8c8f9872d5c --- /dev/null +++ b/Libraries/DeprecatedPropTypes/DeprecatedPointPropType.js @@ -0,0 +1,20 @@ +/** + * 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'; + +const PropTypes = require('prop-types'); + +const PointPropType = PropTypes.shape({ + x: PropTypes.number, + y: PropTypes.number, +}); + +module.exports = PointPropType; diff --git a/Libraries/DeprecatedPropTypes/DeprecatedShadowPropTypesIOS.js b/Libraries/DeprecatedPropTypes/DeprecatedShadowPropTypesIOS.js new file mode 100644 index 00000000000000..889b5624938736 --- /dev/null +++ b/Libraries/DeprecatedPropTypes/DeprecatedShadowPropTypesIOS.js @@ -0,0 +1,25 @@ +/** + * 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 DeprecatedColorPropType = require('DeprecatedColorPropType'); +const ReactPropTypes = require('prop-types'); + +const DeprecatedShadowPropTypesIOS = { + shadowColor: DeprecatedColorPropType, + shadowOffset: ReactPropTypes.shape({ + width: ReactPropTypes.number, + height: ReactPropTypes.number, + }), + shadowOpacity: ReactPropTypes.number, + shadowRadius: ReactPropTypes.number, +}; + +module.exports = DeprecatedShadowPropTypesIOS; diff --git a/Libraries/StyleSheet/StyleSheetPropType.js b/Libraries/DeprecatedPropTypes/DeprecatedStyleSheetPropType.js similarity index 65% rename from Libraries/StyleSheet/StyleSheetPropType.js rename to Libraries/DeprecatedPropTypes/DeprecatedStyleSheetPropType.js index 964c91b5d4d33f..9cad5470ad7374 100644 --- a/Libraries/StyleSheet/StyleSheetPropType.js +++ b/Libraries/DeprecatedPropTypes/DeprecatedStyleSheetPropType.js @@ -1,22 +1,22 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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 + * @flow strict-local */ 'use strict'; -const createStrictShapeTypeChecker = require('createStrictShapeTypeChecker'); +const deprecatedCreateStrictShapeTypeChecker = require('deprecatedCreateStrictShapeTypeChecker'); const flattenStyle = require('flattenStyle'); -function StyleSheetPropType(shape: { +function DeprecatedStyleSheetPropType(shape: { [key: string]: ReactPropsCheckType, }): ReactPropsCheckType { - const shapePropType = createStrictShapeTypeChecker(shape); + const shapePropType = deprecatedCreateStrictShapeTypeChecker(shape); return function(props, propName, componentName, location?, ...rest) { let newProps = props; if (props[propName]) { @@ -28,4 +28,4 @@ function StyleSheetPropType(shape: { }; } -module.exports = StyleSheetPropType; +module.exports = DeprecatedStyleSheetPropType; diff --git a/Libraries/DeprecatedPropTypes/DeprecatedTVViewPropTypes.js b/Libraries/DeprecatedPropTypes/DeprecatedTVViewPropTypes.js new file mode 100644 index 00000000000000..90af60cc27da35 --- /dev/null +++ b/Libraries/DeprecatedPropTypes/DeprecatedTVViewPropTypes.js @@ -0,0 +1,25 @@ +/** + * 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 PropTypes = require('prop-types'); + +const DeprecatedTVViewPropTypes = { + isTVSelectable: PropTypes.bool, + hasTVPreferredFocus: PropTypes.bool, + tvParallaxProperties: PropTypes.object, + tvParallaxShiftDistanceX: PropTypes.number, + tvParallaxShiftDistanceY: PropTypes.number, + tvParallaxTiltAngle: PropTypes.number, + tvParallaxMagnification: PropTypes.number, +}; + +module.exports = DeprecatedTVViewPropTypes; diff --git a/Libraries/DeprecatedPropTypes/DeprecatedTextPropTypes.js b/Libraries/DeprecatedPropTypes/DeprecatedTextPropTypes.js new file mode 100644 index 00000000000000..1723bb56cb6cdd --- /dev/null +++ b/Libraries/DeprecatedPropTypes/DeprecatedTextPropTypes.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. + * + * @flow + * @format + */ + +'use strict'; + +const DeprecatedColorPropType = require('DeprecatedColorPropType'); +const DeprecatedEdgeInsetsPropType = require('DeprecatedEdgeInsetsPropType'); +const DeprecatedStyleSheetPropType = require('DeprecatedStyleSheetPropType'); +const PropTypes = require('prop-types'); +const TextStylePropTypes = require('TextStylePropTypes'); + +const stylePropType = DeprecatedStyleSheetPropType(TextStylePropTypes); + +module.exports = { + ellipsizeMode: PropTypes.oneOf(['head', 'middle', 'tail', 'clip']), + numberOfLines: PropTypes.number, + textBreakStrategy: PropTypes.oneOf(['simple', 'highQuality', 'balanced']), + onLayout: PropTypes.func, + onPress: PropTypes.func, + onLongPress: PropTypes.func, + pressRetentionOffset: DeprecatedEdgeInsetsPropType, + selectable: PropTypes.bool, + selectionColor: DeprecatedColorPropType, + suppressHighlighting: PropTypes.bool, + style: stylePropType, + testID: PropTypes.string, + nativeID: PropTypes.string, + allowFontScaling: PropTypes.bool, + maxFontSizeMultiplier: PropTypes.number, + accessible: PropTypes.bool, + adjustsFontSizeToFit: PropTypes.bool, + minimumFontScale: PropTypes.number, + disabled: PropTypes.bool, +}; diff --git a/Libraries/StyleSheet/TransformPropTypes.js b/Libraries/DeprecatedPropTypes/DeprecatedTransformPropTypes.js similarity index 70% rename from Libraries/StyleSheet/TransformPropTypes.js rename to Libraries/DeprecatedPropTypes/DeprecatedTransformPropTypes.js index 105df3f073b9ad..a463dcc1cd15db 100644 --- a/Libraries/StyleSheet/TransformPropTypes.js +++ b/Libraries/DeprecatedPropTypes/DeprecatedTransformPropTypes.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -40,23 +40,7 @@ const DecomposedMatrixPropType = function( } }; -const TransformPropTypes = { - /** - * `transform` accepts an array of transformation objects. Each object specifies - * the property that will be transformed as the key, and the value to use in the - * transformation. Objects should not be combined. Use a single key/value pair - * per object. - * - * The rotate transformations require a string so that the transform may be - * expressed in degrees (deg) or radians (rad). For example: - * - * `transform([{ rotateX: '45deg' }, { rotateZ: '0.785398rad' }])` - * - * The skew transformations require a string so that the transform may be - * expressed in degrees (deg). For example: - * - * `transform([{ skewX: '45deg' }])` - */ +const DeprecatedTransformPropTypes = { transform: ReactPropTypes.arrayOf( ReactPropTypes.oneOfType([ ReactPropTypes.shape({perspective: ReactPropTypes.number}), @@ -73,17 +57,8 @@ const TransformPropTypes = { ReactPropTypes.shape({skewY: ReactPropTypes.string}), ]), ), - - /** - * Deprecated. Use the transform prop instead. - */ transformMatrix: TransformMatrixPropType, - /** - * Deprecated. Use the transform prop instead. - */ decomposedMatrix: DecomposedMatrixPropType, - - /* Deprecated transform props used on Android only */ scaleX: deprecatedPropType( ReactPropTypes.number, 'Use the transform prop instead.', @@ -106,4 +81,4 @@ const TransformPropTypes = { ), }; -module.exports = TransformPropTypes; +module.exports = DeprecatedTransformPropTypes; diff --git a/Libraries/DeprecatedPropTypes/DeprecatedViewAccessibility.js b/Libraries/DeprecatedPropTypes/DeprecatedViewAccessibility.js new file mode 100644 index 00000000000000..890dd49f0f8672 --- /dev/null +++ b/Libraries/DeprecatedPropTypes/DeprecatedViewAccessibility.js @@ -0,0 +1,55 @@ +/** + * 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'; + +module.exports = { + DeprecatedAccessibilityTraits: [ + 'none', + 'button', + 'link', + 'header', + 'search', + 'image', + 'selected', + 'plays', + 'key', + 'text', + 'summary', + 'disabled', + 'frequentUpdates', + 'startsMedia', + 'adjustable', + 'allowsDirectInteraction', + 'pageTurn', + ], + DeprecatedAccessibilityComponentTypes: [ + 'none', + 'button', + 'radiobutton_checked', + 'radiobutton_unchecked', + ], + // This must be kept in sync with the AccessibilityRolesMask in RCTViewManager.m + DeprecatedAccessibilityRoles: [ + 'none', + 'button', + 'link', + 'search', + 'image', + 'keyboardkey', + 'text', + 'adjustable', + 'imagebutton', + 'header', + 'summary', + ], + // This must be kept in sync with the AccessibilityStatesMask in RCTViewManager.m + DeprecatedAccessibilityStates: ['selected', 'disabled'], +}; diff --git a/Libraries/DeprecatedPropTypes/DeprecatedViewPropTypes.js b/Libraries/DeprecatedPropTypes/DeprecatedViewPropTypes.js new file mode 100644 index 00000000000000..0d5b0746c4a3d8 --- /dev/null +++ b/Libraries/DeprecatedPropTypes/DeprecatedViewPropTypes.js @@ -0,0 +1,409 @@ +/** + * 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 DeprecatedEdgeInsetsPropType = require('DeprecatedEdgeInsetsPropType'); +const PlatformViewPropTypes = require('PlatformViewPropTypes'); +const PropTypes = require('prop-types'); +const DeprecatedStyleSheetPropType = require('DeprecatedStyleSheetPropType'); +const DeprecatedViewStylePropTypes = require('DeprecatedViewStylePropTypes'); + +const { + DeprecatedAccessibilityComponentTypes, + DeprecatedAccessibilityTraits, + DeprecatedAccessibilityRoles, + DeprecatedAccessibilityStates, +} = require('DeprecatedViewAccessibility'); + +const stylePropType = DeprecatedStyleSheetPropType( + DeprecatedViewStylePropTypes, +); + +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 + */ + accessible: PropTypes.bool, + + /** + * Overrides the text that's read by the screen reader when the user interacts + * 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 + */ + accessibilityLabel: PropTypes.node, + + /** + * An accessibility hint helps users understand what will happen when they perform + * an action on the accessibility element when that result is not obvious from the + * accessibility label. + * + * + * See http://facebook.github.io/react-native/docs/view.html#accessibilityHint + */ + accessibilityHint: PropTypes.string, + + /** + * Provides an array of custom actions available for accessibility. + * + * @platform ios + */ + accessibilityActions: PropTypes.arrayOf(PropTypes.string), + + /** + * Prevents view from being inverted if set to true and color inversion is turned on. + * + * @platform ios + */ + accessibilityIgnoresInvertColors: PropTypes.bool, + + /** + * Indicates to accessibility services to treat UI component like a + * native one. Works for Android only. + * + * @platform android + * + * See http://facebook.github.io/react-native/docs/view.html#accessibilitycomponenttype + */ + accessibilityComponentType: PropTypes.oneOf( + DeprecatedAccessibilityComponentTypes, + ), + + /** + * Indicates to accessibility services to treat UI component like a specific role. + */ + accessibilityRole: PropTypes.oneOf(DeprecatedAccessibilityRoles), + + /** + * Indicates to accessibility services that UI Component is in a specific State. + */ + accessibilityStates: PropTypes.arrayOf( + PropTypes.oneOf(DeprecatedAccessibilityStates), + ), + /** + * Indicates to accessibility services whether the user should be notified + * when this view changes. Works for Android API >= 19 only. + * + * @platform android + * + * See http://facebook.github.io/react-native/docs/view.html#accessibilityliveregion + */ + accessibilityLiveRegion: PropTypes.oneOf(['none', 'polite', 'assertive']), + + /** + * Controls how view is important for accessibility which is if it + * fires accessibility events and if it is reported to accessibility services + * that query the screen. Works for Android only. + * + * @platform android + * + * See http://facebook.github.io/react-native/docs/view.html#importantforaccessibility + */ + importantForAccessibility: PropTypes.oneOf([ + 'auto', + 'yes', + 'no', + 'no-hide-descendants', + ]), + + /** + * Provides additional traits to screen reader. By default no traits are + * provided unless specified otherwise in element. + * + * You can provide one trait or an array of many traits. + * + * @platform ios + * + * See http://facebook.github.io/react-native/docs/view.html#accessibilitytraits + */ + accessibilityTraits: PropTypes.oneOfType([ + PropTypes.oneOf(DeprecatedAccessibilityTraits), + PropTypes.arrayOf(PropTypes.oneOf(DeprecatedAccessibilityTraits)), + ]), + + /** + * A value indicating whether VoiceOver should ignore the elements + * within views that are siblings of the receiver. + * Default is `false`. + * + * @platform ios + * + * See http://facebook.github.io/react-native/docs/view.html#accessibilityviewismodal + */ + accessibilityViewIsModal: PropTypes.bool, + + /** + * A value indicating whether the accessibility elements contained within + * this accessibility element are hidden. + * + * @platform ios + * + * See http://facebook.github.io/react-native/docs/view.html#accessibilityElementsHidden + */ + accessibilityElementsHidden: PropTypes.bool, + + /** + * When `accessible` is true, the system will try to invoke this function + * when the user performs an accessibility custom action. + * + * @platform ios + */ + onAccessibilityAction: PropTypes.func, + + /** + * 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 + */ + onAccessibilityTap: PropTypes.func, + + /** + * 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 + */ + onMagicTap: PropTypes.func, + + /** + * Used to locate this view in end-to-end tests. + * + * > This disables the 'layout-only view removal' optimization for this view! + * + * See http://facebook.github.io/react-native/docs/view.html#testid + */ + testID: PropTypes.string, + + /** + * Used to locate this view from native classes. + * + * > This disables the 'layout-only view removal' optimization for this view! + * + * See http://facebook.github.io/react-native/docs/view.html#nativeid + */ + nativeID: PropTypes.string, + + /** + * For most touch interactions, you'll simply want to wrap your component in + * `TouchableHighlight` or `TouchableOpacity`. Check out `Touchable.js`, + * `ScrollResponder.js` and `ResponderEventPlugin.js` for more discussion. + */ + + /** + * The View is now responding for touch events. This is the time to highlight + * and show the user what is happening. + * + * `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 + */ + onResponderGrant: PropTypes.func, + + /** + * The user is moving their finger. + * + * `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 + */ + onResponderMove: PropTypes.func, + + /** + * Another responder is already active and will not release it to that `View` + * asking to be the responder. + * + * `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 + */ + onResponderReject: PropTypes.func, + + /** + * Fired at the end of the touch. + * + * `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 + */ + onResponderRelease: PropTypes.func, + + /** + * The responder has been taken from the `View`. Might be taken by other + * views after a call to `onResponderTerminationRequest`, or might be taken + * by the OS without asking (e.g., happens with control center/ notification + * center on iOS) + * + * `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 + */ + onResponderTerminate: PropTypes.func, + + /** + * Some other `View` wants to become responder and is asking this `View` to + * release its responder. Returning `true` allows its release. + * + * `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 + */ + onResponderTerminationRequest: PropTypes.func, + + /** + * Does this view want to become responder on the start of a touch? + * + * `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 + */ + onStartShouldSetResponder: PropTypes.func, + + /** + * If a parent `View` wants to prevent a child `View` from becoming responder + * on a touch start, it should have this handler which returns `true`. + * + * `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 + */ + onStartShouldSetResponderCapture: PropTypes.func, + + /** + * Does this view want to "claim" touch responsiveness? This is called for + * every touch move on the `View` when it is not the responder. + * + * `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 + */ + onMoveShouldSetResponder: PropTypes.func, + + /** + * If a parent `View` wants to prevent a child `View` from becoming responder + * on a move, it should have this handler which returns `true`. + * + * `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 + */ + onMoveShouldSetResponderCapture: PropTypes.func, + + /** + * This defines how far a touch event can start away from the view. + * Typical interface guidelines recommend touch targets that are at least + * 30 - 40 points/density-independent pixels. + * + * > The touch area never extends past the parent view bounds and the Z-index + * > of sibling views always takes precedence if a touch hits two overlapping + * > views. + * + * See http://facebook.github.io/react-native/docs/view.html#hitslop + */ + hitSlop: DeprecatedEdgeInsetsPropType, + + /** + * Invoked on mount and layout changes with: + * + * `{nativeEvent: { layout: {x, y, width, height}}}` + * + * This event is fired immediately once the layout has been calculated, but + * 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 + */ + 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 + */ + pointerEvents: PropTypes.oneOf(['box-none', 'none', 'box-only', 'auto']), + + /** + * See http://facebook.github.io/react-native/docs/style.html + */ + style: stylePropType, + + /** + * This is a special performance property exposed by `RCTView` and is useful + * for scrolling content when there are many subviews, most of which are + * offscreen. For this property to be effective, it must be applied to a + * view that contains many subviews that extend outside its bound. The + * 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 + */ + removeClippedSubviews: PropTypes.bool, + + /** + * Whether this `View` should render itself (and all of its children) into a + * single hardware texture on the GPU. + * + * @platform android + * + * See http://facebook.github.io/react-native/docs/view.html#rendertohardwaretextureandroid + */ + renderToHardwareTextureAndroid: PropTypes.bool, + + /** + * Whether this `View` should be rendered as a bitmap before compositing. + * + * @platform ios + * + * See http://facebook.github.io/react-native/docs/view.html#shouldrasterizeios + */ + shouldRasterizeIOS: PropTypes.bool, + + /** + * Views that are only used to layout their children or otherwise don't draw + * anything may be automatically removed from the native hierarchy as an + * optimization. Set this property to `false` to disable this optimization and + * ensure that this `View` exists in the native view hierarchy. + * + * @platform android + * + * See http://facebook.github.io/react-native/docs/view.html#collapsable + */ + collapsable: PropTypes.bool, + + /** + * Whether this `View` needs to rendered offscreen and composited with an + * alpha in order to preserve 100% correct colors and blending behavior. + * + * @platform android + * + * See http://facebook.github.io/react-native/docs/view.html#needsoffscreenalphacompositing + */ + needsOffscreenAlphaCompositing: PropTypes.bool, + + /** + * Any additional platform-specific view prop types, or prop type overrides. + */ + ...PlatformViewPropTypes, +}; diff --git a/Libraries/Components/View/ViewStylePropTypes.js b/Libraries/DeprecatedPropTypes/DeprecatedViewStylePropTypes.js similarity index 63% rename from Libraries/Components/View/ViewStylePropTypes.js rename to Libraries/DeprecatedPropTypes/DeprecatedViewStylePropTypes.js index 8f690fb32f6891..546da9cee33e8d 100644 --- a/Libraries/Components/View/ViewStylePropTypes.js +++ b/Libraries/DeprecatedPropTypes/DeprecatedViewStylePropTypes.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -10,28 +10,28 @@ 'use strict'; -const ColorPropType = require('ColorPropType'); -const LayoutPropTypes = require('LayoutPropTypes'); +const DeprecatedColorPropType = require('DeprecatedColorPropType'); +const DeprecatedLayoutPropTypes = require('DeprecatedLayoutPropTypes'); const ReactPropTypes = require('prop-types'); -const ShadowPropTypesIOS = require('ShadowPropTypesIOS'); -const TransformPropTypes = require('TransformPropTypes'); +const DeprecatedShadowPropTypesIOS = require('DeprecatedShadowPropTypesIOS'); +const DeprecatedTransformPropTypes = require('DeprecatedTransformPropTypes'); /** * Warning: Some of these properties may not be supported in all releases. */ -const ViewStylePropTypes = { - ...LayoutPropTypes, - ...ShadowPropTypesIOS, - ...TransformPropTypes, +const DeprecatedViewStylePropTypes = { + ...DeprecatedLayoutPropTypes, + ...DeprecatedShadowPropTypesIOS, + ...DeprecatedTransformPropTypes, backfaceVisibility: ReactPropTypes.oneOf(['visible', 'hidden']), - backgroundColor: ColorPropType, - borderColor: ColorPropType, - borderTopColor: ColorPropType, - borderRightColor: ColorPropType, - borderBottomColor: ColorPropType, - borderLeftColor: ColorPropType, - borderStartColor: ColorPropType, - borderEndColor: ColorPropType, + backgroundColor: DeprecatedColorPropType, + borderColor: DeprecatedColorPropType, + borderTopColor: DeprecatedColorPropType, + borderRightColor: DeprecatedColorPropType, + borderBottomColor: DeprecatedColorPropType, + borderLeftColor: DeprecatedColorPropType, + borderStartColor: DeprecatedColorPropType, + borderEndColor: DeprecatedColorPropType, borderRadius: ReactPropTypes.number, borderTopLeftRadius: ReactPropTypes.number, borderTopRightRadius: ReactPropTypes.number, @@ -58,4 +58,4 @@ const ViewStylePropTypes = { elevation: ReactPropTypes.number, }; -module.exports = ViewStylePropTypes; +module.exports = DeprecatedViewStylePropTypes; diff --git a/Libraries/Utilities/createStrictShapeTypeChecker.js b/Libraries/DeprecatedPropTypes/deprecatedCreateStrictShapeTypeChecker.js similarity index 92% rename from Libraries/Utilities/createStrictShapeTypeChecker.js rename to Libraries/DeprecatedPropTypes/deprecatedCreateStrictShapeTypeChecker.js index ad097e9682344e..524e605ca05b72 100644 --- a/Libraries/Utilities/createStrictShapeTypeChecker.js +++ b/Libraries/DeprecatedPropTypes/deprecatedCreateStrictShapeTypeChecker.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -13,7 +13,7 @@ const invariant = require('fbjs/lib/invariant'); const merge = require('merge'); -function createStrictShapeTypeChecker(shapeTypes: { +function deprecatedCreateStrictShapeTypeChecker(shapeTypes: { [key: string]: ReactPropsCheckType, }): ReactPropsChainableTypeChecker { function checkType( @@ -83,4 +83,4 @@ function createStrictShapeTypeChecker(shapeTypes: { return chainedCheckType; } -module.exports = createStrictShapeTypeChecker; +module.exports = deprecatedCreateStrictShapeTypeChecker; diff --git a/Libraries/EventEmitter/MissingNativeEventEmitterShim.js b/Libraries/EventEmitter/MissingNativeEventEmitterShim.js index 562964b85f4cf4..1b9a51c708a637 100644 --- a/Libraries/EventEmitter/MissingNativeEventEmitterShim.js +++ b/Libraries/EventEmitter/MissingNativeEventEmitterShim.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/EventEmitter/NativeEventEmitter.js b/Libraries/EventEmitter/NativeEventEmitter.js index 2220670fc76909..8aa370b8e4b581 100644 --- a/Libraries/EventEmitter/NativeEventEmitter.js +++ b/Libraries/EventEmitter/NativeEventEmitter.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/EventEmitter/RCTDeviceEventEmitter.js b/Libraries/EventEmitter/RCTDeviceEventEmitter.js index b0977f219abc25..342aa733bf08ff 100644 --- a/Libraries/EventEmitter/RCTDeviceEventEmitter.js +++ b/Libraries/EventEmitter/RCTDeviceEventEmitter.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/EventEmitter/RCTEventEmitter.js b/Libraries/EventEmitter/RCTEventEmitter.js index 1a51905ba20d1e..f84bca058ed366 100644 --- a/Libraries/EventEmitter/RCTEventEmitter.js +++ b/Libraries/EventEmitter/RCTEventEmitter.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/EventEmitter/RCTNativeAppEventEmitter.js b/Libraries/EventEmitter/RCTNativeAppEventEmitter.js index a32cfcef7cf9c7..2d302c014feebb 100644 --- a/Libraries/EventEmitter/RCTNativeAppEventEmitter.js +++ b/Libraries/EventEmitter/RCTNativeAppEventEmitter.js @@ -1,11 +1,11 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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 + * @flow strict-local */ 'use strict'; diff --git a/Libraries/EventEmitter/__mocks__/NativeEventEmitter.js b/Libraries/EventEmitter/__mocks__/NativeEventEmitter.js index e822b72c73c192..e34e60e2e9f201 100644 --- a/Libraries/EventEmitter/__mocks__/NativeEventEmitter.js +++ b/Libraries/EventEmitter/__mocks__/NativeEventEmitter.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Experimental/Incremental.js b/Libraries/Experimental/Incremental.js index cfd0c69fd03cfe..b20fb543e947c5 100644 --- a/Libraries/Experimental/Incremental.js +++ b/Libraries/Experimental/Incremental.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -90,7 +90,7 @@ export type Props = { * Tags instances and associated tasks for easier debugging. */ name: string, - children?: any, + children: React.Node, }; type DefaultProps = { name: string, diff --git a/Libraries/Experimental/IncrementalExample.js b/Libraries/Experimental/IncrementalExample.js index 3cc441fff38591..e63f59a996f974 100644 --- a/Libraries/Experimental/IncrementalExample.js +++ b/Libraries/Experimental/IncrementalExample.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Experimental/IncrementalGroup.js b/Libraries/Experimental/IncrementalGroup.js index af1a7ad63ddb79..03421e92c58f4c 100644 --- a/Libraries/Experimental/IncrementalGroup.js +++ b/Libraries/Experimental/IncrementalGroup.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Experimental/IncrementalPresenter.js b/Libraries/Experimental/IncrementalPresenter.js index 9927179d173966..742d0e93443f24 100644 --- a/Libraries/Experimental/IncrementalPresenter.js +++ b/Libraries/Experimental/IncrementalPresenter.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -11,13 +11,13 @@ 'use strict'; const IncrementalGroup = require('IncrementalGroup'); -const React = require('React'); const PropTypes = require('prop-types'); +const React = require('React'); const View = require('View'); -const ViewPropTypes = require('ViewPropTypes'); - import type {Context} from 'Incremental'; +import type {ViewStyleProp} from 'StyleSheet'; +import type {LayoutEvent} from 'CoreEventTypes'; /** * WARNING: EXPERIMENTAL. Breaking changes will probably happen a lot and will @@ -31,25 +31,19 @@ import type {Context} from 'Incremental'; * * See Incremental.js for more info. */ -type Props = { +type Props = $ReadOnly<{| name: string, disabled?: boolean, - onDone?: () => void, - onLayout?: (event: Object) => void, - style?: mixed, - children?: any, -}; + onDone?: () => mixed, + onLayout?: (event: LayoutEvent) => mixed, + style?: ViewStyleProp, + children?: React.Node, +|}>; + class IncrementalPresenter extends React.Component { context: Context; _isDone: boolean; - static propTypes = { - name: PropTypes.string, - disabled: PropTypes.bool, - onDone: PropTypes.func, - onLayout: PropTypes.func, - style: ViewPropTypes.style, - }; static contextTypes = { incrementalGroup: PropTypes.object, incrementalGroupEnabled: PropTypes.bool, diff --git a/Libraries/Experimental/SwipeableRow/SwipeableFlatList.js b/Libraries/Experimental/SwipeableRow/SwipeableFlatList.js index b01fea760dd0f4..cf54d9d502f7f8 100644 --- a/Libraries/Experimental/SwipeableRow/SwipeableFlatList.js +++ b/Libraries/Experimental/SwipeableRow/SwipeableFlatList.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -17,23 +17,31 @@ const React = require('React'); const SwipeableRow = require('SwipeableRow'); const FlatList = require('FlatList'); +// TODO: Make this $ReadOnly and Exact. Will require doing the same to the props in +// Libraries/Lists/* type SwipableListProps = { /** * To alert the user that swiping is possible, the first row can bounce * on component mount. */ bounceFirstRowOnMount: boolean, - // Maximum distance to open to after a swipe + + /** + * Maximum distance to open to after a swipe + */ maxSwipeDistance: number | (Object => number), - // Callback method to render the view that will be unveiled on swipe + + /** + * Callback method to render the view that will be unveiled on swipe + */ renderQuickActions: renderItemType, }; type Props = SwipableListProps & FlatListProps; -type State = { +type State = {| openRowKey: ?string, -}; +|}; /** * A container component that renders multiple SwipeableRow's in a FlatList @@ -53,29 +61,9 @@ type State = { */ class SwipeableFlatList extends React.Component, State> { - props: Props; - state: State; - _flatListRef: ?FlatList = null; _shouldBounceFirstRowOnMount: boolean = false; - static propTypes = { - ...FlatList.propTypes, - - /** - * To alert the user that swiping is possible, the first row can bounce - * on component mount. - */ - bounceFirstRowOnMount: PropTypes.bool.isRequired, - - // Maximum distance to open to after a swipe - maxSwipeDistance: PropTypes.oneOfType([PropTypes.number, PropTypes.func]) - .isRequired, - - // Callback method to render the view that will be unveiled on swipe - renderQuickActions: PropTypes.func.isRequired, - }; - static defaultProps = { ...FlatList.defaultProps, bounceFirstRowOnMount: true, @@ -100,6 +88,7 @@ class SwipeableFlatList extends React.Component, State> { }} onScroll={this._onScroll} renderItem={this._renderItem} + extraData={this.state} /> ); } diff --git a/Libraries/Experimental/SwipeableRow/SwipeableListView.js b/Libraries/Experimental/SwipeableRow/SwipeableListView.js index bae4eb5f2ff846..3189b728a7962a 100644 --- a/Libraries/Experimental/SwipeableRow/SwipeableListView.js +++ b/Libraries/Experimental/SwipeableRow/SwipeableListView.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -11,30 +11,53 @@ 'use strict'; const ListView = require('ListView'); -const PropTypes = require('prop-types'); const React = require('React'); const SwipeableListViewDataSource = require('SwipeableListViewDataSource'); const SwipeableRow = require('SwipeableRow'); -type DefaultProps = { - bounceFirstRowOnMount: boolean, - renderQuickActions: Function, -}; +type ListViewProps = React.ElementConfig; + +type Props = $ReadOnly<{| + ...ListViewProps, -type Props = { + /** + * To alert the user that swiping is possible, the first row can bounce + * on component mount. + */ bounceFirstRowOnMount: boolean, + /** + * Use `SwipeableListView.getNewDataSource()` to get a data source to use, + * then use it just like you would a normal ListView data source + */ dataSource: SwipeableListViewDataSource, + /** + * Maximum distance to open to after a swipe + */ maxSwipeDistance: | number - | ((rowData: any, sectionID: string, rowID: string) => number), + | ((rowData: Object, sectionID: string, rowID: string) => number), onScroll?: ?Function, - renderRow: Function, - renderQuickActions: Function, -}; + /** + * Callback method to render the swipeable view + */ + renderRow: ( + rowData: Object, + sectionID: string, + rowID: string, + ) => React.Element, + /** + * Callback method to render the view that will be unveiled on swipe + */ + renderQuickActions: ( + rowData: Object, + sectionID: string, + rowID: string, + ) => ?React.Element, +|}>; -type State = { +type State = {| dataSource: Object, -}; +|}; /** * A container component that renders multiple SwipeableRow's in a ListView @@ -70,26 +93,6 @@ class SwipeableListView extends React.Component { }); } - static propTypes = { - /** - * To alert the user that swiping is possible, the first row can bounce - * on component mount. - */ - bounceFirstRowOnMount: PropTypes.bool.isRequired, - /** - * Use `SwipeableListView.getNewDataSource()` to get a data source to use, - * then use it just like you would a normal ListView data source - */ - dataSource: PropTypes.instanceOf(SwipeableListViewDataSource).isRequired, - // Maximum distance to open to after a swipe - maxSwipeDistance: PropTypes.oneOfType([PropTypes.number, PropTypes.func]) - .isRequired, - // Callback method to render the swipeable view - renderRow: PropTypes.func.isRequired, - // Callback method to render the view that will be unveiled on swipe - renderQuickActions: PropTypes.func.isRequired, - }; - static defaultProps = { bounceFirstRowOnMount: false, renderQuickActions: () => null, diff --git a/Libraries/Experimental/SwipeableRow/SwipeableListViewDataSource.js b/Libraries/Experimental/SwipeableRow/SwipeableListViewDataSource.js index 6c409a9acad1c4..38e03c66140d0f 100644 --- a/Libraries/Experimental/SwipeableRow/SwipeableListViewDataSource.js +++ b/Libraries/Experimental/SwipeableRow/SwipeableListViewDataSource.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Experimental/SwipeableRow/SwipeableQuickActionButton.js b/Libraries/Experimental/SwipeableRow/SwipeableQuickActionButton.js index e0ea2ce8cabd23..82e1f7a0ae5e47 100644 --- a/Libraries/Experimental/SwipeableRow/SwipeableQuickActionButton.js +++ b/Libraries/Experimental/SwipeableRow/SwipeableQuickActionButton.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -10,12 +10,12 @@ 'use strict'; +const DeprecatedViewPropTypes = require('DeprecatedViewPropTypes'); const Image = require('Image'); const React = require('React'); const Text = require('Text'); const TouchableHighlight = require('TouchableHighlight'); const View = require('View'); -const ViewPropTypes = require('ViewPropTypes'); import type {ImageSource} from 'ImageSource'; @@ -27,13 +27,22 @@ import type {ImageSource} from 'ImageSource'; class SwipeableQuickActionButton extends React.Component<{ accessibilityLabel?: string, imageSource?: ?(ImageSource | number), - imageStyle?: ?ViewPropTypes.style, + /* $FlowFixMe(>=0.82.0 site=react_native_fb) This comment suppresses an error + * found when Flow v0.82 was deployed. To see the error delete this comment + * and run Flow. */ + imageStyle?: ?DeprecatedViewPropTypes.style, mainView?: ?React.Node, onPress?: Function, - style?: ?ViewPropTypes.style, + /* $FlowFixMe(>=0.82.0 site=react_native_fb) This comment suppresses an error + * found when Flow v0.82 was deployed. To see the error delete this comment + * and run Flow. */ + style?: ?DeprecatedViewPropTypes.style, testID?: string, text?: ?(string | Object | Array), - textStyle?: ?ViewPropTypes.style, + /* $FlowFixMe(>=0.82.0 site=react_native_fb) This comment suppresses an error + * found when Flow v0.82 was deployed. To see the error delete this comment + * and run Flow. */ + textStyle?: ?DeprecatedViewPropTypes.style, }> { render(): React.Node { if (!this.props.imageSource && !this.props.text && !this.props.mainView) { diff --git a/Libraries/Experimental/SwipeableRow/SwipeableQuickActions.js b/Libraries/Experimental/SwipeableRow/SwipeableQuickActions.js index 3642b135d43191..c97f77648af76f 100644 --- a/Libraries/Experimental/SwipeableRow/SwipeableQuickActions.js +++ b/Libraries/Experimental/SwipeableRow/SwipeableQuickActions.js @@ -1,11 +1,11 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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 + * @flow strict-local */ 'use strict'; @@ -14,7 +14,12 @@ const React = require('React'); const StyleSheet = require('StyleSheet'); const View = require('View'); -const ViewPropTypes = require('ViewPropTypes'); +import type {ViewStyleProp} from 'StyleSheet'; + +type Props = $ReadOnly<{| + style?: ?ViewStyleProp, + children: React.Node, +|}>; /** * A thin wrapper around standard quick action buttons that can, if the user @@ -26,13 +31,8 @@ const ViewPropTypes = require('ViewPropTypes'); * * */ -class SwipeableQuickActions extends React.Component<{style?: $FlowFixMe}> { - static propTypes = { - style: ViewPropTypes.style, - }; - +class SwipeableQuickActions extends React.Component { render(): React.Node { - // $FlowFixMe found when converting React.createClass to ES6 const children = this.props.children; let buttons = []; @@ -41,8 +41,7 @@ class SwipeableQuickActions extends React.Component<{style?: $FlowFixMe}> { for (let i = 0; i < children.length; i++) { buttons.push(children[i]); - // $FlowFixMe found when converting React.createClass to ES6 - if (i < this.props.children.length - 1) { + if (i < children.length - 1) { // Not last button buttons.push(); } diff --git a/Libraries/Experimental/SwipeableRow/SwipeableRow.js b/Libraries/Experimental/SwipeableRow/SwipeableRow.js index 3cbeb3d6ca2558..5e9e796cdcdb79 100644 --- a/Libraries/Experimental/SwipeableRow/SwipeableRow.js +++ b/Libraries/Experimental/SwipeableRow/SwipeableRow.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -16,15 +16,14 @@ const PanResponder = require('PanResponder'); const React = require('React'); const PropTypes = require('prop-types'); const StyleSheet = require('StyleSheet'); -/* $FlowFixMe(>=0.54.0 site=react_native_oss) This comment suppresses an error - * found when Flow v0.54 was deployed. To see the error delete this comment and - * run Flow. */ -const TimerMixin = require('react-timer-mixin'); const View = require('View'); const createReactClass = require('create-react-class'); const emptyFunction = require('fbjs/lib/emptyFunction'); +import type {LayoutEvent, PressEvent} from 'CoreEventTypes'; +import type {GestureState} from 'PanResponder'; + const IS_RTL = I18nManager.isRTL; // NOTE: Eventually convert these consts to an input object of configurations @@ -82,8 +81,7 @@ const SwipeableRow = createReactClass({ displayName: 'SwipeableRow', _panResponder: {}, _previousLeft: CLOSED_LEFT_POSITION, - - mixins: [TimerMixin], + _timeoutID: (null: ?TimeoutID), propTypes: { children: PropTypes.any, @@ -154,7 +152,7 @@ const SwipeableRow = createReactClass({ * Do the on mount bounce after a delay because if we animate when other * components are loading, the animation will be laggy */ - this.setTimeout(() => { + this._timeoutID = setTimeout(() => { this._animateBounceBack(ON_MOUNT_BOUNCE_DURATION); }, ON_MOUNT_BOUNCE_DELAY); } @@ -170,6 +168,12 @@ const SwipeableRow = createReactClass({ } }, + componentWillUnmount() { + if (this._timeoutID != null) { + clearTimeout(this._timeoutID); + } + }, + render(): React.Element { // The view hidden behind the main view let slideOutView; @@ -204,7 +208,7 @@ const SwipeableRow = createReactClass({ this._animateToClosedPosition(); }, - _onSwipeableViewLayout(event: Object): void { + _onSwipeableViewLayout(event: LayoutEvent): void { this.setState({ isSwipeableViewRendered: true, rowHeight: event.nativeEvent.layout.height, @@ -212,16 +216,19 @@ const SwipeableRow = createReactClass({ }, _handleMoveShouldSetPanResponderCapture( - event: Object, - gestureState: Object, + event: PressEvent, + gestureState: GestureState, ): boolean { // Decides whether a swipe is responded to by this component or its child return gestureState.dy < 10 && this._isValidSwipe(gestureState); }, - _handlePanResponderGrant(event: Object, gestureState: Object): void {}, + _handlePanResponderGrant( + event: PressEvent, + gestureState: GestureState, + ): void {}, - _handlePanResponderMove(event: Object, gestureState: Object): void { + _handlePanResponderMove(event: PressEvent, gestureState: GestureState): void { if (this._isSwipingExcessivelyRightFromClosedPosition(gestureState)) { return; } @@ -235,22 +242,24 @@ const SwipeableRow = createReactClass({ } }, - _isSwipingRightFromClosed(gestureState: Object): boolean { + _isSwipingRightFromClosed(gestureState: GestureState): boolean { const gestureStateDx = IS_RTL ? -gestureState.dx : gestureState.dx; return this._previousLeft === CLOSED_LEFT_POSITION && gestureStateDx > 0; }, - _swipeFullSpeed(gestureState: Object): void { + _swipeFullSpeed(gestureState: GestureState): void { this.state.currentLeft.setValue(this._previousLeft + gestureState.dx); }, - _swipeSlowSpeed(gestureState: Object): void { + _swipeSlowSpeed(gestureState: GestureState): void { this.state.currentLeft.setValue( this._previousLeft + gestureState.dx / SLOW_SPEED_SWIPE_FACTOR, ); }, - _isSwipingExcessivelyRightFromClosedPosition(gestureState: Object): boolean { + _isSwipingExcessivelyRightFromClosedPosition( + gestureState: GestureState, + ): boolean { /** * We want to allow a BIT of right swipe, to allow users to know that * swiping is available, but swiping right does not do anything @@ -264,8 +273,8 @@ const SwipeableRow = createReactClass({ }, _onPanResponderTerminationRequest( - event: Object, - gestureState: Object, + event: PressEvent, + gestureState: GestureState, ): boolean { return false; }, @@ -338,7 +347,7 @@ const SwipeableRow = createReactClass({ }, // Ignore swipes due to user's finger moving slightly when tapping - _isValidSwipe(gestureState: Object): boolean { + _isValidSwipe(gestureState: GestureState): boolean { if ( this.props.preventSwipeRight && this._previousLeft === CLOSED_LEFT_POSITION && @@ -350,7 +359,7 @@ const SwipeableRow = createReactClass({ return Math.abs(gestureState.dx) > HORIZONTAL_SWIPE_DISTANCE_THRESHOLD; }, - _shouldAnimateRemainder(gestureState: Object): boolean { + _shouldAnimateRemainder(gestureState: GestureState): boolean { /** * If user has swiped past a certain distance, animate the rest of the way * if they let go @@ -361,7 +370,7 @@ const SwipeableRow = createReactClass({ ); }, - _handlePanResponderEnd(event: Object, gestureState: Object): void { + _handlePanResponderEnd(event: PressEvent, gestureState: GestureState): void { const horizontalDistance = IS_RTL ? -gestureState.dx : gestureState.dx; if (this._isSwipingRightFromClosed(gestureState)) { this.props.onOpen(); diff --git a/Libraries/Experimental/WindowedListView.js b/Libraries/Experimental/WindowedListView.js index 15f1d0b4a8755a..830d653d9a39a5 100644 --- a/Libraries/Experimental/WindowedListView.js +++ b/Libraries/Experimental/WindowedListView.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -24,7 +24,7 @@ const clamp = require('clamp'); const deepDiffer = require('deepDiffer'); const infoLog = require('infoLog'); const invariant = require('fbjs/lib/invariant'); -const nullthrows = require('fbjs/lib/nullthrows'); +const nullthrows = require('nullthrows'); import type {NativeMethodsMixinType} from 'ReactNativeTypes'; diff --git a/Libraries/Geolocation/Geolocation.js b/Libraries/Geolocation/Geolocation.js index d252da95bca58f..0cde34c59456bc 100644 --- a/Libraries/Geolocation/Geolocation.js +++ b/Libraries/Geolocation/Geolocation.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Geolocation/RCTLocationObserver.h b/Libraries/Geolocation/RCTLocationObserver.h index 5de0ea289d881d..f3f9e19b8f2902 100644 --- a/Libraries/Geolocation/RCTLocationObserver.h +++ b/Libraries/Geolocation/RCTLocationObserver.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Geolocation/RCTLocationObserver.m b/Libraries/Geolocation/RCTLocationObserver.m index 9e15facfa7ef68..904538d8a64110 100644 --- a/Libraries/Geolocation/RCTLocationObserver.m +++ b/Libraries/Geolocation/RCTLocationObserver.m @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Image/AssetRegistry.js b/Libraries/Image/AssetRegistry.js index b050a9e239cd27..7d9626f8771f42 100644 --- a/Libraries/Image/AssetRegistry.js +++ b/Libraries/Image/AssetRegistry.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Image/AssetSourceResolver.js b/Libraries/Image/AssetSourceResolver.js index a870a325242838..b5650620ae1481 100644 --- a/Libraries/Image/AssetSourceResolver.js +++ b/Libraries/Image/AssetSourceResolver.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Image/Image.android.js b/Libraries/Image/Image.android.js index d0e685a5e64229..3eda5a7c52d2ec 100644 --- a/Libraries/Image/Image.android.js +++ b/Libraries/Image/Image.android.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -10,25 +10,24 @@ 'use strict'; -const ImageStylePropTypes = require('ImageStylePropTypes'); +const DeprecatedImageStylePropTypes = require('DeprecatedImageStylePropTypes'); +const DeprecatedStyleSheetPropType = require('DeprecatedStyleSheetPropType'); +const DeprecatedViewPropTypes = require('DeprecatedViewPropTypes'); +const ImageViewNativeComponent = require('ImageViewNativeComponent'); const NativeModules = require('NativeModules'); +const PropTypes = require('prop-types'); const React = require('React'); const ReactNative = require('ReactNative'); -const PropTypes = require('prop-types'); const StyleSheet = require('StyleSheet'); -const StyleSheetPropType = require('StyleSheetPropType'); const TextAncestor = require('TextAncestor'); -const ViewPropTypes = require('ViewPropTypes'); const flattenStyle = require('flattenStyle'); const merge = require('merge'); -const requireNativeComponent = require('requireNativeComponent'); const resolveAssetSource = require('resolveAssetSource'); const {ImageLoader} = NativeModules; -const RKImage = requireNativeComponent('RCTImageView'); -const RCTTextInlineImage = requireNativeComponent('RCTTextInlineImage'); +const TextInlineImageNativeComponent = require('TextInlineImageNativeComponent'); import type {ImageProps as ImagePropsType} from 'ImageProps'; @@ -38,8 +37,8 @@ function generateRequestId() { } const ImageProps = { - ...ViewPropTypes, - style: StyleSheetPropType(ImageStylePropTypes), + ...DeprecatedViewPropTypes, + style: DeprecatedStyleSheetPropType(DeprecatedImageStylePropTypes), /** * See https://facebook.github.io/react-native/docs/image.html#source */ @@ -182,17 +181,14 @@ declare class ImageComponentType extends ReactNative.NativeComponent< */ let Image = ( props: ImagePropsType, - forwardedRef: ?React.Ref<'RCTTextInlineImage' | 'RKImage'>, + forwardedRef: ?React.Ref<'RCTTextInlineImage' | 'ImageViewNativeComponent'>, ) => { - const source = resolveAssetSource(props.source); + let source = resolveAssetSource(props.source); const defaultSource = resolveAssetSource(props.defaultSource); const loadingIndicatorSource = resolveAssetSource( props.loadingIndicatorSource, ); - // As opposed to the ios version, here we render `null` when there is no source, source.uri - // or source array. - if (source && source.uri === '') { console.warn('source.uri should not be an empty string'); } @@ -215,15 +211,19 @@ let Image = ( ); } - if (!source || (!source.uri && !Array.isArray(source))) { - return null; + if (source && !source.uri && !Array.isArray(source)) { + source = null; } let style; let sources; - if (source.uri) { + 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]); @@ -235,7 +235,9 @@ let Image = ( style, shouldNotifyLoadEvents: !!(onLoadStart || onLoad || onLoadEnd || onError), src: sources, - headers: source.headers, + /* $FlowFixMe(>=0.78.0 site=react_native_android_fb) This issue was found + * when making Flow check .android.js files. */ + headers: source?.headers, defaultSrc: defaultSource ? defaultSource.uri : null, loadingIndicatorSrc: loadingIndicatorSource ? loadingIndicatorSource.uri @@ -247,9 +249,9 @@ let Image = ( {hasTextAncestor => hasTextAncestor ? ( - + ) : ( - + ) } diff --git a/Libraries/Image/Image.ios.js b/Libraries/Image/Image.ios.js index 82e651c0362924..29532dea908e89 100644 --- a/Libraries/Image/Image.ios.js +++ b/Libraries/Image/Image.ios.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -9,7 +9,7 @@ */ 'use strict'; -const ImageProps = require('ImageProps'); +const DeprecatedImagePropType = require('DeprecatedImagePropType'); const NativeModules = require('NativeModules'); const React = require('React'); const ReactNative = require('ReactNative'); @@ -23,6 +23,7 @@ const ImageViewManager = NativeModules.ImageViewManager; const RCTImageView = requireNativeComponent('RCTImageView'); +import type {ImageStyleProp} from 'StyleSheet'; import type {ImageProps as ImagePropsType} from 'ImageProps'; function getSize( @@ -44,13 +45,20 @@ function prefetch(url: string) { return ImageViewManager.prefetchImage(url); } +async function queryCache( + urls: Array, +): Promise> { + return await ImageViewManager.queryCache(urls); +} + declare class ImageComponentType extends ReactNative.NativeComponent< ImagePropsType, > { static getSize: typeof getSize; static prefetch: typeof prefetch; + static queryCache: typeof queryCache; static resolveAssetSource: typeof resolveAssetSource; - static propTypes: typeof ImageProps; + static propTypes: typeof DeprecatedImagePropType; } /** @@ -71,12 +79,14 @@ let Image = ( }; let sources; - let style; + let style: ImageStyleProp; if (Array.isArray(source)) { + // $FlowFixMe flattenStyle is not strong enough style = flattenStyle([styles.base, props.style]) || {}; sources = source; } else { const {width, height, uri} = source; + // $FlowFixMe flattenStyle is not strong enough style = flattenStyle([{width, height}, styles.base, props.style]) || {}; sources = [source]; @@ -130,6 +140,13 @@ Image.getSize = getSize; */ Image.prefetch = prefetch; +/** + * Performs cache interrogation. + * + * See https://facebook.github.io/react-native/docs/image.html#querycache + */ +Image.queryCache = queryCache; + /** * Resolves an asset reference into an object. * @@ -137,7 +154,7 @@ Image.prefetch = prefetch; */ Image.resolveAssetSource = resolveAssetSource; -Image.propTypes = ImageProps; +Image.propTypes = DeprecatedImagePropType; const styles = StyleSheet.create({ base: { diff --git a/Libraries/Image/ImageBackground.js b/Libraries/Image/ImageBackground.js index a128880a17807c..7d04576dcc0c92 100644 --- a/Libraries/Image/ImageBackground.js +++ b/Libraries/Image/ImageBackground.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Image/ImageEditor.js b/Libraries/Image/ImageEditor.js index 66504b501293db..53785b680c15c1 100644 --- a/Libraries/Image/ImageEditor.js +++ b/Libraries/Image/ImageEditor.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -16,25 +16,25 @@ type ImageCropData = { * The top-left corner of the cropped image, specified in the original * image's coordinate space. */ - offset: { + offset: {| x: number, y: number, - }, + |}, /** * The size (dimensions) of the cropped image, specified in the original * image's coordinate space. */ - size: { + size: {| width: number, height: number, - }, + |}, /** * (Optional) size to scale the cropped image to. */ - displaySize?: ?{ + displaySize?: ?{| width: number, height: number, - }, + |}, /** * (Optional) the resizing mode to use when scaling the image. If the * `displaySize` param is not specified, this has no effect. @@ -50,7 +50,9 @@ class ImageEditor { /** * Crop the image specified by the URI param. If URI points to a remote * image, it will be downloaded automatically. If the image cannot be - * loaded/downloaded, the failure callback will be called. + * loaded/downloaded, the failure callback will be called. On Android, a + * downloaded image may be cached in external storage, a publicly accessible + * location, if it has more available space than internal storage. * * If the cropping process is successful, the resultant cropped image * will be stored in the ImageStore, and the URI returned in the success diff --git a/Libraries/Image/ImageProps.js b/Libraries/Image/ImageProps.js index 54f6250e1f1458..9dcf083be07841 100644 --- a/Libraries/Image/ImageProps.js +++ b/Libraries/Image/ImageProps.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -10,18 +10,12 @@ 'use strict'; -const EdgeInsetsPropType = require('EdgeInsetsPropType'); -const ImageSourcePropType = require('ImageSourcePropType'); -const ImageStylePropTypes = require('ImageStylePropTypes'); -const PropTypes = require('prop-types'); -const StyleSheetPropType = require('StyleSheetPropType'); - +import type {SyntheticEvent, LayoutEvent} from 'CoreEventTypes'; +import type {EdgeInsetsProp} from 'EdgeInsetsPropType'; +import type {ImageSource} from 'ImageSource'; +import type {ViewStyleProp, ImageStyleProp} from 'StyleSheet'; import type {DimensionValue} from 'StyleSheetTypes'; import type {ViewProps} from 'ViewPropTypes'; -import type {ImageSource} from 'ImageSource'; -import type {EdgeInsetsProp} from 'EdgeInsetsPropType'; -import type {SyntheticEvent} from 'CoreEventTypes'; -import type {ImageStyleProp} from 'StyleSheet'; type OnLoadEvent = SyntheticEvent< $ReadOnly<{| @@ -37,8 +31,23 @@ type OnLoadEvent = SyntheticEvent< >; type IOSImageProps = $ReadOnly<{| + /** + * A static image to display while loading the image source. + * + * See https://facebook.github.io/react-native/docs/image.html#defaultsource + */ defaultSource?: ?ImageSource, + /** + * Invoked when a partial load of the image is complete. + * + * See https://facebook.github.io/react-native/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 + */ onProgress?: ?( event: SyntheticEvent<$ReadOnly<{|loaded: number, total: number|}>>, ) => void, @@ -51,142 +60,111 @@ type AndroidImageProps = $ReadOnly<{| |}>; export type ImageProps = {| - ...ViewProps, + ...$Diff>, ...IOSImageProps, ...AndroidImageProps, - blurRadius?: number, - capInsets?: ?EdgeInsetsProp, - onError?: ?(event: SyntheticEvent<$ReadOnly<{||}>>) => void, - onLoad?: ?(event: OnLoadEvent) => void, - onLoadEnd?: ?() => void, - onLoadStart?: ?() => void, - resizeMethod?: ?('auto' | 'resize' | 'scale'), - source?: ?ImageSource, - style?: ImageStyleProp, - - // Can be set via props or style, for now - height?: DimensionValue, - width?: DimensionValue, - resizeMode?: ?('cover' | 'contain' | 'stretch' | 'repeat' | 'center'), - - src?: empty, - children?: empty, -|}; - -module.exports = { - /** - * See https://facebook.github.io/react-native/docs/image.html#style - */ - style: StyleSheetPropType(ImageStylePropTypes), - /** - * The image source (either a remote URL or a local file resource). - * - * See https://facebook.github.io/react-native/docs/image.html#source - */ - source: ImageSourcePropType, - /** - * A static image to display while loading the image source. - * - * See https://facebook.github.io/react-native/docs/image.html#defaultsource - */ - defaultSource: PropTypes.oneOfType([ - PropTypes.shape({ - uri: PropTypes.string, - width: PropTypes.number, - height: PropTypes.number, - scale: PropTypes.number, - }), - PropTypes.number, - ]), /** * When true, indicates the image is an accessibility element. * * See https://facebook.github.io/react-native/docs/image.html#accessible */ - accessible: PropTypes.bool, + accessible?: ?boolean, + /** * 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 */ - accessibilityLabel: PropTypes.node, + 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 */ - blurRadius: PropTypes.number, + blurRadius?: ?number, + /** * See https://facebook.github.io/react-native/docs/image.html#capinsets */ - capInsets: EdgeInsetsPropType, + capInsets?: ?EdgeInsetsProp, + /** - * See https://facebook.github.io/react-native/docs/image.html#resizemethod + * Invoked on load error with `{nativeEvent: {error}}`. + * + * See https://facebook.github.io/react-native/docs/image.html#onerror */ - resizeMethod: PropTypes.oneOf(['auto', 'resize', 'scale']), + onError?: ?(event: SyntheticEvent<$ReadOnly<{||}>>) => void, + /** - * Determines how to resize the image when the frame doesn't match the raw - * image dimensions. + * Invoked on mount and layout changes with + * `{nativeEvent: {layout: {x, y, width, height}}}`. * - * See https://facebook.github.io/react-native/docs/image.html#resizemode + * See https://facebook.github.io/react-native/docs/image.html#onlayout */ - resizeMode: PropTypes.oneOf([ - 'cover', - 'contain', - 'stretch', - 'repeat', - 'center', - ]), + + onLayout?: ?(event: LayoutEvent) => mixed, + /** - * A unique identifier for this element to be used in UI Automation - * testing scripts. + * Invoked when load completes successfully. * - * See https://facebook.github.io/react-native/docs/image.html#testid + * See https://facebook.github.io/react-native/docs/image.html#onload */ - testID: PropTypes.string, + onLoad?: ?(event: OnLoadEvent) => void, + /** - * Invoked on mount and layout changes with - * `{nativeEvent: {layout: {x, y, width, height}}}`. + * Invoked when load either succeeds or fails. * - * See https://facebook.github.io/react-native/docs/image.html#onlayout + * See https://facebook.github.io/react-native/docs/image.html#onloadend */ - onLayout: PropTypes.func, + onLoadEnd?: ?() => void, + /** * Invoked on load start. * * See https://facebook.github.io/react-native/docs/image.html#onloadstart */ - onLoadStart: PropTypes.func, + onLoadStart?: ?() => void, + /** - * Invoked on download progress with `{nativeEvent: {loaded, total}}`. - * - * See https://facebook.github.io/react-native/docs/image.html#onprogress + * See https://facebook.github.io/react-native/docs/image.html#resizemethod */ - onProgress: PropTypes.func, + resizeMethod?: ?('auto' | 'resize' | 'scale'), + /** - * Invoked on load error with `{nativeEvent: {error}}`. + * The image source (either a remote URL or a local file resource). * - * See https://facebook.github.io/react-native/docs/image.html#onerror + * See https://facebook.github.io/react-native/docs/image.html#source */ - onError: PropTypes.func, + source?: ?ImageSource, + /** - * Invoked when a partial load of the image is complete. - * - * See https://facebook.github.io/react-native/docs/image.html#onpartialload + * See https://facebook.github.io/react-native/docs/image.html#style */ - onPartialLoad: PropTypes.func, + style?: ?ImageStyleProp, + + // Can be set via props or style, for now + height?: ?DimensionValue, + width?: ?DimensionValue, + /** - * Invoked when load completes successfully. + * 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#onload + * See https://facebook.github.io/react-native/docs/image.html#resizemode */ - onLoad: PropTypes.func, + resizeMode?: ?('cover' | 'contain' | 'stretch' | 'repeat' | 'center'), + /** - * Invoked when load either succeeds or fails. + * A unique identifier for this element to be used in UI Automation + * testing scripts. * - * See https://facebook.github.io/react-native/docs/image.html#onloadend + * See https://facebook.github.io/react-native/docs/image.html#testid */ - onLoadEnd: PropTypes.func, -}; + testID?: ?string, + + src?: empty, + children?: empty, +|}; diff --git a/Libraries/Image/ImageResizeMode.js b/Libraries/Image/ImageResizeMode.js index 48779e383f3119..1dad3309b1588d 100644 --- a/Libraries/Image/ImageResizeMode.js +++ b/Libraries/Image/ImageResizeMode.js @@ -1,52 +1,36 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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 + * @flow strict * @format */ -'use strict'; -/* $FlowFixMe(>=0.54.0 site=react_native_oss) This comment suppresses an error - * found when Flow v0.54 was deployed. To see the error delete this comment and - * run Flow. */ -const keyMirror = require('fbjs/lib/keyMirror'); +'use strict'; /** - * ImageResizeMode - Enum for different image resizing modes, set via - * `resizeMode` style property on `` components. + * ImageResizeMode defines valid values for different image resizing modes set + * via the `resizeMode` style property on ``. */ -const ImageResizeMode = keyMirror({ - /** - * contain - The image will be resized such that it will be completely - * visible, contained within the frame of the View. - */ - contain: null, - /** - * cover - The image will be resized such that the entire area of the view - * is covered by the image, potentially clipping parts of the image. - */ - cover: null, - /** - * stretch - The image will be stretched to fill the entire frame of the - * view without clipping. This may change the aspect ratio of the image, - * distorting it. - */ - stretch: null, - /** - * center - The image will be scaled down such that it is completely visible, - * if bigger than the area of the view. - * The image will not be scaled up. - */ - center: null, +export type ImageResizeMode = + // Resize by scaling down such that it is completely visible, if bigger than + // the area of the view. The image will not be scaled up. + | 'center' + + // Resize such that it will be completely visible, contained within the frame + // of the View. + | 'contain' + + // Resize such that the entire area of the view is covered by the image, + // potentially clipping parts of the image. + | 'cover' - /** - * repeat - The image will be repeated to cover the frame of the View. The - * image will keep it's size and aspect ratio. - */ - repeat: null, -}); + // Resize by repeating to cover the frame of the View. The image will keep its + // size and aspect ratio. + | 'repeat' -module.exports = ImageResizeMode; + // Resize by stretching it to fill the entire frame of the view without + // clipping. This may change the aspect ratio of the image, distorting it. + | 'stretch'; diff --git a/Libraries/Image/ImageSource.js b/Libraries/Image/ImageSource.js index 5c3c84df901209..0e03dc78c0f5d1 100644 --- a/Libraries/Image/ImageSource.js +++ b/Libraries/Image/ImageSource.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -14,15 +14,73 @@ // that might have more keys. This also has to be inexact to support taking // instances of classes like FBIcon. // https://fburl.com/8lynhvtw -type ImageURISource = $ReadOnly<{ +export type ImageURISource = $ReadOnly<{ + /** + * `uri` is a string representing the resource identifier for the image, which + * could be an http address, a local file path, or the name of a static image + * resource (which should be wrapped in the `require('./path/to/image.png')` + * function). + */ uri?: ?string, + + /** + * `bundle` is the iOS asset bundle which the image is included in. This + * will default to [NSBundle mainBundle] if not set. + * @platform ios + */ bundle?: ?string, + + /** + * `method` is the HTTP Method to use. Defaults to GET if not specified. + */ method?: ?string, + + /** + * `headers` is an object representing the HTTP headers to send along with the + * request for a remote image. + */ headers?: ?Object, + + /** + * `body` is the HTTP body to send with the request. This must be a valid + * UTF-8 string, and will be sent exactly as specified, with no + * additional encoding (e.g. URL-escaping or base64) applied. + */ body?: ?string, + + /** + * `cache` determines how the requests handles potentially cached + * responses. + * + * - `default`: Use the native platforms default strategy. `useProtocolCachePolicy` on iOS. + * + * - `reload`: The data for the URL will be loaded from the originating source. + * No existing cache data should be used to satisfy a URL load request. + * + * - `force-cache`: The existing cached data will be used to satisfy the request, + * regardless of its age or expiration date. If there is no existing data in the cache + * corresponding the request, the data is loaded from the originating source. + * + * - `only-if-cached`: The existing cache data will be used to satisfy a request, regardless of + * its age or expiration date. If there is no existing data in the cache corresponding + * to a URL load request, no attempt is made to load the data from the originating source, + * and the load is considered to have failed. + * + * @platform ios + */ cache?: ?('default' | 'reload' | 'force-cache' | 'only-if-cached'), + + /** + * `width` and `height` can be specified if known at build time, in which case + * these will be used to set the default `` component dimensions. + */ width?: ?number, height?: ?number, + + /** + * `scale` is used to indicate the scale factor of the image. Defaults to 1.0 if + * unspecified, meaning that one image pixel equates to one display point / DIP. + */ scale?: ?number, }>; diff --git a/Libraries/Image/ImageSourcePropType.js b/Libraries/Image/ImageSourcePropType.js deleted file mode 100644 index 6f67113fe1bf18..00000000000000 --- a/Libraries/Image/ImageSourcePropType.js +++ /dev/null @@ -1,90 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @no-flow - * @format - */ -'use strict'; - -const PropTypes = require('prop-types'); - -const ImageURISourcePropType = PropTypes.shape({ - /** - * `uri` is a string representing the resource identifier for the image, which - * could be an http address, a local file path, or the name of a static image - * resource (which should be wrapped in the `require('./path/to/image.png')` - * function). - */ - uri: PropTypes.string, - /** - * `bundle` is the iOS asset bundle which the image is included in. This - * will default to [NSBundle mainBundle] if not set. - * @platform ios - */ - bundle: PropTypes.string, - /** - * `method` is the HTTP Method to use. Defaults to GET if not specified. - */ - method: PropTypes.string, - /** - * `headers` is an object representing the HTTP headers to send along with the - * request for a remote image. - */ - headers: PropTypes.objectOf(PropTypes.string), - /** - * `body` is the HTTP body to send with the request. This must be a valid - * UTF-8 string, and will be sent exactly as specified, with no - * additional encoding (e.g. URL-escaping or base64) applied. - */ - body: PropTypes.string, - /** - * `cache` determines how the requests handles potentially cached - * responses. - * - * - `default`: Use the native platforms default strategy. `useProtocolCachePolicy` on iOS. - * - * - `reload`: The data for the URL will be loaded from the originating source. - * No existing cache data should be used to satisfy a URL load request. - * - * - `force-cache`: The existing cached data will be used to satisfy the request, - * regardless of its age or expiration date. If there is no existing data in the cache - * corresponding the request, the data is loaded from the originating source. - * - * - `only-if-cached`: The existing cache data will be used to satisfy a request, regardless of - * its age or expiration date. If there is no existing data in the cache corresponding - * to a URL load request, no attempt is made to load the data from the originating source, - * and the load is considered to have failed. - * - * @platform ios - */ - cache: PropTypes.oneOf([ - 'default', - 'reload', - 'force-cache', - 'only-if-cached', - ]), - /** - * `width` and `height` can be specified if known at build time, in which case - * these will be used to set the default `` component dimensions. - */ - width: PropTypes.number, - height: PropTypes.number, - /** - * `scale` is used to indicate the scale factor of the image. Defaults to 1.0 if - * unspecified, meaning that one image pixel equates to one display point / DIP. - */ - scale: PropTypes.number, -}); - -const ImageSourcePropType = PropTypes.oneOfType([ - ImageURISourcePropType, - // Opaque type returned by require('./image.jpg') - PropTypes.number, - // Multiple sources - PropTypes.arrayOf(ImageURISourcePropType), -]); - -module.exports = ImageSourcePropType; diff --git a/Libraries/Image/ImageStore.js b/Libraries/Image/ImageStore.js index 5373020376a5f1..60273b79f201f2 100644 --- a/Libraries/Image/ImageStore.js +++ b/Libraries/Image/ImageStore.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Image/ImageViewNativeComponent.js b/Libraries/Image/ImageViewNativeComponent.js new file mode 100644 index 00000000000000..47f8d531f756d8 --- /dev/null +++ b/Libraries/Image/ImageViewNativeComponent.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 + */ + +'use strict'; + +const requireNativeComponent = require('requireNativeComponent'); + +const ImageViewNativeComponent = requireNativeComponent('RCTImageView'); + +module.exports = ImageViewNativeComponent; diff --git a/Libraries/Image/RCTGIFImageDecoder.h b/Libraries/Image/RCTGIFImageDecoder.h index 1f942aef4c8ce6..f9cc0eef4ebf94 100644 --- a/Libraries/Image/RCTGIFImageDecoder.h +++ b/Libraries/Image/RCTGIFImageDecoder.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Image/RCTGIFImageDecoder.m b/Libraries/Image/RCTGIFImageDecoder.m index 48ca8aefcf74b4..322d137cda733c 100644 --- a/Libraries/Image/RCTGIFImageDecoder.m +++ b/Libraries/Image/RCTGIFImageDecoder.m @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Image/RCTImageBlurUtils.h b/Libraries/Image/RCTImageBlurUtils.h index 44df37441af92a..2ec7b358d240ee 100644 --- a/Libraries/Image/RCTImageBlurUtils.h +++ b/Libraries/Image/RCTImageBlurUtils.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-present, Facebook, Inc. + * 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. diff --git a/Libraries/Image/RCTImageBlurUtils.m b/Libraries/Image/RCTImageBlurUtils.m index 84c90019bfbcc9..8ee3282de4de4e 100644 --- a/Libraries/Image/RCTImageBlurUtils.m +++ b/Libraries/Image/RCTImageBlurUtils.m @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -35,6 +35,12 @@ size_t bytes = buffer1.rowBytes * buffer1.height; buffer1.data = malloc(bytes); buffer2.data = malloc(bytes); + if (!buffer1.data || !buffer2.data) { + // CWE - 391 : Unchecked error condition + // https://www.cvedetails.com/cwe-details/391/Unchecked-Error-Condition.html + // https://eli.thegreenplace.net/2009/10/30/handling-out-of-memory-conditions-in-c + abort(); + } // A description of how to compute the box kernel width from the Gaussian // radius (aka standard deviation) appears in the SVG spec: @@ -45,6 +51,12 @@ //create temp buffer void *tempBuffer = malloc((size_t)vImageBoxConvolve_ARGB8888(&buffer1, &buffer2, NULL, 0, 0, boxSize, boxSize, NULL, kvImageEdgeExtend + kvImageGetTempBufferSize)); + if (!tempBuffer) { + // CWE - 391 : Unchecked error condition + // https://www.cvedetails.com/cwe-details/391/Unchecked-Error-Condition.html + // https://eli.thegreenplace.net/2009/10/30/handling-out-of-memory-conditions-in-c + abort(); + } //copy image data CFDataRef dataSource = CGDataProviderCopyData(CGImageGetDataProvider(imageRef)); diff --git a/Libraries/Image/RCTImageCache.h b/Libraries/Image/RCTImageCache.h index c0d24ad25a2d41..b7acc1126ca6cd 100644 --- a/Libraries/Image/RCTImageCache.h +++ b/Libraries/Image/RCTImageCache.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Image/RCTImageCache.m b/Libraries/Image/RCTImageCache.m index 4d4803c4ab08e0..1c864f5056e894 100644 --- a/Libraries/Image/RCTImageCache.m +++ b/Libraries/Image/RCTImageCache.m @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Image/RCTImageEditingManager.h b/Libraries/Image/RCTImageEditingManager.h index dda409af33fc22..684855f999e3b1 100644 --- a/Libraries/Image/RCTImageEditingManager.h +++ b/Libraries/Image/RCTImageEditingManager.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Image/RCTImageEditingManager.m b/Libraries/Image/RCTImageEditingManager.m index 2c8330ee9a302b..eb87df96fa77b5 100644 --- a/Libraries/Image/RCTImageEditingManager.m +++ b/Libraries/Image/RCTImageEditingManager.m @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Image/RCTImageLoader.h b/Libraries/Image/RCTImageLoader.h index a0c6e798a8a960..30d472d52dd783 100644 --- a/Libraries/Image/RCTImageLoader.h +++ b/Libraries/Image/RCTImageLoader.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -129,6 +129,14 @@ typedef dispatch_block_t RCTImageLoaderCancellationBlock; */ - (RCTImageLoaderCancellationBlock)getImageSizeForURLRequest:(NSURLRequest *)imageURLRequest block:(void(^)(NSError *error, CGSize size))completionBlock; +/** + * Determines whether given image URLs are cached locally. The `requests` array is expected + * to contain objects convertible to NSURLRequest. The return value maps URLs to strings: + * "disk" for images known to be cached in non-volatile storage, "memory" for images known + * to be cached in memory. Dictionary items corresponding to images that are not known to be + * cached are simply missing. + */ +- (NSDictionary *)getImageCacheStatus:(NSArray *)requests; /** * Allows developers to set their own caching implementation for diff --git a/Libraries/Image/RCTImageLoader.m b/Libraries/Image/RCTImageLoader.m index 775e53e95f7a08..035bc3535f18c4 100644 --- a/Libraries/Image/RCTImageLoader.m +++ b/Libraries/Image/RCTImageLoader.m @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -779,45 +779,69 @@ - (RCTImageLoaderCancellationBlock)getImageSizeForURLRequest:(NSURLRequest *)ima completionBlock:completion]; } -#pragma mark - RCTURLRequestHandler - -- (BOOL)canHandleRequest:(NSURLRequest *)request +- (NSDictionary *)getImageCacheStatus:(NSArray *)requests { - NSURL *requestURL = request.URL; - - // If the data being loaded is a video, return NO - // Even better may be to implement this on the RCTImageURLLoader that would try to load it, - // but we'd have to run the logic both in RCTPhotoLibraryImageLoader and - // RCTAssetsLibraryRequestHandler. Once we drop iOS7 though, we'd drop - // RCTAssetsLibraryRequestHandler and can move it there. - static NSRegularExpression *videoRegex = nil; - if (!videoRegex) { - NSError *error = nil; - videoRegex = [NSRegularExpression regularExpressionWithPattern:@"(?:&|^)ext=MOV(?:&|$)" - options:NSRegularExpressionCaseInsensitive - error:&error]; - if (error) { - RCTLogError(@"%@", error); + NSMutableDictionary *results = [NSMutableDictionary dictionary]; + for (id request in requests) { + NSURLRequest *urlRequest = [RCTConvert NSURLRequest:request]; + if (urlRequest) { + NSCachedURLResponse *cachedResponse = [NSURLCache.sharedURLCache cachedResponseForRequest:urlRequest]; + if (cachedResponse) { + if (cachedResponse.storagePolicy == NSURLCacheStorageAllowedInMemoryOnly) { + [results setObject:@"memory" forKey:urlRequest.URL.absoluteString]; + } else { + [results setObject:@"disk" forKey:urlRequest.URL.absoluteString]; + } } } + } + return results; +} - NSString *query = requestURL.query; - if (query != nil && [videoRegex firstMatchInString:query - options:0 - range:NSMakeRange(0, query.length)]) { - return NO; - } +#pragma mark - RCTURLRequestHandler - for (id loader in _loaders) { - // Don't use RCTImageURLLoader protocol for modules that already conform to - // RCTURLRequestHandler as it's inefficient to decode an image and then - // convert it back into data - if (![loader conformsToProtocol:@protocol(RCTURLRequestHandler)] && - [loader canLoadImageURL:requestURL]) { - return YES; - } +- (BOOL)canHandleRequest:(NSURLRequest *)request +{ + NSURL *requestURL = request.URL; + + // If the data being loaded is a video, return NO + // Even better may be to implement this on the RCTImageURLLoader that would try to load it, + // but we'd have to run the logic both in RCTPhotoLibraryImageLoader and + // RCTAssetsLibraryRequestHandler. Once we drop iOS7 though, we'd drop + // RCTAssetsLibraryRequestHandler and can move it there. + static NSRegularExpression *videoRegex; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + NSError *error = nil; + videoRegex = [NSRegularExpression regularExpressionWithPattern:@"(?:&|^)ext=MOV(?:&|$)" + options:NSRegularExpressionCaseInsensitive + error:&error]; + if (error) { + RCTLogError(@"%@", error); } + }); + + NSString *query = requestURL.query; + if ( + query != nil && + [videoRegex firstMatchInString:query + options:0 + range:NSMakeRange(0, query.length)] + ) { return NO; + } + + for (id loader in _loaders) { + // Don't use RCTImageURLLoader protocol for modules that already conform to + // RCTURLRequestHandler as it's inefficient to decode an image and then + // convert it back into data + if (![loader conformsToProtocol:@protocol(RCTURLRequestHandler)] && + [loader canLoadImageURL:requestURL]) { + return YES; + } + } + + return NO; } - (id)sendRequest:(NSURLRequest *)request withDelegate:(id)delegate diff --git a/Libraries/Image/RCTImageShadowView.h b/Libraries/Image/RCTImageShadowView.h index 168f0f4c1de86d..f79281e731ad99 100644 --- a/Libraries/Image/RCTImageShadowView.h +++ b/Libraries/Image/RCTImageShadowView.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Image/RCTImageShadowView.m b/Libraries/Image/RCTImageShadowView.m index c9ba82e32188cc..9102dc1b3b0b73 100644 --- a/Libraries/Image/RCTImageShadowView.m +++ b/Libraries/Image/RCTImageShadowView.m @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Image/RCTImageStoreManager.h b/Libraries/Image/RCTImageStoreManager.h index 3f070ada1d27be..b1969044524ec5 100644 --- a/Libraries/Image/RCTImageStoreManager.h +++ b/Libraries/Image/RCTImageStoreManager.h @@ -1,4 +1,4 @@ -// Copyright (c) 2004-present, Facebook, Inc. +// 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. diff --git a/Libraries/Image/RCTImageStoreManager.m b/Libraries/Image/RCTImageStoreManager.m index 443885becfff2e..03656e4ea3312d 100644 --- a/Libraries/Image/RCTImageStoreManager.m +++ b/Libraries/Image/RCTImageStoreManager.m @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Image/RCTImageUtils.h b/Libraries/Image/RCTImageUtils.h index d6090ac67ffb48..a4b8216c401dc2 100644 --- a/Libraries/Image/RCTImageUtils.h +++ b/Libraries/Image/RCTImageUtils.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-present, Facebook, Inc. + * 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. diff --git a/Libraries/Image/RCTImageUtils.m b/Libraries/Image/RCTImageUtils.m index 52fe3893307307..5470c8f782895a 100644 --- a/Libraries/Image/RCTImageUtils.m +++ b/Libraries/Image/RCTImageUtils.m @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Image/RCTImageView.h b/Libraries/Image/RCTImageView.h index 70357c359b142e..38f82db455d12b 100644 --- a/Libraries/Image/RCTImageView.h +++ b/Libraries/Image/RCTImageView.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Image/RCTImageView.m b/Libraries/Image/RCTImageView.m index a754bb1078dc3b..3392a54c56ed47 100644 --- a/Libraries/Image/RCTImageView.m +++ b/Libraries/Image/RCTImageView.m @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Image/RCTImageViewManager.h b/Libraries/Image/RCTImageViewManager.h index f718a70246ef41..9aef96cd72a957 100644 --- a/Libraries/Image/RCTImageViewManager.h +++ b/Libraries/Image/RCTImageViewManager.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Image/RCTImageViewManager.m b/Libraries/Image/RCTImageViewManager.m index bd382e4bf191d0..70c5cb98cd52ad 100644 --- a/Libraries/Image/RCTImageViewManager.m +++ b/Libraries/Image/RCTImageViewManager.m @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -82,4 +82,11 @@ - (UIView *)view }]; } +RCT_EXPORT_METHOD(queryCache:(NSArray *)requests + resolve:(RCTPromiseResolveBlock)resolve + reject:(RCTPromiseRejectBlock)reject) +{ + resolve([self.bridge.imageLoader getImageCacheStatus:requests]); +} + @end diff --git a/Libraries/Image/RCTLocalAssetImageLoader.h b/Libraries/Image/RCTLocalAssetImageLoader.h index 4cd79bd403c5a2..df3918ad548c1a 100644 --- a/Libraries/Image/RCTLocalAssetImageLoader.h +++ b/Libraries/Image/RCTLocalAssetImageLoader.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Image/RCTLocalAssetImageLoader.m b/Libraries/Image/RCTLocalAssetImageLoader.m index 091cd70e0eafef..68407f38064ab0 100644 --- a/Libraries/Image/RCTLocalAssetImageLoader.m +++ b/Libraries/Image/RCTLocalAssetImageLoader.m @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Image/RCTResizeMode.h b/Libraries/Image/RCTResizeMode.h index ce0fba5e31afad..9d49f2d32cfeb9 100644 --- a/Libraries/Image/RCTResizeMode.h +++ b/Libraries/Image/RCTResizeMode.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Image/RCTResizeMode.m b/Libraries/Image/RCTResizeMode.m index 1094b7ff96e8c9..34027f8e8a2ec0 100644 --- a/Libraries/Image/RCTResizeMode.m +++ b/Libraries/Image/RCTResizeMode.m @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Image/RelativeImageStub.js b/Libraries/Image/RelativeImageStub.js index dcdeb9b916ac45..f5592d18167102 100644 --- a/Libraries/Image/RelativeImageStub.js +++ b/Libraries/Image/RelativeImageStub.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Image/TextInlineImageNativeComponent.js b/Libraries/Image/TextInlineImageNativeComponent.js new file mode 100644 index 00000000000000..6cbe56362576f9 --- /dev/null +++ b/Libraries/Image/TextInlineImageNativeComponent.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 + */ + +'use strict'; + +const requireNativeComponent = require('requireNativeComponent'); + +const TextInlineImage = requireNativeComponent('RCTTextInlineImage'); + +module.exports = TextInlineImage; diff --git a/Libraries/Image/__tests__/assetRelativePathInSnapshot.js b/Libraries/Image/__tests__/assetRelativePathInSnapshot.js index 973d7171c0cd56..13cb6ac075f81e 100644 --- a/Libraries/Image/__tests__/assetRelativePathInSnapshot.js +++ b/Libraries/Image/__tests__/assetRelativePathInSnapshot.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2017-present, Facebook, Inc. + * 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. diff --git a/Libraries/Image/__tests__/resolveAssetSource-test.js b/Libraries/Image/__tests__/resolveAssetSource-test.js index c22f32a6520413..fb297899f6655a 100644 --- a/Libraries/Image/__tests__/resolveAssetSource-test.js +++ b/Libraries/Image/__tests__/resolveAssetSource-test.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Image/nativeImageSource.js b/Libraries/Image/nativeImageSource.js index 1fdbe1caa97615..3acf36f0bd8519 100644 --- a/Libraries/Image/nativeImageSource.js +++ b/Libraries/Image/nativeImageSource.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Image/resolveAssetSource.js b/Libraries/Image/resolveAssetSource.js index 9c811e574400b1..ebd19e3354fe6e 100644 --- a/Libraries/Image/resolveAssetSource.js +++ b/Libraries/Image/resolveAssetSource.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. diff --git a/Libraries/Inspector/BorderBox.js b/Libraries/Inspector/BorderBox.js index b172871df8e2f2..93d0dd158e14d1 100644 --- a/Libraries/Inspector/BorderBox.js +++ b/Libraries/Inspector/BorderBox.js @@ -1,11 +1,11 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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 + * @flow strict-local */ 'use strict'; diff --git a/Libraries/Inspector/BoxInspector.js b/Libraries/Inspector/BoxInspector.js index af373460053609..05b0580c635b2a 100644 --- a/Libraries/Inspector/BoxInspector.js +++ b/Libraries/Inspector/BoxInspector.js @@ -1,11 +1,11 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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 + * @flow strict-local */ 'use strict'; diff --git a/Libraries/Inspector/ElementBox.js b/Libraries/Inspector/ElementBox.js index dea05dad737894..d360485bcbe5f5 100644 --- a/Libraries/Inspector/ElementBox.js +++ b/Libraries/Inspector/ElementBox.js @@ -1,11 +1,11 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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 + * @flow strict-local */ 'use strict'; diff --git a/Libraries/Inspector/ElementProperties.js b/Libraries/Inspector/ElementProperties.js index 1e360944716fd2..9b6c222ed5babd 100644 --- a/Libraries/Inspector/ElementProperties.js +++ b/Libraries/Inspector/ElementProperties.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -11,7 +11,6 @@ 'use strict'; const BoxInspector = require('BoxInspector'); -const PropTypes = require('prop-types'); const React = require('React'); const StyleInspector = require('StyleInspector'); const StyleSheet = require('StyleSheet'); @@ -24,32 +23,23 @@ const flattenStyle = require('flattenStyle'); const mapWithSeparator = require('mapWithSeparator'); const openFileInEditor = require('openFileInEditor'); -import type {DangerouslyImpreciseStyleProp} from 'StyleSheet'; +import type {ViewStyleProp} from 'StyleSheet'; -class ElementProperties extends React.Component<{ - hierarchy: Array<$FlowFixMe>, - style?: DangerouslyImpreciseStyleProp, - source?: { +type Props = $ReadOnly<{| + hierarchy: Array<{|name: string|}>, + style?: ?ViewStyleProp, + source?: ?{ fileName?: string, lineNumber?: number, }, -}> { - static propTypes = { - hierarchy: PropTypes.array.isRequired, - style: PropTypes.oneOfType([ - PropTypes.object, - PropTypes.array, - PropTypes.number, - ]), - source: PropTypes.shape({ - fileName: PropTypes.string, - lineNumber: PropTypes.number, - }), - }; + frame?: ?Object, + selection?: ?number, + setSelection?: number => mixed, +|}>; +class ElementProperties extends React.Component { render() { const style = flattenStyle(this.props.style); - // $FlowFixMe found when converting React.createClass to ES6 const selection = this.props.selection; let openFileButton; const source = this.props.source; @@ -96,10 +86,7 @@ class ElementProperties extends React.Component<{ {openFileButton} - { - // $FlowFixMe found when converting React.createClass to ES6 - - } + {} diff --git a/Libraries/Inspector/Inspector.js b/Libraries/Inspector/Inspector.js index a5ab122b0cde5b..86d519258b62ed 100644 --- a/Libraries/Inspector/Inspector.js +++ b/Libraries/Inspector/Inspector.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -21,10 +21,6 @@ const Touchable = require('Touchable'); const UIManager = require('UIManager'); const View = require('View'); -/* $FlowFixMe(>=0.54.0 site=react_native_oss) This comment suppresses an error - * found when Flow v0.54 was deployed. To see the error delete this comment and - * run Flow. */ -const emptyObject = require('fbjs/lib/emptyObject'); const invariant = require('fbjs/lib/invariant'); export type ReactRenderer = { @@ -131,7 +127,7 @@ class Inspector extends React.Component< hierarchy: [], inspected: { frame: {left, top, width, height}, - style: props ? props.style : emptyObject, + style: props ? props.style : {}, }, }); }); diff --git a/Libraries/Inspector/InspectorOverlay.js b/Libraries/Inspector/InspectorOverlay.js index 4de9cb2ab8183e..79e2156111c1e2 100644 --- a/Libraries/Inspector/InspectorOverlay.js +++ b/Libraries/Inspector/InspectorOverlay.js @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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. @@ -12,33 +12,29 @@ const Dimensions = require('Dimensions'); const ElementBox = require('ElementBox'); -const PropTypes = require('prop-types'); const React = require('React'); const StyleSheet = require('StyleSheet'); const UIManager = require('UIManager'); const View = require('View'); +import type {ViewStyleProp} from 'StyleSheet'; + type EventLike = { nativeEvent: Object, }; -class InspectorOverlay extends React.Component<{ - inspected?: { - frame?: Object, - style?: any, - }, - inspectedViewTag?: number, - onTouchViewTag: (tag: number, frame: Object, pointerY: number) => void, -}> { - static propTypes = { - inspected: PropTypes.shape({ - frame: PropTypes.object, - style: PropTypes.any, - }), - inspectedViewTag: PropTypes.number, - onTouchViewTag: PropTypes.func.isRequired, - }; +type Inspected = $ReadOnly<{| + frame?: Object, + style?: ViewStyleProp, +|}>; + +type Props = $ReadOnly<{| + inspected?: Inspected, + inspectedViewTag?: ?number, + onTouchViewTag: (tag: number, frame: Object, pointerY: number) => mixed, +|}>; +class InspectorOverlay extends React.Component { findViewForTouchEvent = (e: EventLike) => { const {locationX, locationY} = e.nativeEvent.touches[0]; UIManager.findSubviewIn( diff --git a/Libraries/Inspector/InspectorPanel.js b/Libraries/Inspector/InspectorPanel.js index 2793452d90e578..42c191d7ed530c 100644 --- a/Libraries/Inspector/InspectorPanel.js +++ b/Libraries/Inspector/InspectorPanel.js @@ -1,11 +1,11 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * 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 + * @flow strict-local */ 'use strict'; @@ -14,14 +14,43 @@ const ElementProperties = require('ElementProperties'); const NetworkOverlay = require('NetworkOverlay'); const PerformanceOverlay = require('PerformanceOverlay'); const React = require('React'); -const PropTypes = require('prop-types'); const ScrollView = require('ScrollView'); const StyleSheet = require('StyleSheet'); const Text = require('Text'); const TouchableHighlight = require('TouchableHighlight'); const View = require('View'); -class InspectorPanel extends React.Component<$FlowFixMeProps> { +import type {ViewStyleProp} from 'StyleSheet'; + +type Props = $ReadOnly<{| + devtoolsIsOpen: boolean, + inspecting: boolean, + setInspecting: (val: boolean) => void, + perfing: boolean, + setPerfing: (val: boolean) => void, + touchTargeting: boolean, + setTouchTargeting: (val: boolean) => void, + networking: boolean, + setNetworking: (val: boolean) => void, + hierarchy?: ?Array<{|name: string|}>, + selection?: ?number, + setSelection: number => mixed, + inspected?: ?$ReadOnly<{| + style?: ?ViewStyleProp, + frame?: ?$ReadOnly<{| + top?: ?number, + left?: ?number, + width?: ?number, + height: ?number, + |}>, + source?: ?{| + fileName?: string, + lineNumber?: number, + |}, + |}>, +|}>; + +class InspectorPanel extends React.Component { renderWaiting() { if (this.props.inspecting) { return ( @@ -40,6 +69,7 @@ class InspectorPanel extends React.Component<$FlowFixMeProps> { style={this.props.inspected.style} frame={this.props.inspected.frame} source={this.props.inspected.source} + // $FlowFixMe: Hierarchy should be non-nullable hierarchy={this.props.hierarchy} selection={this.props.selection} setSelection={this.props.setSelection} @@ -57,22 +87,22 @@ class InspectorPanel extends React.Component<$FlowFixMeProps> { {!this.props.devtoolsIsOpen && contents} -