Compare commits

...
23 Commits
Author SHA1 Message Date
Konstantin Raev 515e15242c [0.24.1] Bump version numbers 2016-04-19 11:51:39 +01:00
Konstantin Raev 374307aa99 fixed bug in website deployment condition (face-palm.jpg) 2016-04-19 11:51:09 +01:00
James Ide 5150fa1071 [0.24.0] Bump version numbers 2016-04-18 17:28:36 -07:00
Konstantin RaevandJames Ide 62b46efe10 fixed immutable.js to be 3.7.x because 3.8.0 breaks flow checks
Summary: Closes https://github.com/facebook/react-native/pull/7014

Differential Revision: D3188876

fb-gh-sync-id: 800e1bf31dfd698a4aa076e64bf27b090b841e40
fbshipit-source-id: 800e1bf31dfd698a4aa076e64bf27b090b841e40
2016-04-18 17:28:36 -07:00
James Ide ab21e6baab [0.24.0-rc5] Bump version numbers 2016-04-13 00:20:41 -07:00
Janic DuplessisandJames Ide 03c1688ce6 Add null check before accessing the refresh control ref
Summary:Unmounting the RefreshControl during onRefresh callback causes the native ref to become null, this simply adds a null check to prevent the crash.
Closes https://github.com/facebook/react-native/pull/6931

Differential Revision: D3167637

fb-gh-sync-id: c2420b7a3b672d62dd349a6d35bb05399a00620c
fbshipit-source-id: c2420b7a3b672d62dd349a6d35bb05399a00620c
2016-04-13 00:20:16 -07:00
James Ide 48d6492448 [0.24.0-rc4] Bump version numbers 2016-04-11 12:25:46 -07:00
David AurelioandJames Ide ae799add4b Add support for missing XHR response types
Summary:Fixes #6679

This adds support for the missing response types to XMLHttpRequest.
Don?t ship this yet. This is completely untested. yolo and stuff.
Closes https://github.com/facebook/react-native/pull/6870

Reviewed By: bestander

Differential Revision: D3153628

Pulled By: davidaurelio

fb-gh-sync-id: 76feae3377bc24b931548a9ac1af07943b1048ac
fbshipit-source-id: 76feae3377bc24b931548a9ac1af07943b1048ac
2016-04-11 12:06:40 -07:00
James Ide 82c9924411 [0.24.0-rc3] Bump version numbers 2016-04-07 11:10:17 -07:00
Martin KonicekandJames Ide 3d8e2fe41e Remove confusing warning from ScrollResponder
Summary:I get this warning in cases when nothing went wrong.

Not sure what I can do about the warning. I placed a few sliders in a ScrollView and everything works as expected, so the warning is very confusing.

Lots of people have been hitting the warning and getting confused by it as well:
- https://github.com/facebook/react-native/issues/1501
- https://productpains.com/post/react-native/scrollview-warning-scrollview-doesnt-take-rejection-well-scrolls-anyway (it's one of the [highest rated](https://productpains.com/product/react-native?tab=top) issues).

Reviewed By: sahrens

Differential Revision: D3138736

fb-gh-sync-id: 601b8dfc275a14dff6f17a7903c65bd8347a73e9
fbshipit-source-id: 601b8dfc275a14dff6f17a7903c65bd8347a73e9
2016-04-07 11:08:50 -07:00
James Ide f933154185 Honor the version of "react" under peerDeps when setting up a new project
Summary:We need this since React 15.0.0 is coming and will break `react-native init`, which currently installs the latest version of React. We'll need some changes to React Native to support 15 that Sebastian is actively working on, but till that lands we want `react-native init` to continue working.
Closes https://github.com/facebook/react-native/pull/6846

Differential Revision: D3148182

Pulled By: sebmarkbage

fb-gh-sync-id: 3df5bc184c0b82d2c9c320c620256c7c8568d90b
fbshipit-source-id: 3df5bc184c0b82d2c9c320c620256c7c8568d90b
2016-04-07 11:08:36 -07:00
James Ide 30fcc7602b [0.24.0-rc2] Bump version numbers 2016-04-06 11:06:07 -07:00
Konstantin RaevandJames Ide 26c0d79c06 fixed flow error introduced with Sldier
Summary:cc mkonicek
Closes https://github.com/facebook/react-native/pull/6838

Differential Revision: D3144492

fb-gh-sync-id: 49eeb95fd2ccaa1b77905bd258b36f48c84463e4
fbshipit-source-id: 49eeb95fd2ccaa1b77905bd258b36f48c84463e4
2016-04-06 11:06:07 -07:00
Konstantin RaevandJames Ide d5fa599960 Fixed images required from node_modules
Summary:This fixes https://github.com/facebook/react-native/issues/6638 by resolving AssetRegistry relatively.
Closes https://github.com/facebook/react-native/pull/6822

Reviewed By: davidaurelio

Differential Revision: D3144463

Pulled By: bestander

fb-gh-sync-id: d3eeb24ae9e08a32f742c50ae5f0314fd33d1b6b
fbshipit-source-id: d3eeb24ae9e08a32f742c50ae5f0314fd33d1b6b
2016-04-06 10:57:48 -07:00
Martin BigioandJames Ide 78b66f046a Use ^ version for react-native preset
Summary:See https://github.com/facebook/react-native/issues/6798
Closes https://github.com/facebook/react-native/pull/6814

Differential Revision: D3138776

fb-gh-sync-id: f43404e7bfdf0e3e7c6df16681653d1dd4016e1a
fbshipit-source-id: f43404e7bfdf0e3e7c6df16681653d1dd4016e1a
2016-04-06 10:57:22 -07:00
Martin Konicek 013e715934 Fix website after open sourcing Slider
Reviewed By: bestander

Differential Revision: D3144673

fb-gh-sync-id: bdfc35606c29b227228474e5e6a9c0087898783d
fbshipit-source-id: bdfc35606c29b227228474e5e6a9c0087898783d
2016-04-06 16:52:15 +01:00
Martin Konicek afe78f6935 Open source Android slider
Reviewed By: bestander

Differential Revision: D3127200

fb-gh-sync-id: d3d51b312c2e32cc7a0f4c0bc084139343e97c3e
fbshipit-source-id: d3d51b312c2e32cc7a0f4c0bc084139343e97c3e
2016-04-06 16:50:10 +01:00
James Ide 917c0391ee [0.24.0-rc1] Bump version numbers 2016-04-05 11:32:13 -07:00
Nick LockwoodandJames Ide 6d25667654 Fix UIExplorer Image example on iOS
Reviewed By: javache

Differential Revision: D3138820

fb-gh-sync-id: 83bf3f6c60b80e9303b3c3a47dd5d05069623204
fbshipit-source-id: 83bf3f6c60b80e9303b3c3a47dd5d05069623204
2016-04-05 11:30:24 -07:00
Martin KralikandJames Ide 33dde47ab5 make RCTEventDispatcher dispatch events in incoming order
Reviewed By: javache

Differential Revision: D3138215

fb-gh-sync-id: 430b57d7bb8e3f0f90877b627bfd6a842719ba5d
fbshipit-source-id: 430b57d7bb8e3f0f90877b627bfd6a842719ba5d
2016-04-05 11:30:24 -07:00
Martin KralikandJames Ide c59475415c fixed coalescing key generation for RCTTouchEvent
Summary:Turns our using the same coalescing key until a person removes all fingers off screen is not ideal.
It doesn't work in a case where the first finger starts moving on screen and then a second finger joins it later (almost any pinch gesture),
since we would try to coalesce move events from the start when only one finger was touching screen with events where two fingers were moving on screen.
That doesn't work and results in a crash.

I've changed the logic for generating the coalescing key in order to prevent this.
We no longer have a single key for a single gesture, but we change the key each time amount of fingers increases ("touchStart") or decreases ("touchEnd").

Reviewed By: javache

Differential Revision: D3138275

fb-gh-sync-id: c32230ba401819fe3a70d1752b286d849520be89
fbshipit-source-id: c32230ba401819fe3a70d1752b286d849520be89
2016-04-05 11:30:24 -07:00
Janic DuplessisandJames Ide d457a18766 Fix HMR on Windows
Summary:Tested HMR on Windows and found 2 small issues related to paths that made it not work. Now it works nicely :)

**Test plan (required)**
Tested HMR in UIExplorer on Windows.
Closes https://github.com/facebook/react-native/pull/6678

Differential Revision: D3138379

fb-gh-sync-id: f27cd2fa21f95954685c8c6916d820f41bc187be
fbshipit-source-id: f27cd2fa21f95954685c8c6916d820f41bc187be
2016-04-05 11:30:24 -07:00
James Ide e8854b771e [0.24.0-rc] Bump version numbers 2016-04-04 12:39:23 -07:00
31 changed files with 1159 additions and 75 deletions
+13 -10
View File
@@ -25,6 +25,7 @@
var React = require('react-native');
var {
Image,
Platform,
StyleSheet,
Text,
View,
@@ -425,16 +426,18 @@ exports.examples = [
source={image}
/>
</View>
<View style={styles.leftMargin}>
<Text style={[styles.resizeModeText]}>
Center
</Text>
<Image
style={styles.resizeMode}
resizeMode={Image.resizeMode.center}
source={image}
/>
</View>
{ Platform.OS === 'android' ?
<View style={styles.leftMargin}>
<Text style={[styles.resizeModeText]}>
Center
</Text>
<Image
style={styles.resizeMode}
resizeMode={Image.resizeMode.center}
source={image}
/>
</View>
: null }
</View>
</View>
);
+169
View File
@@ -0,0 +1,169 @@
/**
* The examples provided by Facebook are for non-commercial testing and
* evaluation purposes only.
*
* Facebook reserves all rights not expressly granted.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* @flow
*/
'use strict';
var React = require('react-native');
var {
Slider,
Text,
StyleSheet,
View,
} = React;
var SliderExample = React.createClass({
getDefaultProps() {
return {
value: 0,
}
},
getInitialState() {
return {
value: this.props.value,
};
},
render() {
return (
<View>
<Text style={styles.text} >
{this.state.value && +this.state.value.toFixed(3)}
</Text>
<Slider
{...this.props}
onValueChange={(value) => this.setState({value: value})} />
</View>
);
}
});
var SlidingCompleteExample = React.createClass({
getInitialState() {
return {
slideCompletionValue: 0,
slideCompletionCount: 0,
};
},
render() {
return (
<View>
<SliderExample
{...this.props}
onSlidingComplete={(value) => this.setState({
slideCompletionValue: value,
slideCompletionCount: this.state.slideCompletionCount + 1})} />
<Text>
Completions: {this.state.slideCompletionCount} Value: {this.state.slideCompletionValue}
</Text>
</View>
);
}
});
var styles = StyleSheet.create({
slider: {
height: 10,
margin: 10,
},
text: {
fontSize: 14,
textAlign: 'center',
fontWeight: '500',
margin: 10,
},
});
exports.title = '<Slider>';
exports.displayName = 'SliderExample';
exports.description = 'Slider input for numeric values';
exports.examples = [
{
title: 'Default settings',
render(): ReactElement {
return <SliderExample />;
}
},
{
title: 'Initial value: 0.5',
render(): ReactElement {
return <SliderExample value={0.5} />;
}
},
{
title: 'minimumValue: -1, maximumValue: 2',
render(): ReactElement {
return (
<SliderExample
minimumValue={-1}
maximumValue={2}
/>
);
}
},
{
title: 'step: 0.25',
render(): ReactElement {
return <SliderExample step={0.25} />;
}
},
{
title: 'onSlidingComplete',
render(): ReactElement {
return (
<SlidingCompleteExample />
);
}
},
{
title: 'Custom min/max track tint color',
platform: 'ios',
render(): ReactElement {
return (
<SliderExample
minimumTrackTintColor={'red'}
maximumTrackTintColor={'green'}
/>
);
}
},
{
title: 'Custom thumb image',
platform: 'ios',
render(): ReactElement {
return <SliderExample thumbImage={require('./uie_thumb_big.png')} />;
}
},
{
title: 'Custom track image',
platform: 'ios',
render(): ReactElement {
return <SliderExample trackImage={require('./slider.png')} />;
}
},
{
title: 'Custom min/max track image',
platform: 'ios',
render(): ReactElement {
return (
<SliderExample
minimumTrackImage={require('./slider-left.png')}
maximumTrackImage={require('./slider-right.png')}
/>
);
}
},
];
@@ -23,6 +23,10 @@ export type UIExplorerExample = {
};
var ComponentExamples: Array<UIExplorerExample> = [
{
key: 'SliderExample',
module: require('./SliderExample'),
},
{
key: 'ImageExample',
module: require('./ImageExample'),
+4 -4
View File
@@ -50,8 +50,8 @@ var ComponentExamples: Array<UIExplorerExample> = [
module: require('./ListViewPagingExample'),
},
{
key: 'MapViewExample',
module: require('./MapViewExample'),
key: 'MapViewExample',
module: require('./MapViewExample'),
},
{
key: 'ModalExample',
@@ -90,8 +90,8 @@ var ComponentExamples: Array<UIExplorerExample> = [
module: require('./SegmentedControlIOSExample'),
},
{
key: 'SliderIOSExample',
module: require('./SliderIOSExample'),
key: 'SliderExample',
module: require('./SliderExample'),
},
{
key: 'StatusBarExample',
@@ -133,7 +133,10 @@ const RefreshControl = React.createClass({
_onRefresh() {
this.props.onRefresh && this.props.onRefresh();
this._nativeRef.setNativeProps({refreshing: this.props.refreshing});
if (this._nativeRef) {
this._nativeRef.setNativeProps({refreshing: this.props.refreshing});
}
},
});
-1
View File
@@ -202,7 +202,6 @@ var ScrollResponderMixin = {
* a touch has already started.
*/
scrollResponderHandleResponderReject: function() {
warning(false, "ScrollView doesn't take rejection well - scrolls anyway");
},
/**
+194
View File
@@ -0,0 +1,194 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule Slider
* @flow
*/
'use strict';
var Image = require('Image');
var NativeMethodsMixin = require('NativeMethodsMixin');
var Platform = require('Platform');
var PropTypes = require('ReactPropTypes');
var React = require('React');
var StyleSheet = require('StyleSheet');
var View = require('View');
var requireNativeComponent = require('requireNativeComponent');
type Event = Object;
/**
* A component used to select a single value from a range of values.
*/
var Slider = React.createClass({
mixins: [NativeMethodsMixin],
propTypes: {
...View.propTypes,
/**
* Used to style and layout the `Slider`. See `StyleSheet.js` and
* `ViewStylePropTypes.js` for more info.
*/
style: View.propTypes.style,
/**
* Initial value of the slider. The value should be between minimumValue
* and maximumValue, which default to 0 and 1 respectively.
* Default value is 0.
*
* *This is not a controlled component*, you don't need to update the
* value during dragging.
*/
value: PropTypes.number,
/**
* Step value of the slider. The value should be
* between 0 and (maximumValue - minimumValue).
* Default value is 0.
*/
step: PropTypes.number,
/**
* Initial minimum value of the slider. Default value is 0.
*/
minimumValue: PropTypes.number,
/**
* Initial maximum value of the slider. Default value is 1.
*/
maximumValue: PropTypes.number,
/**
* The color used for the track to the left of the button. Overrides the
* default blue gradient image.
* @platform ios
*/
minimumTrackTintColor: PropTypes.string,
/**
* The color used for the track to the right of the button. Overrides the
* default blue gradient image.
* @platform ios
*/
maximumTrackTintColor: PropTypes.string,
/**
* If true the user won't be able to move the slider.
* Default value is false.
*/
disabled: PropTypes.bool,
/**
* Assigns a single image for the track. Only static images are supported.
* The center pixel of the image will be stretched to fill the track.
* @platform ios
*/
trackImage: Image.propTypes.source,
/**
* Assigns a minimum track image. Only static images are supported. The
* rightmost pixel of the image will be stretched to fill the track.
* @platform ios
*/
minimumTrackImage: Image.propTypes.source,
/**
* Assigns a maximum track image. Only static images are supported. The
* leftmost pixel of the image will be stretched to fill the track.
* @platform ios
*/
maximumTrackImage: Image.propTypes.source,
/**
* Sets an image for the thumb. Only static images are supported.
* @platform ios
*/
thumbImage: Image.propTypes.source,
/**
* Callback continuously called while the user is dragging the slider.
*/
onValueChange: PropTypes.func,
/**
* Callback called when the user finishes changing the value (e.g. when
* the slider is released).
*/
onSlidingComplete: PropTypes.func,
/**
* Used to locate this view in UI automation tests.
*/
testID: PropTypes.string,
},
getDefaultProps: function() : any {
return {
disabled: false,
value: 0,
minimumValue: 0,
maximumValue: 1,
step: 0
};
},
render: function() {
let {style, onValueChange, onSlidingComplete, ...props} = this.props;
props.style = [styles.slider, style];
props.onValueChange = onValueChange && ((event: Event) => {
let userEvent = true;
if (Platform.OS === 'android') {
// On Android there's a special flag telling us the user is
// dragging the slider.
userEvent = event.nativeEvent.fromUser;
}
onValueChange && userEvent && onValueChange(event.nativeEvent.value);
});
props.onChange = props.onValueChange;
props.onSlidingComplete = onSlidingComplete && ((event: Event) => {
onSlidingComplete && onSlidingComplete(event.nativeEvent.value);
});
return <RCTSlider
{...props}
enabled={!this.props.disabled}
onStartShouldSetResponder={() => true}
onResponderTerminationRequest={() => false}
/>;
}
});
let styles;
if (Platform.OS === 'ios') {
styles = StyleSheet.create({
slider: {
height: 40,
},
});
} else {
styles = StyleSheet.create({
slider: {},
});
}
let options = {};
if (Platform.OS === 'android') {
options = {
nativeOnly: {
enabled: true,
}
};
}
const RCTSlider = requireNativeComponent('RCTSlider', Slider, options);
module.exports = Slider;
@@ -22,6 +22,12 @@ var requireNativeComponent = require('requireNativeComponent');
type Event = Object;
/**
* **Note:** SliderIOS is deprecated and will be removed in the future. Use the cross-platform
* Slider as a drop-in replacement with the same API.
*
* An iOS-specific component used to select a single value from a range of values.
*/
var SliderIOS = React.createClass({
mixins: [NativeMethodsMixin],
@@ -120,6 +126,11 @@ var SliderIOS = React.createClass({
},
render: function() {
console.warn(
'SliderIOS is deprecated and will be removed in ' +
'future versions of React Native. Use the cross-platform Slider ' +
'as a drop-in replacement.');
let {style, onValueChange, onSlidingComplete, ...props} = this.props;
props.style = [styles.slider, style];
+126 -27
View File
@@ -13,7 +13,12 @@
var RCTNetworking = require('RCTNetworking');
var RCTDeviceEventEmitter = require('RCTDeviceEventEmitter');
var invariant = require('fbjs/lib/invariant');
const invariant = require('fbjs/lib/invariant');
const utf8 = require('utf8');
const warning = require('fbjs/lib/warning');
type ResponseType = '' | 'arraybuffer' | 'blob' | 'document' | 'json' | 'text';
type Response = ?Object | string;
const UNSENT = 0;
const OPENED = 1;
@@ -21,6 +26,15 @@ const HEADERS_RECEIVED = 2;
const LOADING = 3;
const DONE = 4;
const SUPPORTED_RESPONSE_TYPES = {
arraybuffer: typeof global.ArrayBuffer === 'function',
blob: typeof global.Blob === 'function',
document: false,
json: true,
text: true,
'': true,
};
/**
* Shared base for platform-specific XMLHttpRequest implementations.
*/
@@ -43,9 +57,7 @@ class XMLHttpRequestBase {
upload: any;
readyState: number;
responseHeaders: ?Object;
responseText: ?string;
response: ?string;
responseType: '' | 'text';
responseText: string;
status: number;
timeout: number;
responseURL: ?string;
@@ -57,12 +69,16 @@ class XMLHttpRequestBase {
_requestId: ?number;
_subscriptions: [any];
_method: ?string;
_url: ?string;
_headers: Object;
_sent: boolean;
_aborted: boolean;
_cachedResponse: Response;
_hasError: boolean;
_headers: Object;
_lowerCaseResponseHeaders: Object;
_method: ?string;
_response: string | ?Object;
_responseType: ResponseType;
_sent: boolean;
_url: ?string;
constructor() {
this.UNSENT = UNSENT;
@@ -82,24 +98,101 @@ class XMLHttpRequestBase {
this._aborted = false;
}
_reset() {
_reset(): void {
this.readyState = this.UNSENT;
this.responseHeaders = undefined;
this.responseText = '';
this.response = null;
this.responseType = '';
this.status = 0;
delete this.responseURL;
this._requestId = null;
this._cachedResponse = undefined;
this._hasError = false;
this._headers = {};
this._responseType = '';
this._sent = false;
this._lowerCaseResponseHeaders = {};
this._clearSubscriptions();
}
// $FlowIssue #10784535
get responseType(): ResponseType {
return this._responseType;
}
// $FlowIssue #10784535
set responseType(responseType: ResponseType): void {
if (this.readyState > HEADERS_RECEIVED) {
throw new Error(
"Failed to set the 'responseType' property on 'XMLHttpRequest': The " +
"response type cannot be set if the object's state is LOADING or DONE"
);
}
if (!SUPPORTED_RESPONSE_TYPES.hasOwnProperty(responseType)) {
warning(
`The provided value '${responseType}' is not a valid 'responseType'.`);
return;
}
// redboxes early, e.g. for 'arraybuffer' on ios 7
invariant(
SUPPORTED_RESPONSE_TYPES[responseType] || responseType === 'document',
`The provided value '${responseType}' is unsupported in this environment.`
);
this._responseType = responseType;
}
// $FlowIssue #10784535
get response(): Response {
const {responseType} = this;
if (responseType === '' || responseType === 'text') {
return this.readyState < LOADING || this._hasError
? ''
: this.responseText;
}
if (this.readyState !== DONE) {
return null;
}
if (this._cachedResponse !== undefined) {
return this._cachedResponse;
}
switch (this.responseType) {
case 'document':
this._cachedResponse = null;
break;
case 'arraybuffer':
this._cachedResponse = toArrayBuffer(
this.responseText, this.getResponseHeader('content-type') || '');
break;
case 'blob':
this._cachedResponse = new global.Blob(
[this.responseText],
{type: this.getResponseHeader('content-type') || ''}
);
break;
case 'json':
try {
this._cachedResponse = JSON.parse(this.responseText);
} catch (_) {
this._cachedResponse = null;
}
break;
default:
this._cachedResponse = null;
}
return this._cachedResponse;
}
didCreateRequest(requestId: number): void {
this._requestId = requestId;
this._subscriptions.push(RCTDeviceEventEmitter.addListener(
@@ -151,22 +244,7 @@ class XMLHttpRequestBase {
} else {
this.responseText += responseText;
}
switch(this.responseType) {
case '':
case 'text':
this.response = this.responseText;
break;
case 'blob': // whatwg-fetch sets this in Chrome
/* global Blob: true */
invariant(
typeof Blob === 'function',
`responseType "blob" is only supported on platforms with native Blob support`
);
this.response = new Blob([this.responseText]);
break;
default: //TODO: Support other types, eg: document, arraybuffer, json
invariant(false, `responseType "${this.responseType}" is unsupported`);
}
this._cachedResponse = undefined; // force lazy recomputation
this.setReadyState(this.LOADING);
}
}
@@ -175,6 +253,7 @@ class XMLHttpRequestBase {
if (requestId === this._requestId) {
if (error) {
this.responseText = error;
this._hasError = true;
}
this._clearSubscriptions();
this._requestId = null;
@@ -304,4 +383,24 @@ XMLHttpRequestBase.HEADERS_RECEIVED = HEADERS_RECEIVED;
XMLHttpRequestBase.LOADING = LOADING;
XMLHttpRequestBase.DONE = DONE;
function toArrayBuffer(text: string, contentType: string): ArrayBuffer {
const {length} = text;
if (length === 0) {
return new ArrayBuffer(0);
}
const charsetMatch = contentType.match(/;\s*charset=([^;]*)/i);
const charset = charsetMatch ? charsetMatch[1].trim() : 'utf-8';
if (/^utf-?8$/i.test(charset)) {
return utf8.encode(text);
} else { //TODO: utf16 / ucs2 / utf32
const array = new Uint8Array(length);
for (let i = 0; i < length; i++) {
array[i] = text.charCodeAt(i); // Uint8Array automatically masks with 0xff
}
return array.buffer;
}
}
module.exports = XMLHttpRequestBase;
@@ -0,0 +1,63 @@
/**
* Copyright (c) 2016-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
'use strict';
jest.autoMockOff();
const {encode} = require('../utf8');
describe('UTF-8 encoding:', () => {
it('can encode code points < U+80', () => {
const arrayBuffer = encode('\u0000abcDEF\u007f');
expect(new Uint8Array(arrayBuffer)).toEqual(
new Uint8Array([0x00, 0x61, 0x62, 0x63, 0x44, 0x45, 0x46, 0x7f]));
});
it('can encode code points < U+800', () => {
const arrayBuffer = encode('\u0080\u0548\u07ff');
expect(new Uint8Array(arrayBuffer)).toEqual(
new Uint8Array([0xc2, 0x80, 0xd5, 0x88, 0xdf, 0xbf]));
});
it('can encode code points < U+10000', () => {
const arrayBuffer = encode('\u0800\uac48\uffff');
expect(new Uint8Array(arrayBuffer)).toEqual(
new Uint8Array([0xe0, 0xa0, 0x80, 0xea, 0xb1, 0x88, 0xef, 0xbf, 0xbf]));
});
it('can encode code points in the Supplementary Planes (surrogate pairs)', () => {
const arrayBuffer = encode([
'\ud800\udc00',
'\ud800\ude89',
'\ud83d\ude3b',
'\udbff\udfff'
].join(''));
expect(new Uint8Array(arrayBuffer)).toEqual(
new Uint8Array([
0xf0, 0x90, 0x80, 0x80,
0xf0, 0x90, 0x8a, 0x89,
0xf0, 0x9f, 0x98, 0xbb,
0xf4, 0x8f, 0xbf, 0xbf,
])
);
});
it('allows for stray high surrogates', () => {
const arrayBuffer = encode('a\ud8c6b');
expect(new Uint8Array(arrayBuffer)).toEqual(
new Uint8Array([0x61, 0xed, 0xa3, 0x86, 0x62]));
});
it('allows for stray low surrogates', () => {
const arrayBuffer = encode('a\ude19b');
expect(new Uint8Array(arrayBuffer)).toEqual(
new Uint8Array([0x61, 0xed, 0xb8, 0x99, 0x62]));
});
});
+91
View File
@@ -0,0 +1,91 @@
/**
* Copyright (c) 2016-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule utf8
* @flow
*/
'use strict';
class ByteVector {
_storage: Uint8Array;
_sizeWritten: number;
constructor(size) {
this._storage = new Uint8Array(size);
this._sizeWritten = 0;
}
push(value: number): ByteVector {
const i = this._sizeWritten;
if (i === this._storage.length) {
this._realloc();
}
this._storage[i] = value;
this._sizeWritten = i + 1;
return this;
}
getBuffer(): ArrayBuffer {
return this._storage.buffer.slice(0, this._sizeWritten);
}
_realloc() {
const storage = this._storage;
this._storage = new Uint8Array(align(storage.length * 1.5));
this._storage.set(storage);
}
}
/*eslint-disable no-bitwise */
exports.encode = (string: string): ArrayBuffer => {
const {length} = string;
const bytes = new ByteVector(length);
// each character / char code is assumed to represent an UTF-16 wchar.
// With the notable exception of surrogate pairs, each wchar represents the
// corresponding unicode code point.
// For an explanation of UTF-8 encoding, read [1]
// For an explanation of UTF-16 surrogate pairs, read [2]
//
// [1] https://en.wikipedia.org/wiki/UTF-8#Description
// [2] https://en.wikipedia.org/wiki/UTF-16#U.2B10000_to_U.2B10FFFF
let nextCodePoint = string.charCodeAt(0);
for (let i = 0; i < length; i++) {
let codePoint = nextCodePoint;
nextCodePoint = string.charCodeAt(i + 1);
if (codePoint < 0x80) {
bytes.push(codePoint);
} else if (codePoint < 0x800) {
bytes
.push(0xc0 | codePoint >>> 6)
.push(0x80 | codePoint & 0x3f);
} else if (codePoint >>> 10 === 0x36 && nextCodePoint >>> 10 === 0x37) { // high surrogate & low surrogate
codePoint = 0x10000 + (((codePoint & 0x3ff) << 10) | (nextCodePoint & 0x3ff));
bytes
.push(0xf0 | codePoint >>> 18 & 0x7)
.push(0x80 | codePoint >>> 12 & 0x3f)
.push(0x80 | codePoint >>> 6 & 0x3f)
.push(0x80 | codePoint & 0x3f);
i += 1;
nextCodePoint = string.charCodeAt(i + 1);
} else {
bytes
.push(0xe0 | codePoint >>> 12)
.push(0x80 | codePoint >>> 6 & 0x3f)
.push(0x80 | codePoint & 0x3f);
}
}
return bytes.getBuffer();
};
// align to multiples of 8 bytes
function align(size: number): number {
return size % 8 ? (Math.floor(size / 8) + 1) << 3 : size;
}
+1
View File
@@ -31,6 +31,7 @@ var ReactNative = {
get ProgressViewIOS() { return require('ProgressViewIOS'); },
get ScrollView() { return require('ScrollView'); },
get SegmentedControlIOS() { return require('SegmentedControlIOS'); },
get Slider() { return require('Slider'); },
get SliderIOS() { return require('SliderIOS'); },
get SnapshotViewIOS() { return require('SnapshotViewIOS'); },
get Switch() { return require('Switch'); },
@@ -44,6 +44,7 @@ var ReactNative = Object.assign(Object.create(require('react')), {
ScrollView: require('ScrollView'),
SegmentedControlIOS: require('SegmentedControlIOS'),
SliderIOS: require('SliderIOS'),
Slider: require('Slider'),
SnapshotViewIOS: require('SnapshotViewIOS'),
StatusBar: require('StatusBar'),
Switch: require('Switch'),
+1 -1
View File
@@ -4,7 +4,7 @@ package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
Pod::Spec.new do |s|
s.name = "React"
s.version = package['version']
s.version = "0.24.1"
s.summary = package['description']
s.description = <<-DESC
React Native apps are built using the React JS
+17 -9
View File
@@ -39,9 +39,12 @@ static NSNumber *RCTGetEventID(id<RCTEvent> event)
@implementation RCTEventDispatcher
{
// We need this lock to protect access to _eventQueue and __eventsDispatchScheduled. It's filled in on main thread and consumed on js thread.
// We need this lock to protect access to _events, _eventQueue and _eventsDispatchScheduled. It's filled in on main thread and consumed on js thread.
NSLock *_eventQueueLock;
NSMutableDictionary *_eventQueue;
// We have this id -> event mapping so we coalesce effectively.
NSMutableDictionary<NSNumber *, id<RCTEvent>> *_events;
// This array contains ids of events in order they come in, so we can emit them to JS in the exact same order.
NSMutableArray<NSNumber *> *_eventQueue;
BOOL _eventsDispatchScheduled;
}
@@ -52,7 +55,8 @@ RCT_EXPORT_MODULE()
- (void)setBridge:(RCTBridge *)bridge
{
_bridge = bridge;
_eventQueue = [NSMutableDictionary new];
_events = [NSMutableDictionary new];
_eventQueue = [NSMutableArray new];
_eventQueueLock = [NSLock new];
_eventsDispatchScheduled = NO;
}
@@ -131,12 +135,14 @@ RCT_EXPORT_MODULE()
NSNumber *eventID = RCTGetEventID(event);
id<RCTEvent> previousEvent = _eventQueue[eventID];
id<RCTEvent> previousEvent = _events[eventID];
if (previousEvent) {
RCTAssert([event canCoalesce], @"Got event %@ which cannot be coalesced, but has the same eventID %@ as the previous event %@", event, eventID, previousEvent);
event = [previousEvent coalesceWithEvent:event];
} else {
[_eventQueue addObject:eventID];
}
_eventQueue[eventID] = event;
_events[eventID] = event;
BOOL scheduleEventsDispatch = NO;
if (!_eventsDispatchScheduled) {
@@ -170,13 +176,15 @@ RCT_EXPORT_MODULE()
- (void)flushEventsQueue
{
[_eventQueueLock lock];
NSDictionary *eventQueue = _eventQueue;
_eventQueue = [NSMutableDictionary new];
NSDictionary *events = _events;
_events = [NSMutableDictionary new];
NSMutableArray *eventQueue = _eventQueue;
_eventQueue = [NSMutableArray new];
_eventsDispatchScheduled = NO;
[_eventQueueLock unlock];
for (id<RCTEvent> event in eventQueue.allValues) {
[self dispatchEvent:event];
for (NSNumber *eventId in eventQueue) {
[self dispatchEvent:events[eventId]];
}
}
+2 -1
View File
@@ -234,7 +234,6 @@ static BOOL RCTAnyTouchesChanged(NSSet<UITouch *> *touches)
{
// If gesture just recognized, send all touches to JS as if they just began.
if (self.state == UIGestureRecognizerStateBegan) {
_coalescingKey++;
[self _updateAndDispatchTouches:_nativeTouches.set eventName:@"topTouchStart" originatingTime:0];
// We store this flag separately from `state` because after a gesture is
@@ -253,6 +252,7 @@ static BOOL RCTAnyTouchesChanged(NSSet<UITouch *> *touches)
{
[super touchesBegan:touches withEvent:event];
_coalescingKey++;
// "start" has to record new touches before extracting the event.
// "end"/"cancel" needs to remove the touch *after* extracting the event.
[self _recordNewTouches:touches];
@@ -278,6 +278,7 @@ static BOOL RCTAnyTouchesChanged(NSSet<UITouch *> *touches)
{
[super touchesEnded:touches withEvent:event];
_coalescingKey++;
if (_dispatchedInitialTouches) {
[self _updateAndDispatchTouches:touches eventName:@"touchEnd" originatingTime:event.timestamp];
+1 -1
View File
@@ -1,4 +1,4 @@
VERSION_NAME=0.0.1-master
VERSION_NAME=0.24.1
GROUP=com.facebook.react
POM_NAME=ReactNative
@@ -17,6 +17,7 @@ android_library(
react_native_target('java/com/facebook/react/views/progressbar:progressbar'),
react_native_target('java/com/facebook/react/views/recyclerview:recyclerview'),
react_native_target('java/com/facebook/react/views/scroll:scroll'),
react_native_target('java/com/facebook/react/views/slider:slider'),
react_native_target('java/com/facebook/react/views/swiperefresh:swiperefresh'),
react_native_target('java/com/facebook/react/views/switchview:switchview'),
react_native_target('java/com/facebook/react/views/text:text'),
@@ -47,6 +47,7 @@ import com.facebook.react.views.progressbar.ReactProgressBarViewManager;
import com.facebook.react.views.recyclerview.RecyclerViewBackedScrollViewManager;
import com.facebook.react.views.scroll.ReactHorizontalScrollViewManager;
import com.facebook.react.views.scroll.ReactScrollViewManager;
import com.facebook.react.views.slider.ReactSliderManager;
import com.facebook.react.views.swiperefresh.SwipeRefreshLayoutManager;
import com.facebook.react.views.switchview.ReactSwitchManager;
import com.facebook.react.views.text.ReactRawTextManager;
@@ -109,6 +110,7 @@ public class MainReactPackage implements ReactPackage {
new ReactProgressBarViewManager(),
new ReactRawTextManager(),
new ReactScrollViewManager(),
new ReactSliderManager(),
new ReactSwitchManager(),
new FrescoBasedReactTextInlineImageViewManager(),
new ReactTextInputManager(),
@@ -0,0 +1,23 @@
include_defs('//ReactAndroid/DEFS')
android_library(
name = 'slider',
srcs = glob(['*.java']),
deps = [
react_native_target('java/com/facebook/react/bridge:bridge'),
react_native_target('java/com/facebook/react/common:common'),
react_native_target('java/com/facebook/csslayout:csslayout'),
react_native_target('java/com/facebook/react/uimanager:uimanager'),
react_native_target('java/com/facebook/react/uimanager/annotations:annotations'),
react_native_dep('android_res/android/support/v7/appcompat-orig:res-for-react-native'),
react_native_dep('third-party/android/support/v7/appcompat-orig:appcompat'),
react_native_dep('third-party/java/jsr-305:jsr-305'),
],
visibility = [
'PUBLIC',
],
)
project_config(
src_target = ':slider',
)
@@ -0,0 +1,111 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package com.facebook.react.views.slider;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.SeekBar;
import javax.annotation.Nullable;
/**
* Slider that behaves more like the iOS one, for consistency.
*
* On iOS, the value is 0..1. Android SeekBar only supports integer values.
* For consistency, we pretend in JS that the value is 0..1 but set the
* SeekBar value to 0..100.
*
* Note that the slider is _not_ a controlled component (setValue isn't called
* during dragging).
*/
public class ReactSlider extends SeekBar {
/**
* If step is 0 (unset) we default to this total number of steps.
* Don't use 100 which leads to rounding errors (0.200000000001).
*/
private static int DEFAULT_TOTAL_STEPS = 128;
/**
* We want custom min..max range.
* Android only supports 0..max range so we implement this ourselves.
*/
private double mMinValue = 0;
private double mMaxValue = 0;
/**
* Value sent from JS (setState).
* Doesn't get updated during drag (slider is not a controlled component).
*/
private double mValue = 0;
/**
* If zero it's determined automatically.
*/
private double mStep = 0;
public ReactSlider(Context context, @Nullable AttributeSet attrs, int style) {
super(context, attrs, style);
}
/* package */ void setMaxValue(double max) {
mMaxValue = max;
updateAll();
}
/* package */ void setMinValue(double min) {
mMinValue = min;
updateAll();
}
/* package */ void setValue(double value) {
mValue = value;
updateValue();
}
/* package */ void setStep(double step) {
mStep = step;
updateAll();
}
/**
* Convert SeekBar's native progress value (e.g. 0..100) to a value
* passed to JS (e.g. -1.0..2.5).
*/
public double toRealProgress(int seekBarProgress) {
if (seekBarProgress == getMax()) {
return mMaxValue;
}
return seekBarProgress * mStep + mMinValue;
}
/**
* Update underlying native SeekBar's values.
*/
private void updateAll() {
if (mStep == 0) {
mStep = (mMaxValue - mMinValue) / (double) DEFAULT_TOTAL_STEPS;
}
setMax(getTotalSteps());
updateValue();
}
/**
* Update value only (optimization in case only value is set).
*/
private void updateValue() {
setProgress((int) Math.round(
(mValue - mMinValue) / (mMaxValue - mMinValue) * getTotalSteps()));
}
private int getTotalSteps() {
return (int) Math.ceil((mMaxValue - mMinValue) / mStep);
}
}
@@ -0,0 +1,63 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package com.facebook.react.views.slider;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.uimanager.events.Event;
import com.facebook.react.uimanager.events.RCTEventEmitter;
/**
* Event emitted by a ReactSliderManager when user changes slider position.
*/
public class ReactSliderEvent extends Event<ReactSliderEvent> {
public static final String EVENT_NAME = "topChange";
private final double mValue;
private final boolean mFromUser;
public ReactSliderEvent(int viewId, long timestampMs, double value, boolean fromUser) {
super(viewId, timestampMs);
mValue = value;
mFromUser = fromUser;
}
public double getValue() {
return mValue;
}
public boolean isFromUser() {
return mFromUser;
}
@Override
public String getEventName() {
return EVENT_NAME;
}
@Override
public short getCoalescingKey() {
return 0;
}
@Override
public void dispatch(RCTEventEmitter rctEventEmitter) {
rctEventEmitter.receiveEvent(getViewTag(), getEventName(), serializeEventData());
}
private WritableMap serializeEventData() {
WritableMap eventData = Arguments.createMap();
eventData.putInt("target", getViewTag());
eventData.putDouble("value", getValue());
eventData.putBoolean("fromUser", isFromUser());
return eventData;
}
}
@@ -0,0 +1,155 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package com.facebook.react.views.slider;
import java.util.Map;
import android.view.View;
import android.view.ViewGroup;
import android.widget.SeekBar;
import com.facebook.csslayout.CSSNode;
import com.facebook.csslayout.MeasureOutput;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.common.MapBuilder;
import com.facebook.react.common.SystemClock;
import com.facebook.react.uimanager.LayoutShadowNode;
import com.facebook.react.uimanager.SimpleViewManager;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.UIManagerModule;
import com.facebook.react.uimanager.ViewProps;
import com.facebook.react.uimanager.annotations.ReactProp;
/**
* Manages instances of {@code ReactSlider}.
*
* Note that the slider is _not_ a controlled component.
*/
public class ReactSliderManager extends SimpleViewManager<ReactSlider> {
private static final int STYLE = android.R.attr.seekBarStyle;
private static final String REACT_CLASS = "RCTSlider";
static class ReactSliderShadowNode extends LayoutShadowNode implements
CSSNode.MeasureFunction {
private int mWidth;
private int mHeight;
private boolean mMeasured;
private ReactSliderShadowNode() {
setMeasureFunction(this);
}
@Override
public void measure(CSSNode node, float width, float height, MeasureOutput measureOutput) {
if (!mMeasured) {
SeekBar reactSlider = new ReactSlider(getThemedContext(), null, STYLE);
final int spec = View.MeasureSpec.makeMeasureSpec(
ViewGroup.LayoutParams.WRAP_CONTENT,
View.MeasureSpec.UNSPECIFIED);
reactSlider.measure(spec, spec);
mWidth = reactSlider.getMeasuredWidth();
mHeight = reactSlider.getMeasuredHeight();
mMeasured = true;
}
measureOutput.width = mWidth;
measureOutput.height = mHeight;
}
}
private static final SeekBar.OnSeekBarChangeListener ON_CHANGE_LISTENER =
new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekbar, int progress, boolean fromUser) {
ReactContext reactContext = (ReactContext) seekbar.getContext();
reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher().dispatchEvent(
new ReactSliderEvent(
seekbar.getId(),
SystemClock.nanoTime(),
((ReactSlider)seekbar).toRealProgress(progress),
fromUser));
}
@Override
public void onStartTrackingTouch(SeekBar seekbar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekbar) {
ReactContext reactContext = (ReactContext) seekbar.getContext();
reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher().dispatchEvent(
new ReactSlidingCompleteEvent(
seekbar.getId(),
SystemClock.nanoTime(),
((ReactSlider)seekbar).toRealProgress(seekbar.getProgress())));
}
};
@Override
public String getName() {
return REACT_CLASS;
}
@Override
public LayoutShadowNode createShadowNodeInstance() {
return new ReactSliderShadowNode();
}
@Override
public Class getShadowNodeClass() {
return ReactSliderShadowNode.class;
}
@Override
protected ReactSlider createViewInstance(ThemedReactContext context) {
return new ReactSlider(context, null, STYLE);
}
@ReactProp(name = ViewProps.ENABLED, defaultBoolean = true)
public void setEnabled(ReactSlider view, boolean enabled) {
view.setEnabled(enabled);
}
@ReactProp(name = "value", defaultDouble = 0d)
public void setValue(ReactSlider view, double value) {
view.setOnSeekBarChangeListener(null);
view.setValue(value);
view.setOnSeekBarChangeListener(ON_CHANGE_LISTENER);
}
@ReactProp(name = "minimumValue", defaultDouble = 0d)
public void setMinimumValue(ReactSlider view, double value) {
view.setMinValue(value);
}
@ReactProp(name = "maximumValue", defaultDouble = 1d)
public void setMaximumValue(ReactSlider view, double value) {
view.setMaxValue(value);
}
@ReactProp(name = "step", defaultDouble = 0d)
public void setStep(ReactSlider view, double value) {
view.setStep(value);
}
@Override
protected void addEventEmitters(final ThemedReactContext reactContext, final ReactSlider view) {
view.setOnSeekBarChangeListener(ON_CHANGE_LISTENER);
}
@Override
public Map getExportedCustomDirectEventTypeConstants() {
return MapBuilder.of(
ReactSlidingCompleteEvent.EVENT_NAME,
MapBuilder.of("registrationName", "onSlidingComplete"));
}
}
@@ -0,0 +1,62 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package com.facebook.react.views.slider;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.uimanager.events.Event;
import com.facebook.react.uimanager.events.RCTEventEmitter;
/**
* Event emitted when the user finishes dragging the slider.
*/
public class ReactSlidingCompleteEvent extends Event<ReactSlidingCompleteEvent> {
public static final String EVENT_NAME = "topSlidingComplete";
private final double mValue;
public ReactSlidingCompleteEvent(int viewId, long timestampMs, double value) {
super(viewId, timestampMs);
mValue = value;
}
public double getValue() {
return mValue;
}
@Override
public String getEventName() {
return EVENT_NAME;
}
@Override
public short getCoalescingKey() {
return 0;
}
@Override
public boolean canCoalesce() {
return false;
}
@Override
public void dispatch(RCTEventEmitter rctEventEmitter) {
rctEventEmitter.receiveEvent(getViewTag(), getEventName(), serializeEventData());
}
private WritableMap serializeEventData() {
WritableMap eventData = Arguments.createMap();
eventData.putInt("target", getViewTag());
eventData.putDouble("value", getValue());
return eventData;
}
}
+6
View File
@@ -18,6 +18,12 @@ module.exports = function(options, filename) {
var transform = filename
? './' + path.relative(path.dirname(filename), transformPath) // packager can't handle absolute paths
: hmrTransform;
// Fix the module path to use '/' on Windows.
if (path.sep === '\\') {
transform = transform.replace(/\\/g, '/');
}
return {
plugins: resolvePlugins([
[
+12 -1
View File
@@ -96,6 +96,17 @@ module.exports = yeoman.generators.NamedBase.extend({
return;
}
this.npmInstall('react', { '--save': true });
var reactNativePackageJson = require('../../package.json');
var { peerDependencies } = reactNativePackageJson;
if (!peerDependencies) {
return;
}
var reactVersion = peerDependencies.react;
if (!reactVersion) {
return;
}
this.npmInstall(`react@${reactVersion}`, { '--save': true });
}
});
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "react-native",
"version": "1000.0.0",
"version": "0.24.1",
"description": "A framework for building native apps using React",
"license": "BSD-3-Clause",
"repository": {
@@ -134,7 +134,7 @@
"babel-core": "^6.6.4",
"babel-plugin-external-helpers": "^6.5.0",
"babel-polyfill": "^6.6.1",
"babel-preset-react-native": "1.5.2",
"babel-preset-react-native": "^1.5.2",
"babel-register": "^6.6.0",
"babel-types": "^6.6.4",
"babylon": "^6.6.4",
@@ -148,7 +148,7 @@
"fbjs-scripts": "^0.4.0",
"graceful-fs": "^4.1.2",
"image-size": "^0.3.5",
"immutable": "^3.7.5",
"immutable": "~3.7.6",
"joi": "^6.6.1",
"json-stable-stringify": "^1.0.1",
"json5": "^0.4.0",
@@ -157,7 +157,7 @@
"mkdirp": "^0.5.1",
"module-deps": "^3.9.1",
"node-fetch": "^1.3.3",
"node-haste": "~2.9.4",
"node-haste": "~2.9.6",
"opn": "^3.0.2",
"optimist": "^0.6.1",
"progress": "^1.1.8",
@@ -190,4 +190,4 @@
"react": "^0.14.5",
"shelljs": "0.6.0"
}
}
}
+14 -12
View File
@@ -189,23 +189,24 @@ class Bundler {
);
}
_hmrURL(prefix, platform, extensionOverride, path) {
const matchingRoot = this._projectRoots.find(root => path.startsWith(root));
_hmrURL(prefix, platform, extensionOverride, filePath) {
const matchingRoot = this._projectRoots.find(root => filePath.startsWith(root));
if (!matchingRoot) {
throw new Error('No matching project root for ', path);
throw new Error('No matching project root for ', filePath);
}
const extensionStart = path.lastIndexOf('.');
let resource = path.substring(
// Replaces '\' with '/' for Windows paths.
if (path.sep === '\\') {
filePath = filePath.replace(/\\/g, '/');
}
const extensionStart = filePath.lastIndexOf('.');
let resource = filePath.substring(
matchingRoot.length,
extensionStart !== -1 ? extensionStart : undefined,
);
const extension = extensionStart !== -1
? path.substring(extensionStart + 1)
: null;
return (
prefix + resource +
'.' + extensionOverride + '?' +
@@ -611,10 +612,11 @@ class Bundler {
};
const json = JSON.stringify(asset);
const assetRegistryPath = 'react-native/Libraries/Image/AssetRegistry';
const code =
`module.exports = require('AssetRegistry').registerAsset(${json});`;
const dependencies = ['AssetRegistry'];
const dependencyOffsets = [code.indexOf('AssetRegistry') - 1];
`module.exports = require(${JSON.stringify(assetRegistryPath)}).registerAsset(${json});`;
const dependencies = [assetRegistryPath];
const dependencyOffsets = [code.indexOf(assetRegistryPath) - 1];
return {
asset,
+1 -1
View File
@@ -107,7 +107,7 @@ class Resolver {
cache: opts.cache,
shouldThrowOnUnresolvedErrors: (_, platform) => platform === 'ios',
transformCode: opts.transformCode,
assetDependencies: ['AssetRegistry'],
assetDependencies: ['react-native/Libraries/Image/AssetRegistry'],
});
this._getModuleId = options.getModuleId;
+1 -1
View File
@@ -96,7 +96,7 @@ if (!CI_PULL_REQUEST && CIRCLE_PROJECT_USERNAME === `facebook`) {
if (currentCommit === latestTagCommit) {
echo(`------------ DEPLOYING latest`);
// leave only releases and blog folder
rm(`-rf`, ls(`*`).filter(name => (name !== 'releases') || (name !== 'blog')));
rm(`-rf`, ls(`*`).filter(name => (name !== 'releases') && (name !== 'blog')));
cd(`../..`);
if (exec(`RN_VERSION=${version} RN_LATEST_VERSION=${latestVersion} \
RN_AVAILABLE_DOCS_VERSIONS=${versions} node server/generate.js`).code !== 0) {
+1
View File
@@ -209,6 +209,7 @@ var components = [
'../Libraries/Components/RefreshControl/RefreshControl.js',
'../Libraries/Components/ScrollView/ScrollView.js',
'../Libraries/Components/SegmentedControlIOS/SegmentedControlIOS.ios.js',
'../Libraries/Components/Slider/Slider.js',
'../Libraries/Components/SliderIOS/SliderIOS.ios.js',
'../Libraries/Components/StatusBar/StatusBar.js',
'../Libraries/Components/Switch/Switch.js',