Merge pull request #1610 from sahrens/Updates_Fri_Jun_12
Updates fri jun 12
This commit is contained in:
Коммит
1120769f1b
|
@ -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
|
||||
}];
|
||||
|
|
|
@ -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) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче