mirror of
https://github.com/zhigang1992/react-native-web.git
synced 2026-03-31 10:11:38 +08:00
Compare commits
55 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c122814591 | ||
|
|
efe18f1b7e | ||
|
|
e1b576e427 | ||
|
|
5d77d6e30f | ||
|
|
8fb9a88ee6 | ||
|
|
a7cda988ef | ||
|
|
b239cfb04d | ||
|
|
8e94d858b2 | ||
|
|
aa22b06359 | ||
|
|
2aa565c7c3 | ||
|
|
7b9b57960d | ||
|
|
eae3ee9dca | ||
|
|
74e1a196b6 | ||
|
|
48da9814e7 | ||
|
|
4d391ef57c | ||
|
|
780df69a80 | ||
|
|
6c229da01f | ||
|
|
ae7aa818fb | ||
|
|
306cf67932 | ||
|
|
619c2048be | ||
|
|
b9f9a4f8d7 | ||
|
|
58bc18c2f5 | ||
|
|
073940fc4e | ||
|
|
5c462303de | ||
|
|
5fb92da317 | ||
|
|
cafe10d851 | ||
|
|
b28581f44e | ||
|
|
9333e7e887 | ||
|
|
b28cbbb37e | ||
|
|
a53372ceb3 | ||
|
|
239a43978f | ||
|
|
b4e4bfbb3c | ||
|
|
893963a799 | ||
|
|
e5adc5a37c | ||
|
|
6d908189a7 | ||
|
|
31db333ba3 | ||
|
|
9fe089ca21 | ||
|
|
a314d5b2e4 | ||
|
|
fb845ebf44 | ||
|
|
0d0c7e6e27 | ||
|
|
f37003a079 | ||
|
|
f1fc2a9e37 | ||
|
|
92794cdc9f | ||
|
|
b754776373 | ||
|
|
155b34e495 | ||
|
|
00c9dc4236 | ||
|
|
b66aba1a06 | ||
|
|
17f8a674b8 | ||
|
|
b8080ba775 | ||
|
|
7265736545 | ||
|
|
399f465e59 | ||
|
|
9ee89bc7f7 | ||
|
|
748b2d0f3f | ||
|
|
fb4635e013 | ||
|
|
73b459e770 |
45
LICENSE
45
LICENSE
@@ -1,31 +1,22 @@
|
||||
BSD License
|
||||
MIT License
|
||||
|
||||
For React Native software
|
||||
Copyright (c) 2015-present, Nicolas Gallagher.
|
||||
Copyright (c) 2015-present, Facebook, Inc.
|
||||
|
||||
Copyright (c) 2015-present, Nicolas Gallagher. All rights reserved.
|
||||
Copyright (c) 2015-present, Facebook, Inc. All rights reserved.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name Facebook nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this software without specific
|
||||
prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
24
README.md
24
README.md
@@ -19,21 +19,19 @@ rewriting existing code. React Native for Web can also render to HTML and
|
||||
critical CSS on the server using Node.js.
|
||||
|
||||
Who is using React Native for Web? [Twitter](https://mobile.twitter.com),
|
||||
[Major League Soccer](https://matchcenter.mlssoccer.com), [The
|
||||
[Major League Soccer](https://matchcenter.mlssoccer.com),
|
||||
[Flipkart](https://www.flipkart.com/), Playstation, Uber, [The
|
||||
Times](https://github.com/newsuk/times-components), [React Native's
|
||||
documentation](http://facebook.github.io/react-native/).
|
||||
|
||||
Browser support: Chrome, Firefox, Safari >= 7, IE 10, Edge.
|
||||
Browser support: Chrome, Firefox, Edge, Safari 7+, IE 10+.
|
||||
|
||||
## Quick start
|
||||
|
||||
The easiest way to get started with React Native for Web is to use this
|
||||
[ready-to-go project on Glitch](https://glitch.com/edit/#!/react-native-web-playground).
|
||||
[ready-to-go project on Glitch](https://glitch.com/edit/#!/react-native).
|
||||
You don’t need to install anything to try it out.
|
||||
|
||||
If you are unfamiliar with setting up a React web project, please follow the
|
||||
recommendations in the [React documentation](https://reactjs.org/).
|
||||
|
||||
## Documentation
|
||||
|
||||
You can find the React Native for Web API documentation [on the
|
||||
@@ -97,6 +95,16 @@ You'll notice that there is no reference to `react-dom`; the `App` component is
|
||||
defined using the platform-agnostic APIs and Components introduced by React
|
||||
Native. This allows the app to be rendered to web and native platforms.
|
||||
|
||||
## Integrations
|
||||
|
||||
Examples of using React Native for Web with other web tools:
|
||||
|
||||
* [Next.js](https://github.com/zeit/next.js/tree/master/examples/with-react-native-web)
|
||||
* [Storybook](https://github.com/necolas/react-native-web/tree/0.5.1/website/storybook/.storybook)
|
||||
* [Razzle](https://github.com/jaredpalmer/razzle/tree/master/examples/with-react-native-web)
|
||||
* [Phenomic](https://github.com/phenomic/phenomic/tree/v1.0.0-alpha.20/docs)
|
||||
* [Styleguidist](https://github.com/styleguidist/react-styleguidist/tree/v6.2.6/examples/react-native)
|
||||
|
||||
## Contributing
|
||||
|
||||
The main purpose of this repository is to help evolve React web and native
|
||||
@@ -126,7 +134,9 @@ relatively limited scope. This is a great place to get started.
|
||||
|
||||
## License
|
||||
|
||||
React Native for Web is [BSD licensed](./LICENSE).
|
||||
React Native for Web is [MIT licensed](./LICENSE). By contributing to React
|
||||
Native for Web, you agree that your contributions will be licensed under its
|
||||
MIT license.
|
||||
|
||||
[package-badge]: https://img.shields.io/npm/v/react-native-web.svg?style=flat
|
||||
[package-url]: https://yarnpkg.com/en/package/react-native-web
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"private": true,
|
||||
"version": "0.4.0",
|
||||
"version": "0.5.4",
|
||||
"name": "react-native-web-monorepo",
|
||||
"scripts": {
|
||||
"clean": "del ./packages/*/dist",
|
||||
@@ -19,7 +19,7 @@
|
||||
"prerelease": "yarn test && yarn compile",
|
||||
"release": "node ./scripts/release/publish.js",
|
||||
"postrelease": "yarn website:release && yarn benchmarks:release",
|
||||
"test": "yarn flow && yarn lint:check && yarn jest"
|
||||
"test": "yarn flow && yarn lint:check && yarn jest --runInBand"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-cli": "^6.26.0",
|
||||
@@ -62,6 +62,9 @@
|
||||
"fmt:cmd",
|
||||
"git update-index --again",
|
||||
"eslint"
|
||||
],
|
||||
"packages/react-native-web/src/index.js": [
|
||||
"node ./scripts/babel/createModuleMap.js"
|
||||
]
|
||||
},
|
||||
"prettier": {
|
||||
@@ -69,5 +72,5 @@
|
||||
"singleQuote": true
|
||||
},
|
||||
"author": "Nicolas Gallagher",
|
||||
"license": "BSD-3-Clause"
|
||||
"license": "MIT"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "babel-plugin-react-native-web",
|
||||
"version": "0.4.0",
|
||||
"version": "0.5.4",
|
||||
"description": "Babel plugin for React Native for Web",
|
||||
"main": "index.js",
|
||||
"devDependencies": {
|
||||
|
||||
@@ -41,7 +41,7 @@ import * as ReactNativeModules from 'react-native';
|
||||
|
||||
import ReactNative from 'react-native-web/dist/index';
|
||||
import View from 'react-native-web/dist/exports/View';
|
||||
import Invalid from 'react-native-web/dist/exports/Invalid';
|
||||
import { Invalid } from 'react-native-web/dist/index';
|
||||
import MyView from 'react-native-web/dist/exports/View';
|
||||
import ViewPropTypes from 'react-native-web/dist/exports/ViewPropTypes';
|
||||
import * as ReactNativeModules from 'react-native-web/dist/index';
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
const moduleMap = require('./moduleMap');
|
||||
|
||||
const getDistLocation = importName =>
|
||||
importName ? `react-native-web/dist/exports/${importName}` : undefined;
|
||||
importName && moduleMap[importName] ? `react-native-web/dist/exports/${importName}` : undefined;
|
||||
|
||||
const isReactNativeRequire = (t, node) => {
|
||||
const { declarations } = node;
|
||||
|
||||
61
packages/babel-plugin-react-native-web/src/moduleMap.js
Normal file
61
packages/babel-plugin-react-native-web/src/moduleMap.js
Normal file
@@ -0,0 +1,61 @@
|
||||
// THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT.
|
||||
module.exports = {
|
||||
ART: true,
|
||||
ActivityIndicator: true,
|
||||
Animated: true,
|
||||
AppRegistry: true,
|
||||
AppState: true,
|
||||
AsyncStorage: true,
|
||||
BackHandler: true,
|
||||
Button: true,
|
||||
CheckBox: true,
|
||||
Clipboard: true,
|
||||
ColorPropType: true,
|
||||
Dimensions: true,
|
||||
Easing: true,
|
||||
EdgeInsetsPropType: true,
|
||||
FlatList: true,
|
||||
I18nManager: true,
|
||||
Image: true,
|
||||
ImageBackground: true,
|
||||
InteractionManager: true,
|
||||
Keyboard: true,
|
||||
KeyboardAvoidingView: true,
|
||||
Linking: true,
|
||||
ListView: true,
|
||||
Modal: true,
|
||||
NativeModules: true,
|
||||
NetInfo: true,
|
||||
PanResponder: true,
|
||||
Picker: true,
|
||||
PixelRatio: true,
|
||||
Platform: true,
|
||||
PointPropType: true,
|
||||
ProgressBar: true,
|
||||
RefreshControl: true,
|
||||
SafeAreaView: true,
|
||||
ScrollView: true,
|
||||
SectionList: true,
|
||||
Slider: true,
|
||||
StatusBar: true,
|
||||
StyleSheet: true,
|
||||
Switch: true,
|
||||
Text: true,
|
||||
TextInput: true,
|
||||
TextPropTypes: true,
|
||||
Touchable: true,
|
||||
TouchableHighlight: true,
|
||||
TouchableNativeFeedback: true,
|
||||
TouchableOpacity: true,
|
||||
TouchableWithoutFeedback: true,
|
||||
UIManager: true,
|
||||
Vibration: true,
|
||||
View: true,
|
||||
ViewPropTypes: true,
|
||||
VirtualizedList: true,
|
||||
createElement: true,
|
||||
findNodeHandle: true,
|
||||
processColor: true,
|
||||
render: true,
|
||||
unmountComponentAtNode: true
|
||||
};
|
||||
@@ -19,12 +19,9 @@ yarn benchmarks --watch
|
||||
## Notes
|
||||
|
||||
These benchmarks are approximations of extreme cases that libraries may
|
||||
encounter. The deep and wide tree cases look at the performance of mounting and
|
||||
rendering large trees of styled elements. The dynamic case looks at the
|
||||
performance of repeated style updates to a large mounted tree. Some libraries
|
||||
must inject new styles for each "dynamic style", whereas others may not.
|
||||
Libraries without support for dynamic styles (i.e., they rely on user-authored
|
||||
inline styles) do not include a corresponding benchmark.
|
||||
encounter. Their purpose is to provide an early-warning signal for performance
|
||||
regressions. Each test report includes the mean and standard deviation of the
|
||||
timings, and approximations of the time spent in scripting (S) and layout (L).
|
||||
|
||||
The components used in the render benchmarks are simple enough to be
|
||||
implemented by multiple UI or style libraries. The benchmark implementations
|
||||
@@ -33,6 +30,19 @@ functionality_.
|
||||
|
||||
No benchmark will run for more than 20 seconds.
|
||||
|
||||
### Mount deep/wide tree
|
||||
|
||||
These cases look at the performance of mounting and rendering large trees of
|
||||
elements that use static styles.
|
||||
|
||||
### Update dynamic styles
|
||||
|
||||
This case looks at the performance of repeated style updates to a large mounted
|
||||
tree. Some libraries choose to inject new styles for each "dynamic style",
|
||||
whereas others choose to use inline styles. Libraries without built-in support
|
||||
for dynamic styles (i.e., they rely on user-authored inline styles) are not
|
||||
included.
|
||||
|
||||
## Example results
|
||||
|
||||
### MacBook Pro (2011)
|
||||
@@ -41,52 +51,20 @@ MacBook Pro (13-inch, Early 2011); 2.3 GHz Intel Core i5; 8 GB 1333 MHz DDR3 RAM
|
||||
|
||||
Typical render timings: mean ± standard deviations.
|
||||
|
||||
| Implementation | Mount deep tree (ms) | Mount wide tree (ms) | Dynamic update (ms) |
|
||||
| Implementation | Mount deep tree (ms) | Mount wide tree (ms) | Dynamic update (ms) |
|
||||
| :--- | ---: | ---: | ---: |
|
||||
| `css-modules` | `15.23` `±04.31` | `21.27` `±07.03` | - |
|
||||
| `react-native-web@0.3.2` | `17.52` `±04.44` | `24.14` `±04.39` | `15.03` `±02.22` |
|
||||
| `inline-styles` | `50.06` `±06.70` | `76.38` `±09.58` | `06.43` `±02.02` |
|
||||
|
||||
Other libraries
|
||||
|
||||
| Implementation | Mount deep tree (ms) | Mount wide tree (ms) | Dynamic update (ms) |
|
||||
| :--- | ---: | ---: | ---: |
|
||||
| `aphrodite@1.2.5` | `17.27` `±05.96` | `24.89` `±08.36` | - |
|
||||
| `glamor@2.20.40` | `21.59` `±05.38` | `27.93` `±07.56` | ‡ |
|
||||
| `emotion@8.0.12` | `21.07` `±04.16` | `31.40` `±09.40` | ‡ `19.80` `±13.56` |
|
||||
| `styletron-react@3.0.3` | `23.55` `±05.14` | `34.26` `±07.58` | `10.39` `±02.94` |
|
||||
| `react-fela@5.0.0` | `27.58` `±04.26` | `39.54` `±05.46` | `10.93` `±01.69` |
|
||||
| `react-jss@8.2.1` | `27.31` `±07.87` | `40.74` `±10.67` | - |
|
||||
| `styled-jsx@2.2.1` | `27.46` `±07.85` | `41.47` `±11.53` | `29.16` `±09.98` |
|
||||
| `styled-components@2.4.0` | `43.89` `±06.99` | `63.26` `±09.02` | `16.17` `±03.71` |
|
||||
| `reactxp@0.51.0-alpha.9` | `51.86` `±07.21` | `78.80` `±11.85` | `15.04` `±03.92` |
|
||||
| `radium@0.21.0` | `101.06` `±13.00` | `144.46` `±16.94` | `17.44` `±03.59` |
|
||||
| `css-modules` | `30.19` `±04.84` | `38.25` `±04.85` | - |
|
||||
| `react-native-web@0.4.0` | `36.40` `±04.98` | `51.28` `±05.58` | `19.36` `±02.56` |
|
||||
| `inline-styles` | `64.12` `±07.69` | `94.49` `±11.34` | `09.84` `±02.36` |
|
||||
|
||||
### Moto G4
|
||||
|
||||
Moto G4 (Android 7); Octa-core (4x1.5 GHz & 4x1.2 Ghz); 2 GB RAM. Google Chrome 63
|
||||
Moto G4 (Android 7); Octa-core (4x1.5 GHz & 4x1.2 Ghz); 2 GB RAM. Google Chrome 63.
|
||||
|
||||
Typical render timings: mean ± standard deviations.
|
||||
|
||||
| Implementation | Mount deep tree (ms) | Mount wide tree (ms) | Dynamic update (ms) |
|
||||
| Implementation | Mount deep tree (ms) | Mount wide tree (ms) | Dynamic update (ms) |
|
||||
| :--- | ---: | ---: | ---: |
|
||||
| `css-modules` | `56.18` `±19.54` | `75.95` `±23.55` | - |
|
||||
| `react-native-web@0.3.2` | `68.53` `±21.00` | `101.03` `±25.32` | `60.57` `±09.07` |
|
||||
| `inline-styles` | `140.32` `±23.91` | `208.55` `±35.25` | `20.36` `±04.92` |
|
||||
|
||||
Other libraries
|
||||
|
||||
| Implementation | Mount deep tree (ms) | Mount wide tree (ms) | Dynamic update (ms) |
|
||||
| :--- | ---: | ---: | ---: |
|
||||
| `aphrodite@1.2.5` | `58.77` `±19.73` | `85.83` `±24.64` | - |
|
||||
| `glamor@2.20.40` | `81.05` `±15.87` | `104.02` `±20.92` | ‡ |
|
||||
| `emotion@8.0.12` | `77.12` `±19.61` | `112.04` `±24.43` | ‡ `80.40` `±40.56` |
|
||||
| `styletron-react@3.0.3` | `91.00` `±17.95` | `130.49` `±20.06` | `39.70` `±06.85` |
|
||||
| `react-fela@5.0.0` | `101.36` `±19.55` | `142.18` `±21.87` | `43.64` `±12.24` |
|
||||
| `styled-jsx@2.2.1` | `101.60` `±25.26` | `144.12` `±30.79` | `115.63` `±32.77` |
|
||||
| `react-jss@8.2.1` | `112.46` `±32.07` | `165.96` `±42.54` | - |
|
||||
| `styled-components@2.4.0` | `159.85` `±24.30` | `231.00` `±31.34` | `53.86` `±13.40` |
|
||||
| `reactxp@0.51.0-alpha.9` | `182.05` `±30.72` | `261.25` `±35.54` | `58.20` `±08.62` |
|
||||
| `radium@0.21.0` | `323.93` `±41.46` | `464.70` `±53.93` | `59.13` `±09.76` |
|
||||
|
||||
‡Glamor essentially crashes the browser tab. Emotion gets slower every iteration.
|
||||
| `css-modules` | `98.24` `±20.26` | `143.75` `±25.50` | - |
|
||||
| `react-native-web@0.4.0` | `131.46` `±18.96` | `174.70` `±14.88` | `60.87` `±06.32` |
|
||||
| `inline-styles` | `184.58` `±26.23` | `273.86` `±26.23` | `30.28` `±07.44` |
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "benchmarks",
|
||||
"version": "0.4.0",
|
||||
"version": "0.5.4",
|
||||
"scripts": {
|
||||
"build": "mkdir -p dist && cp -f index.html dist/index.html && webpack --config ./webpack.config.js",
|
||||
"release": "yarn build && git checkout gh-pages && rm -rf ../../benchmarks && mv dist ../../benchmarks && git add -A && git commit -m \"Benchmarks deploy\" && git push origin gh-pages && git checkout -"
|
||||
@@ -9,28 +9,27 @@
|
||||
"dependencies": {
|
||||
"aphrodite": "1.2.5",
|
||||
"classnames": "^2.2.5",
|
||||
"d3-scale-chromatic": "^1.1.1",
|
||||
"emotion": "8.0.12",
|
||||
"fela": "6.1.3",
|
||||
"d3-scale-chromatic": "^1.2.0",
|
||||
"emotion": "^9.0.2",
|
||||
"fela": "^6.1.4",
|
||||
"glamor": "2.20.40",
|
||||
"radium": "0.21.2",
|
||||
"radium": "^0.22.1",
|
||||
"react": "^16.2.0",
|
||||
"react-component-benchmark": "^0.0.4",
|
||||
"react-dom": "^16.2.0",
|
||||
"react-fela": "6.2.4",
|
||||
"react-jss": "8.2.1",
|
||||
"react-native-web": "0.4.0",
|
||||
"reactxp": "0.51.2",
|
||||
"style-loader": "0.20.1",
|
||||
"styled-components": "3.1.2",
|
||||
"styled-jsx": "2.2.2",
|
||||
"styletron-client": "3.0.4",
|
||||
"styletron-react": "3.0.4"
|
||||
"react-fela": "^7.0.1",
|
||||
"react-jss": "^8.3.3",
|
||||
"react-native-web": "0.5.4",
|
||||
"reactxp": "^1.0.0",
|
||||
"styled-components": "^3.2.0",
|
||||
"styled-jsx": "^2.2.5",
|
||||
"styletron-engine-atomic": "^1.0.0",
|
||||
"styletron-react": "^4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-plugin-react-native-web": "0.4.0",
|
||||
"css-loader": "^0.28.9",
|
||||
"style-loader": "^0.19.1",
|
||||
"babel-plugin-react-native-web": "0.5.4",
|
||||
"css-loader": "^0.28.10",
|
||||
"style-loader": "^0.20.2",
|
||||
"webpack": "^3.10.0",
|
||||
"webpack-bundle-analyzer": "^2.9.2"
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ class ReportCard extends React.PureComponent {
|
||||
{fmt(mean)} ±{fmt(stdDev)} ms
|
||||
</Text>
|
||||
<Text style={[styles.smallText, styles.monoFont]}>
|
||||
(S/L) {fmt(meanScripting)} / {fmt(meanLayout)} ms
|
||||
(S/L) {fmt(meanScripting)}/{fmt(meanLayout)} ms
|
||||
</Text>
|
||||
</Fragment>
|
||||
) : (
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/* eslint-disable react/prop-types */
|
||||
import { styled } from 'styletron-react';
|
||||
import { withStyle } from 'styletron-react';
|
||||
import View from './View';
|
||||
|
||||
const Box = styled(
|
||||
const Box = withStyle(
|
||||
View,
|
||||
({ color, fixed = false, layout = 'column', outer = false, ...other }) => ({
|
||||
...styles[`color${color}`],
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* eslint-disable react/prop-types */
|
||||
import React from 'react';
|
||||
import Styletron from 'styletron-client';
|
||||
import { StyletronProvider } from 'styletron-react';
|
||||
import { Client as Styletron } from 'styletron-engine-atomic';
|
||||
import { Provider as StyletronProvider } from 'styletron-react';
|
||||
import View from './View';
|
||||
|
||||
const styletron = new Styletron();
|
||||
@@ -9,7 +9,7 @@ const styletron = new Styletron();
|
||||
class Provider extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<StyletronProvider styletron={styletron}>
|
||||
<StyletronProvider value={styletron}>
|
||||
<View>{this.props.children}</View>
|
||||
</StyletronProvider>
|
||||
);
|
||||
|
||||
@@ -39,7 +39,7 @@ exports[`enzyme.mount complex 1`] = `
|
||||
}
|
||||
>
|
||||
<div
|
||||
className="rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-color-1bodaif rn-display-1471scf rn-font-1lw9tu2 rn-fontFamily-10u92zi rn-fontSize-ubezar rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-paddingTop-wk8lta rn-paddingRight-9aemit rn-paddingBottom-1mdbw0j rn-paddingLeft-gy4na3 rn-verticalAlign-9iso6 rn-textDecoration-bauka4 rn-whiteSpace-q42fyq rn-wordWrap-qvutc0"
|
||||
className="rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-color-1bodaif rn-display-1471scf rn-font-1lw9tu2 rn-fontFamily-14xgk7a rn-fontSize-ubezar rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-paddingTop-wk8lta rn-paddingRight-9aemit rn-paddingBottom-1mdbw0j rn-paddingLeft-gy4na3 rn-verticalAlign-9iso6 rn-textDecoration-bauka4 rn-whiteSpace-q42fyq rn-wordWrap-qvutc0"
|
||||
dir="auto"
|
||||
>
|
||||
Hello World
|
||||
@@ -63,7 +63,7 @@ exports[`enzyme.mount complex 1`] = `
|
||||
</View>
|
||||
<Text>
|
||||
<div
|
||||
className="rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-color-homxoj rn-display-1471scf rn-font-1lw9tu2 rn-fontFamily-10u92zi rn-fontSize-1b43r93 rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-paddingTop-wk8lta rn-paddingRight-9aemit rn-paddingBottom-1mdbw0j rn-paddingLeft-gy4na3 rn-textDecoration-bauka4 rn-whiteSpace-q42fyq rn-wordWrap-qvutc0"
|
||||
className="rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-color-homxoj rn-display-1471scf rn-font-1lw9tu2 rn-fontFamily-14xgk7a rn-fontSize-1b43r93 rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-paddingTop-wk8lta rn-paddingRight-9aemit rn-paddingBottom-1mdbw0j rn-paddingLeft-gy4na3 rn-textDecoration-bauka4 rn-whiteSpace-q42fyq rn-wordWrap-qvutc0"
|
||||
dir="auto"
|
||||
>
|
||||
Nested
|
||||
@@ -117,7 +117,7 @@ exports[`enzyme.mount nested 1`] = `
|
||||
}
|
||||
>
|
||||
<div
|
||||
className="rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-color-1bodaif rn-display-1471scf rn-font-1lw9tu2 rn-fontFamily-10u92zi rn-fontSize-ubezar rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-paddingTop-wk8lta rn-paddingRight-9aemit rn-paddingBottom-1mdbw0j rn-paddingLeft-gy4na3 rn-verticalAlign-9iso6 rn-textDecoration-bauka4 rn-whiteSpace-q42fyq rn-wordWrap-qvutc0"
|
||||
className="rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-color-1bodaif rn-display-1471scf rn-font-1lw9tu2 rn-fontFamily-14xgk7a rn-fontSize-ubezar rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-paddingTop-wk8lta rn-paddingRight-9aemit rn-paddingBottom-1mdbw0j rn-paddingLeft-gy4na3 rn-verticalAlign-9iso6 rn-textDecoration-bauka4 rn-whiteSpace-q42fyq rn-wordWrap-qvutc0"
|
||||
dir="auto"
|
||||
>
|
||||
Hello World
|
||||
@@ -142,7 +142,7 @@ exports[`enzyme.render complex 1`] = `
|
||||
class="rn-alignItems-1oszu61 rn-backgroundColor-1mjtqww rn-borderTopStyle-1efd50x rn-borderRightStyle-14skgim rn-borderBottomStyle-rull8r rn-borderLeftStyle-mm0ijv rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-display-6koalj rn-flexShrink-1pxmb3b rn-flexBasis-7vfszb rn-flexDirection-eqz5dr rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-minHeight-ifefl9 rn-minWidth-bcqeeo rn-paddingTop-m611by rn-paddingRight-1qfoi16 rn-paddingBottom-1mi0q7o rn-paddingLeft-1hfyk0a rn-position-bnwqim rn-zIndex-1lgpqti"
|
||||
>
|
||||
<div
|
||||
class="rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-color-1bodaif rn-display-1471scf rn-font-1lw9tu2 rn-fontFamily-10u92zi rn-fontSize-ubezar rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-paddingTop-wk8lta rn-paddingRight-9aemit rn-paddingBottom-1mdbw0j rn-paddingLeft-gy4na3 rn-verticalAlign-9iso6 rn-textDecoration-bauka4 rn-whiteSpace-q42fyq rn-wordWrap-qvutc0"
|
||||
class="rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-color-1bodaif rn-display-1471scf rn-font-1lw9tu2 rn-fontFamily-14xgk7a rn-fontSize-ubezar rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-paddingTop-wk8lta rn-paddingRight-9aemit rn-paddingBottom-1mdbw0j rn-paddingLeft-gy4na3 rn-verticalAlign-9iso6 rn-textDecoration-bauka4 rn-whiteSpace-q42fyq rn-wordWrap-qvutc0"
|
||||
dir="auto"
|
||||
>
|
||||
Hello World
|
||||
@@ -154,7 +154,7 @@ exports[`enzyme.render complex 1`] = `
|
||||
class="rn-alignItems-1oszu61 rn-borderTopStyle-1efd50x rn-borderRightStyle-14skgim rn-borderBottomStyle-rull8r rn-borderLeftStyle-mm0ijv rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-display-6koalj rn-flexShrink-1pxmb3b rn-flexBasis-7vfszb rn-flexDirection-eqz5dr rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-minHeight-ifefl9 rn-minWidth-bcqeeo rn-paddingTop-1knelpx rn-paddingRight-1ah4tor rn-paddingBottom-k8qxaj rn-paddingLeft-b5h31w rn-position-bnwqim rn-zIndex-1lgpqti"
|
||||
/>
|
||||
<div
|
||||
class="rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-color-homxoj rn-display-1471scf rn-font-1lw9tu2 rn-fontFamily-10u92zi rn-fontSize-1b43r93 rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-paddingTop-wk8lta rn-paddingRight-9aemit rn-paddingBottom-1mdbw0j rn-paddingLeft-gy4na3 rn-textDecoration-bauka4 rn-whiteSpace-q42fyq rn-wordWrap-qvutc0"
|
||||
class="rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-color-homxoj rn-display-1471scf rn-font-1lw9tu2 rn-fontFamily-14xgk7a rn-fontSize-1b43r93 rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-paddingTop-wk8lta rn-paddingRight-9aemit rn-paddingBottom-1mdbw0j rn-paddingLeft-gy4na3 rn-textDecoration-bauka4 rn-whiteSpace-q42fyq rn-wordWrap-qvutc0"
|
||||
dir="auto"
|
||||
>
|
||||
Nested
|
||||
@@ -174,7 +174,7 @@ exports[`enzyme.render nested 1`] = `
|
||||
class="rn-alignItems-1oszu61 rn-backgroundColor-1mjtqww rn-borderTopStyle-1efd50x rn-borderRightStyle-14skgim rn-borderBottomStyle-rull8r rn-borderLeftStyle-mm0ijv rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-display-6koalj rn-flexShrink-1pxmb3b rn-flexBasis-7vfszb rn-flexDirection-eqz5dr rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-minHeight-ifefl9 rn-minWidth-bcqeeo rn-paddingTop-m611by rn-paddingRight-1qfoi16 rn-paddingBottom-1mi0q7o rn-paddingLeft-1hfyk0a rn-position-bnwqim rn-zIndex-1lgpqti"
|
||||
>
|
||||
<div
|
||||
class="rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-color-1bodaif rn-display-1471scf rn-font-1lw9tu2 rn-fontFamily-10u92zi rn-fontSize-ubezar rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-paddingTop-wk8lta rn-paddingRight-9aemit rn-paddingBottom-1mdbw0j rn-paddingLeft-gy4na3 rn-verticalAlign-9iso6 rn-textDecoration-bauka4 rn-whiteSpace-q42fyq rn-wordWrap-qvutc0"
|
||||
class="rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-color-1bodaif rn-display-1471scf rn-font-1lw9tu2 rn-fontFamily-14xgk7a rn-fontSize-ubezar rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-paddingTop-wk8lta rn-paddingRight-9aemit rn-paddingBottom-1mdbw0j rn-paddingLeft-gy4na3 rn-verticalAlign-9iso6 rn-textDecoration-bauka4 rn-whiteSpace-q42fyq rn-wordWrap-qvutc0"
|
||||
dir="auto"
|
||||
>
|
||||
Hello World
|
||||
@@ -252,7 +252,7 @@ exports[`react-test-renderer complex 1`] = `
|
||||
className="rn-alignItems-1oszu61 rn-backgroundColor-1mjtqww rn-borderTopStyle-1efd50x rn-borderRightStyle-14skgim rn-borderBottomStyle-rull8r rn-borderLeftStyle-mm0ijv rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-display-6koalj rn-flexShrink-1pxmb3b rn-flexBasis-7vfszb rn-flexDirection-eqz5dr rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-minHeight-ifefl9 rn-minWidth-bcqeeo rn-paddingTop-m611by rn-paddingRight-1qfoi16 rn-paddingBottom-1mi0q7o rn-paddingLeft-1hfyk0a rn-position-bnwqim rn-zIndex-1lgpqti"
|
||||
>
|
||||
<div
|
||||
className="rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-color-1bodaif rn-display-1471scf rn-font-1lw9tu2 rn-fontFamily-10u92zi rn-fontSize-ubezar rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-paddingTop-wk8lta rn-paddingRight-9aemit rn-paddingBottom-1mdbw0j rn-paddingLeft-gy4na3 rn-verticalAlign-9iso6 rn-textDecoration-bauka4 rn-whiteSpace-q42fyq rn-wordWrap-qvutc0"
|
||||
className="rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-color-1bodaif rn-display-1471scf rn-font-1lw9tu2 rn-fontFamily-14xgk7a rn-fontSize-ubezar rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-paddingTop-wk8lta rn-paddingRight-9aemit rn-paddingBottom-1mdbw0j rn-paddingLeft-gy4na3 rn-verticalAlign-9iso6 rn-textDecoration-bauka4 rn-whiteSpace-q42fyq rn-wordWrap-qvutc0"
|
||||
dir="auto"
|
||||
>
|
||||
Hello World
|
||||
@@ -264,7 +264,7 @@ exports[`react-test-renderer complex 1`] = `
|
||||
className="rn-alignItems-1oszu61 rn-borderTopStyle-1efd50x rn-borderRightStyle-14skgim rn-borderBottomStyle-rull8r rn-borderLeftStyle-mm0ijv rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-display-6koalj rn-flexShrink-1pxmb3b rn-flexBasis-7vfszb rn-flexDirection-eqz5dr rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-minHeight-ifefl9 rn-minWidth-bcqeeo rn-paddingTop-1knelpx rn-paddingRight-1ah4tor rn-paddingBottom-k8qxaj rn-paddingLeft-b5h31w rn-position-bnwqim rn-zIndex-1lgpqti"
|
||||
/>
|
||||
<div
|
||||
className="rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-color-homxoj rn-display-1471scf rn-font-1lw9tu2 rn-fontFamily-10u92zi rn-fontSize-1b43r93 rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-paddingTop-wk8lta rn-paddingRight-9aemit rn-paddingBottom-1mdbw0j rn-paddingLeft-gy4na3 rn-textDecoration-bauka4 rn-whiteSpace-q42fyq rn-wordWrap-qvutc0"
|
||||
className="rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-color-homxoj rn-display-1471scf rn-font-1lw9tu2 rn-fontFamily-14xgk7a rn-fontSize-1b43r93 rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-paddingTop-wk8lta rn-paddingRight-9aemit rn-paddingBottom-1mdbw0j rn-paddingLeft-gy4na3 rn-textDecoration-bauka4 rn-whiteSpace-q42fyq rn-wordWrap-qvutc0"
|
||||
dir="auto"
|
||||
>
|
||||
Nested
|
||||
@@ -284,7 +284,7 @@ exports[`react-test-renderer nested 1`] = `
|
||||
className="rn-alignItems-1oszu61 rn-backgroundColor-1mjtqww rn-borderTopStyle-1efd50x rn-borderRightStyle-14skgim rn-borderBottomStyle-rull8r rn-borderLeftStyle-mm0ijv rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-display-6koalj rn-flexShrink-1pxmb3b rn-flexBasis-7vfszb rn-flexDirection-eqz5dr rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-minHeight-ifefl9 rn-minWidth-bcqeeo rn-paddingTop-m611by rn-paddingRight-1qfoi16 rn-paddingBottom-1mi0q7o rn-paddingLeft-1hfyk0a rn-position-bnwqim rn-zIndex-1lgpqti"
|
||||
>
|
||||
<div
|
||||
className="rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-color-1bodaif rn-display-1471scf rn-font-1lw9tu2 rn-fontFamily-10u92zi rn-fontSize-ubezar rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-paddingTop-wk8lta rn-paddingRight-9aemit rn-paddingBottom-1mdbw0j rn-paddingLeft-gy4na3 rn-verticalAlign-9iso6 rn-textDecoration-bauka4 rn-whiteSpace-q42fyq rn-wordWrap-qvutc0"
|
||||
className="rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-color-1bodaif rn-display-1471scf rn-font-1lw9tu2 rn-fontFamily-14xgk7a rn-fontSize-ubezar rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-paddingTop-wk8lta rn-paddingRight-9aemit rn-paddingBottom-1mdbw0j rn-paddingLeft-gy4na3 rn-verticalAlign-9iso6 rn-textDecoration-bauka4 rn-whiteSpace-q42fyq rn-wordWrap-qvutc0"
|
||||
dir="auto"
|
||||
>
|
||||
Hello World
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "react-native-web",
|
||||
"version": "0.4.0",
|
||||
"version": "0.5.4",
|
||||
"description": "React Native for Web",
|
||||
"main": "dist/index.js",
|
||||
"files": [
|
||||
@@ -27,7 +27,7 @@
|
||||
"react-dom": "16.x.x"
|
||||
},
|
||||
"author": "Nicolas Gallagher",
|
||||
"license": "BSD-3-Clause",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/necolas/react-native-web.git"
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
/**
|
||||
* Copyright (c) 2016-present, Nicolas Gallagher.
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @providesModule ActivityIndicator
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
/**
|
||||
* Copyright (c) 2016-present, Nicolas Gallagher.
|
||||
* 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.
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @providesModule Animated
|
||||
* @flow
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
/**
|
||||
* Copyright (c) 2016-present, Nicolas Gallagher.
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Nicolas Gallagher.
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @providesModule AppRegistry
|
||||
@@ -78,9 +77,9 @@ export default class AppRegistry {
|
||||
params.rootTag = `#${params.rootTag.id}`;
|
||||
|
||||
console.log(
|
||||
`Running application "${appKey}" with appParams: ${JSON.stringify(params)}. ` +
|
||||
`development-level warnings are ${isDevelopment ? 'ON' : 'OFF'}, ` +
|
||||
`performance optimizations are ${isDevelopment ? 'OFF' : 'ON'}`
|
||||
`Running application "${appKey}" with appParams: ${JSON.stringify(params)}.\n` +
|
||||
`Development-level warnings: ${isDevelopment ? 'ON' : 'OFF'}.\n` +
|
||||
`Performance optimizations: ${isDevelopment ? 'OFF' : 'ON'}.`
|
||||
);
|
||||
|
||||
invariant(
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Nicolas Gallagher.
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
/**
|
||||
* Copyright (c) 2016-present, Nicolas Gallagher.
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @providesModule AppState
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Nicolas Gallagher.
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @providesModule AsyncStorage
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
/**
|
||||
* Copyright (c) 2016-present, Nicolas Gallagher.
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @providesModule BackHandler
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
/**
|
||||
* Copyright (c) 2016-present, Nicolas Gallagher.
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @providesModule Button
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
/**
|
||||
* Copyright (c) 2017-present, Nicolas Gallagher.
|
||||
* Copyright (c) 2017-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @providesModule CheckBox
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
/**
|
||||
* Copyright (c) 2016-present, Nicolas Gallagher.
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @providesModule Clipboard
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
/**
|
||||
* 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.
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @providesModule ColorPropType
|
||||
* @noflow
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Nicolas Gallagher.
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @providesModule Dimensions
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
/**
|
||||
* Copyright (c) 2016-present, Nicolas Gallagher.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
/**
|
||||
* 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.
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @providesModule EdgeInsetsPropType
|
||||
* @flow
|
||||
|
||||
@@ -2,44 +2,100 @@
|
||||
|
||||
import I18nManager from '..';
|
||||
|
||||
const getDocumentDir = () => document.documentElement.getAttribute('dir');
|
||||
|
||||
describe('apis/I18nManager', () => {
|
||||
describe('when RTL not enabled', () => {
|
||||
describe('preferred language is LTR', () => {
|
||||
beforeEach(() => {
|
||||
I18nManager.setPreferredLanguageRTL(false);
|
||||
});
|
||||
|
||||
test('is "false" by default', () => {
|
||||
expect(I18nManager.isRTL).toEqual(false);
|
||||
expect(document.documentElement.getAttribute('dir')).toEqual('ltr');
|
||||
describe('isRTL', () => {
|
||||
test('is false', () => {
|
||||
expect(I18nManager.isRTL).toBe(false);
|
||||
expect(getDocumentDir()).toEqual('ltr');
|
||||
});
|
||||
});
|
||||
|
||||
test('is "true" when forced', () => {
|
||||
I18nManager.forceRTL(true);
|
||||
expect(I18nManager.isRTL).toEqual(true);
|
||||
expect(document.documentElement.getAttribute('dir')).toEqual('rtl');
|
||||
I18nManager.forceRTL(false);
|
||||
describe('forceRTL', () => {
|
||||
test('when set to false, "isRTL" is false', () => {
|
||||
I18nManager.forceRTL(false);
|
||||
expect(I18nManager.isRTL).toBe(false);
|
||||
expect(getDocumentDir()).toEqual('ltr');
|
||||
});
|
||||
test('when set to true, "isRTL" is true', () => {
|
||||
I18nManager.forceRTL(true);
|
||||
expect(I18nManager.isRTL).toBe(true);
|
||||
expect(getDocumentDir()).toEqual('rtl');
|
||||
I18nManager.forceRTL(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('swapLeftAndRightInRTL', () => {
|
||||
test('when set to false, "doLeftAndRightSwapInRTL" is false', () => {
|
||||
I18nManager.swapLeftAndRightInRTL(false);
|
||||
expect(I18nManager.doLeftAndRightSwapInRTL).toBe(false);
|
||||
});
|
||||
test('when set to true, "doLeftAndRightSwapInRTL" is true', () => {
|
||||
I18nManager.swapLeftAndRightInRTL(true);
|
||||
expect(I18nManager.doLeftAndRightSwapInRTL).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when RTL is enabled', () => {
|
||||
describe('preferred language is RTL', () => {
|
||||
beforeEach(() => {
|
||||
I18nManager.setPreferredLanguageRTL(true);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
afterAll(() => {
|
||||
I18nManager.setPreferredLanguageRTL(false);
|
||||
});
|
||||
|
||||
test('is "true" by default', () => {
|
||||
expect(I18nManager.isRTL).toEqual(true);
|
||||
expect(document.documentElement.getAttribute('dir')).toEqual('rtl');
|
||||
describe('isRTL', () => {
|
||||
test('is true', () => {
|
||||
expect(I18nManager.isRTL).toBe(true);
|
||||
expect(getDocumentDir()).toEqual('rtl');
|
||||
});
|
||||
});
|
||||
|
||||
test('is "false" when not allowed', () => {
|
||||
I18nManager.allowRTL(false);
|
||||
expect(I18nManager.isRTL).toEqual(false);
|
||||
expect(document.documentElement.getAttribute('dir')).toEqual('ltr');
|
||||
I18nManager.allowRTL(true);
|
||||
describe('allowRTL', () => {
|
||||
test('when set to false, "isRTL" is false', () => {
|
||||
I18nManager.allowRTL(false);
|
||||
expect(I18nManager.isRTL).toBe(false);
|
||||
expect(getDocumentDir()).toEqual('ltr');
|
||||
I18nManager.allowRTL(true);
|
||||
});
|
||||
test('when set to true, "isRTL" is true', () => {
|
||||
I18nManager.allowRTL(true);
|
||||
expect(I18nManager.isRTL).toBe(true);
|
||||
expect(getDocumentDir()).toEqual('rtl');
|
||||
});
|
||||
});
|
||||
|
||||
describe('forceRTL', () => {
|
||||
test('when set to false, "isRTL" is true', () => {
|
||||
I18nManager.forceRTL(false);
|
||||
expect(I18nManager.isRTL).toBe(true);
|
||||
expect(getDocumentDir()).toEqual('rtl');
|
||||
});
|
||||
test('when set to true, "isRTL" is true', () => {
|
||||
I18nManager.forceRTL(true);
|
||||
expect(I18nManager.isRTL).toBe(true);
|
||||
expect(getDocumentDir()).toEqual('rtl');
|
||||
I18nManager.forceRTL(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('swapLeftAndRightInRTL', () => {
|
||||
test('when set to false, "doLeftAndRightSwapInRTL" is false', () => {
|
||||
I18nManager.swapLeftAndRightInRTL(false);
|
||||
expect(I18nManager.doLeftAndRightSwapInRTL).toBe(false);
|
||||
});
|
||||
test('when set to true, "doLeftAndRightSwapInRTL" is true', () => {
|
||||
I18nManager.swapLeftAndRightInRTL(true);
|
||||
expect(I18nManager.doLeftAndRightSwapInRTL).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
/**
|
||||
* Copyright (c) 2016-present, Nicolas Gallagher.
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @providesModule I18nManager
|
||||
@@ -14,11 +13,14 @@ import ExecutionEnvironment from 'fbjs/lib/ExecutionEnvironment';
|
||||
|
||||
type I18nManagerStatus = {
|
||||
allowRTL: (allowRTL: boolean) => void,
|
||||
doLeftAndRightSwapInRTL: boolean,
|
||||
forceRTL: (forceRTL: boolean) => void,
|
||||
isRTL: boolean,
|
||||
setPreferredLanguageRTL: (setRTL: boolean) => void,
|
||||
isRTL: boolean
|
||||
swapLeftAndRightInRTL: (flipStyles: boolean) => void
|
||||
};
|
||||
|
||||
let doLeftAndRightSwapInRTL = true;
|
||||
let isPreferredLanguageRTL = false;
|
||||
let isRTLAllowed = true;
|
||||
let isRTLForced = false;
|
||||
@@ -30,7 +32,7 @@ const isRTL = () => {
|
||||
return isRTLAllowed && isPreferredLanguageRTL;
|
||||
};
|
||||
|
||||
const onChange = () => {
|
||||
const onDirectionChange = () => {
|
||||
if (ExecutionEnvironment.canUseDOM) {
|
||||
if (document.documentElement && document.documentElement.setAttribute) {
|
||||
document.documentElement.setAttribute('dir', isRTL() ? 'rtl' : 'ltr');
|
||||
@@ -41,15 +43,21 @@ const onChange = () => {
|
||||
const I18nManager: I18nManagerStatus = {
|
||||
allowRTL(bool) {
|
||||
isRTLAllowed = bool;
|
||||
onChange();
|
||||
onDirectionChange();
|
||||
},
|
||||
forceRTL(bool) {
|
||||
isRTLForced = bool;
|
||||
onChange();
|
||||
onDirectionChange();
|
||||
},
|
||||
setPreferredLanguageRTL(bool) {
|
||||
isPreferredLanguageRTL = bool;
|
||||
onChange();
|
||||
onDirectionChange();
|
||||
},
|
||||
swapLeftAndRightInRTL(bool) {
|
||||
doLeftAndRightSwapInRTL = bool;
|
||||
},
|
||||
get doLeftAndRightSwapInRTL() {
|
||||
return doLeftAndRightSwapInRTL;
|
||||
},
|
||||
get isRTL() {
|
||||
return isRTL();
|
||||
|
||||
@@ -2,16 +2,20 @@
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import AnimationPropTypes from '../../modules/AnimationPropTypes';
|
||||
import BorderPropTypes from '../../modules/BorderPropTypes';
|
||||
import ColorPropType from '../ColorPropType';
|
||||
import ImageResizeMode from './ImageResizeMode';
|
||||
import InteractionPropTypes from '../../modules/InteractionPropTypes';
|
||||
import LayoutPropTypes from '../../modules/LayoutPropTypes';
|
||||
import ShadowPropTypes from '../../modules/ShadowPropTypes';
|
||||
import TransformPropTypes from '../../modules/TransformPropTypes';
|
||||
import { number, oneOf, string } from 'prop-types';
|
||||
|
||||
const ImageStylePropTypes = {
|
||||
...AnimationPropTypes,
|
||||
...BorderPropTypes,
|
||||
...InteractionPropTypes,
|
||||
...LayoutPropTypes,
|
||||
...ShadowPropTypes,
|
||||
...TransformPropTypes,
|
||||
@@ -26,7 +30,8 @@ const ImageStylePropTypes = {
|
||||
/**
|
||||
* @platform web
|
||||
*/
|
||||
boxShadow: string
|
||||
boxShadow: string,
|
||||
filter: string
|
||||
};
|
||||
|
||||
export default ImageStylePropTypes;
|
||||
|
||||
@@ -180,6 +180,20 @@ describe('components/Image', () => {
|
||||
.attr('src')
|
||||
).toBe(uriTwo);
|
||||
});
|
||||
|
||||
test('is correctly updated when missing in initial render', () => {
|
||||
jest.useFakeTimers();
|
||||
const uri = 'https://testing.com/img.jpg';
|
||||
const component = mount(<Image />);
|
||||
component.setProps({ source: { uri } });
|
||||
jest.runOnlyPendingTimers();
|
||||
expect(
|
||||
component
|
||||
.render()
|
||||
.find('img')
|
||||
.attr('src')
|
||||
).toBe(uri);
|
||||
});
|
||||
});
|
||||
|
||||
describe('prop "style"', () => {
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
/**
|
||||
* Copyright (c) 2016-present, Nicolas Gallagher.
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @providesModule Image
|
||||
@@ -57,7 +56,7 @@ const resolveAssetDimensions = source => {
|
||||
}
|
||||
};
|
||||
|
||||
const svgDataUriPattern = /^data:image\/svg\+xml;/;
|
||||
const svgDataUriPattern = /^(data:image\/svg\+xml;utf8,)(.*)/;
|
||||
const resolveAssetSource = source => {
|
||||
let uri;
|
||||
if (typeof source === 'number') {
|
||||
@@ -72,12 +71,12 @@ const resolveAssetSource = source => {
|
||||
uri = source || '';
|
||||
}
|
||||
|
||||
// SVG data may contain characters (e.g., #, ") that need to be escaped
|
||||
if (svgDataUriPattern.test(uri)) {
|
||||
const parts = uri.split('<svg');
|
||||
const [prefix, ...svgFragment] = parts;
|
||||
const svg = encodeURIComponent(`<svg${svgFragment.join('<svg')}`);
|
||||
return `${prefix}${svg}`;
|
||||
const match = uri.match(svgDataUriPattern);
|
||||
// inline SVG markup may contain characters (e.g., #, ") that need to be escaped
|
||||
if (match) {
|
||||
const [, prefix, svg] = match;
|
||||
const encodedSvg = encodeURIComponent(svg);
|
||||
return `${prefix}${encodedSvg}`;
|
||||
}
|
||||
|
||||
return uri;
|
||||
@@ -168,8 +167,8 @@ class Image extends Component<*, State> {
|
||||
if (uri !== nextUri) {
|
||||
ImageUriCache.remove(uri);
|
||||
const isPreviouslyLoaded = ImageUriCache.has(nextUri);
|
||||
isPreviouslyLoaded && ImageUriCache.add(uri);
|
||||
this._updateImageState(getImageState(uri, isPreviouslyLoaded));
|
||||
isPreviouslyLoaded && ImageUriCache.add(nextUri);
|
||||
this._updateImageState(getImageState(nextUri, isPreviouslyLoaded));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
/**
|
||||
* 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.
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
/**
|
||||
* Copyright (c) 2016-present, Nicolas Gallagher.
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @providesModule InteractionManager
|
||||
@@ -21,9 +20,18 @@ const InteractionManager = {
|
||||
/**
|
||||
* Schedule a function to run after all interactions have completed.
|
||||
*/
|
||||
runAfterInteractions(callback: Function) {
|
||||
invariant(typeof callback === 'function', 'Must specify a function to schedule.');
|
||||
callback();
|
||||
runAfterInteractions(task: ?Function): { then: Function, done: Function, cancel: Function } {
|
||||
console.warn('InteractionManager is not supported on web');
|
||||
const promise = new Promise(resolve => {
|
||||
if (task) {
|
||||
resolve(task());
|
||||
}
|
||||
});
|
||||
return {
|
||||
then: promise.then.bind(promise),
|
||||
done: () => {},
|
||||
cancel: () => {}
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
/**
|
||||
* Copyright (c) 2016-present, Nicolas Gallagher.
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @providesModule Keyboard
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
/**
|
||||
* Copyright (c) 2017-present, Nicolas Gallagher.
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @providesModule KeyboardAvoidingView
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
/**
|
||||
* Copyright (c) 2016-present, Nicolas Gallagher.
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @providesModule Linking
|
||||
@@ -25,7 +24,7 @@ const Linking = {
|
||||
},
|
||||
openURL(url: string): Promise<Object | void> {
|
||||
try {
|
||||
iframeOpen(url);
|
||||
open(url);
|
||||
return Promise.resolve();
|
||||
} catch (e) {
|
||||
return Promise.reject(e);
|
||||
@@ -33,36 +32,16 @@ const Linking = {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Tabs opened using JavaScript may redirect the parent tab using
|
||||
* `window.opener.location`, ignoring cross-origin restrictions and enabling
|
||||
* phishing attacks.
|
||||
*
|
||||
* Safari requires that we open the url by injecting a hidden iframe that calls
|
||||
* window.open(), then removes the iframe from the DOM.
|
||||
*
|
||||
* https://mathiasbynens.github.io/rel-noopener/
|
||||
*/
|
||||
const iframeOpen = url => {
|
||||
const noOpener = url.indexOf('mailto:') !== 0;
|
||||
const open = url => {
|
||||
const anchor = document.createElement('a');
|
||||
anchor.target = '_blank'; // :(
|
||||
anchor.rel = 'noopener';
|
||||
anchor.href = url;
|
||||
const body = document.body;
|
||||
if (body) {
|
||||
const iframe = document.createElement('iframe');
|
||||
iframe.style.display = 'none';
|
||||
body.appendChild(iframe);
|
||||
|
||||
const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
|
||||
const iframeBody = iframeDoc.body;
|
||||
if (iframeBody) {
|
||||
const script = iframeDoc.createElement('script');
|
||||
const openerExpression = noOpener ? 'child.opener = null' : '';
|
||||
script.text = `
|
||||
window.parent = null; window.top = null; window.frameElement = null;
|
||||
var child = window.open("${url}"); ${openerExpression};
|
||||
`;
|
||||
iframeBody.appendChild(script);
|
||||
}
|
||||
body.removeChild(iframe);
|
||||
body.appendChild(anchor);
|
||||
anchor.click();
|
||||
body.removeChild(anchor);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Nicolas Gallagher.
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @providesModule NetInfo
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
/**
|
||||
* Copyright (c) 2017-present, Nicolas Gallagher.
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
/**
|
||||
* Copyright (c) 2017-present, Nicolas Gallagher.
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
|
||||
@@ -10,7 +10,7 @@ exports[`components/Picker prop "children" items 1`] = `
|
||||
|
||||
exports[`components/Picker prop "children" renders items 1`] = `
|
||||
<select
|
||||
className="rn-fontFamily-poiln3 rn-fontSize-7cikom rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw"
|
||||
className="rn-fontFamily-14xgk7a rn-fontSize-7cikom rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw"
|
||||
onChange={[Function]}
|
||||
>
|
||||
<PickerItem
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
/**
|
||||
* Copyright (c) 2017-present, Nicolas Gallagher.
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @providesModule Picker
|
||||
@@ -24,7 +23,7 @@ import { arrayOf, bool, func, number, oneOfType, string } from 'prop-types';
|
||||
const pickerStyleType = StyleSheetPropType(PickerStylePropTypes);
|
||||
|
||||
type Props = {
|
||||
children?: Array<typeof PickerItem>,
|
||||
children?: PickerItem | Array<typeof PickerItem>,
|
||||
enabled?: boolean,
|
||||
onValueChange?: Function,
|
||||
selectedValue?: number | string,
|
||||
@@ -38,7 +37,7 @@ type Props = {
|
||||
|
||||
class Picker extends Component<Props> {
|
||||
static propTypes = {
|
||||
children: arrayOf(PickerItemPropType),
|
||||
children: oneOfType([PickerItemPropType, arrayOf(PickerItemPropType)]),
|
||||
enabled: bool,
|
||||
onValueChange: func,
|
||||
selectedValue: oneOfType([number, string]),
|
||||
@@ -83,7 +82,7 @@ class Picker extends Component<Props> {
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
initial: {
|
||||
fontFamily: 'inherit',
|
||||
fontFamily: 'System',
|
||||
fontSize: 'inherit',
|
||||
margin: 0
|
||||
}
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Nicolas Gallagher.
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @providesModule PixelRatio
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
/**
|
||||
* Copyright (c) 2016-present, Nicolas Gallagher.
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @providesModule Platform
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
/**
|
||||
* 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.
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @providesModule PointPropType
|
||||
* @flow
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
/**
|
||||
* Copyright (c) 2016-present, Nicolas Gallagher.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @providesModule ProgressBar
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
/**
|
||||
* Copyright (c) 2017-present, Nicolas Gallagher.
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @providesModule RefreshControl
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
/**
|
||||
* 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.
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @providesModule SafeAreaView
|
||||
* @flow
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
/**
|
||||
* Copyright (c) 2016-present, Nicolas Gallagher.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
/**
|
||||
* Copyright (c) 2016-present, Nicolas Gallagher.
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @providesModule ScrollView
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
/**
|
||||
* Copyright (c) 2016-present, Nicolas Gallagher.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @providesModule StatusBar
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
/**
|
||||
* Copyright (c) 2016-present, Nicolas Gallagher.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @noflow
|
||||
*/
|
||||
|
||||
/**
|
||||
* WARNING: changes to this file in particular can cause significant changes to
|
||||
* the results of render performance benchmarks.
|
||||
*
|
||||
* @noflow
|
||||
*/
|
||||
|
||||
import { canUseDOM } from 'fbjs/lib/ExecutionEnvironment';
|
||||
@@ -24,8 +25,8 @@ const emptyObject = {};
|
||||
|
||||
export default class ReactNativeStyleResolver {
|
||||
_init() {
|
||||
this.cache = { ltr: {}, rtl: {} };
|
||||
this.injectedCache = { ltr: {}, rtl: {} };
|
||||
this.cache = { ltr: {}, rtl: {}, rtlNoSwap: {} };
|
||||
this.injectedCache = { ltr: {}, rtl: {}, rtlNoSwap: {} };
|
||||
this.styleSheetManager = new StyleSheetManager();
|
||||
}
|
||||
|
||||
@@ -43,7 +44,8 @@ export default class ReactNativeStyleResolver {
|
||||
}
|
||||
|
||||
_injectRegisteredStyle(id) {
|
||||
const dir = I18nManager.isRTL ? 'rtl' : 'ltr';
|
||||
const { doLeftAndRightSwapInRTL, isRTL } = I18nManager;
|
||||
const dir = isRTL ? (doLeftAndRightSwapInRTL ? 'rtl' : 'rtlNoSwap') : 'ltr';
|
||||
if (!this.injectedCache[dir][id]) {
|
||||
const style = flattenStyle(id);
|
||||
const domStyle = createReactDOMStyle(i18nStyle(style));
|
||||
@@ -120,7 +122,7 @@ export default class ReactNativeStyleResolver {
|
||||
|
||||
// Create next DOM style props from current and next RN styles
|
||||
const { classList: rdomClassListNext, style: rdomStyleNext } = this.resolve([
|
||||
I18nManager.isRTL ? i18nStyle(rnStyle) : rnStyle,
|
||||
i18nStyle(rnStyle),
|
||||
rnStyleNext
|
||||
]);
|
||||
|
||||
@@ -196,7 +198,8 @@ export default class ReactNativeStyleResolver {
|
||||
*/
|
||||
_resolveStyleIfNeeded(style, key) {
|
||||
if (key) {
|
||||
const dir = I18nManager.isRTL ? 'rtl' : 'ltr';
|
||||
const { doLeftAndRightSwapInRTL, isRTL } = I18nManager;
|
||||
const dir = isRTL ? (doLeftAndRightSwapInRTL ? 'rtl' : 'rtlNoSwap') : 'ltr';
|
||||
if (!this.cache[dir][key]) {
|
||||
// slow: convert style object to props and cache
|
||||
this.cache[dir][key] = this._resolveStyle(style);
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
/**
|
||||
* Copyright (c) 2016-present, Nicolas Gallagher.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @providesModule StyleSheet
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
/**
|
||||
* Copyright (c) 2016-present, Nicolas Gallagher.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @noflow
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
/**
|
||||
* Copyright (c) 2016-present, Nicolas Gallagher.
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @providesModule StyleSheetValidation
|
||||
@@ -26,6 +25,8 @@ const ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED';
|
||||
export default class StyleSheetValidation {
|
||||
static validateStyleProp(prop: string, style: Object, caller: string) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
const value = style[prop];
|
||||
|
||||
const isCustomProperty = prop.indexOf('--') === 0;
|
||||
if (isCustomProperty) return;
|
||||
|
||||
@@ -35,6 +36,12 @@ export default class StyleSheetValidation {
|
||||
'\nValid style props: ' +
|
||||
JSON.stringify(Object.keys(allStylePropTypes).sort(), null, ' ');
|
||||
styleError(message1, style, caller, message2);
|
||||
} else if (typeof value === 'string' && value.indexOf('!important') > -1) {
|
||||
styleError(
|
||||
`Invalid value of "${value}" set on prop "${prop}". Values cannot include "!important"`,
|
||||
style,
|
||||
caller
|
||||
);
|
||||
} else {
|
||||
const error = allStylePropTypes[prop](
|
||||
style,
|
||||
@@ -92,7 +99,7 @@ StyleSheetValidation.addValidStylePropTypes({
|
||||
clear: string,
|
||||
cursor: string,
|
||||
fill: string,
|
||||
float: oneOf(['left', 'none', 'right']),
|
||||
float: oneOf(['end', 'left', 'none', 'right', 'start']),
|
||||
listStyle: string,
|
||||
pointerEvents: string,
|
||||
tableLayout: string,
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
/**
|
||||
* Copyright (c) 2016-present, Nicolas Gallagher.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
|
||||
@@ -42,14 +42,22 @@ describe('StyleSheet/ReactNativeStyleResolver', () => {
|
||||
testResolve(a, b, c);
|
||||
});
|
||||
|
||||
test('with register before RTL, resolves to className', () => {
|
||||
test('with register before RTL, resolves to correct className', () => {
|
||||
const a = ReactNativePropRegistry.register({ left: '12.34%' });
|
||||
const b = ReactNativePropRegistry.register({ textAlign: 'left' });
|
||||
const c = ReactNativePropRegistry.register({ marginLeft: 10 });
|
||||
I18nManager.forceRTL(true);
|
||||
const resolved = styleResolver.resolve([a, b, c]);
|
||||
|
||||
const resolved1 = styleResolver.resolve([a, b, c]);
|
||||
expect(resolved1).toMatchSnapshot();
|
||||
|
||||
I18nManager.swapLeftAndRightInRTL(false);
|
||||
|
||||
const resolved2 = styleResolver.resolve([a, b, c]);
|
||||
expect(resolved2).toMatchSnapshot();
|
||||
|
||||
I18nManager.swapLeftAndRightInRTL(true);
|
||||
I18nManager.forceRTL(false);
|
||||
expect(resolved).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('with register, resolves to mixed', () => {
|
||||
@@ -102,7 +110,7 @@ describe('StyleSheet/ReactNativeStyleResolver', () => {
|
||||
expect(resolved).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('when RTL=true, resolves to flipped inline styles', () => {
|
||||
test('when isRTL=true, resolves to flipped inline styles', () => {
|
||||
// note: DOM state resolved from { marginLeft: 5, left: 5 } in RTL mode
|
||||
node.style.cssText = 'margin-right: 5px; right: 5px;';
|
||||
I18nManager.forceRTL(true);
|
||||
@@ -111,8 +119,8 @@ describe('StyleSheet/ReactNativeStyleResolver', () => {
|
||||
expect(resolved).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('when RTL=true, resolves to flipped classNames', () => {
|
||||
// note: DOM state resolved from { marginLeft: 5, left: 5 } in RTL mode
|
||||
test('when isRTL=true, resolves to flipped classNames', () => {
|
||||
// note: DOM state resolved from { marginLeft: 5, left: 5 }
|
||||
node.style.cssText = 'margin-right: 5px; right: 5px;';
|
||||
const nextStyle = ReactNativePropRegistry.register({ marginLeft: 10, right: 1 });
|
||||
|
||||
@@ -121,5 +129,19 @@ describe('StyleSheet/ReactNativeStyleResolver', () => {
|
||||
I18nManager.forceRTL(false);
|
||||
expect(resolved).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('when isRTL=true & doLeftAndRightSwapInRTL=false, resolves to non-flipped inline styles', () => {
|
||||
// note: DOM state resolved from { marginRight 5, right: 5, paddingEnd: 5 }
|
||||
node.style.cssText = 'margin-right: 5px; right: 5px; padding-left: 5px';
|
||||
I18nManager.forceRTL(true);
|
||||
I18nManager.swapLeftAndRightInRTL(false);
|
||||
const resolved = styleResolver.resolveWithNode(
|
||||
{ marginRight: 10, right: 10, paddingEnd: 10 },
|
||||
node
|
||||
);
|
||||
I18nManager.forceRTL(false);
|
||||
I18nManager.swapLeftAndRightInRTL(true);
|
||||
expect(resolved).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -9,7 +9,7 @@ Object {
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`StyleSheet/ReactNativeStyleResolver resolve with register before RTL, resolves to className 1`] = `
|
||||
exports[`StyleSheet/ReactNativeStyleResolver resolve with register before RTL, resolves to correct className 1`] = `
|
||||
Object {
|
||||
"classList": Array [
|
||||
"rn-marginRight-zso239",
|
||||
@@ -20,6 +20,17 @@ Object {
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`StyleSheet/ReactNativeStyleResolver resolve with register before RTL, resolves to correct className 2`] = `
|
||||
Object {
|
||||
"classList": Array [
|
||||
"rn-left-2s0hu9",
|
||||
"rn-marginLeft-1n0xq6e",
|
||||
"rn-textAlign-fdjqy7",
|
||||
],
|
||||
"className": "rn-left-2s0hu9 rn-marginLeft-1n0xq6e rn-textAlign-fdjqy7",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`StyleSheet/ReactNativeStyleResolver resolve with register, resolves to className 1`] = `
|
||||
Object {
|
||||
"classList": Array [
|
||||
@@ -246,7 +257,18 @@ Object {
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`StyleSheet/ReactNativeStyleResolver resolveWithNode when RTL=true, resolves to flipped classNames 1`] = `
|
||||
exports[`StyleSheet/ReactNativeStyleResolver resolveWithNode when isRTL=true & doLeftAndRightSwapInRTL=false, resolves to non-flipped inline styles 1`] = `
|
||||
Object {
|
||||
"className": "",
|
||||
"style": Object {
|
||||
"marginRight": "10px",
|
||||
"paddingLeft": "10px",
|
||||
"right": "10px",
|
||||
},
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`StyleSheet/ReactNativeStyleResolver resolveWithNode when isRTL=true, resolves to flipped classNames 1`] = `
|
||||
Object {
|
||||
"className": "rn-left-1u10d71 rn-marginRight-zso239",
|
||||
"style": Object {
|
||||
@@ -256,7 +278,7 @@ Object {
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`StyleSheet/ReactNativeStyleResolver resolveWithNode when RTL=true, resolves to flipped inline styles 1`] = `
|
||||
exports[`StyleSheet/ReactNativeStyleResolver resolveWithNode when isRTL=true, resolves to flipped inline styles 1`] = `
|
||||
Object {
|
||||
"className": "",
|
||||
"style": Object {
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`StyleSheet/createReactDOMStyle fontFamily fontFamily: "System" 1`] = `
|
||||
exports[`StyleSheet/createReactDOMStyle fontFamily "Noto, System" 1`] = `
|
||||
Object {
|
||||
"fontFamily": "-apple-system, BlinkMacSystemFont, \\"Segoe UI\\", Roboto, Ubuntu, \\"Helvetica Neue\\", sans-serif",
|
||||
"fontFamily": "Noto, system-ui, -apple-system, BlinkMacSystemFont, \\"Segoe UI\\", Roboto, Ubuntu, \\"Helvetica Neue\\", sans-serif",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`StyleSheet/createReactDOMStyle fontFamily fontFamily: "monospace" 1`] = `
|
||||
exports[`StyleSheet/createReactDOMStyle fontFamily "System" 1`] = `
|
||||
Object {
|
||||
"fontFamily": "system-ui, -apple-system, BlinkMacSystemFont, \\"Segoe UI\\", Roboto, Ubuntu, \\"Helvetica Neue\\", sans-serif",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`StyleSheet/createReactDOMStyle fontFamily "monospace" 1`] = `
|
||||
Object {
|
||||
"fontFamily": "monospace, monospace",
|
||||
}
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`StyleSheet/i18nStyle LTR mode does not auto-flip 1`] = `
|
||||
Object {
|
||||
"borderBottomLeftRadius": 20,
|
||||
"borderBottomRightRadius": "2rem",
|
||||
"borderLeftColor": "red",
|
||||
"borderLeftStyle": "solid",
|
||||
"borderLeftWidth": 5,
|
||||
"borderRightColor": "blue",
|
||||
"borderRightStyle": "dotted",
|
||||
"borderRightWidth": 6,
|
||||
"borderTopLeftRadius": 10,
|
||||
"borderTopRightRadius": "1rem",
|
||||
"left": 1,
|
||||
"marginLeft": 7,
|
||||
"marginRight": 8,
|
||||
"paddingLeft": 9,
|
||||
"paddingRight": 10,
|
||||
"right": 2,
|
||||
"textAlign": "left",
|
||||
"textShadowOffset": Object {
|
||||
"height": 10,
|
||||
"width": "1rem",
|
||||
},
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`StyleSheet/i18nStyle RTL mode does auto-flip 1`] = `
|
||||
Object {
|
||||
"borderBottomLeftRadius": "2rem",
|
||||
"borderBottomRightRadius": 20,
|
||||
"borderLeftColor": "blue",
|
||||
"borderLeftStyle": "dotted",
|
||||
"borderLeftWidth": 6,
|
||||
"borderRightColor": "red",
|
||||
"borderRightStyle": "solid",
|
||||
"borderRightWidth": 5,
|
||||
"borderTopLeftRadius": "1rem",
|
||||
"borderTopRightRadius": 10,
|
||||
"left": 2,
|
||||
"marginLeft": 8,
|
||||
"marginRight": 7,
|
||||
"paddingLeft": 10,
|
||||
"paddingRight": 9,
|
||||
"right": 1,
|
||||
"textAlign": "right",
|
||||
"textShadowOffset": Object {
|
||||
"height": 10,
|
||||
"width": "-1rem",
|
||||
},
|
||||
}
|
||||
`;
|
||||
@@ -22,6 +22,23 @@ describe('StyleSheet/createReactDOMStyle', () => {
|
||||
expect(firstStyle).toEqual(secondStyle);
|
||||
});
|
||||
|
||||
test('shortform -> longform', () => {
|
||||
const style = {
|
||||
borderStyle: 'solid',
|
||||
boxSizing: 'border-box',
|
||||
borderBottomColor: 'white',
|
||||
borderBottomWidth: 1,
|
||||
borderWidth: 0,
|
||||
marginTop: 50,
|
||||
marginVertical: 25,
|
||||
margin: 10,
|
||||
overflow: 'hidden',
|
||||
overscrollBehavior: 'contain'
|
||||
};
|
||||
|
||||
expect(createReactDOMStyle(style)).toMatchSnapshot();
|
||||
});
|
||||
|
||||
describe('borderWidth styles', () => {
|
||||
test('defaults to 0 when "null"', () => {
|
||||
expect(createReactDOMStyle({ borderWidth: null })).toEqual({
|
||||
@@ -125,30 +142,23 @@ describe('StyleSheet/createReactDOMStyle', () => {
|
||||
expect(createReactDOMStyle({ fontFamily: 'Georgia, Times, serif' })).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('fontFamily: "monospace"', () => {
|
||||
test('"monospace"', () => {
|
||||
expect(createReactDOMStyle({ fontFamily: 'monospace' })).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('fontFamily: "System"', () => {
|
||||
test('"System"', () => {
|
||||
expect(createReactDOMStyle({ fontFamily: 'System' })).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('"Noto, System"', () => {
|
||||
expect(createReactDOMStyle({ fontFamily: 'Noto, System' })).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
test('shortform -> longform', () => {
|
||||
const style = {
|
||||
borderStyle: 'solid',
|
||||
boxSizing: 'border-box',
|
||||
borderBottomColor: 'white',
|
||||
borderBottomWidth: 1,
|
||||
borderWidth: 0,
|
||||
marginTop: 50,
|
||||
marginVertical: 25,
|
||||
margin: 10,
|
||||
overflow: 'hidden',
|
||||
overscrollBehavior: 'contain'
|
||||
};
|
||||
|
||||
expect(createReactDOMStyle(style)).toMatchSnapshot();
|
||||
test('fontVariant', () => {
|
||||
expect(createReactDOMStyle({ fontVariant: ['common-ligatures', 'small-caps'] })).toEqual({
|
||||
fontVariant: 'common-ligatures small-caps'
|
||||
});
|
||||
});
|
||||
|
||||
describe('shadow styles', () => {
|
||||
|
||||
@@ -2,11 +2,9 @@
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import flattenStyle from '../flattenStyle';
|
||||
|
||||
@@ -3,29 +3,8 @@
|
||||
import I18nManager from '../../I18nManager';
|
||||
import i18nStyle from '../i18nStyle';
|
||||
|
||||
const style = {
|
||||
borderLeftColor: 'red',
|
||||
borderRightColor: 'blue',
|
||||
borderTopLeftRadius: 10,
|
||||
borderTopRightRadius: '1rem',
|
||||
borderBottomLeftRadius: 20,
|
||||
borderBottomRightRadius: '2rem',
|
||||
borderLeftStyle: 'solid',
|
||||
borderRightStyle: 'dotted',
|
||||
borderLeftWidth: 5,
|
||||
borderRightWidth: 6,
|
||||
left: 1,
|
||||
marginLeft: 7,
|
||||
marginRight: 8,
|
||||
paddingLeft: 9,
|
||||
paddingRight: 10,
|
||||
right: 2,
|
||||
textAlign: 'left',
|
||||
textShadowOffset: { width: '1rem', height: 10 }
|
||||
};
|
||||
|
||||
describe('StyleSheet/i18nStyle', () => {
|
||||
describe('LTR mode', () => {
|
||||
describe('isRTL is false', () => {
|
||||
beforeEach(() => {
|
||||
I18nManager.allowRTL(false);
|
||||
});
|
||||
@@ -34,12 +13,73 @@ describe('StyleSheet/i18nStyle', () => {
|
||||
I18nManager.allowRTL(true);
|
||||
});
|
||||
|
||||
test('does not auto-flip', () => {
|
||||
expect(i18nStyle(style)).toMatchSnapshot();
|
||||
test('converts end/start properties', () => {
|
||||
const initial = {
|
||||
borderStartColor: 'red',
|
||||
start: 1,
|
||||
marginStart: 5,
|
||||
paddingEnd: 10
|
||||
};
|
||||
const expected = {
|
||||
borderLeftColor: 'red',
|
||||
left: 1,
|
||||
marginLeft: 5,
|
||||
paddingRight: 10
|
||||
};
|
||||
expect(i18nStyle(initial)).toEqual(expected);
|
||||
});
|
||||
|
||||
test('converts end/start values', () => {
|
||||
const initial = {
|
||||
float: 'start',
|
||||
textAlign: 'end'
|
||||
};
|
||||
const expected = {
|
||||
float: 'left',
|
||||
textAlign: 'right'
|
||||
};
|
||||
expect(i18nStyle(initial)).toEqual(expected);
|
||||
});
|
||||
|
||||
test('noop on left/right properties', () => {
|
||||
const initial = {
|
||||
paddingLeft: 0,
|
||||
left: 0,
|
||||
marginRight: 0,
|
||||
paddingRight: 10
|
||||
};
|
||||
expect(i18nStyle(initial)).toEqual(initial);
|
||||
});
|
||||
|
||||
test('noop on left/right values', () => {
|
||||
const initial = {
|
||||
clear: 'left',
|
||||
float: 'left',
|
||||
textAlign: 'right',
|
||||
textShadowOffset: { width: '1rem', height: 10 }
|
||||
};
|
||||
expect(i18nStyle(initial)).toEqual(initial);
|
||||
});
|
||||
|
||||
test('end/start properties take precedence', () => {
|
||||
const initial = {
|
||||
borderStartWidth: 10,
|
||||
borderLeftWidth: 0,
|
||||
end: 10,
|
||||
right: 0,
|
||||
marginStart: 10,
|
||||
marginLeft: 0
|
||||
};
|
||||
const expected = {
|
||||
borderLeftWidth: 10,
|
||||
marginLeft: 10,
|
||||
right: 10
|
||||
};
|
||||
expect(i18nStyle(initial)).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('RTL mode', () => {
|
||||
describe('isRTL is true', () => {
|
||||
beforeEach(() => {
|
||||
I18nManager.forceRTL(true);
|
||||
});
|
||||
@@ -48,8 +88,156 @@ describe('StyleSheet/i18nStyle', () => {
|
||||
I18nManager.forceRTL(false);
|
||||
});
|
||||
|
||||
test('does auto-flip', () => {
|
||||
expect(i18nStyle(style)).toMatchSnapshot();
|
||||
describe('doLeftAndRightSwapInRTL is false', () => {
|
||||
beforeEach(() => {
|
||||
I18nManager.swapLeftAndRightInRTL(false);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
I18nManager.swapLeftAndRightInRTL(true);
|
||||
});
|
||||
|
||||
test('converts end/start properties', () => {
|
||||
const initial = {
|
||||
borderStartColor: 'red',
|
||||
start: 1,
|
||||
marginStart: 5,
|
||||
paddingEnd: 10
|
||||
};
|
||||
const expected = {
|
||||
borderRightColor: 'red',
|
||||
right: 1,
|
||||
marginRight: 5,
|
||||
paddingLeft: 10
|
||||
};
|
||||
expect(i18nStyle(initial)).toEqual(expected);
|
||||
});
|
||||
|
||||
test('converts end/start values', () => {
|
||||
const initial = {
|
||||
float: 'start',
|
||||
textAlign: 'end'
|
||||
};
|
||||
const expected = {
|
||||
float: 'right',
|
||||
textAlign: 'left'
|
||||
};
|
||||
expect(i18nStyle(initial)).toEqual(expected);
|
||||
});
|
||||
|
||||
test('noop on left/right properties', () => {
|
||||
const initial = {
|
||||
paddingLeft: 0,
|
||||
left: 0,
|
||||
marginRight: 0,
|
||||
paddingRight: 10
|
||||
};
|
||||
expect(i18nStyle(initial)).toEqual(initial);
|
||||
});
|
||||
|
||||
test('noop on left/right values', () => {
|
||||
const initial = {
|
||||
clear: 'left',
|
||||
float: 'left',
|
||||
textAlign: 'right',
|
||||
textShadowOffset: { width: '1rem', height: 10 }
|
||||
};
|
||||
expect(i18nStyle(initial)).toEqual(initial);
|
||||
});
|
||||
|
||||
test('end/start properties take precedence', () => {
|
||||
const style = {
|
||||
borderStartWidth: 10,
|
||||
borderRightWidth: 0,
|
||||
end: 10,
|
||||
left: 0,
|
||||
marginStart: 10,
|
||||
marginRight: 0
|
||||
};
|
||||
const expected = {
|
||||
borderRightWidth: 10,
|
||||
marginRight: 10,
|
||||
left: 10
|
||||
};
|
||||
expect(i18nStyle(style)).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('doLeftAndRightSwapInRTL is true', () => {
|
||||
test('converts end/start properties', () => {
|
||||
const initial = {
|
||||
borderStartColor: 'red',
|
||||
start: 1,
|
||||
marginStart: 5,
|
||||
paddingEnd: 10
|
||||
};
|
||||
const expected = {
|
||||
borderRightColor: 'red',
|
||||
right: 1,
|
||||
marginRight: 5,
|
||||
paddingLeft: 10
|
||||
};
|
||||
expect(i18nStyle(initial)).toEqual(expected);
|
||||
});
|
||||
|
||||
test('converts end/start values', () => {
|
||||
const initial = {
|
||||
float: 'start',
|
||||
textAlign: 'end'
|
||||
};
|
||||
const expected = {
|
||||
float: 'right',
|
||||
textAlign: 'left'
|
||||
};
|
||||
expect(i18nStyle(initial)).toEqual(expected);
|
||||
});
|
||||
|
||||
test('converts left/right properties', () => {
|
||||
const initial = {
|
||||
borderLeftColor: 'red',
|
||||
left: 1,
|
||||
marginLeft: 5,
|
||||
paddingRight: 10
|
||||
};
|
||||
const expected = {
|
||||
borderRightColor: 'red',
|
||||
right: 1,
|
||||
marginRight: 5,
|
||||
paddingLeft: 10
|
||||
};
|
||||
expect(i18nStyle(initial)).toEqual(expected);
|
||||
});
|
||||
|
||||
test('converts left/right values', () => {
|
||||
const initial = {
|
||||
float: 'left',
|
||||
textAlign: 'right',
|
||||
textShadowOffset: { width: '1rem', height: 10 }
|
||||
};
|
||||
const expected = {
|
||||
float: 'right',
|
||||
textAlign: 'left',
|
||||
textShadowOffset: { width: '-1rem', height: 10 }
|
||||
};
|
||||
expect(i18nStyle(initial)).toEqual(expected);
|
||||
});
|
||||
|
||||
test('end/start properties take precedence', () => {
|
||||
const style = {
|
||||
borderStartWidth: 10,
|
||||
borderLeftWidth: 0,
|
||||
end: 10,
|
||||
right: 0,
|
||||
marginStart: 10,
|
||||
marginLeft: 0
|
||||
};
|
||||
const expected = {
|
||||
borderRightWidth: 10,
|
||||
marginRight: 10,
|
||||
left: 10
|
||||
};
|
||||
expect(i18nStyle(style)).toEqual(expected);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
/**
|
||||
* Copyright (c) 2016-present, Nicolas Gallagher.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @noflow
|
||||
*/
|
||||
|
||||
import normalizeValue from './normalizeValue';
|
||||
import processColor from '../processColor';
|
||||
|
||||
/**
|
||||
* The browser implements the CSS cascade, where the order of properties is a
|
||||
* factor in determining which styles to paint. React Native is different. It
|
||||
* gives giving precedence to the more specific style property. For example,
|
||||
@@ -13,13 +19,8 @@
|
||||
* This module creates mutally exclusive style declarations by expanding all of
|
||||
* React Native's supported shortform properties (e.g. `padding`) to their
|
||||
* longfrom equivalents.
|
||||
*
|
||||
* @noflow
|
||||
*/
|
||||
|
||||
import normalizeValue from './normalizeValue';
|
||||
import processColor from '../processColor';
|
||||
|
||||
const emptyObject = {};
|
||||
const styleShortFormProperties = {
|
||||
borderColor: ['borderTopColor', 'borderRightColor', 'borderBottomColor', 'borderLeftColor'],
|
||||
@@ -63,7 +64,7 @@ const borderWidthProps = {
|
||||
|
||||
const monospaceFontStack = 'monospace, monospace';
|
||||
const systemFontStack =
|
||||
'-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, "Helvetica Neue", sans-serif';
|
||||
'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, "Helvetica Neue", sans-serif';
|
||||
|
||||
const alphaSortProps = propsArray =>
|
||||
propsArray.sort((a, b) => {
|
||||
@@ -236,8 +237,10 @@ const createReducer = (style, styleProps) => {
|
||||
}
|
||||
|
||||
case 'fontFamily': {
|
||||
if (value === 'System') {
|
||||
resolvedStyle.fontFamily = systemFontStack;
|
||||
if (value.indexOf('System') > -1) {
|
||||
const stack = value.split(/\s*,\s*/);
|
||||
stack[stack.indexOf('System')] = systemFontStack;
|
||||
resolvedStyle.fontFamily = stack.join(', ');
|
||||
} else if (value === 'monospace') {
|
||||
resolvedStyle.fontFamily = monospaceFontStack;
|
||||
} else {
|
||||
@@ -246,6 +249,13 @@ const createReducer = (style, styleProps) => {
|
||||
break;
|
||||
}
|
||||
|
||||
case 'fontVariant': {
|
||||
if (Array.isArray(value) && value.length > 0) {
|
||||
resolvedStyle.fontVariant = value.join(' ');
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'shadowColor':
|
||||
case 'shadowOffset':
|
||||
case 'shadowOpacity':
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
/**
|
||||
* Copyright (c) 2016-present, Nicolas Gallagher.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @noflow
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Nicolas Gallagher.
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @providesModule flattenStyle
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
/**
|
||||
* Copyright (c) 2016-present, Nicolas Gallagher.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @noflow
|
||||
@@ -13,75 +12,119 @@ import multiplyStyleLengthValue from '../../modules/multiplyStyleLengthValue';
|
||||
|
||||
const emptyObject = {};
|
||||
|
||||
/**
|
||||
* Map of property names to their BiDi equivalent.
|
||||
*/
|
||||
const PROPERTIES_TO_SWAP = {
|
||||
borderTopLeftRadius: 'borderTopRightRadius',
|
||||
borderTopRightRadius: 'borderTopLeftRadius',
|
||||
borderBottomLeftRadius: 'borderBottomRightRadius',
|
||||
borderBottomRightRadius: 'borderBottomLeftRadius',
|
||||
borderLeftColor: 'borderRightColor',
|
||||
borderLeftStyle: 'borderRightStyle',
|
||||
borderLeftWidth: 'borderRightWidth',
|
||||
borderRightColor: 'borderLeftColor',
|
||||
borderRightWidth: 'borderLeftWidth',
|
||||
borderRightStyle: 'borderLeftStyle',
|
||||
left: 'right',
|
||||
marginLeft: 'marginRight',
|
||||
marginRight: 'marginLeft',
|
||||
paddingLeft: 'paddingRight',
|
||||
paddingRight: 'paddingLeft',
|
||||
right: 'left'
|
||||
const borderTopLeftRadius = 'borderTopLeftRadius';
|
||||
const borderTopRightRadius = 'borderTopRightRadius';
|
||||
const borderBottomLeftRadius = 'borderBottomLeftRadius';
|
||||
const borderBottomRightRadius = 'borderBottomRightRadius';
|
||||
const borderLeftColor = 'borderLeftColor';
|
||||
const borderLeftStyle = 'borderLeftStyle';
|
||||
const borderLeftWidth = 'borderLeftWidth';
|
||||
const borderRightColor = 'borderRightColor';
|
||||
const borderRightStyle = 'borderRightStyle';
|
||||
const borderRightWidth = 'borderRightWidth';
|
||||
const right = 'right';
|
||||
const marginLeft = 'marginLeft';
|
||||
const marginRight = 'marginRight';
|
||||
const paddingLeft = 'paddingLeft';
|
||||
const paddingRight = 'paddingRight';
|
||||
const left = 'left';
|
||||
|
||||
// Map of LTR property names to their BiDi equivalent.
|
||||
const PROPERTIES_FLIP = {
|
||||
borderTopLeftRadius: borderTopRightRadius,
|
||||
borderTopRightRadius: borderTopLeftRadius,
|
||||
borderBottomLeftRadius: borderBottomRightRadius,
|
||||
borderBottomRightRadius: borderBottomLeftRadius,
|
||||
borderLeftColor: borderRightColor,
|
||||
borderLeftStyle: borderRightStyle,
|
||||
borderLeftWidth: borderRightWidth,
|
||||
borderRightColor: borderLeftColor,
|
||||
borderRightStyle: borderLeftStyle,
|
||||
borderRightWidth: borderLeftWidth,
|
||||
left: right,
|
||||
marginLeft: marginRight,
|
||||
marginRight: marginLeft,
|
||||
paddingLeft: paddingRight,
|
||||
paddingRight: paddingLeft,
|
||||
right: left
|
||||
};
|
||||
|
||||
const PROPERTIES_SWAP_LEFT_RIGHT = {
|
||||
// Map of I18N property names to their LTR equivalent.
|
||||
const PROPERTIES_I18N = {
|
||||
borderTopStartRadius: borderTopLeftRadius,
|
||||
borderTopEndRadius: borderTopRightRadius,
|
||||
borderBottomStartRadius: borderBottomLeftRadius,
|
||||
borderBottomEndRadius: borderBottomRightRadius,
|
||||
borderStartColor: borderLeftColor,
|
||||
borderStartStyle: borderLeftStyle,
|
||||
borderStartWidth: borderLeftWidth,
|
||||
borderEndColor: borderRightColor,
|
||||
borderEndStyle: borderRightStyle,
|
||||
borderEndWidth: borderRightWidth,
|
||||
end: right,
|
||||
marginStart: marginLeft,
|
||||
marginEnd: marginRight,
|
||||
paddingStart: paddingLeft,
|
||||
paddingEnd: paddingRight,
|
||||
start: left
|
||||
};
|
||||
|
||||
const PROPERTIES_VALUE = {
|
||||
clear: true,
|
||||
float: true,
|
||||
textAlign: true
|
||||
};
|
||||
|
||||
/**
|
||||
* Invert the sign of a numeric-like value
|
||||
*/
|
||||
// Invert the sign of a numeric-like value
|
||||
const additiveInverse = (value: String | Number) => multiplyStyleLengthValue(value, -1);
|
||||
|
||||
/**
|
||||
* BiDi flip the given property.
|
||||
*/
|
||||
const flipProperty = (prop: String): String => {
|
||||
return PROPERTIES_TO_SWAP.hasOwnProperty(prop) ? PROPERTIES_TO_SWAP[prop] : prop;
|
||||
};
|
||||
|
||||
const swapLeftRight = (value: String): String => {
|
||||
return value === 'left' ? 'right' : value === 'right' ? 'left' : value;
|
||||
};
|
||||
|
||||
const i18nStyle = originalStyle => {
|
||||
if (!I18nManager.isRTL) {
|
||||
return originalStyle;
|
||||
}
|
||||
|
||||
const { doLeftAndRightSwapInRTL, isRTL } = I18nManager;
|
||||
const style = originalStyle || emptyObject;
|
||||
const frozenProps = {};
|
||||
const nextStyle = {};
|
||||
|
||||
for (const prop in style) {
|
||||
if (!Object.prototype.hasOwnProperty.call(style, prop)) {
|
||||
for (const originalProp in style) {
|
||||
if (!Object.prototype.hasOwnProperty.call(style, originalProp)) {
|
||||
continue;
|
||||
}
|
||||
const originalValue = style[originalProp];
|
||||
let prop = originalProp;
|
||||
let value = originalValue;
|
||||
|
||||
const value = style[prop];
|
||||
// BiDi flip properties
|
||||
if (PROPERTIES_I18N.hasOwnProperty(originalProp)) {
|
||||
// convert start/end
|
||||
const convertedProp = PROPERTIES_I18N[originalProp];
|
||||
prop = isRTL ? PROPERTIES_FLIP[convertedProp] : convertedProp;
|
||||
} else if (isRTL && doLeftAndRightSwapInRTL && PROPERTIES_FLIP[originalProp]) {
|
||||
prop = PROPERTIES_FLIP[originalProp];
|
||||
}
|
||||
|
||||
if (PROPERTIES_TO_SWAP[prop]) {
|
||||
const newProp = flipProperty(prop);
|
||||
nextStyle[newProp] = value;
|
||||
} else if (PROPERTIES_SWAP_LEFT_RIGHT[prop]) {
|
||||
nextStyle[prop] = swapLeftRight(value);
|
||||
} else if (prop === 'textShadowOffset') {
|
||||
// BiDi flip values
|
||||
if (PROPERTIES_VALUE.hasOwnProperty(originalProp)) {
|
||||
if (originalValue === 'start') {
|
||||
value = isRTL ? 'right' : 'left';
|
||||
} else if (originalValue === 'end') {
|
||||
value = isRTL ? 'left' : 'right';
|
||||
} else if (isRTL && doLeftAndRightSwapInRTL) {
|
||||
if (originalValue === 'left') {
|
||||
value = 'right';
|
||||
} else if (originalValue === 'right') {
|
||||
value = 'left';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isRTL && prop === 'textShadowOffset') {
|
||||
nextStyle[prop] = value;
|
||||
nextStyle[prop].width = additiveInverse(value.width);
|
||||
} else {
|
||||
nextStyle[prop] = style[prop];
|
||||
} else if (!frozenProps[prop]) {
|
||||
nextStyle[prop] = value;
|
||||
}
|
||||
|
||||
if (PROPERTIES_I18N[originalProp]) {
|
||||
frozenProps[prop] = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
/**
|
||||
* Copyright (c) 2016-present, Nicolas Gallagher.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
/**
|
||||
* Copyright (c) 2016-present, Nicolas Gallagher.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @noflow
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
/**
|
||||
* Copyright (c) 2016-present, Nicolas Gallagher.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
/**
|
||||
* Copyright (c) 2016-present, Nicolas Gallagher.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @providesModule Switch
|
||||
@@ -136,7 +135,7 @@ class Switch extends Component<*> {
|
||||
thumbStyle,
|
||||
value && styles.thumbOn,
|
||||
{
|
||||
marginLeft: value ? multiplyStyleLengthValue(thumbWidth, -1) : 0
|
||||
marginStart: value ? multiplyStyleLengthValue(thumbWidth, -1) : 0
|
||||
}
|
||||
]}
|
||||
/>
|
||||
@@ -192,12 +191,12 @@ const styles = StyleSheet.create({
|
||||
alignSelf: 'flex-start',
|
||||
borderRadius: '100%',
|
||||
boxShadow: thumbDefaultBoxShadow,
|
||||
left: '0%',
|
||||
start: '0%',
|
||||
transform: [{ translateZ: 0 }],
|
||||
transitionDuration: '0.1s'
|
||||
},
|
||||
thumbOn: {
|
||||
left: '100%'
|
||||
start: '100%'
|
||||
},
|
||||
disabledThumb: {
|
||||
backgroundColor: '#BDBDBD'
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Nicolas Gallagher.
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @providesModule TextPropTypes
|
||||
@@ -24,6 +23,9 @@ const TextPropTypes = {
|
||||
children: any,
|
||||
importantForAccessibility: oneOf(['auto', 'no', 'no-hide-descendants', 'yes']),
|
||||
numberOfLines: number,
|
||||
onBlur: func,
|
||||
onContextMenu: func,
|
||||
onFocus: func,
|
||||
onLayout: func,
|
||||
onPress: func,
|
||||
selectable: bool,
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Nicolas Gallagher.
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
@@ -11,14 +10,10 @@
|
||||
|
||||
import ColorPropType from '../ColorPropType';
|
||||
import ViewStylePropTypes from '../View/ViewStylePropTypes';
|
||||
import { number, oneOf, oneOfType, shape, string } from 'prop-types';
|
||||
import { array, number, oneOf, oneOfType, shape, string } from 'prop-types';
|
||||
|
||||
const numberOrString = oneOfType([number, string]);
|
||||
|
||||
const ShadowOffsetPropType = shape({ width: number, height: number });
|
||||
const TextAlignPropType = oneOf(['center', 'inherit', 'justify', 'justify-all', 'left', 'right']);
|
||||
const WritingDirectionPropType = oneOf(['auto', 'ltr', 'rtl']);
|
||||
|
||||
const TextStylePropTypes = {
|
||||
...ViewStylePropTypes,
|
||||
color: ColorPropType,
|
||||
@@ -27,17 +22,27 @@ const TextStylePropTypes = {
|
||||
fontSize: numberOrString,
|
||||
fontStyle: string,
|
||||
fontWeight: string,
|
||||
fontVariant: array,
|
||||
letterSpacing: numberOrString,
|
||||
lineHeight: numberOrString,
|
||||
textAlign: TextAlignPropType,
|
||||
textAlign: oneOf([
|
||||
'center',
|
||||
'end',
|
||||
'inherit',
|
||||
'justify',
|
||||
'justify-all',
|
||||
'left',
|
||||
'right',
|
||||
'start'
|
||||
]),
|
||||
textAlignVertical: string,
|
||||
textDecorationColor: ColorPropType,
|
||||
textDecorationLine: string,
|
||||
textDecorationStyle: string,
|
||||
textShadowColor: ColorPropType,
|
||||
textShadowOffset: ShadowOffsetPropType,
|
||||
textShadowOffset: shape({ width: number, height: number }),
|
||||
textShadowRadius: number,
|
||||
writingDirection: WritingDirectionPropType,
|
||||
writingDirection: oneOf(['auto', 'ltr', 'rtl']),
|
||||
/* @platform web */
|
||||
textIndent: numberOrString,
|
||||
textOverflow: string,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
exports[`components/Text prop "onPress" 1`] = `
|
||||
<div
|
||||
className="rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-color-homxoj rn-cursor-1loqt21 rn-display-1471scf rn-font-1lw9tu2 rn-fontFamily-10u92zi rn-fontSize-1b43r93 rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-paddingTop-wk8lta rn-paddingRight-9aemit rn-paddingBottom-1mdbw0j rn-paddingLeft-gy4na3 rn-textDecoration-bauka4 rn-whiteSpace-q42fyq rn-wordWrap-qvutc0"
|
||||
className="rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-color-homxoj rn-cursor-1loqt21 rn-display-1471scf rn-font-1lw9tu2 rn-fontFamily-14xgk7a rn-fontSize-1b43r93 rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-paddingTop-wk8lta rn-paddingRight-9aemit rn-paddingBottom-1mdbw0j rn-paddingLeft-gy4na3 rn-textDecoration-bauka4 rn-whiteSpace-q42fyq rn-wordWrap-qvutc0"
|
||||
dir="auto"
|
||||
onClick={[Function]}
|
||||
onKeyDown={[Function]}
|
||||
@@ -12,14 +12,14 @@ exports[`components/Text prop "onPress" 1`] = `
|
||||
|
||||
exports[`components/Text prop "selectable" 1`] = `
|
||||
<div
|
||||
className="rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-color-homxoj rn-display-1471scf rn-font-1lw9tu2 rn-fontFamily-10u92zi rn-fontSize-1b43r93 rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-paddingTop-wk8lta rn-paddingRight-9aemit rn-paddingBottom-1mdbw0j rn-paddingLeft-gy4na3 rn-textDecoration-bauka4 rn-whiteSpace-q42fyq rn-wordWrap-qvutc0"
|
||||
className="rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-color-homxoj rn-display-1471scf rn-font-1lw9tu2 rn-fontFamily-14xgk7a rn-fontSize-1b43r93 rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-paddingTop-wk8lta rn-paddingRight-9aemit rn-paddingBottom-1mdbw0j rn-paddingLeft-gy4na3 rn-textDecoration-bauka4 rn-whiteSpace-q42fyq rn-wordWrap-qvutc0"
|
||||
dir="auto"
|
||||
/>
|
||||
`;
|
||||
|
||||
exports[`components/Text prop "selectable" 2`] = `
|
||||
<div
|
||||
className="rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-color-homxoj rn-display-1471scf rn-font-1lw9tu2 rn-fontFamily-10u92zi rn-fontSize-1b43r93 rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-paddingTop-wk8lta rn-paddingRight-9aemit rn-paddingBottom-1mdbw0j rn-paddingLeft-gy4na3 rn-textDecoration-bauka4 rn-userSelect-lrvibr rn-whiteSpace-q42fyq rn-wordWrap-qvutc0"
|
||||
className="rn-borderTopWidth-13yce4e rn-borderRightWidth-fnigne rn-borderBottomWidth-ndvcnb rn-borderLeftWidth-gxnn5r rn-boxSizing-deolkf rn-color-homxoj rn-display-1471scf rn-font-1lw9tu2 rn-fontFamily-14xgk7a rn-fontSize-1b43r93 rn-marginTop-1mnahxq rn-marginRight-61z16t rn-marginBottom-p1pxzi rn-marginLeft-11wrixw rn-paddingTop-wk8lta rn-paddingRight-9aemit rn-paddingBottom-1mdbw0j rn-paddingLeft-gy4na3 rn-textDecoration-bauka4 rn-userSelect-lrvibr rn-whiteSpace-q42fyq rn-wordWrap-qvutc0"
|
||||
dir="auto"
|
||||
/>
|
||||
`;
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Nicolas Gallagher.
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @providesModule Text
|
||||
@@ -54,6 +53,7 @@ class Text extends Component<*> {
|
||||
selectionColor,
|
||||
suppressHighlighting,
|
||||
textBreakStrategy,
|
||||
tvParallaxProperties,
|
||||
/* eslint-enable */
|
||||
...otherProps
|
||||
} = this.props;
|
||||
@@ -110,6 +110,7 @@ const styles = StyleSheet.create({
|
||||
// inherit parent font styles
|
||||
fontFamily: 'inherit',
|
||||
fontSize: 'inherit',
|
||||
fontVariant: ['inherit'],
|
||||
whiteSpace: 'inherit'
|
||||
},
|
||||
notSelectable: {
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Nicolas Gallagher.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/* eslint-env jasmine, jest */
|
||||
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import TextInput from '..';
|
||||
import { mount, shallow } from 'enzyme';
|
||||
|
||||
@@ -112,8 +113,14 @@ describe('components/TextInput', () => {
|
||||
test('prop "onBlur"', () => {
|
||||
const onBlur = jest.fn();
|
||||
const input = findNativeInput(mount(<TextInput onBlur={onBlur} />));
|
||||
const node = ReactDOM.findDOMNode(input.instance());
|
||||
|
||||
// more accurate blur simulation
|
||||
input.simulate('blur');
|
||||
node.blur();
|
||||
|
||||
expect(onBlur).toHaveBeenCalledTimes(1);
|
||||
expect(TextInput.State.currentlyFocusedField()).toBe(null);
|
||||
});
|
||||
|
||||
test('prop "onChange"', () => {
|
||||
@@ -135,8 +142,14 @@ describe('components/TextInput', () => {
|
||||
test('prop "onFocus"', () => {
|
||||
const onFocus = jest.fn();
|
||||
const input = findNativeInput(mount(<TextInput onFocus={onFocus} />));
|
||||
const node = ReactDOM.findDOMNode(input.instance());
|
||||
|
||||
// more accurate focus simulation
|
||||
input.simulate('focus');
|
||||
node.focus();
|
||||
|
||||
expect(onFocus).toHaveBeenCalledTimes(1);
|
||||
expect(TextInput.State.currentlyFocusedField()).toBe(node);
|
||||
});
|
||||
|
||||
describe('prop "onKeyPress"', () => {
|
||||
@@ -216,6 +229,25 @@ describe('components/TextInput', () => {
|
||||
);
|
||||
});
|
||||
|
||||
test('arrow key', () => {
|
||||
const onKeyPress = jest.fn();
|
||||
const input = findNativeInput(mount(<TextInput onKeyPress={onKeyPress} />));
|
||||
input.simulate('keyPress', { which: 37 });
|
||||
expect(onKeyPress).toHaveBeenCalledTimes(1);
|
||||
expect(onKeyPress).toBeCalledWith(
|
||||
expect.objectContaining({
|
||||
nativeEvent: {
|
||||
altKey: undefined,
|
||||
ctrlKey: undefined,
|
||||
key: 'ArrowLeft',
|
||||
metaKey: undefined,
|
||||
shiftKey: undefined,
|
||||
target: expect.anything()
|
||||
}
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
test('text key', () => {
|
||||
const onKeyPress = jest.fn();
|
||||
const input = findNativeInput(mount(<TextInput onKeyPress={onKeyPress} />));
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Nicolas Gallagher.
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @providesModule TextInput
|
||||
@@ -162,6 +161,9 @@ class TextInput extends Component<*> {
|
||||
|
||||
componentDidMount() {
|
||||
setSelection(this._node, this.props.selection);
|
||||
if (document.activeElement === this._node) {
|
||||
TextInputState._currentlyFocusedNode = this._node;
|
||||
}
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
@@ -264,7 +266,7 @@ class TextInput extends Component<*> {
|
||||
|
||||
_handleBlur = e => {
|
||||
const { onBlur } = this.props;
|
||||
TextInputState.blurTextInput(this._node);
|
||||
TextInputState._currentlyFocusedNode = null;
|
||||
if (onBlur) {
|
||||
onBlur(e);
|
||||
}
|
||||
@@ -284,7 +286,7 @@ class TextInput extends Component<*> {
|
||||
_handleFocus = e => {
|
||||
const { clearTextOnFocus, onFocus, selectTextOnFocus } = this.props;
|
||||
const node = this._node;
|
||||
TextInputState.focusTextInput(this._node);
|
||||
TextInputState._currentlyFocusedNode = this._node;
|
||||
if (onFocus) {
|
||||
onFocus(e);
|
||||
}
|
||||
@@ -297,11 +299,19 @@ class TextInput extends Component<*> {
|
||||
};
|
||||
|
||||
_handleKeyDown = e => {
|
||||
// prevent key events bubbling (see #612)
|
||||
// Prevent key events bubbling (see #612)
|
||||
e.stopPropagation();
|
||||
|
||||
// Backspace, Tab, and Cmd+Enter only fire 'keydown' DOM events
|
||||
if (e.which === 8 || e.which === 9 || (e.which === 13 && e.metaKey)) {
|
||||
// Backspace, Tab, Cmd+Enter, and Arrow keys only fire 'keydown' DOM events
|
||||
if (
|
||||
e.which === 8 ||
|
||||
e.which === 9 ||
|
||||
(e.which === 13 && e.metaKey) ||
|
||||
e.which === 37 ||
|
||||
e.which === 38 ||
|
||||
e.which === 39 ||
|
||||
e.which === 40
|
||||
) {
|
||||
this._handleKeyPress(e);
|
||||
}
|
||||
};
|
||||
@@ -314,24 +324,32 @@ class TextInput extends Component<*> {
|
||||
if (onKeyPress) {
|
||||
let keyValue;
|
||||
switch (e.which) {
|
||||
// backspace
|
||||
case 8:
|
||||
keyValue = 'Backspace';
|
||||
break;
|
||||
// tab
|
||||
case 9:
|
||||
keyValue = 'Tab';
|
||||
break;
|
||||
// enter
|
||||
case 13:
|
||||
keyValue = 'Enter';
|
||||
break;
|
||||
// spacebar
|
||||
case 32:
|
||||
keyValue = ' ';
|
||||
break;
|
||||
case 37:
|
||||
keyValue = 'ArrowLeft';
|
||||
break;
|
||||
case 38:
|
||||
keyValue = 'ArrowUp';
|
||||
break;
|
||||
case 39:
|
||||
keyValue = 'ArrowRight';
|
||||
break;
|
||||
case 40:
|
||||
keyValue = 'ArrowDown';
|
||||
break;
|
||||
default: {
|
||||
// we trim to only care about the keys that has a textual representation
|
||||
// Trim to only care about the keys that have a textual representation
|
||||
if (e.shiftKey) {
|
||||
keyValue = String.fromCharCode(e.which).trim();
|
||||
} else {
|
||||
@@ -398,8 +416,8 @@ const styles = StyleSheet.create({
|
||||
borderStyle: 'solid',
|
||||
borderWidth: 0,
|
||||
boxSizing: 'border-box',
|
||||
color: 'inherit',
|
||||
font: 'inherit',
|
||||
fontFamily: 'System',
|
||||
fontSize: 14,
|
||||
padding: 0,
|
||||
resize: 'none'
|
||||
}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Nicolas Gallagher.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @noflow
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @providesModule ensurePositiveDelayProps
|
||||
|
||||
@@ -3,9 +3,8 @@
|
||||
/**
|
||||
* Copyright (c) 2016-present, Nicolas Gallagher.
|
||||
* Copyright (c) 2013-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @providesModule Touchable
|
||||
@@ -425,13 +424,6 @@ const TouchableMixin = {
|
||||
*/
|
||||
touchableHandleResponderRelease: function(e: Event) {
|
||||
this._receiveSignal(Signals.RESPONDER_RELEASE, e);
|
||||
// Browsers fire mouse events after touch events. This causes the
|
||||
// 'onResponderRelease' handler to be called twice for Touchables.
|
||||
// Auto-fix this issue by calling 'preventDefault' to cancel the mouse
|
||||
// events.
|
||||
if (e.cancelable && !e.isDefaultPrevented()) {
|
||||
e.preventDefault();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
/**
|
||||
* Copyright (c) 2016-present, Nicolas Gallagher.
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @providesModule TouchableHighlight
|
||||
@@ -287,7 +286,7 @@ const styles = StyleSheet.create({
|
||||
},
|
||||
actionable: {
|
||||
cursor: 'pointer',
|
||||
touchAction: 'manipulate'
|
||||
touchAction: 'manipulation'
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
/**
|
||||
* Copyright 2017-present, Nicolas Gallagher
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
/**
|
||||
* Copyright (c) 2016-present, Nicolas Gallagher.
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @providesModule TouchableOpacity
|
||||
@@ -204,7 +203,7 @@ const styles = StyleSheet.create({
|
||||
},
|
||||
actionable: {
|
||||
cursor: 'pointer',
|
||||
touchAction: 'manipulate'
|
||||
touchAction: 'manipulation'
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
/**
|
||||
* Copyright (c) 2016-present, Nicolas Gallagher.
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @providesModule TouchableWithoutFeedback
|
||||
@@ -202,7 +201,7 @@ const TouchableWithoutFeedback = createReactClass({
|
||||
const styles = StyleSheet.create({
|
||||
actionable: {
|
||||
cursor: 'pointer',
|
||||
touchAction: 'manipulate'
|
||||
touchAction: 'manipulation'
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
/**
|
||||
* Copyright (c) 2016-present, Nicolas Gallagher.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @providesModule UIManager
|
||||
@@ -16,11 +15,13 @@ import setValueForStyles from '../../vendor/setValueForStyles';
|
||||
const getRect = node => {
|
||||
const height = node.offsetHeight;
|
||||
const width = node.offsetWidth;
|
||||
let left = 0;
|
||||
let top = 0;
|
||||
let left = node.offsetLeft;
|
||||
let top = node.offsetTop;
|
||||
node = node.offsetParent;
|
||||
|
||||
while (node && node.nodeType === 1 /* Node.ELEMENT_NODE */) {
|
||||
left += node.offsetLeft;
|
||||
top += node.offsetTop;
|
||||
left += node.offsetLeft - node.scrollLeft;
|
||||
top += node.offsetTop - node.scrollTop;
|
||||
node = node.offsetParent;
|
||||
}
|
||||
return { height, left, top, width };
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
/**
|
||||
* Copyright (c) 2016-present, Nicolas Gallagher.
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @providesModule Vibration
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Nicolas Gallagher.
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @providesModule ViewPropTypes
|
||||
@@ -13,7 +12,7 @@
|
||||
import EdgeInsetsPropType, { type EdgeInsetsProp } from '../EdgeInsetsPropType';
|
||||
import StyleSheetPropType from '../../modules/StyleSheetPropType';
|
||||
import ViewStylePropTypes from './ViewStylePropTypes';
|
||||
import { any, array, bool, func, oneOf, oneOfType, string } from 'prop-types';
|
||||
import { any, array, bool, func, object, oneOf, oneOfType, string } from 'prop-types';
|
||||
|
||||
const stylePropType = StyleSheetPropType(ViewStylePropTypes);
|
||||
|
||||
@@ -40,8 +39,11 @@ export type ViewProps = {
|
||||
children?: any,
|
||||
hitSlop?: EdgeInsetsProp,
|
||||
importantForAccessibility?: 'auto' | 'yes' | 'no' | 'no-hide-descendants',
|
||||
onBlur?: Function,
|
||||
onClick?: Function,
|
||||
onClickCapture?: Function,
|
||||
onContextMenu?: Function,
|
||||
onFocus?: Function,
|
||||
onLayout?: (event: ViewLayoutEvent) => void,
|
||||
onResponderGrant?: Function,
|
||||
onResponderMove?: Function,
|
||||
@@ -72,7 +74,8 @@ export type ViewProps = {
|
||||
onMagicTap?: Function,
|
||||
removeClippedSubviews?: boolean,
|
||||
renderToHardwareTextureAndroid?: boolean,
|
||||
shouldRasterizeIOS?: boolean
|
||||
shouldRasterizeIOS?: boolean,
|
||||
tvParallaxProperties?: {}
|
||||
};
|
||||
|
||||
const ViewPropTypes = {
|
||||
@@ -85,8 +88,11 @@ const ViewPropTypes = {
|
||||
children: any,
|
||||
hitSlop: EdgeInsetsPropType,
|
||||
importantForAccessibility: oneOf(['auto', 'no', 'no-hide-descendants', 'yes']),
|
||||
onBlur: func,
|
||||
onClick: func,
|
||||
onClickCapture: func,
|
||||
onContextMenu: func,
|
||||
onFocus: func,
|
||||
onLayout: func,
|
||||
onMoveShouldSetResponder: func,
|
||||
onMoveShouldSetResponderCapture: func,
|
||||
@@ -117,7 +123,8 @@ const ViewPropTypes = {
|
||||
onMagicTap: func,
|
||||
removeClippedSubviews: bool,
|
||||
renderToHardwareTextureAndroid: bool,
|
||||
shouldRasterizeIOS: bool
|
||||
shouldRasterizeIOS: bool,
|
||||
tvParallaxProperties: object
|
||||
};
|
||||
|
||||
export default ViewPropTypes;
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Nicolas Gallagher.
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
@@ -12,16 +11,18 @@
|
||||
import AnimationPropTypes from '../../modules/AnimationPropTypes';
|
||||
import BorderPropTypes from '../../modules/BorderPropTypes';
|
||||
import ColorPropType from '../ColorPropType';
|
||||
import InteractionPropTypes from '../../modules/InteractionPropTypes';
|
||||
import LayoutPropTypes from '../../modules/LayoutPropTypes';
|
||||
import ShadowPropTypes from '../../modules/ShadowPropTypes';
|
||||
import TransformPropTypes from '../../modules/TransformPropTypes';
|
||||
import { number, oneOf, oneOfType, string } from 'prop-types';
|
||||
import { number, oneOf, string } from 'prop-types';
|
||||
|
||||
const overscrollBehaviorType = oneOf(['auto', 'contain', 'none']);
|
||||
|
||||
const ViewStylePropTypes = {
|
||||
...AnimationPropTypes,
|
||||
...BorderPropTypes,
|
||||
...InteractionPropTypes,
|
||||
...LayoutPropTypes,
|
||||
...ShadowPropTypes,
|
||||
...TransformPropTypes,
|
||||
@@ -44,22 +45,12 @@ const ViewStylePropTypes = {
|
||||
backgroundSize: string,
|
||||
boxShadow: string,
|
||||
clip: string,
|
||||
cursor: string,
|
||||
filter: string,
|
||||
outline: string,
|
||||
outlineColor: ColorPropType,
|
||||
overscrollBehavior: overscrollBehaviorType,
|
||||
overscrollBehaviorX: overscrollBehaviorType,
|
||||
overscrollBehaviorY: overscrollBehaviorType,
|
||||
perspective: oneOfType([number, string]),
|
||||
perspectiveOrigin: string,
|
||||
touchAction: string,
|
||||
transitionDelay: string,
|
||||
transitionDuration: string,
|
||||
transitionProperty: string,
|
||||
transitionTimingFunction: string,
|
||||
userSelect: string,
|
||||
willChange: string,
|
||||
WebkitMaskImage: string,
|
||||
WebkitOverflowScrolling: oneOf(['auto', 'touch'])
|
||||
};
|
||||
|
||||
@@ -49,6 +49,7 @@ class View extends Component<ViewProps> {
|
||||
removeClippedSubviews,
|
||||
renderToHardwareTextureAndroid,
|
||||
shouldRasterizeIOS,
|
||||
tvParallaxProperties,
|
||||
/* eslint-enable */
|
||||
...otherProps
|
||||
} = this.props;
|
||||
|
||||
@@ -3,7 +3,10 @@
|
||||
exports[`modules/createElement it normalizes event.nativeEvent 1`] = `
|
||||
Object {
|
||||
"_normalized": true,
|
||||
"bubbles": undefined,
|
||||
"cancelable": undefined,
|
||||
"changedTouches": Array [],
|
||||
"defaultPrevented": undefined,
|
||||
"identifier": undefined,
|
||||
"locationX": undefined,
|
||||
"locationY": undefined,
|
||||
@@ -15,6 +18,8 @@ Object {
|
||||
"target": undefined,
|
||||
"timestamp": 1496876171255,
|
||||
"touches": Array [],
|
||||
"type": undefined,
|
||||
"which": undefined,
|
||||
}
|
||||
`;
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Nicolas Gallagher.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @noflow
|
||||
@@ -22,18 +21,12 @@ import React from 'react';
|
||||
* and remove event handlers when disabled.
|
||||
*/
|
||||
const eventHandlerNames = {
|
||||
onBlur: true,
|
||||
onClick: true,
|
||||
onClickCapture: true,
|
||||
onMoveShouldSetResponder: true,
|
||||
onMoveShouldSetResponderCapture: true,
|
||||
onResponderGrant: true,
|
||||
onResponderMove: true,
|
||||
onResponderReject: true,
|
||||
onContextMenu: true,
|
||||
onFocus: true,
|
||||
onResponderRelease: true,
|
||||
onResponderTerminate: true,
|
||||
onResponderTerminationRequest: true,
|
||||
onStartShouldSetResponder: true,
|
||||
onStartShouldSetResponderCapture: true,
|
||||
onTouchCancel: true,
|
||||
onTouchCancelCapture: true,
|
||||
onTouchEnd: true,
|
||||
@@ -53,6 +46,17 @@ const adjustProps = domProps => {
|
||||
if (isEventHandler) {
|
||||
if (isButtonRole && isDisabled) {
|
||||
domProps[propName] = undefined;
|
||||
} else if (propName === 'onResponderRelease') {
|
||||
// Browsers fire mouse events after touch events. This causes the
|
||||
// 'onResponderRelease' handler to be called twice for Touchables.
|
||||
// Auto-fix this issue by calling 'preventDefault' to cancel the mouse
|
||||
// events.
|
||||
domProps[propName] = e => {
|
||||
if (e.cancelable && !e.isDefaultPrevented()) {
|
||||
e.preventDefault();
|
||||
}
|
||||
return prop(e);
|
||||
};
|
||||
} else {
|
||||
// TODO: move this out of the render path
|
||||
domProps[propName] = e => {
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
/**
|
||||
* Copyright (c) 2016-present, Nicolas Gallagher.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @providesModule findNodeHandle
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
/**
|
||||
* Copyright (c) 2016-present, Nicolas Gallagher.
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @providesModule processColor
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
/**
|
||||
* Copyright (c) 2016-present, Nicolas Gallagher.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @noflow
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
/**
|
||||
* Copyright (c) 2016-present, Nicolas Gallagher.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @noflow
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
/**
|
||||
* Copyright (c) 2017-present, Nicolas Gallagher.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user