Updates from Tue 25 Aug
This commit is contained in:
commit
da7ac11c53
|
@ -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;
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
|
||||
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
|
||||
moduleName:@"Game2048"
|
||||
initialProperties:nil
|
||||
launchOptions:launchOptions];
|
||||
|
||||
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
|
||||
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
|
||||
moduleName:@"MoviesApp"
|
||||
initialProperties:nil
|
||||
launchOptions:launchOptions];
|
||||
|
||||
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
{}
|
|
@ -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";
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
|
||||
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
|
||||
moduleName:@"TicTacToeApp"
|
||||
initialProperties:nil
|
||||
launchOptions:launchOptions];
|
||||
|
||||
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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: {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
declare module 'image!uie_thumb_selected' {
|
||||
/* $FlowIssue #7387208 - There's a flow bug preventing this type from flowing
|
||||
* into a proptype shape */
|
||||
declare module 'image!uie_thumb_selected' {
|
||||
declare var uri: string;
|
||||
declare var isStatic: boolean;
|
||||
}
|
||||
|
|
|
@ -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 />;
|
||||
},
|
||||
|
|
|
@ -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 style={styles.row}>
|
||||
<Text style={styles.rowTitle}>Animated</Text>
|
||||
<SwitchIOS value={this.state.animated} onValueChange={this._toggleAnimated} />
|
||||
</View>
|
||||
</Modal>
|
||||
|
||||
<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,
|
||||
},
|
||||
});
|
||||
|
|
|
@ -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({
|
||||
|
|
|
@ -27,6 +27,7 @@ var {
|
|||
} = React;
|
||||
|
||||
exports.displayName = (undefined: ?string);
|
||||
exports.description = 'Touchable and onPress examples';
|
||||
exports.title = '<Touchable*> and onPress';
|
||||
exports.examples = [
|
||||
{
|
||||
|
|
|
@ -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 */,
|
||||
);
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 |
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
|
||||
- (void)setUp
|
||||
{
|
||||
self.cache = [[RCTCache alloc] init];
|
||||
self.cache = [RCTCache new];
|
||||
self.cache.countLimit = 3;
|
||||
self.cache.totalCostLimit = 100;
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
{
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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
|
||||
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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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?");
|
||||
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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 { \
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
BEGIN {
|
||||
FS = ":"
|
||||
RS = ","
|
||||
}
|
||||
|
||||
/"Version"/ {
|
||||
version = substr($2, 2, length($2) - 2)
|
||||
print int(version)
|
||||
exit 0
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
|
@ -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);
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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),
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
/**
|
||||
* Copyright 2004-present Facebook. All Rights Reserved.
|
||||
*
|
||||
* @providesModule ProgressBarAndroid
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
module.exports = require('UnimplementedView');
|
|
@ -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 &&
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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({
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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({
|
||||
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.
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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];
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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,
|
||||
RCT_EXTERN CGSize RCTTargetSize(CGSize sourceSize, CGFloat sourceScale,
|
||||
CGSize destSize, CGFloat destScale,
|
||||
UIViewContentMode resizeMode);
|
||||
UIViewContentMode resizeMode,
|
||||
BOOL allowUpscaling);
|
||||
|
||||
/**
|
||||
* This function takes an input content size & scale (typically from an image),
|
||||
|
|
|
@ -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
|
||||
|
@ -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,7 +106,37 @@ CGRect RCTClipRect(CGSize sourceSize, CGFloat sourceScale,
|
|||
}
|
||||
}
|
||||
|
||||
RCT_EXTERN BOOL RCTUpscalingRequired(CGSize sourceSize, CGFloat sourceScale,
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
|
@ -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--) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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};
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,14 +15,9 @@ var Map = require('Map');
|
|||
var NativeModules = require('NativeModules');
|
||||
var Platform = require('Platform');
|
||||
var RCTDeviceEventEmitter = require('RCTDeviceEventEmitter');
|
||||
|
||||
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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
#import "RCTBridgeModule.h"
|
||||
|
||||
@interface RCTReachability : NSObject<RCTBridgeModule>
|
||||
@interface RCTNetInfo : NSObject<RCTBridgeModule>
|
||||
|
||||
- (instancetype)initWithHost:(NSString *)host NS_DESIGNATED_INITIALIZER;
|
||||
|
|
@ -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
|
|
@ -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 */,
|
||||
);
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -51,7 +51,7 @@ typedef struct RGBAPixel {
|
|||
{
|
||||
if ((self = [super init])) {
|
||||
_testName = [testName copy];
|
||||
_fileManager = [[NSFileManager alloc] init];
|
||||
_fileManager = [NSFileManager new];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@
|
|||
(CGBitmapInfo)kCGImageAlphaPremultipliedLast
|
||||
);
|
||||
|
||||
CGFloat scaleFactor = [[UIScreen mainScreen] scale];
|
||||
CGFloat scaleFactor = [UIScreen mainScreen].scale;
|
||||
CGContextScaleCTM(referenceImageContext, scaleFactor, scaleFactor);
|
||||
CGContextScaleCTM(imageContext, scaleFactor, scaleFactor);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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,6 +95,10 @@ var ReactNative = {
|
|||
render: render,
|
||||
unmountComponentAtNode: ReactNativeMount.unmountComponentAtNode,
|
||||
|
||||
/* eslint-disable camelcase */
|
||||
unstable_batchedUpdates: ReactUpdates.batchedUpdates,
|
||||
/* eslint-enable camelcase */
|
||||
|
||||
// Hook for JSX spread, don't use this for anything else.
|
||||
__spread: Object.assign,
|
||||
|
||||
|
|
|
@ -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])) {
|
||||
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
Loading…
Reference in New Issue