mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Compare commits
25
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a8342a9673 | ||
|
|
67e119ded8 | ||
|
|
f1cc3ac75a | ||
|
|
39e0750223 | ||
|
|
1668f90f8e | ||
|
|
c9e24899cb | ||
|
|
df15af6142 | ||
|
|
1a72de8a6d | ||
|
|
3fc67a4391 | ||
|
|
446ff94cfe | ||
|
|
1ea4002b72 | ||
|
|
be67788759 | ||
|
|
fa40f5521d | ||
|
|
d38f18987d | ||
|
|
a35cf5cb32 | ||
|
|
9d479ceb92 | ||
|
|
3ef62a4fe9 | ||
|
|
7c3918b747 | ||
|
|
671c46a5e5 | ||
|
|
b91e04f61f | ||
|
|
ff6189b9be | ||
|
|
55501c3ba8 | ||
|
|
2f9ece4e63 | ||
|
|
5c6a168a28 | ||
|
|
65683a6940 |
@@ -9,4 +9,5 @@
|
||||
central = https://repo1.maven.org/maven2
|
||||
|
||||
[alias]
|
||||
movies = //Examples/Movies/android/app:app
|
||||
rntester = //RNTester/android/app:app
|
||||
|
||||
+1
-9
@@ -3,12 +3,4 @@
|
||||
**/staticBundle.js
|
||||
**/main.js
|
||||
Libraries/vendor/**/*
|
||||
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/
|
||||
packager/src/worker-farm/**/*
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
{
|
||||
"root": true,
|
||||
|
||||
"parser": "babel-eslint",
|
||||
|
||||
"ecmaFeatures": {
|
||||
@@ -13,8 +11,6 @@
|
||||
},
|
||||
|
||||
"plugins": [
|
||||
"flowtype",
|
||||
"prettier",
|
||||
"react"
|
||||
],
|
||||
|
||||
@@ -53,17 +49,33 @@
|
||||
"setTimeout": false,
|
||||
"window": false,
|
||||
"XMLHttpRequest": false,
|
||||
"pit": 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
|
||||
},
|
||||
|
||||
"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)
|
||||
@@ -164,10 +176,6 @@
|
||||
"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.
|
||||
|
||||
@@ -233,6 +241,6 @@
|
||||
"react/prop-types": 0,
|
||||
"react/react-in-jsx-scope": 1,
|
||||
"react/self-closing-comp": 1,
|
||||
"react/wrap-multilines": 0
|
||||
"react/wrap-multilines": 0,
|
||||
}
|
||||
}
|
||||
|
||||
+6
-3
@@ -18,6 +18,7 @@
|
||||
; For RN Apps installed via npm, "Libraries" folder is inside
|
||||
; "node_modules/react-native" but in the source repo it is in the root
|
||||
.*/Libraries/react-native/React.js
|
||||
.*/Libraries/react-native/ReactNative.js
|
||||
|
||||
[include]
|
||||
|
||||
@@ -30,6 +31,8 @@ emoji=true
|
||||
|
||||
module.system=haste
|
||||
|
||||
experimental.strict_type_args=true
|
||||
|
||||
munge_underscores=true
|
||||
|
||||
module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> 'RelativeImageStub'
|
||||
@@ -38,12 +41,12 @@ suppress_type=$FlowIssue
|
||||
suppress_type=$FlowFixMe
|
||||
suppress_type=$FixMe
|
||||
|
||||
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\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(4[0-5]\\|[1-3][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native_oss[a-z,_]*\\)?)\\)
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(4[0-5]\\|[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.49.1
|
||||
^0.45.0
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
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
|
||||
+24
-112
@@ -1,124 +1,36 @@
|
||||
<!--
|
||||
PLEASE DON'T DELETE THIS TEMPLATE UNTIL YOU HAVE READ THE FIRST SECTION.
|
||||
-->
|
||||
Please read the following carefully before opening a new issue.
|
||||
Your issue may be closed if it does not provide the information required by this template.
|
||||
|
||||
### Is this a bug report?
|
||||
We use GitHub Issues exclusively for tracking bugs in React Native.
|
||||
|
||||
(write your answer here)
|
||||
- If you have a question, ask on Stack Overflow: http://stackoverflow.com/questions/tagged/react-native
|
||||
- If you have a feature request, post it on Canny: https://react-native.canny.io/feature-requests
|
||||
|
||||
<!--
|
||||
If you answered "Yes":
|
||||
Make sure your issue reproduces on master. Your issue may already have been fixed!
|
||||
If your issue is present in master and in the stable release, try to reproduce your bug on https://snack.expo.io/
|
||||
If you can't reproduce the bug on Snack, provide a sample project.
|
||||
At the very least, provide an example of your code.
|
||||
|
||||
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.
|
||||
--- Delete everything above this line ---
|
||||
|
||||
If you answered "No":
|
||||
### Description
|
||||
|
||||
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
|
||||
Explain what you did, what you expected to happen, and what actually happens.
|
||||
|
||||
Now scroll below!
|
||||
-->
|
||||
### 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 is REQUIRED***
|
||||
|
||||
|
||||
### Have you read the Bugs section of the Contributing to React Native Guide?
|
||||
### Solution
|
||||
|
||||
(Write your answer here.)
|
||||
What needs to be done to address this issue? Ideally, provide a pull request with a fix.
|
||||
|
||||
<!--
|
||||
Please read through the bug reporting guidelines thoroughly:
|
||||
https://github.com/facebook/react-native/blob/master/CONTRIBUTING.md#bugs
|
||||
-->
|
||||
### Additional Information
|
||||
|
||||
### 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 doesn’t 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?
|
||||
It’s fine if you’re 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 can’t share the real code.
|
||||
|
||||
* Or, copy your app and remove things until you’re 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 you’re 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 it’s 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!
|
||||
-->
|
||||
* 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]
|
||||
|
||||
@@ -1,9 +1,32 @@
|
||||
<!--
|
||||
Thank you for sending the PR!
|
||||
Thanks for submitting a PR! Please read these instructions carefully:
|
||||
|
||||
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!
|
||||
- [ ] 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 at https://github.com/facebook/react-native/blob/master/CONTRIBUTING.md to learn more about contributing to React Native.
|
||||
## Motivation (required)
|
||||
|
||||
Happy contributing!
|
||||
-->
|
||||
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
|
||||
|
||||
+4
-7
@@ -23,10 +23,10 @@ project.xcworkspace
|
||||
|
||||
# Gradle
|
||||
/build/
|
||||
/RNTester/android/app/build/
|
||||
/RNTester/android/app/gradle/
|
||||
/RNTester/android/app/gradlew
|
||||
/RNTester/android/app/gradlew.bat
|
||||
/Examples/**/android/app/build/
|
||||
/Examples/**/android/app/gradle/
|
||||
/Examples/**/android/app/gradlew
|
||||
/Examples/**/android/app/gradlew.bat
|
||||
/ReactAndroid/build/
|
||||
|
||||
# Buck
|
||||
@@ -57,6 +57,3 @@ node_modules
|
||||
|
||||
/coverage
|
||||
/third-party
|
||||
|
||||
/website/src
|
||||
/website/build
|
||||
|
||||
+16
-10
@@ -1,22 +1,27 @@
|
||||
language: objective-c
|
||||
|
||||
osx_image: xcode8.3
|
||||
osx_image: xcode8.2
|
||||
|
||||
install:
|
||||
- nvm install 7
|
||||
- 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
|
||||
- rm -Rf "${TMPDIR}/jest_preprocess_cache"
|
||||
- brew install yarn --ignore-dependencies
|
||||
- yarn install
|
||||
- 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
|
||||
|
||||
script:
|
||||
- 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" = 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" = 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 && travis_wait 30 ./scripts/process-podspecs.sh; fi
|
||||
- if [[ ( "$TEST_TYPE" = podspecs ) && ( "$TRAVIS_PULL_REQUEST" = "false" ) ]]; then gem install cocoapods && ./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).
|
||||
@@ -36,6 +41,7 @@ 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
|
||||
|
||||
Vendored
-14
@@ -1,14 +0,0 @@
|
||||
{
|
||||
// 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"
|
||||
}
|
||||
]
|
||||
}
|
||||
+41
-106
@@ -1,124 +1,44 @@
|
||||
# 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 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.
|
||||
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.
|
||||
|
||||
## Our Development Process
|
||||
|
||||
Some of the core team will be working directly on [GitHub](https://github.com/facebook/react-native). These changes will be public from the beginning. Other changesets will come via a bridge with Facebook's internal source control. This is a necessity as it allows engineers at Facebook outside of the core team to move fast and contribute from an environment they are comfortable in.
|
||||
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.
|
||||
|
||||
## Branch Organization
|
||||
### `master` is unsafe
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
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.
|
||||
### Pull Requests
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
**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.
|
||||
|
||||
*Before* submitting a pull request, please make sure the following is done…
|
||||
|
||||
1. Fork the repo and create your branch from `master`.
|
||||
2. Add the copyright notice to the top of any new files you've added.
|
||||
3. Describe your **test plan** in your commit.
|
||||
4. Ensure **tests pass** on Travis and Circle CI.
|
||||
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.
|
||||
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):
|
||||
@@ -140,15 +60,30 @@ 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
|
||||
[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)
|
||||
|
||||
## Style Guide
|
||||
|
||||
Our linter will catch most styling issues that may exist in your code. You can check the status of your code styling by simply running `node linter.js <files touched>`.
|
||||
|
||||
However, there are still some styles that the linter cannot pick up.
|
||||
|
||||
### Code Conventions
|
||||
### Code
|
||||
|
||||
#### General
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ 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,6 +1,6 @@
|
||||
FROM library/node:6.9.2
|
||||
|
||||
ENV YARN_VERSION=0.27.5
|
||||
ENV YARN_VERSION=0.19.1
|
||||
|
||||
# install dependencies
|
||||
RUN apt-get update && apt-get install ocaml libelf-dev -y
|
||||
|
||||
@@ -17,6 +17,7 @@ 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
|
||||
@@ -230,13 +231,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 bundle --max-workers 1 --platform android --dev true --entry-file index.android.js --bundle-output android-bundle.js
|
||||
REACT_NATIVE_MAX_WORKERS=1 react-native bundle --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 bundle --max-workers 1 --platform ios --dev true --entry-file index.ios.js --bundle-output ios-bundle.js
|
||||
REACT_NATIVE_MAX_WORKERS=1 react-native bundle --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
|
||||
|
||||
@@ -1,52 +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.
|
||||
*
|
||||
* @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;
|
||||
@@ -35,7 +35,6 @@ var TESTS = [
|
||||
require('./PromiseTest'),
|
||||
require('./SyncMethodTest'),
|
||||
require('./WebSocketTest'),
|
||||
require('./AccessibilityManagerTest'),
|
||||
];
|
||||
|
||||
TESTS.forEach(
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
'use strict';
|
||||
|
||||
var React = require('react');
|
||||
var createReactClass = require('create-react-class');
|
||||
var ReactNative = require('react-native');
|
||||
var {
|
||||
Image,
|
||||
@@ -25,7 +24,7 @@ var { TestModule } = ReactNative.NativeModules;
|
||||
|
||||
var deepDiffer = require('deepDiffer');
|
||||
|
||||
function debug(...args) {
|
||||
function debug() {
|
||||
// console.log.apply(null, arguments);
|
||||
}
|
||||
|
||||
@@ -59,8 +58,7 @@ type State = {
|
||||
containerStyle?: Style,
|
||||
};
|
||||
|
||||
var LayoutEventsTest = createReactClass({
|
||||
displayName: 'LayoutEventsTest',
|
||||
var LayoutEventsTest = React.createClass({
|
||||
getInitialState(): State {
|
||||
return {
|
||||
didAnimation: false,
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
'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');
|
||||
@@ -25,8 +24,7 @@ var reactViewHeight = 102;
|
||||
var newReactViewWidth = 201;
|
||||
var newReactViewHeight = 202;
|
||||
|
||||
var ReactContentSizeUpdateTest = createReactClass({
|
||||
displayName: 'ReactContentSizeUpdateTest',
|
||||
var ReactContentSizeUpdateTest = React.createClass({
|
||||
mixins: [Subscribable.Mixin,
|
||||
TimerMixin],
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
'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');
|
||||
@@ -23,8 +22,7 @@ var reactViewHeight = 222;
|
||||
|
||||
var finalState = false;
|
||||
|
||||
var SizeFlexibilityUpdateTest = createReactClass({
|
||||
displayName: 'SizeFlexibilityUpdateTest',
|
||||
var SizeFlexibilityUpdateTest = React.createClass({
|
||||
mixins: [Subscribable.Mixin],
|
||||
|
||||
componentWillMount: function() {
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
'use strict';
|
||||
|
||||
var React = require('react');
|
||||
var createReactClass = require('create-react-class');
|
||||
var ReactNative = require('react-native');
|
||||
var TimerMixin = require('react-timer-mixin');
|
||||
|
||||
@@ -23,8 +22,7 @@ var {
|
||||
} = ReactNative;
|
||||
var { TestModule } = ReactNative.NativeModules;
|
||||
|
||||
var TimersTest = createReactClass({
|
||||
displayName: 'TimersTest',
|
||||
var TimersTest = React.createClass({
|
||||
mixins: [TimerMixin],
|
||||
|
||||
_nextTest: () => {},
|
||||
|
||||
@@ -392,7 +392,7 @@ class Shape extends React.Component {
|
||||
render() {
|
||||
var props = this.props;
|
||||
var path = props.d || childrenAsString(props.children);
|
||||
var d = (path instanceof Path ? path : new Path(path)).toJSON();
|
||||
var d = new Path(path).toJSON();
|
||||
return (
|
||||
<NativeShape
|
||||
fill={extractBrush(props.fill, props)}
|
||||
@@ -457,12 +457,11 @@ function extractFont(font) {
|
||||
}
|
||||
var fontFamily = extractSingleFontFamily(font.fontFamily);
|
||||
var fontSize = +font.fontSize || 12;
|
||||
var fontWeight = font.fontWeight != null ? font.fontWeight.toString() : '400';
|
||||
return {
|
||||
// Normalize
|
||||
fontFamily: fontFamily,
|
||||
fontSize: fontSize,
|
||||
fontWeight: fontWeight,
|
||||
fontWeight: font.fontWeight,
|
||||
fontStyle: font.fontStyle,
|
||||
};
|
||||
}
|
||||
@@ -486,8 +485,7 @@ function extractAlignment(alignment) {
|
||||
class Text extends React.Component {
|
||||
render() {
|
||||
var props = this.props;
|
||||
var path = props.path;
|
||||
var textPath = path ? (path instanceof Path ? path : new Path(path)).toJSON() : null;
|
||||
var textPath = props.path ? new Path(props.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() {
|
||||
this._a.__makeNative();
|
||||
super.__makeNative();
|
||||
this._a.__makeNative();
|
||||
}
|
||||
|
||||
__getValue(): number {
|
||||
@@ -1356,8 +1356,8 @@ class AnimatedDiffClamp extends AnimatedWithChildren {
|
||||
}
|
||||
|
||||
__makeNative() {
|
||||
this._a.__makeNative();
|
||||
super.__makeNative();
|
||||
this._a.__makeNative();
|
||||
}
|
||||
|
||||
interpolate(config: InterpolationConfigType): AnimatedInterpolation {
|
||||
@@ -1839,16 +1839,10 @@ function createAnimatedComponent(Component: any): any {
|
||||
}
|
||||
|
||||
render() {
|
||||
const props = this._propsAnimated.__getValue();
|
||||
return (
|
||||
<Component
|
||||
{...props}
|
||||
{...this._propsAnimated.__getValue()}
|
||||
ref={this._setComponentRef}
|
||||
// The native driver updates views directly through the UI thread so we
|
||||
// have to make sure the view doesn't get optimized away because it cannot
|
||||
// go through the NativeViewHierachyManager since it operates on the shadow
|
||||
// thread.
|
||||
collapsable={this._propsAnimated.__isNative ? false : props.collapsable}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -2744,13 +2738,10 @@ module.exports = {
|
||||
* [Origami](https://facebook.github.io/origami/). Tracks velocity state to
|
||||
* create fluid motions as the `toValue` updates, and can be chained together.
|
||||
*
|
||||
* Config is an object that may have the following options. Note that you can
|
||||
* only define bounciness/speed or tension/friction but not both:
|
||||
* Config is an object that may have the following options:
|
||||
*
|
||||
* - `friction`: Controls "bounciness"/overshoot. Default 7.
|
||||
* - `tension`: Controls speed. Default 40.
|
||||
* - `speed`: Controls speed of the animation. Default 12.
|
||||
* - `bounciness`: Controls bounciness. Default 8.
|
||||
* - `useNativeDriver`: Uses the native driver when true. Default false.
|
||||
*/
|
||||
spring,
|
||||
@@ -2825,9 +2816,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,6 +8,8 @@
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
jest.disableAutomock();
|
||||
|
||||
var Animated = require('Animated');
|
||||
describe('Animated tests', () => {
|
||||
beforeEach(() => {
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
'use strict';
|
||||
|
||||
jest
|
||||
.disableAutomock()
|
||||
.setMock('Text', {})
|
||||
.setMock('View', {})
|
||||
.setMock('Image', {})
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
jest.unmock('Easing');
|
||||
|
||||
var Easing = require('Easing');
|
||||
describe('Easing', () => {
|
||||
it('should work with linear', () => {
|
||||
|
||||
@@ -8,6 +8,11 @@
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
jest
|
||||
.unmock('Interpolation')
|
||||
.unmock('Easing')
|
||||
.unmock('normalizeColor');
|
||||
|
||||
var Interpolation = require('Interpolation');
|
||||
var Easing = require('Easing');
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
jest.unmock('bezier');
|
||||
var bezier = require('bezier');
|
||||
|
||||
var identity = function (x) { return x; };
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
const MissingNativeEventEmitterShim = require('MissingNativeEventEmitterShim');
|
||||
const EventEmitter = require('EventEmitter');
|
||||
const NativeEventEmitter = require('NativeEventEmitter');
|
||||
const NativeModules = require('NativeModules');
|
||||
const RCTAppState = NativeModules.AppState;
|
||||
@@ -32,8 +32,8 @@ const invariant = require('fbjs/lib/invariant');
|
||||
* - `background` - The app is running in the background. The user is either
|
||||
* in another app or on the home screen
|
||||
* - `inactive` - This is a state that occurs when transitioning between
|
||||
* foreground & background, and during periods of inactivity such as
|
||||
* entering the Multitasking view or in the event of an incoming call
|
||||
* foreground & background, and during periods of inactivity such as
|
||||
* entering the Multitasking view or in the event of an incoming call
|
||||
*
|
||||
* For more information, see
|
||||
* [Apple's documentation](https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/TheAppLifeCycle/TheAppLifeCycle.html)
|
||||
@@ -87,7 +87,7 @@ class AppState extends NativeEventEmitter {
|
||||
|
||||
_eventHandlers: Object;
|
||||
currentState: ?string;
|
||||
isAvailable: boolean = true;
|
||||
isAvailable: boolean;
|
||||
|
||||
constructor() {
|
||||
super(RCTAppState);
|
||||
@@ -176,31 +176,48 @@ class AppState extends NativeEventEmitter {
|
||||
}
|
||||
}
|
||||
|
||||
if (__DEV__ && !RCTAppState) {
|
||||
class MissingNativeAppStateShim extends MissingNativeEventEmitterShim {
|
||||
constructor() {
|
||||
super('RCTAppState', 'AppState');
|
||||
}
|
||||
function throwMissingNativeModule() {
|
||||
invariant(
|
||||
false,
|
||||
'Cannot use AppState module when native RCTAppState is not included in the build.\n' +
|
||||
'Either include it, or check AppState.isAvailable before calling any methods.'
|
||||
);
|
||||
}
|
||||
|
||||
get currentState(): ?string {
|
||||
this.throwMissingNativeModule();
|
||||
}
|
||||
class MissingNativeAppStateShim extends EventEmitter {
|
||||
// AppState
|
||||
isAvailable: boolean = false;
|
||||
currentState: ?string = null;
|
||||
|
||||
addEventListener(...args: Array<any>) {
|
||||
this.throwMissingNativeModule();
|
||||
}
|
||||
|
||||
removeEventListener(...args: Array<any>) {
|
||||
this.throwMissingNativeModule();
|
||||
}
|
||||
addEventListener() {
|
||||
throwMissingNativeModule();
|
||||
}
|
||||
|
||||
// This module depends on the native `RCTAppState` module. If you don't include it,
|
||||
// `AppState.isAvailable` will return `false`, and any method calls will throw.
|
||||
// We reassign the class variable to keep the autodoc generator happy.
|
||||
AppState = new MissingNativeAppStateShim();
|
||||
} else {
|
||||
removeEventListener() {
|
||||
throwMissingNativeModule();
|
||||
}
|
||||
|
||||
// EventEmitter
|
||||
addListener() {
|
||||
throwMissingNativeModule();
|
||||
}
|
||||
|
||||
removeAllListeners() {
|
||||
throwMissingNativeModule();
|
||||
}
|
||||
|
||||
removeSubscription() {
|
||||
throwMissingNativeModule();
|
||||
}
|
||||
}
|
||||
|
||||
// This module depends on the native `RCTAppState` module. If you don't include it,
|
||||
// `AppState.isAvailable` will return `false`, and any method calls will throw.
|
||||
// We reassign the class variable to keep the autodoc generator happy.
|
||||
if (RCTAppState) {
|
||||
AppState = new AppState();
|
||||
} else {
|
||||
AppState = new MissingNativeAppStateShim();
|
||||
}
|
||||
|
||||
module.exports = AppState;
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
'use strict';
|
||||
|
||||
const ErrorUtils = require('ErrorUtils');
|
||||
const JSTimersExecution = require('JSTimersExecution');
|
||||
const Systrace = require('Systrace');
|
||||
|
||||
const deepFreezeAndThrowOnMutationInDev = require('deepFreezeAndThrowOnMutationInDev');
|
||||
@@ -40,11 +41,8 @@ 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};
|
||||
_callableModules: {[key: string]: Object};
|
||||
_queue: [Array<number>, Array<number>, Array<any>, number];
|
||||
_successCallbacks: Array<?Function>;
|
||||
_failureCallbacks: Array<?Function>;
|
||||
@@ -60,7 +58,7 @@ class MessageQueue {
|
||||
__spy: ?(data: SpyData) => void;
|
||||
|
||||
constructor() {
|
||||
this._lazyCallableModules = {};
|
||||
this._callableModules = {};
|
||||
this._queue = [[], [], [], 0];
|
||||
this._successCallbacks = [];
|
||||
this._failureCallbacks = [];
|
||||
@@ -101,6 +99,7 @@ class MessageQueue {
|
||||
callFunctionReturnFlushedQueue(module: string, method: string, args: Array<any>) {
|
||||
this.__guard(() => {
|
||||
this.__callFunction(module, method, args);
|
||||
this.__callImmediates();
|
||||
});
|
||||
|
||||
return this.flushedQueue();
|
||||
@@ -110,6 +109,7 @@ class MessageQueue {
|
||||
let result;
|
||||
this.__guard(() => {
|
||||
result = this.__callFunction(module, method, args);
|
||||
this.__callImmediates();
|
||||
});
|
||||
|
||||
return [result, this.flushedQueue()];
|
||||
@@ -118,15 +118,14 @@ class MessageQueue {
|
||||
invokeCallbackAndReturnFlushedQueue(cbID: number, args: Array<any>) {
|
||||
this.__guard(() => {
|
||||
this.__invokeCallback(cbID, args);
|
||||
this.__callImmediates();
|
||||
});
|
||||
|
||||
return this.flushedQueue();
|
||||
}
|
||||
|
||||
flushedQueue() {
|
||||
this.__guard(() => {
|
||||
this.__callImmediates();
|
||||
});
|
||||
this.__callImmediates();
|
||||
|
||||
const queue = this._queue;
|
||||
this._queue = [[], [], [], this._callID];
|
||||
@@ -138,24 +137,7 @@ class MessageQueue {
|
||||
}
|
||||
|
||||
registerCallableModule(name: string, module: Object) {
|
||||
this._lazyCallableModules[name] = () => module;
|
||||
}
|
||||
|
||||
registerLazyCallableModule(name: string, factory: void => Object) {
|
||||
let module: Object;
|
||||
let getValue: ?(void => Object) = factory;
|
||||
this._lazyCallableModules[name] = () => {
|
||||
if (getValue) {
|
||||
module = getValue();
|
||||
getValue = null;
|
||||
}
|
||||
return module;
|
||||
};
|
||||
}
|
||||
|
||||
getCallableModule(name: string) {
|
||||
const getValue = this._lazyCallableModules[name];
|
||||
return getValue ? getValue() : null;
|
||||
this._callableModules[name] = module;
|
||||
}
|
||||
|
||||
enqueueNativeCall(moduleID: number, methodID: number, params: Array<any>, onFail: ?Function, onSucc: ?Function) {
|
||||
@@ -237,11 +219,8 @@ class MessageQueue {
|
||||
}
|
||||
|
||||
__callImmediates() {
|
||||
Systrace.beginEvent('JSTimers.callImmediates()');
|
||||
if (!JSTimers) {
|
||||
JSTimers = require('JSTimers');
|
||||
}
|
||||
JSTimers.callImmediates();
|
||||
Systrace.beginEvent('JSTimersExecution.callImmediates()');
|
||||
this.__guard(() => JSTimersExecution.callImmediates());
|
||||
Systrace.endEvent();
|
||||
}
|
||||
|
||||
@@ -252,7 +231,7 @@ class MessageQueue {
|
||||
if (this.__spy) {
|
||||
this.__spy({ type: TO_JS, module, method, args});
|
||||
}
|
||||
const moduleMethods = this.getCallableModule(module);
|
||||
const moduleMethods = this._callableModules[module];
|
||||
invariant(
|
||||
!!moduleMethods,
|
||||
'Module %s is not a registered callable module (calling %s)',
|
||||
|
||||
@@ -15,8 +15,6 @@ const BatchedBridge = require('BatchedBridge');
|
||||
|
||||
const invariant = require('fbjs/lib/invariant');
|
||||
|
||||
import type {ExtendedError} from 'parseErrorStack';
|
||||
|
||||
type ModuleConfig = [
|
||||
string, /* name */
|
||||
?Object, /* constants */
|
||||
@@ -82,12 +80,6 @@ function genMethod(moduleID: number, methodID: number, type: MethodType) {
|
||||
};
|
||||
} else if (type === 'sync') {
|
||||
fn = function(...args: Array<any>) {
|
||||
if (__DEV__) {
|
||||
invariant(global.nativeCallSyncHook, 'Calling synchronous methods on native ' +
|
||||
'modules is not supported in Chrome.\n\n Consider providing alternative ' +
|
||||
'methods to expose this method in debug mode, e.g. by exposing constants ' +
|
||||
'ahead-of-time.');
|
||||
}
|
||||
return global.nativeCallSyncHook(moduleID, methodID, args);
|
||||
};
|
||||
} else {
|
||||
@@ -115,13 +107,13 @@ function arrayContains<T>(array: Array<T>, value: T): boolean {
|
||||
return array.indexOf(value) !== -1;
|
||||
}
|
||||
|
||||
function createErrorFromErrorData(errorData: {message: string}): ExtendedError {
|
||||
function createErrorFromErrorData(errorData: {message: string}): Error {
|
||||
const {
|
||||
message,
|
||||
...extraErrorInfo
|
||||
} = errorData || {};
|
||||
const error : ExtendedError = new Error(message);
|
||||
error.framesToPop = 1;
|
||||
} = errorData;
|
||||
const error = new Error(message);
|
||||
(error:any).framesToPop = 1;
|
||||
return Object.assign(error, extraErrorInfo);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,10 @@
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
// const MessageQueueTestConfig = require('MessageQueueTestConfig');
|
||||
jest.unmock('MessageQueue');
|
||||
jest.unmock('defineLazyObjectProperty');
|
||||
|
||||
let MessageQueue;
|
||||
let MessageQueueTestModule;
|
||||
let queue;
|
||||
@@ -80,34 +84,4 @@ 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,12 +9,10 @@
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
jest
|
||||
.enableAutomock()
|
||||
.unmock('BatchedBridge')
|
||||
.unmock('defineLazyObjectProperty')
|
||||
.unmock('MessageQueue')
|
||||
.unmock('NativeModules');
|
||||
jest.unmock('BatchedBridge');
|
||||
jest.unmock('defineLazyObjectProperty');
|
||||
jest.unmock('MessageQueue');
|
||||
jest.unmock('NativeModules');
|
||||
|
||||
let BatchedBridge;
|
||||
let NativeModules;
|
||||
|
||||
@@ -12,8 +12,7 @@
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
const PropTypes = require('prop-types');
|
||||
const {checkPropTypes} = PropTypes;
|
||||
const {PropTypes, checkPropTypes} = require('React');
|
||||
const RCTCameraRollManager = require('NativeModules').CameraRollManager;
|
||||
|
||||
const createStrictShapeTypeChecker = require('createStrictShapeTypeChecker');
|
||||
@@ -122,12 +121,9 @@ class CameraRoll {
|
||||
static GroupTypesOptions: Object = GROUP_TYPES_OPTIONS;
|
||||
static AssetTypeOptions: Object = ASSET_TYPE_OPTIONS;
|
||||
|
||||
/**
|
||||
* `CameraRoll.saveImageWithTag()` is deprecated. Use `CameraRoll.saveToCameraRoll()` instead.
|
||||
*/
|
||||
static saveImageWithTag(tag: string): Promise<Object> {
|
||||
console.warn(
|
||||
'`CameraRoll.saveImageWithTag()` is deprecated. Use `CameraRoll.saveToCameraRoll()` instead.',
|
||||
'CameraRoll.saveImageWithTag is deprecated. Use CameraRoll.saveToCameraRoll instead',
|
||||
);
|
||||
return this.saveToCameraRoll(tag, 'photo');
|
||||
}
|
||||
|
||||
@@ -18,11 +18,9 @@ var RCTDeviceEventEmitter = require('RCTDeviceEventEmitter');
|
||||
var AccessibilityManager = NativeModules.AccessibilityManager;
|
||||
|
||||
var VOICE_OVER_EVENT = 'voiceOverDidChange';
|
||||
var ANNOUNCEMENT_DID_FINISH_EVENT = 'announcementDidFinish';
|
||||
|
||||
type ChangeEventName = $Enum<{
|
||||
change: string,
|
||||
announcementFinished: string
|
||||
}>;
|
||||
|
||||
var _subscriptions = new Map();
|
||||
@@ -99,54 +97,21 @@ var AccessibilityInfo = {
|
||||
* - `change`: Fires when the state of the screen reader changes. The argument
|
||||
* to the event handler is a boolean. The boolean is `true` when a screen
|
||||
* reader is enabled and `false` otherwise.
|
||||
* - `announcementFinished`: iOS-only event. Fires when the screen reader has
|
||||
* finished making an announcement. The argument to the event handler is a dictionary
|
||||
* with these keys:
|
||||
* - `announcement`: The string announced by the screen reader.
|
||||
* - `success`: A boolean indicating whether the announcement was successfully made.
|
||||
*/
|
||||
addEventListener: function (
|
||||
eventName: ChangeEventName,
|
||||
handler: Function
|
||||
): Object {
|
||||
var listener;
|
||||
|
||||
if (eventName === 'change') {
|
||||
listener = RCTDeviceEventEmitter.addListener(
|
||||
VOICE_OVER_EVENT,
|
||||
handler
|
||||
);
|
||||
} else if (eventName === 'announcementFinished') {
|
||||
listener = RCTDeviceEventEmitter.addListener(
|
||||
ANNOUNCEMENT_DID_FINISH_EVENT,
|
||||
handler
|
||||
);
|
||||
}
|
||||
|
||||
var listener = RCTDeviceEventEmitter.addListener(
|
||||
VOICE_OVER_EVENT,
|
||||
handler
|
||||
);
|
||||
_subscriptions.set(handler, listener);
|
||||
return {
|
||||
remove: AccessibilityInfo.removeEventListener.bind(null, eventName, handler),
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* iOS-Only. Set accessibility focus to a react component.
|
||||
*/
|
||||
setAccessibilityFocus: function(
|
||||
reactTag: number
|
||||
): void {
|
||||
AccessibilityManager.setAccessibilityFocus(reactTag);
|
||||
},
|
||||
|
||||
/**
|
||||
* iOS-Only. Post a string to be announced by the screen reader.
|
||||
*/
|
||||
announceForAccessibility: function(
|
||||
announcement: string
|
||||
): void {
|
||||
AccessibilityManager.announceForAccessibility(announcement);
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove an event handler.
|
||||
*/
|
||||
|
||||
@@ -20,7 +20,6 @@ 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';
|
||||
@@ -37,8 +36,7 @@ type DefaultProps = {
|
||||
/**
|
||||
* Displays a circular loading indicator.
|
||||
*/
|
||||
const ActivityIndicator = createReactClass({
|
||||
displayName: 'ActivityIndicator',
|
||||
const ActivityIndicator = React.createClass({
|
||||
mixins: [NativeMethodsMixin],
|
||||
|
||||
propTypes: {
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
var PropTypes = require('prop-types');
|
||||
var PropTypes = require('React').PropTypes;
|
||||
|
||||
/**
|
||||
* Additional View properties for Apple TV
|
||||
@@ -74,14 +74,4 @@ var TVViewPropTypes = {
|
||||
|
||||
};
|
||||
|
||||
export type TVViewProps = {
|
||||
isTVSelectable?: bool,
|
||||
hasTVPreferredFocus?: bool,
|
||||
tvParallaxProperties?: Object,
|
||||
tvParallaxShiftDistanceX?: number,
|
||||
tvParallaxShiftDistanceY?: number,
|
||||
tvParallaxTiltAngle?: number,
|
||||
tvParallaxMagnification?: number,
|
||||
};
|
||||
|
||||
module.exports = TVViewPropTypes;
|
||||
|
||||
@@ -97,25 +97,25 @@ class Button extends React.Component {
|
||||
} = this.props;
|
||||
const buttonStyles = [styles.button];
|
||||
const textStyles = [styles.text];
|
||||
if (color) {
|
||||
if (Platform.OS === 'ios') {
|
||||
textStyles.push({color: color});
|
||||
} else {
|
||||
buttonStyles.push({backgroundColor: color});
|
||||
}
|
||||
const Touchable = Platform.OS === 'android' ? TouchableNativeFeedback : TouchableOpacity;
|
||||
if (color && Platform.OS === 'ios') {
|
||||
textStyles.push({color: color});
|
||||
} else if (color) {
|
||||
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 Touchable = Platform.OS === 'android' ? TouchableNativeFeedback : TouchableOpacity;
|
||||
const accessibilityTraits = ['button'];
|
||||
if (disabled) {
|
||||
accessibilityTraits.push('disabled');
|
||||
}
|
||||
return (
|
||||
<Touchable
|
||||
accessibilityComponentType="button"
|
||||
@@ -132,27 +132,32 @@ 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,
|
||||
// Material design blue from https://material.google.com/style/color.html#color-color-palette
|
||||
backgroundColor: '#2196F3',
|
||||
backgroundColor: defaultBlue,
|
||||
borderRadius: 2,
|
||||
},
|
||||
}),
|
||||
text: Platform.select({
|
||||
ios: {
|
||||
// iOS blue from https://developer.apple.com/ios/human-interface-guidelines/visual-design/color/
|
||||
color: '#007AFF',
|
||||
color: defaultBlue,
|
||||
textAlign: 'center',
|
||||
padding: 8,
|
||||
fontSize: 18,
|
||||
},
|
||||
android: {
|
||||
color: 'white',
|
||||
textAlign: 'center',
|
||||
color: 'white',
|
||||
padding: 8,
|
||||
fontWeight: '500',
|
||||
},
|
||||
|
||||
@@ -20,7 +20,6 @@ const StyleSheet = require('StyleSheet');
|
||||
const View = require('View');
|
||||
const ViewPropTypes = require('ViewPropTypes');
|
||||
|
||||
const createReactClass = require('create-react-class');
|
||||
const requireNativeComponent = require('requireNativeComponent');
|
||||
|
||||
type DefaultProps = {
|
||||
@@ -37,8 +36,7 @@ type Event = Object;
|
||||
* source of truth.
|
||||
*/
|
||||
// $FlowFixMe(>=0.41.0)
|
||||
const DatePickerIOS = createReactClass({
|
||||
displayName: 'DatePickerIOS',
|
||||
const DatePickerIOS = React.createClass({
|
||||
// TOOD: Put a better type for _picker
|
||||
_picker: (undefined: ?$FlowFixMe),
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@ var ViewPropTypes = require('ViewPropTypes');
|
||||
|
||||
var DrawerConsts = UIManager.AndroidDrawerLayout.Constants;
|
||||
|
||||
var createReactClass = require('create-react-class');
|
||||
var dismissKeyboard = require('dismissKeyboard');
|
||||
var requireNativeComponent = require('requireNativeComponent');
|
||||
|
||||
@@ -68,8 +67,7 @@ var DRAWER_STATES = [
|
||||
* },
|
||||
* ```
|
||||
*/
|
||||
var DrawerLayoutAndroid = createReactClass({
|
||||
displayName: 'DrawerLayoutAndroid',
|
||||
var DrawerLayoutAndroid = React.createClass({
|
||||
statics: {
|
||||
positions: DrawerConsts.DrawerPosition,
|
||||
},
|
||||
|
||||
@@ -100,9 +100,7 @@ let Keyboard = {
|
||||
* - `keyboardDidChangeFrame`
|
||||
*
|
||||
* Note that if you set `android:windowSoftInputMode` to `adjustResize` or `adjustNothing`,
|
||||
* 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.
|
||||
* only `keyboardDidShow` and `keyboardDidHide` events will available on Android.
|
||||
*
|
||||
* @param {function} callback function to be called when the event fires.
|
||||
*/
|
||||
|
||||
@@ -11,19 +11,23 @@
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
const createReactClass = require('create-react-class');
|
||||
const Keyboard = require('Keyboard');
|
||||
const LayoutAnimation = require('LayoutAnimation');
|
||||
const Platform = require('Platform');
|
||||
const PropTypes = require('prop-types');
|
||||
const React = require('React');
|
||||
const PropTypes = require('prop-types');
|
||||
const TimerMixin = require('react-timer-mixin');
|
||||
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,
|
||||
@@ -36,6 +40,11 @@ type KeyboardChangeEvent = {
|
||||
duration?: number,
|
||||
easing?: string,
|
||||
};
|
||||
type LayoutEvent = {
|
||||
nativeEvent: {
|
||||
layout: Rect,
|
||||
}
|
||||
};
|
||||
|
||||
const viewRef = 'VIEW';
|
||||
|
||||
@@ -44,8 +53,7 @@ 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 = createReactClass({
|
||||
displayName: 'KeyboardAvoidingView',
|
||||
const KeyboardAvoidingView = React.createClass({
|
||||
mixins: [TimerMixin],
|
||||
|
||||
propTypes: {
|
||||
@@ -77,7 +85,7 @@ const KeyboardAvoidingView = createReactClass({
|
||||
},
|
||||
|
||||
subscriptions: ([]: Array<EmitterSubscription>),
|
||||
frame: (null: ?ViewLayout),
|
||||
frame: (null: ?Rect),
|
||||
|
||||
relativeKeyboardHeight(keyboardFrame: ScreenRect): number {
|
||||
const frame = this.frame;
|
||||
@@ -85,11 +93,12 @@ const KeyboardAvoidingView = createReactClass({
|
||||
return 0;
|
||||
}
|
||||
|
||||
const keyboardY = keyboardFrame.screenY - this.props.keyboardVerticalOffset;
|
||||
|
||||
// Calculate the displacement needed for the view such that it
|
||||
// no longer overlaps with the keyboard
|
||||
return Math.max(frame.y + frame.height - keyboardY, 0);
|
||||
const y1 = Math.max(frame.y, keyboardFrame.screenY - this.props.keyboardVerticalOffset);
|
||||
const y2 = Math.min(frame.y + frame.height, keyboardFrame.screenY + keyboardFrame.height - this.props.keyboardVerticalOffset);
|
||||
if (frame.y > keyboardFrame.screenY) {
|
||||
return frame.y + frame.height - keyboardFrame.screenY - this.props.keyboardVerticalOffset;
|
||||
}
|
||||
return Math.max(y2 - y1, 0);
|
||||
},
|
||||
|
||||
onKeyboardChange(event: ?KeyboardChangeEvent) {
|
||||
@@ -113,7 +122,7 @@ const KeyboardAvoidingView = createReactClass({
|
||||
this.setState({bottom: height});
|
||||
},
|
||||
|
||||
onLayout(event: ViewLayoutEvent) {
|
||||
onLayout(event: LayoutEvent) {
|
||||
this.frame = event.nativeEvent.layout;
|
||||
},
|
||||
|
||||
|
||||
@@ -11,12 +11,10 @@
|
||||
'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 = createReactClass({
|
||||
displayName: 'LazyRenderer',
|
||||
var LazyRenderer = React.createClass({
|
||||
mixin: [TimerMixin],
|
||||
|
||||
propTypes: {
|
||||
|
||||
@@ -1,110 +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 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,7 +23,6 @@ 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');
|
||||
@@ -305,8 +304,7 @@ type Event = Object;
|
||||
* is pushed.
|
||||
*
|
||||
*/
|
||||
var NavigatorIOS = createReactClass({
|
||||
displayName: 'NavigatorIOS',
|
||||
var NavigatorIOS = React.createClass({
|
||||
|
||||
propTypes: {
|
||||
|
||||
@@ -436,7 +434,7 @@ var NavigatorIOS = createReactClass({
|
||||
titleTextColor: PropTypes.string,
|
||||
|
||||
/**
|
||||
* Boolean value that indicates whether the navigation bar is
|
||||
* Bboolean value that indicates whether the navigation bar is
|
||||
* translucent.
|
||||
*/
|
||||
translucent: PropTypes.bool,
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
|
||||
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');
|
||||
@@ -23,6 +22,8 @@ var ViewStylePropTypes = require('ViewStylePropTypes');
|
||||
var processColor = require('processColor');
|
||||
var requireNativeComponent = require('requireNativeComponent');
|
||||
|
||||
var ReactPropTypes = React.PropTypes;
|
||||
|
||||
var REF_PICKER = 'picker';
|
||||
var MODE_DROPDOWN = 'dropdown';
|
||||
|
||||
@@ -52,7 +53,7 @@ class PickerAndroid extends React.Component {
|
||||
static propTypes = {
|
||||
...ViewPropTypes,
|
||||
style: pickerStyleType,
|
||||
selectedValue: ReactPropTypes.any,
|
||||
selectedValue: React.PropTypes.any,
|
||||
enabled: ReactPropTypes.bool,
|
||||
mode: ReactPropTypes.oneOf(['dialog', 'dropdown']),
|
||||
onValueChange: ReactPropTypes.func,
|
||||
|
||||
@@ -22,12 +22,10 @@ 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 = createReactClass({
|
||||
displayName: 'PickerIOS',
|
||||
var PickerIOS = React.createClass({
|
||||
mixins: [NativeMethodsMixin],
|
||||
|
||||
propTypes: {
|
||||
|
||||
@@ -16,7 +16,6 @@ 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 = [
|
||||
@@ -29,7 +28,7 @@ var STYLE_ATTRIBUTES = [
|
||||
'LargeInverse',
|
||||
];
|
||||
|
||||
var indeterminateType = function(props, propName, componentName, ...rest) {
|
||||
var indeterminateType = function(props, propName, componentName) {
|
||||
var checker = function() {
|
||||
var indeterminate = props[propName];
|
||||
var styleAttr = props.styleAttr;
|
||||
@@ -38,7 +37,7 @@ var indeterminateType = function(props, propName, componentName, ...rest) {
|
||||
}
|
||||
};
|
||||
|
||||
return PropTypes.bool(props, propName, componentName, ...rest) || checker();
|
||||
return PropTypes.bool(props, propName, componentName) || checker();
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -64,8 +63,7 @@ var indeterminateType = function(props, propName, componentName, ...rest) {
|
||||
* },
|
||||
* ```
|
||||
*/
|
||||
var ProgressBarAndroid = createReactClass({
|
||||
displayName: 'ProgressBarAndroid',
|
||||
var ProgressBarAndroid = React.createClass({
|
||||
propTypes: {
|
||||
...ViewPropTypes,
|
||||
/**
|
||||
|
||||
@@ -18,15 +18,13 @@ 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 = createReactClass({
|
||||
displayName: 'ProgressViewIOS',
|
||||
var ProgressViewIOS = React.createClass({
|
||||
mixins: [NativeMethodsMixin],
|
||||
|
||||
propTypes: {
|
||||
|
||||
@@ -18,7 +18,6 @@ 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') {
|
||||
@@ -73,8 +72,7 @@ if (Platform.OS === 'android') {
|
||||
* in the `onRefresh` function otherwise the refresh indicator will stop immediately.
|
||||
*/
|
||||
// $FlowFixMe(>=0.41.0)
|
||||
const RefreshControl = createReactClass({
|
||||
displayName: 'RefreshControl',
|
||||
const RefreshControl = React.createClass({
|
||||
statics: {
|
||||
SIZE: RefreshLayoutConsts.SIZE,
|
||||
},
|
||||
|
||||
@@ -465,16 +465,6 @@ var ScrollResponderMixin = {
|
||||
ScrollViewManager.zoomToRect(this.scrollResponderGetScrollableNode(), rect, animated !== false);
|
||||
},
|
||||
|
||||
/**
|
||||
* Displays the scroll indicators momentarily.
|
||||
*
|
||||
* @platform ios
|
||||
*/
|
||||
scrollResponderFlashScrollIndicators: function() {
|
||||
invariant(ScrollViewManager && ScrollViewManager.flashScrollIndicators, 'flashScrollIndicators is not implemented');
|
||||
ScrollViewManager.flashScrollIndicators(this.scrollResponderGetScrollableNode());
|
||||
},
|
||||
|
||||
/**
|
||||
* This method should be used as the callback to onFocus in a TextInputs'
|
||||
* parent view. Note that any module using this mixin needs to return
|
||||
|
||||
@@ -27,15 +27,11 @@ 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
|
||||
@@ -73,8 +69,7 @@ import type {NativeMethodsMixinType} from 'ReactNativeTypes';
|
||||
* supports out of the box.
|
||||
*/
|
||||
// $FlowFixMe(>=0.41.0)
|
||||
const ScrollView = createReactClass({
|
||||
displayName: 'ScrollView',
|
||||
const ScrollView = React.createClass({
|
||||
propTypes: {
|
||||
...ViewPropTypes,
|
||||
/**
|
||||
@@ -137,18 +132,16 @@ const ScrollView = createReactClass({
|
||||
* These styles will be applied to the scroll view content container which
|
||||
* wraps all of the child views. Example:
|
||||
*
|
||||
* ```
|
||||
* return (
|
||||
* <ScrollView contentContainerStyle={styles.contentContainer}>
|
||||
* </ScrollView>
|
||||
* );
|
||||
* ...
|
||||
* const styles = StyleSheet.create({
|
||||
* contentContainer: {
|
||||
* paddingVertical: 20
|
||||
* }
|
||||
* });
|
||||
* ```
|
||||
* return (
|
||||
* <ScrollView contentContainerStyle={styles.contentContainer}>
|
||||
* </ScrollView>
|
||||
* );
|
||||
* ...
|
||||
* const styles = StyleSheet.create({
|
||||
* contentContainer: {
|
||||
* paddingVertical: 20
|
||||
* }
|
||||
* });
|
||||
*/
|
||||
contentContainerStyle: StyleSheetPropType(ViewStylePropTypes),
|
||||
/**
|
||||
@@ -157,10 +150,8 @@ const ScrollView = createReactClass({
|
||||
* shortcuts `"normal"` and `"fast"` which match the underlying iOS settings
|
||||
* for `UIScrollViewDecelerationRateNormal` and
|
||||
* `UIScrollViewDecelerationRateFast` respectively.
|
||||
*
|
||||
* - `'normal'`: 0.998 (the default)
|
||||
* - `'fast'`: 0.99
|
||||
*
|
||||
* - normal: 0.998 (the default)
|
||||
* - fast: 0.99
|
||||
* @platform ios
|
||||
*/
|
||||
decelerationRate: PropTypes.oneOfType([
|
||||
@@ -174,11 +165,9 @@ const ScrollView = createReactClass({
|
||||
horizontal: PropTypes.bool,
|
||||
/**
|
||||
* The style of the scroll indicators.
|
||||
*
|
||||
* - `'default'` (the default), same as `black`.
|
||||
* - `'black'`, scroll indicator is black. This style is good against a light background.
|
||||
* - `'white'`, scroll indicator is white. This style is good against a dark background.
|
||||
*
|
||||
* - `default` (the default), same as `black`.
|
||||
* - `black`, scroll indicator is black. This style is good against a light background.
|
||||
* - `white`, scroll indicator is white. This style is good against a dark background.
|
||||
* @platform ios
|
||||
*/
|
||||
indicatorStyle: PropTypes.oneOf([
|
||||
@@ -200,10 +189,9 @@ const ScrollView = createReactClass({
|
||||
canCancelContentTouches: PropTypes.bool,
|
||||
/**
|
||||
* Determines whether the keyboard gets dismissed in response to a drag.
|
||||
*
|
||||
* - `'none'` (the default), drags do not dismiss the keyboard.
|
||||
* - `'on-drag'`, the keyboard is dismissed when a drag begins.
|
||||
* - `'interactive'`, the keyboard is dismissed interactively with the drag and moves in
|
||||
* - 'none' (the default), drags do not dismiss the keyboard.
|
||||
* - 'on-drag', the keyboard is dismissed when a drag begins.
|
||||
* - 'interactive', the keyboard is dismissed interactively with the drag and moves in
|
||||
* synchrony with the touch; dragging upwards cancels the dismissal.
|
||||
* On android this is not supported and it will have the same behavior as 'none'.
|
||||
*/
|
||||
@@ -215,14 +203,14 @@ const ScrollView = createReactClass({
|
||||
/**
|
||||
* Determines when the keyboard should stay visible after a tap.
|
||||
*
|
||||
* - `'never'` (the default), tapping outside of the focused text input when the keyboard
|
||||
* - 'never' (the default), tapping outside of the focused text input when the keyboard
|
||||
* is up dismisses the keyboard. When this happens, children won't receive the tap.
|
||||
* - `'always'`, the keyboard will not dismiss automatically, and the scroll view will not
|
||||
* - 'always', the keyboard will not dismiss automatically, and the scroll view will not
|
||||
* catch taps, but children of the scroll view can catch taps.
|
||||
* - `'handled'`, the keyboard will not dismiss automatically when the tap was handled by
|
||||
* - 'handled', the keyboard will not dismiss automatically when the tap was handled by
|
||||
* a children, (or captured by an ancestor).
|
||||
* - `false`, deprecated, use 'never' instead
|
||||
* - `true`, deprecated, use 'always' instead
|
||||
* - false, deprecated, use 'never' instead
|
||||
* - true, deprecated, use 'always' instead
|
||||
*/
|
||||
keyboardShouldPersistTaps: PropTypes.oneOf(['always', 'never', 'handled', false, true]),
|
||||
/**
|
||||
@@ -259,15 +247,11 @@ const ScrollView = createReactClass({
|
||||
* 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,
|
||||
/**
|
||||
* When false, the view cannot be scrolled via touch interaction.
|
||||
* When false, the content does not scroll.
|
||||
* The default value is true.
|
||||
*
|
||||
* Note that the view can be always be scrolled by calling `scrollTo`.
|
||||
*/
|
||||
scrollEnabled: PropTypes.bool,
|
||||
/**
|
||||
@@ -318,21 +302,17 @@ const ScrollView = createReactClass({
|
||||
/**
|
||||
* When set, causes the scroll view to stop at multiples of the value of
|
||||
* `snapToInterval`. This can be used for paginating through children
|
||||
* that have lengths smaller than the scroll view. Typically used in
|
||||
* combination with `snapToAlignment` and `decelerationRate="fast"`.
|
||||
* Overrides less configurable `pagingEnabled` prop.
|
||||
*
|
||||
* that have lengths smaller than the scroll view. Used in combination
|
||||
* with `snapToAlignment`.
|
||||
* @platform ios
|
||||
*/
|
||||
snapToInterval: PropTypes.number,
|
||||
/**
|
||||
* When `snapToInterval` is set, `snapToAlignment` will define the relationship
|
||||
* of the snapping to the scroll view.
|
||||
*
|
||||
* - `'start'` (the default) will align the snap at the left (horizontal) or top (vertical)
|
||||
* - `'center'` will align the snap in the center
|
||||
* - `'end'` will align the snap at the right (horizontal) or bottom (vertical)
|
||||
*
|
||||
* - `start` (the default) will align the snap at the left (horizontal) or top (vertical)
|
||||
* - `center` will align the snap in the center
|
||||
* - `end` will align the snap at the right (horizontal) or bottom (vertical)
|
||||
* @platform ios
|
||||
*/
|
||||
snapToAlignment: PropTypes.oneOf([
|
||||
@@ -397,15 +377,6 @@ const ScrollView = createReactClass({
|
||||
'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],
|
||||
@@ -513,30 +484,24 @@ const ScrollView = createReactClass({
|
||||
this.scrollTo({x, y, animated: false});
|
||||
},
|
||||
|
||||
/**
|
||||
* Displays the scroll indicators momentarily.
|
||||
*
|
||||
* @platform ios
|
||||
*/
|
||||
flashScrollIndicators: function() {
|
||||
this.getScrollResponder().scrollResponderFlashScrollIndicators();
|
||||
},
|
||||
|
||||
_getKeyForIndex: function(index, childArray) {
|
||||
const child = childArray[index];
|
||||
return child && child.key;
|
||||
},
|
||||
|
||||
_updateAnimatedNodeAttachment: function() {
|
||||
if (this._scrollAnimatedValueAttachment) {
|
||||
this._scrollAnimatedValueAttachment.detach();
|
||||
}
|
||||
if (this.props.stickyHeaderIndices && this.props.stickyHeaderIndices.length > 0) {
|
||||
this._scrollAnimatedValueAttachment = Animated.attachNativeEvent(
|
||||
this._scrollViewRef,
|
||||
'onScroll',
|
||||
[{nativeEvent: {contentOffset: {y: this._scrollAnimatedValue}}}]
|
||||
);
|
||||
if (!this._scrollAnimatedValueAttachment) {
|
||||
this._scrollAnimatedValueAttachment = Animated.attachNativeEvent(
|
||||
this._scrollViewRef,
|
||||
'onScroll',
|
||||
[{nativeEvent: {contentOffset: {y: this._scrollAnimatedValue}}}]
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if (this._scrollAnimatedValueAttachment) {
|
||||
this._scrollAnimatedValueAttachment.detach();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -601,8 +566,8 @@ const ScrollView = createReactClass({
|
||||
this._scrollViewRef = ref;
|
||||
},
|
||||
|
||||
_innerViewRef: (null: ?NativeMethodsMixinType),
|
||||
_setInnerViewRef: function(ref: ?NativeMethodsMixinType) {
|
||||
_innerViewRef: (null: ?View),
|
||||
_setInnerViewRef: function(ref: ?View) {
|
||||
this._innerViewRef = ref;
|
||||
},
|
||||
|
||||
@@ -612,10 +577,6 @@ const ScrollView = createReactClass({
|
||||
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;
|
||||
@@ -689,13 +650,7 @@ const ScrollView = createReactClass({
|
||||
{...contentSizeChangeProps}
|
||||
ref={this._setInnerViewRef}
|
||||
style={contentContainerStyle}
|
||||
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
|
||||
}
|
||||
removeClippedSubviews={this.props.removeClippedSubviews}
|
||||
collapsable={false}>
|
||||
{children}
|
||||
</ScrollContentContainerViewClass>;
|
||||
@@ -710,9 +665,6 @@ const ScrollView = createReactClass({
|
||||
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,
|
||||
@@ -741,7 +693,6 @@ const ScrollView = createReactClass({
|
||||
scrollEventThrottle: hasStickyHeaders ? 1 : this.props.scrollEventThrottle,
|
||||
sendMomentumEvents: (this.props.onMomentumScrollBegin || this.props.onMomentumScrollEnd) ?
|
||||
true : false,
|
||||
DEPRECATED_sendUpdatedChildFrames,
|
||||
};
|
||||
|
||||
const { decelerationRate } = this.props;
|
||||
@@ -838,7 +789,6 @@ 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);
|
||||
}
|
||||
|
||||
|
||||
@@ -61,9 +61,8 @@ class ScrollViewStickyHeader extends React.Component {
|
||||
|
||||
render() {
|
||||
const {measured, layoutHeight, layoutY, nextHeaderLayoutY} = this.state;
|
||||
const inputRange: Array<number> = [-1, 0];
|
||||
const outputRange: Array<number> = [0, 0];
|
||||
|
||||
let translateY;
|
||||
if (measured) {
|
||||
// The interpolation looks like:
|
||||
// - Negative scroll: no translation
|
||||
@@ -75,8 +74,8 @@ class ScrollViewStickyHeader extends React.Component {
|
||||
// header to continue scrolling up and make room for the next sticky header.
|
||||
// In the case that there is no next header just translate equally to
|
||||
// scroll indefinetly.
|
||||
inputRange.push(layoutY);
|
||||
outputRange.push(0);
|
||||
const inputRange = [-1, 0, layoutY];
|
||||
const outputRange: Array<number> = [0, 0, 0];
|
||||
// Sometimes headers jump around so we make sure we don't violate the monotonic inputRange
|
||||
// condition.
|
||||
const collisionPoint = (nextHeaderLayoutY || 0) - layoutHeight;
|
||||
@@ -87,12 +86,14 @@ class ScrollViewStickyHeader extends React.Component {
|
||||
inputRange.push(layoutY + 1);
|
||||
outputRange.push(1);
|
||||
}
|
||||
translateY = this.props.scrollAnimatedValue.interpolate({
|
||||
inputRange,
|
||||
outputRange,
|
||||
});
|
||||
} else {
|
||||
translateY = 0;
|
||||
}
|
||||
|
||||
const translateY = this.props.scrollAnimatedValue.interpolate({
|
||||
inputRange,
|
||||
outputRange,
|
||||
});
|
||||
const child = React.Children.only(this.props.children);
|
||||
|
||||
return (
|
||||
|
||||
@@ -17,7 +17,6 @@ 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 = {
|
||||
@@ -50,8 +49,7 @@ type Event = Object;
|
||||
* ````
|
||||
*/
|
||||
// $FlowFixMe(>=0.41.0)
|
||||
var SegmentedControlIOS = createReactClass({
|
||||
displayName: 'SegmentedControlIOS',
|
||||
var SegmentedControlIOS = React.createClass({
|
||||
mixins: [NativeMethodsMixin],
|
||||
|
||||
propTypes: {
|
||||
|
||||
@@ -21,7 +21,6 @@ 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;
|
||||
@@ -30,8 +29,7 @@ type Event = Object;
|
||||
* A component used to select a single value from a range of values.
|
||||
*/
|
||||
// $FlowFixMe(>=0.41.0)
|
||||
var Slider = createReactClass({
|
||||
displayName: 'Slider',
|
||||
var Slider = React.createClass({
|
||||
mixins: [NativeMethodsMixin],
|
||||
|
||||
propTypes: {
|
||||
|
||||
@@ -63,10 +63,7 @@ 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) {
|
||||
@@ -83,29 +80,20 @@ function mergePropsStack(
|
||||
*/
|
||||
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,
|
||||
};
|
||||
}
|
||||
@@ -153,7 +141,7 @@ class StatusBar extends React.Component {
|
||||
props: {
|
||||
hidden?: boolean,
|
||||
animated?: boolean,
|
||||
backgroundColor?: string,
|
||||
backgroundColor?: $FlowFixMe,
|
||||
translucent?: boolean,
|
||||
barStyle?: 'default' | 'light-content' | 'dark-content',
|
||||
networkActivityIndicatorVisible?: boolean,
|
||||
@@ -227,9 +215,7 @@ 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;
|
||||
@@ -290,7 +276,11 @@ 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.
|
||||
*
|
||||
@@ -303,7 +293,10 @@ class StatusBar extends React.Component {
|
||||
*
|
||||
* @platform ios
|
||||
*/
|
||||
showHideTransition: PropTypes.oneOf(['fade', 'slide']),
|
||||
showHideTransition: PropTypes.oneOf([
|
||||
'fade',
|
||||
'slide',
|
||||
]),
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
@@ -350,52 +343,38 @@ 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) {
|
||||
|
||||
@@ -19,7 +19,6 @@ 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 = {
|
||||
@@ -39,8 +38,7 @@ type DefaultProps = {
|
||||
* @keyword toggle
|
||||
*/
|
||||
// $FlowFixMe(>=0.41.0)
|
||||
var Switch = createReactClass({
|
||||
displayName: 'Switch',
|
||||
var Switch = React.createClass({
|
||||
propTypes: {
|
||||
...ViewPropTypes,
|
||||
/**
|
||||
|
||||
@@ -17,7 +17,6 @@ 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');
|
||||
@@ -169,8 +168,7 @@ const DataDetectorTypes = [
|
||||
*
|
||||
*/
|
||||
// $FlowFixMe(>=0.41.0)
|
||||
const TextInput = createReactClass({
|
||||
displayName: 'TextInput',
|
||||
const TextInput = React.createClass({
|
||||
statics: {
|
||||
/* TODO(brentvatne) docs are needed for this */
|
||||
State: TextInputState,
|
||||
@@ -630,7 +628,7 @@ const TextInput = createReactClass({
|
||||
var textContainer;
|
||||
|
||||
var props = Object.assign({}, this.props);
|
||||
props.style = [this.props.style];
|
||||
props.style = [styles.input, this.props.style];
|
||||
|
||||
if (props.selection && props.selection.end == null) {
|
||||
props.selection = {start: props.selection.start, end: props.selection.start};
|
||||
@@ -861,6 +859,9 @@ const TextInput = createReactClass({
|
||||
});
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
input: {
|
||||
alignSelf: 'stretch',
|
||||
},
|
||||
multilineInput: {
|
||||
// This default top inset makes RCTTextView seem as close as possible
|
||||
// to single-line RCTTextField defaults, using the system defaults
|
||||
|
||||
@@ -53,7 +53,7 @@ var TextInputState = {
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {number} textFieldID id of the text field to unfocus
|
||||
* @param {number} textFieldID id of the text field to focus
|
||||
* Unfocuses the specified text field
|
||||
* noop if it wasn't focused
|
||||
*/
|
||||
|
||||
@@ -20,7 +20,6 @@ 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');
|
||||
|
||||
@@ -66,8 +65,7 @@ var optionalImageSource = PropTypes.oneOfType([
|
||||
*
|
||||
* [0]: https://developer.android.com/reference/android/support/v7/widget/Toolbar.html
|
||||
*/
|
||||
var ToolbarAndroid = createReactClass({
|
||||
displayName: 'ToolbarAndroid',
|
||||
var ToolbarAndroid = React.createClass({
|
||||
mixins: [NativeMethodsMixin],
|
||||
|
||||
propTypes: {
|
||||
|
||||
@@ -15,7 +15,6 @@ 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');
|
||||
|
||||
@@ -36,8 +35,7 @@ var PRESS_RETENTION_OFFSET = {top: 20, left: 20, right: 20, bottom: 30};
|
||||
* interesting interactions such as `handleTouchablePress`.
|
||||
*/
|
||||
// $FlowFixMe(>=0.41.0)
|
||||
var TouchableBounce = createReactClass({
|
||||
displayName: 'TouchableBounce',
|
||||
var TouchableBounce = React.createClass({
|
||||
mixins: [Touchable.Mixin, NativeMethodsMixin],
|
||||
|
||||
propTypes: {
|
||||
|
||||
@@ -7,36 +7,37 @@
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* @providesModule TouchableHighlight
|
||||
* @flow
|
||||
* @noflow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
const ColorPropType = require('ColorPropType');
|
||||
const NativeMethodsMixin = require('NativeMethodsMixin');
|
||||
// Note (avik): add @flow when Flow supports spread properties in propTypes
|
||||
|
||||
var ColorPropType = require('ColorPropType');
|
||||
var NativeMethodsMixin = require('NativeMethodsMixin');
|
||||
const PropTypes = require('prop-types');
|
||||
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');
|
||||
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 ViewPropTypes = require('ViewPropTypes');
|
||||
|
||||
const createReactClass = require('create-react-class');
|
||||
const ensureComponentIsNative = require('ensureComponentIsNative');
|
||||
const ensurePositiveDelayProps = require('ensurePositiveDelayProps');
|
||||
const keyOf = require('fbjs/lib/keyOf');
|
||||
const merge = require('merge');
|
||||
var ensureComponentIsNative = require('ensureComponentIsNative');
|
||||
var ensurePositiveDelayProps = require('ensurePositiveDelayProps');
|
||||
var keyOf = require('fbjs/lib/keyOf');
|
||||
var merge = require('merge');
|
||||
|
||||
import type {Event} from 'TouchableWithoutFeedback';
|
||||
type Event = Object;
|
||||
|
||||
const DEFAULT_PROPS = {
|
||||
var DEFAULT_PROPS = {
|
||||
activeOpacity: 0.85,
|
||||
underlayColor: 'black',
|
||||
};
|
||||
|
||||
const PRESS_RETENTION_OFFSET = {top: 20, left: 20, right: 20, bottom: 30};
|
||||
var PRESS_RETENTION_OFFSET = {top: 20, left: 20, right: 20, bottom: 30};
|
||||
|
||||
/**
|
||||
* A wrapper for making views respond properly to touches.
|
||||
@@ -67,8 +68,7 @@ const PRESS_RETENTION_OFFSET = {top: 20, left: 20, right: 20, bottom: 30};
|
||||
* ```
|
||||
*/
|
||||
|
||||
var TouchableHighlight = createReactClass({
|
||||
displayName: 'TouchableHighlight',
|
||||
var TouchableHighlight = React.createClass({
|
||||
propTypes: {
|
||||
...TouchableWithoutFeedback.propTypes,
|
||||
/**
|
||||
@@ -108,6 +108,7 @@ var TouchableHighlight = createReactClass({
|
||||
* @platform ios
|
||||
*/
|
||||
tvParallaxProperties: PropTypes.object,
|
||||
|
||||
},
|
||||
|
||||
mixins: [NativeMethodsMixin, TimerMixin, Touchable.Mixin],
|
||||
|
||||
@@ -18,7 +18,6 @@ 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');
|
||||
|
||||
@@ -71,8 +70,7 @@ var PRESS_RETENTION_OFFSET = {top: 20, left: 20, right: 20, bottom: 30};
|
||||
* ```
|
||||
*/
|
||||
|
||||
var TouchableNativeFeedback = createReactClass({
|
||||
displayName: 'TouchableNativeFeedback',
|
||||
var TouchableNativeFeedback = React.createClass({
|
||||
propTypes: {
|
||||
...TouchableWithoutFeedback.propTypes,
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@ 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');
|
||||
|
||||
@@ -52,8 +51,7 @@ var PRESS_RETENTION_OFFSET = {top: 20, left: 20, right: 20, bottom: 30};
|
||||
* },
|
||||
* ```
|
||||
*/
|
||||
var TouchableOpacity = createReactClass({
|
||||
displayName: 'TouchableOpacity',
|
||||
var TouchableOpacity = React.createClass({
|
||||
mixins: [TimerMixin, Touchable.Mixin, NativeMethodsMixin],
|
||||
|
||||
propTypes: {
|
||||
|
||||
@@ -17,7 +17,6 @@ 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');
|
||||
|
||||
@@ -26,7 +25,7 @@ const {
|
||||
AccessibilityTraits,
|
||||
} = require('ViewAccessibility');
|
||||
|
||||
export type Event = Object;
|
||||
type Event = Object;
|
||||
|
||||
const PRESS_RETENTION_OFFSET = {top: 20, left: 20, right: 20, bottom: 30};
|
||||
|
||||
@@ -37,8 +36,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.
|
||||
*/
|
||||
const TouchableWithoutFeedback = createReactClass({
|
||||
displayName: 'TouchableWithoutFeedback',
|
||||
// $FlowFixMe(>=0.41.0)
|
||||
const TouchableWithoutFeedback = React.createClass({
|
||||
mixins: [TimerMixin, Touchable.Mixin],
|
||||
|
||||
propTypes: {
|
||||
@@ -89,7 +88,6 @@ const TouchableWithoutFeedback = createReactClass({
|
||||
* reactivated! Move it back and forth several times while the scroll view
|
||||
* is disabled. Ensure you pass in a constant to reduce memory allocations.
|
||||
*/
|
||||
// $FlowFixMe: Expected a React PropType instead
|
||||
pressRetentionOffset: EdgeInsetsPropType,
|
||||
/**
|
||||
* This defines how far your touch can start away from the button. This is
|
||||
@@ -99,7 +97,6 @@ const TouchableWithoutFeedback = createReactClass({
|
||||
* of sibling views always takes precedence if a touch hits two overlapping
|
||||
* views.
|
||||
*/
|
||||
// $FlowFixMe: Expected a React PropType instead
|
||||
hitSlop: EdgeInsetsPropType,
|
||||
},
|
||||
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
jest.disableAutomock();
|
||||
|
||||
const React = require('React');
|
||||
const ReactTestRenderer = require('react-test-renderer');
|
||||
const Text = require('Text');
|
||||
|
||||
@@ -1,34 +1,25 @@
|
||||
/**
|
||||
* 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 UnimplementedView
|
||||
* @flow
|
||||
* @format
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
const React = require('React');
|
||||
const StyleSheet = require('StyleSheet');
|
||||
|
||||
/**
|
||||
* Common implementation for a simple stubbed view. Simply applies the view's styles to the inner
|
||||
* View component and renders its children.
|
||||
*
|
||||
* @providesModule UnimplementedView
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var React = require('React');
|
||||
var StyleSheet = require('StyleSheet');
|
||||
|
||||
class UnimplementedView extends React.Component {
|
||||
setNativeProps() {
|
||||
setNativeProps = () => {
|
||||
// Do nothing.
|
||||
// This method is required in order to use this view as a Touchable* child.
|
||||
// See ensureComponentIsNative.js for more info
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
// Workaround require cycle from requireNativeComponent
|
||||
const View = require('View');
|
||||
var View = require('View');
|
||||
return (
|
||||
<View style={[styles.unimplementedView, this.props.style]}>
|
||||
{this.props.children}
|
||||
@@ -37,14 +28,12 @@ class UnimplementedView extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
unimplementedView: __DEV__
|
||||
? {
|
||||
alignSelf: 'flex-start',
|
||||
borderColor: 'red',
|
||||
borderWidth: 1,
|
||||
}
|
||||
: {},
|
||||
var styles = StyleSheet.create({
|
||||
unimplementedView: {
|
||||
borderWidth: 1,
|
||||
borderColor: 'red',
|
||||
alignSelf: 'flex-start',
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = UnimplementedView;
|
||||
|
||||
@@ -8,23 +8,13 @@
|
||||
*
|
||||
* @providesModule ShadowPropTypesIOS
|
||||
* @flow
|
||||
* @format
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
const ColorPropType = require('ColorPropType');
|
||||
const ReactPropTypes = require('prop-types');
|
||||
var ColorPropType = require('ColorPropType');
|
||||
var ReactPropTypes = require('React').PropTypes;
|
||||
|
||||
/**
|
||||
* These props can be used to dynamically generate shadows on views, images, text, etc.
|
||||
*
|
||||
* Because they are dynamically generated, they may cause performance regressions. Static
|
||||
* shadow image asset may be a better way to go for optimal performance.
|
||||
*
|
||||
* These properties are iOS only - for similar functionality on Android, use the [`elevation`
|
||||
* property](docs/viewstyleproptypes.html#elevation).
|
||||
*/
|
||||
const ShadowPropTypesIOS = {
|
||||
var ShadowPropTypesIOS = {
|
||||
/**
|
||||
* Sets the drop shadow color
|
||||
* @platform ios
|
||||
@@ -34,10 +24,9 @@ const ShadowPropTypesIOS = {
|
||||
* Sets the drop shadow offset
|
||||
* @platform ios
|
||||
*/
|
||||
shadowOffset: ReactPropTypes.shape({
|
||||
width: ReactPropTypes.number,
|
||||
height: ReactPropTypes.number,
|
||||
}),
|
||||
shadowOffset: ReactPropTypes.shape(
|
||||
{width: ReactPropTypes.number, height: ReactPropTypes.number}
|
||||
),
|
||||
/**
|
||||
* Sets the drop shadow opacity (multiplied by the color's alpha component)
|
||||
* @platform ios
|
||||
|
||||
@@ -9,23 +9,30 @@
|
||||
* @providesModule View
|
||||
* @flow
|
||||
*/
|
||||
"use strict";
|
||||
'use strict';
|
||||
|
||||
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 NativeMethodsMixin = require('NativeMethodsMixin');
|
||||
const NativeModules = require('NativeModules');
|
||||
const Platform = require('Platform');
|
||||
const React = require('React');
|
||||
const PropTypes = require('prop-types');
|
||||
const ReactNativeFeatureFlags = require('ReactNativeFeatureFlags');
|
||||
const ReactNativeStyleAttributes = require('ReactNativeStyleAttributes');
|
||||
const ReactNativeViewAttributes = require('ReactNativeViewAttributes');
|
||||
const ViewPropTypes = require('ViewPropTypes');
|
||||
|
||||
const createReactClass = require("create-react-class");
|
||||
const invariant = require("fbjs/lib/invariant");
|
||||
const requireNativeComponent = require("requireNativeComponent");
|
||||
const invariant = require('fbjs/lib/invariant');
|
||||
const warning = require('fbjs/lib/warning');
|
||||
|
||||
import type { ViewProps } from "ViewPropTypes";
|
||||
const {
|
||||
AccessibilityComponentTypes,
|
||||
AccessibilityTraits,
|
||||
} = require('ViewAccessibility');
|
||||
|
||||
export type Props = ViewProps;
|
||||
const requireNativeComponent = require('requireNativeComponent');
|
||||
|
||||
const forceTouchAvailable = (NativeModules.PlatformConstants &&
|
||||
NativeModules.PlatformConstants.forceTouchAvailable) || false;
|
||||
|
||||
/**
|
||||
* The most fundamental component for building a UI, `View` is a container that supports layout with
|
||||
@@ -74,8 +81,7 @@ export type Props = ViewProps;
|
||||
* - `touches` - Array of all current touches on the screen.
|
||||
*/
|
||||
// $FlowFixMe(>=0.41.0)
|
||||
const View = createReactClass({
|
||||
displayName: "View",
|
||||
const View = React.createClass({
|
||||
// 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
|
||||
@@ -85,61 +91,143 @@ const View = createReactClass({
|
||||
// `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.
|
||||
// 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.
|
||||
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} />;
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const RCTView = requireNativeComponent("RCTView", View, {
|
||||
// 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, {
|
||||
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__) {
|
||||
if (
|
||||
__DEV__ ||
|
||||
ReactNativeFeatureFlags.useFiber
|
||||
) {
|
||||
mixinStatics(View);
|
||||
ViewToExport = View;
|
||||
} else {
|
||||
// TODO (bvaughn) Remove this mixin once all static View accessors are gone.
|
||||
mixinStatics((RCTView : any));
|
||||
}
|
||||
|
||||
// No one should depend on the DEV-mode createClass View wrapper.
|
||||
module.exports = ((ViewToExport: any): typeof RCTView);
|
||||
// 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);
|
||||
|
||||
@@ -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,
|
||||
@@ -27,63 +27,8 @@ if (Platform.isTVOS) {
|
||||
TVViewPropTypes = require('TVViewPropTypes');
|
||||
}
|
||||
|
||||
import type {
|
||||
AccessibilityComponentType,
|
||||
AccessibilityTrait,
|
||||
} from 'ViewAccessibility';
|
||||
import type {EdgeInsetsProp} from 'EdgeInsetsPropType';
|
||||
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 = {
|
||||
accessible?: bool,
|
||||
accessibilityLabel?: React$PropType$Primitive<any>,
|
||||
accessibilityComponentType?: AccessibilityComponentType,
|
||||
accessibilityLiveRegion?: 'none' | 'polite' | 'assertive',
|
||||
importantForAccessibility?: 'auto'| 'yes'| 'no'| 'no-hide-descendants',
|
||||
accessibilityTraits?: AccessibilityTrait | Array<AccessibilityTrait>,
|
||||
accessibilityViewIsModal?: bool,
|
||||
onAccessibilityTap?: Function,
|
||||
onMagicTap?: Function,
|
||||
testID?: string,
|
||||
nativeID?: string,
|
||||
onLayout?: (event: ViewLayoutEvent) => void,
|
||||
onResponderGrant?: Function,
|
||||
onResponderMove?: Function,
|
||||
onResponderReject?: Function,
|
||||
onResponderRelease?: Function,
|
||||
onResponderTerminate?: Function,
|
||||
onResponderTerminationRequest?: Function,
|
||||
onStartShouldSetResponder?: Function,
|
||||
onStartShouldSetResponderCapture?: Function,
|
||||
onMoveShouldSetResponder?: Function,
|
||||
onMoveShouldSetResponderCapture?: Function,
|
||||
hitSlop?: EdgeInsetsProp,
|
||||
pointerEvents?: 'box-none'| 'none'| 'box-only'| 'auto',
|
||||
style?: stylePropType,
|
||||
removeClippedSubviews?: bool,
|
||||
renderToHardwareTextureAndroid?: bool,
|
||||
shouldRasterizeIOS?: bool,
|
||||
collapsable?: bool,
|
||||
needsOffscreenAlphaCompositing?: bool,
|
||||
} & TVViewProps;
|
||||
|
||||
module.exports = {
|
||||
...TVViewPropTypes,
|
||||
|
||||
@@ -232,6 +177,8 @@ 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 ColorPropType = require('ColorPropType');
|
||||
var LayoutPropTypes = require('LayoutPropTypes');
|
||||
var ReactPropTypes = require('prop-types');
|
||||
var ReactPropTypes = require('React').PropTypes;
|
||||
var ColorPropType = require('ColorPropType');
|
||||
var ShadowPropTypesIOS = require('ShadowPropTypesIOS');
|
||||
var TransformPropTypes = require('TransformPropTypes');
|
||||
|
||||
|
||||
@@ -75,7 +75,6 @@ class ViewPagerAndroid extends React.Component {
|
||||
onPageScrollStateChanged?: Function,
|
||||
onPageSelected?: Function,
|
||||
pageMargin?: number,
|
||||
peekEnabled?: boolean,
|
||||
keyboardDismissMode?: 'none' | 'on-drag',
|
||||
scrollEnabled?: boolean,
|
||||
};
|
||||
@@ -138,12 +137,6 @@ 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() {
|
||||
|
||||
@@ -120,13 +120,6 @@ class WebView extends React.Component {
|
||||
*/
|
||||
javaScriptEnabled: PropTypes.bool,
|
||||
|
||||
/**
|
||||
* Used on Android Lollipop and above only, third party cookies are enabled
|
||||
* by default for WebView on Android Kitkat and below and on iOS
|
||||
* @platform android
|
||||
*/
|
||||
thirdPartyCookiesEnabled: PropTypes.bool,
|
||||
|
||||
/**
|
||||
* Used on Android only, controls whether DOM Storage is enabled or not
|
||||
* @platform android
|
||||
@@ -199,7 +192,6 @@ class WebView extends React.Component {
|
||||
|
||||
static defaultProps = {
|
||||
javaScriptEnabled : true,
|
||||
thirdPartyCookiesEnabled: true,
|
||||
scalesPageToFit: true,
|
||||
saveFormDataDisabled: false
|
||||
};
|
||||
@@ -261,7 +253,6 @@ class WebView extends React.Component {
|
||||
injectedJavaScript={this.props.injectedJavaScript}
|
||||
userAgent={this.props.userAgent}
|
||||
javaScriptEnabled={this.props.javaScriptEnabled}
|
||||
thirdPartyCookiesEnabled={this.props.thirdPartyCookiesEnabled}
|
||||
domStorageEnabled={this.props.domStorageEnabled}
|
||||
messagingEnabled={typeof this.props.onMessage === 'function'}
|
||||
onMessage={this.onMessage}
|
||||
|
||||
@@ -285,14 +285,6 @@ class WebView extends React.Component {
|
||||
*/
|
||||
javaScriptEnabled: PropTypes.bool,
|
||||
|
||||
/**
|
||||
* Boolean value to enable third party cookies in the `WebView`. Used on
|
||||
* Android Lollipop and above only as third party cookies are enabled by
|
||||
* default on Android Kitkat and below and on iOS. The default value is `true`.
|
||||
* @platform android
|
||||
*/
|
||||
thirdPartyCookiesEnabled: PropTypes.bool,
|
||||
|
||||
/**
|
||||
* Boolean value to control whether DOM Storage is enabled. Used only in
|
||||
* Android.
|
||||
@@ -367,10 +359,6 @@ class WebView extends React.Component {
|
||||
]),
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
scalesPageToFit: true,
|
||||
};
|
||||
|
||||
state = {
|
||||
viewState: WebViewState.IDLE,
|
||||
lastErrorEvent: (null: ?ErrorEvent),
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
'use strict';
|
||||
|
||||
|
||||
jest.disableAutomock();
|
||||
|
||||
var parseErrorStack = require('parseErrorStack');
|
||||
|
||||
function getFakeError() {
|
||||
|
||||
@@ -18,22 +18,20 @@ export type StackFrame = {
|
||||
methodName: string,
|
||||
};
|
||||
|
||||
export type ExtendedError = Error & {
|
||||
framesToPop?: number,
|
||||
};
|
||||
var stacktraceParser = require('stacktrace-parser');
|
||||
|
||||
function parseErrorStack(e: ExtendedError): Array<StackFrame> {
|
||||
function parseErrorStack(e: Error): Array<StackFrame> {
|
||||
if (!e || !e.stack) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const stacktraceParser = require('stacktrace-parser');
|
||||
const stack = Array.isArray(e.stack) ? e.stack : stacktraceParser.parse(e.stack);
|
||||
var stack = Array.isArray(e.stack) ? e.stack : stacktraceParser.parse(e.stack);
|
||||
|
||||
let framesToPop = typeof e.framesToPop === 'number' ? e.framesToPop : 0;
|
||||
var framesToPop = typeof e.framesToPop === 'number' ? e.framesToPop : 0;
|
||||
while (framesToPop--) {
|
||||
stack.shift();
|
||||
}
|
||||
|
||||
return stack;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,28 +13,24 @@
|
||||
|
||||
if (__DEV__) {
|
||||
const AppState = require('AppState');
|
||||
const WebSocket = require('WebSocket');
|
||||
const {PlatformConstants} = require('NativeModules');
|
||||
const {connectToDevTools} = require('react-devtools-core');
|
||||
|
||||
// Initialize dev tools only if the native module for WebSocket is available
|
||||
if (WebSocket.isAvailable) {
|
||||
connectToDevTools({
|
||||
isAppActive() {
|
||||
// Don't steal the DevTools from currently active app.
|
||||
// Note: if you add any AppState subscriptions to this file,
|
||||
// you will also need to guard against `AppState.isAvailable`,
|
||||
// or the code will throw for bundles that don't have it.
|
||||
return AppState.currentState !== 'background';
|
||||
},
|
||||
// Special case: Genymotion is running on a different host.
|
||||
host: PlatformConstants && PlatformConstants.ServerHost ?
|
||||
PlatformConstants.ServerHost.split(':')[0] :
|
||||
'localhost',
|
||||
// Read the optional global variable for backward compatibility.
|
||||
// It was added in https://github.com/facebook/react-native/commit/bf2b435322e89d0aeee8792b1c6e04656c2719a0.
|
||||
port: window.__REACT_DEVTOOLS_PORT__,
|
||||
resolveRNStyle: require('flattenStyle'),
|
||||
});
|
||||
}
|
||||
connectToDevTools({
|
||||
isAppActive() {
|
||||
// Don't steal the DevTools from currently active app.
|
||||
// Note: if you add any AppState subscriptions to this file,
|
||||
// you will also need to guard against `AppState.isAvailable`,
|
||||
// or the code will throw for bundles that don't have it.
|
||||
return AppState.currentState !== 'background';
|
||||
},
|
||||
// Special case: Genymotion is running on a different host.
|
||||
host: PlatformConstants && PlatformConstants.ServerHost ?
|
||||
PlatformConstants.ServerHost.split(':')[0] :
|
||||
'localhost',
|
||||
// Read the optional global variable for backward compatibility.
|
||||
// It was added in https://github.com/facebook/react-native/commit/bf2b435322e89d0aeee8792b1c6e04656c2719a0.
|
||||
port: window.__REACT_DEVTOOLS_PORT__,
|
||||
resolveRNStyle: require('flattenStyle'),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -11,13 +11,11 @@
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
import type {ExtendedError} from 'parseErrorStack';
|
||||
|
||||
/**
|
||||
* Handles the developer-visible aspect of errors and exceptions
|
||||
*/
|
||||
let exceptionID = 0;
|
||||
function reportException(e: ExtendedError, isFatal: bool) {
|
||||
function reportException(e: Error, isFatal: bool) {
|
||||
const {ExceptionsManager} = require('NativeModules');
|
||||
if (ExceptionsManager) {
|
||||
const parseErrorStack = require('parseErrorStack');
|
||||
@@ -86,7 +84,7 @@ function reactConsoleErrorHandler() {
|
||||
// (Note: Logic duplicated in polyfills/console.js.)
|
||||
return;
|
||||
}
|
||||
const error : ExtendedError = new Error('console.error: ' + str);
|
||||
const error : any = new Error('console.error: ' + str);
|
||||
error.framesToPop = 1;
|
||||
reportException(error, /* isFatal */ false);
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
/* eslint-disable strict */
|
||||
/* globals window: true */
|
||||
|
||||
|
||||
/**
|
||||
* Sets up global variables typical in most JavaScript environments.
|
||||
*
|
||||
@@ -95,21 +96,28 @@ if (!global.process.env.NODE_ENV) {
|
||||
global.process.env.NODE_ENV = __DEV__ ? 'development' : 'production';
|
||||
}
|
||||
|
||||
// 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 profile
|
||||
const Systrace = require('Systrace');
|
||||
Systrace.setEnabled(global.__RCTProfileIsProfiling || false);
|
||||
|
||||
// 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.registerCallableModule('Systrace', require('Systrace'));
|
||||
BatchedBridge.registerCallableModule('JSTimersExecution', require('JSTimersExecution'));
|
||||
BatchedBridge.registerCallableModule('HeapCapture', require('HeapCapture'));
|
||||
BatchedBridge.registerCallableModule('SamplingProfiler', require('SamplingProfiler'));
|
||||
|
||||
if (__DEV__) {
|
||||
BatchedBridge.registerCallableModule('HMRClient', require('HMRClient'));
|
||||
}
|
||||
|
||||
// RCTLog needs to register with BatchedBridge
|
||||
require('RCTLog');
|
||||
|
||||
// Set up error handler
|
||||
if (!global.__fbDisableExceptionsManager) {
|
||||
const handleError = (e, isFatal) => {
|
||||
@@ -127,26 +135,6 @@ if (!global.__fbDisableExceptionsManager) {
|
||||
ErrorUtils.setGlobalHandler(handleError);
|
||||
}
|
||||
|
||||
// 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:
|
||||
// ERROR: Event loop not supported.
|
||||
defineProperty(global, 'Promise', () => require('Promise'));
|
||||
|
||||
// Set up regenerator.
|
||||
defineProperty(global, 'regeneratorRuntime', () => {
|
||||
// The require just sets up the global, so make sure when we first
|
||||
// invoke it the global does not exist
|
||||
delete global.regeneratorRuntime;
|
||||
require('regenerator-runtime/runtime');
|
||||
return global.regeneratorRuntime;
|
||||
});
|
||||
|
||||
// Set up timers
|
||||
const defineLazyTimer = name => {
|
||||
defineProperty(global, name, () => require('JSTimers')[name]);
|
||||
@@ -162,6 +150,29 @@ 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 Promise
|
||||
// The native Promise implementation throws the following error:
|
||||
// ERROR: Event loop not supported.
|
||||
defineProperty(global, 'Promise', () => require('Promise'));
|
||||
|
||||
// Set up regenerator.
|
||||
defineProperty(global, 'regeneratorRuntime', () => {
|
||||
// The require just sets up the global, so make sure when we first
|
||||
// invoke it the global does not exist
|
||||
delete global.regeneratorRuntime;
|
||||
require('regenerator-runtime/runtime');
|
||||
return global.regeneratorRuntime;
|
||||
});
|
||||
|
||||
// Set up XHR
|
||||
// The native XMLHttpRequest in Chrome dev tools is CORS aware and won't
|
||||
// let you fetch anything from the internet
|
||||
@@ -174,15 +185,6 @@ 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) {
|
||||
@@ -193,31 +195,31 @@ if (navigator === undefined) {
|
||||
defineProperty(navigator, 'product', () => 'ReactNative', true);
|
||||
defineProperty(navigator, 'geolocation', () => require('Geolocation'));
|
||||
|
||||
// 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 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 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');
|
||||
}
|
||||
|
||||
// Set up inspector
|
||||
const JSInspector = require('JSInspector');
|
||||
JSInspector.registerAgent(require('NetworkAgent'));
|
||||
// not when debugging in chrome
|
||||
// TODO(t12832058) This check is broken
|
||||
if (!window.document) {
|
||||
require('setupDevtools');
|
||||
}
|
||||
|
||||
require('RCTDebugComponentOwnership');
|
||||
}
|
||||
|
||||
// Set up inspector
|
||||
if (__DEV__) {
|
||||
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.
|
||||
require('RCTDeviceEventEmitter');
|
||||
require('RCTNativeAppEventEmitter');
|
||||
require('PerformanceLogger');
|
||||
|
||||
@@ -7,39 +7,63 @@
|
||||
* 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');
|
||||
|
||||
import type {ExtendedError} from 'parseErrorStack';
|
||||
import type {JSTimerType} from 'JSTimersExecution';
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
// 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;
|
||||
}
|
||||
|
||||
export type JSTimerType =
|
||||
| 'setTimeout'
|
||||
| 'setInterval'
|
||||
| 'requestAnimationFrame'
|
||||
| 'setImmediate'
|
||||
| 'requestIdleCallback';
|
||||
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;
|
||||
}
|
||||
|
||||
// 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;
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const MAX_TIMER_DURATION_MS = 60 * 1000;
|
||||
const IS_ANDROID = Platform.OS === 'android';
|
||||
@@ -49,152 +73,6 @@ 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
|
||||
@@ -205,24 +83,13 @@ 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;
|
||||
},
|
||||
@@ -231,24 +98,13 @@ 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;
|
||||
},
|
||||
@@ -258,18 +114,15 @@ const JSTimers = {
|
||||
* current JavaScript execution loop.
|
||||
*/
|
||||
setImmediate: function(func: Function, ...args?: any) {
|
||||
const id = _allocateCallback(
|
||||
() => func.apply(undefined, args),
|
||||
'setImmediate',
|
||||
);
|
||||
immediates.push(id);
|
||||
const id = _allocateCallback(() => func.apply(undefined, args), 'setImmediate');
|
||||
JSTimersExecution.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;
|
||||
@@ -278,60 +131,25 @@ const JSTimers = {
|
||||
/**
|
||||
* @param {function} func Callback to be invoked every frame and provided
|
||||
* with time remaining in frame.
|
||||
* @param {?object} options
|
||||
*/
|
||||
requestIdleCallback: function(func: Function, options: ?Object) {
|
||||
if (requestIdleCallbacks.length === 0) {
|
||||
requestIdleCallback: function(func : Function) {
|
||||
if (JSTimersExecution.requestIdleCallbacks.length === 0) {
|
||||
Timing.setSendIdleEvents(true);
|
||||
}
|
||||
|
||||
const timeout = options && options.timeout;
|
||||
const id = _allocateCallback(
|
||||
timeout != null
|
||||
? deadline => {
|
||||
const timeoutId = requestIdleCallbackTimeouts[id];
|
||||
if (timeoutId) {
|
||||
JSTimers.clearTimeout(timeoutId);
|
||||
requestIdleCallbackTimeouts[id];
|
||||
}
|
||||
return func(deadline);
|
||||
}
|
||||
: func,
|
||||
'requestIdleCallback',
|
||||
);
|
||||
requestIdleCallbacks.push(id);
|
||||
|
||||
if (timeout != null) {
|
||||
const timeoutId = JSTimers.setTimeout(() => {
|
||||
const index = requestIdleCallbacks.indexOf(id);
|
||||
if (index > -1) {
|
||||
requestIdleCallbacks.splice(index, 1);
|
||||
_callTimer(id, performanceNow(), true);
|
||||
}
|
||||
delete requestIdleCallbackTimeouts[id];
|
||||
if (requestIdleCallbacks.length === 0) {
|
||||
Timing.setSendIdleEvents(false);
|
||||
}
|
||||
}, timeout);
|
||||
requestIdleCallbackTimeouts[id] = timeoutId;
|
||||
}
|
||||
const id = _allocateCallback(func, 'requestIdleCallback');
|
||||
JSTimersExecution.requestIdleCallbacks.push(id);
|
||||
return id;
|
||||
},
|
||||
|
||||
cancelIdleCallback: function(timerID: number) {
|
||||
_freeCallback(timerID);
|
||||
const index = requestIdleCallbacks.indexOf(timerID);
|
||||
const index = JSTimersExecution.requestIdleCallbacks.indexOf(timerID);
|
||||
if (index !== -1) {
|
||||
requestIdleCallbacks.splice(index, 1);
|
||||
JSTimersExecution.requestIdleCallbacks.splice(index, 1);
|
||||
}
|
||||
|
||||
const timeoutId = requestIdleCallbackTimeouts[timerID];
|
||||
if (timeoutId) {
|
||||
JSTimers.clearTimeout(timeoutId);
|
||||
delete requestIdleCallbackTimeouts[timerID];
|
||||
}
|
||||
|
||||
if (requestIdleCallbacks.length === 0) {
|
||||
if (JSTimersExecution.requestIdleCallbacks.length === 0) {
|
||||
Timing.setSendIdleEvents(false);
|
||||
}
|
||||
},
|
||||
@@ -346,136 +164,15 @@ const JSTimers = {
|
||||
|
||||
clearImmediate: function(timerID: number) {
|
||||
_freeCallback(timerID);
|
||||
const index = immediates.indexOf(timerID);
|
||||
const index = JSTimersExecution.immediates.indexOf(timerID);
|
||||
if (index !== -1) {
|
||||
immediates.splice(index, 1);
|
||||
JSTimersExecution.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;
|
||||
|
||||
@@ -0,0 +1,241 @@
|
||||
/**
|
||||
* 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: [],
|
||||
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) {
|
||||
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));
|
||||
},
|
||||
});
|
||||
} 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() {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* 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;
|
||||
@@ -1,54 +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 MissingNativeEventEmitterShim
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
const EmitterSubscription = require('EmitterSubscription');
|
||||
const EventEmitter = require('EventEmitter');
|
||||
|
||||
const invariant = require('fbjs/lib/invariant');
|
||||
|
||||
class MissingNativeEventEmitterShim extends EventEmitter {
|
||||
isAvailable: boolean = false;
|
||||
_nativeModuleName: string;
|
||||
_nativeEventEmitterName: string;
|
||||
|
||||
constructor(nativeModuleName: string, nativeEventEmitterName: string) {
|
||||
super(null);
|
||||
this._nativeModuleName = nativeModuleName;
|
||||
this._nativeEventEmitterName = nativeEventEmitterName;
|
||||
}
|
||||
|
||||
throwMissingNativeModule() {
|
||||
invariant(
|
||||
false,
|
||||
`Cannot use '${this._nativeEventEmitterName}' module when ` +
|
||||
`native '${this._nativeModuleName}' is not included in the build. ` +
|
||||
`Either include it, or check '${this._nativeEventEmitterName}'.isAvailable ` +
|
||||
'before calling any methods.'
|
||||
);
|
||||
}
|
||||
|
||||
// EventEmitter
|
||||
addListener(eventType: string, listener: Function, context: ?Object): EmitterSubscription {
|
||||
this.throwMissingNativeModule();
|
||||
}
|
||||
|
||||
removeAllListeners(eventType: string) {
|
||||
this.throwMissingNativeModule();
|
||||
}
|
||||
|
||||
removeSubscription(subscription: EmitterSubscription) {
|
||||
this.throwMissingNativeModule();
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = MissingNativeEventEmitterShim;
|
||||
@@ -23,6 +23,7 @@ import type EmitterSubscription from 'EmitterSubscription';
|
||||
* a subset of the standard EventEmitter node module API.
|
||||
*/
|
||||
class NativeEventEmitter extends EventEmitter {
|
||||
|
||||
_nativeModule: Object;
|
||||
|
||||
constructor(nativeModule: Object) {
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
const EventEmitter = require('EventEmitter');
|
||||
const EventSubscriptionVendor = require('EventSubscriptionVendor');
|
||||
const BatchedBridge = require('BatchedBridge');
|
||||
|
||||
import type EmitterSubscription from 'EmitterSubscription';
|
||||
|
||||
@@ -69,4 +70,11 @@ class RCTDeviceEventEmitter extends EventEmitter {
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = new RCTDeviceEventEmitter();
|
||||
RCTDeviceEventEmitter = new RCTDeviceEventEmitter();
|
||||
|
||||
BatchedBridge.registerCallableModule(
|
||||
'RCTDeviceEventEmitter',
|
||||
RCTDeviceEventEmitter
|
||||
);
|
||||
|
||||
module.exports = RCTDeviceEventEmitter;
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
const BatchedBridge = require('BatchedBridge');
|
||||
const RCTDeviceEventEmitter = require('RCTDeviceEventEmitter');
|
||||
|
||||
/**
|
||||
@@ -18,4 +19,10 @@ const RCTDeviceEventEmitter = require('RCTDeviceEventEmitter');
|
||||
* adding all event listeners directly to RCTNativeAppEventEmitter.
|
||||
*/
|
||||
const RCTNativeAppEventEmitter = RCTDeviceEventEmitter;
|
||||
|
||||
BatchedBridge.registerCallableModule(
|
||||
'RCTNativeAppEventEmitter',
|
||||
RCTNativeAppEventEmitter
|
||||
);
|
||||
|
||||
module.exports = RCTNativeAppEventEmitter;
|
||||
|
||||
@@ -12,11 +12,12 @@
|
||||
'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,11 +12,12 @@
|
||||
'use strict';
|
||||
|
||||
const Image = require('Image');
|
||||
const PropTypes = require('prop-types');
|
||||
const React = require('React');
|
||||
const PropTypes = require('prop-types');
|
||||
const Text = require('Text');
|
||||
const TouchableHighlight = require('TouchableHighlight');
|
||||
const View = require('View');
|
||||
|
||||
const ViewPropTypes = require('ViewPropTypes');
|
||||
|
||||
import type {ImageSource} from 'ImageSource';
|
||||
@@ -30,12 +31,12 @@ class SwipeableQuickActionButton extends React.Component {
|
||||
props: {
|
||||
accessibilityLabel?: string,
|
||||
imageSource: ImageSource | number,
|
||||
imageStyle?: ?ViewPropTypes.style,
|
||||
imageStyle?: ?View.propTypes.style,
|
||||
onPress?: Function,
|
||||
style?: ?ViewPropTypes.style,
|
||||
style?: ?View.propTypes.style,
|
||||
testID?: string,
|
||||
text?: ?(string | Object | Array<string | Object>),
|
||||
textStyle?: ?ViewPropTypes.style,
|
||||
textStyle?: ?View.propTypes.style,
|
||||
};
|
||||
|
||||
static propTypes = {
|
||||
|
||||
@@ -20,7 +20,6 @@ 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;
|
||||
@@ -62,8 +61,7 @@ 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 = createReactClass({
|
||||
displayName: 'SwipeableRow',
|
||||
const SwipeableRow = React.createClass({
|
||||
_panResponder: {},
|
||||
_previousLeft: CLOSED_LEFT_POSITION,
|
||||
|
||||
@@ -72,8 +70,6 @@ const SwipeableRow = createReactClass({
|
||||
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,
|
||||
@@ -110,8 +106,6 @@ const SwipeableRow = createReactClass({
|
||||
getDefaultProps(): Object {
|
||||
return {
|
||||
isOpen: false,
|
||||
preventSwipeLeft: false,
|
||||
preventSwipeRight: false,
|
||||
maxSwipeDistance: 0,
|
||||
onOpen: emptyFunction,
|
||||
onClose: emptyFunction,
|
||||
@@ -196,11 +190,6 @@ const SwipeableRow = createReactClass({
|
||||
);
|
||||
},
|
||||
|
||||
close(): void {
|
||||
this.props.onClose();
|
||||
this._animateToClosedPosition();
|
||||
},
|
||||
|
||||
_onSwipeableViewLayout(event: Object): void {
|
||||
this.setState({
|
||||
isSwipeableViewRendered: true,
|
||||
@@ -279,7 +268,6 @@ const SwipeableRow = createReactClass({
|
||||
{
|
||||
duration,
|
||||
toValue,
|
||||
useNativeDriver: true,
|
||||
},
|
||||
).start(() => {
|
||||
this._previousLeft = toValue;
|
||||
@@ -339,12 +327,6 @@ const SwipeableRow = createReactClass({
|
||||
|
||||
// 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;
|
||||
},
|
||||
|
||||
|
||||
@@ -27,8 +27,6 @@ const infoLog = require('infoLog');
|
||||
const invariant = require('fbjs/lib/invariant');
|
||||
const nullthrows = require('fbjs/lib/nullthrows');
|
||||
|
||||
import type {NativeMethodsMixinType} from 'ReactNativeTypes';
|
||||
|
||||
const DEBUG = false;
|
||||
|
||||
/**
|
||||
@@ -75,15 +73,11 @@ type Props = {
|
||||
/**
|
||||
* Rendered when the list is scrolled faster than rows can be rendered.
|
||||
*/
|
||||
renderWindowBoundaryIndicator?: (
|
||||
showIndicator: boolean,
|
||||
) => ?React.Element<any>,
|
||||
renderWindowBoundaryIndicator?: () => ?React.Element<any>,
|
||||
/**
|
||||
* Always rendered at the bottom of all the rows.
|
||||
*/
|
||||
renderFooter?: (
|
||||
showFooter: boolean,
|
||||
) => ?React.Element<any>,
|
||||
renderFooter?: () => ?React.Element<any>,
|
||||
/**
|
||||
* Pipes through normal onScroll events from the underlying `ScrollView`.
|
||||
*/
|
||||
@@ -615,7 +609,7 @@ type CellProps = {
|
||||
};
|
||||
class CellRenderer extends React.Component {
|
||||
props: CellProps;
|
||||
_containerRef: NativeMethodsMixinType;
|
||||
_containerRef: View;
|
||||
_offscreenRenderDone = false;
|
||||
_timeout = 0;
|
||||
_lastLayout: ?Object = null;
|
||||
|
||||
@@ -20,9 +20,6 @@ const warning = require('fbjs/lib/warning');
|
||||
|
||||
const LocationEventEmitter = new NativeEventEmitter(RCTLocationObserver);
|
||||
|
||||
const Platform = require('Platform');
|
||||
const PermissionsAndroid = require('PermissionsAndroid');
|
||||
|
||||
var subscriptions = [];
|
||||
var updatesEnabled = false;
|
||||
|
||||
@@ -74,23 +71,13 @@ type GeoOptions = {
|
||||
*/
|
||||
var Geolocation = {
|
||||
|
||||
/*
|
||||
* Request suitable Location permission based on the key configured on pList.
|
||||
* If NSLocationAlwaysUsageDescription is set, it will request Always authorization,
|
||||
* although if NSLocationWhenInUseUsageDescription is set, it will request InUse
|
||||
* authorization.
|
||||
*/
|
||||
requestAuthorization: function() {
|
||||
RCTLocationObserver.requestAuthorization();
|
||||
},
|
||||
|
||||
/*
|
||||
* Invokes the success callback once with the latest location info. Supported
|
||||
* options: timeout (ms), maximumAge (ms), enableHighAccuracy (bool)
|
||||
* On Android, if the location is cached this can return almost immediately,
|
||||
* or it will request an update which might take a while.
|
||||
*/
|
||||
getCurrentPosition: async function(
|
||||
getCurrentPosition: function(
|
||||
geo_success: Function,
|
||||
geo_error?: Function,
|
||||
geo_options?: GeoOptions
|
||||
@@ -99,27 +86,11 @@ var Geolocation = {
|
||||
typeof geo_success === 'function',
|
||||
'Must provide a valid geo_success callback.'
|
||||
);
|
||||
let hasPermission = true;
|
||||
// Supports Android's new permission model. For Android older devices,
|
||||
// it's always on.
|
||||
if (Platform.OS === 'android' && Platform.Version >= 23) {
|
||||
hasPermission = await PermissionsAndroid.check(
|
||||
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
|
||||
);
|
||||
if (!hasPermission) {
|
||||
const status = await PermissionsAndroid.request(
|
||||
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
|
||||
);
|
||||
hasPermission = status === PermissionsAndroid.RESULTS.GRANTED;
|
||||
}
|
||||
}
|
||||
if (hasPermission) {
|
||||
RCTLocationObserver.getCurrentPosition(
|
||||
geo_options || {},
|
||||
geo_success,
|
||||
geo_error || logError,
|
||||
);
|
||||
}
|
||||
RCTLocationObserver.getCurrentPosition(
|
||||
geo_options || {},
|
||||
geo_success,
|
||||
geo_error || logError
|
||||
);
|
||||
},
|
||||
|
||||
/*
|
||||
@@ -175,7 +146,7 @@ var Geolocation = {
|
||||
for (var ii = 0; ii < subscriptions.length; ii++) {
|
||||
var sub = subscriptions[ii];
|
||||
if (sub) {
|
||||
warning(false, 'Called stopObserving with existing subscriptions.');
|
||||
warning('Called stopObserving with existing subscriptions.');
|
||||
sub[0].remove();
|
||||
// array element refinements not yet enabled in Flow
|
||||
var sub1 = sub[1]; sub1 && sub1.remove();
|
||||
|
||||
@@ -135,7 +135,27 @@ RCT_EXPORT_MODULE()
|
||||
|
||||
- (void)beginLocationUpdatesWithDesiredAccuracy:(CLLocationAccuracy)desiredAccuracy distanceFilter:(CLLocationDistance)distanceFilter
|
||||
{
|
||||
[self requestAuthorization];
|
||||
if (!_locationManager) {
|
||||
_locationManager = [CLLocationManager new];
|
||||
_locationManager.delegate = self;
|
||||
}
|
||||
|
||||
// Request location access permission
|
||||
if ([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationAlwaysUsageDescription"] &&
|
||||
[_locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
|
||||
[_locationManager requestAlwaysAuthorization];
|
||||
|
||||
// On iOS 9+ we also need to enable background updates
|
||||
NSArray *backgroundModes = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"UIBackgroundModes"];
|
||||
if(backgroundModes && [backgroundModes containsObject:@"location"]) {
|
||||
if([_locationManager respondsToSelector:@selector(setAllowsBackgroundLocationUpdates:)]) {
|
||||
[_locationManager setAllowsBackgroundLocationUpdates:YES];
|
||||
}
|
||||
}
|
||||
} else if ([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationWhenInUseUsageDescription"] &&
|
||||
[_locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
|
||||
[_locationManager requestWhenInUseAuthorization];
|
||||
}
|
||||
|
||||
_locationManager.distanceFilter = distanceFilter;
|
||||
_locationManager.desiredAccuracy = desiredAccuracy;
|
||||
@@ -160,31 +180,6 @@ RCT_EXPORT_MODULE()
|
||||
|
||||
#pragma mark - Public API
|
||||
|
||||
RCT_EXPORT_METHOD(requestAuthorization)
|
||||
{
|
||||
if (!_locationManager) {
|
||||
_locationManager = [CLLocationManager new];
|
||||
_locationManager.delegate = self;
|
||||
}
|
||||
|
||||
// Request location access permission
|
||||
if ([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationAlwaysUsageDescription"] &&
|
||||
[_locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
|
||||
[_locationManager requestAlwaysAuthorization];
|
||||
|
||||
// On iOS 9+ we also need to enable background updates
|
||||
NSArray *backgroundModes = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"UIBackgroundModes"];
|
||||
if (backgroundModes && [backgroundModes containsObject:@"location"]) {
|
||||
if ([_locationManager respondsToSelector:@selector(setAllowsBackgroundLocationUpdates:)]) {
|
||||
[_locationManager setAllowsBackgroundLocationUpdates:YES];
|
||||
}
|
||||
}
|
||||
} else if ([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationWhenInUseUsageDescription"] &&
|
||||
[_locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
|
||||
[_locationManager requestWhenInUseAuthorization];
|
||||
}
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(startObserving:(RCTLocationOptions)options)
|
||||
{
|
||||
checkLocationConfig();
|
||||
|
||||
@@ -25,7 +25,6 @@ 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');
|
||||
@@ -77,8 +76,7 @@ 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 = createReactClass({
|
||||
displayName: 'Image',
|
||||
var Image = React.createClass({
|
||||
propTypes: {
|
||||
...ViewPropTypes,
|
||||
style: StyleSheetPropType(ImageStylePropTypes),
|
||||
|
||||
@@ -23,7 +23,6 @@ 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');
|
||||
@@ -35,10 +34,8 @@ 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 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!
|
||||
* This example shows both fetching and displaying an image from local
|
||||
* storage as well as one from network.
|
||||
*
|
||||
* ```ReactNativeWebPlayer
|
||||
* import React, { Component } from 'react';
|
||||
@@ -55,10 +52,6 @@ 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>
|
||||
* );
|
||||
* }
|
||||
@@ -110,17 +103,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.3.0'
|
||||
* compile 'com.facebook.fresco:animated-base-support:1.0.1'
|
||||
*
|
||||
* // For animated GIF support
|
||||
* compile 'com.facebook.fresco:animated-gif:1.3.0'
|
||||
* compile 'com.facebook.fresco:animated-gif:1.0.1'
|
||||
*
|
||||
* // For WebP support, including animated WebP
|
||||
* compile 'com.facebook.fresco:animated-webp:1.3.0'
|
||||
* compile 'com.facebook.fresco:webpsupport:1.3.0'
|
||||
* compile 'com.facebook.fresco:animated-webp:1.0.1'
|
||||
* compile 'com.facebook.fresco:webpsupport:1.0.1'
|
||||
*
|
||||
* // For WebP support, without animations
|
||||
* compile 'com.facebook.fresco:webpsupport:1.3.0'
|
||||
* compile 'com.facebook.fresco:webpsupport:1.0.1'
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
@@ -133,8 +126,7 @@ const ImageViewManager = NativeModules.ImageViewManager;
|
||||
*
|
||||
*/
|
||||
// $FlowFixMe(>=0.41.0)
|
||||
const Image = createReactClass({
|
||||
displayName: 'Image',
|
||||
const Image = React.createClass({
|
||||
propTypes: {
|
||||
/**
|
||||
* > `ImageResizeMode` is an `Enum` for different image resizing modes, set via the
|
||||
@@ -150,9 +142,6 @@ const Image = createReactClass({
|
||||
* The native side will then choose the best `uri` to display based on the
|
||||
* measured size of the image container. A `cache` property can be added to
|
||||
* control how networked request interacts with the local cache.
|
||||
*
|
||||
* The currently supported formats are `png`, `jpg`, `jpeg`, `bmp`, `gif`,
|
||||
* `webp` (Android only), `psd` (iOS only).
|
||||
*/
|
||||
source: ImageSourcePropType,
|
||||
/**
|
||||
@@ -192,6 +181,7 @@ const Image = createReactClass({
|
||||
accessibilityLabel: PropTypes.node,
|
||||
/**
|
||||
* blurRadius: the blur radius of the blur filter added to the image
|
||||
* @platform ios
|
||||
*/
|
||||
blurRadius: PropTypes.number,
|
||||
/**
|
||||
|
||||
@@ -1,94 +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 ImageBackground
|
||||
* @flow
|
||||
* @format
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
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.
|
||||
*
|
||||
* ```ReactNativeWebPlayer
|
||||
* import React, { Component } from 'react';
|
||||
* import { AppRegistry, View, ImageBackground, Text } from 'react-native';
|
||||
*
|
||||
* class DisplayAnImageBackground extends Component {
|
||||
* render() {
|
||||
* return (
|
||||
* <ImageBackground
|
||||
* style={{width: 50, height: 50}}
|
||||
* source={{uri: 'https://facebook.github.io/react/img/logo_og.png'}}
|
||||
* >
|
||||
* <Text>React</Text>
|
||||
* </ImageBackground>
|
||||
* );
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* // App registration and rendering
|
||||
* AppRegistry.registerComponent('DisplayAnImageBackground', () => DisplayAnImageBackground);
|
||||
* ```
|
||||
*/
|
||||
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} ref={this._captureRef}>
|
||||
<Image
|
||||
{...props}
|
||||
style={[
|
||||
StyleSheet.absoluteFill,
|
||||
{
|
||||
// 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,
|
||||
]}
|
||||
ref={imageRef}
|
||||
/>
|
||||
{children}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ImageBackground;
|
||||
@@ -11,7 +11,7 @@
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
const PropTypes = require('prop-types');
|
||||
const {PropTypes} = require('React');
|
||||
|
||||
const ImageURISourcePropType = PropTypes.shape({
|
||||
/**
|
||||
|
||||
@@ -11,13 +11,14 @@
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var ColorPropType = require('ColorPropType');
|
||||
var ImageResizeMode = require('ImageResizeMode');
|
||||
var LayoutPropTypes = require('LayoutPropTypes');
|
||||
var ReactPropTypes = require('prop-types');
|
||||
var ColorPropType = require('ColorPropType');
|
||||
var ShadowPropTypesIOS = require('ShadowPropTypesIOS');
|
||||
var TransformPropTypes = require('TransformPropTypes');
|
||||
|
||||
var ReactPropTypes = require('React').PropTypes;
|
||||
|
||||
var ImageStylePropTypes = {
|
||||
...LayoutPropTypes,
|
||||
...ShadowPropTypesIOS,
|
||||
|
||||
@@ -29,8 +29,6 @@
|
||||
354631681B69857700AA0B86 /* RCTImageEditingManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 354631671B69857700AA0B86 /* RCTImageEditingManager.m */; };
|
||||
3D302E181DF8228100D6DDAE /* RCTImageUtils.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 134B00A01B54232B00EC8DFB /* RCTImageUtils.h */; };
|
||||
3D302F211DF8269200D6DDAE /* RCTImageUtils.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 134B00A01B54232B00EC8DFB /* RCTImageUtils.h */; };
|
||||
3DA05A5A1EE0312600805843 /* RCTImageShadowView.h in Headers */ = {isa = PBXBuildFile; fileRef = 59AB09281EDE5DD1009F97B5 /* RCTImageShadowView.h */; };
|
||||
3DA05A5B1EE0312900805843 /* RCTImageShadowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 59AB09291EDE5DD1009F97B5 /* RCTImageShadowView.m */; };
|
||||
3DED3A8A1DE6F79800336DD7 /* RCTGIFImageDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 1304D5B01AA8C50D0002E2BE /* RCTGIFImageDecoder.h */; };
|
||||
3DED3A8B1DE6F79800336DD7 /* RCTImageBlurUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = EEF314701C9B0DD30049118E /* RCTImageBlurUtils.h */; };
|
||||
3DED3A8C1DE6F79800336DD7 /* RCTImageCache.h in Headers */ = {isa = PBXBuildFile; fileRef = CCD34C251D4B8FE900268922 /* RCTImageCache.h */; };
|
||||
@@ -53,8 +51,6 @@
|
||||
3DED3A9E1DE6F7A400336DD7 /* RCTImageViewManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 1304D5A91AA8C4A30002E2BE /* RCTImageViewManager.h */; };
|
||||
3DED3A9F1DE6F7A400336DD7 /* RCTLocalAssetImageLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 13EF7F7D1BC825B1003F47DD /* RCTLocalAssetImageLoader.h */; };
|
||||
3DED3AA01DE6F7A400336DD7 /* RCTResizeMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 3D5FA63E1DE4B44A0058FD77 /* RCTResizeMode.h */; };
|
||||
59AB092A1EDE5DD1009F97B5 /* RCTImageShadowView.h in Headers */ = {isa = PBXBuildFile; fileRef = 59AB09281EDE5DD1009F97B5 /* RCTImageShadowView.h */; };
|
||||
59AB092B1EDE5DD1009F97B5 /* RCTImageShadowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 59AB09291EDE5DD1009F97B5 /* RCTImageShadowView.m */; };
|
||||
CCD34C271D4B8FE900268922 /* RCTImageCache.m in Sources */ = {isa = PBXBuildFile; fileRef = CCD34C261D4B8FE900268922 /* RCTImageCache.m */; };
|
||||
EEF314721C9B0DD30049118E /* RCTImageBlurUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = EEF314711C9B0DD30049118E /* RCTImageBlurUtils.m */; };
|
||||
/* End PBXBuildFile section */
|
||||
@@ -106,8 +102,6 @@
|
||||
3D5FA63E1DE4B44A0058FD77 /* RCTResizeMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTResizeMode.h; sourceTree = "<group>"; };
|
||||
3D5FA68C1DE4BA290058FD77 /* libRCTNetwork.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libRCTNetwork.a; path = "../Network/build/Debug-iphoneos/libRCTNetwork.a"; sourceTree = "<group>"; };
|
||||
58B5115D1A9E6B3D00147676 /* libRCTImage.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRCTImage.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
59AB09281EDE5DD1009F97B5 /* RCTImageShadowView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTImageShadowView.h; sourceTree = "<group>"; };
|
||||
59AB09291EDE5DD1009F97B5 /* RCTImageShadowView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTImageShadowView.m; sourceTree = "<group>"; };
|
||||
CCD34C251D4B8FE900268922 /* RCTImageCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = RCTImageCache.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
|
||||
CCD34C261D4B8FE900268922 /* RCTImageCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTImageCache.m; sourceTree = "<group>"; };
|
||||
EEF314701C9B0DD30049118E /* RCTImageBlurUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = RCTImageBlurUtils.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
|
||||
@@ -126,8 +120,6 @@
|
||||
58B511541A9E6B3D00147676 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
3D5FA68B1DE4BA290058FD77 /* Frameworks */,
|
||||
58B5115E1A9E6B3D00147676 /* Products */,
|
||||
1304D5B01AA8C50D0002E2BE /* RCTGIFImageDecoder.h */,
|
||||
1304D5B11AA8C50D0002E2BE /* RCTGIFImageDecoder.m */,
|
||||
EEF314701C9B0DD30049118E /* RCTImageBlurUtils.h */,
|
||||
@@ -138,8 +130,6 @@
|
||||
354631671B69857700AA0B86 /* RCTImageEditingManager.m */,
|
||||
3D5FA63C1DE4B44A0058FD77 /* RCTImageLoader.h */,
|
||||
143879371AAD32A300F088A5 /* RCTImageLoader.m */,
|
||||
59AB09281EDE5DD1009F97B5 /* RCTImageShadowView.h */,
|
||||
59AB09291EDE5DD1009F97B5 /* RCTImageShadowView.m */,
|
||||
3D5FA63D1DE4B44A0058FD77 /* RCTImageStoreManager.h */,
|
||||
35123E6A1B59C99D00EBAD80 /* RCTImageStoreManager.m */,
|
||||
134B00A01B54232B00EC8DFB /* RCTImageUtils.h */,
|
||||
@@ -152,6 +142,8 @@
|
||||
13EF7F7E1BC825B1003F47DD /* RCTLocalAssetImageLoader.m */,
|
||||
3D5FA63E1DE4B44A0058FD77 /* RCTResizeMode.h */,
|
||||
139A38831C4D587C00862840 /* RCTResizeMode.m */,
|
||||
58B5115E1A9E6B3D00147676 /* Products */,
|
||||
3D5FA68B1DE4BA290058FD77 /* Frameworks */,
|
||||
);
|
||||
indentWidth = 2;
|
||||
sourceTree = "<group>";
|
||||
@@ -180,7 +172,6 @@
|
||||
3DED3A8D1DE6F79800336DD7 /* RCTImageEditingManager.h in Headers */,
|
||||
3DED3A8E1DE6F79800336DD7 /* RCTImageLoader.h in Headers */,
|
||||
3DED3A8F1DE6F79800336DD7 /* RCTImageStoreManager.h in Headers */,
|
||||
59AB092A1EDE5DD1009F97B5 /* RCTImageShadowView.h in Headers */,
|
||||
3DED3A911DE6F79800336DD7 /* RCTImageView.h in Headers */,
|
||||
3DED3A921DE6F79800336DD7 /* RCTImageViewManager.h in Headers */,
|
||||
3DED3A931DE6F79800336DD7 /* RCTLocalAssetImageLoader.h in Headers */,
|
||||
@@ -199,7 +190,6 @@
|
||||
3DED3A9A1DE6F7A400336DD7 /* RCTImageLoader.h in Headers */,
|
||||
3DED3A9B1DE6F7A400336DD7 /* RCTImageStoreManager.h in Headers */,
|
||||
3DED3A9C1DE6F7A400336DD7 /* RCTImageUtils.h in Headers */,
|
||||
3DA05A5A1EE0312600805843 /* RCTImageShadowView.h in Headers */,
|
||||
3DED3A9D1DE6F7A400336DD7 /* RCTImageView.h in Headers */,
|
||||
3DED3A9E1DE6F7A400336DD7 /* RCTImageViewManager.h in Headers */,
|
||||
3DED3A9F1DE6F7A400336DD7 /* RCTLocalAssetImageLoader.h in Headers */,
|
||||
@@ -293,7 +283,6 @@
|
||||
2D3B5F1C1D9B0D1300451313 /* RCTResizeMode.m in Sources */,
|
||||
2D3B5F221D9B0D1300451313 /* RCTImageViewManager.m in Sources */,
|
||||
2D3B5F211D9B0D1300451313 /* RCTImageView.m in Sources */,
|
||||
3DA05A5B1EE0312900805843 /* RCTImageShadowView.m in Sources */,
|
||||
2D3B5F201D9B0D1300451313 /* RCTImageLoader.m in Sources */,
|
||||
2D3B5F1B1D9B0D0700451313 /* RCTImageBlurUtils.m in Sources */,
|
||||
2D3B5F241D9B0D1300451313 /* RCTImageUtils.m in Sources */,
|
||||
@@ -312,7 +301,6 @@
|
||||
139A38841C4D587C00862840 /* RCTResizeMode.m in Sources */,
|
||||
1304D5AB1AA8C4A30002E2BE /* RCTImageView.m in Sources */,
|
||||
EEF314721C9B0DD30049118E /* RCTImageBlurUtils.m in Sources */,
|
||||
59AB092B1EDE5DD1009F97B5 /* RCTImageShadowView.m in Sources */,
|
||||
13EF7F7F1BC825B1003F47DD /* RCTLocalAssetImageLoader.m in Sources */,
|
||||
134B00A21B54232B00EC8DFB /* RCTImageUtils.m in Sources */,
|
||||
CCD34C271D4B8FE900268922 /* RCTImageCache.m in Sources */,
|
||||
@@ -329,6 +317,7 @@
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVES = YES;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
@@ -347,6 +336,7 @@
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVES = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
@@ -457,7 +447,9 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_STATIC_ANALYZER_MODE = deep;
|
||||
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
);
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_NAME = RCTImage;
|
||||
PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/RCTImage;
|
||||
@@ -469,7 +461,9 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_STATIC_ANALYZER_MODE = deep;
|
||||
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
);
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_NAME = RCTImage;
|
||||
PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/RCTImage;
|
||||
|
||||
+585
-609
File diff suppressed because it is too large
Load Diff
@@ -1,25 +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.
|
||||
*/
|
||||
|
||||
#import "RCTImageShadowView.h"
|
||||
|
||||
#import <React/RCTLog.h>
|
||||
|
||||
@implementation RCTImageShadowView
|
||||
|
||||
- (void)insertReactSubview:(RCTShadowView *)subview atIndex:(NSInteger)atIndex
|
||||
{
|
||||
RCTLogWarn(@"Using <Image> with children is deprecated "
|
||||
"and will be an error in the near future. "
|
||||
"Please reconsider the layout or use <ImageBackground> instead.");
|
||||
|
||||
[super insertReactSubview:subview atIndex:atIndex];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -14,18 +14,12 @@
|
||||
#import <React/RCTConvert.h>
|
||||
|
||||
#import "RCTImageLoader.h"
|
||||
#import "RCTImageShadowView.h"
|
||||
#import "RCTImageView.h"
|
||||
|
||||
@implementation RCTImageViewManager
|
||||
|
||||
RCT_EXPORT_MODULE()
|
||||
|
||||
- (RCTShadowView *)shadowView
|
||||
{
|
||||
return [RCTImageShadowView new];
|
||||
}
|
||||
|
||||
- (UIView *)view
|
||||
{
|
||||
return [[RCTImageView alloc] initWithBridge:self.bridge];
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user