Updates from Tue 25 Aug

This commit is contained in:
Martin Konicek 2015-08-25 19:21:59 +01:00
commit da7ac11c53
258 changed files with 6409 additions and 4361 deletions

View File

@ -12,7 +12,7 @@
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
1461632D1AC3E23900C2F5AD /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1461632C1AC3E22900C2F5AD /* libReact.a */; };
58C1E40E1ACF54E9006D1A47 /* libRCTAnimationExperimental.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 58C1E40B1ACF54B4006D1A47 /* libRCTAnimationExperimental.a */; };
5F82F1781B85785200FAE87E /* libRCTWebSocket.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5F82F1771B85784500FAE87E /* libRCTWebSocket.a */; };
832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; };
/* End PBXBuildFile section */
@ -24,12 +24,12 @@
remoteGlobalIDString = 83CBBA2E1A601D0E00E9B192;
remoteInfo = React;
};
58C1E40A1ACF54B4006D1A47 /* PBXContainerItemProxy */ = {
5F82F1761B85784500FAE87E /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 13ACB66C1AC2113500FF4204 /* RCTAnimationExperimental.xcodeproj */;
containerPortal = 5F82F1721B85784500FAE87E /* RCTWebSocket.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 134814201AA4EA6300B7C361;
remoteInfo = RCTAnimationExperimental;
remoteGlobalIDString = 3C86DF461ADF2C930047B81A;
remoteInfo = RCTWebSocket;
};
832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
@ -41,7 +41,6 @@
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
13ACB66C1AC2113500FF4204 /* RCTAnimationExperimental.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTAnimationExperimental.xcodeproj; path = ../../Libraries/Animation/RCTAnimationExperimental.xcodeproj; sourceTree = "<group>"; };
13B07F961A680F5B00A75B9A /* 2048.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = 2048.app; sourceTree = BUILT_PRODUCTS_DIR; };
13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = 2048/AppDelegate.h; sourceTree = "<group>"; };
13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = 2048/AppDelegate.m; sourceTree = "<group>"; };
@ -50,6 +49,7 @@
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = 2048/Info.plist; sourceTree = "<group>"; };
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = 2048/main.m; sourceTree = "<group>"; };
146163271AC3E22900C2F5AD /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = ../../React/React.xcodeproj; sourceTree = "<group>"; };
5F82F1721B85784500FAE87E /* RCTWebSocket.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWebSocket.xcodeproj; path = ../../Libraries/WebSocket/RCTWebSocket.xcodeproj; sourceTree = "<group>"; };
832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = ../../Libraries/Text/RCTText.xcodeproj; sourceTree = "<group>"; };
/* End PBXFileReference section */
@ -58,8 +58,8 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
5F82F1781B85785200FAE87E /* libRCTWebSocket.a in Frameworks */,
1461632D1AC3E23900C2F5AD /* libReact.a in Frameworks */,
58C1E40E1ACF54E9006D1A47 /* libRCTAnimationExperimental.a in Frameworks */,
832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -88,10 +88,10 @@
name = Products;
sourceTree = "<group>";
};
58C1E4071ACF54B4006D1A47 /* Products */ = {
5F82F1731B85784500FAE87E /* Products */ = {
isa = PBXGroup;
children = (
58C1E40B1ACF54B4006D1A47 /* libRCTAnimationExperimental.a */,
5F82F1771B85784500FAE87E /* libRCTWebSocket.a */,
);
name = Products;
sourceTree = "<group>";
@ -99,9 +99,9 @@
832341AE1AAA6A7D00B99B32 /* Libraries */ = {
isa = PBXGroup;
children = (
5F82F1721B85784500FAE87E /* RCTWebSocket.xcodeproj */,
146163271AC3E22900C2F5AD /* React.xcodeproj */,
832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */,
13ACB66C1AC2113500FF4204 /* RCTAnimationExperimental.xcodeproj */,
);
name = Libraries;
sourceTree = "<group>";
@ -174,14 +174,14 @@
productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */;
projectDirPath = "";
projectReferences = (
{
ProductGroup = 58C1E4071ACF54B4006D1A47 /* Products */;
ProjectRef = 13ACB66C1AC2113500FF4204 /* RCTAnimationExperimental.xcodeproj */;
},
{
ProductGroup = 832341B11AAA6A8300B99B32 /* Products */;
ProjectRef = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */;
},
{
ProductGroup = 5F82F1731B85784500FAE87E /* Products */;
ProjectRef = 5F82F1721B85784500FAE87E /* RCTWebSocket.xcodeproj */;
},
{
ProductGroup = 146163281AC3E22900C2F5AD /* Products */;
ProjectRef = 146163271AC3E22900C2F5AD /* React.xcodeproj */;
@ -202,11 +202,11 @@
remoteRef = 1461632B1AC3E22900C2F5AD /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
58C1E40B1ACF54B4006D1A47 /* libRCTAnimationExperimental.a */ = {
5F82F1771B85784500FAE87E /* libRCTWebSocket.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libRCTAnimationExperimental.a;
remoteRef = 58C1E40A1ACF54B4006D1A47 /* PBXContainerItemProxy */;
path = libRCTWebSocket.a;
remoteRef = 5F82F1761B85784500FAE87E /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
832341B51AAA6A8300B99B32 /* libRCTText.a */ = {
@ -266,10 +266,7 @@
);
INFOPLIST_FILE = "$(SRCROOT)/2048/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"/Users/sahrens/src/fbobjc-hg/Libraries/FBReactKit/js/react-native-github/Libraries/Animation/build/Debug-iphoneos",
);
LIBRARY_SEARCH_PATHS = "$(inherited)";
OTHER_LDFLAGS = "-ObjC";
PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = 2048;
@ -287,10 +284,7 @@
);
INFOPLIST_FILE = "$(SRCROOT)/2048/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"/Users/sahrens/src/fbobjc-hg/Libraries/FBReactKit/js/react-native-github/Libraries/Animation/build/Debug-iphoneos",
);
LIBRARY_SEARCH_PATHS = "$(inherited)";
OTHER_LDFLAGS = "-ObjC";
PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = 2048;

View File

@ -52,6 +52,7 @@
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
moduleName:@"Game2048"
initialProperties:nil
launchOptions:launchOptions];
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];

View File

@ -53,6 +53,7 @@
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
moduleName:@"MoviesApp"
initialProperties:nil
launchOptions:launchOptions];
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];

View File

@ -0,0 +1 @@
{}

View File

@ -565,6 +565,11 @@
"DEBUG=1",
"$(inherited)",
);
HEADER_SEARCH_PATHS = (
"$(inherited)",
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
"$(SRCROOT)/../../../React/**",
);
INFOPLIST_FILE = SampleAppTests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 8.2;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
@ -582,6 +587,11 @@
"$(SDKROOT)/Developer/Library/Frameworks",
"$(inherited)",
);
HEADER_SEARCH_PATHS = (
"$(inherited)",
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
"$(SRCROOT)/../../../React/**",
);
INFOPLIST_FILE = SampleAppTests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 8.2;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";

View File

@ -20,6 +20,20 @@
ReferencedContainer = "container:SampleApp.xcodeproj">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "NO"
buildForArchiving = "NO"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "00E356ED1AD99517003FC87E"
BuildableName = "SampleAppTests.xctest"
BlueprintName = "SampleAppTests"
ReferencedContainer = "container:SampleApp.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
@ -28,6 +42,16 @@
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "00E356ED1AD99517003FC87E"
BuildableName = "SampleAppTests.xctest"
BlueprintName = "SampleAppTests"
ReferencedContainer = "container:SampleApp.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference

View File

@ -47,10 +47,11 @@
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
moduleName:@"SampleApp"
initialProperties:nil
launchOptions:launchOptions];
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIViewController *rootViewController = [[UIViewController alloc] init];
UIViewController *rootViewController = [UIViewController new];
rootViewController.view = rootView;
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];

View File

@ -10,8 +10,7 @@
#import <UIKit/UIKit.h>
#import <XCTest/XCTest.h>
#import "RCTAssert.h"
#import "RCTRedBox.h"
#import "RCTLog.h"
#import "RCTRootView.h"
#define TIMEOUT_SECONDS 240
@ -23,7 +22,6 @@
@implementation SampleAppTests
- (BOOL)findSubviewInView:(UIView *)view matching:(BOOL(^)(UIView *view))test
{
if (test(view)) {
@ -37,18 +35,23 @@
return NO;
}
- (void)testRendersWelcomeScreen {
- (void)testRendersWelcomeScreen
{
UIViewController *vc = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS];
BOOL foundElement = NO;
NSString *redboxError = nil;
__block NSString *redboxError = nil;
RCTSetLogFunction(^(RCTLogLevel level, NSString *fileName, NSNumber *lineNumber, NSString *message) {
if (level >= RCTLogLevelError) {
redboxError = message;
}
});
while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) {
[[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
[[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
redboxError = [[RCTRedBox sharedInstance] currentErrorMessage];
foundElement = [self findSubviewInView:vc.view matching:^BOOL(UIView *view) {
if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) {
return YES;
@ -57,6 +60,8 @@
}];
}
RCTSetLogFunction(RCTDefaultLogFunction);
XCTAssertNil(redboxError, @"RedBox error: %@", redboxError);
XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS);
}

View File

@ -14,6 +14,7 @@
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
144C5F691AC3E5E300B004E7 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 144C5F681AC3E5D800B004E7 /* libReact.a */; };
58C572511AA6229D00CDF9C8 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 58C5724D1AA6224400CDF9C8 /* libRCTText.a */; };
5FF8942E1B85571A007731BE /* libRCTWebSocket.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5FF8942D1B8556F8007731BE /* libRCTWebSocket.a */; };
832044981B492C2500E297FC /* libRCTSettings.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832044951B492C1E00E297FC /* libRCTSettings.a */; };
/* End PBXBuildFile section */
@ -39,6 +40,13 @@
remoteGlobalIDString = 58B5119B1A9E6C1200147676;
remoteInfo = RCTText;
};
5FF8942C1B8556F8007731BE /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 5FF894281B8556F8007731BE /* RCTWebSocket.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 3C86DF461ADF2C930047B81A;
remoteInfo = RCTWebSocket;
};
832044941B492C1E00E297FC /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 8320448F1B492C1E00E297FC /* RCTSettings.xcodeproj */;
@ -59,6 +67,7 @@
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = TicTacToe/main.m; sourceTree = "<group>"; };
144C5F631AC3E5D800B004E7 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = ../../React/React.xcodeproj; sourceTree = "<group>"; };
587650DA1A9EB0DB008B8F17 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = ../../Libraries/Text/RCTText.xcodeproj; sourceTree = "<group>"; };
5FF894281B8556F8007731BE /* RCTWebSocket.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWebSocket.xcodeproj; path = ../../Libraries/WebSocket/RCTWebSocket.xcodeproj; sourceTree = "<group>"; };
8320448F1B492C1E00E297FC /* RCTSettings.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTSettings.xcodeproj; path = ../../Libraries/Settings/RCTSettings.xcodeproj; sourceTree = "<group>"; };
/* End PBXFileReference section */
@ -67,6 +76,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
5FF8942E1B85571A007731BE /* libRCTWebSocket.a in Frameworks */,
144C5F691AC3E5E300B004E7 /* libReact.a in Frameworks */,
1341803E1AA91802003F314A /* libRCTImage.a in Frameworks */,
58C572511AA6229D00CDF9C8 /* libRCTText.a in Frameworks */,
@ -109,6 +119,7 @@
58C572071AA6126D00CDF9C8 /* Libraries */ = {
isa = PBXGroup;
children = (
5FF894281B8556F8007731BE /* RCTWebSocket.xcodeproj */,
144C5F631AC3E5D800B004E7 /* React.xcodeproj */,
134180381AA917ED003F314A /* RCTImage.xcodeproj */,
8320448F1B492C1E00E297FC /* RCTSettings.xcodeproj */,
@ -125,6 +136,14 @@
name = Products;
sourceTree = "<group>";
};
5FF894291B8556F8007731BE /* Products */ = {
isa = PBXGroup;
children = (
5FF8942D1B8556F8007731BE /* libRCTWebSocket.a */,
);
name = Products;
sourceTree = "<group>";
};
832044901B492C1E00E297FC /* Products */ = {
isa = PBXGroup;
children = (
@ -205,6 +224,10 @@
ProductGroup = 58C572481AA6224300CDF9C8 /* Products */;
ProjectRef = 587650DA1A9EB0DB008B8F17 /* RCTText.xcodeproj */;
},
{
ProductGroup = 5FF894291B8556F8007731BE /* Products */;
ProjectRef = 5FF894281B8556F8007731BE /* RCTWebSocket.xcodeproj */;
},
{
ProductGroup = 144C5F641AC3E5D800B004E7 /* Products */;
ProjectRef = 144C5F631AC3E5D800B004E7 /* React.xcodeproj */;
@ -239,6 +262,13 @@
remoteRef = 58C5724C1AA6224400CDF9C8 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
5FF8942D1B8556F8007731BE /* libRCTWebSocket.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libRCTWebSocket.a;
remoteRef = 5FF8942C1B8556F8007731BE /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
832044951B492C1E00E297FC /* libRCTSettings.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;

View File

@ -52,6 +52,7 @@
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
moduleName:@"TicTacToeApp"
initialProperties:nil
launchOptions:launchOptions];
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];

View File

@ -27,6 +27,8 @@ var AccessibilityInfo = require('AccessibilityInfo');
var UIExplorerBlock = require('./UIExplorerBlock');
var UIExplorerPage = require('./UIExplorerPage');
var importantForAccessibilityValues = ['auto', 'yes', 'no', 'no-hide-descendants'];
var AccessibilityAndroidExample = React.createClass({
statics: {
@ -38,6 +40,8 @@ var AccessibilityAndroidExample = React.createClass({
return {
count: 0,
talkbackEnabled: false,
backgroundImportantForAcc: 0,
forgroundImportantForAcc: 0,
};
},
@ -79,6 +83,18 @@ var AccessibilityAndroidExample = React.createClass({
});
},
_changeBackgroundImportantForAcc: function() {
this.setState({
backgroundImportantForAcc: (this.state.backgroundImportantForAcc + 1) % 4,
});
},
_changeForgroundImportantForAcc: function() {
this.setState({
forgroundImportantForAcc: (this.state.forgroundImportantForAcc + 1) % 4,
});
},
render: function() {
return (
<UIExplorerPage title={'Accessibility'}>
@ -148,6 +164,77 @@ var AccessibilityAndroidExample = React.createClass({
</TouchableWithoutFeedback>
</UIExplorerBlock>
<UIExplorerBlock title="Overlapping views and importantForAccessibility property">
<View style={styles.container}>
<View
style={{
position: 'absolute',
left: 10,
top: 10,
right: 10,
height: 100,
backgroundColor: 'green'}}
accessible={true}
accessibilityLabel="First layout"
importantForAccessibility={
importantForAccessibilityValues[this.state.backgroundImportantForAcc]}>
<View accessible={true}>
<Text style={{fontSize: 25}}>
Hello
</Text>
</View>
</View>
<View
style={{
position: 'absolute',
left: 10,
top: 25,
right: 10,
height: 110,
backgroundColor: 'yellow', opacity: 0.5}}
accessible={true}
accessibilityLabel="Second layout"
importantForAccessibility={
importantForAccessibilityValues[this.state.forgroundImportantForAcc]}>
<View accessible={true}>
<Text style={{fontSize: 20}}>
world
</Text>
</View>
</View>
</View>
<TouchableWithoutFeedback onPress={this._changeBackgroundImportantForAcc}>
<View style={styles.embedded}>
<Text>
Change importantForAccessibility for background layout.
</Text>
</View>
</TouchableWithoutFeedback>
<View accessible={true}>
<Text>
Background layout importantForAccessibility
</Text>
<Text>
{importantForAccessibilityValues[this.state.backgroundImportantForAcc]}
</Text>
</View>
<TouchableWithoutFeedback onPress={this._changeForgroundImportantForAcc}>
<View style={styles.embedded}>
<Text>
Change importantForAccessibility for forground layout.
</Text>
</View>
</TouchableWithoutFeedback>
<View accessible={true}>
<Text>
Forground layout importantForAccessibility
</Text>
<Text>
{importantForAccessibilityValues[this.state.forgroundImportantForAcc]}
</Text>
</View>
</UIExplorerBlock>
</UIExplorerPage>
);
},
@ -158,6 +245,12 @@ var styles = StyleSheet.create({
backgroundColor: 'yellow',
padding:10,
},
container: {
flex: 1,
backgroundColor: 'white',
padding: 10,
height:150,
},
});
module.exports = AccessibilityAndroidExample;

View File

@ -340,7 +340,7 @@ exports.examples = [
];
var fullImage = {uri: 'http://facebook.github.io/react/img/logo_og.png'};
var smallImage = {uri: 'http://facebook.github.io/react/img/logo_small.png'};
var smallImage = {uri: 'http://facebook.github.io/react/img/logo_small_2x.png'};
var styles = StyleSheet.create({
base: {

View File

@ -15,37 +15,37 @@
*/
'use strict';
/* $FlowIssue #7387208 - There's a flow bug preventing this type from flowing
* into a proptype shape */
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;
}
/* $FlowIssue #7387208 - There's a flow bug preventing this type from flowing
* into a proptype shape */
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;
}
/* $FlowIssue #7387208 - There's a flow bug preventing this type from flowing
* into a proptype shape */
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;
}
/* $FlowIssue #7387208 - There's a flow bug preventing this type from flowing
* into a proptype shape */
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;
}
/* $FlowIssue #7387208 - There's a flow bug preventing this type from flowing
* into a proptype shape */
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;
}

View File

@ -138,11 +138,11 @@ var styles = StyleSheet.create({
},
});
exports.title = 'onLayout';
exports.title = 'Layout Events';
exports.description = 'Layout events can be used to measure view size and position.';
exports.examples = [
{
title: 'onLayout',
title: 'LayoutEventExample',
render: function(): ReactElement {
return <LayoutEventExample />;
},

View File

@ -19,6 +19,7 @@ var React = require('react-native');
var {
Modal,
StyleSheet,
SwitchIOS,
Text,
TouchableHighlight,
View,
@ -29,53 +30,98 @@ exports.framework = 'React';
exports.title = '<Modal>';
exports.description = 'Component for presenting modal views.';
var ModalExample = React.createClass({
getInitialState: function() {
var Button = React.createClass({
getInitialState() {
return {
openModal: null,
active: false,
};
},
_closeModal: function() {
this.setState({openModal: null});
_onHighlight() {
this.setState({active: true});
},
_openAnimatedModal: function() {
this.setState({openModal: 'animated'});
_onUnhighlight() {
this.setState({active: false});
},
_openNotAnimatedModal: function() {
this.setState({openModal: 'not-animated'});
render() {
var colorStyle = {
color: this.state.active ? '#fff' : '#000',
};
return (
<TouchableHighlight
onHideUnderlay={this._onUnhighlight}
onPress={this.props.onPress}
onShowUnderlay={this._onHighlight}
style={[styles.button, this.props.style]}
underlayColor="#a9d9d4">
<Text style={[styles.buttonText, colorStyle]}>{this.props.children}</Text>
</TouchableHighlight>
);
}
});
var ModalExample = React.createClass({
getInitialState() {
return {
animated: true,
modalVisible: false,
transparent: false,
};
},
render: function() {
_setModalVisible(visible) {
this.setState({modalVisible: visible});
},
_toggleAnimated() {
this.setState({animated: !this.state.animated});
},
_toggleTransparent() {
this.setState({transparent: !this.state.transparent});
},
render() {
var modalBackgroundStyle = {
backgroundColor: this.state.transparent ? 'rgba(0, 0, 0, 0.5)' : '#f5fcff',
};
var innerContainerTransparentStyle = this.state.transparent
? {backgroundColor: '#fff', padding: 20}
: null;
return (
<View>
<Modal animated={true} visible={this.state.openModal === 'animated'}>
<View style={styles.container}>
<Text>This modal was presented with animation.</Text>
<TouchableHighlight underlayColor="#a9d9d4" onPress={this._closeModal}>
<Text>Close</Text>
</TouchableHighlight>
<Modal
animated={this.state.animated}
transparent={this.state.transparent}
visible={this.state.modalVisible}>
<View style={[styles.container, modalBackgroundStyle]}>
<View style={[styles.innerContainer, innerContainerTransparentStyle]}>
<Text>This modal was presented {this.state.animated ? 'with' : 'without'} animation.</Text>
<Button
onPress={this._setModalVisible.bind(this, false)}
style={styles.modalButton}>
Close
</Button>
</View>
</View>
</Modal>
<Modal visible={this.state.openModal === 'not-animated'}>
<View style={styles.container}>
<Text>This modal was presented immediately, without animation.</Text>
<TouchableHighlight underlayColor="#a9d9d4" onPress={this._closeModal}>
<Text>Close</Text>
</TouchableHighlight>
</View>
</Modal>
<View style={styles.row}>
<Text style={styles.rowTitle}>Animated</Text>
<SwitchIOS value={this.state.animated} onValueChange={this._toggleAnimated} />
</View>
<TouchableHighlight underlayColor="#a9d9d4" onPress={this._openAnimatedModal}>
<Text>Present Animated</Text>
</TouchableHighlight>
<View style={styles.row}>
<Text style={styles.rowTitle}>Transparent</Text>
<SwitchIOS value={this.state.transparent} onValueChange={this._toggleTransparent} />
</View>
<TouchableHighlight underlayColor="#a9d9d4" onPress={this._openNotAnimatedModal}>
<Text>Present Without Animation</Text>
</TouchableHighlight>
<Button onPress={this._setModalVisible.bind(this, true)}>
Present
</Button>
</View>
);
},
@ -91,9 +137,36 @@ exports.examples = [
var styles = StyleSheet.create({
container: {
alignItems: 'center',
backgroundColor: '#f5fcff',
flex: 1,
justifyContent: 'center',
padding: 20,
},
innerContainer: {
borderRadius: 10,
},
row: {
alignItems: 'center',
flex: 1,
flexDirection: 'row',
marginBottom: 20,
},
rowTitle: {
flex: 1,
fontWeight: 'bold',
},
button: {
borderRadius: 5,
flex: 1,
height: 44,
justifyContent: 'center',
overflow: 'hidden',
},
buttonText: {
fontSize: 18,
margin: 5,
textAlign: 'center',
},
modalButton: {
marginTop: 10,
},
});

View File

@ -23,6 +23,8 @@ var {
View,
} = React;
var base64Icon = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEsAAABLCAQAAACSR7JhAAADtUlEQVR4Ac3YA2Bj6QLH0XPT1Fzbtm29tW3btm3bfLZtv7e2ObZnms7d8Uw098tuetPzrxv8wiISrtVudrG2JXQZ4VOv+qUfmqCGGl1mqLhoA52oZlb0mrjsnhKpgeUNEs91Z0pd1kvihA3ULGVHiQO2narKSHKkEMulm9VgUyE60s1aWoMQUbpZOWE+kaqs4eLEjdIlZTcFZB0ndc1+lhB1lZrIuk5P2aib1NBpZaL+JaOGIt0ls47SKzLC7CqrlGF6RZ09HGoNy1lYl2aRSWL5GuzqWU1KafRdoRp0iOQEiDzgZPnG6DbldcomadViflnl/cL93tOoVbsOLVM2jylvdWjXolWX1hmfZbGR/wjypDjFLSZIRov09BgYmtUqPQPlQrPapecLgTIy0jMgPKtTeob2zWtrGH3xvjUkPCtNg/tm1rjwrMa+mdUkPd3hWbH0jArPGiU9ufCsNNWFZ40wpwn+62/66R2RUtoso1OB34tnLOcy7YB1fUdc9e0q3yru8PGM773vXsuZ5YIZX+5xmHwHGVvlrGPN6ZSiP1smOsMMde40wKv2VmwPPVXNut4sVpUreZiLBHi0qln/VQeI/LTMYXpsJtFiclUN+5HVZazim+Ky+7sAvxWnvjXrJFneVtLWLyPJu9K3cXLWeOlbMTlrIelbMDlrLenrjEQOtIF+fuI9xRp9ZBFp6+b6WT8RrxEpdK64BuvHgDk+vUy+b5hYk6zfyfs051gRoNO1usU12WWRWL73/MMEy9pMi9qIrR4ZpV16Rrvduxazmy1FSvuFXRkqTnE7m2kdb5U8xGjLw/spRr1uTov4uOgQE+0N/DvFrG/Jt7i/FzwxbA9kDanhf2w+t4V97G8lrT7wc08aA2QNUkuTfW/KimT01wdlfK4yEw030VfT0RtZbzjeMprNq8m8tnSTASrTLti64oBNdpmMQm0eEwvfPwRbUBywG5TzjPCsdwk3IeAXjQblLCoXnDVeoAz6SfJNk5TTzytCNZk/POtTSV40NwOFWzw86wNJRpubpXsn60NJFlHeqlYRbslqZm2jnEZ3qcSKgm0kTli3zZVS7y/iivZTweYXJ26Y+RTbV1zh3hYkgyFGSTKPfRVbRqWWVReaxYeSLarYv1Qqsmh1s95S7G+eEWK0f3jYKTbV6bOwepjfhtafsvUsqrQvrGC8YhmnO9cSCk3yuY984F1vesdHYhWJ5FvASlacshUsajFt2mUM9pqzvKGcyNJW0arTKN1GGGzQlH0tXwLDgQTurS8eIQAAAABJRU5ErkJggg==';
var TabBarExample = React.createClass({
statics: {
title: '<TabBarIOS>',
@ -55,6 +57,7 @@ var TabBarExample = React.createClass({
barTintColor="darkslateblue">
<TabBarIOS.Item
title="Blue Tab"
icon={{uri: base64Icon, scale: 3}}
selected={this.state.selectedTab === 'blueTab'}
onPress={() => {
this.setState({

View File

@ -27,6 +27,7 @@ var {
} = React;
exports.displayName = (undefined: ?string);
exports.description = 'Touchable and onPress examples';
exports.title = '<Touchable*> and onPress';
exports.examples = [
{

View File

@ -25,7 +25,7 @@
13DF61B61B67A45000EDB188 /* RCTMethodArgumentTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 13DF61B51B67A45000EDB188 /* RCTMethodArgumentTests.m */; };
141FC1211B222EBB004D5FFB /* IntegrationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 141FC1201B222EBB004D5FFB /* IntegrationTests.m */; };
143BC5A11B21E45C00462512 /* UIExplorerSnapshotTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 143BC5A01B21E45C00462512 /* UIExplorerSnapshotTests.m */; };
144D21241B2204C5006DB32B /* RCTClipRectTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 144D21231B2204C5006DB32B /* RCTClipRectTests.m */; };
144D21241B2204C5006DB32B /* RCTImageUtilTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 144D21231B2204C5006DB32B /* RCTImageUtilTests.m */; };
147CED4C1AB3532B00DA3E4C /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 147CED4B1AB34F8C00DA3E4C /* libRCTActionSheet.a */; };
1497CFAC1B21F5E400C1F8F2 /* RCTAllocationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1497CFA41B21F5E400C1F8F2 /* RCTAllocationTests.m */; };
1497CFAD1B21F5E400C1F8F2 /* RCTBridgeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1497CFA51B21F5E400C1F8F2 /* RCTBridgeTests.m */; };
@ -54,6 +54,7 @@
3578590A1B28D2CF00341EDB /* libRCTLinking.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 357859011B28D2C500341EDB /* libRCTLinking.a */; };
834C36EC1AF8DED70019C93C /* libRCTSettings.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 834C36D21AF8DA610019C93C /* libRCTSettings.a */; };
83636F8F1B53F22C009F943E /* RCTUIManagerScenarioTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 83636F8E1B53F22C009F943E /* RCTUIManagerScenarioTests.m */; };
83A936C81B7E0F08005B9C36 /* RCTConvert_UIColorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 83A936C71B7E0F08005B9C36 /* RCTConvert_UIColorTests.m */; };
D85B829E1AB6D5D7003F4FE2 /* libRCTVibration.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D85B829C1AB6D5CE003F4FE2 /* libRCTVibration.a */; };
/* End PBXBuildFile section */
@ -191,7 +192,7 @@
143BC5951B21E3E100462512 /* UIExplorerIntegrationTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UIExplorerIntegrationTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
143BC5981B21E3E100462512 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
143BC5A01B21E45C00462512 /* UIExplorerSnapshotTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIExplorerSnapshotTests.m; sourceTree = "<group>"; };
144D21231B2204C5006DB32B /* RCTClipRectTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTClipRectTests.m; sourceTree = "<group>"; };
144D21231B2204C5006DB32B /* RCTImageUtilTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTImageUtilTests.m; sourceTree = "<group>"; };
1497CFA41B21F5E400C1F8F2 /* RCTAllocationTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTAllocationTests.m; sourceTree = "<group>"; };
1497CFA51B21F5E400C1F8F2 /* RCTBridgeTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTBridgeTests.m; sourceTree = "<group>"; };
1497CFA61B21F5E400C1F8F2 /* RCTContextExecutorTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTContextExecutorTests.m; sourceTree = "<group>"; };
@ -216,6 +217,7 @@
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>"; };
83636F8E1B53F22C009F943E /* RCTUIManagerScenarioTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTUIManagerScenarioTests.m; sourceTree = "<group>"; };
83A936C71B7E0F08005B9C36 /* RCTConvert_UIColorTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTConvert_UIColorTests.m; sourceTree = "<group>"; };
D85B82911AB6D5CE003F4FE2 /* RCTVibration.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTVibration.xcodeproj; path = ../../Libraries/Vibration/RCTVibration.xcodeproj; sourceTree = "<group>"; };
/* End PBXFileReference section */
@ -357,12 +359,13 @@
1497CFA41B21F5E400C1F8F2 /* RCTAllocationTests.m */,
1497CFA51B21F5E400C1F8F2 /* RCTBridgeTests.m */,
138D6A151B53CD440074A87E /* RCTCacheTests.m */,
144D21231B2204C5006DB32B /* RCTClipRectTests.m */,
1497CFA61B21F5E400C1F8F2 /* RCTContextExecutorTests.m */,
1497CFA71B21F5E400C1F8F2 /* RCTConvert_NSURLTests.m */,
83A936C71B7E0F08005B9C36 /* RCTConvert_UIColorTests.m */,
1497CFA81B21F5E400C1F8F2 /* RCTConvert_UIFontTests.m */,
1497CFA91B21F5E400C1F8F2 /* RCTEventDispatcherTests.m */,
1300627E1B59179B0043FE5A /* RCTGzipTests.m */,
144D21231B2204C5006DB32B /* RCTImageUtilTests.m */,
13DB03471B5D2ED500C27245 /* RCTJSONTests.m */,
13DF61B51B67A45000EDB188 /* RCTMethodArgumentTests.m */,
1393D0371B68CD1300E1B601 /* RCTModuleMethodTests.m */,
@ -793,7 +796,7 @@
buildActionMask = 2147483647;
files = (
1497CFB01B21F5E400C1F8F2 /* RCTConvert_UIFontTests.m in Sources */,
144D21241B2204C5006DB32B /* RCTClipRectTests.m in Sources */,
144D21241B2204C5006DB32B /* RCTImageUtilTests.m in Sources */,
1393D0381B68CD1300E1B601 /* RCTModuleMethodTests.m in Sources */,
1497CFB21B21F5E400C1F8F2 /* RCTSparseArrayTests.m in Sources */,
1300627F1B59179B0043FE5A /* RCTGzipTests.m in Sources */,
@ -805,6 +808,7 @@
138D6A171B53CD440074A87E /* RCTCacheTests.m in Sources */,
13DB03481B5D2ED500C27245 /* RCTJSONTests.m in Sources */,
1497CFAC1B21F5E400C1F8F2 /* RCTAllocationTests.m in Sources */,
83A936C81B7E0F08005B9C36 /* RCTConvert_UIColorTests.m in Sources */,
13DF61B61B67A45000EDB188 /* RCTMethodArgumentTests.m in Sources */,
138D6A181B53CD440074A87E /* RCTShadowViewTests.m in Sources */,
);

View File

@ -30,10 +30,11 @@
launchOptions:launchOptions];
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
moduleName:@"UIExplorerApp"];
moduleName:@"UIExplorerApp"
initialProperties:nil];
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIViewController *rootViewController = [[UIViewController alloc] init];
UIViewController *rootViewController = [UIViewController new];
rootViewController.view = rootView;
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];

View File

@ -29,7 +29,7 @@
RCTAssert(NO, @"Tests should be run on 32-bit device simulators (e.g. iPhone 5)");
#endif
NSOperatingSystemVersion version = [[NSProcessInfo processInfo] operatingSystemVersion];
NSOperatingSystemVersion version = [NSProcessInfo processInfo].operatingSystemVersion;
RCTAssert(version.majorVersion == 8 || version.minorVersion >= 3, @"Tests should be run on iOS 8.3+, found %zd.%zd.%zd", version.majorVersion, version.minorVersion, version.patchVersion);
_runner = RCTInitRunnerForApp(@"Examples/UIExplorer/UIExplorerIntegrationTests/js/IntegrationTestsApp", nil);
}

View File

@ -45,12 +45,12 @@
{
[super setUp];
_uiManager = [[RCTUIManager alloc] init];
_uiManager = [RCTUIManager new];
// Register 20 views to use in the tests
for (NSInteger i = 1; i <= 20; i++) {
UIView *registeredView = [[UIView alloc] init];
[registeredView setReactTag:@(i)];
UIView *registeredView = [UIView new];
registeredView.reactTag = @(i);
_uiManager.viewRegistry[i] = registeredView;
}
}
@ -92,7 +92,7 @@
NSArray *removeAtIndices = @[@0, @4, @8, @12, @16];
for (NSNumber *index in removeAtIndices) {
NSNumber *reactTag = @([index integerValue] + 2);
NSNumber *reactTag = @(index.integerValue + 2);
[removedViews addObject:_uiManager.viewRegistry[reactTag]];
}
for (NSInteger i = 2; i < 20; i++) {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View File

@ -36,7 +36,7 @@
RCTAssert(NO, @"Tests should be run on 32-bit device simulators (e.g. iPhone 5)");
#endif
NSOperatingSystemVersion version = [[NSProcessInfo processInfo] operatingSystemVersion];
NSOperatingSystemVersion version = [NSProcessInfo processInfo].operatingSystemVersion;
RCTAssert(version.majorVersion == 8 || version.minorVersion >= 3, @"Snapshot tests should be run on iOS 8.3+, found %zd.%zd.%zd", version.majorVersion, version.minorVersion, version.patchVersion);
_runner = RCTInitRunnerForApp(@"Examples/UIExplorer/UIExplorerApp.ios", nil);
_runner.recordMode = NO;

View File

@ -49,7 +49,7 @@ var COMPONENTS = [
require('./SwitchIOSExample'),
require('./TabBarIOSExample'),
require('./TextExample.ios'),
require('./TextInputExample'),
require('./TextInputExample.ios'),
require('./TouchableExample'),
require('./ViewExample'),
require('./WebViewExample'),
@ -74,7 +74,7 @@ var APIS = [
require('./StatusBarIOSExample'),
require('./TimerExample'),
require('./VibrationIOSExample'),
require('./XHRExample'),
require('./XHRExample.ios'),
require('./ImageEditingExample'),
];
@ -123,32 +123,6 @@ class UIExplorerList extends React.Component {
);
}
componentDidMount() {
var wasUIExplorer = false;
var didOpenExample = false;
this.props.navigator.navigationContext.addListener('didfocus', (event) => {
var isUIExplorer = event.data.route.title === 'UIExplorer';
if (!didOpenExample && isUIExplorer) {
didOpenExample = true;
var visibleExampleTitle = Settings.get('visibleExample');
if (visibleExampleTitle) {
var predicate = (example) => example.title === visibleExampleTitle;
var foundExample = APIS.find(predicate) || COMPONENTS.find(predicate);
if (foundExample) {
setTimeout(() => this._openExample(foundExample), 100);
}
} else if (!wasUIExplorer && isUIExplorer) {
Settings.set({visibleExample: null});
}
}
wasUIExplorer = isUIExplorer;
});
}
renderAdditionalView(renderRow: Function, renderTextInput: Function): React.Component {
return renderTextInput(styles.searchTextInput);
}
@ -171,7 +145,6 @@ class UIExplorerList extends React.Component {
}
onPressRow(example: any) {
Settings.set({visibleExample: example.title});
this._openExample(example);
}
}

View File

@ -42,15 +42,16 @@ _Pragma("clang diagnostic pop")
@end
@interface AllocationTestModule : NSObject<RCTBridgeModule, RCTInvalidating>
@property (nonatomic, assign, getter=isValid) BOOL valid;
@end
@implementation AllocationTestModule
RCT_EXPORT_MODULE();
@synthesize valid = _valid;
- (id)init
- (instancetype)init
{
if ((self = [super init])) {
_valid = YES;
@ -81,6 +82,7 @@ RCT_EXPORT_METHOD(test:(__unused NSString *)a
@autoreleasepool {
RCTRootView *view = [[RCTRootView alloc] initWithBundleURL:nil
moduleName:@""
initialProperties:nil
launchOptions:nil];
weakBridge = view.bridge;
XCTAssertNotNil(weakBridge, @"RCTBridge should have been created");
@ -92,7 +94,7 @@ RCT_EXPORT_METHOD(test:(__unused NSString *)a
- (void)testModulesAreInvalidated
{
AllocationTestModule *module = [[AllocationTestModule alloc] init];
AllocationTestModule *module = [AllocationTestModule new];
@autoreleasepool {
RCTBridge *bridge = [[RCTBridge alloc] initWithBundleURL:nil
moduleProvider:^{
@ -111,7 +113,7 @@ RCT_EXPORT_METHOD(test:(__unused NSString *)a
{
__weak AllocationTestModule *weakModule;
@autoreleasepool {
AllocationTestModule *module = [[AllocationTestModule alloc] init];
AllocationTestModule *module = [AllocationTestModule new];
RCTBridge *bridge = [[RCTBridge alloc] initWithBundleURL:nil
moduleProvider:^{
return @[module];
@ -177,15 +179,15 @@ RCT_EXPORT_METHOD(test:(__unused NSString *)a
RCTBridge *bridge = [[RCTBridge alloc] initWithBundleURL:nil
moduleProvider:nil
launchOptions:nil];
__weak id rootContentView;
__weak UIView *rootContentView;
@autoreleasepool {
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge moduleName:@""];
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge moduleName:@"" initialProperties:nil];
RUN_RUNLOOP_WHILE(!(rootContentView = [rootView valueForKey:@"contentView"]))
XCTAssertTrue([rootContentView isValid], @"RCTContentView should be valid");
XCTAssertTrue(rootContentView.userInteractionEnabled, @"RCTContentView should be valid");
(void)rootView;
}
XCTAssertFalse([rootContentView isValid], @"RCTContentView should have been invalidated");
XCTAssertFalse(rootContentView.userInteractionEnabled, @"RCTContentView should have been invalidated");
}
- (void)testUnderlyingBridgeIsDeallocated

View File

@ -37,7 +37,7 @@
- (void)setUp
{
self.cache = [[RCTCache alloc] init];
self.cache = [RCTCache new];
self.cache.countLimit = 3;
self.cache.totalCostLimit = 100;
}

View File

@ -33,7 +33,7 @@
- (void)setUp
{
[super setUp];
_executor = [[RCTContextExecutor alloc] init];
_executor = [RCTContextExecutor new];
[_executor setUp];
}
@ -129,7 +129,7 @@ static uint64_t _get_time_nanoseconds(void)
";
[_executor executeApplicationScript:script sourceURL:[NSURL URLWithString:@"http://localhost:8081/"] onComplete:^(__unused NSError *error) {
NSMutableArray *params = [[NSMutableArray alloc] init];
NSMutableArray *params = [NSMutableArray new];
id data = @1;
for (int i = 0; i < 4; i++) {
double samples[runs / frequency];

View File

@ -0,0 +1,79 @@
/**
* The examples provided by Facebook are for non-commercial testing and
* evaluation purposes only.
*
* Facebook reserves all rights not expressly granted.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#import <XCTest/XCTest.h>
#import "RCTConvert.h"
@interface RCTConvert_UIColorTests : XCTestCase
@end
@implementation RCTConvert_UIColorTests
#define XCTAssertEqualColors(color1, color2) do { \
CGFloat r1, g1, b1, a1; \
CGFloat r2, g2, b2, a2; \
XCTAssertTrue([(color1) getRed:&r1 green:&g1 blue:&b1 alpha:&a1] && \
[(color2) getRed:&r2 green:&g2 blue:&b2 alpha:&a2] && \
r1 == r2 && g1 == g2 && b1 == b2 && a1 == a2, \
@"rgba(%d, %d, %d, %.3f) != rgba(%d, %d, %d, %.3f)", \
(int)(r1 * 255), (int)(g1 * 255), (int)(b1 * 255), a1, \
(int)(r2 * 255), (int)(g2 * 255), (int)(b2 * 255), a2 \
); \
} while (0)
- (void)testHex3
{
UIColor *color = [RCTConvert UIColor:@"#333"];
UIColor *expected = [UIColor colorWithWhite:0.2 alpha:1.0];
XCTAssertEqualColors(color, expected);
}
- (void)testHex6
{
UIColor *color = [RCTConvert UIColor:@"#666"];
UIColor *expected = [UIColor colorWithWhite:0.4 alpha:1.0];
XCTAssertEqualColors(color, expected);
}
- (void)testRGB
{
UIColor *color = [RCTConvert UIColor:@"rgb(51, 102, 153)"];
UIColor *expected = [UIColor colorWithRed:0.2 green:0.4 blue:0.6 alpha:1.0];
XCTAssertEqualColors(color, expected);
}
- (void)testRGBA
{
UIColor *color = [RCTConvert UIColor:@"rgba(51, 102, 153, 0.5)"];
UIColor *expected = [UIColor colorWithRed:0.2 green:0.4 blue:0.6 alpha:0.5];
XCTAssertEqualColors(color, expected);
}
- (void)testHSL
{
UIColor *color = [RCTConvert UIColor:@"hsl(30, 50%, 50%)"];
UIColor *expected = [UIColor colorWithHue:30.0 / 360.0 saturation:0.5 brightness:0.5 alpha:1.0];
XCTAssertEqualColors(color, expected);
}
- (void)testHSLA
{
UIColor *color = [RCTConvert UIColor:@"hsla(30, 50%, 50%, 0.5)"];
UIColor *expected = [UIColor colorWithHue:30.0 / 360.0 saturation:0.5 brightness:0.5 alpha:0.5];
XCTAssertEqualColors(color, expected);
}
@end

View File

@ -162,8 +162,8 @@
- (void)testFamilyStyleAndWeight
{
{
UIFont *expected = [UIFont fontWithName:@"HelveticaNeue-UltraLightItalic" size:14];
UIFont *result = [RCTConvert UIFont:@{@"fontFamily": @"Helvetica Neue", @"fontStyle": @"italic", @"fontWeight": @"100"}];
UIFont *expected = [UIFont fontWithName:@"HelveticaNeue-LightItalic" size:14];
UIFont *result = [RCTConvert UIFont:@{@"fontFamily": @"Helvetica Neue", @"fontStyle": @"italic", @"fontWeight": @"300"}];
RCTAssertEqualFonts(expected, result);
}
{

View File

@ -61,7 +61,7 @@
[super setUp];
_bridge = [OCMockObject mockForClass:[RCTBridge class]];
_eventDispatcher = [[RCTEventDispatcher alloc] init];
_eventDispatcher = [RCTEventDispatcher new];
((id<RCTBridgeModule>)_eventDispatcher).bridge = _bridge;
_eventName = RCTNormalizeInputEventName(@"sampleEvent");

View File

@ -67,7 +67,7 @@ extern BOOL RCTIsGzippedData(NSData *data);
@"headers": @{@"Content-Encoding": @"gzip"},
};
RCTNetworking *networker = [[RCTNetworking alloc] init];
RCTNetworking *networker = [RCTNetworking new];
__block NSURLRequest *request = nil;
[networker buildRequest:query completionBlock:^(NSURLRequest *_request) {
request = _request;

View File

@ -33,11 +33,11 @@ RCTAssertEqualPoints(a.origin, b.origin); \
RCTAssertEqualSizes(a.size, b.size); \
}
@interface RCTClipRectTests : XCTestCase
@interface RCTImageUtilTests : XCTestCase
@end
@implementation RCTClipRectTests
@implementation RCTImageUtilTests
- (void)testLandscapeSourceLandscapeTarget
{
@ -46,19 +46,19 @@ RCTAssertEqualSizes(a.size, b.size); \
{
CGRect expected = {CGPointZero, {100, 20}};
CGRect result = RCTClipRect(content, 1, target, 1, UIViewContentModeScaleToFill);
CGRect result = RCTTargetRect(content, target, 1, UIViewContentModeScaleToFill);
RCTAssertEqualRects(expected, result);
}
{
CGRect expected = {CGPointZero, {100, 10}};
CGRect result = RCTClipRect(content, 1, target, 1, UIViewContentModeScaleAspectFit);
CGRect result = RCTTargetRect(content, target, 1, UIViewContentModeScaleAspectFit);
RCTAssertEqualRects(expected, result);
}
{
CGRect expected = {{-50, 0}, {200, 20}};
CGRect result = RCTClipRect(content, 1, target, 1, UIViewContentModeScaleAspectFill);
CGRect result = RCTTargetRect(content, target, 1, UIViewContentModeScaleAspectFill);
RCTAssertEqualRects(expected, result);
}
}
@ -69,20 +69,20 @@ RCTAssertEqualSizes(a.size, b.size); \
CGSize target = {100, 20};
{
CGRect expected = {CGPointZero, {10, 20}};
CGRect result = RCTClipRect(content, 1, target, 1, UIViewContentModeScaleToFill);
CGRect expected = {CGPointZero, {100, 20}};
CGRect result = RCTTargetRect(content, target, 1, UIViewContentModeScaleToFill);
RCTAssertEqualRects(expected, result);
}
{
CGRect expected = {CGPointZero, {2, 20}};
CGRect result = RCTClipRect(content, 1, target, 1, UIViewContentModeScaleAspectFit);
CGRect result = RCTTargetRect(content, target, 1, UIViewContentModeScaleAspectFit);
RCTAssertEqualRects(expected, result);
}
{
CGRect expected = {{0, -49}, {10, 100}};
CGRect result = RCTClipRect(content, 1, target, 1, UIViewContentModeScaleAspectFill);
CGRect expected = {{0, -490}, {100, 1000}};
CGRect result = RCTTargetRect(content, target, 1, UIViewContentModeScaleAspectFill);
RCTAssertEqualRects(expected, result);
}
}
@ -93,20 +93,20 @@ RCTAssertEqualSizes(a.size, b.size); \
CGSize target = {20, 50};
{
CGRect expected = {CGPointZero, {10, 50}};
CGRect result = RCTClipRect(content, 1, target, 1, UIViewContentModeScaleToFill);
CGRect expected = {CGPointZero, {20, 50}};
CGRect result = RCTTargetRect(content, target, 1, UIViewContentModeScaleToFill);
RCTAssertEqualRects(expected, result);
}
{
CGRect expected = {CGPointZero, {5, 50}};
CGRect result = RCTClipRect(content, 1, target, 1, UIViewContentModeScaleAspectFit);
CGRect result = RCTTargetRect(content, target, 1, UIViewContentModeScaleAspectFit);
RCTAssertEqualRects(expected, result);
}
{
CGRect expected = {{0, -37.5}, {10, 100}};
CGRect result = RCTClipRect(content, 2, target, 2, UIViewContentModeScaleAspectFill);
CGRect expected = {{0, -75}, {20, 200}};
CGRect result = RCTTargetRect(content, target, 2, UIViewContentModeScaleAspectFill);
RCTAssertEqualRects(expected, result);
}
}
@ -117,8 +117,8 @@ RCTAssertEqualSizes(a.size, b.size); \
CGSize target = {20, 50};
{
CGRect expected = {{0, -38}, {10, 100}};
CGRect result = RCTClipRect(content, 1, target, 1, UIViewContentModeScaleAspectFill);
CGRect expected = {{0, -75}, {20, 200}};
CGRect result = RCTTargetRect(content, target, 1, UIViewContentModeScaleAspectFill);
RCTAssertEqualRects(expected, result);
}
}
@ -129,7 +129,7 @@ RCTAssertEqualSizes(a.size, b.size); \
CGSize target = {3, 3};
CGRect expected = {CGPointZero, {3, 3}};
CGRect result = RCTClipRect(content, 2, target, 1, UIViewContentModeScaleToFill);
CGRect result = RCTTargetRect(content, target, 1, UIViewContentModeScaleToFill);
RCTAssertEqualRects(expected, result);
}

View File

@ -15,6 +15,7 @@
#import <UIKit/UIKit.h>
#import <XCTest/XCTest.h>
#import "RCTBridgeModule.h"
#import "RCTModuleMethod.h"
#import "RCTLog.h"
@ -30,11 +31,16 @@ static BOOL RCTLogsError(void (^block)(void))
return loggedError;
}
@interface RCTModuleMethodTests : XCTestCase
@interface RCTModuleMethodTests : XCTestCase <RCTBridgeModule>
@end
@implementation RCTModuleMethodTests
{
CGRect _s;
}
+ (NSString *)moduleName { return nil; }
- (void)doFooWithBar:(__unused NSString *)bar { }
@ -56,6 +62,7 @@ static BOOL RCTLogsError(void (^block)(void))
- (void)doFooWithNumber:(__unused NSNumber *)n { }
- (void)doFooWithDouble:(__unused double)n { }
- (void)doFooWithInteger:(__unused NSInteger)n { }
- (void)doFooWithCGRect:(CGRect)s { _s = s; }
- (void)testNumbersNonnull
{
@ -63,9 +70,11 @@ static BOOL RCTLogsError(void (^block)(void))
// Specifying an NSNumber param without nonnull isn't allowed
XCTAssertTrue(RCTLogsError(^{
NSString *methodName = @"doFooWithNumber:(NSNumber *)n";
(void)[[RCTModuleMethod alloc] initWithObjCMethodName:methodName
JSMethodName:nil
moduleClass:[self class]];
RCTModuleMethod *method = [[RCTModuleMethod alloc] initWithObjCMethodName:methodName
JSMethodName:nil
moduleClass:[self class]];
// Invoke method to trigger parsing
[method invokeWithBridge:nil module:self arguments:@[@1]];
}));
}
@ -100,4 +109,16 @@ static BOOL RCTLogsError(void (^block)(void))
}
}
- (void)testStructArgument
{
NSString *methodName = @"doFooWithCGRect:(CGRect)s";
RCTModuleMethod *method = [[RCTModuleMethod alloc] initWithObjCMethodName:methodName
JSMethodName:nil
moduleClass:[self class]];
CGRect r = CGRectMake(10, 20, 30, 40);
[method invokeWithBridge:nil module:self arguments:@[@[@10, @20, @30, @40]]];
XCTAssertTrue(CGRectEqualToRect(r, _s));
}
@end

View File

@ -99,7 +99,7 @@
- (RCTShadowView *)_shadowViewWithStyle:(void(^)(css_style_t *style))styleBlock
{
RCTShadowView *shadowView = [[RCTShadowView alloc] init];
RCTShadowView *shadowView = [RCTShadowView new];
css_style_t style = shadowView.cssNode->style;
styleBlock(&style);

View File

@ -25,13 +25,13 @@
- (void)testDictionary
{
id<RCTComponent> myView = [[UIView alloc] init];
id<RCTComponent> myView = [UIView new];
myView.reactTag = @4;
id<RCTComponent> myOtherView = [[UIView alloc] init];
id<RCTComponent> myOtherView = [UIView new];
myOtherView.reactTag = @5;
RCTSparseArray *registry = [[RCTSparseArray alloc] init];
RCTSparseArray *registry = [RCTSparseArray new];
XCTAssertNil(registry[@4], @"how did you have a view when none are registered?");
XCTAssertNil(registry[@5], @"how did you have a view when none are registered?");

View File

@ -44,12 +44,12 @@
{
[super setUp];
_uiManager = [[RCTUIManager alloc] init];
_uiManager = [RCTUIManager new];
// Register 20 views to use in the tests
for (NSInteger i = 1; i <= 20; i++) {
UIView *registeredView = [[UIView alloc] init];
[registeredView setReactTag:@(i)];
UIView *registeredView = [UIView new];
registeredView.reactTag = @(i);
_uiManager.viewRegistry[i] = registeredView;
}
}
@ -91,7 +91,7 @@
NSArray *removeAtIndices = @[@0, @4, @8, @12, @16];
for (NSNumber *index in removeAtIndices) {
NSNumber *reactTag = @([index integerValue] + 2);
NSNumber *reactTag = @(index.integerValue + 2);
[removedViews addObject:_uiManager.viewRegistry[reactTag]];
}
for (NSInteger i = 2; i < 20; i++) {

View File

@ -8,7 +8,7 @@
#include "JSProfilerPrivate.h"
#include "JSStringRef.h"
#include <yajl/yajl_gen.h>
#include <YAJL/yajl_gen.h>
#define GEN_AND_CHECK(expr) \
do { \

View File

@ -1,6 +1,12 @@
HEADER_PATHS := `find ./tmp/JavaScriptCore -name '*.h' | xargs -I{} dirname {} | uniq | xargs -I{} echo "-I {}"`
SDK_VERSION=$(shell plutil -convert json -o - /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/SDKSettings.plist | awk -f parseSDKVersion.awk)
CERT ?= "iPhone Developer"
ifneq ($(SDK_VERSION), 8)
all:
$(error "Expected to be compiled with iOS SDK version 8, found $(SDK_VERSION)")
endif
ios8: prepare build generate
prepare: clean create download
@ -45,8 +51,8 @@ yajl:
echo `find . -name '*.c'`
cd ./tmp/yajl-2.1.0/src && \
clang -arch arm64 -arch armv7 -std=c99 \
-I /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.3.sdk/usr/include/ \
-I /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.3.sdk/usr/include/machine \
-I /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/include/ \
-I /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/include/machine \
-I ../build/yajl-2.1.0/include \
-c `find . -name '*.c'`
libtool -static -o ./tmp/yajl.a `find ./tmp/yajl-2.1.0/src/ -name '*.o'`
@ -77,12 +83,12 @@ arm64:
-I ./tmp/WebCore-7600.1.25/icu \
-I ./tmp/WTF-7600.1.24 \
-I ./tmp/yajl-2.1.0/build/yajl-2.1.0/include \
-I /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.3.sdk/usr/include \
-I /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.3.sdk/usr/include/machine \
-I /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/include \
-I /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/include/machine \
-DNDEBUG=1\
-miphoneos-version-min=8.0 \
-L /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.3.sdk/usr/lib \
-L /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.3.sdk/usr/lib/system \
-L /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/lib \
-L /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/lib/system \
${HEADER_PATHS} \
-undefined dynamic_lookup \
./JSCLegacyProfiler.mm ./tmp/yajl.a
@ -96,11 +102,11 @@ armv7:
-I ./tmp/WebCore-7600.1.25/icu \
-I ./tmp/WTF-7600.1.24 \
-I ./tmp/yajl-2.1.0/build/yajl-2.1.0/include \
-I /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.3.sdk/usr/include \
-I /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/include \
-DNDEBUG=1\
-miphoneos-version-min=8.0 \
-L /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.3.sdk/usr/lib \
-L /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.3.sdk/usr/lib/system \
-L /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/lib \
-L /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/lib/system \
${HEADER_PATHS} \
-undefined dynamic_lookup \
./JSCLegacyProfiler.mm ./tmp/yajl.a

View File

@ -0,0 +1,10 @@
BEGIN {
FS = ":"
RS = ","
}
/"Version"/ {
version = substr($2, 2, length($2) - 2)
print int(version)
exit 0
}

View File

@ -27,7 +27,7 @@ RCT_EXPORT_MODULE()
- (instancetype)init
{
if ((self = [super init])) {
_callbacks = [[NSMutableDictionary alloc] init];
_callbacks = [NSMutableDictionary new];
}
return self;
}
@ -41,7 +41,7 @@ RCT_EXPORT_METHOD(showActionSheetWithOptions:(NSDictionary *)options
failureCallback:(__unused RCTResponseSenderBlock)failureCallback
successCallback:(RCTResponseSenderBlock)successCallback)
{
UIActionSheet *actionSheet = [[UIActionSheet alloc] init];
UIActionSheet *actionSheet = [UIActionSheet new];
actionSheet.title = options[@"title"];
@ -60,7 +60,7 @@ RCT_EXPORT_METHOD(showActionSheetWithOptions:(NSDictionary *)options
_callbacks[RCTKeyForInstance(actionSheet)] = successCallback;
UIWindow *appWindow = [[[UIApplication sharedApplication] delegate] window];
UIWindow *appWindow = [UIApplication sharedApplication].delegate.window;
if (appWindow == nil) {
RCTLogError(@"Tried to display action sheet but there is no application window. options: %@", options);
return;
@ -81,12 +81,12 @@ RCT_EXPORT_METHOD(showShareActionSheetWithOptions:(NSDictionary *)options
if (URL) {
[items addObject:URL];
}
if ([items count] == 0) {
if (items.count == 0) {
failureCallback(@[@"No `url` or `message` to share"]);
return;
}
UIActivityViewController *share = [[UIActivityViewController alloc] initWithActivityItems:items applicationActivities:nil];
UIViewController *ctrl = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
UIViewController *ctrl = [UIApplication sharedApplication].delegate.window.rootViewController;
#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_8_0
@ -126,7 +126,7 @@ RCT_EXPORT_METHOD(showShareActionSheetWithOptions:(NSDictionary *)options
RCTLogWarn(@"No callback registered for action sheet: %@", actionSheet.title);
}
[[[[UIApplication sharedApplication] delegate] window] makeKeyWindow];
[[UIApplication sharedApplication].delegate.window makeKeyWindow];
}
#pragma mark Private

View File

@ -33,13 +33,13 @@ type EndCallback = (result: EndResult) => void;
// Note(vjeux): this would be better as an interface but flow doesn't
// support them yet
class Animated {
attach(): void {}
detach(): void {}
__attach(): void {}
__detach(): void {}
__getValue(): any {}
getAnimatedValue(): any { return this.__getValue(); }
addChild(child: Animated) {}
removeChild(child: Animated) {}
getChildren(): Array<Animated> { return []; }
__getAnimatedValue(): any { return this.__getValue(); }
__addChild(child: Animated) {}
__removeChild(child: Animated) {}
__getChildren(): Array<Animated> { return []; }
}
// Important note: start() and stop() will only be called at most once.
@ -71,14 +71,14 @@ class AnimatedWithChildren extends Animated {
this._children = [];
}
addChild(child: Animated): void {
__addChild(child: Animated): void {
if (this._children.length === 0) {
this.attach();
this.__attach();
}
this._children.push(child);
}
removeChild(child: Animated): void {
__removeChild(child: Animated): void {
var index = this._children.indexOf(child);
if (index === -1) {
console.warn('Trying to remove a child that doesn\'t exist');
@ -86,11 +86,11 @@ class AnimatedWithChildren extends Animated {
}
this._children.splice(index, 1);
if (this._children.length === 0) {
this.detach();
this.__detach();
}
}
getChildren(): Array<Animated> {
__getChildren(): Array<Animated> {
return this._children;
}
}
@ -123,7 +123,7 @@ function _flush(rootNode: AnimatedValue): void {
if (typeof node.update === 'function') {
animatedStyles.add(node);
} else {
node.getChildren().forEach(findAnimatedStyles);
node.__getChildren().forEach(findAnimatedStyles);
}
}
findAnimatedStyles(rootNode);
@ -518,7 +518,7 @@ class AnimatedValue extends AnimatedWithChildren {
this._listeners = {};
}
detach() {
__detach() {
this.stopAnimation();
}
@ -584,7 +584,7 @@ class AnimatedValue extends AnimatedWithChildren {
}
stopTracking(): void {
this._tracking && this._tracking.detach();
this._tracking && this._tracking.__detach();
this._tracking = null;
}
@ -715,12 +715,12 @@ class AnimatedInterpolation extends AnimatedWithChildren {
return new AnimatedInterpolation(this, Interpolation.create(config));
}
attach(): void {
this._parent.addChild(this);
__attach(): void {
this._parent.__addChild(this);
}
detach(): void {
this._parent.removeChild(this);
__detach(): void {
this._parent.__removeChild(this);
}
}
@ -747,13 +747,13 @@ class AnimatedTransform extends AnimatedWithChildren {
});
}
getAnimatedValue(): Array<Object> {
__getAnimatedValue(): Array<Object> {
return this._transforms.map(transform => {
var result = {};
for (var key in transform) {
var value = transform[key];
if (value instanceof Animated) {
result[key] = value.getAnimatedValue();
result[key] = value.__getAnimatedValue();
} else {
// All transform components needed to recompose matrix
result[key] = value;
@ -763,23 +763,23 @@ class AnimatedTransform extends AnimatedWithChildren {
});
}
attach(): void {
__attach(): void {
this._transforms.forEach(transform => {
for (var key in transform) {
var value = transform[key];
if (value instanceof Animated) {
value.addChild(this);
value.__addChild(this);
}
}
});
}
detach(): void {
__detach(): void {
this._transforms.forEach(transform => {
for (var key in transform) {
var value = transform[key];
if (value instanceof Animated) {
value.removeChild(this);
value.__removeChild(this);
}
}
});
@ -814,31 +814,31 @@ class AnimatedStyle extends AnimatedWithChildren {
return style;
}
getAnimatedValue(): Object {
__getAnimatedValue(): Object {
var style = {};
for (var key in this._style) {
var value = this._style[key];
if (value instanceof Animated) {
style[key] = value.getAnimatedValue();
style[key] = value.__getAnimatedValue();
}
}
return style;
}
attach(): void {
__attach(): void {
for (var key in this._style) {
var value = this._style[key];
if (value instanceof Animated) {
value.addChild(this);
value.__addChild(this);
}
}
}
detach(): void {
__detach(): void {
for (var key in this._style) {
var value = this._style[key];
if (value instanceof Animated) {
value.removeChild(this);
value.__removeChild(this);
}
}
}
@ -861,7 +861,7 @@ class AnimatedProps extends Animated {
}
this._props = props;
this._callback = callback;
this.attach();
this.__attach();
}
__getValue(): Object {
@ -877,31 +877,31 @@ class AnimatedProps extends Animated {
return props;
}
getAnimatedValue(): Object {
__getAnimatedValue(): Object {
var props = {};
for (var key in this._props) {
var value = this._props[key];
if (value instanceof Animated) {
props[key] = value.getAnimatedValue();
props[key] = value.__getAnimatedValue();
}
}
return props;
}
attach(): void {
__attach(): void {
for (var key in this._props) {
var value = this._props[key];
if (value instanceof Animated) {
value.addChild(this);
value.__addChild(this);
}
}
}
detach(): void {
__detach(): void {
for (var key in this._props) {
var value = this._props[key];
if (value instanceof Animated) {
value.removeChild(this);
value.__removeChild(this);
}
}
}
@ -918,7 +918,7 @@ function createAnimatedComponent(Component: any): any {
_propsAnimated: AnimatedProps;
componentWillUnmount() {
this._propsAnimated && this._propsAnimated.detach();
this._propsAnimated && this._propsAnimated.__detach();
}
setNativeProps(props) {
@ -940,7 +940,7 @@ function createAnimatedComponent(Component: any): any {
// forceUpdate.
var callback = () => {
if (this.refs[refName].setNativeProps) {
var value = this._propsAnimated.getAnimatedValue();
var value = this._propsAnimated.__getAnimatedValue();
this.refs[refName].setNativeProps(value);
} else {
this.forceUpdate();
@ -960,7 +960,7 @@ function createAnimatedComponent(Component: any): any {
// This way the intermediate state isn't to go to 0 and trigger
// this expensive recursive detaching to then re-attach everything on
// the very next operation.
oldPropsAnimated && oldPropsAnimated.detach();
oldPropsAnimated && oldPropsAnimated.__detach();
}
componentWillReceiveProps(nextProps) {
@ -1000,19 +1000,19 @@ class AnimatedTracking extends Animated {
this._animationClass = animationClass;
this._animationConfig = animationConfig;
this._callback = callback;
this.attach();
this.__attach();
}
__getValue(): Object {
return this._parent.__getValue();
}
attach(): void {
this._parent.addChild(this);
__attach(): void {
this._parent.__addChild(this);
}
detach(): void {
this._parent.removeChild(this);
__detach(): void {
this._parent.__removeChild(this);
}
update(): void {

View File

@ -37,7 +37,7 @@ describe('Animated', () => {
}
}, callback);
expect(anim.getChildren().length).toBe(3);
expect(anim.__getChildren().length).toBe(3);
expect(node.__getValue()).toEqual({
style: {
@ -65,8 +65,8 @@ describe('Animated', () => {
},
});
node.detach();
expect(anim.getChildren().length).toBe(0);
node.__detach();
expect(anim.__getChildren().length).toBe(0);
anim.setValue(1);
expect(callback.mock.calls.length).toBe(1);
@ -74,7 +74,7 @@ describe('Animated', () => {
it('does not detach on updates', () => {
var anim = new Animated.Value(0);
anim.detach = jest.genMockFunction();
anim.__detach = jest.genMockFunction();
var c = new Animated.View();
c.props = {
@ -84,16 +84,16 @@ describe('Animated', () => {
};
c.componentWillMount();
expect(anim.detach).not.toBeCalled();
expect(anim.__detach).not.toBeCalled();
c.componentWillReceiveProps({
style: {
opacity: anim,
},
});
expect(anim.detach).not.toBeCalled();
expect(anim.__detach).not.toBeCalled();
c.componentWillUnmount();
expect(anim.detach).toBeCalled();
expect(anim.__detach).toBeCalled();
});
@ -442,7 +442,7 @@ describe('Animated Vectors', () => {
},
});
node.detach();
node.__detach();
vec.setValue({x: 1, y: 1});
expect(callback.mock.calls.length).toBe(2);

View File

@ -1,268 +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 POPAnimationMixin
* @flow
*/
'use strict';
var POPAnimationOrNull = require('POPAnimation');
var React = require('React');
if (!POPAnimationOrNull) {
// POP animation isn't available in the OSS fork - this is a temporary
// workaround to enable its availability to be determined at runtime.
module.exports = (null : ?{});
} else {
// At this point, POPAnimationOrNull is guaranteed to be
// non-null. Bring it local to preserve type refinement.
var POPAnimation = POPAnimationOrNull;
var invariant = require('invariant');
var warning = require('warning');
var POPAnimationMixin = {
/**
* Different ways to interpolate between beginning and end states
* of properties during animation, such as spring, linear, and decay.
*/
AnimationTypes: POPAnimation.Types,
AnimationProperties: POPAnimation.Properties,
getInitialState: function(): Object {
this._popAnimationEnqueuedAnimationTimeouts = [];
return {
_currentAnimationsByNodeHandle: {},
};
},
_ensureBookkeepingSetup: function(nodeHandle: any) {
if (!this.state._currentAnimationsByNodeHandle[nodeHandle]) {
this.state._currentAnimationsByNodeHandle[nodeHandle] = [];
}
},
/**
* Start animating the View with ref `refKey`.
*
* @param {key} refKey The key to reference the View to be animated.
*
* @param {number|Object} anim Either the identifier returned by
* POPAnimation.create* or an object defining all the necessary
* properties of the animation you wish to start (including type, matching
* an entry in AnimationTypes).
*
* @param {func} doneCallback A callback fired when the animation is done, and
* is passed a `finished` param that indicates whether the animation
* completely finished, or was interrupted.
*/
startAnimation: function(
refKey: string,
anim: number | {type: number; property: number;},
doneCallback: (finished: bool) => void
) {
var animID: number = 0;
if (typeof anim === 'number') {
animID = anim;
} else {
invariant(
anim instanceof Object &&
anim.type !== undefined &&
anim.property !== undefined,
'Animation definitions must specify a type of animation and a ' +
'property to animate.'
);
animID = POPAnimation.createAnimation(anim.type, anim);
}
invariant(
this.refs[refKey],
'Invalid refKey ' + refKey + ' for anim:\n' + JSON.stringify(anim) +
'\nvalid refs: ' + JSON.stringify(Object.keys(this.refs))
);
var refNodeHandle = React.findNodeHandle(this.refs[refKey]);
this.startAnimationWithNodeHandle(refNodeHandle, animID, doneCallback);
},
/**
* Starts an animation on a native node.
*
* @param {NodeHandle} nodeHandle Handle to underlying native node.
* @see `startAnimation`.
*/
startAnimationWithNodeHandle: function(
nodeHandle: any,
animID: number,
doneCallback: (finished: bool) => void
) {
this._ensureBookkeepingSetup(nodeHandle);
var animations = this.state._currentAnimationsByNodeHandle[nodeHandle];
var animIndex = animations.length;
animations.push(animID);
var cleanupWrapper = (finished) => {
if (!this.isMounted()) {
return;
}
animations[animIndex] = 0; // zero it out so we don't try to stop it
var allDone = true;
for (var ii = 0; ii < animations.length; ii++) {
if (animations[ii]) {
allDone = false;
break;
}
}
if (allDone) {
this.state._currentAnimationsByNodeHandle[nodeHandle] = undefined;
}
doneCallback && doneCallback(finished);
};
// Hack to aviod race condition in POP:
var animationTimeoutHandler = setTimeout(() => {
POPAnimation.addAnimation(nodeHandle, animID, cleanupWrapper);
}, 1);
this._popAnimationEnqueuedAnimationTimeouts.push(animationTimeoutHandler);
},
/**
* Starts multiple animations with one shared callback that is called when all
* animations complete.
*
* @param {Array(Object} animations Array of objects defining all the
* animations to start, each with shape `{ref|nodeHandle, anim}`.
* @param {func} onSuccess A callback fired when all animations have returned,
* and is passed a finished arg that is true if all animations finished
* completely.
* @param {func} onFailure Not supported yet.
*/
startAnimations: function(
animations: Array<Object>,
onSuccess: (finished: boolean) => void,
onFailure: () => void
) {
var numReturned = 0;
var numFinished = 0;
var numAnimations = animations.length;
var metaCallback = (finished) => {
if (finished) {
++numFinished;
}
if (++numReturned === numAnimations) {
onSuccess && onSuccess(numFinished === numAnimations);
}
};
animations.forEach((anim) => {
warning(
anim.ref != null || anim.nodeHandle != null &&
!anim.ref !== !anim.nodeHandle,
'Animations must be specified with either ref xor nodeHandle'
);
if (anim.ref) {
this.startAnimation(anim.ref, anim.anim, metaCallback);
} else if (anim.nodeHandle) {
this.startAnimationWithNodeHandle(anim.nodeHandle, anim.anim, metaCallback);
}
});
},
/**
* Stop any and all animations operating on the View with native node handle
* `nodeHandle`.
*
* @param {NodeHandle} component The instance to stop animations
* on. Do not pass a composite component.
*/
stopNodeHandleAnimations: function(nodeHandle: any) {
if (!this.state._currentAnimationsByNodeHandle[nodeHandle]) {
return;
}
var anims = this.state._currentAnimationsByNodeHandle[nodeHandle];
for (var i = 0; i < anims.length; i++) {
var anim = anims[i];
if (anim) {
// Note: Converting the string key to a number `nodeHandle`.
POPAnimation.removeAnimation(+nodeHandle, anim);
}
}
this.state._currentAnimationsByNodeHandle[nodeHandle] = undefined;
},
/**
* Stop any and all animations operating on the View with ref `refKey`.
*
* @param {key} refKey The key to reference the View to be animated.
*/
stopAnimations: function(refKey: string) {
invariant(this.refs[refKey], 'invalid ref');
this.stopNodeHandleAnimations(React.findNodeHandle(this.refs[refKey]));
},
/**
* Stop any and all animations created by this component on itself and
* subviews.
*/
stopAllAnimations: function() {
for (var nodeHandle in this.state._currentAnimationsByNodeHandle) {
this.stopNodeHandleAnimations(nodeHandle);
}
},
/**
* Animates size and position of a view referenced by `refKey` to a specific
* frame.
*
* @param {key} refKey ref key for view to animate.
* @param {Object} frame The frame to animate the view to, specified as {left,
* top, width, height}.
* @param {const} type What type of interpolation to use, selected from
* `inperpolationTypes`.
* @param {Object} event Event encapsulating synthetic and native data that
* may have triggered this animation. Velocity is extracted from it if
* possible and applied to the animation.
* @param {func} doneCallback A callback fired when the animation is done, and
* is passed a `finished` param that indicates whether the animation
* completely finished, or was interrupted.
*/
animateToFrame: function(
refKey: string,
frame: {left: number; top: number; width: number; height: number;},
type: number,
velocity: number,
doneCallback: (finished: boolean) => void
) {
var animFrame = { // Animations use a centered coordinate system.
x: frame.left + frame.width / 2,
y: frame.top + frame.height / 2,
w: frame.width,
h: frame.height
};
var posAnim = POPAnimation.createAnimation(type, {
property: POPAnimation.Properties.position,
toValue: [animFrame.x, animFrame.y],
velocity: velocity || [0, 0],
});
var sizeAnim = POPAnimation.createAnimation(type, {
property: POPAnimation.Properties.size,
toValue: [animFrame.w, animFrame.h]
});
this.startAnimation(refKey, posAnim, doneCallback);
this.startAnimation(refKey, sizeAnim);
},
// Cleanup any potentially leaked animations.
componentWillUnmount: function() {
this.stopAllAnimations();
this._popAnimationEnqueuedAnimationTimeouts.forEach(animationTimeoutHandler => {
clearTimeout(animationTimeoutHandler);
});
this._popAnimationEnqueuedAnimationTimeouts = [];
}
};
module.exports = POPAnimationMixin;
}

View File

@ -122,11 +122,7 @@ var AppStateIOS = {
_eventHandlers[type].delete(handler);
},
// 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),
currentState: (RCTAppState && RCTAppState.initialAppState : ?string),
};

View File

@ -1,187 +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 POPAnimation
*/
'use strict';
var RCTPOPAnimationManager = require('NativeModules').POPAnimationManager;
if (!RCTPOPAnimationManager) {
// POP animation isn't available in the OSS fork - this is a temporary
// workaround to enable its availability to be determined at runtime.
// For Flow let's pretend like we always export POPAnimation
// so all our users don't need to do null checks
module.exports = null;
} else {
var ReactPropTypes = require('ReactPropTypes');
var createStrictShapeTypeChecker = require('createStrictShapeTypeChecker');
var getObjectValues = require('getObjectValues');
var invariant = require('invariant');
var merge = require('merge');
var RCTTypes = RCTPOPAnimationManager.Types;
var RCTProperties = RCTPOPAnimationManager.Properties;
var Properties = {
bounds: RCTProperties.bounds,
opacity: RCTProperties.opacity,
position: RCTProperties.position,
positionX: RCTProperties.positionX,
positionY: RCTProperties.positionY,
zPosition: RCTProperties.zPosition,
rotation: RCTProperties.rotation,
rotationX: RCTProperties.rotationX,
rotationY: RCTProperties.rotationY,
scaleX: RCTProperties.scaleX,
scaleXY: RCTProperties.scaleXY,
scaleY: RCTProperties.scaleY,
shadowColor: RCTProperties.shadowColor,
shadowOffset: RCTProperties.shadowOffset,
shadowOpacity: RCTProperties.shadowOpacity,
shadowRadius: RCTProperties.shadowRadius,
size: RCTProperties.size,
subscaleXY: RCTProperties.subscaleXY,
subtranslationX: RCTProperties.subtranslationX,
subtranslationXY: RCTProperties.subtranslationXY,
subtranslationY: RCTProperties.subtranslationY,
subtranslationZ: RCTProperties.subtranslationZ,
translationX: RCTProperties.translationX,
translationXY: RCTProperties.translationXY,
translationY: RCTProperties.translationY,
translationZ: RCTProperties.translationZ,
};
var Types = {
decay: RCTTypes.decay,
easeIn: RCTTypes.easeIn,
easeInEaseOut: RCTTypes.easeInEaseOut,
easeOut: RCTTypes.easeOut,
linear: RCTTypes.linear,
spring: RCTTypes.spring,
};
type Attrs = {
type?: $Enum<typeof Types>;
property?: $Enum<typeof Properties>;
fromValue?: any;
toValue?: any;
duration?: any;
velocity?: any;
deceleration?: any;
springBounciness?: any;
dynamicsFriction?: any;
dynamicsMass?: any;
dynamicsTension?: any;
}
var POPAnimation = {
Types: Types,
Properties: Properties,
attributeChecker: createStrictShapeTypeChecker({
type: ReactPropTypes.oneOf(getObjectValues(Types)),
property: ReactPropTypes.oneOf(getObjectValues(Properties)),
fromValue: ReactPropTypes.any,
toValue: ReactPropTypes.any,
duration: ReactPropTypes.any,
velocity: ReactPropTypes.any,
deceleration: ReactPropTypes.any,
springBounciness: ReactPropTypes.any,
dynamicsFriction: ReactPropTypes.any,
dynamicsMass: ReactPropTypes.any,
dynamicsTension: ReactPropTypes.any,
}),
lastUsedTag: 0,
allocateTagForAnimation: function(): number {
return ++this.lastUsedTag;
},
createAnimation: function(typeName: number, attrs: Attrs): number {
var tag = this.allocateTagForAnimation();
if (__DEV__) {
POPAnimation.attributeChecker(
{attrs},
'attrs',
'POPAnimation.createAnimation'
);
POPAnimation.attributeChecker(
{attrs: {type: typeName}},
'attrs',
'POPAnimation.createAnimation'
);
}
RCTPOPAnimationManager.createAnimationInternal(tag, typeName, attrs);
return tag;
},
createSpringAnimation: function(attrs: Attrs): number {
return this.createAnimation(this.Types.spring, attrs);
},
createDecayAnimation: function(attrs: Attrs): number {
return this.createAnimation(this.Types.decay, attrs);
},
createLinearAnimation: function(attrs: Attrs): number {
return this.createAnimation(this.Types.linear, attrs);
},
createEaseInAnimation: function(attrs: Attrs): number {
return this.createAnimation(this.Types.easeIn, attrs);
},
createEaseOutAnimation: function(attrs: Attrs): number {
return this.createAnimation(this.Types.easeOut, attrs);
},
createEaseInEaseOutAnimation: function(attrs: Attrs): number {
return this.createAnimation(this.Types.easeInEaseOut, attrs);
},
addAnimation: function(nodeHandle: any, anim: number, callback: Function) {
RCTPOPAnimationManager.addAnimation(nodeHandle, anim, callback);
},
removeAnimation: function(nodeHandle: any, anim: number) {
RCTPOPAnimationManager.removeAnimation(nodeHandle, anim);
},
};
// Make sure that we correctly propagate RCTPOPAnimationManager constants
// to POPAnimation
if (__DEV__) {
var allProperties = merge(
RCTPOPAnimationManager.Properties,
RCTPOPAnimationManager.Properties
);
for (var key in allProperties) {
invariant(
POPAnimation.Properties[key] === RCTPOPAnimationManager.Properties[key],
'POPAnimation doesn\'t copy property ' + key + ' correctly'
);
}
var allTypes = merge(
RCTPOPAnimationManager.Types,
RCTPOPAnimationManager.Types
);
for (var key in allTypes) {
invariant(
POPAnimation.Types[key] === RCTPOPAnimationManager.Types[key],
'POPAnimation doesn\'t copy type ' + key + ' correctly'
);
}
}
module.exports = POPAnimation;
}

View File

@ -0,0 +1,8 @@
/**
* Copyright 2004-present Facebook. All Rights Reserved.
*
* @providesModule ProgressBarAndroid
*/
'use strict';
module.exports = require('UnimplementedView');

View File

@ -181,7 +181,7 @@ var ScrollResponderMixin = {
scrollResponderHandleStartShouldSetResponderCapture: function(e: Event): boolean {
// First see if we want to eat taps while the keyboard is up
var currentlyFocusedTextInput = TextInputState.currentlyFocusedField();
if (!this.props.keyboardShouldPersistTaps &&
if (this.props.keyboardShouldPersistTaps === false &&
currentlyFocusedTextInput != null &&
e.target !== currentlyFocusedTextInput) {
return true;
@ -242,7 +242,7 @@ var ScrollResponderMixin = {
// By default scroll views will unfocus a textField
// if another touch occurs outside of it
var currentlyFocusedTextInput = TextInputState.currentlyFocusedField();
if (!this.props.keyboardShouldPersistTaps &&
if (this.props.keyboardShouldPersistTaps === false &&
currentlyFocusedTextInput != null &&
e.target !== currentlyFocusedTextInput &&
!this.state.observedScrollSinceBecomingResponder &&

View File

@ -15,7 +15,6 @@ var EdgeInsetsPropType = require('EdgeInsetsPropType');
var Platform = require('Platform');
var PointPropType = require('PointPropType');
var RCTScrollView = require('NativeModules').UIManager.RCTScrollView;
var RCTScrollViewConsts = RCTScrollView.Constants;
var React = require('React');
var ReactNativeViewAttributes = require('ReactNativeViewAttributes');
var RCTUIManager = require('NativeModules').UIManager;
@ -27,6 +26,7 @@ var ViewStylePropTypes = require('ViewStylePropTypes');
var createReactNativeComponentClass = require('createReactNativeComponentClass');
var deepDiffer = require('deepDiffer');
var dismissKeyboard = require('dismissKeyboard');
var flattenStyle = require('flattenStyle');
var insetsDiffer = require('insetsDiffer');
var invariant = require('invariant');
@ -156,9 +156,9 @@ var ScrollView = React.createClass({
* Determines whether the keyboard gets dismissed in response to a drag.
* - 'none' (the default), drags do not dismiss the keyboard.
* - 'on-drag', the keyboard is dismissed when a drag begins.
* - 'interactive', the keyboard is dismissed interactively with the drag
* and moves in synchrony with the touch; dragging upwards cancels the
* dismissal.
* - 'interactive', the keyboard is dismissed interactively with the drag and moves in
* synchrony with the touch; dragging upwards cancels the dismissal.
* On android this is not supported and it will have the same behavior as 'none'.
*/
keyboardDismissMode: PropTypes.oneOf([
'none', // default
@ -170,7 +170,6 @@ var ScrollView = React.createClass({
* is up dismisses the keyboard. When true, the scroll view will not catch
* taps, and the keyboard will not dismiss automatically. The default value
* is false.
* @platform ios
*/
keyboardShouldPersistTaps: PropTypes.bool,
/**
@ -310,6 +309,11 @@ var ScrollView = React.createClass({
);
}
}
if (Platform.OS === 'android') {
if (this.props.keyboardDismissMode === 'on-drag') {
dismissKeyboard();
}
}
this.scrollResponderHandleScroll(e);
},
@ -380,13 +384,6 @@ var ScrollView = React.createClass({
} else {
ScrollViewClass = AndroidScrollView;
}
var keyboardDismissModeConstants = {
'none': RCTScrollViewConsts.KeyboardDismissMode.None, // default
'interactive': RCTScrollViewConsts.KeyboardDismissMode.Interactive,
'on-drag': RCTScrollViewConsts.KeyboardDismissMode.OnDrag,
};
props.keyboardDismissMode = props.keyboardDismissMode ?
keyboardDismissModeConstants[props.keyboardDismissMode] : undefined;
}
invariant(
ScrollViewClass !== undefined,

View File

@ -7,7 +7,6 @@
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule TabBarItemIOS
* @flow
*/
'use strict';
@ -108,22 +107,15 @@ var TabBarItemIOS = React.createClass({
tabContents = <View />;
}
var icon = this.props.systemIcon || (
this.props.icon && this.props.icon.uri
);
var badge = typeof this.props.badge === 'number' ?
'' + this.props.badge :
this.props.badge;
return (
<RCTTabBarItem
icon={icon}
selectedIcon={this.props.selectedIcon && this.props.selectedIcon.uri}
onPress={this.props.onPress}
selected={this.props.selected}
{...this.props}
icon={this.props.systemIcon || this.props.icon}
badge={badge}
title={this.props.title}
style={[styles.tab, this.props.style]}>
{tabContents}
</RCTTabBarItem>

View File

@ -18,6 +18,7 @@ var Touchable = require('Touchable');
var merge = require('merge');
type Event = Object;
type State = {
animationID: ?number;
};
@ -41,6 +42,8 @@ var TouchableBounce = React.createClass({
propTypes: {
onPress: React.PropTypes.func,
onPressIn: React.PropTypes.func,
onPressOut: React.PropTypes.func,
// The function passed takes a callback to start the animation which should
// be run after this onPress handler is done. You can use this (for example)
// to update UI before starting the animation.
@ -73,15 +76,17 @@ var TouchableBounce = React.createClass({
* `Touchable.Mixin` self callbacks. The mixin will invoke these if they are
* defined on your component.
*/
touchableHandleActivePressIn: function() {
touchableHandleActivePressIn: function(e: Event) {
this.bounceTo(0.93, 0.1, 0);
this.props.onPressIn && this.props.onPressIn(e);
},
touchableHandleActivePressOut: function() {
touchableHandleActivePressOut: function(e: Event) {
this.bounceTo(1, 0.4, 0);
this.props.onPressOut && this.props.onPressOut(e);
},
touchableHandlePress: function() {
touchableHandlePress: function(e: Event) {
var onPressWithCompletion = this.props.onPressWithCompletion;
if (onPressWithCompletion) {
onPressWithCompletion(() => {
@ -92,7 +97,7 @@ var TouchableBounce = React.createClass({
}
this.bounceTo(1, 10, 10, this.props.onPressAnimationComplete);
this.props.onPress && this.props.onPress();
this.props.onPress && this.props.onPress(e);
},
touchableGetPressRectOffset: function(): typeof PRESS_RECT_OFFSET {

View File

@ -28,6 +28,8 @@ var keyOf = require('keyOf');
var merge = require('merge');
var onlyChild = require('onlyChild');
type Event = Object;
var DEFAULT_PROPS = {
activeOpacity: 0.8,
underlayColor: 'black',
@ -138,30 +140,30 @@ var TouchableHighlight = React.createClass({
* `Touchable.Mixin` self callbacks. The mixin will invoke these if they are
* defined on your component.
*/
touchableHandleActivePressIn: function() {
touchableHandleActivePressIn: function(e: Event) {
this.clearTimeout(this._hideTimeout);
this._hideTimeout = null;
this._showUnderlay();
this.props.onPressIn && this.props.onPressIn();
this.props.onPressIn && this.props.onPressIn(e);
},
touchableHandleActivePressOut: function() {
touchableHandleActivePressOut: function(e: Event) {
if (!this._hideTimeout) {
this._hideUnderlay();
}
this.props.onPressOut && this.props.onPressOut();
this.props.onPressOut && this.props.onPressOut(e);
},
touchableHandlePress: function() {
touchableHandlePress: function(e: Event) {
this.clearTimeout(this._hideTimeout);
this._showUnderlay();
this._hideTimeout = this.setTimeout(this._hideUnderlay,
this.props.delayPressOut || 100);
this.props.onPress && this.props.onPress();
this.props.onPress && this.props.onPress(e);
},
touchableHandleLongPress: function() {
this.props.onLongPress && this.props.onLongPress();
touchableHandleLongPress: function(e: Event) {
this.props.onLongPress && this.props.onLongPress(e);
},
touchableGetPressRectOffset: function() {
@ -214,12 +216,12 @@ var TouchableHighlight = React.createClass({
onResponderGrant={this.touchableHandleResponderGrant}
onResponderMove={this.touchableHandleResponderMove}
onResponderRelease={this.touchableHandleResponderRelease}
onResponderTerminate={this.touchableHandleResponderTerminate}>
onResponderTerminate={this.touchableHandleResponderTerminate}
testID={this.props.testID}>
{cloneWithProps(
onlyChild(this.props.children),
{
ref: CHILD_REF,
testID: this.props.testID,
}
)}
</View>

View File

@ -23,6 +23,8 @@ var ensurePositiveDelayProps = require('ensurePositiveDelayProps');
var flattenStyle = require('flattenStyle');
var keyOf = require('keyOf');
type Event = Object;
/**
* A wrapper for making views respond properly to touches.
* On press down, the opacity of the wrapped view is decreased, dimming it.
@ -77,9 +79,6 @@ var TouchableOpacity = React.createClass({
ensurePositiveDelayProps(this.props);
},
componentDidUpdate: function() {
},
componentWillReceiveProps: function(nextProps) {
ensurePositiveDelayProps(nextProps);
},
@ -95,32 +94,32 @@ var TouchableOpacity = React.createClass({
* `Touchable.Mixin` self callbacks. The mixin will invoke these if they are
* defined on your component.
*/
touchableHandleActivePressIn: function() {
touchableHandleActivePressIn: function(e: Event) {
this.clearTimeout(this._hideTimeout);
this._hideTimeout = null;
this._opacityActive();
this.props.onPressIn && this.props.onPressIn();
this.props.onPressIn && this.props.onPressIn(e);
},
touchableHandleActivePressOut: function() {
touchableHandleActivePressOut: function(e: Event) {
if (!this._hideTimeout) {
this._opacityInactive();
}
this.props.onPressOut && this.props.onPressOut();
this.props.onPressOut && this.props.onPressOut(e);
},
touchableHandlePress: function() {
touchableHandlePress: function(e: Event) {
this.clearTimeout(this._hideTimeout);
this._opacityActive();
this._hideTimeout = this.setTimeout(
this._opacityInactive,
this.props.delayPressOut || 100
);
this.props.onPress && this.props.onPress();
this.props.onPress && this.props.onPress(e);
},
touchableHandleLongPress: function() {
this.props.onLongPress && this.props.onLongPress();
touchableHandleLongPress: function(e: Event) {
this.props.onLongPress && this.props.onLongPress(e);
},
touchableGetPressRectOffset: function() {

View File

@ -17,6 +17,8 @@ var Touchable = require('Touchable');
var ensurePositiveDelayProps = require('ensurePositiveDelayProps');
var onlyChild = require('onlyChild');
type Event = Object;
/**
* When the scroll view is disabled, this defines how far your touch may move
* off of the button, before deactivating the button. Once deactivated, try
@ -25,8 +27,6 @@ var onlyChild = require('onlyChild');
*/
var PRESS_RECT_OFFSET = {top: 20, left: 20, right: 20, bottom: 30};
type Event = Object;
/**
* Do not use unless you have a very good reason. All the elements that
* respond to press should have a visual feedback when touched. This is
@ -79,16 +79,16 @@ var TouchableWithoutFeedback = React.createClass({
this.props.onPress && this.props.onPress(e);
},
touchableHandleActivePressIn: function() {
this.props.onPressIn && this.props.onPressIn();
touchableHandleActivePressIn: function(e: Event) {
this.props.onPressIn && this.props.onPressIn(e);
},
touchableHandleActivePressOut: function() {
this.props.onPressOut && this.props.onPressOut();
touchableHandleActivePressOut: function(e: Event) {
this.props.onPressOut && this.props.onPressOut(e);
},
touchableHandleLongPress: function() {
this.props.onLongPress && this.props.onLongPress();
touchableHandleLongPress: function(e: Event) {
this.props.onLongPress && this.props.onLongPress(e);
},
touchableGetPressRectOffset: function(): typeof PRESS_RECT_OFFSET {

View File

@ -44,13 +44,6 @@ var AccessibilityTraits = [
'pageTurn',
];
// <<<<< WARNING >>>>>
// If adding any properties to View that could change the way layout-only status
// works on iOS, make sure to update ReactNativeViewAttributes.js and
// RCTShadowView.m (in the -[RCTShadowView isLayoutOnly] method).
// <<<<< WARNING >>>>>
/**
* The most fundamental component for building UI, `View` is a
* container that supports layout with flexbox, style, some touch handling, and
@ -100,10 +93,13 @@ var View = React.createClass({
/**
* Indicates to accessibility services to treat UI component like a
* native one. Works for Android only.
* @platform android
*/
accessibilityComponentType: PropTypes.oneOf([
'none',
'button',
'radiobutton_checked',
'radiobutton_unchecked',
]),
/**
@ -111,6 +107,7 @@ var View = React.createClass({
* when this view changes. Works for Android API >= 19 only.
* See http://developer.android.com/reference/android/view/View.html#attr_android:accessibilityLiveRegion
* for references.
* @platform android
*/
accessibilityLiveRegion: PropTypes.oneOf([
'none',
@ -118,9 +115,33 @@ var View = React.createClass({
'assertive',
]),
/**
* Controls how view is important for accessibility which is if it
* fires accessibility events and if it is reported to accessibility services
* that query the screen. Works for Android only.
* See http://developer.android.com/reference/android/R.attr.html#importantForAccessibility
* for references.
* Possible values:
* 'auto' - The system determines whether the view is important for accessibility -
* default (recommended).
* 'yes' - The view is important for accessibility.
* 'no' - The view is not important for accessibility.
* 'no-hide-descendants' - The view is not important for accessibility,
* nor are any of its descendant views.
*
* @platform android
*/
importantForAccessibility: PropTypes.oneOf([
'auto',
'yes',
'no',
'no-hide-descendants',
]),
/**
* Provides additional traits to screen reader. By default no traits are
* provided unless specified otherwise in element
* @platform ios
*/
accessibilityTraits: PropTypes.oneOfType([
PropTypes.oneOf(AccessibilityTraits),

View File

@ -119,16 +119,16 @@ var NavigatorBreadcrumbNavigationBar = React.createClass({
}
if (interpolate.Crumb(CRUMB_PROPS[index].style, amount)) {
this.refs['crumb_' + index].setNativeProps(CRUMB_PROPS[index]);
this._setPropsIfExists('crumb_' + index, CRUMB_PROPS[index]);
}
if (interpolate.Icon(ICON_PROPS[index].style, amount)) {
this.refs['icon_' + index].setNativeProps(ICON_PROPS[index]);
this._setPropsIfExists('icon_' + index, ICON_PROPS[index]);
}
if (interpolate.Separator(SEPARATOR_PROPS[index].style, amount)) {
this.refs['separator_' + index].setNativeProps(SEPARATOR_PROPS[index]);
this._setPropsIfExists('separator_' + index, SEPARATOR_PROPS[index]);
}
if (interpolate.Title(TITLE_PROPS[index].style, amount)) {
this.refs['title_' + index].setNativeProps(TITLE_PROPS[index]);
this._setPropsIfExists('title_' + index, TITLE_PROPS[index]);
}
var right = this.refs['right_' + index];
if (right &&
@ -165,13 +165,10 @@ var NavigatorBreadcrumbNavigationBar = React.createClass({
renderToHardwareTextureAndroid: renderToHardwareTexture,
};
this.refs['icon_' + index].setNativeProps(props);
this.refs['separator_' + index].setNativeProps(props);
this.refs['title_' + index].setNativeProps(props);
var right = this.refs['right_' + index];
if (right) {
right.setNativeProps(props);
}
this._setPropsIfExists('icon_' + index, props);
this._setPropsIfExists('separator_' + index, props);
this._setPropsIfExists('title_' + index, props);
this._setPropsIfExists('right_' + index, props);
},
componentWillMount: function() {
@ -260,6 +257,11 @@ var NavigatorBreadcrumbNavigationBar = React.createClass({
this._descriptors.right = this._descriptors.right.set(route, rightButtonDescriptor);
return rightButtonDescriptor;
},
_setPropsIfExists: function(ref, props) {
var ref = this.refs[ref];
ref && ref.setNativeProps(props);
},
});
var styles = StyleSheet.create({

View File

@ -115,11 +115,11 @@ RCT_EXPORT_MODULE()
{
if ((self = [super init])) {
_locationManager = [[CLLocationManager alloc] init];
_locationManager = [CLLocationManager new];
_locationManager.distanceFilter = RCT_DEFAULT_LOCATION_ACCURACY;
_locationManager.delegate = self;
_pendingRequests = [[NSMutableArray alloc] init];
_pendingRequests = [NSMutableArray new];
}
return self;
}
@ -231,7 +231,7 @@ RCT_EXPORT_METHOD(getCurrentPosition:(RCTLocationOptions)options
}
// Create request
RCTLocationRequest *request = [[RCTLocationRequest alloc] init];
RCTLocationRequest *request = [RCTLocationRequest new];
request.successBlock = successBlock;
request.errorBlock = errorBlock ?: ^(NSArray *args){};
request.options = options;
@ -252,7 +252,7 @@ RCT_EXPORT_METHOD(getCurrentPosition:(RCTLocationOptions)options
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
// Create event
CLLocation *location = [locations lastObject];
CLLocation *location = locations.lastObject;
_lastLocationEvent = @{
@"coords": @{
@"latitude": @(location.coordinate.latitude),

View File

@ -60,9 +60,13 @@ var Image = React.createClass({
* could be an http address, a local file path, or the name of a static image
* resource (which should be wrapped in the `require('image!name')` function).
*/
source: PropTypes.shape({
uri: PropTypes.string,
}),
source: PropTypes.oneOfType([
PropTypes.shape({
uri: PropTypes.string,
}),
// Opaque type returned by require('./image.jpg')
PropTypes.number,
]),
/**
* A static image to display while downloading the final image off the
* network.

View File

@ -34,12 +34,12 @@ RCT_EXPORT_METHOD(saveImageWithTag:(NSString *)imageTag
errorCallback(loadError);
return;
}
[_bridge.assetsLibrary writeImageToSavedPhotosAlbum:[loadedImage CGImage] metadata:nil completionBlock:^(NSURL *assetURL, NSError *saveError) {
[_bridge.assetsLibrary writeImageToSavedPhotosAlbum:loadedImage.CGImage metadata:nil completionBlock:^(NSURL *assetURL, NSError *saveError) {
if (saveError) {
RCTLogWarn(@"Error saving cropped image: %@", saveError);
errorCallback(saveError);
} else {
successCallback(@[[assetURL absoluteString]]);
successCallback(@[assetURL.absoluteString]);
}
}];
}];
@ -47,7 +47,7 @@ RCT_EXPORT_METHOD(saveImageWithTag:(NSString *)imageTag
- (void)callCallback:(RCTResponseSenderBlock)callback withAssets:(NSArray *)assets hasNextPage:(BOOL)hasNextPage
{
if (![assets count]) {
if (!assets.count) {
callback(@[@{
@"edges": assets,
@"page_info": @{
@ -94,7 +94,7 @@ RCT_EXPORT_METHOD(getPhotos:(NSDictionary *)params
BOOL __block foundAfter = NO;
BOOL __block hasNextPage = NO;
BOOL __block calledCallback = NO;
NSMutableArray *assets = [[NSMutableArray alloc] init];
NSMutableArray *assets = [NSMutableArray new];
[_bridge.assetsLibrary enumerateGroupsWithTypes:groupTypes usingBlock:^(ALAssetsGroup *group, BOOL *stopGroups) {
if (group && (groupName == nil || [groupName isEqualToString:[group valueForProperty:ALAssetsGroupPropertyName]])) {
@ -109,14 +109,14 @@ RCT_EXPORT_METHOD(getPhotos:(NSDictionary *)params
[group enumerateAssetsWithOptions:NSEnumerationReverse usingBlock:^(ALAsset *result, NSUInteger index, BOOL *stopAssets) {
if (result) {
NSString *uri = [(NSURL *)[result valueForProperty:ALAssetPropertyAssetURL] absoluteString];
NSString *uri = ((NSURL *)[result valueForProperty:ALAssetPropertyAssetURL]).absoluteString;
if (afterCursor && !foundAfter) {
if ([afterCursor isEqualToString:uri]) {
foundAfter = YES;
}
return; // Skip until we get to the first one
}
if (first == [assets count]) {
if (first == assets.count) {
*stopAssets = YES;
*stopGroups = YES;
hasNextPage = YES;
@ -138,7 +138,7 @@ RCT_EXPORT_METHOD(getPhotos:(NSDictionary *)params
@"width": @(dimensions.width),
@"isStored": @YES,
},
@"timestamp": @([date timeIntervalSince1970]),
@"timestamp": @(date.timeIntervalSince1970),
@"location": loc ?
@{
@"latitude": @(loc.coordinate.latitude),

View File

@ -85,7 +85,7 @@ CAKeyframeAnimation *RCTGIFImageWithFileURL(NSURL *URL)
return nil;
}
if (![URL isFileURL]) {
if (!URL.fileURL) {
RCTLogError(@"Loading remote image URLs synchronously is a really bad idea.");
return nil;
}

View File

@ -15,9 +15,6 @@
#import "RCTNetworking.h"
#import "RCTUtils.h"
CGSize RCTTargetSizeForClipRect(CGRect);
CGRect RCTClipRect(CGSize, CGFloat, CGSize, CGFloat, UIViewContentMode);
@implementation RCTImageDownloader
{
NSURLCache *_cache;
@ -33,7 +30,7 @@ RCT_EXPORT_MODULE()
static RCTImageDownloader *sharedInstance;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[RCTImageDownloader alloc] init];
sharedInstance = [RCTImageDownloader new];
});
return sharedInstance;
}
@ -131,14 +128,14 @@ RCT_EXPORT_MODULE()
UIImage *image = [UIImage imageWithData:data scale:scale];
if (image && !CGSizeEqualToSize(size, CGSizeZero)) {
// Get scale and size
CGRect imageRect = RCTClipRect(image.size, scale, size, scale, resizeMode);
CGSize destSize = RCTTargetSizeForClipRect(imageRect);
// Get destination size
CGSize targetSize = RCTTargetSize(image.size, image.scale,
size, scale, resizeMode, NO);
// Decompress image at required size
BOOL opaque = !RCTImageHasAlpha(image.CGImage);
UIGraphicsBeginImageContextWithOptions(destSize, opaque, scale);
[image drawInRect:imageRect];
UIGraphicsBeginImageContextWithOptions(targetSize, opaque, scale);
[image drawInRect:(CGRect){CGPointZero, targetSize}];
image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}

View File

@ -85,8 +85,8 @@ static UIImage *RCTScaledImageForAsset(ALAssetRepresentation *representation,
}
CGSize sourceSize = representation.dimensions;
CGRect targetRect = RCTClipRect(sourceSize, representation.scale, size, scale, resizeMode);
CGSize targetSize = targetRect.size;
CGSize targetSize = RCTTargetSize(sourceSize, representation.scale,
size, scale, resizeMode, NO);
NSDictionary *options = @{
(id)kCGImageSourceShouldAllowFloat: @YES,
@ -103,7 +103,7 @@ static UIImage *RCTScaledImageForAsset(ALAssetRepresentation *representation,
if (imageRef) {
UIImage *image = [UIImage imageWithCGImage:imageRef scale:scale
orientation:(UIImageOrientation)representation.orientation];
orientation:UIImageOrientationUp];
CGImageRelease(imageRef);
return image;
}
@ -114,7 +114,7 @@ static UIImage *RCTScaledImageForAsset(ALAssetRepresentation *representation,
- (ALAssetsLibrary *)assetsLibrary
{
if (!_assetsLibrary) {
_assetsLibrary = [[ALAssetsLibrary alloc] init];
_assetsLibrary = [ALAssetsLibrary new];
}
return _assetsLibrary;
}
@ -170,7 +170,7 @@ static UIImage *RCTScaledImageForAsset(ALAssetRepresentation *representation,
// The 'ph://' prefix is used by FBMediaKit to differentiate between
// assets-library. It is prepended to the local ID so that it is in the
// form of an, NSURL which is what assets-library uses.
NSString *phAssetID = [imageTag substringFromIndex:[@"ph://" length]];
NSString *phAssetID = [imageTag substringFromIndex:@"ph://".length];
PHFetchResult *results = [PHAsset fetchAssetsWithLocalIdentifiers:@[phAssetID] options:nil];
if (results.count == 0) {
NSString *errorText = [NSString stringWithFormat:@"Failed to fetch PHAsset with local identifier %@ with no error message.", phAssetID];
@ -179,9 +179,9 @@ static UIImage *RCTScaledImageForAsset(ALAssetRepresentation *representation,
return ^{};
}
PHAsset *asset = [results firstObject];
PHAsset *asset = results.firstObject;
PHImageRequestOptions *imageOptions = [[PHImageRequestOptions alloc] init];
PHImageRequestOptions *imageOptions = [PHImageRequestOptions new];
BOOL useMaximumSize = CGSizeEqualToSize(size, CGSizeZero);
CGSize targetSize;

View File

@ -31,9 +31,9 @@ RCT_EXPORT_MODULE(ImagePickerIOS);
- (instancetype)init
{
if ((self = [super init])) {
_pickers = [[NSMutableArray alloc] init];
_pickerCallbacks = [[NSMutableArray alloc] init];
_pickerCancelCallbacks = [[NSMutableArray alloc] init];
_pickers = [NSMutableArray new];
_pickerCallbacks = [NSMutableArray new];
_pickerCancelCallbacks = [NSMutableArray new];
}
return self;
}
@ -53,10 +53,10 @@ RCT_EXPORT_METHOD(openCameraDialog:(NSDictionary *)config
successCallback:(RCTResponseSenderBlock)callback
cancelCallback:(RCTResponseSenderBlock)cancelCallback)
{
UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow;
UIViewController *rootViewController = keyWindow.rootViewController;
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
UIImagePickerController *imagePicker = [UIImagePickerController new];
imagePicker.delegate = self;
imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
@ -75,14 +75,14 @@ RCT_EXPORT_METHOD(openSelectDialog:(NSDictionary *)config
successCallback:(RCTResponseSenderBlock)callback
cancelCallback:(RCTResponseSenderBlock)cancelCallback)
{
UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow;
UIViewController *rootViewController = keyWindow.rootViewController;
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
UIImagePickerController *imagePicker = [UIImagePickerController new];
imagePicker.delegate = self;
imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
NSMutableArray *allowedTypes = [[NSMutableArray alloc] init];
NSMutableArray *allowedTypes = [NSMutableArray new];
if ([config[@"showImages"] boolValue]) {
[allowedTypes addObject:(NSString *)kUTTypeImage];
}
@ -109,7 +109,7 @@ didFinishPickingMediaWithInfo:(NSDictionary *)info
[_pickerCallbacks removeObjectAtIndex:index];
[_pickerCancelCallbacks removeObjectAtIndex:index];
UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow;
UIViewController *rootViewController = keyWindow.rootViewController;
[rootViewController dismissViewControllerAnimated:YES completion:nil];
@ -125,7 +125,7 @@ didFinishPickingMediaWithInfo:(NSDictionary *)info
[_pickerCallbacks removeObjectAtIndex:index];
[_pickerCancelCallbacks removeObjectAtIndex:index];
UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow;
UIViewController *rootViewController = keyWindow.rootViewController;
[rootViewController dismissViewControllerAnimated:YES completion:nil];

View File

@ -22,13 +22,13 @@ RCT_EXPORT_MODULE()
- (BOOL)canHandleRequest:(NSURLRequest *)request
{
return [@[@"assets-library", @"ph"] containsObject:[request.URL.scheme lowercaseString]];
return [@[@"assets-library", @"ph"] containsObject:request.URL.scheme.lowercaseString];
}
- (id)sendRequest:(NSURLRequest *)request
withDelegate:(id<RCTURLRequestDelegate>)delegate
{
NSString *URLString = [request.URL absoluteString];
NSString *URLString = request.URL.absoluteString;
__block RCTImageLoaderCancellationBlock requestToken = nil;
requestToken = [_bridge.imageLoader loadImageWithTag:URLString callback:^(NSError *error, UIImage *image) {

View File

@ -21,12 +21,12 @@
RCT_EXPORT_MODULE()
- (id)init
- (instancetype)init
{
if ((self = [super init])) {
// TODO: need a way to clear this store
_store = [[NSMutableDictionary alloc] init];
_store = [NSMutableDictionary new];
}
return self;
}
@ -34,7 +34,7 @@ RCT_EXPORT_MODULE()
- (NSString *)storeImage:(UIImage *)image
{
RCTAssertMainThread();
NSString *tag = [NSString stringWithFormat:@"rct-image-store://%tu", [_store count]];
NSString *tag = [NSString stringWithFormat:@"rct-image-store://%tu", _store.count];
_store[tag] = image;
return tag;
}
@ -101,13 +101,13 @@ RCT_EXPORT_METHOD(addImageFromBase64:(NSString *)base64String
- (BOOL)canHandleRequest:(NSURLRequest *)request
{
return [@[@"rct-image-store"] containsObject:[request.URL.scheme lowercaseString]];
return [@[@"rct-image-store"] containsObject:request.URL.scheme.lowercaseString];
}
- (id)sendRequest:(NSURLRequest *)request
withDelegate:(id<RCTURLRequestDelegate>)delegate
{
NSString *imageTag = [request.URL absoluteString];
NSString *imageTag = request.URL.absoluteString;
[self getImageForTag:imageTag withBlock:^(UIImage *image) {
if (!image) {
NSError *error = RCTErrorWithMessage([NSString stringWithFormat:@"Invalid imageTag: %@", imageTag]);

View File

@ -13,20 +13,24 @@
#import "RCTDefines.h"
/**
* Returns the optimal context size for an image drawn using the clip rect
* returned by RCTClipRect.
* This function takes an input content size (typically from an image), a target
* size and scale that it will be drawn at (typically in a CGContext) and then
* calculates the rectangle to draw the image into so that it will be sized and
* positioned correctly if drawn using the specified content mode.
*/
RCT_EXTERN CGSize RCTTargetSizeForClipRect(CGRect clipRect);
RCT_EXTERN CGRect RCTTargetRect(CGSize sourceSize, CGSize destSize,
CGFloat destScale, UIViewContentMode resizeMode);
/**
* This function takes an input content size & scale (typically from an image),
* a target size & scale that it will be drawn into (typically a CGContext) and
* then calculates the optimal rectangle to draw the image into so that it will
* be sized and positioned correctly if drawn using the specified content mode.
* a target size & scale at which it will be displayed (typically in a
* UIImageView) and then calculates the optimal size at which to redraw the
* image so that it will be displayed correctly with the specified content mode.
*/
RCT_EXTERN CGRect RCTClipRect(CGSize sourceSize, CGFloat sourceScale,
CGSize destSize, CGFloat destScale,
UIViewContentMode resizeMode);
RCT_EXTERN CGSize RCTTargetSize(CGSize sourceSize, CGFloat sourceScale,
CGSize destSize, CGFloat destScale,
UIViewContentMode resizeMode,
BOOL allowUpscaling);
/**
* This function takes an input content size & scale (typically from an image),

View File

@ -29,28 +29,14 @@ static CGSize RCTCeilSize(CGSize size, CGFloat scale)
};
}
CGSize RCTTargetSizeForClipRect(CGRect clipRect)
{
return (CGSize){
clipRect.size.width + clipRect.origin.x * 2,
clipRect.size.height + clipRect.origin.y * 2
};
}
CGRect RCTClipRect(CGSize sourceSize, CGFloat sourceScale,
CGSize destSize, CGFloat destScale,
UIViewContentMode resizeMode)
CGRect RCTTargetRect(CGSize sourceSize, CGSize destSize,
CGFloat destScale, UIViewContentMode resizeMode)
{
if (CGSizeEqualToSize(destSize, CGSizeZero)) {
// Assume we require the largest size available
return (CGRect){CGPointZero, sourceSize};
}
// Precompensate for scale
CGFloat scale = sourceScale / destScale;
sourceSize.width *= scale;
sourceSize.height *= scale;
CGFloat aspect = sourceSize.width / sourceSize.height;
// If only one dimension in destSize is non-zero (for example, an Image
// with `flex: 1` whose height is indeterminate), calculate the unknown
@ -61,7 +47,7 @@ CGRect RCTClipRect(CGSize sourceSize, CGFloat sourceScale,
if (destSize.height == 0) {
destSize.height = destSize.width / aspect;
}
// Calculate target aspect ratio if needed (don't bother if resizeMode == stretch)
CGFloat targetAspect = 0.0;
if (resizeMode != UIViewContentModeScaleToFill) {
@ -74,20 +60,18 @@ CGRect RCTClipRect(CGSize sourceSize, CGFloat sourceScale,
switch (resizeMode) {
case UIViewContentModeScaleToFill: // stretch
sourceSize.width = MIN(destSize.width, sourceSize.width);
sourceSize.height = MIN(destSize.height, sourceSize.height);
return (CGRect){CGPointZero, RCTCeilSize(sourceSize, destScale)};
return (CGRect){CGPointZero, RCTCeilSize(destSize, destScale)};
case UIViewContentModeScaleAspectFit: // contain
if (targetAspect <= aspect) { // target is taller than content
sourceSize.width = destSize.width = MIN(sourceSize.width, destSize.width);
sourceSize.width = destSize.width = destSize.width;
sourceSize.height = sourceSize.width / aspect;
} else { // target is wider than content
sourceSize.height = destSize.height = MIN(sourceSize.height, destSize.height);
sourceSize.height = destSize.height = destSize.height;
sourceSize.width = sourceSize.height * aspect;
}
return (CGRect){CGPointZero, RCTCeilSize(sourceSize, destScale)};
@ -96,7 +80,7 @@ CGRect RCTClipRect(CGSize sourceSize, CGFloat sourceScale,
if (targetAspect <= aspect) { // target is taller than content
sourceSize.height = destSize.height = MIN(sourceSize.height, destSize.height);
sourceSize.height = destSize.height = destSize.height;
sourceSize.width = sourceSize.height * aspect;
destSize.width = destSize.height * targetAspect;
return (CGRect){
@ -106,7 +90,7 @@ CGRect RCTClipRect(CGSize sourceSize, CGFloat sourceScale,
} else { // target is wider than content
sourceSize.width = destSize.width = MIN(sourceSize.width, destSize.width);
sourceSize.width = destSize.width = destSize.width;
sourceSize.height = sourceSize.width / aspect;
destSize.height = destSize.width / targetAspect;
return (CGRect){
@ -122,9 +106,39 @@ CGRect RCTClipRect(CGSize sourceSize, CGFloat sourceScale,
}
}
RCT_EXTERN BOOL RCTUpscalingRequired(CGSize sourceSize, CGFloat sourceScale,
CGSize destSize, CGFloat destScale,
UIViewContentMode resizeMode)
CGSize RCTTargetSize(CGSize sourceSize, CGFloat sourceScale,
CGSize destSize, CGFloat destScale,
UIViewContentMode resizeMode,
BOOL allowUpscaling)
{
switch (resizeMode) {
case UIViewContentModeScaleToFill: // stretch
if (!allowUpscaling) {
CGFloat scale = sourceScale / destScale;
destSize.width = MIN(sourceSize.width * scale, destSize.width);
destSize.height = MIN(sourceSize.height * scale, destSize.height);
}
return RCTCeilSize(destSize, destScale);
default: {
// Get target size
CGSize size = RCTTargetRect(sourceSize, destSize, destScale, resizeMode).size;
if (!allowUpscaling) {
// return sourceSize if target size is larger
if (sourceSize.width * sourceScale < size.width * destScale) {
return sourceSize;
}
}
return size;
}
}
}
BOOL RCTUpscalingRequired(CGSize sourceSize, CGFloat sourceScale,
CGSize destSize, CGFloat destScale,
UIViewContentMode resizeMode)
{
if (CGSizeEqualToSize(destSize, CGSizeZero)) {
// Assume we require the largest size available

View File

@ -14,6 +14,7 @@
#import "RCTEventDispatcher.h"
#import "RCTGIFImage.h"
#import "RCTImageLoader.h"
#import "RCTImageUtils.h"
#import "RCTUtils.h"
#import "UIView+React.h"
@ -41,9 +42,9 @@
return self;
}
RCT_NOT_IMPLEMENTED(-init)
RCT_NOT_IMPLEMENTED(- (instancetype)init)
- (void)_updateImage
- (void)updateImage
{
UIImage *image = self.image;
if (!image) {
@ -72,7 +73,7 @@ RCT_NOT_IMPLEMENTED(-init)
image = image ?: _defaultImage;
if (image != super.image) {
super.image = image;
[self _updateImage];
[self updateImage];
}
}
@ -80,7 +81,7 @@ RCT_NOT_IMPLEMENTED(-init)
{
if (!UIEdgeInsetsEqualToEdgeInsets(_capInsets, capInsets)) {
_capInsets = capInsets;
[self _updateImage];
[self updateImage];
}
}
@ -88,7 +89,7 @@ RCT_NOT_IMPLEMENTED(-init)
{
if (_renderingMode != renderingMode) {
_renderingMode = renderingMode;
[self _updateImage];
[self updateImage];
}
}
@ -100,6 +101,16 @@ RCT_NOT_IMPLEMENTED(-init)
}
}
- (void)setContentMode:(UIViewContentMode)contentMode
{
if (self.contentMode != contentMode) {
super.contentMode = contentMode;
if ([RCTImageLoader isAssetLibraryImage:_src] || [RCTImageLoader isRemoteImage:_src]) {
[self reloadImage];
}
}
}
- (void)reloadImage
{
if (_src && !CGSizeEqualToSize(self.frame.size, CGSizeZero)) {
@ -165,12 +176,15 @@ RCT_NOT_IMPLEMENTED(-init)
if (self.image == nil) {
[self reloadImage];
} else if ([RCTImageLoader isAssetLibraryImage:_src] || [RCTImageLoader isRemoteImage:_src]) {
CGSize imageSize = {
self.image.size.width / RCTScreenScale(),
self.image.size.height / RCTScreenScale()
};
CGFloat widthChangeFraction = imageSize.width ? ABS(imageSize.width - frame.size.width) / imageSize.width : 1;
CGFloat heightChangeFraction = imageSize.height ? ABS(imageSize.height - frame.size.height) / imageSize.height : 1;
// Get optimal image size
CGSize currentSize = self.image.size;
CGSize idealSize = RCTTargetSize(self.image.size, self.image.scale, frame.size,
RCTScreenScale(), self.contentMode, YES);
CGFloat widthChangeFraction = ABS(currentSize.width - idealSize.width) / currentSize.width;
CGFloat heightChangeFraction = ABS(currentSize.height - idealSize.height) / currentSize.height;
// If the combined change is more than 20%, reload the asset in case there is a better size.
if (widthChangeFraction + heightChangeFraction > 0.2) {
[self reloadImage];

View File

@ -80,6 +80,9 @@ function installConsoleErrorReporter() {
console.reportException = reportException;
console.errorOriginal = console.error.bind(console);
console.error = function reactConsoleError() {
// Note that when using the built-in context executor on iOS (i.e., not
// Chrome debugging), console.error is already stubbed out to cause a
// redbox via RCTNativeLoggingHook.
console.errorOriginal.apply(null, arguments);
if (!console.reportErrorsAsExceptions) {
return;
@ -88,6 +91,7 @@ function installConsoleErrorReporter() {
if (str.slice(0, 10) === '"Warning: ') {
// React warnings use console.error so that a stack trace is shown, but
// we don't (currently) want these to show a redbox
// (Note: Logic duplicated in polyfills/console.js.)
return;
}
var error: any = new Error('console.error: ' + str);

View File

@ -59,6 +59,13 @@ function setUpRedBoxConsoleErrorHandler() {
}
}
function setupFlowChecker() {
if (__DEV__) {
var checkFlowAtRuntime = require('checkFlowAtRuntime');
checkFlowAtRuntime();
}
}
/**
* Sets up a set of window environment wrappers that ensure that the
* BatchedBridge is flushed after each tick. In both the case of the
@ -124,13 +131,14 @@ function setUpWebSockets() {
}
function setupProfile() {
console.profile = console.profile || GLOBAL.consoleProfile || function () {};
console.profileEnd = console.profileEnd || GLOBAL.consoleProfileEnd || function () {};
console.profile = console.profile || GLOBAL.nativeTraceBeginSection || function () {};
console.profileEnd = console.profileEnd || GLOBAL.nativeTraceEndSection || function () {};
require('BridgeProfiling').swizzleReactPerf();
}
function setUpProcessEnv() {
GLOBAL.process = {env: {NODE_ENV: __DEV__ ? 'development' : 'production'}};
GLOBAL.process = GLOBAL.process || {};
GLOBAL.process.env = {NODE_ENV: __DEV__ ? 'development' : 'production'};
}
setUpRedBoxErrorHandler();
@ -143,3 +151,4 @@ setUpGeolocation();
setUpWebSockets();
setupProfile();
setUpProcessEnv();
setupFlowChecker();

View File

@ -0,0 +1,59 @@
/**
* 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 checkFlowAtRuntime
*
*/
'use strict';
function checkFlowAtRuntime() {
var url = getPackagerURL();
if (!url) {
return;
}
fetch(url + 'flow/')
.then(response => response.json())
.then(response => {
if (response.silentError) {
return;
}
throw {
message: response.message,
stack: response.errors.map(err => {
return {
...err,
methodName: err.description,
file: err.filename,
};
}),
};
},
() => {
//if fetch fails, silently give up
})
.done();
}
function getPackagerURL() {
var NativeModules = require('NativeModules');
var scriptURL = (NativeModules
&& NativeModules.SourceCode
&& NativeModules.SourceCode.scriptURL)
|| '';
// extract the url of the packager from the whole scriptURL
// we match until the first / after http(s)://
// i.e. http://www.mypackger.com/debug/my/bundle -> http://www.mypackger.com/
return getFirstOrNull(scriptURL.match(/^https?:\/\/[^/]+\//));
}
function getFirstOrNull(ar) {
return ar ? ar[0] : null;
}
module.exports = checkFlowAtRuntime;

View File

@ -32,7 +32,7 @@ function parseErrorStack(e, sourceMapInstance) {
return [];
}
var stack = stacktraceParser.parse(e.stack);
var stack = Array.isArray(e.stack) ? e.stack : stacktraceParser.parse(e.stack);
var framesToPop = e.framesToPop || 0;
while (framesToPop--) {

View File

@ -42,7 +42,7 @@ RCT_EXPORT_MODULE()
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation
{
NSDictionary *payload = @{@"url": [URL absoluteString]};
NSDictionary *payload = @{@"url": URL.absoluteString};
[[NSNotificationCenter defaultCenter] postNotificationName:RCTOpenURLNotification
object:self
userInfo:payload];
@ -52,7 +52,7 @@ RCT_EXPORT_MODULE()
- (void)handleOpenURLNotification:(NSNotification *)notification
{
[_bridge.eventDispatcher sendDeviceEventWithName:@"openURL"
body:[notification userInfo]];
body:notification.userInfo];
}
RCT_EXPORT_METHOD(openURL:(NSURL *)URL)
@ -72,7 +72,7 @@ RCT_EXPORT_METHOD(canOpenURL:(NSURL *)URL
- (NSDictionary *)constantsToExport
{
NSURL *initialURL = _bridge.launchOptions[UIApplicationLaunchOptionsURLKey];
return @{@"initialURL": RCTNullIfNil([initialURL absoluteString])};
return @{@"initialURL": RCTNullIfNil(initialURL.absoluteString)};
}
@end

View File

@ -11,6 +11,7 @@
*/
'use strict';
var PropTypes = require('ReactPropTypes');
var React = require('React');
var StyleSheet = require('StyleSheet');
var View = require('View');
@ -24,9 +25,16 @@ class Modal extends React.Component {
return null;
}
if (this.props.transparent) {
var containerBackgroundColor = {backgroundColor: 'transparent'};
}
return (
<RCTModalHostView animated={this.props.animated} style={styles.modal}>
<View style={styles.container}>
<RCTModalHostView
animated={this.props.animated}
transparent={this.props.transparent}
style={styles.modal}>
<View style={[styles.container, containerBackgroundColor]}>
{this.props.children}
</View>
</RCTModalHostView>
@ -34,6 +42,11 @@ class Modal extends React.Component {
}
}
Modal.propTypes = {
animated: PropTypes.bool,
transparent: PropTypes.bool,
};
var styles = StyleSheet.create({
modal: {
position: 'absolute',

View File

@ -74,7 +74,7 @@ class FormData {
var contentDisposition = 'form-data; name="' + name + '"';
var headers: Headers = {'content-disposition': contentDisposition};
if (typeof value === 'string') {
return {string: value, headers};
return {string: value, headers, fieldName: name};
}
// The body part is a "blob", which in React Native just means
@ -87,7 +87,7 @@ class FormData {
if (typeof value.type === 'string') {
headers['content-type'] = value.type;
}
return {...value, headers};
return {...value, headers, fieldName: name};
});
}
}

View File

@ -15,14 +15,9 @@ var Map = require('Map');
var NativeModules = require('NativeModules');
var Platform = require('Platform');
var RCTDeviceEventEmitter = require('RCTDeviceEventEmitter');
var RCTNetInfo = NativeModules.NetInfo;
if (Platform.OS === 'ios') {
var RCTNetInfo = NativeModules.Reachability;
} else if (Platform.OS === 'android') {
var RCTNetInfo = NativeModules.NetInfo;
}
var DEVICE_REACHABILITY_EVENT = 'reachabilityDidChange';
var DEVICE_REACHABILITY_EVENT = 'networkDidChange';
type ChangeEventName = $Enum<{
change: string;
@ -151,7 +146,7 @@ var NetInfo = {
var listener = RCTDeviceEventEmitter.addListener(
DEVICE_REACHABILITY_EVENT,
(appStateData) => {
handler(appStateData.network_reachability);
handler(appStateData.network_info);
}
);
_subscriptions.set(handler, listener);

View File

@ -51,7 +51,7 @@
_uploadProgressBlock = nil;
}
RCT_NOT_IMPLEMENTED(-init)
RCT_NOT_IMPLEMENTED(- (instancetype)init)
- (void)cancel
{
@ -101,7 +101,7 @@ RCT_NOT_IMPLEMENTED(-init)
{
if ([self validateRequestToken:requestToken]) {
if (!_data) {
_data = [[NSMutableData alloc] init];
_data = [NSMutableData new];
}
[_data appendData:data];
if (_incrementalDataBlock) {

View File

@ -47,7 +47,7 @@ RCT_EXPORT_MODULE()
- (BOOL)canHandleRequest:(NSURLRequest *)request
{
return [@[@"http", @"https", @"file"] containsObject:[request.URL.scheme lowercaseString]];
return [@[@"http", @"https", @"file"] containsObject:request.URL.scheme.lowercaseString];
}
- (NSURLSessionDataTask *)sendRequest:(NSURLRequest *)request
@ -55,7 +55,7 @@ RCT_EXPORT_MODULE()
{
// Lazy setup
if (!_session && [self isValid]) {
NSOperationQueue *callbackQueue = [[NSOperationQueue alloc] init];
NSOperationQueue *callbackQueue = [NSOperationQueue new];
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
_session = [NSURLSession sessionWithConfiguration:configuration
delegate:self

View File

@ -11,7 +11,7 @@
#import "RCTBridgeModule.h"
@interface RCTReachability : NSObject<RCTBridgeModule>
@interface RCTNetInfo : NSObject<RCTBridgeModule>
- (instancetype)initWithHost:(NSString *)host NS_DESIGNATED_INITIALIZER;

View File

@ -7,7 +7,7 @@
* of patent rights can be found in the PATENTS file in the same directory.
*/
#import "RCTReachability.h"
#import "RCTNetInfo.h"
#import "RCTAssert.h"
#import "RCTBridge.h"
@ -18,7 +18,7 @@ static NSString *const RCTReachabilityStateNone = @"none";
static NSString *const RCTReachabilityStateWifi = @"wifi";
static NSString *const RCTReachabilityStateCell = @"cell";
@implementation RCTReachability
@implementation RCTNetInfo
{
SCNetworkReachabilityRef _reachability;
NSString *_status;
@ -30,7 +30,7 @@ RCT_EXPORT_MODULE()
static void RCTReachabilityCallback(__unused SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void *info)
{
RCTReachability *self = (__bridge id)info;
RCTNetInfo *self = (__bridge id)info;
NSString *status = RCTReachabilityStateUnknown;
if ((flags & kSCNetworkReachabilityFlagsReachable) == 0 ||
(flags & kSCNetworkReachabilityFlagsConnectionRequired) != 0) {
@ -51,8 +51,8 @@ static void RCTReachabilityCallback(__unused SCNetworkReachabilityRef target, SC
if (![status isEqualToString:self->_status]) {
self->_status = status;
[self->_bridge.eventDispatcher sendDeviceEventWithName:@"reachabilityDidChange"
body:@{@"network_reachability": status}];
[self->_bridge.eventDispatcher sendDeviceEventWithName:@"networkDidChange"
body:@{@"network_info": status}];
}
}
@ -90,7 +90,7 @@ static void RCTReachabilityCallback(__unused SCNetworkReachabilityRef target, SC
RCT_EXPORT_METHOD(getCurrentReachability:(RCTResponseSenderBlock)getSuccess
withErrorCallback:(__unused RCTResponseSenderBlock)getError)
{
getSuccess(@[@{@"network_reachability": _status}]);
getSuccess(@[@{@"network_info": _status}]);
}
@end

View File

@ -7,7 +7,7 @@
objects = {
/* Begin PBXBuildFile section */
1372B7371AB03E7B00659ED6 /* RCTReachability.m in Sources */ = {isa = PBXBuildFile; fileRef = 1372B7361AB03E7B00659ED6 /* RCTReachability.m */; };
1372B7371AB03E7B00659ED6 /* RCTNetInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 1372B7361AB03E7B00659ED6 /* RCTNetInfo.m */; };
13D6D66A1B5FCF8200883BE9 /* RCTDownloadTask.m in Sources */ = {isa = PBXBuildFile; fileRef = 13D6D6691B5FCF8200883BE9 /* RCTDownloadTask.m */; };
352DA0BA1B17855800AA15A8 /* RCTHTTPRequestHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 352DA0B81B17855800AA15A8 /* RCTHTTPRequestHandler.m */; };
58B512081A9E6CE300147676 /* RCTNetworking.m in Sources */ = {isa = PBXBuildFile; fileRef = 58B512071A9E6CE300147676 /* RCTNetworking.m */; };
@ -26,8 +26,8 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
1372B7351AB03E7B00659ED6 /* RCTReachability.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTReachability.h; sourceTree = "<group>"; };
1372B7361AB03E7B00659ED6 /* RCTReachability.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTReachability.m; sourceTree = "<group>"; };
1372B7351AB03E7B00659ED6 /* RCTNetInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = RCTNetInfo.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
1372B7361AB03E7B00659ED6 /* RCTNetInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = RCTNetInfo.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
13D6D6681B5FCF8200883BE9 /* RCTDownloadTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTDownloadTask.h; sourceTree = "<group>"; };
13D6D6691B5FCF8200883BE9 /* RCTDownloadTask.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTDownloadTask.m; sourceTree = "<group>"; };
352DA0B71B17855800AA15A8 /* RCTHTTPRequestHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTHTTPRequestHandler.h; sourceTree = "<group>"; };
@ -55,10 +55,10 @@
13D6D6691B5FCF8200883BE9 /* RCTDownloadTask.m */,
352DA0B71B17855800AA15A8 /* RCTHTTPRequestHandler.h */,
352DA0B81B17855800AA15A8 /* RCTHTTPRequestHandler.m */,
1372B7351AB03E7B00659ED6 /* RCTNetInfo.h */,
1372B7361AB03E7B00659ED6 /* RCTNetInfo.m */,
58B512061A9E6CE300147676 /* RCTNetworking.h */,
58B512071A9E6CE300147676 /* RCTNetworking.m */,
1372B7351AB03E7B00659ED6 /* RCTReachability.h */,
1372B7361AB03E7B00659ED6 /* RCTReachability.m */,
58B511DC1A9E6C8500147676 /* Products */,
);
indentWidth = 2;
@ -130,7 +130,7 @@
buildActionMask = 2147483647;
files = (
13D6D66A1B5FCF8200883BE9 /* RCTDownloadTask.m in Sources */,
1372B7371AB03E7B00659ED6 /* RCTReachability.m in Sources */,
1372B7371AB03E7B00659ED6 /* RCTNetInfo.m in Sources */,
58B512081A9E6CE300147676 /* RCTNetworking.m in Sources */,
352DA0BA1B17855800AA15A8 /* RCTHTTPRequestHandler.m in Sources */,
);

View File

@ -65,7 +65,7 @@ static NSString *RCTGenerateFormBoundary()
parts = [formData mutableCopy];
_callback = callback;
multipartBody = [[NSMutableData alloc] init];
multipartBody = [NSMutableData new];
boundary = RCTGenerateFormBoundary();
return [_networker processDataForHTTPQuery:parts[0] callback:^(NSError *error, NSDictionary *result) {
@ -88,7 +88,7 @@ static NSString *RCTGenerateFormBoundary()
NSMutableDictionary *headers = [parts[0][@"headers"] mutableCopy];
NSString *partContentType = result[@"contentType"];
if (partContentType != nil) {
[headers setObject:partContentType forKey:@"content-type"];
headers[@"content-type"] = partContentType;
}
[headers enumerateKeysAndObjectsUsingBlock:^(NSString *parameterKey, NSString *parameterValue, BOOL *stop) {
[multipartBody appendData:[[NSString stringWithFormat:@"%@: %@\r\n", parameterKey, parameterValue]
@ -132,7 +132,7 @@ RCT_EXPORT_MODULE()
- (instancetype)init
{
if ((self = [super init])) {
_tasksByRequestID = [[NSMutableDictionary alloc] init];
_tasksByRequestID = [NSMutableDictionary new];
}
return self;
}
@ -140,12 +140,12 @@ RCT_EXPORT_MODULE()
- (RCTURLRequestCancellationBlock)buildRequest:(NSDictionary *)query
completionBlock:(void (^)(NSURLRequest *request))block
{
NSURL *URL = [RCTConvert NSURL:query[@"url"]];
NSURL *URL = [RCTConvert NSURL:query[@"url"]]; // this is marked as nullable in JS, but should not be null
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];
request.HTTPMethod = [[RCTConvert NSString:query[@"method"]] uppercaseString] ?: @"GET";
request.HTTPMethod = [RCTConvert NSString:RCTNilIfNull(query[@"method"])].uppercaseString ?: @"GET";
request.allHTTPHeaderFields = [RCTConvert NSDictionary:query[@"headers"]];
NSDictionary *data = [RCTConvert NSDictionary:query[@"data"]];
NSDictionary *data = [RCTConvert NSDictionary:RCTNilIfNull(query[@"data"])];
return [self processDataForHTTPQuery:data callback:^(NSError *error, NSDictionary *result) {
if (error) {
RCTLogError(@"Error processing request body: %@", error);
@ -161,7 +161,7 @@ RCT_EXPORT_MODULE()
// Gzip the request body
if ([request.allHTTPHeaderFields[@"Content-Encoding"] isEqualToString:@"gzip"]) {
request.HTTPBody = RCTGzipData(request.HTTPBody, -1 /* default */);
[request setValue:[@(request.HTTPBody.length) description] forHTTPHeaderField:@"Content-Length"];
[request setValue:(@(request.HTTPBody.length)).description forHTTPHeaderField:@"Content-Length"];
}
block(request);
@ -195,7 +195,7 @@ RCT_EXPORT_MODULE()
return NSOrderedSame;
}
}];
id<RCTURLRequestHandler> handler = [handlers lastObject];
id<RCTURLRequestHandler> handler = handlers.lastObject;
if (!handler) {
RCTLogError(@"No suitable request handler found for %@", request.URL);
}
@ -220,7 +220,7 @@ RCT_EXPORT_MODULE()
* - @"contentType" (NSString): the content type header of the request
*
*/
- (RCTURLRequestCancellationBlock)processDataForHTTPQuery:(NSDictionary *)query callback:
- (RCTURLRequestCancellationBlock)processDataForHTTPQuery:(nullable NSDictionary *)query callback:
(RCTURLRequestCancellationBlock (^)(NSError *error, NSDictionary *result))callback
{
if (!query) {
@ -248,7 +248,7 @@ RCT_EXPORT_MODULE()
}
NSDictionaryArray *formData = [RCTConvert NSDictionaryArray:query[@"formData"]];
if (formData) {
RCTHTTPFormDataHelper *formDataHelper = [[RCTHTTPFormDataHelper alloc] init];
RCTHTTPFormDataHelper *formDataHelper = [RCTHTTPFormDataHelper new];
formDataHelper.networker = self;
return [formDataHelper process:formData callback:callback];
}

View File

@ -104,8 +104,7 @@ class XMLHttpRequest extends XMLHttpRequestBase {
sendImpl(method: ?string, url: ?string, headers: Object, data: any): void {
if (typeof data === 'string') {
data = {string: data};
}
if (data instanceof FormData) {
} else if (data instanceof FormData) {
data = {formData: data.getParts()};
}
RCTNetworking.sendRequest(

View File

@ -6,7 +6,9 @@
*/
'use strict';
var Platform = require('Platform');
var React = require('React');
var RCTUIManager = require('NativeModules').UIManager;
var StyleSheet = require('StyleSheet');
var View = require('View');
@ -72,7 +74,15 @@ var Portal = React.createClass({
return [];
}
return _portalRef._getOpenModals();
}
},
notifyAccessibilityService: function() {
if (!_portalRef) {
console.error('Calling closeModal but no Portal has been rendered.');
return;
}
_portalRef._notifyAccessibilityService();
},
},
getInitialState: function() {
@ -80,6 +90,11 @@ var Portal = React.createClass({
},
_showModal: function(tag: string, component: any) {
// We are about to open first modal, so Portal will appear.
// Let's disable accessibility for background view on Android.
if (this._getOpenModals().length === 0) {
this.props.onModalVisibilityChanged(true);
}
// This way state is chained through multiple calls to
// _showModal, _closeModal correctly.
this.setState((state) => {
@ -93,6 +108,11 @@ var Portal = React.createClass({
if (!this.state.modals.hasOwnProperty(tag)) {
return;
}
// We are about to close last modal, so Portal will disappear.
// Let's enable accessibility for application view on Android.
if (this._getOpenModals().length === 1) {
this.props.onModalVisibilityChanged(false);
}
// This way state is chained through multiple calls to
// _showModal, _closeModal correctly.
this.setState((state) => {
@ -106,6 +126,20 @@ var Portal = React.createClass({
return Object.keys(this.state.modals);
},
_notifyAccessibilityService: function() {
if (Platform.OS === 'android') {
// We need to send accessibility event in a new batch, as otherwise
// TextViews have no text set at the moment of populating event.
setTimeout(() => {
if (this._getOpenModals().length > 0) {
RCTUIManager.sendAccessibilityEvent(
React.findNodeHandle(this),
RCTUIManager.AccessibilityEventTypes.typeWindowStateChanged);
}
}, 0);
}
},
render: function() {
_portalRef = this;
if (!this.state.modals) {
@ -119,7 +153,9 @@ var Portal = React.createClass({
return null;
}
return (
<View style={styles.modalsContainer}>
<View
style={styles.modalsContainer}
importantForAccessibility="yes">
{modals}
</View>
);

View File

@ -32,7 +32,7 @@ NSString *const RCTRemoteNotificationsRegistered = @"RemoteNotificationsRegister
+ (UILocalNotification *)UILocalNotification:(id)json
{
NSDictionary *details = [self NSDictionary:json];
UILocalNotification *notification = [[UILocalNotification alloc] init];
UILocalNotification *notification = [UILocalNotification new];
notification.fireDate = [RCTConvert NSDate:details[@"fireDate"]] ?: [NSDate date];
notification.alertBody = [RCTConvert NSString:details[@"alertBody"]];
return notification;
@ -108,13 +108,13 @@ RCT_EXPORT_MODULE()
- (void)handleRemoteNotificationReceived:(NSNotification *)notification
{
[_bridge.eventDispatcher sendDeviceEventWithName:@"remoteNotificationReceived"
body:[notification userInfo]];
body:notification.userInfo];
}
- (void)handleRemoteNotificationsRegistered:(NSNotification *)notification
{
[_bridge.eventDispatcher sendDeviceEventWithName:@"remoteNotificationsRegistered"
body:[notification userInfo]];
body:notification.userInfo];
}
/**
@ -175,7 +175,7 @@ RCT_EXPORT_METHOD(checkPermissions:(RCTResponseSenderBlock)callback)
{
NSUInteger types = 0;
if ([UIApplication instancesRespondToSelector:@selector(currentUserNotificationSettings)]) {
types = [[[UIApplication sharedApplication] currentUserNotificationSettings] types];
types = [[UIApplication sharedApplication] currentUserNotificationSettings].types;
} else {
#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_8_0
@ -186,7 +186,7 @@ RCT_EXPORT_METHOD(checkPermissions:(RCTResponseSenderBlock)callback)
}
NSMutableDictionary *permissions = [[NSMutableDictionary alloc] init];
NSMutableDictionary *permissions = [NSMutableDictionary new];
permissions[@"alert"] = @((types & UIUserNotificationTypeAlert) > 0);
permissions[@"badge"] = @((types & UIUserNotificationTypeBadge) > 0);
permissions[@"sound"] = @((types & UIUserNotificationTypeSound) > 0);

View File

@ -51,7 +51,7 @@ typedef struct RGBAPixel {
{
if ((self = [super init])) {
_testName = [testName copy];
_fileManager = [[NSFileManager alloc] init];
_fileManager = [NSFileManager new];
}
return self;
}

View File

@ -65,7 +65,7 @@
(CGBitmapInfo)kCGImageAlphaPremultipliedLast
);
CGFloat scaleFactor = [[UIScreen mainScreen] scale];
CGFloat scaleFactor = [UIScreen mainScreen].scale;
CGContextScaleCTM(referenceImageContext, scaleFactor, scaleFactor);
CGContextScaleCTM(imageContext, scaleFactor, scaleFactor);

View File

@ -44,7 +44,7 @@ RCT_EXPORT_METHOD(verifySnapshot:(RCTResponseSenderBlock)callback)
[_bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) {
NSString *testName = NSStringFromSelector(_testSelector);
_snapshotCounter[testName] = [@([_snapshotCounter[testName] integerValue] + 1) stringValue];
_snapshotCounter[testName] = (@([_snapshotCounter[testName] integerValue] + 1)).stringValue;
NSError *error = nil;
BOOL success = [_controller compareSnapshotOfView:_view

View File

@ -11,7 +11,7 @@
#import "FBSnapshotTestController.h"
#import "RCTAssert.h"
#import "RCTRedBox.h"
#import "RCTLog.h"
#import "RCTRootView.h"
#import "RCTTestModule.h"
#import "RCTUtils.h"
@ -55,7 +55,7 @@
return self;
}
RCT_NOT_IMPLEMENTED(-init)
RCT_NOT_IMPLEMENTED(- (instancetype)init)
- (void)setRecordMode:(BOOL)recordMode
{
@ -83,12 +83,18 @@ RCT_NOT_IMPLEMENTED(-init)
- (void)runTest:(SEL)test module:(NSString *)moduleName
initialProps:(NSDictionary *)initialProps expectErrorBlock:(BOOL(^)(NSString *error))expectErrorBlock
{
__block NSString *error = nil;
RCTSetLogFunction(^(RCTLogLevel level, NSString *fileName, NSNumber *lineNumber, NSString *message) {
if (level >= RCTLogLevelError) {
error = message;
}
});
RCTBridge *bridge = [[RCTBridge alloc] initWithBundleURL:_scriptURL
moduleProvider:_moduleProvider
launchOptions:nil];
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge moduleName:moduleName];
rootView.initialProperties = initialProps;
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge moduleName:moduleName initialProperties:initialProps];
rootView.frame = CGRectMake(0, 0, 320, 2000); // Constant size for testing on multiple devices
NSString *testModuleName = RCTBridgeModuleNameForClass([RCTTestModule class]);
@ -99,24 +105,23 @@ RCT_NOT_IMPLEMENTED(-init)
testModule.view = rootView;
UIViewController *vc = [UIApplication sharedApplication].delegate.window.rootViewController;
vc.view = [[UIView alloc] init];
vc.view = [UIView new];
[vc.view addSubview:rootView]; // Add as subview so it doesn't get resized
NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS];
NSString *error = [[RCTRedBox sharedInstance] currentErrorMessage];
while ([date timeIntervalSinceNow] > 0 && testModule.status == RCTTestStatusPending && error == nil) {
while (date.timeIntervalSinceNow > 0 && testModule.status == RCTTestStatusPending && error == nil) {
[[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
[[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
error = [[RCTRedBox sharedInstance] currentErrorMessage];
}
[rootView removeFromSuperview];
RCTSetLogFunction(RCTDefaultLogFunction);
NSArray *nonLayoutSubviews = [vc.view.subviews filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id subview, NSDictionary *bindings) {
return ![NSStringFromClass([subview class]) isEqualToString:@"_UILayoutGuide"];
}]];
RCTAssert(nonLayoutSubviews.count == 0, @"There shouldn't be any other views: %@", nonLayoutSubviews);
[[RCTRedBox sharedInstance] dismiss];
if (expectErrorBlock) {
RCTAssert(expectErrorBlock(error), @"Expected an error but nothing matched.");
} else {

View File

@ -12,7 +12,6 @@
'use strict';
var NativeModules = require('NativeModules');
var RCTPOPAnimationManager = NativeModules.POPAnimationManager;
var RCTUIManager = NativeModules.UIManager;
var TextInputState = require('TextInputState');
@ -38,32 +37,8 @@ type MeasureLayoutOnSuccessCallback = (
height: number
) => void
var animationIDInvariant = function(
funcName: string,
anim: number
) {
invariant(
anim,
funcName + ' must be called with a valid animation ID returned from' +
' POPAnimation.createAnimation, received: "' + anim + '"'
);
};
var NativeMethodsMixin = {
addAnimation: function(anim: number, callback?: (finished: bool) => void) {
animationIDInvariant('addAnimation', anim);
RCTPOPAnimationManager.addAnimation(
findNodeHandle(this),
anim,
mountSafeCallback(this, callback)
);
},
removeAnimation: function(anim: number) {
animationIDInvariant('removeAnimation', anim);
RCTPOPAnimationManager.removeAnimation(findNodeHandle(this), anim);
},
measure: function(callback: MeasureOnSuccessCallback) {
RCTUIManager.measure(
findNodeHandle(this),

View File

@ -21,6 +21,7 @@ var ReactInstanceHandles = require('ReactInstanceHandles');
var ReactNativeDefaultInjection = require('ReactNativeDefaultInjection');
var ReactNativeMount = require('ReactNativeMount');
var ReactPropTypes = require('ReactPropTypes');
var ReactUpdates = require('ReactUpdates');
var deprecated = require('deprecated');
var findNodeHandle = require('findNodeHandle');
@ -94,7 +95,11 @@ var ReactNative = {
render: render,
unmountComponentAtNode: ReactNativeMount.unmountComponentAtNode,
// Hook for JSX spread, don't use this for anything else.
/* eslint-disable camelcase */
unstable_batchedUpdates: ReactUpdates.batchedUpdates,
/* eslint-enable camelcase */
// Hook for JSX spread, don't use this for anything else.
__spread: Object.assign,
unmountComponentAtNodeAndRemoveContainer: ReactNativeMount.unmountComponentAtNodeAndRemoveContainer,

View File

@ -27,6 +27,7 @@ var warning = require('warning');
var registrationNames = ReactNativeEventEmitter.registrationNames;
var putListener = ReactNativeEventEmitter.putListener;
var deleteListener = ReactNativeEventEmitter.deleteListener;
var deleteAllListeners = ReactNativeEventEmitter.deleteAllListeners;
type ReactNativeBaseComponentViewConfig = {
@ -230,7 +231,11 @@ ReactNativeBaseComponent.Mixin = {
_reconcileListenersUponUpdate: function(prevProps, nextProps) {
for (var key in nextProps) {
if (registrationNames[key] && (nextProps[key] !== prevProps[key])) {
putListener(this._rootNodeID, key, nextProps[key]);
if (nextProps[key]) {
putListener(this._rootNodeID, key, nextProps[key]);
} else {
deleteListener(this._rootNodeID, key);
}
}
}
},

Some files were not shown because too many files have changed in this diff Show More