Compare commits

...
312 Commits
Author SHA1 Message Date
Hector Ramos dc04bf3d96 Working! 2017-11-15 15:34:32 -08:00
Hector Ramos 8e34e7bd5f latest 2017-11-14 12:51:44 -08:00
Hector Ramos 68f6799b7c Lots of progress into build-docs.js 2017-11-13 14:21:44 -08:00
Hector Ramos 2c130e6a9f wip3 2017-10-31 14:11:35 -07:00
Hector Ramos 21423bdf22 WIP 2017-10-31 14:09:41 -07:00
Hector Ramos e5332504cc wip 2017-10-31 11:51:47 -07:00
Hector Ramos 292f035ae8 progress 2017-10-31 11:19:00 -07:00
Hector Ramos a6c4ae0e75 Moving on to master docs 2017-10-30 17:04:16 -07:00
Hector Ramos e4b5e9ef85 Progress 2017-10-27 13:23:00 -07:00
Hector Ramos 732831dc27 Progress :D 2017-10-27 11:51:58 -07:00
Hector Ramos b150fdfdce mostly there 2017-10-26 23:46:53 -07:00
Hector Ramos 73f2007679 moast there 2017-10-26 18:46:40 -07:00
Hector Ramos da2a8b365c PROGRESS 2017-10-26 16:22:28 -07:00
Hector Ramos 143ecf4c62 Progress 2017-10-26 15:36:54 -07:00
Hector Ramos c8d6cb9e49 WIP{ 2017-10-26 15:20:59 -07:00
Hector Ramos 0661c6f254 WIP 2017-10-09 15:08:36 -07:00
Hector Ramos 5f4a5388ac WIP 2017-10-06 14:30:06 -07:00
Hector Ramos 445dac2743 Progress towards making single "import everything from GitHub, including every tag" script. 2017-10-05 15:36:45 -07:00
Hector Ramos 2d230bee78 Versioning WIP 2017-10-04 17:02:20 -07:00
Hector Ramos 382abb4b45 Adjust layout 2017-10-04 13:20:28 -07:00
Hector Ramos b0e4b89b58 Docs 2017-10-03 13:46:34 -07:00
Hector Ramos 0b8525847f Fix method titles in props 2017-09-29 14:41:15 -07:00
Hector Ramos 09a923599e More styling updates 2017-09-29 14:39:45 -07:00
Hector Ramos e7b7951c96 Styles for props 2017-09-29 14:39:31 -07:00
Hector Ramos a91d0d8c35 Additional css changes 2017-09-27 16:49:19 -07:00
Hector Ramos 47206fdd3c wip 2017-09-25 14:28:16 -07:00
Hector Ramos b02efd9e96 Make showcase logos square 2017-09-12 17:49:45 -07:00
Hector Ramos 31894136f4 Images and static assets 2017-09-05 09:31:56 -07:00
Hector Ramos 9b6639ad12 Fix tabs styling. 2017-09-01 14:19:26 -07:00
Hector Ramos 11f838f349 Adjust styling to match production site. 2017-09-01 13:32:38 -07:00
Hector Ramos 34787cc0eb Updated scripts. 2017-08-31 11:29:32 -07:00
Hector Ramos d40bea925f Move autodocs script to docgen/server 2017-08-31 10:41:57 -07:00
Hector Ramos 692d3f72fb Move to Docusaurus. 2017-08-31 10:38:26 -07:00
Dean GandFacebook Github Bot cb9b266b8e Update sectionList keyExtractor docs
Summary:
Added language to explain that you still need to add keys for each section even if you use a keyExtractor method.

No code changed; just clarified documentation.
Closes https://github.com/facebook/react-native/pull/15007

Differential Revision: D5425897

Pulled By: hramos

fbshipit-source-id: db44064a28a673feeda5a6765ea45217d3ae51e2
2017-07-14 13:23:21 -07:00
Janic DuplessisandFacebook Github Bot ccb4e67756 Blog - Background color is not supported by the native driver
Summary:
This was a lie, background color is not supported (yet). Sorry for the false hopes :)

Fixes #14178
Closes https://github.com/facebook/react-native/pull/15013

Differential Revision: D5424676

Pulled By: hramos

fbshipit-source-id: ea592bf633f1632c931a9f18fe2fa9ebad6136be
2017-07-14 10:19:33 -07:00
Janic DuplessisandFacebook Github Bot ad9b66fc6f Add myself to CODEOWNERS for animated
Summary: Closes https://github.com/facebook/react-native/pull/15014

Differential Revision: D5424672

Pulled By: hramos

fbshipit-source-id: 2da5d0eeb8c1eec07e9d1569dec034f224475e64
2017-07-14 10:19:33 -07:00
Miguel Jimenez EsunandFacebook Github Bot 1fe8f89bc8 Update Jest to 20.1.0, chi.1
Reviewed By: davidaurelio

Differential Revision: D5423945

fbshipit-source-id: deb58ba9288883b5d671148aeaa59da6629d0de4
2017-07-14 10:19:32 -07:00
Paco Estevez GarciaandFacebook Github Bot a1e053cc50 Add Framework name to Attach selection
Reviewed By: Hypuk, javache

Differential Revision: D5389047

fbshipit-source-id: 90e2a5f805561e47e7705e7935ced7556a374616
2017-07-14 07:50:40 -07:00
Brian VaughnandFacebook Github Bot 221286be13 React sync for revisions cb32253...5495e49
Reviewed By: acdlite

Differential Revision: D5416055

fbshipit-source-id: c69de0d699f11dec4a71fb6e3f924ade3446bba0
2017-07-13 17:38:57 -07:00
Héctor RamosandFacebook Github Bot 07972cf3bf Add gantman to contributors
Summary: Closes https://github.com/facebook/react-native/pull/15009

Differential Revision: D5420862

Pulled By: hramos

fbshipit-source-id: ecf1c7054f9b6792e606e58e37b109f0af62c9c3
2017-07-13 17:17:23 -07:00
Adam ComellaandFacebook Github Bot 09401ed56f Android: Support setting background color on ARTSurfaceView
Summary:
This fixes support for the `backgroundColor` style prop on an `ART.Surface`.

`ARTSurfaceViewManager` inherits its `setBackgroundColor` implementation from `BaseViewManager`. This implementation broke in API 24 because API 24 removed support for `setBackgroundColor`on `TextureViews`. `ARTSurfaceView` inherits from `TextureView` so it also lost support for `setBackgroundColor`.

To fix this, the implementation of `ART.Surface's` `setBackgroundColor` was moved to the shadow node. The implementation now draws the background color on the canvas.

In a test app, verified that initializing and changing the background color on an `ART.Surface` works. Verified that the background renders as transparent when a background color isn't set. Also, this change is being used in my team's app.

Adam Comella
Microsoft Corp.
Closes https://github.com/facebook/react-native/pull/14117

Differential Revision: D5419574

Pulled By: hramos

fbshipit-source-id: 022bfed553e33e2d493f68b4bf5aa16dd304934d
2017-07-13 16:18:50 -07:00
Eli WhiteandFacebook Github Bot c885357cc9 Wait for packager to start
Reviewed By: shergin

Differential Revision: D5408443

fbshipit-source-id: 4a9b37822c1f5c0db3d8be71862d5049bca1ecdd
2017-07-13 15:36:12 -07:00
Miguel Jimenez EsunandFacebook Github Bot 6dd9d16833 Move Array<string> to $ReadOnlyArray<string>. Separate polyfill list into a file.
Summary: Move the returned type of `getPolyfills` from a standard `Array` to a read-only one, so that we make sure the array is not modified once created. Also, refactor the list of polyfills included by default to a generic, central file, then require it both from the CLI utils as well as the development server.

Reviewed By: jeanlauliac

Differential Revision: D5406553

fbshipit-source-id: ab980288bb1c625338de469da77dd6fc70bcedbc
2017-07-13 03:38:23 -07:00
Maarten SchumacherandFacebook Github Bot cad2d9b072 Be able to scroll to last item in list
Summary:
The invariant condition doesn't allow scrolling to the last index

Here is a simple reproduction of the problem: https://snack.expo.io/BJ59gzWrZ

Surely, if the last item is rendered, we should be able to scroll to it without an invariant failing?

Tested locally that this change fixes the issue.
Closes https://github.com/facebook/react-native/pull/14934

Differential Revision: D5414535

Pulled By: shergin

fbshipit-source-id: 38dac4c0e2ae5e1e199a67ca0e98e8f7325e77f4
2017-07-13 00:03:51 -07:00
Eli WhiteandFacebook Github Bot e3cfcdfb9c Remove silly exit
Reviewed By: Yu-w

Differential Revision: D5413747

fbshipit-source-id: c3423c4bf2b60204099bd68825797d71b0c217bc
2017-07-12 23:37:27 -07:00
Christian BrevikandFacebook Github Bot e2c87b59be Android: Set WebViewManager methods/fields as protected instead of private
Summary:
**Motivation**

See discussion in #10946. The motivation is to make `ReactWebViewManager` more extensible.

Re-using logic from the ReactWebViewManager when implementing your own custom WebView is a pain since so much of the logic is set as `private`.

This PR makes for easier extension/overriding of behavior, and less duplication of code, since most of the methods/fields are set as `protected` instead.

I've also made some "create" methods for the `WebView` and `WebViewBridge` so they can more easily be overridden.

**Test plan**
The test plan is the same as the other PR (#10946). I've made an simple test app which extends `RCTWebViewManager`: https://github.com/cbrevik/overrideWebview

See [CustomWebViewManager.java](https://github.com/cbrevik/overrideWebview/blob/master/android/app/src/main/java/com/overridewebview/CustomWebViewManager.java) for a simple implementation.

CC shergin (https://github.com/facebook/react-native/pull/10946#issuecomment-304763562)
Closes https://github.com/facebook/react-native/pull/14261

Differential Revision: D5413922

Pulled By: shergin

fbshipit-source-id: d2f6d478f2a147e2e7b5e05c195a8b28a0a3d576
2017-07-12 21:14:32 -07:00
Eli WhiteandFacebook Github Bot aafccdf622 Revert D5409825: [RN] Convert easy files to Prettier
Differential Revision: D5409825

fbshipit-source-id: f797a40b58bc6bcc6ae53ed820a10ab49d3f10f5
2017-07-12 19:23:58 -07:00
Héctor RamosandFacebook Github Bot bfece1d800 Update ISSUE_TEMPLATE.md
Summary: Closes https://github.com/facebook/react-native/pull/14990

Differential Revision: D5411770

Pulled By: hramos

fbshipit-source-id: ddabba4ec7ce83a19eeadecae41ce11004e36e4e
2017-07-12 16:50:38 -07:00
Steffen MatthischkeandFacebook Github Bot e43c061e95 Podspec: add required "DevSupport" dependency "InspectorInterfaces.{cpp,h}
Summary:
This PR fixes #14975.
* Podspec: add InspectorInterfaces.h/cpp to the "jschelpers_legacy" subspec.

1. lint the Podspecs: `./scripts/process-podspecs.sh`
2. check that an iOS project can integrate "DevSupport" via Cocoapods again. I'll already checked it on this branch of the demo project: https://github.com/HeEAaD/Demo-ReactNative-0.47.0-rc2-Podspec-issue/tree/fix
Closes https://github.com/facebook/react-native/pull/14988

Differential Revision: D5411733

Pulled By: javache

fbshipit-source-id: bb46cf3461e0857c7508264dafa204067af182c6
2017-07-12 16:27:28 -07:00
Héctor RamosandFacebook Github Bot e02bafd9cf Update Releases.md
Summary:
Minor cleanup. #trivial
Closes https://github.com/facebook/react-native/pull/14987

Differential Revision: D5411371

Pulled By: hramos

fbshipit-source-id: 9ce851ba787ab8a5d334fa3cd975f86d838b9487
2017-07-12 16:08:22 -07:00
Eli WhiteandFacebook Github Bot c198911561 Convert easy files to Prettier
Reviewed By: zertosh

Differential Revision: D5409825

fbshipit-source-id: 81f67be174cc8ecfcd0955dfec83955ebdc84622
2017-07-12 16:08:22 -07:00
Eli WhiteandFacebook Github Bot 320aea8bca shelljs/global -> shelljs
Reviewed By: zertosh

Differential Revision: D5407207

fbshipit-source-id: df5d1a38a35d27c9c429ea972acab58322441813
2017-07-12 16:08:22 -07:00
Tieme van VeenandFacebook Github Bot e57655274d Fix 14436 - Docs: ios-native-ui-guide 'RNTMap' -> 'MKMapView' fix
Summary:
Quick fix for https://github.com/facebook/react-native/issues/14436
Closes https://github.com/facebook/react-native/pull/14982

Differential Revision: D5409794

Pulled By: javache

fbshipit-source-id: ea59a9a11b689459e68c05a92095fdcee1da717f
2017-07-12 14:50:32 -07:00
Tieme van VeenandFacebook Github Bot c41b5a02f2 Docs: ios-native-ui-guide RCTConvert categories edit
Summary:
I was struggling a bit with the [iOS Native UI Components tutorial](https://facebook.github.io/react-native/docs/native-components-ios.html#content).

As noted here it's outdated. https://github.com/facebook/react-native/issues/14436

In my opinion, these steps are more clear when the header files are also included in the example. Besides that, the tutorial can use the already existing `RCTConvert+CoreLocation` category for simplicity.
Closes https://github.com/facebook/react-native/pull/14983

Differential Revision: D5409803

Pulled By: javache

fbshipit-source-id: f7fe1d2b542e8df602dc0f0636efb4d764090811
2017-07-12 14:09:55 -07:00
Eli WhiteandFacebook Github Bot d9f98191eb Removing @nolint from flow files
Reviewed By: zertosh

Differential Revision: D5407058

fbshipit-source-id: 54e9cbc1a9739bcf104752f3421cc7cba41730cc
2017-07-12 14:09:54 -07:00
Eli WhiteandFacebook Github Bot fc86f25f9a Run eslint on all js files
Reviewed By: zertosh

Differential Revision: D5405047

fbshipit-source-id: 5ade9d8beb3688d8bb08a208709c0dbf1ec671b2
2017-07-12 14:09:53 -07:00
Brian VaughnandFacebook Github Bot 1d353b4ef7 Try to match React DevTools theme with current Nuclide theme
Reviewed By: spicyj

Differential Revision: D5362305

fbshipit-source-id: 7d8464f768d124cbb31ba211d81a01a89d6bf692
2017-07-12 12:24:43 -07:00
Brooks LyretteandFacebook Github Bot 98b925ceec Updated example 'Podfile' to consistently use single quotes.
Summary: Closes https://github.com/facebook/react-native/pull/14973

Differential Revision: D5407186

Pulled By: javache

fbshipit-source-id: 78cf68abbbb2fb97786973ce8e3e26b8afdd2a74
2017-07-12 11:18:52 -07:00
Georgiy KassabliandFacebook Github Bot 820026f69b Fixing the issue with node dimensions rounding in Yoga
Reviewed By: emilsjolander

Differential Revision: D5406211

fbshipit-source-id: df1d54ed0805dfc3abbd8f0ceae30f6d8c26d61a
2017-07-12 09:30:29 -07:00
James IdeandFacebook Github Bot 9f87728f5d Change polyfills to getPolyfills function for more configurability
Summary:
Changing the `polyfills` option to `getPolyfills({platform})` will let us return a different set of polyfills for each platform. See https://github.com/facebook/metro-bundler/issues/25 for the motivation.
Closes https://github.com/facebook/react-native/pull/14943

Differential Revision: D5405878

Pulled By: mjesun

fbshipit-source-id: 908e49a286841f97655603d92d0fdfb000547510
2017-07-12 08:18:14 -07:00
Felix OghinaandFacebook Github Bot 999851a389 Update OSS Fresco dependency
Reviewed By: oprisnik

Differential Revision: D5406106

fbshipit-source-id: 3d928f431701b783fa0862d0dff818ec61d8b737
2017-07-12 07:54:09 -07:00
Pieter De BaetsandFacebook Github Bot fc68dfbed6 Enable flow for TouchableHighlight
Reviewed By: fkgozali

Differential Revision: D5388762

fbshipit-source-id: bec790a5e2ae5dbaf0f7bd2681ef156e870ed797
2017-07-12 04:15:41 -07:00
harry-gandFacebook Github Bot ec8118b637 Better doc for 'data:' uri scheme & mandatory size
Summary:
It is quite confusing that the 'data:' uri scheme is not documented, but working.
It is very useful when getting e.g. an icon from a REST call.

Also, the mandatory size style for network & data images should be mentioned here, not only in the image guide.

<!--
Thank you for sending the PR!

If you changed any code, please provide us with clear instructions on how you verified your changes work. In other words, a test plan is *required*. Bonus points for screenshots and videos!

Please read the Contribution Guidelines at https://github.com/facebook/react-native/blob/master/CONTRIBUTING.md to learn more about contributing to React Native.

Happy contributing!
-->
Closes https://github.com/facebook/react-native/pull/14826

Differential Revision: D5401671

Pulled By: hramos

fbshipit-source-id: 8f1f28a94095eeaccae9234e059e0983ba3556b2
2017-07-11 15:33:37 -07:00
Adam MiskiewiczandFacebook Github Bot 8ea6cea39a MaskedViewIOS -- A way to apply alpha masks to views on iOS
Summary:
It's very important in complex UIs to be able to apply alpha channel-based masks to arbitrary content. Common use cases include adding gradient masks at the top or bottom of scroll views, creating masked text effects, feathering images, and generally just masking views while still allowing transparency of those views.

The original motivation for creating this component stemmed from work on `react-navigation`. As I tried to mimic behavior in the native iOS header, I needed to be able to achieve the effect pictured here (this is a screenshot from a native iOS application):

![iOS native navbar animation](https://slack-imgs.com/?c=1&url=https%3A%2F%2Fd3vv6lp55qjaqc.cloudfront.net%2Fitems%2F0N3g1Q3H423P3m1c1z3E%2FScreen%2520Shot%25202017-07-06%2520at%252011.57.29%2520AM.png)

In this image, there are two masks:

- A mask on the back button chevron
- A gradient mask on the right button

In addition, the underlying view in the navigation bar is intended to be a UIBlurView. Thus, alpha masking is the only way to achieve this effect.

Behind the scenes, the `maskView` property on `UIView` is used. This is a shortcut to setting the mask on the CALayer directly.

This gives us the ability to mask any view with any other view. While building this component (and testing in the context of an Expo app), I was able to use a `GLView` (a view that renders an OpenGL context) to mask a `Video` component!

I chose to implement this only on iOS right now, as the Android implementation is a) significantly more complicated and b) will most likely not be as performant (especially when trying to mask more complex views).

Review the `<MaskedViewIOS>` section in the RNTester app, observe that views are masked appropriately.

![example](https://d3vv6lp55qjaqc.cloudfront.net/items/250X092v2k3f212f3O16/Screen%20Recording%202017-07-07%20at%2012.18%20PM.gif?X-CloudApp-Visitor-Id=abb33b3e3769bbe2f7b26d13dc5d1442&v=5f9e2d4c)
Closes https://github.com/facebook/react-native/pull/14898

Differential Revision: D5398721

Pulled By: javache

fbshipit-source-id: 343af874e2d664541aca1fefe922cf7d82aea701
2017-07-11 15:05:57 -07:00
Raj SuvariyaandFacebook Github Bot 0c44b9e9b0 Update IntegrationWithExistingApps.md
Summary:
Conflict in the project name in package.json and index.xxx.js

<!--
Thank you for sending the PR!

If you changed any code, please provide us with clear instructions on how you verified your changes work. In other words, a test plan is *required*. Bonus points for screenshots and videos!

Please read the Contribution Guidelines at https://github.com/facebook/react-native/blob/master/CONTRIBUTING.md to learn more about contributing to React Native.

Happy contributing!
-->
Closes https://github.com/facebook/react-native/pull/14940

Differential Revision: D5398809

Pulled By: hramos

fbshipit-source-id: 0ed12e8a39e5c477594396b4b781acd8a93f429d
2017-07-11 14:32:40 -07:00
Valentin SherginandFacebook Github Bot 7cdd4d48c8 Nits: [NSNull null] was changed to (id)kCFNull`
Reviewed By: javache

Differential Revision: D5398734

fbshipit-source-id: 823e860b5da9cc9850fafa49c1d9b746580856b0
2017-07-11 12:31:15 -07:00
Héctor RamosandFacebook Github Bot 18c795bfcc Update AnimatedImplementation.js
Summary:
Small sample code fix, based on #12175
Closes https://github.com/facebook/react-native/pull/14948

Differential Revision: D5399724

Pulled By: hramos

fbshipit-source-id: dd4de3b06dcec090f0c636b8d4c1f315cefc8b1b
2017-07-11 12:31:15 -07:00
gabrielandFacebook Github Bot 3f16aa5559 added chromium support for devTools on linux
Summary:
<details>
  Thanks for submitting a PR! Please read these instructions carefully:

  - [ ] Explain the **motivation** for making this change.
  - [ ] Provide a **test plan** demonstrating that the code is solid.
  - [ ] Match the **code formatting** of the rest of the codebase.
  - [ ] Target the `master` branch, NOT a "stable" branch.

  Please read the [Contribution Guidelines](https://github.com/facebook/react-native/blob/master/CONTRIBUTING.md) to learn more about contributing to React Native.
</details>

_What existing problem does the pull request solve?_

On Linux, the packager caught an "Google Chrome exited with error: { Error: spawn google-chrome ENOENT}" when trying to launch the devTools because google-chrome is not installed but chromium is.
Thus, this pull request maps the platform Linux with chromium for launching the debugger automatically in the packager

_A good test plan has the exact commands you ran and their output, provides screenshots or videos if the pull request changes UI or updates the website._

- enter on terminal
    > react-native start
- launch the app in dev mode with "Debug JS remotely" enabled
- the packager prints "Launching Dev Tools..." and launch chromium with the debugger
![screenshot](https://user-images.githubusercontent.com/13065528/27481217-ceaf5e58-581b-11e7-976f-75c107596ad3.png)
Closes https://github.com/facebook/react-native/pull/14696

Differential Revision: D5398564

Pulled By: hramos

fbshipit-source-id: 151f83b549492c8716a248eb16f7e24c5658b32e
2017-07-11 12:31:15 -07:00
Héctor RamosandFacebook Github Bot a616a2d99d Add Animated to list of APIs
Summary:
Also: move `Button` down to UI, and `StyleSheet` up to Basic Components.
Closes https://github.com/facebook/react-native/pull/14405

Differential Revision: D5209838

Pulled By: hramos

fbshipit-source-id: ffcd3a146a5c277f8d7e824c9a7595d2e7b720ae
2017-07-11 11:18:57 -07:00
Liu ZhanhongandFacebook Github Bot 6b29fe78c4 Avoid creating a new Path instance for performance
Summary:
New a Path instance will cause a slice call to exist path.

```js
// react-native/Libraries/ART/ARTSerializablePath.js
if (path instanceof SerializablePath) {
  this.path = path.path.slice(0);
}
```

Most of d3's APIs can set context when we don't want to use d3's build-in path object. And in RN envirenment, we must use RN's path instance. So we can use RN's path as a context in d3 avoiding doing conversions from svg's path string to arrays. But with existing code, when Shape receive a `d` proprety, it new a path instance and will cause calling slice in a very large array.

Typical usage is as follows

```js
import React from 'react';
import { View, ART } from 'react-native';
import { line } from 'd3-shape';
import { scaleLinear } from 'd3-scale';

const { Path, Surface, Shape } = ART;
const width = 360;
const height = 300;
const data = [5,2,7,6,9,1,8,4,3];
const x = scaleLinear().range([0, width]).domain([0, data.length]);
const y = scaleLinear().range([height, 0]).domain([0, 9]);
const myline = line()
    .x(function(d, i) {
      return x(i);
    })
    .y(function(d) { return y(d); });

// use RN's ART Path
const path = Path();
myline.context(path)(data);

class TestArt extends React.Component {
  render() {
    return (
      <View>
        <Surface width={width} height={height}>
          <Shape
            stroke="red"
            d={
              // use RN's ART Path
              path
              // use d3's path
              // myline(data)
            }
          />
        </Surface>
      </View>
    );
  }
}
```
Closes https://github.com/facebook/react-native/pull/14551

Differential Revision: D5398653

Pulled By: javache

fbshipit-source-id: 1264acfb8844b60584604a664e0474f9e212d1d1
2017-07-11 11:18:56 -07:00
Giles Van GruisenandFacebook Github Bot 5f1408858a Support additional dependency declaration format
Summary:
Thanks for submitting a PR! Please read these instructions carefully:

- [x] Explain the **motivation** for making this change.
- [x] Provide a **test plan** demonstrating that the code is solid.
- [x] Match the **code formatting** of the rest of the codebase.
- [x] Target the `master` branch, NOT a "stable" branch.

Previously, `isInstalled` was somewhat naively checking for the presence
of a string in the `build.gradle` file to determine whether or not that
dependency was already linked. I.e.:

```
    compile project(':${name}')\n
```

…where `name` is replaced with the name of the dependency being checked.

This was inflexible as it only supported that particular format of
`compile` definition. Another, valid `compile` definition follows:

```
    compile(project(':example') { … }
```

However, this failed the check because it didn't _exactly_ match the
format for which the check was searching the `build.gradle` contents. As
a result, running `react-native link` would incorrectly duplicate the
dependency definition and thus cause a crash upon launching the app.

This change adds an `installPattern` to the object returned from
`makeBuildPatch`, which includes the particular dependency name and is
valid for both `compile` definition formats.

This commit adds an additional compile definition in the associated fixture,
an additional test case in `isInstalled.spec.js` to check for this additional
format, and an additional test in `makeBuildPatch.spec.js` to ensure the
object returned includes the aforementioned `installPattern` Regex pattern.

Sign the [CLA][2], if you haven't already. 

Small pull requests are much easier to review and more likely to get merged. Make sure the PR does only one thing, otherwise please split it. 

Make sure all **tests pass** on both [Travis][3] and [Circle CI][4]. PRs that break tests are unlikely to be merged.

For more info, see the ["Pull Requests"][5] section of our "Contributing" guidelines.

[1]: https://medium.com/martinkonicek/what-is-a-test-plan-8bfc840ec171#.y9lcuqqi9
[2]: https://code.facebook.com/cla
[3]: https://travis-ci.org/facebook/react-native
[4]: http://circleci.com/gh/facebook/react-native
[5]: https://github.com/facebook/react-native/blob/master/CONTRIBUTING.md#pull-requests
Closes https://github.com/facebook/react-native/pull/14475

Differential Revision: D5398552

Pulled By: hramos

fbshipit-source-id: 1eaf84ba5bcfc43202f13c6b8fcfc68c30f36c33
2017-07-11 11:18:56 -07:00
Koen PuntandFacebook Github Bot 51e258e6e7 Rename _remoteNotificationCompleteCalllbackCalled to _remoteNotificationCompleteCallbackCalled
Summary:
Just noticed this typo
Closes https://github.com/facebook/react-native/pull/14886

Differential Revision: D5398308

Pulled By: hramos

fbshipit-source-id: 9ef5155fb4d8a7b44ac9ba0c3e13871391081f1a
2017-07-11 11:06:21 -07:00
Eli PerkinsandFacebook Github Bot 78e2030e95 Clean up -[RCTRootView cancelTouches] header docs
Summary:
Just a little typo fixing and wording clean up around some header docs.
Closes https://github.com/facebook/react-native/pull/14947

Differential Revision: D5398609

Pulled By: javache

fbshipit-source-id: 3eb40ef3308130c1d28b2efc7bb64d493e98825b
2017-07-11 11:06:21 -07:00
Kathy GrayandFacebook Github Bot 50f200ba90 Fix RCTNetworking error message
Reviewed By: javache

Differential Revision: D5397652

fbshipit-source-id: ab081dfa5f29c0b672eda6a1a22d23e6fc0881c1
2017-07-11 09:10:20 -07:00
Miguel Jimenez EsunandFacebook Github Bot ad0fe15e2e Move polyfills to react-native
Summary:
React Native bundler (aka Metro Bundler) was splitted from the main codebase some time ago (now it lives [[https://github.com/facebook/metro-bundler|here]]). To make it more agnostic, polyfills will be moved out from it, so people who doesn't need them does not include them. However, RN will still need them, so the first step is to copy them back to RN so that we can provide them to Metro Bundler later.

We also include a way of passing the list of polyfills to include, as an `Array<string>`. The field is called `polyfills`, and defaults to the traditional list that is currently included in the package manager [see here](https://github.com/facebook/metro-bundler/blob/be1843cddcff78802cd774c8a75fe8647df0135d/packages/metro-bundler/src/defaults.js#L27-L37).

In future commits, `metro-bundler` will be able to manage the `polyfills` array passed to it, and use it, instead of the pre-defined ones.

Reviewed By: davidaurelio

Differential Revision: D5381614

fbshipit-source-id: 749d536b781843ecb3067803e44398cd6df941f1
2017-07-11 03:47:16 -07:00
Sean WangandFacebook Github Bot 88fb45ddf9 Clarity in pagingEnabled description for ScrollView
Summary:
Current description is misleading (without looking at implementation) to believe that both horizontal and vertical pagination are supported on both platforms. This comment clarifies that vertical pagination is not supported on Android.
Closes https://github.com/facebook/react-native/pull/14844

Differential Revision: D5393488

Pulled By: hramos

fbshipit-source-id: e79246a65e1011b2667e7eea67e85e17394026a8
2017-07-10 17:46:14 -07:00
Alexander KomissarovandFacebook Github Bot 8f363b2c49 Converting more android support library dependencies in React Native. Now for v7
Reviewed By: achen1

Differential Revision: D5332443

fbshipit-source-id: 085be2d542feb29c3727958908648237c3ed0503
2017-07-10 17:18:11 -07:00
Christian BrevikandFacebook Github Bot 684e03590b Support native ViewManager inheritance on iOS
Summary:
**Motivation**
This is a re-worked version of #14260, by shergin's suggestion.

For iOS, if you want to inherit from a native ViewManagers, your custom ViewManager will not automatically export the parents' props. So the only way to do this today, is to basically copy/paste the parent ViewManager-file, and add your own custom logic.

With this PR, this is made more extensible by exporting the `baseModuleName` (i.e. the iOS `superclass` of the ViewManager), and then using that value to re-establish the inheritance relationship in `requireNativeComponent`.

**Test plan**
I've run this with a test project, and it works fine there. But needs more testing.

Opened this PR as [per shergin's suggestion](https://github.com/facebook/react-native/pull/10946#issuecomment-311860545) though, so we can discuss approach.

**Discussion**
* Android already supports inheritance, so this change should be compatible with that. But, not every prop available on `UIManager.RCTView.NativeProps` is actually exported by every ViewManager. So should `UIManager.RCTView.NativeProps` still be merged with `viewConfig.NativeProps`, even if the individual ViewManager does not export/use them to begin with?
* Does this break other platforms? [UWP](https://github.com/Microsoft/react-native-windows)?
Closes https://github.com/facebook/react-native/pull/14775

Differential Revision: D5392953

Pulled By: shergin

fbshipit-source-id: 5212da616acfba50cc285e2997d183cf8b2cd09f
2017-07-10 16:01:12 -07:00
Eli WhiteandFacebook Github Bot 10230707cb Enforce Prettier for @format
Reviewed By: zertosh

Differential Revision: D5392376

fbshipit-source-id: 6f09a4d8f4542c3a74aadb8d62fd216529a4f2bc
2017-07-10 15:37:36 -07:00
Sai GrandhiandFacebook Github Bot d7f671135c Update copyToClipBoard.js
Summary:
Since copy to clipboard functionality is now available in Linux, the comment above `copyToClipboard` function has been updated.
Closes https://github.com/facebook/react-native/pull/14773

Differential Revision: D5392372

Pulled By: hramos

fbshipit-source-id: 6e2668e1a89d37f9d5707fa36b3639895cd5bffd
2017-07-10 15:22:50 -07:00
harry-gandFacebook Github Bot dfd3b22275 Better doc for 'data:' uri scheme
Summary:
It is quite confusing that the 'data:' uri scheme is not documented, but working.
It is very useful when getting e.g. an icon from a REST call.
Closes https://github.com/facebook/react-native/pull/14827

Differential Revision: D5392326

Pulled By: hramos

fbshipit-source-id: 815851c27273f99ce281fb35fc6fbcf8cf781ff9
2017-07-10 14:17:27 -07:00
Eli WhiteandFacebook Github Bot 40fdd6d91c Enable eslint on circle ci
Reviewed By: zertosh

Differential Revision: D5374369

fbshipit-source-id: 5ffd246bc6fa735d781ed71cd293b7883184b786
2017-07-10 12:08:32 -07:00
Lukas WöhrlandFacebook Github Bot 5da0a9909e Reset the hadOverflow flag at the beginning of the algorithm
Summary:
This fixes the case where we change the layout, so that it doesn't overflow anymore.

This also improves the readability by using `|=` instead of referencing the value twice.
Closes https://github.com/facebook/yoga/pull/587

Differential Revision: D5388657

Pulled By: emilsjolander

fbshipit-source-id: ce1b1ded1feed7314a2c16bf695f62b866c19ea0
2017-07-10 12:08:32 -07:00
Liron YahdavandFacebook Github Bot dec62ffc3e Clarify JavaScript module naming edge case
Summary:
I've been burned by https://stackoverflow.com/questions/35052565/undefined-is-not-an-object-from-native-module-in-react-native/36580178 a few times, when I name a native module with RCT prefix. This will hopefully save me and others from that pain in the future.

<!--
Thank you for sending the PR!

If you changed any code, please provide us with clear instructions on how you verified your changes work. In other words, a test plan is *required*. Bonus points for screenshots and videos!

Please read the Contribution Guidelines at https://github.com/facebook/react-native/blob/master/CONTRIBUTING.md to learn more about contributing to React Native.

Happy contributing!
-->
Closes https://github.com/facebook/react-native/pull/14903

Differential Revision: D5390343

Pulled By: hramos

fbshipit-source-id: 73667d703b097e70e15ff42c54b7ccc6b480104f
2017-07-10 11:36:48 -07:00
Nurzhan BakibayevandFacebook Github Bot c00abe53c3 Move inspector proxy out of the packager
Reviewed By: pakoito

Differential Revision: D5369099

fbshipit-source-id: ff806d784b70804181c5c54837352f66e45d1b9e
2017-07-10 06:31:23 -07:00
Pieter De BaetsandFacebook Github Bot f1cbb11620 Replace -[RCTConvert folly_dynamic:] with direct calls to convertIdToFollyDynamic
Reviewed By: kathryngray

Differential Revision: D5355734

fbshipit-source-id: 4ba1533b75c8e271a86a2d5cc3a3354e52f83db2
2017-07-10 05:31:04 -07:00
PatrickandFacebook Github Bot dc97e3fb4e Fixed ImageBackground could't be wrapped by Touchable* component
Summary:
In 0.46, as warning's advice, I use `ImageBackground` to replace `Image`s which used as background image wrapper, and in some cases, I also wrap `ImageBackground` with `TouchableHighlight` to make it clickable.

But here comes an error:

> Touchable child must either be native or forward setNativeProps to a native component

![2017-07-07 3 25 19](https://user-images.githubusercontent.com/3055294/27948869-f7c5832c-632d-11e7-97ba-5074cca82961.png)

So I pick some code from `Image.ios.js` into `ImageBackground.js` to solve it.

Please help to review, thanks!
Closes https://github.com/facebook/react-native/pull/14884

Reviewed By: shergin

Differential Revision: D5380988

Pulled By: javache

fbshipit-source-id: 35fda029030a39e720b6266f5d0a27ea3ff145ef
2017-07-10 05:03:25 -07:00
Kevin LuvianandFacebook Github Bot e6941990ef Fixed new line and prioritise blurOnSubmit in multiline text input
Summary:
What existing problem does the pull request solve?
this fixes #13506 and #12717 where:
- there are some issues when pressing enter with some keyboard
- blurOnSubmit is not working with multiline

I think this should be in stable branch as this is pretty critical, isn't it?

- just create a TextInput with multiline and press enter with samsung keyboard
before, it won't create a new line, now it will.

- just create a TextInput with multiline and blurOnSubmit true and press enter
before, it won't blur, and wont create a new line (on some keyboard, it will create a new line), now it will blur only
Closes https://github.com/facebook/react-native/pull/13890

Reviewed By: achen1

Differential Revision: D5333464

Pulled By: shergin

fbshipit-source-id: a0597d1b1967d4de1486e728e03160e1bb15afeb
2017-07-09 15:34:10 -07:00
James IdeandFacebook Github Bot 1954fd4cef Remove unused npm dependencies and add missing ones
Summary:
A couple of npm dependencies are unused (grepped for them or their variants since some are Babel presets/plugins) and there were also some missing that are listed in react-native's package.json but are directly required by the website.
Closes https://github.com/facebook/react-native/pull/14880

Differential Revision: D5383816

Pulled By: hramos

fbshipit-source-id: 704cea500d92542078fddbb8777e6855d70e4659
2017-07-08 01:45:01 -07:00
Brent VatneandFacebook Github Bot 2781739fbe Fix type of StatusBar backgroundColor so it is displayed correctly in docs
Summary:
![screen shot 2017-07-07 at 2 54 01 pm](https://user-images.githubusercontent.com/90494/27978425-3d4c7702-6324-11e7-8cea-0f1e121e84d6.png)

![screen shot 2017-07-07 at 2 55 08 pm](https://user-images.githubusercontent.com/90494/27978437-4943df46-6324-11e7-9a64-ad30599811f2.png)

The change that set this type to $FlowFixMe was a [massive one-year-old old commit](https://github.com/facebook/react-native/commit/a2fb703bbb988038323c55b29b40e8f5ff52966d) and I don't think it is necessary anymore (flow passes with this change). If it does, it must be something internal to Facebook, maybe we should $FlowFixIt somehow?
Closes https://github.com/facebook/react-native/pull/14895

Differential Revision: D5385198

Pulled By: hramos

fbshipit-source-id: a769f8589f4b8d7421b6445f2c0bf08857a7dd1f
2017-07-07 20:33:31 -07:00
Luke RhodesandFacebook Github Bot bf1b67ee5f Support for preventing swipe left or swipe right
Summary:
The primary use case for this is disabling swipe right when using react-navigation's swipe to go back feature.
Closes https://github.com/facebook/react-native/pull/14684

Differential Revision: D5386554

Pulled By: sahrens

fbshipit-source-id: 1e7c4caaa804f86977d391c1bdb62be69342b551
2017-07-07 20:03:20 -07:00
Hector RamosandFacebook Github Bot dedffdc235 Add CODEOWNERS file to automatically request reviews.
Summary:
Recently announced: https://github.com/blog/2392-introducing-code-owners

These are non-blocking for the time being.
Closes https://github.com/facebook/react-native/pull/14897

Differential Revision: D5385189

Pulled By: hramos

fbshipit-source-id: 711827573f85577b70f3627d66a1f9f00fe7f90d
2017-07-07 16:32:28 -07:00
LironErmanandFacebook Github Bot 6db97d638d Add note to add the service to AndroidManifest
Summary:
If not you will try to start the service but nothing would happen

<!--
Thank you for sending the PR!

If you changed any code, please provide us with clear instructions on how you verified your changes work. In other words, a test plan is *required*. Bonus points for screenshots and videos!

Please read the Contribution Guidelines at https://github.com/facebook/react-native/blob/master/CONTRIBUTING.md to learn more about contributing to React Native.

Happy contributing!
-->
Closes https://github.com/facebook/react-native/pull/14813

Differential Revision: D5384460

Pulled By: hramos

fbshipit-source-id: 6131d7901d3324da97672141c4774b7810051526
2017-07-07 15:18:36 -07:00
Seth FitzsimmonsandFacebook Github Bot 9afb71fde8 Replace React.createClass with create-react-class
Summary:
This replaces all uses of `React.createClass` with `createReactClass` from the `create-react-class` package, attempting to match use of `var` and `const` according to local style.

Fixes #14620
Refs #14712
Closes https://github.com/facebook/react-native/pull/14729

Differential Revision: D5321810

Pulled By: hramos

fbshipit-source-id: ae7b40640b2773fd89c3fb727ec87f688bebf585
2017-07-07 14:36:01 -07:00
Pieter De BaetsandFacebook Github Bot 20224b74a4 Remove deprecated RCTAssert aliases
Reviewed By: fromcelticpark

Differential Revision: D5380783

fbshipit-source-id: 790d7e1bc6d99411ecc471df88f7b1f31680e7a0
2017-07-07 12:21:59 -07:00
Pieter De BaetsandFacebook Github Bot 8548ca09f1 Remove unused RCTDebugComponentOwnership
Reviewed By: sahrens

Differential Revision: D5380887

fbshipit-source-id: ff81324718d64d7a04ef4bd293d30dd6f3aabb2a
2017-07-07 12:04:04 -07:00
Christoph NakazawaandFacebook Github Bot e0eee0bb49 Revert D5321193: BREAKING: Add regenerator-runtime on demand, based on the files
Differential Revision: D5321193

fbshipit-source-id: 9113ed78e59ae9e9f3f86ca2fda2db3bd8c0dd7c
2017-07-07 10:48:37 -07:00
David AurelioandFacebook Github Bot 9b06a3193e Update throat dependency to 3.2.0
Summary: it has flow definitions now. OMG!

Reviewed By: cpojer

Differential Revision: D5381183

fbshipit-source-id: bdb3863b24da9802eeeb8a7d08f05d629f735178
2017-07-07 09:21:24 -07:00
Miguel Jimenez EsunandFacebook Github Bot 361f03badb BREAKING: Add regenerator-runtime on demand, based on the files
Summary:
Adding a Babel plugin that will analyze the file looking for any potential candidate to use `regenerator-runtime`, and if so, will inject dynamically the module. The module is injected per file, so we avoid polluting the global environment. The plugin is also able to inject the `require` call beforehand, so that the inliner can pick them and inline them.

The Babel plugin is part of `react-native-babel-preset`, so as long as you are using this preset you are safe. If not, you should include the specific transformer into your list of plugins, as `react-native-babel-preset/transforms/transform-regenerator-runtime-insertion.js`.

Reviewed By: davidaurelio

Differential Revision: D5321193

fbshipit-source-id: fd4805b28c8a2b986842e23570a64003370d2067
2017-07-07 07:47:13 -07:00
James IdeandFacebook Github Bot 3e96fb1de3 Upgrade the version of Yarn to 0.27.5 for CI
Summary:
The TravisCI tests were using an especially old version of Yarn. Upgrade to 0.27.5 so we're using a version closer to the version that more people (and especially RN maintainers) would be using.
Closes https://github.com/facebook/react-native/pull/14883

Differential Revision: D5380987

Pulled By: javache

fbshipit-source-id: d600c6c4dbf881006065d1e294226b6a2a60a70b
2017-07-07 06:24:31 -07:00
Kathy GrayandFacebook Github Bot 6796abbe55 Using shared bridge path for RN
Reviewed By: javache

Differential Revision: D5002111

fbshipit-source-id: 86c2856145a6595823fd027145b050a6fba3d90d
2017-07-07 05:30:38 -07:00
Pieter De BaetsandFacebook Github Bot a8a29a92a0 Simplify macro usage in MethodInvoker
Reviewed By: kathryngray

Differential Revision: D5363934

fbshipit-source-id: a9cffb10b4d6244d1d66267f6c1e07ba69663b9c
2017-07-07 03:06:21 -07:00
Pieter De BaetsandFacebook Github Bot 9108f98ca7 Add type for onLayout
Reviewed By: sahrens

Differential Revision: D5364203

fbshipit-source-id: ad87179422b0e595fc78db21a3108d50ba31564c
2017-07-07 03:06:21 -07:00
James IdeandFacebook Github Bot 6e13adbf56 Remove remnants of the packager
Summary:
There were still some references to "packager/" that are no longer used since the `packager` directory has been deleted after moving to Metro. Cleaned up the ones that were doing nothing and updated the references that are still meaningful.
Closes https://github.com/facebook/react-native/pull/14881

Reviewed By: cpojer

Differential Revision: D5380731

Pulled By: javache

fbshipit-source-id: 1355268f48db47343d0d38fae2598b64c8c01475
2017-07-07 03:06:21 -07:00
Pieter De BaetsandFacebook Github Bot 6c2beaffdc Fix Travis podspec CI for Cxx bridge
Summary:
Fixed the test script to properly setup our third-party deps and tweaked the third-party specs a bit so they work correctly.

This currently works for projects using static libraries, but fails when using dynamic libraries (`--use-libraries`)

cc mhorowitz alloy
Closes https://github.com/facebook/react-native/pull/14100

Differential Revision: D5380728

Pulled By: javache

fbshipit-source-id: e78b6bd4466ebf2bf30b7e361eff10ec14b36a55
2017-07-07 02:32:07 -07:00
Grace KuandFacebook Github Bot 79bf089bc5 Make visible to fix build when focusing on ReactKit
Reviewed By: dinhviethoa

Differential Revision: D5372827

fbshipit-source-id: 4cc718e88bc2da08b104d22ffc83691a62b1de4e
2017-07-06 19:46:45 -07:00
Marc HorowitzandFacebook Github Bot 26f01faf1b Make OSS CocoaPods build work with or without use_frameworks!
Reviewed By: javache

Differential Revision: D5361624

fbshipit-source-id: c2e5e8985827208a43e06932f746c6b9ccb146ad
2017-07-06 17:41:47 -07:00
Marc HorowitzandFacebook Github Bot 1ef21ece92 OSS build fix: use #import "..." instead of #import <RCTText/...>
Reviewed By: javache

Differential Revision: D5361615

fbshipit-source-id: 90d08eb5dea81253c1f7ea582ed2508eec1ba117
2017-07-06 17:07:28 -07:00
Spencer AhrensandFacebook Github Bot 1054644631 Use fixed point in inspector
Reviewed By: achen1, TheSavior

Differential Revision: D5365796

fbshipit-source-id: 07a4de096c6b79e633c9b73d42744953396e2abe
2017-07-06 14:52:28 -07:00
Parashuram NandFacebook Github Bot 352c3d97b3 Updating the usage of inquirer API
Summary:
Inquirer was changed to a later version in https://github.com/facebook/react-native/commit/bada25d158e070fd683a10b8ff9cdcb8d2498b14. However, the API also needed to be updated to use a promise based version.
Closes https://github.com/facebook/react-native/pull/14848

Differential Revision: D5375663

Pulled By: javache

fbshipit-source-id: 635798a43905301c65db5f63b9cfba1c16964870
2017-07-06 14:34:45 -07:00
superyarikandFacebook Github Bot f8ae461bc1 Update FlatList.js
Summary:
<!--
Thank you for sending the PR!

If you changed any code, please provide us with clear instructions on how you verified your changes work. In other words, a test plan is *required*. Bonus points for screenshots and videos!

Please read the Contribution Guidelines at https://github.com/facebook/react-native/blob/master/CONTRIBUTING.md to learn more about contributing to React Native.

Happy contributing!
-->
Closes https://github.com/facebook/react-native/pull/14764

Differential Revision: D5375730

Pulled By: javache

fbshipit-source-id: 776db77c4dc681edef5832552b220197225e9d3f
2017-07-06 14:34:45 -07:00
Pieter De BaetsandFacebook Github Bot 465a68db1f Remove xcode_public_headers_symlinks from RN BUCK files
Reviewed By: dinhviethoa

Differential Revision: D5321259

fbshipit-source-id: b07ff4a01280251deb2113a62197d96d5c2e37a1
2017-07-06 12:16:20 -07:00
Valentin SherginandFacebook Github Bot 2be921c88a Fixed possible inconsistency in view hierarchy caused by deleting animation
Summary:
This diff fixes a possibly inconsistent state of view hierarchy caused by async delayed deleting manipulation on UIView's tree.
Even if new approach may seem tricky, the previous one was just terribly wrong.

Reviewed By: javache

Differential Revision: D5374670

fbshipit-source-id: 36f27330aa8b0e4e00fe43739afe3bc6a8602e30
2017-07-06 12:16:20 -07:00
Spencer AhrensandFacebook Github Bot 2c9e113f8e Add ListView deprecation message to docs
Summary:
Could have sworn we put this in a while ago...
Closes https://github.com/facebook/react-native/pull/14870

Differential Revision: D5376747

Pulled By: sahrens

fbshipit-source-id: d2bf3efea205defa48d6cd7f853739f17eb39ece
2017-07-06 11:51:32 -07:00
BillydubbandFacebook Github Bot ed04d77c2c import HashMap
Summary:
Project won't build otherwise

<!--
Thank you for sending the PR!

If you changed any code, please provide us with clear instructions on how you verified your changes work. In other words, a test plan is *required*. Bonus points for screenshots and videos!

Please read the Contribution Guidelines at https://github.com/facebook/react-native/blob/master/CONTRIBUTING.md to learn more about contributing to React Native.

Happy contributing!
-->
Closes https://github.com/facebook/react-native/pull/14835

Differential Revision: D5375496

Pulled By: javache

fbshipit-source-id: 415abb0fd257a4f871acbcb89be26b10b96a01c6
2017-07-06 11:51:32 -07:00
Alexander KomissarovandFacebook Github Bot 1ab96fd077 Converting android support library dependencies to be provided_deps in React Native.
Reviewed By: bestander

Differential Revision: D5326236

fbshipit-source-id: 3f2ca43a78c4c868ed6665b4d9f61630631f9502
2017-07-05 19:15:22 -07:00
Pieter De BaetsandFacebook Github Bot 51afde821d Remove some outdated references to xreact
Reviewed By: kathryngray

Differential Revision: D5339824

fbshipit-source-id: 486212dcf0e80036fa548a139e38358ae251ef2a
2017-07-04 08:00:44 -07:00
Lukas WöhrlandFacebook Github Bot b437d61475 Fix text node rounding with fractional dimensions matching the rounding factor
Summary:
If we have a fractional measure output which matches the subpixel rounding factor, we still should round both dimension into the same direction.

Fixes facebook/yoga#580.
Closes https://github.com/facebook/yoga/pull/583

Reviewed By: marco-cova

Differential Revision: D5274212

Pulled By: emilsjolander

fbshipit-source-id: 1febf9194210437ab77f91319d10d4da9b284b79
2017-07-04 06:29:59 -07:00
Kathy GrayandFacebook Github Bot 3525998884 Setup experiment for split packages
Reviewed By: javache

Differential Revision: D5314224

fbshipit-source-id: b9bc28b8f4e058db1dcc0c17f7dc84bf15eb33f9
2017-07-04 04:01:14 -07:00
Kathy GrayandFacebook Github Bot e301a36606 Splitting packages into core bridge and core RN
Reviewed By: javache

Differential Revision: D4953811

fbshipit-source-id: 05ab9acc81e31bbb85005cd80eeebc550a6c452e
2017-07-04 04:01:14 -07:00
Valentin SherginandFacebook Github Bot 0fd061ec3d New (actually old) way to make RCTUITextField editable/non-editable
Reviewed By: mmmulani, sahrens

Differential Revision: D5368181

fbshipit-source-id: 9580adb4980e758fba2bf4ee4460eaaa6823358a
2017-07-03 21:22:37 -07:00
Tim YungandFacebook Github Bot c28595e3fb RN: Add close to SwipeableRow
Reviewed By: sahrens

Differential Revision: D5365597

fbshipit-source-id: 18cc896b551ce11b64c85067d5f17b3614762814
2017-07-03 19:21:53 -07:00
Valentin SherginandFacebook Github Bot 6312d67bcb RCTAnimation & RCTLayoutAnimation were decoupled from RCTUIManager
Reviewed By: javache

Differential Revision: D5351726

fbshipit-source-id: f13e5cd47483f2d5f9b194c10ae3fb6e99e08d84
2017-07-03 16:15:50 -07:00
Miguel Jimenez EsunandFacebook Github Bot e7c1cf5b7d Add a new babel transformer for inlining regenerator-runtime per file
Reviewed By: davidaurelio

Differential Revision: D5364134

fbshipit-source-id: 45aae705f961819d5a8e3a8a23c2e8b9300d3cb5
2017-07-03 10:04:22 -07:00
Miguel Jimenez EsunandFacebook Github Bot 304dc6bd77 Update Jest to 20.1 alpha 3
Reviewed By: cpojer

Differential Revision: D5356174

fbshipit-source-id: b718f9e40d731999329b7ff0e6d498a523772c84
2017-07-03 10:04:22 -07:00
Miguel Jimenez EsunandFacebook Github Bot 1d7c990424 Make a method used externaly (in a test) public
Summary: The method is being used in a test, so if a private method name mangling happens, the name of the method changes and the test fails.

Reviewed By: cpojer

Differential Revision: D5347967

fbshipit-source-id: ee964c2876bcfea5253d2ce7f9f02d4dbeebeab3
2017-07-03 07:53:58 -07:00
Kaibin YinandFacebook Github Bot c42080eaaf add peeking feature in AndroidViewPage(RN)
Reviewed By: sahrens

Differential Revision: D5340198

fbshipit-source-id: b2986a320a39225882d4289b193e1d22e9e7547e
2017-06-30 22:21:06 -07:00
Andrey MishaninandFacebook Github Bot ecd5829bf8 Overflow detection in Yoga
Reviewed By: gkassabli

Differential Revision: D5336645

fbshipit-source-id: c4f87d1754d7bac848e8d347b31d619393b94d2c
2017-06-30 09:33:52 -07:00
Pieter De BaetsandFacebook Github Bot 12ab236629 Fix references to deprecated assets in separate bundles
Reviewed By: sahrens

Differential Revision: D5346879

fbshipit-source-id: 9d1008765514006deef2182e61f42a7247ea9a85
2017-06-30 07:00:12 -07:00
Jean LauliacandFacebook Github Bot d494282fd1 metro-bundler: upgrade jest-haste-map
Reviewed By: cpojer

Differential Revision: D5346860

fbshipit-source-id: 16e9eeeb28804af81428745fda4ffc05a461845c
2017-06-29 08:31:19 -07:00
Joana LopesandFacebook Github Bot 25d19e3830 Translating NativeArray into NativeMap on getConstants
Reviewed By: javache

Differential Revision: D5321741

fbshipit-source-id: 2465c69a5bd1d4f3cf20ba73e163372b12616312
2017-06-29 04:19:30 -07:00
Jean LauliacandFacebook Github Bot 33057aacbf React Native: disable multipart bundle transmission for now
Reviewed By: davidaurelio

Differential Revision: D5329011

fbshipit-source-id: 5093bc5b1858314512313934fba04f4343fe0d5b
2017-06-29 04:19:30 -07:00
Raul Gomez AcunaandFacebook Github Bot d666f30665 react-native link support for native Android modules developed in Kotlin
Summary:
Currently React Native cli does not support linking native Android modules written in Kotlin. This PR aims to add support to it and closes #14561

- New unit tests added to verify the added functionality, they can be found inside:
`local-cli/core/__tests__/android/findPackageClassName.spec.js`

- Existing unit tests passed.
Closes https://github.com/facebook/react-native/pull/14660

Differential Revision: D5316981

Pulled By: shergin

fbshipit-source-id: 98354ba1e1ce1080a9a4b9958ef39893472038a1
2017-06-29 01:15:36 -07:00
Hank BrekkeandFacebook Github Bot 0797dae500 Jest Mocks for NetInfo and Linking
Summary:
This isn't exhaustive, but it's a few more functions that these modules normally export which need to be stubbed.
Closes https://github.com/facebook/react-native/pull/14432

Differential Revision: D5345928

Pulled By: shergin

fbshipit-source-id: f333056ac43ce7c75c6734bca8dc9035745721df
2017-06-29 01:00:39 -07:00
Peter PistoriusandFacebook Github Bot 185948604c Fix scalesPageToFit default property for iOS WebView.
Summary:
`scalesPageToFit`'s [documented default value is true](https://github.com/facebook/react-native/blob/master/Libraries/Components/WebView/WebView.ios.js#L318), but it's not explicitly set anywhere on iOS. On Android it's [set to true in defaultProps](https://github.com/facebook/react-native/blob/master/Libraries/Components/WebView/WebView.android.js#L203). This pull-request add the default behaviour.

```
import { WebView } from 'react-native;
/* ... */
<WebView source={{ uri: 'https://google.com' }} />
```

You should be able to zoom in and out using the pinch gesture.

1. Does the reviewer have any additional thoughts around the rest of the defaultProps which aren't explicitly set?
2. Does the reviewer have any additional thoughts on how these two components (iOS/ Android) can share more code?
Closes https://github.com/facebook/react-native/pull/14363

Differential Revision: D5345883

Pulled By: shergin

fbshipit-source-id: e7b9b89f13d6adcdc705244871e00b7a5da52c64
2017-06-29 01:00:39 -07:00
Marshall RochandFacebook Github Bot 16747dd807 @allow-large-files Flow v0.49
Reviewed By: nmote

Differential Revision: D5339224

fbshipit-source-id: a18f0afb2ce75df736662d84951e392db1e2dbbf
2017-06-28 21:32:48 -07:00
Janic DuplessisandFacebook Github Bot 960e5db0ed Add dev bundle download listener on Android
Summary:
This exposes a way to listen to JS bundle download events when creating a ReactInstanceManager. This can be used to display a custom native UI while the JS bundle is loading. It is a pretty specific use case but Expo will need this to display loading progress on the app loading splash screen.

**Test plan**
Tested by adding a listener to the ReactInstanceManager in the Expo app and checked that it gets called when the bundle is loading.
Closes https://github.com/facebook/react-native/pull/12984

Reviewed By: devknoll

Differential Revision: D4797638

Pulled By: hramos

fbshipit-source-id: 04d7cd4071535670c1bcb121566748e495197c80
2017-06-28 20:01:17 -07:00
Christopher ChedeauandFacebook Github Bot c848c3820b Codemod prettier to 1.5.2
Differential Revision: D5339725

fbshipit-source-id: 631338436a7d69b0ab0721507bdab4ae4e207065
2017-06-28 12:50:30 -07:00
Alex DvornikovandFacebook Github Bot 2f193b9bc1 Allow RCTModuleData to explicitly opt out from performing its set up on the main queue
Reviewed By: javache

Differential Revision: D5328995

fbshipit-source-id: 6ef6c260a01ee3b088665b13587ff25b84b51771
2017-06-28 06:16:54 -07:00
Summer KitaharaandFacebook Github Bot 937568b472 Fixing typo in AppContainer
Summary: Fixed a typo. Adding an optional wrapper component to AppContainer.

Reviewed By: fkgozali

Differential Revision: D5330056

fbshipit-source-id: 8e33fcbfb21168c641abbd54b79d272a7c361889
2017-06-27 18:15:58 -07:00
Spencer AhrensandFacebook Github Bot afa47924d6 warn when setting pagingEnabled when snapToInterval at the same time
Reviewed By: fkgozali

Differential Revision: D5326342

fbshipit-source-id: 2bf6b66f81e9aedaad288495f254f04af32dc63d
2017-06-27 16:22:45 -07:00
Valentin SherginandFacebook Github Bot 2b1795c5ad Support <TextInput keyboardType="numeric" returnKeyType="done" /> on iOS
Summary:
Standard only-numeric (number pad) keyboard on iOS does not have any "Done" or "Enter" button, and this is often very badly hurt user experience.
Usually it can be solved by implementing custom `inputAccessoryView`, but RN does not have built-in support for customizing it.
So, this commit introduced limited support only for "Done" button (returnKeyType="done") and it should suite very well for the vast majority of use cases.
This is highly requested feature, see more details here:
https://github.com/facebook/react-native/issues/1190

Reviewed By: mmmulani

Differential Revision: D5268020

fbshipit-source-id: 90bd5bffac6aaa1fb7c5c2ac539b35b04d45918f
2017-06-27 16:22:45 -07:00
Valentin SherginandFacebook Github Bot 1081b21f3e Bunch of <TextInput> props was unified
Reviewed By: mmmulani

Differential Revision: D5144743

fbshipit-source-id: ee82f84d7a54a60c72c14fd24396bf65fa60639e
2017-06-27 16:22:45 -07:00
Valentin SherginandFacebook Github Bot a8c45ac1c3 RCTTextInput: Common layout logic was moved to base class
Summary:
Nothing really changed except that there is no code duplication in this part anymore.
More unification is coming!

Reviewed By: mmmulani

Differential Revision: D5144435

fbshipit-source-id: 390f795be3228907b254f8656783232013c36abe
2017-06-27 16:22:44 -07:00
Valentin SherginandFacebook Github Bot 3364488af0 Introducting RCTTextInput, base class for both text inputs
Summary: Some basic same to both classes functionality was moved to base class, and it is just a beginning.

Reviewed By: mmmulani

Differential Revision: D5144429

fbshipit-source-id: 56c6400d46f4cf3c0058fe936cba524dd5d490df
2017-06-27 16:22:44 -07:00
Valentin SherginandFacebook Github Bot 6ba8e29c89 Introducing RCTBackedTextInputViewProtocol
Summary: RCTBackedTextInputViewProtocol is supposed to unify interface of backed text inputs which will make them accessible from managers and wrapper views.

Reviewed By: mmmulani

Differential Revision: D5144428

fbshipit-source-id: 473e7364d4af2edcd87c5555200e1325c38a8214
2017-06-27 16:22:44 -07:00
Valentin SherginandFacebook Github Bot 2bf41672f8 placeholderText was renamed to just placeholder in RCTTextView
Summary: We have to have RCTTextView and RCTTextInput as much unified as possible, and this is a small step in this direction.

Reviewed By: javache

Differential Revision: D5143877

fbshipit-source-id: ee8fcab6093fe5d994c85110b07ea16e64fed262
2017-06-27 16:22:44 -07:00
Valentin SherginandFacebook Github Bot 719f0005f6 editable property was implemented for RCTUITextField
Summary: `UITextField` surprisingly does not have `editable` property (only UITextView does), so we have to implement it ourselfs.

Reviewed By: javache

Differential Revision: D5153070

fbshipit-source-id: 5a76c623fc5c7c3eec10c600c942cf82c93833cd
2017-06-27 16:22:44 -07:00
Wenjia MaandFacebook Github Bot f954f3d9b6 Add velocity to onScrollEndDrag event
Reviewed By: achen1

Differential Revision: D5330215

fbshipit-source-id: e45a302b325c38294324f4f384a5604355dc05aa
2017-06-27 15:57:00 -07:00
Hector RamosandFacebook Github Bot 75eb55096e Increase text size, rename Tutorial, update nav...
Summary:
Several things here. See commits.
Closes https://github.com/facebook/react-native/pull/14757

Differential Revision: D5332034

Pulled By: hramos

fbshipit-source-id: 6ff9e33c0bc9d2ea3dd5b1a4752621ce7e83f9bb
2017-06-27 14:18:07 -07:00
Dapeng GaoandFacebook Github Bot 7ee051db28 Clearer code in Button.js
Summary:
Thanks for submitting a PR! Please read these instructions carefully:

- [x] Explain the **motivation** for making this change.
- [x] Provide a **test plan** demonstrating that the code is solid.
- [x] Match the **code formatting** of the rest of the codebase.
- [x] Target the `master` branch, NOT a "stable" branch.

What existing problem does the pull request solve?
* Combined repeating `if` checks for clearer logic.
* `defaultBlue` is inlined because it is only used once for each OS.

- Updated the `Button.js` file in an existing project and all buttons behave exactly the same. Here is a simple demo:
  ![](http://i.makeagif.com/media/6-11-2017/B0Bhry.gif)

- There is no change in the underlying logic of the code.
Closes https://github.com/facebook/react-native/pull/14455

Differential Revision: D5330112

Pulled By: hramos

fbshipit-source-id: 7fd1a0609f0bb2123208d0e1b3da2bc779f9583d
2017-06-27 11:33:34 -07:00
Pieter De BaetsandFacebook Github Bot 14538aa038 Export some more symbols
Reviewed By: alexeylang

Differential Revision: D5328772

fbshipit-source-id: 7122af7e9bcb14ecdb224fd63ea1be57e4c7f20e
2017-06-27 11:16:13 -07:00
Dirk StoopandFacebook Github Bot 58aca39105 Fix #14566, image in second code sample not rendering
Summary:
Fixes #14566, as suggested by hramos. Only change from our convo is that I set the height to 180 in this pull request instead of 240. This to respect the aspect ratio of the source image.

- run website, visit in browser, verify that second example code section renders correctly
- copy and paste example code of second example into the App.js of a freshly created react native app
- prepend "export default" to line 4 of the pasted code
- run the app for ios or android (npm start ios)
- verify that the image of that terrible high-five actually renders in the app now

Closes https://github.com/facebook/react-native/pull/14571

Differential Revision: D5330093

Pulled By: hramos

fbshipit-source-id: a0afcd16d07ac25080af41f9619df0703f11b152
2017-06-27 11:16:13 -07:00
Spencer AhrensandFacebook Github Bot 1a5489bb70 Fix SnapshotExample
Reviewed By: fkgozali

Differential Revision: D5327149

fbshipit-source-id: 685bd2f52b6457b03db2e49df67c9830dd6c102a
2017-06-27 09:40:24 -07:00
Hector RamosandFacebook Github Bot 22ab231c2e Update templates, CONTRIBUTING
Summary:
Continuation of #14730 which didn't land cleanly.
Closes https://github.com/facebook/react-native/pull/14753

Differential Revision: D5329443

Pulled By: hramos

fbshipit-source-id: 2abb94d2aeaeb8694bebdc2dc0319520635d43cd
2017-06-27 09:40:24 -07:00
Alex KringandFacebook Github Bot bb832e1238 Akring integration tests fix
Summary:
Fix a bug that allows us to run integration tests in our android project, where RN is specified as a module to our project.

sdkHandler does not exist. The android documentation suggests that we should be using android.ndkDirectory instead.

http://tools.android.com/tech-docs/new-build-system/migrating-to-1-0-0

An alternative solution would be to set the environment variable ANDROID_NDK, but we do not want to rely on setting this environemnt variable at a system wide level.

We ran two tests.
1.) perform a gradle sync from within our Android studio project, and verify there is no error output.
2.) build android using ./gradleW, from command land. Verify there are no build errors.
Closes https://github.com/facebook/react-native/pull/14136

Differential Revision: D5327421

Pulled By: shergin

fbshipit-source-id: d9e18519a8ca318f2026eb409b90cb09e2adbda1
2017-06-26 21:01:17 -07:00
Summer KitaharaandFacebook Github Bot 162d92da0e Adding an optional wrapper component to app components
Summary: Changing AppContainer to render a wrapper component in it, if it exists. This wrapper is NOT a required property of AppContainer. Now, app-wide properties can be passed down via context to the container's children.

Reviewed By: sahrens, fkgozali

Differential Revision: D5283895

fbshipit-source-id: 8595e22c4b5ebf5d0e57f358152fba8a80cb2723
2017-06-26 16:33:05 -07:00
Brian VaughnandFacebook Github Bot 30352ecbf2 React sync for revisions 4aea7c3...cb32253
Reviewed By: sebmarkbage

Differential Revision: D5322642

fbshipit-source-id: 91ac72b2fc3be9c5805db1ac4bd72d3fcee5b70f
2017-06-26 15:15:59 -07:00
Chris BlappertandFacebook Github Bot c0505cedf1 Packager postprocessing hook
Reviewed By: davidaurelio

Differential Revision: D5244060

fbshipit-source-id: 3f5f9ab9aeeb63eca13d6dab089c2bda42f70c33
2017-06-26 10:31:57 -07:00
Pieter De BaetsandFacebook Github Bot 83faa4b608 Simplify Catalyst handleMemoryPressure
Reviewed By: cwdick

Differential Revision: D5200555

fbshipit-source-id: 86f12acca33ece265d3482ba52de9afcc83173cd
2017-06-26 06:01:14 -07:00
Alexey LangandFacebook Github Bot e2dff82160 Fix visibility of installGlobalFunction(..)
Reviewed By: javache

Differential Revision: D5319733

fbshipit-source-id: cfe796f13920924bbdbdd2a2741a70f492a141f9
2017-06-26 05:15:42 -07:00
David AurelioandFacebook Github Bot 1faf40b02a Upgrade metro-bundler to v0.9.0
Summary: Upgrade metro-bundler to v0.9.0. This version has no functional change. The only change is that the structure of the npm package reflects the structure of the source code.

Reviewed By: bestander

Differential Revision: D5315651

fbshipit-source-id: 3a69337106d4ccf708823c80d304941973360e8e
2017-06-24 17:15:55 -07:00
Ben ClaytonandFacebook Github Bot a38f5b6b6a Document URI for Android asset folder images
Summary:
How to load images from the Android assets folder was undocumented, and took us a little while to find out how to do it.

This is a documentation-only change.

To confirm the syntax works create a sample app with an image at `android/app/src/main/assets/foo.png`.

Then add JSX `<Image style={{width:100, height:100}} source={{uri: 'asset:/foo.png'}} />`.

See that the image is rendered (Android only).
Closes https://github.com/facebook/react-native/pull/14626

Differential Revision: D5316887

Pulled By: AaaChiuuu

fbshipit-source-id: f7d07b8b83d6460de86c1a2efac0955300cfcd78
2017-06-23 20:45:29 -07:00
Kenji MiwaandFacebook Github Bot 08b8216e4f Uninstall app before testing the production build
Summary:
Otherwise you may get the error `"Package <package_name> signatures do not match the previously installed version; ignoring!`

<details>
  Thanks for submitting a PR! Please read these instructions carefully:

  - [ ] Explain the **motivation** for making this change.
  - [ ] Provide a **test plan** demonstrating that the code is solid.
  - [ ] Match the **code formatting** of the rest of the codebase.
  - [ ] Target the `master` branch, NOT a "stable" branch.

  Please read the [Contribution Guidelines](https://github.com/facebook/react-native/blob/master/CONTRIBUTING.md) to learn more about contributing to React Native.
</details>

_What existing problem does the pull request solve?_

_A good test plan has the exact commands you ran and their output, provides screenshots or videos if the pull request changes UI or updates the website._
Closes https://github.com/facebook/react-native/pull/14577

Differential Revision: D5272060

Pulled By: AaaChiuuu

fbshipit-source-id: 23d88b8dddc4a7d8c6f58361a1cbcd8e6bb750d3
2017-06-23 20:31:17 -07:00
Andrew Y. ChenandFacebook Github Bot 076eaec805 Revert D5238126: Add velocity to onScrollEndDrag event
Differential Revision: D5238126

fbshipit-source-id: a8b5f9445fa15a0ef0851303961dbf63b5d46623
2017-06-23 19:02:27 -07:00
Pieter De BaetsandFacebook Github Bot e2628f93b5 Rename Executor to JSExecutor
Summary:
* Cleanup some header files so we use more forward declarations
* Rename Executor to JSExecutor.h
* Move some typedefs to more appropriate locations

Reviewed By: mhorowitz

Differential Revision: D5301913

fbshipit-source-id: e75154797eb3f531d2f42a5e95409f4062b85f91
2017-06-23 17:01:25 -07:00
Tommy ParnellandFacebook Github Bot 6aea140a33 improve choco command
Summary:
<details>
  Thanks for submitting a PR! Please read these instructions carefully:

  - [ x ] Explain the **motivation** for making this change.
  - [ x ] Provide a **test plan** demonstrating that the code is solid.
  - [ x ] Match the **code formatting** of the rest of the codebase.
  - [ x ] Target the `master` branch, NOT a "stable" branch.

  Please read the [Contribution Guidelines](https://github.com/facebook/react-native/blob/master/CONTRIBUTING.md) to learn more about contributing to React Native.
</details>

Consolidates the install to 1 command for windows. Also add the `-y` flag so chocolatey doesn't license prompt for each command.

* Get a windows laptop
* Run the 1 command
Closes https://github.com/facebook/react-native/pull/14710

Differential Revision: D5314510

Pulled By: hramos

fbshipit-source-id: 54d46822eb93d4dec7161ef7d4933d6964f40ef3
2017-06-23 15:52:52 -07:00
Valentin SherginandFacebook Github Bot 44310da324 TextInput: Fixed textWasPaste prop for singleline TextInput
Summary: This regression was recently introduced when RCTTextField was splitted into two classes.

Reviewed By: mmmulani

Differential Revision: D5313055

fbshipit-source-id: 1027ddeed7ea9a4bf6f30b0182092f42588b83e3
2017-06-23 14:16:43 -07:00
Wenjia MaandFacebook Github Bot d4cda7168f Add velocity to onScrollEndDrag event
Summary:
1. Calculated the fling slow down velocity using OnScrollDispatchHelper
2. Calculated the END_DRAG velocity using velocity tracker in VelocityHelper.
3. Change the interface of ReactScrollViewHelper to pass velocity on x & y.

Pending future work:
Calculate the velocity of BEGIN_DRAG, MOMENTUM_BEGIN and MOMENTUM_END
Add threshold in ScrollResponder.js instead of checking x & y velocity equal zero

Reviewed By: achen1

Differential Revision: D5238126

fbshipit-source-id: 35fb70dda8ab66cd152413cb9c1c041354f1c061
2017-06-23 14:00:57 -07:00
Mehdi MulaniandFacebook Github Bot dbd7a4e3a1 Revert D5197885 to unbreak Internal App
Reviewed By: shergin

Differential Revision: D5312189

fbshipit-source-id: 07f6944994068638703611db9522b1861f1688e2
2017-06-23 13:05:49 -07:00
Pieter De BaetsandFacebook Github Bot 7516fa56d7 Reorder module setup in InitializeCore
Reviewed By: fromcelticpark

Differential Revision: D5292888

fbshipit-source-id: 1f1e2f4fcd22f5471117aafdf3b7d73745c14e6b
2017-06-23 10:37:59 -07:00
Andrew Y. ChenandFacebook Github Bot ecccd06662 API check for removeOnGlobalLayoutListener in ReactRootView
Reviewed By: AaaChiuuu

Differential Revision: D5308604

fbshipit-source-id: adf4abbdd59e54c18fcae946f2f7e3af89e7190c
2017-06-23 10:37:59 -07:00
Nick EddyandFacebook Github Bot a6607968c4 Fixing drawing bug in ReactArt on Android
Summary: This change fixes rendering issues with arcs having an inner radius.  The root cause was a bug that lost the negative sign for counter-clockwise angles.  The previous code also incorrectly set the start angle to the end angle.

Differential Revision: D5298320

fbshipit-source-id: 4d11edfed5bdab0cf68313d22f94ef0e3711a1a8
2017-06-23 09:30:37 -07:00
Mike LambertandFacebook Github Bot 1ee602b655 Fix problems if _updateCellsToRender gets called too early
Summary:
(prior to the scroll metrics being set up, or prior to the view being scrolled to the right location).

I'm using a StackNavigator to push a FlatList secondary screen, and it was causing extraneous rendering (item X ->item 0 -> item X)

I've logged inside the render functions of my `renderItem` function, and verified that it no longer attempts to render item 0 anymore. And I've verified from the `VirtualizedList.state` no longer renders a `{first: 0, last: 0}`, but persistently stays at `{first: X, last: X}` from start until things stabilize.
Closes https://github.com/facebook/react-native/pull/14562

Reviewed By: bvaughn

Differential Revision: D5283771

Pulled By: sahrens

fbshipit-source-id: 0f70ac0b89922449bd20bfa69edbc8939eafdf1f
2017-06-22 18:48:19 -07:00
Seth FitzsimmonsandFacebook Github Bot 8e9322c65e react@16 did away with PropTypes; require prop-types instead
Summary:
react@16 (a peerDependency) did away with the PropTypes export in favor of the prop-types module.

This updates all of the remaining references to `React.PropTypes`.
Closes https://github.com/facebook/react-native/pull/14641

Differential Revision: D5287167

Pulled By: javache

fbshipit-source-id: a917e29aa0e5470260568995dfe97f5528ec265e
2017-06-22 13:49:57 -07:00
Kathy GrayandFacebook Github Bot 2b89416ac0 Only load core modules once
Reviewed By: javache, AaaChiuuu

Differential Revision: D5303176

fbshipit-source-id: f00ecacaa695ce7a4f8b57c66cee38bb70883cae
2017-06-22 11:55:19 -07:00
Jan SöndermannandFacebook Github Bot 4429a8dde6 Fix typo
Summary: Closes https://github.com/facebook/react-native/pull/14676

Differential Revision: D5301501

Pulled By: javache

fbshipit-source-id: e9527031a728f2ccc422ef5664b6b8d613c9583f
2017-06-22 11:16:17 -07:00
Pieter De BaetsandFacebook Github Bot b6cfad27f8 Allow no args to be passed to rejection callback
Reviewed By: davidaurelio

Differential Revision:
D5301417

Tags: accept2ship

fbshipit-source-id: a4fb74dd50eb63579e7b69a6d48d4020f718b81c
2017-06-22 10:04:09 -07:00
Pieter De BaetsandFacebook Github Bot d795fa1b2c Update native references to JSTimers
Reviewed By: AaaChiuuu

Differential Revision: D5294997

fbshipit-source-id: 3003d56f744af0c35b1ffef7bdd71617d4f948c3
2017-06-22 09:52:33 -07:00
Pieter De BaetsandFacebook Github Bot 0ae11f12f3 Merge JSTimers and JSTimersExecution
Reviewed By: mmmulani

Differential Revision: D5292923

fbshipit-source-id: d8331cbac28ba3bbf47c9746238a755b707903ea
2017-06-22 09:52:33 -07:00
Pieter De BaetsandFacebook Github Bot e9f657f2bd Stop using Map in JSTimers
Reviewed By: fromcelticpark

Differential Revision: D5292912

fbshipit-source-id: a14552b895d586cf24627cc457069d9909b2ecc2
2017-06-22 09:52:33 -07:00
Pieter De BaetsandFacebook Github Bot 94d9f00dd6 Remove unused RCTRenderingPerf
Reviewed By: josephsavona

Differential Revision: D5292898

fbshipit-source-id: 33605c994c3457134556acc328542611a2247d27
2017-06-22 09:01:04 -07:00
Alan WangandFacebook Github Bot 09ba07e4fa fix error caused by first argument short when calling warning function
Summary:
<details>
  Thanks for submitting a PR! Please read these instructions carefully:

  - [X] Explain the **motivation** for making this change.
  - [] Provide a **test plan** demonstrating that the code is solid.
  - [X] Match the **code formatting** of the rest of the codebase.
  - [X] Target the `master` branch, NOT a "stable" branch.

  Please read the [Contribution Guidelines](https://github.com/facebook/react-native/blob/master/CONTRIBUTING.md) to learn more about contributing to React Native.
</details>

My app crashed when I call navigator.geolocation.stopObserving(). I found it is caused by the reason that one argument short. So I added false to the first argument. Then bug is fixed.

1. call both navigator.geolocation.watchPosition and navigator.geolocation.getCurrentPosition
2. then call navigator.geolocation.stopObserving()
3. error happened before I fixed, and correct Warning "Called stopObserving with existing subscriptions." shown after I fixed.
Closes https://github.com/facebook/react-native/pull/14673

Differential Revision: D5301503

Pulled By: javache

fbshipit-source-id: 9e85064beb1052bb89bf42355ffd308fe9eaec53
2017-06-22 08:46:43 -07:00
Pieter De BaetsandFacebook Github Bot c5004d5dd0 Make startup errors in the websocket executor invalidate the bridge
Reviewed By: mhorowitz

Differential Revision: D5226936

fbshipit-source-id: b6d605974674d0e6f86559f2583553e3636d389b
2017-06-22 08:37:13 -07:00
Nathaniel Rankin WebbandFacebook Github Bot 502604074c Fixed ScrollView's .scrollToEnd to refrain from exceeding start boundary.
Summary:
Thanks for submitting a pull request! Please provide enough information so that others can review your pull request:

> **Unless you are a React Native release maintainer and cherry-picking an *existing* commit into a current release, ensure your pull request is targeting the `master` React Native branch.**

Explain the **motivation** for making this change. What existing problem does the pull request solve?

The problem occurs when a ScrollView's content height is smaller than the ScrollView height.  If the method `scrollToEnd` is called on the ScrollView, it will pull the content down until the bottom of the content is aligned with the bottom of the Scrollview container.

This fix will ensure the proper functionality: That the furthest the ScrollView can scroll down is to where the top of the content container is at the origin (i.e., the ScrollView scroll number cannot be less than 0).

Prefer **small pull requests**. These are much easier to review and more likely to get merged. Make sure the PR does only one thing, otherwise please split it.

**Test plan (required)**

Demonstrate the code is solid. Example: The exact commands you ran and their output, screenshots / videos if the pull request changes UI.

Make sure tests pass on both Travis and Circle CI.

I tested on a scenario where the ScrollView is almost the full size of the screen, and the content of the ScrollView has a height of much less.  In this situation, the `scrollToEnd` method was executed and the content stayed in the same position.  This is the intended behavior.  If the content of the ScrollView is smaller than the height of the ScrollView, then the `scrollToEnd` method should not scroll anywhere.

**Code formatting**

Look around. Match the style of the rest of the codebase. See also the simple [style guide](https://github.com/facebook/react-native/blob/master/CONTRIBUTING.md#style-guide).

For more info, see the ["Pull Requests" section of our "Contributing" guidelines](https://github.com/facebook/react-native/blob/master/CONTRIBUTING.md#pull-requests).
Closes https://github.com/facebook/react-native/pull/12889

Reviewed By: javache

Differential Revision: D5289894

Pulled By: sahrens

fbshipit-source-id: df2e779ee855c1dea85d33649d754371ad244bca
2017-06-21 18:20:34 -07:00
Kathy GrayandFacebook Github Bot 4566f01fbd Fix package order on reactinstancemanager
Reviewed By: alexeylang

Differential Revision: D5296348

fbshipit-source-id: bfd859085758f1f78a927b2ad4464ed9aff82c58
2017-06-21 16:30:38 -07:00
Hector RamosandFacebook Github Bot 4f74b752df Backfill with React Native posts from code.facebook.com
Summary:
Adding links to related posts from Facebook Code
Closes https://github.com/facebook/react-native/pull/14666

Differential Revision: D5296691

Pulled By: hramos

fbshipit-source-id: cbd3d2349b162268fcbc7478d8a083ccd6e5154a
2017-06-21 16:05:17 -07:00
dlowder-salesforceandFacebook Github Bot 31fe832d04 Fix Apple TV compile errors
Summary:
Apple TV compilation is currently broken in master -- this fixes it.

Existing tests will pass after this change.
Closes https://github.com/facebook/react-native/pull/14652

Differential Revision: D5295021

Pulled By: javache

fbshipit-source-id: 8b4b0db0afa1caeacac0ad01abbed80fa7e39738
2017-06-21 15:16:31 -07:00
Brian VaughnandFacebook Github Bot 119959252e Remove RN fiber createClass wrapper around View
Reviewed By: spicyj

Differential Revision: D5241527

fbshipit-source-id: 9209004544e83cc0f03fcaa27c9b1acf8db09930
2017-06-21 12:38:06 -07:00
tenodiandFacebook Github Bot 31e1f37314 Blog post for React Native monthly meeting #1
Summary:
A blog post with notes from the first React Native monthly meeting.

I've gathered notes after the meeting in this blog post. Think it might be useful for a broader audience in React Native community.

No test plan, submitting just a documentation file.

cc hramos ericvicenti
Closes https://github.com/facebook/react-native/pull/14665

Differential Revision: D5294423

Pulled By: hramos

fbshipit-source-id: be7641622902cda47f391a2364e0f5aac45403ea
2017-06-21 12:08:45 -07:00
Kathy GrayandFacebook Github Bot 5c5410459e Setting bridge up for sharing: allowing native modules to register after init
Reviewed By: javache

Differential Revision: D4945784

fbshipit-source-id: 80e7236e9ccd5d5c9a7fba7c96b98fc38b43a2fc
2017-06-21 12:08:45 -07:00
Nurzhan BakibayevandFacebook Github Bot 1ae54b5108 Separate port constant for inspector proxy server.
Reviewed By: johnislarry

Differential Revision: D5282980

fbshipit-source-id: e714965e2bb4849e24138d326c757352b238aba6
2017-06-21 08:01:44 -07:00
ArturKlajnerokandFacebook Github Bot 7d1981ef82 Removing test-driver symlink in ios third party install script
Summary:
After execution of `scripts/ios-install-third-party.sh` a symlink is created :
`<YOUR-APP-PATH>/node_modules/react-native/third-party/glog-0.3.4/test-driver`
that is pointing to `test-driver -> /usr/share/automake-1.14/test-driver`
This can be executed indirectly by `react-native run-ios`.

This breaks the bundle process if the system don't contain a given file under the link and having this strict dependency on the system setup is not a good practice.

Once the `test-driver` symlink is created android app release is failing, for :
`./gradlew assembleRelease`
the `:app:bundleReleaseJsAndAssets` returns :
```
FAILURE: Build failed with an exception.

* What went wrong:
Could not list contents of '<YOUR-APP-PATH>/node_modules/react-native/third-party/glog-0.3.4/test-driver'. Couldn't follow symbolic link.
```
Related issues:
https://github.com/facebook/react-native/issues/14417
https://github.com/facebook/react-native/issues/14464
https://github.com/facebook/react-native/issues/14548

1. Create new project with `react-native init <YOUR-APP>`
2. cd `<YOUR-APP>/`
3. Run app on iOS `react-native run-ios` so `scripts/ios-install-third-party.sh` is executed.
4. cd `android/`
5. Run android app release `./gradlew assembleRelease` (it will work properly after this fix and fail if the `test-driver` symlink exists)

IMHO we should resolve the issue with this quick fix and apply the proper fix later after the new version of `google/glog` will be released.
The proper cleanup of files generated by autotools was already applied : https://github.com/google/glog/pull/188

Please let me know if I should provide more details : javache, mhorowitz, hramos
Closes https://github.com/facebook/react-native/pull/14638

Differential Revision: D5292362

Pulled By: javache

fbshipit-source-id: 81ff2273420ea078d624a76e781a5b67b96e6a4e
2017-06-21 07:45:37 -07:00
Janic DuplessisandFacebook Github Bot 5c53f89dd8 Fix configure glog script when building from xcodebuild
Summary:
I encountered an issue when building with fastlane gym / xcodebuild where glog would not build because of missing config.h header file. I tracked it down to the ios-configure-glog.sh script that ended up error-ing because of missing valid c compiler. I guess it didn't enter the if to set c compiler env in xcodebuild and that env doesn't have proper values set like it does in xcode so just removing this check fixed it. Also tested that it still works properly in xcode.
Closes https://github.com/facebook/react-native/pull/14267

Differential Revision: D5285691

Pulled By: javache

fbshipit-source-id: df5315926c2d2d78806618df3d9c9bbbb974d1ea
2017-06-21 06:45:28 -07:00
David AurelioandFacebook Github Bot 1230549c77 Upgrade babel-preset-fbjs
Summary: Upgrades `babel-preset-fbjs` to v2.1.4, which has better support for moving es2015 imports around.

Reviewed By: BYK

Differential Revision: D5287818

fbshipit-source-id: a2fa7b0267b913f126b37946cf24dd4c5146c245
2017-06-21 02:00:44 -07:00
Tim YungandFacebook Github Bot 5550a25628 RN: Expose unstable_batchedUpdates on react-native
Reviewed By: spicyj

Differential Revision: D5284484

fbshipit-source-id: bdc0a1c3babfa1a5c3343f084bdd5d4ff4f2d46a
2017-06-21 00:47:08 -07:00
Justin StanleyandFacebook Github Bot bc718fd729 Fixed an incorrect word in the blurTextInput() documentation.
Summary:
In `TextInputState`'s `blurTextInput()` documentation, the parameter description`id of the text field to focus` should be `id of the text field to unfocus`, since this is `blurTextInput` and not `focusTextInput`.

N/A (just documentation fix).
Closes https://github.com/facebook/react-native/pull/14367

Differential Revision: D5200263

Pulled By: shergin

fbshipit-source-id: b3e9ab60e555ad9050474b59a728761180618190
2017-06-20 19:31:29 -07:00
Hank BrekkeandFacebook Github Bot ec68536e08 iOS presentationStyle Modal Appearance
Summary:
When using `<Modal` on larger iOS devices, esp. iPad and iPhone 7 Plus devices, there is no way to use the system functionality for controlling the appearance of modals (`presentationStyle`), which improves the native system's animation and display of smaller content appearing within large horizontal space.

I've added a new picker for selecting a `presentationStyle` within  the RNTester app. See below for the appearance of this change, as well as the relevant changes to the RN documentation.

![may-22-2017 09-49-50](https://cloud.githubusercontent.com/assets/3521186/26315020/6d4b1cb0-3ed5-11e7-8ac8-a996f1ee00f9.gif)
<img width="1051" alt="screen shot 2017-05-22 at 9 50 12 am" src="https://cloud.githubusercontent.com/assets/3521186/26315021/6d4cbf7a-3ed5-11e7-9d13-a5d20c9f3533.png">
Closes https://github.com/facebook/react-native/pull/14102

Differential Revision: D5281990

Pulled By: shergin

fbshipit-source-id: 882d8cb79e7adb0b4437cdf26e5e7ab1fc04f4c1
2017-06-20 19:22:57 -07:00
Héctor RamosandFacebook Github Bot 70ca432e5a Add Wix.com
Summary: Closes https://github.com/facebook/react-native/pull/14642

Differential Revision: D5286727

Pulled By: hramos

fbshipit-source-id: 837072234dca7a54371174727881956831c34036
2017-06-20 19:22:57 -07:00
Yu WangandFacebook Github Bot 70e0455522 Implement nativeID prop to allow native code to reference react managed views in iOS
Reviewed By: javache

Differential Revision: D5228055

fbshipit-source-id: 8c934501d4ac946d80bf93d2ddb50f5fc38aea3c
2017-06-20 19:01:27 -07:00
zongwanandFacebook Github Bot d217921b5e Update VirtualizedList.js, fix wrong position after scrollToEnd when props.refreshing === true
Summary:
Pull request again for clean branch

Thanks for submitting a PR! Please read these instructions carefully:

- [x] Explain the **motivation** for making this change.
- [x] Provide a **test plan** demonstrating that the code is solid.
- [x] Match the **code formatting** of the rest of the codebase.
- [x] Target the `master` branch, NOT a "stable" branch.

What existing problem does the pull request solve?
Fix #14033
Fix wrong position after `scrollToEnd` when `props.refreshing === true`

**Before**

![before](https://cloud.githubusercontent.com/assets/1185694/26242273/657f0180-3cba-11e7-9360-49269fd1bb2f.gif)

**After**

![after](https://cloud.githubusercontent.com/assets/1185694/26242503/465a856c-3cbb-11e7-98fb-f3256fd45c15.gif)

Sign the [CLA][2], if you haven't already.

Small pull requests are much easier to review and more likely to get merged. Make sure the PR does only one thing, otherwise please split it.

Make sure all **tests pass** on both [Travis][3] and [Circle CI][4]. PRs that break tests are unlikely to be merged.

For more info, see the ["Pull Requests"][5] section of our "Contributing" guidelines.

[1]: https://medium.com/martinkonicek/what-is-a-test-plan-8bfc840ec171#.y9lcuqqi9
[2]: https://code.facebook.com/cla
[3]: https://travis-ci.org/facebook/react-native
[4]: http://circleci.com/gh/facebook/react-native
[5]: https://github.com/facebook/react-native/blob/master/CONTRIBUTING.md#pull-requests
Closes https://github.com/facebook/react-native/pull/14089

Differential Revision: D5283973

Pulled By: sahrens

fbshipit-source-id: 9bef9a922c15aa5bed11a59acbd7b48a76946d29
2017-06-20 19:01:27 -07:00
Mehdi MulaniandFacebook Github Bot 112e3767ce Fix crash in AccessibilityManager
Summary:
Fix this crash by making sure the RCTDeviceInfo is doing things on the main thread.
This fixes #14043.

Reviewed By: ashwinb

Differential Revision: D5286746

fbshipit-source-id: cce3426a6e7e7221cff82f8bca663d9a060dd358
2017-06-20 18:45:58 -07:00
Valentin SherginandFacebook Github Bot b1e64a448a Refined type for display style property
Reviewed By: javache

Differential Revision: D5185158

fbshipit-source-id: 02fef3862e20e9a5023bfe57601c3cf92ac273e5
2017-06-20 17:16:46 -07:00
Valentin SherginandFacebook Github Bot a04322fa1b Support display: none; style (iOS)
Summary:
Yes, `display: none;` did not work on iOS before this commit.
Now it "just works". It can be useful when some view needs to be hidden temporary and efficiently.

Reviewed By: javache

Differential Revision: D5173936

fbshipit-source-id: 83a03fff04dd3a872d7dd6bf673189f932906776
2017-06-20 17:16:46 -07:00
Valentin SherginandFacebook Github Bot ac3f345b07 Fixed assertion caused by invalid layout of hidden Yoga nodes
Summary:
That's interesting!
If we apply `display: none;` style to some node, Yoga will stop calculation layout for this subtree (which is reasonable).
So, from RN perspective we have to stop applying layout for hidden subtree because it is meaningless and causes another errors.

Note: We do actually not support `display: none;` yet. It stops computing layout, but it does not hide the views!

Reviewed By: javache

Differential Revision: D5168651

fbshipit-source-id: 29a9385c76a0f9d637285fc0d268ccc39879ca0a
2017-06-20 17:16:46 -07:00
Valentin SherginandFacebook Github Bot abfa63c67e Introducing -[RCTShadowView canHaveSubviews]
Summary:
Override `canHaveSubviews` in RCTShadowView subclass to disallow any nested content.
For now, this prop will be checked only in DEV mode for performance reasons.

Reviewed By: javache

Differential Revision: D5189083

fbshipit-source-id: 87087dd806e1fd7320128dab969b13642174f81c
2017-06-20 17:16:46 -07:00
Valentin SherginandFacebook Github Bot d0ad6ad413 Removed support of mysterious "deprecated" scale in RCTImageSource
Reviewed By: fkgozali

Differential Revision: D5197885

fbshipit-source-id: 06b7ee0ed71e07f1db1db053fbbd5f9834d56586
2017-06-20 17:16:43 -07:00
Yu WangandFacebook Github Bot 01adc71ade add cmd+opt+ctrl+D to globally invoke dev menu for Android
Reviewed By: frantic

Differential Revision: D5280788

fbshipit-source-id: ce11d122ee17a2ba8d8aa2e91fc6639610791577
2017-06-20 17:01:46 -07:00
Janic DuplessisandFacebook Github Bot a2b0ee0fc3 FlatList - Add dev validation of the object returned by getItemLayout
Summary:
Returning an object that doesn't have all the required properties from `getItemLayout` doesn't cause a flow error (maybe because we are using `createAnimatedComponent`) and caused ALL items to be rendered which caused perf issues that were hard to debug (typo lenght -> length -_-). This adds a simple warning in DEV mode using checkPropTypes.

**Test plan**
Tested in RNTester by passing a bad `getItemLayout` function.
![image](https://cloud.githubusercontent.com/assets/2677334/26329030/5b32ba90-3f13-11e7-9190-08f05a5c0682.png)
Closes https://github.com/facebook/react-native/pull/14111

Differential Revision: D5283942

Pulled By: sahrens

fbshipit-source-id: 8909532dfddd8628b7fb3380c198f0dfa88f240a
2017-06-20 10:45:32 -07:00
Janic DuplessisandFacebook Github Bot 407ec0023f Disable subview clipping when sticky headers are enabled
Summary:
Subview clipping still causes issues on Android and would be pretty hard to fix properly, I investigated this a bit and sticky header views are getting removed because it doesn't take transform into consideration. It would also require to recalculate subview clipping on every transform change so I think it is better to just disable subview clipping in when there are sticky headers, especially since we seem to be moving away from subview clipping with things like FlatList.

**Test plan**
Tested that sticky headers work in ListView paging example.

Fixes #14000
Closes https://github.com/facebook/react-native/pull/14010

Differential Revision: D5283723

Pulled By: sahrens

fbshipit-source-id: 183b3202765ae09aaae05497694c3f514e969ea1
2017-06-20 09:34:55 -07:00
Rene WeberandFacebook Github Bot 75508c12ff Add setNativeProps
Summary:
Curently FlatList does not implement setting native props directly like the old ListView did. This pr introduce the `setNativeProps` function which delegates to MetroListView or VirtualizedList. Thos don't have `setNativeProps` handling either, so, I delegated further to the respective ListView and Scroll components, which do have handling for it, thus, allowing to set the native props through FlatList.

Create a project with a FlatList and change a native property using `setNativeProps`:

```javascript
  componentDidMount() {
        setInterval(() => {
            this.list.setNativeProps({ style: {backgroundColor:"white"} })
        }, 1000)
    }

  render() {
    return (
      <View style={styles.container}>
        <FlatList ref={component => this.list = component}
                  style={{backgroundColor:"black"}}
                  data={[{key: 'a'}, {key: 'b'}]}
                  renderItem={({item}) => <Text>{item.key}</Text>} />
      </View>
    )
  }
```

Fixes #13501
Closes https://github.com/facebook/react-native/pull/13529

Differential Revision: D5283593

Pulled By: sahrens

fbshipit-source-id: 8f96f88e286042d82452fef924689b5a8a783987
2017-06-20 09:34:55 -07:00
Guy BlankandFacebook Github Bot 60783aa6ba Expose content-available APS key for iOS silent push
Summary:
<details>
  Thanks for submitting a PR! Please read these instructions carefully:

  - [ ] Explain the **motivation** for making this change.
  - [ ] Provide a **test plan** demonstrating that the code is solid.
  - [ ] Match the **code formatting** of the rest of the codebase.
  - [ ] Target the `master` branch, NOT a "stable" branch.

  Please read the [Contribution Guidelines](https://github.com/facebook/react-native/blob/master/CONTRIBUTING.md) to learn more about contributing to React Native.
</details>

_What existing problem does the pull request solve?
In iOS when sending a silent push notification you need to configure the 'content-available' APS key to the value of 1 (When this key is present, the system wakes up your app in the background and delivers the notification to its app delegate, see [apple docs](https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/PayloadKeyReference.html#//apple_ref/doc/uid/TP40008194-CH17-SW1)).

This PR exposes this property to the notification event handler so app code can handle silent push scenario specifically. Currently this property is not available.

I've updated the PushNotificationIOSExample in the RNTester.

1. Open RNTester in xcode
2. Enable the  push notifications capability
3. run on device
4. Go to PushNotificationIOS
5. click on "send fake notification"
6. verify alert message contains 'content-available' with a value of 1.
Closes https://github.com/facebook/react-native/pull/14584

Differential Revision: D5279181

Pulled By: shergin

fbshipit-source-id: d2288e147d89ba267f54265d819aa0a9969095e7
2017-06-19 16:46:31 -07:00
Mike LambertandFacebook Github Bot ebcf5fd241 Fix initial-render triggering a render of all items.
Summary:
When rendering a large list without a getItemLayout (ie SectionList, where it's hard to compute), it freaks out and attempt to render them all, starving the rendering/layout engine from computing the size (and more accurately figurnge out how few it actually should render.)

Before this change, with <FlatList maxToRenderPerBatch={5} data={objectOfLengthN} />, I essentially saw it doing:
```
{first: 0, last: 0}
{first: 0, last: 5}
{first: 0, last: 10}
....
{first: 0, last: N}
```
(no more hiPri renders since all elements have been rendered)
(actually renders and lays out all N objects, and computes their sizes)
(realizes that it doesn't need to show all N for my current screen size and row size)
```{first: 0, last: 55}```

After this change, that whole first part where it keeps incrementing `last` to try to "keep up with the scrolling" disappears.
Closes https://github.com/facebook/react-native/pull/14563

Differential Revision: D5278796

Pulled By: sahrens

fbshipit-source-id: 5db117b40909ec4bc92fba9b5556c6a2add046ac
2017-06-19 16:04:44 -07:00
Andrew Y. ChenandFacebook Github Bot 3c4057cbb4 Revert D5172643: [ReactImageView] Remove useless code from ReactImageView.RoundedCornerPostprocessor
Differential Revision: D5172643

fbshipit-source-id: d8d27586d81479c950fe3dd49b24ad5ee29861fc
2017-06-19 14:46:49 -07:00
Tim YungandFacebook Github Bot a26d87628c RN: Improve Audio for Maintaining Priority
Summary:
The React Native Remote Debugger page (`debugger.html`) contains an embedded silent sound file to maintain tab priority in Google Chrome.

This revision simply replaces the existing one with a better one that has the following characteristics:

- 1s Duration
- 10Hz Frequency
- -48dBFS Amplitude
- Fades in/out to reduce audible clicks on loop.
- 44.1kHz @ 16bit to maximimize compatibility.
- Smaller size.

Much thanks to Stephane Pigeon (http://stephanepigeon.com/) for designing the sound file specifically for this use case.

Reviewed By: mmmulani

Differential Revision: D5273591

fbshipit-source-id: 81668cc0a829e008263907fc1fa7150b72691371
2017-06-19 13:30:51 -07:00
Andrew Y. ChenandFacebook Github Bot e82ceb24eb Fix dev loading indicator
Reviewed By: AaaChiuuu

Differential Revision: D5277176

fbshipit-source-id: 04a8af068310490957e8bc1e690e2cdb927e4dff
2017-06-19 13:16:19 -07:00
TinoandFacebook Github Bot 3ba8e6a901 Keyboard will show documentation
Summary:
Clarified documentation for keyboardWillShow on Android as seen in issue #14275

Clarifies documentation of keyboardWillShow

None as it is just a comment that changed.
Closes https://github.com/facebook/react-native/pull/14350

Differential Revision: D5275173

Pulled By: shergin

fbshipit-source-id: d4fb08de71e6be40bb363dfc82d38b191570c476
2017-06-19 11:06:33 -07:00
Hector RamosandFacebook Github Bot 8aabce3f1c Clean up the help page
Summary: Closes https://github.com/facebook/react-native/pull/14569

Differential Revision: D5275055

Pulled By: hramos

fbshipit-source-id: 1393da637a970e89fba40ea694641e4c26dfa3d9
2017-06-19 10:30:33 -07:00
Pieter De BaetsandFacebook Github Bot 3e4a8928b3 Fix reference to invariant
Reviewed By: davidaurelio, bvaughn

Differential Revision: D5274530

fbshipit-source-id: 0b75976bb91b530a371521d5381a3d53f0ad2640
2017-06-19 08:46:32 -07:00
Aleksei AndrosovandFacebook Github Bot 8377b30b8d ImageBackground: use cached styles
Summary:
Replace object with cached styles from StyleSheet

Create new style object may cause performance problems

Check that ImageBackground position works the same way.
Closes https://github.com/facebook/react-native/pull/14486

Differential Revision: D5274503

Pulled By: shergin

fbshipit-source-id: 09b81e6f7ae2ada7f68854e409909caafd85e56a
2017-06-19 08:46:32 -07:00
David AurelioandFacebook Github Bot 86328e9266 Upgrade babel-transform-react-native to v2.0.0
Summary: Upgrades `babel-transform-react-native` to v2.0.0, which exposes a factory function. That way, the preset will include/exclude dev tools according to `process.env.NODE_ENV` even when that value changes over time.

Reviewed By: cpojer

Differential Revision: D5246801

fbshipit-source-id: 74a1e7e0fb1476750e1fe21ce4befd475907b415
2017-06-19 08:22:23 -07:00
Andrew Y. ChenandFacebook Github Bot 56969d51fa Don't crash if Window permission isn't granted for dev loading view
Reviewed By: AaaChiuuu

Differential Revision: D5263844

fbshipit-source-id: bf10375ddc43158ce77e09682605068e28f690ef
2017-06-19 08:22:23 -07:00
Joe RickerbyandFacebook Github Bot fa147f02e5 Update overflow docstring to add note on Android
Summary:
The overflow: visible option does not work on Android. This just add a little note to the docs of that property to make that clear.

See #3198  and https://react-native.canny.io/feature-requests/p/add-overflow-support-to-android .

Make it clear that this property is unavailable on Android. We had to figure this out by trial and error when porting an existing codebase, a small note in the docs would be helpful!

I could not find how to build the website - I tried `cd website && npm install && node ./server/generate.js` but I'm getting an error (*JSDOC_ERROR: There are no input files to process.*). But it is such a small change I can't see how it would break the docs build!
Closes https://github.com/facebook/react-native/pull/14103

Differential Revision: D5225814

Pulled By: shergin

fbshipit-source-id: a3136e791178d2a7090f324041be23628130199e
2017-06-18 19:45:27 -07:00
Tim YungandFacebook Github Bot ce5ae53669 RN: Replace Workaround w/ Upgraded mock-fs
Reviewed By: cpojer

Differential Revision: D5271612

fbshipit-source-id: 1579f34d4c4e64706f2f128e848b5f6d3d838097
2017-06-18 01:01:59 -07:00
Tim YungandFacebook Github Bot 398746fa09 RN: Remove lodash (Attempt 2)
Reviewed By: cpojer

Differential Revision: D5268874

fbshipit-source-id: 795bc3fda6c29e514b6149f0bdf4f4aa3f131a6d
2017-06-16 18:15:17 -07:00
Taylor KlineandFacebook Github Bot fd34018d08 Use possessive 'its' not 'it's'
Summary:
Very simple documentation grammar update.
Closes https://github.com/facebook/react-native/pull/14567

Differential Revision: D5269433

Pulled By: hramos

fbshipit-source-id: 2cf38166f53d01fa2465da2b25a3247312dabfb7
2017-06-16 17:00:35 -07:00
Naman GoelandFacebook Github Bot 0801d94faa Revert D5255886: [JS] Stop using lodash in RN
Differential Revision: D5255886

fbshipit-source-id: 605dd413a579be5321006ffb26ce9e04843bc0f8
2017-06-16 12:17:00 -07:00
Lukas WöhrlandFacebook Github Bot 3b93ba9af7 The total flex factores need to be a minimum of 1 if any
Summary:
The only thing I found in the spec for this change is the following. Not exactly sure if this is the thing this PR is about:

> For each flex item, subtract its outer flex base size from its max-content contribution size. If that result is not zero, divide it by (if the result was positive) its **flex grow factor floored at 1** or (if the result was negative) by its scaled flex shrink factor, having **floored the flex shrink factor at 1**. This is the item’s max-content flex fraction.

But at least it seems a required change.

Fixes facebook/yoga#566
Closes https://github.com/facebook/yoga/pull/572

Differential Revision: D5264388

Pulled By: emilsjolander

fbshipit-source-id: 0004d1c3b9bad070a98cd6766c1adc06a54475f8
2017-06-16 07:46:28 -07:00
Christoph PojerandFacebook Github Bot 8fa55ca7b5 Stop using lodash in RN
Reviewed By: yungsters

Differential Revision: D5255886

fbshipit-source-id: 18845785c3192f0ae1d02da0b944bc1b3c2fba52
2017-06-16 04:48:02 -07:00
Christoph PojerandFacebook Github Bot 5d515113e7 Don't require prettyFormat in every single bundle.
Summary:
WTF

(I updated it to the latest version too)

Reviewed By: yungsters

Differential Revision: D5256525

fbshipit-source-id: f3c7d620faf817a0e3c1e4c2bed9370318dff40a
2017-06-16 04:31:56 -07:00
Jonathan BalleranoandFacebook Github Bot eaac3b57ee Add a type cast to RCT_ENUM_CONVERTER for C++ compatibility
Summary:
C++ doesn't provide an implicit cast to an enum value from the enum's backing type. When a `.mm` file calls `RCT_ENUM_CONVERTER`, we end up with the following compiler error:
> Error: cannot initialize return object of type `<TypeName>` with an rvalue of type `NSInteger`

Since `RCT_ENUM_CONVERTER` is a macro, this error will appear whenever we try to expand the macro in a C++ context.

The project compiles and runs as expected when this additional cast is added 😃
Closes https://github.com/facebook/react-native/pull/14408

Reviewed By: javache

Differential Revision: D5215584

Pulled By: jballer

fbshipit-source-id: 7f4464afd7cd9dc9a014f646278bae20731f08ba
2017-06-15 19:07:21 -07:00
Marc HorowitzandFacebook Github Bot a555551aaf Add some debug logging if tar fails
Summary: This is to help debug the root cause of https://github.com/facebook/react-native/issues/14423

Reviewed By: javache

Differential Revision: D5254713

fbshipit-source-id: 1ca90205144b3a069d927ba6636f0ef0138b51a0
2017-06-15 13:05:05 -07:00
Marc HorowitzandFacebook Github Bot 4fd427e249 Remove unused folly/File.{h,cpp} from OSS React Xcode project
Summary: This fixes https://github.com/facebook/react-native/issues/14328

Reviewed By: javache

Differential Revision: D5254711

fbshipit-source-id: e9b81e537cca9d6648f44ed61acd127015d2e1f8
2017-06-15 13:05:05 -07:00
Marc HorowitzandFacebook Github Bot f3f44eee59 Work around the broken way CocoaPods/Xcode deals with header maps
Summary:
See https://github.com/facebook/react-native/issues/14326 for the bug
this fixes.  This is a pretty ugly hack to work around what I think is
a CP bug.  Since the C++ dependencies are only needed to build RN
itself, and not applications, don't the conflicting headers as source
files.  Instead, use preserve_paths to get them unpacked into the
source tree under Pods/<Pod>, and arrange for them to get used with
HEADER_SEARCH_PATHS.  This keeps them out of the project, so they
don't get included in the header map, and other (badly structured)
projects don't get confused.

Reviewed By: javache

Differential Revision: D5254716

fbshipit-source-id: cf33dcbcc71b5247843650c33ccf4fb08378e584
2017-06-15 13:05:04 -07:00
Alex DvornikovandFacebook Github Bot c143313a20 Make RCTSamplingProfilerPackagerMethod not depend on RCTBridge
Reviewed By: javache

Differential Revision: D5245899

fbshipit-source-id: a99de4cbf0ddd9c8ee98cbbf438f8930a57e917c
2017-06-15 12:07:34 -07:00
Alex DvornikovandFacebook Github Bot d27ff20588 Make RCTPackagerConnection not depend on RCTBridge
Reviewed By: javache

Differential Revision: D5245497

fbshipit-source-id: 3c41dca98fc39c77d4b3c8932ee2a5b84880cf8c
2017-06-15 12:07:34 -07:00
Alexander ZubkoandFacebook Github Bot 390c8cf96e Add a section about Platform.Version on iOS
Summary:
The docs don't have a section about `Platform.Version` on iOS, but it's available.

Very simple change. I've used the section for Android as an example.
Closes https://github.com/facebook/react-native/pull/14437

Differential Revision: D5250499

Pulled By: hramos

fbshipit-source-id: 29d1323e443fc1c5710283515c4233a192d354a0
2017-06-15 09:21:18 -07:00
Pascal HartigandFacebook Github Bot 2cc1195035 Fix license headers
Reviewed By: IanChilds

Differential Revision: D5255424

fbshipit-source-id: 23439ac035f74f2fd1c756b8185e39199e748e33
2017-06-15 07:45:46 -07:00
Ethan LillieandFacebook Github Bot 2083516f45 Correct its/it's homophone in NativeModulesIOS.md
Summary: Closes https://github.com/facebook/react-native/pull/14522

Differential Revision: D5254055

Pulled By: javache

fbshipit-source-id: aa764fc15baaeb349573b443ec24bbdea1255de9
2017-06-15 03:30:33 -07:00
Aaron ChiuandFacebook Github Bot e48ad9609c tag INITIALIZE_MODULE marker with the non-zero instance key
Reviewed By: javache

Differential Revision: D5255044

fbshipit-source-id: 9bd72970488cfba4271562e83416f6515b9e77b3
2017-06-15 02:50:37 -07:00
Pieter De BaetsandFacebook Github Bot 559805d0b0 Remove SetBuilder
Reviewed By: AaaChiuuu

Differential Revision: D5237184

fbshipit-source-id: dde09febd0d4a5a42a62c7c6fbda3e6713d26152
2017-06-14 16:48:26 -07:00
Aaron ChiuandFacebook Github Bot 7464d5e1a2 use .contains
Reviewed By: achen1

Differential Revision: D5242469

fbshipit-source-id: d666b1264e6e40bb2649ab91bc63ecb6decb1532
2017-06-14 16:31:10 -07:00
Avik ChaudhuriandFacebook Github Bot 71401c1185 update xplat/js to flow 0.48.0
Reviewed By: zertosh

Differential Revision: D5243415

fbshipit-source-id: 78ea4f7f29bcd6a70650f24ceb05f06b18b39018
2017-06-14 15:47:21 -07:00
Hector RamosandFacebook Github Bot 0d3b7fe472 Update guidelines.
Summary:
Consolidate tips on CONTRIBUTING.md, and reduce the wall of text when opening a new issue. Hoping this will encourage more people to read through the text.
Closes https://github.com/facebook/react-native/pull/14518

Differential Revision: D5250443

Pulled By: hramos

fbshipit-source-id: 91213c4ceca12225d9f54d1e1e81e020c6e463b3
2017-06-14 15:16:59 -07:00
Viacheslav RadchenkoandFacebook Github Bot 879edf0d05 Added RCTInspectorDevServerHelper call in FBReactJSExecutor. Added UTF8StringForSourceURL
Reviewed By: javache

Differential Revision: D5246399

fbshipit-source-id: 179ff0b69886c4ff71911fc7b1d3491ff4d5967d
2017-06-14 14:10:10 -07:00
Miguel Jiménez EsúnandFacebook Github Bot c9a39b3bd3 Move jest to version 20
Reviewed By: cpojer

Differential Revision: D5235642

fbshipit-source-id: eaeee1c5f67cf295fdc9798fb13bd5a83706af10
2017-06-14 12:48:22 -07:00
Pieter De BaetsandFacebook Github Bot 9250250364 Call Systrace.setEnabled from CxxBridge
Reviewed By: alexeylang

Differential Revision: D5247016

fbshipit-source-id: 7e31e38d7adae8d432a11199a1de572d082169e3
2017-06-14 11:16:05 -07:00
James BurnettandFacebook Github Bot 383915caeb use default jest automock config setting
Reviewed By: cpojer

Differential Revision: D5246071

fbshipit-source-id: aec9078a5187621745507c4411c40aa993d9d94f
2017-06-14 10:07:58 -07:00
David AurelioandFacebook Github Bot bc22a4da7e Make preset a function to account for different dev settings
Summary: Makes `babel-preset-react-native` a factory function that allows to include/exclude dev tool transforms per transform.

Reviewed By: jeanlauliac

Differential Revision: D5237158

fbshipit-source-id: aa7be0fc0f471575b4ee1c5a0e266e2ed2477fc6
2017-06-14 09:32:37 -07:00
David AurelioandFacebook Github Bot 5c57601769 Remove retainLines and sourceMaps options
Summary:
`retainLines` is no longer necessary with the much improved source map generation.
`sourceMaps` is handled by the transformer itself.

Reviewed By: cpojer

Differential Revision: D5237103

fbshipit-source-id: e5c6bf5aa9d553fce9c3f4d59b3ea0057d45cfdc
2017-06-14 09:32:37 -07:00
Pieter De BaetsandFacebook Github Bot 534bbfac8f Report Java stack from errors from sync native module calls
Reviewed By: mhorowitz

Differential Revision: D5069794

fbshipit-source-id: ede314034a2eb6b063a22dbd6e5d13c8ad66e20c
2017-06-14 09:32:37 -07:00
Pieter De BaetsandFacebook Github Bot d67628eb5a Revert D5245159: [react-native][PR] Fix broken link in /docs/MoreResources.md
Differential Revision: D5245159

fbshipit-source-id: 3f4f28242512634abae08ebd8e815dfc504b9826
2017-06-14 07:36:18 -07:00
Pieter De BaetsandFacebook Github Bot c25f356675 Avoid crash when accessing jsContextRef without an executor
Reviewed By: adamjernst

Differential Revision: D5237039

fbshipit-source-id: 6a86da90605b896093e0ef99b0fcf079bf9854bf
2017-06-14 05:32:27 -07:00
Pieter De BaetsandFacebook Github Bot ce6fb337a1 Breaking - remove unused registration of JS modules
Summary: It's now unnecessary to declare which JS modules you want to expose on your package. To upgrade, remove all overrides of `createJSModules` and keeping calling your JS modules as before.

Reviewed By: AaaChiuuu

Differential Revision: D5229259

fbshipit-source-id: 1160826c951433722f1fe0421c1200883ba1a348
2017-06-14 03:52:17 -07:00
Antoine GrantandFacebook Github Bot 71ea94b51e Fix typo
Summary:
Thanks for submitting a PR! Please read these instructions carefully:

- [x] Explain the **motivation** for making this change.
- [-] Provide a **test plan** demonstrating that the code is solid.
- [-] Match the **code formatting** of the rest of the codebase.
- [x] Target the `master` branch, NOT a "stable" branch.

What existing problem does the pull request solve?
There was a typo.

Sign the [CLA][2], if you haven't already.

Small pull requests are much easier to review and more likely to get merged. Make sure the PR does only one thing, otherwise please split it.

Make sure all **tests pass** on both [Travis][3] and [Circle CI][4]. PRs that break tests are unlikely to be merged.

For more info, see the ["Pull Requests"][5] section of our "Contributing" guidelines.

[1]: https://medium.com/martinkonicek/what-is-a-test-plan-8bfc840ec171#.y9lcuqqi9
[2]: https://code.facebook.com/cla
[3]: https://travis-ci.org/facebook/react-native
[4]: http://circleci.com/gh/facebook/react-native
[5]: https://github.com/facebook/react-native/blob/master/CONTRIBUTING.md#pull-requests
Closes https://github.com/facebook/react-native/pull/14502

Differential Revision: D5245157

Pulled By: javache

fbshipit-source-id: 037e68e4ea585f73802253bb1acdd15dc38cd3b9
2017-06-14 02:03:28 -07:00
Nikolai KatkovandFacebook Github Bot 0431164bbd Fix broken link in /docs/MoreResources.md
Summary:
`Next →` link on `https://facebook.github.io/react-native/docs/more-resources.html` is currently broken

Click on `Next →` link and make sure you are not redirected to the main page
Closes https://github.com/facebook/react-native/pull/14487

Differential Revision: D5245159

Pulled By: javache

fbshipit-source-id: c8bc75af28736ab074c99a238b49368af313e598
2017-06-14 02:03:28 -07:00
CarlosandFacebook Github Bot e428fb4a8b Fix typo
Summary:
Change word exmaple for example

Fix a typo on the Docs
Closes https://github.com/facebook/react-native/pull/14501

Differential Revision: D5242980

Pulled By: javache

fbshipit-source-id: 0d394a5a552df9001729cd01453606a8711081e2
2017-06-14 02:03:27 -07:00
James BurnettandFacebook Github Bot 51c0e81557 remove disableAutomock from jest tests (new default) @bypass-lint
Reviewed By: cpojer

Differential Revision: D5237192

fbshipit-source-id: dccca52a91259d7fea27931f92bca94184a82d4a
2017-06-13 15:04:09 -07:00
Valentin SherginandFacebook Github Bot 7707905550 Improved <ImageBackground>
Reviewed By: sahrens

Differential Revision: D5214113

fbshipit-source-id: 1eca2347f97a1ff13f71906688a33b9ed7a3a7f4
2017-06-13 14:02:40 -07:00
Eric VicentiandFacebook Github Bot c78ddf2c3d Fix header on RNTester file
Reviewed By: hramos

Differential Revision: D5214933

fbshipit-source-id: 42ef48eead88200fc33029923ce1f4b1b5acf3b2
2017-06-13 12:18:45 -07:00
Eric VicentiandFacebook Github Bot c4818d9394 Fix header on RNTester file
Reviewed By: hramos

Differential Revision: D5215027

fbshipit-source-id: 8e2dd4b4bfc94767839b44bf7af489a76d1caad7
2017-06-13 09:47:14 -07:00
Pieter De BaetsandFacebook Github Bot 64825389df Fix timers not firing when running in JS debugger
Reviewed By: mhorowitz

Differential Revision: D5227125

fbshipit-source-id: 3dadb3f2e2fd088853537c09cc019d7be6319444
2017-06-13 09:31:55 -07:00
LxxyxandFacebook Github Bot 96d3be18bf upgrade image-size version fix caculate webp image size bugs
Summary:
When I try to use webp for app. But some webp images get an error message `unsupported file type` by image-size@0.3.5.

And I in image-size repo I found a issue https://github.com/image-size/image-size/issues/65.
This is the same problem.

And try image-size^0.5.1 the error fixed.

![image](https://cloud.githubusercontent.com/assets/13161470/23597366/403a3070-026d-11e7-8666-f4357f1eee73.png)
Closes https://github.com/facebook/react-native/pull/14238

Reviewed By: davidaurelio

Differential Revision: D5145534

Pulled By: javache

fbshipit-source-id: a2aeeae19e928ffefbd0b32501d34069ed37386d
2017-06-13 09:31:55 -07:00
Christoph PojerandFacebook Github Bot 29d9c35e12 Add --maxWorkers flag and allow transformers to run in-band.
Summary:
This diff cleans up some cruft and adds some features:

* It removes the usage of an env variable to control workers.
* It removes the lazy and handwavy calculation on how many workers to use for jest-haste-map. Jest itself uses the maximum amount of workers available and it has never been reported as an issue – especially since it is a one-time startup cost of about 3 seconds on a cold cache only.
* It adds a `--max-workers` flag to replace the env variable. This one is able to control both the number of workers for `jest-haste-map` as well as the transformers.
* It makes the transformers run in the parent process if 1 or fewer workers are are specified. This should help with debugging.

Once you approve this diff, I will publish a new version of metro to npm and update the version used in RN and remove the use of the env variable altogether: https://our.intern.facebook.com/intern/biggrep/?corpus=xplat&filename=&case=false&view=default&extre=&s=REACT_NATIVE_MAX_WORKERS&engine=apr_strmatch&context=false&filter[uninteresting]=false&filter[intern]=false&filter[test]=false&grep_regex=

Note: the process of adding a CLI option is really broken. Commander also has a weird API. We should consider building a better public API for Metro and then consider how to build a new CLI on top of it and simplify our internal integration. I really don't like how Metro is integrated across pieces of the RN cli in ways that is hard to manage. But that is a larger task for another time :)

Reviewed By: jeanlauliac

Differential Revision: D5217726

fbshipit-source-id: 74efddbb87755a9e744c816fbc62efa21f6a79bf
2017-06-13 09:16:03 -07:00
Janic DuplessisandFacebook Github Bot f7044419be Native Animated - Call x.__makeNative before super.__makeNative
Summary:
This fixes a `Attempt to get native tag from node not marked as "native"` error that happens because some animated values are not converted to native before calling the base class `__makeNative`. This makes sure we call the `__makeNative` method of input nodes before calling `super.__makeNative`.

**Test plan**
Tested that it fixes the issue I encountered and that native animations still work with properly in RNTester.
Closes https://github.com/facebook/react-native/pull/14435

Differential Revision: D5236092

Pulled By: javache

fbshipit-source-id: cb02616aec05f220c65b58831ca4334b58d0383b
2017-06-13 08:45:42 -07:00
Josh FarrantandFacebook Github Bot 1dd825d261 Fixed typo in NavigatorIOS.ios.js
Summary:
Bboolean -> Boolean
Closes https://github.com/facebook/react-native/pull/14469

Differential Revision: D5236093

Pulled By: javache

fbshipit-source-id: b9318a933fa37b89dab320a879d3c60490edaeed
2017-06-13 08:31:37 -07:00
Fred LiuandFacebook Github Bot 8dd15f2c87 Allow video uploads
Summary: Allows video uploads from native iOS by using the proper network handler, `RCTAssetsLibrary` rather than `RCTImageLoader`. Currently, uploading a camera roll video via its `assets-library://` URI would upload the first image frame. This fixes it by checking if the `assets-library://` URI is of the extension `MOV`, and if so, declines to process it from `RCTImageLoader`.

Reviewed By: javache

Differential Revision: D5223351

fbshipit-source-id: 8de92c5bb72acb02ed4d9fb92d69f68c8b5d1b36
2017-06-13 08:16:43 -07:00
Pieter De BaetsandFacebook Github Bot 53d5504f40 Stop requiring registration of callable JS modules
Reviewed By: AaaChiuuu

Differential Revision: D5229073

fbshipit-source-id: d6d1967982ae379733a7e9667515ca9f074aadd4
2017-06-13 05:46:31 -07:00
Spencer AhrensandFacebook Github Bot 1d30f833a6 Add inverted option
Reviewed By: bvaughn

Differential Revision: D5210277

fbshipit-source-id: 5a8b196b90a2ac6d20397113ef4bd76446ea9fa3
2017-06-12 22:45:49 -07:00
Spencer AhrensandFacebook Github Bot 0a3e6e0e76 prettier
Reviewed By: fkgozali

Differential Revision: D5210279

fbshipit-source-id: 4b376a09b4bcfb42a2dc48b9903849d58929b7db
2017-06-12 22:45:49 -07:00
Spencer AhrensandFacebook Github Bot 63f7efcd32 Add basic nested VirtualizedList support
Summary:
This uses `context` to render inner lists of the same orientation to a plain `View` without
virtualization instead of rendering nested `ScrollView`s trying to scroll in the same direction,
which can cause problems.

Reviewed By: bvaughn

Differential Revision: D5174942

fbshipit-source-id: 989150294098de837b0ffb401c7f5679a3928a03
2017-06-12 22:45:48 -07:00
Andrew ImmandFacebook Github Bot 2c32acb755 Add https options to RN CLI server
Reviewed By: davidaurelio

Differential Revision: D5223852

fbshipit-source-id: 91025751ddf1f4ec4adcc768b69b936ee1a68edf
2017-06-12 16:15:37 -07:00
Andrew ImmandFacebook Github Bot 50b11aa09b Update remaining PropTypes references
Reviewed By: bvaughn

Differential Revision: D5231309

fbshipit-source-id: d54ee4f73dae63124f4462c138383447829a2551
2017-06-12 16:03:09 -07:00
Brian VaughnandFacebook Github Bot 40b5486eea React sync for revisions a37012a...4aea7c3
Reviewed By: gaearon

Differential Revision: D5222812

fbshipit-source-id: 3dd3dd82f2a8a5080bb3a47b78f92eb26c435b11
2017-06-12 14:20:48 -07:00
Andrew LinfootandFacebook Github Bot 94116dbad5 Add documentation for supporting custom require types
Summary:
See https://github.com/facebook/metro-bundler/pull/4
Closes https://github.com/facebook/react-native/pull/14433

Differential Revision: D5230109

Pulled By: shergin

fbshipit-source-id: f797218ad214dc3912ab3a9bcf837103502bfce4
2017-06-12 13:32:20 -07:00
Pieter De BaetsandFacebook Github Bot 2e4284215c Handle fatal errors thrown by the Chrome debugger
Reviewed By: mmmulani

Differential Revision: D5219190

fbshipit-source-id: 16cff0e08de9c53d7a3e10897ddec3e6924c3bf5
2017-06-12 03:38:51 -07:00
Xin Lux LiuandFacebook Github Bot 947d77dab5 Revert D5176953: [rn] Remove DialogWhenLarge style from devsupport
Differential Revision: D5176953

fbshipit-source-id: 9e43fc71841dcd0edb43ed9de407bab9bb759f3a
2017-06-11 18:34:29 -07:00
Andrew Y. ChenandFacebook Github Bot ac19ddeea8 Revert D5176953: [rn] Remove DialogWhenLarge style from devsupport
Differential Revision: D5176953

fbshipit-source-id: 130e4180de02d4ad14a9c4c5d7a672741b8f40b7
2017-06-11 17:32:18 -07:00
Owen AuchandFacebook Github Bot e8df8d9fd5 Corrected spelling of the word "properties" in error message in ReactAndroid/build.gradle
Summary:
The misspelling in the error message bothered me.

N/A
Closes https://github.com/facebook/react-native/pull/14425

Differential Revision: D5225388

Pulled By: shergin

fbshipit-source-id: b20f31f0685099ae1d1c3dd2de74dfb33eadfd6e
2017-06-11 00:15:40 -07:00
Valentin SherginandFacebook Github Bot b6cf4eeed6 Fixed: blurOnSubmit should be true by default for singleline <TextInput>
Differential Revision: D5224356

fbshipit-source-id: e8a9f607270ab93e40cca3b701bdcb31524137fe
2017-06-10 08:32:24 -07:00
James BurnettandFacebook Github Bot 01afc16bfc disable automock in fbsource/xplat
Reviewed By: cpojer

Differential Revision: D5221281

fbshipit-source-id: 65ef24a0ed59cffadc96b54ae9c4f6d1f677522d
2017-06-10 07:02:10 -07:00
Marco CovaandFacebook Github Bot f908cce679 Rounding error in width/height fixed
Reviewed By: emilsjolander

Differential Revision:
D5209073

Tags: accept2ship

fbshipit-source-id: a3a6a43767aa707ebfa5eee62a83adcdd88d7ce6
2017-06-10 05:35:55 -07:00
Tim YungandFacebook Github Bot 6407071424 RN: Node v8 Workaround for local-cli/core/__tests__
Reviewed By: raluca-elena

Differential Revision: D5224358

fbshipit-source-id: 66c923bd3a38af47fcacbd1ee758bd28253ecf31
2017-06-10 00:08:23 -07:00
Tim YungandFacebook Github Bot 223eab930b RN: Cleanup local-cli/core/__tests__
Reviewed By: raluca-elena

Differential Revision: D5224347

fbshipit-source-id: 99a729c49bec28bf89d9dc91530958beec878828
2017-06-10 00:08:23 -07:00
Tim YungandFacebook Github Bot 82edc131b0 RN: Fix deepFreezeAndThrowOnMutationInDev-test for Node v8.1.0
Reviewed By: raluca-elena

Differential Revision: D5222219

fbshipit-source-id: e34903a506b8e6e0c81e1c21fd9e8e015b25b2d7
2017-06-09 16:04:18 -07:00
Aaron ChiuandFacebook Github Bot a1321aedd7 add a bunch of debug log statements
Reviewed By: achen1

Differential Revision: D5216191

fbshipit-source-id: 8e8e05d4bcd8b2112fbd15b3809946f1caa0edbe
2017-06-09 15:49:57 -07:00
David AurelioandFacebook Github Bot 4990c5c5b3 Move type definitions used for metro bundler from React Native
Summary: Moves type definitions for uglify and babel from React Native to Metro Bundler. We need it there.

Reviewed By: cpojer

Differential Revision: D5217795

fbshipit-source-id: 9ec349cd8caf077eaa3c6fa3d090ffd47893e967
2017-06-09 14:02:05 -07:00
Brian VaughnandFacebook Github Bot 9d4cc7cce4 Check before overriding global.performance
Reviewed By: gaearon

Differential Revision: D5218876

fbshipit-source-id: 7fbe9ca020774a0c53d8cbb64996680112828709
2017-06-09 13:17:41 -07:00
Ben NhamandFacebook Github Bot 2984628357 add marker surrounding entire native module creation
Reviewed By: javache

Differential Revision: D5200856

fbshipit-source-id: 35b0e627224d518126a1cfdd36d6af264dd186cf
2017-06-09 06:22:39 -07:00
Ben NhamandFacebook Github Bot 80bc07fd60 add support for multiple bridge listeners
Reviewed By: AaaChiuuu

Differential Revision: D5200830

fbshipit-source-id: 2a12267edddd2558146721e02a0b80d649755050
2017-06-09 06:22:39 -07:00
Tim YungandFacebook Github Bot 3b6d2cd782 RN: Upgrade to babel-preset-fbjs@2.1.3
Reviewed By: raluca-elena

Differential Revision: D5216819

fbshipit-source-id: 054eea9c3f27da9616c49acfe1b2674bbceb49ec
2017-06-09 02:04:03 -07:00
Adam MiskiewiczandFacebook Github Bot f847fbe021 Fix broken default getProjectRoots
Summary:
In <= 0.44, the default implementation of getProjectRoots() came from `local-cli/core/default.config.js`. With changes happening in the CLI and the packager over the course of the last two months, various pieces of this logic (specifically `local-cli/utils/Config.js`) were rewritten, and though default.config.js was still being imported and used in `local-cli/core/index.js`, the default `getProjectRoots()` was being overriden by the defaults specified in `local-cli/utils/Config.js`.

This PR moves the logic from default.config.js into Config.js and index.js, as appropriate. Specifically:

- The `getProjectCommands()`, `getProjectConfig()`, and `getDependencyConfig()` methods, which have traditionally not been part of the rn-cli.config.js spec, are now defined in `local-cli/core/index.js`.
- The `getProjectRoots()` method, which contained logic for properly resolving the _actual_ project root as well as resolving symlinks within that root, has been moved to `local-cli/utils/Config.js`, to match the fact that other default  rn-cli.config.js definitions live there.
Closes https://github.com/facebook/react-native/pull/14412

Differential Revision: D5216887

Pulled By: hramos

fbshipit-source-id: 7a3840ecf0ad8ea3f6d7bbd3d54e4f02950c6a32
2017-06-09 01:16:45 -07:00
Aaron ChiuandFacebook Github Bot c639a1f802 fix dev reloading
Reviewed By: achen1

Differential Revision: D5187906

fbshipit-source-id: 8c35ee0747bdc0f6748ecdca54e223eafe37e105
2017-06-08 19:31:21 -07:00
Brian VaughnandFacebook Github Bot a4947d1778 React Native sync
Reviewed By: sebmarkbage

Differential Revision: D5214576

fbshipit-source-id: 41f350ce8961851c7404257df8295d505471d9f4
2017-06-08 19:15:59 -07:00
Dan AbramovandFacebook Github Bot 32a0ee0975 Implement Systrace integration for Fiber
Reviewed By: bvaughn

Differential Revision: D5210738

fbshipit-source-id: db7df5ca7a1b4944f86719361d22ec3cc2ce8f22
2017-06-08 14:31:52 -07:00
Alex DvornikovandFacebook Github Bot e38641cd73 Fixed error in _getCallableModule method in MessageQueue
Reviewed By: javache

Differential Revision: D5208462

fbshipit-source-id: 13f71e2b7988305eccfa91c349ff120fad9129f0
2017-06-08 12:49:37 -07:00
Kexi LongandFacebook Github Bot a0a7d97c7b Exposed progressViewOffset to VirtualizedList and FlatList
Reviewed By: sahrens

Differential Revision: D5204107

fbshipit-source-id: df2928830f84ea012d532f24c776dee8d2b96989
2017-06-08 12:32:14 -07:00
Mike LambertandFacebook Github Bot 5840a9051d Fix deltatime calculation.
Summary:
This is necessary to fix an extraneous warning when a VirtualizedList is constructed on the first frame.

On the first frame, the dt is huge (ie, time since epoch).
On the second frame (which may legitimately be slow as a result of a lot to render), it will then assume there were two consecutive slow frames, and print a warning:
  "VirtualizedList: You have a large list that is slow to update..."
Closes https://github.com/facebook/react-native/pull/14393

Differential Revision: D5210467

Pulled By: sahrens

fbshipit-source-id: 2e79218c3d66a4a9df4884f328a125047ef264ed
2017-06-08 12:17:01 -07:00
John O'LearyandFacebook Github Bot 62b20ce582 Scrollview updatedChildFrames data controlled by prop
Summary: Optimize ScrollView by adding flag "DEPRECATED_sendUpdatedChildFrames" to gate whether updatedChildFrames data is computed and propagated on scroll events.  The frame data is used in ListView by the onChangeVisibleRows prop.  When this prop is not defined, unnecessary computation in ScrollView should not be performed.

Reviewed By: sahrens

Differential Revision: D5174898

fbshipit-source-id: e3eaed8760b76becf14dfeb00122bdebdaeae4ef
2017-06-08 12:03:02 -07:00
Alex KotliarskyiandFacebook Github Bot d062cc252e Promise support for C++ bridge
Summary: Looks like `CxxModule::Method` already supports 0..2 callbacks. Based on Obj-C implementation (RCTModuleMethod.m:492) and JS bridge code (NativeModules.js:76), 2 callbacks native method is transformed to JS promise by JS part of the bridge.

Reviewed By: javache

Differential Revision: D5207852

fbshipit-source-id: 5aad86d45b97397f2bc3a4dbc648a60d96a4689e
2017-06-08 11:47:26 -07:00
Christoph PojerandFacebook Github Bot cbb8d6f628 Remove worker from local-cli
Reviewed By: davidaurelio

Differential Revision: D5208910

fbshipit-source-id: 245436276185fff1a516a00d4c631e885f463e53
2017-06-08 10:33:09 -07:00
Jean LauliacandFacebook Github Bot 4a7ebdf757 packager: fix arc lint
Reviewed By: cpojer

Differential Revision: D5209393

fbshipit-source-id: 2efcb4cb7a556690778248a640398c9739ce9a50
2017-06-08 10:22:50 -07:00
James BurnettandFacebook Github Bot 3360999431 disable automock by default in as many places as possible @bypass-lint
Reviewed By: cpojer

Differential Revision: D5190858

fbshipit-source-id: d3125cf81427dbbe3362ef1f958413394a6dc51d
2017-06-08 07:45:54 -07:00
Theo YaungandFacebook Github Bot ba2e486b33 Connection management
Reviewed By: javache

Differential Revision: D5171773

fbshipit-source-id: 6421739736f732e021e85474253ab0ddb3804b0a
2017-06-08 07:45:53 -07:00
Pieter De BaetsandFacebook Github Bot a9e8b7bca5 Remove unused package_js.py
Reviewed By: AaaChiuuu

Differential Revision: D5200573

fbshipit-source-id: 5bc5cc66d3ce979a6ca2db9241e1de4eab45f234
2017-06-08 03:45:41 -07:00
Aaron ChiuandFacebook Github Bot f978109281 Ingore two other test of similar nature (and failure)
Reviewed By: javache

Differential Revision: D5208387

fbshipit-source-id: b32412c1591b2e3e461a3c2a3f99beb9ca7cd552
2017-06-08 02:30:03 -07:00
Hector RamosandFacebook Github Bot 71c812ae0e Restore proper ordering of docs in the sidebar
Summary:
Quickfix: The ordering here was lost when a previous PR was merged.
Closes https://github.com/facebook/react-native/pull/14378

Differential Revision: D5203833

Pulled By: hramos

fbshipit-source-id: 9282a5a5c9aa81ae5e1f5fe6692192ac1db57c08
2017-06-07 15:00:39 -07:00
Hector RamosandFacebook Github Bot f42f2dff37 New Handling Touches Tutorial
Summary:
Finally, a place where `Button` is properly introduced. This is based on the old Handling Touches guide, which has been simplified (with some content moved over to the scroll views tutorial).

I've also updated the ordering of the guides into something that makes more sense to someone just getting started with React Native.
Closes https://github.com/facebook/react-native/pull/14371

Differential Revision: D5201127

Pulled By: hramos

fbshipit-source-id: 819192e2db9febb8a315f51693dae557752b6002
2017-06-07 11:51:21 -07:00
Pieter De BaetsandFacebook Github Bot 81c2f3b189 Cleanup Platform
Reviewed By: dcaspi

Differential Revision: D5185504

fbshipit-source-id: 4f7e9f9068598418b346a7370f6be241a0784b60
2017-06-07 10:19:01 -07:00
Xavier VillelégierandFacebook Github Bot f7c89b4187 Update default blue on iOS
Summary:
Hey,

The `defaultBlue` variable is currently `#0C42FD`. We can see that it's not the same as iOS. According to the official Apple website it's supposed to be `#007AFF`.
See the `Blue` color on [this page](https://developer.apple.com/ios/human-interface-guidelines/visual-design/color/)

No code added.
Closes https://github.com/facebook/react-native/pull/14339

Differential Revision: D5199906

Pulled By: hramos

fbshipit-source-id: c06b0081556dddbfe7fecd255eff941cbbfb95ee
2017-06-07 08:47:36 -07:00
Hector RamosandFacebook Github Bot 4f3da46146 Add Components and APIs Overview Guide
Summary:
Essential components such as View, Text, and Button are easily overlooked amongst the long list of components and APIs due to a lack of categorization. The basic components are already introduced as part of the tutorial, but they may be missed by people who prefer scanning over the docs.

Built website on localhost. Preview of the website as seem on Chrome on macOS:

![screencapture-localhost-8079-react-native-docs-components-and-apis-html-1496357491473](https://cloud.githubusercontent.com/assets/165856/26704237/902d0986-46e2-11e7-9624-17db692ae11e.png)

Preview as seen on an iPhone Plus (via Chrome console):
![screen shot 2017-06-01 at 3 57 00 pm](https://cloud.githubusercontent.com/assets/165856/26704309/05c8ff7e-46e3-11e7-99ff-b7402f5265d4.png)
Closes https://github.com/facebook/react-native/pull/14265

Differential Revision: D5192597

Pulled By: hramos

fbshipit-source-id: f281a14230468458f3da674a82df263fb9f064f4
2017-06-07 08:20:27 -07:00
Christoph PojerandFacebook Github Bot 236e9e4d01 Remove react-native/packager folder.
Summary: This folder is not necessary any longer. All the code now lives in https://github.com/facebook/metro-bundler

Reviewed By: davidaurelio, jeanlauliac

Differential Revision: D5199196

fbshipit-source-id: 35bf0f10a9163f53426db9a76f8f853dceb69167
2017-06-07 07:30:32 -07:00
2923 changed files with 216432 additions and 42974 deletions
+9 -1
View File
@@ -3,4 +3,12 @@
**/staticBundle.js
**/main.js
Libraries/vendor/**/*
packager/src/worker-farm/**/*
Libraries/Renderer/*
website/node_modules
pr-inactivity-bookmarklet.js
question-bookmarklet.js
flow/
website/core/metadata.js
website/core/metadata-blog.js
website/src/react-native/docs/
website/src/react-native/blog/
+17 -25
View File
@@ -1,4 +1,6 @@
{
"root": true,
"parser": "babel-eslint",
"ecmaFeatures": {
@@ -11,6 +13,8 @@
},
"plugins": [
"flowtype",
"prettier",
"react"
],
@@ -49,33 +53,17 @@
"setTimeout": false,
"window": false,
"XMLHttpRequest": false,
"pit": false,
// Flow global types.
"ReactComponent": false,
"ReactClass": false,
"ReactElement": false,
"ReactPropsCheckType": false,
"ReactPropsChainableTypeChecker": false,
"ReactPropTypes": false,
"SyntheticEvent": false,
"$Either": false,
"$All": false,
"$ArrayBufferView": false,
"$Tuple": false,
"$Supertype": false,
"$Subtype": false,
"$Shape": false,
"$Diff": false,
"$Keys": false,
"$Enum": false,
"$Exports": false,
"$FlowIssue": false,
"$FlowFixMe": false,
"$FixMe": false
"pit": false
},
"rules": {
// Flow Plugin
// The following rules are made available via `eslint-plugin-flowtype`
"flowtype/define-flow-type": 1,
"flowtype/use-flow-type": 1,
// General
"comma-dangle": 0, // disallow trailing commas in object literals
"no-cond-assign": 1, // disallow assignment in conditional expressions
"no-console": 0, // disallow use of console (off by default in the node environment)
@@ -176,6 +164,10 @@
"no-restricted-modules": 1, // restrict usage of specified node modules (off by default)
"no-sync": 0, // disallow use of synchronous methods (off by default)
// Prettier Plugin
// https://github.com/prettier/eslint-plugin-prettier
"prettier/prettier": [2, "fb", "@format"],
// Stylistic Issues
// These rules are purely matters of style and are quite subjective.
@@ -241,6 +233,6 @@
"react/prop-types": 0,
"react/react-in-jsx-scope": 1,
"react/self-closing-comp": 1,
"react/wrap-multilines": 0,
"react/wrap-multilines": 0
}
}
+3 -3
View File
@@ -38,12 +38,12 @@ suppress_type=$FlowIssue
suppress_type=$FlowFixMe
suppress_type=$FixMe
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(4[0-7]\\|[1-3][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native_oss[a-z,_]*\\)?)\\)
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(4[0-7]\\|[1-3][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native_oss[a-z,_]*\\)?)\\)?:? #[0-9]+
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(4[0-9]\\|[1-3][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native_oss[a-z,_]*\\)?)\\)
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(4[0-9]\\|[1-3][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native_oss[a-z,_]*\\)?)\\)?:? #[0-9]+
suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError
unsafe.enable_getters_and_setters=true
[version]
^0.47.0
^0.49.1
+9
View File
@@ -0,0 +1,9 @@
docs/* @hramos
blog/* @hramos
Libraries/Animated/* @janicduplessis
Libraries/NativeAnimation/* @janicduplessis
ReactAndroid/src/main/java/com/facebook/react/animated/* @janicduplessis
website/* @hramos
website/showcase.json @hramos
package.json @hramos @ericnakagawa
website/package.json @hramos @ericnakagawa
+112 -32
View File
@@ -1,44 +1,124 @@
Please read the following carefully. Issues that do not follow these guidelines will be closed.
<!--
PLEASE DON'T DELETE THIS TEMPLATE UNTIL YOU HAVE READ THE FIRST SECTION.
-->
We use GitHub Issues exclusively for tracking bugs in React Native.
### Is this a bug report?
- Have a question? Ask on Stack Overflow: http://stackoverflow.com/questions/tagged/react-native
- Have a feature request? Submit it here: https://react-native.canny.io/feature-requests
- Want to know more about future plans? Check out the roadmap: https://github.com/facebook/react-native/wiki/Roadmap
(write your answer here)
## Reporting Bugs
<!--
If you answered "Yes":
Report a single bug per issue.
We expect that it will take you about 30 minutes to produce a high-quality bug report.
While this may seem like a lot, putting care into issues helps us fix them faster.
For bug reports, it is REQUIRED to fill the rest of this template, or the issue will be closed.
### Reproducing bugs
If you answered "No":
- Always provide reproduction steps.
- Use Snack. Try to reproduce your bug on https://snack.expo.io/ first of all.
If the bug cannot be reproduced using Snack, verify that the issue can be reproduced locally by targeting the latest release candidate. Ideally, check if the issue is present in master as well.
- Do not forget to include sample code that reproduces the issue.
We use GitHub Issues exclusively for tracking bugs in React Native. If you're looking for help,
check out the How to Get In Touch section of the following guide:
https://github.com/facebook/react-native/blob/master/CONTRIBUTING.md#how-to-get-in-touch
Issues that do not describe a bug or do not follow the template will be closed.
--- Delete everything above this line ---
### Description
Explain what you did, what you expected to happen, and what actually happens.
### Reproduction Steps and Sample Code
List all the steps required to reproduce the issue you're reporting. These steps should be clear and concise.
***An example of your code or a repro using Snack is REQUIRED***
Now scroll below!
-->
### Solution
### Have you read the Bugs section of the Contributing to React Native Guide?
What needs to be done to address this issue? Ideally, provide a pull request with a fix.
(Write your answer here.)
### Additional Information
<!--
Please read through the bug reporting guidelines thoroughly:
https://github.com/facebook/react-native/blob/master/CONTRIBUTING.md#bugs
-->
* React Native version: [FILL THIS OUT: Be specific, filling out "latest" here is not enough.]
* Platform: [FILL THIS OUT: iOS, Android, or both?]
* Development Operating System: [FILL THIS OUT: Are you developing on macOS, Linux, or Windows?]
* Dev tools: [FILL THIS OUT: Xcode or Android Studio version, iOS or Android SDK version, if applicable]
### Environment
<!--
Please fill in all the relevant fields by running these commands in terminal.
-->
1. `react-native -v`:
2. `node -v`:
3. `npm -v`:
4. `yarn --version` (if you use Yarn):
Then, specify:
<!-- (What platform are you building for? Choose any from iOS, Android, AppleTV.) -->
- Target Platform:
<!-- Which operating system are you using? Specify macOS, Windows, or Linux, along with specific release versions -->
- Development Operating System:
<!-- Include any additional relevant information. Are you using Xcode or Android Studio to build native code? Is the issue specific to a particular iOS or Android SDK? -->
- Build tools:
### Steps to Reproduce
<!--
How would you describe your issue to someone who doesnt know you or your project?
Try to write a sequence of steps that anybody can repeat to see the issue.
Be specific! If the bug cannot be reproduced, your issue may be closed.
-->
(Write your steps here:)
1.
2.
3.
### Expected Behavior
<!--
How did you expect your project to behave?
Its fine if youre not sure your understanding is correct.
Just write down what you thought would happen.
-->
(Write what you thought would happen.)
### Actual Behavior
<!--
Did something go wrong?
Is something broken, or not behaving as you expected?
Describe this section in detail, and attach screenshots if possible.
Don't just say "it doesn't work"!
-->
(Write what happened. Add screenshots!)
### Reproducible Demo
<!--
Please share a project that reproduces the issue.
There are two ways to do it:
* Create a new app using https://snack.expo.io/ and try to reproduce the issue in it.
This is useful if you roughly know where the problem is, or cant share the real code.
* Or, copy your app and remove things until youre left with the minimal reproducible demo.
This is useful for finding the root cause. You may then optionally create a Snack.
This is a good guide to creating bug demos: https://stackoverflow.com/help/mcve
Once youre done, copy and paste the link to the Snack or a public GitHub repository below:
-->
(Paste the link to an example project and exact instructions to reproduce the issue.)
<!--
What happens if you skip this step?
Someone will read your bug report, and maybe will be able to help you,
but its unlikely that it will get much attention from the team. Eventually,
the issue will likely get closed in favor of issues that have reproducible demos.
Please remember that:
* Issues without reproducible demos have a very low priority.
* The person fixing the bug would have to do that anyway. Please be respectful of their time.
* You might figure out the issues yourself as you work on extracting it.
Thanks for helping us help you!
-->
+6 -29
View File
@@ -1,32 +1,9 @@
Thanks for submitting a PR! Please read these instructions carefully:
<!--
Thank you for sending the PR!
- [ ] Explain the **motivation** for making this change.
- [ ] Provide a **test plan** demonstrating that the code is solid.
- [ ] Match the **code formatting** of the rest of the codebase.
- [ ] Target the `master` branch, NOT a "stable" branch.
If you changed any code, please provide us with clear instructions on how you verified your changes work. In other words, a test plan is *required*. Bonus points for screenshots and videos!
## Motivation (required)
Please read the Contribution Guidelines at https://github.com/facebook/react-native/blob/master/CONTRIBUTING.md to learn more about contributing to React Native.
What existing problem does the pull request solve?
## Test Plan (required)
A good test plan has the exact commands you ran and their output, provides screenshots or videos if the pull request changes UI or updates the website. See [What is a Test Plan?][1] to learn more.
If you have added code that should be tested, add tests.
## Next Steps
Sign the [CLA][2], if you haven't already.
Small pull requests are much easier to review and more likely to get merged. Make sure the PR does only one thing, otherwise please split it.
Make sure all **tests pass** on both [Travis][3] and [Circle CI][4]. PRs that break tests are unlikely to be merged.
For more info, see the ["Pull Requests"][5] section of our "Contributing" guidelines.
[1]: https://medium.com/@martinkonicek/what-is-a-test-plan-8bfc840ec171#.y9lcuqqi9
[2]: https://code.facebook.com/cla
[3]: https://travis-ci.org/facebook/react-native
[4]: http://circleci.com/gh/facebook/react-native
[5]: https://github.com/facebook/react-native/blob/master/CONTRIBUTING.md#pull-requests
Happy contributing!
-->
+3
View File
@@ -57,3 +57,6 @@ node_modules
/coverage
/third-party
/website/src
/website/build
+9 -15
View File
@@ -3,25 +3,20 @@ language: objective-c
osx_image: xcode8.3
install:
- mkdir -p /Users/travis/build/facebook/.nvm
- export NVM_DIR="/Users/travis/build/facebook/.nvm"
- brew install nvm
- source $(brew --prefix nvm)/nvm.sh
# TODO npm 2 started stalling on Travis, t11852928
# Use node 6 because that is what runs on land-blocking tests
- nvm install 6
- nvm install 7
- rm -Rf "${TMPDIR}/jest_preprocess_cache"
- wget https://github.com/yarnpkg/yarn/releases/download/v0.16.0/yarn-0.16.0.js
- export yarn="node $(pwd)/yarn-0.16.0.js"
- $yarn install
- brew install yarn --ignore-dependencies
- yarn install
script:
- if [[ "$TEST_TYPE" = objc-ios ]]; then travis_retry travis_wait ./scripts/objc-test-ios.sh test; fi
- if [[ "$TEST_TYPE" = objc-tvos ]]; then travis_retry travis_wait ./scripts/objc-test-tvos.sh; fi
- if [[ "$TEST_TYPE" = objc-ios ]]; then travis_retry travis_wait 30 ./scripts/objc-test-ios.sh test; fi
- if [[ "$TEST_TYPE" = objc-tvos ]]; then travis_retry travis_wait 30 ./scripts/objc-test-tvos.sh; fi
- if [[ "$TEST_TYPE" = e2e-objc ]]; then node ./scripts/run-ci-e2e-tests.js --ios --js --retries 3; fi
- if [[ ( "$TEST_TYPE" = podspecs ) && ( "$TRAVIS_PULL_REQUEST" = "false" ) ]]; then gem install cocoapods && ./scripts/process-podspecs.sh; fi
- if [[ ( "$TEST_TYPE" = podspecs ) && ( "$TRAVIS_PULL_REQUEST" = "false" ) ]]; then gem install cocoapods && travis_wait 30 ./scripts/process-podspecs.sh; fi
cache:
- cocoapods
- yarn
matrix:
- fast_finish: true # Fail the whole build as soon as one test type fails. Should help with Travis capacity issues (very long queues).
@@ -41,7 +36,6 @@ branches:
notifications:
email:
recipients:
- mkonicek@fb.com
- douglowder@mac.com # Doug Lowder built and maintains Apple TV specific code and wants to be notified about tvOS failures.
- eloy@artsy.net # Eloy Durán maintains the podspecs test and wants to be notified about failures.
on_failure: change
+14
View File
@@ -0,0 +1,14 @@
{
// Use IntelliSense to learn about possible Node.js debug attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"program": "${workspaceRoot}/Libraries/react-native/react-native-implementation.js"
}
]
}
+106 -41
View File
@@ -1,44 +1,124 @@
# Contributing to React Native
React Native is one of Facebook's first open source projects that is both under very active development and is also being used to ship code to everybody on [facebook.com](https://facebook.com). We're still working out the kinks to make contributing to this project as easy and transparent as possible, but we're not quite there yet. Hopefully this document makes the process for contributing clear and preempts some questions you may have.
React Native is one of Facebook's first open source projects that is both under very active development and is also being used to ship code to everybody on https://facebook.com. We're still working out the kinks to make contributing to this project as easy and transparent as possible, but we're not quite there yet. Hopefully this document makes the process for contributing clear and preempts some questions you may have.
## Code of Conduct
Facebook has adopted a Code of Conduct that we expect project participants to adhere to. Please read [the full text](https://code.facebook.com/codeofconduct) so that you can understand what actions will and will not be tolerated.
## Our Development Process
Some of the core team will be working directly on GitHub. These changes will be public from the beginning. Other changesets will come via a bridge with Facebook's internal source control. This is a necessity as it allows engineers at Facebook outside of the core team to move fast and contribute from an environment they are comfortable in.
Some of the core team will be working directly on [GitHub](https://github.com/facebook/react-native). These changes will be public from the beginning. Other changesets will come via a bridge with Facebook's internal source control. This is a necessity as it allows engineers at Facebook outside of the core team to move fast and contribute from an environment they are comfortable in.
### `master` is unsafe
## Branch Organization
We will do our best to keep `master` in good shape, with tests passing at all times. But in order to move fast, we will make API changes that your application might not be compatible with. We will do our best to communicate these changes and version appropriately so you can lock into a specific version if need be.
We will do our best to keep `master` in good shape, with tests passing at all times. But in order to move fast, we will make API changes that your application might not be compatible with. We will do our best to [communicate these changes](https://github.com/facebook/react-native/releases) and version appropriately so you can lock into a specific version if need be.
### Pull Requests
To see what changes are coming and provide better feedback to React Native contributors, use the [latest release candidate](http://facebook.github.io/react-native/versions.html) when possible. By the time a release candidate is released, the changes it contains will have been shipped in production Facebook apps for over two weeks.
## Bugs
#### Where to Find Known Issues
We are using [GitHub Issues](https://github.com/facebook/react-native/issues) for our public bugs. Before filing a new task, try to make sure your problem doesn't already exist.
Questions and feature requests are tracked elsewhere:
- Have a question? [Ask on Stack Overflow](http://stackoverflow.com/questions/tagged/react-native).
- If you have a question regarding future plans, check out the [roadmap](https://github.com/facebook/react-native/wiki/Roadmap).
- Have a feature request that is not covered in the roadmap? [Add it here](https://react-native.canny.io/feature-requests).
#### Reporting New Issues
The best way to get your bug fixed is to provide a reduced test case. Please provide either a [Sketch](https://sketch.expo.io/) or a public repository with a runnable example.
Please report a single bug per issue. Always provide reproduction steps. You can use Snack in many cases to demonstrate an issue: https://snack.expo.io/. If the bug cannot be reproduced using Snack, verify that the issue can be reproduced locally by targeting the latest release candidate. Ideally, check if the issue is present in master as well.
Do not forget to include sample code that reproduces the issue. Only open issues for bugs affecting either the latest stable release, or the current release candidate, or master (see http://facebook.github.io/react-native/versions.html). If it is not clear from your report that the issue can be reproduced in one of these releases, your issue will be closed.
We're not able to provide support through GitHub Issues. If you're looking for help with your code, consider asking on Stack Overflow: http://stackoverflow.com/questions/tagged/react-native
#### Security Bugs
Facebook has a [bounty program](https://www.facebook.com/whitehat/) for the safe disclosure of security bugs. With that in mind, please do not file public issues; go through the process outlined on that page.
## How to Get in Touch
Many React Native users are active on [Stack Overflow](http://stackoverflow.com/questions/tagged/react-native).
If you want to get a general sense of what React Native folks talk about, check out the [React Native Community](https://www.facebook.com/groups/react.native.community) Facebook group.
There is also [an active community of React and React Native users on the Discord chat platform](https://discord.gg/0ZcbPKXt5bZjGY5n) in case you need help.
The React Native team sends out periodical updates through the following channels:
* [Blog](https://facebook.github.io/react-native/blog/)
* [Twitter](https://www.twitter.com/reactnative)
Core contributors to React Native meet monthly and post their meeting notes on the React Native blog. You can also find ad hoc discussions in the [React Native Core Contributors](https://www.facebook.com/groups/reactnativeoss/) Facebook group.
## Proposing a Change
If you intend to change the public API, or make any non-trivial changes to the implementation, we recommend [filing an issue](https://github.com/facebook/react-native/issues/new). This lets us reach an agreement on your proposal before you put significant effort into it.
If you're only fixing a bug, it's fine to submit a pull request right away but we still recommend to file an issue detailing what you're fixing. This is helpful in case we don't accept that specific fix but want to keep track of the issue.
## Pull Requests
If you send a pull request, please do it against the master branch. We maintain stable branches for stable releases separately but we don't accept pull requests to them directly. Instead, we cherry-pick non-breaking changes from master to the latest stable version.
The core team will be monitoring for pull requests. When we get one, we'll run some Facebook-specific integration tests on it first. From here, we'll need to get another person to sign off on the changes and then merge the pull request. For API changes we may need to fix internal uses, which could cause some delay. We'll do our best to provide updates and feedback throughout the process.
**Please submit your pull request on the `master` branch**. If the fix is critical and should be included in a stable branch please mention it and it will be cherry picked into it by a project maintainer.
Small pull requests are much easier to review and more likely to get merged. Make sure the PR does only one thing, otherwise please split it.
*Before* submitting a pull request, please make sure the following is done…
1. Fork the repo and create your branch from `master`.
2. **Describe your test plan in your commit.**
- If you've added code that should be tested, add tests!
- If you've changed APIs, update the documentation.
- If you've updated the docs, verify the website locally and submit screenshots if applicable.
```
$ cd website
$ npm install && npm start
Open the following in your browser: http://localhost:8079/react-native/index.html
```
3. Add the copyright notice to the top of any new files you've added.
4. Ensure tests pass on Travis and Circle CI.
2. Add the copyright notice to the top of any new files you've added.
3. Describe your **test plan** in your commit.
4. Ensure **tests pass** on Travis and Circle CI.
5. Make sure your code lints (`node linter.js <files touched>`).
6. If you haven't already, sign the [CLA](https://code.facebook.com/cla).
6. If you haven't already, sign the CLA: https://code.facebook.com/cla
7. Squash your commits (`git rebase -i`).
One intent alongside one commit makes it clearer for people to review and easier to understand your intention.
> **Note:** It is not necessary to keep clicking `Merge master to your branch` on the PR page. You would want to merge master if there are conflicts or tests are failing. The Facebook-GitHub-Bot ultimately squashes all commits to a single one before merging your PR.
#### Test plan
A good test plan has the exact commands you ran and their output, provides screenshots or videos if the pull request changes UI or updates the website.
- If you've added code that should be tested, add tests!
- If you've changed APIs, update the documentation.
- If you've updated the docs, verify the website locally and submit screenshots if applicable (see `website/README.md`)
See "What is a Test Plan?" to learn more:
https://medium.com/@martinkonicek/what-is-a-test-plan-8bfc840ec171#.y9lcuqqi9
#### Continuous integration tests
Make sure all **tests pass** on both [Travis][travis] and [Circle CI][circle]. PRs that break tests are unlikely to be merged.
You can learn more about running tests and contributing to React Native here: https://facebook.github.io/react-native/docs/testing.html
[travis]: https://travis-ci.org/facebook/react-native
[circle]: http://circleci.com/gh/facebook/react-native
#### Breaking changes
When adding a new breaking change, follow this template in your pull request:
```
### New breaking change here
- **Who does this affect**:
- **How to migrate**:
- **Why make this breaking change**:
- **Severity (number of people affected x effort)**:
```
If your pull request is merged, a core contributor will update the [list of breaking changes](https://github.com/facebook/react-native/wiki/Breaking-Changes) which is then used to populate the release notes.
#### Copyright Notice for files
Copy and paste this to the top of your new file(s):
@@ -60,30 +140,15 @@ If you've added a new module, add a `@providesModule <moduleName>` at the end of
In order to accept your pull request, we need you to submit a CLA. You only need to do this once, so if you've done this for another Facebook open source project, you're good to go. If you are submitting a pull request for the first time, just let us know that you have completed the CLA and we can cross-check with your GitHub username.
[Complete your CLA here](https://code.facebook.com/cla)
## Bugs
### Where to Find Known Issues
We are using GitHub Issues for our public bugs. We keep a close eye on this and try to make it clear when we have an internal fix in progress. Before filing a new task, try to make sure your problem doesn't already exist.
### Reporting New Issues
The best way to get your bug fixed is to provide a reduced test case. Please provide either a public repository with a runnable example or a [Sketch](https://sketch.expo.io/).
### Security Bugs
Facebook has a [bounty program](https://www.facebook.com/whitehat/) for the safe disclosure of security bugs. With that in mind, please do not file public issues; go through the process outlined on that page.
## How to Get in Touch
* [Facebook](https://www.facebook.com/groups/react.native.community/)
* [Twitter](https://www.twitter.com/reactnative)
Complete your CLA here: https://code.facebook.com/cla
## Style Guide
### Code
Our linter will catch most styling issues that may exist in your code. You can check the status of your code styling by simply running `node linter.js <files touched>`.
However, there are still some styles that the linter cannot pick up.
### Code Conventions
#### General
-1
View File
@@ -3,7 +3,6 @@ FROM containership/android-base:latest
# set default environment variables
ENV GRADLE_OPTS="-Dorg.gradle.jvmargs=\"-Xmx512m -XX:+HeapDumpOnOutOfMemoryError\""
ENV JAVA_TOOL_OPTIONS="-Dfile.encoding=UTF8"
ENV REACT_NATIVE_MAX_WORKERS=1
# add ReactAndroid directory
ADD .buckconfig /app/.buckconfig
+1 -1
View File
@@ -1,6 +1,6 @@
FROM library/node:6.9.2
ENV YARN_VERSION=0.19.1
ENV YARN_VERSION=0.27.5
# install dependencies
RUN apt-get update && apt-get install ocaml libelf-dev -y
+2 -3
View File
@@ -17,7 +17,6 @@ AVD_UUID=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 8 | head -n 1)
ANDROID_NPM_DEPS="appium@1.5.1 mocha@2.4.5 wd@0.3.11 colors@1.0.3 pretty-data2@0.40.1"
CLI_PACKAGE=$ROOT/react-native-cli/react-native-cli-*.tgz
PACKAGE=$ROOT/react-native-*.tgz
REACT_NATIVE_MAX_WORKERS=1
# solve issue with max user watches limit
echo 65536 | tee -a /proc/sys/fs/inotify/max_user_watches
@@ -231,13 +230,13 @@ function e2e_suite() {
# js tests
if [ $RUN_JS -ne 0 ]; then
# Check the packager produces a bundle (doesn't throw an error)
REACT_NATIVE_MAX_WORKERS=1 react-native bundle --platform android --dev true --entry-file index.android.js --bundle-output android-bundle.js
react-native bundle --max-workers 1 --platform android --dev true --entry-file index.android.js --bundle-output android-bundle.js
if [ $? -ne 0 ]; then
echo "Could not build android bundle"
return 1
fi
REACT_NATIVE_MAX_WORKERS=1 react-native bundle --platform ios --dev true --entry-file index.ios.js --bundle-output ios-bundle.js
react-native bundle --max-workers 1 --platform ios --dev true --entry-file index.ios.js --bundle-output ios-bundle.js
if [ $? -ne 0 ]; then
echo "Could not build iOS bundle"
return 1
@@ -0,0 +1,52 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @flow
* @providesModule AccessibilityManagerTest
*/
'use strict';
const React = require('react');
const ReactNative = require('react-native');
const { View } = ReactNative;
const RCTDeviceEventEmitter = require('RCTDeviceEventEmitter');
const {
TestModule,
AccessibilityManager,
} = ReactNative.NativeModules;
class AccessibilityManagerTest extends React.Component {
componentDidMount() {
AccessibilityManager.setAccessibilityContentSizeMultipliers({
'extraSmall': 1.0,
'small': 2.0,
'medium': 3.0,
'large': 4.0,
'extraLarge': 5.0,
'extraExtraLarge': 6.0,
'extraExtraExtraLarge': 7.0,
'accessibilityMedium': 8.0,
'accessibilityLarge': 9.0,
'accessibilityExtraLarge': 10.0,
'accessibilityExtraExtraLarge': 11.0,
'accessibilityExtraExtraExtraLarge': 12.0,
});
RCTDeviceEventEmitter.addListener('didUpdateDimensions', update => {
TestModule.markTestPassed(update.window.fontScale === 4.0);
});
}
render(): React.Element<any> {
return <View />;
}
}
AccessibilityManagerTest.displayName = 'AccessibilityManagerTest';
module.exports = AccessibilityManagerTest;
+1
View File
@@ -35,6 +35,7 @@ var TESTS = [
require('./PromiseTest'),
require('./SyncMethodTest'),
require('./WebSocketTest'),
require('./AccessibilityManagerTest'),
];
TESTS.forEach(
+3 -1
View File
@@ -12,6 +12,7 @@
'use strict';
var React = require('react');
var createReactClass = require('create-react-class');
var ReactNative = require('react-native');
var {
Image,
@@ -58,7 +59,8 @@ type State = {
containerStyle?: Style,
};
var LayoutEventsTest = React.createClass({
var LayoutEventsTest = createReactClass({
displayName: 'LayoutEventsTest',
getInitialState(): State {
return {
didAnimation: false,
@@ -10,6 +10,7 @@
'use strict';
var React = require('react');
var createReactClass = require('create-react-class');
var ReactNative = require('react-native');
var RCTNativeAppEventEmitter = require('RCTNativeAppEventEmitter');
var Subscribable = require('Subscribable');
@@ -24,7 +25,8 @@ var reactViewHeight = 102;
var newReactViewWidth = 201;
var newReactViewHeight = 202;
var ReactContentSizeUpdateTest = React.createClass({
var ReactContentSizeUpdateTest = createReactClass({
displayName: 'ReactContentSizeUpdateTest',
mixins: [Subscribable.Mixin,
TimerMixin],
@@ -10,6 +10,7 @@
'use strict';
var React = require('react');
var createReactClass = require('create-react-class');
var ReactNative = require('react-native');
var RCTNativeAppEventEmitter = require('RCTNativeAppEventEmitter');
var Subscribable = require('Subscribable');
@@ -22,7 +23,8 @@ var reactViewHeight = 222;
var finalState = false;
var SizeFlexibilityUpdateTest = React.createClass({
var SizeFlexibilityUpdateTest = createReactClass({
displayName: 'SizeFlexibilityUpdateTest',
mixins: [Subscribable.Mixin],
componentWillMount: function() {
+3 -1
View File
@@ -12,6 +12,7 @@
'use strict';
var React = require('react');
var createReactClass = require('create-react-class');
var ReactNative = require('react-native');
var TimerMixin = require('react-timer-mixin');
@@ -22,7 +23,8 @@ var {
} = ReactNative;
var { TestModule } = ReactNative.NativeModules;
var TimersTest = React.createClass({
var TimersTest = createReactClass({
displayName: 'TimersTest',
mixins: [TimerMixin],
_nextTest: () => {},
+3 -2
View File
@@ -392,7 +392,7 @@ class Shape extends React.Component {
render() {
var props = this.props;
var path = props.d || childrenAsString(props.children);
var d = new Path(path).toJSON();
var d = (path instanceof Path ? path : new Path(path)).toJSON();
return (
<NativeShape
fill={extractBrush(props.fill, props)}
@@ -486,7 +486,8 @@ function extractAlignment(alignment) {
class Text extends React.Component {
render() {
var props = this.props;
var textPath = props.path ? new Path(props.path).toJSON() : null;
var path = props.path;
var textPath = path ? (path instanceof Path ? path : new Path(path)).toJSON() : null;
var textFrame = extractFontAndLines(
props.font,
childrenAsString(props.children)
@@ -1218,9 +1218,9 @@ class AnimatedDivision extends AnimatedWithChildren {
}
__makeNative() {
super.__makeNative();
this._a.__makeNative();
this._b.__makeNative();
super.__makeNative();
}
__getValue(): number {
@@ -1266,9 +1266,9 @@ class AnimatedMultiplication extends AnimatedWithChildren {
}
__makeNative() {
super.__makeNative();
this._a.__makeNative();
this._b.__makeNative();
super.__makeNative();
}
__getValue(): number {
@@ -1309,8 +1309,8 @@ class AnimatedModulo extends AnimatedWithChildren {
}
__makeNative() {
super.__makeNative();
this._a.__makeNative();
super.__makeNative();
}
__getValue(): number {
@@ -1356,8 +1356,8 @@ class AnimatedDiffClamp extends AnimatedWithChildren {
}
__makeNative() {
super.__makeNative();
this._a.__makeNative();
super.__makeNative();
}
interpolate(config: InterpolationConfigType): AnimatedInterpolation {
@@ -2825,9 +2825,9 @@ module.exports = {
*
*```javascript
* onScroll={Animated.event(
* [{nativeEvent: {contentOffset: {x: this._scrollX}}}]
* [{nativeEvent: {contentOffset: {x: this._scrollX}}}],
* {listener}, // Optional async listener
* )
* )}
* ...
* onPanResponderMove: Animated.event([
* null, // raw event arg ignored
@@ -8,8 +8,6 @@
*/
'use strict';
jest.disableAutomock();
var Animated = require('Animated');
describe('Animated tests', () => {
beforeEach(() => {
@@ -9,7 +9,6 @@
'use strict';
jest
.disableAutomock()
.setMock('Text', {})
.setMock('View', {})
.setMock('Image', {})
@@ -8,8 +8,6 @@
*/
'use strict';
jest.unmock('Easing');
var Easing = require('Easing');
describe('Easing', () => {
it('should work with linear', () => {
@@ -8,11 +8,6 @@
*/
'use strict';
jest
.unmock('Interpolation')
.unmock('Easing')
.unmock('normalizeColor');
var Interpolation = require('Interpolation');
var Easing = require('Easing');
@@ -10,7 +10,6 @@
'use strict';
jest.unmock('bezier');
var bezier = require('bezier');
var identity = function (x) { return x; };
+12 -6
View File
@@ -15,7 +15,6 @@
'use strict';
const ErrorUtils = require('ErrorUtils');
const JSTimersExecution = require('JSTimersExecution');
const Systrace = require('Systrace');
const deepFreezeAndThrowOnMutationInDev = require('deepFreezeAndThrowOnMutationInDev');
@@ -41,6 +40,9 @@ const TRACE_TAG_REACT_APPS = 1 << 17;
const DEBUG_INFO_LIMIT = 32;
// Work around an initialization order issue
let JSTimers = null;
class MessageQueue {
_lazyCallableModules: {[key: string]: void => Object};
_queue: [Array<number>, Array<number>, Array<any>, number];
@@ -151,8 +153,9 @@ class MessageQueue {
};
}
_getCallableModule(name: string) {
return this._lazyCallableModules[name]();
getCallableModule(name: string) {
const getValue = this._lazyCallableModules[name];
return getValue ? getValue() : null;
}
enqueueNativeCall(moduleID: number, methodID: number, params: Array<any>, onFail: ?Function, onSucc: ?Function) {
@@ -234,8 +237,11 @@ class MessageQueue {
}
__callImmediates() {
Systrace.beginEvent('JSTimersExecution.callImmediates()');
JSTimersExecution.callImmediates();
Systrace.beginEvent('JSTimers.callImmediates()');
if (!JSTimers) {
JSTimers = require('JSTimers');
}
JSTimers.callImmediates();
Systrace.endEvent();
}
@@ -246,7 +252,7 @@ class MessageQueue {
if (this.__spy) {
this.__spy({ type: TO_JS, module, method, args});
}
const moduleMethods = this._getCallableModule(module);
const moduleMethods = this.getCallableModule(module);
invariant(
!!moduleMethods,
'Module %s is not a registered callable module (calling %s)',
+6 -4
View File
@@ -15,6 +15,8 @@ const BatchedBridge = require('BatchedBridge');
const invariant = require('fbjs/lib/invariant');
import type {ExtendedError} from 'parseErrorStack';
type ModuleConfig = [
string, /* name */
?Object, /* constants */
@@ -113,13 +115,13 @@ function arrayContains<T>(array: Array<T>, value: T): boolean {
return array.indexOf(value) !== -1;
}
function createErrorFromErrorData(errorData: {message: string}): Error {
function createErrorFromErrorData(errorData: {message: string}): ExtendedError {
const {
message,
...extraErrorInfo
} = errorData;
const error = new Error(message);
(error:any).framesToPop = 1;
} = errorData || {};
const error : ExtendedError = new Error(message);
error.framesToPop = 1;
return Object.assign(error, extraErrorInfo);
}
@@ -9,10 +9,6 @@
*/
'use strict';
// const MessageQueueTestConfig = require('MessageQueueTestConfig');
jest.unmock('MessageQueue');
jest.unmock('defineLazyObjectProperty');
let MessageQueue;
let MessageQueueTestModule;
let queue;
@@ -84,4 +80,34 @@ describe('MessageQueue', function() {
queue.__invokeCallback(1);
expect(() => queue.__invokeCallback(0)).toThrow();
});
it('should throw when calling with unknown module', () => {
const unknownModule = 'UnknownModule', unknownMethod = 'UnknownMethod';
expect(() => queue.__callFunction(unknownModule, unknownMethod)).toThrow(
`Module ${unknownModule} is not a registered callable module (calling ${unknownMethod})`,
);
});
it('should return lazily registered module', () => {
const dummyModule = {}, name = 'modulesName';
queue.registerLazyCallableModule(name, () => dummyModule);
expect(queue.getCallableModule(name)).toEqual(dummyModule);
});
it('should not initialize lazily registered module before it was used for the first time', () => {
const dummyModule = {}, name = 'modulesName';
const factory = jest.fn(() => dummyModule);
queue.registerLazyCallableModule(name, factory);
expect(factory).not.toHaveBeenCalled();
});
it('should initialize lazily registered module only once', () => {
const dummyModule = {}, name = 'modulesName';
const factory = jest.fn(() => dummyModule);
queue.registerLazyCallableModule(name, factory);
queue.getCallableModule(name);
queue.getCallableModule(name);
expect(factory).toHaveBeenCalledTimes(1);
});
});
@@ -9,10 +9,12 @@
*/
'use strict';
jest.unmock('BatchedBridge');
jest.unmock('defineLazyObjectProperty');
jest.unmock('MessageQueue');
jest.unmock('NativeModules');
jest
.enableAutomock()
.unmock('BatchedBridge')
.unmock('defineLazyObjectProperty')
.unmock('MessageQueue')
.unmock('NativeModules');
let BatchedBridge;
let NativeModules;
+2 -1
View File
@@ -12,7 +12,8 @@
*/
'use strict';
const {PropTypes, checkPropTypes} = require('React');
const PropTypes = require('prop-types');
const {checkPropTypes} = PropTypes;
const RCTCameraRollManager = require('NativeModules').CameraRollManager;
const createStrictShapeTypeChecker = require('createStrictShapeTypeChecker');
@@ -20,6 +20,7 @@ const StyleSheet = require('StyleSheet');
const View = require('View');
const ViewPropTypes = require('ViewPropTypes');
const createReactClass = require('create-react-class');
const requireNativeComponent = require('requireNativeComponent');
const GRAY = '#999999';
@@ -36,7 +37,8 @@ type DefaultProps = {
/**
* Displays a circular loading indicator.
*/
const ActivityIndicator = React.createClass({
const ActivityIndicator = createReactClass({
displayName: 'ActivityIndicator',
mixins: [NativeMethodsMixin],
propTypes: {
@@ -10,7 +10,7 @@
* @flow
*/
'use strict';
var PropTypes = require('React').PropTypes;
var PropTypes = require('prop-types');
/**
* Additional View properties for Apple TV
+14 -19
View File
@@ -97,25 +97,25 @@ class Button extends React.Component {
} = this.props;
const buttonStyles = [styles.button];
const textStyles = [styles.text];
const Touchable = Platform.OS === 'android' ? TouchableNativeFeedback : TouchableOpacity;
if (color && Platform.OS === 'ios') {
textStyles.push({color: color});
} else if (color) {
buttonStyles.push({backgroundColor: color});
if (color) {
if (Platform.OS === 'ios') {
textStyles.push({color: color});
} else {
buttonStyles.push({backgroundColor: color});
}
}
const accessibilityTraits = ['button'];
if (disabled) {
buttonStyles.push(styles.buttonDisabled);
textStyles.push(styles.textDisabled);
accessibilityTraits.push('disabled');
}
invariant(
typeof title === 'string',
'The title prop of a Button must be a string',
);
const formattedTitle = Platform.OS === 'android' ? title.toUpperCase() : title;
const accessibilityTraits = ['button'];
if (disabled) {
accessibilityTraits.push('disabled');
}
const Touchable = Platform.OS === 'android' ? TouchableNativeFeedback : TouchableOpacity;
return (
<Touchable
accessibilityComponentType="button"
@@ -132,32 +132,27 @@ class Button extends React.Component {
}
}
// Material design blue from https://material.google.com/style/color.html#color-color-palette
let defaultBlue = '#2196F3';
if (Platform.OS === 'ios') {
// Measured default tintColor from iOS 10
defaultBlue = '#0C42FD';
}
const styles = StyleSheet.create({
button: Platform.select({
ios: {},
android: {
elevation: 4,
backgroundColor: defaultBlue,
// Material design blue from https://material.google.com/style/color.html#color-color-palette
backgroundColor: '#2196F3',
borderRadius: 2,
},
}),
text: Platform.select({
ios: {
color: defaultBlue,
// iOS blue from https://developer.apple.com/ios/human-interface-guidelines/visual-design/color/
color: '#007AFF',
textAlign: 'center',
padding: 8,
fontSize: 18,
},
android: {
textAlign: 'center',
color: 'white',
textAlign: 'center',
padding: 8,
fontWeight: '500',
},
@@ -20,6 +20,7 @@ const StyleSheet = require('StyleSheet');
const View = require('View');
const ViewPropTypes = require('ViewPropTypes');
const createReactClass = require('create-react-class');
const requireNativeComponent = require('requireNativeComponent');
type DefaultProps = {
@@ -36,7 +37,8 @@ type Event = Object;
* source of truth.
*/
// $FlowFixMe(>=0.41.0)
const DatePickerIOS = React.createClass({
const DatePickerIOS = createReactClass({
displayName: 'DatePickerIOS',
// TOOD: Put a better type for _picker
_picker: (undefined: ?$FlowFixMe),
@@ -24,6 +24,7 @@ var ViewPropTypes = require('ViewPropTypes');
var DrawerConsts = UIManager.AndroidDrawerLayout.Constants;
var createReactClass = require('create-react-class');
var dismissKeyboard = require('dismissKeyboard');
var requireNativeComponent = require('requireNativeComponent');
@@ -67,7 +68,8 @@ var DRAWER_STATES = [
* },
* ```
*/
var DrawerLayoutAndroid = React.createClass({
var DrawerLayoutAndroid = createReactClass({
displayName: 'DrawerLayoutAndroid',
statics: {
positions: DrawerConsts.DrawerPosition,
},
+3 -1
View File
@@ -100,7 +100,9 @@ let Keyboard = {
* - `keyboardDidChangeFrame`
*
* Note that if you set `android:windowSoftInputMode` to `adjustResize` or `adjustNothing`,
* only `keyboardDidShow` and `keyboardDidHide` events will available on Android.
* only `keyboardDidShow` and `keyboardDidHide` events will be available on Android.
* `keyboardWillShow` as well as `keyboardWillHide` are generally not available on Android
* since there is no native corresponding event.
*
* @param {function} callback function to be called when the event fires.
*/
@@ -11,6 +11,7 @@
*/
'use strict';
const createReactClass = require('create-react-class');
const Keyboard = require('Keyboard');
const LayoutAnimation = require('LayoutAnimation');
const Platform = require('Platform');
@@ -21,13 +22,8 @@ const View = require('View');
const ViewPropTypes = require('ViewPropTypes');
import type EmitterSubscription from 'EmitterSubscription';
import type {ViewLayout, ViewLayoutEvent} from 'ViewPropTypes';
type Rect = {
x: number,
y: number,
width: number,
height: number,
};
type ScreenRect = {
screenX: number,
screenY: number,
@@ -40,11 +36,6 @@ type KeyboardChangeEvent = {
duration?: number,
easing?: string,
};
type LayoutEvent = {
nativeEvent: {
layout: Rect,
}
};
const viewRef = 'VIEW';
@@ -53,7 +44,8 @@ const viewRef = 'VIEW';
* It can automatically adjust either its position or bottom padding based on the position of the keyboard.
*/
// $FlowFixMe(>=0.41.0)
const KeyboardAvoidingView = React.createClass({
const KeyboardAvoidingView = createReactClass({
displayName: 'KeyboardAvoidingView',
mixins: [TimerMixin],
propTypes: {
@@ -85,7 +77,7 @@ const KeyboardAvoidingView = React.createClass({
},
subscriptions: ([]: Array<EmitterSubscription>),
frame: (null: ?Rect),
frame: (null: ?ViewLayout),
relativeKeyboardHeight(keyboardFrame: ScreenRect): number {
const frame = this.frame;
@@ -121,7 +113,7 @@ const KeyboardAvoidingView = React.createClass({
this.setState({bottom: height});
},
onLayout(event: LayoutEvent) {
onLayout(event: ViewLayoutEvent) {
this.frame = event.nativeEvent.layout;
},
+3 -1
View File
@@ -11,10 +11,12 @@
'use strict';
var React = require('React');
var createReactClass = require('create-react-class');
var PropTypes = require('prop-types');
var TimerMixin = require('react-timer-mixin');
var LazyRenderer = React.createClass({
var LazyRenderer = createReactClass({
displayName: 'LazyRenderer',
mixin: [TimerMixin],
propTypes: {
@@ -6,8 +6,9 @@
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule MaskedViewIOS
* @flow
*/
'use strict';
module.exports = 0xFB0BD1E5;
module.exports = require('UnimplementedView');
@@ -0,0 +1,110 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule MaskedViewIOS
* @flow
*/
const React = require('React');
const StyleSheet = require('StyleSheet');
const View = require('View');
const ViewPropTypes = require('ViewPropTypes');
const requireNativeComponent = require('requireNativeComponent');
const ReactPropTypes = React.PropTypes;
import type { ViewProps } from 'ViewPropTypes';
type Props = ViewProps & {
children: any,
/**
* Should be a React element to be rendered and applied as the
* mask for the child element.
*/
maskElement: React.Element<*>,
};
/**
* Renders the child view with a mask specified in the `maskElement` prop.
*
* ```
* import React from 'react';
* import { MaskedView, Text, View } from 'react-native';
*
* class MyMaskedView extends React.Component {
* render() {
* return (
* <MaskedView
* style={{ flex: 1 }}
* maskElement={
* <View style={styles.maskContainerStyle}>
* <Text style={styles.maskTextStyle}>
* Basic Mask
* </Text>
* </View>
* }
* >
* <View style={{ flex: 1, backgroundColor: 'blue' }} />
* </MaskedView>
* );
* }
* }
* ```
*
* The above example will render a view with a blue background that fills its
* parent, and then mask that view with text that says "Basic Mask".
*
* The alpha channel of the view rendered by the `maskElement` prop determines how
* much of the view's content and background shows through. Fully or partially
* opaque pixels allow the underlying content to show through but fully
* transparent pixels block that content.
*
*/
class MaskedViewIOS extends React.Component {
props: Props;
static propTypes = {
...ViewPropTypes,
maskElement: ReactPropTypes.element.isRequired,
};
_hasWarnedInvalidRenderMask = false;
render() {
const { maskElement, children, ...otherViewProps } = this.props;
if (!React.isValidElement(maskElement)) {
if (!this._hasWarnedInvalidRenderMask) {
console.warn(
'MaskedView: Invalid `maskElement` prop was passed to MaskedView. ' +
'Expected a React Element. No mask will render.'
);
this._hasWarnedInvalidRenderMask = true;
}
return <View {...otherViewProps}>{children}</View>;
}
return (
<RCTMaskedView {...otherViewProps}>
<View pointerEvents="none" style={StyleSheet.absoluteFill}>
{maskElement}
</View>
{children}
</RCTMaskedView>
);
}
}
const RCTMaskedView = requireNativeComponent('RCTMaskedView', {
name: 'RCTMaskedView',
displayName: 'RCTMaskedView',
propTypes: {
...ViewPropTypes,
},
});
module.exports = MaskedViewIOS;
@@ -23,6 +23,7 @@ var TVEventHandler = require('TVEventHandler');
var View = require('View');
var ViewPropTypes = require('ViewPropTypes');
var createReactClass = require('create-react-class');
var invariant = require('fbjs/lib/invariant');
var logError = require('logError');
var requireNativeComponent = require('requireNativeComponent');
@@ -304,7 +305,8 @@ type Event = Object;
* is pushed.
*
*/
var NavigatorIOS = React.createClass({
var NavigatorIOS = createReactClass({
displayName: 'NavigatorIOS',
propTypes: {
@@ -434,7 +436,7 @@ var NavigatorIOS = React.createClass({
titleTextColor: PropTypes.string,
/**
* Bboolean value that indicates whether the navigation bar is
* Boolean value that indicates whether the navigation bar is
* translucent.
*/
translucent: PropTypes.bool,
@@ -14,6 +14,7 @@
var ColorPropType = require('ColorPropType');
var React = require('React');
var ReactPropTypes = require('prop-types');
var StyleSheet = require('StyleSheet');
var StyleSheetPropType = require('StyleSheetPropType');
const ViewPropTypes = require('ViewPropTypes');
@@ -22,8 +23,6 @@ var ViewStylePropTypes = require('ViewStylePropTypes');
var processColor = require('processColor');
var requireNativeComponent = require('requireNativeComponent');
var ReactPropTypes = React.PropTypes;
var REF_PICKER = 'picker';
var MODE_DROPDOWN = 'dropdown';
@@ -53,7 +52,7 @@ class PickerAndroid extends React.Component {
static propTypes = {
...ViewPropTypes,
style: pickerStyleType,
selectedValue: React.PropTypes.any,
selectedValue: ReactPropTypes.any,
enabled: ReactPropTypes.bool,
mode: ReactPropTypes.oneOf(['dialog', 'dropdown']),
onValueChange: ReactPropTypes.func,
+3 -1
View File
@@ -22,10 +22,12 @@ var View = require('View');
const ViewPropTypes = require('ViewPropTypes');
var processColor = require('processColor');
var createReactClass = require('create-react-class');
var itemStylePropType = StyleSheetPropType(TextStylePropTypes);
var requireNativeComponent = require('requireNativeComponent');
var PickerIOS = React.createClass({
var PickerIOS = createReactClass({
displayName: 'PickerIOS',
mixins: [NativeMethodsMixin],
propTypes: {
@@ -16,6 +16,7 @@ var PropTypes = require('prop-types');
var ViewPropTypes = require('ViewPropTypes');
var ColorPropType = require('ColorPropType');
var createReactClass = require('create-react-class');
var requireNativeComponent = require('requireNativeComponent');
var STYLE_ATTRIBUTES = [
@@ -63,7 +64,8 @@ var indeterminateType = function(props, propName, componentName, ...rest) {
* },
* ```
*/
var ProgressBarAndroid = React.createClass({
var ProgressBarAndroid = createReactClass({
displayName: 'ProgressBarAndroid',
propTypes: {
...ViewPropTypes,
/**
@@ -18,13 +18,15 @@ var PropTypes = require('prop-types');
var StyleSheet = require('StyleSheet');
var ViewPropTypes = require('ViewPropTypes');
var createReactClass = require('create-react-class');
var requireNativeComponent = require('requireNativeComponent');
/**
* Use `ProgressViewIOS` to render a UIProgressView on iOS.
*/
// $FlowFixMe(>=0.41.0)
var ProgressViewIOS = React.createClass({
var ProgressViewIOS = createReactClass({
displayName: 'ProgressViewIOS',
mixins: [NativeMethodsMixin],
propTypes: {
@@ -18,6 +18,7 @@ const React = require('React');
const PropTypes = require('prop-types');
const ViewPropTypes = require('ViewPropTypes');
const createReactClass = require('create-react-class');
const requireNativeComponent = require('requireNativeComponent');
if (Platform.OS === 'android') {
@@ -72,7 +73,8 @@ if (Platform.OS === 'android') {
* in the `onRefresh` function otherwise the refresh indicator will stop immediately.
*/
// $FlowFixMe(>=0.41.0)
const RefreshControl = React.createClass({
const RefreshControl = createReactClass({
displayName: 'RefreshControl',
statics: {
SIZE: RefreshLayoutConsts.SIZE,
},
+39 -6
View File
@@ -27,11 +27,15 @@ const View = require('View');
const ViewPropTypes = require('ViewPropTypes');
const ViewStylePropTypes = require('ViewStylePropTypes');
const createReactClass = require('create-react-class');
const dismissKeyboard = require('dismissKeyboard');
const flattenStyle = require('flattenStyle');
const invariant = require('fbjs/lib/invariant');
const processDecelerationRate = require('processDecelerationRate');
const requireNativeComponent = require('requireNativeComponent');
const warning = require('fbjs/lib/warning');
import type {NativeMethodsMixinType} from 'ReactNativeTypes';
/**
* Component that wraps platform ScrollView while providing
@@ -69,7 +73,8 @@ const requireNativeComponent = require('requireNativeComponent');
* supports out of the box.
*/
// $FlowFixMe(>=0.41.0)
const ScrollView = React.createClass({
const ScrollView = createReactClass({
displayName: 'ScrollView',
propTypes: {
...ViewPropTypes,
/**
@@ -254,6 +259,8 @@ const ScrollView = React.createClass({
* When true, the scroll view stops on multiples of the scroll view's size
* when scrolling. This can be used for horizontal pagination. The default
* value is false.
*
* Note: Vertical pagination is not supported on Android.
*/
pagingEnabled: PropTypes.bool,
/**
@@ -311,8 +318,10 @@ const ScrollView = React.createClass({
/**
* When set, causes the scroll view to stop at multiples of the value of
* `snapToInterval`. This can be used for paginating through children
* that have lengths smaller than the scroll view. Used in combination
* with `snapToAlignment`.
* that have lengths smaller than the scroll view. Typically used in
* combination with `snapToAlignment` and `decelerationRate="fast"`.
* Overrides less configurable `pagingEnabled` prop.
*
* @platform ios
*/
snapToInterval: PropTypes.number,
@@ -388,6 +397,15 @@ const ScrollView = React.createClass({
'always',
'never',
]),
/**
* When true, ScrollView will emit updateChildFrames data in scroll events,
* otherwise will not compute or emit child frame data. This only exists
* to support legacy issues, `onLayout` should be used instead to retrieve
* frame data.
* The default value is false.
* @platform ios
*/
DEPRECATED_sendUpdatedChildFrames: PropTypes.bool,
},
mixins: [ScrollResponder.Mixin],
@@ -583,8 +601,8 @@ const ScrollView = React.createClass({
this._scrollViewRef = ref;
},
_innerViewRef: (null: ?View),
_setInnerViewRef: function(ref: ?View) {
_innerViewRef: (null: ?NativeMethodsMixinType),
_setInnerViewRef: function(ref: ?NativeMethodsMixinType) {
this._innerViewRef = ref;
},
@@ -594,6 +612,10 @@ const ScrollView = React.createClass({
if (Platform.OS === 'ios') {
ScrollViewClass = RCTScrollView;
ScrollContentContainerViewClass = RCTScrollContentView;
warning(
!this.props.snapToInterval || !this.props.pagingEnabled,
'snapToInterval is currently ignored when pagingEnabled is true.'
);
} else if (Platform.OS === 'android') {
if (this.props.horizontal) {
ScrollViewClass = AndroidHorizontalScrollView;
@@ -667,7 +689,13 @@ const ScrollView = React.createClass({
{...contentSizeChangeProps}
ref={this._setInnerViewRef}
style={contentContainerStyle}
removeClippedSubviews={this.props.removeClippedSubviews}
removeClippedSubviews={
// Subview clipping causes issues with sticky headers on Android and
// would be hard to fix properly in a performant way.
Platform.OS === 'android' && hasStickyHeaders ?
false :
this.props.removeClippedSubviews
}
collapsable={false}>
{children}
</ScrollContentContainerViewClass>;
@@ -682,6 +710,9 @@ const ScrollView = React.createClass({
this.props.alwaysBounceVertical :
!this.props.horizontal;
const DEPRECATED_sendUpdatedChildFrames =
!!this.props.DEPRECATED_sendUpdatedChildFrames;
const baseStyle = this.props.horizontal ? styles.baseHorizontal : styles.baseVertical;
const props = {
...this.props,
@@ -710,6 +741,7 @@ const ScrollView = React.createClass({
scrollEventThrottle: hasStickyHeaders ? 1 : this.props.scrollEventThrottle,
sendMomentumEvents: (this.props.onMomentumScrollBegin || this.props.onMomentumScrollEnd) ?
true : false,
DEPRECATED_sendUpdatedChildFrames,
};
const { decelerationRate } = this.props;
@@ -806,6 +838,7 @@ if (Platform.OS === 'android') {
(ScrollView: ReactClass<any>),
nativeOnlyProps,
);
// $FlowFixMe (bvaughn) Update ComponentInterface in ViewPropTypes to include a string type (for Fiber host components) in a follow-up.
RCTScrollContentView = requireNativeComponent('RCTScrollContentView', View);
}
@@ -17,6 +17,7 @@ var PropTypes = require('prop-types');
var StyleSheet = require('StyleSheet');
var ViewPropTypes = require('ViewPropTypes');
var createReactClass = require('create-react-class');
var requireNativeComponent = require('requireNativeComponent');
type DefaultProps = {
@@ -49,7 +50,8 @@ type Event = Object;
* ````
*/
// $FlowFixMe(>=0.41.0)
var SegmentedControlIOS = React.createClass({
var SegmentedControlIOS = createReactClass({
displayName: 'SegmentedControlIOS',
mixins: [NativeMethodsMixin],
propTypes: {
+3 -1
View File
@@ -21,6 +21,7 @@ var PropTypes = require('prop-types');
var StyleSheet = require('StyleSheet');
var ViewPropTypes = require('ViewPropTypes');
var createReactClass = require('create-react-class');
var requireNativeComponent = require('requireNativeComponent');
type Event = Object;
@@ -29,7 +30,8 @@ type Event = Object;
* A component used to select a single value from a range of values.
*/
// $FlowFixMe(>=0.41.0)
var Slider = React.createClass({
var Slider = createReactClass({
displayName: 'Slider',
mixins: [NativeMethodsMixin],
propTypes: {
+56 -35
View File
@@ -63,7 +63,10 @@ type DefaultProps = {
/**
* Merges the prop stack with the default values.
*/
function mergePropsStack(propsStack: Array<Object>, defaultValues: Object): Object {
function mergePropsStack(
propsStack: Array<Object>,
defaultValues: Object
): Object {
return propsStack.reduce((prev, cur) => {
for (const prop in cur) {
if (cur[prop] != null) {
@@ -80,20 +83,29 @@ function mergePropsStack(propsStack: Array<Object>, defaultValues: Object): Obje
*/
function createStackEntry(props: any): any {
return {
backgroundColor: props.backgroundColor != null ? {
value: props.backgroundColor,
animated: props.animated,
} : null,
barStyle: props.barStyle != null ? {
value: props.barStyle,
animated: props.animated,
} : null,
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,
hidden:
props.hidden != null
? {
value: props.hidden,
animated: props.animated,
transition: props.showHideTransition,
}
: null,
networkActivityIndicatorVisible: props.networkActivityIndicatorVisible,
};
}
@@ -141,7 +153,7 @@ class StatusBar extends React.Component {
props: {
hidden?: boolean,
animated?: boolean,
backgroundColor?: $FlowFixMe,
backgroundColor?: string,
translucent?: boolean,
barStyle?: 'default' | 'light-content' | 'dark-content',
networkActivityIndicatorVisible?: boolean,
@@ -215,7 +227,9 @@ class StatusBar extends React.Component {
*/
static setNetworkActivityIndicatorVisible(visible: boolean) {
if (Platform.OS !== 'ios') {
console.warn('`setNetworkActivityIndicatorVisible` is only available on iOS');
console.warn(
'`setNetworkActivityIndicatorVisible` is only available on iOS'
);
return;
}
StatusBar._defaultProps.networkActivityIndicatorVisible = visible;
@@ -276,11 +290,7 @@ class StatusBar extends React.Component {
/**
* Sets the color of the status bar text.
*/
barStyle: PropTypes.oneOf([
'default',
'light-content',
'dark-content',
]),
barStyle: PropTypes.oneOf(['default', 'light-content', 'dark-content']),
/**
* If the network activity indicator should be visible.
*
@@ -293,10 +303,7 @@ class StatusBar extends React.Component {
*
* @platform ios
*/
showHideTransition: PropTypes.oneOf([
'fade',
'slide',
]),
showHideTransition: PropTypes.oneOf(['fade', 'slide']),
};
static defaultProps = {
@@ -343,38 +350,52 @@ class StatusBar extends React.Component {
clearImmediate(StatusBar._updateImmediate);
StatusBar._updateImmediate = setImmediate(() => {
const oldProps = StatusBar._currentValues;
const mergedProps = mergePropsStack(StatusBar._propsStack, StatusBar._defaultProps);
const mergedProps = mergePropsStack(
StatusBar._propsStack,
StatusBar._defaultProps
);
// Update the props that have changed using the merged values from the props stack.
if (Platform.OS === 'ios') {
if (!oldProps || oldProps.barStyle.value !== mergedProps.barStyle.value) {
if (
!oldProps ||
oldProps.barStyle.value !== mergedProps.barStyle.value
) {
StatusBarManager.setStyle(
mergedProps.barStyle.value,
mergedProps.barStyle.animated,
mergedProps.barStyle.animated
);
}
if (!oldProps || oldProps.hidden.value !== mergedProps.hidden.value) {
StatusBarManager.setHidden(
mergedProps.hidden.value,
mergedProps.hidden.animated ?
mergedProps.hidden.transition :
'none',
mergedProps.hidden.animated ? mergedProps.hidden.transition : 'none'
);
}
if (!oldProps || oldProps.networkActivityIndicatorVisible !== mergedProps.networkActivityIndicatorVisible) {
if (
!oldProps ||
oldProps.networkActivityIndicatorVisible !==
mergedProps.networkActivityIndicatorVisible
) {
StatusBarManager.setNetworkActivityIndicatorVisible(
mergedProps.networkActivityIndicatorVisible
);
}
} else if (Platform.OS === 'android') {
if (!oldProps || oldProps.barStyle.value !== mergedProps.barStyle.value) {
if (
!oldProps ||
oldProps.barStyle.value !== mergedProps.barStyle.value
) {
StatusBarManager.setStyle(mergedProps.barStyle.value);
}
if (!oldProps || oldProps.backgroundColor.value !== mergedProps.backgroundColor.value) {
if (
!oldProps ||
oldProps.backgroundColor.value !== mergedProps.backgroundColor.value
) {
StatusBarManager.setColor(
processColor(mergedProps.backgroundColor.value),
mergedProps.backgroundColor.animated,
mergedProps.backgroundColor.animated
);
}
if (!oldProps || oldProps.hidden.value !== mergedProps.hidden.value) {
+3 -1
View File
@@ -19,6 +19,7 @@ const PropTypes = require('prop-types');
var StyleSheet = require('StyleSheet');
const ViewPropTypes = require('ViewPropTypes');
var createReactClass = require('create-react-class');
var requireNativeComponent = require('requireNativeComponent');
type DefaultProps = {
@@ -38,7 +39,8 @@ type DefaultProps = {
* @keyword toggle
*/
// $FlowFixMe(>=0.41.0)
var Switch = React.createClass({
var Switch = createReactClass({
displayName: 'Switch',
propTypes: {
...ViewPropTypes,
/**
+3 -1
View File
@@ -17,6 +17,7 @@ const EventEmitter = require('EventEmitter');
const NativeMethodsMixin = require('NativeMethodsMixin');
const Platform = require('Platform');
const React = require('React');
const createReactClass = require('create-react-class');
const PropTypes = require('prop-types');
const ReactNative = require('ReactNative');
const StyleSheet = require('StyleSheet');
@@ -168,7 +169,8 @@ const DataDetectorTypes = [
*
*/
// $FlowFixMe(>=0.41.0)
const TextInput = React.createClass({
const TextInput = createReactClass({
displayName: 'TextInput',
statics: {
/* TODO(brentvatne) docs are needed for this */
State: TextInputState,
@@ -53,7 +53,7 @@ var TextInputState = {
},
/**
* @param {number} textFieldID id of the text field to focus
* @param {number} textFieldID id of the text field to unfocus
* Unfocuses the specified text field
* noop if it wasn't focused
*/
@@ -20,6 +20,7 @@ var UIManager = require('UIManager');
var ViewPropTypes = require('ViewPropTypes');
var ColorPropType = require('ColorPropType');
var createReactClass = require('create-react-class');
var requireNativeComponent = require('requireNativeComponent');
var resolveAssetSource = require('resolveAssetSource');
@@ -65,7 +66,8 @@ var optionalImageSource = PropTypes.oneOfType([
*
* [0]: https://developer.android.com/reference/android/support/v7/widget/Toolbar.html
*/
var ToolbarAndroid = React.createClass({
var ToolbarAndroid = createReactClass({
displayName: 'ToolbarAndroid',
mixins: [NativeMethodsMixin],
propTypes: {
@@ -15,6 +15,7 @@ var Animated = require('Animated');
var EdgeInsetsPropType = require('EdgeInsetsPropType');
var NativeMethodsMixin = require('NativeMethodsMixin');
var React = require('React');
var createReactClass = require('create-react-class');
var PropTypes = require('prop-types');
var Touchable = require('Touchable');
@@ -35,7 +36,8 @@ var PRESS_RETENTION_OFFSET = {top: 20, left: 20, right: 20, bottom: 30};
* interesting interactions such as `handleTouchablePress`.
*/
// $FlowFixMe(>=0.41.0)
var TouchableBounce = React.createClass({
var TouchableBounce = createReactClass({
displayName: 'TouchableBounce',
mixins: [Touchable.Mixin, NativeMethodsMixin],
propTypes: {
@@ -7,37 +7,36 @@
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule TouchableHighlight
* @noflow
* @flow
*/
'use strict';
// Note (avik): add @flow when Flow supports spread properties in propTypes
var ColorPropType = require('ColorPropType');
var NativeMethodsMixin = require('NativeMethodsMixin');
const ColorPropType = require('ColorPropType');
const NativeMethodsMixin = require('NativeMethodsMixin');
const PropTypes = require('prop-types');
var React = require('React');
var ReactNativeViewAttributes = require('ReactNativeViewAttributes');
var StyleSheet = require('StyleSheet');
var TimerMixin = require('react-timer-mixin');
var Touchable = require('Touchable');
var TouchableWithoutFeedback = require('TouchableWithoutFeedback');
var View = require('View');
const React = require('React');
const ReactNativeViewAttributes = require('ReactNativeViewAttributes');
const StyleSheet = require('StyleSheet');
const TimerMixin = require('react-timer-mixin');
const Touchable = require('Touchable');
const TouchableWithoutFeedback = require('TouchableWithoutFeedback');
const View = require('View');
const ViewPropTypes = require('ViewPropTypes');
var ensureComponentIsNative = require('ensureComponentIsNative');
var ensurePositiveDelayProps = require('ensurePositiveDelayProps');
var keyOf = require('fbjs/lib/keyOf');
var merge = require('merge');
const createReactClass = require('create-react-class');
const ensureComponentIsNative = require('ensureComponentIsNative');
const ensurePositiveDelayProps = require('ensurePositiveDelayProps');
const keyOf = require('fbjs/lib/keyOf');
const merge = require('merge');
type Event = Object;
import type {Event} from 'TouchableWithoutFeedback';
var DEFAULT_PROPS = {
const DEFAULT_PROPS = {
activeOpacity: 0.85,
underlayColor: 'black',
};
var PRESS_RETENTION_OFFSET = {top: 20, left: 20, right: 20, bottom: 30};
const PRESS_RETENTION_OFFSET = {top: 20, left: 20, right: 20, bottom: 30};
/**
* A wrapper for making views respond properly to touches.
@@ -68,7 +67,8 @@ var PRESS_RETENTION_OFFSET = {top: 20, left: 20, right: 20, bottom: 30};
* ```
*/
var TouchableHighlight = React.createClass({
var TouchableHighlight = createReactClass({
displayName: 'TouchableHighlight',
propTypes: {
...TouchableWithoutFeedback.propTypes,
/**
@@ -108,7 +108,6 @@ var TouchableHighlight = React.createClass({
* @platform ios
*/
tvParallaxProperties: PropTypes.object,
},
mixins: [NativeMethodsMixin, TimerMixin, Touchable.Mixin],
@@ -18,6 +18,7 @@ var Touchable = require('Touchable');
var TouchableWithoutFeedback = require('TouchableWithoutFeedback');
var UIManager = require('UIManager');
var createReactClass = require('create-react-class');
var ensurePositiveDelayProps = require('ensurePositiveDelayProps');
var processColor = require('processColor');
@@ -70,7 +71,8 @@ var PRESS_RETENTION_OFFSET = {top: 20, left: 20, right: 20, bottom: 30};
* ```
*/
var TouchableNativeFeedback = React.createClass({
var TouchableNativeFeedback = createReactClass({
displayName: 'TouchableNativeFeedback',
propTypes: {
...TouchableWithoutFeedback.propTypes,
@@ -22,6 +22,7 @@ var TimerMixin = require('react-timer-mixin');
var Touchable = require('Touchable');
var TouchableWithoutFeedback = require('TouchableWithoutFeedback');
var createReactClass = require('create-react-class');
var ensurePositiveDelayProps = require('ensurePositiveDelayProps');
var flattenStyle = require('flattenStyle');
@@ -51,7 +52,8 @@ var PRESS_RETENTION_OFFSET = {top: 20, left: 20, right: 20, bottom: 30};
* },
* ```
*/
var TouchableOpacity = React.createClass({
var TouchableOpacity = createReactClass({
displayName: 'TouchableOpacity',
mixins: [TimerMixin, Touchable.Mixin, NativeMethodsMixin],
propTypes: {
@@ -17,6 +17,7 @@ const PropTypes = require('prop-types');
const TimerMixin = require('react-timer-mixin');
const Touchable = require('Touchable');
const createReactClass = require('create-react-class');
const ensurePositiveDelayProps = require('ensurePositiveDelayProps');
const warning = require('fbjs/lib/warning');
@@ -25,7 +26,7 @@ const {
AccessibilityTraits,
} = require('ViewAccessibility');
type Event = Object;
export type Event = Object;
const PRESS_RETENTION_OFFSET = {top: 20, left: 20, right: 20, bottom: 30};
@@ -36,8 +37,8 @@ const PRESS_RETENTION_OFFSET = {top: 20, left: 20, right: 20, bottom: 30};
* TouchableWithoutFeedback supports only one child.
* If you wish to have several child components, wrap them in a View.
*/
// $FlowFixMe(>=0.41.0)
const TouchableWithoutFeedback = React.createClass({
const TouchableWithoutFeedback = createReactClass({
displayName: 'TouchableWithoutFeedback',
mixins: [TimerMixin, Touchable.Mixin],
propTypes: {
@@ -88,6 +89,7 @@ const TouchableWithoutFeedback = React.createClass({
* reactivated! Move it back and forth several times while the scroll view
* is disabled. Ensure you pass in a constant to reduce memory allocations.
*/
// $FlowFixMe: Expected a React PropType instead
pressRetentionOffset: EdgeInsetsPropType,
/**
* This defines how far your touch can start away from the button. This is
@@ -97,6 +99,7 @@ const TouchableWithoutFeedback = React.createClass({
* of sibling views always takes precedence if a touch hits two overlapping
* views.
*/
// $FlowFixMe: Expected a React PropType instead
hitSlop: EdgeInsetsPropType,
},
@@ -8,8 +8,6 @@
*/
'use strict';
jest.disableAutomock();
const React = require('React');
const ReactTestRenderer = require('react-test-renderer');
const Text = require('Text');
+30 -121
View File
@@ -9,31 +9,21 @@
* @providesModule View
* @flow
*/
'use strict';
"use strict";
const NativeMethodsMixin = require('NativeMethodsMixin');
const NativeModules = require('NativeModules');
const Platform = require('Platform');
const PropTypes = require('prop-types');
const React = require('React');
const ReactNativeFeatureFlags = require('ReactNativeFeatureFlags');
const ReactNativeStyleAttributes = require('ReactNativeStyleAttributes');
const ReactNativeViewAttributes = require('ReactNativeViewAttributes');
const ViewPropTypes = require('ViewPropTypes');
const NativeMethodsMixin = require("NativeMethodsMixin");
const Platform = require("Platform");
const PropTypes = require("prop-types");
const React = require("React");
const ReactNativeStyleAttributes = require("ReactNativeStyleAttributes");
const ReactNativeViewAttributes = require("ReactNativeViewAttributes");
const ViewPropTypes = require("ViewPropTypes");
const invariant = require('fbjs/lib/invariant');
const requireNativeComponent = require('requireNativeComponent');
const warning = require('fbjs/lib/warning');
const createReactClass = require("create-react-class");
const invariant = require("fbjs/lib/invariant");
const requireNativeComponent = require("requireNativeComponent");
const {
AccessibilityComponentTypes,
AccessibilityTraits,
} = require('ViewAccessibility');
const forceTouchAvailable = (NativeModules.PlatformConstants &&
NativeModules.PlatformConstants.forceTouchAvailable) || false;
import type {ViewProps} from 'ViewPropTypes';
import type { ViewProps } from "ViewPropTypes";
export type Props = ViewProps;
@@ -84,7 +74,8 @@ export type Props = ViewProps;
* - `touches` - Array of all current touches on the screen.
*/
// $FlowFixMe(>=0.41.0)
const View = React.createClass({
const View = createReactClass({
displayName: "View",
// TODO: We should probably expose the mixins, viewConfig, and statics publicly. For example,
// one of the props is of type AccessibilityComponentType. That is defined as a const[] above,
// but it is not rendered by the docs, since `statics` below is not rendered. So its Possible
@@ -94,143 +85,61 @@ const View = React.createClass({
// `propTypes` should not be accessed directly on View since this wrapper only
// exists for DEV mode. However it's important for them to be declared.
// If the object passed to `createClass` specifies `propTypes`, Flow will
// create a static type from it. This property will be over-written below with
// a warn-on-use getter though.
// TODO (bvaughn) Remove the warn-on-use comment after April 1.
// create a static type from it.
propTypes: ViewPropTypes,
// ReactElementValidator will (temporarily) use this private accessor when
// detected to avoid triggering the warning message.
// TODO (bvaughn) Remove this after April 1 ReactNative RC is tagged.
statics: {
__propTypesSecretDontUseThesePlease: ViewPropTypes
},
/**
* `NativeMethodsMixin` will look for this when invoking `setNativeProps`. We
* make `this` look like an actual native component class.
*/
viewConfig: {
uiViewClassName: 'RCTView',
uiViewClassName: "RCTView",
validAttributes: ReactNativeViewAttributes.RCTView
},
contextTypes: {
isInAParentText: PropTypes.bool,
isInAParentText: PropTypes.bool
},
render: function() {
invariant(
!(this.context.isInAParentText && Platform.OS === 'android'),
'Nesting of <View> within <Text> is not supported on Android.');
!(this.context.isInAParentText && Platform.OS === "android"),
"Nesting of <View> within <Text> is not supported on Android."
);
// WARNING: This method will not be used in production mode as in that mode we
// replace wrapper component View with generated native wrapper RCTView. Avoid
// adding functionality this component that you'd want to be available in both
// dev and prod modes.
return <RCTView {...this.props} />;
},
}
});
// Warn about unsupported use of View static properties as these will no longer
// be supported with React fiber. This warning message will go away in the next
// ReactNative release. Use defineProperty() rather than createClass() statics
// because the mixin process auto-triggers the 1-time warning message.
// TODO (bvaughn) Remove this after April 1 ReactNative RC is tagged.
function mixinStatics (target) {
let warnedAboutAccessibilityTraits = false;
let warnedAboutAccessibilityComponentType = false;
let warnedAboutForceTouchAvailable = false;
let warnedAboutPropTypes = false;
// $FlowFixMe https://github.com/facebook/flow/issues/285
Object.defineProperty(target, 'AccessibilityTraits', {
get: function() {
warning(
warnedAboutAccessibilityTraits,
'View.AccessibilityTraits has been deprecated and will be ' +
'removed in a future version of ReactNative. Use ' +
'ViewAccessibility.AccessibilityTraits instead.'
);
warnedAboutAccessibilityTraits = true;
return AccessibilityTraits;
}
});
// $FlowFixMe https://github.com/facebook/flow/issues/285
Object.defineProperty(target, 'AccessibilityComponentType', {
get: function() {
warning(
warnedAboutAccessibilityComponentType,
'View.AccessibilityComponentType has been deprecated and will be ' +
'removed in a future version of ReactNative. Use ' +
'ViewAccessibility.AccessibilityComponentTypes instead.'
);
warnedAboutAccessibilityComponentType = true;
return AccessibilityComponentTypes;
}
});
// $FlowFixMe https://github.com/facebook/flow/issues/285
Object.defineProperty(target, 'forceTouchAvailable', {
get: function() {
warning(
warnedAboutForceTouchAvailable,
'View.forceTouchAvailable has been deprecated and will be removed ' +
'in a future version of ReactNative. Use ' +
'NativeModules.PlatformConstants.forceTouchAvailable instead.'
);
warnedAboutForceTouchAvailable = true;
return forceTouchAvailable;
}
});
// $FlowFixMe https://github.com/facebook/flow/issues/285
Object.defineProperty(target, 'propTypes', {
get: function() {
warning(
warnedAboutPropTypes,
'View.propTypes has been deprecated and will be removed in a future ' +
'version of ReactNative. Use ViewPropTypes instead.'
);
warnedAboutPropTypes = true;
return ViewPropTypes;
}
});
}
const RCTView = requireNativeComponent('RCTView', View, {
const RCTView = requireNativeComponent("RCTView", View, {
nativeOnly: {
nativeBackgroundAndroid: true,
nativeForegroundAndroid: true,
nativeForegroundAndroid: true
}
});
if (__DEV__) {
const UIManager = require('UIManager');
const viewConfig = UIManager.viewConfigs && UIManager.viewConfigs.RCTView || {};
const UIManager = require("UIManager");
const viewConfig =
(UIManager.viewConfigs && UIManager.viewConfigs.RCTView) || {};
for (const prop in viewConfig.nativeProps) {
const viewAny: any = View; // Appease flow
if (!viewAny.propTypes[prop] && !ReactNativeStyleAttributes[prop]) {
throw new Error(
'View is missing propType for native prop `' + prop + '`'
"View is missing propType for native prop `" + prop + "`"
);
}
}
}
// TODO (bvaughn) Remove feature flags once all static View accessors are gone.
// We temporarily wrap fiber native views with the create-class View above,
// Because external code sometimes accesses static properties of this view.
let ViewToExport = RCTView;
if (
__DEV__ ||
ReactNativeFeatureFlags.useFiber
) {
mixinStatics(View);
if (__DEV__) {
ViewToExport = View;
} else {
// TODO (bvaughn) Remove this mixin once all static View accessors are gone.
mixinStatics((RCTView : any));
}
// TODO (bvaughn) Temporarily mask Flow warnings for View property accesses.
// We're wrapping the string type (Fiber) for now to avoid any actual problems.
module.exports = ((ViewToExport : any) : typeof View);
// No one should depend on the DEV-mode createClass View wrapper.
module.exports = ((ViewToExport: any): typeof RCTView);
+15 -3
View File
@@ -13,10 +13,10 @@
const EdgeInsetsPropType = require('EdgeInsetsPropType');
const Platform = require('Platform');
const PropTypes = require('prop-types');
const StyleSheetPropType = require('StyleSheetPropType');
const ViewStylePropTypes = require('ViewStylePropTypes');
const { PropTypes } = require('React');
const {
AccessibilityComponentTypes,
AccessibilityTraits,
@@ -36,6 +36,19 @@ import type {TVViewProps} from 'TVViewPropTypes';
const stylePropType = StyleSheetPropType(ViewStylePropTypes);
export type ViewLayout = {
x: number,
y: number,
width: number,
height: number,
}
export type ViewLayoutEvent = {
nativeEvent: {
layout: ViewLayout,
}
}
// There's no easy way to create a different type if(Platform.isTVOS):
// so we must include TVViewProps
export type ViewProps = {
@@ -50,6 +63,7 @@ export type ViewProps = {
onMagicTap?: Function,
testID?: string,
nativeID?: string,
onLayout?: (event: ViewLayoutEvent) => void,
onResponderGrant?: Function,
onResponderMove?: Function,
onResponderReject?: Function,
@@ -218,8 +232,6 @@ module.exports = {
* Used to locate this view from native classes.
*
* > This disables the 'layout-only view removal' optimization for this view!
*
* @platform android
*/
nativeID: PropTypes.string,
@@ -11,9 +11,9 @@
*/
'use strict';
var LayoutPropTypes = require('LayoutPropTypes');
var ReactPropTypes = require('React').PropTypes;
var ColorPropType = require('ColorPropType');
var LayoutPropTypes = require('LayoutPropTypes');
var ReactPropTypes = require('prop-types');
var ShadowPropTypesIOS = require('ShadowPropTypesIOS');
var TransformPropTypes = require('TransformPropTypes');
@@ -75,6 +75,7 @@ class ViewPagerAndroid extends React.Component {
onPageScrollStateChanged?: Function,
onPageSelected?: Function,
pageMargin?: number,
peekEnabled?: boolean,
keyboardDismissMode?: 'none' | 'on-drag',
scrollEnabled?: boolean,
};
@@ -137,6 +138,12 @@ class ViewPagerAndroid extends React.Component {
* The default value is true.
*/
scrollEnabled: PropTypes.bool,
/**
* Whether enable showing peekFraction or not. If this is true, the preview of
* last and next page will show in current screen. Defaults to false.
*/
peekEnabled: PropTypes.bool,
};
componentDidMount() {
@@ -367,6 +367,10 @@ class WebView extends React.Component {
]),
};
static defaultProps = {
scalesPageToFit: true,
};
state = {
viewState: WebViewState.IDLE,
lastErrorEvent: (null: ?ErrorEvent),
@@ -9,8 +9,6 @@
'use strict';
jest.disableAutomock();
var parseErrorStack = require('parseErrorStack');
function getFakeError() {
+7 -5
View File
@@ -18,20 +18,22 @@ export type StackFrame = {
methodName: string,
};
var stacktraceParser = require('stacktrace-parser');
export type ExtendedError = Error & {
framesToPop?: number,
};
function parseErrorStack(e: Error): Array<StackFrame> {
function parseErrorStack(e: ExtendedError): Array<StackFrame> {
if (!e || !e.stack) {
return [];
}
var stack = Array.isArray(e.stack) ? e.stack : stacktraceParser.parse(e.stack);
const stacktraceParser = require('stacktrace-parser');
const stack = Array.isArray(e.stack) ? e.stack : stacktraceParser.parse(e.stack);
var framesToPop = typeof e.framesToPop === 'number' ? e.framesToPop : 0;
let framesToPop = typeof e.framesToPop === 'number' ? e.framesToPop : 0;
while (framesToPop--) {
stack.shift();
}
return stack;
}
+4 -2
View File
@@ -11,11 +11,13 @@
*/
'use strict';
import type {ExtendedError} from 'parseErrorStack';
/**
* Handles the developer-visible aspect of errors and exceptions
*/
let exceptionID = 0;
function reportException(e: Error, isFatal: bool) {
function reportException(e: ExtendedError, isFatal: bool) {
const {ExceptionsManager} = require('NativeModules');
if (ExceptionsManager) {
const parseErrorStack = require('parseErrorStack');
@@ -84,7 +86,7 @@ function reactConsoleErrorHandler() {
// (Note: Logic duplicated in polyfills/console.js.)
return;
}
const error : any = new Error('console.error: ' + str);
const error : ExtendedError = new Error('console.error: ' + str);
error.framesToPop = 1;
reportException(error, /* isFatal */ false);
}
+52 -58
View File
@@ -13,7 +13,6 @@
/* eslint-disable strict */
/* globals window: true */
/**
* Sets up global variables typical in most JavaScript environments.
*
@@ -96,28 +95,21 @@ if (!global.process.env.NODE_ENV) {
global.process.env.NODE_ENV = __DEV__ ? 'development' : 'production';
}
// Set up profile
const Systrace = require('Systrace');
Systrace.setEnabled(global.__RCTProfileIsProfiling || false);
// Setup the Systrace profiling hooks if necessary
if (global.__RCTProfileIsProfiling) {
const Systrace = require('Systrace');
Systrace.setEnabled(true);
}
if (__DEV__ && global.performance === undefined) {
const Systrace = require('Systrace');
global.performance = Systrace.getUserTimingPolyfill();
}
// Set up console
const ExceptionsManager = require('ExceptionsManager');
ExceptionsManager.installConsoleErrorReporter();
// TODO: Move these around to solve the cycle in a cleaner way
const BatchedBridge = require('BatchedBridge');
BatchedBridge.registerLazyCallableModule('Systrace', () => require('Systrace'));
BatchedBridge.registerLazyCallableModule('JSTimersExecution', () => require('JSTimersExecution'));
BatchedBridge.registerLazyCallableModule('HeapCapture', () => require('HeapCapture'));
BatchedBridge.registerLazyCallableModule('SamplingProfiler', () => require('SamplingProfiler'));
BatchedBridge.registerLazyCallableModule('RCTLog', () => require('RCTLog'));
if (__DEV__) {
if (!global.__RCTProfileIsProfiling) {
BatchedBridge.registerCallableModule('HMRClient', require('HMRClient'));
}
}
// Set up error handler
if (!global.__fbDisableExceptionsManager) {
const handleError = (e, isFatal) => {
@@ -135,29 +127,11 @@ if (!global.__fbDisableExceptionsManager) {
ErrorUtils.setGlobalHandler(handleError);
}
// Set up timers
const defineLazyTimer = name => {
defineProperty(global, name, () => require('JSTimers')[name]);
};
defineLazyTimer('setTimeout');
defineLazyTimer('setInterval');
defineLazyTimer('setImmediate');
defineLazyTimer('clearTimeout');
defineLazyTimer('clearInterval');
defineLazyTimer('clearImmediate');
defineLazyTimer('requestAnimationFrame');
defineLazyTimer('cancelAnimationFrame');
defineLazyTimer('requestIdleCallback');
defineLazyTimer('cancelIdleCallback');
// Set up alert
if (!global.alert) {
global.alert = function(text) {
// Require Alert on demand. Requiring it too early can lead to issues
// with things like Platform not being fully initialized.
require('Alert').alert('Alert', '' + text);
};
}
// Set up collections
// We can't make these lazy because `Map` checks for `global.Map` (which wouldc
// not exist if it were lazily defined).
defineProperty(global, 'Map', () => require('Map'), true);
defineProperty(global, 'Set', () => require('Set'), true);
// Set up Promise
// The native Promise implementation throws the following error:
@@ -173,6 +147,21 @@ defineProperty(global, 'regeneratorRuntime', () => {
return global.regeneratorRuntime;
});
// Set up timers
const defineLazyTimer = name => {
defineProperty(global, name, () => require('JSTimers')[name]);
};
defineLazyTimer('setTimeout');
defineLazyTimer('setInterval');
defineLazyTimer('setImmediate');
defineLazyTimer('clearTimeout');
defineLazyTimer('clearInterval');
defineLazyTimer('clearImmediate');
defineLazyTimer('requestAnimationFrame');
defineLazyTimer('cancelAnimationFrame');
defineLazyTimer('requestIdleCallback');
defineLazyTimer('cancelIdleCallback');
// Set up XHR
// The native XMLHttpRequest in Chrome dev tools is CORS aware and won't
// let you fetch anything from the internet
@@ -185,6 +174,15 @@ defineProperty(global, 'Request', () => require('fetch').Request);
defineProperty(global, 'Response', () => require('fetch').Response);
defineProperty(global, 'WebSocket', () => require('WebSocket'));
// Set up alert
if (!global.alert) {
global.alert = function(text) {
// Require Alert on demand. Requiring it too early can lead to issues
// with things like Platform not being fully initialized.
require('Alert').alert('Alert', '' + text);
};
}
// Set up Geolocation
let navigator = global.navigator;
if (navigator === undefined) {
@@ -195,35 +193,31 @@ if (navigator === undefined) {
defineProperty(navigator, 'product', () => 'ReactNative', true);
defineProperty(navigator, 'geolocation', () => require('Geolocation'));
// Set up collections
// We can't make these lazy because `Map` checks for `global.Map` (which wouldc
// not exist if it were lazily defined).
defineProperty(global, 'Map', () => require('Map'), true);
defineProperty(global, 'Set', () => require('Set'), true);
// Just to make sure the JS gets packaged up. Wait until the JS environment has
// been initialized before requiring them.
const BatchedBridge = require('BatchedBridge');
BatchedBridge.registerLazyCallableModule('Systrace', () => require('Systrace'));
BatchedBridge.registerLazyCallableModule('JSTimers', () => require('JSTimers'));
BatchedBridge.registerLazyCallableModule('HeapCapture', () => require('HeapCapture'));
BatchedBridge.registerLazyCallableModule('SamplingProfiler', () => require('SamplingProfiler'));
BatchedBridge.registerLazyCallableModule('RCTLog', () => require('RCTLog'));
BatchedBridge.registerLazyCallableModule('RCTDeviceEventEmitter', () => require('RCTDeviceEventEmitter'));
BatchedBridge.registerLazyCallableModule('RCTNativeAppEventEmitter', () => require('RCTNativeAppEventEmitter'));
BatchedBridge.registerLazyCallableModule('PerformanceLogger', () => require('PerformanceLogger'));
// Set up devtools
if (__DEV__) {
if (!global.__RCTProfileIsProfiling) {
BatchedBridge.registerCallableModule('HMRClient', require('HMRClient'));
// not when debugging in chrome
// TODO(t12832058) This check is broken
if (!window.document) {
require('setupDevtools');
}
require('RCTDebugComponentOwnership');
// In order to use Cmd+P to record/dump perf data, we need to make sure
// this module is available in the bundle
require('RCTRenderingPerf');
// Set up inspector
const JSInspector = require('JSInspector');
JSInspector.registerAgent(require('NetworkAgent'));
}
}
// Just to make sure the JS gets packaged up. Wait until the JS environment has
// been initialized before requiring them.
BatchedBridge.registerLazyCallableModule('RCTDeviceEventEmitter', () => require('RCTDeviceEventEmitter'));
BatchedBridge.registerLazyCallableModule('RCTNativeAppEventEmitter', () => require('RCTNativeAppEventEmitter'));
BatchedBridge.registerLazyCallableModule('PerformanceLogger', () => require('PerformanceLogger'));
+351 -84
View File
@@ -7,64 +7,39 @@
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule JSTimers
* @format
* @flow
*/
'use strict';
// Note that the module JSTimers is split into two in order to solve a cycle
// in dependencies. NativeModules > BatchedBridge > MessageQueue > JSTimersExecution
const JSTimersExecution = require('JSTimersExecution');
const Platform = require('Platform');
const Systrace = require('Systrace');
const invariant = require('fbjs/lib/invariant');
const performanceNow = require('fbjs/lib/performanceNow');
const warning = require('fbjs/lib/warning');
const {Timing} = require('NativeModules');
const performanceNow = require('fbjs/lib/performanceNow');
import type {JSTimerType} from 'JSTimersExecution';
import type {ExtendedError} from 'parseErrorStack';
// Returns a free index if one is available, and the next consecutive index otherwise.
function _getFreeIndex(): number {
let freeIndex = JSTimersExecution.timerIDs.indexOf(null);
if (freeIndex === -1) {
freeIndex = JSTimersExecution.timerIDs.length;
}
return freeIndex;
}
/**
* JS implementation of timer functions. Must be completely driven by an
* external clock signal, all that's stored here is timerID, timer type, and
* callback.
*/
function _allocateCallback(func: Function, type: JSTimerType): number {
const id = JSTimersExecution.GUID++;
const freeIndex = _getFreeIndex();
JSTimersExecution.timerIDs[freeIndex] = id;
JSTimersExecution.callbacks[freeIndex] = func;
JSTimersExecution.types[freeIndex] = type;
if (__DEV__) {
const parseErrorStack = require('parseErrorStack');
const e = (new Error() : any);
e.framesToPop = 1;
const stack = parseErrorStack(e);
if (stack) {
JSTimersExecution.identifiers[freeIndex] = stack.shift();
}
}
return id;
}
export type JSTimerType =
| 'setTimeout'
| 'setInterval'
| 'requestAnimationFrame'
| 'setImmediate'
| 'requestIdleCallback';
function _freeCallback(timerID: number) {
// JSTimersExecution.timerIDs contains nulls after timers have been removed;
// ignore nulls upfront so indexOf doesn't find them
if (timerID == null) {
return;
}
const index = JSTimersExecution.timerIDs.indexOf(timerID);
// See corresponding comment in `callTimers` for reasoning behind this
if (index !== -1) {
JSTimersExecution._clearIndex(index);
const type = JSTimersExecution.types[index];
if (type !== 'setImmediate' && type !== 'requestIdleCallback') {
Timing.deleteTimer(timerID);
}
}
}
// These timing contants should be kept in sync with the ones in native ios and
// android `RCTTiming` module.
const FRAME_DURATION = 1000 / 60;
const IDLE_CALLBACK_FRAME_DEADLINE = 1;
const MAX_TIMER_DURATION_MS = 60 * 1000;
const IS_ANDROID = Platform.OS === 'android';
@@ -74,6 +49,152 @@ const ANDROID_LONG_TIMER_MESSAGE =
'module awake, and timers can only be called when the app is in the foreground. ' +
'See https://github.com/facebook/react-native/issues/12981 for more info.';
// Parallel arrays
const callbacks: Array<?Function> = [];
const types: Array<?JSTimerType> = [];
const timerIDs: Array<?number> = [];
let immediates: Array<number> = [];
let requestIdleCallbacks: Array<number> = [];
const requestIdleCallbackTimeouts: {[number]: number} = {};
const identifiers: Array<null | {methodName: string}> = [];
let GUID = 1;
let errors: ?Array<Error> = null;
let hasEmittedTimeDriftWarning = false;
// Returns a free index if one is available, and the next consecutive index otherwise.
function _getFreeIndex(): number {
let freeIndex = timerIDs.indexOf(null);
if (freeIndex === -1) {
freeIndex = timerIDs.length;
}
return freeIndex;
}
function _allocateCallback(func: Function, type: JSTimerType): number {
const id = GUID++;
const freeIndex = _getFreeIndex();
timerIDs[freeIndex] = id;
callbacks[freeIndex] = func;
types[freeIndex] = type;
if (__DEV__) {
const parseErrorStack = require('parseErrorStack');
const error: ExtendedError = new Error();
error.framesToPop = 1;
const stack = parseErrorStack(error);
if (stack) {
identifiers[freeIndex] = stack.shift();
}
}
return id;
}
/**
* Calls the callback associated with the ID. Also unregister that callback
* if it was a one time timer (setTimeout), and not unregister it if it was
* recurring (setInterval).
*/
function _callTimer(timerID: number, frameTime: number, didTimeout: ?boolean) {
warning(
timerID <= GUID,
'Tried to call timer with ID %s but no such timer exists.',
timerID,
);
// timerIndex of -1 means that no timer with that ID exists. There are
// two situations when this happens, when a garbage timer ID was given
// and when a previously existing timer was deleted before this callback
// fired. In both cases we want to ignore the timer id, but in the former
// case we warn as well.
const timerIndex = timerIDs.indexOf(timerID);
if (timerIndex === -1) {
return;
}
const type = types[timerIndex];
const callback = callbacks[timerIndex];
if (!callback || !type) {
console.error('No callback found for timerID ' + timerID);
return;
}
if (__DEV__) {
const identifier = identifiers[timerIndex] || {};
Systrace.beginEvent('Systrace.callTimer: ' + identifier.methodName);
}
// Clear the metadata
if (
type === 'setTimeout' ||
type === 'setImmediate' ||
type === 'requestAnimationFrame' ||
type === 'requestIdleCallback'
) {
_clearIndex(timerIndex);
}
try {
if (
type === 'setTimeout' ||
type === 'setInterval' ||
type === 'setImmediate'
) {
callback();
} else if (type === 'requestAnimationFrame') {
callback(performanceNow());
} else if (type === 'requestIdleCallback') {
callback({
timeRemaining: function() {
// TODO: Optimisation: allow running for longer than one frame if
// there are no pending JS calls on the bridge from native. This
// would require a way to check the bridge queue synchronously.
return Math.max(0, FRAME_DURATION - (performanceNow() - frameTime));
},
didTimeout: !!didTimeout,
});
} else {
console.error('Tried to call a callback with invalid type: ' + type);
}
} catch (e) {
// Don't rethrow so that we can run all timers.
if (!errors) {
errors = [e];
} else {
errors.push(e);
}
}
if (__DEV__) {
Systrace.endEvent();
}
}
function _clearIndex(i: number) {
timerIDs[i] = null;
callbacks[i] = null;
types[i] = null;
identifiers[i] = null;
}
function _freeCallback(timerID: number) {
// timerIDs contains nulls after timers have been removed;
// ignore nulls upfront so indexOf doesn't find them
if (timerID == null) {
return;
}
const index = timerIDs.indexOf(timerID);
// See corresponding comment in `callTimers` for reasoning behind this
if (index !== -1) {
_clearIndex(index);
const type = types[index];
if (type !== 'setImmediate' && type !== 'requestIdleCallback') {
Timing.deleteTimer(timerID);
}
}
}
/**
* JS implementation of timer functions. Must be completely driven by an
* external clock signal, all that's stored here is timerID, timer type, and
@@ -84,13 +205,24 @@ const JSTimers = {
* @param {function} func Callback to be invoked after `duration` ms.
* @param {number} duration Number of milliseconds.
*/
setTimeout: function(func: Function, duration: number, ...args?: any): number {
setTimeout: function(
func: Function,
duration: number,
...args?: any
): number {
if (__DEV__ && IS_ANDROID && duration > MAX_TIMER_DURATION_MS) {
console.warn(
ANDROID_LONG_TIMER_MESSAGE + '\n' + '(Saw setTimeout with duration ' +
duration + 'ms)');
ANDROID_LONG_TIMER_MESSAGE +
'\n' +
'(Saw setTimeout with duration ' +
duration +
'ms)',
);
}
const id = _allocateCallback(() => func.apply(undefined, args), 'setTimeout');
const id = _allocateCallback(
() => func.apply(undefined, args),
'setTimeout',
);
Timing.createTimer(id, duration || 0, Date.now(), /* recurring */ false);
return id;
},
@@ -99,13 +231,24 @@ const JSTimers = {
* @param {function} func Callback to be invoked every `duration` ms.
* @param {number} duration Number of milliseconds.
*/
setInterval: function(func: Function, duration: number, ...args?: any): number {
setInterval: function(
func: Function,
duration: number,
...args?: any
): number {
if (__DEV__ && IS_ANDROID && duration > MAX_TIMER_DURATION_MS) {
console.warn(
ANDROID_LONG_TIMER_MESSAGE + '\n' + '(Saw setInterval with duration ' +
duration + 'ms)');
ANDROID_LONG_TIMER_MESSAGE +
'\n' +
'(Saw setInterval with duration ' +
duration +
'ms)',
);
}
const id = _allocateCallback(() => func.apply(undefined, args), 'setInterval');
const id = _allocateCallback(
() => func.apply(undefined, args),
'setInterval',
);
Timing.createTimer(id, duration || 0, Date.now(), /* recurring */ true);
return id;
},
@@ -115,15 +258,18 @@ const JSTimers = {
* current JavaScript execution loop.
*/
setImmediate: function(func: Function, ...args?: any) {
const id = _allocateCallback(() => func.apply(undefined, args), 'setImmediate');
JSTimersExecution.immediates.push(id);
const id = _allocateCallback(
() => func.apply(undefined, args),
'setImmediate',
);
immediates.push(id);
return id;
},
/**
* @param {function} func Callback to be invoked every frame.
*/
requestAnimationFrame: function(func : Function) {
requestAnimationFrame: function(func: Function) {
const id = _allocateCallback(func, 'requestAnimationFrame');
Timing.createTimer(id, 1, Date.now(), /* recurring */ false);
return id;
@@ -134,58 +280,58 @@ const JSTimers = {
* with time remaining in frame.
* @param {?object} options
*/
requestIdleCallback: function(func : Function, options : ?Object) {
if (JSTimersExecution.requestIdleCallbacks.length === 0) {
requestIdleCallback: function(func: Function, options: ?Object) {
if (requestIdleCallbacks.length === 0) {
Timing.setSendIdleEvents(true);
}
const timeout = options && options.timeout;
const id = _allocateCallback(
timeout != null ?
deadline => {
const timeoutId = JSTimersExecution.requestIdleCallbackTimeouts.get(id);
if (timeoutId) {
JSTimers.clearTimeout(timeoutId);
JSTimersExecution.requestIdleCallbackTimeouts.delete(id);
timeout != null
? deadline => {
const timeoutId = requestIdleCallbackTimeouts[id];
if (timeoutId) {
JSTimers.clearTimeout(timeoutId);
requestIdleCallbackTimeouts[id];
}
return func(deadline);
}
return func(deadline);
} :
func,
'requestIdleCallback'
: func,
'requestIdleCallback',
);
JSTimersExecution.requestIdleCallbacks.push(id);
requestIdleCallbacks.push(id);
if (timeout != null) {
const timeoutId = JSTimers.setTimeout(() => {
const index = JSTimersExecution.requestIdleCallbacks.indexOf(id);
const index = requestIdleCallbacks.indexOf(id);
if (index > -1) {
JSTimersExecution.requestIdleCallbacks.splice(index, 1);
JSTimersExecution.callTimer(id, performanceNow(), true);
requestIdleCallbacks.splice(index, 1);
_callTimer(id, performanceNow(), true);
}
JSTimersExecution.requestIdleCallbackTimeouts.delete(id);
if (JSTimersExecution.requestIdleCallbacks.length === 0) {
delete requestIdleCallbackTimeouts[id];
if (requestIdleCallbacks.length === 0) {
Timing.setSendIdleEvents(false);
}
}, timeout);
JSTimersExecution.requestIdleCallbackTimeouts.set(id, timeoutId);
requestIdleCallbackTimeouts[id] = timeoutId;
}
return id;
},
cancelIdleCallback: function(timerID: number) {
_freeCallback(timerID);
const index = JSTimersExecution.requestIdleCallbacks.indexOf(timerID);
const index = requestIdleCallbacks.indexOf(timerID);
if (index !== -1) {
JSTimersExecution.requestIdleCallbacks.splice(index, 1);
requestIdleCallbacks.splice(index, 1);
}
const timeoutId = JSTimersExecution.requestIdleCallbackTimeouts.get(timerID);
const timeoutId = requestIdleCallbackTimeouts[timerID];
if (timeoutId) {
JSTimers.clearTimeout(timeoutId);
JSTimersExecution.requestIdleCallbackTimeouts.delete(timerID);
delete requestIdleCallbackTimeouts[timerID];
}
if (JSTimersExecution.requestIdleCallbacks.length === 0) {
if (requestIdleCallbacks.length === 0) {
Timing.setSendIdleEvents(false);
}
},
@@ -200,15 +346,136 @@ const JSTimers = {
clearImmediate: function(timerID: number) {
_freeCallback(timerID);
const index = JSTimersExecution.immediates.indexOf(timerID);
const index = immediates.indexOf(timerID);
if (index !== -1) {
JSTimersExecution.immediates.splice(index, 1);
immediates.splice(index, 1);
}
},
cancelAnimationFrame: function(timerID: number) {
_freeCallback(timerID);
},
/**
* This is called from the native side. We are passed an array of timerIDs,
* and
*/
callTimers: function(timersToCall: Array<number>) {
invariant(
timersToCall.length !== 0,
'Cannot call `callTimers` with an empty list of IDs.',
);
// $FlowFixMe: optionals do not allow assignment from null
errors = null;
for (let i = 0; i < timersToCall.length; i++) {
_callTimer(timersToCall[i], 0);
}
if (errors) {
const errorCount = errors.length;
if (errorCount > 1) {
// Throw all the other errors in a setTimeout, which will throw each
// error one at a time
for (let ii = 1; ii < errorCount; ii++) {
JSTimers.setTimeout(
(error => {
throw error;
}).bind(null, errors[ii]),
0,
);
}
}
throw errors[0];
}
},
callIdleCallbacks: function(frameTime: number) {
if (
FRAME_DURATION - (performanceNow() - frameTime) <
IDLE_CALLBACK_FRAME_DEADLINE
) {
return;
}
// $FlowFixMe: optionals do not allow assignment from null
errors = null;
if (requestIdleCallbacks.length > 0) {
const passIdleCallbacks = requestIdleCallbacks.slice();
requestIdleCallbacks = [];
for (let i = 0; i < passIdleCallbacks.length; ++i) {
_callTimer(passIdleCallbacks[i], frameTime);
}
}
if (requestIdleCallbacks.length === 0) {
Timing.setSendIdleEvents(false);
}
if (errors) {
errors.forEach(error =>
JSTimers.setTimeout(() => {
throw error;
}, 0),
);
}
},
/**
* Performs a single pass over the enqueued immediates. Returns whether
* more immediates are queued up (can be used as a condition a while loop).
*/
callImmediatesPass() {
if (__DEV__) {
Systrace.beginEvent('callImmediatesPass()');
}
// The main reason to extract a single pass is so that we can track
// in the system trace
if (immediates.length > 0) {
const passImmediates = immediates.slice();
immediates = [];
// Use for loop rather than forEach as per @vjeux's advice
// https://github.com/facebook/react-native/commit/c8fd9f7588ad02d2293cac7224715f4af7b0f352#commitcomment-14570051
for (let i = 0; i < passImmediates.length; ++i) {
_callTimer(passImmediates[i], 0);
}
}
if (__DEV__) {
Systrace.endEvent();
}
return immediates.length > 0;
},
/**
* This is called after we execute any command we receive from native but
* before we hand control back to native.
*/
callImmediates() {
errors = null;
while (JSTimers.callImmediatesPass()) {}
if (errors) {
errors.forEach(error =>
JSTimers.setTimeout(() => {
throw error;
}, 0),
);
}
},
/**
* Called from native (in development) when environment times are out-of-sync.
*/
emitTimeDriftWarning(warningMessage: string) {
if (hasEmittedTimeDriftWarning) {
return;
}
hasEmittedTimeDriftWarning = true;
console.warn(warningMessage);
},
};
module.exports = JSTimers;
-246
View File
@@ -1,246 +0,0 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule JSTimersExecution
* @flow
*/
'use strict';
const Systrace = require('Systrace');
const invariant = require('fbjs/lib/invariant');
const performanceNow = require('fbjs/lib/performanceNow');
const warning = require('fbjs/lib/warning');
// These timing contants should be kept in sync with the ones in native ios and
// android `RCTTiming` module.
const FRAME_DURATION = 1000 / 60;
const IDLE_CALLBACK_FRAME_DEADLINE = 1;
let hasEmittedTimeDriftWarning = false;
export type JSTimerType =
'setTimeout' |
'setInterval' |
'requestAnimationFrame' |
'setImmediate' |
'requestIdleCallback';
/**
* JS implementation of timer functions. Must be completely driven by an
* external clock signal, all that's stored here is timerID, timer type, and
* callback.
*/
const JSTimersExecution = {
GUID: 1,
// Parallel arrays
callbacks: ([] : Array<?Function>),
types: ([] : Array<?JSTimerType>),
timerIDs: ([] : Array<?number>),
immediates: [],
requestIdleCallbacks: [],
requestIdleCallbackTimeouts: (new Map() : Map<number, number>),
identifiers: ([] : Array<null | {methodName: string}>),
errors: (null : ?Array<Error>),
/**
* Calls the callback associated with the ID. Also unregister that callback
* if it was a one time timer (setTimeout), and not unregister it if it was
* recurring (setInterval).
*/
callTimer(timerID: number, frameTime: number, didTimeout: ?boolean) {
warning(
timerID <= JSTimersExecution.GUID,
'Tried to call timer with ID %s but no such timer exists.',
timerID
);
// timerIndex of -1 means that no timer with that ID exists. There are
// two situations when this happens, when a garbage timer ID was given
// and when a previously existing timer was deleted before this callback
// fired. In both cases we want to ignore the timer id, but in the former
// case we warn as well.
const timerIndex = JSTimersExecution.timerIDs.indexOf(timerID);
if (timerIndex === -1) {
return;
}
const type = JSTimersExecution.types[timerIndex];
const callback = JSTimersExecution.callbacks[timerIndex];
if (!callback || !type) {
console.error('No callback found for timerID ' + timerID);
return;
}
if (__DEV__) {
const identifier = JSTimersExecution.identifiers[timerIndex] || {};
Systrace.beginEvent('Systrace.callTimer: ' + identifier.methodName);
}
// Clear the metadata
if (type === 'setTimeout' || type === 'setImmediate' ||
type === 'requestAnimationFrame' || type === 'requestIdleCallback') {
JSTimersExecution._clearIndex(timerIndex);
}
try {
if (type === 'setTimeout' || type === 'setInterval' ||
type === 'setImmediate') {
callback();
} else if (type === 'requestAnimationFrame') {
callback(performanceNow());
} else if (type === 'requestIdleCallback') {
callback({
timeRemaining: function() {
// TODO: Optimisation: allow running for longer than one frame if
// there are no pending JS calls on the bridge from native. This
// would require a way to check the bridge queue synchronously.
return Math.max(0, FRAME_DURATION - (performanceNow() - frameTime));
},
didTimeout: !!didTimeout,
});
} else {
console.error('Tried to call a callback with invalid type: ' + type);
}
} catch (e) {
// Don't rethrow so that we can run all timers.
if (!JSTimersExecution.errors) {
JSTimersExecution.errors = [e];
} else {
JSTimersExecution.errors.push(e);
}
}
if (__DEV__) {
Systrace.endEvent();
}
},
/**
* This is called from the native side. We are passed an array of timerIDs,
* and
*/
callTimers(timerIDs: [number]) {
invariant(
timerIDs.length !== 0,
'Cannot call `callTimers` with an empty list of IDs.'
);
JSTimersExecution.errors = null;
for (let i = 0; i < timerIDs.length; i++) {
JSTimersExecution.callTimer(timerIDs[i], 0);
}
const errors = JSTimersExecution.errors;
if (errors) {
const errorCount = errors.length;
if (errorCount > 1) {
// Throw all the other errors in a setTimeout, which will throw each
// error one at a time
for (let ii = 1; ii < errorCount; ii++) {
require('JSTimers').setTimeout(
((error) => { throw error; }).bind(null, errors[ii]),
0
);
}
}
throw errors[0];
}
},
callIdleCallbacks: function(frameTime: number) {
if (FRAME_DURATION - (performanceNow() - frameTime) < IDLE_CALLBACK_FRAME_DEADLINE) {
return;
}
JSTimersExecution.errors = null;
if (JSTimersExecution.requestIdleCallbacks.length > 0) {
const passIdleCallbacks = JSTimersExecution.requestIdleCallbacks.slice();
JSTimersExecution.requestIdleCallbacks = [];
for (let i = 0; i < passIdleCallbacks.length; ++i) {
JSTimersExecution.callTimer(passIdleCallbacks[i], frameTime);
}
}
if (JSTimersExecution.requestIdleCallbacks.length === 0) {
const { Timing } = require('NativeModules');
Timing.setSendIdleEvents(false);
}
if (JSTimersExecution.errors) {
JSTimersExecution.errors.forEach((error) =>
require('JSTimers').setTimeout(() => { throw error; }, 0)
);
}
},
/**
* Performs a single pass over the enqueued immediates. Returns whether
* more immediates are queued up (can be used as a condition a while loop).
*/
callImmediatesPass() {
if (__DEV__) {
Systrace.beginEvent('JSTimersExecution.callImmediatesPass()');
}
// The main reason to extract a single pass is so that we can track
// in the system trace
if (JSTimersExecution.immediates.length > 0) {
const passImmediates = JSTimersExecution.immediates.slice();
JSTimersExecution.immediates = [];
// Use for loop rather than forEach as per @vjeux's advice
// https://github.com/facebook/react-native/commit/c8fd9f7588ad02d2293cac7224715f4af7b0f352#commitcomment-14570051
for (let i = 0; i < passImmediates.length; ++i) {
JSTimersExecution.callTimer(passImmediates[i], 0);
}
}
if (__DEV__) {
Systrace.endEvent();
}
return JSTimersExecution.immediates.length > 0;
},
/**
* This is called after we execute any command we receive from native but
* before we hand control back to native.
*/
callImmediates() {
JSTimersExecution.errors = null;
while (JSTimersExecution.callImmediatesPass()) {}
if (JSTimersExecution.errors) {
JSTimersExecution.errors.forEach((error) =>
require('JSTimers').setTimeout(() => { throw error; }, 0)
);
}
},
/**
* Called from native (in development) when environment times are out-of-sync.
*/
emitTimeDriftWarning(warningMessage: string) {
if (hasEmittedTimeDriftWarning) {
return;
}
hasEmittedTimeDriftWarning = true;
console.warn(warningMessage);
},
_clearIndex(i: number) {
JSTimersExecution.timerIDs[i] = null;
JSTimersExecution.callbacks[i] = null;
JSTimersExecution.types[i] = null;
JSTimersExecution.identifiers[i] = null;
},
};
module.exports = JSTimersExecution;
@@ -1,41 +0,0 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* Utility class to provide the component owner hierarchy to native code for
* debugging purposes.
*
* @providesModule RCTDebugComponentOwnership
* @flow
*/
'use strict';
var BatchedBridge = require('BatchedBridge');
var RCTDebugComponentOwnership = {
/**
* Asynchronously returns the owner hierarchy as an array of strings. Request id is
* passed along to the native module so that the native module can identify the
* particular call instance.
*
* Example returned owner hierarchy: ['RootView', 'Dialog', 'TitleView', 'Text']
*/
getOwnerHierarchy: function(requestID: number, tag: number) {
// Consider cleaning up these unused modules in a separate diff.
throw new Error(
'This seems to be unused. Will disable until it is needed again.'
);
},
};
BatchedBridge.registerCallableModule(
'RCTDebugComponentOwnership',
RCTDebugComponentOwnership
);
module.exports = RCTDebugComponentOwnership;
@@ -12,12 +12,11 @@
'use strict';
const ListView = require('ListView');
const PropTypes = require('prop-types');
const React = require('React');
const SwipeableListViewDataSource = require('SwipeableListViewDataSource');
const SwipeableRow = require('SwipeableRow');
const {PropTypes} = React;
type DefaultProps = {
bounceFirstRowOnMount: boolean,
renderQuickActions: Function,
@@ -12,12 +12,11 @@
'use strict';
const Image = require('Image');
const React = require('React');
const PropTypes = require('prop-types');
const React = require('React');
const Text = require('Text');
const TouchableHighlight = require('TouchableHighlight');
const View = require('View');
const ViewPropTypes = require('ViewPropTypes');
import type {ImageSource} from 'ImageSource';
@@ -31,12 +30,12 @@ class SwipeableQuickActionButton extends React.Component {
props: {
accessibilityLabel?: string,
imageSource: ImageSource | number,
imageStyle?: ?View.propTypes.style,
imageStyle?: ?ViewPropTypes.style,
onPress?: Function,
style?: ?View.propTypes.style,
style?: ?ViewPropTypes.style,
testID?: string,
text?: ?(string | Object | Array<string | Object>),
textStyle?: ?View.propTypes.style,
textStyle?: ?ViewPropTypes.style,
};
static propTypes = {
@@ -20,6 +20,7 @@ const StyleSheet = require('StyleSheet');
const TimerMixin = require('react-timer-mixin');
const View = require('View');
const createReactClass = require('create-react-class');
const emptyFunction = require('fbjs/lib/emptyFunction');
const IS_RTL = I18nManager.isRTL;
@@ -61,7 +62,8 @@ const RIGHT_SWIPE_THRESHOLD = 30 * SLOW_SPEED_SWIPE_FACTOR;
* used in a normal ListView. See the renderRow for SwipeableListView to see how
* to use this component separately.
*/
const SwipeableRow = React.createClass({
const SwipeableRow = createReactClass({
displayName: 'SwipeableRow',
_panResponder: {},
_previousLeft: CLOSED_LEFT_POSITION,
@@ -70,6 +72,8 @@ const SwipeableRow = React.createClass({
propTypes: {
children: PropTypes.any,
isOpen: PropTypes.bool,
preventSwipeLeft: PropTypes.bool,
preventSwipeRight: PropTypes.bool,
maxSwipeDistance: PropTypes.number.isRequired,
onOpen: PropTypes.func.isRequired,
onClose: PropTypes.func.isRequired,
@@ -106,6 +110,8 @@ const SwipeableRow = React.createClass({
getDefaultProps(): Object {
return {
isOpen: false,
preventSwipeLeft: false,
preventSwipeRight: false,
maxSwipeDistance: 0,
onOpen: emptyFunction,
onClose: emptyFunction,
@@ -190,6 +196,11 @@ const SwipeableRow = React.createClass({
);
},
close(): void {
this.props.onClose();
this._animateToClosedPosition();
},
_onSwipeableViewLayout(event: Object): void {
this.setState({
isSwipeableViewRendered: true,
@@ -268,6 +279,7 @@ const SwipeableRow = React.createClass({
{
duration,
toValue,
useNativeDriver: true,
},
).start(() => {
this._previousLeft = toValue;
@@ -327,6 +339,12 @@ const SwipeableRow = React.createClass({
// Ignore swipes due to user's finger moving slightly when tapping
_isValidSwipe(gestureState: Object): boolean {
if (this.props.preventSwipeLeft && gestureState.dx < 0) {
return false;
}
if (this.props.preventSwipeRight && gestureState.dx > 0) {
return false;
}
return Math.abs(gestureState.dx) > HORIZONTAL_SWIPE_DISTANCE_THRESHOLD;
},
+3 -1
View File
@@ -27,6 +27,8 @@ const infoLog = require('infoLog');
const invariant = require('fbjs/lib/invariant');
const nullthrows = require('fbjs/lib/nullthrows');
import type {NativeMethodsMixinType} from 'ReactNativeTypes';
const DEBUG = false;
/**
@@ -613,7 +615,7 @@ type CellProps = {
};
class CellRenderer extends React.Component {
props: CellProps;
_containerRef: View;
_containerRef: NativeMethodsMixinType;
_offscreenRenderDone = false;
_timeout = 0;
_lastLayout: ?Object = null;
+1 -1
View File
@@ -175,7 +175,7 @@ var Geolocation = {
for (var ii = 0; ii < subscriptions.length; ii++) {
var sub = subscriptions[ii];
if (sub) {
warning('Called stopObserving with existing subscriptions.');
warning(false, 'Called stopObserving with existing subscriptions.');
sub[0].remove();
// array element refinements not yet enabled in Flow
var sub1 = sub[1]; sub1 && sub1.remove();
+3 -1
View File
@@ -25,6 +25,7 @@ var View = require('View');
var ViewPropTypes = require('ViewPropTypes');
var ViewStylePropTypes = require('ViewStylePropTypes');
var createReactClass = require('create-react-class');
var filterObject = require('fbjs/lib/filterObject');
var flattenStyle = require('flattenStyle');
var merge = require('merge');
@@ -76,7 +77,8 @@ var ImageViewAttributes = merge(ReactNativeViewAttributes.UIView, {
var ViewStyleKeys = new Set(Object.keys(ViewStylePropTypes));
var ImageSpecificStyleKeys = new Set(Object.keys(ImageStylePropTypes).filter(x => !ViewStyleKeys.has(x)));
var Image = React.createClass({
var Image = createReactClass({
displayName: 'Image',
propTypes: {
...ViewPropTypes,
style: StyleSheetPropType(ImageStylePropTypes),
+16 -8
View File
@@ -23,6 +23,7 @@ const ReactNativeViewAttributes = require('ReactNativeViewAttributes');
const StyleSheet = require('StyleSheet');
const StyleSheetPropType = require('StyleSheetPropType');
const createReactClass = require('create-react-class');
const flattenStyle = require('flattenStyle');
const requireNativeComponent = require('requireNativeComponent');
const resolveAssetSource = require('resolveAssetSource');
@@ -34,8 +35,10 @@ const ImageViewManager = NativeModules.ImageViewManager;
* including network images, static resources, temporary local images, and
* images from local disk, such as the camera roll.
*
* This example shows both fetching and displaying an image from local
* storage as well as one from network.
* This example shows fetching and displaying an image from local storage
* as well as one from network and even from data provided in the `'data:'` uri scheme.
*
* > Note that for network and data images, you will need to manually specify the dimensions of your image!
*
* ```ReactNativeWebPlayer
* import React, { Component } from 'react';
@@ -52,6 +55,10 @@ const ImageViewManager = NativeModules.ImageViewManager;
* style={{width: 50, height: 50}}
* source={{uri: 'https://facebook.github.io/react/img/logo_og.png'}}
* />
* <Image
* style={{width: 66, height: 58}}
* source={{uri: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADMAAAAzCAYAAAA6oTAqAAAAEXRFWHRTb2Z0d2FyZQBwbmdjcnVzaEB1SfMAAABQSURBVGje7dSxCQBACARB+2/ab8BEeQNhFi6WSYzYLYudDQYGBgYGBgYGBgYGBgYGBgZmcvDqYGBgmhivGQYGBgYGBgYGBgYGBgYGBgbmQw+P/eMrC5UTVAAAAABJRU5ErkJggg=='}}
* />
* </View>
* );
* }
@@ -103,17 +110,17 @@ const ImageViewManager = NativeModules.ImageViewManager;
* ```
* dependencies {
* // If your app supports Android versions before Ice Cream Sandwich (API level 14)
* compile 'com.facebook.fresco:animated-base-support:1.0.1'
* compile 'com.facebook.fresco:animated-base-support:1.3.0'
*
* // For animated GIF support
* compile 'com.facebook.fresco:animated-gif:1.0.1'
* compile 'com.facebook.fresco:animated-gif:1.3.0'
*
* // For WebP support, including animated WebP
* compile 'com.facebook.fresco:animated-webp:1.0.1'
* compile 'com.facebook.fresco:webpsupport:1.0.1'
* compile 'com.facebook.fresco:animated-webp:1.3.0'
* compile 'com.facebook.fresco:webpsupport:1.3.0'
*
* // For WebP support, without animations
* compile 'com.facebook.fresco:webpsupport:1.0.1'
* compile 'com.facebook.fresco:webpsupport:1.3.0'
* }
* ```
*
@@ -126,7 +133,8 @@ const ImageViewManager = NativeModules.ImageViewManager;
*
*/
// $FlowFixMe(>=0.41.0)
const Image = React.createClass({
const Image = createReactClass({
displayName: 'Image',
propTypes: {
/**
* > `ImageResizeMode` is an `Enum` for different image resizing modes, set via the
+31 -6
View File
@@ -14,8 +14,13 @@
const Image = require('Image');
const React = require('React');
const StyleSheet = require('StyleSheet');
const View = require('View');
const ensureComponentIsNative = require('ensureComponentIsNative');
import type {NativeMethodsMixinType} from 'ReactNativeTypes';
/**
* Very simple drop-in replacement for <Image> which supports nesting views.
*
@@ -41,20 +46,40 @@ const View = require('View');
* ```
*/
class ImageBackground extends React.Component {
setNativeProps(props: Object) {
// Work-around flow
const viewRef = this._viewRef;
if (viewRef) {
ensureComponentIsNative(viewRef);
viewRef.setNativeProps(props);
}
}
_viewRef: ?NativeMethodsMixinType = null;
_captureRef = ref => {
this._viewRef = ref;
};
render() {
const {children, style, imageStyle, imageRef, ...props} = this.props;
return (
<View style={style}>
<View style={style} ref={this._captureRef}>
<Image
{...props}
style={[
StyleSheet.absoluteFill,
{
position: 'absolute',
left: 0,
right: 0,
top: 0,
bottom: 0,
// Temporary Workaround:
// Current (imperfect yet) implementation of <Image> overwrites width and height styles
// (which is not quite correct), and these styles conflict with explicitly set styles
// of <ImageBackground> and with our internal layout model here.
// So, we have to proxy/reapply these styles explicitly for actual <Image> component.
// This workaround should be removed after implementing proper support of
// intrinsic content size of the <Image>.
width: style.width,
height: style.height,
},
imageStyle,
]}
+1 -1
View File
@@ -11,7 +11,7 @@
*/
'use strict';
const {PropTypes} = require('React');
const PropTypes = require('prop-types');
const ImageURISourcePropType = PropTypes.shape({
/**
+2 -3
View File
@@ -11,14 +11,13 @@
*/
'use strict';
var ColorPropType = require('ColorPropType');
var ImageResizeMode = require('ImageResizeMode');
var LayoutPropTypes = require('LayoutPropTypes');
var ColorPropType = require('ColorPropType');
var ReactPropTypes = require('prop-types');
var ShadowPropTypesIOS = require('ShadowPropTypesIOS');
var TransformPropTypes = require('TransformPropTypes');
var ReactPropTypes = require('React').PropTypes;
var ImageStylePropTypes = {
...LayoutPropTypes,
...ShadowPropTypesIOS,
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -12,7 +12,7 @@
'use strict';
// This is a stub for flow to make it understand require('./icon.png')
// See packager/src/Bundler/index.js
// See metro-bundler/src/Bundler/index.js
var AssetRegistry = require('AssetRegistry');
@@ -8,12 +8,6 @@
*/
'use strict';
jest
.unmock('AssetRegistry')
.unmock('AssetSourceResolver')
.unmock('../resolveAssetSource')
.unmock('../../../local-cli/bundle/assetPathUtils');
var AssetRegistry = require('AssetRegistry');
var Platform = require('Platform');
var NativeModules = require('NativeModules');
+2 -3
View File
@@ -35,10 +35,10 @@ class BoxInspector extends React.Component {
<BoxContainer title="padding" box={padding}>
<View>
<Text style={styles.innerText}>
({frame.left}, {frame.top})
({(frame.left || 0).toFixed(1)}, {(frame.top || 0).toFixed(1)})
</Text>
<Text style={styles.innerText}>
{frame.width} &times; {frame.height}
{(frame.width || 0).toFixed(1)} &times; {(frame.height || 0).toFixed(1)}
</Text>
</View>
</BoxContainer>
@@ -110,4 +110,3 @@ var styles = StyleSheet.create({
});
module.exports = BoxInspector;
+1 -1
View File
@@ -26,7 +26,7 @@ const UIManager = require('UIManager');
const View = require('View');
const emptyObject = require('fbjs/lib/emptyObject');
const invariant = require('invariant');
const invariant = require('fbjs/lib/invariant');
export type ReactRenderer = {
getInspectorDataForViewTag: (viewTag: number) => Object,
@@ -11,7 +11,6 @@
'use strict';
jest
.disableAutomock()
.mock('ErrorUtils')
.mock('BatchedBridge');
@@ -11,7 +11,6 @@
'use strict';
jest
.disableAutomock()
.mock('ErrorUtils')
.mock('BatchedBridge');
@@ -164,6 +163,7 @@ describe('promise tasks', () => {
}
beforeEach(() => {
jest.resetModules();
jest.useFakeTimers();
InteractionManager = require('InteractionManager');
BatchedBridge = require('BatchedBridge');
sequenceId = 0;
@@ -256,7 +256,9 @@ describe('promise tasks', () => {
expectToBeCalledOnce(task2);
});
const bigAsyncTest = () => {
const bigAsyncTest = (resolve) => {
jest.useRealTimers();
const task1 = createSequenceTask(1);
const task2 = jest.fn(() => {
expect(++sequenceId).toBe(2);
@@ -282,27 +284,25 @@ describe('promise tasks', () => {
InteractionManager.runAfterInteractions({gen: task2, name: 'gen2'});
InteractionManager.runAfterInteractions(task6);
jest.runAllTimers();
// runAllTimers doesn't actually run all timers with nested timer functions
// inside Promises, so we have to call it extra times.
jest.runAllTimers();
jest.runAllTimers();
setTimeout(() => {
expectToBeCalledOnce(task1);
expectToBeCalledOnce(task2);
expectToBeCalledOnce(task3);
expectToBeCalledOnce(task4);
expectToBeCalledOnce(task5);
expectToBeCalledOnce(task6);
expectToBeCalledOnce(task1);
expectToBeCalledOnce(task2);
expectToBeCalledOnce(task3);
expectToBeCalledOnce(task4);
expectToBeCalledOnce(task5);
expectToBeCalledOnce(task6);
resolve();
}, 100);
};
it('resolves async tasks recusively before other queued tasks', () => {
bigAsyncTest();
return new Promise(bigAsyncTest);
});
it('should also work with a deadline', () => {
InteractionManager.setDeadline(100);
BatchedBridge.getEventLoopRunningTime.mockReturnValue(200);
bigAsyncTest();
return new Promise(bigAsyncTest);
});
});
@@ -9,7 +9,7 @@
*/
'use strict';
jest.unmock('InteractionMixin');
jest.enableAutomock().unmock('InteractionMixin');
describe('InteractionMixin', () => {
var InteractionManager;
@@ -10,7 +10,7 @@
'use strict';
jest.unmock('TaskQueue');
const Promise = require('promise');
function expectToBeCalledOnce(fn) {
expect(fn.mock.calls.length).toBe(1);
+26 -13
View File
@@ -8,6 +8,7 @@
*
* @providesModule FillRateHelper
* @flow
* @format
*/
/* eslint-disable no-console-disallow */
@@ -56,17 +57,15 @@ class FillRateHelper {
_mostlyBlankStartTime = (null: ?number);
_samplesStartTime = (null: ?number);
static addListener(
callback: (FillRateInfo) => void
): {remove: () => void} {
static addListener(callback: FillRateInfo => void): {remove: () => void} {
warning(
_sampleRate !== null,
'Call `FillRateHelper.setSampleRate` before `addListener`.'
'Call `FillRateHelper.setSampleRate` before `addListener`.',
);
_listeners.push(callback);
return {
remove: () => {
_listeners = _listeners.filter((listener) => callback !== listener);
_listeners = _listeners.filter(listener => callback !== listener);
},
};
}
@@ -98,7 +97,8 @@ class FillRateHelper {
}
const start = this._samplesStartTime; // const for flow
if (start == null) {
DEBUG && console.debug('FillRateHelper: bail on deactivate with no start time');
DEBUG &&
console.debug('FillRateHelper: bail on deactivate with no start time');
return;
}
if (this._info.sample_count < _minSampleCount) {
@@ -115,10 +115,13 @@ class FillRateHelper {
const derived = {
avg_blankness: this._info.pixels_blank / this._info.pixels_sampled,
avg_speed: this._info.pixels_scrolled / (total_time_spent / 1000),
avg_speed_when_any_blank: this._info.any_blank_speed_sum / this._info.any_blank_count,
any_blank_per_min: this._info.any_blank_count / (total_time_spent / 1000 / 60),
avg_speed_when_any_blank:
this._info.any_blank_speed_sum / this._info.any_blank_count,
any_blank_per_min:
this._info.any_blank_count / (total_time_spent / 1000 / 60),
any_blank_time_frac: this._info.any_blank_ms / total_time_spent,
mostly_blank_per_min: this._info.mostly_blank_count / (total_time_spent / 1000 / 60),
mostly_blank_per_min:
this._info.mostly_blank_count / (total_time_spent / 1000 / 60),
mostly_blank_time_frac: this._info.mostly_blank_ms / total_time_spent,
};
for (const key in derived) {
@@ -126,7 +129,7 @@ class FillRateHelper {
}
console.debug('FillRateHelper deactivateAndFlush: ', {derived, info});
}
_listeners.forEach((listener) => listener(info));
_listeners.forEach(listener => listener(info));
this._resetData();
}
@@ -147,7 +150,11 @@ class FillRateHelper {
visibleLength: number,
},
): number {
if (!this._enabled || props.getItemCount(props.data) === 0 || this._samplesStartTime == null) {
if (
!this._enabled ||
props.getItemCount(props.data) === 0 ||
this._samplesStartTime == null
) {
return 0;
}
const {dOffset, offset, velocity, visibleLength} = scrollMetrics;
@@ -180,7 +187,10 @@ class FillRateHelper {
// Only count blankTop if we aren't rendering the first item, otherwise we will count the header
// as blank.
if (firstFrame && first > 0) {
blankTop = Math.min(visibleLength, Math.max(0, firstFrame.offset - offset));
blankTop = Math.min(
visibleLength,
Math.max(0, firstFrame.offset - offset),
);
}
let blankBottom = 0;
let last = state.last;
@@ -193,7 +203,10 @@ class FillRateHelper {
// footer as blank.
if (lastFrame && last < props.getItemCount(props.data) - 1) {
const bottomEdge = lastFrame.offset + lastFrame.length;
blankBottom = Math.min(visibleLength, Math.max(0, offset + visibleLength - bottomEdge));
blankBottom = Math.min(
visibleLength,
Math.max(0, offset + visibleLength - bottomEdge),
);
}
const pixels_blank = Math.round(blankTop + blankBottom);
const blankness = pixels_blank / visibleLength;
+80 -23
View File
@@ -8,6 +8,7 @@
*
* @providesModule FlatList
* @flow
* @format
*/
'use strict';
@@ -37,7 +38,7 @@ type RequiredProps<ItemT> = {
* onShowUnderlay={separators.highlight}
* onHideUnderlay={separators.unhighlight}>
* <View style={{backgroundColor: 'white'}}>
* <Text>{item.title}}</Text>
* <Text>{item.title}</Text>
* </View>
* </TouchableHighlight>
* )}
@@ -109,8 +110,10 @@ type OptionalProps<ItemT> = {
* Remember to include separator length (height or width) in your offset calculation if you
* specify `ItemSeparatorComponent`.
*/
getItemLayout?: (data: ?Array<ItemT>, index: number) =>
{length: number, offset: number, index: number},
getItemLayout?: (
data: ?Array<ItemT>,
index: number,
) => {length: number, offset: number, index: number},
/**
* If true, renders items next to each other horizontally instead of stacked vertically.
*/
@@ -128,6 +131,10 @@ type OptionalProps<ItemT> = {
* `getItemLayout` to be implemented.
*/
initialScrollIndex?: ?number,
/**
* Reverses the direction of scroll. Uses scale transforms of -1.
*/
inverted?: ?boolean,
/**
* Used to extract a unique key for a given item at the specified index. Key is used for caching
* and as the react key to track item re-ordering. The default extractor checks `item.key`, then
@@ -163,6 +170,11 @@ type OptionalProps<ItemT> = {
viewableItems: Array<ViewToken>,
changed: Array<ViewToken>,
}) => void,
/**
* Set this when offset is needed for the loading indicator to show correctly.
* @platform android
*/
progressViewOffset?: number,
legacyImplementation?: ?boolean,
/**
* Set this true while waiting for new data from a refresh.
@@ -179,7 +191,9 @@ type OptionalProps<ItemT> = {
*/
viewabilityConfig?: ViewabilityConfig,
};
type Props<ItemT> = RequiredProps<ItemT> & OptionalProps<ItemT> & VirtualizedListProps;
type Props<ItemT> = RequiredProps<ItemT> &
OptionalProps<ItemT> &
VirtualizedListProps;
const defaultProps = {
...VirtualizedList.defaultProps,
@@ -273,7 +287,7 @@ type DefaultProps = typeof defaultProps;
* }
*
* This is a convenience wrapper around [`<VirtualizedList>`](docs/virtualizedlist.html),
* and thus inherits it's props (as well as those of `ScrollView`) that aren't explicitly listed
* and thus inherits its props (as well as those of `ScrollView`) that aren't explicitly listed
* here, along with the following caveats:
*
* - Internal state is not preserved when content scrolls out of the render window. Make sure all
@@ -290,7 +304,11 @@ type DefaultProps = typeof defaultProps;
* Alternatively, you can provide a custom `keyExtractor` prop.
*
*/
class FlatList<ItemT> extends React.PureComponent<DefaultProps, Props<ItemT>, void> {
class FlatList<ItemT> extends React.PureComponent<
DefaultProps,
Props<ItemT>,
void,
> {
static defaultProps: DefaultProps = defaultProps;
props: Props<ItemT>;
/**
@@ -309,7 +327,10 @@ class FlatList<ItemT> extends React.PureComponent<DefaultProps, Props<ItemT>, vo
* `getItemLayout` prop.
*/
scrollToIndex(params: {
animated?: ?boolean, index: number, viewOffset?: number, viewPosition?: number,
animated?: ?boolean,
index: number,
viewOffset?: number,
viewPosition?: number,
}) {
this._listRef.scrollToIndex(params);
}
@@ -320,13 +341,17 @@ class FlatList<ItemT> extends React.PureComponent<DefaultProps, Props<ItemT>, vo
* Note: cannot scroll to locations outside the render window without specifying the
* `getItemLayout` prop.
*/
scrollToItem(params: {animated?: ?boolean, item: ItemT, viewPosition?: number}) {
scrollToItem(params: {
animated?: ?boolean,
item: ItemT,
viewPosition?: number,
}) {
this._listRef.scrollToItem(params);
}
/**
* Scroll to a specific content pixel offset in the list.
*
*
* Check out [scrollToOffset](docs/virtualizedlist.html#scrolltooffset) of VirtualizedList
*/
scrollToOffset(params: {animated?: ?boolean, offset: number}) {
@@ -366,6 +391,12 @@ class FlatList<ItemT> extends React.PureComponent<DefaultProps, Props<ItemT>, vo
}
}
setNativeProps(props: Object) {
if (this._listRef) {
this._listRef.setNativeProps(props);
}
}
componentWillMount() {
this._checkProps(this.props);
}
@@ -374,7 +405,7 @@ class FlatList<ItemT> extends React.PureComponent<DefaultProps, Props<ItemT>, vo
invariant(
nextProps.numColumns === this.props.numColumns,
'Changing numColumns on the fly is not supported. Change the key prop on FlatList when ' +
'changing the number of columns to force a fresh render of the component.'
'changing the number of columns to force a fresh render of the component.',
);
this._checkProps(nextProps);
}
@@ -382,7 +413,9 @@ class FlatList<ItemT> extends React.PureComponent<DefaultProps, Props<ItemT>, vo
_hasWarnedLegacy = false;
_listRef: VirtualizedList;
_captureRef = (ref) => { this._listRef = ref; };
_captureRef = ref => {
this._listRef = ref;
};
_checkProps(props: Props<ItemT>) {
const {
@@ -393,20 +426,29 @@ class FlatList<ItemT> extends React.PureComponent<DefaultProps, Props<ItemT>, vo
numColumns,
columnWrapperStyle,
} = props;
invariant(!getItem && !getItemCount, 'FlatList does not support custom data formats.');
invariant(
!getItem && !getItemCount,
'FlatList does not support custom data formats.',
);
if (numColumns > 1) {
invariant(!horizontal, 'numColumns does not support horizontal.');
} else {
invariant(!columnWrapperStyle, 'columnWrapperStyle not supported for single column lists');
invariant(
!columnWrapperStyle,
'columnWrapperStyle not supported for single column lists',
);
}
if (legacyImplementation) {
invariant(numColumns === 1, 'Legacy list does not support multiple columns.');
invariant(
numColumns === 1,
'Legacy list does not support multiple columns.',
);
// Warning: may not have full feature parity and is meant more for debugging and performance
// comparison.
if (!this._hasWarnedLegacy) {
console.warn(
'FlatList: Using legacyImplementation - some features not supported and performance ' +
'may suffer'
'may suffer',
);
this._hasWarnedLegacy = true;
}
@@ -437,10 +479,12 @@ class FlatList<ItemT> extends React.PureComponent<DefaultProps, Props<ItemT>, vo
invariant(
Array.isArray(items),
'FlatList: Encountered internal consistency error, expected each item to consist of an ' +
'array with 1-%s columns; instead, received a single item.',
'array with 1-%s columns; instead, received a single item.',
numColumns,
);
return items.map((it, kk) => keyExtractor(it, index * numColumns + kk)).join(':');
return items
.map((it, kk) => keyExtractor(it, index * numColumns + kk))
.join(':');
} else {
return keyExtractor(items, index);
}
@@ -455,7 +499,7 @@ class FlatList<ItemT> extends React.PureComponent<DefaultProps, Props<ItemT>, vo
});
}
_onViewableItemsChanged = (info) => {
_onViewableItemsChanged = info => {
const {numColumns, onViewableItemsChanged} = this.props;
if (!onViewableItemsChanged) {
return;
@@ -463,8 +507,10 @@ class FlatList<ItemT> extends React.PureComponent<DefaultProps, Props<ItemT>, vo
if (numColumns > 1) {
const changed = [];
const viewableItems = [];
info.viewableItems.forEach((v) => this._pushMultiColumnViewable(viewableItems, v));
info.changed.forEach((v) => this._pushMultiColumnViewable(changed, v));
info.viewableItems.forEach(v =>
this._pushMultiColumnViewable(viewableItems, v),
);
info.changed.forEach(v => this._pushMultiColumnViewable(changed, v));
onViewableItemsChanged({viewableItems, changed});
} else {
onViewableItemsChanged(info);
@@ -475,7 +521,10 @@ class FlatList<ItemT> extends React.PureComponent<DefaultProps, Props<ItemT>, vo
const {renderItem, numColumns, columnWrapperStyle} = this.props;
if (numColumns > 1) {
const {item, index} = info;
invariant(Array.isArray(item), 'Expected array of items with numColumns > 1');
invariant(
Array.isArray(item),
'Expected array of items with numColumns > 1',
);
return (
<View style={[{flexDirection: 'row'}, columnWrapperStyle]}>
{item.map((it, kk) => {
@@ -495,7 +544,13 @@ class FlatList<ItemT> extends React.PureComponent<DefaultProps, Props<ItemT>, vo
render() {
if (this.props.legacyImplementation) {
return <MetroListView {...this.props} items={this.props.data} ref={this._captureRef} />;
return (
<MetroListView
{...this.props}
items={this.props.data}
ref={this._captureRef}
/>
);
} else {
return (
<VirtualizedList
@@ -505,7 +560,9 @@ class FlatList<ItemT> extends React.PureComponent<DefaultProps, Props<ItemT>, vo
getItemCount={this._getItemCount}
keyExtractor={this._keyExtractor}
ref={this._captureRef}
onViewableItemsChanged={this.props.onViewableItemsChanged && this._onViewableItemsChanged}
onViewableItemsChanged={
this.props.onViewableItemsChanged && this._onViewableItemsChanged
}
/>
);
}
+142 -87
View File
@@ -8,6 +8,7 @@
*
* @providesModule ListView
* @flow
* @format
*/
'use strict';
@@ -24,6 +25,7 @@ var TimerMixin = require('react-timer-mixin');
var View = require('View');
var cloneReferencedElement = require('react-clone-referenced-element');
var createReactClass = require('create-react-class');
var isEmpty = require('isEmpty');
var merge = require('merge');
@@ -33,8 +35,13 @@ var DEFAULT_SCROLL_RENDER_AHEAD = 1000;
var DEFAULT_END_REACHED_THRESHOLD = 1000;
var DEFAULT_SCROLL_CALLBACK_THROTTLE = 50;
/**
* DEPRECATED - use one of the new list components, such as [`FlatList`](docs/flatlist.html)
* or [`SectionList`](docs/sectionlist.html) for bounded memory use, fewer bugs,
* better performance, an easier to use API, and more features. Check out this
* [blog post](https://facebook.github.io/react-native/blog/2017/03/13/better-list-views.html)
* for more details.
*
* ListView - A core component designed for efficient display of vertically
* scrolling lists of changing data. The minimal API is to create a
* [`ListView.DataSource`](docs/listviewdatasource.html), populate it with a simple
@@ -85,7 +92,8 @@ var DEFAULT_SCROLL_CALLBACK_THROTTLE = 50;
* rendering rows.
*/
var ListView = React.createClass({
var ListView = createReactClass({
displayName: 'ListView',
_childFrames: ([]: Array<Object>),
_sentEndForContentLength: (null: ?number),
_scrollComponent: (null: any),
@@ -233,7 +241,9 @@ var ListView = React.createClass({
getMetrics: function() {
return {
contentLength: this.scrollProperties.contentLength,
totalRows: (this.props.enableEmptySections ? this.props.dataSource.getRowAndSectionCount() : this.props.dataSource.getRowCount()),
totalRows: this.props.enableEmptySections
? this.props.dataSource.getRowAndSectionCount()
: this.props.dataSource.getRowCount(),
renderedRows: this.state.curRenderedRowsCount,
visibleRows: Object.keys(this._visibleRows).length,
};
@@ -279,14 +289,14 @@ var ListView = React.createClass({
*
* See `ScrollView#scrollToEnd`.
*/
scrollToEnd: function(options?: ?{ animated?: ?boolean }) {
scrollToEnd: function(options?: ?{animated?: ?boolean}) {
if (this._scrollComponent) {
if (this._scrollComponent.scrollToEnd) {
this._scrollComponent.scrollToEnd(options);
} else {
console.warn(
'The scroll component used by the ListView does not support ' +
'scrollToEnd. Check the renderScrollComponent prop of your ListView.'
'scrollToEnd. Check the renderScrollComponent prop of your ListView.',
);
}
}
@@ -328,7 +338,7 @@ var ListView = React.createClass({
getInitialState: function() {
return {
curRenderedRowsCount: this.props.initialListSize,
highlightedRow: ({} : Object),
highlightedRow: ({}: Object),
};
},
@@ -341,7 +351,7 @@ var ListView = React.createClass({
this.scrollProperties = {
visibleLength: null,
contentLength: null,
offset: 0
offset: 0,
};
this._childFrames = [];
this._visibleRows = {};
@@ -358,20 +368,24 @@ var ListView = React.createClass({
},
componentWillReceiveProps: function(nextProps: Object) {
if (this.props.dataSource !== nextProps.dataSource ||
this.props.initialListSize !== nextProps.initialListSize) {
this.setState((state, props) => {
this._prevRenderedRowsCount = 0;
return {
curRenderedRowsCount: Math.min(
Math.max(
state.curRenderedRowsCount,
props.initialListSize
if (
this.props.dataSource !== nextProps.dataSource ||
this.props.initialListSize !== nextProps.initialListSize
) {
this.setState(
(state, props) => {
this._prevRenderedRowsCount = 0;
return {
curRenderedRowsCount: Math.min(
Math.max(state.curRenderedRowsCount, props.initialListSize),
props.enableEmptySections
? props.dataSource.getRowAndSectionCount()
: props.dataSource.getRowCount(),
),
props.enableEmptySections ? props.dataSource.getRowAndSectionCount() : props.dataSource.getRowCount()
),
};
}, () => this._renderMoreRowsIfNeeded());
};
},
() => this._renderMoreRowsIfNeeded(),
);
}
},
@@ -405,26 +419,32 @@ var ListView = React.createClass({
if (rowIDs.length === 0) {
if (this.props.enableEmptySections === undefined) {
var warning = require('fbjs/lib/warning');
warning(false, 'In next release empty section headers will be rendered.'
+ ' In this release you can use \'enableEmptySections\' flag to render empty section headers.');
warning(
false,
'In next release empty section headers will be rendered.' +
" In this release you can use 'enableEmptySections' flag to render empty section headers.",
);
continue;
} else {
var invariant = require('fbjs/lib/invariant');
invariant(
this.props.enableEmptySections,
'In next release \'enableEmptySections\' flag will be deprecated, empty section headers will always be rendered.'
+ ' If empty section headers are not desirable their indices should be excluded from sectionIDs object.'
+ ' In this release \'enableEmptySections\' may only have value \'true\' to allow empty section headers rendering.');
"In next release 'enableEmptySections' flag will be deprecated, empty section headers will always be rendered." +
' If empty section headers are not desirable their indices should be excluded from sectionIDs object.' +
" In this release 'enableEmptySections' may only have value 'true' to allow empty section headers rendering.",
);
}
}
if (renderSectionHeader) {
const element = renderSectionHeader(
dataSource.getSectionHeaderData(sectionIdx),
sectionID
sectionID,
);
if (element) {
bodyComponents.push(React.cloneElement(element, {key: 's_' + sectionID}));
bodyComponents.push(
React.cloneElement(element, {key: 's_' + sectionID}),
);
if (this.props.stickySectionHeadersEnabled) {
stickySectionHeaderIndices.push(totalIndex);
}
@@ -435,9 +455,10 @@ var ListView = React.createClass({
for (var rowIdx = 0; rowIdx < rowIDs.length; rowIdx++) {
var rowID = rowIDs[rowIdx];
var comboID = sectionID + '_' + rowID;
var shouldUpdateRow = rowCount >= this._prevRenderedRowsCount &&
var shouldUpdateRow =
rowCount >= this._prevRenderedRowsCount &&
dataSource.rowShouldUpdate(sectionIdx, rowIdx);
var row =
var row = (
<StaticRenderer
key={'r_' + comboID}
shouldUpdate={!!shouldUpdateRow}
@@ -446,29 +467,31 @@ var ListView = React.createClass({
dataSource.getRowData(sectionIdx, rowIdx),
sectionID,
rowID,
this._onRowHighlighted
this._onRowHighlighted,
)}
/>;
/>
);
bodyComponents.push(row);
totalIndex++;
if (this.props.renderSeparator &&
(rowIdx !== rowIDs.length - 1 || sectionIdx === allRowIDs.length - 1)) {
if (
this.props.renderSeparator &&
(rowIdx !== rowIDs.length - 1 || sectionIdx === allRowIDs.length - 1)
) {
var adjacentRowHighlighted =
this.state.highlightedRow.sectionID === sectionID && (
this.state.highlightedRow.rowID === rowID ||
this.state.highlightedRow.rowID === rowIDs[rowIdx + 1]
);
this.state.highlightedRow.sectionID === sectionID &&
(this.state.highlightedRow.rowID === rowID ||
this.state.highlightedRow.rowID === rowIDs[rowIdx + 1]);
var separator = this.props.renderSeparator(
sectionID,
rowID,
adjacentRowHighlighted
adjacentRowHighlighted,
);
if (separator) {
bodyComponents.push(
<View key={'s_' + comboID}>
{separator}
</View>
</View>,
);
totalIndex++;
}
@@ -482,10 +505,7 @@ var ListView = React.createClass({
}
}
var {
renderScrollComponent,
...props
} = this.props;
var {renderScrollComponent, ...props} = this.props;
if (!props.scrollEventThrottle) {
props.scrollEventThrottle = DEFAULT_SCROLL_CALLBACK_THROTTLE;
}
@@ -494,7 +514,9 @@ var ListView = React.createClass({
}
Object.assign(props, {
onScroll: this._onScroll,
stickyHeaderIndices: this.props.stickyHeaderIndices.concat(stickySectionHeaderIndices),
stickyHeaderIndices: this.props.stickyHeaderIndices.concat(
stickySectionHeaderIndices,
),
// Do not pass these events downstream to ScrollView since they will be
// registered in ListView's own ScrollResponder.Mixin
@@ -504,11 +526,19 @@ var ListView = React.createClass({
onKeyboardDidHide: undefined,
});
return cloneReferencedElement(renderScrollComponent(props), {
ref: this._setScrollComponentRef,
onContentSizeChange: this._onContentSizeChange,
onLayout: this._onLayout,
}, header, bodyComponents, footer);
return cloneReferencedElement(
renderScrollComponent(props),
{
ref: this._setScrollComponentRef,
onContentSizeChange: this._onContentSizeChange,
onLayout: this._onLayout,
DEPRECATED_sendUpdatedChildFrames:
typeof props.onChangeVisibleRows !== undefined,
},
header,
bodyComponents,
footer,
);
},
/**
@@ -523,7 +553,8 @@ var ListView = React.createClass({
// RCTScrollViewManager.calculateChildFrames is not available on
// every platform
RCTScrollViewManager && RCTScrollViewManager.calculateChildFrames &&
RCTScrollViewManager &&
RCTScrollViewManager.calculateChildFrames &&
RCTScrollViewManager.calculateChildFrames(
ReactNative.findNodeHandle(scrollComponent),
this._updateVisibleRows,
@@ -541,7 +572,8 @@ var ListView = React.createClass({
this._updateVisibleRows();
this._renderMoreRowsIfNeeded();
}
this.props.onContentSizeChange && this.props.onContentSizeChange(width, height);
this.props.onContentSizeChange &&
this.props.onContentSizeChange(width, height);
},
_onLayout: function(event: Object) {
@@ -556,10 +588,16 @@ var ListView = React.createClass({
},
_maybeCallOnEndReached: function(event?: Object) {
if (this.props.onEndReached &&
this.scrollProperties.contentLength !== this._sentEndForContentLength &&
this._getDistanceFromEnd(this.scrollProperties) < this.props.onEndReachedThreshold &&
this.state.curRenderedRowsCount === (this.props.enableEmptySections ? this.props.dataSource.getRowAndSectionCount() : this.props.dataSource.getRowCount())) {
if (
this.props.onEndReached &&
this.scrollProperties.contentLength !== this._sentEndForContentLength &&
this._getDistanceFromEnd(this.scrollProperties) <
this.props.onEndReachedThreshold &&
this.state.curRenderedRowsCount ===
(this.props.enableEmptySections
? this.props.dataSource.getRowAndSectionCount()
: this.props.dataSource.getRowCount())
) {
this._sentEndForContentLength = this.scrollProperties.contentLength;
this.props.onEndReached(event);
return true;
@@ -568,9 +606,14 @@ var ListView = React.createClass({
},
_renderMoreRowsIfNeeded: function() {
if (this.scrollProperties.contentLength === null ||
if (
this.scrollProperties.contentLength === null ||
this.scrollProperties.visibleLength === null ||
this.state.curRenderedRowsCount === (this.props.enableEmptySections ? this.props.dataSource.getRowAndSectionCount() : this.props.dataSource.getRowCount())) {
this.state.curRenderedRowsCount ===
(this.props.enableEmptySections
? this.props.dataSource.getRowAndSectionCount()
: this.props.dataSource.getRowCount())
) {
this._maybeCallOnEndReached();
return;
}
@@ -582,23 +625,32 @@ var ListView = React.createClass({
},
_pageInNewRows: function() {
this.setState((state, props) => {
var rowsToRender = Math.min(
state.curRenderedRowsCount + props.pageSize,
(props.enableEmptySections ? props.dataSource.getRowAndSectionCount() : props.dataSource.getRowCount())
);
this._prevRenderedRowsCount = state.curRenderedRowsCount;
return {
curRenderedRowsCount: rowsToRender
};
}, () => {
this._measureAndUpdateScrollProps();
this._prevRenderedRowsCount = this.state.curRenderedRowsCount;
});
this.setState(
(state, props) => {
var rowsToRender = Math.min(
state.curRenderedRowsCount + props.pageSize,
props.enableEmptySections
? props.dataSource.getRowAndSectionCount()
: props.dataSource.getRowCount(),
);
this._prevRenderedRowsCount = state.curRenderedRowsCount;
return {
curRenderedRowsCount: rowsToRender,
};
},
() => {
this._measureAndUpdateScrollProps();
this._prevRenderedRowsCount = this.state.curRenderedRowsCount;
},
);
},
_getDistanceFromEnd: function(scrollProperties: Object) {
return scrollProperties.contentLength - scrollProperties.visibleLength - scrollProperties.offset;
return (
scrollProperties.contentLength -
scrollProperties.visibleLength -
scrollProperties.offset
);
},
_updateVisibleRows: function(updatedFrames?: Array<Object>) {
@@ -606,7 +658,7 @@ var ListView = React.createClass({
return; // No need to compute visible rows if there is no callback
}
if (updatedFrames) {
updatedFrames.forEach((newFrame) => {
updatedFrames.forEach(newFrame => {
this._childFrames[newFrame.index] = merge(newFrame);
});
}
@@ -637,8 +689,10 @@ var ListView = React.createClass({
var rowID = rowIDs[rowIdx];
var frame = this._childFrames[totalIndex];
totalIndex++;
if (this.props.renderSeparator &&
(rowIdx !== rowIDs.length - 1 || sectionIdx === allRowIDs.length - 1)){
if (
this.props.renderSeparator &&
(rowIdx !== rowIDs.length - 1 || sectionIdx === allRowIDs.length - 1)
) {
totalIndex++;
}
if (!frame) {
@@ -647,7 +701,7 @@ var ListView = React.createClass({
var rowVisible = visibleSection[rowID];
var min = isVertical ? frame.y : frame.x;
var max = min + (isVertical ? frame.height : frame.width);
if ((!min && !max) || (min === max)) {
if ((!min && !max) || min === max) {
break;
}
if (min > visibleMax || max < visibleMin) {
@@ -674,27 +728,28 @@ var ListView = React.createClass({
delete this._visibleRows[sectionID];
}
}
visibilityChanged && this.props.onChangeVisibleRows(this._visibleRows, changedRows);
visibilityChanged &&
this.props.onChangeVisibleRows(this._visibleRows, changedRows);
},
_onScroll: function(e: Object) {
var isVertical = !this.props.horizontal;
this.scrollProperties.visibleLength = e.nativeEvent.layoutMeasurement[
isVertical ? 'height' : 'width'
];
this.scrollProperties.contentLength = e.nativeEvent.contentSize[
isVertical ? 'height' : 'width'
];
this.scrollProperties.offset = e.nativeEvent.contentOffset[
isVertical ? 'y' : 'x'
];
this.scrollProperties.visibleLength =
e.nativeEvent.layoutMeasurement[isVertical ? 'height' : 'width'];
this.scrollProperties.contentLength =
e.nativeEvent.contentSize[isVertical ? 'height' : 'width'];
this.scrollProperties.offset =
e.nativeEvent.contentOffset[isVertical ? 'y' : 'x'];
this._updateVisibleRows(e.nativeEvent.updatedChildFrames);
if (!this._maybeCallOnEndReached(e)) {
this._renderMoreRowsIfNeeded();
}
if (this.props.onEndReached &&
this._getDistanceFromEnd(this.scrollProperties) > this.props.onEndReachedThreshold) {
if (
this.props.onEndReached &&
this._getDistanceFromEnd(this.scrollProperties) >
this.props.onEndReachedThreshold
) {
// Scrolled out of the end zone, so it should be able to trigger again.
this._sentEndForContentLength = null;
}
+47 -36
View File
@@ -8,6 +8,7 @@
*
* @providesModule ListViewDataSource
* @flow
* @format
*/
'use strict';
@@ -18,26 +19,26 @@ var warning = require('fbjs/lib/warning');
function defaultGetRowData(
dataBlob: any,
sectionID: number | string,
rowID: number | string
rowID: number | string,
): any {
return dataBlob[sectionID][rowID];
}
function defaultGetSectionHeaderData(
dataBlob: any,
sectionID: number | string
sectionID: number | string,
): any {
return dataBlob[sectionID];
}
type differType = (data1: any, data2: any) => bool;
type differType = (data1: any, data2: any) => boolean;
type ParamType = {
rowHasChanged: differType,
getRowData?: ?typeof defaultGetRowData,
sectionHeaderHasChanged?: ?differType,
getSectionHeaderData?: ?typeof defaultGetSectionHeaderData,
}
};
/**
* Provides efficient data processing and access to the
@@ -74,7 +75,6 @@ type ParamType = {
*/
class ListViewDataSource {
/**
* You can provide custom extraction and `hasChanged` functions for section
* headers and rows. If absent, data will be extracted with the
@@ -103,7 +103,7 @@ class ListViewDataSource {
constructor(params: ParamType) {
invariant(
params && typeof params.rowHasChanged === 'function',
'Must provide a rowHasChanged function.'
'Must provide a rowHasChanged function.',
);
this._rowHasChanged = params.rowHasChanged;
this._getRowData = params.getRowData || defaultGetRowData;
@@ -138,10 +138,10 @@ class ListViewDataSource {
* handle merging of old and new data separately and then pass that into
* this function as the `dataBlob`.
*/
cloneWithRows(
dataBlob: $ReadOnlyArray<any> | {+[key: string]: any},
rowIdentities: ?$ReadOnlyArray<string>
): ListViewDataSource {
cloneWithRows(
dataBlob: $ReadOnlyArray<any> | {+[key: string]: any},
rowIdentities: ?$ReadOnlyArray<string>,
): ListViewDataSource {
var rowIds = rowIdentities ? [[...rowIdentities]] : null;
if (!this._sectionHeaderHasChanged) {
this._sectionHeaderHasChanged = () => false;
@@ -161,17 +161,19 @@ class ListViewDataSource {
* Note: this returns a new object!
*/
cloneWithRowsAndSections(
dataBlob: any,
sectionIdentities: ?Array<string>,
rowIdentities: ?Array<Array<string>>
dataBlob: any,
sectionIdentities: ?Array<string>,
rowIdentities: ?Array<Array<string>>,
): ListViewDataSource {
invariant(
typeof this._sectionHeaderHasChanged === 'function',
'Must provide a sectionHeaderHasChanged function with section data.'
'Must provide a sectionHeaderHasChanged function with section data.',
);
invariant(
!sectionIdentities || !rowIdentities || sectionIdentities.length === rowIdentities.length,
'row and section ids lengths must be the same'
!sectionIdentities ||
!rowIdentities ||
sectionIdentities.length === rowIdentities.length,
'row and section ids lengths must be the same',
);
var newSource = new ListViewDataSource({
@@ -190,7 +192,7 @@ class ListViewDataSource {
newSource.rowIdentities = rowIdentities;
} else {
newSource.rowIdentities = [];
newSource.sectionIdentities.forEach((sectionID) => {
newSource.sectionIdentities.forEach(sectionID => {
newSource.rowIdentities.push(Object.keys(dataBlob[sectionID]));
});
}
@@ -199,7 +201,7 @@ class ListViewDataSource {
newSource._calculateDirtyArrays(
this._dataBlob,
this.sectionIdentities,
this.rowIdentities
this.rowIdentities,
);
return newSource;
@@ -210,16 +212,18 @@ class ListViewDataSource {
}
getRowAndSectionCount(): number {
return (this._cachedRowCount + this.sectionIdentities.length);
return this._cachedRowCount + this.sectionIdentities.length;
}
/**
* Returns if the row is dirtied and needs to be rerendered
*/
rowShouldUpdate(sectionIndex: number, rowIndex: number): bool {
rowShouldUpdate(sectionIndex: number, rowIndex: number): boolean {
var needsUpdate = this._dirtyRows[sectionIndex][rowIndex];
warning(needsUpdate !== undefined,
'missing dirtyBit for section, row: ' + sectionIndex + ', ' + rowIndex);
warning(
needsUpdate !== undefined,
'missing dirtyBit for section, row: ' + sectionIndex + ', ' + rowIndex,
);
return needsUpdate;
}
@@ -231,7 +235,7 @@ class ListViewDataSource {
var rowID = this.rowIdentities[sectionIndex][rowIndex];
warning(
sectionID !== undefined && rowID !== undefined,
'rendering invalid section, row: ' + sectionIndex + ', ' + rowIndex
'rendering invalid section, row: ' + sectionIndex + ', ' + rowIndex,
);
return this._getRowData(this._dataBlob, sectionID, rowID);
}
@@ -282,10 +286,12 @@ class ListViewDataSource {
/**
* Returns if the section header is dirtied and needs to be rerendered
*/
sectionHeaderShouldUpdate(sectionIndex: number): bool {
sectionHeaderShouldUpdate(sectionIndex: number): boolean {
var needsUpdate = this._dirtySections[sectionIndex];
warning(needsUpdate !== undefined,
'missing dirtyBit for section: ' + sectionIndex);
warning(
needsUpdate !== undefined,
'missing dirtyBit for section: ' + sectionIndex,
);
return needsUpdate;
}
@@ -297,8 +303,10 @@ class ListViewDataSource {
return null;
}
var sectionID = this.sectionIdentities[sectionIndex];
warning(sectionID !== undefined,
'renderSection called on invalid section: ' + sectionIndex);
warning(
sectionID !== undefined,
'renderSection called on invalid section: ' + sectionIndex,
);
return this._getSectionHeaderData(this._dataBlob, sectionID);
}
@@ -312,8 +320,8 @@ class ListViewDataSource {
_sectionHeaderHasChanged: ?differType;
_dataBlob: any;
_dirtyRows: Array<Array<bool>>;
_dirtySections: Array<bool>;
_dirtyRows: Array<Array<boolean>>;
_dirtySections: Array<boolean>;
_cachedRowCount: number;
// These two 'protected' variables are accessed by ListView to iterate over
@@ -324,7 +332,7 @@ class ListViewDataSource {
_calculateDirtyArrays(
prevDataBlob: any,
prevSectionIDs: Array<string>,
prevRowIDs: Array<Array<string>>
prevRowIDs: Array<Array<string>>,
): void {
// construct a hashmap of the existing (old) id arrays
var prevSectionsHash = keyedDictionaryFromArray(prevSectionIDs);
@@ -333,7 +341,7 @@ class ListViewDataSource {
var sectionID = prevSectionIDs[ii];
warning(
!prevRowsHash[sectionID],
'SectionID appears more than once: ' + sectionID
'SectionID appears more than once: ' + sectionID,
);
prevRowsHash[sectionID] = keyedDictionaryFromArray(prevRowIDs[ii]);
}
@@ -351,13 +359,17 @@ class ListViewDataSource {
if (!dirty && sectionHeaderHasChanged) {
dirty = sectionHeaderHasChanged(
this._getSectionHeaderData(prevDataBlob, sectionID),
this._getSectionHeaderData(this._dataBlob, sectionID)
this._getSectionHeaderData(this._dataBlob, sectionID),
);
}
this._dirtySections.push(!!dirty);
this._dirtyRows[sIndex] = [];
for (var rIndex = 0; rIndex < this.rowIdentities[sIndex].length; rIndex++) {
for (
var rIndex = 0;
rIndex < this.rowIdentities[sIndex].length;
rIndex++
) {
var rowID = this.rowIdentities[sIndex][rIndex];
// dirty if the section is new, row is new or _rowHasChanged is true
dirty =
@@ -365,7 +377,7 @@ class ListViewDataSource {
!prevRowsHash[sectionID][rowID] ||
this._rowHasChanged(
this._getRowData(prevDataBlob, sectionID, rowID),
this._getRowData(this._dataBlob, sectionID, rowID)
this._getRowData(this._dataBlob, sectionID, rowID),
);
this._dirtyRows[sIndex].push(!!dirty);
}
@@ -395,5 +407,4 @@ function keyedDictionaryFromArray(arr) {
return result;
}
module.exports = ListViewDataSource;
@@ -7,6 +7,7 @@
* of patent rights can be found in the PATENTS file in the same directory.
*
* @flow
* @format
*/
'use strict';
@@ -18,8 +19,8 @@ const StaticRenderer = require('StaticRenderer');
class ListViewMock extends React.Component {
static latestRef: ?ListViewMock;
static defaultProps = {
renderScrollComponent: (props) => <ScrollView {...props} />,
}
renderScrollComponent: props => <ScrollView {...props} />,
};
componentDidMount() {
ListViewMock.latestRef = this;
}
@@ -41,9 +42,9 @@ class ListViewMock extends React.Component {
null,
dataSource.getRowData(sectionIdx, rowIdx),
sectionID,
rowID
rowID,
)}
/>
/>,
);
}
}
+37 -19
View File
@@ -8,6 +8,7 @@
*
* @providesModule MetroListView
* @flow
* @format
*/
'use strict';
@@ -62,10 +63,18 @@ class MetroListView extends React.Component {
scrollToEnd(params?: ?{animated?: ?boolean}) {
throw new Error('scrollToEnd not supported in legacy ListView.');
}
scrollToIndex(params: {animated?: ?boolean, index: number, viewPosition?: number}) {
scrollToIndex(params: {
animated?: ?boolean,
index: number,
viewPosition?: number,
}) {
throw new Error('scrollToIndex not supported in legacy ListView.');
}
scrollToItem(params: {animated?: ?boolean, item: Item, viewPosition?: number}) {
scrollToItem(params: {
animated?: ?boolean,
item: Item,
viewPosition?: number,
}) {
throw new Error('scrollToItem not supported in legacy ListView.');
}
scrollToLocation(params: {
@@ -80,12 +89,17 @@ class MetroListView extends React.Component {
scrollToOffset(params: {animated?: ?boolean, offset: number}) {
const {animated, offset} = params;
this._listRef.scrollTo(
this.props.horizontal ? {x: offset, animated} : {y: offset, animated}
this.props.horizontal ? {x: offset, animated} : {y: offset, animated},
);
}
getListRef() {
return this._listRef;
}
setNativeProps(props: Object) {
if (this._listRef) {
this._listRef.setNativeProps(props);
}
}
static defaultProps: DefaultProps = {
keyExtractor: (item, index) => item.key || String(index),
renderScrollComponent: (props: Props) => {
@@ -106,19 +120,17 @@ class MetroListView extends React.Component {
}
},
};
state = this._computeState(
this.props,
{
ds: new ListView.DataSource({
rowHasChanged: (itemA, itemB) => true,
sectionHeaderHasChanged: () => true,
getSectionHeaderData: (dataBlob, sectionID) => this.state.sectionHeaderData[sectionID],
}),
sectionHeaderData: {},
},
);
state = this._computeState(this.props, {
ds: new ListView.DataSource({
rowHasChanged: (itemA, itemB) => true,
sectionHeaderHasChanged: () => true,
getSectionHeaderData: (dataBlob, sectionID) =>
this.state.sectionHeaderData[sectionID],
}),
sectionHeaderData: {},
});
componentWillReceiveProps(newProps: Props) {
this.setState((state) => this._computeState(newProps, state));
this.setState(state => this._computeState(newProps, state));
}
render() {
return (
@@ -134,7 +146,9 @@ class MetroListView extends React.Component {
);
}
_listRef: ListView;
_captureRef = (ref) => { this._listRef = ref; };
_captureRef = ref => {
this._listRef = ref;
};
_computeState(props: Props, state) {
const sectionHeaderData = {};
if (props.sections) {
@@ -163,10 +177,14 @@ class MetroListView extends React.Component {
};
_renderSectionHeader = (section, sectionID) => {
const {renderSectionHeader} = this.props;
invariant(renderSectionHeader, 'Must provide renderSectionHeader with sections prop');
invariant(
renderSectionHeader,
'Must provide renderSectionHeader with sections prop',
);
return renderSectionHeader({section});
}
_renderSeparator = (sID, rID) => <this.props.SeparatorComponent key={sID + rID} />;
};
_renderSeparator = (sID, rID) =>
<this.props.SeparatorComponent key={sID + rID} />;
}
module.exports = MetroListView;
+22 -11
View File
@@ -8,6 +8,7 @@
*
* @providesModule SectionList
* @flow
* @format
*/
'use strict';
@@ -121,12 +122,16 @@ type OptionalProps<SectionT: SectionBase<any>> = {
* to improve perceived performance of scroll-to-top actions.
*/
initialNumToRender: number,
/**
* Reverses the direction of scroll. Uses scale transforms of -1.
*/
inverted?: ?boolean,
/**
* Used to extract a unique key for a given item at the specified index. Key is used for caching
* and as the react key to track item re-ordering. The default extractor checks item.key, then
* falls back to using the index, like react does.
* falls back to using the index, like react does. Note that this sets keys for each item, but
* each overall section still needs its own key.
*/
keyExtractor: (item: Item, index: number) => string,
/**
* Called once when the scroll position gets within `onEndReachedThreshold` of the rendered
@@ -181,9 +186,9 @@ type OptionalProps<SectionT: SectionBase<any>> = {
legacyImplementation?: ?boolean,
};
type Props<SectionT> = RequiredProps<SectionT>
& OptionalProps<SectionT>
& VirtualizedSectionListProps<SectionT>;
type Props<SectionT> = RequiredProps<SectionT> &
OptionalProps<SectionT> &
VirtualizedSectionListProps<SectionT>;
const defaultProps = {
...VirtualizedSectionList.defaultProps,
@@ -230,7 +235,7 @@ type DefaultProps = typeof defaultProps;
* />
*
* This is a convenience wrapper around [`<VirtualizedList>`](docs/virtualizedlist.html),
* and thus inherits it's props (as well as those of `ScrollView`) that aren't explicitly listed
* and thus inherits its props (as well as those of `ScrollView`) that aren't explicitly listed
* here, along with the following caveats:
*
* - Internal state is not preserved when content scrolls out of the render window. Make sure all
@@ -247,9 +252,11 @@ type DefaultProps = typeof defaultProps;
* Alternatively, you can provide a custom `keyExtractor` prop.
*
*/
class SectionList<SectionT: SectionBase<any>>
extends React.PureComponent<DefaultProps, Props<SectionT>, void>
{
class SectionList<SectionT: SectionBase<any>> extends React.PureComponent<
DefaultProps,
Props<SectionT>,
void,
> {
props: Props<SectionT>;
static defaultProps: DefaultProps = defaultProps;
@@ -311,12 +318,16 @@ class SectionList<SectionT: SectionBase<any>>
}
render() {
const List = this.props.legacyImplementation ? MetroListView : VirtualizedSectionList;
const List = this.props.legacyImplementation
? MetroListView
: VirtualizedSectionList;
return <List {...this.props} ref={this._captureRef} />;
}
_wrapperListRef: MetroListView | VirtualizedSectionList<any>;
_captureRef = (ref) => { this._wrapperListRef = ref; };
_captureRef = ref => {
this._wrapperListRef = ref;
};
}
module.exports = SectionList;
+79 -41
View File
@@ -8,12 +8,19 @@
*
* @providesModule ViewabilityHelper
* @flow
* @format
*/
'use strict';
const invariant = require('fbjs/lib/invariant');
export type ViewToken = {item: any, key: string, index: ?number, isViewable: boolean, section?: any};
export type ViewToken = {
item: any,
key: string,
index: ?number,
isViewable: boolean,
section?: any,
};
export type ViewabilityConfig = {|
/**
@@ -64,7 +71,9 @@ class ViewabilityHelper {
_viewableIndices: Array<number> = [];
_viewableItems: Map<string, ViewToken> = new Map();
constructor(config: ViewabilityConfig = {viewAreaCoveragePercentThreshold: 0}) {
constructor(
config: ViewabilityConfig = {viewAreaCoveragePercentThreshold: 0},
) {
this._config = config;
}
@@ -85,14 +94,19 @@ class ViewabilityHelper {
getFrameMetrics: (index: number) => ?{length: number, offset: number},
renderRange?: {first: number, last: number}, // Optional optimization to reduce the scan size
): Array<number> {
const {itemVisiblePercentThreshold, viewAreaCoveragePercentThreshold} = this._config;
const {
itemVisiblePercentThreshold,
viewAreaCoveragePercentThreshold,
} = this._config;
const viewAreaMode = viewAreaCoveragePercentThreshold != null;
const viewablePercentThreshold = viewAreaMode ?
viewAreaCoveragePercentThreshold :
itemVisiblePercentThreshold;
const viewablePercentThreshold = viewAreaMode
? viewAreaCoveragePercentThreshold
: itemVisiblePercentThreshold;
invariant(
viewablePercentThreshold != null &&
(itemVisiblePercentThreshold != null) !== (viewAreaCoveragePercentThreshold != null),
itemVisiblePercentThreshold !=
null !==
(viewAreaCoveragePercentThreshold != null),
'Must set exactly one of itemVisiblePercentThreshold or viewAreaCoveragePercentThreshold',
);
const viewableIndices = [];
@@ -103,7 +117,7 @@ class ViewabilityHelper {
const {first, last} = renderRange || {first: 0, last: itemCount - 1};
invariant(
last < itemCount,
'Invalid render range ' + JSON.stringify({renderRange, itemCount})
'Invalid render range ' + JSON.stringify({renderRange, itemCount}),
);
for (let idx = first; idx <= last; idx++) {
const metrics = getFrameMetrics(idx);
@@ -112,16 +126,18 @@ class ViewabilityHelper {
}
const top = metrics.offset - scrollOffset;
const bottom = top + metrics.length;
if ((top < viewportHeight) && (bottom > 0)) {
if (top < viewportHeight && bottom > 0) {
firstVisible = idx;
if (_isViewable(
viewAreaMode,
viewablePercentThreshold,
top,
bottom,
viewportHeight,
metrics.length,
)) {
if (
_isViewable(
viewAreaMode,
viewablePercentThreshold,
top,
bottom,
viewportHeight,
metrics.length,
)
) {
viewableIndices.push(idx);
}
} else if (firstVisible >= 0) {
@@ -141,7 +157,10 @@ class ViewabilityHelper {
viewportHeight: number,
getFrameMetrics: (index: number) => ?{length: number, offset: number},
createViewToken: (index: number, isViewable: boolean) => ViewToken,
onViewableItemsChanged: ({viewableItems: Array<ViewToken>, changed: Array<ViewToken>}) => void,
onViewableItemsChanged: ({
viewableItems: Array<ViewToken>,
changed: Array<ViewToken>,
}) => void,
renderRange?: {first: number, last: number}, // Optional optimization to reduce the scan size
): void {
const updateTime = Date.now();
@@ -149,7 +168,9 @@ class ViewabilityHelper {
// Only count updates after the first item is rendered and has a frame.
this._lastUpdateTime = updateTime;
}
const updateElapsed = this._lastUpdateTime ? updateTime - this._lastUpdateTime : 0;
const updateElapsed = this._lastUpdateTime
? updateTime - this._lastUpdateTime
: 0;
if (this._config.waitForInteraction && !this._hasInteracted) {
return;
}
@@ -163,25 +184,35 @@ class ViewabilityHelper {
renderRange,
);
}
if (this._viewableIndices.length === viewableIndices.length &&
this._viewableIndices.every((v, ii) => v === viewableIndices[ii])) {
if (
this._viewableIndices.length === viewableIndices.length &&
this._viewableIndices.every((v, ii) => v === viewableIndices[ii])
) {
// We might get a lot of scroll events where visibility doesn't change and we don't want to do
// extra work in those cases.
return;
}
this._viewableIndices = viewableIndices;
this._lastUpdateTime = updateTime;
if (this._config.minimumViewTime && updateElapsed < this._config.minimumViewTime) {
const handle = setTimeout(
() => {
this._timers.delete(handle);
this._onUpdateSync(viewableIndices, onViewableItemsChanged, createViewToken);
},
this._config.minimumViewTime,
);
if (
this._config.minimumViewTime &&
updateElapsed < this._config.minimumViewTime
) {
const handle = setTimeout(() => {
this._timers.delete(handle);
this._onUpdateSync(
viewableIndices,
onViewableItemsChanged,
createViewToken,
);
}, this._config.minimumViewTime);
this._timers.add(handle);
} else {
this._onUpdateSync(viewableIndices, onViewableItemsChanged, createViewToken);
this._onUpdateSync(
viewableIndices,
onViewableItemsChanged,
createViewToken,
);
}
}
@@ -192,17 +223,21 @@ class ViewabilityHelper {
this._hasInteracted = true;
}
_onUpdateSync(viewableIndicesToCheck, onViewableItemsChanged, createViewToken) {
_onUpdateSync(
viewableIndicesToCheck,
onViewableItemsChanged,
createViewToken,
) {
// Filter out indices that have gone out of view since this call was scheduled.
viewableIndicesToCheck = viewableIndicesToCheck.filter(
(ii) => this._viewableIndices.includes(ii)
viewableIndicesToCheck = viewableIndicesToCheck.filter(ii =>
this._viewableIndices.includes(ii),
);
const prevItems = this._viewableItems;
const nextItems = new Map(
viewableIndicesToCheck.map(ii => {
const viewable = createViewToken(ii, true);
return [viewable.key, viewable];
})
}),
);
const changed = [];
@@ -218,12 +253,14 @@ class ViewabilityHelper {
}
if (changed.length > 0) {
this._viewableItems = nextItems;
onViewableItemsChanged({viewableItems: Array.from(nextItems.values()), changed});
onViewableItemsChanged({
viewableItems: Array.from(nextItems.values()),
changed,
});
}
}
}
function _isViewable(
viewAreaMode: boolean,
viewablePercentThreshold: number,
@@ -231,12 +268,13 @@ function _isViewable(
bottom: number,
viewportHeight: number,
itemLength: number,
): bool {
): boolean {
if (_isEntirelyVisible(top, bottom, viewportHeight)) {
return true;
} else {
const pixels = _getPixelsVisible(top, bottom, viewportHeight);
const percent = 100 * (viewAreaMode ? pixels / viewportHeight : pixels / itemLength);
const percent =
100 * (viewAreaMode ? pixels / viewportHeight : pixels / itemLength);
return percent >= viewablePercentThreshold;
}
}
@@ -244,7 +282,7 @@ function _isViewable(
function _getPixelsVisible(
top: number,
bottom: number,
viewportHeight: number
viewportHeight: number,
): number {
const visibleHeight = Math.min(bottom, viewportHeight) - Math.max(top, 0);
return Math.max(0, visibleHeight);
@@ -253,8 +291,8 @@ function _getPixelsVisible(
function _isEntirelyVisible(
top: number,
bottom: number,
viewportHeight: number
): bool {
viewportHeight: number,
): boolean {
return top >= 0 && bottom <= viewportHeight && bottom > top;
}

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