Merge pull request #1610 from sahrens/Updates_Fri_Jun_12

Updates fri jun 12
This commit is contained in:
Spencer Ahrens 2015-06-12 14:54:18 -07:00
Родитель 78db5ca1b9 3b40124024
Коммит 1120769f1b
58 изменённых файлов: 837 добавлений и 285 удалений

Просмотреть файл

@ -36,5 +36,12 @@ Examples/UIExplorer/ImageMocks.js
[options]
module.system=haste
suppress_type=$FlowIssue
suppress_type=$FlowFixMe
suppress_type=$FixMe
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue #[0-9]+
[version]
0.11.0
0.12.0

Просмотреть файл

@ -34,11 +34,14 @@ var MovieCell = React.createClass({
var criticsScore = this.props.movie.ratings.critics_score;
return (
<View>
<TouchableHighlight
<TouchableHighlight
onPress={this.props.onSelect}
onShowUnderlay={this.props.onHighlight}
onHideUnderlay={this.props.onUnhighlight}>
<View style={styles.row}>
{/* $FlowIssue #7363964 - There's a bug in Flow where you cannot
* omit a property or set it to undefined if it's inside a shape,
* even if it isn't required */}
<Image
source={getImageSource(this.props.movie, 'det')}
style={styles.cellImage}

Просмотреть файл

@ -34,6 +34,9 @@ var MovieScreen = React.createClass({
return (
<ScrollView contentContainerStyle={styles.contentContainer}>
<View style={styles.mainSection}>
{/* $FlowIssue #7363964 - There's a bug in Flow where you cannot
* omit a property or set it to undefined if it's inside a shape,
* even if it isn't required */}
<Image
source={getImageSource(this.props.movie, 'det')}
style={styles.detailsImage}

Просмотреть файл

@ -33,4 +33,4 @@ node_modules/react-native/Libraries/react-native/react-native-interface.js
module.system=haste
[version]
0.11.0
0.12.0

Просмотреть файл

@ -118,6 +118,17 @@ var Cell = React.createClass({
}
},
imageStyle() {
switch (this.props.player) {
case 1:
return styles.imageX;
case 2:
return styles.imageO;
default:
return {};
}
},
textContents() {
switch (this.props.player) {
case 1:
@ -147,7 +158,7 @@ var Cell = React.createClass({
underlayColor="transparent"
activeOpacity={0.5}>
<View style={[styles.cell, this.cellStyle()]}>
<Image source={{uri: this.imageContents()}} />
<Image source={{uri: this.imageContents()}} style={this.imageStyle()}/>
</View>
</TouchableHighlight>
);
@ -293,6 +304,17 @@ var styles = StyleSheet.create({
color: '#b9dc2f',
},
// CELL IMAGE
imageX: {
width: 34,
height: 42,
},
imageO: {
width: 45,
height: 41,
},
// GAME OVER
overlay: {

Просмотреть файл

@ -55,7 +55,7 @@ var AccessibilityIOSExample = React.createClass({
},
});
exports.title = 'AcccessibilityIOS';
exports.title = 'AccessibilityIOS';
exports.description = 'Interface to show iOS\' accessibility samples';
exports.examples = [
{

Просмотреть файл

@ -16,26 +16,36 @@
'use strict';
declare module 'image!story-background' {
/* $FlowIssue #7387208 - There's a flow bug preventing this type from flowing
* into a proptype shape */
declare var uri: string;
declare var isStatic: boolean;
}
declare module 'image!uie_comment_highlighted' {
/* $FlowIssue #7387208 - There's a flow bug preventing this type from flowing
* into a proptype shape */
declare var uri: string;
declare var isStatic: boolean;
}
declare module 'image!uie_comment_normal' {
/* $FlowIssue #7387208 - There's a flow bug preventing this type from flowing
* into a proptype shape */
declare var uri: string;
declare var isStatic: boolean;
}
declare module 'image!uie_thumb_normal' {
/* $FlowIssue #7387208 - There's a flow bug preventing this type from flowing
* into a proptype shape */
declare var uri: string;
declare var isStatic: boolean;
}
declare module 'image!uie_thumb_selected' {
/* $FlowIssue #7387208 - There's a flow bug preventing this type from flowing
* into a proptype shape */
declare var uri: string;
declare var isStatic: boolean;
}

Просмотреть файл

@ -163,8 +163,8 @@ var MapViewExample = React.createClass({
style={styles.map}
onRegionChange={this._onRegionChange}
onRegionChangeComplete={this._onRegionChangeComplete}
region={this.state.mapRegion}
annotations={this.state.annotations}
region={this.state.mapRegion || undefined}
annotations={this.state.annotations || undefined}
/>
<MapRegionInput
onChange={this._onRegionInputChanged}

Просмотреть файл

@ -45,6 +45,7 @@
14D6D7281B2222EF001FB087 /* libRCTWebSocket.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139FDED91B0651EA00C62182 /* libRCTWebSocket.a */; };
14D6D7291B2222EF001FB087 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 14AADF041AC3DB95002390C9 /* libReact.a */; };
14DC67F41AB71881001358AB /* libRCTPushNotification.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 14DC67F11AB71876001358AB /* libRCTPushNotification.a */; };
3578590A1B28D2CF00341EDB /* libRCTLinking.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 357859011B28D2C500341EDB /* libRCTLinking.a */; };
834C36EC1AF8DED70019C93C /* libRCTSettings.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 834C36D21AF8DA610019C93C /* libRCTSettings.a */; };
D85B829E1AB6D5D7003F4FE2 /* libRCTVibration.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D85B829C1AB6D5CE003F4FE2 /* libRCTVibration.a */; };
/* End PBXBuildFile section */
@ -120,6 +121,13 @@
remoteGlobalIDString = 134814201AA4EA6300B7C361;
remoteInfo = RCTPushNotification;
};
357859001B28D2C500341EDB /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 357858F81B28D2C400341EDB /* RCTLinking.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 134814201AA4EA6300B7C361;
remoteInfo = RCTLinking;
};
58005BED1ABA80530062E044 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 58005BE41ABA80530062E044 /* RCTTest.xcodeproj */;
@ -192,6 +200,7 @@
14D6D7101B220EB3001FB087 /* libOCMock.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libOCMock.a; sourceTree = "<group>"; };
14DC67E71AB71876001358AB /* RCTPushNotification.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTPushNotification.xcodeproj; path = ../../Libraries/PushNotificationIOS/RCTPushNotification.xcodeproj; sourceTree = "<group>"; };
14E0EEC81AB118F7000DECC3 /* RCTActionSheet.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTActionSheet.xcodeproj; path = ../../Libraries/ActionSheetIOS/RCTActionSheet.xcodeproj; sourceTree = "<group>"; };
357858F81B28D2C400341EDB /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = ../../Libraries/LinkingIOS/RCTLinking.xcodeproj; sourceTree = "<group>"; };
58005BE41ABA80530062E044 /* RCTTest.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTTest.xcodeproj; path = ../../Libraries/RCTTest/RCTTest.xcodeproj; sourceTree = "<group>"; };
D85B82911AB6D5CE003F4FE2 /* RCTVibration.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTVibration.xcodeproj; path = ../../Libraries/Vibration/RCTVibration.xcodeproj; sourceTree = "<group>"; };
/* End PBXFileReference section */
@ -226,6 +235,7 @@
134454601AAFCABD003F0779 /* libRCTAdSupport.a in Frameworks */,
134A8A2A1AACED7A00945AAE /* libRCTGeolocation.a in Frameworks */,
13417FE91AA91432003F314A /* libRCTImage.a in Frameworks */,
3578590A1B28D2CF00341EDB /* libRCTLinking.a in Frameworks */,
1341802C1AA9178B003F314A /* libRCTNetwork.a in Frameworks */,
14DC67F41AB71881001358AB /* libRCTPushNotification.a in Frameworks */,
834C36EC1AF8DED70019C93C /* libRCTSettings.a in Frameworks */,
@ -255,6 +265,7 @@
134454551AAFCAAE003F0779 /* RCTAdSupport.xcodeproj */,
134A8A201AACED6A00945AAE /* RCTGeolocation.xcodeproj */,
13417FE31AA91428003F314A /* RCTImage.xcodeproj */,
357858F81B28D2C400341EDB /* RCTLinking.xcodeproj */,
134180261AA91779003F314A /* RCTNetwork.xcodeproj */,
13CC9D481AEED2B90020D1C2 /* RCTSettings.xcodeproj */,
58005BE41ABA80530062E044 /* RCTTest.xcodeproj */,
@ -432,6 +443,14 @@
name = Products;
sourceTree = "<group>";
};
357858F91B28D2C400341EDB /* Products */ = {
isa = PBXGroup;
children = (
357859011B28D2C500341EDB /* libRCTLinking.a */,
);
name = Products;
sourceTree = "<group>";
};
58005BE51ABA80530062E044 /* Products */ = {
isa = PBXGroup;
children = (
@ -581,6 +600,10 @@
ProductGroup = 13417FE41AA91428003F314A /* Products */;
ProjectRef = 13417FE31AA91428003F314A /* RCTImage.xcodeproj */;
},
{
ProductGroup = 357858F91B28D2C400341EDB /* Products */;
ProjectRef = 357858F81B28D2C400341EDB /* RCTLinking.xcodeproj */;
},
{
ProductGroup = 134180271AA91779003F314A /* Products */;
ProjectRef = 134180261AA91779003F314A /* RCTNetwork.xcodeproj */;
@ -687,6 +710,13 @@
remoteRef = 14DC67F01AB71876001358AB /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
357859011B28D2C500341EDB /* libRCTLinking.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libRCTLinking.a;
remoteRef = 357859001B28D2C500341EDB /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
58005BEE1ABA80530062E044 /* libRCTTest.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;

Просмотреть файл

@ -37,9 +37,9 @@ var UIExplorerPage = React.createClass({
var ContentWrapper;
var wrapperProps = {};
if (this.props.noScroll) {
ContentWrapper = View;
ContentWrapper = (View: ReactClass<any, any, any>);
} else {
ContentWrapper = ScrollView;
ContentWrapper = (ScrollView: ReactClass<any, any, any>);
wrapperProps.keyboardShouldPersistTaps = true;
wrapperProps.keyboardDismissMode = 'interactive';
}

Просмотреть файл

@ -57,7 +57,7 @@ static uint64_t _get_time_nanoseconds(void)
JSContextGroupRef group = JSContextGroupCreate();
JSGlobalContextRef context = JSGlobalContextCreateInGroup(group, NULL);
id message = @[@[@1, @2, @3, @4], @[@{@"a": @1}, @{@"b": @2}], [NSNull null]];
id message = @[@[@1, @2, @3, @4], @[@{@"a": @1}, @{@"b": @2}], (id)kCFNull];
NSString *code = RCTJSONStringify(message, NULL);
JSStringRef script = JSStringCreateWithCFString((__bridge CFStringRef)code);
JSValueRef error = NULL;

Просмотреть файл

@ -28,7 +28,7 @@ TEST_PATH(name, _input, [[[NSBundle mainBundle] bundlePath] stringByAppendingPat
// Basic tests
TEST_URL(basic, @"http://example.com", @"http://example.com")
TEST_URL(null, [NSNull null], nil)
TEST_URL(null, (id)kCFNull, nil)
// Local files
TEST_PATH(fileURL, @"file:///blah/hello.jsbundle", @"/blah/hello.jsbundle")

Просмотреть файл

@ -17,11 +17,17 @@
var React = require('react-native');
var {
AlertIOS,
CameraRoll,
Image,
LinkingIOS,
PixelRatio,
ProgressViewIOS,
StyleSheet,
View,
Text,
TextInput,
TouchableHighlight,
View,
} = React;
class Downloader extends React.Component {
@ -109,6 +115,182 @@ class Downloader extends React.Component {
}
}
var PAGE_SIZE = 20;
class FormUploader extends React.Component {
_isMounted: boolean;
_fetchRandomPhoto: () => void;
_addTextParam: () => void;
_upload: () => void;
constructor(props) {
super(props);
this.state = {
isUploading: false,
randomPhoto: null,
textParams: [],
};
this._isMounted = true;
this._fetchRandomPhoto = this._fetchRandomPhoto.bind(this);
this._addTextParam = this._addTextParam.bind(this);
this._upload = this._upload.bind(this);
this._fetchRandomPhoto();
}
_fetchRandomPhoto() {
CameraRoll.getPhotos(
{first: PAGE_SIZE},
(data) => {
console.log('isMounted', this._isMounted);
if (!this._isMounted) {
return;
}
var edges = data.edges;
var edge = edges[Math.floor(Math.random() * edges.length)];
var randomPhoto = edge && edge.node && edge.node.image;
if (randomPhoto) {
this.setState({randomPhoto});
}
},
(error) => undefined
);
}
_addTextParam() {
var textParams = this.state.textParams;
textParams.push({name: '', value: ''});
this.setState({textParams});
}
componentWillUnmount() {
this._isMounted = false;
}
_onTextParamNameChange(index, text) {
var textParams = this.state.textParams;
textParams[index].name = text;
this.setState({textParams});
}
_onTextParamValueChange(index, text) {
var textParams = this.state.textParams;
textParams[index].value = text;
this.setState({textParams});
}
_upload() {
var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://posttestserver.com/post.php');
xhr.onload = () => {
this.setState({isUploading: false});
if (xhr.status !== 200) {
AlertIOS.alert(
'Upload failed',
'Expected HTTP 200 OK response, got ' + xhr.status
);
return;
}
if (!xhr.responseText) {
AlertIOS.alert(
'Upload failed',
'No response payload.'
);
return;
}
var index = xhr.responseText.indexOf('http://www.posttestserver.com/');
if (index === -1) {
AlertIOS.alert(
'Upload failed',
'Invalid response payload.'
);
return;
}
var url = xhr.responseText.slice(index).split('\n')[0];
LinkingIOS.openURL(url);
};
var formdata = new FormData();
if (this.state.randomPhoto) {
formdata.append('image', {...this.state.randomPhoto, name: 'image.jpg'});
}
this.state.textParams.forEach(
(param) => formdata.append(param.name, param.value)
);
xhr.send(formdata);
this.setState({isUploading: true});
}
render() {
var image = null;
if (this.state.randomPhoto) {
image = (
<Image
source={this.state.randomPhoto}
style={styles.randomPhoto}
/>
);
}
var textItems = this.state.textParams.map((item, index) => (
<View style={styles.paramRow}>
<TextInput
autoCapitalize="none"
autoCorrect={false}
onChangeText={this._onTextParamNameChange.bind(this, index)}
placeholder="name..."
style={styles.textInput}
/>
<Text style={styles.equalSign}>=</Text>
<TextInput
autoCapitalize="none"
autoCorrect={false}
onChangeText={this._onTextParamValueChange.bind(this, index)}
placeholder="value..."
style={styles.textInput}
/>
</View>
));
var uploadButtonLabel = this.state.isUploading ? 'Uploading...' : 'Upload';
var uploadButton = (
<View style={styles.uploadButtonBox}>
<Text style={styles.uploadButtonLabel}>{uploadButtonLabel}</Text>
</View>
);
if (!this.state.isUploading) {
uploadButton = (
<TouchableHighlight onPress={this._upload}>
{uploadButton}
</TouchableHighlight>
);
}
return (
<View>
<View style={[styles.paramRow, styles.photoRow]}>
<Text style={styles.photoLabel}>
Random photo from your library
(<Text style={styles.textButton} onPress={this._fetchRandomPhoto}>
update
</Text>)
</Text>
{image}
</View>
{textItems}
<View>
<Text
style={[styles.textButton, styles.addTextParamButton]}
onPress={this._addTextParam}>
Add a text param
</Text>
</View>
<View style={styles.uploadButton}>
{uploadButton}
</View>
</View>
);
}
}
exports.framework = 'React';
exports.title = 'XMLHttpRequest';
exports.description = 'XMLHttpRequest';
@ -117,6 +299,11 @@ exports.examples = [{
render() {
return <Downloader/>;
}
}, {
title: 'multipart/form-data Upload',
render() {
return <FormUploader/>;
}
}];
var styles = StyleSheet.create({
@ -126,6 +313,52 @@ var styles = StyleSheet.create({
},
button: {
backgroundColor: '#eeeeee',
padding: 10,
padding: 8,
},
paramRow: {
flexDirection: 'row',
paddingVertical: 8,
alignItems: 'center',
borderBottomWidth: 1 / PixelRatio.get(),
borderBottomColor: 'grey',
},
photoLabel: {
flex: 1,
},
randomPhoto: {
width: 50,
height: 50,
},
textButton: {
color: 'blue',
},
addTextParamButton: {
marginTop: 8,
},
textInput: {
flex: 1,
borderRadius: 3,
borderColor: 'grey',
borderWidth: 1,
height: 30,
paddingLeft: 8,
},
equalSign: {
paddingHorizontal: 4,
},
uploadButton: {
marginTop: 16,
},
uploadButtonBox: {
flex: 1,
paddingVertical: 12,
alignItems: 'center',
backgroundColor: 'blue',
borderRadius: 4,
},
uploadButtonLabel: {
color: 'white',
fontSize: 16,
fontWeight: '500',
},
});

Просмотреть файл

@ -10,6 +10,7 @@
#import "RCTActionSheetManager.h"
#import "RCTLog.h"
#import "RCTUtils.h"
@interface RCTActionSheetManager () <UIActionSheetDelegate>
@ -90,7 +91,7 @@ RCT_EXPORT_METHOD(showShareActionSheetWithOptions:(NSDictionary *)options
if (activityError) {
failureCallback(@[[activityError localizedDescription]]);
} else {
successCallback(@[@(completed), (activityType ?: [NSNull null])]);
successCallback(@[@(completed), RCTNullIfNil(activityType)]);
}
};
} else {
@ -100,7 +101,7 @@ RCT_EXPORT_METHOD(showShareActionSheetWithOptions:(NSDictionary *)options
if (![UIActivityViewController instancesRespondToSelector:@selector(completionWithItemsHandler)]) {
// Legacy iOS 7 implementation
share.completionHandler = ^(NSString *activityType, BOOL completed) {
successCallback(@[@(completed), (activityType ?: [NSNull null])]);
successCallback(@[@(completed), RCTNullIfNil(activityType)]);
};
} else
@ -109,7 +110,7 @@ RCT_EXPORT_METHOD(showShareActionSheetWithOptions:(NSDictionary *)options
{
// iOS 8 version
share.completionWithItemsHandler = ^(NSString *activityType, BOOL completed, NSArray *returnedItems, NSError *activityError) {
successCallback(@[@(completed), (activityType ?: [NSNull null])]);
successCallback(@[@(completed), RCTNullIfNil(activityType)]);
};
}
}

Просмотреть файл

@ -122,7 +122,11 @@ var AppStateIOS = {
_eventHandlers[type].delete(handler);
},
currentState: (null : ?String),
// TODO: getCurrentAppState callback seems to be called at a really late stage
// after app launch. Trying to get currentState when mounting App component
// will likely to have the initial value here.
// Initialize to 'active' instead of null.
currentState: ('active' : ?string),
};

Просмотреть файл

@ -82,6 +82,19 @@ var MapView = React.createClass({
*/
scrollEnabled: React.PropTypes.bool,
/**
* The map type to be displayed.
*
* - standard: standard road map (default)
* - satellite: satellite view
* - hybrid: satellite view with roads and points of interest overlayed
*/
mapType: React.PropTypes.oneOf([
'standard',
'satellite',
'hybrid',
]),
/**
* The region to be displayed by the map.
*

Просмотреть файл

@ -83,16 +83,16 @@ var NavigatorTransitionerIOS = React.createClass({
type Route = {
component: Function;
title: string;
passProps: Object;
backButtonTitle: string;
backButtonIcon: Object;
leftButtonTitle: string;
leftButtonIcon: Object;
onLeftButtonPress: Function;
rightButtonTitle: string;
rightButtonIcon: Object;
onRightButtonPress: Function;
wrapperStyle: any;
passProps?: Object;
backButtonTitle?: string;
backButtonIcon?: Object;
leftButtonTitle?: string;
leftButtonIcon?: Object;
onLeftButtonPress?: Function;
rightButtonTitle?: string;
rightButtonIcon?: Object;
onRightButtonPress?: Function;
wrapperStyle?: any;
};
type State = {

Просмотреть файл

@ -200,6 +200,16 @@ var ScrollView = React.createClass({
this.refs[SCROLLVIEW].setNativeProps(props);
},
/**
* Returns a reference to the underlying scroll responder, which supports
* operations like `scrollTo`. All ScrollView-like components should
* implement this method so that they can be composed while providing access
* to the underlying scroll responder's methods.
*/
getScrollResponder: function(): ReactComponent {
return this;
},
getInnerViewNode: function(): any {
return React.findNodeHandle(this.refs[INNERVIEW]);
},
@ -299,7 +309,7 @@ var ScrollView = React.createClass({
onResponderRelease: this.scrollResponderHandleResponderRelease,
onResponderReject: this.scrollResponderHandleResponderReject,
};
var ScrollViewClass;
if (Platform.OS === 'ios') {
ScrollViewClass = RCTScrollView;

Просмотреть файл

@ -43,6 +43,11 @@ var WebView = React.createClass({
startInLoadingState: PropTypes.bool, // force WebView to show loadingView on first load
style: View.propTypes.style,
javaScriptEnabledAndroid: PropTypes.bool,
/**
* Sets the user-agent for this WebView. The user-agent can also be set in native through
* WebViewConfig, but this can and will overwrite that config.
*/
userAgent: PropTypes.string,
/**
* Used to locate this view in end-to-end tests.
*/
@ -91,6 +96,7 @@ var WebView = React.createClass({
key="webViewKey"
style={webViewStyles}
url={this.props.url}
userAgent={this.props.userAgent}
javaScriptEnabledAndroid={this.props.javaScriptEnabledAndroid}
contentInset={this.props.contentInset}
automaticallyAdjustContentInsets={this.props.automaticallyAdjustContentInsets}
@ -172,6 +178,7 @@ var RCTWebView = createReactNativeComponentClass({
validAttributes: merge(ReactNativeViewAttributes.UIView, {
url: true,
javaScriptEnabledAndroid: true,
userAgent: true,
}),
uiViewClassName: 'RCTWebView',
});

Просмотреть файл

@ -313,14 +313,14 @@ var FromTheFrontAndroid = {
opacity: {
from: 0,
to: 1,
min: 0,
min: 0.5,
max: 1,
type: 'linear',
extrapolate: false,
round: 100,
},
transformTranslate: {
from: {x: 0, y: 50, z: 0},
from: {x: 0, y: 100, z: 0},
to: {x: 0, y: 0, z: 0},
min: 0,
max: 1,
@ -329,7 +329,7 @@ var FromTheFrontAndroid = {
round: PixelRatio.get(),
},
translateY: {
from: 50,
from: 100,
to: 0,
min: 0,
max: 1,
@ -432,6 +432,8 @@ var NavigatorSceneConfigs = {
FloatFromBottomAndroid: {
...BaseConfig,
gestures: null,
defaultTransitionVelocity: 3,
springFriction: 20,
animationInterpolators: {
into: buildStyleInterpolator(FromTheFrontAndroid),
out: buildStyleInterpolator(ToTheBackAndroid),

Просмотреть файл

@ -22,7 +22,7 @@
#import "RCTLog.h"
#import "RCTUtils.h"
static void RCTDispatchCallbackOnMainQueue(void (^ __nonnull callback)(NSError *, id), NSError *error, UIImage *image)
static void RCTDispatchCallbackOnMainQueue(void (^callback)(NSError *, id), NSError *error, UIImage *image)
{
if ([NSThread isMainThread]) {
callback(error, image);

Просмотреть файл

@ -11,15 +11,15 @@
*/
'use strict';
var BoxInspector = require('BoxInspector');
var PropTypes = require('ReactPropTypes');
var React = require('React');
var StyleInspector = require('StyleInspector');
var StyleSheet = require('StyleSheet');
var Text = require('Text');
var View = require('View');
var PropTypes = require('ReactPropTypes');
var BoxInspector = require('BoxInspector');
var StyleInspector = require('StyleInspector');
var TouchableHighlight = require('TouchableHighlight');
var TouchableWithoutFeedback = require('TouchableWithoutFeedback');
var View = require('View');
var flattenStyle = require('flattenStyle');
var mapWithSeparator = require('mapWithSeparator');
@ -93,7 +93,6 @@ var styles = StyleSheet.create({
justifyContent: 'space-between',
},
info: {
backgroundColor: 'rgba(0, 0, 0, 0.7)',
padding: 10,
},
path: {

Просмотреть файл

@ -0,0 +1,115 @@
/**
* 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 Inspector
* @flow
*/
'use strict';
var Dimensions = require('Dimensions');
var InspectorOverlay = require('InspectorOverlay');
var InspectorPanel = require('InspectorPanel');
var InspectorUtils = require('InspectorUtils');
var React = require('React');
var StyleSheet = require('StyleSheet');
var UIManager = require('NativeModules').UIManager;
var View = require('View');
class Inspector extends React.Component {
constructor(props: Object) {
super(props);
this.state = {
panelPos: 'bottom',
inspecting: true,
inspected: null,
};
}
setSelection(i: number) {
var instance = this.state.hierarchy[i];
var publicInstance = instance.getPublicInstance();
UIManager.measure(React.findNodeHandle(instance), (x, y, width, height, left, top) => {
this.setState({
inspected: {
frame: {left, top, width, height},
style: publicInstance.props ? publicInstance.props.style : {},
},
selection: i,
});
});
}
onTouchInstance(instance: Object, frame: Object, pointerY: number) {
var hierarchy = InspectorUtils.getOwnerHierarchy(instance);
var publicInstance = instance.getPublicInstance();
var props = publicInstance.props || {};
this.setState({
panelPos: pointerY > Dimensions.get('window').height / 2 ? 'top' : 'bottom',
selection: hierarchy.length - 1,
hierarchy,
inspected: {
style: props.style || {},
frame,
},
});
}
setInspecting(val: bool) {
this.setState({
inspecting: val,
});
}
render() {
var panelPosition;
if (this.state.panelPos === 'bottom') {
panelPosition = {bottom: -Dimensions.get('window').height};
} else {
panelPosition = {top: 0};
}
return (
<View style={styles.container}>
{this.state.inspecting &&
<InspectorOverlay
rootTag={this.props.rootTag}
inspected={this.state.inspected}
inspectedViewTag={this.props.inspectedViewTag}
onTouchInstance={this.onTouchInstance.bind(this)}
/>}
<View style={[styles.panelContainer, panelPosition]}>
<InspectorPanel
inspecting={this.state.inspecting}
setInspecting={this.setInspecting.bind(this)}
inspected={this.state.inspected}
hierarchy={this.state.hierarchy}
selection={this.state.selection}
setSelection={this.setSelection.bind(this)}
/>
</View>
</View>
);
}
}
var styles = StyleSheet.create({
container: {
position: 'absolute',
backgroundColor: 'transparent',
top: 0,
left: 0,
right: 0,
height: 0,
},
panelContainer: {
position: 'absolute',
left: 0,
right: 0,
},
});
module.exports = Inspector;

Просмотреть файл

@ -0,0 +1,81 @@
/**
* 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 InspectorOverlay
* @flow
*/
'use strict';
var Dimensions = require('Dimensions');
var InspectorUtils = require('InspectorUtils');
var React = require('React');
var StyleSheet = require('StyleSheet');
var UIManager = require('NativeModules').UIManager;
var View = require('View');
var ElementBox = require('ElementBox');
var PropTypes = React.PropTypes;
type EventLike = {
nativeEvent: Object;
};
var InspectorOverlay = React.createClass({
propTypes: {
inspectedViewTag: PropTypes.object,
onTouchInstance: PropTypes.func.isRequired,
},
findViewForTouchEvent: function(e: EventLike) {
var {locationX, locationY} = e.nativeEvent.touches[0];
UIManager.findSubviewIn(
this.props.inspectedViewTag,
[locationX, locationY],
(nativeViewTag, left, top, width, height) => {
var instance = InspectorUtils.findInstanceByNativeTag(this.props.rootTag, nativeViewTag);
if (!instance) {
return;
}
this.props.onTouchInstance(instance, {left, top, width, height}, locationY);
}
);
},
shouldSetResponser: function(e: EventLike): bool {
this.findViewForTouchEvent(e);
return true;
},
render: function() {
var content = null;
if (this.props.inspected) {
content = <ElementBox frame={this.props.inspected.frame} style={this.props.inspected.style} />;
}
return (
<View
onStartShouldSetResponder={this.shouldSetResponser}
onResponderMove={this.findViewForTouchEvent}
style={[styles.inspector, {height: Dimensions.get('window').height}]}>
{content}
</View>
);
}
});
var styles = StyleSheet.create({
inspector: {
backgroundColor: 'transparent',
position: 'absolute',
left: 0,
top: 0,
right: 0,
},
});
module.exports = InspectorOverlay;

Просмотреть файл

@ -0,0 +1,119 @@
/**
* 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 InspectorPanel
* @flow
*/
'use strict';
var React = require('React');
var StyleSheet = require('StyleSheet');
var Text = require('Text');
var View = require('View');
var ElementProperties = require('ElementProperties');
var TouchableHighlight = require('TouchableHighlight');
var PropTypes = React.PropTypes;
class InspectorPanel extends React.Component {
renderWaiting() {
if (this.props.inspecting) {
return (
<Text style={styles.waitingText}>
Tap something to inspect it
</Text>
);
}
return <Text style={styles.waitingText}>Nothing is inspected</Text>;
}
render() {
var contents;
if (this.props.inspected) {
contents = (
<ElementProperties
style={this.props.inspected.style}
frame={this.props.inspected.frame}
hierarchy={this.props.hierarchy}
selection={this.props.selection}
setSelection={this.props.setSelection}
/>
);
} else {
contents = (
<View style={styles.waiting}>
{this.renderWaiting()}
</View>
);
}
return (
<View style={styles.container}>
{contents}
<View style={styles.buttonRow}>
<Button
title={'Inspect'}
pressed={this.props.inspecting}
onClick={this.props.setInspecting}/>
</View>
</View>
);
}
}
InspectorPanel.propTypes = {
inspecting: PropTypes.bool,
setInspecting: PropTypes.func,
inspected: PropTypes.object,
};
class Button extends React.Component {
render() {
return (
<TouchableHighlight onPress={() => this.props.onClick(!this.props.pressed)} style={[
styles.button,
this.props.pressed && styles.buttonPressed
]}>
<Text style={styles.buttonText}>{this.props.title}</Text>
</TouchableHighlight>
);
}
}
var styles = StyleSheet.create({
buttonRow: {
flexDirection: 'row',
},
button: {
backgroundColor: 'rgba(0, 0, 0, 0.3)',
margin: 2,
height: 30,
justifyContent: 'center',
alignItems: 'center',
},
buttonPressed: {
backgroundColor: 'rgba(255, 255, 255, 0.3)',
},
buttonText: {
textAlign: 'center',
color: 'white',
margin: 5,
},
container: {
backgroundColor: 'rgba(0, 0, 0, 0.7)',
},
waiting: {
height: 100,
},
waitingText: {
fontSize: 20,
textAlign: 'center',
marginVertical: 20,
},
});
module.exports = InspectorPanel;

Просмотреть файл

@ -6,7 +6,7 @@
* 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 Inspector
* @providesModule InspectorUtils
*/
'use strict';

Просмотреть файл

@ -20,7 +20,7 @@
*
* If none are set, returns false.
*/
function resolveBoxStyle(prefix: String, style: Object): ?Object {
function resolveBoxStyle(prefix: string, style: Object): ?Object {
var res = {};
var subs = ['top', 'left', 'bottom', 'right'];
var set = false;

Просмотреть файл

@ -11,6 +11,7 @@
#import "RCTBridge.h"
#import "RCTEventDispatcher.h"
#import "RCTUtils.h"
NSString *const RCTOpenURLNotification = @"RCTOpenURLNotification";
@ -76,7 +77,7 @@ RCT_EXPORT_METHOD(canOpenURL:(NSURL *)URL
- (NSDictionary *)constantsToExport
{
NSURL *initialURL = _bridge.launchOptions[UIApplicationLaunchOptionsURLKey];
return @{@"initialURL": [initialURL absoluteString] ?: [NSNull null]};
return @{@"initialURL": RCTNullIfNil([initialURL absoluteString])};
}
@end

Просмотреть файл

@ -147,7 +147,7 @@ var NetInfo = {
eventName: ChangeEventName,
handler: Function
): void {
_subscriptions[handler] = RCTDeviceEventEmitter.addListener(
_subscriptions[String(handler)] = RCTDeviceEventEmitter.addListener(
DEVICE_REACHABILITY_EVENT,
(appStateData) => {
handler(appStateData.network_reachability);
@ -159,11 +159,11 @@ var NetInfo = {
eventName: ChangeEventName,
handler: Function
): void {
if (!_subscriptions[handler]) {
if (!_subscriptions[String(handler)]) {
return;
}
_subscriptions[handler].remove();
_subscriptions[handler] = null;
_subscriptions[String(handler)].remove();
_subscriptions[String(handler)] = null;
},
fetch: function(): Promise {
@ -204,12 +204,12 @@ NetInfo.isConnected = {
eventName: ChangeEventName,
handler: Function
): void {
_isConnectedSubscriptions[handler] = (connection) => {
_isConnectedSubscriptions[String(handler)] = (connection) => {
handler(_isConnected(connection));
};
NetInfo.addEventListener(
eventName,
_isConnectedSubscriptions[handler]
_isConnectedSubscriptions[String(handler)]
);
},
@ -219,7 +219,7 @@ NetInfo.isConnected = {
): void {
NetInfo.removeEventListener(
eventName,
_isConnectedSubscriptions[handler]
_isConnectedSubscriptions[String(handler)]
);
},

Просмотреть файл

@ -42,7 +42,7 @@ typedef void (^RCTHTTPQueryResult)(NSError *error, NSDictionary *result);
NSString *boundary;
}
- (void)process:(NSArray *)formData callback:(nonnull void (^)(NSError *error, NSDictionary *result))callback
- (void)process:(NSArray *)formData callback:(void (^)(NSError *error, NSDictionary *result))callback
{
if (![formData count]) {
callback(nil, nil);
@ -202,6 +202,7 @@ typedef void (^RCTDataLoaderCallback)(NSData *data, NSString *MIMEType, NSError
{
NSInteger _currentRequestID;
NSMapTable *_activeRequests;
dispatch_queue_t _methodQueue;
}
@synthesize bridge = _bridge;
@ -212,6 +213,7 @@ RCT_EXPORT_MODULE()
{
if ((self = [super init])) {
_currentRequestID = 0;
_methodQueue = dispatch_queue_create("com.facebook.React.RCTDataManager", DISPATCH_QUEUE_SERIAL);
_activeRequests = [[NSMapTable alloc] initWithKeyOptions:NSPointerFunctionsStrongMemory
valueOptions:NSPointerFunctionsStrongMemory
capacity:0];
@ -219,6 +221,11 @@ RCT_EXPORT_MODULE()
return self;
}
- (dispatch_queue_t)methodQueue
{
return _methodQueue;
}
- (void)buildRequest:(NSDictionary *)query
responseSender:(RCTResponseSenderBlock)responseSender
{
@ -298,7 +305,7 @@ RCT_EXPORT_MODULE()
* - @"contentType" (NSString): the content type header of the request
*
*/
- (void)processDataForHTTPQuery:(NSDictionary *)query callback:(nonnull void (^)(NSError *error, NSDictionary *result))callback
- (void)processDataForHTTPQuery:(NSDictionary *)query callback:(void (^)(NSError *error, NSDictionary *result))callback
{
if (!query) {
callback(nil, nil);
@ -381,55 +388,62 @@ RCT_EXPORT_MODULE()
- (void)URLRequest:(id)requestToken didReceiveResponse:(NSURLResponse *)response
{
RCTActiveURLRequest *request = [_activeRequests objectForKey:requestToken];
RCTAssert(request != nil, @"Unrecognized request token: %@", requestToken);
dispatch_async(_methodQueue, ^{
RCTActiveURLRequest *request = [_activeRequests objectForKey:requestToken];
RCTAssert(request != nil, @"Unrecognized request token: %@", requestToken);
request.response = response;
request.response = response;
NSHTTPURLResponse *httpResponse = nil;
if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
// Might be a local file request
httpResponse = (NSHTTPURLResponse *)response;
}
NSHTTPURLResponse *httpResponse = nil;
if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
// Might be a local file request
httpResponse = (NSHTTPURLResponse *)response;
}
NSArray *responseJSON = @[request.requestID,
@(httpResponse.statusCode ?: 200),
httpResponse.allHeaderFields ?: @{},
];
NSArray *responseJSON = @[request.requestID,
@(httpResponse.statusCode ?: 200),
httpResponse.allHeaderFields ?: @{},
];
[_bridge.eventDispatcher sendDeviceEventWithName:@"didReceiveNetworkResponse"
body:responseJSON];
[_bridge.eventDispatcher sendDeviceEventWithName:@"didReceiveNetworkResponse"
body:responseJSON];
});
}
- (void)URLRequest:(id)requestToken didReceiveData:(NSData *)data
{
RCTActiveURLRequest *request = [_activeRequests objectForKey:requestToken];
RCTAssert(request != nil, @"Unrecognized request token: %@", requestToken);
dispatch_async(_methodQueue, ^{
RCTActiveURLRequest *request = [_activeRequests objectForKey:requestToken];
RCTAssert(request != nil, @"Unrecognized request token: %@", requestToken);
if (request.incrementalUpdates) {
[self sendData:data forRequestToken:requestToken];
} else {
[request.data appendData:data];
}
if (request.incrementalUpdates) {
[self sendData:data forRequestToken:requestToken];
} else {
[request.data appendData:data];
}
});
}
- (void)URLRequest:(id)requestToken didCompleteWithError:(NSError *)error
{
RCTActiveURLRequest *request = [_activeRequests objectForKey:requestToken];
RCTAssert(request != nil, @"Unrecognized request token: %@", requestToken);
dispatch_async(_methodQueue, ^{
RCTActiveURLRequest *request = [_activeRequests objectForKey:requestToken];
RCTAssert(request != nil, @"Unrecognized request token: %@", requestToken);
if (!request.incrementalUpdates) {
[self sendData:request.data forRequestToken:requestToken];
}
if (!request.incrementalUpdates) {
[self sendData:request.data forRequestToken:requestToken];
}
NSArray *responseJSON = @[request.requestID,
error.localizedDescription ?: [NSNull null]
];
NSArray *responseJSON = @[
request.requestID,
RCTNullIfNil(error.localizedDescription),
];
[_bridge.eventDispatcher sendDeviceEventWithName:@"didCompleteNetworkResponse"
body:responseJSON];
[_bridge.eventDispatcher sendDeviceEventWithName:@"didCompleteNetworkResponse"
body:responseJSON];
[_activeRequests removeObjectForKey:requestToken];
[_activeRequests removeObjectForKey:requestToken];
});
}
#pragma mark - JS API

Просмотреть файл

@ -11,11 +11,12 @@
*/
'use strict';
var Map = require('Map');
var RCTDeviceEventEmitter = require('RCTDeviceEventEmitter');
var RCTPushNotificationManager = require('NativeModules').PushNotificationManager;
var invariant = require('invariant');
var _notifHandlers = {};
var _notifHandlers = new Map();
var _initialNotification = RCTPushNotificationManager &&
RCTPushNotificationManager.initialNotification;
@ -65,21 +66,23 @@ class PushNotificationIOS {
type === 'notification' || type === 'register',
'PushNotificationIOS only supports `notification` and `register` events'
);
var listener;
if (type === 'notification') {
_notifHandlers[handler] = RCTDeviceEventEmitter.addListener(
listener = RCTDeviceEventEmitter.addListener(
DEVICE_NOTIF_EVENT,
(notifData) => {
handler(new PushNotificationIOS(notifData));
}
);
} else if (type === 'register') {
_notifHandlers[handler] = RCTDeviceEventEmitter.addListener(
listener = RCTDeviceEventEmitter.addListener(
NOTIF_REGISTER_EVENT,
(registrationInfo) => {
handler(registrationInfo.deviceToken);
}
);
}
_notifHandlers.set(handler, listener);
}
/**
@ -143,11 +146,12 @@ class PushNotificationIOS {
type === 'notification' || type === 'register',
'PushNotificationIOS only supports `notification` and `register` events'
);
if (!_notifHandlers[handler]) {
var listener = _notifHandlers.get(handler);
if (!listener) {
return;
}
_notifHandlers[handler].remove();
_notifHandlers[handler] = null;
listener.remove();
_notifHandlers.delete(handler);
}

Просмотреть файл

@ -11,6 +11,7 @@
#import "RCTBridge.h"
#import "RCTEventDispatcher.h"
#import "RCTUtils.h"
#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_8_0
@ -172,7 +173,7 @@ RCT_EXPORT_METHOD(checkPermissions:(RCTResponseSenderBlock)callback)
- (NSDictionary *)constantsToExport
{
return @{
@"initialNotification": _initialNotification ?: [NSNull null]
@"initialNotification": RCTNullIfNil(_initialNotification),
};
}

Просмотреть файл

@ -1,132 +0,0 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule InspectorOverlay
*/
'use strict';
var Dimensions = require('Dimensions');
var Inspector = require('Inspector');
var React = require('React');
var StyleSheet = require('StyleSheet');
var Text = require('Text');
var UIManager = require('NativeModules').UIManager;
var View = require('View');
var ElementBox = require('ElementBox');
var ElementProperties = require('ElementProperties');
var InspectorOverlay = React.createClass({
getInitialState: function() {
return {
frame: null,
pointerY: 0,
hierarchy: [],
selection: -1,
};
},
findViewForTouchEvent: function(e) {
var {locationX, locationY} = e.nativeEvent.touches[0];
UIManager.findSubviewIn(
this.props.inspectedViewTag,
[locationX, locationY],
(nativeViewTag, left, top, width, height) => {
var instance = Inspector.findInstanceByNativeTag(this.props.rootTag, nativeViewTag);
if (!instance) {
return;
}
var hierarchy = Inspector.getOwnerHierarchy(instance);
var publicInstance = instance.getPublicInstance();
this.setState({
hierarchy,
pointerY: locationY,
selection: hierarchy.length - 1,
frame: {left, top, width, height},
style: publicInstance.props ? publicInstance.props.style : {},
});
}
);
},
setSelection(i) {
var instance = this.state.hierarchy[i];
var publicInstance = instance.getPublicInstance();
UIManager.measure(React.findNodeHandle(instance), (x, y, width, height, left, top) => {
this.setState({
frame: {left, top, width, height},
style: publicInstance.props ? publicInstance.props.style : {},
selection: i,
});
});
},
shouldSetResponser: function(e) {
this.findViewForTouchEvent(e);
return true;
},
render: function() {
var content = [];
var justifyContent = 'flex-end';
if (this.state.frame) {
var distanceToTop = this.state.pointerY;
var distanceToBottom = Dimensions.get('window').height - distanceToTop;
justifyContent = distanceToTop > distanceToBottom
? 'flex-start'
: 'flex-end';
content.push(<ElementBox frame={this.state.frame} style={this.state.style} />);
content.push(
<ElementProperties
style={this.state.style}
frame={this.state.frame}
hierarchy={this.state.hierarchy}
selection={this.state.selection}
setSelection={this.setSelection}
/>
);
} else {
content.push(
<View style={styles.welcomeMessage}>
<Text style={styles.welcomeText}>Welcome to the inspector! Tap something to inspect it.</Text>
</View>
);
}
return (
<View
onStartShouldSetResponder={this.shouldSetResponser}
onResponderMove={this.findViewForTouchEvent}
style={[styles.inspector, {justifyContent}]}>
{content}
</View>
);
}
});
var styles = StyleSheet.create({
welcomeMessage: {
backgroundColor: 'rgba(0, 0, 0, 0.7)',
padding: 10,
paddingVertical: 50,
},
welcomeText: {
color: 'white',
},
inspector: {
backgroundColor: 'rgba(255,255,255,0.0)',
position: 'absolute',
left: 0,
top: 0,
right: 0,
bottom: 0,
},
});
module.exports = InspectorOverlay;

Просмотреть файл

@ -10,7 +10,7 @@
*/
'use strict';
var InspectorOverlay = require('InspectorOverlay');
var Inspector = require('Inspector');
var RCTDeviceEventEmitter = require('RCTDeviceEventEmitter');
var React = require('React');
var StyleSheet = require('StyleSheet');
@ -30,7 +30,7 @@ var AppContainer = React.createClass({
toggleElementInspector: function() {
var inspector = this.state.inspector
? null
: <InspectorOverlay
: <Inspector
rootTag={this.props.rootTag}
inspectedViewTag={React.findNodeHandle(this.refs.main)}
/>;

Просмотреть файл

@ -26,7 +26,7 @@ type ReactNativeBaseComponentViewConfig = {
*/
var createReactNativeComponentClass = function(
viewConfig: ReactNativeBaseComponentViewConfig
): Function { // returning Function is lossy :/
): ReactClass<any, any, any> {
var Constructor = function(element) {
this._currentElement = element;
@ -39,7 +39,7 @@ var createReactNativeComponentClass = function(
Constructor.prototype = new ReactNativeBaseComponent(viewConfig);
Constructor.prototype.constructor = Constructor;
return Constructor;
return ((Constructor: any): ReactClass);
};
module.exports = createReactNativeComponentClass;

Просмотреть файл

@ -14,7 +14,7 @@
var GLOBAL = GLOBAL || this;
var BridgeProfiling = {
profile(profileName: String, args?: any) {
profile(profileName: string, args?: any) {
if (GLOBAL.__BridgeProfilingIsProfiling) {
if (args) {
try {

Просмотреть файл

@ -13,6 +13,7 @@
#import "RCTEventDispatcher.h"
#import "RCTSRWebSocket.h"
#import "RCTSparseArray.h"
#import "RCTUtils.h"
@implementation RCTSRWebSocket (React)
@ -107,7 +108,7 @@ RCT_EXPORT_METHOD(close:(NSNumber *)socketID)
{
[_bridge.eventDispatcher sendDeviceEventWithName:@"websocketClosed" body:@{
@"code": @(code),
@"reason": reason,
@"reason": RCTNullIfNil(reason),
@"clean": @(wasClean),
@"id": webSocket.reactTag
}];

4
Libraries/react-native/react-native.js поставляемый
Просмотреть файл

@ -65,6 +65,10 @@ var ReactNative = Object.assign(Object.create(require('React')), {
Platform: require('Platform'),
requireNativeComponent: require('requireNativeComponent'),
// Prop Types
EdgeInsetsPropType: require('EdgeInsetsPropType'),
PointPropType: require('PointPropType'),
addons: {
LinkedStateMixin: require('LinkedStateMixin'),
Perf: undefined,

Просмотреть файл

@ -103,4 +103,10 @@ Pod::Spec.new do |s|
ss.source_files = "Libraries/WebSocket/*.{h,m}"
ss.preserve_paths = "Libraries/WebSocket/*.js"
end
s.subspec 'RCTLinkingIOS' do |ss|
ss.dependency 'React/Core'
ss.source_files = "Libraries/LinkingIOS/*.{h,m}"
ss.preserve_paths = "Libraries/LinkingIOS/*.js"
end
end

Просмотреть файл

@ -449,7 +449,7 @@ case _value: { \
// Set arguments
NSUInteger index = 0;
for (id json in arguments) {
id arg = (json == [NSNull null]) ? nil : json;
id arg = RCTNilIfNull(json);
void (^block)(RCTBridge *, NSNumber *, NSInvocation *, NSUInteger, id) = _argumentBlocks[index];
block(bridge, context, invocation, index + 2, arg);
index++;
@ -1012,7 +1012,7 @@ RCT_INNER_BRIDGE_ONLY(_invokeAndProcessModule:(NSString *)module method:(NSStrin
if (queue) {
_queuesByID[moduleID] = queue;
} else {
_queuesByID[moduleID] = [NSNull null];
_queuesByID[moduleID] = (id)kCFNull;
}
}
@ -1266,8 +1266,8 @@ RCT_INNER_BRIDGE_ONLY(_invokeAndProcessModule:(NSString *)module method:(NSStrin
context:context
callback:^(id json, NSError *error) {
RCTProfileEndEvent(@"FetchApplicationScriptCallbacks", @"js_call,init", @{
@"json": json ?: [NSNull null],
@"error": error ?: [NSNull null],
@"json": RCTNullIfNil(json),
@"error": RCTNullIfNil(error),
});
[self _handleBuffer:json context:context];
@ -1293,7 +1293,7 @@ RCT_INNER_BRIDGE_ONLY(_invokeAndProcessModule:(NSString *)module method:(NSStrin
queue = _queuesByID[moduleID];
}
if (queue == [NSNull null]) {
if (queue == (id)kCFNull) {
[_javaScriptExecutor executeBlockOnJavaScriptQueue:block];
} else {
dispatch_async(queue ?: _methodQueue, block);
@ -1509,7 +1509,7 @@ RCT_INNER_BRIDGE_ONLY(_invokeAndProcessModule:(NSString *)module method:(NSStrin
@"module": method.moduleClassName,
@"method": method.JSMethodName,
@"selector": NSStringFromSelector(method.selector),
@"args": RCTJSONStringify(params ?: [NSNull null], NULL),
@"args": RCTJSONStringify(RCTNullIfNil(params), NULL),
});
return YES;

Просмотреть файл

@ -54,7 +54,7 @@ RCT_CONVERTER(NSString *, NSString, description)
RCTLogConvertError(json, "a number");
}
return number;
} else if (json && json != [NSNull null]) {
} else if (json && json != (id)kCFNull) {
RCTLogConvertError(json, "a number");
}
return nil;
@ -141,7 +141,7 @@ RCT_CONVERTER(NSString *, NSString, description)
"Expected format: YYYY-MM-DD'T'HH:mm:ss.sssZ", json);
}
return date;
} else if (json && json != [NSNull null]) {
} else if (json && json != (id)kCFNull) {
RCTLogConvertError(json, "a date");
}
return nil;

Просмотреть файл

@ -18,21 +18,6 @@
#define RCT_EXTERN extern __attribute__((visibility("default")))
#endif
/**
* Nullability for Xcode 6.2
*/
#if !__has_feature(nullability)
#define NS_ASSUME_NONNULL_BEGIN
#define NS_ASSUME_NONNULL_END
#define nullable
#define nonnull
#define null_unspecified
#define null_resettable
#define __nullable
#define __nonnull
#define __null_unspecified
#endif
/**
* The RCT_DEBUG macro can be used to exclude error checking and logging code
* from release builds to improve performance and reduce binary size.

Просмотреть файл

@ -171,9 +171,6 @@ void _RCTLogFormat(
// Log to red box
if (level >= RCTLOG_REDBOX_LEVEL) {
if (level < RCTLOG_FATAL_LEVEL) {
[[RCTRedBox sharedInstance] setNextBackgroundColor:[UIColor colorWithRed:0.9 green:0.4 blue:0.2 alpha:1]];
}
[[RCTRedBox sharedInstance] showErrorMessage:message];
}

Просмотреть файл

@ -107,8 +107,8 @@ typedef NS_ENUM(NSInteger, RCTTouchEventType) {
NSMutableDictionary *reactTouch = [[NSMutableDictionary alloc] initWithCapacity:9];
reactTouch[@"target"] = reactTag;
reactTouch[@"identifier"] = @(touchID);
reactTouch[@"touches"] = [NSNull null]; // We hijack this touchObj to serve both as an event
reactTouch[@"changedTouches"] = [NSNull null]; // and as a Touch object, so making this JIT friendly.
reactTouch[@"touches"] = (id)kCFNull; // We hijack this touchObj to serve both as an event
reactTouch[@"changedTouches"] = (id)kCFNull; // and as a Touch object, so making this JIT friendly.
// Add to arrays
[_touchViews addObject:targetView];

Просмотреть файл

@ -68,6 +68,8 @@
NSThread *_javaScriptThread;
}
@synthesize valid = _valid;
RCT_EXPORT_MODULE()
/**
@ -135,7 +137,7 @@ static JSValueRef RCTConsoleProfile(JSContextRef context, JSObjectRef object, JS
profileName = [NSString stringWithFormat:@"Profile %d", profileCounter++];
}
id profileInfo = [NSNull null];
id profileInfo = (id)kCFNull;
if (argumentCount > 1 && !JSValueIsUndefined(context, arguments[1])) {
profileInfo = @[RCTJSValueToNSString(context, arguments[1])];
}
@ -224,6 +226,7 @@ static NSError *RCTNSErrorFromJSError(JSContextRef context, JSValueRef jsError)
@"Can't initialize RCTContextExecutor without a javaScriptThread");
if ((self = [super init])) {
_valid = YES;
_javaScriptThread = javaScriptThread;
__weak RCTContextExecutor *weakSelf = self;
[self executeBlockOnJavaScriptQueue: ^{
@ -248,12 +251,11 @@ static NSError *RCTNSErrorFromJSError(JSContextRef context, JSValueRef jsError)
__weak RCTContextExecutor *weakSelf = self;
[self executeBlockOnJavaScriptQueue:^{
RCTContextExecutor *strongSelf = weakSelf;
if (!strongSelf) {
if (!strongSelf.isValid) {
return;
}
if (!strongSelf->_context) {
JSGlobalContextRef ctx = JSGlobalContextCreate(NULL);
JSGlobalContextRetain(ctx);
strongSelf->_context = [[RCTJavaScriptContext alloc] initWithJSContext:ctx];
}
[strongSelf _addNativeHook:RCTNativeLoggingHook withName:"nativeLoggingHook"];
@ -263,7 +265,7 @@ static NSError *RCTNSErrorFromJSError(JSContextRef context, JSValueRef jsError)
[strongSelf _addNativeHook:RCTConsoleProfileEnd withName:"consoleProfileEnd"];
for (NSString *event in @[RCTProfileDidStartProfiling, RCTProfileDidEndProfiling]) {
[[NSNotificationCenter defaultCenter] addObserver:self
[[NSNotificationCenter defaultCenter] addObserver:strongSelf
selector:@selector(toggleProfilingFlag:)
name:event
object:nil];
@ -297,13 +299,14 @@ static NSError *RCTNSErrorFromJSError(JSContextRef context, JSValueRef jsError)
}
- (BOOL)isValid
{
return _context.isValid;
}
- (void)invalidate
{
if (!self.isValid) {
return;
}
_valid = NO;
#if RCT_DEV
[[NSNotificationCenter defaultCenter] removeObserver:self];
#endif

Просмотреть файл

@ -164,14 +164,14 @@ RCT_EXPORT_MODULE()
return errorOut;
}
id value = [self _getValueForKey:key errorOut:&errorOut];
[result addObject:@[key, value ?: [NSNull null]]]; // Insert null if missing or failure.
[result addObject:@[key, RCTNullIfNil(value)]]; // Insert null if missing or failure.
return errorOut;
}
- (NSString *)_getValueForKey:(NSString *)key errorOut:(NSDictionary **)errorOut
{
id value = _manifest[key]; // nil means missing, null means there is a data file, anything else is an inline value.
if (value == [NSNull null]) {
if (value == (id)kCFNull) {
NSString *filePath = [self _filePathForKey:key];
value = RCTReadFile(filePath, key, errorOut);
}
@ -195,7 +195,7 @@ RCT_EXPORT_MODULE()
NSString *filePath = [self _filePathForKey:key];
NSError *error;
if (value.length <= kInlineValueThreshold) {
if (_manifest[key] && _manifest[key] != [NSNull null]) {
if (_manifest[key] && _manifest[key] != (id)kCFNull) {
// If the value already existed but wasn't inlined, remove the old file.
[[NSFileManager defaultManager] removeItemAtPath:filePath error:nil];
}
@ -206,7 +206,7 @@ RCT_EXPORT_MODULE()
if (error) {
errorOut = RCTMakeError(@"Failed to write value.", error, @{@"key": key});
} else {
_manifest[key] = [NSNull null]; // Mark existence of file with null, any other value is inline data.
_manifest[key] = (id)kCFNull; // Mark existence of file with null, any other value is inline data.
}
return errorOut;
}
@ -223,7 +223,7 @@ RCT_EXPORT_METHOD(multiGet:(NSArray *)keys
id errorOut = [self _ensureSetup];
if (errorOut) {
callback(@[@[errorOut], [NSNull null]]);
callback(@[@[errorOut], (id)kCFNull]);
return;
}
NSMutableArray *errors;
@ -232,7 +232,7 @@ RCT_EXPORT_METHOD(multiGet:(NSArray *)keys
id keyError = [self _appendItemForKey:key toArray:result];
RCTAppendError(keyError, &errors);
}
callback(@[errors ?: [NSNull null], result]);
callback(@[RCTNullIfNil(errors), result]);
}
RCT_EXPORT_METHOD(multiSet:(NSArray *)kvPairs
@ -250,7 +250,7 @@ RCT_EXPORT_METHOD(multiSet:(NSArray *)kvPairs
}
[self _writeManifest:&errors];
if (callback) {
callback(@[errors ?: [NSNull null]]);
callback(@[RCTNullIfNil(errors)]);
}
}
@ -282,7 +282,7 @@ RCT_EXPORT_METHOD(multiMerge:(NSArray *)kvPairs
}
[self _writeManifest:&errors];
if (callback) {
callback(@[errors ?: [NSNull null]]);
callback(@[RCTNullIfNil(errors)]);
}
}
@ -306,7 +306,7 @@ RCT_EXPORT_METHOD(multiRemove:(NSArray *)keys
}
[self _writeManifest:&errors];
if (callback) {
callback(@[errors ?: [NSNull null]]);
callback(@[RCTNullIfNil(errors)]);
}
}
@ -323,7 +323,7 @@ RCT_EXPORT_METHOD(clear:(RCTResponseSenderBlock)callback)
errorOut = [self _writeManifest:nil];
}
if (callback) {
callback(@[errorOut ?: [NSNull null]]);
callback(@[RCTNullIfNil(errorOut)]);
}
}
@ -331,9 +331,9 @@ RCT_EXPORT_METHOD(getAllKeys:(RCTResponseSenderBlock)callback)
{
id errorOut = [self _ensureSetup];
if (errorOut) {
callback(@[errorOut, [NSNull null]]);
callback(@[errorOut, (id)kCFNull]);
} else {
callback(@[[NSNull null], [_manifest allKeys]]);
callback(@[(id)kCFNull, [_manifest allKeys]]);
}
}

Просмотреть файл

@ -44,9 +44,7 @@ RCT_EXPORT_METHOD(reportSoftException:(NSString *)message
[_delegate handleSoftJSExceptionWithMessage:message stack:stack];
return;
}
RCTRedBox *box = [RCTRedBox sharedInstance];
[box setNextBackgroundColor:[UIColor colorWithRed:0.9 green:0.4 blue:0.2 alpha:1]];
[box showErrorMessage:message withStack:stack];
[[RCTRedBox sharedInstance] showErrorMessage:message withStack:stack];
}
RCT_EXPORT_METHOD(reportFatalException:(NSString *)message

Просмотреть файл

@ -471,7 +471,7 @@ static NSDictionary *RCTViewConfigForModule(Class managerClass, NSString *viewNa
[frames addObject:[NSValue valueWithCGRect:shadowView.frame]];
[areNew addObject:@(shadowView.isNewView)];
[parentsAreNew addObject:@(shadowView.superview.isNewView)];
id event = [NSNull null];
id event = (id)kCFNull;
if (shadowView.hasOnLayout) {
event = @{
@"target": shadowView.reactTag,
@ -519,7 +519,7 @@ static NSDictionary *RCTViewConfigForModule(Class managerClass, NSString *viewNa
void (^completion)(BOOL finished) = ^(BOOL finished) {
completionsCalled++;
if (event != [NSNull null]) {
if (event != (id)kCFNull) {
[self.bridge.eventDispatcher sendInputEventWithName:@"topLayout" body:event];
}
if (callback && completionsCalled == frames.count - 1) {
@ -753,7 +753,7 @@ static BOOL RCTCallPropertySetter(NSString *key, SEL setter, id value, id view,
// TODO: cache respondsToSelector tests
if ([manager respondsToSelector:setter]) {
if (value == [NSNull null]) {
if (value == (id)kCFNull) {
value = nil;
}
@ -906,7 +906,7 @@ RCT_EXPORT_METHOD(blur:(NSNumber *)reactTag)
RCT_EXPORT_METHOD(findSubviewIn:(NSNumber *)reactTag atPoint:(CGPoint)point callback:(RCTResponseSenderBlock)callback) {
if (!reactTag) {
callback(@[[NSNull null]]);
callback(@[(id)kCFNull]);
return;
}
@ -920,7 +920,7 @@ RCT_EXPORT_METHOD(findSubviewIn:(NSNumber *)reactTag atPoint:(CGPoint)point call
}
callback(@[
target.reactTag ?: [NSNull null],
RCTNullIfNil(target.reactTag),
@(frame.origin.x),
@(frame.origin.y),
@(frame.size.width),

Просмотреть файл

@ -15,6 +15,7 @@
+ (MKCoordinateSpan)MKCoordinateSpan:(id)json;
+ (MKCoordinateRegion)MKCoordinateRegion:(id)json;
+ (MKShape *)MKShape:(id)json;
+ (MKMapType)MKMapType:(id)json;
typedef NSArray MKShapeArray;
+ (MKShapeArray *)MKShapeArray:(id)json;

Просмотреть файл

@ -43,4 +43,10 @@
RCT_ARRAY_CONVERTER(MKShape)
RCT_ENUM_CONVERTER(MKMapType, (@{
@"standard": @(MKMapTypeStandard),
@"satellite": @(MKMapTypeSatellite),
@"hybrid": @(MKMapTypeHybrid),
}), MKMapTypeStandard, integerValue)
@end

Просмотреть файл

@ -41,6 +41,7 @@ RCT_EXPORT_VIEW_PROPERTY(scrollEnabled, BOOL)
RCT_EXPORT_VIEW_PROPERTY(maxDelta, CGFloat)
RCT_EXPORT_VIEW_PROPERTY(minDelta, CGFloat)
RCT_EXPORT_VIEW_PROPERTY(legalLabelInsets, UIEdgeInsets)
RCT_EXPORT_VIEW_PROPERTY(mapType, MKMapType)
RCT_EXPORT_VIEW_PROPERTY(annotations, MKShapeArray)
RCT_CUSTOM_VIEW_PROPERTY(region, MKCoordinateRegion, RCTMap)
{

Просмотреть файл

@ -60,7 +60,7 @@
"react-timer-mixin": "^0.13.1",
"react-tools": "0.13.2",
"rebound": "^0.0.12",
"sane": "tadeuzagallo/sane#a029f8b04a",
"sane": "^1.1.2",
"source-map": "0.1.31",
"stacktrace-parser": "frantic/stacktrace-parser#493c5e5638",
"uglify-js": "~2.4.16",

Просмотреть файл

@ -53,6 +53,9 @@ var options = parseCommandLine([{
}, {
command: 'skipflow',
description: 'Disable flow checks'
}, {
command: 'nonPersistent',
description: 'Disable file watcher'
}]);
if (options.projectRoots) {
@ -199,6 +202,7 @@ function statusPageMiddleware(req, res, next) {
function getAppMiddleware(options) {
return ReactPackager.middleware({
nonPersistent: options.nonPersistent,
projectRoots: options.projectRoots,
blacklistRE: blacklist(options.platform),
cacheVersion: '2',

Просмотреть файл

@ -67,7 +67,6 @@ function createWatcher(rootConfig) {
var watcher = new Watcher(rootConfig.dir, {
glob: rootConfig.globs,
dot: false,
ignore: '**/node_modules/**/*',
});
return new Promise(function(resolve, reject) {