Compare commits

...
Author SHA1 Message Date
Mike Grabowski de9019295d [0.58.4] Bump version numbers 2019-02-06 17:45:47 +01:00
Mike Grabowski 6436157b85 Revert "[0.58.4] Bump version numbers"
This reverts commit 6c839455ba.
2019-02-06 17:44:54 +01:00
chrisnojima 5e875474ef fix incorrect type which makes animated gifs not loop forever on device (#22987)
Summary:
https://github.com/facebook/react-native/issues/22985

This 1 liner fixes the animation looping being broken on ios devices. The original source of the bug is here: https://github.com/facebook/react-native/commit/95ef882#diff-e57b12f931820d7e0949e5cbb2701dcfR35

We set the value to a special large float, and assign it to repeatCount which is also a float, so this should be a float.

Changelog:

[iOS] [Fixed] - Fix animated GIFs not looping forever
Pull Request resolved: https://github.com/facebook/react-native/pull/22987

Differential Revision: D13682645

Pulled By: hramos

fbshipit-source-id: 96b0602b418e3ebe369427a24777cd4374ac5d48
2019-02-06 17:43:11 +01:00
Mike Grabowski 0bb1ba8ad5 Two more paths 2019-02-06 17:26:30 +01:00
Mike Grabowski 4a572761fa Invalidade Gradle cache 2019-02-06 17:17:54 +01:00
cpojer 8bddcb6cb0 Backport fix from https://github.com/react-native-community/react-native-cli/pull/138 2019-02-06 10:14:38 +00:00
Christoph Nakazawa 98bcfe00fb Merge pull request #23293 from osunnarvik/parse_simulator_list
Parse simulator list
2019-02-05 15:41:38 +00:00
Ole-Kristian Sunnarvik 9a8c9596eb handles simulator where prefix is included 2019-02-05 13:56:57 +01:00
Mike Grabowski 6c839455ba [0.58.4] Bump version numbers 2019-02-04 17:52:41 +01:00
Jyrno Ader 2781ef0173 Android: Add error description to Image onError callback (#22737)
Summary:
fixes #19073

Changelog:
----------

[Android] [Fixed] - Add error description to Image onError callback
Pull Request resolved: https://github.com/facebook/react-native/pull/22737

Differential Revision: D13676224

Pulled By: hramos

fbshipit-source-id: 0dea7e97ae6517b8980ad02827f19d22cd3ef933
2019-02-04 17:52:22 +01:00
scisci c3bd3416e8 Fix Native Rotation Android (#18872)
Summary:
Fixes #14161
Android crashes in some cases if an animated transform config contains a string value, like a rotation.
This PR fixes that by ensuring all values sent to the native side are doubles. It adds `__transformDataType` to AnimatedTransform.js.

Added integration test `ReactAndroid/src/androidText/js/AnimatedTransformTestModule.js` This test fails with the following error `INSTRUMENTATION_RESULT: longMsg=java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Double`, if the changes to AnimatedTransform.js are reverted.

[Android] [Fixed] - Fixes Android crash on animated style with string rotation
Pull Request resolved: https://github.com/facebook/react-native/pull/18872

Differential Revision: D13894676

Pulled By: cpojer

fbshipit-source-id: 297e8132563460802e53f3ac551c3ba9ed943736
2019-02-04 17:51:20 +01:00
Dulmandakh e1694ee041 bump soloader to 0.6.0 (#23239)
Summary:
Bump soloader to 0.6.0, which added support for App Bundling and help reduce app size.

[Android] [Changed] - Bump Soloader to 0.6.0

CI is green and everything works just fine.
Pull Request resolved: https://github.com/facebook/react-native/pull/23239

Differential Revision: D13915901

Pulled By: cpojer

fbshipit-source-id: 917705326b76fc3356828e5d00e6148e292bd12a
2019-02-04 17:50:28 +01:00
Vladimir Timofeev 6943b2e495 Remove jest and jest-junit from runtime dependencies (#23276)
Summary:
Commit 06c13b3e06 pretend to update jest
to new version, but also adds jest and jest-junit to runtime dependencies
list (in addition to dev dependencies).

This commit fixes this, by removing jest and jest-junit from runtime
dependeincies.

As for motivation... story is short:
1. Updating RN 0.58.1 -> 0.58.3 I found that whole babel@6 infrastructure was returned to my `node_modules` (it is dangerous, because many tools like metro can found it and use it instead of babel@7).
2. It was because of this commit: 9d19ab0c0c that have 130 random files changed (and provides no meaning description).
But it points to: b864e7e63e (which also provides no meaning description, why it was reverted?)
And finally points to: 696bd89013, which was a "sync with master" commit. Ok. So it was from master.
3. Then I checked that jest still in runtime dependencies on master and fixed that. Also I hope this will be cherry picked into 0.58-stable.

[General] [Fixed] - Fix jest and jest-junit to be only development dependencies
Pull Request resolved: https://github.com/facebook/react-native/pull/23276

Differential Revision: D13941275

Pulled By: cpojer

fbshipit-source-id: a6f3377e670554b21f3ebd2f12d33e29d2969df1
2019-02-04 17:49:50 +01:00
Mike Grabowski adf1274955 [0.58.3] Bump version numbers 2019-01-28 19:22:29 +01:00
Le Xu 9e42e009ab Back out "[react-native][PR] [flow-strict] Flow strict StatusBar"
Summary:
Original commit changeset: 27f69c6df3a8

This reverts D13103971

Differential Revision: D13185679

fbshipit-source-id: 0de9da31bd75786c7978e2c3860486ac37420342
2019-01-28 19:20:50 +01:00
Mike Grabowski 6084cf1401 [0.58.2] Bump version numbers 2019-01-28 17:08:24 +01:00
Mike Grabowski 1add9b4f08 Update few files after syncing changes: 2019-01-28 15:08:34 +01:00
Mike Grabowski f8c484dfbf Update Flow config 2019-01-28 15:02:13 +01:00
Mike Grabowski 9d19ab0c0c Bring missing changes to 0.58-stable branch
This reverts commit b864e7e63e.
2019-01-28 14:56:57 +01:00
Mike Grabowski a289b7efb0 [0.58.1] Bump version numbers 2019-01-25 16:32:43 +01:00
Dulmandakh abf9b26040 fix packager start in 0.58 (#23160) 2019-01-25 16:21:15 +01:00
Mike Grabowski 57ad19758d [0.58.0] Bump version numbers 2019-01-24 21:01:54 +01:00
Dulmandakh 1d5fe77468 fix validate-android-test-env.sh (#22961)
Summary:
fix validate-android-test-env.sh to not parse .gradle files for build tools versions, because it was removed.

Changelog:
----------
[CI] [Changed] - fix validate-android-test-env.sh to not try parse .gradle files
Pull Request resolved: https://github.com/facebook/react-native/pull/22961

Differential Revision: D13655750

Pulled By: hramos

fbshipit-source-id: 1accb6ac7a7c74ab335dd92977b0b090820a622c
2019-01-24 16:08:13 +01:00
Héctor Ramos d811d38823 Bump to Android Build Tools 28.0.3, Gradle 4.10.2, Gradle Plugin 3.2.1
Summary: Bump Android Build Tools to Version 28.0.3, Gradle to 4.10.2, and the Android Gradle Plugin to 3.2.1.

Reviewed By: mdvacca

Differential Revision: D13631120

fbshipit-source-id: 709aa25a7a8e1ff0bfc0a969ba6e7cd92850bc0f
2019-01-24 12:57:54 +01:00
Vladimir Timofeev 23cfa29ac7 Fix tests in template project (0.58-stable) (#23128)
* Restore __tests__ folder in HelloWorld template

PR #18019 Removed __tests__ and __fixtures__ folders from npm package.
But it also effectively removed __tests__ folder from initial project
template. This commit restores __tests__ in template application.

It applicable only to 0.58-stable branch because in master, templates
was moved to another location. I think we should recheck what is ignored
in master after this landed.

* Use babel.config.js in template HelloWorld application

* Add babel-core@^7.0.0-bridge.0 to jest dependencies when react-native init new project. This should fix tests with babel7.
2019-01-23 19:00:39 +01:00
Louis Lagrange 26793a052a Add HTTP cache by default (like iOS) (#18348)
Summary:
<!--
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.

You can learn more about contributing to React Native here: http://facebook.github.io/react-native/docs/contributing.html

Happy contributing!

-->

On iOS, the cache is enabled by default but it's not the case on Android. This PR adds 10Mo of HTTP cache by default. 10Mo was chosen arbitrarily.

Fixes #16795

<!--(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!)-->

I wrote it so there's no breaking change for those already using the `OkHttpClientProvider.createClient` and `OkHttpClientProvider.createClientBuilder` public methods.

1. react-native init TestAndroidCache
2. Followed https://facebook.github.io/react-native/docs/android-building-from-source.html to build  with this branch as react-native
3. Added the following code in the App.js (with correct URL_WITH_CACHE_CONTROL)
4. Made sure the debugger is closed
5. Throttled my mac's network speed with the `Network link conditioner` (edge)
6. Tapped "Fetch", it shows ~4000
7. Tapped "Fetch" again, it shows ~6

```js
import React, { Component } from 'react';
import {
  StyleSheet,
  Alert,
  View,
  Button
} from 'react-native';

type Props = {};
export default class App extends Component<Props> {
  fetch = () => {
    const start = Date.now();
    fetch('{URL_WITH_CACHE_CONTROL}').then(() => {
      const diff = Date.now() - start;
      Alert.alert(diff.toString());
    });
  };

  render() {
    return (
      <View style={styles.container}>
        <Button title={"fetch"} onPress={this.fetch} />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
});
```

None

<!--
Help reviewers and the release process by writing your own release notes

**INTERNAL and MINOR tagged notes will not be included in the next version's final release notes.**

  CATEGORY
[----------]        TYPE
[ CLI      ]   [-------------]      LOCATION
[ DOCS     ]   [ BREAKING    ]   [-------------]
[ GENERAL  ]   [ BUGFIX      ]   [-{Component}-]
[ INTERNAL ]   [ ENHANCEMENT ]   [ {File}      ]
[ IOS      ]   [ FEATURE     ]   [ {Directory} ]   |-----------|
[ ANDROID  ]   [ MINOR       ]   [ {Framework} ] - | {Message} |
[----------]   [-------------]   [-------------]   |-----------|

[CATEGORY] [TYPE] [LOCATION] - MESSAGE

 EXAMPLES:

 [IOS] [BREAKING] [FlatList] - Change a thing that breaks other things
 [ANDROID] [BUGFIX] [TextInput] - Did a thing to TextInput
 [CLI] [FEATURE] [local-cli/info/info.js] - CLI easier to do things with
 [DOCS] [BUGFIX] [GettingStarted.md] - Accidentally a thing/word
 [GENERAL] [ENHANCEMENT] [Yoga] - Added new yoga thing/position
 [INTERNAL] [FEATURE] [./scripts] - Added thing to script that nobody will see
-->
[ANDROID] [FEATURE] [Networking] Add HTTP caching
Pull Request resolved: https://github.com/facebook/react-native/pull/18348

Differential Revision: D13680430

Pulled By: hramos

fbshipit-source-id: 1e49cf75702db72b20a316e9cdd971605f8fe7e0
2019-01-23 12:31:29 +01:00
Dulmandakh ec887c25a4 android support library 28.0.0 (#23109)
Summary:
Bump Android Support Library to 28.0.0. Therefore fix Android CI

Changelog:
----------
[Android] [Changed] - Bump Android Support Library to 28.0.0.
Pull Request resolved: https://github.com/facebook/react-native/pull/23109

Differential Revision: D13779835

Pulled By: mdvacca

fbshipit-source-id: 7645ffe2c04ca81424b2f9cfa43dc4ec30c50e25
2019-01-23 12:30:00 +01:00
David Vacca fd5042dcef Upgrade Android support library to version 28 in RN
Summary: This diff upgrades the Android Support Library to use version 28.0.0

Reviewed By: cpojer

Differential Revision: D13737512

fbshipit-source-id: 7b3d9c384df0b25e5ce48e769e1ff0ac9be9f104
2019-01-23 12:29:54 +01:00
Michael Diarmid 9f14ac2244 Add Network Security Config file (fixes #22375) (#23105)
Summary:
This fixes #22375. Android API level 28 and above now blocks all [clear text requests](https://developer.android.com/training/articles/security-config#CleartextTrafficPermitted) unless a network configuration rule is added to exclude it specifically.

The packager falls into this category and therefore gets blocked; resulting in the app being unable to connect to it.

Domains/IPs for the config have been taken from [here](https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/AndroidInfoHelpers.java#L20-L22).

This change only adds to DevSupport android resources - so won't affect builds without DevSupport, e.g. release builds.

Changelog:
----------

[ANDROID] [DevSupport] add Network Security Config file to allow access to packager via cleartext requests in Android API 28 and above. (fixes #22375)
Pull Request resolved: https://github.com/facebook/react-native/pull/23105

Differential Revision: D13781516

Pulled By: cpojer

fbshipit-source-id: f7574f3e1b0fe6984efe1d0598ef631385c245bc
2019-01-23 12:20:34 +01:00
Mike Grabowski 60b3942389 [0.58.0-rc.3] Bump version numbers 2019-01-17 16:02:13 +01:00
Mike Grabowski 9151e0d400 Revert "[0.58.0-rc.3] Bump version numbers"
This reverts commit 22af50ad95.
2019-01-17 16:02:05 +01:00
Mike Grabowski 22af50ad95 [0.58.0-rc.3] Bump version numbers 2019-01-17 15:40:47 +01:00
gengjiawen 0244caf513 Fix ReactAndroid bundle issue (#22799)
Summary:
Related change: https://github.com/facebook/react-native/commit/0a293a014bc8ef11191829a79a7419a3fa448852.

Changelog:
----------

[Bugfix] [Android] - fix 64bit so bundle issue.
Pull Request resolved: https://github.com/facebook/react-native/pull/22799

Differential Revision: D13669711

Pulled By: hramos

fbshipit-source-id: 0234b4731db0c74c8e4b8b738a19ae971fadb702
2019-01-17 11:29:27 +01:00
Mike Grabowski fb4e4fd099 evert "Remove unused files and code for old JSC and gcc build (#23014)"
This reverts commit bbf439862c.
2019-01-17 10:53:19 +01:00
Mike Grabowski 4ff693b93b Re-trigger Android build 2019-01-16 20:31:06 +01:00
Kudo Chien bbf439862c Remove unused files and code for old JSC and gcc build (#23014)
Summary:
----------

1. Unused prebuilt old JSC for 64bits.
2. Folly patch for gcc build.
Pull Request resolved: https://github.com/facebook/react-native/pull/23014

Differential Revision: D13690139

Pulled By: cpojer

fbshipit-source-id: 64555f5b9a5fbd4156e42eeff13da721846c2521
2019-01-16 16:46:05 +01:00
Thibault Malbranche 54e82a8c42 Added WebView deprecation warning (#22980)
Summary:
Changelog:
----------

Help reviewers and the release process by writing your own changelog entry. See http://facebook.github.io/react-native/docs/contributing#changelog for an example.

[General] [Deprecated] - Deprecation warning for WebView as it has been extracted from core.
Pull Request resolved: https://github.com/facebook/react-native/pull/22980

Differential Revision: D13664505

Pulled By: hramos

fbshipit-source-id: 0cfc06015e77c52bed9eeebd97c8cbca6eacd8ce
2019-01-16 16:44:00 +01:00
Monte Thakkar dbdb509f26 Updated RedBox screen (#22242)
Summary:
[Re: RedBox screen is a bit scary - Discussions and Proposals](https://github.com/react-native-community/discussions-and-proposals/issues/42)

Per hramos:
> The RedScreen was inspired by Ruby on Rails's error screen

> I do see the RedBox screen could be made less jarring while still successfully displaying all the information we need.

Hence jamonholmgren came up with the idea that only the header & footer of the RedBox screen could be red. This makes the content a bit more readable as well as makes the screen a little less intimidating.

Also frantic made the suggestion that since the bottom buttons are not as important, they don't need to stand out. Hence only the header of the RedBox screen which displays the error is made red.

Screenshots:
----------

<div style="flex-direction: row">
<img width="325" alt="orginal" src="https://user-images.githubusercontent.com/7840686/48322916-b4958b80-e5de-11e8-9276-33378d1b41c5.png">
<img width="320" alt="redbox_v2_ios" src="https://user-images.githubusercontent.com/7840686/48665300-cce32b80-ea60-11e8-8e8f-88f74bad30ca.png">

</div>

<div style="flex-direction: row">
<img width="300" alt="original_android" src="https://user-images.githubusercontent.com/7840686/48322958-d5f67780-e5de-11e8-891c-1b20bd00e67b.png">
<img width="300" alt="redbox_v2_android" src="https://user-images.githubusercontent.com/7840686/48665312-f13f0800-ea60-11e8-9fb6-47e03c809789.png">

</div>
Pull Request resolved: https://github.com/facebook/react-native/pull/22242

Reviewed By: hramos

Differential Revision: D13564287

Pulled By: cpojer

fbshipit-source-id: fcb6ba5e20d863f4b957d20f3787f5b7a365bfdb
2019-01-16 16:43:37 +01:00
Dulmandakh 34a585e093 bump okhttp to 3.12.1 (#22877)
Summary:
Bump OkHTTP to 3.12.1.

Changelog:
----------
[Android] [Changed] - bump OkHTTP 3.12.1
Pull Request resolved: https://github.com/facebook/react-native/pull/22877

Differential Revision: D13639172

Pulled By: hramos

fbshipit-source-id: 780d10207877637592ea3eb25eff445bc2986f91
2019-01-16 16:43:10 +01:00
Edward Karuna 7546aeaf8d Copy bundled resources and js in Android App Bundle builds (#21738)
Summary:
Android App Bundle builds use the packageBundle and bundle tasks instead
of the package and assemble tasks the APK builds use. Because of this,
the resources and js bundles weren't getting copied into the final
artifact. In an App Bundle build, the merged assets must be present
during the buildPreBundle step in order to arrive in the App Bundle.
Pull Request resolved: https://github.com/facebook/react-native/pull/21738

Differential Revision: D13669288

Pulled By: cpojer

fbshipit-source-id: 0e985983f04504b69e447dbc1f3f34cf8f4eb927
2019-01-16 16:38:34 +01:00
Mike Grabowski d25e304bcc [0.58.0-rc.2] Bump version numbers 2019-01-03 23:19:14 +01:00
Mike Grabowski c162c89edf Attempt fixing Detox 2019-01-03 22:57:50 +01:00
Mike Grabowski 57c6403048 Trigger tests 2019-01-03 22:23:26 +01:00
Mike Grabowski c8b1bdb88e Fix missing header on single-example pages 2019-01-03 21:55:50 +01:00
Mike Grabowski c88a7ca24a Do not display filter when doing snapshot tests on iOS 2019-01-03 21:48:46 +01:00
Mike Grabowski e0093fc98d Revert "Update some snapshots, still need to run tvOS and iOS 10"
This reverts commit 19c3a08ca8.
2019-01-03 19:34:07 +01:00
Mike Grabowski 19c3a08ca8 Update some snapshots, still need to run tvOS and iOS 10 2019-01-03 19:33:05 +01:00
Mike Grabowski e29ca07749 Ignore a Flow error 2019-01-03 19:21:18 +01:00
Mike Grabowski 54cb03c8d6 Fix a ESLint error 2019-01-03 19:13:30 +01:00
Josh Justice bd79303d5b Added filtering to RNTester example screens (#22777)
Summary:
This PR adds filtering functionality to individual example screens of RNTester. This is useful for Detox testing of RNTester, since Detox requires elements to be visible on the screen before they can be interacted with. Instead of needing to scroll an arbitrary amount, the test can enter the name of the example to be tested, just as is done on the main screen. This will lead to simpler and more reliable E2E tests for long example screens. This PR doesn't add any automated tests using the filter; those will be added in a separate PR.

This is implemented by extracting the existing filtering functionality out of `RNTesterExampleList` into a shared `RNTesterExampleFilter` component that can be used both within `RNTesterExampleList` (the main screen) and `RNTesterExampleContainer` (the example screen).

![simulator screen shot - iphone 8 - 2018-12-24 at 08 22 46](https://user-images.githubusercontent.com/15832198/50401564-4273a300-0755-11e9-9120-9bf8fbb70261.png)

![simulator screen shot - iphone 8 - 2018-12-24 at 08 22 51](https://user-images.githubusercontent.com/15832198/50401566-44d5fd00-0755-11e9-9637-6e5ddce1c476.png)

Changelog:
----------

[General] [Added] - Added filtering to RNTester example screens
Pull Request resolved: https://github.com/facebook/react-native/pull/22777

Reviewed By: TheSavior

Differential Revision: D13561744

Pulled By: rickhanlonii

fbshipit-source-id: cb120626a8e2b8440f88b871557c0b92fbef5edc
2019-01-03 18:58:05 +01:00
Josh Justice 68f6325849 Fix failing Switch E2E tests (#22698)
Summary:
Switch E2E tests have been failing on master, although they pass locally.

Changelog:
----------

Help reviewers and the release process by writing your own changelog entry. See http://facebook.github.io/react-native/docs/contributing#changelog for an example.

[General] [Fixed] - Fix failing Switch E2E tests
Pull Request resolved: https://github.com/facebook/react-native/pull/22698

Differential Revision: D13511917

Pulled By: hramos

fbshipit-source-id: b2f5cac1927531a855699e34e1a37036773f0aad
2019-01-03 18:57:21 +01:00
Josh Justice 1c22c10aa2 Remove persistence from RNTester app (#22596)
Summary:
Previously the RNTester app saved what screen you were on and what filter text was entered into the initial screen. This made e2e testing complex, as each test needed to manually restore the state to the home screen. If the state ever got out of sync with the test's expectations, it could lead to multiple failed tests.

There is still one specific component that uses persistence: `RNTesterSettingSwitchRow`. Persistence can be removed from this component next time tests for it are updated. As a result, `RNTesterStatePersister` is not yet entirely removed from the app.
Pull Request resolved: https://github.com/facebook/react-native/pull/22596

Differential Revision: D13413457

Pulled By: cpojer

fbshipit-source-id: 3faa26a94139397b4bce6b62ff43e9c2f870b145
2019-01-03 18:57:17 +01:00
Héctor Ramos 1df4713e9a test_ios → : Update iOS Snapshots, remove tvOS tests, disable failing tests (#22720)
Summary:
The following tests are disabled in this PR:

- testTimersTest is failing due to undefined this.setTimeout, probably introduced back in 61346d3. Tracking a fix in https://github.com/facebook/react-native/issues/22695
- testTheTester_ExpectError is failing as RCTTestRunner is not properly passing through the error. Tracking a fix in https://github.com/facebook/react-native/issues/22697

I've added a comment regarding testWebSocketTest and how to ensure it passes locally.

This PR also fixes all remaining snapshot tests, which were failing due to the use of iPhone XS as a iOS Simulator on Circle CI. We are using iPhone 6s for SST internally, and this allows us to be consistent.
Pull Request resolved: https://github.com/facebook/react-native/pull/22720

Differential Revision: D13532788

Pulled By: hramos

fbshipit-source-id: 75681236032839bf88180611ee68826b53cc96eb
2018-12-24 13:45:34 +01:00
Radek Czemerys f09ab6df25 Remove ActivityIndicator from ScrollView snapshot tests (#22729)
Summary:
`ActivityIndicator` was not consistent when running snapshot tests so I removed it.

From diff:
![image](https://user-images.githubusercontent.com/7029942/50274094-9c662700-043c-11e9-9cac-ccc1b69695c1.png)

Changelog:
----------

[iOS] [FIXED] - Fixed ScrollViewExample snapshot tests
Pull Request resolved: https://github.com/facebook/react-native/pull/22729

Differential Revision: D13528756

Pulled By: hramos

fbshipit-source-id: 747d91ad6a8fb8f0aa8022496bd8855a90710142
2018-12-24 13:44:40 +01:00
Héctor Ramos 94e7a10141 Update RNTester snapshots
Summary:
The iOS snapshots have been out of date for months, but the failure was not caught in open source's  `test_objc` job because `xcpretty` was swallowing the non-zero error code.

To fix this, I enabled recording mode in RNTesterSnapshotTests.m temporarily, and re-ran the tests in order to update the snapshots. I've also switched the test device used by Circle CI to iPhone 6s to be consistent with the snapshot tests that run internally at Facebook.

Integration tests are not fully fixed yet, but I can confirm the following tests are fixed by this diff:

```
-[RNTesterIntegrationTests testImageSnapshotTest]
-[RNTesterIntegrationTests testSimpleSnapshotTest]
-[RNTesterSnapshotTests testARTExample]
-[RNTesterSnapshotTests testLayoutExample]
-[RNTesterSnapshotTests testSliderExample]
-[RNTesterSnapshotTests testSwitchExample]
-[RNTesterSnapshotTests testTabBarExample]
-[RNTesterSnapshotTests testTextExample]
-[RNTesterSnapshotTests testViewExample]
```

I've also fixed a few shellcheck warnings in related scripts.

Reviewed By: fkgozali

Differential Revision: D13506865

fbshipit-source-id: dab985130c2ff3cb9dea19d1f87c8ee65d8c141e
2018-12-24 13:43:37 +01:00
Mike Grabowski be40199f13 §Revert "[0.58.0-rc.2] Bump version numbers"
This reverts commit 6ae2ebfcab.
2018-12-19 14:00:56 +01:00
Héctor Ramos e4fffa281e Fix RNTesterUnitTests failure (#22658)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/22658

Add JavaScriptCore.framework to RNTester's RNTesterUnitTests target. This resolves the failure seen when running `scripts/objc-test-ios.sh test` seen in Circle CI.

 See D9875409 for a related diff (https://github.com/facebook/react-native/commit/78fcf7c5598ce7f5d0d62110eb34fe5a4b962e71 in open source).

Without this diff, `scripts/objc-test-ios.sh test` would fail with the following error (see Circle https://circleci.com/gh/facebook/react-native/63704):

```
�  ld: symbol(s) not found for architecture x86_64

�  clang: error: linker command failed with exit code 1 (use -v to see invocation)

Testing failed:
	"_JSObjectGetPrototype", referenced from:
	"_JSObjectSetPrototype", referenced from:
	"_JSPropertyNameAccumulatorAddName", referenced from:
	"_JSObjectCopyPropertyNames", referenced from:
	"_JSContextGetGlobalObject", referenced from:
	"_JSValueMakeString", referenced from:
	"_JSValueIsNumber", referenced from:
	"_JSClassCreate", referenced from:
	"_JSObjectGetPropertyAtIndex", referenced from:
	"_JSObjectMakeArray", referenced from:
	"_JSEvaluateScript", referenced from:
	"_JSValueIsUndefined", referenced from:
	"_JSPropertyNameArrayGetCount", referenced from:
	"_JSPropertyNameArrayGetNameAtIndex", referenced from:
	"_JSPropertyNameArrayRelease", referenced from:
	"_JSValueMakeUndefined", referenced from:
	"_JSValueMakeNull", referenced from:
	"_JSStringCreateWithUTF8CString", referenced from:
	"_JSObjectSetProperty", referenced from:
	"_JSObjectHasProperty", referenced from:
	"_kJSClassDefinitionEmpty", referenced from:
	"_JSObjectIsFunction", referenced from:
	"_JSValueIsBoolean", referenced from:
	"_JSValueIsInstanceOfConstructor", referenced from:
	"_JSValueIsObjectOfClass", referenced from:
	"_JSValueToNumber", referenced from:
	"_JSGlobalContextRelease", referenced from:
	"_JSValueToBoolean", referenced from:
	"_JSValueIsArray", referenced from:
	"_JSValueMakeNumber", referenced from:
	"_JSObjectSetPrivate", referenced from:
	"_JSValueIsNull", referenced from:
	"_JSObjectSetPropertyAtIndex", referenced from:
	"_JSValueIsObject", referenced from:
	"_JSValueMakeBoolean", referenced from:
	"_JSValueUnprotect", referenced from:
	"_JSValueToStringCopy", referenced from:
	"_JSObjectGetProperty", referenced from:
	"_JSValueToObject", referenced from:
	"_JSObjectGetPrivate", referenced from:
	"_JSStringRelease", referenced from:
	"_JSGlobalContextRetain", referenced from:
	"_JSStringIsEqual", referenced from:
	"_JSStringGetMaximumUTF8CStringSize", referenced from:
	"_JSObjectCallAsFunction", referenced from:
	"_JSStringGetUTF8CString", referenced from:
	"_JSValueProtect", referenced from:
	"_JSValueIsString", referenced from:
	"_JSStringRetain", referenced from:
	"_JSObjectMake", referenced from:
	"_JSGlobalContextCreateInGroup", referenced from:
	"_JSObjectCallAsConstructor", referenced from:
	Linker command failed with exit code 1 (use -v to see invocation)
	Testing cancelled because the build failed.
** TEST FAILED **
```

Reviewed By: fkgozali

Differential Revision: D13474936

fbshipit-source-id: b12ddd6dcb95a7a588463d74cc0798dd591bdd78
2018-12-19 10:59:22 +01:00
Mike Grabowski 6ae2ebfcab [0.58.0-rc.2] Bump version numbers 2018-12-18 19:35:57 +01:00
Héctor Ramos b8c0d9d289 Bump RN OSS iOS tests to iOS SDK 12.1, Xcode 10.1
Summary:
Use Xcode 10.1 and iOS 12.1 SDK to run iOS tests on an iOS 12.1 iPhone XS Simulator, all of which are available on a default Xcode 10.1 install.

Note that we were previously running iOS tests using Xcode 10.1 and the 12.1 SDK in a separate `test_xcode10` workflow on Circle CI. This was in place to allow us to track Xcode 10 compatibility during the Xcode 10 beta. Now that Xcode 10 has been public for a while, we can drop the compatibility check and use Xcode 10 in our main iOS test workflow.

Reviewed By: TheSavior

Differential Revision: D13317891

fbshipit-source-id: 04c17bf3a2e9d3617f14a46b4ed30a5491a4f4a4
2018-12-18 19:34:40 +01:00
Mike Grabowski 7c04c09923 Revert "[0.58.0-rc.2] Bump version numbers"
This reverts commit 8c3111af31.
2018-12-18 19:32:08 +01:00
Mike Grabowski 8c3111af31 [0.58.0-rc.2] Bump version numbers 2018-12-18 14:48:35 +01:00
Mike Grabowski 26af339a47 Fix bad application of windows ci commit 2018-12-17 19:57:30 +01:00
Sunny Luo 76fc78e740 Use relative path for SCRIPTDIR (#22598)
Summary:
Fixes https://github.com/facebook/react-native/issues/22521

The current approach has an issue with white spaces when compiling in Xcode 10.1

![space](https://user-images.githubusercontent.com/615282/49782648-07836f80-fd52-11e8-952f-b93f8c593c60.png)

Change back to relative path fixes this issue
Pull Request resolved: https://github.com/facebook/react-native/pull/22598

Differential Revision: D13421446

Pulled By: hramos

fbshipit-source-id: 688157b2e951399059cb6c95e2a6ce8d176e9b9c
2018-12-17 19:55:28 +01:00
Salakar 1d949a12fa Allow 'userInfo' for native promise.reject + add native error stack support (#20940)
Summary:
As mentioned [here](https://github.com/react-native-community/react-native-releases/issues/34#issuecomment-417718601), Android is missing native Promise reject with a `userInfo` `WritableMap` support and also `nativeStack` support (which addresses `TODO(8850038)`). This PR adds Android support for both of these.

React Native on iOS ([here](https://github.com/facebook/react-native/blob/master/React/Base/RCTUtils.m#L433)) and Windows ([here](https://github.com/Microsoft/react-native-windows/pull/732)) already support this so this is a relatively minor addition to bring Android in line with the other platforms. (JS support is also [here](https://github.com/facebook/react-native/blob/master/Libraries/BatchedBridge/NativeModules.js#L145-L148))

Existing methods remain unchanged other than general cleanup of variable names (`e -> throwable`) and adding code comments/docs.

Additionally, the `ShareTestModule` implementation of Promise (SimplePromise) was updated to reflect these changes - other line changes in this file are from formatting in Android Studio - if this is an issue let me know.

 - Currently inconsistent with other platforms.
 - Blocking a couple of issues over at [invertase/react-native-firebase](https://github.com/invertase/react-native-firebase) - save for re-writing everything to Promise resolve only - which is no small change and isn't a great solution either.
Pull Request resolved: https://github.com/facebook/react-native/pull/20940

Differential Revision: D13412527

Pulled By: cpojer

fbshipit-source-id: 2ca6c5f3db9ff2c2986b02edda80bc73432f66d3
2018-12-17 19:55:10 +01:00
Salil Apte 8302e0cd8f Fixes animated gifs incorrectly looping/not stopping on last frame (#21999)
Summary:
Currently, if you load an animated gif using the standard `Image` component, it will not correctly respect the loop count property found in the Netscape App Extension block of the file. The issues are as follows:

1) If the App Extension isn't present, the animated gif loops indefinitely when it should not loop at all.
2) If the App Extension is present, the animated gif loops one less time than it should.

The other issue is that once the looping completes, the image doesn't pause at the last frame but instead, loops back to the beginning of the animation e.g. frame 1.

The fix does a few things:

1) If there is _no_ App Extension present, the image doesn't loop at all
2) If there _is_ an App Extension present, it loops the correct amount of times. For instance, if the loop count is 1, it means the gif should loop _once_ after it finishes playing, for a total of _two_ total loops.
3) Once the number of loops completes (assuming loop count isn't set to 0 which means infinite), the animation pauses on the last frame.
Pull Request resolved: https://github.com/facebook/react-native/pull/21999

Differential Revision: D13287005

Pulled By: hramos

fbshipit-source-id: f7210ad40e0e76c9ec454953b8a067569d3feaaa
2018-12-17 19:54:19 +01:00
Igor Mandrigin e3b7e81c8c Avoid using -[UITextView setAttributedString:] while user is typing (#19809)
Summary:
iOS-specific.
For languages with complex input (such as Japanese or Chinese), a user has to type multiple characters that are then merged into a single one.
If `-[UITextView setAttributedString:]` is used while the user is still typing, it resets the input and characters are not being treated as typed together.

This PR avoids calling this method if possible, replacing it by just copying the attributes if the string has not been changed. That preserves the state and user can continue to type Korean or Chinese characters.

Fixes #19339

<!--
  Required: Write your motivation here.
  If this PR fixes an issue, type "Fixes #issueNumber" to automatically close the issue when the PR is merged.
-->

<!--
  Required: 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!
-->

Essentially, the steps to reproduce are described in [the issue](https://github.com/facebook/react-native/issues/19339):

1. Type some Korean characters in TextInput, such as "하늘" (buttons `ㅎ`,`ㅏ`,`ㄴ`,`ㅡ`,`ㄹ`).
2. Then move the cursor to the beginning of the text, type "파란" (buttons `ㅍ`,`ㅏ`,`ㄹ`,`ㅏ`,`ㄴ`) this time.

**Behaviour before this fix (broken)**
Actual text: `ㅍㅏㄹㅏㄴ하늘`.
Expected text: `파란하늘`.
Characters aren't combined properly.

![ezgif com-resize](https://user-images.githubusercontent.com/466427/41613572-4256dda8-73f6-11e8-99a9-0ab833202b95.gif)

**Behaviour after this fix (correct)**
Actual text: `파란하늘`.
Expected text: `파란하늘`.
Characters are combined, the same behaviour is in vanilla iOS `UITextView`.

![input-with-fix](https://user-images.githubusercontent.com/466427/41613526-1aae2284-73f6-11e8-87f2-c1cef51cd83a.gif)

<!--
  Does this PR require a documentation change?
  Create a PR at https://github.com/facebook/react-native-website and add a link to it here.
-->

<!--
  Required.
  Help reviewers and the release process by writing your own release notes. See below for an example.
-->

[IOS] [BUGFIX] [TextView] - Fix Korean/Chinese/Japanese input for multiline TextView on iOS.

<!--
  **INTERNAL and MINOR tagged notes will not be included in the next version's final release notes.**

    CATEGORY
  [----------]      TYPE
  [ CLI      ] [-------------]    LOCATION
  [ DOCS     ] [ BREAKING    ] [-------------]
  [ GENERAL  ] [ BUGFIX      ] [ {Component} ]
  [ INTERNAL ] [ ENHANCEMENT ] [ {Filename}  ]
  [ IOS      ] [ FEATURE     ] [ {Directory} ]   |-----------|
  [ ANDROID  ] [ MINOR       ] [ {Framework} ] - | {Message} |
  [----------] [-------------] [-------------]   |-----------|

 EXAMPLES:

 [IOS] [BREAKING] [FlatList] - Change a thing that breaks other things
 [ANDROID] [BUGFIX] [TextInput] - Did a thing to TextInput
 [CLI] [FEATURE] [local-cli/info/info.js] - CLI easier to do things with
 [DOCS] [BUGFIX] [GettingStarted.md] - Accidentally a thing/word
 [GENERAL] [ENHANCEMENT] [Yoga] - Added new yoga thing/position
 [INTERNAL] [FEATURE] [./scripts] - Added thing to script that nobody will see
-->
Pull Request resolved: https://github.com/facebook/react-native/pull/19809

Differential Revision: D13326614

Pulled By: shergin

fbshipit-source-id: 6a5cab3f7290f0f623a6f4c29353a573eb321b0b
2018-12-17 19:53:46 +01:00
Max Sherman 2472e65b62 Record thread cpu time for native modules thread
Summary: I want the same instrumentation we did for the JS thread for the NM thread.  This diff adds thread cpu time.

Reviewed By: alexeylang

Differential Revision: D13328876

fbshipit-source-id: 7b310956c52907ffbd881f864e1f8e774853d7f5
2018-12-17 19:53:32 +01:00
Ian Park 7709285708 Fix bug in comparison logic of object property (#22348)
Summary:
`instance.hasOwnProperty` has potential danger because of some object could be eliminate own prototype chain. Update code be more reliable.

This PR is solution of #22308 issue. (Fixes #22308)
Pull Request resolved: https://github.com/facebook/react-native/pull/22348

Differential Revision: D13334882

Pulled By: cpojer

fbshipit-source-id: 9b9310a972e933af1962666d7b0c683ff43cc5b2
2018-12-17 19:53:24 +01:00
Zack Sheppard e7a52675cb Extend reason message for RCTFatalException (#22532)
Summary:
Fixes #22530

As described in the issue, the previous behavior for the `RCTFatal` macro was to truncate the `reason` on the resulting `NSException` to 75 characters. This would ensure the reason would fit on a single line, but resulted in issues debugging errors that occurred in the wild, as many crash logging tools (like Sentry) discard the `name` value of the exception and use the `reason` as their primary identifier. At 75 characters, useful information like the location of the error would usually be truncated.

- [x] This extends the truncation threshold to 175 characters, which should be short enough to prevent full-screen-takeover length errors, but long enough to provide useful context to the error.
- [x] This adds a `userInfo` value to the resulting `NSException`. It copies over the `userInfo` from the `NSError` passed to the macro, and adds an "untruncated message" value that contains the untruncated version of the `NSException`'s reason.

[iOS] [Changed] - RCTFatalExceptions now include more information in their reason and a userInfo.

<!--

  CATEGORY may be:

  - [General]
  - [iOS]
  - [Android]

  TYPE may be:

  - [Added] for new features.
  - [Changed] for changes in existing functionality.
  - [Deprecated] for soon-to-be removed features.
  - [Removed] for now removed features.
  - [Fixed] for any bug fixes.
  - [Security] in case of vulnerabilities.

  For more detail, see https://keepachangelog.com/en/1.0.0/#how

  MESSAGE may answer "what and why" on a feature level. Use this to briefly tell React Native users about notable changes.

  EXAMPLES:

  [General] [Added] - Add snapToOffsets prop to ScrollView component
  [General] [Fixed] - Fix various issues in snapToInterval on ScrollView component
  [iOS] [Fixed] - Fix crash in RCTImagePicker

-->
Pull Request resolved: https://github.com/facebook/react-native/pull/22532

Differential Revision: D13373469

Pulled By: cpojer

fbshipit-source-id: ac140d14ce76e1664869437c2c178bdd65ab6e0e
2018-12-17 19:53:16 +01:00
Elliott Sprehn 06dc51f8a9 Don't crash on second resolve or reject in PromiseImpl. (#20303)
Summary:
Promise semantics per JS should allow calling resolve or reject repeatedly without crashing. Only the first one should do anything, but others should be allowed. This change fixes the Java bridge for Android. A separate change is needed for iOS.

Issue #20262
Pull Request resolved: https://github.com/facebook/react-native/pull/20303

Differential Revision: D13396975

Pulled By: cpojer

fbshipit-source-id: 81f14f73654fa7c44e043f574a39fda481ace44b
2018-12-17 19:53:08 +01:00
Albert Sun 319fa03125 Ensure RCTImageCache's DateFormatter is only allocated once
Summary: This change attempts to fix a crash within RCTImageCache's new dateWithHeaderString method. This is a speculative fix as there aren't any concrete repro steps.

Reviewed By: hramos

Differential Revision: D13278666

fbshipit-source-id: cdb69b1296c946d89e14c074329280994d87ddcd
2018-12-17 19:52:53 +01:00
David Vacca 3c454eef8f Fix NPE when opening Google Search Assist when a RN Dialog is displayed
Summary:
This fixes app crashes on opening android search assistant when a RN modal is visible. The root cause is that ViewGroup.dispatchProvideStructure() method uses the private variable 'mChildren' to access the children of a view group instead of the publicApi.

This fixes the top crash for the react_MarketplaceProductDetailsNonIPadRoute route.

This also fixes github issues:
https://github.com/facebook/react-native/issues/15932
https://github.com/facebook/react-native/issues/13201
https://github.com/facebook/react-native/issues/15440

that were closed without a fix

Reviewed By: PeteTheHeat

Differential Revision: D13375993

fbshipit-source-id: d603cb4ef65a423c63a6ef2b51235702c7dbffcb
2018-12-17 19:52:45 +01:00
David Vacca c43b7b93b2 fix possible NPE in StatusBarModule
Summary:
This diff fixes a NPE happening in StatusBarModule when the style passed by parameter is null.
Even if JS shoulnd't send a null value, this method should not crash with an NPE. I'm not changing behavior, only avoiding NPE when status is null

Reviewed By: RSNara

Differential Revision: D13287057

fbshipit-source-id: cc5ac4e97083d63f2bf65c03bac0dc9bce976423
2018-12-17 19:52:39 +01:00
Ivan Filenko d8f28ceef8 Bump ws package to 1.1.5 due to vulnerability issues (#21769)
Summary:
Update `ws` package from 1.1.0 to 1.1.5 due to vulnerability issues.

Here is `npm audit` report:
```

                       === npm audit security report ===

┌──────────────────────────────────────────────────────────────────────────────┐
│                                Manual Review                                 │
│            Some vulnerabilities require your attention to resolve            │
│                                                                              │
│         Visit https://go.npm.me/audit-guide for additional guidance          │
└──────────────────────────────────────────────────────────────────────────────┘
┌───────────────┬──────────────────────────────────────────────────────────────┐
│ High          │ Denial of Service                                            │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Package       │ ws                                                           │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Patched in    │ >= 1.1.5 <2.0.0 || >=3.3.1                                   │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Dependency of │ c635d8a886cde7688a0123f573cc5b1f0430780052ba848c8fa1dc8a4c3… │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Path          │ c635d8a886cde7688a0123f573cc5b1f0430780052ba848c8fa1dc8a4c3… │
│               │ > react-devtools-core > ws                                   │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ More info     │ https://nodesecurity.io/advisories/550                       │
└───────────────┴──────────────────────────────────────────────────────────────┘
```
Pull Request resolved: https://github.com/facebook/react-native/pull/21769

Reviewed By: hramos

Differential Revision: D10379892

Pulled By: cpojer

fbshipit-source-id: 9d03f8231a90c5f55eb95ccac029aedd45a49a2d
2018-12-17 19:52:32 +01:00
Héctor Ramos 370fde33da Propagate exit code in test_objc (#22562)
Summary:
Any failures in `test_objc` within the objc-test.sh script have been kept hidden as `xcpretty` was swallowing the exit code from xcodebuild.

Fixes the issue TheSavior brought up in #22470 where failing snapshot tests were not reflected on Circle.

Run on Circle CI and confirm `test_objc` fails (iOS tests *are* broken on master).
Pull Request resolved: https://github.com/facebook/react-native/pull/22562

Differential Revision: D13406987

Pulled By: hramos

fbshipit-source-id: 3f3da01ab4c0ad87077813b06d2fdf788f32f6b8
2018-12-17 19:52:11 +01:00
Eli White 1b302b3f2a Add detox tests for Switch (#22470)
Summary:
Reorganized some of the switch examples to be more testable:

Before:
![simulator screen shot - iphone xs - 2018-12-01 at 02 27 47](https://user-images.githubusercontent.com/249164/49327066-bcc35580-f510-11e8-860d-fc07a574f80c.png)

After:
![simulator screen shot - iphone xs - 2018-12-01 at 02 27 06](https://user-images.githubusercontent.com/249164/49327068-bf25af80-f510-11e8-95c6-7aa4a9095b91.png)

Tests pass!

```
yarn build-ios-e2e && yarn test-ios-e2e
```
<img width="711" alt="screen shot 2018-12-01 at 2 20 33 am" src="https://user-images.githubusercontent.com/249164/49327070-c64cbd80-f510-11e8-8cad-84c3fe42941e.png">

Changelog:
----------
Help reviewers and the release process by writing your own changelog entry. When the change doesn't impact React Native developers, it may be ommitted from the changelog for brevity. See below for an example.

[Internal] [Added] - Detox tests for Switch
Pull Request resolved: https://github.com/facebook/react-native/pull/22470

Reviewed By: RSNara

Differential Revision: D13290329

Pulled By: TheSavior

fbshipit-source-id: 91c1b895dd5e1acc4330618e6d3165c7f9215997
2018-12-17 19:50:51 +01:00
Héctor Ramos 808a156769 Merge appveyor.yml with .appveyor/config.yml (#22529)
Summary:
A recent PR was merged with changes to appveyor.yml, but that file recently moved to .appveyor/config.yml
Pull Request resolved: https://github.com/facebook/react-native/pull/22529

Differential Revision: D13342085

Pulled By: hramos

fbshipit-source-id: d243e233ef769ab279dacdd48444248fbdec9417
2018-12-17 19:49:21 +01:00
Rick Hanlon d1e312d8ce Fix ActivityIndicator snapshot test, add toMatchShallowSnapshot
Summary:
This diff adds a custom matcher which will wrap a given component and shallow render it, snapshotting the result with the formatting users will see when they do the same.

I also update the ActivityIndicator test to use this new strategy, and add an additional check that the displayName is set.

For context see:
- https://github.com/facebook/react-native/pull/21950
- https://github.com/rajivshah3/rn-broken-snapshot/blob/broken-example/__tests__/App.spec.js#L3
- https://github.com/facebook/react-native/issues/21937

Reviewed By: TheSavior

Differential Revision: D13326689

fbshipit-source-id: 8ed2302a8aad12962fa2498a46d2502ccfb5c737
2018-12-17 19:48:38 +01:00
Lea Bärtschi cd8051c939 Remove trailing slash from origin header if no port is specified (#22290)
Summary:
Fixes #16304

The standard format for origin HTTP headers does not allow a trailing slash. In order to not get warnings when connecting a websocket, I removed the trailing slash when generating the default origin HTTP header for the websocket connect request.

Release Notes:
----------
[Android] [Fixed] - Fixed default origin header for websocket connections to match the standard format (https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Origin) in WebSocketModule
Pull Request resolved: https://github.com/facebook/react-native/pull/22290

Differential Revision: D13374345

Pulled By: cpojer

fbshipit-source-id: 1173241f2b6912fd6df5e196053a950bb42ff01b
2018-12-17 19:48:29 +01:00
gengjiawen cb85396fab fix windows ci
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/22557

Differential Revision: D13381568

Pulled By: hramos

fbshipit-source-id: db2ca0615c4cde5b0a4ae8ae824a005bcc1e2a1c
2018-12-17 19:48:11 +01:00
Rick Hanlon 00c7c5ade1 Add e2e tests, bug fixes for testIDs (#22537)
Summary:
This PR adds e2e tests for the Picker and DatePicker components.

While writing these tests, I also found and fixed two bugs where we wern't passing the `testID` down to the native components, so detox couldn't look them up. This confirms what was mentioned by rotemmiz [here](https://github.com/wix/Detox/issues/798#issuecomment-401412276)
Pull Request resolved: https://github.com/facebook/react-native/pull/22537

Reviewed By: cpojer

Differential Revision: D13371307

Pulled By: rickhanlonii

fbshipit-source-id: a4dfcdb5913645bceca0c7353328eeb9ad0f6558
2018-12-17 19:46:46 +01:00
Josh Justice 1fdfed51c3 Detox debug build (#22572)
Summary:
Adds a Detox configuration and instructions for running the app in development mode in Detox. This speeds up developing tests, because changes to production code don't require a full rebuild.
Pull Request resolved: https://github.com/facebook/react-native/pull/22572

Differential Revision: D13396883

Pulled By: cpojer

fbshipit-source-id: 186cc8d75eccae411b602cb0f68f0e11856e0743
2018-12-17 19:46:43 +01:00
Josh Justice 0189ea2c2b Add Touchable E2E tests (#22570)
Summary:
Adds some initial tests for Touchable*. It only tests the first screen worth of examples; in a separate PR I'll work on an alternate way to "scroll" to individual examples in tests, before I add tests for the rest of the Touchable examples.

On the live stream where I began writing these tests, I reorganized the "Touchable feedback examples" to the top of the list so it would be on-screen for testing. I didn't include this reorganization or test in this PR; that can be added in once the "alternative to scrolling" is added in, to avoid having to reorganize.

Changelog:
----------
[General] [Added] - Add E2E tests for Touchable
Pull Request resolved: https://github.com/facebook/react-native/pull/22570

Differential Revision: D13400348

Pulled By: TheSavior

fbshipit-source-id: 821af135296049090427a16472cc14dabeb10ab4
2018-12-17 19:46:18 +01:00
gengjiawen 860d01a2c4 Enable ci for windows (#22028)
Summary:
Enable ci for windows
appveyor pass.
https://github.com/facebook/react-native/pull/21835
 [GENERAL] [INTERNAL] [CI] - Enable ci for windows
Pull Request resolved: https://github.com/facebook/react-native/pull/22028

Differential Revision: D13318242

Pulled By: cpojer

fbshipit-source-id: be4b9b9fe6a4e21572f3d6c38b15a2acf8bb2662
2018-12-17 19:45:59 +01:00
Dulmandakh 8e39451512 Bump Android SDK to 28, Build Tools to 28.0.2, Gradle to 4.7, Gradle Plugin to 3.2.0 (#21632)
Summary:
This PR is bumping compileSdkVersion to 28, buildToolsVersion to 28.0.2, Gradle to 4.7, Android Gradle plugin to 3.2.0.

Gradle 4.7 added support for Java 10 and 11.

allow-large-files

Release Notes:
--------------
[ANDROID] [ENHANCEMENT] [SDK] - bump to 28

Pull Request resolved: https://github.com/facebook/react-native/pull/21632

Reviewed By: mdvacca

Differential Revision: D13084836

Pulled By: hramos

fbshipit-source-id: e0f493881e80e87faf8c3ef1ac77044495966a49
2018-12-17 19:44:58 +01:00
Mike Grabowski c0bf7a128c [0.58.0-rc.1] Bump version numbers 2018-12-06 09:39:36 +01:00
Tim Yung e54d1e27ea React sync for revisions 3ff2c7c...6bf5e85
Summary:
@public
This sync includes the following changes:
- **[6bf5e8598](https://github.com/facebook/react/commit/6bf5e8598)**: Fix scheduler setTimeout() re-entrancy check (#14384) //<Brian Vaughn>//
- **[7a48c900b](https://github.com/facebook/react/commit/7a48c900b)**: Prevent a v8 deopt when profiling (#14383) //<Brian Vaughn>//
- **[f00c2755b](https://github.com/facebook/react/commit/f00c2755b)**: Removed unnecessary externals from Jest bundles (#14372) //<Brian Vaughn>//
- **[52bea95cf](https://github.com/facebook/react/commit/52bea95cf)**: Fixed scheduler setTimeout fallback (#14358) //<Brian Vaughn>//
- **[1d25aa578](https://github.com/facebook/react/commit/1d25aa578)**: [Fizz] New Server Rendering Infra (#14144) //<Sebastian Markbåge>//
- **[f1bf28160](https://github.com/facebook/react/commit/f1bf28160)**: Fix bug in cloneHook (#14364) //<Imre Osswald>//
- **[16e120438](https://github.com/facebook/react/commit/16e120438)**: [Fire] Add initial build infrastructure (#14359) //<Dan Abramov>//
- **[d14ba87b1](https://github.com/facebook/react/commit/d14ba87b1)**: Validate propTypes for lazy() and memo() and warn about invalid patterns (#14298) //<Dan Abramov>//
- **[4f964f09c](https://github.com/facebook/react/commit/4f964f09c)**: Adding isMemo check to react-is package (#14313) //<Jinto Jose>//
- **[c2a2d8a53](https://github.com/facebook/react/commit/c2a2d8a53)**: Remove useMutationEffect (#14336) //<Sophie Alpert>//
- **[48f1e5b3c](https://github.com/facebook/react/commit/48f1e5b3c)**: Add a null type test for memo (#14325) //<chun shang>//
- **[f93f3402f](https://github.com/facebook/react/commit/f93f3402f)**: Make useEffect(async) warning more verbose (#14327) //<Dan Abramov>//
- **[ee3ef3a07](https://github.com/facebook/react/commit/ee3ef3a07)**: Fix regression: Errors not emitted in streams (#14314) //<Pelle Wessman>//
- **[33f6f5e53](https://github.com/facebook/react/commit/33f6f5e53)**: Remove usage of `fbjs/lib/invariant` in ReactNativeViewConfigRegistry. (#14330) //<Christoph Nakazawa>//
- **[686f1060a](https://github.com/facebook/react/commit/686f1060a)**: Publish a local release (canary or stable) to NPM (#14260) //<Brian Vaughn>//
- **[7475120ce](https://github.com/facebook/react/commit/7475120ce)**: Prevent deopts from modifying exports object in stable builds (#14309) //<Dan Abramov>//
- **[0c7189d92](https://github.com/facebook/react/commit/0c7189d92)**: Fix resolution of outer props with React.memo() (#14312) //<Dan Abramov>//
- **[14be29b2b](https://github.com/facebook/react/commit/14be29b2b)**: Add more test coverage for nested memo() (#14311) //<Dan Abramov>//
- **[dc0dd4bbf](https://github.com/facebook/react/commit/dc0dd4bbf)**: Use |0 to coerce to number (#14297) //<Dan Abramov>//
- **[dd8205cef](https://github.com/facebook/react/commit/dd8205cef)**: List ignored types instead of included types in the stack (#14308) //<Dan Abramov>//
- **[a9fdf8a32](https://github.com/facebook/react/commit/a9fdf8a32)**: Warn about reassigning this.props (#14277) //<Dan Abramov>//
- **[327cf0ee3](https://github.com/facebook/react/commit/327cf0ee3)**: Fix support for mixing react-dom/server@16.6 and react@<16.6 (#14291) //<Dan Abramov>//
- **[c954efa70](https://github.com/facebook/react/commit/c954efa70)**: Remove `import * as` pattern from the codebase (#14282) //<Sebastian Markbåge>//
- **[ccb14e270](https://github.com/facebook/react/commit/ccb14e270)**: Fix SSR useCallback in render phase (#14279) //<Dan Abramov>//
- **[0e9cb3f5d](https://github.com/facebook/react/commit/0e9cb3f5d)**: Clear fields on unmount of fiber to avoid memory leak (#14276) //<Dominic Gannaway>//
- **[592676503](https://github.com/facebook/react/commit/592676503)**: Revert "Clear memoizedState on unmount of fiber to avoid memory leak (#14218)" (#14275) //<Dominic Gannaway>//
- **[9b2fb24f9](https://github.com/facebook/react/commit/9b2fb24f9)**: Clear memoizedState on unmount of fiber to avoid memory leak (#14218) //<Dominic Gannaway>//
- **[a22fabc2a](https://github.com/facebook/react/commit/a22fabc2a)**: Reduce scheduler serialization overhead (#14249) //<Jason Miller>//
- **[21d5f7d32](https://github.com/facebook/react/commit/21d5f7d32)**: Wrap shorthand CSS property collision warning in feature flag (#14245) //<Andrew Clark>//
- **[8feeed10d](https://github.com/facebook/react/commit/8feeed10d)**: [scheduler] Remove window.postMessage fallback //<Andrew Clark>//
- **[5bce0ef10](https://github.com/facebook/react/commit/5bce0ef10)**: [scheduler] Post to MessageChannel instead of window (#14234) //<Andrew Clark>//
- **[f55795c8e](https://github.com/facebook/react/commit/f55795c8e)**: Add regression test for #14188 (#14197) //<Dan Abramov>//
- **[b98adb648](https://github.com/facebook/react/commit/b98adb648)**: Simplify CSS shorthand property warning (#14183) //<Sophie Alpert>//
- **[f8bfd5868](https://github.com/facebook/react/commit/f8bfd5868)**: fix typo //<Sebastian Markbage>//
- **[961eb65b4](https://github.com/facebook/react/commit/961eb65b4)**: Use unique thread ID for each partial render to access Context (#14182) //<Sebastian Markbåge>//
- **[1a6ab1e9b](https://github.com/facebook/react/commit/1a6ab1e9b)**: SimpleMemoComponent should warn if a ref is given (#14178) //<Sophie Alpert>//
- **[8ae867e6b](https://github.com/facebook/react/commit/8ae867e6b)**: Warn about conflicting style values during updates (#14181) //<Sophie Alpert>//
- **[d5e1bf07d](https://github.com/facebook/react/commit/d5e1bf07d)**: Renamed outdated schedule/tracing referecnes (#14177) //<Brian Vaughn>//
- **[2dd4ba11e](https://github.com/facebook/react/commit/2dd4ba11e)**: ESlint -> ESLint //<Andrew Clark>//
- **[9cc631a53](https://github.com/facebook/react/commit/9cc631a53)**: Don't run danger on bad build (#14143) //<Sophie Alpert>//
- **[1034e26fe](https://github.com/facebook/react/commit/1034e26fe)**: Fix typos (#14124) //<Heaven>//
- **[5618da49d](https://github.com/facebook/react/commit/5618da49d)**: Fix comment typo (#14156) //<Bartosz Gordon>//
- **[9fb919945](https://github.com/facebook/react/commit/9fb919945)**: Add global to ESLint plugin bundle config //<Andrew Clark>//
- **[c174f8592](https://github.com/facebook/react/commit/c174f8592)**: Add fb build of ESLint plugin (#14165) //<Andrew Clark>//
- **[02e4848e3](https://github.com/facebook/react/commit/02e4848e3)**: Improved suspense support in ReactDOMServer (#14161) //<Alex Taylor>//
- **[4b163fee1](https://github.com/facebook/react/commit/4b163fee1)**: Remove errant return assignment (#14164) //<Andrew Clark>//
- **[e58ecda9a](https://github.com/facebook/react/commit/e58ecda9a)**: Suspense fuzz tester (#14147) //<Andrew Clark>//
- **[7fd1661f8](https://github.com/facebook/react/commit/7fd1661f8)**:  Don't warn if an unmounted component is pinged (#14158) //<Andrew Clark>//
- **[f9e9913f0](https://github.com/facebook/react/commit/f9e9913f0)**: [Synchronous Suspense] Don't delete children of suspended component (#14157) //<Andrew Clark>//
- **[7c560131b](https://github.com/facebook/react/commit/7c560131b)**: Adding logger pri (#14155) //<Nathan Schloss>//
- **[3d8bda70e](https://github.com/facebook/react/commit/3d8bda70e)**: Refactor ESLint configuration to enable better IDE integration (#13914) //<Minh Nguyen>//
- **[051272f20](https://github.com/facebook/react/commit/051272f20)**: Use Entry in `yarn build ...` Instead of Label (#14148) //<Sebastian Markbåge>//

Release Notes:
[GENERAL] [FEATURE] [React] - React sync for revisions 3ff2c7c...6bf5e85

Reviewed By: bvaughn

Differential Revision: D13288288

fbshipit-source-id: 89a4837a9198c53fc79306933f589ef25d8bb4b6
2018-12-04 15:38:21 +01:00
Valentin Shergin f6566c77b1 Summary:
Calling -[UIScrollView setContentOffset] with NaN values can cause a crash. That's not clear why exactly the computation returns NaN sometime, but the implemented sanitizing should help to detect this problem during development (and this also prevents the app from crashing).

See attached task for more details.

Reviewed By: fkgozali

Differential Revision: D13242729

fbshipit-source-id: 747bf1b42e02597e9f1300eee24547563ab29b27
2018-12-04 15:37:25 +01:00
Nicolas Gallagher 747b5e47ef Fix text alpha bug
Summary: Set the default text radius to 0 so that text shadows aren't applied to every text node

Reviewed By: mdvacca

Differential Revision: D13027589

fbshipit-source-id: 4f7386059ac1654b8f77dddf9eb1b772f6049e23
2018-12-04 15:35:54 +01:00
Michael Blanchard 0b32a65bbd Fix: Add displayName to ActivityIndicator (#22417)
Summary:
Similar to #21950, this adds displayName to `ActivityIndicator`, so it displays the correct component name in snapshots instead of `Component`.

Fixes #21937 (a little bit more than it was already fixed).
Pull Request resolved: https://github.com/facebook/react-native/pull/22417

Differential Revision: D13205376

Pulled By: TheSavior

fbshipit-source-id: 21e71d4980d159a1f33d32d83346b48257ec21d4
2018-12-04 15:35:35 +01:00
Ramanpreet Nara 3fbefa8664 Revert D13105396
Summary: D13105396 broke a few things, so I'm reverting it. See: https://fburl.com/toehyir8

Reviewed By: sahrens, mmmulani

Differential Revision: D13220491

fbshipit-source-id: 35594099eea7f40d2fb948ae2010db4babb7093d
2018-12-04 15:35:21 +01:00
Radek Czemerys 19a7ecc837 Fix Xcode 10 builds (broken by folly upgrade) (#22394)
Summary:
[Folly upgrade](https://github.com/facebook/react-native/commit/a70625abd7bf4fba3dafb8a969a73854b7ddcd42) introduced changes that have to be applied to `Install Third Party` script in order to use `New build system` from Xcode 10. Unfortunately, this might happen again if someone changes folly. Also removes non-existent files from folly podspec.
Pull Request resolved: https://github.com/facebook/react-native/pull/22394

Differential Revision: D13192463

Pulled By: hramos

fbshipit-source-id: ea0eeb6e1e7f6d7dfcdb6d1dee28b1a640ee7097
2018-11-27 12:25:12 +01:00
Mike Grabowski 0c1c66e719 [0.58.0-rc.0] Bump version numbers 2018-11-22 18:30:52 +01:00
Mike Grabowski e71fb64ecd Apply same config for Android 2018-11-22 18:29:16 +01:00
Mike Grabowski 26bdd5ba4e Make Metro untyped instead of ignored to let Metro-config resolve type annotations 2018-11-22 18:25:47 +01:00
Mike Grabowski e0ea58ecbd Add missing Metro Config 2018-11-22 18:18:37 +01:00
Kudo Chien 64dd60fb7d Fix ReactAndroid build break. (#22377)
Summary:
During C++ build, we need the libjsc.so.
  But arm64-v8a and x86_64 libjsc.so are in different path and this error raised:

    Android NDK: ERROR:/home/circleci/react-native/ReactAndroid/build/third-party-ndk/jsc/Android.mk:jsc: LOCAL_SRC_FILES points to a missing file
    /opt/ndk/android-ndk-r17c/build/core/prebuilt-library.mk:45: *** Android NDK: Aborting    .  Stop.
    Android NDK: Check that /home/circleci/react-native/ReactAndroid/build/third-party-ndk/jsc/jni/arm64-v8a/libjsc.so exists  or that its path is correct

  The commit moves prebuilt libjsc.so into
  ReactAndroid/src/main/jni/third-party/jsc/jni and let ndkbuild script find the prebuilt libjsc.so.
  For AAR packaging, modify the jniLibs so that gradle android library plugin could find the prebuilt libjsc.so as well.
Pull Request resolved: https://github.com/facebook/react-native/pull/22377

Differential Revision: D13166556

Pulled By: hramos

fbshipit-source-id: 61daaede7defbc66491a3e2f20058e7d248ba13e
2018-11-22 17:55:40 +01:00
gengjiawen d4d457b4eb Fix jsc regression.Fixes #22274 (#22293)
Summary:
My silly mistake when tinkering with the jsc lib. Also you have this patch first https://github.com/facebook/react-native/pull/22295.
Kudo plz review.

![image](https://user-images.githubusercontent.com/3759816/48561684-758f6f00-e92b-11e8-905b-e394f72349f7.png)
Pull Request resolved: https://github.com/facebook/react-native/pull/22293

Differential Revision: D13153931

Pulled By: hramos

fbshipit-source-id: 8a6efa0cd8abbff359f082d5ea7713933b6e7ac6
2018-11-22 17:55:31 +01:00
Mike Grabowski b864e7e63e Revert "Merge branch 'master' into 0.58-stable"
This reverts commit 696bd89013, reversing
changes made to a525941ab6.
2018-11-22 17:53:44 +01:00
Mike Grabowski 696bd89013 Merge branch 'master' into 0.58-stable 2018-11-22 17:33:25 +01:00
Rafael Oleza a525941ab6 Bump metro@0.49.1
Summary: galavant-fistbump

Reviewed By: jeanlauliac

Differential Revision: D13027247

fbshipit-source-id: 3635527b6c745111b26d9f61666c30e696b04526
2018-11-13 23:52:11 +01:00
146 changed files with 3620 additions and 1422 deletions
+2 -2
View File
@@ -1,8 +1,8 @@
environment:
ANDROID_HOME: "C:\\android-sdk-windows"
ANDROID_NDK: "C:\\android-sdk-windows\\android-ndk-r17c"
ANDROID_BUILD_VERSION: 27
ANDROID_TOOLS_VERSION: 27.0.3
ANDROID_BUILD_VERSION: 28
ANDROID_TOOLS_VERSION: 28.0.3
GRADLE_OPTS: -Dorg.gradle.daemon=false
+1 -1
View File
@@ -1,6 +1,6 @@
[android]
target = android-27
target = android-28
[download]
max_number_of_retries = 3
+30 -68
View File
@@ -28,24 +28,24 @@ aliases:
- &restore-cache-android-packages
keys:
- v1-android-sdkmanager-packages-api-27-alpha-{{ checksum "scripts/.tests.env" }}
- v1-android-sdkmanager-packages-api-28-alpha-{{ checksum "scripts/.tests.env" }}
- &save-cache-android-packages
paths:
- /opt/android/sdk
key: v1-android-sdkmanager-packages-api-27-alpha-{{ checksum "scripts/.tests.env" }}
key: v1-android-sdkmanager-packages-api-28-alpha-{{ checksum "scripts/.tests.env" }}
- &restore-cache-gradle
keys:
- v1-gradle-{{ .Branch }}-{{ checksum "build.gradle" }}-{{ checksum "ReactAndroid/build.gradle" }}
- v2-gradle-{{ .Branch }}-{{ checksum "build.gradle" }}-{{ checksum "ReactAndroid/build.gradle" }}
# Fallback in case checksum fails
- v1-gradle-{{ .Branch }}-{{ checksum "build.gradle" }}-
- v1-gradle-{{ .Branch }}-
- v2-gradle-{{ .Branch }}-{{ checksum "build.gradle" }}-
- v2-gradle-{{ .Branch }}-
# Fallback in case this is a first-time run on a fork
- v1-gradle-master-
- v2-gradle-master-
- &save-cache-gradle
paths:
- ~/.gradle
key: v1-gradle-{{ .Branch }}-{{ checksum "build.gradle" }}-{{ checksum "ReactAndroid/build.gradle" }}
key: v2-gradle-{{ .Branch }}-{{ checksum "build.gradle" }}-{{ checksum "ReactAndroid/build.gradle" }}
- &restore-cache-ndk
keys:
@@ -75,14 +75,22 @@ aliases:
- &restore-cache-downloads-gradle
keys:
- v1-gradle-{{ checksum "ReactAndroid/build.gradle" }}-{{ checksum "scripts/circleci/gradle_download_deps.sh" }}
- v1-gradle-
- v2-gradle-{{ checksum "ReactAndroid/build.gradle" }}-{{ checksum "scripts/circleci/gradle_download_deps.sh" }}
- v2-gradle-
- &save-cache-downloads-gradle
paths:
- ~/.gradle
- ReactAndroid/build/downloads
- ReactAndroid/build/third-party-ndk
key: v1-gradle-{{ checksum "ReactAndroid/build.gradle" }}-{{ checksum "scripts/circleci/gradle_download_deps.sh" }}
key: v2-gradle-{{ checksum "ReactAndroid/build.gradle" }}-{{ checksum "scripts/circleci/gradle_download_deps.sh" }}
- &restore-cache-homebrew
keys:
- v1-homebrew
- &save-cache-homebrew
paths:
- /usr/local/Homebrew
key: v1-homebrew
# Branch Filtering
- &filter-only-master-stable
@@ -233,7 +241,7 @@ aliases:
- &compile-native-libs
name: Compile Native Libs for Unit and Integration Tests
command: ./gradlew :ReactAndroid:packageReactNdkLibsForBuck -Pjobs=$BUILD_THREADS -Pcom.android.build.threadPoolSize=1
command: ./gradlew :ReactAndroid:packageReactNdkLibsForBuck -Pjobs=$BUILD_THREADS
no_output_timeout: 6m
- &run-android-unit-tests
@@ -277,20 +285,12 @@ aliases:
- &boot-simulator-iphone
name: Boot iPhone Simulator
command: xcrun simctl boot "iPhone 5s" || true
- &boot-simulator-appletv
name: Boot Apple TV Simulator
command: xcrun simctl boot "Apple TV" || true
command: source scripts/.tests.env && xcrun simctl boot "$IOS_DEVICE" || true
- &run-objc-ios-tests
name: iOS Test Suite
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: |
@@ -304,16 +304,12 @@ aliases:
- &run-e2e-tests
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;
command: ./scripts/circleci/exec_author_check.sh node ./scripts/run-ci-e2e-tests.js --android --ios --js --retries 3;
- &run-objc-ios-e2e-tests
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 (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 (Disabled)
command: ./scripts/circleci/exec_author_check.sh node ./scripts/run-ci-e2e-tests.js --android --retries 3;
@@ -337,7 +333,7 @@ js_defaults: &js_defaults
android_defaults: &android_defaults
<<: *defaults
docker:
- image: circleci/android:api-27-node8-alpha
- image: circleci/android:api-28-node8-alpha
resource_class: "large"
environment:
- TERM: "dumb"
@@ -350,7 +346,7 @@ android_defaults: &android_defaults
macos_defaults: &macos_defaults
<<: *defaults
macos:
xcode: "9.4.0"
xcode: "10.1.0"
version: 2
jobs:
@@ -416,51 +412,19 @@ jobs:
- store_test_results:
path: ~/react-native/reports/junit
# Runs unit tests on iOS and Apple TV devices
test_objc:
# Runs unit tests on iOS devices
test_ios:
<<: *macos_defaults
steps:
- attach_workspace:
at: ~/react-native
- run: *boot-simulator-iphone
- run: *boot-simulator-appletv
- restore-cache: *restore-cache-homebrew
- run: *brew-install-watchman
- save-cache: *save-cache-homebrew
- 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
# Xcode 10: Runs unit tests on iOS and Apple TV devices
test_objc_xcode10:
<<: *defaults
macos:
xcode: "10.0.0"
steps:
- 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
@@ -703,8 +667,8 @@ workflows:
requires:
- checkout_code
# Test iOS & tvOS
- test_objc:
# Test iOS
- test_ios:
filters: *filter-ignore-gh-pages
requires:
- checkout_code
@@ -715,8 +679,6 @@ workflows:
- checkout_code
# Tooling Compatibility Checks
- test_objc_xcode10:
filters: *filter-ignore-gh-pages
- test_node10:
filters: *filter-ignore-gh-pages
+3 -3
View File
@@ -22,9 +22,6 @@
; 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/.*
@@ -102,3 +99,6 @@ untyped-type-import
[version]
^0.86.0
[untyped]
.*/node_modules/metro/.*
+3 -3
View File
@@ -22,9 +22,6 @@
; 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/.*
@@ -102,3 +99,6 @@ untyped-type-import
[version]
^0.86.0
[untyped]
.*/node_modules/metro/.*
+1 -1
View File
@@ -50,7 +50,7 @@ ADD react.gradle /app/react.gradle
RUN ./gradlew :ReactAndroid:downloadBoost :ReactAndroid:downloadDoubleConversion :ReactAndroid:downloadFolly :ReactAndroid:downloadGlog :ReactAndroid:downloadJSCHeaders
# compile native libs with Gradle script, we need bridge for unit and integration tests
RUN ./gradlew :ReactAndroid:packageReactNdkLibsForBuck -Pjobs=1 -Pcom.android.build.threadPoolSize=1
RUN ./gradlew :ReactAndroid:packageReactNdkLibsForBuck -Pjobs=1
# add all react-native code
ADD . /app
+2 -2
View File
@@ -23,8 +23,8 @@ LABEL maintainer="Héctor Ramos <hector@fb.com>"
# set default build arguments
ARG SDK_VERSION=sdk-tools-linux-3859397.zip
ARG ANDROID_BUILD_VERSION=27
ARG ANDROID_TOOLS_VERSION=27.0.3
ARG ANDROID_BUILD_VERSION=28
ARG ANDROID_TOOLS_VERSION=28.0.3
ARG BUCK_VERSION=v2018.10.29.01
ARG NDK_VERSION=17c
ARG NODE_VERSION=8.10.0
@@ -260,6 +260,22 @@ function shouldUseNativeDriver(config: AnimationConfig | EventConfig): boolean {
return config.useNativeDriver || false;
}
function transformDataType(value: any): number {
// Change the string type to number type so we can reuse the same logic in
// iOS and Android platform
if (typeof value !== 'string') {
return value;
}
if (/deg$/.test(value)) {
const degrees = parseFloat(value) || 0;
const radians = (degrees * Math.PI) / 180.0;
return radians;
} else {
// Assume radians
return parseFloat(value) || 0;
}
}
module.exports = {
API,
addWhitelistedStyleProp,
@@ -272,6 +288,7 @@ module.exports = {
generateNewAnimationId,
assertNativeAnimatedModule,
shouldUseNativeDriver,
transformDataType,
get nativeEventEmitter() {
if (!nativeEventEmitter) {
nativeEventEmitter = new NativeEventEmitter(NativeAnimatedModule);
@@ -347,21 +347,7 @@ class AnimatedInterpolation extends AnimatedWithChildren {
}
__transformDataType(range: Array<any>) {
// Change the string array type to number array
// So we can reuse the same logic in iOS and Android platform
return range.map(function(value) {
if (typeof value !== 'string') {
return value;
}
if (/deg$/.test(value)) {
const degrees = parseFloat(value) || 0;
const radians = (degrees * Math.PI) / 180.0;
return radians;
} else {
// Assume radians
return parseFloat(value) || 0;
}
});
return range.map(NativeAnimatedHelper.transformDataType);
}
__getNativeConfig(): any {
@@ -103,7 +103,7 @@ class AnimatedTransform extends AnimatedWithChildren {
transConfigs.push({
type: 'static',
property: key,
value,
value: NativeAnimatedHelper.transformDataType(value),
});
}
}
@@ -112,6 +112,7 @@ const ActivityIndicator = (
// $FlowFixMe - TODO T29156721 `React.forwardRef` is not defined in Flow, yet.
const ActivityIndicatorWithRef = React.forwardRef(ActivityIndicator);
ActivityIndicatorWithRef.displayName = 'ActivityIndicator';
ActivityIndicatorWithRef.defaultProps = {
animating: true,
@@ -0,0 +1,54 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
* @emails oncall+react_native
* @flow
*/
'use strict';
const React = require('React');
const ActivityIndicator = require('ActivityIndicator');
const render = require('../../../../jest/renderer');
describe('ActivityIndicator', () => {
it('should set displayName to prevent <Component /> regressions', () => {
expect(ActivityIndicator.displayName).toBe('ActivityIndicator');
});
it('should render as <ActivityIndicator> when mocked', () => {
const instance = render.create(
<ActivityIndicator size="large" color="#0000ff" />,
);
expect(instance).toMatchSnapshot();
});
it('should shallow render as <ActivityIndicator> when mocked', () => {
const output = render.shallow(
<ActivityIndicator size="large" color="#0000ff" />,
);
expect(output).toMatchSnapshot();
});
it('should shallow render as <ForwardRef(ActivityIndicator)> when not mocked', () => {
jest.dontMock('ActivityIndicator');
const output = render.shallow(
<ActivityIndicator size="large" color="#0000ff" />,
);
expect(output).toMatchSnapshot();
});
it('should render as <View> when not mocked', () => {
jest.dontMock('ActivityIndicator');
const instance = render.create(
<ActivityIndicator size="large" color="#0000ff" />,
);
expect(instance).toMatchSnapshot();
});
});
@@ -0,0 +1,54 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`ActivityIndicator should render as <ActivityIndicator> when mocked 1`] = `
<ActivityIndicator
animating={true}
color="#0000ff"
hidesWhenStopped={true}
size="large"
/>
`;
exports[`ActivityIndicator should render as <View> when not mocked 1`] = `
<View
style={
Object {
"alignItems": "center",
"justifyContent": "center",
}
}
>
<RCTActivityIndicatorView
animating={true}
color="#0000ff"
hidesWhenStopped={true}
indeterminate={true}
size="large"
style={
Object {
"height": 36,
"width": 36,
}
}
styleAttr="Normal"
/>
</View>
`;
exports[`ActivityIndicator should shallow render as <ActivityIndicator> when mocked 1`] = `
<ActivityIndicator
animating={true}
color="#0000ff"
hidesWhenStopped={true}
size="large"
/>
`;
exports[`ActivityIndicator should shallow render as <ForwardRef(ActivityIndicator)> when not mocked 1`] = `
<ForwardRef(ActivityIndicator)
animating={true}
color="#0000ff"
hidesWhenStopped={true}
size="large"
/>
`;
@@ -148,6 +148,7 @@ class DatePickerIOS extends React.Component<Props> {
return (
<View style={props.style}>
<RCTDatePickerIOS
testID={props.testID}
ref={picker => {
this._picker = picker;
}}
@@ -47,6 +47,7 @@ type RCTPickerIOSType = Class<
onStartShouldSetResponder: () => boolean,
selectedIndex: number,
style?: ?TextStyleProp,
testID?: ?string,
|}>,
>,
>;
@@ -114,6 +115,7 @@ class PickerIOS extends React.Component<Props, State> {
ref={picker => {
this._picker = picker;
}}
testID={this.props.testID}
style={[styles.pickerIOS, this.props.itemStyle]}
items={this.state.items}
selectedIndex={this.state.selectedIndex}
+38 -70
View File
@@ -5,7 +5,7 @@
* LICENSE file in the root directory of this source tree.
*
* @format
* @flow strict-local
* @flow
*/
'use strict';
@@ -103,56 +103,13 @@ type Props = $ReadOnly<{|
barStyle?: ?('default' | 'light-content' | 'dark-content'),
|}>;
type StackEntryProps = {|
/**
* The background color of the status bar.
*
* @platform android
*/
backgroundColor: {|
value: ?string,
animated: ?boolean,
|},
/**
* Sets the color of the status bar text.
*/
barStyle: {|
value: ?string,
animated: ?boolean,
|},
/**
* 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.
*/
translucent: ?boolean,
/**
*
*/
hidden: {|
value: ?boolean,
animated: boolean,
transition: ?('slide' | 'fade'),
|},
/**
* If the network activity indicator should be visible.
*
* @platform ios
*/
networkActivityIndicatorVisible: ?boolean,
|};
/**
* Merges the prop stack with the default values.
*/
function mergePropsStack(
propsStack: $ReadOnlyArray<StackEntryProps>,
defaultValues: StackEntryProps,
): StackEntryProps {
const init: StackEntryProps = {
...defaultValues,
};
propsStack: Array<Object>,
defaultValues: Object,
): Object {
return propsStack.reduce((prev, cur) => {
for (const prop in cur) {
if (cur[prop] != null) {
@@ -160,31 +117,39 @@ function mergePropsStack(
}
}
return prev;
}, init);
}, Object.assign({}, defaultValues));
}
/**
* Returns an object to insert in the props stack from the props
* and the transition/animation info.
*/
function createStackEntry(props: Props): StackEntryProps {
function createStackEntry(props: any): any {
return {
backgroundColor: {
value: props.backgroundColor,
animated: props.animated,
},
barStyle: {
value: props.barStyle,
animated: props.animated,
},
translucent: props.translucent || false,
hidden: {
value: props.hidden,
animated: props.animated || false,
transition: props.showHideTransition,
},
networkActivityIndicatorVisible:
props.networkActivityIndicatorVisible || false,
backgroundColor:
props.backgroundColor != null
? {
value: props.backgroundColor,
animated: props.animated,
}
: null,
barStyle:
props.barStyle != null
? {
value: props.barStyle,
animated: props.animated,
}
: null,
translucent: props.translucent,
hidden:
props.hidden != null
? {
value: props.hidden,
animated: props.animated,
transition: props.showHideTransition,
}
: null,
networkActivityIndicatorVisible: props.networkActivityIndicatorVisible,
};
}
@@ -228,9 +193,9 @@ function createStackEntry(props: Props): StackEntryProps {
* `currentHeight` (Android only) The height of the status bar.
*/
class StatusBar extends React.Component<Props> {
static _propsStack: Array<StackEntryProps> = [];
static _propsStack = [];
static _defaultProps: StackEntryProps = createStackEntry({
static _defaultProps = createStackEntry({
animated: false,
showHideTransition: 'fade',
backgroundColor: 'black',
@@ -265,9 +230,10 @@ class StatusBar extends React.Component<Props> {
* changing the status bar hidden property.
*/
static setHidden(hidden: boolean, animation?: StatusBarAnimation) {
animation = animation || 'none';
StatusBar._defaultProps.hidden.value = hidden;
if (Platform.OS === 'ios') {
StatusBarManager.setHidden(hidden, animation || 'none');
StatusBarManager.setHidden(hidden, animation);
} else if (Platform.OS === 'android') {
StatusBarManager.setHidden(hidden);
}
@@ -279,9 +245,10 @@ class StatusBar extends React.Component<Props> {
* @param animated Animate the style change.
*/
static setBarStyle(style: StatusBarStyle, animated?: boolean) {
animated = animated || false;
StatusBar._defaultProps.barStyle.value = style;
if (Platform.OS === 'ios') {
StatusBarManager.setStyle(style, animated || false);
StatusBarManager.setStyle(style, animated);
} else if (Platform.OS === 'android') {
StatusBarManager.setStyle(style);
}
@@ -312,8 +279,9 @@ class StatusBar extends React.Component<Props> {
console.warn('`setBackgroundColor` is only available on Android');
return;
}
animated = animated || false;
StatusBar._defaultProps.backgroundColor.value = color;
StatusBarManager.setColor(processColor(color), animated || false);
StatusBarManager.setColor(processColor(color), animated);
}
/**
+5 -1
View File
@@ -1265,7 +1265,11 @@ const TextInput = createReactClass({
}
},
_onBlur: function(event: BlurEvent) {
_onBlur: function(event: Event) {
// This is a hack to fix https://fburl.com/toehyir8
// @todo(rsnara) Figure out why this is necessary.
this.blur();
if (this.props.onBlur) {
this.props.onBlur(event);
}
+4 -4
View File
@@ -1,17 +1,17 @@
/**
* @generated by scripts/bump-oss-version.js
*
* Copyright (c) Facebook, Inc. and 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
* @generated by scripts/bump-oss-version.js
* @flow
*/
exports.version = {
major: 0,
minor: 0,
patch: 0,
minor: 58,
patch: 4,
prerelease: null,
};
+13 -2
View File
@@ -32,7 +32,17 @@ RCT_EXPORT_MODULE()
{
CGImageSourceRef imageSource = CGImageSourceCreateWithData((CFDataRef)imageData, NULL);
NSDictionary<NSString *, id> *properties = (__bridge_transfer NSDictionary *)CGImageSourceCopyProperties(imageSource, NULL);
NSUInteger loopCount = [properties[(id)kCGImagePropertyGIFDictionary][(id)kCGImagePropertyGIFLoopCount] unsignedIntegerValue];
CGFloat loopCount = 0;
if ([[properties[(id)kCGImagePropertyGIFDictionary] allKeys] containsObject:(id)kCGImagePropertyGIFLoopCount]) {
loopCount = [properties[(id)kCGImagePropertyGIFDictionary][(id)kCGImagePropertyGIFLoopCount] unsignedIntegerValue];
if (loopCount == 0) {
// A loop count of 0 means infinite
loopCount = HUGE_VALF;
} else {
// A loop count of 1 means it should repeat twice, 2 means, thrice, etc.
loopCount += 1;
}
}
UIImage *image = nil;
size_t imageCount = CGImageSourceGetCount(imageSource);
@@ -84,11 +94,12 @@ RCT_EXPORT_MODULE()
// Create animation
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"contents"];
animation.calculationMode = kCAAnimationDiscrete;
animation.repeatCount = loopCount == 0 ? HUGE_VALF : loopCount;
animation.repeatCount = loopCount;
animation.keyTimes = keyTimes;
animation.values = images;
animation.duration = duration;
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;
image.reactKeyframeAnimation = animation;
} else {
+10 -10
View File
@@ -32,8 +32,6 @@ static NSString *RCTCacheKeyForImage(NSString *imageTag, CGSize size, CGFloat sc
NSOperationQueue *_imageDecodeQueue;
NSCache *_decodedImageCache;
NSMutableDictionary *_cacheStaleTimes;
NSDateFormatter *_headerDateFormatter;
}
- (instancetype)init
@@ -50,7 +48,7 @@ static NSString *RCTCacheKeyForImage(NSString *imageTag, CGSize size, CGFloat sc
selector:@selector(clearCache)
name:UIApplicationWillResignActiveNotification
object:nil];
return self;
}
@@ -137,14 +135,16 @@ static NSString *RCTCacheKeyForImage(NSString *imageTag, CGSize size, CGFloat sc
}
- (NSDate *)dateWithHeaderString:(NSString *)headerDateString {
if (_headerDateFormatter == nil) {
_headerDateFormatter = [[NSDateFormatter alloc] init];
_headerDateFormatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];
_headerDateFormatter.dateFormat = @"EEE',' dd MMM yyyy HH':'mm':'ss 'GMT'";
_headerDateFormatter.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0];
}
static NSDateFormatter *formatter;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
formatter = [[NSDateFormatter alloc] init];
formatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];
formatter.dateFormat = @"EEE',' dd MMM yyyy HH':'mm':'ss 'GMT'";
formatter.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0];
});
return [_headerDateFormatter dateFromString:headerDateString];
return [formatter dateFromString:headerDateString];
}
@end
@@ -12,7 +12,12 @@
jest.mock('ErrorUtils').mock('BatchedBridge');
const isWindows = process.platform === 'win32';
function expectToBeCalledOnce(fn) {
// todo fix this test case on widnows
if (isWindows) {
return;
}
expect(fn.mock.calls.length).toBe(1);
}
+1 -1
View File
@@ -1 +1 @@
3ff2c7ccd4d174786aed0f16cc0dd784816ae977
6bf5e859860938b8cb7153ee928c01ad45656969
File diff suppressed because it is too large Load Diff
+47 -51
View File
@@ -956,10 +956,6 @@ var eventTypes$1 = {
}
}
},
customBubblingEventTypes$1 =
ReactNativeViewConfigRegistry.customBubblingEventTypes,
customDirectEventTypes$1 =
ReactNativeViewConfigRegistry.customDirectEventTypes,
ReactNativeBridgeEventPlugin = {
eventTypes: ReactNativeViewConfigRegistry.eventTypes,
extractEvents: function(
@@ -969,8 +965,10 @@ var eventTypes$1 = {
nativeEventTarget
) {
if (null == targetInst) return null;
var bubbleDispatchConfig = customBubblingEventTypes$1[topLevelType],
directDispatchConfig = customDirectEventTypes$1[topLevelType];
var bubbleDispatchConfig =
ReactNativeViewConfigRegistry.customBubblingEventTypes[topLevelType],
directDispatchConfig =
ReactNativeViewConfigRegistry.customDirectEventTypes[topLevelType];
invariant(
bubbleDispatchConfig || directDispatchConfig,
'Unsupported top level event type "%s" dispatched',
@@ -1505,7 +1503,7 @@ function dispatchEvent(target, topLevelType, nativeEvent) {
function shim$1() {
invariant(
!1,
"The current renderer does not support hyration. This error is likely caused by a bug in React. Please file an issue."
"The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue."
);
}
var nextReactTag = 2;
@@ -1619,17 +1617,19 @@ function getStackByFiberInDevAndProd(workInProgress) {
var info = "";
do {
a: switch (workInProgress.tag) {
case 2:
case 16:
case 0:
case 1:
case 5:
case 8:
case 13:
case 3:
case 4:
case 6:
case 7:
case 10:
case 9:
var JSCompiler_inline_result = "";
break a;
default:
var owner = workInProgress._debugOwner,
source = workInProgress._debugSource,
name = getComponentName(workInProgress.type);
var JSCompiler_inline_result = null;
JSCompiler_inline_result = null;
owner && (JSCompiler_inline_result = getComponentName(owner.type));
owner = name;
name = "";
@@ -1643,9 +1643,6 @@ function getStackByFiberInDevAndProd(workInProgress) {
: JSCompiler_inline_result &&
(name = " (created by " + JSCompiler_inline_result + ")");
JSCompiler_inline_result = "\n in " + (owner || "Unknown") + name;
break a;
default:
JSCompiler_inline_result = "";
}
info += JSCompiler_inline_result;
workInProgress = workInProgress.return;
@@ -3379,7 +3376,8 @@ function updateMemoComponent(
"function" === typeof type &&
!shouldConstruct(type) &&
void 0 === type.defaultProps &&
null === Component.compare
null === Component.compare &&
void 0 === Component.defaultProps
)
return (
(workInProgress.tag = 15),
@@ -3817,7 +3815,6 @@ function updateSuspenseComponent(
nextDidTimeout
? ((renderExpirationTime = nextProps.fallback),
(nextProps = createWorkInProgress(mode, mode.pendingProps, 0)),
(nextProps.effectTag |= 2),
0 === (workInProgress.mode & 1) &&
((nextDidTimeout =
null !== workInProgress.memoizedState
@@ -3830,7 +3827,6 @@ function updateSuspenseComponent(
renderExpirationTime,
current$$1.expirationTime
)),
(mode.effectTag |= 2),
(renderExpirationTime = nextProps),
(nextProps.childExpirationTime = 0),
(renderExpirationTime.return = mode.return = workInProgress))
@@ -3844,9 +3840,7 @@ function updateSuspenseComponent(
nextDidTimeout
? ((nextDidTimeout = nextProps.fallback),
(nextProps = createFiberFromFragment(null, mode, 0, null)),
(nextProps.effectTag |= 2),
(nextProps.child = current$$1),
(current$$1.return = nextProps),
0 === (workInProgress.mode & 1) &&
(nextProps.child =
null !== workInProgress.memoizedState
@@ -4082,8 +4076,9 @@ function beginWork(current$$1, workInProgress, renderExpirationTime) {
default:
invariant(
!1,
"Element type is invalid. Received a promise that resolves to: %s. Promise elements must resolve to a class or function.",
current$$1
"Element type is invalid. Received a promise that resolves to: %s. Lazy element type must resolve to a class or function.%s",
current$$1,
""
);
}
return getDerivedStateFromProps;
@@ -4390,9 +4385,10 @@ function beginWork(current$$1, workInProgress, renderExpirationTime) {
return (
(context = workInProgress.type),
(hasContext = resolveDefaultProps(
context.type,
context,
workInProgress.pendingProps
)),
(hasContext = resolveDefaultProps(context.type, hasContext)),
updateMemoComponent(
current$$1,
workInProgress,
@@ -4979,20 +4975,22 @@ function completeUnitOfWork(workInProgress) {
break a;
}
instance = null !== instance;
viewConfig = null !== current && null !== current.memoizedState;
renderExpirationTime =
null !== current && null !== current.memoizedState;
null !== current &&
!instance &&
viewConfig &&
renderExpirationTime &&
((current = current.child.sibling),
null !== current &&
reconcileChildFibers(
current$$1,
current,
null,
renderExpirationTime
));
((viewConfig = current$$1.firstEffect),
null !== viewConfig
? ((current$$1.firstEffect = current),
(current.nextEffect = viewConfig))
: ((current$$1.firstEffect = current$$1.lastEffect = current),
(current.nextEffect = null)),
(current.effectTag = 8)));
if (
instance !== viewConfig ||
instance !== renderExpirationTime ||
(0 === (current$$1.effectTag & 1) && instance)
)
current$$1.effectTag |= 4;
@@ -5183,14 +5181,7 @@ function renderRoot(root$jscomp$0, isYieldy) {
thenable.then(returnFiber$jscomp$0, returnFiber$jscomp$0);
if (0 === (value.mode & 1)) {
value.effectTag |= 64;
reconcileChildren(
sourceFiber$jscomp$0.alternate,
sourceFiber$jscomp$0,
null,
returnFiber
);
sourceFiber$jscomp$0.effectTag &= -1025;
sourceFiber$jscomp$0.effectTag &= -933;
sourceFiber$jscomp$0.effectTag &= -1957;
1 === sourceFiber$jscomp$0.tag &&
null === sourceFiber$jscomp$0.alternate &&
(sourceFiber$jscomp$0.tag = 17);
@@ -5447,7 +5438,7 @@ function scheduleWorkToRoot(fiber, expirationTime) {
}
node = node.return;
}
return null === root ? null : root;
return root;
}
function scheduleWork(fiber, expirationTime) {
fiber = scheduleWorkToRoot(fiber, expirationTime);
@@ -5944,9 +5935,14 @@ function completeRoot$1(root, finishedWork$jscomp$0, expirationTime) {
}
prevState.return = null;
prevState.child = null;
prevState.alternate &&
((prevState.alternate.child = null),
(prevState.alternate.return = null));
prevState.memoizedState = null;
prevState.updateQueue = null;
var alternate = prevState.alternate;
null !== alternate &&
((alternate.return = null),
(alternate.child = null),
(alternate.memoizedState = null),
(alternate.updateQueue = null));
}
nextEffect = nextEffect.nextEffect;
}
@@ -6101,7 +6097,7 @@ function onUncaughtError(error) {
nextFlushedRoot.expirationTime = 0;
hasUnhandledError || ((hasUnhandledError = !0), (unhandledError = error));
}
function findHostInstance$1(component) {
function findHostInstance(component) {
var fiber = component._reactInternalFiber;
void 0 === fiber &&
("function" === typeof component.render
@@ -6214,7 +6210,7 @@ function findNodeHandle(componentOrHandle) {
if (componentOrHandle._nativeTag) return componentOrHandle._nativeTag;
if (componentOrHandle.canonical && componentOrHandle.canonical._nativeTag)
return componentOrHandle.canonical._nativeTag;
componentOrHandle = findHostInstance$1(componentOrHandle);
componentOrHandle = findHostInstance(componentOrHandle);
return null == componentOrHandle
? componentOrHandle
: componentOrHandle.canonical
@@ -6310,7 +6306,7 @@ var roots = new Map(),
};
return ReactNativeComponent;
})(React.Component);
})(findNodeHandle, findHostInstance$1),
})(findNodeHandle, findHostInstance),
findNodeHandle: findNodeHandle,
render: function(element, containerTag, callback) {
var root = roots.get(containerTag);
@@ -6418,7 +6414,7 @@ var roots = new Map(),
TextInputState.blurTextInput(findNodeHandle(this));
}
};
})(findNodeHandle, findHostInstance$1)
})(findNodeHandle, findHostInstance)
}
};
(function(devToolsConfig) {
+51 -54
View File
@@ -957,10 +957,6 @@ var eventTypes$1 = {
}
}
},
customBubblingEventTypes$1 =
ReactNativeViewConfigRegistry.customBubblingEventTypes,
customDirectEventTypes$1 =
ReactNativeViewConfigRegistry.customDirectEventTypes,
ReactNativeBridgeEventPlugin = {
eventTypes: ReactNativeViewConfigRegistry.eventTypes,
extractEvents: function(
@@ -970,8 +966,10 @@ var eventTypes$1 = {
nativeEventTarget
) {
if (null == targetInst) return null;
var bubbleDispatchConfig = customBubblingEventTypes$1[topLevelType],
directDispatchConfig = customDirectEventTypes$1[topLevelType];
var bubbleDispatchConfig =
ReactNativeViewConfigRegistry.customBubblingEventTypes[topLevelType],
directDispatchConfig =
ReactNativeViewConfigRegistry.customDirectEventTypes[topLevelType];
invariant(
bubbleDispatchConfig || directDispatchConfig,
'Unsupported top level event type "%s" dispatched',
@@ -1506,7 +1504,7 @@ function dispatchEvent(target, topLevelType, nativeEvent) {
function shim$1() {
invariant(
!1,
"The current renderer does not support hyration. This error is likely caused by a bug in React. Please file an issue."
"The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue."
);
}
var nextReactTag = 2;
@@ -1620,17 +1618,19 @@ function getStackByFiberInDevAndProd(workInProgress) {
var info = "";
do {
a: switch (workInProgress.tag) {
case 2:
case 16:
case 0:
case 1:
case 5:
case 8:
case 13:
case 3:
case 4:
case 6:
case 7:
case 10:
case 9:
var JSCompiler_inline_result = "";
break a;
default:
var owner = workInProgress._debugOwner,
source = workInProgress._debugSource,
name = getComponentName(workInProgress.type);
var JSCompiler_inline_result = null;
JSCompiler_inline_result = null;
owner && (JSCompiler_inline_result = getComponentName(owner.type));
owner = name;
name = "";
@@ -1644,9 +1644,6 @@ function getStackByFiberInDevAndProd(workInProgress) {
: JSCompiler_inline_result &&
(name = " (created by " + JSCompiler_inline_result + ")");
JSCompiler_inline_result = "\n in " + (owner || "Unknown") + name;
break a;
default:
JSCompiler_inline_result = "";
}
info += JSCompiler_inline_result;
workInProgress = workInProgress.return;
@@ -3437,7 +3434,8 @@ function updateMemoComponent(
"function" === typeof type &&
!shouldConstruct(type) &&
void 0 === type.defaultProps &&
null === Component.compare
null === Component.compare &&
void 0 === Component.defaultProps
)
return (
(workInProgress.tag = 15),
@@ -3885,7 +3883,6 @@ function updateSuspenseComponent(
current$$1.pendingProps,
0
);
renderExpirationTime.effectTag |= 2;
0 === (workInProgress.mode & 1) &&
((nextDidTimeout =
null !== workInProgress.memoizedState
@@ -3905,7 +3902,6 @@ function updateSuspenseComponent(
nextProps,
mode.expirationTime
);
nextProps.effectTag |= 2;
mode = renderExpirationTime;
renderExpirationTime.childExpirationTime = 0;
renderExpirationTime = nextProps;
@@ -3920,9 +3916,7 @@ function updateSuspenseComponent(
else if (((current$$1 = current$$1.child), nextDidTimeout)) {
nextDidTimeout = nextProps.fallback;
nextProps = createFiberFromFragment(null, mode, 0, null);
nextProps.effectTag |= 2;
nextProps.child = current$$1;
current$$1.return = nextProps;
0 === (workInProgress.mode & 1) &&
(nextProps.child =
null !== workInProgress.memoizedState
@@ -4170,8 +4164,9 @@ function beginWork(current$$1, workInProgress, renderExpirationTime) {
default:
invariant(
!1,
"Element type is invalid. Received a promise that resolves to: %s. Promise elements must resolve to a class or function.",
current$$1
"Element type is invalid. Received a promise that resolves to: %s. Lazy element type must resolve to a class or function.%s",
current$$1,
""
);
}
return getDerivedStateFromProps;
@@ -4479,9 +4474,10 @@ function beginWork(current$$1, workInProgress, renderExpirationTime) {
return (
(context = workInProgress.type),
(hasContext = resolveDefaultProps(
context.type,
context,
workInProgress.pendingProps
)),
(hasContext = resolveDefaultProps(context.type, hasContext)),
updateMemoComponent(
current$$1,
workInProgress,
@@ -4906,14 +4902,7 @@ function throwException(
thenable.then(returnFiber, returnFiber);
if (0 === (value.mode & 1)) {
value.effectTag |= 64;
reconcileChildren(
sourceFiber.alternate,
sourceFiber,
null,
renderExpirationTime
);
sourceFiber.effectTag &= -1025;
sourceFiber.effectTag &= -933;
sourceFiber.effectTag &= -1957;
1 === sourceFiber.tag &&
null === sourceFiber.alternate &&
(sourceFiber.tag = 17);
@@ -5033,7 +5022,7 @@ var DispatcherWithoutHooks = { readContext: readContext },
invariant(
null != tracing.__interactionsRef &&
null != tracing.__interactionsRef.current,
"It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `schedule/tracing` module with `schedule/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at http://fb.me/react-profiling"
"It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at http://fb.me/react-profiling"
);
var isWorking = !1,
nextUnitOfWork = null,
@@ -5171,9 +5160,14 @@ function commitAllHostEffects() {
}
effectTag.return = null;
effectTag.child = null;
effectTag.alternate &&
((effectTag.alternate.child = null),
(effectTag.alternate.return = null));
effectTag.memoizedState = null;
effectTag.updateQueue = null;
effectTag = effectTag.alternate;
null !== effectTag &&
((effectTag.return = null),
(effectTag.child = null),
(effectTag.memoizedState = null),
(effectTag.updateQueue = null));
}
nextEffect = nextEffect.nextEffect;
}
@@ -5586,20 +5580,22 @@ function completeUnitOfWork(workInProgress) {
break a;
}
fiber = null !== fiber;
viewConfig = null !== current && null !== current.memoizedState;
renderExpirationTime =
null !== current && null !== current.memoizedState;
null !== current &&
!fiber &&
viewConfig &&
renderExpirationTime &&
((current = current.child.sibling),
null !== current &&
reconcileChildFibers(
current$$1,
current,
null,
renderExpirationTime
));
((viewConfig = current$$1.firstEffect),
null !== viewConfig
? ((current$$1.firstEffect = current),
(current.nextEffect = viewConfig))
: ((current$$1.firstEffect = current$$1.lastEffect = current),
(current.nextEffect = null)),
(current.effectTag = 8)));
if (
fiber !== viewConfig ||
fiber !== renderExpirationTime ||
(0 === (current$$1.effectTag & 1) && fiber)
)
current$$1.effectTag |= 4;
@@ -5959,9 +5955,10 @@ function scheduleWorkToRoot(fiber, expirationTime) {
}
node = node.return;
}
if (null === root) return null;
fiber = tracing.__interactionsRef.current;
if (0 < fiber.size) {
if (
null !== root &&
((fiber = tracing.__interactionsRef.current), 0 < fiber.size)
) {
alternate = root.pendingInteractionMap;
var pendingInteractions = alternate.get(expirationTime);
null != pendingInteractions
@@ -6290,7 +6287,7 @@ function onUncaughtError(error) {
nextFlushedRoot.expirationTime = 0;
hasUnhandledError || ((hasUnhandledError = !0), (unhandledError = error));
}
function findHostInstance$1(component) {
function findHostInstance(component) {
var fiber = component._reactInternalFiber;
void 0 === fiber &&
("function" === typeof component.render
@@ -6403,7 +6400,7 @@ function findNodeHandle(componentOrHandle) {
if (componentOrHandle._nativeTag) return componentOrHandle._nativeTag;
if (componentOrHandle.canonical && componentOrHandle.canonical._nativeTag)
return componentOrHandle.canonical._nativeTag;
componentOrHandle = findHostInstance$1(componentOrHandle);
componentOrHandle = findHostInstance(componentOrHandle);
return null == componentOrHandle
? componentOrHandle
: componentOrHandle.canonical
@@ -6499,7 +6496,7 @@ var roots = new Map(),
};
return ReactNativeComponent;
})(React.Component);
})(findNodeHandle, findHostInstance$1),
})(findNodeHandle, findHostInstance),
findNodeHandle: findNodeHandle,
render: function(element, containerTag, callback) {
var root = roots.get(containerTag);
@@ -6612,7 +6609,7 @@ var roots = new Map(),
TextInputState.blurTextInput(findNodeHandle(this));
}
};
})(findNodeHandle, findHostInstance$1)
})(findNodeHandle, findHostInstance)
}
};
(function(devToolsConfig) {
File diff suppressed because it is too large Load Diff
@@ -956,10 +956,6 @@ var eventTypes$1 = {
}
}
},
customBubblingEventTypes$1 =
ReactNativeViewConfigRegistry.customBubblingEventTypes,
customDirectEventTypes$1 =
ReactNativeViewConfigRegistry.customDirectEventTypes,
ReactNativeBridgeEventPlugin = {
eventTypes: ReactNativeViewConfigRegistry.eventTypes,
extractEvents: function(
@@ -969,8 +965,10 @@ var eventTypes$1 = {
nativeEventTarget
) {
if (null == targetInst) return null;
var bubbleDispatchConfig = customBubblingEventTypes$1[topLevelType],
directDispatchConfig = customDirectEventTypes$1[topLevelType];
var bubbleDispatchConfig =
ReactNativeViewConfigRegistry.customBubblingEventTypes[topLevelType],
directDispatchConfig =
ReactNativeViewConfigRegistry.customDirectEventTypes[topLevelType];
invariant(
bubbleDispatchConfig || directDispatchConfig,
'Unsupported top level event type "%s" dispatched',
@@ -1077,9 +1075,6 @@ function _receiveRootNodeIDEvent(rootNodeID, topLevelType, nativeEventParam) {
});
}
RCTEventEmitter.register({
getListener: getListener,
registrationNames: registrationNameModules,
_receiveRootNodeIDEvent: _receiveRootNodeIDEvent,
receiveEvent: function(rootNodeID, topLevelType, nativeEventParam) {
_receiveRootNodeIDEvent(rootNodeID, topLevelType, nativeEventParam);
},
@@ -1606,7 +1601,7 @@ function setTimeoutCallback() {
function shim$1() {
invariant(
!1,
"The current renderer does not support hyration. This error is likely caused by a bug in React. Please file an issue."
"The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue."
);
}
var UPDATE_SIGNAL = {},
@@ -1642,17 +1637,19 @@ function getStackByFiberInDevAndProd(workInProgress) {
var info = "";
do {
a: switch (workInProgress.tag) {
case 2:
case 16:
case 0:
case 1:
case 5:
case 8:
case 13:
case 3:
case 4:
case 6:
case 7:
case 10:
case 9:
var JSCompiler_inline_result = "";
break a;
default:
var owner = workInProgress._debugOwner,
source = workInProgress._debugSource,
name = getComponentName(workInProgress.type);
var JSCompiler_inline_result = null;
JSCompiler_inline_result = null;
owner && (JSCompiler_inline_result = getComponentName(owner.type));
owner = name;
name = "";
@@ -1666,9 +1663,6 @@ function getStackByFiberInDevAndProd(workInProgress) {
: JSCompiler_inline_result &&
(name = " (created by " + JSCompiler_inline_result + ")");
JSCompiler_inline_result = "\n in " + (owner || "Unknown") + name;
break a;
default:
JSCompiler_inline_result = "";
}
info += JSCompiler_inline_result;
workInProgress = workInProgress.return;
@@ -3402,7 +3396,8 @@ function updateMemoComponent(
"function" === typeof type &&
!shouldConstruct(type) &&
void 0 === type.defaultProps &&
null === Component.compare
null === Component.compare &&
void 0 === Component.defaultProps
)
return (
(workInProgress.tag = 15),
@@ -3840,7 +3835,6 @@ function updateSuspenseComponent(
nextDidTimeout
? ((renderExpirationTime = nextProps.fallback),
(nextProps = createWorkInProgress(mode, mode.pendingProps, 0)),
(nextProps.effectTag |= 2),
0 === (workInProgress.mode & 1) &&
((nextDidTimeout =
null !== workInProgress.memoizedState
@@ -3853,7 +3847,6 @@ function updateSuspenseComponent(
renderExpirationTime,
current$$1.expirationTime
)),
(mode.effectTag |= 2),
(renderExpirationTime = nextProps),
(nextProps.childExpirationTime = 0),
(renderExpirationTime.return = mode.return = workInProgress))
@@ -3867,9 +3860,7 @@ function updateSuspenseComponent(
nextDidTimeout
? ((nextDidTimeout = nextProps.fallback),
(nextProps = createFiberFromFragment(null, mode, 0, null)),
(nextProps.effectTag |= 2),
(nextProps.child = current$$1),
(current$$1.return = nextProps),
0 === (workInProgress.mode & 1) &&
(nextProps.child =
null !== workInProgress.memoizedState
@@ -4105,8 +4096,9 @@ function beginWork(current$$1, workInProgress, renderExpirationTime) {
default:
invariant(
!1,
"Element type is invalid. Received a promise that resolves to: %s. Promise elements must resolve to a class or function.",
current$$1
"Element type is invalid. Received a promise that resolves to: %s. Lazy element type must resolve to a class or function.%s",
current$$1,
""
);
}
return getDerivedStateFromProps;
@@ -4413,9 +4405,10 @@ function beginWork(current$$1, workInProgress, renderExpirationTime) {
return (
(context = workInProgress.type),
(hasContext = resolveDefaultProps(
context.type,
context,
workInProgress.pendingProps
)),
(hasContext = resolveDefaultProps(context.type, hasContext)),
updateMemoComponent(
current$$1,
workInProgress,
@@ -4942,7 +4935,12 @@ function commitWork(current$$1, finishedWork) {
}
else {
if (6 === newProps.tag) throw Error("Not yet implemented.");
if (null !== newProps.child) {
if (13 === newProps.tag && null !== newProps.memoizedState) {
current$$1 = newProps.child.sibling;
current$$1.return = newProps;
newProps = current$$1;
continue;
} else if (null !== newProps.child) {
newProps.child.return = newProps;
newProps = newProps.child;
continue;
@@ -5225,20 +5223,22 @@ function completeUnitOfWork(workInProgress) {
break a;
}
newProps = null !== newProps;
type = null !== current && null !== current.memoizedState;
renderExpirationTime =
null !== current && null !== current.memoizedState;
null !== current &&
!newProps &&
type &&
((current = current.child.sibling),
null !== current &&
reconcileChildFibers(
current$$1,
current,
null,
renderExpirationTime
));
renderExpirationTime &&
((type = current.child.sibling),
null !== type &&
((current = current$$1.firstEffect),
null !== current
? ((current$$1.firstEffect = type),
(type.nextEffect = current))
: ((current$$1.firstEffect = current$$1.lastEffect = type),
(type.nextEffect = null)),
(type.effectTag = 8)));
if (
newProps !== type ||
newProps !== renderExpirationTime ||
(0 === (current$$1.effectTag & 1) && newProps)
)
current$$1.effectTag |= 4;
@@ -5432,14 +5432,7 @@ function renderRoot(root$jscomp$0, isYieldy) {
thenable.then(returnFiber$jscomp$0, returnFiber$jscomp$0);
if (0 === (value.mode & 1)) {
value.effectTag |= 64;
reconcileChildren(
sourceFiber$jscomp$0.alternate,
sourceFiber$jscomp$0,
null,
returnFiber
);
sourceFiber$jscomp$0.effectTag &= -1025;
sourceFiber$jscomp$0.effectTag &= -933;
sourceFiber$jscomp$0.effectTag &= -1957;
1 === sourceFiber$jscomp$0.tag &&
null === sourceFiber$jscomp$0.alternate &&
(sourceFiber$jscomp$0.tag = 17);
@@ -5696,7 +5689,7 @@ function scheduleWorkToRoot(fiber, expirationTime) {
}
node = node.return;
}
return null === root ? null : root;
return root;
}
function scheduleWork(fiber, expirationTime) {
fiber = scheduleWorkToRoot(fiber, expirationTime);
@@ -6121,13 +6114,18 @@ function completeRoot(root, finishedWork$jscomp$0, expirationTime) {
commitWork(nextEffect.alternate, nextEffect);
break;
case 8:
(prevState = nextEffect),
unmountHostComponents(prevState),
(prevState.return = null),
(prevState.child = null),
prevState.alternate &&
((prevState.alternate.child = null),
(prevState.alternate.return = null));
prevState = nextEffect;
unmountHostComponents(prevState);
prevState.return = null;
prevState.child = null;
prevState.memoizedState = null;
prevState.updateQueue = null;
var alternate = prevState.alternate;
null !== alternate &&
((alternate.return = null),
(alternate.child = null),
(alternate.memoizedState = null),
(alternate.updateQueue = null));
}
nextEffect = nextEffect.nextEffect;
}
@@ -6151,24 +6149,24 @@ function completeRoot(root, finishedWork$jscomp$0, expirationTime) {
var effectTag$jscomp$0 = nextEffect.effectTag;
if (effectTag$jscomp$0 & 36) {
var current$$1$jscomp$1 = nextEffect.alternate;
current$$1 = nextEffect;
prevProps = currentRef;
switch (current$$1.tag) {
alternate = nextEffect;
current$$1 = currentRef;
switch (alternate.tag) {
case 0:
case 11:
case 15:
break;
case 1:
var instance$jscomp$0 = current$$1.stateNode;
if (current$$1.effectTag & 4)
var instance$jscomp$0 = alternate.stateNode;
if (alternate.effectTag & 4)
if (null === current$$1$jscomp$1)
instance$jscomp$0.componentDidMount();
else {
var prevProps$jscomp$0 =
current$$1.elementType === current$$1.type
alternate.elementType === alternate.type
? current$$1$jscomp$1.memoizedProps
: resolveDefaultProps(
current$$1.type,
alternate.type,
current$$1$jscomp$1.memoizedProps
);
instance$jscomp$0.componentDidUpdate(
@@ -6177,32 +6175,32 @@ function completeRoot(root, finishedWork$jscomp$0, expirationTime) {
instance$jscomp$0.__reactInternalSnapshotBeforeUpdate
);
}
var updateQueue = current$$1.updateQueue;
var updateQueue = alternate.updateQueue;
null !== updateQueue &&
commitUpdateQueue(
current$$1,
alternate,
updateQueue,
instance$jscomp$0,
prevProps
current$$1
);
break;
case 3:
var _updateQueue = current$$1.updateQueue;
var _updateQueue = alternate.updateQueue;
if (null !== _updateQueue) {
prevState = null;
if (null !== current$$1.child)
switch (current$$1.child.tag) {
prevProps = null;
if (null !== alternate.child)
switch (alternate.child.tag) {
case 5:
prevState = current$$1.child.stateNode;
prevProps = alternate.child.stateNode;
break;
case 1:
prevState = current$$1.child.stateNode;
prevProps = alternate.child.stateNode;
}
commitUpdateQueue(
current$$1,
alternate,
_updateQueue,
prevState,
prevProps
prevProps,
current$$1
);
}
break;
@@ -6276,7 +6274,7 @@ function onUncaughtError(error) {
nextFlushedRoot.expirationTime = 0;
hasUnhandledError || ((hasUnhandledError = !0), (unhandledError = error));
}
function findHostInstance$1(component) {
function findHostInstance(component) {
var fiber = component._reactInternalFiber;
void 0 === fiber &&
("function" === typeof component.render
@@ -6389,7 +6387,7 @@ function findNodeHandle(componentOrHandle) {
if (componentOrHandle._nativeTag) return componentOrHandle._nativeTag;
if (componentOrHandle.canonical && componentOrHandle.canonical._nativeTag)
return componentOrHandle.canonical._nativeTag;
componentOrHandle = findHostInstance$1(componentOrHandle);
componentOrHandle = findHostInstance(componentOrHandle);
return null == componentOrHandle
? componentOrHandle
: componentOrHandle.canonical
@@ -6485,7 +6483,7 @@ var roots = new Map(),
};
return ReactNativeComponent;
})(React.Component);
})(findNodeHandle, findHostInstance$1),
})(findNodeHandle, findHostInstance),
findNodeHandle: findNodeHandle,
render: function(element, containerTag, callback) {
var root = roots.get(containerTag);
@@ -6598,7 +6596,7 @@ var roots = new Map(),
TextInputState.blurTextInput(findNodeHandle(this));
}
};
})(findNodeHandle, findHostInstance$1),
})(findNodeHandle, findHostInstance),
computeComponentStackForErrorReporting: function(reactTag) {
return (reactTag = getInstanceFromTag(reactTag))
? getStackByFiberInDevAndProd(reactTag)
@@ -957,10 +957,6 @@ var eventTypes$1 = {
}
}
},
customBubblingEventTypes$1 =
ReactNativeViewConfigRegistry.customBubblingEventTypes,
customDirectEventTypes$1 =
ReactNativeViewConfigRegistry.customDirectEventTypes,
ReactNativeBridgeEventPlugin = {
eventTypes: ReactNativeViewConfigRegistry.eventTypes,
extractEvents: function(
@@ -970,8 +966,10 @@ var eventTypes$1 = {
nativeEventTarget
) {
if (null == targetInst) return null;
var bubbleDispatchConfig = customBubblingEventTypes$1[topLevelType],
directDispatchConfig = customDirectEventTypes$1[topLevelType];
var bubbleDispatchConfig =
ReactNativeViewConfigRegistry.customBubblingEventTypes[topLevelType],
directDispatchConfig =
ReactNativeViewConfigRegistry.customDirectEventTypes[topLevelType];
invariant(
bubbleDispatchConfig || directDispatchConfig,
'Unsupported top level event type "%s" dispatched',
@@ -1078,9 +1076,6 @@ function _receiveRootNodeIDEvent(rootNodeID, topLevelType, nativeEventParam) {
});
}
RCTEventEmitter.register({
getListener: getListener,
registrationNames: registrationNameModules,
_receiveRootNodeIDEvent: _receiveRootNodeIDEvent,
receiveEvent: function(rootNodeID, topLevelType, nativeEventParam) {
_receiveRootNodeIDEvent(rootNodeID, topLevelType, nativeEventParam);
},
@@ -1607,7 +1602,7 @@ function setTimeoutCallback() {
function shim$1() {
invariant(
!1,
"The current renderer does not support hyration. This error is likely caused by a bug in React. Please file an issue."
"The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue."
);
}
var UPDATE_SIGNAL = {},
@@ -1643,17 +1638,19 @@ function getStackByFiberInDevAndProd(workInProgress) {
var info = "";
do {
a: switch (workInProgress.tag) {
case 2:
case 16:
case 0:
case 1:
case 5:
case 8:
case 13:
case 3:
case 4:
case 6:
case 7:
case 10:
case 9:
var JSCompiler_inline_result = "";
break a;
default:
var owner = workInProgress._debugOwner,
source = workInProgress._debugSource,
name = getComponentName(workInProgress.type);
var JSCompiler_inline_result = null;
JSCompiler_inline_result = null;
owner && (JSCompiler_inline_result = getComponentName(owner.type));
owner = name;
name = "";
@@ -1667,9 +1664,6 @@ function getStackByFiberInDevAndProd(workInProgress) {
: JSCompiler_inline_result &&
(name = " (created by " + JSCompiler_inline_result + ")");
JSCompiler_inline_result = "\n in " + (owner || "Unknown") + name;
break a;
default:
JSCompiler_inline_result = "";
}
info += JSCompiler_inline_result;
workInProgress = workInProgress.return;
@@ -3460,7 +3454,8 @@ function updateMemoComponent(
"function" === typeof type &&
!shouldConstruct(type) &&
void 0 === type.defaultProps &&
null === Component.compare
null === Component.compare &&
void 0 === Component.defaultProps
)
return (
(workInProgress.tag = 15),
@@ -3908,7 +3903,6 @@ function updateSuspenseComponent(
current$$1.pendingProps,
0
);
renderExpirationTime.effectTag |= 2;
0 === (workInProgress.mode & 1) &&
((nextDidTimeout =
null !== workInProgress.memoizedState
@@ -3928,7 +3922,6 @@ function updateSuspenseComponent(
nextProps,
mode.expirationTime
);
nextProps.effectTag |= 2;
mode = renderExpirationTime;
renderExpirationTime.childExpirationTime = 0;
renderExpirationTime = nextProps;
@@ -3943,9 +3936,7 @@ function updateSuspenseComponent(
else if (((current$$1 = current$$1.child), nextDidTimeout)) {
nextDidTimeout = nextProps.fallback;
nextProps = createFiberFromFragment(null, mode, 0, null);
nextProps.effectTag |= 2;
nextProps.child = current$$1;
current$$1.return = nextProps;
0 === (workInProgress.mode & 1) &&
(nextProps.child =
null !== workInProgress.memoizedState
@@ -4193,8 +4184,9 @@ function beginWork(current$$1, workInProgress, renderExpirationTime) {
default:
invariant(
!1,
"Element type is invalid. Received a promise that resolves to: %s. Promise elements must resolve to a class or function.",
current$$1
"Element type is invalid. Received a promise that resolves to: %s. Lazy element type must resolve to a class or function.%s",
current$$1,
""
);
}
return getDerivedStateFromProps;
@@ -4502,9 +4494,10 @@ function beginWork(current$$1, workInProgress, renderExpirationTime) {
return (
(context = workInProgress.type),
(hasContext = resolveDefaultProps(
context.type,
context,
workInProgress.pendingProps
)),
(hasContext = resolveDefaultProps(context.type, hasContext)),
updateMemoComponent(
current$$1,
workInProgress,
@@ -5031,7 +5024,12 @@ function commitWork(current$$1, finishedWork) {
}
else {
if (6 === newProps.tag) throw Error("Not yet implemented.");
if (null !== newProps.child) {
if (13 === newProps.tag && null !== newProps.memoizedState) {
current$$1 = newProps.child.sibling;
current$$1.return = newProps;
newProps = current$$1;
continue;
} else if (null !== newProps.child) {
newProps.child.return = newProps;
newProps = newProps.child;
continue;
@@ -5149,14 +5147,7 @@ function throwException(
thenable.then(returnFiber, returnFiber);
if (0 === (value.mode & 1)) {
value.effectTag |= 64;
reconcileChildren(
sourceFiber.alternate,
sourceFiber,
null,
renderExpirationTime
);
sourceFiber.effectTag &= -1025;
sourceFiber.effectTag &= -933;
sourceFiber.effectTag &= -1957;
1 === sourceFiber.tag &&
null === sourceFiber.alternate &&
(sourceFiber.tag = 17);
@@ -5276,7 +5267,7 @@ var DispatcherWithoutHooks = { readContext: readContext },
invariant(
null != tracing.__interactionsRef &&
null != tracing.__interactionsRef.current,
"It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `schedule/tracing` module with `schedule/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at http://fb.me/react-profiling"
"It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at http://fb.me/react-profiling"
);
var isWorking = !1,
nextUnitOfWork = null,
@@ -5356,9 +5347,14 @@ function commitAllHostEffects() {
unmountHostComponents(effectTag),
(effectTag.return = null),
(effectTag.child = null),
effectTag.alternate &&
((effectTag.alternate.child = null),
(effectTag.alternate.return = null));
(effectTag.memoizedState = null),
(effectTag.updateQueue = null),
(effectTag = effectTag.alternate),
null !== effectTag &&
((effectTag.return = null),
(effectTag.child = null),
(effectTag.memoizedState = null),
(effectTag.updateQueue = null));
}
nextEffect = nextEffect.nextEffect;
}
@@ -5769,19 +5765,24 @@ function completeUnitOfWork(workInProgress) {
break a;
}
fiber = null !== fiber;
type = null !== current && null !== current.memoizedState;
renderExpirationTime =
null !== current && null !== current.memoizedState;
null !== current &&
!fiber &&
type &&
((current = current.child.sibling),
null !== current &&
reconcileChildFibers(
current$$1,
current,
null,
renderExpirationTime
));
if (fiber !== type || (0 === (current$$1.effectTag & 1) && fiber))
renderExpirationTime &&
((type = current.child.sibling),
null !== type &&
((current = current$$1.firstEffect),
null !== current
? ((current$$1.firstEffect = type),
(type.nextEffect = current))
: ((current$$1.firstEffect = current$$1.lastEffect = type),
(type.nextEffect = null)),
(type.effectTag = 8)));
if (
fiber !== renderExpirationTime ||
(0 === (current$$1.effectTag & 1) && fiber)
)
current$$1.effectTag |= 4;
break;
case 7:
@@ -6147,9 +6148,10 @@ function scheduleWorkToRoot(fiber, expirationTime) {
}
node = node.return;
}
if (null === root) return null;
fiber = tracing.__interactionsRef.current;
if (0 < fiber.size) {
if (
null !== root &&
((fiber = tracing.__interactionsRef.current), 0 < fiber.size)
) {
alternate = root.pendingInteractionMap;
var pendingInteractions = alternate.get(expirationTime);
null != pendingInteractions
@@ -6478,7 +6480,7 @@ function onUncaughtError(error) {
nextFlushedRoot.expirationTime = 0;
hasUnhandledError || ((hasUnhandledError = !0), (unhandledError = error));
}
function findHostInstance$1(component) {
function findHostInstance(component) {
var fiber = component._reactInternalFiber;
void 0 === fiber &&
("function" === typeof component.render
@@ -6591,7 +6593,7 @@ function findNodeHandle(componentOrHandle) {
if (componentOrHandle._nativeTag) return componentOrHandle._nativeTag;
if (componentOrHandle.canonical && componentOrHandle.canonical._nativeTag)
return componentOrHandle.canonical._nativeTag;
componentOrHandle = findHostInstance$1(componentOrHandle);
componentOrHandle = findHostInstance(componentOrHandle);
return null == componentOrHandle
? componentOrHandle
: componentOrHandle.canonical
@@ -6687,7 +6689,7 @@ var roots = new Map(),
};
return ReactNativeComponent;
})(React.Component);
})(findNodeHandle, findHostInstance$1),
})(findNodeHandle, findHostInstance),
findNodeHandle: findNodeHandle,
render: function(element, containerTag, callback) {
var root = roots.get(containerTag);
@@ -6805,7 +6807,7 @@ var roots = new Map(),
TextInputState.blurTextInput(findNodeHandle(this));
}
};
})(findNodeHandle, findHostInstance$1),
})(findNodeHandle, findHostInstance),
computeComponentStackForErrorReporting: function(reactTag) {
return (reactTag = getInstanceFromTag(reactTag))
? getStackByFiberInDevAndProd(reactTag)
+1
View File
@@ -59,6 +59,7 @@ export type ReactContext<T> = {
_currentValue: T,
_currentValue2: T,
_threadCount: number,
// DEV only
_currentRenderer?: Object | null,
@@ -110,7 +110,21 @@ static UIColor *defaultPlaceholderColor()
- (void)setAttributedText:(NSAttributedString *)attributedText
{
[super setAttributedText:attributedText];
// Using `setAttributedString:` while user is typing breaks some internal mechanics
// when entering complex input languages such as Chinese, Korean or Japanese.
// see: https://github.com/facebook/react-native/issues/19339
// We try to avoid calling this method as much as we can.
// If the text has changed, there is nothing we can do.
if (![super.attributedText.string isEqualToString:attributedText.string]) {
[super setAttributedText:attributedText];
} else {
// But if the text is preserved, we just copying the attributes from the source string.
if (![super.attributedText isEqualToAttributedString:attributedText]) {
[self copyTextAttributesFrom:attributedText];
}
}
[self textDidChange];
}
@@ -241,4 +255,20 @@ static UIColor *defaultPlaceholderColor()
_placeholderView.hidden = !isVisible;
}
#pragma mark - Utility Methods
- (void)copyTextAttributesFrom:(NSAttributedString *)sourceString
{
[self.textStorage beginEditing];
NSTextStorage *textStorage = self.textStorage;
[sourceString enumerateAttributesInRange:NSMakeRange(0, sourceString.length)
options:NSAttributedStringEnumerationReverse
usingBlock:^(NSDictionary<NSAttributedStringKey,id> * _Nonnull attrs, NSRange range, BOOL * _Nonnull stop) {
[textStorage setAttributes:attrs range:range];
}];
[self.textStorage endEditing];
}
@end
+10
View File
@@ -14,6 +14,7 @@ const invariant = require('fbjs/lib/invariant');
let showedListViewDeprecation = false;
let showedSwipeableListViewDeprecation = false;
let showedWebWiewDeprecation = false;
// Export React, plus some native additions.
module.exports = {
@@ -170,6 +171,15 @@ module.exports = {
return require('VirtualizedList');
},
get WebView() {
if (!showedWebWiewDeprecation) {
console.warn(
'WebView has been extracted from react-native core and will be removed in a future release. ' +
"It can now be installed and imported from 'react-native-webview' instead of 'react-native'. " +
'See https://github.com/react-native-community/react-native-webview for more informations.',
);
showedWebWiewDeprecation = true;
}
return require('WebView');
},
+1 -1
View File
@@ -23,7 +23,7 @@ function mergeInto(one, two) {
if (two != null) {
checkMergeObjectArg(two);
for (var key in two) {
if (!two.hasOwnProperty(key)) {
if (!Object.prototype.hasOwnProperty.call(two, key)) {
continue;
}
one[key] = two[key];
+2 -2
View File
@@ -104,10 +104,10 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c
DoubleConversion: bb338842f62ab1d708ceb63ec3d999f0f3d98ecd
Folly: cd7933b82a5f7673ed71bafe631f44a575ae77ab
Folly: de497beb10f102453a1afa9edbf8cf8a251890de
glog: aefd1eb5dda2ab95ba0938556f34b98e2da3a60d
React: 9b873b38b92ed8012d7cdf3b965477095ed364c4
yoga: b1ce48b6cf950b98deae82838f5173ea7cf89e85
yoga: 0885622311729a02c2bc02dca97167787a51488b
PODFILE CHECKSUM: 7af77fbc34af9646e8c6389e7e2c0b4663bb16d9
+23
View File
@@ -58,6 +58,29 @@ Run the following commands from the react-native folder:
_Note: The native libs are still built using gradle. Full build with buck is coming soon(tm)._
## Running Detox Tests on iOS
Install Detox from [here](https://github.com/wix/Detox/blob/master/docs/Introduction.GettingStarted.md).
To run the e2e tests locally, run the following commands from the react-native folder:
yarn build-ios-e2e
yarn test-ios-e2e
These are the equivalent of running:
detox build -c ios.sim.release
detox test -c ios.sim.release --cleanup
These build the app in Release mode, so the production code is bundled and included in the built app.
When developing E2E tests, you may want to run in development mode, so that changes to the production code show up immediately. To do this, run:
detox build -c ios.sim.debug
detox test -c ios.sim.debug
You will also need to have Metro Bundler running in another terminal. Note that if you've previously run the E2E tests in release mode, you may need to delete the `RNTester/build` folder before rerunning `detox build`.
## Built from source
Building the app on both iOS and Android means building the React Native framework from source. This way you're running the latest native and JS code the way you see it in your clone of the github repo.
+3 -1
View File
@@ -131,6 +131,7 @@
C654F0B31EB34A73000B7A9A /* RNTesterTestModule.m in Sources */ = {isa = PBXBuildFile; fileRef = C654F0B21EB34A73000B7A9A /* RNTesterTestModule.m */; };
C654F17E1EB34D24000B7A9A /* RNTesterTestModule.m in Sources */ = {isa = PBXBuildFile; fileRef = C654F0B21EB34A73000B7A9A /* RNTesterTestModule.m */; };
D85B829E1AB6D5D7003F4FE2 /* libRCTVibration.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D85B829C1AB6D5CE003F4FE2 /* libRCTVibration.a */; };
E77B20F321C481F8007FDF6D /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EDEBC7DA214C681C00DD5AC8 /* JavaScriptCore.framework */; };
ED2970992150247000B7C4FE /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ED2970982150247000B7C4FE /* JavaScriptCore.framework */; };
EDEBC856214C774100DD5AC8 /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EDEBC7DA214C681C00DD5AC8 /* JavaScriptCore.framework */; };
/* End PBXBuildFile section */
@@ -573,6 +574,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
E77B20F321C481F8007FDF6D /* JavaScriptCore.framework in Frameworks */,
19BA89031F8439A700741C5A /* libRCTBlob.a in Frameworks */,
192F69DA1E8240E2008692C7 /* libRCTAnimation.a in Frameworks */,
14D6D71E1B2222EF001FB087 /* libRCTActionSheet.a in Frameworks */,
@@ -1682,7 +1684,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "export NODE_BINARY=node\n$SRCROOT/../scripts/react-native-xcode.sh RNTester/js/RNTesterApp.ios.js";
shellScript = "export NODE_BINARY=node\n$SRCROOT/../scripts/react-native-xcode.sh RNTester/js/RNTesterApp.ios.js\n";
};
/* End PBXShellScriptBuildPhase section */
+2
View File
@@ -2,6 +2,8 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>UIStatusBarStyle</key>
<string>UIStatusBarStyleBlackTranslucent</string>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
@@ -49,20 +49,21 @@
configurationBlock:nil];
}
- (void)testTheTester_ExpectError
{
[_runner runTest:_cmd
module:@"IntegrationTestHarnessTest"
initialProps:@{@"shouldThrow": @YES}
configurationBlock:nil
expectErrorRegex:@"because shouldThrow"];
}
// Disabled
//- (void)testTheTester_ExpectError
//{
// [_runner runTest:_cmd
// module:@"IntegrationTestHarnessTest"
// initialProps:@{@"shouldThrow": @YES}
//configurationBlock:nil
// expectErrorRegex:@"because shouldThrow"];
//}
#pragma mark - JS tests
// This list should be kept in sync with IntegrationTestsApp.js
RCT_TEST(IntegrationTestHarnessTest)
RCT_TEST(TimersTest)
// RCT_TEST(TimersTest) // Disabled due to issue introduced in 61346d3
RCT_TEST(AsyncStorageTest)
RCT_TEST(AppEventsTest)
//RCT_TEST(ImageCachePolicyTest) // This test never passed.
@@ -71,7 +72,7 @@ RCT_TEST(ImageSnapshotTest)
RCT_TEST(SimpleSnapshotTest)
RCT_TEST(SyncMethodTest)
RCT_TEST(PromiseTest)
RCT_TEST_ONLY_WITH_PACKAGER(WebSocketTest)
RCT_TEST_ONLY_WITH_PACKAGER(WebSocketTest) // Requires a WebSocket test server, see scripts/objc-test.sh
RCT_TEST(AccessibilityManagerTest)
#if !TARGET_OS_TV // tvOS does not fully support WebView
Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 152 KiB

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 313 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 147 KiB

After

Width:  |  Height:  |  Size: 285 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 166 KiB

After

Width:  |  Height:  |  Size: 167 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 336 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 145 KiB

After

Width:  |  Height:  |  Size: 143 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 365 KiB

After

Width:  |  Height:  |  Size: 322 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 562 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 200 KiB

After

Width:  |  Height:  |  Size: 200 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 367 KiB

+3 -3
View File
@@ -91,8 +91,8 @@ def enableSeparateBuildPerCPUArchitecture = true
def enableProguardInReleaseBuilds = true
android {
compileSdkVersion 27
buildToolsVersion "27.0.3"
compileSdkVersion 28
buildToolsVersion "28.0.2"
defaultConfig {
applicationId "com.facebook.react.uiapp"
@@ -131,7 +131,7 @@ android {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support:appcompat-v7:28.0.0'
// Build React Native from source
implementation project(':ReactAndroid')
+55
View File
@@ -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.
*
* @emails oncall+react_native
* @format
*/
/* global device, element, by, expect */
describe('Button', () => {
beforeAll(async () => {
await device.reloadReactNative();
await element(by.id('explorer_search')).replaceText('<Button>');
await element(
by.label('<Button> Simple React Native button component.'),
).tap();
});
afterAll(async () => {
//TODO - remove app state persistency, till then, we must go back to main screen,
await element(by.label('Back')).tap();
});
it('Simple button should be tappable', async () => {
await element(by.label('Press Me')).tap();
await expect(element(by.text('Simple has been pressed!'))).toBeVisible();
await element(by.text('OK')).tap();
});
it('Adjusted color button should be tappable', async () => {
await element(by.label('Press Purple')).tap();
await expect(element(by.text('Purple has been pressed!'))).toBeVisible();
await element(by.text('OK')).tap();
});
it("Two buttons with JustifyContent:'space-between' should be tappable", async () => {
await element(by.label('This looks great!')).tap();
await expect(element(by.text('Left has been pressed!'))).toBeVisible();
await element(by.text('OK')).tap();
await element(by.label('Ok!')).tap();
await expect(element(by.text('Right has been pressed!'))).toBeVisible();
await element(by.text('OK')).tap();
});
it('Disabled button should not interact', async () => {
await element(by.label('I Am Disabled')).tap();
await expect(
element(by.text('Disabled has been pressed!')),
).toBeNotVisible();
});
});
@@ -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.
*
* @emails oncall+react_native
* @format
*/
/* global element, by, expect */
describe('DatePickerIOS', () => {
beforeAll(async () => {
await element(by.id('explorer_search')).replaceText('<DatePickerIOS>');
await element(
by.label(
'<DatePickerIOS> Select dates and times using the native UIDatePicker.',
),
).tap();
});
afterAll(async () => {
await element(by.label('Back')).tap();
});
it('Should change indicator with datetime picker', async () => {
const testID = 'date-and-time';
const indicatorID = 'date-and-time-indicator';
const testElement = await element(
by.type('UIPickerView').withAncestor(by.id(testID)),
);
const indicator = await element(by.id(indicatorID));
await expect(testElement).toBeVisible();
await expect(indicator).toBeVisible();
await testElement.setColumnToValue(0, 'Dec 4');
await testElement.setColumnToValue(1, '4');
await testElement.setColumnToValue(2, '10');
await testElement.setColumnToValue(3, 'AM');
await expect(indicator).toHaveText('12/4/2005 4:10 AM');
});
it('Should change indicator with date-only picker', async () => {
const testID = 'date-only';
const indicatorID = 'date-and-time-indicator';
const testElement = await element(
by.type('UIPickerView').withAncestor(by.id(testID)),
);
const indicator = await element(by.id(indicatorID));
await expect(testElement).toBeVisible();
await expect(indicator).toBeVisible();
await testElement.setColumnToValue(0, 'November');
await testElement.setColumnToValue(1, '3');
await testElement.setColumnToValue(2, '2006');
await expect(indicator).toHaveText('11/3/2006 4:10 AM');
});
});
+30
View File
@@ -0,0 +1,30 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @emails oncall+react_native
* @format
*/
/* global element, by, expect */
describe('Picker', () => {
beforeAll(async () => {
await element(by.id('explorer_search')).replaceText('<Picker>');
await element(
by.label(
'<Picker> Provides multiple options to choose from, using either a dropdown menu or a dialog.',
),
).tap();
});
afterAll(async () => {
await element(by.label('Back')).tap();
});
it('should be selectable by ID', async () => {
await expect(element(by.id('basic-picker'))).toBeVisible();
});
});
+81
View File
@@ -0,0 +1,81 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @emails oncall+react_native
* @format
*/
/* global device, element, by, expect */
const jestExpect = require('expect');
describe('Switch', () => {
beforeEach(async () => {
await device.reloadReactNative();
await element(by.id('explorer_search')).replaceText('<Switch>');
await element(by.label('<Switch> Native boolean input')).tap();
});
it('Switch that starts off should switch', async () => {
const testID = 'on-off-initial-off';
const indicatorID = 'on-off-initial-off-indicator';
await expect(element(by.id(testID))).toHaveValue('0');
await expect(element(by.id(indicatorID))).toHaveText('Off');
await element(by.id(testID)).tap();
await expect(element(by.id(testID))).toHaveValue('1');
await expect(element(by.id(indicatorID))).toHaveText('On');
});
it('Switch that starts on should switch', async () => {
const testID = 'on-off-initial-on';
const indicatorID = 'on-off-initial-on-indicator';
await expect(element(by.id(testID))).toHaveValue('1');
await expect(element(by.id(indicatorID))).toHaveText('On');
await element(by.id(testID)).tap();
await expect(element(by.id(testID))).toHaveValue('0');
await expect(element(by.id(indicatorID))).toHaveText('Off');
});
it('disabled switch should not toggle', async () => {
const onTestID = 'disabled-initial-on';
const offTestID = 'disabled-initial-off';
const onIndicatorID = 'disabled-initial-on-indicator';
const offIndicatorID = 'disabled-initial-off-indicator';
await expect(element(by.id(onTestID))).toHaveValue('1');
await expect(element(by.id(onIndicatorID))).toHaveText('On');
try {
await element(by.id(onTestID)).tap();
throw new Error('Does not match');
} catch (err) {
jestExpect(err.message.message).toEqual(
jestExpect.stringContaining(
'Cannot perform action due to constraint(s) failure',
),
);
}
await expect(element(by.id(onTestID))).toHaveValue('1');
await expect(element(by.id(onIndicatorID))).toHaveText('On');
await expect(element(by.id(offTestID))).toHaveValue('0');
await expect(element(by.id(offIndicatorID))).toHaveText('Off');
try {
await element(by.id(offTestID)).tap();
throw new Error('Does not match');
} catch (err) {
jestExpect(err.message.message).toEqual(
jestExpect.stringContaining(
'Cannot perform action due to constraint(s) failure',
),
);
}
await expect(element(by.id(offTestID))).toHaveValue('0');
await expect(element(by.id(offIndicatorID))).toHaveText('Off');
});
});
+72
View File
@@ -0,0 +1,72 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @emails oncall+react_native
* @format
*/
/* global element, by, expect */
describe('Touchable', () => {
beforeAll(async () => {
await element(by.id('explorer_search')).replaceText('<Touchable*');
await element(
by.label('<Touchable*> and onPress Touchable and onPress examples.'),
).tap();
});
afterAll(async () => {
//TODO - remove app state persistency, till then, we must go back to main screen,
await element(by.label('Back')).tap();
});
it('Touchable Highlight should be tappable', async () => {
const buttonID = 'touchable_highlight_image_button';
const button2ID = 'touchable_highlight_text_button';
const consoleID = 'touchable_highlight_console';
await element(by.id(buttonID)).tap();
await expect(element(by.id(consoleID))).toHaveText(
'TouchableHighlight onPress',
);
await element(by.id(buttonID)).tap();
await expect(element(by.id(consoleID))).toHaveText(
'2x TouchableHighlight onPress',
);
await element(by.id(button2ID)).tap();
await expect(element(by.id(consoleID))).toHaveText(
'3x TouchableHighlight onPress',
);
});
it('Touchable Without Feedback should be tappable', async () => {
const buttonID = 'touchable_without_feedback_button';
const consoleID = 'touchable_without_feedback_console';
await element(by.id(buttonID)).tap();
await expect(element(by.id(consoleID))).toHaveText(
'TouchableWithoutFeedback onPress',
);
await element(by.id(buttonID)).tap();
await expect(element(by.id(consoleID))).toHaveText(
'2x TouchableWithoutFeedback onPress',
);
});
it('Text should be tappable', async () => {
const buttonID = 'tappable_text';
const consoleID = 'tappable_text_console';
await element(by.id(buttonID)).tap();
await expect(element(by.id(consoleID))).toHaveText('text onPress');
await element(by.id(buttonID)).tap();
await expect(element(by.id(consoleID))).toHaveText('2x text onPress');
});
});
+8 -2
View File
@@ -46,10 +46,13 @@ class DatePickerExample extends React.Component<
return (
<View>
<WithLabel label="Value:">
<Text>
<Text testID="date-and-time-indicator">
{this.state.date.toLocaleDateString() +
' ' +
this.state.date.toLocaleTimeString()}
this.state.date.toLocaleTimeString([], {
hour: '2-digit',
minute: '2-digit',
})}
</Text>
</WithLabel>
<WithLabel label="Timezone:">
@@ -62,6 +65,7 @@ class DatePickerExample extends React.Component<
</WithLabel>
<Heading label="Date + time picker" />
<DatePickerIOS
testID="date-and-time"
date={this.state.date}
mode="datetime"
timeZoneOffsetInMinutes={this.state.timeZoneOffsetInHours * 60}
@@ -69,6 +73,7 @@ class DatePickerExample extends React.Component<
/>
<Heading label="Date picker" />
<DatePickerIOS
testID="date-only"
date={this.state.date}
mode="date"
timeZoneOffsetInMinutes={this.state.timeZoneOffsetInHours * 60}
@@ -76,6 +81,7 @@ class DatePickerExample extends React.Component<
/>
<Heading label="Time picker, 10-minute interval" />
<DatePickerIOS
testID="time-only"
date={this.state.date}
mode="time"
timeZoneOffsetInMinutes={this.state.timeZoneOffsetInHours * 60}
+1
View File
@@ -38,6 +38,7 @@ class PickerExample extends React.Component<{}, $FlowFixMeState> {
<RNTesterPage title="<Picker>">
<RNTesterBlock title="Basic Picker">
<Picker
testID="basic-picker"
style={styles.picker}
selectedValue={this.state.selected1}
onValueChange={this.onValueChange.bind(this, 'selected1')}>
+6 -12
View File
@@ -70,17 +70,8 @@ class RNTesterApp extends React.Component<Props, RNTesterNavigationState> {
);
const urlAction = URIActionMap(url);
const launchAction = exampleAction || urlAction;
if (err || !storedString) {
const initialAction = launchAction || {type: 'InitialAction'};
this.setState(RNTesterNavigationReducer(undefined, initialAction));
return;
}
const storedState = JSON.parse(storedString);
if (launchAction) {
this.setState(RNTesterNavigationReducer(storedState, launchAction));
return;
}
this.setState(storedState);
const initialAction = launchAction || {type: 'InitialAction'};
this.setState(RNTesterNavigationReducer(undefined, initialAction));
});
});
@@ -179,7 +170,10 @@ RNTesterList.ComponentExamples.concat(RNTesterList.APIExamples).forEach(
render() {
return (
<SnapshotViewIOS>
<RNTesterExampleContainer module={ExampleModule} />
<RNTesterExampleContainer
module={ExampleModule}
displayFilter={false}
/>
</SnapshotViewIOS>
);
}
+29 -1
View File
@@ -12,6 +12,7 @@
const React = require('react');
const {Platform} = require('react-native');
const RNTesterBlock = require('./RNTesterBlock');
const RNTesterExampleFilter = require('./RNTesterExampleFilter');
const RNTesterPage = require('./RNTesterPage');
class RNTesterExampleContainer extends React.Component {
@@ -37,9 +38,36 @@ class RNTesterExampleContainer extends React.Component {
return <this.props.module />;
}
if (
this.props.displayFilter === false ||
this.props.module.examples.length === 1
) {
return (
<RNTesterPage title={this.props.title}>
{this.props.module.examples.map(this.renderExample)}
</RNTesterPage>
);
}
const filter = ({example, filterRegex}) => filterRegex.test(example.title);
const sections = [
{
data: this.props.module.examples,
title: 'EXAMPLES',
key: 'e',
},
];
return (
<RNTesterPage title={this.props.title}>
{this.props.module.examples.map(this.renderExample)}
<RNTesterExampleFilter
sections={sections}
filter={filter}
render={({filteredSections}) =>
filteredSections[0].data.map(this.renderExample)
}
/>
</RNTesterPage>
);
}
+106
View File
@@ -0,0 +1,106 @@
/**
* Copyright (c) Facebook, Inc. and 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 StyleSheet = require('StyleSheet');
const TextInput = require('TextInput');
const View = require('View');
type Props = {
filter: Function,
render: Function,
/*
* $FlowFixMe: We shoudl better type this (ideally so that render and filter are
* aware of what they receive)
*/
sections: Object,
disableSearch?: boolean,
};
type State = {
filter: string,
};
class RNTesterExampleFilter extends React.Component<Props, State> {
state = {filter: ''};
render() {
const filterText = this.state.filter;
let filterRegex = /.*/;
try {
filterRegex = new RegExp(String(filterText), 'i');
} catch (error) {
console.warn(
'Failed to create RegExp: %s\n%s',
filterText,
error.message,
);
}
const filter = example =>
this.props.disableSearch || this.props.filter({example, filterRegex});
const filteredSections = this.props.sections.map(section => ({
...section,
data: section.data.filter(filter),
}));
return (
<View>
{this._renderTextInput()}
{this.props.render({filteredSections})}
</View>
);
}
_renderTextInput(): ?React.Element<any> {
if (this.props.disableSearch) {
return null;
}
return (
<View style={styles.searchRow}>
<TextInput
autoCapitalize="none"
autoCorrect={false}
clearButtonMode="always"
onChangeText={text => {
this.setState(() => ({filter: text}));
}}
placeholder="Search..."
underlineColorAndroid="transparent"
style={styles.searchTextInput}
testID="explorer_search"
value={this.state.filter}
/>
</View>
);
}
}
const styles = StyleSheet.create({
searchRow: {
backgroundColor: '#eeeeee',
padding: 10,
},
searchTextInput: {
backgroundColor: 'white',
borderColor: '#cccccc',
borderRadius: 3,
borderWidth: 1,
paddingLeft: 8,
paddingVertical: 0,
height: 35,
},
});
module.exports = RNTesterExampleFilter;
+30 -89
View File
@@ -15,17 +15,15 @@ const React = require('react');
const SectionList = require('SectionList');
const StyleSheet = require('StyleSheet');
const Text = require('Text');
const TextInput = require('TextInput');
const TouchableHighlight = require('TouchableHighlight');
const RNTesterActions = require('./RNTesterActions');
const RNTesterStatePersister = require('./RNTesterStatePersister');
const RNTesterExampleFilter = require('./RNTesterExampleFilter');
const View = require('View');
/* $FlowFixMe(>=0.78.0 site=react_native_android_fb) This issue was found when
* making Flow check .android.js files. */
import type {RNTesterExample} from './RNTesterList.ios';
import type {PassProps} from './RNTesterStatePersister';
import type {TextStyleProp, ViewStyleProp} from 'StyleSheet';
import type {ViewStyleProp} from 'StyleSheet';
type Props = {
onNavigate: Function,
@@ -33,8 +31,6 @@ type Props = {
ComponentExamples: Array<RNTesterExample>,
APIExamples: Array<RNTesterExample>,
},
persister: PassProps<*>,
searchTextInputStyle: TextStyleProp,
style?: ?ViewStyleProp,
};
@@ -74,55 +70,47 @@ const renderSectionHeader = ({section}) => (
class RNTesterExampleList extends React.Component<Props, $FlowFixMeState> {
render() {
const filterText = this.props.persister.state.filter;
let filterRegex = /.*/;
try {
filterRegex = new RegExp(String(filterText), 'i');
} catch (error) {
console.warn(
'Failed to create RegExp: %s\n%s',
filterText,
error.message,
);
}
const filter = example =>
const filter = ({example, filterRegex}) =>
/* $FlowFixMe(>=0.68.0 site=react_native_fb) This comment suppresses an
* error found when Flow v0.68 was deployed. To see the error delete this
* comment and run Flow. */
this.props.disableSearch ||
(filterRegex.test(example.module.title) &&
(!Platform.isTV || example.supportsTVOS));
* error found when Flow v0.68 was deployed. To see the error delete this
* comment and run Flow. */
filterRegex.test(example.module.title) &&
(!Platform.isTV || example.supportsTVOS);
const sections = [
{
data: this.props.list.ComponentExamples.filter(filter),
data: this.props.list.ComponentExamples,
title: 'COMPONENTS',
key: 'c',
},
{
data: this.props.list.APIExamples.filter(filter),
data: this.props.list.APIExamples,
title: 'APIS',
key: 'a',
},
];
return (
<View style={[styles.listContainer, this.props.style]}>
{this._renderTitleRow()}
{this._renderTextInput()}
<SectionList
ItemSeparatorComponent={ItemSeparator}
contentContainerStyle={{backgroundColor: 'white'}}
style={styles.list}
<RNTesterExampleFilter
sections={sections}
renderItem={this._renderItem}
enableEmptySections={true}
itemShouldUpdate={this._itemShouldUpdate}
keyboardShouldPersistTaps="handled"
automaticallyAdjustContentInsets={false}
keyboardDismissMode="on-drag"
renderSectionHeader={renderSectionHeader}
filter={filter}
render={({filteredSections}) => (
<SectionList
ItemSeparatorComponent={ItemSeparator}
contentContainerStyle={styles.sectionListContentContainer}
style={styles.list}
sections={filteredSections}
renderItem={this._renderItem}
enableEmptySections={true}
itemShouldUpdate={this._itemShouldUpdate}
keyboardShouldPersistTaps="handled"
automaticallyAdjustContentInsets={false}
keyboardDismissMode="on-drag"
renderSectionHeader={renderSectionHeader}
/>
)}
/>
</View>
);
@@ -164,32 +152,6 @@ class RNTesterExampleList extends React.Component<Props, $FlowFixMeState> {
);
}
_renderTextInput(): ?React.Element<any> {
/* $FlowFixMe(>=0.68.0 site=react_native_fb) This comment suppresses an
* error found when Flow v0.68 was deployed. To see the error delete this
* comment and run Flow. */
if (this.props.disableSearch) {
return null;
}
return (
<View style={styles.searchRow}>
<TextInput
autoCapitalize="none"
autoCorrect={false}
clearButtonMode="always"
onChangeText={text => {
this.props.persister.setState(() => ({filter: text}));
}}
placeholder="Search..."
underlineColorAndroid="transparent"
style={[styles.searchTextInput, this.props.searchTextInputStyle]}
testID="explorer_search"
value={this.props.persister.state.filter}
/>
</View>
);
}
_handleRowPress(exampleKey: string): void {
this.props.onNavigate(RNTesterActions.ExampleAction(exampleKey));
}
@@ -199,17 +161,6 @@ const ItemSeparator = ({highlighted}) => (
<View style={highlighted ? styles.separatorHighlighted : styles.separator} />
);
/* $FlowFixMe(>=0.85.0 site=react_native_fb) This comment suppresses an error
* found when Flow v0.85 was deployed. To see the error, delete this comment
* and run Flow. */
RNTesterExampleList = RNTesterStatePersister.createContainer(
RNTesterExampleList,
{
cacheKeySuffix: () => 'mainList',
getInitialState: () => ({filter: ''}),
},
);
const styles = StyleSheet.create({
listContainer: {
flex: 1,
@@ -238,6 +189,9 @@ const styles = StyleSheet.create({
height: StyleSheet.hairlineWidth,
backgroundColor: 'rgb(217, 217, 217)',
},
sectionListContentContainer: {
backgroundColor: 'white',
},
rowTitleText: {
fontSize: 17,
fontWeight: '500',
@@ -247,19 +201,6 @@ const styles = StyleSheet.create({
color: '#888888',
lineHeight: 20,
},
searchRow: {
backgroundColor: '#eeeeee',
padding: 10,
},
searchTextInput: {
backgroundColor: 'white',
borderColor: '#cccccc',
borderRadius: 3,
borderWidth: 1,
paddingLeft: 8,
paddingVertical: 0,
height: 35,
},
});
module.exports = RNTesterExampleList;
-3
View File
@@ -9,7 +9,6 @@
*/
'use strict';
const ActivityIndicator = require('ActivityIndicator');
const Platform = require('Platform');
const React = require('react');
const ReactNative = require('react-native');
@@ -155,7 +154,6 @@ if (Platform.OS === 'ios') {
autoscrollToTopThreshold: 10,
}}
style={styles.scrollView}>
<ActivityIndicator style={{height: 40}} />
{this.state.items.map(item =>
React.cloneElement(item, {key: item.props.msg}),
)}
@@ -168,7 +166,6 @@ if (Platform.OS === 'ios') {
autoscrollToTopThreshold: 10,
}}
style={[styles.scrollView, styles.horizontalScrollView]}>
<ActivityIndicator style={{width: 40}} />
{this.state.items.map(item =>
React.cloneElement(item, {key: item.props.msg, style: null}),
)}
+88 -15
View File
@@ -11,10 +11,37 @@
'use strict';
const React = require('react');
const ReactNative = require('react-native');
const {Switch, Text, View} = ReactNative;
const {Switch, Text, View} = require('react-native');
class BasicSwitchExample extends React.Component<{}, $FlowFixMeState> {
type OnOffIndicatorProps = $ReadOnly<{|on: boolean, testID: string|}>;
function OnOffIndicator({on, testID}: OnOffIndicatorProps) {
return <Text testID={testID}>{on ? 'On' : 'Off'}</Text>;
}
type ExampleRowProps = $ReadOnly<{|children: React.Node|}>;
function ExampleRow({children}: ExampleRowProps) {
return (
<View
style={{
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
marginBottom: 10,
}}>
{children}
</View>
);
}
type SimpleSwitchExampleState = $ReadOnly<{|
trueSwitchIsOn: boolean,
falseSwitchIsOn: boolean,
|}>;
class BasicSwitchExample extends React.Component<
{||},
SimpleSwitchExampleState,
> {
state = {
trueSwitchIsOn: true,
falseSwitchIsOn: false,
@@ -23,26 +50,72 @@ class BasicSwitchExample extends React.Component<{}, $FlowFixMeState> {
render() {
return (
<View>
<Switch
onValueChange={value => this.setState({falseSwitchIsOn: value})}
style={{marginBottom: 10}}
value={this.state.falseSwitchIsOn}
/>
<Switch
onValueChange={value => this.setState({trueSwitchIsOn: value})}
value={this.state.trueSwitchIsOn}
/>
<ExampleRow>
<Switch
testID="on-off-initial-off"
onValueChange={value => this.setState({falseSwitchIsOn: value})}
value={this.state.falseSwitchIsOn}
/>
<OnOffIndicator
on={this.state.falseSwitchIsOn}
testID="on-off-initial-off-indicator"
/>
</ExampleRow>
<ExampleRow>
<Switch
testID="on-off-initial-on"
onValueChange={value => this.setState({trueSwitchIsOn: value})}
value={this.state.trueSwitchIsOn}
/>
<OnOffIndicator
on={this.state.trueSwitchIsOn}
testID="on-off-initial-on-indicator"
/>
</ExampleRow>
</View>
);
}
}
class DisabledSwitchExample extends React.Component<{}> {
class DisabledSwitchExample extends React.Component<
{||},
SimpleSwitchExampleState,
> {
state = {
trueSwitchIsOn: true,
falseSwitchIsOn: false,
};
render() {
return (
<View>
<Switch disabled={true} style={{marginBottom: 10}} value={true} />
<Switch disabled={true} value={false} />
<ExampleRow>
<Switch
testID="disabled-initial-off"
disabled={true}
onValueChange={value => this.setState({falseSwitchIsOn: value})}
value={this.state.falseSwitchIsOn}
/>
<OnOffIndicator
on={this.state.falseSwitchIsOn}
testID="disabled-initial-off-indicator"
/>
</ExampleRow>
<ExampleRow>
<Switch
testID="disabled-initial-on"
disabled={true}
onValueChange={value => this.setState({trueSwitchIsOn: value})}
value={this.state.trueSwitchIsOn}
/>
<OnOffIndicator
on={this.state.trueSwitchIsOn}
testID="disabled-initial-on-indicator"
/>
</ExampleRow>
</View>
);
}
+61 -28
View File
@@ -45,30 +45,7 @@ exports.examples = [
'background color change as well with the activeOpacity and ' +
'underlayColor props.',
render: function() {
return (
<View>
<View style={styles.row}>
<TouchableHighlight
style={styles.wrapper}
onPress={() => console.log('stock THW image - highlight')}>
<Image source={heartImage} style={styles.image} />
</TouchableHighlight>
<TouchableHighlight
style={styles.wrapper}
activeOpacity={1}
tvParallaxProperties={{
pressMagnification: 1.3,
pressDuration: 0.6,
}}
underlayColor="rgb(210, 230, 255)"
onPress={() => console.log('custom THW text - highlight')}>
<View style={styles.wrapperCustom}>
<Text style={styles.text}>Tap Here For Custom Highlight!</Text>
</View>
</TouchableHighlight>
</View>
</View>
);
return <TouchableHighlightBox />;
},
},
{
@@ -157,6 +134,57 @@ exports.examples = [
},
];
class TouchableHighlightBox extends React.Component<{}, $FlowFixMeState> {
state = {
timesPressed: 0,
};
touchableOnPress = () => {
this.setState({
timesPressed: this.state.timesPressed + 1,
});
};
render() {
let textLog = '';
if (this.state.timesPressed > 1) {
textLog = this.state.timesPressed + 'x TouchableHighlight onPress';
} else if (this.state.timesPressed > 0) {
textLog = 'TouchableHighlight onPress';
}
return (
<View>
<View style={styles.row}>
<TouchableHighlight
style={styles.wrapper}
testID="touchable_highlight_image_button"
onPress={this.touchableOnPress}>
<Image source={heartImage} style={styles.image} />
</TouchableHighlight>
<TouchableHighlight
style={styles.wrapper}
testID="touchable_highlight_text_button"
activeOpacity={1}
tvParallaxProperties={{
pressMagnification: 1.3,
pressDuration: 0.6,
}}
underlayColor="rgb(210, 230, 255)"
onPress={this.touchableOnPress}>
<View style={styles.wrapperCustom}>
<Text style={styles.text}>Tap Here For Custom Highlight!</Text>
</View>
</TouchableHighlight>
</View>
<View style={styles.logBox}>
<Text testID="touchable_highlight_console">{textLog}</Text>
</View>
</View>
);
}
}
class TouchableWithoutFeedbackBox extends React.Component<{}, $FlowFixMeState> {
state = {
timesPressed: 0,
@@ -178,13 +206,15 @@ class TouchableWithoutFeedbackBox extends React.Component<{}, $FlowFixMeState> {
return (
<View>
<TouchableWithoutFeedback onPress={this.textOnPress}>
<TouchableWithoutFeedback
onPress={this.textOnPress}
testID="touchable_without_feedback_button">
<View style={styles.wrapperCustom}>
<Text style={styles.text}>Tap Here For No Feedback!</Text>
</View>
</TouchableWithoutFeedback>
<View style={styles.logBox}>
<Text>{textLog}</Text>
<Text testID="touchable_without_feedback_console">{textLog}</Text>
</View>
</View>
);
@@ -212,11 +242,14 @@ class TextOnPressBox extends React.Component<{}, $FlowFixMeState> {
return (
<View>
<Text style={styles.textBlock} onPress={this.textOnPress}>
<Text
style={styles.textBlock}
testID="tappable_text"
onPress={this.textOnPress}>
Text has built-in onPress handling
</Text>
<View style={styles.logBox}>
<Text>{textLog}</Text>
<Text testID="tappable_text_console">{textLog}</Text>
</View>
</View>
);
+15 -2
View File
@@ -12,6 +12,7 @@ NSString *const RCTErrorDomain = @"RCTErrorDomain";
NSString *const RCTJSStackTraceKey = @"RCTJSStackTraceKey";
NSString *const RCTJSRawStackTraceKey = @"RCTJSRawStackTraceKey";
NSString *const RCTFatalExceptionName = @"RCTFatalException";
NSString *const RCTUntruncatedMessageKey = @"RCTUntruncatedMessageKey";
static NSString *const RCTAssertFunctionStack = @"RCTAssertFunctionStack";
@@ -128,8 +129,20 @@ void RCTFatal(NSError *error)
@try {
#endif
NSString *name = [NSString stringWithFormat:@"%@: %@", RCTFatalExceptionName, error.localizedDescription];
NSString *message = RCTFormatError(error.localizedDescription, error.userInfo[RCTJSStackTraceKey], 75);
@throw [[NSException alloc] initWithName:name reason:message userInfo:nil];
// Truncate the localized description to 175 characters to avoid wild screen overflows
NSString *message = RCTFormatError(error.localizedDescription, error.userInfo[RCTJSStackTraceKey], 175);
// Attach an untruncated copy of the description to the userInfo, in case it is needed
NSMutableDictionary *userInfo = [error.userInfo mutableCopy];
[userInfo setObject:RCTFormatError(error.localizedDescription, error.userInfo[RCTJSStackTraceKey], -1)
forKey:RCTUntruncatedMessageKey];
// Expected resulting exception information:
// name: RCTFatalException: <underlying error description>
// reason: <underlying error description plus JS stack trace, truncated to 175 characters>
// userInfo: <underlying error userinfo, plus untruncated description plus JS stack trace>
@throw [[NSException alloc] initWithName:name reason:message userInfo:userInfo];
#if DEBUG
} @catch (NSException *e) {}
#endif
+2 -2
View File
@@ -21,8 +21,8 @@ static void __makeVersion()
{
__rnVersion = @{
RCTVersionMajor: @(0),
RCTVersionMinor: @(0),
RCTVersionPatch: @(0),
RCTVersionMinor: @(58),
RCTVersionPatch: @(4),
RCTVersionPrerelease: [NSNull null],
};
}
+55 -23
View File
@@ -47,7 +47,7 @@
#else
self.windowLevel = UIWindowLevelStatusBar - 1;
#endif
self.backgroundColor = [UIColor colorWithRed:0.8 green:0 blue:0 alpha:1];
self.backgroundColor = [UIColor colorWithRed:0.1 green:0.1 blue:0.1 alpha:1];
self.hidden = YES;
UIViewController *rootController = [UIViewController new];
@@ -58,7 +58,7 @@
const CGFloat buttonHeight = 60;
CGRect detailsFrame = rootView.bounds;
detailsFrame.size.height -= buttonHeight;
detailsFrame.size.height -= buttonHeight + [self bottomSafeViewHeight];
_stackTraceTableView = [[UITableView alloc] initWithFrame:detailsFrame style:UITableViewStylePlain];
_stackTraceTableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
@@ -73,10 +73,10 @@
[rootView addSubview:_stackTraceTableView];
#if TARGET_OS_SIMULATOR
NSString *reloadText = @"Reload JS (\u2318R)";
NSString *dismissText = @"Dismiss (ESC)";
NSString *copyText = @"Copy (\u2325\u2318C)";
NSString *extraText = @"Extra Info (\u2318E)";
NSString *reloadText = @"Reload\n(\u2318R)";
NSString *dismissText = @"Dismiss\n(ESC)";
NSString *copyText = @"Copy\n(\u2325\u2318C)";
NSString *extraText = @"Extra Info\n(\u2318E)";
#else
NSString *reloadText = @"Reload JS";
NSString *dismissText = @"Dismiss";
@@ -88,53 +88,85 @@
dismissButton.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleRightMargin;
dismissButton.accessibilityIdentifier = @"redbox-dismiss";
dismissButton.titleLabel.font = [UIFont systemFontOfSize:13];
dismissButton.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
dismissButton.titleLabel.textAlignment = NSTextAlignmentCenter;
dismissButton.backgroundColor = [UIColor colorWithRed:0.1 green:0.1 blue:0.1 alpha:1];
[dismissButton setTitle:dismissText forState:UIControlStateNormal];
[dismissButton setTitleColor:[UIColor colorWithWhite:1 alpha:0.5] forState:UIControlStateNormal];
[dismissButton setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted];
[dismissButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[dismissButton setTitleColor:[UIColor colorWithWhite:1 alpha:0.5] forState:UIControlStateHighlighted];
[dismissButton addTarget:self action:@selector(dismiss) forControlEvents:UIControlEventTouchUpInside];
UIButton *reloadButton = [UIButton buttonWithType:UIButtonTypeCustom];
reloadButton.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin;
reloadButton.accessibilityIdentifier = @"redbox-reload";
reloadButton.titleLabel.font = [UIFont systemFontOfSize:13];
reloadButton.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
reloadButton.titleLabel.textAlignment = NSTextAlignmentCenter;
reloadButton.backgroundColor = [UIColor colorWithRed:0.1 green:0.1 blue:0.1 alpha:1];
[reloadButton setTitle:reloadText forState:UIControlStateNormal];
[reloadButton setTitleColor:[UIColor colorWithWhite:1 alpha:0.5] forState:UIControlStateNormal];
[reloadButton setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted];
[reloadButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[reloadButton setTitleColor:[UIColor colorWithWhite:1 alpha:0.5] forState:UIControlStateHighlighted];
[reloadButton addTarget:self action:@selector(reload) forControlEvents:UIControlEventTouchUpInside];
UIButton *copyButton = [UIButton buttonWithType:UIButtonTypeCustom];
copyButton.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin;
copyButton.accessibilityIdentifier = @"redbox-copy";
copyButton.titleLabel.font = [UIFont systemFontOfSize:13];
copyButton.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
copyButton.titleLabel.textAlignment = NSTextAlignmentCenter;
copyButton.backgroundColor = [UIColor colorWithRed:0.1 green:0.1 blue:0.1 alpha:1];
[copyButton setTitle:copyText forState:UIControlStateNormal];
[copyButton setTitleColor:[UIColor colorWithWhite:1 alpha:0.5] forState:UIControlStateNormal];
[copyButton setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted];
[copyButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[copyButton setTitleColor:[UIColor colorWithWhite:1 alpha:0.5] forState:UIControlStateHighlighted];
[copyButton addTarget:self action:@selector(copyStack) forControlEvents:UIControlEventTouchUpInside];
UIButton *extraButton = [UIButton buttonWithType:UIButtonTypeCustom];
extraButton.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin;
extraButton.accessibilityIdentifier = @"redbox-extra";
extraButton.titleLabel.font = [UIFont systemFontOfSize:13];
extraButton.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
extraButton.titleLabel.textAlignment = NSTextAlignmentCenter;
extraButton.backgroundColor = [UIColor colorWithRed:0.1 green:0.1 blue:0.1 alpha:1];
[extraButton setTitle:extraText forState:UIControlStateNormal];
[extraButton setTitleColor:[UIColor colorWithWhite:1 alpha:0.5] forState:UIControlStateNormal];
[extraButton setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted];
[extraButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[extraButton setTitleColor:[UIColor colorWithWhite:1 alpha:0.5] forState:UIControlStateHighlighted];
[extraButton addTarget:self action:@selector(showExtraDataViewController) forControlEvents:UIControlEventTouchUpInside];
CGFloat buttonWidth = self.bounds.size.width / 4;
dismissButton.frame = CGRectMake(0, self.bounds.size.height - buttonHeight, buttonWidth, buttonHeight);
reloadButton.frame = CGRectMake(buttonWidth, self.bounds.size.height - buttonHeight, buttonWidth, buttonHeight);
copyButton.frame = CGRectMake(buttonWidth * 2, self.bounds.size.height - buttonHeight, buttonWidth, buttonHeight);
extraButton.frame = CGRectMake(buttonWidth * 3, self.bounds.size.height - buttonHeight, buttonWidth, buttonHeight);
CGFloat bottomButtonHeight = self.bounds.size.height - buttonHeight - [self bottomSafeViewHeight];
dismissButton.frame = CGRectMake(0, bottomButtonHeight, buttonWidth, buttonHeight);
reloadButton.frame = CGRectMake(buttonWidth, bottomButtonHeight, buttonWidth, buttonHeight);
copyButton.frame = CGRectMake(buttonWidth * 2, bottomButtonHeight, buttonWidth, buttonHeight);
extraButton.frame = CGRectMake(buttonWidth * 3, bottomButtonHeight, buttonWidth, buttonHeight);
UIView *topBorder = [[UIView alloc] initWithFrame:CGRectMake(0, bottomButtonHeight + 1, rootView.frame.size.width, 1)];
topBorder.backgroundColor = [UIColor colorWithRed:0.70 green:0.70 blue:0.70 alpha:1.0];
[rootView addSubview:dismissButton];
[rootView addSubview:reloadButton];
[rootView addSubview:copyButton];
[rootView addSubview:extraButton];
[rootView addSubview:topBorder];
UIView *bottomSafeView = [UIView new];
bottomSafeView.backgroundColor = [UIColor colorWithRed:0.1 green:0.1 blue:0.1 alpha:1];
bottomSafeView.frame = CGRectMake(0, self.bounds.size.height - [self bottomSafeViewHeight], self.bounds.size.width, [self bottomSafeViewHeight]);
[rootView addSubview:bottomSafeView];
}
return self;
}
- (NSInteger)bottomSafeViewHeight
{
if (@available(iOS 11.0, *)) {
return [UIApplication sharedApplication].delegate.window.safeAreaInsets.bottom;
} else {
return 0;
}
}
RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
- (void)dealloc
@@ -247,14 +279,14 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
- (UITableViewCell *)reuseCell:(UITableViewCell *)cell forErrorMessage:(NSString *)message
{
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"msg-cell"];
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"msg-cell"];
cell.textLabel.accessibilityIdentifier = @"redbox-error";
cell.textLabel.textColor = [UIColor whiteColor];
cell.textLabel.font = [UIFont boldSystemFontOfSize:16];
cell.textLabel.lineBreakMode = NSLineBreakByWordWrapping;
cell.textLabel.numberOfLines = 0;
cell.detailTextLabel.textColor = [UIColor whiteColor];
cell.backgroundColor = [UIColor clearColor];
cell.backgroundColor = [UIColor colorWithRed:0.82 green:0.10 blue:0.15 alpha:1.0];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
@@ -267,11 +299,11 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
{
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"cell"];
cell.textLabel.textColor = [UIColor colorWithWhite:1 alpha:0.9];
cell.textLabel.textColor = [UIColor whiteColor];
cell.textLabel.font = [UIFont fontWithName:@"Menlo-Regular" size:14];
cell.textLabel.lineBreakMode = NSLineBreakByCharWrapping;
cell.textLabel.numberOfLines = 2;
cell.detailTextLabel.textColor = [UIColor colorWithWhite:1 alpha:0.7];
cell.detailTextLabel.textColor = [UIColor colorWithRed:0.70 green:0.70 blue:0.70 alpha:1.0];
cell.detailTextLabel.font = [UIFont fontWithName:@"Menlo-Regular" size:11];
cell.detailTextLabel.lineBreakMode = NSLineBreakByTruncatingMiddle;
cell.backgroundColor = [UIColor clearColor];
+10 -5
View File
@@ -4023,14 +4023,10 @@
"../third-party/glog-0.3.5/src/glog/raw_logging.h",
"../third-party/glog-0.3.5/src/glog/stl_logging.h",
"../third-party/glog-0.3.5/src/glog/vlog_is_on.h",
"../third-party/folly-2018.10.22.00/folly/detail/MallocImpl.cpp",
"../third-party/folly-2018.10.22.00/folly/portability/BitsFunctexcept.cpp",
"../third-party/folly-2018.10.22.00/folly/memory/detail/MallocImpl.cpp",
"../third-party/folly-2018.10.22.00/folly/Demangle.cpp",
"../third-party/folly-2018.10.22.00/folly/StringBase.cpp",
"../third-party/folly-2018.10.22.00/folly/Unicode.cpp",
"../third-party/folly-2018.10.22.00/folly/AtomicIntrusiveLinkedList.h",
"../third-party/folly-2018.10.22.00/folly/Bits.cpp",
"../third-party/folly-2018.10.22.00/folly/Bits.h",
"../third-party/folly-2018.10.22.00/folly/Conv.cpp",
"../third-party/folly-2018.10.22.00/folly/Conv.h",
"../third-party/folly-2018.10.22.00/folly/dynamic-inl.h",
@@ -4043,6 +4039,15 @@
"../third-party/folly-2018.10.22.00/folly/MoveWrapper.h",
"../third-party/folly-2018.10.22.00/folly/Optional.h",
"../third-party/folly-2018.10.22.00/folly/ScopeGuard.h",
"../third-party/folly-2018.10.22.00/folly/json_pointer.cpp",
"../third-party/folly-2018.10.22.00/folly/String.cpp",
"../third-party/folly-2018.10.22.00/folly/detail/Demangle.cpp",
"../third-party/folly-2018.10.22.00/folly/hash/SpookyHashV2.cpp",
"../third-party/folly-2018.10.22.00/folly/lang/ColdClass.cpp",
"../third-party/folly-2018.10.22.00/folly/container/detail/F14Table.cpp",
"../third-party/folly-2018.10.22.00/folly/ScopeGuard.cpp",
"../third-party/folly-2018.10.22.00/folly/lang/Assume.cpp",
"../third-party/folly-2018.10.22.00/folly/Format.cpp",
"../third-party/double-conversion-1.1.6/src/bignum-dtoa.cc",
"../third-party/double-conversion-1.1.6/src/bignum-dtoa.h",
"../third-party/double-conversion-1.1.6/src/bignum.cc",
+4 -1
View File
@@ -303,7 +303,10 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init)
contentOffset.y = -(scrollViewSize.height - subviewSize.height) / 2.0;
}
}
super.contentOffset = contentOffset;
super.contentOffset = CGPointMake(
RCTSanitizeNaNValue(contentOffset.x, @"scrollView.contentOffset.x"),
RCTSanitizeNaNValue(contentOffset.y, @"scrollView.contentOffset.y"));
}
- (void)setFrame:(CGRect)frame
+5 -5
View File
@@ -266,8 +266,8 @@ task packageReactNdkLibsForBuck(dependsOn: packageReactNdkLibs, type: Copy) {
}
android {
compileSdkVersion 27
buildToolsVersion "27.0.3"
compileSdkVersion 28
buildToolsVersion "28.0.2"
defaultConfig {
minSdkVersion 16
@@ -316,14 +316,14 @@ android {
dependencies {
api 'com.facebook.infer.annotation:infer-annotation:0.11.2'
api 'javax.inject:javax.inject:1'
api 'com.android.support:appcompat-v7:27.1.1'
api 'com.android.support:appcompat-v7:28.0.0'
api "com.facebook.fresco:fresco:${FRESCO_VERSION}"
api "com.facebook.fresco:imagepipeline-okhttp3:${FRESCO_VERSION}"
api 'com.facebook.soloader:soloader:0.5.1'
api "com.facebook.soloader:soloader:${SO_LOADER_VERSION}"
api 'com.google.code.findbugs:jsr305:3.0.2'
api "com.squareup.okhttp3:okhttp:${OKHTTP_VERSION}"
api "com.squareup.okhttp3:okhttp-urlconnection:${OKHTTP_VERSION}"
api 'com.squareup.okio:okio:1.14.0'
api 'com.squareup.okio:okio:1.15.0'
compile 'org.webkit:android-jsc:r174650'
testImplementation "junit:junit:${JUNIT_VERSION}"
+3 -2
View File
@@ -1,4 +1,4 @@
VERSION_NAME=1000.0.0-master
VERSION_NAME=0.58.4
GROUP=com.facebook.react
POM_NAME=ReactNative
@@ -13,7 +13,8 @@ FEST_ASSERT_CORE_VERSION=2.0M10
ANDROID_SUPPORT_TEST_VERSION=1.0.2
FRESCO_VERSION=1.10.0
OKHTTP_VERSION=3.11.0
OKHTTP_VERSION=3.12.1
SO_LOADER_VERSION=0.6.0
BOOST_VERSION=1_63_0
DOUBLE_CONVERSION_VERSION=1.1.6
+2 -2
View File
@@ -8,8 +8,8 @@ fb_native.android_prebuilt_aar(
fb_native.remote_file(
name = "appcompat-binary-aar",
sha1 = "22b1ef4ff9ef1a3513c18eb132d597eac6ef1a86",
url = "mvn:com.android.support:appcompat-v7:aar:27.1.1",
sha1 = "132586ec59604a86703796851a063a0ac61f697b",
url = "mvn:com.android.support:appcompat-v7:aar:28.0.0",
)
fb_native.android_prebuilt_aar(
@@ -6,6 +6,8 @@
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- needed for screenshot tests -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- needed for image onError tests -->
<uses-permission android:name="android.permission.INTERNET" />
<application
android:hardwareAccelerated="false">
@@ -7,6 +7,8 @@
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- needed for screenshot tests -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- needed for image onError tests -->
<uses-permission android:name="android.permission.INTERNET" />
<application
android:hardwareAccelerated="false">
@@ -0,0 +1,55 @@
/**
* Copyright (c) 2013-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.
*/
package com.facebook.react.tests;
import android.view.View;
import com.facebook.react.testing.ReactInstanceSpecForTest;
import com.facebook.react.testing.StringRecordingModule;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.testing.ReactAppInstrumentationTestCase;
import com.facebook.react.testing.ReactTestHelper;
/**
* Integration test for {@code removeClippedSubviews} property that verify correct scrollview
* behavior
*/
public class AnimatedTransformTest extends ReactAppInstrumentationTestCase {
private StringRecordingModule mStringRecordingModule;
@Override
protected String getReactApplicationKeyUnderTest() {
return "AnimatedTransformTestApp";
}
@Override
protected ReactInstanceSpecForTest createReactInstanceSpecForTest() {
mStringRecordingModule = new StringRecordingModule();
return super.createReactInstanceSpecForTest()
.addNativeModule(mStringRecordingModule);
}
public void testAnimatedRotation() {
waitForBridgeAndUIIdle();
View button = ReactTestHelper.getViewWithReactTestId(
getActivity().getRootView(),
"TouchableOpacity");
// Tap the button which triggers the animated transform containing the
// rotation strings.
createGestureGenerator().startGesture(button).endGesture();
waitForBridgeAndUIIdle();
// The previous cast error will prevent it from getting here
assertEquals(2, mStringRecordingModule.getCalls().size());
}
}
@@ -0,0 +1,46 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.tests;
import android.view.View;
import com.facebook.react.testing.ReactAppInstrumentationTestCase;
import com.facebook.react.testing.ReactInstanceSpecForTest;
import com.facebook.react.testing.StringRecordingModule;
/**
* Simple test case to check that onError does not get called with undefined
*/
public class ImageErrorTestCase extends ReactAppInstrumentationTestCase {
private StringRecordingModule mStringRecordingModule;
@Override
protected String getReactApplicationKeyUnderTest() {
return "ImageErrorTestApp";
}
public void testErrorHasCause() throws Exception {
assertNotNull(getViewByTestId("image-1"));
assertNotNull(getViewByTestId("image-2"));
assertNotNull(getViewByTestId("image-3"));
Thread.sleep(3000);
assertEquals(3, mStringRecordingModule.getCalls().size());
assertEquals("Got error: Unsupported uri scheme! Uri is: ", mStringRecordingModule.getCalls().get(0));
assertEquals("Got error: /does/not/exist: open failed: ENOENT (No such file or directory)", mStringRecordingModule.getCalls().get(1));
assertEquals("Got error: Unexpected HTTP code Response{protocol=http/1.1, code=404, message=Not Found, url=https://typo_error_facebook.github.io/react/logo-og.png}", mStringRecordingModule.getCalls().get(2));
}
@Override
protected ReactInstanceSpecForTest createReactInstanceSpecForTest() {
mStringRecordingModule = new StringRecordingModule();
return super.createReactInstanceSpecForTest()
.addNativeModule(mStringRecordingModule);
}
}
@@ -0,0 +1,81 @@
/**
* Copyright (c) 2013-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.
*
* @providesModule AnimatedTransformTestModule
*/
'use strict';
var BatchedBridge = require('BatchedBridge');
var React = require('React');
var StyleSheet = require('StyleSheet');
var View = require('View');
var TouchableOpacity = require('TouchableOpacity');
var Text = require('Text');
var RecordingModule = require('NativeModules').Recording;
const styles = StyleSheet.create({
base: {
width: 200,
height: 200,
backgroundColor: 'red',
transform: [{rotate: '0deg'}],
},
transformed: {
transform: [{rotate: '45deg'}],
},
});
/**
* This app presents a TouchableOpacity which was the simplest way to
* demonstrate this issue. Tapping the TouchableOpacity causes an animated
* transform to be created for the rotation property. Since the property isn't
* animated itself, it comes through as a static property, but static properties
* can't currently handle strings which causes a string->double cast exception.
*/
class AnimatedTransformTestApp extends React.Component {
constructor(props) {
super(props);
this.toggle = this.toggle.bind(this);
}
state = {
flag: false,
};
toggle() {
this.setState({
flag: !this.state.flag,
});
}
render() {
// Using this to verify if its fixed.
RecordingModule.record('render');
return (
<View style={StyleSheet.absoluteFill}>
<TouchableOpacity
onPress={this.toggle}
testID="TouchableOpacity"
style={[styles.base, this.state.flag ? styles.transformed : null]}>
<Text>TouchableOpacity</Text>
</TouchableOpacity>
</View>
);
}
}
var AnimatedTransformTestModule = {
AnimatedTransformTestApp: AnimatedTransformTestApp,
};
BatchedBridge.registerCallableModule(
'AnimatedTransformTestModule',
AnimatedTransformTestModule
);
module.exports = AnimatedTransformTestModule;
@@ -0,0 +1,58 @@
/**
* Copyright (c) Facebook, Inc. and 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
*/
'use strict';
const React = require('React');
const Image = require('Image');
const StyleSheet = require('StyleSheet');
const View = require('View');
const RecordingModule = require('NativeModules').Recording;
class ImageErrorTestApp extends React.Component {
onError = e => {
RecordingModule.record('Got error: ' + e.nativeEvent.error);
};
render() {
// For some reason image-2 needs explicit height. Without it onError is not triggered.
return (
<View>
<Image
testID="image-1"
source={{uri: '/does/not/exist'}}
onError={this.onError}
/>
<Image
testID="image-2"
source={{uri: 'file:///does/not/exist'}}
style={styles.image}
onError={this.onError}
/>
<Image
testID="image-3"
source={{
uri: 'https://TYPO_ERROR_facebook.github.io/react/logo-og.png',
}}
onError={this.onError}
/>
</View>
);
}
}
const styles = StyleSheet.create({
image: {
height: 50,
width: 50,
},
});
module.exports = ImageErrorTestApp;
@@ -35,6 +35,11 @@ require('TimePickerDialogTestModule');
const AppRegistry = require('AppRegistry');
const apps = [
{
appKey: 'AnimatedTransformTestApp',
component: () =>
require('AnimatedTransformTestModule').AnimatedTransformTestApp,
},
{
appKey: 'CatalystRootViewTestApp',
component: () =>
@@ -58,6 +63,10 @@ const apps = [
appKey: 'ImageOverlayColorTestApp',
component: () => require('ImageOverlayColorTestApp'),
},
{
appKey: 'ImageErrorTestApp',
component: () => require('ImageErrorTestApp'),
},
{
appKey: 'InitialPropsTestApp',
component: () => require('InitialPropsTestApp'),
@@ -28,7 +28,6 @@ rn_android_library(
"PUBLIC",
],
deps = [
react_native_dep("third-party/android/support-annotations:android-support-annotations"),
react_native_dep("java/com/facebook/debug/debugoverlay/model:model"),
react_native_dep("java/com/facebook/systrace:systrace"),
react_native_dep("libraries/fbcore/src/main/java/com/facebook/common/logging:logging"),
@@ -7,48 +7,119 @@
package com.facebook.react.bridge;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
/*
* Interface that represents a JavaScript Promise which can be passed to the native module as a
* method parameter.
*
* Methods annotated with {@link ReactMethod} that use {@link Promise} as type of the last parameter
* Methods annotated with {@link ReactMethod} that use a {@link Promise} as the last parameter
* will be marked as "promise" and will return a promise when invoked from JavaScript.
*/
public interface Promise {
/**
* Successfully resolve the Promise.
* Successfully resolve the Promise with an optional value.
*
* @param value Object
*/
void resolve(@Nullable Object value);
/**
* Report an error which wasn't caused by an exception.
* Report an error without an exception using a custom code and error message.
*
* @param code String
* @param message String
*/
void reject(String code, String message);
/**
* Report an exception.
* Report an exception with a custom code.
*
* @param code String
* @param throwable Throwable
*/
void reject(String code, Throwable e);
void reject(String code, Throwable throwable);
/**
* Report an exception with a custom error message.
* Report an exception with a custom code and error message.
*
* @param code String
* @param message String
* @param throwable Throwable
*/
void reject(String code, String message, Throwable e);
void reject(String code, String message, Throwable throwable);
/**
* Report an error which wasn't caused by an exception.
* @deprecated Prefer passing a module-specific error code to JS.
* Using this method will pass the error code "EUNSPECIFIED".
*/
@Deprecated
void reject(String message);
/**
* Report an exception, with default error code.
* Useful in catch-all scenarios where it's unclear why the error occurred.
*
* @param throwable Throwable
*/
void reject(Throwable reason);
void reject(Throwable throwable);
/* ---------------------------
* With userInfo WritableMap
* --------------------------- */
/**
* Report an exception, with default error code, with userInfo.
* Useful in catch-all scenarios where it's unclear why the error occurred.
*
* @param throwable Throwable
* @param userInfo WritableMap
*/
void reject(Throwable throwable, WritableMap userInfo);
/**
* Reject with a code and userInfo WritableMap.
*
* @param code String
* @param userInfo WritableMap
*/
void reject(String code, @Nonnull WritableMap userInfo);
/**
* Report an exception with a custom code and userInfo.
*
* @param code String
* @param throwable Throwable
* @param userInfo WritableMap
*/
void reject(String code, Throwable throwable, WritableMap userInfo);
/**
* Report an error with a custom code, error message and userInfo,
* an error not caused by an exception.
*
* @param code String
* @param message String
* @param userInfo WritableMap
*/
void reject(String code, String message, @Nonnull WritableMap userInfo);
/**
* Report an exception with a custom code, error message and userInfo.
*
* @param code String
* @param message String
* @param throwable Throwable
* @param userInfo WritableMap
*/
void reject(String code, String message, Throwable throwable, WritableMap userInfo);
/* ------------
* Deprecated
* ------------ */
/**
* Report an error which wasn't caused by an exception.
*
* @deprecated Prefer passing a module-specific error code to JS.
* Using this method will pass the error code "EUNSPECIFIED".
*/
@Deprecated
void reject(String message);
}
@@ -5,67 +5,242 @@
* LICENSE file in the root directory of this source tree.
*/
/**
* Implementation of two javascript functions that can be used to resolve or reject a js promise.
*/
package com.facebook.react.bridge;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/*
* Implementation of {@link Promise} that represents a JavaScript Promise which can be passed to the
* native module as a method parameter.
*
* Methods annotated with {@link ReactMethod} that use a {@link Promise} as the last parameter
* will be marked as "promise" and will return a promise when invoked from JavaScript.
*/
public class PromiseImpl implements Promise {
// Number of stack frames to parse and return to mReject.invoke
// for ERROR_MAP_KEY_NATIVE_STACK
private static final int ERROR_STACK_FRAME_LIMIT = 10;
private static final String DEFAULT_ERROR = "EUNSPECIFIED";
private static final String ERROR_DEFAULT_CODE = "EUNSPECIFIED";
private static final String ERROR_DEFAULT_MESSAGE = "Error not specified.";
private @Nullable Callback mResolve;
private @Nullable Callback mReject;
// Keys for mReject's WritableMap
private static final String ERROR_MAP_KEY_CODE = "code";
private static final String ERROR_MAP_KEY_MESSAGE = "message";
private static final String ERROR_MAP_KEY_USER_INFO = "userInfo";
private static final String ERROR_MAP_KEY_NATIVE_STACK = "nativeStackAndroid";
// Keys for ERROR_MAP_KEY_NATIVE_STACK's StackFrame maps
private static final String STACK_FRAME_KEY_FILE = "file";
private static final String STACK_FRAME_KEY_LINE_NUMBER = "lineNumber";
private static final String STACK_FRAME_KEY_METHOD_NAME = "methodName";
private @Nullable
Callback mResolve;
private @Nullable
Callback mReject;
public PromiseImpl(@Nullable Callback resolve, @Nullable Callback reject) {
mResolve = resolve;
mReject = reject;
}
/**
* Successfully resolve the Promise with an optional value.
*
* @param value Object
*/
@Override
public void resolve(Object value) {
if (mResolve != null) {
mResolve.invoke(value);
mResolve = null;
mReject = null;
}
}
/**
* Report an error without an exception using a custom code and error message.
*
* @param code String
* @param message String
*/
@Override
public void reject(String code, String message) {
reject(code, message, /*Throwable*/null);
reject(code, message, /*Throwable*/null, /*WritableMap*/null);
}
/**
* Report an exception with a custom code.
*
* @param code String
* @param throwable Throwable
*/
@Override
public void reject(String code, Throwable throwable) {
reject(code, /*Message*/null, throwable, /*WritableMap*/null);
}
/**
* Report an exception with a custom code and error message.
*
* @param code String
* @param message String
* @param throwable Throwable
*/
@Override
public void reject(String code, String message, Throwable throwable) {
reject(code, message, throwable, /*WritableMap*/null);
}
/**
* Report an exception, with default error code.
* Useful in catch-all scenarios where it's unclear why the error occurred.
*
* @param throwable Throwable
*/
@Override
public void reject(Throwable throwable) {
reject(/*Code*/null, /*Message*/null, throwable, /*WritableMap*/null);
}
/* ---------------------------
* With userInfo WritableMap
* --------------------------- */
/**
* Report an exception, with default error code, with userInfo.
* Useful in catch-all scenarios where it's unclear why the error occurred.
*
* @param throwable Throwable
* @param userInfo WritableMap
*/
@Override
public void reject(Throwable throwable, WritableMap userInfo) {
reject(/*Code*/null, /*Message*/null, throwable, userInfo);
}
/**
* Reject with a code and userInfo WritableMap.
*
* @param code String
* @param userInfo WritableMap
*/
@Override
public void reject(String code, @Nonnull WritableMap userInfo) {
reject(code, /*Message*/null, /*Throwable*/null, userInfo);
}
/**
* Report an exception with a custom code and userInfo.
*
* @param code String
* @param throwable Throwable
* @param userInfo WritableMap
*/
@Override
public void reject(String code, Throwable throwable, WritableMap userInfo) {
reject(code, /*Message*/null, throwable, userInfo);
}
/**
* Report an error with a custom code, error message and userInfo,
* an error not caused by an exception.
*
* @param code String
* @param message String
* @param userInfo WritableMap
*/
@Override
public void reject(String code, String message, @Nonnull WritableMap userInfo) {
reject(code, message, /*Throwable*/null, userInfo);
}
/**
* Report an exception with a custom code, error message and userInfo.
*
* @param code String
* @param message String
* @param throwable Throwable
* @param userInfo WritableMap
*/
@Override
public void reject(
@Nullable String code,
@Nullable String message,
@Nullable Throwable throwable,
@Nullable WritableMap userInfo
) {
if (mReject == null) {
mResolve = null;
return;
}
WritableNativeMap errorInfo = new WritableNativeMap();
if (code == null) {
errorInfo.putString(ERROR_MAP_KEY_CODE, ERROR_DEFAULT_CODE);
} else {
errorInfo.putString(ERROR_MAP_KEY_CODE, code);
}
// Use the custom message if provided otherwise use the throwable message.
if (message != null) {
errorInfo.putString(ERROR_MAP_KEY_MESSAGE, message);
} else if (throwable != null) {
errorInfo.putString(ERROR_MAP_KEY_MESSAGE, throwable.getMessage());
} else {
// The JavaScript side expects a map with at least an error message.
// /Libraries/BatchedBridge/NativeModules.js -> createErrorFromErrorData
// TYPE: (errorData: { message: string })
errorInfo.putString(ERROR_MAP_KEY_MESSAGE, ERROR_DEFAULT_MESSAGE);
}
// For consistency with iOS ensure userInfo key exists, even if we null it.
// iOS: /React/Base/RCTUtils.m -> RCTJSErrorFromCodeMessageAndNSError
if (userInfo != null) {
errorInfo.putMap(ERROR_MAP_KEY_USER_INFO, userInfo);
} else {
errorInfo.putNull(ERROR_MAP_KEY_USER_INFO);
}
// Attach a nativeStackAndroid array if a throwable was passed
// this matches iOS behavior - iOS adds a `nativeStackIOS` property
// iOS: /React/Base/RCTUtils.m -> RCTJSErrorFromCodeMessageAndNSError
if (throwable != null) {
StackTraceElement[] stackTrace = throwable.getStackTrace();
WritableNativeArray nativeStackAndroid = new WritableNativeArray();
// Build an an Array of StackFrames to match JavaScript:
// iOS: /Libraries/Core/Devtools/parseErrorStack.js -> StackFrame
for (int i = 0; i < stackTrace.length && i < ERROR_STACK_FRAME_LIMIT; i++) {
StackTraceElement frame = stackTrace[i];
WritableMap frameMap = new WritableNativeMap();
// NOTE: no column number exists StackTraceElement
frameMap.putString(STACK_FRAME_KEY_FILE, frame.getFileName());
frameMap.putInt(STACK_FRAME_KEY_LINE_NUMBER, frame.getLineNumber());
frameMap.putString(STACK_FRAME_KEY_METHOD_NAME, frame.getMethodName());
nativeStackAndroid.pushMap(frameMap);
}
errorInfo.putArray(ERROR_MAP_KEY_NATIVE_STACK, nativeStackAndroid);
} else {
errorInfo.putArray(ERROR_MAP_KEY_NATIVE_STACK, new WritableNativeArray());
}
mReject.invoke(errorInfo);
mResolve = null;
mReject = null;
}
/* ------------
* Deprecated
* ------------ */
@Override
@Deprecated
public void reject(String message) {
reject(DEFAULT_ERROR, message, /*Throwable*/null);
}
@Override
public void reject(String code, Throwable e) {
reject(code, e.getMessage(), e);
}
@Override
public void reject(Throwable e) {
reject(DEFAULT_ERROR, e.getMessage(), e);
}
@Override
public void reject(String code, String message, @Nullable Throwable e) {
if (mReject != null) {
if (code == null) {
code = DEFAULT_ERROR;
}
// The JavaScript side expects a map with at least the error message.
// It is possible to expose all kind of information. It will be available on the JS
// error instance.
WritableNativeMap errorInfo = new WritableNativeMap();
errorInfo.putString("code", code);
errorInfo.putString("message", message);
// TODO(8850038): add the stack trace info in, need to figure out way to serialize that
mReject.invoke(errorInfo);
}
reject(/*Code*/null, message, /*Throwable*/null, /*WritableMap*/null);
}
}
@@ -12,7 +12,6 @@ rn_android_library(
],
deps = [
react_native_dep("libraries/fbcore/src/main/java/com/facebook/common/logging:logging"),
react_native_dep("third-party/android/support-annotations:android-support-annotations"),
react_native_dep("third-party/java/infer-annotations:infer-annotations"),
react_native_dep("third-party/java/jsr-305:jsr-305"),
react_native_dep("third-party/java/okhttp:okhttp3"),
@@ -4,7 +4,6 @@ rn_android_library(
name = "blob",
srcs = glob(["**/*.java"]),
provided_deps = [
react_native_dep("third-party/android/support-annotations:android-support-annotations"),
react_native_dep("third-party/android/support/v4:lib-support-v4"),
],
visibility = [
@@ -4,7 +4,6 @@ rn_android_library(
name = "fresco",
srcs = glob(["**/*.java"]),
provided_deps = [
react_native_dep("third-party/android/support-annotations:android-support-annotations"),
react_native_dep("third-party/android/support/v4:lib-support-v4"),
],
visibility = [
@@ -103,7 +103,7 @@ public class NetInfoModule extends ReactContextBaseJavaModule
@ReactMethod
public void getCurrentConnectivity(Promise promise) {
if (mNoNetworkPermission) {
promise.reject(ERROR_MISSING_PERMISSION, MISSING_PERMISSION_MESSAGE, null);
promise.reject(ERROR_MISSING_PERMISSION, MISSING_PERMISSION_MESSAGE);
return;
}
promise.resolve(createConnectivityEventMap());
@@ -112,7 +112,7 @@ public class NetInfoModule extends ReactContextBaseJavaModule
@ReactMethod
public void isConnectionMetered(Promise promise) {
if (mNoNetworkPermission) {
promise.reject(ERROR_MISSING_PERMISSION, MISSING_PERMISSION_MESSAGE, null);
promise.reject(ERROR_MISSING_PERMISSION, MISSING_PERMISSION_MESSAGE);
return;
}
promise.resolve(ConnectivityManagerCompat.isActiveNetworkMetered(mConnectivityManager));
@@ -163,7 +163,7 @@ public final class NetworkingModule extends ReactContextBaseJavaModule {
* @param context the ReactContext of the application
*/
public NetworkingModule(final ReactApplicationContext context) {
this(context, null, OkHttpClientProvider.createClient(), null);
this(context, null, OkHttpClientProvider.createClient(context), null);
}
/**
@@ -174,7 +174,7 @@ public final class NetworkingModule extends ReactContextBaseJavaModule {
public NetworkingModule(
ReactApplicationContext context,
List<NetworkInterceptorCreator> networkInterceptorCreators) {
this(context, null, OkHttpClientProvider.createClient(), networkInterceptorCreators);
this(context, null, OkHttpClientProvider.createClient(context), networkInterceptorCreators);
}
/**
@@ -183,7 +183,7 @@ public final class NetworkingModule extends ReactContextBaseJavaModule {
* caller does not provide one explicitly
*/
public NetworkingModule(ReactApplicationContext context, String defaultUserAgent) {
this(context, defaultUserAgent, OkHttpClientProvider.createClient(), null);
this(context, defaultUserAgent, OkHttpClientProvider.createClient(context), null);
}
@Override
@@ -7,16 +7,19 @@
package com.facebook.react.modules.network;
import android.content.Context;
import android.os.Build;
import com.facebook.common.logging.FLog;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable;
import okhttp3.Cache;
import okhttp3.ConnectionSpec;
import okhttp3.OkHttpClient;
import okhttp3.TlsVersion;
@@ -57,6 +60,13 @@ public class OkHttpClientProvider {
return createClientBuilder().build();
}
public static OkHttpClient createClient(Context context) {
if (sFactory != null) {
return sFactory.createNewNetworkModuleClient();
}
return createClientBuilder(context).build();
}
public static OkHttpClient.Builder createClientBuilder() {
// No timeouts by default
OkHttpClient.Builder client = new OkHttpClient.Builder()
@@ -68,6 +78,24 @@ public class OkHttpClientProvider {
return enableTls12OnPreLollipop(client);
}
public static OkHttpClient.Builder createClientBuilder(Context context) {
int cacheSize = 10 * 1024 * 1024; // 10 Mo
return createClientBuilder(context, cacheSize);
}
public static OkHttpClient.Builder createClientBuilder(Context context, int cacheSize) {
OkHttpClient.Builder client = createClientBuilder();
if (cacheSize == 0) {
return client;
}
File cacheDirectory = new File(context.getCacheDir(), "http-cache");
Cache cache = new Cache(cacheDirectory, cacheSize);
return client.cache(cache);
}
/*
On Android 4.1-4.4 (API level 16 to 19) TLS 1.1 and 1.2 are
available but not enabled by default. The following method
@@ -166,7 +166,7 @@ public class StatusBarModule extends ReactContextBaseJavaModule {
}
@ReactMethod
public void setStyle(final String style) {
public void setStyle(@Nullable final String style) {
final Activity activity = getCurrentActivity();
if (activity == null) {
FLog.w(ReactConstants.TAG, "StatusBarModule: Ignored status bar change, current activity is null.");
@@ -181,7 +181,7 @@ public class StatusBarModule extends ReactContextBaseJavaModule {
public void run() {
View decorView = activity.getWindow().getDecorView();
decorView.setSystemUiVisibility(
style.equals("dark-content") ? View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR : 0);
"dark-content".equals(style) ? View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR : 0);
}
}
);
@@ -16,7 +16,7 @@ import java.util.Map;
public class ReactNativeVersion {
public static final Map<String, Object> VERSION = MapBuilder.<String, Object>of(
"major", 0,
"minor", 0,
"patch", 0,
"minor", 58,
"patch", 4,
"prerelease", null);
}
@@ -357,7 +357,7 @@ public final class WebSocketModule extends ReactContextBaseJavaModule {
requestURI.getHost(),
requestURI.getPort());
} else {
defaultOrigin = String.format("%s://%s/", scheme, requestURI.getHost());
defaultOrigin = String.format("%s://%s", scheme, requestURI.getHost());
}
return defaultOrigin;
@@ -13,7 +13,6 @@ rn_android_library(
),
provided_deps = [
react_native_dep("third-party/android/support/v4:lib-support-v4"),
react_native_dep("third-party/android/support-annotations:android-support-annotations"),
],
required_for_source_only_abi = True,
visibility = [
@@ -626,6 +626,7 @@ public class UIViewOperationQueue {
private long mProfiledBatchRunStartTime;
private long mProfiledBatchBatchedExecutionTime;
private long mProfiledBatchNonBatchedExecutionTime;
private long mThreadCpuTime;
public UIViewOperationQueue(
ReactApplicationContext reactContext,
@@ -664,6 +665,7 @@ public class UIViewOperationQueue {
perfMap.put("RunStartTime", mProfiledBatchRunStartTime);
perfMap.put("BatchedExecutionTime", mProfiledBatchBatchedExecutionTime);
perfMap.put("NonBatchedExecutionTime", mProfiledBatchNonBatchedExecutionTime);
perfMap.put("NativeModulesThreadCpuTime", mThreadCpuTime);
return perfMap;
}
@@ -866,6 +868,7 @@ public class UIViewOperationQueue {
.flush();
try {
final long dispatchViewUpdatesTime = SystemClock.uptimeMillis();
final long nativeModulesThreadCpuTime = SystemClock.currentThreadTimeMillis();
// Store the current operation queues to dispatch and create new empty ones to continue
// receiving new operations
@@ -920,6 +923,7 @@ public class UIViewOperationQueue {
mProfiledBatchLayoutTime = layoutTime;
mProfiledBatchDispatchViewUpdatesTime = dispatchViewUpdatesTime;
mProfiledBatchRunStartTime = runStartTime;
mThreadCpuTime = nativeModulesThreadCpuTime;
Systrace.beginAsyncSection(
Systrace.TRACE_TAG_REACT_JAVA_BRIDGE,

Some files were not shown because too many files have changed in this diff Show More