Compare commits

..

14 Commits

Author SHA1 Message Date
Nicolas Gallagher
bc68b0b6f4 0.0.61 2016-12-27 18:09:11 +00:00
Nicolas Gallagher
44ecbc072e [change] update React and Touchables
Update to React@15.4. The 'EventConstants' module no longer exports a
key-mirror, which was preventing the 'ResponderEventPlugin' from working
as it did with React@15.3.

Close #255
2016-12-27 17:57:27 +00:00
Nicolas Gallagher
4cf4905fc2 [change] add support for ShadowPropTypes
Fix #44
2016-12-26 13:57:19 +00:00
Nicolas Gallagher
509920be4b [add] Image 'prefetch' and 'getSize' statics
Fix #160
2016-12-26 13:31:40 +00:00
Gethin Webster
04e3c23e67 [fix] ListView updates rows when dataSource changes
Close #295
2016-12-23 12:51:40 +00:00
Nicolas Gallagher
32f454de66 [change] add Platform and Touchable to 'core' module 2016-12-23 12:45:54 +00:00
Nicolas Gallagher
1273bfc7cf Address avoidable object creation 2016-12-23 12:22:32 +00:00
Nicolas Gallagher
dc7f526f6b [fix] TextInput props
- Add missing 'onSubmitEditing' propType and test
- Add 'dir=auto' DOM attribute to allow browser to switch writing
  direction for RTL languages
2016-12-17 23:38:36 +00:00
Nicolas Gallagher
7cda89c5ce 0.0.60 2016-12-16 12:15:23 +00:00
Nicolas Gallagher
695eba45af [add] Clipboard API
Close #125
Fix #122
2016-12-16 11:59:22 +00:00
Nicolas Gallagher
92a2cb274a [fix] remove TextInput default flex value 2016-12-16 11:39:12 +00:00
Nicolas Gallagher
b1ca04d11e Rename I18nManager example 2016-12-16 11:35:11 +00:00
Nicolas Gallagher
22ab70ea6f 0.0.59 2016-12-14 17:42:15 +00:00
Gethin Webster
49f36d8eb1 Update to ListView functionality
Re-build ListView from the core react-native component, to get better
feature parity

Ensure lists with small initialListSize render correctly

Changes as requested via PR
2016-12-14 09:39:05 -08:00
52 changed files with 1200 additions and 509 deletions

View File

@@ -27,7 +27,7 @@ online with [React Native for Web: Playground](http://codepen.io/necolas/pen/PZz
To install in your app:
```
npm install --save react@15.3 react-native-web
npm install --save react@15.4 react-native-web
```
Read the [Client and Server rendering](docs/guides/rendering.md) guide.
@@ -70,6 +70,7 @@ Exported modules:
* [`AppRegistry`](docs/apis/AppRegistry.md)
* [`AppState`](docs/apis/AppState.md)
* [`AsyncStorage`](docs/apis/AsyncStorage.md)
* [`Clipboard`](docs/apis/Clipboard.md)
* [`Dimensions`](docs/apis/Dimensions.md)
* [`I18nManager`](docs/apis/I18nManager.md)
* [`NativeMethods`](docs/apis/NativeMethods.md)

16
docs/apis/Clipboard.md Normal file
View File

@@ -0,0 +1,16 @@
# Clipboard
Clipboard gives you an interface for setting to the clipboard. (Getting
clipboard content is not supported on web.)
## Methods
static **getString**()
Returns a `Promise` of an empty string.
static **setString**(content: string): boolean
Copies a string to the clipboard. On web, some browsers may not support copying
to the clipboard, therefore, this function returns a boolean to indicate if the
copy was successful.

View File

@@ -75,6 +75,23 @@ Example usage:
<Image resizeMode={Image.resizeMode.contain} />
```
## Methods
static **getSize**(uri: string, success: (width, height) => {}, failure: function)
Retrieve the width and height (in pixels) of an image prior to displaying it.
This method can fail if the image cannot be found, or fails to download.
(In order to retrieve the image dimensions, the image may first need to be
loaded or downloaded, after which it will be cached. This means that in
principle you could use this method to preload images, however it is not
optimized for that purpose, and may in future be implemented in a way that does
not fully load/download the image data.)
static **prefetch**(url: string): Promise
Prefetches a remote image for later use by downloading it.
## Examples
```js

View File

@@ -27,14 +27,48 @@ the `url-loader` to the webpack config:
module.exports = {
// ...
module: {
loaders: {
test: /\.(gif|jpe?g|png|svg)$/,
loader: 'url-loader',
query: { name: '[name].[hash:16].[ext]' }
}
loaders: [
{
test: /\.(gif|jpe?g|png|svg)$/,
loader: 'url-loader',
query: { name: '[name].[hash:16].[ext]' }
}
]
}
};
```
## Dependencies
Many OSS React Native packages are not compiled to ES5 before being published.
This can result in webpack build errors. To avoid this issue you should
configure webpack (or your bundler of choice) to run
`babel-preset-react-native` over the necessary `node_module`. For example:
```js
// webpack.config.js
module.exports = {
// ...
module: {
loaders: [
{
// transpile to ES5
test: /\.jsx?$/,
include: [
path.resolve(__dirname, 'src'),
path.resolve(__dirname, 'node_modules/react-native-something')
],
loader: 'babel-loader',
query: { cacheDirectory: true }
}
]
}
};
```
Please refer to the webpack documentation for more information.
## Web-specific code
Minor platform differences can use the `Platform` module.

View File

@@ -16,8 +16,9 @@ module.exports = {
}
```
The `react-native-web` package also includes a `core` module that exports only
`ReactNative`, `Image`, `StyleSheet`, `Text`, `TextInput`, and `View`.
The `react-native-web` package also includes a `core` module that exports a
subset of modules: `ReactNative`, `I18nManager`, `Platform`, `StyleSheet`,
`Image`, `Text`, `TextInput`, `Touchable`, and `View`.
```js
// webpack.config.js

View File

@@ -0,0 +1,33 @@
import { Clipboard, Text, TextInput, View } from 'react-native'
import React, { Component } from 'react';
import { action, storiesOf } from '@kadira/storybook';
class ClipboardExample extends Component {
render() {
return (
<View style={{ minWidth: 300 }}>
<Text onPress={this._handleSet}>Copy to clipboard</Text>
<TextInput
multiline={true}
placeholder={'Try pasting here afterwards'}
style={{ borderWidth: 1, height: 200, marginVertical: 20 }}
/>
<Text onPress={this._handleGet}>(Clipboard.getString returns a Promise that always resolves to an empty string on web)</Text>
</View>
)
}
_handleGet() {
Clipboard.getString().then((value) => { console.log(`Clipboard value: ${value}`) });
}
_handleSet() {
const success = Clipboard.setString('This text was copied to the clipboard by React Native');
console.log(`Clipboard.setString success? ${success}`);
}
}
storiesOf('api: Clipboard', module)
.add('setString', () => (
<ClipboardExample />
));

View File

@@ -1,8 +1,8 @@
import { storiesOf } from '@kadira/storybook';
import { I18nManager, StyleSheet, TouchableHighlight, Text, View } from 'react-native'
import React, { Component } from 'react';
import { storiesOf, action } from '@kadira/storybook';
class RTLExample extends Component {
class I18nManagerExample extends Component {
componentWillUnmount() {
I18nManager.setPreferredLanguageRTL(false)
}
@@ -75,5 +75,5 @@ const styles = StyleSheet.create({
storiesOf('api: I18nManager', module)
.add('RTL layout', () => (
<RTLExample />
<I18nManagerExample />
))

View File

@@ -28,10 +28,9 @@ import { ActivityIndicator, Image, Platform, StyleSheet, Text, View } from 'reac
var base64Icon = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEsAAABLCAQAAACSR7JhAAADtUlEQVR4Ac3YA2Bj6QLH0XPT1Fzbtm29tW3btm3bfLZtv7e2ObZnms7d8Uw098tuetPzrxv8wiISrtVudrG2JXQZ4VOv+qUfmqCGGl1mqLhoA52oZlb0mrjsnhKpgeUNEs91Z0pd1kvihA3ULGVHiQO2narKSHKkEMulm9VgUyE60s1aWoMQUbpZOWE+kaqs4eLEjdIlZTcFZB0ndc1+lhB1lZrIuk5P2aib1NBpZaL+JaOGIt0ls47SKzLC7CqrlGF6RZ09HGoNy1lYl2aRSWL5GuzqWU1KafRdoRp0iOQEiDzgZPnG6DbldcomadViflnl/cL93tOoVbsOLVM2jylvdWjXolWX1hmfZbGR/wjypDjFLSZIRov09BgYmtUqPQPlQrPapecLgTIy0jMgPKtTeob2zWtrGH3xvjUkPCtNg/tm1rjwrMa+mdUkPd3hWbH0jArPGiU9ufCsNNWFZ40wpwn+62/66R2RUtoso1OB34tnLOcy7YB1fUdc9e0q3yru8PGM773vXsuZ5YIZX+5xmHwHGVvlrGPN6ZSiP1smOsMMde40wKv2VmwPPVXNut4sVpUreZiLBHi0qln/VQeI/LTMYXpsJtFiclUN+5HVZazim+Ky+7sAvxWnvjXrJFneVtLWLyPJu9K3cXLWeOlbMTlrIelbMDlrLenrjEQOtIF+fuI9xRp9ZBFp6+b6WT8RrxEpdK64BuvHgDk+vUy+b5hYk6zfyfs051gRoNO1usU12WWRWL73/MMEy9pMi9qIrR4ZpV16Rrvduxazmy1FSvuFXRkqTnE7m2kdb5U8xGjLw/spRr1uTov4uOgQE+0N/DvFrG/Jt7i/FzwxbA9kDanhf2w+t4V97G8lrT7wc08aA2QNUkuTfW/KimT01wdlfK4yEw030VfT0RtZbzjeMprNq8m8tnSTASrTLti64oBNdpmMQm0eEwvfPwRbUBywG5TzjPCsdwk3IeAXjQblLCoXnDVeoAz6SfJNk5TTzytCNZk/POtTSV40NwOFWzw86wNJRpubpXsn60NJFlHeqlYRbslqZm2jnEZ3qcSKgm0kTli3zZVS7y/iivZTweYXJ26Y+RTbV1zh3hYkgyFGSTKPfRVbRqWWVReaxYeSLarYv1Qqsmh1s95S7G+eEWK0f3jYKTbV6bOwepjfhtafsvUsqrQvrGC8YhmnO9cSCk3yuY984F1vesdHYhWJ5FvASlacshUsajFt2mUM9pqzvKGcyNJW0arTKN1GGGzQlH0tXwLDgQTurS8eIQAAAABJRU5ErkJggg==';
//var ImageCapInsetsExample = require('./ImageCapInsetsExample');
//const IMAGE_PREFETCH_URL = 'http://facebook.github.io/origami/public/images/blog-hero.jpg?r=1&t=' + Date.now();
//var prefetchTask = Image.prefetch(IMAGE_PREFETCH_URL);
const IMAGE_PREFETCH_URL = 'http://origami.design/public/images/bird-logo.png?r=1&t=' + Date.now();
var prefetchTask = Image.prefetch(IMAGE_PREFETCH_URL);
/*
var NetworkImageCallbackExample = React.createClass({
getInitialState: function() {
return {
@@ -88,7 +87,6 @@ var NetworkImageCallbackExample = React.createClass({
});
}
});
*/
var NetworkImageExample = React.createClass({
getInitialState: function() {
@@ -118,7 +116,6 @@ var NetworkImageExample = React.createClass({
}
});
/*
var ImageSizeExample = React.createClass({
getInitialState: function() {
return {
@@ -133,24 +130,25 @@ var ImageSizeExample = React.createClass({
},
render: function() {
return (
<View style={{flexDirection: 'row'}}>
<Image
style={{
width: 60,
height: 60,
backgroundColor: 'transparent',
marginRight: 10,
}}
source={this.props.source} />
<View>
<Text>
Actual dimensions:{'\n'}
Width: {this.state.width}, Height: {this.state.height}
width: {this.state.width}, height: {this.state.height}
</Text>
<Image
source={this.props.source}
style={{
backgroundColor: '#eee',
height: 227,
marginTop: 10,
width: 323
}}
/>
</View>
);
},
});
*/
/*
var MultipleSourcesExample = React.createClass({
getInitialState: function() {
@@ -239,17 +237,17 @@ const examples = [
);
},
},
/*
{
title: 'Image Loading Events',
render: function() {
return (
<NetworkImageCallbackExample source={{uri: 'http://facebook.github.io/origami/public/images/blog-hero.jpg?r=1&t=' + Date.now()}}
prefetchedSource={{uri: IMAGE_PREFETCH_URL}}/>
<NetworkImageCallbackExample
source={{uri: 'http://origami.design/public/images/bird-logo.png?r=1&t=' + Date.now()}}
prefetchedSource={{uri: IMAGE_PREFETCH_URL}}
/>
);
},
},
*/
{
title: 'Error Handler',
render: function() {
@@ -263,7 +261,7 @@ const examples = [
title: 'Image Download Progress',
render: function() {
return (
<NetworkImageExample source={{uri: 'http://facebook.github.io/origami/public/images/blog-hero.jpg?r=1'}}/>
<NetworkImageExample source={{uri: 'http://origami.design/public/images/bird-logo.png?r=1'}}/>
);
},
platform: 'ios',
@@ -567,14 +565,12 @@ const examples = [
platform: 'ios',
},
*/
/*
{
title: 'Image Size',
render: function() {
return <ImageSizeExample source={fullImage} />;
return <ImageSizeExample source={{ uri: 'https://upload.wikimedia.org/wikipedia/commons/d/d7/Chestnut-mandibled_Toucan.jpg' }} />;
},
},
*/
/*
{
title: 'MultipleSourcesExample',

View File

@@ -1,4 +1,80 @@
import React from 'react';
import { storiesOf, action } from '@kadira/storybook';
import { ListView } from 'react-native'
import { storiesOf } from '@kadira/storybook';
import { ListView, StyleSheet, Text, View } from 'react-native';
const generateData = (length) => Array.from({ length }).map((item, i) => i);
const dataSource = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 });
storiesOf('component: ListView', module)
.add('vertical', () => (
<View style={styles.scrollViewContainer}>
<ListView
contentContainerStyle={styles.scrollViewContentContainerStyle}
dataSource={dataSource.cloneWithRows(generateData(100))}
initialListSize={100}
// eslint-disable-next-line react/jsx-no-bind
onScroll={(e) => { console.log('ScrollView.onScroll', e); } }
// eslint-disable-next-line react/jsx-no-bind
renderRow={(row) => (
<View><Text>{row}</Text></View>
)}
scrollEventThrottle={1000} // 1 event per second
style={styles.scrollViewStyle}
/>
</View>
))
.add('incremental rendering - large pageSize', () => (
<View style={styles.scrollViewContainer}>
<ListView
contentContainerStyle={styles.scrollViewContentContainerStyle}
dataSource={dataSource.cloneWithRows(generateData(5000))}
initialListSize={100}
// eslint-disable-next-line react/jsx-no-bind
onScroll={(e) => { console.log('ScrollView.onScroll', e); } }
pageSize={50}
// eslint-disable-next-line react/jsx-no-bind
renderRow={(row) => (
<View><Text>{row}</Text></View>
)}
scrollEventThrottle={1000} // 1 event per second
style={styles.scrollViewStyle}
/>
</View>
))
.add('incremental rendering - small pageSize', () => (
<View style={styles.scrollViewContainer}>
<ListView
contentContainerStyle={styles.scrollViewContentContainerStyle}
dataSource={dataSource.cloneWithRows(generateData(5000))}
initialListSize={5}
// eslint-disable-next-line react/jsx-no-bind
onScroll={(e) => { console.log('ScrollView.onScroll', e); } }
pageSize={1}
// eslint-disable-next-line react/jsx-no-bind
renderRow={(row) => (
<View><Text>{row}</Text></View>
)}
scrollEventThrottle={1000} // 1 event per second
style={styles.scrollViewStyle}
/>
</View>
));
const styles = StyleSheet.create({
box: {
flexGrow: 1,
justifyContent: 'center',
borderWidth: 1
},
scrollViewContainer: {
height: '200px',
width: 300
},
scrollViewStyle: {
borderWidth: '1px'
},
scrollViewContentContainerStyle: {
backgroundColor: '#eee',
padding: '10px'
}
});

View File

@@ -59,7 +59,7 @@ class TextEventsExample extends React.Component {
render() {
return (
<View>
<View style={{ alignItems: 'center' }}>
<TextInput
autoCapitalize="none"
placeholder="Enter text to see events"
@@ -83,7 +83,7 @@ class TextEventsExample extends React.Component {
onKeyPress={(event) => {
this.updateText('onKeyPress key: ' + event.nativeEvent.key);
}}
style={styles.default}
style={[ styles.default, { maxWidth: 200 } ]}
/>
<Text style={styles.eventLabel}>
{this.state.curText}{'\n'}

View File

@@ -31,6 +31,17 @@ var styles = StyleSheet.create({
borderColor: '#000033',
borderWidth: 1,
},
shadowBox: {
width: 100,
height: 100,
borderWidth: 2,
},
shadow: {
shadowOpacity: 0.5,
shadowColor: 'red',
shadowRadius: 3,
shadowOffset: { width: 3, height: 3 },
},
zIndex: {
justifyContent: 'space-around',
width: 100,
@@ -242,6 +253,19 @@ const examples = [
return <ZIndexExample />;
},
},
{
title: 'Basic shadow',
render() {
return <View style={[ styles.shadowBox, styles.shadow ]} />;
}
},
{
title: 'Shaped shadow',
description: 'borderRadius: 50',
render() {
return <View style={[ styles.shadowBox, styles.shadow, {borderRadius: 50} ]} />;
}
}
];
examples.forEach((example) => {

View File

@@ -1,6 +1,6 @@
{
"name": "react-native-web",
"version": "0.0.58",
"version": "0.0.61",
"description": "React Native for Web",
"main": "dist/index.js",
"files": [
@@ -28,7 +28,7 @@
"deep-assign": "^2.0.0",
"fbjs": "^0.8.4",
"inline-style-prefixer": "^2.0.1",
"react-dom": "~15.3.2",
"react-dom": "~15.4.1",
"react-textarea-autosize": "^4.0.4",
"react-timer-mixin": "^0.13.3"
},
@@ -49,15 +49,15 @@
"file-loader": "^0.9.0",
"jest": "^16.0.2",
"node-libs-browser": "^0.5.3",
"react": "~15.3.2",
"react-addons-test-utils": "~15.3.2",
"react-test-renderer": "~15.3.2",
"react": "~15.4.1",
"react-addons-test-utils": "~15.4.1",
"react-test-renderer": "~15.4.1",
"url-loader": "^0.5.7",
"webpack": "^1.13.2",
"webpack-bundle-analyzer": "^1.5.3"
},
"peerDependencies": {
"react": "~15.3.2"
"react": "~15.4.1"
},
"author": "Nicolas Gallagher",
"license": "BSD-3-Clause",

View File

@@ -8,9 +8,10 @@
import { Component } from 'react';
import invariant from 'fbjs/lib/invariant';
import { unmountComponentAtNode } from 'react/lib/ReactMount';
import { unmountComponentAtNode } from 'react-dom/lib/ReactMount';
import renderApplication, { getApplication } from './renderApplication';
const emptyObject = {};
const runnables = {};
type ComponentProvider = () => Component<any, any, any>
@@ -41,8 +42,8 @@ class AppRegistry {
static registerComponent(appKey: string, getComponentFunc: ComponentProvider): string {
runnables[appKey] = {
getApplication: ({ initialProps } = {}) => getApplication(getComponentFunc(), initialProps),
run: ({ initialProps, rootTag }) => renderApplication(getComponentFunc(), initialProps, rootTag)
getApplication: ({ initialProps } = emptyObject) => getApplication(getComponentFunc(), initialProps),
run: ({ initialProps = emptyObject, rootTag }) => renderApplication(getComponentFunc(), initialProps, rootTag)
};
return appKey;
}

View File

@@ -7,7 +7,7 @@
*/
import invariant from 'fbjs/lib/invariant';
import { render } from 'react/lib/ReactMount';
import { render } from 'react-dom/lib/ReactMount';
import ReactNativeApp from './ReactNativeApp';
import StyleSheet from '../../apis/StyleSheet';
import React, { Component } from 'react';

View File

@@ -0,0 +1,21 @@
class Clipboard {
static getString() {
return Promise.resolve('');
}
static setString(text) {
let success = false;
const textField = document.createElement('textarea');
textField.innerText = text;
document.body.appendChild(textField);
textField.select();
try {
document.execCommand('copy');
success = true;
} catch (e) {}
document.body.removeChild(textField);
return success;
}
}
module.exports = Clipboard;

View File

@@ -6,7 +6,7 @@
"use strict";
var TouchHistoryMath = require('react/lib/TouchHistoryMath');
var TouchHistoryMath = require('react-dom/lib/TouchHistoryMath');
var currentCentroidXOfTouchesChangedAfter =
TouchHistoryMath.currentCentroidXOfTouchesChangedAfter;

View File

@@ -9,8 +9,8 @@
import { PropTypes } from 'react'
import ImageStylePropTypes from '../../components/Image/ImageStylePropTypes'
import ReactPropTypeLocations from 'react/lib/ReactPropTypeLocations'
import ReactPropTypesSecret from 'react/lib/ReactPropTypesSecret'
import ReactPropTypeLocations from 'react-dom/lib/ReactPropTypeLocations'
import ReactPropTypesSecret from 'react-dom/lib/ReactPropTypesSecret'
import TextStylePropTypes from '../../components/Text/TextStylePropTypes'
import ViewStylePropTypes from '../../components/View/ViewStylePropTypes'
import warning from 'fbjs/lib/warning'

View File

@@ -0,0 +1,47 @@
/* eslint-env jasmine, jest */
import processBoxShadow from '../processBoxShadow';
describe('apis/StyleSheet/processBoxShadow', () => {
test('missing shadowColor', () => {
const style = {
shadowOffset: { width: 1, height: 2 }
};
expect(processBoxShadow(style)).toEqual({});
});
test('shadowColor only', () => {
const style = {
shadowColor: 'red'
};
expect(processBoxShadow(style)).toEqual({
boxShadow: '0px 0px 0px rgba(255,0,0,1)'
});
});
test('shadowColor and shadowOpacity only', () => {
const style = {
shadowColor: 'red',
shadowOpacity: 0.5
};
expect(processBoxShadow(style)).toEqual({
boxShadow: '0px 0px 0px rgba(255,0,0,0.5)'
});
});
test('shadowOffset, shadowRadius, shadowSpread', () => {
const style = {
shadowColor: 'rgba(50,60,70,0.5)',
shadowOffset: { width: 1, height: 2 },
shadowOpacity: 0.5,
shadowRadius: 3
};
expect(processBoxShadow(style)).toEqual({
boxShadow: '2px 1px 3px rgba(50,60,70,0.25)'
});
});
});

View File

@@ -1,11 +1,13 @@
import expandStyle from './expandStyle';
import flattenStyle from '../../modules/flattenStyle';
import i18nStyle from './i18nStyle';
import processBoxShadow from './processBoxShadow';
import processTextShadow from './processTextShadow';
import processTransform from './processTransform';
import processVendorPrefixes from './processVendorPrefixes';
const processors = [
processBoxShadow,
processTextShadow,
processTransform,
processVendorPrefixes

View File

@@ -1,6 +1,8 @@
import I18nManager from '../I18nManager';
import multiplyStyleLengthValue from '../../modules/multiplyStyleLengthValue';
const emptyObject = {};
/**
* Map of property names to their BiDi equivalent.
*/
@@ -64,38 +66,40 @@ const swapLtrRtl = (value:String): String => {
return value === 'ltr' ? 'rtl' : value === 'rtl' ? 'ltr' : value;
};
const i18nStyle = (style = {}) => {
const i18nStyle = (style = emptyObject) => {
const newStyle = {};
for (const prop in style) {
if (style.hasOwnProperty(prop)) {
const indexOfNoFlip = prop.indexOf('$noI18n');
if (!Object.prototype.hasOwnProperty.call(style, prop)) {
continue;
}
if (I18nManager.isRTL) {
if (PROPERTIES_TO_SWAP[prop]) {
const newProp = flipProperty(prop);
newStyle[newProp] = style[prop];
} else if (PROPERTIES_SWAP_LEFT_RIGHT[prop]) {
newStyle[prop] = swapLeftRight(style[prop]);
} else if (PROPERTIES_SWAP_LTR_RTL[prop]) {
newStyle[prop] = swapLtrRtl(style[prop]);
} else if (prop === 'textShadowOffset') {
newStyle[prop] = style[prop];
newStyle[prop].width = additiveInverse(style[prop].width);
} else if (prop === 'transform') {
newStyle[prop] = style[prop].map(flipTransform);
} else if (indexOfNoFlip > -1) {
const newProp = prop.substring(0, indexOfNoFlip);
newStyle[newProp] = style[prop];
} else {
newStyle[prop] = style[prop];
}
const indexOfNoFlip = prop.indexOf('$noI18n');
if (I18nManager.isRTL) {
if (PROPERTIES_TO_SWAP[prop]) {
const newProp = flipProperty(prop);
newStyle[newProp] = style[prop];
} else if (PROPERTIES_SWAP_LEFT_RIGHT[prop]) {
newStyle[prop] = swapLeftRight(style[prop]);
} else if (PROPERTIES_SWAP_LTR_RTL[prop]) {
newStyle[prop] = swapLtrRtl(style[prop]);
} else if (prop === 'textShadowOffset') {
newStyle[prop] = style[prop];
newStyle[prop].width = additiveInverse(style[prop].width);
} else if (prop === 'transform') {
newStyle[prop] = style[prop].map(flipTransform);
} else if (indexOfNoFlip > -1) {
const newProp = prop.substring(0, indexOfNoFlip);
newStyle[newProp] = style[prop];
} else {
if (indexOfNoFlip > -1) {
const newProp = prop.substring(0, indexOfNoFlip);
newStyle[newProp] = style[prop];
} else {
newStyle[prop] = style[prop];
}
newStyle[prop] = style[prop];
}
} else {
if (indexOfNoFlip > -1) {
const newProp = prop.substring(0, indexOfNoFlip);
newStyle[newProp] = style[prop];
} else {
newStyle[prop] = style[prop];
}
}
}

View File

@@ -24,7 +24,9 @@ const unitlessNumbers = {
scale: true,
scaleX: true,
scaleY: true,
scaleZ: true
scaleZ: true,
// RN properties
shadowOpacity: true
};
const normalizeValue = (property, value) => {

View File

@@ -0,0 +1,33 @@
import normalizeColor from '../../modules/normalizeColor';
import normalizeValue from './normalizeValue';
const applyOpacity = (color, opacity) => {
const normalizedColor = normalizeColor(color);
const colorNumber = normalizedColor === null ? 0x00000000 : normalizedColor;
const r = (colorNumber & 0xff000000) >>> 24;
const g = (colorNumber & 0x00ff0000) >>> 16;
const b = (colorNumber & 0x0000ff00) >>> 8;
const a = (((colorNumber & 0x000000ff) >>> 0) / 255).toFixed(2);
return `rgba(${r},${g},${b},${a * opacity})`;
};
// TODO: add inset and spread support
const processBoxShadow = (style) => {
if (style && style.shadowColor) {
const { height, width } = style.shadowOffset || {};
const opacity = style.shadowOpacity != null ? style.shadowOpacity : 1;
const color = applyOpacity(style.shadowColor, opacity);
const blurRadius = normalizeValue(null, style.shadowRadius || 0);
const offsetX = normalizeValue(null, height || 0);
const offsetY = normalizeValue(null, width || 0);
const boxShadow = `${offsetX} ${offsetY} ${blurRadius} ${color}`;
style.boxShadow = style.boxShadow ? `${style.boxShadow}, ${boxShadow}` : boxShadow;
}
delete style.shadowColor;
delete style.shadowOffset;
delete style.shadowOpacity;
delete style.shadowRadius;
return style;
};
module.exports = processBoxShadow;

View File

@@ -1,5 +1,5 @@
import createReactStyleObject from '../StyleSheet/createReactStyleObject';
import CSSPropertyOperations from 'react/lib/CSSPropertyOperations';
import CSSPropertyOperations from 'react-dom/lib/CSSPropertyOperations';
const _measureLayout = (node, relativeToNativeNode, callback) => {
const relativeNode = relativeToNativeNode || node.parentNode;
@@ -35,8 +35,11 @@ const UIManager = {
updateView(node, props, component /* only needed to surpress React errors in development */) {
for (const prop in props) {
const value = props[prop];
if (!Object.prototype.hasOwnProperty.call(props, prop)) {
continue;
}
const value = props[prop];
switch (prop) {
case 'style':
// convert styles to DOM-styles

View File

@@ -1,6 +1,7 @@
/* global window */
import applyNativeMethods from '../../modules/applyNativeMethods';
import ImageResizeMode from './ImageResizeMode';
import ImageLoader from '../../modules/ImageLoader';
import ImageStylePropTypes from './ImageStylePropTypes';
import requestAnimationFrame from 'fbjs/lib/requestAnimationFrame';
import StyleSheet from '../../apis/StyleSheet';
@@ -8,6 +9,8 @@ import StyleSheetPropType from '../../propTypes/StyleSheetPropType';
import View from '../View';
import React, { Component, PropTypes } from 'react';
const emptyObject = {};
const STATUS_ERRORED = 'ERRORED';
const STATUS_LOADED = 'LOADED';
const STATUS_LOADING = 'LOADING';
@@ -52,14 +55,22 @@ class Image extends Component {
};
static defaultProps = {
style: {}
style: emptyObject
};
static getSize(uri, success, failure) {
ImageLoader.getSize(uri, success, failure);
}
static prefetch(uri) {
return ImageLoader.prefetch(uri);
}
static resizeMode = ImageResizeMode;
constructor(props, context) {
super(props, context);
this.state = { isLoaded: false };
this.state = { shouldDisplaySource: false };
const uri = resolveAssetSource(props.source);
this._imageState = uri ? STATUS_PENDING : STATUS_IDLE;
this._isMounted = false;
@@ -73,7 +84,7 @@ class Image extends Component {
}
componentDidUpdate() {
if (this._imageState === STATUS_PENDING && !this.image) {
if (this._imageState === STATUS_PENDING) {
this._createImageLoader();
}
}
@@ -91,7 +102,7 @@ class Image extends Component {
}
render() {
const { isLoaded } = this.state;
const { shouldDisplaySource } = this.state;
const {
accessibilityLabel,
accessible,
@@ -101,13 +112,17 @@ class Image extends Component {
source,
testID,
/* eslint-disable */
onError,
onLoad,
onLoadEnd,
onLoadStart,
resizeMode,
/* eslint-enable */
...other
} = this.props;
const displayImage = resolveAssetSource(!isLoaded ? defaultSource : source);
const imageSizeStyle = resolveAssetDimensions(!isLoaded ? defaultSource : source);
const displayImage = resolveAssetSource(shouldDisplaySource ? source : defaultSource);
const imageSizeStyle = resolveAssetDimensions(shouldDisplaySource ? source : defaultSource);
const backgroundImage = displayImage ? `url("${displayImage}")` : null;
const originalStyle = StyleSheet.flatten(this.props.style);
const finalResizeMode = resizeMode || originalStyle.resizeMode || ImageResizeMode.cover;
@@ -137,28 +152,21 @@ class Image extends Component {
}
_createImageLoader() {
const uri = resolveAssetSource(this.props.source);
this._destroyImageLoader();
this.image = new window.Image();
this.image.onerror = this._onError;
this.image.onload = this._onLoad;
this.image.src = uri;
const uri = resolveAssetSource(this.props.source);
this._imageRequestId = ImageLoader.load(uri, this._onLoad, this._onError);
this._onLoadStart();
}
_destroyImageLoader() {
if (this.image) {
this.image.onerror = null;
this.image.onload = null;
this.image = null;
if (this._imageRequestId) {
ImageLoader.abort(this._imageRequestId);
this._imageRequestId = null;
}
}
_onError = () => {
const { onError, source } = this.props;
this._destroyImageLoader();
this._onLoadEnd();
this._updateImageState(STATUS_ERRORED);
if (onError) {
onError({
@@ -167,13 +175,13 @@ class Image extends Component {
}
});
}
this._onLoadEnd();
}
_onLoad = (e) => {
const { onLoad } = this.props;
const event = { nativeEvent: e };
this._destroyImageLoader();
this._updateImageState(STATUS_LOADED);
if (onLoad) { onLoad(event); }
this._onLoadEnd();
@@ -192,11 +200,12 @@ class Image extends Component {
_updateImageState(status) {
this._imageState = status;
const isLoaded = this._imageState === STATUS_LOADED;
if (isLoaded !== this.state.isLoaded) {
const shouldDisplaySource = this._imageState === STATUS_LOADED || this._imageState === STATUS_LOADING;
// only triggers a re-render when the image is loading (to support PJEG), loaded, or failed
if (shouldDisplaySource !== this.state.shouldDisplaySource) {
requestAnimationFrame(() => {
if (this._isMounted) {
this.setState({ isLoaded });
this.setState({ shouldDisplaySource });
}
});
}

View File

@@ -2,18 +2,27 @@ import applyNativeMethods from '../../modules/applyNativeMethods';
import ListViewDataSource from './ListViewDataSource';
import ListViewPropTypes from './ListViewPropTypes';
import ScrollView from '../ScrollView';
import View from '../View';
import React, { Component } from 'react';
import StaticRenderer from '../StaticRenderer';
import React, { Component, isEmpty, merge } from 'react';
import requestAnimationFrame from 'fbjs/lib/requestAnimationFrame';
const DEFAULT_PAGE_SIZE = 1;
const DEFAULT_INITIAL_ROWS = 10;
const DEFAULT_SCROLL_RENDER_AHEAD = 1000;
const DEFAULT_END_REACHED_THRESHOLD = 1000;
const DEFAULT_SCROLL_CALLBACK_THROTTLE = 50;
class ListView extends Component {
static propTypes = ListViewPropTypes;
static defaultProps = {
initialListSize: 10,
pageSize: 1,
initialListSize: DEFAULT_INITIAL_ROWS,
pageSize: DEFAULT_PAGE_SIZE,
renderScrollComponent: (props) => <ScrollView {...props} />,
scrollRenderAheadDistance: 1000,
onEndReachedThreshold: 1000,
scrollRenderAheadDistance: DEFAULT_SCROLL_RENDER_AHEAD,
onEndReachedThreshold: DEFAULT_END_REACHED_THRESHOLD,
scrollEventThrottle: DEFAULT_SCROLL_CALLBACK_THROTTLE,
removeClippedSubviews: true,
stickyHeaderIndices: []
};
@@ -26,6 +35,48 @@ class ListView extends Component {
highlightedRow: {}
};
this.onRowHighlighted = (sectionId, rowId) => this._onRowHighlighted(sectionId, rowId);
this.scrollProperties = {};
}
componentWillMount() {
// this data should never trigger a render pass, so don't put in state
this.scrollProperties = {
visibleLength: null,
contentLength: null,
offset: 0
};
this._childFrames = [];
this._visibleRows = {};
this._prevRenderedRowsCount = 0;
this._sentEndForContentLength = null;
}
componentDidMount() {
// do this in animation frame until componentDidMount actually runs after
// the component is laid out
requestAnimationFrame(() => {
this._measureAndUpdateScrollProps();
});
}
componentWillReceiveProps(nextProps: Object) {
if (this.props.dataSource !== nextProps.dataSource || this.props.initialListSize !== nextProps.initialListSize) {
this.setState((state, props) => {
this._prevRenderedRowsCount = 0;
return {
curRenderedRowsCount: Math.min(
Math.max(state.curRenderedRowsCount, props.initialListSize),
props.enableEmptySections ? props.dataSource.getRowAndSectionCount() : props.dataSource.getRowCount()
)
};
}, () => this._renderMoreRowsIfNeeded());
}
}
componentDidUpdate() {
requestAnimationFrame(() => {
this._measureAndUpdateScrollProps();
});
}
getScrollResponder() {
@@ -40,58 +91,313 @@ class ListView extends Component {
return this._scrollViewRef && this._scrollViewRef.setNativeProps(props);
}
_onRowHighlighted(sectionId, rowId) {
_onRowHighlighted = (sectionId, rowId) => {
this.setState({ highlightedRow: { sectionId, rowId } });
}
renderSectionHeaderFn = (data, sectionID) => {
return () => this.props.renderSectionHeader(data, sectionID);
}
renderRowFn = (data, sectionID, rowID) => {
return () => this.props.renderRow(data, sectionID, rowID, this._onRowHighlighted);
}
render() {
const dataSource = this.props.dataSource;
const header = this.props.renderHeader ? this.props.renderHeader() : undefined;
const footer = this.props.renderFooter ? this.props.renderFooter() : undefined;
// render sections and rows
const children = [];
const sections = dataSource.rowIdentities;
const renderRow = this.props.renderRow;
const renderSectionHeader = this.props.renderSectionHeader;
const renderSeparator = this.props.renderSeparator;
for (let sectionIdx = 0, sectionCnt = sections.length; sectionIdx < sectionCnt; sectionIdx++) {
const rows = sections[sectionIdx];
const sectionId = dataSource.sectionIdentities[sectionIdx];
// render optional section header
if (renderSectionHeader) {
const section = dataSource.getSectionHeaderData(sectionIdx);
const key = `s_${sectionId}`;
const child = <View key={key}>{renderSectionHeader(section, sectionId)}</View>;
children.push(child);
const dataSource = this.props.dataSource;
const allRowIDs = dataSource.rowIdentities;
let rowCount = 0;
const sectionHeaderIndices = [];
const header = this.props.renderHeader && this.props.renderHeader();
const footer = this.props.renderFooter && this.props.renderFooter();
let totalIndex = header ? 1 : 0;
for (let sectionIdx = 0; sectionIdx < allRowIDs.length; sectionIdx++) {
const sectionID = dataSource.sectionIdentities[sectionIdx];
const rowIDs = allRowIDs[sectionIdx];
if (rowIDs.length === 0) {
if (this.props.enableEmptySections === undefined) {
const warning = require('fbjs/lib/warning');
warning(false, 'In next release empty section headers will be rendered.' +
' In this release you can use \'enableEmptySections\' flag to render empty section headers.');
continue;
} else {
const invariant = require('fbjs/lib/invariant');
invariant(
this.props.enableEmptySections,
'In next release \'enableEmptySections\' flag will be deprecated,' +
' empty section headers will always be rendered. If empty section headers' +
' are not desirable their indices should be excluded from sectionIDs object.' +
' In this release \'enableEmptySections\' may only have value \'true\'' +
' to allow empty section headers rendering.');
}
}
// render rows
for (let rowIdx = 0, rowCnt = rows.length; rowIdx < rowCnt; rowIdx++) {
const rowId = rows[rowIdx];
const row = dataSource.getRowData(sectionIdx, rowIdx);
const key = `r_${sectionId}_${rowId}`;
const child = <View key={key}>{renderRow(row, sectionId, rowId, this.onRowHighlighted)}</View>;
children.push(child);
if (this.props.renderSectionHeader) {
const shouldUpdateHeader = rowCount >= this._prevRenderedRowsCount &&
dataSource.sectionHeaderShouldUpdate(sectionIdx);
children.push(
<StaticRenderer
key={`s_${sectionID}`}
render={this.renderSectionHeaderFn(
dataSource.getSectionHeaderData(sectionIdx),
sectionID
)}
shouldUpdate={!!shouldUpdateHeader}
/>
);
sectionHeaderIndices.push(totalIndex++);
}
// render optional separator
if (renderSeparator && ((rowIdx !== rows.length - 1) || (sectionIdx === sections.length - 1))) {
for (let rowIdx = 0; rowIdx < rowIDs.length; rowIdx++) {
const rowID = rowIDs[rowIdx];
const comboID = `${sectionID}_${rowID}`;
const shouldUpdateRow = rowCount >= this._prevRenderedRowsCount &&
dataSource.rowShouldUpdate(sectionIdx, rowIdx);
const row =
<StaticRenderer
key={`r_${comboID}`}
render={this.renderRowFn(
dataSource.getRowData(sectionIdx, rowIdx),
sectionID,
rowID
)}
shouldUpdate={!!shouldUpdateRow}
/>;
children.push(row);
totalIndex++;
if (this.props.renderSeparator &&
(rowIdx !== rowIDs.length - 1 || sectionIdx === allRowIDs.length - 1)) {
const adjacentRowHighlighted =
this.state.highlightedRow.sectionID === sectionId && (
this.state.highlightedRow.rowID === rowId ||
this.state.highlightedRow.rowID === rows[rowIdx + 1]);
const separator = renderSeparator(sectionId, rowId, adjacentRowHighlighted);
children.push(separator);
this.state.highlightedRow.sectionID === sectionID && (
this.state.highlightedRow.rowID === rowID ||
this.state.highlightedRow.rowID === rowIDs[rowIdx + 1]
);
const separator = this.props.renderSeparator(
sectionID,
rowID,
adjacentRowHighlighted
);
if (separator) {
children.push(separator);
totalIndex++;
}
}
if (++rowCount === this.state.curRenderedRowsCount) {
break;
}
}
if (rowCount >= this.state.curRenderedRowsCount) {
break;
}
}
return React.cloneElement(this.props.renderScrollComponent(this.props), {
ref: this._setScrollViewRef
const {
renderScrollComponent,
...props
} = this.props;
Object.assign(props, {
onScroll: this._onScroll,
stickyHeaderIndices: this.props.stickyHeaderIndices.concat(sectionHeaderIndices),
// Do not pass these events downstream to ScrollView since they will be
// registered in ListView's own ScrollResponder.Mixin
onKeyboardWillShow: undefined,
onKeyboardWillHide: undefined,
onKeyboardDidShow: undefined,
onKeyboardDidHide: undefined
});
return React.cloneElement(renderScrollComponent(props), {
ref: this._setScrollViewRef,
onContentSizeChange: this._onContentSizeChange,
onLayout: this._onLayout
}, header, children, footer);
}
_measureAndUpdateScrollProps() {
const scrollComponent = this.getScrollResponder();
if (!scrollComponent || !scrollComponent.getInnerViewNode) {
return;
}
this._updateVisibleRows();
}
_onLayout = (event: Object) => {
const { width, height } = event.nativeEvent.layout;
const visibleLength = !this.props.horizontal ? height : width;
if (visibleLength !== this.scrollProperties.visibleLength) {
this.scrollProperties.visibleLength = visibleLength;
this._updateVisibleRows();
this._renderMoreRowsIfNeeded();
}
this.props.onLayout && this.props.onLayout(event);
}
_updateVisibleRows(updatedFrames?: Array<Object>) {
if (!this.props.onChangeVisibleRows) {
return; // No need to compute visible rows if there is no callback
}
if (updatedFrames) {
updatedFrames.forEach((newFrame) => {
this._childFrames[newFrame.index] = merge(newFrame);
});
}
const isVertical = !this.props.horizontal;
const dataSource = this.props.dataSource;
const visibleMin = this.scrollProperties.offset;
const visibleMax = visibleMin + this.scrollProperties.visibleLength;
const allRowIDs = dataSource.rowIdentities;
const header = this.props.renderHeader && this.props.renderHeader();
let totalIndex = header ? 1 : 0;
let visibilityChanged = false;
const changedRows = {};
for (let sectionIdx = 0; sectionIdx < allRowIDs.length; sectionIdx++) {
const rowIDs = allRowIDs[sectionIdx];
if (rowIDs.length === 0) {
continue;
}
const sectionID = dataSource.sectionIdentities[sectionIdx];
if (this.props.renderSectionHeader) {
totalIndex++;
}
let visibleSection = this._visibleRows[sectionID];
if (!visibleSection) {
visibleSection = {};
}
for (let rowIdx = 0; rowIdx < rowIDs.length; rowIdx++) {
const rowID = rowIDs[rowIdx];
const frame = this._childFrames[totalIndex];
totalIndex++;
if (this.props.renderSeparator &&
(rowIdx !== rowIDs.length - 1 || sectionIdx === allRowIDs.length - 1)) {
totalIndex++;
}
if (!frame) {
break;
}
const rowVisible = visibleSection[rowID];
const min = isVertical ? frame.y : frame.x;
const max = min + (isVertical ? frame.height : frame.width);
if ((!min && !max) || (min === max)) {
break;
}
if (min > visibleMax || max < visibleMin) {
if (rowVisible) {
visibilityChanged = true;
delete visibleSection[rowID];
if (!changedRows[sectionID]) {
changedRows[sectionID] = {};
}
changedRows[sectionID][rowID] = false;
}
} else if (!rowVisible) {
visibilityChanged = true;
visibleSection[rowID] = true;
if (!changedRows[sectionID]) {
changedRows[sectionID] = {};
}
changedRows[sectionID][rowID] = true;
}
}
if (!isEmpty(visibleSection)) {
this._visibleRows[sectionID] = visibleSection;
} else if (this._visibleRows[sectionID]) {
delete this._visibleRows[sectionID];
}
}
visibilityChanged && this.props.onChangeVisibleRows(this._visibleRows, changedRows);
}
_onContentSizeChange = (width: number, height: number) => {
const contentLength = !this.props.horizontal ? height : width;
if (contentLength !== this.scrollProperties.contentLength) {
this.scrollProperties.contentLength = contentLength;
this._updateVisibleRows();
this._renderMoreRowsIfNeeded();
}
this.props.onContentSizeChange && this.props.onContentSizeChange(width, height);
}
_getDistanceFromEnd(scrollProperties: Object) {
return scrollProperties.contentLength - scrollProperties.visibleLength - scrollProperties.offset;
}
_maybeCallOnEndReached(event?: Object) {
if (this.props.onEndReached &&
this.scrollProperties.contentLength !== this._sentEndForContentLength &&
this._getDistanceFromEnd(this.scrollProperties) < this.props.onEndReachedThreshold &&
this.state.curRenderedRowsCount === (this.props.enableEmptySections ?
this.props.dataSource.getRowAndSectionCount() : this.props.dataSource.getRowCount())) {
this._sentEndForContentLength = this.scrollProperties.contentLength;
this.props.onEndReached(event);
return true;
}
return false;
}
_renderMoreRowsIfNeeded() {
if (this.scrollProperties.contentLength === null ||
this.scrollProperties.visibleLength === null ||
this.state.curRenderedRowsCount === (this.props.enableEmptySections ?
this.props.dataSource.getRowAndSectionCount() : this.props.dataSource.getRowCount())) {
this._maybeCallOnEndReached();
return;
}
const distanceFromEnd = this._getDistanceFromEnd(this.scrollProperties);
if (distanceFromEnd < this.props.scrollRenderAheadDistance) {
this._pageInNewRows();
}
}
_pageInNewRows() {
this.setState((state, props) => {
const rowsToRender = Math.min(
state.curRenderedRowsCount + props.pageSize,
(props.enableEmptySections ? props.dataSource.getRowAndSectionCount() : props.dataSource.getRowCount())
);
this._prevRenderedRowsCount = state.curRenderedRowsCount;
return {
curRenderedRowsCount: rowsToRender
};
}, () => {
this._measureAndUpdateScrollProps();
this._prevRenderedRowsCount = this.state.curRenderedRowsCount;
});
}
_onScroll = (e: Object) => {
const isVertical = !this.props.horizontal;
this.scrollProperties.visibleLength = e.nativeEvent.layoutMeasurement[
isVertical ? 'height' : 'width'
];
this.scrollProperties.contentLength = e.nativeEvent.contentSize[
isVertical ? 'height' : 'width'
];
this.scrollProperties.offset = e.nativeEvent.contentOffset[
isVertical ? 'y' : 'x'
];
this._updateVisibleRows(e.nativeEvent.updatedChildFrames);
if (!this._maybeCallOnEndReached(e)) {
this._renderMoreRowsIfNeeded();
}
if (this.props.onEndReached &&
this._getDistanceFromEnd(this.scrollProperties) > this.props.onEndReachedThreshold) {
// Scrolled out of the end zone, so it should be able to trigger again.
this._sentEndForContentLength = null;
}
this.props.onScroll && this.props.onScroll(e);
};
_setScrollViewRef = (component) => {
this._scrollViewRef = component;
}

View File

@@ -17,6 +17,8 @@ import View from '../View';
import ViewStylePropTypes from '../View/ViewStylePropTypes';
import React, { Component, PropTypes } from 'react';
const emptyObject = {};
/* eslint-disable react/prefer-es6-class */
const ScrollView = React.createClass({
propTypes: {
@@ -79,7 +81,7 @@ const ScrollView = React.createClass({
if (typeof y === 'number') {
console.warn('`scrollTo(y, x, animated)` is deprecated. Use `scrollTo({x: 5, y: 5, animated: true})` instead.');
} else {
({ x, y, animated } = y || {});
({ x, y, animated } = y || emptyObject);
}
this.getScrollResponder().scrollResponderScrollTo({ x: x || 0, y: y || 0, animated: animated !== false });
@@ -236,7 +238,6 @@ const styles = StyleSheet.create({
overflowY: 'hidden'
},
contentContainer: {
flexGrow: 1,
transform: [ { translateZ: 0 } ]
},
contentContainerHorizontal: {

View File

@@ -67,7 +67,7 @@ exports[`components/Switch disabled when "false" a default checkbox is rendered
"WebkitFlexBasis": "auto",
"WebkitFlexDirection": "column",
"WebkitFlexShrink": 0,
"WebkitTransition": "0.1s",
"WebkitTransitionDuration": "0.1s",
"alignItems": "stretch",
"backgroundColor": "#939393",
"borderBottomLeftRadius": "10px",
@@ -112,7 +112,7 @@ exports[`components/Switch disabled when "false" a default checkbox is rendered
"textAlign": "inherit",
"textDecoration": "none",
"top": "0px",
"transition": "0.1s",
"transitionDuration": "0.1s",
"width": "90%",
}
} />
@@ -130,7 +130,7 @@ exports[`components/Switch disabled when "false" a default checkbox is rendered
"WebkitFlexDirection": "column",
"WebkitFlexShrink": 0,
"WebkitTransform": "translateX(0%)",
"WebkitTransition": "0.1s",
"WebkitTransitionDuration": "0.1s",
"alignItems": "stretch",
"alignSelf": "flex-start",
"backgroundColor": "#FAFAFA",
@@ -176,7 +176,7 @@ exports[`components/Switch disabled when "false" a default checkbox is rendered
"textAlign": "inherit",
"textDecoration": "none",
"transform": "translateX(0%)",
"transition": "0.1s",
"transitionDuration": "0.1s",
"width": "20px",
}
} />
@@ -281,7 +281,7 @@ exports[`components/Switch disabled when "true" a disabled checkbox is rendered
"WebkitFlexBasis": "auto",
"WebkitFlexDirection": "column",
"WebkitFlexShrink": 0,
"WebkitTransition": "0.1s",
"WebkitTransitionDuration": "0.1s",
"alignItems": "stretch",
"backgroundColor": "#D5D5D5",
"borderBottomLeftRadius": "10px",
@@ -326,7 +326,7 @@ exports[`components/Switch disabled when "true" a disabled checkbox is rendered
"textAlign": "inherit",
"textDecoration": "none",
"top": "0px",
"transition": "0.1s",
"transitionDuration": "0.1s",
"width": "90%",
}
} />
@@ -344,7 +344,7 @@ exports[`components/Switch disabled when "true" a disabled checkbox is rendered
"WebkitFlexDirection": "column",
"WebkitFlexShrink": 0,
"WebkitTransform": "translateX(0%)",
"WebkitTransition": "0.1s",
"WebkitTransitionDuration": "0.1s",
"alignItems": "stretch",
"alignSelf": "flex-start",
"backgroundColor": "#BDBDBD",
@@ -390,7 +390,7 @@ exports[`components/Switch disabled when "true" a disabled checkbox is rendered
"textAlign": "inherit",
"textDecoration": "none",
"transform": "translateX(0%)",
"transition": "0.1s",
"transitionDuration": "0.1s",
"width": "20px",
}
} />
@@ -495,7 +495,7 @@ exports[`components/Switch value when "false" an unchecked checkbox is rendered
"WebkitFlexBasis": "auto",
"WebkitFlexDirection": "column",
"WebkitFlexShrink": 0,
"WebkitTransition": "0.1s",
"WebkitTransitionDuration": "0.1s",
"alignItems": "stretch",
"backgroundColor": "#939393",
"borderBottomLeftRadius": "10px",
@@ -540,7 +540,7 @@ exports[`components/Switch value when "false" an unchecked checkbox is rendered
"textAlign": "inherit",
"textDecoration": "none",
"top": "0px",
"transition": "0.1s",
"transitionDuration": "0.1s",
"width": "90%",
}
} />
@@ -558,7 +558,7 @@ exports[`components/Switch value when "false" an unchecked checkbox is rendered
"WebkitFlexDirection": "column",
"WebkitFlexShrink": 0,
"WebkitTransform": "translateX(0%)",
"WebkitTransition": "0.1s",
"WebkitTransitionDuration": "0.1s",
"alignItems": "stretch",
"alignSelf": "flex-start",
"backgroundColor": "#FAFAFA",
@@ -604,7 +604,7 @@ exports[`components/Switch value when "false" an unchecked checkbox is rendered
"textAlign": "inherit",
"textDecoration": "none",
"transform": "translateX(0%)",
"transition": "0.1s",
"transitionDuration": "0.1s",
"width": "20px",
}
} />
@@ -709,7 +709,7 @@ exports[`components/Switch value when "true" a checked checkbox is rendered 1`]
"WebkitFlexBasis": "auto",
"WebkitFlexDirection": "column",
"WebkitFlexShrink": 0,
"WebkitTransition": "0.1s",
"WebkitTransitionDuration": "0.1s",
"alignItems": "stretch",
"backgroundColor": "#A3D3CF",
"borderBottomLeftRadius": "10px",
@@ -754,7 +754,7 @@ exports[`components/Switch value when "true" a checked checkbox is rendered 1`]
"textAlign": "inherit",
"textDecoration": "none",
"top": "0px",
"transition": "0.1s",
"transitionDuration": "0.1s",
"width": "90%",
}
} />
@@ -772,7 +772,7 @@ exports[`components/Switch value when "true" a checked checkbox is rendered 1`]
"WebkitFlexDirection": "column",
"WebkitFlexShrink": 0,
"WebkitTransform": "translateX(100%)",
"WebkitTransition": "0.1s",
"WebkitTransitionDuration": "0.1s",
"alignItems": "stretch",
"alignSelf": "flex-start",
"backgroundColor": "#009688",
@@ -818,7 +818,7 @@ exports[`components/Switch value when "true" a checked checkbox is rendered 1`]
"textAlign": "inherit",
"textDecoration": "none",
"transform": "translateX(100%)",
"transition": "0.1s",
"transitionDuration": "0.1s",
"width": "20px",
}
} />

View File

@@ -7,6 +7,7 @@ import UIManager from '../../apis/UIManager';
import View from '../View';
import React, { Component, PropTypes } from 'react';
const emptyObject = {};
const thumbDefaultBoxShadow = '0px 1px 3px rgba(0,0,0,0.5)';
const thumbFocusedBoxShadow = `${thumbDefaultBoxShadow}, 0 0 0 10px rgba(0,0,0,0.1)`;
@@ -28,7 +29,7 @@ class Switch extends Component {
activeThumbColor: '#009688',
activeTrackColor: '#A3D3CF',
disabled: false,
style: {},
style: emptyObject,
thumbColor: '#FAFAFA',
trackColor: '#939393',
value: false
@@ -151,7 +152,7 @@ const styles = StyleSheet.create({
...StyleSheet.absoluteFillObject,
height: '70%',
margin: 'auto',
transition: '0.1s',
transitionDuration: '0.1s',
width: '90%'
},
disabledTrack: {
@@ -161,7 +162,7 @@ const styles = StyleSheet.create({
alignSelf: 'flex-start',
borderRadius: '100%',
boxShadow: thumbDefaultBoxShadow,
transition: '0.1s'
transitionDuration: '0.1s'
},
disabledThumb: {
backgroundColor: '#BDBDBD'

View File

@@ -40,25 +40,24 @@ class Text extends Component {
onLayout,
suppressHighlighting,
/* eslint-enable */
...other
...otherProps
} = this.props;
if (onPress) {
other.onClick = onPress;
other.onKeyDown = this._createEnterHandler(onPress);
other.tabIndex = 0;
otherProps.onClick = onPress;
otherProps.onKeyDown = this._createEnterHandler(onPress);
otherProps.tabIndex = 0;
}
return createDOMElement('span', {
...other,
style: [
styles.initial,
style,
!selectable && styles.notSelectable,
numberOfLines === 1 && styles.singleLineStyle,
onPress && styles.pressable
]
});
otherProps.style = [
styles.initial,
style,
!selectable && styles.notSelectable,
numberOfLines === 1 && styles.singleLineStyle,
onPress && styles.pressable
];
return createDOMElement('span', otherProps);
}
_createEnterHandler(fn) {

View File

@@ -169,8 +169,6 @@ describe('components/TextInput', () => {
}
});
test('prop "onLayout"');
test('prop "onSelectionChange"', (done) => {
const input = findNativeInput(mount(<TextInput defaultValue='12345' onSelectionChange={onSelectionChange} />));
input.simulate('select', { target: { selectionStart: 0, selectionEnd: 3 } });
@@ -181,6 +179,16 @@ describe('components/TextInput', () => {
}
});
describe('prop "onSubmitEditing"', () => {
test('single-line input', (done) => {
const input = findNativeInput(mount(<TextInput defaultValue='12345' onSubmitEditing={onSubmitEditing} />));
input.simulate('keyPress', { which: 13 });
function onSubmitEditing(e) {
done();
}
});
});
test('prop "secureTextEntry"', () => {
let input = findNativeInput(shallow(<TextInput secureTextEntry />));
expect(input.prop('type')).toEqual('password');

View File

@@ -10,6 +10,8 @@ import UIManager from '../../apis/UIManager';
import View from '../View';
import { Component, PropTypes } from 'react';
const emptyObject = {};
/**
* React Native events differ from W3C events.
*/
@@ -72,6 +74,7 @@ class TextInput extends Component {
onFocus: PropTypes.func,
onKeyPress: PropTypes.func,
onSelectionChange: PropTypes.func,
onSubmitEditing: PropTypes.func,
placeholder: PropTypes.string,
placeholderTextColor: PropTypes.string,
secureTextEntry: PropTypes.bool,
@@ -93,7 +96,7 @@ class TextInput extends Component {
multiline: false,
numberOfLines: 2,
secureTextEntry: false,
style: {}
style: emptyObject
};
blur() {
@@ -152,7 +155,7 @@ class TextInput extends Component {
selectionColor,
selectTextOnFocus,
/* eslint-enable */
...other
...otherProps
} = this.props;
let type;
@@ -185,9 +188,9 @@ class TextInput extends Component {
const component = multiline ? TextareaAutosize : 'input';
const props = {
...other,
Object.assign(otherProps, {
autoCorrect: autoCorrect ? 'on' : 'off',
dir: 'auto',
onBlur: normalizeEventHandler(this._handleBlur),
onChange: normalizeEventHandler(this._handleChange),
onFocus: normalizeEventHandler(this._handleFocus),
@@ -199,16 +202,16 @@ class TextInput extends Component {
styles.initial,
style
]
};
});
if (multiline) {
props.maxRows = maxNumberOfLines || numberOfLines;
props.minRows = numberOfLines;
otherProps.maxRows = maxNumberOfLines || numberOfLines;
otherProps.minRows = numberOfLines;
} else {
props.type = type;
otherProps.type = type;
}
return createDOMElement(component, props);
return createDOMElement(component, otherProps);
}
_handleBlur = (e) => {
@@ -243,7 +246,7 @@ class TextInput extends Component {
}
_handleSelectionChange = (e) => {
const { onSelectionChange, selection = {} } = this.props;
const { onSelectionChange, selection = emptyObject } = this.props;
if (onSelectionChange) {
try {
const node = e.target;
@@ -270,7 +273,6 @@ const styles = StyleSheet.create({
borderWidth: 0,
boxSizing: 'border-box',
color: 'inherit',
flex: 1,
font: 'inherit',
padding: 0
}

View File

@@ -6,7 +6,7 @@
'use strict';
var PooledClass = require('react/lib/PooledClass');
var PooledClass = require('react-dom/lib/PooledClass');
var twoArgumentPooler = PooledClass.twoArgumentPooler;

View File

@@ -6,7 +6,7 @@
'use strict';
var PooledClass = require('react/lib/PooledClass');
var PooledClass = require('react-dom/lib/PooledClass');
var twoArgumentPooler = PooledClass.twoArgumentPooler;

View File

@@ -566,13 +566,13 @@ var TouchableMixin = {
* @sideeffects
* @private
*/
_remeasureMetricsOnActivation: function(e) {
/* @edit begin */
UIManager.measure(
e.nativeEvent.target,
this._handleQueryLayout
);
/* @edit end */
_remeasureMetricsOnActivation: function() {
const tag = this.state.touchable.responderID;
if (tag == null) {
return;
}
UIManager.measure(tag, this._handleQueryLayout);
},
_handleQueryLayout: function(l, t, w, h, globalX, globalY) {
@@ -684,7 +684,7 @@ var TouchableMixin = {
}
if (!IsActive[curState] && IsActive[nextState]) {
this._remeasureMetricsOnActivation(e);
this._remeasureMetricsOnActivation();
}
if (IsPressingIn[curState] && signal === Signals.LONG_PRESS_DETECTED) {
@@ -692,16 +692,9 @@ var TouchableMixin = {
}
if (newIsHighlight && !curIsHighlight) {
this._savePressInLocation(e);
this.touchableHandleActivePressIn && this.touchableHandleActivePressIn(e);
} else if (!newIsHighlight && curIsHighlight && this.touchableHandleActivePressOut) {
if (this.touchableGetPressOutDelayMS && this.touchableGetPressOutDelayMS()) {
this.pressOutDelayTimeout = setTimeout(() => {
this.touchableHandleActivePressOut(e);
}, this.touchableGetPressOutDelayMS());
} else {
this.touchableHandleActivePressOut(e);
}
this._startHighlight(e);
} else if (!newIsHighlight && curIsHighlight) {
this._endHighlight(e);
}
if (IsPressingIn[curState] && signal === Signals.RESPONDER_RELEASE) {
@@ -714,49 +707,40 @@ var TouchableMixin = {
var shouldInvokePress = !IsLongPressingIn[curState] || pressIsLongButStillCallOnPress;
if (shouldInvokePress && this.touchableHandlePress) {
if (!newIsHighlight && !curIsHighlight) {
// we never highlighted because of delay, but we should highlight now
this._startHighlight(e);
this._endHighlight(e);
}
this.touchableHandlePress(e);
}
}
this.touchableDelayTimeout && clearTimeout(this.touchableDelayTimeout);
this.touchableDelayTimeout = null;
}
},
_startHighlight: function(e) {
this._savePressInLocation(e);
this.touchableHandleActivePressIn && this.touchableHandleActivePressIn(e);
},
_endHighlight: function(e) {
if (this.touchableHandleActivePressOut) {
if (this.touchableGetPressOutDelayMS && this.touchableGetPressOutDelayMS()) {
this.pressOutDelayTimeout = setTimeout(() => {
this.touchableHandleActivePressOut(e);
}, this.touchableGetPressOutDelayMS());
} else {
this.touchableHandleActivePressOut(e);
}
}
},
};
var Touchable = {
Mixin: TouchableMixin,
TOUCH_TARGET_DEBUG: false, // Highlights all touchable targets. Toggle with Inspector.
/**
* Renders a debugging overlay to visualize touch target with hitSlop (might not work on Android).
*/
renderDebugView: ({color, hitSlop}) => {
if (!Touchable.TOUCH_TARGET_DEBUG) {
return null;
}
if (process.env.NODE_ENV === 'production') {
throw Error('Touchable.TOUCH_TARGET_DEBUG should not be enabled in prod!');
}
const debugHitSlopStyle = {};
hitSlop = hitSlop || {top: 0, bottom: 0, left: 0, right: 0};
for (const key in hitSlop) {
debugHitSlopStyle[key] = -hitSlop[key];
}
const hexColor = '#' + ('00000000' + normalizeColor(color).toString(16)).substr(-8);
return (
<View
pointerEvents="none"
style={{
position: 'absolute',
borderColor: hexColor.slice(0, -2) + '55', // More opaque
borderWidth: 1,
borderStyle: 'dashed',
backgroundColor: hexColor.slice(0, -2) + '0F', // Less opaque
...debugHitSlopStyle
}}
/>
);
}
Mixin: TouchableMixin
};
module.exports = Touchable;

View File

@@ -33,7 +33,7 @@ type Event = Object;
var DEFAULT_PROPS = {
accessibilityRole: 'button',
activeOpacity: 0.8,
activeOpacity: 0.85,
underlayColor: 'black'
};
@@ -55,13 +55,13 @@ var PRESS_RETENTION_OFFSET = {top: 20, left: 20, right: 20, bottom: 30};
* <TouchableHighlight onPress={this._onPressButton}>
* <Image
* style={styles.button}
* source={require('image!myButton')}
* source={require('./myButton')}
* />
* </TouchableHighlight>
* );
* },
* ```
* > **NOTE**: TouchableHighlight supports only one child
* > **NOTE**: TouchableHighlight must have one child (not zero or more than one)
* >
* > If you wish to have several child components, wrap them in a View.
*/

View File

@@ -43,7 +43,7 @@ var PRESS_RETENTION_OFFSET = {top: 20, left: 20, right: 20, bottom: 30};
* <TouchableOpacity onPress={this._onPressButton}>
* <Image
* style={styles.button}
* source={require('image!myButton')}
* source={require('./myButton')}
* />
* </TouchableOpacity>
* );
@@ -60,12 +60,14 @@ var TouchableOpacity = React.createClass({
* active.
*/
activeOpacity: React.PropTypes.number,
focusedOpacity: React.PropTypes.number
},
getDefaultProps: function() {
return {
accessibilityRole: 'button',
activeOpacity: 0.2,
focusedOpacity: 0.7
};
},
@@ -81,10 +83,11 @@ var TouchableOpacity = React.createClass({
ensurePositiveDelayProps(nextProps);
},
setOpacityTo: function(value) {
setOpacityTo: function(value: number, duration: number) {
this.setNativeProps({
style: {
opacity: value
opacity: value,
transitionDuration: duration
}
});
},
@@ -94,26 +97,20 @@ var TouchableOpacity = React.createClass({
* defined on your component.
*/
touchableHandleActivePressIn: function(e: Event) {
this.clearTimeout(this._hideTimeout);
this._hideTimeout = null;
this._opacityActive();
if (e.dispatchConfig.registrationName === 'onResponderGrant') {
this._opacityActive(0);
} else {
this._opacityActive(150);
}
this.props.onPressIn && this.props.onPressIn(e);
},
touchableHandleActivePressOut: function(e: Event) {
if (!this._hideTimeout) {
this._opacityInactive();
}
this._opacityInactive(250);
this.props.onPressOut && this.props.onPressOut(e);
},
touchableHandlePress: function(e: Event) {
this.clearTimeout(this._hideTimeout);
this._opacityActive();
this._hideTimeout = this.setTimeout(
this._opacityInactive,
this.props.delayPressOut || 100
);
this.props.onPress && this.props.onPress(e);
},
@@ -142,19 +139,22 @@ var TouchableOpacity = React.createClass({
return this.props.delayPressOut;
},
_opacityActive: function() {
this.setOpacityTo(this.props.activeOpacity);
_opacityActive: function(duration: number) {
this.setOpacityTo(this.props.activeOpacity, duration);
},
_opacityInactive: function() {
this.clearTimeout(this._hideTimeout);
this._hideTimeout = null;
_opacityInactive: function(duration: number) {
var childStyle = flattenStyle(this.props.style) || {};
this.setOpacityTo(
childStyle.opacity === undefined ? 1 : childStyle.opacity
childStyle.opacity === undefined ? 1 : childStyle.opacity,
duration
);
},
_opacityFocused: function() {
this.setOpacityTo(this.props.focusedOpacity);
},
_onKeyEnter(e, callback) {
var ENTER = 13
if (e.keyCode === ENTER) {
@@ -197,7 +197,8 @@ var TouchableOpacity = React.createClass({
var styles = StyleSheet.create({
root: {
cursor: 'pointer',
transition: 'opacity 0.15s',
transitionProperty: 'opacity',
transitionDuration: '0.15s',
userSelect: 'none'
},
disabled: {

View File

@@ -22,12 +22,12 @@ var StyleSheet = require('../../apis/StyleSheet');
type Event = Object;
var PRESS_RETENTION_OFFSET = {top: 20, left: 20, right: 20, bottom: 30};
const PRESS_RETENTION_OFFSET = {top: 20, left: 20, right: 20, bottom: 30};
/**
* Do not use unless you have a very good reason. All the elements that
* respond to press should have a visual feedback when touched. This is
* one of the primary reason a "web" app doesn't feel "native".
* one of the primary reasons a "web" app doesn't feel "native".
*
* > **NOTE**: TouchableWithoutFeedback supports only one child
* >
@@ -144,7 +144,7 @@ const TouchableWithoutFeedback = React.createClass({
return this.props.delayPressOut || 0;
},
render: function(): ReactElement<any> {
render: function(): React.Element<any> {
// Note(avik): remove dynamic typecast once Flow has been upgraded
const child = React.Children.only(this.props.children);
let children = child.props.children;
@@ -153,12 +153,6 @@ const TouchableWithoutFeedback = React.createClass({
'TouchableWithoutFeedback does not work well with Text children. Wrap children in a View instead. See ' +
((child._owner && child._owner.getName && child._owner.getName()) || '<unknown>')
);
if (Touchable.TOUCH_TARGET_DEBUG && child.type && child.type.displayName === 'View') {
if (!Array.isArray(children)) {
children = [children];
}
children.push(Touchable.renderDebugView({color: 'red', hitSlop: this.props.hitSlop}));
}
const style = (Touchable.TOUCH_TARGET_DEBUG && child.type && child.type.displayName === 'Text') ?
[
styles.root,

View File

@@ -2,6 +2,7 @@ import BorderPropTypes from '../../propTypes/BorderPropTypes';
import ColorPropType from '../../propTypes/ColorPropType';
import LayoutPropTypes from '../../propTypes/LayoutPropTypes';
import { PropTypes } from 'react';
import ShadowPropTypes from '../../propTypes/ShadowPropTypes';
import TransformPropTypes from '../../propTypes/TransformPropTypes';
const { number, oneOf, string } = PropTypes;
@@ -11,6 +12,7 @@ const hiddenOrVisible = oneOf([ 'hidden', 'visible' ]);
module.exports = process.env.NODE_ENV !== 'production' ? {
...BorderPropTypes,
...LayoutPropTypes,
...ShadowPropTypes,
...TransformPropTypes,
backfaceVisibility: hiddenOrVisible,
backgroundColor: ColorPropType,
@@ -32,7 +34,10 @@ module.exports = process.env.NODE_ENV !== 'production' ? {
outline: string,
overflowX: autoOrHiddenOrVisible,
overflowY: autoOrHiddenOrVisible,
transition: string,
transitionDelay: string,
transitionDuration: string,
transitionProperty: string,
transitionTimingFunction: string,
userSelect: string,
visibility: hiddenOrVisible,
WebkitOverflowScrolling: oneOf([ 'auto', 'touch' ])

View File

@@ -99,7 +99,7 @@ class View extends Component {
onMagicTap,
removeClippedSubviews,
/* eslint-enable */
...other
...otherProps
} = this.props;
const flattenedStyle = StyleSheet.flatten(style);
@@ -107,27 +107,24 @@ class View extends Component {
// 'View' needs to set 'flexShrink:0' only when there is no 'flex' or 'flexShrink' style provided
const needsFlexReset = !flattenedStyle || (flattenedStyle.flex == null && flattenedStyle.flexShrink == null);
const normalizedEventHandlers = eventHandlerNames.reduce((handlerProps, handlerName) => {
const component = this.context.isInAButtonView ? 'span' : 'div';
eventHandlerNames.reduce((props, handlerName) => {
const handler = this.props[handlerName];
if (typeof handler === 'function') {
handlerProps[handlerName] = this._normalizeEventForHandler(handler, handlerName);
props[handlerName] = this._normalizeEventForHandler(handler, handlerName);
}
return handlerProps;
}, {});
return props;
}, otherProps);
const component = this.context.isInAButtonView ? 'span' : 'div';
const props = {
...other,
...normalizedEventHandlers,
style: [
styles.initial,
style,
needsFlexReset && styles.flexReset,
pointerEventsStyle
]
};
otherProps.style = [
styles.initial,
style,
needsFlexReset && styles.flexReset,
pointerEventsStyle
];
return createDOMElement(component, props);
return createDOMElement(component, otherProps);
}
_normalizeEventForHandler(handler, handlerName) {

View File

@@ -1,17 +1,22 @@
import findNodeHandle from './modules/findNodeHandle';
import ReactDefaultInjection from 'react/lib/ReactDefaultInjection';
import { render, unmountComponentAtNode } from 'react/lib/ReactMount';
import ReactDefaultInjection from 'react-dom/lib/ReactDefaultInjection';
import { render, unmountComponentAtNode } from 'react-dom/lib/ReactMount';
ReactDefaultInjection.inject();
// APIs
import I18nManager from './apis/I18nManager';
import Platform from './apis/Platform';
import StyleSheet from './apis/StyleSheet';
// components
import Image from './components/Image';
import Text from './components/Text';
import TextInput from './components/TextInput';
import Touchable from './components/Touchable/Touchable';
import TouchableHighlight from './components/Touchable/TouchableHighlight';
import TouchableOpacity from './components/Touchable/TouchableOpacity';
import TouchableWithoutFeedback from './components/Touchable/TouchableWithoutFeedback';
import View from './components/View';
// modules
@@ -24,11 +29,16 @@ const ReactNativeCore = {
unmountComponentAtNode,
// APIs
I18nManager,
Platform,
StyleSheet,
// components
Image,
Text,
TextInput,
Touchable,
TouchableHighlight,
TouchableOpacity,
TouchableWithoutFeedback,
View
};

View File

@@ -1,6 +1,6 @@
import findNodeHandle from './modules/findNodeHandle';
import ReactDefaultInjection from 'react/lib/ReactDefaultInjection';
import { render, unmountComponentAtNode } from 'react/lib/ReactMount';
import ReactDefaultInjection from 'react-dom/lib/ReactDefaultInjection';
import { render, unmountComponentAtNode } from 'react-dom/lib/ReactMount';
ReactDefaultInjection.inject();
@@ -9,6 +9,7 @@ import Animated from './apis/Animated';
import AppRegistry from './apis/AppRegistry';
import AppState from './apis/AppState';
import AsyncStorage from './apis/AsyncStorage';
import Clipboard from './apis/Clipboard';
import Dimensions from './apis/Dimensions';
import Easing from 'animated/lib/Easing';
import I18nManager from './apis/I18nManager';
@@ -58,6 +59,7 @@ const ReactNative = {
AppRegistry,
AppState,
AsyncStorage,
Clipboard,
Dimensions,
Easing,
I18nManager,

View File

@@ -0,0 +1,48 @@
let id = 0;
const requests = {};
const ImageLoader = {
abort(requestId: number) {
let image = requests[`${requestId}`];
if (image) {
image.onerror = image.onload = image = null;
delete requests[`${requestId}`];
}
},
getSize(uri, success, failure) {
let complete = false;
const interval = setInterval(callback, 16);
const requestId = ImageLoader.load(uri, callback, callback);
function callback() {
const image = requests[`${requestId}`];
if (image) {
const { naturalHeight, naturalWidth } = image;
if (naturalHeight && naturalWidth) {
success(naturalWidth, naturalHeight);
complete = true;
}
}
if (complete) {
ImageLoader.abort(requestId);
clearInterval(interval);
}
}
},
load(uri, onLoad, onError): number {
id += 1;
const image = new window.Image();
image.onerror = onError;
image.onload = onLoad;
image.src = uri;
requests[`${id}`] = image;
return id;
},
prefetch(uri): Promise {
return new Promise((resolve, reject) => {
ImageLoader.load(uri, resolve, reject);
});
}
};
export default ImageLoader;

View File

@@ -105,6 +105,8 @@ var warning = require('fbjs/lib/warning');
* this.props.onKeyboardDidHide
*/
const emptyObject = {};
var IS_ANIMATING_TOUCH_START_THRESHOLD_MS = 16;
type State = {
@@ -378,7 +380,7 @@ var ScrollResponderMixin = {
if (typeof x === 'number') {
console.warn('`scrollResponderScrollTo(x, y, animated)` is deprecated. Use `scrollResponderScrollTo({x: 5, y: 5, animated: true})` instead.');
} else {
({x, y, animated} = x || {});
({x, y, animated} = x || emptyObject);
}
const node = this.scrollResponderGetScrollableNode()
node.scrollLeft = x || 0

View File

@@ -7,13 +7,15 @@
import emptyFunction from 'fbjs/lib/emptyFunction';
const emptyObject = {};
const applyLayout = (Component) => {
const componentDidMount = Component.prototype.componentDidMount || emptyFunction;
const componentDidUpdate = Component.prototype.componentDidUpdate || emptyFunction;
Component.prototype.componentDidMount = function () {
componentDidMount.call(this);
this._layoutState = {};
this._layoutState = emptyObject;
this._handleLayout();
};

View File

@@ -1,6 +1,8 @@
import React from 'react';
import StyleSheet from '../../apis/StyleSheet';
const emptyObject = {};
const roleComponents = {
article: 'article',
banner: 'header',
@@ -17,7 +19,7 @@ const roleComponents = {
region: 'section'
};
const createDOMElement = (component, rnProps = {}) => {
const createDOMElement = (component, rnProps = emptyObject) => {
const {
accessibilityLabel,
accessibilityLiveRegion,
@@ -25,15 +27,14 @@ const createDOMElement = (component, rnProps = {}) => {
accessible = true,
testID,
type,
...other
...domProps
} = rnProps;
const accessibilityComponent = accessibilityRole && roleComponents[accessibilityRole];
const Component = accessibilityComponent || component;
const domProps = {
...other,
...StyleSheet.resolve(other)
};
Object.assign(domProps, StyleSheet.resolve(domProps));
if (!accessible) { domProps['aria-hidden'] = true; }
if (accessibilityLabel) { domProps['aria-label'] = accessibilityLabel; }
if (accessibilityLiveRegion) { domProps['aria-live'] = accessibilityLiveRegion; }

View File

@@ -1,2 +1,2 @@
import findNodeHandle from 'react/lib/findDOMNode';
import findNodeHandle from 'react-dom/lib/findDOMNode';
export default findNodeHandle;

View File

@@ -1,22 +1,19 @@
// based on https://github.com/facebook/react/pull/4303/files
import EventConstants from 'react/lib/EventConstants';
import EventPluginRegistry from 'react/lib/EventPluginRegistry';
import EventPluginRegistry from 'react-dom/lib/EventPluginRegistry';
import normalizeNativeEvent from './normalizeNativeEvent';
import ResponderEventPlugin from 'react/lib/ResponderEventPlugin';
import ResponderTouchHistoryStore from 'react/lib/ResponderTouchHistoryStore';
import ResponderEventPlugin from 'react-dom/lib/ResponderEventPlugin';
import ResponderTouchHistoryStore from 'react-dom/lib/ResponderTouchHistoryStore';
const {
topMouseDown,
topMouseMove,
topMouseUp,
topScroll,
topSelectionChange,
topTouchCancel,
topTouchEnd,
topTouchMove,
topTouchStart
} = EventConstants.topLevelTypes;
const topMouseDown = 'topMouseDown';
const topMouseMove = 'topMouseMove';
const topMouseUp = 'topMouseUp';
const topScroll = 'topScroll';
const topSelectionChange = 'topSelectionChange';
const topTouchCancel = 'topTouchCancel';
const topTouchEnd = 'topTouchEnd';
const topTouchMove = 'topTouchMove';
const topTouchStart = 'topTouchStart';
const endDependencies = [ topTouchCancel, topTouchEnd, topMouseUp ];
const moveDependencies = [ topTouchMove, topMouseMove ];

View File

@@ -1,5 +1,7 @@
const emptyArray = [];
// Mobile Safari re-uses touch objects, so we copy the properties we want and normalize the identifier
const normalizeTouches = (touches = []) => Array.prototype.slice.call(touches).map((touch) => {
const normalizeTouches = (touches = emptyArray) => Array.prototype.slice.call(touches).map((touch) => {
const identifier = touch.identifier > 20 ? (touch.identifier % 20) : touch.identifier;
const rect = touch.target && touch.target.getBoundingClientRect();
@@ -59,21 +61,23 @@ function normalizeTouchEvent(nativeEvent) {
}
function normalizeMouseEvent(nativeEvent) {
const touches = [ {
_normalized: true,
clientX: nativeEvent.clientX,
clientY: nativeEvent.clientY,
force: nativeEvent.force,
locationX: nativeEvent.clientX,
locationY: nativeEvent.clientY,
identifier: 0,
pageX: nativeEvent.pageX,
pageY: nativeEvent.pageY,
screenX: nativeEvent.screenX,
screenY: nativeEvent.screenY,
target: nativeEvent.target,
timestamp: Date.now()
} ];
const touches = [
{
_normalized: true,
clientX: nativeEvent.clientX,
clientY: nativeEvent.clientY,
force: nativeEvent.force,
locationX: nativeEvent.clientX,
locationY: nativeEvent.clientY,
identifier: 0,
pageX: nativeEvent.pageX,
pageY: nativeEvent.pageY,
screenX: nativeEvent.screenX,
screenY: nativeEvent.screenY,
target: nativeEvent.target,
timestamp: Date.now()
}
];
return {
_normalized: true,
changedTouches: touches,
@@ -87,7 +91,7 @@ function normalizeMouseEvent(nativeEvent) {
stopPropagation: nativeEvent.stopPropagation.bind(nativeEvent),
target: nativeEvent.target,
timestamp: touches[0].timestamp,
touches: (nativeEvent.type === 'mouseup') ? [] : touches
touches: (nativeEvent.type === 'mouseup') ? emptyArray : touches
};
}

View File

@@ -14,7 +14,7 @@ import { PropTypes } from 'react'
var colorPropType = function(isRequired, props, propName, componentName, location, propFullName) {
var normalizeColor = require('../modules/normalizeColor');
var ReactPropTypeLocationNames = require('react/lib/ReactPropTypeLocationNames');
var ReactPropTypeLocationNames = require('react-dom/lib/ReactPropTypeLocationNames');
var color = props[propName];
if (color === undefined || color === null) {
if (isRequired) {

View File

@@ -0,0 +1,18 @@
import ColorPropType from './ColorPropType';
import { PropTypes } from 'react';
const { number, oneOfType, shape, string } = PropTypes;
const numberOrString = oneOfType([ number, string ]);
const ShadowPropTypes = {
shadowColor: ColorPropType,
shadowOffset: shape({
width: numberOrString,
height: numberOrString
}),
shadowOpacity: number,
shadowRadius: numberOrString,
shadowSpread: numberOrString
};
module.exports = ShadowPropTypes;

View File

@@ -12,8 +12,8 @@
*/
import invariant from 'fbjs/lib/invariant'
import ReactPropTypeLocationNames from 'react/lib/ReactPropTypeLocationNames'
import ReactPropTypesSecret from 'react/lib/ReactPropTypesSecret'
import ReactPropTypeLocationNames from 'react-dom/lib/ReactPropTypeLocationNames'
import ReactPropTypesSecret from 'react-dom/lib/ReactPropTypesSecret'
function createStrictShapeTypeChecker(
shapeTypes: {[key: string]: ReactPropsCheckType}

313
yarn.lock
View File

@@ -1,5 +1,7 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
"@kadira/react-split-pane@^1.4.0":
version "1.4.7"
resolved "https://registry.yarnpkg.com/@kadira/react-split-pane/-/react-split-pane-1.4.7.tgz#6d753d4a9fe62fe82056e323a6bcef7f026972b5"
@@ -96,6 +98,10 @@
webpack-dev-middleware "^1.6.0"
webpack-hot-middleware "^2.13.2"
Base64@~0.2.0:
version "0.2.1"
resolved "https://registry.yarnpkg.com/Base64/-/Base64-0.2.1.tgz#ba3a4230708e186705065e66babdd4c35cf60028"
abab@^1.0.0:
version "1.0.3"
resolved "https://registry.yarnpkg.com/abab/-/abab-1.0.3.tgz#b81de5f7274ec4e756d797cd834f303642724e5d"
@@ -316,14 +322,14 @@ async-each@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d"
async@1.x, async@^1.3.0, async@^1.4.0, async@^1.4.2:
version "1.5.2"
resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a"
async@^0.9.0:
version "0.9.2"
resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d"
async@^1.3.0, async@^1.4.0, async@^1.4.2, async@1.x:
version "1.5.2"
resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a"
async@~0.2.6:
version "0.2.10"
resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1"
@@ -628,6 +634,14 @@ babel-plugin-transform-async-to-generator@^6.16.0, babel-plugin-transform-async-
babel-plugin-syntax-async-functions "^6.8.0"
babel-runtime "^6.0.0"
babel-plugin-transform-class-properties@6.16.0:
version "6.16.0"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.16.0.tgz#969bca24d34e401d214f36b8af5c1346859bc904"
dependencies:
babel-helper-function-name "^6.8.0"
babel-plugin-syntax-class-properties "^6.8.0"
babel-runtime "^6.9.1"
babel-plugin-transform-class-properties@^6.5.0:
version "6.19.0"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.19.0.tgz#1274b349abaadc835164e2004f4a2444a2788d5f"
@@ -637,14 +651,6 @@ babel-plugin-transform-class-properties@^6.5.0:
babel-runtime "^6.9.1"
babel-template "^6.15.0"
babel-plugin-transform-class-properties@6.16.0:
version "6.16.0"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.16.0.tgz#969bca24d34e401d214f36b8af5c1346859bc904"
dependencies:
babel-helper-function-name "^6.8.0"
babel-plugin-syntax-class-properties "^6.8.0"
babel-runtime "^6.9.1"
babel-plugin-transform-es2015-arrow-functions@^6.3.13, babel-plugin-transform-es2015-arrow-functions@^6.5.0:
version "6.8.0"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.8.0.tgz#5b63afc3181bdc9a8c4d481b5a4f3f7d7fef3d9d"
@@ -689,18 +695,18 @@ babel-plugin-transform-es2015-computed-properties@^6.3.13, babel-plugin-transfor
babel-runtime "^6.0.0"
babel-template "^6.8.0"
babel-plugin-transform-es2015-destructuring@^6.18.0, babel-plugin-transform-es2015-destructuring@^6.5.0, babel-plugin-transform-es2015-destructuring@^6.6.0:
version "6.19.0"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.19.0.tgz#ff1d911c4b3f4cab621bd66702a869acd1900533"
dependencies:
babel-runtime "^6.9.0"
babel-plugin-transform-es2015-destructuring@6.16.0:
version "6.16.0"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.16.0.tgz#050fe0866f5d53b36062ee10cdf5bfe64f929627"
dependencies:
babel-runtime "^6.9.0"
babel-plugin-transform-es2015-destructuring@^6.18.0, babel-plugin-transform-es2015-destructuring@^6.5.0, babel-plugin-transform-es2015-destructuring@^6.6.0:
version "6.19.0"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.19.0.tgz#ff1d911c4b3f4cab621bd66702a869acd1900533"
dependencies:
babel-runtime "^6.9.0"
babel-plugin-transform-es2015-duplicate-keys@^6.6.0:
version "6.8.0"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.8.0.tgz#fd8f7f7171fc108cc1c70c3164b9f15a81c25f7d"
@@ -768,17 +774,6 @@ babel-plugin-transform-es2015-object-super@^6.3.13:
babel-helper-replace-supers "^6.8.0"
babel-runtime "^6.0.0"
babel-plugin-transform-es2015-parameters@^6.18.0, babel-plugin-transform-es2015-parameters@^6.5.0, babel-plugin-transform-es2015-parameters@^6.6.0:
version "6.18.0"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.18.0.tgz#9b2cfe238c549f1635ba27fc1daa858be70608b1"
dependencies:
babel-helper-call-delegate "^6.18.0"
babel-helper-get-function-arity "^6.18.0"
babel-runtime "^6.9.0"
babel-template "^6.16.0"
babel-traverse "^6.18.0"
babel-types "^6.18.0"
babel-plugin-transform-es2015-parameters@6.17.0:
version "6.17.0"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.17.0.tgz#e06d30cef897f46adb4734707bbe128a0d427d58"
@@ -790,6 +785,17 @@ babel-plugin-transform-es2015-parameters@6.17.0:
babel-traverse "^6.16.0"
babel-types "^6.16.0"
babel-plugin-transform-es2015-parameters@^6.18.0, babel-plugin-transform-es2015-parameters@^6.5.0, babel-plugin-transform-es2015-parameters@^6.6.0:
version "6.18.0"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.18.0.tgz#9b2cfe238c549f1635ba27fc1daa858be70608b1"
dependencies:
babel-helper-call-delegate "^6.18.0"
babel-helper-get-function-arity "^6.18.0"
babel-runtime "^6.9.0"
babel-template "^6.16.0"
babel-traverse "^6.18.0"
babel-types "^6.18.0"
babel-plugin-transform-es2015-shorthand-properties@^6.18.0, babel-plugin-transform-es2015-shorthand-properties@^6.3.13, babel-plugin-transform-es2015-shorthand-properties@^6.5.0:
version "6.18.0"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.18.0.tgz#e2ede3b7df47bf980151926534d1dd0cbea58f43"
@@ -852,16 +858,16 @@ babel-plugin-transform-object-assign@^6.5.0:
dependencies:
babel-runtime "^6.0.0"
babel-plugin-transform-object-rest-spread@^6.5.0:
version "6.19.0"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.19.0.tgz#f6ac428ee3cb4c6aa00943ed1422ce813603b34c"
babel-plugin-transform-object-rest-spread@6.16.0:
version "6.16.0"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.16.0.tgz#db441d56fffc1999052fdebe2e2f25ebd28e36a9"
dependencies:
babel-plugin-syntax-object-rest-spread "^6.8.0"
babel-runtime "^6.0.0"
babel-plugin-transform-object-rest-spread@6.16.0:
version "6.16.0"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.16.0.tgz#db441d56fffc1999052fdebe2e2f25ebd28e36a9"
babel-plugin-transform-object-rest-spread@^6.5.0:
version "6.19.0"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.19.0.tgz#f6ac428ee3cb4c6aa00943ed1422ce813603b34c"
dependencies:
babel-plugin-syntax-object-rest-spread "^6.8.0"
babel-runtime "^6.0.0"
@@ -878,14 +884,14 @@ babel-plugin-transform-react-display-name@^6.3.13, babel-plugin-transform-react-
dependencies:
babel-runtime "^6.0.0"
babel-plugin-transform-react-jsx-self@^6.11.0, babel-plugin-transform-react-jsx-self@6.11.0:
babel-plugin-transform-react-jsx-self@6.11.0, babel-plugin-transform-react-jsx-self@^6.11.0:
version "6.11.0"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx-self/-/babel-plugin-transform-react-jsx-self-6.11.0.tgz#605c9450c1429f97a930f7e1dfe3f0d9d0dbd0f4"
dependencies:
babel-plugin-syntax-jsx "^6.8.0"
babel-runtime "^6.9.0"
babel-plugin-transform-react-jsx-source@^6.3.13, babel-plugin-transform-react-jsx-source@^6.5.0, babel-plugin-transform-react-jsx-source@6.9.0:
babel-plugin-transform-react-jsx-source@6.9.0, babel-plugin-transform-react-jsx-source@^6.3.13, babel-plugin-transform-react-jsx-source@^6.5.0:
version "6.9.0"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx-source/-/babel-plugin-transform-react-jsx-source-6.9.0.tgz#af684a05c2067a86e0957d4f343295ccf5dccf00"
dependencies:
@@ -904,7 +910,7 @@ babel-plugin-transform-react-remove-prop-types:
version "0.2.11"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.2.11.tgz#05eb7cc4670d6506d801680576589c7abcd51b00"
babel-plugin-transform-regenerator@^6.16.0, babel-plugin-transform-regenerator@^6.5.0, babel-plugin-transform-regenerator@^6.6.0, babel-plugin-transform-regenerator@6.16.1:
babel-plugin-transform-regenerator@6.16.1, babel-plugin-transform-regenerator@^6.16.0, babel-plugin-transform-regenerator@^6.5.0, babel-plugin-transform-regenerator@^6.6.0:
version "6.16.1"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.16.1.tgz#a75de6b048a14154aae14b0122756c5bed392f59"
dependencies:
@@ -1098,16 +1104,16 @@ babel-register@^6.18.0:
mkdirp "^0.5.1"
source-map-support "^0.4.2"
babel-runtime@^6.0.0, babel-runtime@^6.11.6, babel-runtime@^6.18.0, babel-runtime@^6.5.0, babel-runtime@^6.9.0, babel-runtime@^6.9.1, babel-runtime@^6.9.2, babel-runtime@6.x.x:
version "6.18.0"
resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.18.0.tgz#0f4177ffd98492ef13b9f823e9994a02584c9078"
babel-runtime@6.11.6:
version "6.11.6"
resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.11.6.tgz#6db707fef2d49c49bfa3cb64efdb436b518b8222"
dependencies:
core-js "^2.4.0"
regenerator-runtime "^0.9.5"
babel-runtime@6.11.6:
version "6.11.6"
resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.11.6.tgz#6db707fef2d49c49bfa3cb64efdb436b518b8222"
babel-runtime@6.x.x, babel-runtime@^6.0.0, babel-runtime@^6.11.6, babel-runtime@^6.18.0, babel-runtime@^6.5.0, babel-runtime@^6.9.0, babel-runtime@^6.9.1, babel-runtime@^6.9.2:
version "6.18.0"
resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.18.0.tgz#0f4177ffd98492ef13b9f823e9994a02584c9078"
dependencies:
core-js "^2.4.0"
regenerator-runtime "^0.9.5"
@@ -1161,17 +1167,13 @@ balanced-match@~0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.1.0.tgz#b504bd05869b39259dd0c5efc35d843176dccc4a"
base64-js@^1.0.2:
version "1.2.0"
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.2.0.tgz#a39992d723584811982be5e290bb6a53d86700f1"
base64-js@0.0.8:
version "0.0.8"
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-0.0.8.tgz#1101e9544f4a76b1bc3b26d452ca96d7a35e7978"
Base64@~0.2.0:
version "0.2.1"
resolved "https://registry.yarnpkg.com/Base64/-/Base64-0.2.1.tgz#ba3a4230708e186705065e66babdd4c35cf60028"
base64-js@^1.0.2:
version "1.2.0"
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.2.0.tgz#a39992d723584811982be5e290bb6a53d86700f1"
bcrypt-pbkdf@^1.0.0:
version "1.0.0"
@@ -1505,14 +1507,14 @@ colormin@^1.0.5:
css-color-names "0.0.4"
has "^1.0.1"
colors@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63"
colors@1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b"
colors@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63"
combined-stream@^1.0.5, combined-stream@~1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009"
@@ -1733,7 +1735,7 @@ csso@~2.2.1:
clap "^1.0.9"
source-map "^0.5.3"
"cssom@>= 0.3.0 < 0.4.0", cssom@0.3.x:
cssom@0.3.x, "cssom@>= 0.3.0 < 0.4.0":
version "0.3.1"
resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.1.tgz#c9e37ef2490e64f6d1baa10fda852257082c25d3"
@@ -1765,14 +1767,14 @@ dashdash@^1.12.0:
dependencies:
assert-plus "^1.0.0"
date-now@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b"
date-now@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/date-now/-/date-now-1.0.1.tgz#bb7d086438debe4182a485fb3df3fbfb99d6153c"
date-now@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b"
debounce:
version "1.0.0"
resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.0.0.tgz#0948af513d2e4ce407916f8506a423d3f9cf72d8"
@@ -1877,7 +1879,7 @@ doctrine@^1.2.0, doctrine@^1.2.2:
esutils "^2.0.2"
isarray "^1.0.0"
dom-serializer@~0.1.0, dom-serializer@0:
dom-serializer@0, dom-serializer@~0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.0.tgz#073c697546ce0780ce23be4a28e293e40bc30c82"
dependencies:
@@ -1892,7 +1894,7 @@ domain-browser@^1.1.1:
version "1.1.7"
resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.1.7.tgz#867aa4b093faa05f1de08c06f4d7b21fdf8698bc"
domelementtype@^1.3.0, domelementtype@1:
domelementtype@1, domelementtype@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.0.tgz#b17aed82e8ab59e52dd9c19b1756e0fc187204c2"
@@ -1906,7 +1908,7 @@ domhandler@^2.3.0:
dependencies:
domelementtype "1"
domutils@^1.5.1, domutils@1.5.1:
domutils@1.5.1, domutils@^1.5.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf"
dependencies:
@@ -1984,7 +1986,7 @@ enzyme@^2.4.1:
object.values "^1.0.3"
uuid "^2.0.3"
errno@^0.1.3, "errno@>=0.1.1 <0.2.0-0":
"errno@>=0.1.1 <0.2.0-0", errno@^0.1.3:
version "0.1.4"
resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.4.tgz#b896e23a9e5e8ba33871fc996abd3635fc9a1c7d"
dependencies:
@@ -2057,7 +2059,7 @@ es6-shim@^0.35.1:
version "0.35.1"
resolved "https://registry.yarnpkg.com/es6-shim/-/es6-shim-0.35.1.tgz#a23524009005b031ab4a352ac196dfdfd1144ab7"
es6-symbol@~3.1, es6-symbol@~3.1.0, es6-symbol@3:
es6-symbol@3, es6-symbol@~3.1, es6-symbol@~3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.0.tgz#94481c655e7a7cad82eba832d97d5433496d7ffa"
dependencies:
@@ -2081,7 +2083,7 @@ escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
escodegen@^1.6.1, escodegen@1.8.x:
escodegen@1.8.x, escodegen@^1.6.1:
version "1.8.1"
resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.8.1.tgz#5a5b53af4693110bebb0867aa3430dd3b70a1018"
dependencies:
@@ -2166,7 +2168,7 @@ espree@^3.3.1:
acorn "^4.0.1"
acorn-jsx "^3.0.0"
esprima@^2.6.0, esprima@^2.7.1, esprima@2.7.x:
esprima@2.7.x, esprima@^2.6.0, esprima@^2.7.1:
version "2.7.3"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581"
@@ -2301,7 +2303,7 @@ fb-watchman@^1.8.0, fb-watchman@^1.9.0:
dependencies:
bser "^1.0.2"
fbjs@^0.8.4:
fbjs@^0.8.1, fbjs@^0.8.4:
version "0.8.6"
resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.6.tgz#7eb67d6986b2d5007a9b6e92e0e7cb6f75cad290"
dependencies:
@@ -2536,7 +2538,7 @@ glob-parent@^2.0.0:
dependencies:
is-glob "^2.0.0"
glob@^5.0.15, glob@^5.0.5, glob@5.x:
glob@5.x, glob@^5.0.15, glob@^5.0.5:
version "5.0.15"
resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1"
dependencies:
@@ -2667,7 +2669,7 @@ hoek@2.x.x:
version "2.16.3"
resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed"
hoist-non-react-statics@^1.2.0, hoist-non-react-statics@1.x.x:
hoist-non-react-statics@1.x.x, hoist-non-react-statics@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-1.2.0.tgz#aa448cf0986d55cc40773b17174b7dd066cb7cfb"
@@ -2738,14 +2740,14 @@ hyphenate-style-name@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.2.tgz#31160a36930adaf1fc04c6074f7eb41465d4ec4b"
iconv-lite@^0.4.13, iconv-lite@~0.4.13:
version "0.4.15"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.15.tgz#fe265a218ac6a57cfe854927e9d04c19825eddeb"
iconv-lite@0.4.13:
version "0.4.13"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.13.tgz#1f88aba4ab0b1508e8312acc39345f36e992e2f2"
iconv-lite@^0.4.13, iconv-lite@~0.4.13:
version "0.4.15"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.15.tgz#fe265a218ac6a57cfe854927e9d04c19825eddeb"
icss-replace-symbols@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/icss-replace-symbols/-/icss-replace-symbols-1.0.2.tgz#cb0b6054eb3af6edc9ab1d62d01933e2d4c8bfa5"
@@ -2791,7 +2793,7 @@ inflight@^1.0.4:
once "^1.3.0"
wrappy "1"
inherits@^2.0.1, inherits@~2.0.0, inherits@~2.0.1, inherits@2, inherits@2.0.3:
inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@~2.0.0, inherits@~2.0.1:
version "2.0.3"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
@@ -2836,7 +2838,7 @@ interpret@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.1.tgz#d579fb7f693b858004947af39fa0db49f795602c"
invariant@^2.2.0, invariant@2.x.x:
invariant@2.x.x, invariant@^2.2.0:
version "2.2.2"
resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360"
dependencies:
@@ -3031,14 +3033,14 @@ is-utf8@^0.2.0:
version "0.2.1"
resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72"
isarray@^1.0.0, isarray@~1.0.0, isarray@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
isarray@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf"
isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
isexe@^1.1.1:
version "1.1.2"
resolved "https://registry.yarnpkg.com/isexe/-/isexe-1.1.2.tgz#36f3e22e60750920f5e7241a476a8c6a42275ad0"
@@ -3345,7 +3347,7 @@ js-tokens@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-2.0.0.tgz#79903f5563ee778cc1162e6dcf1a0027c97f9cb5"
js-yaml@^3.4.3, js-yaml@^3.5.1, js-yaml@3.x:
js-yaml@3.x, js-yaml@^3.4.3, js-yaml@^3.5.1:
version "3.7.0"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.7.0.tgz#5c967ddd837a9bfdca5f2de84253abe8a1c03b80"
dependencies:
@@ -3484,7 +3486,7 @@ load-json-file@^1.0.0:
pinkie-promise "^2.0.0"
strip-bom "^2.0.0"
loader-utils@^0.2.11, loader-utils@^0.2.16, loader-utils@^0.2.7, loader-utils@~0.2.2, loader-utils@~0.2.5, loader-utils@0.2.x:
loader-utils@0.2.x, loader-utils@^0.2.11, loader-utils@^0.2.16, loader-utils@^0.2.7, loader-utils@~0.2.2, loader-utils@~0.2.5:
version "0.2.16"
resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-0.2.16.tgz#f08632066ed8282835dff88dfb52704765adee6d"
dependencies:
@@ -3675,7 +3677,7 @@ lodash.words@^3.0.0:
dependencies:
lodash._root "^3.0.0"
lodash@^4.0.0, lodash@^4.16.4, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0, lodash@^4.6.1, lodash@4.x.x:
lodash@4.x.x, lodash@^4.0.0, lodash@^4.16.4, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0, lodash@^4.6.1:
version "4.17.2"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.2.tgz#34a3055babe04ce42467b607d700072c7ff6bf42"
@@ -3812,21 +3814,21 @@ mime-types@^2.1.12, mime-types@~2.1.11, mime-types@~2.1.13, mime-types@~2.1.7:
dependencies:
mime-db "~1.25.0"
mime@^1.3.4, mime@1.3.4:
version "1.3.4"
resolved "https://registry.yarnpkg.com/mime/-/mime-1.3.4.tgz#115f9e3b6b3daf2959983cb38f149a2d40eb5d53"
mime@1.2.x:
version "1.2.11"
resolved "https://registry.yarnpkg.com/mime/-/mime-1.2.11.tgz#58203eed86e3a5ef17aed2b7d9ebd47f0a60dd10"
mime@1.3.4, mime@^1.3.4:
version "1.3.4"
resolved "https://registry.yarnpkg.com/mime/-/mime-1.3.4.tgz#115f9e3b6b3daf2959983cb38f149a2d40eb5d53"
min-document@^2.19.0:
version "2.19.0"
resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685"
dependencies:
dom-walk "^0.1.0"
minimatch@^3.0.0, minimatch@^3.0.2, "minimatch@2 || 3":
"minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.2:
version "3.0.3"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.3.tgz#2a4e4090b96b2db06a9d7df01055a62a77c9b774"
dependencies:
@@ -3838,19 +3840,15 @@ minimatch@2.x:
dependencies:
brace-expansion "^1.0.0"
minimist@0.0.8, minimist@~0.0.1:
version "0.0.8"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
minimist@~0.0.1:
version "0.0.10"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf"
minimist@0.0.8:
version "0.0.8"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
mkdirp@^0.5.0, mkdirp@^0.5.1, "mkdirp@>=0.5 0", mkdirp@~0.5.0, mkdirp@~0.5.1, mkdirp@0.5.x:
mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
dependencies:
@@ -4009,7 +4007,7 @@ nomnom@^1.8.1:
chalk "~0.4.0"
underscore "~1.6.0"
nopt@~3.0.6, nopt@3.x:
nopt@3.x, nopt@~3.0.6:
version "3.0.6"
resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9"
dependencies:
@@ -4130,7 +4128,7 @@ on-finished@~2.3.0:
dependencies:
ee-first "1.1.1"
once@^1.3.0, once@1.x:
once@1.x, once@^1.3.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
dependencies:
@@ -4625,26 +4623,26 @@ prr@~0.0.0:
version "0.0.0"
resolved "https://registry.yarnpkg.com/prr/-/prr-0.0.0.tgz#1a84b85908325501411853d0081ee3fa86e2926a"
punycode@^1.2.4, punycode@^1.4.1:
version "1.4.1"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
punycode@1.3.2:
version "1.3.2"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d"
punycode@^1.2.4, punycode@^1.4.1:
version "1.4.1"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
q@^1.1.2:
version "1.4.1"
resolved "https://registry.yarnpkg.com/q/-/q-1.4.1.tgz#55705bcd93c5f3673530c2c2cbc0c2b3addc286e"
qs@^6.1.0, qs@^6.2.0, qs@~6.3.0:
version "6.3.0"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.3.0.tgz#f403b264f23bc01228c74131b407f18d5ea5d442"
qs@6.2.0:
version "6.2.0"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.2.0.tgz#3b7848c03c2dece69a9522b0fae8c4126d745f3b"
qs@^6.1.0, qs@^6.2.0, qs@~6.3.0:
version "6.3.0"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.3.0.tgz#f403b264f23bc01228c74131b407f18d5ea5d442"
query-string@^4.1.0:
version "4.2.3"
resolved "https://registry.yarnpkg.com/query-string/-/query-string-4.2.3.tgz#9f27273d207a25a8ee4c7b8c74dcd45d556db822"
@@ -4656,7 +4654,7 @@ querystring-es3@~0.2.0:
version "0.2.1"
resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73"
querystring@^0.2.0, querystring@0.2.0:
querystring@0.2.0, querystring@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620"
@@ -4680,9 +4678,9 @@ rc@^1.0.1, rc@^1.1.6, rc@~1.1.6:
minimist "^1.2.0"
strip-json-comments "~1.0.4"
react-addons-test-utils@~15.3.2:
version "15.3.2"
resolved "https://registry.yarnpkg.com/react-addons-test-utils/-/react-addons-test-utils-15.3.2.tgz#c09a44f583425a4a9c1b38444d7a6c3e6f0f41f6"
react-addons-test-utils@~15.4.1:
version "15.4.1"
resolved "https://registry.yarnpkg.com/react-addons-test-utils/-/react-addons-test-utils-15.4.1.tgz#1e4caab151bf27cce26df5f9cb714f4fd8359ae1"
react-deep-force-update@^1.0.0:
version "1.0.1"
@@ -4700,9 +4698,13 @@ react-docgen@^2.12.1:
nomnom "^1.8.1"
recast "^0.11.5"
react-dom@~15.3.2:
version "15.3.2"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-15.3.2.tgz#c46b0aa5380d7b838e7a59c4a7beff2ed315531f"
react-dom@~15.4.1:
version "15.4.1"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-15.4.1.tgz#d54c913261aaedb17adc20410d029dcc18a1344a"
dependencies:
fbjs "^0.8.1"
loose-envify "^1.1.0"
object-assign "^4.1.0"
react-fuzzy@^0.3.3:
version "0.3.3"
@@ -4767,9 +4769,9 @@ react-stubber@^1.0.0:
dependencies:
babel-runtime "^6.5.0"
react-test-renderer@~15.3.2:
version "15.3.2"
resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-15.3.2.tgz#d8f083d37d2d41e97bbdc26a1dd9282f0baf7857"
react-test-renderer@~15.4.1:
version "15.4.1"
resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-15.4.1.tgz#e38cd7057868d4a655d3764689735b4b97260706"
react-textarea-autosize@^4.0.4:
version "4.0.5"
@@ -4786,9 +4788,9 @@ react-transform-hmr@^1.0.4:
global "^4.3.0"
react-proxy "^1.1.7"
react@~15.3.2:
version "15.3.2"
resolved "https://registry.yarnpkg.com/react/-/react-15.3.2.tgz#a7bccd2fee8af126b0317e222c28d1d54528d09e"
react@~15.4.1:
version "15.4.1"
resolved "https://registry.yarnpkg.com/react/-/react-15.4.1.tgz#498e918602677a3983cd0fd206dfe700389a0dd6"
dependencies:
fbjs "^0.8.4"
loose-envify "^1.1.0"
@@ -4825,30 +4827,7 @@ readable-stream@^1.0.27-1, readable-stream@^1.1.13:
isarray "0.0.1"
string_decoder "~0.10.x"
readable-stream@^2.0.0, "readable-stream@^2.0.0 || ^1.1.13", readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5:
version "2.2.2"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.2.tgz#a9e6fec3c7dda85f8bb1b3ba7028604556fc825e"
dependencies:
buffer-shims "^1.0.0"
core-util-is "~1.0.0"
inherits "~2.0.1"
isarray "~1.0.0"
process-nextick-args "~1.0.6"
string_decoder "~0.10.x"
util-deprecate "~1.0.1"
readable-stream@~2.0.0:
version "2.0.6"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.0.6.tgz#8f90341e68a53ccc928788dacfcd11b36eb9b78e"
dependencies:
core-util-is "~1.0.0"
inherits "~2.0.1"
isarray "~1.0.0"
process-nextick-args "~1.0.6"
string_decoder "~0.10.x"
util-deprecate "~1.0.1"
readable-stream@~2.1.4:
readable-stream@^2.0.0, "readable-stream@^2.0.0 || ^1.1.13", readable-stream@^2.0.5, readable-stream@~2.1.4:
version "2.1.5"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.1.5.tgz#66fa8b720e1438b364681f2ad1a63c618448c9d0"
dependencies:
@@ -4860,6 +4839,17 @@ readable-stream@~2.1.4:
string_decoder "~0.10.x"
util-deprecate "~1.0.1"
readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@~2.0.0:
version "2.0.6"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.0.6.tgz#8f90341e68a53ccc928788dacfcd11b36eb9b78e"
dependencies:
core-util-is "~1.0.0"
inherits "~2.0.1"
isarray "~1.0.0"
process-nextick-args "~1.0.6"
string_decoder "~0.10.x"
util-deprecate "~1.0.1"
readdirp@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78"
@@ -5043,7 +5033,7 @@ resolve-from@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226"
resolve@^1.1.6, resolve@1.1.7, resolve@1.1.x:
resolve@1.1.7, resolve@1.1.x, resolve@^1.1.6:
version "1.1.7"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b"
@@ -5060,7 +5050,7 @@ right-align@^0.1.1:
dependencies:
align-text "^0.1.1"
rimraf@^2.2.8, rimraf@^2.4.3, rimraf@^2.4.4, rimraf@~2.5.1, rimraf@~2.5.4, rimraf@2:
rimraf@2, rimraf@^2.2.8, rimraf@^2.4.3, rimraf@^2.4.4, rimraf@~2.5.1, rimraf@~2.5.4:
version "2.5.4"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.5.4.tgz#96800093cbf1a0c86bd95b4625467535c29dfa04"
dependencies:
@@ -5101,7 +5091,7 @@ semver-diff@^2.0.0:
dependencies:
semver "^5.0.3"
semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@~5.3.0, "semver@2 || 3 || 4 || 5":
"semver@2 || 3 || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@~5.3.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f"
@@ -5157,7 +5147,7 @@ sha.js@2.2.6:
version "2.2.6"
resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.2.6.tgz#17ddeddc5f722fb66501658895461977867315ba"
shallowequal@^0.2.2, shallowequal@0.2.x:
shallowequal@0.2.x, shallowequal@^0.2.2:
version "0.2.2"
resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-0.2.2.tgz#1e32fd5bcab6ad688a4812cb0cc04efc75c7014e"
dependencies:
@@ -5277,10 +5267,6 @@ strict-uri-encode@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713"
string_decoder@~0.10.25, string_decoder@~0.10.x:
version "0.10.31"
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94"
string-width@^1.0.1, string-width@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3"
@@ -5316,6 +5302,10 @@ string.prototype.padstart@^3.0.0:
es-abstract "^1.4.3"
function-bind "^1.0.2"
string_decoder@~0.10.25, string_decoder@~0.10.x:
version "0.10.31"
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94"
stringstream@~0.0.4:
version "0.0.5"
resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878"
@@ -5609,7 +5599,7 @@ util-deprecate@~1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
util@~0.10.3, util@0.10.3:
util@0.10.3, util@~0.10.3:
version "0.10.3"
resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9"
dependencies:
@@ -5784,13 +5774,17 @@ widest-line@^1.0.0:
dependencies:
string-width "^1.0.1"
window-size@0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d"
window-size@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.2.0.tgz#b4315bb4214a3d7058ebeee892e13fa24d98b075"
window-size@0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d"
wordwrap@0.0.2:
version "0.0.2"
resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f"
wordwrap@^1.0.0, wordwrap@~1.0.0:
version "1.0.0"
@@ -5800,10 +5794,6 @@ wordwrap@~0.0.2:
version "0.0.3"
resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107"
wordwrap@0.0.2:
version "0.0.2"
resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f"
worker-farm@^1.3.1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.3.1.tgz#4333112bb49b17aa050b87895ca6b2cacf40e5ff"
@@ -5845,7 +5835,7 @@ xdg-basedir@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-2.0.1.tgz#4d8b8f1eccd3419aa362061becef515e1e559635"
xtend@^4.0.0, "xtend@>=4.0.0 <4.1.0-0":
"xtend@>=4.0.0 <4.1.0-0", xtend@^4.0.0:
version "4.0.1"
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"
@@ -5887,4 +5877,3 @@ yargs@~3.10.0:
cliui "^2.1.0"
decamelize "^1.0.0"
window-size "0.1.0"